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.
ACMGenericCodec()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
~ACMGenericCodec()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
Add10MsData(const uint32_t timestamp,const int16_t * data,const uint16_t length_smpl,const uint8_t audio_channel)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
Add10MsDataSafe(const uint32_t timestamp,const int16_t * data,const uint16_t length_smpl,const uint8_t audio_channel)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
HasFrameToEncode() const193 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
Encode(uint8_t * bitstream,int16_t * bitstream_len_byte,uint32_t * timestamp,WebRtcACMEncodingType * encoding_type)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
EncoderInitialized()365 bool ACMGenericCodec::EncoderInitialized() {
366 ReadLockScoped rl(codec_wrapper_lock_);
367 return encoder_initialized_;
368 }
369
EncoderParams(WebRtcACMCodecParams * enc_params)370 int16_t ACMGenericCodec::EncoderParams(WebRtcACMCodecParams* enc_params) {
371 ReadLockScoped rl(codec_wrapper_lock_);
372 return EncoderParamsSafe(enc_params);
373 }
374
EncoderParamsSafe(WebRtcACMCodecParams * enc_params)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
ResetEncoder()395 int16_t ACMGenericCodec::ResetEncoder() {
396 WriteLockScoped lockCodec(codec_wrapper_lock_);
397 ReadLockScoped lockNetEq(*neteq_decode_lock_);
398 return ResetEncoderSafe();
399 }
400
ResetEncoderSafe()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
InternalResetEncoder()438 int16_t ACMGenericCodec::InternalResetEncoder() {
439 // Call the codecs internal encoder initialization/reset function.
440 return InternalInitEncoder(&encoder_params_);
441 }
442
InitEncoder(WebRtcACMCodecParams * codec_params,bool force_initialization)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
InitEncoderSafe(WebRtcACMCodecParams * codec_params,bool force_initialization)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
ResetNoMissedSamples()518 void ACMGenericCodec::ResetNoMissedSamples() {
519 WriteLockScoped cs(codec_wrapper_lock_);
520 num_missed_samples_ = 0;
521 }
522
IncreaseNoMissedSamples(const int16_t num_samples)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.
NoMissedSamples() const528 uint32_t ACMGenericCodec::NoMissedSamples() const {
529 ReadLockScoped cs(codec_wrapper_lock_);
530 return num_missed_samples_;
531 }
532
DestructEncoder()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
SetBitRate(const int32_t bitrate_bps)555 int16_t ACMGenericCodec::SetBitRate(const int32_t bitrate_bps) {
556 WriteLockScoped wl(codec_wrapper_lock_);
557 return SetBitRateSafe(bitrate_bps);
558 }
559
SetBitRateSafe(const int32_t bitrate_bps)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:
GetEstimatedBandwidth()579 int32_t ACMGenericCodec::GetEstimatedBandwidth() {
580 WriteLockScoped wl(codec_wrapper_lock_);
581 return GetEstimatedBandwidthSafe();
582 }
583
GetEstimatedBandwidthSafe()584 int32_t ACMGenericCodec::GetEstimatedBandwidthSafe() {
585 // All codecs but iSAC will return -1.
586 return -1;
587 }
588
SetEstimatedBandwidth(int32_t estimated_bandwidth)589 int32_t ACMGenericCodec::SetEstimatedBandwidth(int32_t estimated_bandwidth) {
590 WriteLockScoped wl(codec_wrapper_lock_);
591 return SetEstimatedBandwidthSafe(estimated_bandwidth);
592 }
593
SetEstimatedBandwidthSafe(int32_t)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
GetRedPayload(uint8_t * red_payload,int16_t * payload_bytes)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
GetRedPayloadSafe(uint8_t *,int16_t *)607 int32_t ACMGenericCodec::GetRedPayloadSafe(uint8_t* /* red_payload */,
608 int16_t* /* payload_bytes */) {
609 return -1; // Do nothing by default.
610 }
611
CreateEncoder()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
DestructEncoderInst(void * ptr_inst)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
EarliestTimestamp() const637 uint32_t ACMGenericCodec::EarliestTimestamp() const {
638 ReadLockScoped cs(codec_wrapper_lock_);
639 return in_timestamp_[0];
640 }
641
SetVAD(bool * enable_dtx,bool * enable_vad,ACMVADMode * mode)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
SetVADSafe(bool * enable_dtx,bool * enable_vad,ACMVADMode * mode)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
EnableDTX()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
DisableDTX()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
EnableVAD(ACMVADMode mode)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
DisableVAD()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
ReplaceInternalDTX(const bool replace_internal_dtx)807 int32_t ACMGenericCodec::ReplaceInternalDTX(const bool replace_internal_dtx) {
808 WriteLockScoped cs(codec_wrapper_lock_);
809 return ReplaceInternalDTXSafe(replace_internal_dtx);
810 }
811
ReplaceInternalDTXSafe(const bool)812 int32_t ACMGenericCodec::ReplaceInternalDTXSafe(
813 const bool /* replace_internal_dtx */) {
814 return -1;
815 }
816
IsInternalDTXReplaced(bool * internal_dtx_replaced)817 int32_t ACMGenericCodec::IsInternalDTXReplaced(bool* internal_dtx_replaced) {
818 WriteLockScoped cs(codec_wrapper_lock_);
819 return IsInternalDTXReplacedSafe(internal_dtx_replaced);
820 }
821
IsInternalDTXReplacedSafe(bool * internal_dtx_replaced)822 int32_t ACMGenericCodec::IsInternalDTXReplacedSafe(
823 bool* internal_dtx_replaced) {
824 *internal_dtx_replaced = false;
825 return 0;
826 }
827
ProcessFrameVADDTX(uint8_t * bitstream,int16_t * bitstream_len_byte,int16_t * samples_processed)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
SamplesLeftToEncode()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
SetUniqueID(const uint32_t id)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.
EncoderSampFreq(uint16_t * samp_freq_hz)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
ConfigISACBandwidthEstimator(const uint8_t,const uint16_t,const bool)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
SetISACMaxRate(const uint32_t)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
SetISACMaxPayloadSize(const uint16_t)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
UpdateEncoderSampFreq(uint16_t)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
REDPayloadISAC(const int32_t,const int16_t,uint8_t *,int16_t *)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