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