1*d9f75844SAndroid Build Coastguard Worker /* 2*d9f75844SAndroid Build Coastguard Worker * Copyright (c) 2020 The WebRTC project authors. All Rights Reserved. 3*d9f75844SAndroid Build Coastguard Worker * 4*d9f75844SAndroid Build Coastguard Worker * Use of this source code is governed by a BSD-style license 5*d9f75844SAndroid Build Coastguard Worker * that can be found in the LICENSE file in the root of the source 6*d9f75844SAndroid Build Coastguard Worker * tree. An additional intellectual property rights grant can be found 7*d9f75844SAndroid Build Coastguard Worker * in the file PATENTS. All contributing project authors may 8*d9f75844SAndroid Build Coastguard Worker * be found in the AUTHORS file in the root of the source tree. 9*d9f75844SAndroid Build Coastguard Worker */ 10*d9f75844SAndroid Build Coastguard Worker 11*d9f75844SAndroid Build Coastguard Worker #ifndef AUDIO_VOIP_AUDIO_EGRESS_H_ 12*d9f75844SAndroid Build Coastguard Worker #define AUDIO_VOIP_AUDIO_EGRESS_H_ 13*d9f75844SAndroid Build Coastguard Worker 14*d9f75844SAndroid Build Coastguard Worker #include <memory> 15*d9f75844SAndroid Build Coastguard Worker #include <string> 16*d9f75844SAndroid Build Coastguard Worker 17*d9f75844SAndroid Build Coastguard Worker #include "api/audio_codecs/audio_format.h" 18*d9f75844SAndroid Build Coastguard Worker #include "api/sequence_checker.h" 19*d9f75844SAndroid Build Coastguard Worker #include "api/task_queue/task_queue_factory.h" 20*d9f75844SAndroid Build Coastguard Worker #include "audio/audio_level.h" 21*d9f75844SAndroid Build Coastguard Worker #include "audio/utility/audio_frame_operations.h" 22*d9f75844SAndroid Build Coastguard Worker #include "call/audio_sender.h" 23*d9f75844SAndroid Build Coastguard Worker #include "modules/audio_coding/include/audio_coding_module.h" 24*d9f75844SAndroid Build Coastguard Worker #include "modules/rtp_rtcp/include/report_block_data.h" 25*d9f75844SAndroid Build Coastguard Worker #include "modules/rtp_rtcp/source/rtp_rtcp_interface.h" 26*d9f75844SAndroid Build Coastguard Worker #include "modules/rtp_rtcp/source/rtp_sender_audio.h" 27*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/synchronization/mutex.h" 28*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/task_queue.h" 29*d9f75844SAndroid Build Coastguard Worker #include "rtc_base/time_utils.h" 30*d9f75844SAndroid Build Coastguard Worker 31*d9f75844SAndroid Build Coastguard Worker namespace webrtc { 32*d9f75844SAndroid Build Coastguard Worker 33*d9f75844SAndroid Build Coastguard Worker // AudioEgress receives input samples from AudioDeviceModule via 34*d9f75844SAndroid Build Coastguard Worker // AudioTransportImpl through AudioSender interface. Once it encodes the sample 35*d9f75844SAndroid Build Coastguard Worker // via selected encoder through AudioPacketizationCallback interface, the 36*d9f75844SAndroid Build Coastguard Worker // encoded payload will be packetized by the RTP stack, resulting in ready to 37*d9f75844SAndroid Build Coastguard Worker // send RTP packet to remote endpoint. 38*d9f75844SAndroid Build Coastguard Worker // 39*d9f75844SAndroid Build Coastguard Worker // TaskQueue is used to encode and send RTP asynchrounously as some OS platform 40*d9f75844SAndroid Build Coastguard Worker // uses the same thread for both audio input and output sample deliveries which 41*d9f75844SAndroid Build Coastguard Worker // can affect audio quality. 42*d9f75844SAndroid Build Coastguard Worker // 43*d9f75844SAndroid Build Coastguard Worker // Note that this class is originally based on ChannelSend in 44*d9f75844SAndroid Build Coastguard Worker // audio/channel_send.cc with non-audio related logic trimmed as aimed for 45*d9f75844SAndroid Build Coastguard Worker // smaller footprint. 46*d9f75844SAndroid Build Coastguard Worker class AudioEgress : public AudioSender, public AudioPacketizationCallback { 47*d9f75844SAndroid Build Coastguard Worker public: 48*d9f75844SAndroid Build Coastguard Worker AudioEgress(RtpRtcpInterface* rtp_rtcp, 49*d9f75844SAndroid Build Coastguard Worker Clock* clock, 50*d9f75844SAndroid Build Coastguard Worker TaskQueueFactory* task_queue_factory); 51*d9f75844SAndroid Build Coastguard Worker ~AudioEgress() override; 52*d9f75844SAndroid Build Coastguard Worker 53*d9f75844SAndroid Build Coastguard Worker // Set the encoder format and payload type for AudioCodingModule. 54*d9f75844SAndroid Build Coastguard Worker // It's possible to change the encoder type during its active usage. 55*d9f75844SAndroid Build Coastguard Worker // `payload_type` must be the type that is negotiated with peer through 56*d9f75844SAndroid Build Coastguard Worker // offer/answer. 57*d9f75844SAndroid Build Coastguard Worker void SetEncoder(int payload_type, 58*d9f75844SAndroid Build Coastguard Worker const SdpAudioFormat& encoder_format, 59*d9f75844SAndroid Build Coastguard Worker std::unique_ptr<AudioEncoder> encoder); 60*d9f75844SAndroid Build Coastguard Worker 61*d9f75844SAndroid Build Coastguard Worker // Start or stop sending operation of AudioEgress. This will start/stop 62*d9f75844SAndroid Build Coastguard Worker // the RTP stack also causes encoder queue thread to start/stop 63*d9f75844SAndroid Build Coastguard Worker // processing input audio samples. StartSend will return false if 64*d9f75844SAndroid Build Coastguard Worker // a send codec has not been set. 65*d9f75844SAndroid Build Coastguard Worker bool StartSend(); 66*d9f75844SAndroid Build Coastguard Worker void StopSend(); 67*d9f75844SAndroid Build Coastguard Worker 68*d9f75844SAndroid Build Coastguard Worker // Query the state of the RTP stack. This returns true if StartSend() 69*d9f75844SAndroid Build Coastguard Worker // called and false if StopSend() is called. 70*d9f75844SAndroid Build Coastguard Worker bool IsSending() const; 71*d9f75844SAndroid Build Coastguard Worker 72*d9f75844SAndroid Build Coastguard Worker // Enable or disable Mute state. 73*d9f75844SAndroid Build Coastguard Worker void SetMute(bool mute); 74*d9f75844SAndroid Build Coastguard Worker 75*d9f75844SAndroid Build Coastguard Worker // Retrieve current encoder format info. This returns encoder format set 76*d9f75844SAndroid Build Coastguard Worker // by SetEncoder() and if encoder is not set, this will return nullopt. GetEncoderFormat()77*d9f75844SAndroid Build Coastguard Worker absl::optional<SdpAudioFormat> GetEncoderFormat() const { 78*d9f75844SAndroid Build Coastguard Worker MutexLock lock(&lock_); 79*d9f75844SAndroid Build Coastguard Worker return encoder_format_; 80*d9f75844SAndroid Build Coastguard Worker } 81*d9f75844SAndroid Build Coastguard Worker 82*d9f75844SAndroid Build Coastguard Worker // Register the payload type and sample rate for DTMF (RFC 4733) payload. 83*d9f75844SAndroid Build Coastguard Worker void RegisterTelephoneEventType(int rtp_payload_type, int sample_rate_hz); 84*d9f75844SAndroid Build Coastguard Worker 85*d9f75844SAndroid Build Coastguard Worker // Send DTMF named event as specified by 86*d9f75844SAndroid Build Coastguard Worker // https://tools.ietf.org/html/rfc4733#section-3.2 87*d9f75844SAndroid Build Coastguard Worker // `duration_ms` specifies the duration of DTMF packets that will be emitted 88*d9f75844SAndroid Build Coastguard Worker // in place of real RTP packets instead. 89*d9f75844SAndroid Build Coastguard Worker // This will return true when requested dtmf event is successfully scheduled 90*d9f75844SAndroid Build Coastguard Worker // otherwise false when the dtmf queue reached maximum of 20 events. 91*d9f75844SAndroid Build Coastguard Worker bool SendTelephoneEvent(int dtmf_event, int duration_ms); 92*d9f75844SAndroid Build Coastguard Worker 93*d9f75844SAndroid Build Coastguard Worker // See comments on LevelFullRange, TotalEnergy, TotalDuration from 94*d9f75844SAndroid Build Coastguard Worker // audio/audio_level.h. GetInputAudioLevel()95*d9f75844SAndroid Build Coastguard Worker int GetInputAudioLevel() const { return input_audio_level_.LevelFullRange(); } GetInputTotalEnergy()96*d9f75844SAndroid Build Coastguard Worker double GetInputTotalEnergy() const { 97*d9f75844SAndroid Build Coastguard Worker return input_audio_level_.TotalEnergy(); 98*d9f75844SAndroid Build Coastguard Worker } GetInputTotalDuration()99*d9f75844SAndroid Build Coastguard Worker double GetInputTotalDuration() const { 100*d9f75844SAndroid Build Coastguard Worker return input_audio_level_.TotalDuration(); 101*d9f75844SAndroid Build Coastguard Worker } 102*d9f75844SAndroid Build Coastguard Worker 103*d9f75844SAndroid Build Coastguard Worker // Implementation of AudioSender interface. 104*d9f75844SAndroid Build Coastguard Worker void SendAudioData(std::unique_ptr<AudioFrame> audio_frame) override; 105*d9f75844SAndroid Build Coastguard Worker 106*d9f75844SAndroid Build Coastguard Worker // Implementation of AudioPacketizationCallback interface. 107*d9f75844SAndroid Build Coastguard Worker int32_t SendData(AudioFrameType frame_type, 108*d9f75844SAndroid Build Coastguard Worker uint8_t payload_type, 109*d9f75844SAndroid Build Coastguard Worker uint32_t timestamp, 110*d9f75844SAndroid Build Coastguard Worker const uint8_t* payload_data, 111*d9f75844SAndroid Build Coastguard Worker size_t payload_size) override; 112*d9f75844SAndroid Build Coastguard Worker 113*d9f75844SAndroid Build Coastguard Worker private: SetEncoderFormat(const SdpAudioFormat & encoder_format)114*d9f75844SAndroid Build Coastguard Worker void SetEncoderFormat(const SdpAudioFormat& encoder_format) { 115*d9f75844SAndroid Build Coastguard Worker MutexLock lock(&lock_); 116*d9f75844SAndroid Build Coastguard Worker encoder_format_ = encoder_format; 117*d9f75844SAndroid Build Coastguard Worker } 118*d9f75844SAndroid Build Coastguard Worker 119*d9f75844SAndroid Build Coastguard Worker mutable Mutex lock_; 120*d9f75844SAndroid Build Coastguard Worker 121*d9f75844SAndroid Build Coastguard Worker // Current encoder format selected by caller. 122*d9f75844SAndroid Build Coastguard Worker absl::optional<SdpAudioFormat> encoder_format_ RTC_GUARDED_BY(lock_); 123*d9f75844SAndroid Build Coastguard Worker 124*d9f75844SAndroid Build Coastguard Worker // Synchronization is handled internally by RtpRtcp. 125*d9f75844SAndroid Build Coastguard Worker RtpRtcpInterface* const rtp_rtcp_; 126*d9f75844SAndroid Build Coastguard Worker 127*d9f75844SAndroid Build Coastguard Worker // Synchronization is handled internally by RTPSenderAudio. 128*d9f75844SAndroid Build Coastguard Worker RTPSenderAudio rtp_sender_audio_; 129*d9f75844SAndroid Build Coastguard Worker 130*d9f75844SAndroid Build Coastguard Worker // Synchronization is handled internally by AudioCodingModule. 131*d9f75844SAndroid Build Coastguard Worker const std::unique_ptr<AudioCodingModule> audio_coding_; 132*d9f75844SAndroid Build Coastguard Worker 133*d9f75844SAndroid Build Coastguard Worker // Synchronization is handled internally by voe::AudioLevel. 134*d9f75844SAndroid Build Coastguard Worker voe::AudioLevel input_audio_level_; 135*d9f75844SAndroid Build Coastguard Worker 136*d9f75844SAndroid Build Coastguard Worker // Struct that holds all variables used by encoder task queue. 137*d9f75844SAndroid Build Coastguard Worker struct EncoderContext { 138*d9f75844SAndroid Build Coastguard Worker // Offset used to mark rtp timestamp in sample rate unit in 139*d9f75844SAndroid Build Coastguard Worker // newly received audio frame from AudioTransport. 140*d9f75844SAndroid Build Coastguard Worker uint32_t frame_rtp_timestamp_ = 0; 141*d9f75844SAndroid Build Coastguard Worker 142*d9f75844SAndroid Build Coastguard Worker // Flag to track mute state from caller. `previously_muted_` is used to 143*d9f75844SAndroid Build Coastguard Worker // track previous state as part of input to AudioFrameOperations::Mute 144*d9f75844SAndroid Build Coastguard Worker // to implement fading effect when (un)mute is invoked. 145*d9f75844SAndroid Build Coastguard Worker bool mute_ = false; 146*d9f75844SAndroid Build Coastguard Worker bool previously_muted_ = false; 147*d9f75844SAndroid Build Coastguard Worker }; 148*d9f75844SAndroid Build Coastguard Worker 149*d9f75844SAndroid Build Coastguard Worker EncoderContext encoder_context_ RTC_GUARDED_BY(encoder_queue_); 150*d9f75844SAndroid Build Coastguard Worker 151*d9f75844SAndroid Build Coastguard Worker // Defined last to ensure that there are no running tasks when the other 152*d9f75844SAndroid Build Coastguard Worker // members are destroyed. 153*d9f75844SAndroid Build Coastguard Worker rtc::TaskQueue encoder_queue_; 154*d9f75844SAndroid Build Coastguard Worker }; 155*d9f75844SAndroid Build Coastguard Worker 156*d9f75844SAndroid Build Coastguard Worker } // namespace webrtc 157*d9f75844SAndroid Build Coastguard Worker 158*d9f75844SAndroid Build Coastguard Worker #endif // AUDIO_VOIP_AUDIO_EGRESS_H_ 159