1 /*
2  *  Copyright (c) 2012 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 WEBRTC_MODULES_AUDIO_CODING_ACM2_AUDIO_CODING_MODULE_IMPL_H_
12 #define WEBRTC_MODULES_AUDIO_CODING_ACM2_AUDIO_CODING_MODULE_IMPL_H_
13 
14 #include <string>
15 #include <vector>
16 
17 #include "webrtc/base/buffer.h"
18 #include "webrtc/base/scoped_ptr.h"
19 #include "webrtc/base/thread_annotations.h"
20 #include "webrtc/common_types.h"
21 #include "webrtc/engine_configurations.h"
22 #include "webrtc/modules/audio_coding/acm2/acm_receiver.h"
23 #include "webrtc/modules/audio_coding/acm2/acm_resampler.h"
24 #include "webrtc/modules/audio_coding/acm2/codec_manager.h"
25 
26 namespace webrtc {
27 
28 class CriticalSectionWrapper;
29 class AudioCodingImpl;
30 
31 namespace acm2 {
32 
33 class AudioCodingModuleImpl final : public AudioCodingModule {
34  public:
35   friend webrtc::AudioCodingImpl;
36 
37   explicit AudioCodingModuleImpl(const AudioCodingModule::Config& config);
38   ~AudioCodingModuleImpl() override;
39 
40   /////////////////////////////////////////
41   //   Sender
42   //
43 
44   // Can be called multiple times for Codec, CNG, RED.
45   int RegisterSendCodec(const CodecInst& send_codec) override;
46 
47   void RegisterExternalSendCodec(
48       AudioEncoder* external_speech_encoder) override;
49 
50   // Get current send codec.
51   rtc::Optional<CodecInst> SendCodec() const override;
52 
53   // Get current send frequency.
54   int SendFrequency() const override;
55 
56   // Sets the bitrate to the specified value in bits/sec. In case the codec does
57   // not support the requested value it will choose an appropriate value
58   // instead.
59   void SetBitRate(int bitrate_bps) override;
60 
61   // Register a transport callback which will be
62   // called to deliver the encoded buffers.
63   int RegisterTransportCallback(AudioPacketizationCallback* transport) override;
64 
65   // Add 10 ms of raw (PCM) audio data to the encoder.
66   int Add10MsData(const AudioFrame& audio_frame) override;
67 
68   /////////////////////////////////////////
69   // (RED) Redundant Coding
70   //
71 
72   // Configure RED status i.e. on/off.
73   int SetREDStatus(bool enable_red) override;
74 
75   // Get RED status.
76   bool REDStatus() const override;
77 
78   /////////////////////////////////////////
79   // (FEC) Forward Error Correction (codec internal)
80   //
81 
82   // Configure FEC status i.e. on/off.
83   int SetCodecFEC(bool enabled_codec_fec) override;
84 
85   // Get FEC status.
86   bool CodecFEC() const override;
87 
88   // Set target packet loss rate
89   int SetPacketLossRate(int loss_rate) override;
90 
91   /////////////////////////////////////////
92   //   (VAD) Voice Activity Detection
93   //   and
94   //   (CNG) Comfort Noise Generation
95   //
96 
97   int SetVAD(bool enable_dtx = true,
98              bool enable_vad = false,
99              ACMVADMode mode = VADNormal) override;
100 
101   int VAD(bool* dtx_enabled,
102           bool* vad_enabled,
103           ACMVADMode* mode) const override;
104 
105   int RegisterVADCallback(ACMVADCallback* vad_callback) override;
106 
107   /////////////////////////////////////////
108   //   Receiver
109   //
110 
111   // Initialize receiver, resets codec database etc.
112   int InitializeReceiver() override;
113 
114   // Get current receive frequency.
115   int ReceiveFrequency() const override;
116 
117   // Get current playout frequency.
118   int PlayoutFrequency() const override;
119 
120   // Register possible receive codecs, can be called multiple times,
121   // for codecs, CNG, DTMF, RED.
122   int RegisterReceiveCodec(const CodecInst& receive_codec) override;
123 
124   int RegisterExternalReceiveCodec(int rtp_payload_type,
125                                    AudioDecoder* external_decoder,
126                                    int sample_rate_hz,
127                                    int num_channels,
128                                    const std::string& name) override;
129 
130   // Get current received codec.
131   int ReceiveCodec(CodecInst* current_codec) const override;
132 
133   // Incoming packet from network parsed and ready for decode.
134   int IncomingPacket(const uint8_t* incoming_payload,
135                      const size_t payload_length,
136                      const WebRtcRTPHeader& rtp_info) override;
137 
138   // Incoming payloads, without rtp-info, the rtp-info will be created in ACM.
139   // One usage for this API is when pre-encoded files are pushed in ACM.
140   int IncomingPayload(const uint8_t* incoming_payload,
141                       const size_t payload_length,
142                       uint8_t payload_type,
143                       uint32_t timestamp) override;
144 
145   // Minimum playout delay.
146   int SetMinimumPlayoutDelay(int time_ms) override;
147 
148   // Maximum playout delay.
149   int SetMaximumPlayoutDelay(int time_ms) override;
150 
151   // Smallest latency NetEq will maintain.
152   int LeastRequiredDelayMs() const override;
153 
154   // Get playout timestamp.
155   int PlayoutTimestamp(uint32_t* timestamp) override;
156 
157   // Get 10 milliseconds of raw audio data to play out, and
158   // automatic resample to the requested frequency if > 0.
159   int PlayoutData10Ms(int desired_freq_hz, AudioFrame* audio_frame) override;
160 
161   /////////////////////////////////////////
162   //   Statistics
163   //
164 
165   int GetNetworkStatistics(NetworkStatistics* statistics) override;
166 
167   int SetOpusApplication(OpusApplicationMode application) override;
168 
169   // If current send codec is Opus, informs it about the maximum playback rate
170   // the receiver will render.
171   int SetOpusMaxPlaybackRate(int frequency_hz) override;
172 
173   int EnableOpusDtx() override;
174 
175   int DisableOpusDtx() override;
176 
177   int UnregisterReceiveCodec(uint8_t payload_type) override;
178 
179   int EnableNack(size_t max_nack_list_size) override;
180 
181   void DisableNack() override;
182 
183   std::vector<uint16_t> GetNackList(int64_t round_trip_time_ms) const override;
184 
185   void GetDecodingCallStatistics(AudioDecodingCallStats* stats) const override;
186 
187  private:
188   struct InputData {
189     uint32_t input_timestamp;
190     const int16_t* audio;
191     size_t length_per_channel;
192     size_t audio_channel;
193     // If a re-mix is required (up or down), this buffer will store a re-mixed
194     // version of the input.
195     int16_t buffer[WEBRTC_10MS_PCM_AUDIO];
196   };
197 
198   // This member class writes values to the named UMA histogram, but only if
199   // the value has changed since the last time (and always for the first call).
200   class ChangeLogger {
201    public:
ChangeLogger(const std::string & histogram_name)202     explicit ChangeLogger(const std::string& histogram_name)
203         : histogram_name_(histogram_name) {}
204     // Logs the new value if it is different from the last logged value, or if
205     // this is the first call.
206     void MaybeLog(int value);
207 
208    private:
209     int last_value_ = 0;
210     int first_time_ = true;
211     const std::string histogram_name_;
212   };
213 
214   int Add10MsDataInternal(const AudioFrame& audio_frame, InputData* input_data)
215       EXCLUSIVE_LOCKS_REQUIRED(acm_crit_sect_);
216   int Encode(const InputData& input_data)
217       EXCLUSIVE_LOCKS_REQUIRED(acm_crit_sect_);
218 
219   int InitializeReceiverSafe() EXCLUSIVE_LOCKS_REQUIRED(acm_crit_sect_);
220 
221   bool HaveValidEncoder(const char* caller_name) const
222       EXCLUSIVE_LOCKS_REQUIRED(acm_crit_sect_);
223 
224   // Preprocessing of input audio, including resampling and down-mixing if
225   // required, before pushing audio into encoder's buffer.
226   //
227   // in_frame: input audio-frame
228   // ptr_out: pointer to output audio_frame. If no preprocessing is required
229   //          |ptr_out| will be pointing to |in_frame|, otherwise pointing to
230   //          |preprocess_frame_|.
231   //
232   // Return value:
233   //   -1: if encountering an error.
234   //    0: otherwise.
235   int PreprocessToAddData(const AudioFrame& in_frame,
236                           const AudioFrame** ptr_out)
237       EXCLUSIVE_LOCKS_REQUIRED(acm_crit_sect_);
238 
239   // Change required states after starting to receive the codec corresponding
240   // to |index|.
241   int UpdateUponReceivingCodec(int index);
242 
243   const rtc::scoped_ptr<CriticalSectionWrapper> acm_crit_sect_;
244   rtc::Buffer encode_buffer_ GUARDED_BY(acm_crit_sect_);
245   int id_;  // TODO(henrik.lundin) Make const.
246   uint32_t expected_codec_ts_ GUARDED_BY(acm_crit_sect_);
247   uint32_t expected_in_ts_ GUARDED_BY(acm_crit_sect_);
248   ACMResampler resampler_ GUARDED_BY(acm_crit_sect_);
249   AcmReceiver receiver_;  // AcmReceiver has it's own internal lock.
250   ChangeLogger bitrate_logger_ GUARDED_BY(acm_crit_sect_);
251   CodecManager codec_manager_ GUARDED_BY(acm_crit_sect_);
252   RentACodec rent_a_codec_ GUARDED_BY(acm_crit_sect_);
253 
254   // This is to keep track of CN instances where we can send DTMFs.
255   uint8_t previous_pltype_ GUARDED_BY(acm_crit_sect_);
256 
257   // Used when payloads are pushed into ACM without any RTP info
258   // One example is when pre-encoded bit-stream is pushed from
259   // a file.
260   // IMPORTANT: this variable is only used in IncomingPayload(), therefore,
261   // no lock acquired when interacting with this variable. If it is going to
262   // be used in other methods, locks need to be taken.
263   rtc::scoped_ptr<WebRtcRTPHeader> aux_rtp_header_;
264 
265   bool receiver_initialized_ GUARDED_BY(acm_crit_sect_);
266 
267   AudioFrame preprocess_frame_ GUARDED_BY(acm_crit_sect_);
268   bool first_10ms_data_ GUARDED_BY(acm_crit_sect_);
269 
270   bool first_frame_ GUARDED_BY(acm_crit_sect_);
271   uint32_t last_timestamp_ GUARDED_BY(acm_crit_sect_);
272   uint32_t last_rtp_timestamp_ GUARDED_BY(acm_crit_sect_);
273 
274   const rtc::scoped_ptr<CriticalSectionWrapper> callback_crit_sect_;
275   AudioPacketizationCallback* packetization_callback_
276       GUARDED_BY(callback_crit_sect_);
277   ACMVADCallback* vad_callback_ GUARDED_BY(callback_crit_sect_);
278 };
279 
280 }  // namespace acm2
281 }  // namespace webrtc
282 
283 #endif  // WEBRTC_MODULES_AUDIO_CODING_ACM2_AUDIO_CODING_MODULE_IMPL_H_
284