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(¤t_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