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/include/rtp_rtcp.h"
24 #include "modules/rtp_rtcp/source/rtp_sender_audio.h"
25 #include "rtc_base/task_queue.h"
26 #include "rtc_base/thread_checker.h"
27 #include "rtc_base/time_utils.h"
28 
29 namespace webrtc {
30 
31 // AudioEgress receives input samples from AudioDeviceModule via
32 // AudioTransportImpl through AudioSender interface. Once it encodes the sample
33 // via selected encoder through AudioPacketizationCallback interface, the
34 // encoded payload will be packetized by the RTP stack, resulting in ready to
35 // send RTP packet to remote endpoint.
36 //
37 // This class enforces single worker thread access by caller via SequenceChecker
38 // in debug mode as expected thread usage pattern. In order to minimize the hold
39 // on audio input thread from OS, TaskQueue is employed to encode and send RTP
40 // asynchrounously.
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(RtpRtcp* 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.
75   absl::optional<SdpAudioFormat> GetEncoderFormat() const;
76 
77   // Register the payload type and sample rate for DTMF (RFC 4733) payload.
78   void RegisterTelephoneEventType(int rtp_payload_type, int sample_rate_hz);
79 
80   // Send DTMF named event as specified by
81   // https://tools.ietf.org/html/rfc4733#section-3.2
82   // |duration_ms| specifies the duration of DTMF packets that will be emitted
83   // in place of real RTP packets instead.
84   // This will return true when requested dtmf event is successfully scheduled
85   // otherwise false when the dtmf queue reached maximum of 20 events.
86   bool SendTelephoneEvent(int dtmf_event, int duration_ms);
87 
88   // Implementation of AudioSender interface.
89   void SendAudioData(std::unique_ptr<AudioFrame> audio_frame) override;
90 
91   // Implementation of AudioPacketizationCallback interface.
92   int32_t SendData(AudioFrameType frame_type,
93                    uint8_t payload_type,
94                    uint32_t timestamp,
95                    const uint8_t* payload_data,
96                    size_t payload_size) override;
97 
98  private:
99   // Ensure that single worker thread access.
100   SequenceChecker worker_thread_checker_;
101 
102   // Current encoder format selected by caller.
103   absl::optional<SdpAudioFormat> encoder_format_
104       RTC_GUARDED_BY(worker_thread_checker_);
105 
106   // Synchronization is handled internally by RtpRtcp.
107   RtpRtcp* const rtp_rtcp_;
108 
109   // Synchronization is handled internally by RTPSenderAudio.
110   RTPSenderAudio rtp_sender_audio_;
111 
112   // Synchronization is handled internally by AudioCodingModule.
113   const std::unique_ptr<AudioCodingModule> audio_coding_;
114 
115   // Struct that holds all variables used by encoder task queue.
116   struct EncoderContext {
117     // Offset used to mark rtp timestamp in sample rate unit in
118     // newly received audio frame from AudioTransport.
119     uint32_t frame_rtp_timestamp_ = 0;
120 
121     // Flag to track mute state from caller. |previously_muted_| is used to
122     // track previous state as part of input to AudioFrameOperations::Mute
123     // to implement fading effect when (un)mute is invoked.
124     bool mute_ = false;
125     bool previously_muted_ = false;
126   };
127 
128   EncoderContext encoder_context_ RTC_GUARDED_BY(encoder_queue_);
129 
130   // Defined last to ensure that there are no running tasks when the other
131   // members are destroyed.
132   rtc::TaskQueue encoder_queue_;
133 };
134 
135 }  // namespace webrtc
136 
137 #endif  // AUDIO_VOIP_AUDIO_EGRESS_H_
138