OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license | 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 | 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 | 6 * tree. An additional intellectual property rights grant can be found |
7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
9 */ | 9 */ |
10 | 10 |
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
126 AudioCodingModuleImpl::~AudioCodingModuleImpl() = default; | 126 AudioCodingModuleImpl::~AudioCodingModuleImpl() = default; |
127 | 127 |
128 int32_t AudioCodingModuleImpl::Encode(const InputData& input_data) { | 128 int32_t AudioCodingModuleImpl::Encode(const InputData& input_data) { |
129 AudioEncoder::EncodedInfo encoded_info; | 129 AudioEncoder::EncodedInfo encoded_info; |
130 uint8_t previous_pltype; | 130 uint8_t previous_pltype; |
131 | 131 |
132 // Check if there is an encoder before. | 132 // Check if there is an encoder before. |
133 if (!HaveValidEncoder("Process")) | 133 if (!HaveValidEncoder("Process")) |
134 return -1; | 134 return -1; |
135 | 135 |
136 AudioEncoder* audio_encoder = codec_manager_.CurrentEncoder(); | 136 AudioEncoder* audio_encoder = rent_a_codec_.GetEncoderStack(); |
137 // Scale the timestamp to the codec's RTP timestamp rate. | 137 // Scale the timestamp to the codec's RTP timestamp rate. |
138 uint32_t rtp_timestamp = | 138 uint32_t rtp_timestamp = |
139 first_frame_ ? input_data.input_timestamp | 139 first_frame_ ? input_data.input_timestamp |
140 : last_rtp_timestamp_ + | 140 : last_rtp_timestamp_ + |
141 rtc::CheckedDivExact( | 141 rtc::CheckedDivExact( |
142 input_data.input_timestamp - last_timestamp_, | 142 input_data.input_timestamp - last_timestamp_, |
143 static_cast<uint32_t>(rtc::CheckedDivExact( | 143 static_cast<uint32_t>(rtc::CheckedDivExact( |
144 audio_encoder->SampleRateHz(), | 144 audio_encoder->SampleRateHz(), |
145 audio_encoder->RtpTimestampRateHz()))); | 145 audio_encoder->RtpTimestampRateHz()))); |
146 last_timestamp_ = input_data.input_timestamp; | 146 last_timestamp_ = input_data.input_timestamp; |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
191 return static_cast<int32_t>(encode_buffer_.size()); | 191 return static_cast<int32_t>(encode_buffer_.size()); |
192 } | 192 } |
193 | 193 |
194 ///////////////////////////////////////// | 194 ///////////////////////////////////////// |
195 // Sender | 195 // Sender |
196 // | 196 // |
197 | 197 |
198 // Can be called multiple times for Codec, CNG, RED. | 198 // Can be called multiple times for Codec, CNG, RED. |
199 int AudioCodingModuleImpl::RegisterSendCodec(const CodecInst& send_codec) { | 199 int AudioCodingModuleImpl::RegisterSendCodec(const CodecInst& send_codec) { |
200 CriticalSectionScoped lock(acm_crit_sect_.get()); | 200 CriticalSectionScoped lock(acm_crit_sect_.get()); |
201 return codec_manager_.RegisterEncoder(send_codec); | 201 if (!codec_manager_.RegisterEncoder(send_codec)) { |
202 return -1; | |
hlundin-webrtc
2015/12/15 13:42:03
I'd like to see some logging, so that it is possib
kwiberg-webrtc
2015/12/16 10:57:48
codec_manager_.RegisterEncoder already logs in all
hlundin-webrtc
2015/12/16 11:58:35
Acknowledged.
| |
203 } | |
204 auto* sp = codec_manager_.GetStackParams(); | |
205 if (codec_manager_.GetCodecInst() && !sp->speech_encoder) { | |
hlundin-webrtc
2015/12/15 13:42:03
Please, add a comment to explain this condition. I
kwiberg-webrtc
2015/12/16 10:57:48
Done.
| |
206 AudioEncoder* enc = | |
207 rent_a_codec_.RentEncoder(*codec_manager_.GetCodecInst()); | |
208 if (!enc) | |
209 return -1; | |
hlundin-webrtc
2015/12/15 13:42:03
Log here too, please.
kwiberg-webrtc
2015/12/16 10:57:48
Same answer: rent_a_codec_.RentEncoder already log
| |
210 sp->speech_encoder = enc; | |
211 } | |
212 if (sp->speech_encoder) | |
213 rent_a_codec_.RentEncoderStack(sp); | |
214 return 0; | |
202 } | 215 } |
203 | 216 |
204 void AudioCodingModuleImpl::RegisterExternalSendCodec( | 217 void AudioCodingModuleImpl::RegisterExternalSendCodec( |
205 AudioEncoder* external_speech_encoder) { | 218 AudioEncoder* external_speech_encoder) { |
206 CriticalSectionScoped lock(acm_crit_sect_.get()); | 219 CriticalSectionScoped lock(acm_crit_sect_.get()); |
207 codec_manager_.RegisterEncoder(external_speech_encoder); | 220 auto* sp = codec_manager_.GetStackParams(); |
221 sp->speech_encoder = external_speech_encoder; | |
222 rent_a_codec_.RentEncoderStack(sp); | |
208 } | 223 } |
209 | 224 |
210 // Get current send codec. | 225 // Get current send codec. |
211 rtc::Optional<CodecInst> AudioCodingModuleImpl::SendCodec() const { | 226 rtc::Optional<CodecInst> AudioCodingModuleImpl::SendCodec() const { |
212 CriticalSectionScoped lock(acm_crit_sect_.get()); | 227 CriticalSectionScoped lock(acm_crit_sect_.get()); |
213 return codec_manager_.GetCodecInst(); | 228 auto* ci = codec_manager_.GetCodecInst(); |
229 if (ci) { | |
230 return rtc::Optional<CodecInst>(*ci); | |
231 } | |
232 auto* enc = codec_manager_.GetStackParams()->speech_encoder; | |
233 if (enc) { | |
234 return rtc::Optional<CodecInst>(CodecManager::ForgeCodecInst(enc)); | |
235 } | |
236 return rtc::Optional<CodecInst>(); | |
214 } | 237 } |
215 | 238 |
216 // Get current send frequency. | 239 // Get current send frequency. |
217 int AudioCodingModuleImpl::SendFrequency() const { | 240 int AudioCodingModuleImpl::SendFrequency() const { |
218 WEBRTC_TRACE(webrtc::kTraceStream, webrtc::kTraceAudioCoding, id_, | 241 WEBRTC_TRACE(webrtc::kTraceStream, webrtc::kTraceAudioCoding, id_, |
219 "SendFrequency()"); | 242 "SendFrequency()"); |
220 CriticalSectionScoped lock(acm_crit_sect_.get()); | 243 CriticalSectionScoped lock(acm_crit_sect_.get()); |
221 | 244 |
222 if (!codec_manager_.CurrentEncoder()) { | 245 auto* enc = rent_a_codec_.GetEncoderStack(); |
hlundin-webrtc
2015/12/15 13:42:03
const auto*
(Because GetEncoderStack() violates th
kwiberg-webrtc
2015/12/16 10:57:48
Done.
| |
246 if (!enc) { | |
223 WEBRTC_TRACE(webrtc::kTraceStream, webrtc::kTraceAudioCoding, id_, | 247 WEBRTC_TRACE(webrtc::kTraceStream, webrtc::kTraceAudioCoding, id_, |
224 "SendFrequency Failed, no codec is registered"); | 248 "SendFrequency Failed, no codec is registered"); |
225 return -1; | 249 return -1; |
226 } | 250 } |
227 | 251 |
228 return codec_manager_.CurrentEncoder()->SampleRateHz(); | 252 return enc->SampleRateHz(); |
229 } | 253 } |
230 | 254 |
231 void AudioCodingModuleImpl::SetBitRate(int bitrate_bps) { | 255 void AudioCodingModuleImpl::SetBitRate(int bitrate_bps) { |
232 CriticalSectionScoped lock(acm_crit_sect_.get()); | 256 CriticalSectionScoped lock(acm_crit_sect_.get()); |
233 if (codec_manager_.CurrentEncoder()) { | 257 auto* enc = rent_a_codec_.GetEncoderStack(); |
234 codec_manager_.CurrentEncoder()->SetTargetBitrate(bitrate_bps); | 258 if (enc) { |
259 enc->SetTargetBitrate(bitrate_bps); | |
235 } | 260 } |
236 } | 261 } |
237 | 262 |
238 // Register a transport callback which will be called to deliver | 263 // Register a transport callback which will be called to deliver |
239 // the encoded buffers. | 264 // the encoded buffers. |
240 int AudioCodingModuleImpl::RegisterTransportCallback( | 265 int AudioCodingModuleImpl::RegisterTransportCallback( |
241 AudioPacketizationCallback* transport) { | 266 AudioPacketizationCallback* transport) { |
242 CriticalSectionScoped lock(callback_crit_sect_.get()); | 267 CriticalSectionScoped lock(callback_crit_sect_.get()); |
243 packetization_callback_ = transport; | 268 packetization_callback_ = transport; |
244 return 0; | 269 return 0; |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
291 const AudioFrame* ptr_frame; | 316 const AudioFrame* ptr_frame; |
292 // Perform a resampling, also down-mix if it is required and can be | 317 // Perform a resampling, also down-mix if it is required and can be |
293 // performed before resampling (a down mix prior to resampling will take | 318 // performed before resampling (a down mix prior to resampling will take |
294 // place if both primary and secondary encoders are mono and input is in | 319 // place if both primary and secondary encoders are mono and input is in |
295 // stereo). | 320 // stereo). |
296 if (PreprocessToAddData(audio_frame, &ptr_frame) < 0) { | 321 if (PreprocessToAddData(audio_frame, &ptr_frame) < 0) { |
297 return -1; | 322 return -1; |
298 } | 323 } |
299 | 324 |
300 // Check whether we need an up-mix or down-mix? | 325 // Check whether we need an up-mix or down-mix? |
301 bool remix = ptr_frame->num_channels_ != | 326 const int current_num_channels = |
302 codec_manager_.CurrentEncoder()->NumChannels(); | 327 rent_a_codec_.GetEncoderStack()->NumChannels(); |
328 bool remix = ptr_frame->num_channels_ != current_num_channels; | |
303 | 329 |
304 if (remix) { | 330 if (remix) { |
305 if (ptr_frame->num_channels_ == 1) { | 331 if (ptr_frame->num_channels_ == 1) { |
306 if (UpMix(*ptr_frame, WEBRTC_10MS_PCM_AUDIO, input_data->buffer) < 0) | 332 if (UpMix(*ptr_frame, WEBRTC_10MS_PCM_AUDIO, input_data->buffer) < 0) |
307 return -1; | 333 return -1; |
308 } else { | 334 } else { |
309 if (DownMix(*ptr_frame, WEBRTC_10MS_PCM_AUDIO, input_data->buffer) < 0) | 335 if (DownMix(*ptr_frame, WEBRTC_10MS_PCM_AUDIO, input_data->buffer) < 0) |
310 return -1; | 336 return -1; |
311 } | 337 } |
312 } | 338 } |
313 | 339 |
314 // When adding data to encoders this pointer is pointing to an audio buffer | 340 // When adding data to encoders this pointer is pointing to an audio buffer |
315 // with correct number of channels. | 341 // with correct number of channels. |
316 const int16_t* ptr_audio = ptr_frame->data_; | 342 const int16_t* ptr_audio = ptr_frame->data_; |
317 | 343 |
318 // For pushing data to primary, point the |ptr_audio| to correct buffer. | 344 // For pushing data to primary, point the |ptr_audio| to correct buffer. |
319 if (codec_manager_.CurrentEncoder()->NumChannels() != | 345 if (current_num_channels != ptr_frame->num_channels_) |
hlundin-webrtc
2015/12/15 13:42:02
Did ptr_frame->num_channels_ change since remix wa
kwiberg-webrtc
2015/12/16 10:57:48
No, it really shouldn't. Done.
| |
320 ptr_frame->num_channels_) | |
321 ptr_audio = input_data->buffer; | 346 ptr_audio = input_data->buffer; |
322 | 347 |
323 input_data->input_timestamp = ptr_frame->timestamp_; | 348 input_data->input_timestamp = ptr_frame->timestamp_; |
324 input_data->audio = ptr_audio; | 349 input_data->audio = ptr_audio; |
325 input_data->length_per_channel = ptr_frame->samples_per_channel_; | 350 input_data->length_per_channel = ptr_frame->samples_per_channel_; |
326 input_data->audio_channel = codec_manager_.CurrentEncoder()->NumChannels(); | 351 input_data->audio_channel = current_num_channels; |
327 | 352 |
328 return 0; | 353 return 0; |
329 } | 354 } |
330 | 355 |
331 // Perform a resampling and down-mix if required. We down-mix only if | 356 // Perform a resampling and down-mix if required. We down-mix only if |
332 // encoder is mono and input is stereo. In case of dual-streaming, both | 357 // encoder is mono and input is stereo. In case of dual-streaming, both |
333 // encoders has to be mono for down-mix to take place. | 358 // encoders has to be mono for down-mix to take place. |
334 // |*ptr_out| will point to the pre-processed audio-frame. If no pre-processing | 359 // |*ptr_out| will point to the pre-processed audio-frame. If no pre-processing |
335 // is required, |*ptr_out| points to |in_frame|. | 360 // is required, |*ptr_out| points to |in_frame|. |
336 int AudioCodingModuleImpl::PreprocessToAddData(const AudioFrame& in_frame, | 361 int AudioCodingModuleImpl::PreprocessToAddData(const AudioFrame& in_frame, |
337 const AudioFrame** ptr_out) { | 362 const AudioFrame** ptr_out) { |
338 bool resample = (in_frame.sample_rate_hz_ != | 363 const auto* enc = rent_a_codec_.GetEncoderStack(); |
339 codec_manager_.CurrentEncoder()->SampleRateHz()); | 364 bool resample = in_frame.sample_rate_hz_ != enc->SampleRateHz(); |
hlundin-webrtc
2015/12/15 13:42:02
const
kwiberg-webrtc
2015/12/16 10:57:48
Done.
| |
340 | 365 |
341 // This variable is true if primary codec and secondary codec (if exists) | 366 // This variable is true if primary codec and secondary codec (if exists) |
342 // are both mono and input is stereo. | 367 // are both mono and input is stereo. |
343 bool down_mix = (in_frame.num_channels_ == 2) && | 368 bool down_mix = in_frame.num_channels_ == 2 && enc->NumChannels() == 1; |
hlundin-webrtc
2015/12/15 13:42:03
const
Add a TODO to generalize the condition; it s
kwiberg-webrtc
2015/12/16 10:57:48
Done.
| |
344 (codec_manager_.CurrentEncoder()->NumChannels() == 1); | |
345 | 369 |
346 if (!first_10ms_data_) { | 370 if (!first_10ms_data_) { |
347 expected_in_ts_ = in_frame.timestamp_; | 371 expected_in_ts_ = in_frame.timestamp_; |
348 expected_codec_ts_ = in_frame.timestamp_; | 372 expected_codec_ts_ = in_frame.timestamp_; |
349 first_10ms_data_ = true; | 373 first_10ms_data_ = true; |
350 } else if (in_frame.timestamp_ != expected_in_ts_) { | 374 } else if (in_frame.timestamp_ != expected_in_ts_) { |
351 // TODO(turajs): Do we need a warning here. | 375 // TODO(turajs): Do we need a warning here. |
352 expected_codec_ts_ += | 376 expected_codec_ts_ += |
353 (in_frame.timestamp_ - expected_in_ts_) * | 377 (in_frame.timestamp_ - expected_in_ts_) * |
354 static_cast<uint32_t>( | 378 static_cast<uint32_t>(static_cast<double>(enc->SampleRateHz()) / |
355 (static_cast<double>( | 379 static_cast<double>(in_frame.sample_rate_hz_)); |
356 codec_manager_.CurrentEncoder()->SampleRateHz()) / | |
357 static_cast<double>(in_frame.sample_rate_hz_))); | |
358 expected_in_ts_ = in_frame.timestamp_; | 380 expected_in_ts_ = in_frame.timestamp_; |
359 } | 381 } |
360 | 382 |
361 | 383 |
362 if (!down_mix && !resample) { | 384 if (!down_mix && !resample) { |
363 // No pre-processing is required. | 385 // No pre-processing is required. |
364 expected_in_ts_ += static_cast<uint32_t>(in_frame.samples_per_channel_); | 386 expected_in_ts_ += static_cast<uint32_t>(in_frame.samples_per_channel_); |
365 expected_codec_ts_ += static_cast<uint32_t>(in_frame.samples_per_channel_); | 387 expected_codec_ts_ += static_cast<uint32_t>(in_frame.samples_per_channel_); |
366 *ptr_out = &in_frame; | 388 *ptr_out = &in_frame; |
367 return 0; | 389 return 0; |
(...skipping 18 matching lines...) Expand all Loading... | |
386 | 408 |
387 preprocess_frame_.timestamp_ = expected_codec_ts_; | 409 preprocess_frame_.timestamp_ = expected_codec_ts_; |
388 preprocess_frame_.samples_per_channel_ = in_frame.samples_per_channel_; | 410 preprocess_frame_.samples_per_channel_ = in_frame.samples_per_channel_; |
389 preprocess_frame_.sample_rate_hz_ = in_frame.sample_rate_hz_; | 411 preprocess_frame_.sample_rate_hz_ = in_frame.sample_rate_hz_; |
390 // If it is required, we have to do a resampling. | 412 // If it is required, we have to do a resampling. |
391 if (resample) { | 413 if (resample) { |
392 // The result of the resampler is written to output frame. | 414 // The result of the resampler is written to output frame. |
393 dest_ptr_audio = preprocess_frame_.data_; | 415 dest_ptr_audio = preprocess_frame_.data_; |
394 | 416 |
395 int samples_per_channel = resampler_.Resample10Msec( | 417 int samples_per_channel = resampler_.Resample10Msec( |
396 src_ptr_audio, in_frame.sample_rate_hz_, | 418 src_ptr_audio, in_frame.sample_rate_hz_, enc->SampleRateHz(), |
397 codec_manager_.CurrentEncoder()->SampleRateHz(), | |
398 preprocess_frame_.num_channels_, AudioFrame::kMaxDataSizeSamples, | 419 preprocess_frame_.num_channels_, AudioFrame::kMaxDataSizeSamples, |
399 dest_ptr_audio); | 420 dest_ptr_audio); |
400 | 421 |
401 if (samples_per_channel < 0) { | 422 if (samples_per_channel < 0) { |
402 WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, id_, | 423 WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, id_, |
403 "Cannot add 10 ms audio, resampling failed"); | 424 "Cannot add 10 ms audio, resampling failed"); |
404 return -1; | 425 return -1; |
405 } | 426 } |
406 preprocess_frame_.samples_per_channel_ = | 427 preprocess_frame_.samples_per_channel_ = |
407 static_cast<size_t>(samples_per_channel); | 428 static_cast<size_t>(samples_per_channel); |
408 preprocess_frame_.sample_rate_hz_ = | 429 preprocess_frame_.sample_rate_hz_ = enc->SampleRateHz(); |
409 codec_manager_.CurrentEncoder()->SampleRateHz(); | |
410 } | 430 } |
411 | 431 |
412 expected_codec_ts_ += | 432 expected_codec_ts_ += |
413 static_cast<uint32_t>(preprocess_frame_.samples_per_channel_); | 433 static_cast<uint32_t>(preprocess_frame_.samples_per_channel_); |
414 expected_in_ts_ += static_cast<uint32_t>(in_frame.samples_per_channel_); | 434 expected_in_ts_ += static_cast<uint32_t>(in_frame.samples_per_channel_); |
415 | 435 |
416 return 0; | 436 return 0; |
417 } | 437 } |
418 | 438 |
419 ///////////////////////////////////////// | 439 ///////////////////////////////////////// |
420 // (RED) Redundant Coding | 440 // (RED) Redundant Coding |
421 // | 441 // |
422 | 442 |
423 bool AudioCodingModuleImpl::REDStatus() const { | 443 bool AudioCodingModuleImpl::REDStatus() const { |
424 CriticalSectionScoped lock(acm_crit_sect_.get()); | 444 CriticalSectionScoped lock(acm_crit_sect_.get()); |
425 return codec_manager_.red_enabled(); | 445 return codec_manager_.GetStackParams()->use_red; |
426 } | 446 } |
427 | 447 |
428 // Configure RED status i.e on/off. | 448 // Configure RED status i.e on/off. |
429 int AudioCodingModuleImpl::SetREDStatus( | 449 int AudioCodingModuleImpl::SetREDStatus(bool enable_red) { |
hlundin-webrtc
2015/12/15 13:42:03
Does this compile when WEBRTC_CODEC_RED is not def
kwiberg-webrtc
2015/12/16 10:57:48
It really should. It's not an error for a function
| |
430 #ifdef WEBRTC_CODEC_RED | 450 #ifdef WEBRTC_CODEC_RED |
431 bool enable_red) { | |
432 CriticalSectionScoped lock(acm_crit_sect_.get()); | 451 CriticalSectionScoped lock(acm_crit_sect_.get()); |
433 return codec_manager_.SetCopyRed(enable_red) ? 0 : -1; | 452 if (!codec_manager_.SetCopyRed(enable_red)) { |
453 return -1; | |
454 } | |
455 auto* sp = codec_manager_.GetStackParams(); | |
456 if (sp->speech_encoder) | |
457 rent_a_codec_.RentEncoderStack(sp); | |
458 return 0; | |
434 #else | 459 #else |
435 bool /* enable_red */) { | |
436 WEBRTC_TRACE(webrtc::kTraceWarning, webrtc::kTraceAudioCoding, id_, | 460 WEBRTC_TRACE(webrtc::kTraceWarning, webrtc::kTraceAudioCoding, id_, |
437 " WEBRTC_CODEC_RED is undefined"); | 461 " WEBRTC_CODEC_RED is undefined"); |
438 return -1; | 462 return -1; |
439 #endif | 463 #endif |
440 } | 464 } |
441 | 465 |
442 ///////////////////////////////////////// | 466 ///////////////////////////////////////// |
443 // (FEC) Forward Error Correction (codec internal) | 467 // (FEC) Forward Error Correction (codec internal) |
444 // | 468 // |
445 | 469 |
446 bool AudioCodingModuleImpl::CodecFEC() const { | 470 bool AudioCodingModuleImpl::CodecFEC() const { |
447 CriticalSectionScoped lock(acm_crit_sect_.get()); | 471 CriticalSectionScoped lock(acm_crit_sect_.get()); |
448 return codec_manager_.codec_fec_enabled(); | 472 return codec_manager_.GetStackParams()->use_codec_fec; |
449 } | 473 } |
450 | 474 |
451 int AudioCodingModuleImpl::SetCodecFEC(bool enable_codec_fec) { | 475 int AudioCodingModuleImpl::SetCodecFEC(bool enable_codec_fec) { |
452 CriticalSectionScoped lock(acm_crit_sect_.get()); | 476 CriticalSectionScoped lock(acm_crit_sect_.get()); |
453 return codec_manager_.SetCodecFEC(enable_codec_fec); | 477 if (!codec_manager_.SetCodecFEC(enable_codec_fec)) { |
478 return -1; | |
479 } | |
480 auto* sp = codec_manager_.GetStackParams(); | |
481 if (sp->speech_encoder) | |
482 rent_a_codec_.RentEncoderStack(sp); | |
483 if (enable_codec_fec) { | |
484 return sp->use_codec_fec ? 0 : -1; | |
485 } else { | |
486 RTC_DCHECK(!sp->use_codec_fec); | |
487 return 0; | |
488 } | |
454 } | 489 } |
455 | 490 |
456 int AudioCodingModuleImpl::SetPacketLossRate(int loss_rate) { | 491 int AudioCodingModuleImpl::SetPacketLossRate(int loss_rate) { |
457 CriticalSectionScoped lock(acm_crit_sect_.get()); | 492 CriticalSectionScoped lock(acm_crit_sect_.get()); |
458 if (HaveValidEncoder("SetPacketLossRate")) { | 493 if (HaveValidEncoder("SetPacketLossRate")) { |
459 codec_manager_.CurrentEncoder()->SetProjectedPacketLossRate(loss_rate / | 494 rent_a_codec_.GetEncoderStack()->SetProjectedPacketLossRate(loss_rate / |
460 100.0); | 495 100.0); |
461 } | 496 } |
462 return 0; | 497 return 0; |
463 } | 498 } |
464 | 499 |
465 ///////////////////////////////////////// | 500 ///////////////////////////////////////// |
466 // (VAD) Voice Activity Detection | 501 // (VAD) Voice Activity Detection |
467 // | 502 // |
468 int AudioCodingModuleImpl::SetVAD(bool enable_dtx, | 503 int AudioCodingModuleImpl::SetVAD(bool enable_dtx, |
469 bool enable_vad, | 504 bool enable_vad, |
470 ACMVADMode mode) { | 505 ACMVADMode mode) { |
471 // Note: |enable_vad| is not used; VAD is enabled based on the DTX setting. | 506 // Note: |enable_vad| is not used; VAD is enabled based on the DTX setting. |
472 RTC_DCHECK_EQ(enable_dtx, enable_vad); | 507 RTC_DCHECK_EQ(enable_dtx, enable_vad); |
473 CriticalSectionScoped lock(acm_crit_sect_.get()); | 508 CriticalSectionScoped lock(acm_crit_sect_.get()); |
474 return codec_manager_.SetVAD(enable_dtx, mode); | 509 if (!codec_manager_.SetVAD(enable_dtx, mode)) { |
510 return -1; | |
511 } | |
512 auto* sp = codec_manager_.GetStackParams(); | |
513 if (sp->speech_encoder) | |
514 rent_a_codec_.RentEncoderStack(sp); | |
515 return 0; | |
475 } | 516 } |
476 | 517 |
477 // Get VAD/DTX settings. | 518 // Get VAD/DTX settings. |
478 int AudioCodingModuleImpl::VAD(bool* dtx_enabled, bool* vad_enabled, | 519 int AudioCodingModuleImpl::VAD(bool* dtx_enabled, bool* vad_enabled, |
479 ACMVADMode* mode) const { | 520 ACMVADMode* mode) const { |
480 CriticalSectionScoped lock(acm_crit_sect_.get()); | 521 CriticalSectionScoped lock(acm_crit_sect_.get()); |
481 codec_manager_.VAD(dtx_enabled, vad_enabled, mode); | 522 const auto* sp = codec_manager_.GetStackParams(); |
523 *dtx_enabled = *vad_enabled = sp->use_cng; | |
524 *mode = sp->vad_mode; | |
482 return 0; | 525 return 0; |
483 } | 526 } |
484 | 527 |
485 ///////////////////////////////////////// | 528 ///////////////////////////////////////// |
486 // Receiver | 529 // Receiver |
487 // | 530 // |
488 | 531 |
489 int AudioCodingModuleImpl::InitializeReceiver() { | 532 int AudioCodingModuleImpl::InitializeReceiver() { |
490 CriticalSectionScoped lock(acm_crit_sect_.get()); | 533 CriticalSectionScoped lock(acm_crit_sect_.get()); |
491 return InitializeReceiverSafe(); | 534 return InitializeReceiverSafe(); |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
558 | 601 |
559 // Check if the payload-type is valid. | 602 // Check if the payload-type is valid. |
560 if (!RentACodec::IsPayloadTypeValid(codec.pltype)) { | 603 if (!RentACodec::IsPayloadTypeValid(codec.pltype)) { |
561 LOG_F(LS_ERROR) << "Invalid payload type " << codec.pltype << " for " | 604 LOG_F(LS_ERROR) << "Invalid payload type " << codec.pltype << " for " |
562 << codec.plname; | 605 << codec.plname; |
563 return -1; | 606 return -1; |
564 } | 607 } |
565 | 608 |
566 // Get |decoder| associated with |codec|. |decoder| is NULL if |codec| does | 609 // Get |decoder| associated with |codec|. |decoder| is NULL if |codec| does |
567 // not own its decoder. | 610 // not own its decoder. |
568 return receiver_.AddCodec(*codec_index, codec.pltype, codec.channels, | 611 return receiver_.AddCodec( |
569 codec.plfreq, codec_manager_.GetAudioDecoder(codec), | 612 *codec_index, codec.pltype, codec.channels, codec.plfreq, |
570 codec.plname); | 613 STR_CASE_CMP(codec.plname, "isac") == 0 ? rent_a_codec_.RentIsacDecoder() |
614 : nullptr, | |
615 codec.plname); | |
571 } | 616 } |
572 | 617 |
573 int AudioCodingModuleImpl::RegisterExternalReceiveCodec( | 618 int AudioCodingModuleImpl::RegisterExternalReceiveCodec( |
574 int rtp_payload_type, | 619 int rtp_payload_type, |
575 AudioDecoder* external_decoder, | 620 AudioDecoder* external_decoder, |
576 int sample_rate_hz, | 621 int sample_rate_hz, |
577 int num_channels, | 622 int num_channels, |
578 const std::string& name) { | 623 const std::string& name) { |
579 CriticalSectionScoped lock(acm_crit_sect_.get()); | 624 CriticalSectionScoped lock(acm_crit_sect_.get()); |
580 RTC_DCHECK(receiver_initialized_); | 625 RTC_DCHECK(receiver_initialized_); |
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
702 case kVoip: | 747 case kVoip: |
703 app = AudioEncoder::Application::kSpeech; | 748 app = AudioEncoder::Application::kSpeech; |
704 break; | 749 break; |
705 case kAudio: | 750 case kAudio: |
706 app = AudioEncoder::Application::kAudio; | 751 app = AudioEncoder::Application::kAudio; |
707 break; | 752 break; |
708 default: | 753 default: |
709 FATAL(); | 754 FATAL(); |
710 return 0; | 755 return 0; |
711 } | 756 } |
712 return codec_manager_.CurrentEncoder()->SetApplication(app) ? 0 : -1; | 757 return rent_a_codec_.GetEncoderStack()->SetApplication(app) ? 0 : -1; |
713 } | 758 } |
714 | 759 |
715 // Informs Opus encoder of the maximum playback rate the receiver will render. | 760 // Informs Opus encoder of the maximum playback rate the receiver will render. |
716 int AudioCodingModuleImpl::SetOpusMaxPlaybackRate(int frequency_hz) { | 761 int AudioCodingModuleImpl::SetOpusMaxPlaybackRate(int frequency_hz) { |
717 CriticalSectionScoped lock(acm_crit_sect_.get()); | 762 CriticalSectionScoped lock(acm_crit_sect_.get()); |
718 if (!HaveValidEncoder("SetOpusMaxPlaybackRate")) { | 763 if (!HaveValidEncoder("SetOpusMaxPlaybackRate")) { |
719 return -1; | 764 return -1; |
720 } | 765 } |
721 if (!codec_manager_.CurrentEncoderIsOpus()) | 766 if (!codec_manager_.CurrentEncoderIsOpus()) |
722 return -1; | 767 return -1; |
723 codec_manager_.CurrentEncoder()->SetMaxPlaybackRate(frequency_hz); | 768 rent_a_codec_.GetEncoderStack()->SetMaxPlaybackRate(frequency_hz); |
724 return 0; | 769 return 0; |
725 } | 770 } |
726 | 771 |
727 int AudioCodingModuleImpl::EnableOpusDtx() { | 772 int AudioCodingModuleImpl::EnableOpusDtx() { |
728 CriticalSectionScoped lock(acm_crit_sect_.get()); | 773 CriticalSectionScoped lock(acm_crit_sect_.get()); |
729 if (!HaveValidEncoder("EnableOpusDtx")) { | 774 if (!HaveValidEncoder("EnableOpusDtx")) { |
730 return -1; | 775 return -1; |
731 } | 776 } |
732 if (!codec_manager_.CurrentEncoderIsOpus()) | 777 if (!codec_manager_.CurrentEncoderIsOpus()) |
733 return -1; | 778 return -1; |
734 return codec_manager_.CurrentEncoder()->SetDtx(true) ? 0 : -1; | 779 return rent_a_codec_.GetEncoderStack()->SetDtx(true) ? 0 : -1; |
735 } | 780 } |
736 | 781 |
737 int AudioCodingModuleImpl::DisableOpusDtx() { | 782 int AudioCodingModuleImpl::DisableOpusDtx() { |
738 CriticalSectionScoped lock(acm_crit_sect_.get()); | 783 CriticalSectionScoped lock(acm_crit_sect_.get()); |
739 if (!HaveValidEncoder("DisableOpusDtx")) { | 784 if (!HaveValidEncoder("DisableOpusDtx")) { |
740 return -1; | 785 return -1; |
741 } | 786 } |
742 if (!codec_manager_.CurrentEncoderIsOpus()) | 787 if (!codec_manager_.CurrentEncoderIsOpus()) |
743 return -1; | 788 return -1; |
744 return codec_manager_.CurrentEncoder()->SetDtx(false) ? 0 : -1; | 789 return rent_a_codec_.GetEncoderStack()->SetDtx(false) ? 0 : -1; |
745 } | 790 } |
746 | 791 |
747 int AudioCodingModuleImpl::PlayoutTimestamp(uint32_t* timestamp) { | 792 int AudioCodingModuleImpl::PlayoutTimestamp(uint32_t* timestamp) { |
748 return receiver_.GetPlayoutTimestamp(timestamp) ? 0 : -1; | 793 return receiver_.GetPlayoutTimestamp(timestamp) ? 0 : -1; |
749 } | 794 } |
750 | 795 |
751 bool AudioCodingModuleImpl::HaveValidEncoder(const char* caller_name) const { | 796 bool AudioCodingModuleImpl::HaveValidEncoder(const char* caller_name) const { |
752 if (!codec_manager_.CurrentEncoder()) { | 797 if (!rent_a_codec_.GetEncoderStack()) { |
753 WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, id_, | 798 WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, id_, |
754 "%s failed: No send codec is registered.", caller_name); | 799 "%s failed: No send codec is registered.", caller_name); |
755 return false; | 800 return false; |
756 } | 801 } |
757 return true; | 802 return true; |
758 } | 803 } |
759 | 804 |
760 int AudioCodingModuleImpl::UnregisterReceiveCodec(uint8_t payload_type) { | 805 int AudioCodingModuleImpl::UnregisterReceiveCodec(uint8_t payload_type) { |
761 return receiver_.RemoveCodec(payload_type); | 806 return receiver_.RemoveCodec(payload_type); |
762 } | 807 } |
(...skipping 15 matching lines...) Expand all Loading... | |
778 return receiver_.LeastRequiredDelayMs(); | 823 return receiver_.LeastRequiredDelayMs(); |
779 } | 824 } |
780 | 825 |
781 void AudioCodingModuleImpl::GetDecodingCallStatistics( | 826 void AudioCodingModuleImpl::GetDecodingCallStatistics( |
782 AudioDecodingCallStats* call_stats) const { | 827 AudioDecodingCallStats* call_stats) const { |
783 receiver_.GetDecodingCallStatistics(call_stats); | 828 receiver_.GetDecodingCallStatistics(call_stats); |
784 } | 829 } |
785 | 830 |
786 } // namespace acm2 | 831 } // namespace acm2 |
787 } // namespace webrtc | 832 } // namespace webrtc |
OLD | NEW |