diff options
Diffstat (limited to 'third_party/libwebrtc/audio/voip/audio_egress.h')
-rw-r--r-- | third_party/libwebrtc/audio/voip/audio_egress.h | 158 |
1 files changed, 158 insertions, 0 deletions
diff --git a/third_party/libwebrtc/audio/voip/audio_egress.h b/third_party/libwebrtc/audio/voip/audio_egress.h new file mode 100644 index 0000000000..989e5bda59 --- /dev/null +++ b/third_party/libwebrtc/audio/voip/audio_egress.h @@ -0,0 +1,158 @@ +/* + * Copyright (c) 2020 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#ifndef AUDIO_VOIP_AUDIO_EGRESS_H_ +#define AUDIO_VOIP_AUDIO_EGRESS_H_ + +#include <memory> +#include <string> + +#include "api/audio_codecs/audio_format.h" +#include "api/sequence_checker.h" +#include "api/task_queue/task_queue_factory.h" +#include "audio/audio_level.h" +#include "audio/utility/audio_frame_operations.h" +#include "call/audio_sender.h" +#include "modules/audio_coding/include/audio_coding_module.h" +#include "modules/rtp_rtcp/include/report_block_data.h" +#include "modules/rtp_rtcp/source/rtp_rtcp_interface.h" +#include "modules/rtp_rtcp/source/rtp_sender_audio.h" +#include "rtc_base/synchronization/mutex.h" +#include "rtc_base/task_queue.h" +#include "rtc_base/time_utils.h" + +namespace webrtc { + +// AudioEgress receives input samples from AudioDeviceModule via +// AudioTransportImpl through AudioSender interface. Once it encodes the sample +// via selected encoder through AudioPacketizationCallback interface, the +// encoded payload will be packetized by the RTP stack, resulting in ready to +// send RTP packet to remote endpoint. +// +// TaskQueue is used to encode and send RTP asynchrounously as some OS platform +// uses the same thread for both audio input and output sample deliveries which +// can affect audio quality. +// +// Note that this class is originally based on ChannelSend in +// audio/channel_send.cc with non-audio related logic trimmed as aimed for +// smaller footprint. +class AudioEgress : public AudioSender, public AudioPacketizationCallback { + public: + AudioEgress(RtpRtcpInterface* rtp_rtcp, + Clock* clock, + TaskQueueFactory* task_queue_factory); + ~AudioEgress() override; + + // Set the encoder format and payload type for AudioCodingModule. + // It's possible to change the encoder type during its active usage. + // `payload_type` must be the type that is negotiated with peer through + // offer/answer. + void SetEncoder(int payload_type, + const SdpAudioFormat& encoder_format, + std::unique_ptr<AudioEncoder> encoder); + + // Start or stop sending operation of AudioEgress. This will start/stop + // the RTP stack also causes encoder queue thread to start/stop + // processing input audio samples. StartSend will return false if + // a send codec has not been set. + bool StartSend(); + void StopSend(); + + // Query the state of the RTP stack. This returns true if StartSend() + // called and false if StopSend() is called. + bool IsSending() const; + + // Enable or disable Mute state. + void SetMute(bool mute); + + // Retrieve current encoder format info. This returns encoder format set + // by SetEncoder() and if encoder is not set, this will return nullopt. + absl::optional<SdpAudioFormat> GetEncoderFormat() const { + MutexLock lock(&lock_); + return encoder_format_; + } + + // Register the payload type and sample rate for DTMF (RFC 4733) payload. + void RegisterTelephoneEventType(int rtp_payload_type, int sample_rate_hz); + + // Send DTMF named event as specified by + // https://tools.ietf.org/html/rfc4733#section-3.2 + // `duration_ms` specifies the duration of DTMF packets that will be emitted + // in place of real RTP packets instead. + // This will return true when requested dtmf event is successfully scheduled + // otherwise false when the dtmf queue reached maximum of 20 events. + bool SendTelephoneEvent(int dtmf_event, int duration_ms); + + // See comments on LevelFullRange, TotalEnergy, TotalDuration from + // audio/audio_level.h. + int GetInputAudioLevel() const { return input_audio_level_.LevelFullRange(); } + double GetInputTotalEnergy() const { + return input_audio_level_.TotalEnergy(); + } + double GetInputTotalDuration() const { + return input_audio_level_.TotalDuration(); + } + + // Implementation of AudioSender interface. + void SendAudioData(std::unique_ptr<AudioFrame> audio_frame) override; + + // Implementation of AudioPacketizationCallback interface. + int32_t SendData(AudioFrameType frame_type, + uint8_t payload_type, + uint32_t timestamp, + const uint8_t* payload_data, + size_t payload_size) override; + + private: + void SetEncoderFormat(const SdpAudioFormat& encoder_format) { + MutexLock lock(&lock_); + encoder_format_ = encoder_format; + } + + mutable Mutex lock_; + + // Current encoder format selected by caller. + absl::optional<SdpAudioFormat> encoder_format_ RTC_GUARDED_BY(lock_); + + // Synchronization is handled internally by RtpRtcp. + RtpRtcpInterface* const rtp_rtcp_; + + // Synchronization is handled internally by RTPSenderAudio. + RTPSenderAudio rtp_sender_audio_; + + // Synchronization is handled internally by AudioCodingModule. + const std::unique_ptr<AudioCodingModule> audio_coding_; + + // Synchronization is handled internally by voe::AudioLevel. + voe::AudioLevel input_audio_level_; + + // Struct that holds all variables used by encoder task queue. + struct EncoderContext { + // Offset used to mark rtp timestamp in sample rate unit in + // newly received audio frame from AudioTransport. + uint32_t frame_rtp_timestamp_ = 0; + + // Flag to track mute state from caller. `previously_muted_` is used to + // track previous state as part of input to AudioFrameOperations::Mute + // to implement fading effect when (un)mute is invoked. + bool mute_ = false; + bool previously_muted_ = false; + }; + + EncoderContext encoder_context_ RTC_GUARDED_BY(encoder_queue_); + + // Defined last to ensure that there are no running tasks when the other + // members are destroyed. + rtc::TaskQueue encoder_queue_; +}; + +} // namespace webrtc + +#endif // AUDIO_VOIP_AUDIO_EGRESS_H_ |