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