• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include "webrtc/modules/audio_coding/main/acm2/audio_coding_module_impl.h"
12 
13 #include <assert.h>
14 #include <stdlib.h>
15 #include <vector>
16 
17 #include "webrtc/engine_configurations.h"
18 #include "webrtc/modules/audio_coding/main/interface/audio_coding_module_typedefs.h"
19 #include "webrtc/modules/audio_coding/main/acm2/acm_codec_database.h"
20 #include "webrtc/modules/audio_coding/main/acm2/acm_common_defs.h"
21 #include "webrtc/modules/audio_coding/main/acm2/acm_generic_codec.h"
22 #include "webrtc/modules/audio_coding/main/acm2/acm_resampler.h"
23 #include "webrtc/modules/audio_coding/main/acm2/call_statistics.h"
24 #include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
25 #include "webrtc/system_wrappers/interface/rw_lock_wrapper.h"
26 #include "webrtc/system_wrappers/interface/trace.h"
27 #include "webrtc/typedefs.h"
28 
29 namespace webrtc {
30 
31 namespace acm2 {
32 
33 enum {
34   kACMToneEnd = 999
35 };
36 
37 // Maximum number of bytes in one packet (PCM16B, 20 ms packets, stereo).
38 enum {
39   kMaxPacketSize = 2560
40 };
41 
42 // Maximum number of payloads that can be packed in one RED packet. For
43 // regular RED, we only pack two payloads. In case of dual-streaming, in worst
44 // case we might pack 3 payloads in one RED packet.
45 enum {
46   kNumRedFragmentationVectors = 2,
47   kMaxNumFragmentationVectors = 3
48 };
49 
50 // If packet N is arrived all packets prior to N - |kNackThresholdPackets| which
51 // are not received are considered as lost, and appear in NACK list.
52 enum {
53   kNackThresholdPackets = 2
54 };
55 
56 namespace {
57 
58 // TODO(turajs): the same functionality is used in NetEq. If both classes
59 // need them, make it a static function in ACMCodecDB.
IsCodecRED(const CodecInst * codec)60 bool IsCodecRED(const CodecInst* codec) {
61   return (STR_CASE_CMP(codec->plname, "RED") == 0);
62 }
63 
IsCodecRED(int index)64 bool IsCodecRED(int index) {
65   return (IsCodecRED(&ACMCodecDB::database_[index]));
66 }
67 
IsCodecCN(const CodecInst * codec)68 bool IsCodecCN(const CodecInst* codec) {
69   return (STR_CASE_CMP(codec->plname, "CN") == 0);
70 }
71 
IsCodecCN(int index)72 bool IsCodecCN(int index) {
73   return (IsCodecCN(&ACMCodecDB::database_[index]));
74 }
75 
76 // Stereo-to-mono can be used as in-place.
DownMix(const AudioFrame & frame,int length_out_buff,int16_t * out_buff)77 int DownMix(const AudioFrame& frame, int length_out_buff, int16_t* out_buff) {
78   if (length_out_buff < frame.samples_per_channel_) {
79     return -1;
80   }
81   for (int n = 0; n < frame.samples_per_channel_; ++n)
82     out_buff[n] = (frame.data_[2 * n] + frame.data_[2 * n + 1]) >> 1;
83   return 0;
84 }
85 
86 // Mono-to-stereo can be used as in-place.
UpMix(const AudioFrame & frame,int length_out_buff,int16_t * out_buff)87 int UpMix(const AudioFrame& frame, int length_out_buff, int16_t* out_buff) {
88   if (length_out_buff < frame.samples_per_channel_) {
89     return -1;
90   }
91   for (int n = frame.samples_per_channel_ - 1; n >= 0; --n) {
92     out_buff[2 * n + 1] = frame.data_[n];
93     out_buff[2 * n] = frame.data_[n];
94   }
95   return 0;
96 }
97 
98 // Return 1 if timestamp t1 is less than timestamp t2, while compensating for
99 // wrap-around.
TimestampLessThan(uint32_t t1,uint32_t t2)100 static int TimestampLessThan(uint32_t t1, uint32_t t2) {
101   uint32_t kHalfFullRange = static_cast<uint32_t>(0xFFFFFFFF) / 2;
102   if (t1 == t2) {
103     return 0;
104   } else if (t1 < t2) {
105     if (t2 - t1 < kHalfFullRange)
106       return 1;
107     return 0;
108   } else {
109     if (t1 - t2 < kHalfFullRange)
110       return 0;
111     return 1;
112   }
113 }
114 
115 }  // namespace
116 
AudioCodingModuleImpl(const AudioCodingModule::Config & config)117 AudioCodingModuleImpl::AudioCodingModuleImpl(
118     const AudioCodingModule::Config& config)
119     : acm_crit_sect_(CriticalSectionWrapper::CreateCriticalSection()),
120       id_(config.id),
121       expected_codec_ts_(0xD87F3F9F),
122       expected_in_ts_(0xD87F3F9F),
123       send_codec_inst_(),
124       cng_nb_pltype_(255),
125       cng_wb_pltype_(255),
126       cng_swb_pltype_(255),
127       cng_fb_pltype_(255),
128       red_pltype_(255),
129       vad_enabled_(false),
130       dtx_enabled_(false),
131       vad_mode_(VADNormal),
132       stereo_send_(false),
133       current_send_codec_idx_(-1),
134       send_codec_registered_(false),
135       receiver_(config),
136       is_first_red_(true),
137       red_enabled_(false),
138       last_red_timestamp_(0),
139       codec_fec_enabled_(false),
140       previous_pltype_(255),
141       aux_rtp_header_(NULL),
142       receiver_initialized_(false),
143       secondary_send_codec_inst_(),
144       codec_timestamp_(expected_codec_ts_),
145       first_10ms_data_(false),
146       callback_crit_sect_(CriticalSectionWrapper::CreateCriticalSection()),
147       packetization_callback_(NULL),
148       vad_callback_(NULL) {
149 
150   // Nullify send codec memory, set payload type and set codec name to
151   // invalid values.
152   const char no_name[] = "noCodecRegistered";
153   strncpy(send_codec_inst_.plname, no_name, RTP_PAYLOAD_NAME_SIZE - 1);
154   send_codec_inst_.pltype = -1;
155 
156   strncpy(secondary_send_codec_inst_.plname, no_name,
157           RTP_PAYLOAD_NAME_SIZE - 1);
158   secondary_send_codec_inst_.pltype = -1;
159 
160   for (int i = 0; i < ACMCodecDB::kMaxNumCodecs; i++) {
161     codecs_[i] = NULL;
162     mirror_codec_idx_[i] = -1;
163   }
164 
165   // Allocate memory for RED.
166   red_buffer_ = new uint8_t[MAX_PAYLOAD_SIZE_BYTE];
167 
168   // TODO(turajs): This might not be exactly how this class is supposed to work.
169   // The external usage might be that |fragmentationVectorSize| has to match
170   // the allocated space for the member-arrays, while here, we allocate
171   // according to the maximum number of fragmentations and change
172   // |fragmentationVectorSize| on-the-fly based on actual number of
173   // fragmentations. However, due to copying to local variable before calling
174   // SendData, the RTP module receives a "valid" fragmentation, where allocated
175   // space matches |fragmentationVectorSize|, therefore, this should not cause
176   // any problem. A better approach is not using RTPFragmentationHeader as
177   // member variable, instead, use an ACM-specific structure to hold RED-related
178   // data. See module_common_type.h for the definition of
179   // RTPFragmentationHeader.
180   fragmentation_.VerifyAndAllocateFragmentationHeader(
181       kMaxNumFragmentationVectors);
182 
183   // Register the default payload type for RED and for CNG at sampling rates of
184   // 8, 16, 32 and 48 kHz.
185   for (int i = (ACMCodecDB::kNumCodecs - 1); i >= 0; i--) {
186     if (IsCodecRED(i)) {
187       red_pltype_ = static_cast<uint8_t>(ACMCodecDB::database_[i].pltype);
188     } else if (IsCodecCN(i)) {
189       if (ACMCodecDB::database_[i].plfreq == 8000) {
190         cng_nb_pltype_ = static_cast<uint8_t>(ACMCodecDB::database_[i].pltype);
191       } else if (ACMCodecDB::database_[i].plfreq == 16000) {
192         cng_wb_pltype_ = static_cast<uint8_t>(ACMCodecDB::database_[i].pltype);
193       } else if (ACMCodecDB::database_[i].plfreq == 32000) {
194         cng_swb_pltype_ = static_cast<uint8_t>(ACMCodecDB::database_[i].pltype);
195       } else if (ACMCodecDB::database_[i].plfreq == 48000) {
196         cng_fb_pltype_ = static_cast<uint8_t>(ACMCodecDB::database_[i].pltype);
197       }
198     }
199   }
200 
201   if (InitializeReceiverSafe() < 0) {
202     WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, id_,
203                  "Cannot initialize receiver");
204   }
205   WEBRTC_TRACE(webrtc::kTraceMemory, webrtc::kTraceAudioCoding, id_, "Created");
206 }
207 
~AudioCodingModuleImpl()208 AudioCodingModuleImpl::~AudioCodingModuleImpl() {
209   {
210     CriticalSectionScoped lock(acm_crit_sect_);
211     current_send_codec_idx_ = -1;
212 
213     for (int i = 0; i < ACMCodecDB::kMaxNumCodecs; i++) {
214       if (codecs_[i] != NULL) {
215         // Mirror index holds the address of the codec memory.
216         assert(mirror_codec_idx_[i] > -1);
217         if (codecs_[mirror_codec_idx_[i]] != NULL) {
218           delete codecs_[mirror_codec_idx_[i]];
219           codecs_[mirror_codec_idx_[i]] = NULL;
220         }
221 
222         codecs_[i] = NULL;
223       }
224     }
225 
226     if (red_buffer_ != NULL) {
227       delete[] red_buffer_;
228       red_buffer_ = NULL;
229     }
230   }
231 
232   if (aux_rtp_header_ != NULL) {
233     delete aux_rtp_header_;
234     aux_rtp_header_ = NULL;
235   }
236 
237   delete callback_crit_sect_;
238   callback_crit_sect_ = NULL;
239 
240   delete acm_crit_sect_;
241   acm_crit_sect_ = NULL;
242   WEBRTC_TRACE(webrtc::kTraceMemory, webrtc::kTraceAudioCoding, id_,
243                "Destroyed");
244 }
245 
ChangeUniqueId(const int32_t id)246 int32_t AudioCodingModuleImpl::ChangeUniqueId(const int32_t id) {
247   {
248     CriticalSectionScoped lock(acm_crit_sect_);
249     id_ = id;
250 
251     for (int i = 0; i < ACMCodecDB::kMaxNumCodecs; i++) {
252       if (codecs_[i] != NULL) {
253         codecs_[i]->SetUniqueID(id);
254       }
255     }
256   }
257 
258   receiver_.set_id(id_);
259   return 0;
260 }
261 
262 // Returns the number of milliseconds until the module want a
263 // worker thread to call Process.
TimeUntilNextProcess()264 int32_t AudioCodingModuleImpl::TimeUntilNextProcess() {
265   CriticalSectionScoped lock(acm_crit_sect_);
266 
267   if (!HaveValidEncoder("TimeUntilNextProcess")) {
268     return -1;
269   }
270   return codecs_[current_send_codec_idx_]->SamplesLeftToEncode() /
271       (send_codec_inst_.plfreq / 1000);
272 }
273 
Process()274 int32_t AudioCodingModuleImpl::Process() {
275   bool dual_stream;
276   {
277     CriticalSectionScoped lock(acm_crit_sect_);
278     dual_stream = (secondary_encoder_.get() != NULL);
279   }
280   if (dual_stream) {
281     return ProcessDualStream();
282   }
283   return ProcessSingleStream();
284 }
285 
EncodeFragmentation(int fragmentation_index,int payload_type,uint32_t current_timestamp,ACMGenericCodec * encoder,uint8_t * stream)286 int AudioCodingModuleImpl::EncodeFragmentation(int fragmentation_index,
287                                                int payload_type,
288                                                uint32_t current_timestamp,
289                                                ACMGenericCodec* encoder,
290                                                uint8_t* stream) {
291   int16_t len_bytes = MAX_PAYLOAD_SIZE_BYTE;
292   uint32_t rtp_timestamp;
293   WebRtcACMEncodingType encoding_type;
294   if (encoder->Encode(stream, &len_bytes, &rtp_timestamp, &encoding_type) < 0) {
295     return -1;
296   }
297   assert(encoding_type == kActiveNormalEncoded);
298   assert(len_bytes > 0);
299 
300   fragmentation_.fragmentationLength[fragmentation_index] = len_bytes;
301   fragmentation_.fragmentationPlType[fragmentation_index] = payload_type;
302   fragmentation_.fragmentationTimeDiff[fragmentation_index] =
303       static_cast<uint16_t>(current_timestamp - rtp_timestamp);
304   fragmentation_.fragmentationVectorSize++;
305   return len_bytes;
306 }
307 
308 // Primary payloads are sent immediately, whereas a single secondary payload is
309 // buffered to be combined with "the next payload."
310 // Normally "the next payload" would be a primary payload. In case two
311 // consecutive secondary payloads are generated with no primary payload in
312 // between, then two secondary payloads are packed in one RED.
ProcessDualStream()313 int AudioCodingModuleImpl::ProcessDualStream() {
314   uint8_t stream[kMaxNumFragmentationVectors * MAX_PAYLOAD_SIZE_BYTE];
315   uint32_t current_timestamp;
316   int16_t length_bytes = 0;
317   RTPFragmentationHeader my_fragmentation;
318 
319   uint8_t my_red_payload_type;
320 
321   {
322     CriticalSectionScoped lock(acm_crit_sect_);
323     // Check if there is an encoder before.
324     if (!HaveValidEncoder("ProcessDualStream") ||
325         secondary_encoder_.get() == NULL) {
326       return -1;
327     }
328     ACMGenericCodec* primary_encoder = codecs_[current_send_codec_idx_];
329     // If primary encoder has a full frame of audio to generate payload.
330     bool primary_ready_to_encode = primary_encoder->HasFrameToEncode();
331     // If the secondary encoder has a frame of audio to generate a payload.
332     bool secondary_ready_to_encode = secondary_encoder_->HasFrameToEncode();
333 
334     if (!primary_ready_to_encode && !secondary_ready_to_encode) {
335       // Nothing to send.
336       return 0;
337     }
338     int len_bytes_previous_secondary = static_cast<int>(
339         fragmentation_.fragmentationLength[2]);
340     assert(len_bytes_previous_secondary <= MAX_PAYLOAD_SIZE_BYTE);
341     bool has_previous_payload = len_bytes_previous_secondary > 0;
342 
343     uint32_t primary_timestamp = primary_encoder->EarliestTimestamp();
344     uint32_t secondary_timestamp = secondary_encoder_->EarliestTimestamp();
345 
346     if (!has_previous_payload && !primary_ready_to_encode &&
347         secondary_ready_to_encode) {
348       // Secondary payload will be the ONLY bit-stream. Encode by secondary
349       // encoder, store the payload, and return. No packet is sent.
350       int16_t len_bytes = MAX_PAYLOAD_SIZE_BYTE;
351       WebRtcACMEncodingType encoding_type;
352       if (secondary_encoder_->Encode(red_buffer_, &len_bytes,
353                                      &last_red_timestamp_,
354                                      &encoding_type) < 0) {
355         WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, id_,
356                      "ProcessDual(): Encoding of secondary encoder Failed");
357         return -1;
358       }
359       assert(len_bytes > 0);
360       assert(encoding_type == kActiveNormalEncoded);
361       assert(len_bytes <= MAX_PAYLOAD_SIZE_BYTE);
362       fragmentation_.fragmentationLength[2] = len_bytes;
363       return 0;
364     }
365 
366     // Initialize with invalid but different values, so later can have sanity
367     // check if they are different.
368     int index_primary = -1;
369     int index_secondary = -2;
370     int index_previous_secondary = -3;
371 
372     if (primary_ready_to_encode) {
373       index_primary = secondary_ready_to_encode ?
374           TimestampLessThan(primary_timestamp, secondary_timestamp) : 0;
375       index_primary += has_previous_payload ?
376           TimestampLessThan(primary_timestamp, last_red_timestamp_) : 0;
377     }
378 
379     if (secondary_ready_to_encode) {
380       // Timestamp of secondary payload can only be less than primary payload,
381       // but is always larger than the timestamp of previous secondary payload.
382       index_secondary = primary_ready_to_encode ?
383           (1 - TimestampLessThan(primary_timestamp, secondary_timestamp)) : 0;
384     }
385 
386     if (has_previous_payload) {
387       index_previous_secondary = primary_ready_to_encode ?
388           (1 - TimestampLessThan(primary_timestamp, last_red_timestamp_)) : 0;
389       // If secondary is ready it always have a timestamp larger than previous
390       // secondary. So the index is either 0 or 1.
391       index_previous_secondary += secondary_ready_to_encode ? 1 : 0;
392     }
393 
394     // Indices must not be equal.
395     assert(index_primary != index_secondary);
396     assert(index_primary != index_previous_secondary);
397     assert(index_secondary != index_previous_secondary);
398 
399     // One of the payloads has to be at position zero.
400     assert(index_primary == 0 || index_secondary == 0 ||
401            index_previous_secondary == 0);
402 
403     // Timestamp of the RED payload.
404     if (index_primary == 0) {
405       current_timestamp = primary_timestamp;
406     } else if (index_secondary == 0) {
407       current_timestamp = secondary_timestamp;
408     } else {
409       current_timestamp = last_red_timestamp_;
410     }
411 
412     fragmentation_.fragmentationVectorSize = 0;
413     if (has_previous_payload) {
414       assert(index_previous_secondary >= 0 &&
415              index_previous_secondary < kMaxNumFragmentationVectors);
416       assert(len_bytes_previous_secondary <= MAX_PAYLOAD_SIZE_BYTE);
417       memcpy(&stream[index_previous_secondary * MAX_PAYLOAD_SIZE_BYTE],
418              red_buffer_, sizeof(stream[0]) * len_bytes_previous_secondary);
419       fragmentation_.fragmentationLength[index_previous_secondary] =
420           len_bytes_previous_secondary;
421       fragmentation_.fragmentationPlType[index_previous_secondary] =
422           secondary_send_codec_inst_.pltype;
423       fragmentation_.fragmentationTimeDiff[index_previous_secondary] =
424           static_cast<uint16_t>(current_timestamp - last_red_timestamp_);
425       fragmentation_.fragmentationVectorSize++;
426     }
427 
428     if (primary_ready_to_encode) {
429       assert(index_primary >= 0 && index_primary < kMaxNumFragmentationVectors);
430       int i = index_primary * MAX_PAYLOAD_SIZE_BYTE;
431       if (EncodeFragmentation(index_primary, send_codec_inst_.pltype,
432                               current_timestamp, primary_encoder,
433                               &stream[i]) < 0) {
434         WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, id_,
435                      "ProcessDualStream(): Encoding of primary encoder Failed");
436         return -1;
437       }
438     }
439 
440     if (secondary_ready_to_encode) {
441       assert(index_secondary >= 0 &&
442              index_secondary < kMaxNumFragmentationVectors - 1);
443       int i = index_secondary * MAX_PAYLOAD_SIZE_BYTE;
444       if (EncodeFragmentation(index_secondary,
445                               secondary_send_codec_inst_.pltype,
446                               current_timestamp, secondary_encoder_.get(),
447                               &stream[i]) < 0) {
448         WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, id_,
449                      "ProcessDualStream(): Encoding of secondary encoder "
450                      "Failed");
451         return -1;
452       }
453     }
454     // Copy to local variable, as it will be used outside the ACM lock.
455     my_fragmentation.CopyFrom(fragmentation_);
456     my_red_payload_type = red_pltype_;
457     length_bytes = 0;
458     for (int n = 0; n < fragmentation_.fragmentationVectorSize; n++) {
459       length_bytes += fragmentation_.fragmentationLength[n];
460     }
461   }
462 
463   {
464     CriticalSectionScoped lock(callback_crit_sect_);
465     if (packetization_callback_ != NULL) {
466       // Callback with payload data, including redundant data (RED).
467       if (packetization_callback_->SendData(kAudioFrameSpeech,
468                                             my_red_payload_type,
469                                             current_timestamp, stream,
470                                             length_bytes,
471                                             &my_fragmentation) < 0) {
472         return -1;
473       }
474     }
475   }
476 
477   {
478     CriticalSectionScoped lock(acm_crit_sect_);
479     // Now that data is sent, clean up fragmentation.
480     ResetFragmentation(0);
481   }
482   return 0;
483 }
484 
485 // Process any pending tasks such as timeouts.
ProcessSingleStream()486 int AudioCodingModuleImpl::ProcessSingleStream() {
487   // Make room for 1 RED payload.
488   uint8_t stream[2 * MAX_PAYLOAD_SIZE_BYTE];
489   // TODO(turajs): |length_bytes| & |red_length_bytes| can be of type int if
490   // ACMGenericCodec::Encode() & ACMGenericCodec::GetRedPayload() allows.
491   int16_t length_bytes = 2 * MAX_PAYLOAD_SIZE_BYTE;
492   int16_t red_length_bytes = length_bytes;
493   uint32_t rtp_timestamp;
494   int status;
495   WebRtcACMEncodingType encoding_type;
496   FrameType frame_type = kAudioFrameSpeech;
497   uint8_t current_payload_type = 0;
498   bool has_data_to_send = false;
499   bool red_active = false;
500   RTPFragmentationHeader my_fragmentation;
501 
502   // Keep the scope of the ACM critical section limited.
503   {
504     CriticalSectionScoped lock(acm_crit_sect_);
505     // Check if there is an encoder before.
506     if (!HaveValidEncoder("ProcessSingleStream")) {
507       return -1;
508     }
509     status = codecs_[current_send_codec_idx_]->Encode(stream, &length_bytes,
510                                                       &rtp_timestamp,
511                                                       &encoding_type);
512     if (status < 0) {
513       // Encode failed.
514       WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, id_,
515                    "ProcessSingleStream(): Encoding Failed");
516       length_bytes = 0;
517       return -1;
518     } else if (status == 0) {
519       // Not enough data.
520       return 0;
521     } else {
522       switch (encoding_type) {
523         case kNoEncoding: {
524           current_payload_type = previous_pltype_;
525           frame_type = kFrameEmpty;
526           length_bytes = 0;
527           break;
528         }
529         case kActiveNormalEncoded:
530         case kPassiveNormalEncoded: {
531           current_payload_type = static_cast<uint8_t>(send_codec_inst_.pltype);
532           frame_type = kAudioFrameSpeech;
533           break;
534         }
535         case kPassiveDTXNB: {
536           current_payload_type = cng_nb_pltype_;
537           frame_type = kAudioFrameCN;
538           is_first_red_ = true;
539           break;
540         }
541         case kPassiveDTXWB: {
542           current_payload_type = cng_wb_pltype_;
543           frame_type = kAudioFrameCN;
544           is_first_red_ = true;
545           break;
546         }
547         case kPassiveDTXSWB: {
548           current_payload_type = cng_swb_pltype_;
549           frame_type = kAudioFrameCN;
550           is_first_red_ = true;
551           break;
552         }
553         case kPassiveDTXFB: {
554           current_payload_type = cng_fb_pltype_;
555           frame_type = kAudioFrameCN;
556           is_first_red_ = true;
557           break;
558         }
559       }
560       has_data_to_send = true;
561       previous_pltype_ = current_payload_type;
562 
563       // Redundancy encode is done here. The two bitstreams packetized into
564       // one RTP packet and the fragmentation points are set.
565       // Only apply RED on speech data.
566       if ((red_enabled_) &&
567           ((encoding_type == kActiveNormalEncoded) ||
568               (encoding_type == kPassiveNormalEncoded))) {
569         // RED is enabled within this scope.
570         //
571         // Note that, a special solution exists for iSAC since it is the only
572         // codec for which GetRedPayload has a non-empty implementation.
573         //
574         // Summary of the RED scheme below (use iSAC as example):
575         //
576         //  1st (is_first_red_ is true) encoded iSAC frame (primary #1) =>
577         //      - call GetRedPayload() and store redundancy for packet #1 in
578         //        second fragment of RED buffer (old data)
579         //      - drop the primary iSAC frame
580         //      - don't call SendData
581         //  2nd (is_first_red_ is false) encoded iSAC frame (primary #2) =>
582         //      - store primary #2 in 1st fragment of RED buffer and send the
583         //        combined packet
584         //      - the transmitted packet contains primary #2 (new) and
585         //        redundancy for packet #1 (old)
586         //      - call GetRed_Payload() and store redundancy for packet #2 in
587         //        second fragment of RED buffer
588         //
589         //  ...
590         //
591         //  Nth encoded iSAC frame (primary #N) =>
592         //      - store primary #N in 1st fragment of RED buffer and send the
593         //        combined packet
594         //      - the transmitted packet contains primary #N (new) and
595         //        reduncancy for packet #(N-1) (old)
596         //      - call GetRedPayload() and store redundancy for packet #N in
597         //        second fragment of RED buffer
598         //
599         //  For all other codecs, GetRedPayload does nothing and returns -1 =>
600         //  redundant data is only a copy.
601         //
602         //  First combined packet contains : #2 (new) and #1 (old)
603         //  Second combined packet contains: #3 (new) and #2 (old)
604         //  Third combined packet contains : #4 (new) and #3 (old)
605         //
606         //  Hence, even if every second packet is dropped, perfect
607         //  reconstruction is possible.
608         red_active = true;
609 
610         has_data_to_send = false;
611         // Skip the following part for the first packet in a RED session.
612         if (!is_first_red_) {
613           // Rearrange stream such that RED packets are included.
614           // Replace stream now that we have stored current stream.
615           memcpy(stream + fragmentation_.fragmentationOffset[1], red_buffer_,
616                  fragmentation_.fragmentationLength[1]);
617           // Update the fragmentation time difference vector, in number of
618           // timestamps.
619           uint16_t time_since_last = static_cast<uint16_t>(
620               rtp_timestamp - last_red_timestamp_);
621 
622           // Update fragmentation vectors.
623           fragmentation_.fragmentationPlType[1] =
624               fragmentation_.fragmentationPlType[0];
625           fragmentation_.fragmentationTimeDiff[1] = time_since_last;
626           has_data_to_send = true;
627         }
628 
629         // Insert new packet length.
630         fragmentation_.fragmentationLength[0] = length_bytes;
631 
632         // Insert new packet payload type.
633         fragmentation_.fragmentationPlType[0] = current_payload_type;
634         last_red_timestamp_ = rtp_timestamp;
635 
636         // Can be modified by the GetRedPayload() call if iSAC is utilized.
637         red_length_bytes = length_bytes;
638 
639         // A fragmentation header is provided => packetization according to
640         // RFC 2198 (RTP Payload for Redundant Audio Data) will be used.
641         // First fragment is the current data (new).
642         // Second fragment is the previous data (old).
643         length_bytes = static_cast<int16_t>(
644             fragmentation_.fragmentationLength[0] +
645             fragmentation_.fragmentationLength[1]);
646 
647         // Get, and store, redundant data from the encoder based on the recently
648         // encoded frame.
649         // NOTE - only iSAC contains an implementation; all other codecs does
650         // nothing and returns -1.
651         if (codecs_[current_send_codec_idx_]->GetRedPayload(
652             red_buffer_, &red_length_bytes) == -1) {
653           // The codec was not iSAC => use current encoder output as redundant
654           // data instead (trivial RED scheme).
655           memcpy(red_buffer_, stream, red_length_bytes);
656         }
657 
658         is_first_red_ = false;
659         // Update payload type with RED payload type.
660         current_payload_type = red_pltype_;
661         // We have packed 2 payloads.
662         fragmentation_.fragmentationVectorSize = kNumRedFragmentationVectors;
663 
664         // Copy to local variable, as it will be used outside ACM lock.
665         my_fragmentation.CopyFrom(fragmentation_);
666         // Store RED length.
667         fragmentation_.fragmentationLength[1] = red_length_bytes;
668       }
669     }
670   }
671 
672   if (has_data_to_send) {
673     CriticalSectionScoped lock(callback_crit_sect_);
674 
675     if (packetization_callback_ != NULL) {
676       if (red_active) {
677         // Callback with payload data, including redundant data (RED).
678         packetization_callback_->SendData(frame_type, current_payload_type,
679                                           rtp_timestamp, stream, length_bytes,
680                                           &my_fragmentation);
681       } else {
682         // Callback with payload data.
683         packetization_callback_->SendData(frame_type, current_payload_type,
684                                           rtp_timestamp, stream, length_bytes,
685                                           NULL);
686       }
687     }
688 
689     if (vad_callback_ != NULL) {
690       // Callback with VAD decision.
691       vad_callback_->InFrameType(static_cast<int16_t>(encoding_type));
692     }
693   }
694   return length_bytes;
695 }
696 
697 /////////////////////////////////////////
698 //   Sender
699 //
700 
701 // Initialize send codec.
InitializeSender()702 int AudioCodingModuleImpl::InitializeSender() {
703   CriticalSectionScoped lock(acm_crit_sect_);
704 
705   // Start with invalid values.
706   send_codec_registered_ = false;
707   current_send_codec_idx_ = -1;
708   send_codec_inst_.plname[0] = '\0';
709 
710   // Delete all encoders to start fresh.
711   for (int id = 0; id < ACMCodecDB::kMaxNumCodecs; id++) {
712     if (codecs_[id] != NULL) {
713       codecs_[id]->DestructEncoder();
714     }
715   }
716 
717   // Initialize RED.
718   is_first_red_ = true;
719   if (red_enabled_ || secondary_encoder_.get() != NULL) {
720     if (red_buffer_ != NULL) {
721       memset(red_buffer_, 0, MAX_PAYLOAD_SIZE_BYTE);
722     }
723     if (red_enabled_) {
724       ResetFragmentation(kNumRedFragmentationVectors);
725     } else {
726       ResetFragmentation(0);
727     }
728   }
729 
730   return 0;
731 }
732 
ResetEncoder()733 int AudioCodingModuleImpl::ResetEncoder() {
734   CriticalSectionScoped lock(acm_crit_sect_);
735   if (!HaveValidEncoder("ResetEncoder")) {
736     return -1;
737   }
738   return codecs_[current_send_codec_idx_]->ResetEncoder();
739 }
740 
CreateCodec(const CodecInst & codec)741 ACMGenericCodec* AudioCodingModuleImpl::CreateCodec(const CodecInst& codec) {
742   ACMGenericCodec* my_codec = NULL;
743 
744   my_codec = ACMCodecDB::CreateCodecInstance(codec);
745   if (my_codec == NULL) {
746     // Error, could not create the codec.
747     WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, id_,
748                  "ACMCodecDB::CreateCodecInstance() failed in CreateCodec()");
749     return my_codec;
750   }
751   my_codec->SetUniqueID(id_);
752   my_codec->SetNetEqDecodeLock(receiver_.DecodeLock());
753 
754   return my_codec;
755 }
756 
757 // Check if the given codec is a valid to be registered as send codec.
IsValidSendCodec(const CodecInst & send_codec,bool is_primary_encoder,int acm_id,int * mirror_id)758 static int IsValidSendCodec(const CodecInst& send_codec,
759                             bool is_primary_encoder,
760                             int acm_id,
761                             int* mirror_id) {
762   if ((send_codec.channels != 1) && (send_codec.channels != 2)) {
763     WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, acm_id,
764                  "Wrong number of channels (%d, only mono and stereo are "
765                  "supported) for %s encoder", send_codec.channels,
766                  is_primary_encoder ? "primary" : "secondary");
767     return -1;
768   }
769 
770   int codec_id = ACMCodecDB::CodecNumber(send_codec, mirror_id);
771   if (codec_id < 0) {
772     WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, acm_id,
773                  "Invalid codec setting for the send codec.");
774     return -1;
775   }
776 
777   // TODO(tlegrand): Remove this check. Already taken care of in
778   // ACMCodecDB::CodecNumber().
779   // Check if the payload-type is valid
780   if (!ACMCodecDB::ValidPayloadType(send_codec.pltype)) {
781     WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, acm_id,
782                  "Invalid payload-type %d for %s.", send_codec.pltype,
783                  send_codec.plname);
784     return -1;
785   }
786 
787   // Telephone-event cannot be a send codec.
788   if (!STR_CASE_CMP(send_codec.plname, "telephone-event")) {
789     WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, acm_id,
790                  "telephone-event cannot be a send codec");
791     *mirror_id = -1;
792     return -1;
793   }
794 
795   if (ACMCodecDB::codec_settings_[codec_id].channel_support
796       < send_codec.channels) {
797     WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, acm_id,
798                  "%d number of channels not supportedn for %s.",
799                  send_codec.channels, send_codec.plname);
800     *mirror_id = -1;
801     return -1;
802   }
803 
804   if (!is_primary_encoder) {
805     // If registering the secondary encoder, then RED and CN are not valid
806     // choices as encoder.
807     if (IsCodecRED(&send_codec)) {
808       WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, acm_id,
809                    "RED cannot be secondary codec");
810       *mirror_id = -1;
811       return -1;
812     }
813 
814     if (IsCodecCN(&send_codec)) {
815       WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, acm_id,
816                    "DTX cannot be secondary codec");
817       *mirror_id = -1;
818       return -1;
819     }
820   }
821   return codec_id;
822 }
823 
RegisterSecondarySendCodec(const CodecInst & send_codec)824 int AudioCodingModuleImpl::RegisterSecondarySendCodec(
825     const CodecInst& send_codec) {
826   CriticalSectionScoped lock(acm_crit_sect_);
827   if (!send_codec_registered_) {
828     return -1;
829   }
830   // Primary and Secondary codecs should have the same sampling rates.
831   if (send_codec.plfreq != send_codec_inst_.plfreq) {
832     return -1;
833   }
834   int mirror_id;
835   int codec_id = IsValidSendCodec(send_codec, false, id_, &mirror_id);
836   if (codec_id < 0) {
837     return -1;
838   }
839   ACMGenericCodec* encoder = CreateCodec(send_codec);
840   WebRtcACMCodecParams codec_params;
841   // Initialize the codec before registering. For secondary codec VAD & DTX are
842   // disabled.
843   memcpy(&(codec_params.codec_inst), &send_codec, sizeof(CodecInst));
844   codec_params.enable_vad = false;
845   codec_params.enable_dtx = false;
846   codec_params.vad_mode = VADNormal;
847   // Force initialization.
848   if (encoder->InitEncoder(&codec_params, true) < 0) {
849     // Could not initialize, therefore cannot be registered.
850     delete encoder;
851     return -1;
852   }
853   secondary_encoder_.reset(encoder);
854   memcpy(&secondary_send_codec_inst_, &send_codec, sizeof(send_codec));
855 
856   // Disable VAD & DTX.
857   SetVADSafe(false, false, VADNormal);
858 
859   // Cleaning.
860   if (red_buffer_) {
861     memset(red_buffer_, 0, MAX_PAYLOAD_SIZE_BYTE);
862   }
863   ResetFragmentation(0);
864   return 0;
865 }
866 
UnregisterSecondarySendCodec()867 void AudioCodingModuleImpl::UnregisterSecondarySendCodec() {
868   CriticalSectionScoped lock(acm_crit_sect_);
869   if (secondary_encoder_.get() == NULL) {
870     return;
871   }
872   secondary_encoder_.reset();
873   ResetFragmentation(0);
874 }
875 
SecondarySendCodec(CodecInst * secondary_codec) const876 int AudioCodingModuleImpl::SecondarySendCodec(
877     CodecInst* secondary_codec) const {
878   CriticalSectionScoped lock(acm_crit_sect_);
879   if (secondary_encoder_.get() == NULL) {
880     return -1;
881   }
882   memcpy(secondary_codec, &secondary_send_codec_inst_,
883          sizeof(secondary_send_codec_inst_));
884   return 0;
885 }
886 
887 // Can be called multiple times for Codec, CNG, RED.
RegisterSendCodec(const CodecInst & send_codec)888 int AudioCodingModuleImpl::RegisterSendCodec(const CodecInst& send_codec) {
889   int mirror_id;
890   int codec_id = IsValidSendCodec(send_codec, true, id_, &mirror_id);
891 
892   CriticalSectionScoped lock(acm_crit_sect_);
893 
894   // Check for reported errors from function IsValidSendCodec().
895   if (codec_id < 0) {
896     if (!send_codec_registered_) {
897       // This values has to be NULL if there is no codec registered.
898       current_send_codec_idx_ = -1;
899     }
900     return -1;
901   }
902 
903   // RED can be registered with other payload type. If not registered a default
904   // payload type is used.
905   if (IsCodecRED(&send_codec)) {
906     // TODO(tlegrand): Remove this check. Already taken care of in
907     // ACMCodecDB::CodecNumber().
908     // Check if the payload-type is valid
909     if (!ACMCodecDB::ValidPayloadType(send_codec.pltype)) {
910       WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, id_,
911                    "Invalid payload-type %d for %s.", send_codec.pltype,
912                    send_codec.plname);
913       return -1;
914     }
915     // Set RED payload type.
916     red_pltype_ = static_cast<uint8_t>(send_codec.pltype);
917     return 0;
918   }
919 
920   // CNG can be registered with other payload type. If not registered the
921   // default payload types from codec database will be used.
922   if (IsCodecCN(&send_codec)) {
923     // CNG is registered.
924     switch (send_codec.plfreq) {
925       case 8000: {
926         cng_nb_pltype_ = static_cast<uint8_t>(send_codec.pltype);
927         break;
928       }
929       case 16000: {
930         cng_wb_pltype_ = static_cast<uint8_t>(send_codec.pltype);
931         break;
932       }
933       case 32000: {
934         cng_swb_pltype_ = static_cast<uint8_t>(send_codec.pltype);
935         break;
936       }
937       case 48000: {
938         cng_fb_pltype_ = static_cast<uint8_t>(send_codec.pltype);
939         break;
940       }
941       default: {
942         WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, id_,
943                      "RegisterSendCodec() failed, invalid frequency for CNG "
944                      "registration");
945         return -1;
946       }
947     }
948     return 0;
949   }
950 
951   // Set Stereo, and make sure VAD and DTX is turned off.
952   if (send_codec.channels == 2) {
953     stereo_send_ = true;
954     if (vad_enabled_ || dtx_enabled_) {
955       WEBRTC_TRACE(webrtc::kTraceWarning, webrtc::kTraceAudioCoding, id_,
956                    "VAD/DTX is turned off, not supported when sending stereo.");
957     }
958     vad_enabled_ = false;
959     dtx_enabled_ = false;
960   } else {
961     stereo_send_ = false;
962   }
963 
964   // Check if the codec is already registered as send codec.
965   bool is_send_codec;
966   if (send_codec_registered_) {
967     int send_codec_mirror_id;
968     int send_codec_id = ACMCodecDB::CodecNumber(send_codec_inst_,
969                                                 &send_codec_mirror_id);
970     assert(send_codec_id >= 0);
971     is_send_codec = (send_codec_id == codec_id) ||
972         (mirror_id == send_codec_mirror_id);
973   } else {
974     is_send_codec = false;
975   }
976 
977   // If there is secondary codec registered and the new send codec has a
978   // sampling rate different than that of secondary codec, then unregister the
979   // secondary codec.
980   if (secondary_encoder_.get() != NULL &&
981       secondary_send_codec_inst_.plfreq != send_codec.plfreq) {
982     secondary_encoder_.reset();
983     ResetFragmentation(0);
984   }
985 
986   // If new codec, or new settings, register.
987   if (!is_send_codec) {
988     if (codecs_[mirror_id] == NULL) {
989       codecs_[mirror_id] = CreateCodec(send_codec);
990       if (codecs_[mirror_id] == NULL) {
991         WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, id_,
992                      "Cannot Create the codec");
993         return -1;
994       }
995       mirror_codec_idx_[mirror_id] = mirror_id;
996     }
997 
998     if (mirror_id != codec_id) {
999       codecs_[codec_id] = codecs_[mirror_id];
1000       mirror_codec_idx_[codec_id] = mirror_id;
1001     }
1002 
1003     ACMGenericCodec* codec_ptr = codecs_[codec_id];
1004     WebRtcACMCodecParams codec_params;
1005 
1006     memcpy(&(codec_params.codec_inst), &send_codec, sizeof(CodecInst));
1007     codec_params.enable_vad = vad_enabled_;
1008     codec_params.enable_dtx = dtx_enabled_;
1009     codec_params.vad_mode = vad_mode_;
1010     // Force initialization.
1011     if (codec_ptr->InitEncoder(&codec_params, true) < 0) {
1012       // Could not initialize the encoder.
1013 
1014       // Check if already have a registered codec.
1015       // Depending on that different messages are logged.
1016       if (!send_codec_registered_) {
1017         current_send_codec_idx_ = -1;
1018         WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, id_,
1019                      "Cannot Initialize the encoder No Encoder is registered");
1020       } else {
1021         WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, id_,
1022                      "Cannot Initialize the encoder, continue encoding with "
1023                      "the previously registered codec");
1024       }
1025       return -1;
1026     }
1027 
1028     // Update states.
1029     dtx_enabled_ = codec_params.enable_dtx;
1030     vad_enabled_ = codec_params.enable_vad;
1031     vad_mode_ = codec_params.vad_mode;
1032 
1033     // Everything is fine so we can replace the previous codec with this one.
1034     if (send_codec_registered_) {
1035       // If we change codec we start fresh with RED.
1036       // This is not strictly required by the standard.
1037       is_first_red_ = true;
1038       codec_ptr->SetVAD(&dtx_enabled_, &vad_enabled_, &vad_mode_);
1039 
1040       if (!codec_ptr->HasInternalFEC()) {
1041         codec_fec_enabled_ = false;
1042       } else {
1043         if (codec_ptr->SetFEC(codec_fec_enabled_) < 0) {
1044           WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, id_,
1045                        "Cannot set codec FEC");
1046           return -1;
1047         }
1048       }
1049     }
1050 
1051     current_send_codec_idx_ = codec_id;
1052     send_codec_registered_ = true;
1053     memcpy(&send_codec_inst_, &send_codec, sizeof(CodecInst));
1054     previous_pltype_ = send_codec_inst_.pltype;
1055     return 0;
1056   } else {
1057     // If codec is the same as already registered check if any parameters
1058     // has changed compared to the current values.
1059     // If any parameter is valid then apply it and record.
1060     bool force_init = false;
1061 
1062     if (mirror_id != codec_id) {
1063       codecs_[codec_id] = codecs_[mirror_id];
1064       mirror_codec_idx_[codec_id] = mirror_id;
1065     }
1066 
1067     // Check the payload type.
1068     if (send_codec.pltype != send_codec_inst_.pltype) {
1069       // At this point check if the given payload type is valid.
1070       // Record it later when the sampling frequency is changed
1071       // successfully.
1072       if (!ACMCodecDB::ValidPayloadType(send_codec.pltype)) {
1073         WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, id_,
1074                      "Out of range payload type");
1075         return -1;
1076       }
1077     }
1078 
1079     // If there is a codec that ONE instance of codec supports multiple
1080     // sampling frequencies, then we need to take care of it here.
1081     // one such a codec is iSAC. Both WB and SWB are encoded and decoded
1082     // with one iSAC instance. Therefore, we need to update the encoder
1083     // frequency if required.
1084     if (send_codec_inst_.plfreq != send_codec.plfreq) {
1085       force_init = true;
1086 
1087       // If sampling frequency is changed we have to start fresh with RED.
1088       is_first_red_ = true;
1089     }
1090 
1091     // If packet size or number of channels has changed, we need to
1092     // re-initialize the encoder.
1093     if (send_codec_inst_.pacsize != send_codec.pacsize) {
1094       force_init = true;
1095     }
1096     if (send_codec_inst_.channels != send_codec.channels) {
1097       force_init = true;
1098     }
1099 
1100     if (force_init) {
1101       WebRtcACMCodecParams codec_params;
1102 
1103       memcpy(&(codec_params.codec_inst), &send_codec, sizeof(CodecInst));
1104       codec_params.enable_vad = vad_enabled_;
1105       codec_params.enable_dtx = dtx_enabled_;
1106       codec_params.vad_mode = vad_mode_;
1107 
1108       // Force initialization.
1109       if (codecs_[current_send_codec_idx_]->InitEncoder(&codec_params,
1110                                                         true) < 0) {
1111         WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, id_,
1112                      "Could not change the codec packet-size.");
1113         return -1;
1114       }
1115 
1116       send_codec_inst_.plfreq = send_codec.plfreq;
1117       send_codec_inst_.pacsize = send_codec.pacsize;
1118       send_codec_inst_.channels = send_codec.channels;
1119     }
1120 
1121     // If the change of sampling frequency has been successful then
1122     // we store the payload-type.
1123     send_codec_inst_.pltype = send_codec.pltype;
1124 
1125     // Check if a change in Rate is required.
1126     if (send_codec.rate != send_codec_inst_.rate) {
1127       if (codecs_[codec_id]->SetBitRate(send_codec.rate) < 0) {
1128         WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, id_,
1129                      "Could not change the codec rate.");
1130         return -1;
1131       }
1132       send_codec_inst_.rate = send_codec.rate;
1133     }
1134 
1135     if (!codecs_[codec_id]->HasInternalFEC()) {
1136       codec_fec_enabled_ = false;
1137     } else {
1138       if (codecs_[codec_id]->SetFEC(codec_fec_enabled_) < 0) {
1139         WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, id_,
1140                      "Cannot set codec FEC");
1141         return -1;
1142       }
1143     }
1144 
1145     previous_pltype_ = send_codec_inst_.pltype;
1146     return 0;
1147   }
1148 }
1149 
1150 // Get current send codec.
SendCodec(CodecInst * current_codec) const1151 int AudioCodingModuleImpl::SendCodec(
1152     CodecInst* current_codec) const {
1153   WEBRTC_TRACE(webrtc::kTraceStream, webrtc::kTraceAudioCoding, id_,
1154                "SendCodec()");
1155   CriticalSectionScoped lock(acm_crit_sect_);
1156 
1157   if (!send_codec_registered_) {
1158     WEBRTC_TRACE(webrtc::kTraceStream, webrtc::kTraceAudioCoding, id_,
1159                  "SendCodec Failed, no codec is registered");
1160     return -1;
1161   }
1162   WebRtcACMCodecParams encoder_param;
1163   codecs_[current_send_codec_idx_]->EncoderParams(&encoder_param);
1164   encoder_param.codec_inst.pltype = send_codec_inst_.pltype;
1165   memcpy(current_codec, &(encoder_param.codec_inst), sizeof(CodecInst));
1166 
1167   return 0;
1168 }
1169 
1170 // Get current send frequency.
SendFrequency() const1171 int AudioCodingModuleImpl::SendFrequency() const {
1172   WEBRTC_TRACE(webrtc::kTraceStream, webrtc::kTraceAudioCoding, id_,
1173                "SendFrequency()");
1174   CriticalSectionScoped lock(acm_crit_sect_);
1175 
1176   if (!send_codec_registered_) {
1177     WEBRTC_TRACE(webrtc::kTraceStream, webrtc::kTraceAudioCoding, id_,
1178                  "SendFrequency Failed, no codec is registered");
1179     return -1;
1180   }
1181 
1182   return send_codec_inst_.plfreq;
1183 }
1184 
1185 // Get encode bitrate.
1186 // Adaptive rate codecs return their current encode target rate, while other
1187 // codecs return there longterm avarage or their fixed rate.
SendBitrate() const1188 int AudioCodingModuleImpl::SendBitrate() const {
1189   CriticalSectionScoped lock(acm_crit_sect_);
1190 
1191   if (!send_codec_registered_) {
1192     WEBRTC_TRACE(webrtc::kTraceStream, webrtc::kTraceAudioCoding, id_,
1193                  "SendBitrate Failed, no codec is registered");
1194     return -1;
1195   }
1196 
1197   WebRtcACMCodecParams encoder_param;
1198   codecs_[current_send_codec_idx_]->EncoderParams(&encoder_param);
1199 
1200   return encoder_param.codec_inst.rate;
1201 }
1202 
1203 // Set available bandwidth, inform the encoder about the estimated bandwidth
1204 // received from the remote party.
SetReceivedEstimatedBandwidth(int bw)1205 int AudioCodingModuleImpl::SetReceivedEstimatedBandwidth(int bw) {
1206   return codecs_[current_send_codec_idx_]->SetEstimatedBandwidth(bw);
1207 }
1208 
1209 // Register a transport callback which will be called to deliver
1210 // the encoded buffers.
RegisterTransportCallback(AudioPacketizationCallback * transport)1211 int AudioCodingModuleImpl::RegisterTransportCallback(
1212     AudioPacketizationCallback* transport) {
1213   CriticalSectionScoped lock(callback_crit_sect_);
1214   packetization_callback_ = transport;
1215   return 0;
1216 }
1217 
1218 // Add 10MS of raw (PCM) audio data to the encoder.
Add10MsData(const AudioFrame & audio_frame)1219 int AudioCodingModuleImpl::Add10MsData(
1220     const AudioFrame& audio_frame) {
1221   if (audio_frame.samples_per_channel_ <= 0) {
1222     assert(false);
1223     WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, id_,
1224                  "Cannot Add 10 ms audio, payload length is negative or "
1225                  "zero");
1226     return -1;
1227   }
1228 
1229   if (audio_frame.sample_rate_hz_ > 48000) {
1230     assert(false);
1231     WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, id_,
1232                  "Cannot Add 10 ms audio, input frequency not valid");
1233     return -1;
1234   }
1235 
1236   // If the length and frequency matches. We currently just support raw PCM.
1237   if ((audio_frame.sample_rate_hz_ / 100)
1238       != audio_frame.samples_per_channel_) {
1239     WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, id_,
1240                  "Cannot Add 10 ms audio, input frequency and length doesn't"
1241                  " match");
1242     return -1;
1243   }
1244 
1245   if (audio_frame.num_channels_ != 1 && audio_frame.num_channels_ != 2) {
1246     WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, id_,
1247                  "Cannot Add 10 ms audio, invalid number of channels.");
1248     return -1;
1249   }
1250 
1251   CriticalSectionScoped lock(acm_crit_sect_);
1252   // Do we have a codec registered?
1253   if (!HaveValidEncoder("Add10MsData")) {
1254     return -1;
1255   }
1256 
1257   const AudioFrame* ptr_frame;
1258   // Perform a resampling, also down-mix if it is required and can be
1259   // performed before resampling (a down mix prior to resampling will take
1260   // place if both primary and secondary encoders are mono and input is in
1261   // stereo).
1262   if (PreprocessToAddData(audio_frame, &ptr_frame) < 0) {
1263     return -1;
1264   }
1265 
1266   // Check whether we need an up-mix or down-mix?
1267   bool remix = ptr_frame->num_channels_ != send_codec_inst_.channels;
1268   if (secondary_encoder_.get() != NULL) {
1269     remix = remix ||
1270         (ptr_frame->num_channels_ != secondary_send_codec_inst_.channels);
1271   }
1272 
1273   // If a re-mix is required (up or down), this buffer will store re-mixed
1274   // version of the input.
1275   int16_t buffer[WEBRTC_10MS_PCM_AUDIO];
1276   if (remix) {
1277     if (ptr_frame->num_channels_ == 1) {
1278       if (UpMix(*ptr_frame, WEBRTC_10MS_PCM_AUDIO, buffer) < 0)
1279         return -1;
1280     } else {
1281       if (DownMix(*ptr_frame, WEBRTC_10MS_PCM_AUDIO, buffer) < 0)
1282         return -1;
1283     }
1284   }
1285 
1286   // When adding data to encoders this pointer is pointing to an audio buffer
1287   // with correct number of channels.
1288   const int16_t* ptr_audio = ptr_frame->data_;
1289 
1290   // For pushing data to primary, point the |ptr_audio| to correct buffer.
1291   if (send_codec_inst_.channels != ptr_frame->num_channels_)
1292     ptr_audio = buffer;
1293 
1294   if (codecs_[current_send_codec_idx_]->Add10MsData(
1295       ptr_frame->timestamp_, ptr_audio, ptr_frame->samples_per_channel_,
1296       send_codec_inst_.channels) < 0)
1297     return -1;
1298 
1299   if (secondary_encoder_.get() != NULL) {
1300     // For pushing data to secondary, point the |ptr_audio| to correct buffer.
1301     ptr_audio = ptr_frame->data_;
1302     if (secondary_send_codec_inst_.channels != ptr_frame->num_channels_)
1303       ptr_audio = buffer;
1304 
1305     if (secondary_encoder_->Add10MsData(
1306         ptr_frame->timestamp_, ptr_audio, ptr_frame->samples_per_channel_,
1307         secondary_send_codec_inst_.channels) < 0)
1308       return -1;
1309   }
1310 
1311   return 0;
1312 }
1313 
1314 // Perform a resampling and down-mix if required. We down-mix only if
1315 // encoder is mono and input is stereo. In case of dual-streaming, both
1316 // encoders has to be mono for down-mix to take place.
1317 // |*ptr_out| will point to the pre-processed audio-frame. If no pre-processing
1318 // is required, |*ptr_out| points to |in_frame|.
PreprocessToAddData(const AudioFrame & in_frame,const AudioFrame ** ptr_out)1319 int AudioCodingModuleImpl::PreprocessToAddData(const AudioFrame& in_frame,
1320                                                const AudioFrame** ptr_out) {
1321   // Primary and secondary (if exists) should have the same sampling rate.
1322   assert((secondary_encoder_.get() != NULL) ?
1323       secondary_send_codec_inst_.plfreq == send_codec_inst_.plfreq : true);
1324 
1325   bool resample = (in_frame.sample_rate_hz_ != send_codec_inst_.plfreq);
1326 
1327   // This variable is true if primary codec and secondary codec (if exists)
1328   // are both mono and input is stereo.
1329   bool down_mix;
1330   if (secondary_encoder_.get() != NULL) {
1331     down_mix = (in_frame.num_channels_ == 2) &&
1332         (send_codec_inst_.channels == 1) &&
1333         (secondary_send_codec_inst_.channels == 1);
1334   } else {
1335     down_mix = (in_frame.num_channels_ == 2) &&
1336         (send_codec_inst_.channels == 1);
1337   }
1338 
1339   if (!first_10ms_data_) {
1340     expected_in_ts_ = in_frame.timestamp_;
1341     expected_codec_ts_ = in_frame.timestamp_;
1342     first_10ms_data_ = true;
1343   } else if (in_frame.timestamp_ != expected_in_ts_) {
1344     // TODO(turajs): Do we need a warning here.
1345     expected_codec_ts_ += (in_frame.timestamp_ - expected_in_ts_) *
1346         static_cast<uint32_t>((static_cast<double>(send_codec_inst_.plfreq) /
1347                     static_cast<double>(in_frame.sample_rate_hz_)));
1348     expected_in_ts_ = in_frame.timestamp_;
1349   }
1350 
1351 
1352   if (!down_mix && !resample) {
1353     // No pre-processing is required.
1354     expected_in_ts_ += in_frame.samples_per_channel_;
1355     expected_codec_ts_ += in_frame.samples_per_channel_;
1356     *ptr_out = &in_frame;
1357     return 0;
1358   }
1359 
1360   *ptr_out = &preprocess_frame_;
1361   preprocess_frame_.num_channels_ = in_frame.num_channels_;
1362   int16_t audio[WEBRTC_10MS_PCM_AUDIO];
1363   const int16_t* src_ptr_audio = in_frame.data_;
1364   int16_t* dest_ptr_audio = preprocess_frame_.data_;
1365   if (down_mix) {
1366     // If a resampling is required the output of a down-mix is written into a
1367     // local buffer, otherwise, it will be written to the output frame.
1368     if (resample)
1369       dest_ptr_audio = audio;
1370     if (DownMix(in_frame, WEBRTC_10MS_PCM_AUDIO, dest_ptr_audio) < 0)
1371       return -1;
1372     preprocess_frame_.num_channels_ = 1;
1373     // Set the input of the resampler is the down-mixed signal.
1374     src_ptr_audio = audio;
1375   }
1376 
1377   preprocess_frame_.timestamp_ = expected_codec_ts_;
1378   preprocess_frame_.samples_per_channel_ = in_frame.samples_per_channel_;
1379   preprocess_frame_.sample_rate_hz_ = in_frame.sample_rate_hz_;
1380   // If it is required, we have to do a resampling.
1381   if (resample) {
1382     // The result of the resampler is written to output frame.
1383     dest_ptr_audio = preprocess_frame_.data_;
1384 
1385     preprocess_frame_.samples_per_channel_ =
1386         resampler_.Resample10Msec(src_ptr_audio,
1387                                   in_frame.sample_rate_hz_,
1388                                   send_codec_inst_.plfreq,
1389                                   preprocess_frame_.num_channels_,
1390                                   AudioFrame::kMaxDataSizeSamples,
1391                                   dest_ptr_audio);
1392 
1393     if (preprocess_frame_.samples_per_channel_ < 0) {
1394       WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, id_,
1395                    "Cannot add 10 ms audio, resampling failed");
1396       return -1;
1397     }
1398     preprocess_frame_.sample_rate_hz_ = send_codec_inst_.plfreq;
1399   }
1400 
1401   expected_codec_ts_ += preprocess_frame_.samples_per_channel_;
1402   expected_in_ts_ += in_frame.samples_per_channel_;
1403 
1404   return 0;
1405 }
1406 
1407 /////////////////////////////////////////
1408 //   (RED) Redundant Coding
1409 //
1410 
REDStatus() const1411 bool AudioCodingModuleImpl::REDStatus() const {
1412   CriticalSectionScoped lock(acm_crit_sect_);
1413 
1414   return red_enabled_;
1415 }
1416 
1417 // Configure RED status i.e on/off.
SetREDStatus(bool enable_red)1418 int AudioCodingModuleImpl::SetREDStatus(
1419 #ifdef WEBRTC_CODEC_RED
1420     bool enable_red) {
1421   CriticalSectionScoped lock(acm_crit_sect_);
1422 
1423   if (enable_red == true && codec_fec_enabled_ == true) {
1424     WEBRTC_TRACE(webrtc::kTraceWarning, webrtc::kTraceAudioCoding, id_,
1425                  "Codec internal FEC and RED cannot be co-enabled.");
1426     return -1;
1427   }
1428 
1429   if (red_enabled_ != enable_red) {
1430     // Reset the RED buffer.
1431     memset(red_buffer_, 0, MAX_PAYLOAD_SIZE_BYTE);
1432 
1433     // Reset fragmentation buffers.
1434     ResetFragmentation(kNumRedFragmentationVectors);
1435     // Set red_enabled_.
1436     red_enabled_ = enable_red;
1437   }
1438   is_first_red_ = true;  // Make sure we restart RED.
1439   return 0;
1440 #else
1441     bool /* enable_red */) {
1442   red_enabled_ = false;
1443   WEBRTC_TRACE(webrtc::kTraceWarning, webrtc::kTraceAudioCoding, id_,
1444                "  WEBRTC_CODEC_RED is undefined => red_enabled_ = %d",
1445                red_enabled_);
1446   return -1;
1447 #endif
1448 }
1449 
1450 /////////////////////////////////////////
1451 //   (FEC) Forward Error Correction (codec internal)
1452 //
1453 
1454 bool AudioCodingModuleImpl::CodecFEC() const {
1455   return codec_fec_enabled_;
1456 }
1457 
1458 int AudioCodingModuleImpl::SetCodecFEC(bool enable_codec_fec) {
1459   CriticalSectionScoped lock(acm_crit_sect_);
1460 
1461   if (enable_codec_fec == true && red_enabled_ == true) {
1462     WEBRTC_TRACE(webrtc::kTraceWarning, webrtc::kTraceAudioCoding, id_,
1463                  "Codec internal FEC and RED cannot be co-enabled.");
1464     return -1;
1465   }
1466 
1467   // Set codec FEC.
1468   if (HaveValidEncoder("SetCodecFEC") &&
1469       codecs_[current_send_codec_idx_]->SetFEC(enable_codec_fec) < 0) {
1470       WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, id_,
1471                    "Set codec internal FEC failed.");
1472     return -1;
1473   }
1474   codec_fec_enabled_ = enable_codec_fec;
1475   return 0;
1476 }
1477 
1478 int AudioCodingModuleImpl::SetPacketLossRate(int loss_rate) {
1479   if (HaveValidEncoder("SetPacketLossRate") &&
1480       codecs_[current_send_codec_idx_]->SetPacketLossRate(loss_rate) < 0) {
1481       WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, id_,
1482                    "Set packet loss rate failed.");
1483     return -1;
1484   }
1485   return 0;
1486 }
1487 
1488 /////////////////////////////////////////
1489 //   (VAD) Voice Activity Detection
1490 //
1491 int AudioCodingModuleImpl::SetVAD(bool enable_dtx,
1492                                   bool enable_vad,
1493                                   ACMVADMode mode) {
1494   CriticalSectionScoped lock(acm_crit_sect_);
1495   return SetVADSafe(enable_dtx, enable_vad, mode);
1496 }
1497 
1498 int AudioCodingModuleImpl::SetVADSafe(bool enable_dtx,
1499                                       bool enable_vad,
1500                                       ACMVADMode mode) {
1501   // Sanity check of the mode.
1502   if ((mode != VADNormal) && (mode != VADLowBitrate)
1503       && (mode != VADAggr) && (mode != VADVeryAggr)) {
1504     WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, id_,
1505                  "Invalid VAD Mode %d, no change is made to VAD/DTX status",
1506                  mode);
1507     return -1;
1508   }
1509 
1510   // Check that the send codec is mono. We don't support VAD/DTX for stereo
1511   // sending.
1512   if ((enable_dtx || enable_vad) && stereo_send_) {
1513     WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, id_,
1514                  "VAD/DTX not supported for stereo sending");
1515     dtx_enabled_ = false;
1516     vad_enabled_ = false;
1517     vad_mode_ = mode;
1518     return -1;
1519   }
1520 
1521   // We don't support VAD/DTX when dual-streaming is enabled, i.e.
1522   // secondary-encoder is registered.
1523   if ((enable_dtx || enable_vad) && secondary_encoder_.get() != NULL) {
1524     WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, id_,
1525                  "VAD/DTX not supported when dual-streaming is enabled.");
1526     dtx_enabled_ = false;
1527     vad_enabled_ = false;
1528     vad_mode_ = mode;
1529     return -1;
1530   }
1531 
1532   // Store VAD/DTX settings. Values can be changed in the call to "SetVAD"
1533   // below.
1534   dtx_enabled_ = enable_dtx;
1535   vad_enabled_ = enable_vad;
1536   vad_mode_ = mode;
1537 
1538   // If a send codec is registered, set VAD/DTX for the codec.
1539   if (HaveValidEncoder("SetVAD") && codecs_[current_send_codec_idx_]->SetVAD(
1540       &dtx_enabled_, &vad_enabled_,  &vad_mode_) < 0) {
1541       // SetVAD failed.
1542       WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, id_,
1543                    "SetVAD failed");
1544       vad_enabled_ = false;
1545       dtx_enabled_ = false;
1546       return -1;
1547   }
1548   return 0;
1549 }
1550 
1551 // Get VAD/DTX settings.
1552 int AudioCodingModuleImpl::VAD(bool* dtx_enabled, bool* vad_enabled,
1553                                ACMVADMode* mode) const {
1554   CriticalSectionScoped lock(acm_crit_sect_);
1555 
1556   *dtx_enabled = dtx_enabled_;
1557   *vad_enabled = vad_enabled_;
1558   *mode = vad_mode_;
1559 
1560   return 0;
1561 }
1562 
1563 /////////////////////////////////////////
1564 //   Receiver
1565 //
1566 
1567 int AudioCodingModuleImpl::InitializeReceiver() {
1568   CriticalSectionScoped lock(acm_crit_sect_);
1569   return InitializeReceiverSafe();
1570 }
1571 
1572 // Initialize receiver, resets codec database etc.
1573 int AudioCodingModuleImpl::InitializeReceiverSafe() {
1574   // If the receiver is already initialized then we want to destroy any
1575   // existing decoders. After a call to this function, we should have a clean
1576   // start-up.
1577   if (receiver_initialized_) {
1578     if (receiver_.RemoveAllCodecs() < 0)
1579       return -1;
1580   }
1581   receiver_.set_id(id_);
1582   receiver_.ResetInitialDelay();
1583   receiver_.SetMinimumDelay(0);
1584   receiver_.SetMaximumDelay(0);
1585   receiver_.FlushBuffers();
1586 
1587   // Register RED and CN.
1588   for (int i = 0; i < ACMCodecDB::kNumCodecs; i++) {
1589     if (IsCodecRED(i) || IsCodecCN(i)) {
1590       uint8_t pl_type = static_cast<uint8_t>(ACMCodecDB::database_[i].pltype);
1591       if (receiver_.AddCodec(i, pl_type, 1, NULL) < 0) {
1592         WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, id_,
1593                      "Cannot register master codec.");
1594         return -1;
1595       }
1596     }
1597   }
1598   receiver_initialized_ = true;
1599   return 0;
1600 }
1601 
1602 // TODO(turajs): If NetEq opens an API for reseting the state of decoders then
1603 // implement this method. Otherwise it should be removed. I might be that by
1604 // removing and registering a decoder we can achieve the effect of resetting.
1605 // Reset the decoder state.
1606 int AudioCodingModuleImpl::ResetDecoder() {
1607   return 0;
1608 }
1609 
1610 // Get current receive frequency.
1611 int AudioCodingModuleImpl::ReceiveFrequency() const {
1612   WEBRTC_TRACE(webrtc::kTraceStream, webrtc::kTraceAudioCoding, id_,
1613                "ReceiveFrequency()");
1614 
1615   CriticalSectionScoped lock(acm_crit_sect_);
1616 
1617   int codec_id = receiver_.last_audio_codec_id();
1618 
1619   int sample_rate_hz;
1620   if (codec_id < 0)
1621     sample_rate_hz = receiver_.current_sample_rate_hz();
1622   else
1623     sample_rate_hz = ACMCodecDB::database_[codec_id].plfreq;
1624 
1625   // TODO(tlegrand): Remove this option when we have full 48 kHz support.
1626   return (sample_rate_hz > 32000) ? 32000 : sample_rate_hz;
1627 }
1628 
1629 // Get current playout frequency.
1630 int AudioCodingModuleImpl::PlayoutFrequency() const {
1631   WEBRTC_TRACE(webrtc::kTraceStream, webrtc::kTraceAudioCoding, id_,
1632                "PlayoutFrequency()");
1633 
1634   CriticalSectionScoped lock(acm_crit_sect_);
1635 
1636   return receiver_.current_sample_rate_hz();
1637 }
1638 
1639 // Register possible receive codecs, can be called multiple times,
1640 // for codecs, CNG (NB, WB and SWB), DTMF, RED.
1641 int AudioCodingModuleImpl::RegisterReceiveCodec(const CodecInst& codec) {
1642   CriticalSectionScoped lock(acm_crit_sect_);
1643 
1644   if (codec.channels > 2 || codec.channels < 0) {
1645     WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, id_,
1646                  "Unsupported number of channels, %d.", codec.channels);
1647     return -1;
1648   }
1649 
1650   // TODO(turajs) do we need this for NetEq 4?
1651   if (!receiver_initialized_) {
1652     if (InitializeReceiverSafe() < 0) {
1653       WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, id_,
1654                    "Cannot initialize receiver, failed registering codec.");
1655       return -1;
1656     }
1657   }
1658 
1659   int mirror_id;
1660   int codec_id = ACMCodecDB::ReceiverCodecNumber(codec, &mirror_id);
1661 
1662   if (codec_id < 0 || codec_id >= ACMCodecDB::kNumCodecs) {
1663     WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, id_,
1664                  "Wrong codec params to be registered as receive codec");
1665     return -1;
1666   }
1667 
1668   // Check if the payload-type is valid.
1669   if (!ACMCodecDB::ValidPayloadType(codec.pltype)) {
1670     WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, id_,
1671                  "Invalid payload-type %d for %s.", codec.pltype,
1672                  codec.plname);
1673     return -1;
1674   }
1675 
1676   AudioDecoder* decoder = NULL;
1677   // Get |decoder| associated with |codec|. |decoder| can be NULL if |codec|
1678   // does not own its decoder.
1679   if (GetAudioDecoder(codec, codec_id, mirror_id, &decoder) < 0) {
1680     WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, id_,
1681                  "Wrong codec params to be registered as receive codec");
1682     return -1;
1683   }
1684   uint8_t payload_type = static_cast<uint8_t>(codec.pltype);
1685   return receiver_.AddCodec(codec_id, payload_type, codec.channels, decoder);
1686 }
1687 
1688 // Get current received codec.
1689 int AudioCodingModuleImpl::ReceiveCodec(CodecInst* current_codec) const {
1690   return receiver_.LastAudioCodec(current_codec);
1691 }
1692 
1693 // Incoming packet from network parsed and ready for decode.
1694 int AudioCodingModuleImpl::IncomingPacket(const uint8_t* incoming_payload,
1695                                           const int payload_length,
1696                                           const WebRtcRTPHeader& rtp_header) {
1697   if (payload_length < 0) {
1698     WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, id_,
1699                  "IncomingPacket() Error, payload-length cannot be negative");
1700     return -1;
1701   }
1702   int last_audio_pltype = receiver_.last_audio_payload_type();
1703   if (receiver_.InsertPacket(rtp_header, incoming_payload, payload_length) <
1704       0) {
1705     return -1;
1706   }
1707   if (receiver_.last_audio_payload_type() != last_audio_pltype) {
1708     int index = receiver_.last_audio_codec_id();
1709     assert(index >= 0);
1710     CriticalSectionScoped lock(acm_crit_sect_);
1711 
1712     // |codec_[index]| might not be even created, simply because it is not
1713     // yet registered as send codec. Even if it is registered, unless the
1714     // codec shares same instance for encoder and decoder, this call is
1715     // useless.
1716     if (codecs_[index] != NULL)
1717       codecs_[index]->UpdateDecoderSampFreq(index);
1718   }
1719   return 0;
1720 }
1721 
1722 // Minimum playout delay (Used for lip-sync).
1723 int AudioCodingModuleImpl::SetMinimumPlayoutDelay(int time_ms) {
1724   if ((time_ms < 0) || (time_ms > 10000)) {
1725     WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, id_,
1726                  "Delay must be in the range of 0-1000 milliseconds.");
1727     return -1;
1728   }
1729   return receiver_.SetMinimumDelay(time_ms);
1730 }
1731 
1732 int AudioCodingModuleImpl::SetMaximumPlayoutDelay(int time_ms) {
1733   if ((time_ms < 0) || (time_ms > 10000)) {
1734     WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, id_,
1735                  "Delay must be in the range of 0-1000 milliseconds.");
1736     return -1;
1737   }
1738   return receiver_.SetMaximumDelay(time_ms);
1739 }
1740 
1741 // Estimate the Bandwidth based on the incoming stream, needed for one way
1742 // audio where the RTCP send the BW estimate.
1743 // This is also done in the RTP module.
1744 int AudioCodingModuleImpl::DecoderEstimatedBandwidth() const {
1745   // We can estimate far-end to near-end bandwidth if the iSAC are sent. Check
1746   // if the last received packets were iSAC packet then retrieve the bandwidth.
1747   int last_audio_codec_id = receiver_.last_audio_codec_id();
1748   if (last_audio_codec_id >= 0 &&
1749       STR_CASE_CMP("ISAC", ACMCodecDB::database_[last_audio_codec_id].plname)) {
1750     CriticalSectionScoped lock(acm_crit_sect_);
1751     return codecs_[last_audio_codec_id]->GetEstimatedBandwidth();
1752   }
1753   return -1;
1754 }
1755 
1756 // Set playout mode for: voice, fax, streaming or off.
1757 int AudioCodingModuleImpl::SetPlayoutMode(AudioPlayoutMode mode) {
1758   receiver_.SetPlayoutMode(mode);
1759   return 0;  // TODO(turajs): return value is for backward compatibility.
1760 }
1761 
1762 // Get playout mode voice, fax, streaming or off.
1763 AudioPlayoutMode AudioCodingModuleImpl::PlayoutMode() const {
1764   return receiver_.PlayoutMode();
1765 }
1766 
1767 // Get 10 milliseconds of raw audio data to play out.
1768 // Automatic resample to the requested frequency.
1769 int AudioCodingModuleImpl::PlayoutData10Ms(int desired_freq_hz,
1770                                            AudioFrame* audio_frame) {
1771   // GetAudio always returns 10 ms, at the requested sample rate.
1772   if (receiver_.GetAudio(desired_freq_hz, audio_frame) != 0) {
1773     WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, id_,
1774                  "PlayoutData failed, RecOut Failed");
1775     return -1;
1776   }
1777 
1778   audio_frame->id_ = id_;
1779   return 0;
1780 }
1781 
1782 /////////////////////////////////////////
1783 //   Statistics
1784 //
1785 
1786 // TODO(turajs) change the return value to void. Also change the corresponding
1787 // NetEq function.
1788 int AudioCodingModuleImpl::NetworkStatistics(ACMNetworkStatistics* statistics) {
1789   receiver_.NetworkStatistics(statistics);
1790   return 0;
1791 }
1792 
1793 void AudioCodingModuleImpl::DestructEncoderInst(void* inst) {
1794   CriticalSectionScoped lock(acm_crit_sect_);
1795   WEBRTC_TRACE(webrtc::kTraceDebug, webrtc::kTraceAudioCoding, id_,
1796                "DestructEncoderInst()");
1797   if (!HaveValidEncoder("DestructEncoderInst"))
1798     return;
1799   codecs_[current_send_codec_idx_]->DestructEncoderInst(inst);
1800 }
1801 
1802 int AudioCodingModuleImpl::RegisterVADCallback(ACMVADCallback* vad_callback) {
1803   WEBRTC_TRACE(webrtc::kTraceDebug, webrtc::kTraceAudioCoding, id_,
1804                "RegisterVADCallback()");
1805   CriticalSectionScoped lock(callback_crit_sect_);
1806   vad_callback_ = vad_callback;
1807   return 0;
1808 }
1809 
1810 // TODO(tlegrand): Modify this function to work for stereo, and add tests.
1811 int AudioCodingModuleImpl::IncomingPayload(const uint8_t* incoming_payload,
1812                                            int payload_length,
1813                                            uint8_t payload_type,
1814                                            uint32_t timestamp) {
1815   if (payload_length < 0) {
1816     // Log error in trace file.
1817     WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, id_,
1818                  "IncomingPacket() Error, payload-length cannot be negative");
1819     return -1;
1820   }
1821 
1822   // We are not acquiring any lock when interacting with |aux_rtp_header_| no
1823   // other method uses this member variable.
1824   if (aux_rtp_header_ == NULL) {
1825     // This is the first time that we are using |dummy_rtp_header_|
1826     // so we have to create it.
1827     aux_rtp_header_ = new WebRtcRTPHeader;
1828     aux_rtp_header_->header.payloadType = payload_type;
1829     // Don't matter in this case.
1830     aux_rtp_header_->header.ssrc = 0;
1831     aux_rtp_header_->header.markerBit = false;
1832     // Start with random numbers.
1833     aux_rtp_header_->header.sequenceNumber = 0x1234;  // Arbitrary.
1834     aux_rtp_header_->type.Audio.channel = 1;
1835   }
1836 
1837   aux_rtp_header_->header.timestamp = timestamp;
1838   IncomingPacket(incoming_payload, payload_length, *aux_rtp_header_);
1839   // Get ready for the next payload.
1840   aux_rtp_header_->header.sequenceNumber++;
1841   return 0;
1842 }
1843 
1844 int AudioCodingModuleImpl::ReplaceInternalDTXWithWebRtc(bool use_webrtc_dtx) {
1845   CriticalSectionScoped lock(acm_crit_sect_);
1846 
1847   if (!HaveValidEncoder("ReplaceInternalDTXWithWebRtc")) {
1848     WEBRTC_TRACE(
1849         webrtc::kTraceError, webrtc::kTraceAudioCoding, id_,
1850         "Cannot replace codec internal DTX when no send codec is registered.");
1851     return -1;
1852   }
1853 
1854   int res = codecs_[current_send_codec_idx_]->ReplaceInternalDTX(
1855       use_webrtc_dtx);
1856   // Check if VAD is turned on, or if there is any error.
1857   if (res == 1) {
1858     vad_enabled_ = true;
1859   } else if (res < 0) {
1860     WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, id_,
1861                  "Failed to set ReplaceInternalDTXWithWebRtc(%d)",
1862                  use_webrtc_dtx);
1863     return res;
1864   }
1865 
1866   return 0;
1867 }
1868 
1869 int AudioCodingModuleImpl::IsInternalDTXReplacedWithWebRtc(
1870     bool* uses_webrtc_dtx) {
1871   CriticalSectionScoped lock(acm_crit_sect_);
1872 
1873   if (!HaveValidEncoder("IsInternalDTXReplacedWithWebRtc")) {
1874     return -1;
1875   }
1876   if (codecs_[current_send_codec_idx_]->IsInternalDTXReplaced(uses_webrtc_dtx)
1877       < 0) {
1878     return -1;
1879   }
1880   return 0;
1881 }
1882 
1883 int AudioCodingModuleImpl::SetISACMaxRate(int max_bit_per_sec) {
1884   CriticalSectionScoped lock(acm_crit_sect_);
1885 
1886   if (!HaveValidEncoder("SetISACMaxRate")) {
1887     return -1;
1888   }
1889 
1890   return codecs_[current_send_codec_idx_]->SetISACMaxRate(max_bit_per_sec);
1891 }
1892 
1893 int AudioCodingModuleImpl::SetISACMaxPayloadSize(int max_size_bytes) {
1894   CriticalSectionScoped lock(acm_crit_sect_);
1895 
1896   if (!HaveValidEncoder("SetISACMaxPayloadSize")) {
1897     return -1;
1898   }
1899 
1900   return codecs_[current_send_codec_idx_]->SetISACMaxPayloadSize(
1901       max_size_bytes);
1902 }
1903 
1904 int AudioCodingModuleImpl::ConfigISACBandwidthEstimator(
1905     int frame_size_ms,
1906     int rate_bit_per_sec,
1907     bool enforce_frame_size) {
1908   CriticalSectionScoped lock(acm_crit_sect_);
1909 
1910   if (!HaveValidEncoder("ConfigISACBandwidthEstimator")) {
1911     return -1;
1912   }
1913 
1914   return codecs_[current_send_codec_idx_]->ConfigISACBandwidthEstimator(
1915       frame_size_ms, rate_bit_per_sec, enforce_frame_size);
1916 }
1917 
1918 int AudioCodingModuleImpl::PlayoutTimestamp(uint32_t* timestamp) {
1919   return receiver_.GetPlayoutTimestamp(timestamp) ? 0 : -1;
1920 }
1921 
1922 bool AudioCodingModuleImpl::HaveValidEncoder(const char* caller_name) const {
1923   if ((!send_codec_registered_) || (current_send_codec_idx_ < 0) ||
1924       (current_send_codec_idx_ >= ACMCodecDB::kNumCodecs)) {
1925     WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, id_,
1926                  "%s failed: No send codec is registered.", caller_name);
1927     return false;
1928   }
1929   if ((current_send_codec_idx_ < 0) ||
1930       (current_send_codec_idx_ >= ACMCodecDB::kNumCodecs)) {
1931     WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, id_,
1932                  "%s failed: Send codec index out of range.", caller_name);
1933     return false;
1934   }
1935   if (codecs_[current_send_codec_idx_] == NULL) {
1936     WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, id_,
1937                  "%s failed: Send codec is NULL pointer.", caller_name);
1938     return false;
1939   }
1940   return true;
1941 }
1942 
1943 int AudioCodingModuleImpl::UnregisterReceiveCodec(uint8_t payload_type) {
1944   return receiver_.RemoveCodec(payload_type);
1945 }
1946 
1947 // TODO(turajs): correct the type of |length_bytes| when it is corrected in
1948 // GenericCodec.
1949 int AudioCodingModuleImpl::REDPayloadISAC(int isac_rate,
1950                                           int isac_bw_estimate,
1951                                           uint8_t* payload,
1952                                           int16_t* length_bytes) {
1953   if (!HaveValidEncoder("EncodeData")) {
1954     return -1;
1955   }
1956   int status;
1957   status = codecs_[current_send_codec_idx_]->REDPayloadISAC(isac_rate,
1958                                                             isac_bw_estimate,
1959                                                             payload,
1960                                                             length_bytes);
1961   return status;
1962 }
1963 
1964 void AudioCodingModuleImpl::ResetFragmentation(int vector_size) {
1965   for (int n = 0; n < kMaxNumFragmentationVectors; n++) {
1966     fragmentation_.fragmentationOffset[n] = n * MAX_PAYLOAD_SIZE_BYTE;
1967   }
1968   memset(fragmentation_.fragmentationLength, 0, kMaxNumFragmentationVectors *
1969          sizeof(fragmentation_.fragmentationLength[0]));
1970   memset(fragmentation_.fragmentationTimeDiff, 0, kMaxNumFragmentationVectors *
1971          sizeof(fragmentation_.fragmentationTimeDiff[0]));
1972   memset(fragmentation_.fragmentationPlType,
1973          0,
1974          kMaxNumFragmentationVectors *
1975              sizeof(fragmentation_.fragmentationPlType[0]));
1976   fragmentation_.fragmentationVectorSize = static_cast<uint16_t>(vector_size);
1977 }
1978 
1979 int AudioCodingModuleImpl::GetAudioDecoder(const CodecInst& codec, int codec_id,
1980                                            int mirror_id,
1981                                            AudioDecoder** decoder) {
1982   if (ACMCodecDB::OwnsDecoder(codec_id)) {
1983     // This codec has to own its own decoder. Therefore, it should create the
1984     // corresponding AudioDecoder class and insert it into NetEq. If the codec
1985     // does not exist create it.
1986     //
1987     // TODO(turajs): this part of the code is common with RegisterSendCodec(),
1988     //               make a method for it.
1989     if (codecs_[mirror_id] == NULL) {
1990       codecs_[mirror_id] = CreateCodec(codec);
1991       if (codecs_[mirror_id] == NULL) {
1992         WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, id_,
1993                      "Cannot Create the codec");
1994         return -1;
1995       }
1996       mirror_codec_idx_[mirror_id] = mirror_id;
1997     }
1998 
1999     if (mirror_id != codec_id) {
2000       codecs_[codec_id] = codecs_[mirror_id];
2001       mirror_codec_idx_[codec_id] = mirror_id;
2002     }
2003     *decoder = codecs_[codec_id]->Decoder(codec_id);
2004     if (!*decoder) {
2005       assert(false);
2006       return -1;
2007     }
2008   } else {
2009     *decoder = NULL;
2010   }
2011 
2012   return 0;
2013 }
2014 
2015 int AudioCodingModuleImpl::SetInitialPlayoutDelay(int delay_ms) {
2016   {
2017     CriticalSectionScoped lock(acm_crit_sect_);
2018     // Initialize receiver, if it is not initialized. Otherwise, initial delay
2019     // is reset upon initialization of the receiver.
2020     if (!receiver_initialized_)
2021       InitializeReceiverSafe();
2022   }
2023   return receiver_.SetInitialDelay(delay_ms);
2024 }
2025 
2026 int AudioCodingModuleImpl::EnableNack(size_t max_nack_list_size) {
2027   return receiver_.EnableNack(max_nack_list_size);
2028 }
2029 
2030 void AudioCodingModuleImpl::DisableNack() {
2031   receiver_.DisableNack();
2032 }
2033 
2034 std::vector<uint16_t> AudioCodingModuleImpl::GetNackList(
2035     int round_trip_time_ms) const {
2036   return receiver_.GetNackList(round_trip_time_ms);
2037 }
2038 
2039 int AudioCodingModuleImpl::LeastRequiredDelayMs() const {
2040   return receiver_.LeastRequiredDelayMs();
2041 }
2042 
2043 void AudioCodingModuleImpl::GetDecodingCallStatistics(
2044       AudioDecodingCallStats* call_stats) const {
2045   receiver_.GetDecodingCallStatistics(call_stats);
2046 }
2047 
2048 }  // namespace acm2
2049 
2050 }  // namespace webrtc
2051