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