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_MAIN_ACM2_AUDIO_CODING_MODULE_IMPL_H_ 12 #define WEBRTC_MODULES_AUDIO_CODING_MAIN_ACM2_AUDIO_CODING_MODULE_IMPL_H_ 13 14 #include <vector> 15 16 #include "webrtc/common_types.h" 17 #include "webrtc/engine_configurations.h" 18 #include "webrtc/modules/audio_coding/main/acm2/acm_codec_database.h" 19 #include "webrtc/modules/audio_coding/main/acm2/acm_receiver.h" 20 #include "webrtc/modules/audio_coding/main/acm2/acm_resampler.h" 21 #include "webrtc/system_wrappers/interface/scoped_ptr.h" 22 #include "webrtc/system_wrappers/interface/thread_annotations.h" 23 24 namespace webrtc { 25 26 class CriticalSectionWrapper; 27 28 namespace acm2 { 29 30 class ACMDTMFDetection; 31 class ACMGenericCodec; 32 33 class AudioCodingModuleImpl : public AudioCodingModule { 34 public: 35 explicit AudioCodingModuleImpl(const AudioCodingModule::Config& config); 36 ~AudioCodingModuleImpl(); 37 38 // Change the unique identifier of this object. 39 virtual int32_t ChangeUniqueId(const int32_t id); 40 41 // Returns the number of milliseconds until the module want a worker thread 42 // to call Process. 43 int32_t TimeUntilNextProcess(); 44 45 // Process any pending tasks such as timeouts. 46 int32_t Process(); 47 48 ///////////////////////////////////////// 49 // Sender 50 // 51 52 // Initialize send codec. 53 int InitializeSender(); 54 55 // Reset send codec. 56 int ResetEncoder(); 57 58 // Can be called multiple times for Codec, CNG, RED. 59 int RegisterSendCodec(const CodecInst& send_codec); 60 61 // Register Secondary codec for dual-streaming. Dual-streaming is activated 62 // right after the secondary codec is registered. 63 int RegisterSecondarySendCodec(const CodecInst& send_codec); 64 65 // Unregister the secondary codec. Dual-streaming is deactivated right after 66 // deregistering secondary codec. 67 void UnregisterSecondarySendCodec(); 68 69 // Get the secondary codec. 70 int SecondarySendCodec(CodecInst* secondary_codec) const; 71 72 // Get current send codec. 73 int SendCodec(CodecInst* current_codec) const; 74 75 // Get current send frequency. 76 int SendFrequency() const; 77 78 // Get encode bit-rate. 79 // Adaptive rate codecs return their current encode target rate, while other 80 // codecs return there long-term average or their fixed rate. 81 int SendBitrate() const; 82 83 // Set available bandwidth, inform the encoder about the 84 // estimated bandwidth received from the remote party. 85 virtual int SetReceivedEstimatedBandwidth(int bw); 86 87 // Register a transport callback which will be 88 // called to deliver the encoded buffers. 89 int RegisterTransportCallback(AudioPacketizationCallback* transport); 90 91 // Add 10 ms of raw (PCM) audio data to the encoder. 92 int Add10MsData(const AudioFrame& audio_frame); 93 94 ///////////////////////////////////////// 95 // (RED) Redundant Coding 96 // 97 98 // Configure RED status i.e. on/off. 99 int SetREDStatus(bool enable_red); 100 101 // Get RED status. 102 bool REDStatus() const; 103 104 ///////////////////////////////////////// 105 // (FEC) Forward Error Correction (codec internal) 106 // 107 108 // Configure FEC status i.e. on/off. 109 int SetCodecFEC(bool enabled_codec_fec); 110 111 // Get FEC status. 112 bool CodecFEC() const; 113 114 // Set target packet loss rate 115 int SetPacketLossRate(int loss_rate); 116 117 ///////////////////////////////////////// 118 // (VAD) Voice Activity Detection 119 // and 120 // (CNG) Comfort Noise Generation 121 // 122 123 int SetVAD(bool enable_dtx = true, 124 bool enable_vad = false, 125 ACMVADMode mode = VADNormal); 126 127 int VAD(bool* dtx_enabled, bool* vad_enabled, ACMVADMode* mode) const; 128 129 int RegisterVADCallback(ACMVADCallback* vad_callback); 130 131 ///////////////////////////////////////// 132 // Receiver 133 // 134 135 // Initialize receiver, resets codec database etc. 136 int InitializeReceiver(); 137 138 // Reset the decoder state. 139 int ResetDecoder(); 140 141 // Get current receive frequency. 142 int ReceiveFrequency() const; 143 144 // Get current playout frequency. 145 int PlayoutFrequency() const; 146 147 // Register possible receive codecs, can be called multiple times, 148 // for codecs, CNG, DTMF, RED. 149 int RegisterReceiveCodec(const CodecInst& receive_codec); 150 151 // Get current received codec. 152 int ReceiveCodec(CodecInst* current_codec) const; 153 154 // Incoming packet from network parsed and ready for decode. 155 int IncomingPacket(const uint8_t* incoming_payload, 156 int payload_length, 157 const WebRtcRTPHeader& rtp_info); 158 159 // Incoming payloads, without rtp-info, the rtp-info will be created in ACM. 160 // One usage for this API is when pre-encoded files are pushed in ACM. 161 int IncomingPayload(const uint8_t* incoming_payload, 162 int payload_length, 163 uint8_t payload_type, 164 uint32_t timestamp); 165 166 // Minimum playout delay. 167 int SetMinimumPlayoutDelay(int time_ms); 168 169 // Maximum playout delay. 170 int SetMaximumPlayoutDelay(int time_ms); 171 172 // Smallest latency NetEq will maintain. 173 int LeastRequiredDelayMs() const; 174 175 // Impose an initial delay on playout. ACM plays silence until |delay_ms| 176 // audio is accumulated in NetEq buffer, then starts decoding payloads. 177 int SetInitialPlayoutDelay(int delay_ms); 178 179 // TODO(turajs): DTMF playout is always activated in NetEq these APIs should 180 // be removed, as well as all VoE related APIs and methods. 181 // 182 // Configure Dtmf playout status i.e on/off playout the incoming outband Dtmf 183 // tone. 184 int SetDtmfPlayoutStatus(bool enable) { return 0; } 185 186 // Get Dtmf playout status. 187 bool DtmfPlayoutStatus() const { return true; } 188 189 // Estimate the Bandwidth based on the incoming stream, needed 190 // for one way audio where the RTCP send the BW estimate. 191 // This is also done in the RTP module . 192 int DecoderEstimatedBandwidth() const; 193 194 // Set playout mode voice, fax. 195 int SetPlayoutMode(AudioPlayoutMode mode); 196 197 // Get playout mode voice, fax. 198 AudioPlayoutMode PlayoutMode() const; 199 200 // Get playout timestamp. 201 int PlayoutTimestamp(uint32_t* timestamp); 202 203 // Get 10 milliseconds of raw audio data to play out, and 204 // automatic resample to the requested frequency if > 0. 205 int PlayoutData10Ms(int desired_freq_hz, AudioFrame* audio_frame); 206 207 ///////////////////////////////////////// 208 // Statistics 209 // 210 211 int NetworkStatistics(ACMNetworkStatistics* statistics); 212 213 void DestructEncoderInst(void* inst); 214 215 // GET RED payload for iSAC. The method id called when 'this' ACM is 216 // the default ACM. 217 int REDPayloadISAC(int isac_rate, 218 int isac_bw_estimate, 219 uint8_t* payload, 220 int16_t* length_bytes); 221 222 int ReplaceInternalDTXWithWebRtc(bool use_webrtc_dtx); 223 224 int IsInternalDTXReplacedWithWebRtc(bool* uses_webrtc_dtx); 225 226 int SetISACMaxRate(int max_bit_per_sec); 227 228 int SetISACMaxPayloadSize(int max_size_bytes); 229 230 int ConfigISACBandwidthEstimator(int frame_size_ms, 231 int rate_bit_per_sec, 232 bool enforce_frame_size = false); 233 234 int UnregisterReceiveCodec(uint8_t payload_type); 235 236 int EnableNack(size_t max_nack_list_size); 237 238 void DisableNack(); 239 240 std::vector<uint16_t> GetNackList(int round_trip_time_ms) const; 241 242 void GetDecodingCallStatistics(AudioDecodingCallStats* stats) const; 243 244 private: 245 int UnregisterReceiveCodecSafe(int payload_type); 246 247 ACMGenericCodec* CreateCodec(const CodecInst& codec); 248 249 int InitializeReceiverSafe() EXCLUSIVE_LOCKS_REQUIRED(acm_crit_sect_); 250 251 bool HaveValidEncoder(const char* caller_name) const; 252 253 // Set VAD/DTX status. This function does not acquire a lock, and it is 254 // created to be called only from inside a critical section. 255 int SetVADSafe(bool enable_dtx, bool enable_vad, ACMVADMode mode) 256 EXCLUSIVE_LOCKS_REQUIRED(acm_crit_sect_); 257 258 // Process buffered audio when dual-streaming is not enabled (When RED is 259 // enabled still this function is used.) 260 int ProcessSingleStream(); 261 262 // Process buffered audio when dual-streaming is enabled, i.e. secondary send 263 // codec is registered. 264 int ProcessDualStream(); 265 266 // Preprocessing of input audio, including resampling and down-mixing if 267 // required, before pushing audio into encoder's buffer. 268 // 269 // in_frame: input audio-frame 270 // ptr_out: pointer to output audio_frame. If no preprocessing is required 271 // |ptr_out| will be pointing to |in_frame|, otherwise pointing to 272 // |preprocess_frame_|. 273 // 274 // Return value: 275 // -1: if encountering an error. 276 // 0: otherwise. 277 int PreprocessToAddData(const AudioFrame& in_frame, 278 const AudioFrame** ptr_out) 279 EXCLUSIVE_LOCKS_REQUIRED(acm_crit_sect_); 280 281 // Change required states after starting to receive the codec corresponding 282 // to |index|. 283 int UpdateUponReceivingCodec(int index); 284 285 int EncodeFragmentation(int fragmentation_index, 286 int payload_type, 287 uint32_t current_timestamp, 288 ACMGenericCodec* encoder, 289 uint8_t* stream) 290 EXCLUSIVE_LOCKS_REQUIRED(acm_crit_sect_); 291 292 void ResetFragmentation(int vector_size) 293 EXCLUSIVE_LOCKS_REQUIRED(acm_crit_sect_); 294 295 // Get a pointer to AudioDecoder of the given codec. For some codecs, e.g. 296 // iSAC, encoding and decoding have to be performed on a shared 297 // codec-instance. By calling this method, we get the codec-instance that ACM 298 // owns, then pass that to NetEq. This way, we perform both encoding and 299 // decoding on the same codec-instance. Furthermore, ACM would have control 300 // over decoder functionality if required. If |codec| does not share an 301 // instance between encoder and decoder, the |*decoder| is set NULL. 302 // The field ACMCodecDB::CodecSettings.owns_decoder indicates that if a 303 // codec owns the decoder-instance. For such codecs |*decoder| should be a 304 // valid pointer, otherwise it will be NULL. 305 int GetAudioDecoder(const CodecInst& codec, int codec_id, 306 int mirror_id, AudioDecoder** decoder); 307 308 CriticalSectionWrapper* acm_crit_sect_; 309 int id_; // TODO(henrik.lundin) Make const. 310 uint32_t expected_codec_ts_ GUARDED_BY(acm_crit_sect_); 311 uint32_t expected_in_ts_ GUARDED_BY(acm_crit_sect_); 312 CodecInst send_codec_inst_ GUARDED_BY(acm_crit_sect_); 313 314 uint8_t cng_nb_pltype_ GUARDED_BY(acm_crit_sect_); 315 uint8_t cng_wb_pltype_ GUARDED_BY(acm_crit_sect_); 316 uint8_t cng_swb_pltype_ GUARDED_BY(acm_crit_sect_); 317 uint8_t cng_fb_pltype_ GUARDED_BY(acm_crit_sect_); 318 319 uint8_t red_pltype_ GUARDED_BY(acm_crit_sect_); 320 bool vad_enabled_ GUARDED_BY(acm_crit_sect_); 321 bool dtx_enabled_ GUARDED_BY(acm_crit_sect_); 322 ACMVADMode vad_mode_ GUARDED_BY(acm_crit_sect_); 323 ACMGenericCodec* codecs_[ACMCodecDB::kMaxNumCodecs]; 324 int mirror_codec_idx_[ACMCodecDB::kMaxNumCodecs]; 325 bool stereo_send_ GUARDED_BY(acm_crit_sect_); 326 int current_send_codec_idx_; 327 bool send_codec_registered_; 328 ACMResampler resampler_ GUARDED_BY(acm_crit_sect_); 329 AcmReceiver receiver_; 330 331 // RED. 332 bool is_first_red_ GUARDED_BY(acm_crit_sect_); 333 bool red_enabled_ GUARDED_BY(acm_crit_sect_); 334 335 // TODO(turajs): |red_buffer_| is allocated in constructor, why having them 336 // as pointers and not an array. If concerned about the memory, then make a 337 // set-up function to allocate them only when they are going to be used, i.e. 338 // RED or Dual-streaming is enabled. 339 uint8_t* red_buffer_ GUARDED_BY(acm_crit_sect_); 340 341 // TODO(turajs): we actually don't need |fragmentation_| as a member variable. 342 // It is sufficient to keep the length & payload type of previous payload in 343 // member variables. 344 RTPFragmentationHeader fragmentation_ GUARDED_BY(acm_crit_sect_); 345 uint32_t last_red_timestamp_ GUARDED_BY(acm_crit_sect_); 346 347 // Codec internal FEC 348 bool codec_fec_enabled_; 349 350 // This is to keep track of CN instances where we can send DTMFs. 351 uint8_t previous_pltype_ GUARDED_BY(acm_crit_sect_); 352 353 // Used when payloads are pushed into ACM without any RTP info 354 // One example is when pre-encoded bit-stream is pushed from 355 // a file. 356 // IMPORTANT: this variable is only used in IncomingPayload(), therefore, 357 // no lock acquired when interacting with this variable. If it is going to 358 // be used in other methods, locks need to be taken. 359 WebRtcRTPHeader* aux_rtp_header_; 360 361 bool receiver_initialized_ GUARDED_BY(acm_crit_sect_); 362 363 AudioFrame preprocess_frame_ GUARDED_BY(acm_crit_sect_); 364 CodecInst secondary_send_codec_inst_ GUARDED_BY(acm_crit_sect_); 365 scoped_ptr<ACMGenericCodec> secondary_encoder_ GUARDED_BY(acm_crit_sect_); 366 uint32_t codec_timestamp_ GUARDED_BY(acm_crit_sect_); 367 bool first_10ms_data_ GUARDED_BY(acm_crit_sect_); 368 369 CriticalSectionWrapper* callback_crit_sect_; 370 AudioPacketizationCallback* packetization_callback_ 371 GUARDED_BY(callback_crit_sect_); 372 ACMVADCallback* vad_callback_ GUARDED_BY(callback_crit_sect_); 373 }; 374 375 } // namespace acm2 376 377 } // namespace webrtc 378 379 #endif // WEBRTC_MODULES_AUDIO_CODING_MAIN_ACM2_AUDIO_CODING_MODULE_IMPL_H_ 380