Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / third_party / webrtc / modules / audio_coding / main / acm2 / acm_generic_codec.cc
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/acm_generic_codec.h"
12
13 #include <assert.h>
14 #include <string.h>
15
16 #include "webrtc/common_audio/vad/include/webrtc_vad.h"
17 #include "webrtc/modules/audio_coding/codecs/cng/include/webrtc_cng.h"
18 #include "webrtc/modules/audio_coding/main/acm2/acm_codec_database.h"
19 #include "webrtc/modules/audio_coding/main/acm2/acm_common_defs.h"
20 #include "webrtc/system_wrappers/interface/trace.h"
21
22 namespace webrtc {
23
24 namespace acm2 {
25
26 // Enum for CNG
27 enum {
28   kMaxPLCParamsCNG = WEBRTC_CNG_MAX_LPC_ORDER,
29   kNewCNGNumLPCParams = 8
30 };
31
32 // Interval for sending new CNG parameters (SID frames) is 100 msec.
33 enum {
34   kCngSidIntervalMsec = 100
35 };
36
37 // We set some of the variables to invalid values as a check point
38 // if a proper initialization has happened. Another approach is
39 // to initialize to a default codec that we are sure is always included.
40 ACMGenericCodec::ACMGenericCodec()
41     : in_audio_ix_write_(0),
42       in_audio_ix_read_(0),
43       in_timestamp_ix_write_(0),
44       in_audio_(NULL),
45       in_timestamp_(NULL),
46       frame_len_smpl_(-1),  // invalid value
47       num_channels_(1),
48       codec_id_(-1),  // invalid value
49       num_missed_samples_(0),
50       encoder_exist_(false),
51       encoder_initialized_(false),
52       registered_in_neteq_(false),
53       has_internal_dtx_(false),
54       ptr_vad_inst_(NULL),
55       vad_enabled_(false),
56       vad_mode_(VADNormal),
57       dtx_enabled_(false),
58       ptr_dtx_inst_(NULL),
59       num_lpc_params_(kNewCNGNumLPCParams),
60       sent_cn_previous_(false),
61       prev_frame_cng_(0),
62       has_internal_fec_(false),
63       codec_wrapper_lock_(*RWLockWrapper::CreateRWLock()),
64       last_timestamp_(0xD87F3F9F),
65       unique_id_(0) {
66   // Initialize VAD vector.
67   for (int i = 0; i < MAX_FRAME_SIZE_10MSEC; i++) {
68     vad_label_[i] = 0;
69   }
70   // Nullify memory for encoder and decoder, and set payload type to an
71   // invalid value.
72   memset(&encoder_params_, 0, sizeof(WebRtcACMCodecParams));
73   encoder_params_.codec_inst.pltype = -1;
74 }
75
76 ACMGenericCodec::~ACMGenericCodec() {
77   // Check all the members which are pointers, and if they are not NULL
78   // delete/free them.
79   if (ptr_vad_inst_ != NULL) {
80     WebRtcVad_Free(ptr_vad_inst_);
81     ptr_vad_inst_ = NULL;
82   }
83   if (in_audio_ != NULL) {
84     delete[] in_audio_;
85     in_audio_ = NULL;
86   }
87   if (in_timestamp_ != NULL) {
88     delete[] in_timestamp_;
89     in_timestamp_ = NULL;
90   }
91   if (ptr_dtx_inst_ != NULL) {
92     WebRtcCng_FreeEnc(ptr_dtx_inst_);
93     ptr_dtx_inst_ = NULL;
94   }
95   delete &codec_wrapper_lock_;
96 }
97
98 int32_t ACMGenericCodec::Add10MsData(const uint32_t timestamp,
99                                      const int16_t* data,
100                                      const uint16_t length_smpl,
101                                      const uint8_t audio_channel) {
102   WriteLockScoped wl(codec_wrapper_lock_);
103   return Add10MsDataSafe(timestamp, data, length_smpl, audio_channel);
104 }
105
106 int32_t ACMGenericCodec::Add10MsDataSafe(const uint32_t timestamp,
107                                          const int16_t* data,
108                                          const uint16_t length_smpl,
109                                          const uint8_t audio_channel) {
110   // The codec expects to get data in correct sampling rate. Get the sampling
111   // frequency of the codec.
112   uint16_t plfreq_hz;
113   if (EncoderSampFreq(&plfreq_hz) < 0) {
114     return -1;
115   }
116
117   // Sanity check to make sure the length of the input corresponds to 10 ms.
118   if ((plfreq_hz / 100) != length_smpl) {
119     // This is not 10 ms of audio, given the sampling frequency of the codec.
120     return -1;
121   }
122
123   if (last_timestamp_ == timestamp) {
124     // Same timestamp as the last time, overwrite.
125     if ((in_audio_ix_write_ >= length_smpl * audio_channel) &&
126         (in_timestamp_ix_write_ > 0)) {
127       in_audio_ix_write_ -= length_smpl * audio_channel;
128       assert(in_timestamp_ix_write_ >= 0);
129
130       in_timestamp_ix_write_--;
131       assert(in_audio_ix_write_ >= 0);
132       WEBRTC_TRACE(webrtc::kTraceDebug, webrtc::kTraceAudioCoding, unique_id_,
133                    "Adding 10ms with previous timestamp, overwriting the "
134                    "previous 10ms");
135     } else {
136       WEBRTC_TRACE(webrtc::kTraceDebug, webrtc::kTraceAudioCoding, unique_id_,
137                    "Adding 10ms with previous timestamp, this will sound bad");
138     }
139   }
140
141   last_timestamp_ = timestamp;
142
143   // If the data exceeds the buffer size, we throw away the oldest data and
144   // add the newly received 10 msec at the end.
145   if ((in_audio_ix_write_ + length_smpl * audio_channel) >
146       AUDIO_BUFFER_SIZE_W16) {
147     // Get the number of samples to be overwritten.
148     int16_t missed_samples = in_audio_ix_write_ + length_smpl * audio_channel -
149         AUDIO_BUFFER_SIZE_W16;
150
151     // Move the data (overwrite the old data).
152     memmove(in_audio_, in_audio_ + missed_samples,
153             (AUDIO_BUFFER_SIZE_W16 - length_smpl * audio_channel) *
154             sizeof(int16_t));
155
156     // Copy the new data.
157     memcpy(in_audio_ + (AUDIO_BUFFER_SIZE_W16 - length_smpl * audio_channel),
158            data, length_smpl * audio_channel * sizeof(int16_t));
159
160     // Get the number of 10 ms blocks which are overwritten.
161     int16_t missed_10ms_blocks =static_cast<int16_t>(
162         (missed_samples / audio_channel * 100) / plfreq_hz);
163
164     // Move the timestamps.
165     memmove(in_timestamp_, in_timestamp_ + missed_10ms_blocks,
166             (in_timestamp_ix_write_ - missed_10ms_blocks) * sizeof(uint32_t));
167     in_timestamp_ix_write_ -= missed_10ms_blocks;
168     assert(in_timestamp_ix_write_ >= 0);
169
170     in_timestamp_[in_timestamp_ix_write_] = timestamp;
171     in_timestamp_ix_write_++;
172     assert(in_timestamp_ix_write_ < TIMESTAMP_BUFFER_SIZE_W32);
173
174     // Buffer is full.
175     in_audio_ix_write_ = AUDIO_BUFFER_SIZE_W16;
176     IncreaseNoMissedSamples(missed_samples);
177     return -missed_samples;
178   }
179
180   // Store the input data in our data buffer.
181   memcpy(in_audio_ + in_audio_ix_write_, data,
182          length_smpl * audio_channel * sizeof(int16_t));
183   in_audio_ix_write_ += length_smpl * audio_channel;
184   assert(in_timestamp_ix_write_ < TIMESTAMP_BUFFER_SIZE_W32);
185
186   in_timestamp_[in_timestamp_ix_write_] = timestamp;
187   in_timestamp_ix_write_++;
188   assert(in_timestamp_ix_write_ < TIMESTAMP_BUFFER_SIZE_W32);
189   return 0;
190 }
191
192 bool ACMGenericCodec::HasFrameToEncode() const {
193   ReadLockScoped lockCodec(codec_wrapper_lock_);
194   if (in_audio_ix_write_ < frame_len_smpl_ * num_channels_)
195     return false;
196   return true;
197 }
198
199 int16_t ACMGenericCodec::Encode(uint8_t* bitstream,
200                                 int16_t* bitstream_len_byte,
201                                 uint32_t* timestamp,
202                                 WebRtcACMEncodingType* encoding_type) {
203   if (!HasFrameToEncode()) {
204     // There is not enough audio
205     *timestamp = 0;
206     *bitstream_len_byte = 0;
207     // Doesn't really matter what this parameter set to
208     *encoding_type = kNoEncoding;
209     return 0;
210   }
211   WriteLockScoped lockCodec(codec_wrapper_lock_);
212
213   // Not all codecs accept the whole frame to be pushed into encoder at once.
214   // Some codecs needs to be feed with a specific number of samples different
215   // from the frame size. If this is the case, |myBasicCodingBlockSmpl| will
216   // report a number different from 0, and we will loop over calls to encoder
217   // further down, until we have encode a complete frame.
218   const int16_t my_basic_coding_block_smpl =
219       ACMCodecDB::BasicCodingBlock(codec_id_);
220   if (my_basic_coding_block_smpl < 0 || !encoder_initialized_ ||
221       !encoder_exist_) {
222     // This should not happen, but in case it does, report no encoding done.
223     *timestamp = 0;
224     *bitstream_len_byte = 0;
225     *encoding_type = kNoEncoding;
226     WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, unique_id_,
227                  "EncodeSafe: error, basic coding sample block is negative");
228     return -1;
229   }
230   // This makes the internal encoder read from the beginning of the buffer.
231   in_audio_ix_read_ = 0;
232   *timestamp = in_timestamp_[0];
233
234   // Process the audio through VAD. The function will set |_vad_labels|.
235   // If VAD is disabled all entries in |_vad_labels| are set to ONE (active).
236   int16_t status = 0;
237   int16_t dtx_processed_samples = 0;
238   status = ProcessFrameVADDTX(bitstream, bitstream_len_byte,
239                               &dtx_processed_samples);
240   if (status < 0) {
241     *timestamp = 0;
242     *bitstream_len_byte = 0;
243     *encoding_type = kNoEncoding;
244   } else {
245     if (dtx_processed_samples > 0) {
246       // Dtx have processed some samples, and even if a bit-stream is generated
247       // we should not do any encoding (normally there won't be enough data).
248
249       // Setting the following makes sure that the move of audio data and
250       // timestamps done correctly.
251       in_audio_ix_read_ = dtx_processed_samples;
252       // This will let the owner of ACMGenericCodec to know that the
253       // generated bit-stream is DTX to use correct payload type.
254       uint16_t samp_freq_hz;
255       EncoderSampFreq(&samp_freq_hz);
256       if (samp_freq_hz == 8000) {
257         *encoding_type = kPassiveDTXNB;
258       } else if (samp_freq_hz == 16000) {
259         *encoding_type = kPassiveDTXWB;
260       } else if (samp_freq_hz == 32000) {
261         *encoding_type = kPassiveDTXSWB;
262       } else if (samp_freq_hz == 48000) {
263         *encoding_type = kPassiveDTXFB;
264       } else {
265         status = -1;
266         WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, unique_id_,
267                      "EncodeSafe: Wrong sampling frequency for DTX.");
268       }
269
270       // Transport empty frame if we have an empty bitstream.
271       if ((*bitstream_len_byte == 0) &&
272           (sent_cn_previous_ ||
273           ((in_audio_ix_write_ - in_audio_ix_read_) <= 0))) {
274         // Makes sure we transmit an empty frame.
275         *bitstream_len_byte = 1;
276         *encoding_type = kNoEncoding;
277       }
278       sent_cn_previous_ = true;
279     } else {
280       // We should encode the audio frame. Either VAD and/or DTX is off, or the
281       // audio was considered "active".
282
283       sent_cn_previous_ = false;
284       if (my_basic_coding_block_smpl == 0) {
285         // This codec can handle all allowed frame sizes as basic coding block.
286         status = InternalEncode(bitstream, bitstream_len_byte);
287         if (status < 0) {
288           // TODO(tlegrand): Maybe reseting the encoder to be fresh for the next
289           // frame.
290           WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding,
291                        unique_id_, "EncodeSafe: error in internal_encode");
292           *bitstream_len_byte = 0;
293           *encoding_type = kNoEncoding;
294         }
295       } else {
296         // A basic-coding-block for this codec is defined so we loop over the
297         // audio with the steps of the basic-coding-block.
298         int16_t tmp_bitstream_len_byte;
299
300         // Reset the variables which will be incremented in the loop.
301         *bitstream_len_byte = 0;
302         bool done = false;
303         while (!done) {
304           status = InternalEncode(&bitstream[*bitstream_len_byte],
305                                   &tmp_bitstream_len_byte);
306           *bitstream_len_byte += tmp_bitstream_len_byte;
307
308           // Guard Against errors and too large payloads.
309           if ((status < 0) || (*bitstream_len_byte > MAX_PAYLOAD_SIZE_BYTE)) {
310             // Error has happened, and even if we are in the middle of a full
311             // frame we have to exit. Before exiting, whatever bits are in the
312             // buffer are probably corrupted, so we ignore them.
313             *bitstream_len_byte = 0;
314             *encoding_type = kNoEncoding;
315             // We might have come here because of the second condition.
316             status = -1;
317             WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding,
318                          unique_id_, "EncodeSafe: error in InternalEncode");
319             // break from the loop
320             break;
321           }
322           done = in_audio_ix_read_ >= frame_len_smpl_ * num_channels_;
323         }
324       }
325       if (status >= 0) {
326         *encoding_type = (vad_label_[0] == 1) ? kActiveNormalEncoded :
327             kPassiveNormalEncoded;
328         // Transport empty frame if we have an empty bitstream.
329         if ((*bitstream_len_byte == 0) &&
330             ((in_audio_ix_write_ - in_audio_ix_read_) <= 0)) {
331           // Makes sure we transmit an empty frame.
332           *bitstream_len_byte = 1;
333           *encoding_type = kNoEncoding;
334         }
335       }
336     }
337   }
338
339   // Move the timestamp buffer according to the number of 10 ms blocks
340   // which are read.
341   uint16_t samp_freq_hz;
342   EncoderSampFreq(&samp_freq_hz);
343   int16_t num_10ms_blocks = static_cast<int16_t>(
344       (in_audio_ix_read_ / num_channels_ * 100) / samp_freq_hz);
345   if (in_timestamp_ix_write_ > num_10ms_blocks) {
346     memmove(in_timestamp_, in_timestamp_ + num_10ms_blocks,
347             (in_timestamp_ix_write_ - num_10ms_blocks) * sizeof(int32_t));
348   }
349   in_timestamp_ix_write_ -= num_10ms_blocks;
350   assert(in_timestamp_ix_write_ >= 0);
351
352   // Remove encoded audio and move next audio to be encoded to the beginning
353   // of the buffer. Accordingly, adjust the read and write indices.
354   if (in_audio_ix_read_ < in_audio_ix_write_) {
355     memmove(in_audio_, &in_audio_[in_audio_ix_read_],
356             (in_audio_ix_write_ - in_audio_ix_read_) * sizeof(int16_t));
357   }
358   in_audio_ix_write_ -= in_audio_ix_read_;
359   in_audio_ix_read_ = 0;
360   return (status < 0) ? (-1) : (*bitstream_len_byte);
361 }
362
363 bool ACMGenericCodec::EncoderInitialized() {
364   ReadLockScoped rl(codec_wrapper_lock_);
365   return encoder_initialized_;
366 }
367
368 int16_t ACMGenericCodec::EncoderParams(WebRtcACMCodecParams* enc_params) {
369   ReadLockScoped rl(codec_wrapper_lock_);
370   return EncoderParamsSafe(enc_params);
371 }
372
373 int16_t ACMGenericCodec::EncoderParamsSafe(WebRtcACMCodecParams* enc_params) {
374   // Codec parameters are valid only if the encoder is initialized.
375   if (encoder_initialized_) {
376     int32_t current_rate;
377     memcpy(enc_params, &encoder_params_, sizeof(WebRtcACMCodecParams));
378     current_rate = enc_params->codec_inst.rate;
379     CurrentRate(&current_rate);
380     enc_params->codec_inst.rate = current_rate;
381     return 0;
382   } else {
383     enc_params->codec_inst.plname[0] = '\0';
384     enc_params->codec_inst.pltype = -1;
385     enc_params->codec_inst.pacsize = 0;
386     enc_params->codec_inst.rate = 0;
387     WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, unique_id_,
388                  "EncoderParamsSafe: error, encoder not initialized");
389     return -1;
390   }
391 }
392
393 int16_t ACMGenericCodec::ResetEncoder() {
394   WriteLockScoped lockCodec(codec_wrapper_lock_);
395   return ResetEncoderSafe();
396 }
397
398 int16_t ACMGenericCodec::ResetEncoderSafe() {
399   if (!encoder_exist_ || !encoder_initialized_) {
400     // We don't reset if encoder doesn't exists or isn't initialized yet.
401     return 0;
402   }
403
404   in_audio_ix_write_ = 0;
405   in_audio_ix_read_ = 0;
406   in_timestamp_ix_write_ = 0;
407   num_missed_samples_ = 0;
408   memset(in_audio_, 0, AUDIO_BUFFER_SIZE_W16 * sizeof(int16_t));
409   memset(in_timestamp_, 0, TIMESTAMP_BUFFER_SIZE_W32 * sizeof(int32_t));
410
411   // Store DTX/VAD parameters.
412   bool enable_vad = vad_enabled_;
413   bool enable_dtx = dtx_enabled_;
414   ACMVADMode mode = vad_mode_;
415
416   // Reset the encoder.
417   if (InternalResetEncoder() < 0) {
418     WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, unique_id_,
419                  "ResetEncoderSafe: error in reset encoder");
420     return -1;
421   }
422
423   // Disable DTX & VAD to delete the states and have a fresh start.
424   DisableDTX();
425   DisableVAD();
426
427   // Set DTX/VAD.
428   int status = SetVADSafe(&enable_dtx, &enable_vad, &mode);
429   dtx_enabled_ = enable_dtx;
430   vad_enabled_ = enable_vad;
431   vad_mode_ = mode;
432   return status;
433 }
434
435 int16_t ACMGenericCodec::InternalResetEncoder() {
436   // Call the codecs internal encoder initialization/reset function.
437   return InternalInitEncoder(&encoder_params_);
438 }
439
440 int16_t ACMGenericCodec::InitEncoder(WebRtcACMCodecParams* codec_params,
441                                      bool force_initialization) {
442   WriteLockScoped lockCodec(codec_wrapper_lock_);
443   return InitEncoderSafe(codec_params, force_initialization);
444 }
445
446 int16_t ACMGenericCodec::InitEncoderSafe(WebRtcACMCodecParams* codec_params,
447                                          bool force_initialization) {
448   // Check if we got a valid set of parameters.
449   int mirrorID;
450   int codec_number = ACMCodecDB::CodecNumber(codec_params->codec_inst,
451                                              &mirrorID);
452   assert(codec_number >= 0);
453
454   // Check if the parameters are for this codec.
455   if ((codec_id_ >= 0) && (codec_id_ != codec_number) &&
456       (codec_id_ != mirrorID)) {
457     // The current codec is not the same as the one given by codec_params.
458     WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, unique_id_,
459                  "InitEncoderSafe: current codec is not the same as the one "
460                  "given by codec_params");
461     return -1;
462   }
463
464   if (encoder_initialized_ && !force_initialization) {
465     // The encoder is already initialized, and we don't want to force
466     // initialization.
467     return 0;
468   }
469   int16_t status;
470   if (!encoder_exist_) {
471     // New encoder, start with creating.
472     encoder_initialized_ = false;
473     status = CreateEncoder();
474     if (status < 0) {
475       WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, unique_id_,
476                    "InitEncoderSafe: cannot create encoder");
477       return -1;
478     } else {
479       encoder_exist_ = true;
480     }
481   }
482   frame_len_smpl_ = codec_params->codec_inst.pacsize;
483   num_channels_ = codec_params->codec_inst.channels;
484   status = InternalInitEncoder(codec_params);
485   if (status < 0) {
486     WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, unique_id_,
487                  "InitEncoderSafe: error in init encoder");
488     encoder_initialized_ = false;
489     return -1;
490   } else {
491     // TODO(turajs): Move these allocations to the constructor issue 2445.
492     // Store encoder parameters.
493     memcpy(&encoder_params_, codec_params, sizeof(WebRtcACMCodecParams));
494     encoder_initialized_ = true;
495     if (in_audio_ == NULL) {
496       in_audio_ = new int16_t[AUDIO_BUFFER_SIZE_W16];
497     }
498     if (in_timestamp_ == NULL) {
499       in_timestamp_ = new uint32_t[TIMESTAMP_BUFFER_SIZE_W32];
500     }
501   }
502
503   // Fresh start of audio buffer.
504   memset(in_audio_, 0, sizeof(*in_audio_) * AUDIO_BUFFER_SIZE_W16);
505   memset(in_timestamp_, 0, sizeof(*in_timestamp_) * TIMESTAMP_BUFFER_SIZE_W32);
506   in_audio_ix_write_ = 0;
507   in_audio_ix_read_ = 0;
508   in_timestamp_ix_write_ = 0;
509
510   return SetVADSafe(&codec_params->enable_dtx, &codec_params->enable_vad,
511                     &codec_params->vad_mode);
512 }
513
514 void ACMGenericCodec::ResetNoMissedSamples() {
515   WriteLockScoped cs(codec_wrapper_lock_);
516   num_missed_samples_ = 0;
517 }
518
519 void ACMGenericCodec::IncreaseNoMissedSamples(const int16_t num_samples) {
520   num_missed_samples_ += num_samples;
521 }
522
523 // Get the number of missed samples, this can be public.
524 uint32_t ACMGenericCodec::NoMissedSamples() const {
525   ReadLockScoped cs(codec_wrapper_lock_);
526   return num_missed_samples_;
527 }
528
529 void ACMGenericCodec::DestructEncoder() {
530   WriteLockScoped wl(codec_wrapper_lock_);
531
532   // Disable VAD and delete the instance.
533   if (ptr_vad_inst_ != NULL) {
534     WebRtcVad_Free(ptr_vad_inst_);
535     ptr_vad_inst_ = NULL;
536   }
537   vad_enabled_ = false;
538   vad_mode_ = VADNormal;
539
540   // Disable DTX and delete the instance.
541   dtx_enabled_ = false;
542   if (ptr_dtx_inst_ != NULL) {
543     WebRtcCng_FreeEnc(ptr_dtx_inst_);
544     ptr_dtx_inst_ = NULL;
545   }
546   num_lpc_params_ = kNewCNGNumLPCParams;
547
548   DestructEncoderSafe();
549 }
550
551 int16_t ACMGenericCodec::SetBitRate(const int32_t bitrate_bps) {
552   WriteLockScoped wl(codec_wrapper_lock_);
553   return SetBitRateSafe(bitrate_bps);
554 }
555
556 int16_t ACMGenericCodec::SetBitRateSafe(const int32_t bitrate_bps) {
557   // If the codec can change the bit-rate this function is overloaded.
558   // Otherwise the only acceptable value is the one that is in the database.
559   CodecInst codec_params;
560   if (ACMCodecDB::Codec(codec_id_, &codec_params) < 0) {
561     WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, unique_id_,
562                  "SetBitRateSafe: error in ACMCodecDB::Codec");
563     return -1;
564   }
565   if (codec_params.rate != bitrate_bps) {
566     WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, unique_id_,
567                  "SetBitRateSafe: rate value is not acceptable");
568     return -1;
569   } else {
570     return 0;
571   }
572 }
573
574 // iSAC specific functions:
575 int32_t ACMGenericCodec::GetEstimatedBandwidth() {
576   WriteLockScoped wl(codec_wrapper_lock_);
577   return GetEstimatedBandwidthSafe();
578 }
579
580 int32_t ACMGenericCodec::GetEstimatedBandwidthSafe() {
581   // All codecs but iSAC will return -1.
582   return -1;
583 }
584
585 int32_t ACMGenericCodec::SetEstimatedBandwidth(int32_t estimated_bandwidth) {
586   WriteLockScoped wl(codec_wrapper_lock_);
587   return SetEstimatedBandwidthSafe(estimated_bandwidth);
588 }
589
590 int32_t ACMGenericCodec::SetEstimatedBandwidthSafe(
591     int32_t /*estimated_bandwidth*/) {
592   // All codecs but iSAC will return -1.
593   return -1;
594 }
595 // End of iSAC specific functions.
596
597 int32_t ACMGenericCodec::GetRedPayload(uint8_t* red_payload,
598                                        int16_t* payload_bytes) {
599   WriteLockScoped wl(codec_wrapper_lock_);
600   return GetRedPayloadSafe(red_payload, payload_bytes);
601 }
602
603 int32_t ACMGenericCodec::GetRedPayloadSafe(uint8_t* /* red_payload */,
604                                            int16_t* /* payload_bytes */) {
605   return -1;  // Do nothing by default.
606 }
607
608 int16_t ACMGenericCodec::CreateEncoder() {
609   int16_t status = 0;
610   if (!encoder_exist_) {
611     status = InternalCreateEncoder();
612     // We just created the codec and obviously it is not initialized.
613     encoder_initialized_ = false;
614   }
615   if (status < 0) {
616     WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, unique_id_,
617                  "CreateEncoder: error in internal create encoder");
618     encoder_exist_ = false;
619   } else {
620     encoder_exist_ = true;
621   }
622   return status;
623 }
624
625 void ACMGenericCodec::DestructEncoderInst(void* ptr_inst) {
626   if (ptr_inst != NULL) {
627     WriteLockScoped lockCodec(codec_wrapper_lock_);
628     InternalDestructEncoderInst(ptr_inst);
629   }
630 }
631
632 uint32_t ACMGenericCodec::EarliestTimestamp() const {
633   ReadLockScoped cs(codec_wrapper_lock_);
634   return in_timestamp_[0];
635 }
636
637 int16_t ACMGenericCodec::SetVAD(bool* enable_dtx,
638                                 bool* enable_vad,
639                                 ACMVADMode* mode) {
640   WriteLockScoped cs(codec_wrapper_lock_);
641   return SetVADSafe(enable_dtx, enable_vad, mode);
642 }
643
644 int16_t ACMGenericCodec::SetVADSafe(bool* enable_dtx,
645                                     bool* enable_vad,
646                                     ACMVADMode* mode) {
647   if (!STR_CASE_CMP(encoder_params_.codec_inst.plname, "OPUS") ||
648       encoder_params_.codec_inst.channels == 2 ) {
649     // VAD/DTX is not supported for Opus (even if sending mono), or other
650     // stereo codecs.
651     DisableDTX();
652     DisableVAD();
653     *enable_dtx = false;
654     *enable_vad = false;
655     return 0;
656   }
657
658   if (*enable_dtx) {
659     // Make G729 AnnexB a special case.
660     if (!STR_CASE_CMP(encoder_params_.codec_inst.plname, "G729")
661         && !has_internal_dtx_) {
662       if (ACMGenericCodec::EnableDTX() < 0) {
663         WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, unique_id_,
664                      "SetVADSafe: error in enable DTX");
665         *enable_dtx = false;
666         *enable_vad = vad_enabled_;
667         return -1;
668       }
669     } else {
670       if (EnableDTX() < 0) {
671         WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, unique_id_,
672                      "SetVADSafe: error in enable DTX");
673         *enable_dtx = false;
674         *enable_vad = vad_enabled_;
675         return -1;
676       }
677     }
678
679     // If codec does not have internal DTX (normal case) enabling DTX requires
680     // an active VAD. '*enable_dtx == true' overwrites VAD status.
681     // If codec has internal DTX, practically we don't need WebRtc VAD, however,
682     // we let the user to turn it on if they need call-backs on silence.
683     if (!has_internal_dtx_) {
684       // DTX is enabled, and VAD will be activated.
685       *enable_vad = true;
686     }
687   } else {
688     // Make G729 AnnexB a special case.
689     if (!STR_CASE_CMP(encoder_params_.codec_inst.plname, "G729")
690         && !has_internal_dtx_) {
691       ACMGenericCodec::DisableDTX();
692       *enable_dtx = false;
693     } else {
694       DisableDTX();
695       *enable_dtx = false;
696     }
697   }
698
699   int16_t status = (*enable_vad) ? EnableVAD(*mode) : DisableVAD();
700   if (status < 0) {
701     // Failed to set VAD, disable DTX.
702     WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, unique_id_,
703     "SetVADSafe: error in enable VAD");
704     DisableDTX();
705     *enable_dtx = false;
706     *enable_vad = false;
707   }
708   return status;
709 }
710
711 int16_t ACMGenericCodec::EnableDTX() {
712   if (has_internal_dtx_) {
713     // We should not be here if we have internal DTX this function should be
714     // overloaded by the derived class in this case.
715     return -1;
716   }
717   if (!dtx_enabled_) {
718     if (WebRtcCng_CreateEnc(&ptr_dtx_inst_) < 0) {
719       ptr_dtx_inst_ = NULL;
720       return -1;
721     }
722     uint16_t freq_hz;
723     EncoderSampFreq(&freq_hz);
724     if (WebRtcCng_InitEnc(ptr_dtx_inst_, freq_hz, kCngSidIntervalMsec,
725                           num_lpc_params_) < 0) {
726       // Couldn't initialize, has to return -1, and free the memory.
727       WebRtcCng_FreeEnc(ptr_dtx_inst_);
728       ptr_dtx_inst_ = NULL;
729       return -1;
730     }
731     dtx_enabled_ = true;
732   }
733   return 0;
734 }
735
736 int16_t ACMGenericCodec::DisableDTX() {
737   if (has_internal_dtx_) {
738     // We should not be here if we have internal DTX this function should be
739     // overloaded by the derived class in this case.
740     return -1;
741   }
742   if (ptr_dtx_inst_ != NULL) {
743     WebRtcCng_FreeEnc(ptr_dtx_inst_);
744     ptr_dtx_inst_ = NULL;
745   }
746   dtx_enabled_ = false;
747   return 0;
748 }
749
750 int16_t ACMGenericCodec::EnableVAD(ACMVADMode mode) {
751   if ((mode < VADNormal) || (mode > VADVeryAggr)) {
752     WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, unique_id_,
753                  "EnableVAD: error in VAD mode range");
754     return -1;
755   }
756
757   if (!vad_enabled_) {
758     if (WebRtcVad_Create(&ptr_vad_inst_) < 0) {
759       ptr_vad_inst_ = NULL;
760       WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, unique_id_,
761                    "EnableVAD: error in create VAD");
762       return -1;
763     }
764     if (WebRtcVad_Init(ptr_vad_inst_) < 0) {
765       WebRtcVad_Free(ptr_vad_inst_);
766       ptr_vad_inst_ = NULL;
767       WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, unique_id_,
768                    "EnableVAD: error in init VAD");
769       return -1;
770     }
771   }
772
773   // Set the VAD mode to the given value.
774   if (WebRtcVad_set_mode(ptr_vad_inst_, mode) < 0) {
775     // We failed to set the mode and we have to return -1. If we already have a
776     // working VAD (vad_enabled_ == true) then we leave it to work. Otherwise,
777     // the following will be executed.
778     if (!vad_enabled_) {
779       // We just created the instance but cannot set the mode we have to free
780       // the memory.
781       WebRtcVad_Free(ptr_vad_inst_);
782       ptr_vad_inst_ = NULL;
783     }
784     WEBRTC_TRACE(webrtc::kTraceDebug, webrtc::kTraceAudioCoding, unique_id_,
785                  "EnableVAD: failed to set the VAD mode");
786     return -1;
787   }
788   vad_mode_ = mode;
789   vad_enabled_ = true;
790   return 0;
791 }
792
793 int16_t ACMGenericCodec::DisableVAD() {
794   if (ptr_vad_inst_ != NULL) {
795     WebRtcVad_Free(ptr_vad_inst_);
796     ptr_vad_inst_ = NULL;
797   }
798   vad_enabled_ = false;
799   return 0;
800 }
801
802 int32_t ACMGenericCodec::ReplaceInternalDTX(const bool replace_internal_dtx) {
803   WriteLockScoped cs(codec_wrapper_lock_);
804   return ReplaceInternalDTXSafe(replace_internal_dtx);
805 }
806
807 int32_t ACMGenericCodec::ReplaceInternalDTXSafe(
808     const bool /* replace_internal_dtx */) {
809   return -1;
810 }
811
812 int32_t ACMGenericCodec::IsInternalDTXReplaced(bool* internal_dtx_replaced) {
813   WriteLockScoped cs(codec_wrapper_lock_);
814   return IsInternalDTXReplacedSafe(internal_dtx_replaced);
815 }
816
817 int32_t ACMGenericCodec::IsInternalDTXReplacedSafe(
818     bool* internal_dtx_replaced) {
819   *internal_dtx_replaced = false;
820   return 0;
821 }
822
823 int16_t ACMGenericCodec::ProcessFrameVADDTX(uint8_t* bitstream,
824                                             int16_t* bitstream_len_byte,
825                                             int16_t* samples_processed) {
826   if (!vad_enabled_) {
827     // VAD not enabled, set all |vad_lable_[]| to 1 (speech detected).
828     for (int n = 0; n < MAX_FRAME_SIZE_10MSEC; n++) {
829       vad_label_[n] = 1;
830     }
831     *samples_processed = 0;
832     return 0;
833   }
834
835   uint16_t freq_hz;
836   EncoderSampFreq(&freq_hz);
837
838   // Calculate number of samples in 10 ms blocks, and number ms in one frame.
839   int16_t samples_in_10ms = static_cast<int16_t>(freq_hz / 100);
840   int32_t frame_len_ms = static_cast<int32_t>(frame_len_smpl_) * 1000 / freq_hz;
841   int16_t status = -1;
842
843   // Vector for storing maximum 30 ms of mono audio at 48 kHz.
844   int16_t audio[1440];
845
846   // Calculate number of VAD-blocks to process, and number of samples in each
847   // block.
848   int num_samples_to_process[2];
849   if (frame_len_ms == 40) {
850     // 20 ms in each VAD block.
851     num_samples_to_process[0] = num_samples_to_process[1] = 2 * samples_in_10ms;
852   } else {
853     // For 10-30 ms framesizes, second VAD block will be size zero ms,
854     // for 50 and 60 ms first VAD block will be 30 ms.
855     num_samples_to_process[0] =
856         (frame_len_ms > 30) ? 3 * samples_in_10ms : frame_len_smpl_;
857     num_samples_to_process[1] = frame_len_smpl_ - num_samples_to_process[0];
858   }
859
860   int offset = 0;
861   int loops = (num_samples_to_process[1] > 0) ? 2 : 1;
862   for (int i = 0; i < loops; i++) {
863     // TODO(turajs): Do we need to care about VAD together with stereo?
864     // If stereo, calculate mean of the two channels.
865     if (num_channels_ == 2) {
866       for (int j = 0; j < num_samples_to_process[i]; j++) {
867         audio[j] = (in_audio_[(offset + j) * 2] +
868             in_audio_[(offset + j) * 2 + 1]) / 2;
869       }
870       offset = num_samples_to_process[0];
871     } else {
872       // Mono, copy data from in_audio_ to continue work on.
873       memcpy(audio, in_audio_, sizeof(int16_t) * num_samples_to_process[i]);
874     }
875
876     // Call VAD.
877     status = static_cast<int16_t>(WebRtcVad_Process(ptr_vad_inst_,
878                                                     static_cast<int>(freq_hz),
879                                                     audio,
880                                                     num_samples_to_process[i]));
881     vad_label_[i] = status;
882
883     if (status < 0) {
884       // This will force that the data be removed from the buffer.
885       *samples_processed += num_samples_to_process[i];
886       return -1;
887     }
888
889     // If VAD decision non-active, update DTX. NOTE! We only do this if the
890     // first part of a frame gets the VAD decision "inactive". Otherwise DTX
891     // might say it is time to transmit SID frame, but we will encode the whole
892     // frame, because the first part is active.
893     *samples_processed = 0;
894     if ((status == 0) && (i == 0) && dtx_enabled_ && !has_internal_dtx_) {
895       int16_t bitstream_len;
896       int num_10ms_frames = num_samples_to_process[i] / samples_in_10ms;
897       *bitstream_len_byte = 0;
898       for (int n = 0; n < num_10ms_frames; n++) {
899         // This block is (passive) && (vad enabled). If first CNG after
900         // speech, force SID by setting last parameter to "1".
901         status = WebRtcCng_Encode(ptr_dtx_inst_, &audio[n * samples_in_10ms],
902                                   samples_in_10ms, bitstream, &bitstream_len,
903                                   !prev_frame_cng_);
904         if (status < 0) {
905           return -1;
906         }
907
908         // Update previous frame was CNG.
909         prev_frame_cng_ = 1;
910
911         *samples_processed += samples_in_10ms * num_channels_;
912
913         // |bitstream_len_byte| will only be > 0 once per 100 ms.
914         *bitstream_len_byte += bitstream_len;
915       }
916
917       // Check if all samples got processed by the DTX.
918       if (*samples_processed != num_samples_to_process[i] * num_channels_) {
919         // Set to zero since something went wrong. Shouldn't happen.
920         *samples_processed = 0;
921       }
922     } else {
923       // Update previous frame was not CNG.
924       prev_frame_cng_ = 0;
925     }
926
927     if (*samples_processed > 0) {
928       // The block contains inactive speech, and is processed by DTX.
929       // Discontinue running VAD.
930       break;
931     }
932   }
933
934   return status;
935 }
936
937 int16_t ACMGenericCodec::SamplesLeftToEncode() {
938   ReadLockScoped rl(codec_wrapper_lock_);
939   return (frame_len_smpl_ <= in_audio_ix_write_) ? 0 :
940       (frame_len_smpl_ - in_audio_ix_write_);
941 }
942
943 void ACMGenericCodec::SetUniqueID(const uint32_t id) {
944   unique_id_ = id;
945 }
946
947 // This function is replaced by codec specific functions for some codecs.
948 int16_t ACMGenericCodec::EncoderSampFreq(uint16_t* samp_freq_hz) {
949   int32_t f;
950   f = ACMCodecDB::CodecFreq(codec_id_);
951   if (f < 0) {
952     WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, unique_id_,
953                  "EncoderSampFreq: codec frequency is negative");
954     return -1;
955   } else {
956     *samp_freq_hz = static_cast<uint16_t>(f);
957     return 0;
958   }
959 }
960
961 int32_t ACMGenericCodec::ConfigISACBandwidthEstimator(
962     const uint8_t /* init_frame_size_msec */,
963     const uint16_t /* init_rate_bit_per_sec */,
964     const bool /* enforce_frame_size  */) {
965   WEBRTC_TRACE(webrtc::kTraceWarning, webrtc::kTraceAudioCoding, unique_id_,
966                "The send-codec is not iSAC, failed to config iSAC bandwidth "
967                "estimator.");
968   return -1;
969 }
970
971 int32_t ACMGenericCodec::SetISACMaxRate(
972     const uint32_t /* max_rate_bit_per_sec */) {
973   WEBRTC_TRACE(webrtc::kTraceWarning, webrtc::kTraceAudioCoding, unique_id_,
974                "The send-codec is not iSAC, failed to set iSAC max rate.");
975   return -1;
976 }
977
978 int32_t ACMGenericCodec::SetISACMaxPayloadSize(
979     const uint16_t /* max_payload_len_bytes */) {
980   WEBRTC_TRACE(webrtc::kTraceWarning, webrtc::kTraceAudioCoding, unique_id_,
981                "The send-codec is not iSAC, failed to set iSAC max "
982                "payload-size.");
983   return -1;
984 }
985
986 int16_t ACMGenericCodec::UpdateEncoderSampFreq(
987     uint16_t /* samp_freq_hz */) {
988   WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, unique_id_,
989                "It is asked for a change in smapling frequency while the "
990                "current  send-codec supports only one sampling rate.");
991   return -1;
992 }
993
994 int16_t ACMGenericCodec::REDPayloadISAC(const int32_t /* isac_rate */,
995                                         const int16_t /* isac_bw_estimate */,
996                                         uint8_t* /* payload */,
997                                         int16_t* /* payload_len_bytes */) {
998   WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, unique_id_,
999                "Error: REDPayloadISAC is an iSAC specific function");
1000   return -1;
1001 }
1002
1003 int ACMGenericCodec::SetOpusMaxBandwidth(int /* max_bandwidth */) {
1004   WEBRTC_TRACE(webrtc::kTraceWarning, webrtc::kTraceAudioCoding, unique_id_,
1005                "The send-codec is not Opus, failed to set maximum bandwidth.");
1006   return -1;
1007 }
1008
1009 }  // namespace acm2
1010
1011 }  // namespace webrtc