Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(32)

Side by Side Diff: webrtc/modules/audio_coding/main/acm2/codec_manager.cc

Issue 1443653004: Move CNG and RED management into the Rent-A-Codec (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Created 5 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved. 2 * Copyright (c) 2015 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 222 matching lines...) Expand 10 before | Expand all | Expand 10 after
233 if (send_codec.channels != 1) { 233 if (send_codec.channels != 1) {
234 if (dtx_enabled_) { 234 if (dtx_enabled_) {
235 WEBRTC_TRACE(webrtc::kTraceWarning, webrtc::kTraceAudioCoding, dummy_id, 235 WEBRTC_TRACE(webrtc::kTraceWarning, webrtc::kTraceAudioCoding, dummy_id,
236 "VAD/DTX is turned off, not supported when sending stereo."); 236 "VAD/DTX is turned off, not supported when sending stereo.");
237 } 237 }
238 dtx_enabled_ = false; 238 dtx_enabled_ = false;
239 } 239 }
240 240
241 // Check if the codec is already registered as send codec. 241 // Check if the codec is already registered as send codec.
242 bool new_codec = true; 242 bool new_codec = true;
243 if (codec_owner_.Encoder()) { 243 if (CurrentEncoder()) {
244 auto new_codec_id = RentACodec::CodecIdByInst(send_codec_inst_); 244 auto new_codec_id = RentACodec::CodecIdByInst(send_codec_inst_);
245 RTC_DCHECK(new_codec_id); 245 RTC_DCHECK(new_codec_id);
246 auto old_codec_id = RentACodec::CodecIdFromIndex(codec_id); 246 auto old_codec_id = RentACodec::CodecIdFromIndex(codec_id);
247 new_codec = !old_codec_id || *new_codec_id != *old_codec_id; 247 new_codec = !old_codec_id || *new_codec_id != *old_codec_id;
248 } 248 }
249 249
250 if (RedPayloadType(send_codec.plfreq) == -1) { 250 if (RedPayloadType(send_codec.plfreq) == -1) {
251 red_enabled_ = false; 251 red_enabled_ = false;
252 } 252 }
253 253
254 encoder_is_opus_ = IsOpus(send_codec); 254 encoder_is_opus_ = IsOpus(send_codec);
255 255
256 if (new_codec) { 256 if (new_codec) {
257 // This is a new codec. Register it and return. 257 // This is a new codec. Register it and return.
258 RTC_DCHECK(CodecSupported(send_codec)); 258 RTC_DCHECK(CodecSupported(send_codec));
259 if (IsOpus(send_codec)) { 259 if (IsOpus(send_codec)) {
260 // VAD/DTX not supported. 260 // VAD/DTX not supported.
261 dtx_enabled_ = false; 261 dtx_enabled_ = false;
262 } 262 }
263 AudioEncoder* enc = rent_a_codec_.RentEncoder(send_codec); 263 AudioEncoder* enc = rent_a_codec_.RentEncoder(send_codec);
264 if (!enc) 264 if (!enc)
265 return -1; 265 return -1;
266 codec_owner_.SetEncoders( 266 rent_a_codec_.RentEncoderStack(
267 enc, dtx_enabled_ ? CngPayloadType(send_codec.plfreq) : -1, 267 enc, dtx_enabled_
hlundin-webrtc 2015/11/16 08:59:17 The two conditionals in this expression are slight
kwiberg-webrtc 2015/11/16 12:01:37 Done.
268 vad_mode_, red_enabled_ ? RedPayloadType(send_codec.plfreq) : -1); 268 ? rtc::Optional<RentACodec::CngConfig>(RentACodec::CngConfig{
269 RTC_DCHECK(codec_owner_.Encoder()); 269 CngPayloadType(send_codec.plfreq), vad_mode_})
270 : rtc::Optional<RentACodec::CngConfig>(),
271 red_enabled_ ? rtc::Optional<int>(RedPayloadType(send_codec.plfreq))
272 : rtc::Optional<int>());
273 RTC_DCHECK(CurrentEncoder());
270 274
271 codec_fec_enabled_ = codec_fec_enabled_ && 275 codec_fec_enabled_ = codec_fec_enabled_ &&
272 enc->SetFec(codec_fec_enabled_); 276 enc->SetFec(codec_fec_enabled_);
273 277
274 send_codec_inst_ = send_codec; 278 send_codec_inst_ = send_codec;
275 return 0; 279 return 0;
276 } 280 }
277 281
278 // This is an existing codec; re-create it if any parameters have changed. 282 // This is an existing codec; re-create it if any parameters have changed.
279 if (send_codec_inst_.plfreq != send_codec.plfreq || 283 if (send_codec_inst_.plfreq != send_codec.plfreq ||
280 send_codec_inst_.pacsize != send_codec.pacsize || 284 send_codec_inst_.pacsize != send_codec.pacsize ||
281 send_codec_inst_.channels != send_codec.channels) { 285 send_codec_inst_.channels != send_codec.channels) {
282 AudioEncoder* enc = rent_a_codec_.RentEncoder(send_codec); 286 AudioEncoder* enc = rent_a_codec_.RentEncoder(send_codec);
283 if (!enc) 287 if (!enc)
284 return -1; 288 return -1;
285 codec_owner_.SetEncoders( 289 rent_a_codec_.RentEncoderStack(
286 enc, dtx_enabled_ ? CngPayloadType(send_codec.plfreq) : -1, 290 enc, dtx_enabled_
287 vad_mode_, red_enabled_ ? RedPayloadType(send_codec.plfreq) : -1); 291 ? rtc::Optional<RentACodec::CngConfig>(RentACodec::CngConfig{
288 RTC_DCHECK(codec_owner_.Encoder()); 292 CngPayloadType(send_codec.plfreq), vad_mode_})
293 : rtc::Optional<RentACodec::CngConfig>(),
294 red_enabled_ ? rtc::Optional<int>(RedPayloadType(send_codec.plfreq))
295 : rtc::Optional<int>());
296 RTC_DCHECK(CurrentEncoder());
289 } 297 }
290 send_codec_inst_.plfreq = send_codec.plfreq; 298 send_codec_inst_.plfreq = send_codec.plfreq;
291 send_codec_inst_.pacsize = send_codec.pacsize; 299 send_codec_inst_.pacsize = send_codec.pacsize;
292 send_codec_inst_.channels = send_codec.channels; 300 send_codec_inst_.channels = send_codec.channels;
293 send_codec_inst_.pltype = send_codec.pltype; 301 send_codec_inst_.pltype = send_codec.pltype;
294 302
295 // Check if a change in Rate is required. 303 // Check if a change in Rate is required.
296 if (send_codec.rate != send_codec_inst_.rate) { 304 if (send_codec.rate != send_codec_inst_.rate) {
297 codec_owner_.Encoder()->SetTargetBitrate(send_codec.rate); 305 CurrentEncoder()->SetTargetBitrate(send_codec.rate);
298 send_codec_inst_.rate = send_codec.rate; 306 send_codec_inst_.rate = send_codec.rate;
299 } 307 }
300 308
301 codec_fec_enabled_ = 309 codec_fec_enabled_ =
302 codec_fec_enabled_ && codec_owner_.Encoder()->SetFec(codec_fec_enabled_); 310 codec_fec_enabled_ && CurrentEncoder()->SetFec(codec_fec_enabled_);
303 311
304 return 0; 312 return 0;
305 } 313 }
306 314
307 void CodecManager::RegisterEncoder(AudioEncoder* external_speech_encoder) { 315 void CodecManager::RegisterEncoder(AudioEncoder* external_speech_encoder) {
308 // Make up a CodecInst. 316 // Make up a CodecInst.
309 send_codec_inst_.channels = external_speech_encoder->NumChannels(); 317 send_codec_inst_.channels = external_speech_encoder->NumChannels();
310 send_codec_inst_.plfreq = external_speech_encoder->SampleRateHz(); 318 send_codec_inst_.plfreq = external_speech_encoder->SampleRateHz();
311 send_codec_inst_.pacsize = rtc::CheckedDivExact( 319 send_codec_inst_.pacsize = rtc::CheckedDivExact(
312 static_cast<int>(external_speech_encoder->Max10MsFramesInAPacket() * 320 static_cast<int>(external_speech_encoder->Max10MsFramesInAPacket() *
313 send_codec_inst_.plfreq), 321 send_codec_inst_.plfreq),
314 100); 322 100);
315 send_codec_inst_.pltype = -1; // Not valid. 323 send_codec_inst_.pltype = -1; // Not valid.
316 send_codec_inst_.rate = -1; // Not valid. 324 send_codec_inst_.rate = -1; // Not valid.
317 static const char kName[] = "external"; 325 static const char kName[] = "external";
318 memcpy(send_codec_inst_.plname, kName, sizeof(kName)); 326 memcpy(send_codec_inst_.plname, kName, sizeof(kName));
319 327
320 if (send_codec_inst_.channels != 1) 328 if (send_codec_inst_.channels != 1)
321 dtx_enabled_ = false; 329 dtx_enabled_ = false;
322 if (codec_fec_enabled_) { 330 if (codec_fec_enabled_) {
323 // Switch FEC on. On failure, remember that FEC is off. 331 // Switch FEC on. On failure, remember that FEC is off.
324 if (!external_speech_encoder->SetFec(true)) 332 if (!external_speech_encoder->SetFec(true))
325 codec_fec_enabled_ = false; 333 codec_fec_enabled_ = false;
326 } else { 334 } else {
327 // Switch FEC off. This shouldn't fail. 335 // Switch FEC off. This shouldn't fail.
328 const bool success = external_speech_encoder->SetFec(false); 336 const bool success = external_speech_encoder->SetFec(false);
329 RTC_DCHECK(success); 337 RTC_DCHECK(success);
330 } 338 }
331 int cng_pt = dtx_enabled_ 339
332 ? CngPayloadType(external_speech_encoder->SampleRateHz()) 340 rent_a_codec_.RentEncoderStack(
333 : -1; 341 external_speech_encoder,
334 int red_pt = red_enabled_ ? RedPayloadType(send_codec_inst_.plfreq) : -1; 342 dtx_enabled_
335 codec_owner_.SetEncoders(external_speech_encoder, cng_pt, vad_mode_, red_pt); 343 ? rtc::Optional<RentACodec::CngConfig>(RentACodec::CngConfig{
344 CngPayloadType(external_speech_encoder->SampleRateHz()),
345 vad_mode_})
346 : rtc::Optional<RentACodec::CngConfig>(),
347 red_enabled_ ? rtc::Optional<int>(RedPayloadType(
348 external_speech_encoder->SampleRateHz()))
349 : rtc::Optional<int>());
336 } 350 }
337 351
338 rtc::Optional<CodecInst> CodecManager::GetCodecInst() const { 352 rtc::Optional<CodecInst> CodecManager::GetCodecInst() const {
339 int dummy_id = 0; 353 int dummy_id = 0;
340 WEBRTC_TRACE(webrtc::kTraceStream, webrtc::kTraceAudioCoding, dummy_id, 354 WEBRTC_TRACE(webrtc::kTraceStream, webrtc::kTraceAudioCoding, dummy_id,
341 "SendCodec()"); 355 "SendCodec()");
342 356
343 if (!codec_owner_.Encoder()) { 357 if (!CurrentEncoder()) {
344 WEBRTC_TRACE(webrtc::kTraceStream, webrtc::kTraceAudioCoding, dummy_id, 358 WEBRTC_TRACE(webrtc::kTraceStream, webrtc::kTraceAudioCoding, dummy_id,
345 "SendCodec Failed, no codec is registered"); 359 "SendCodec Failed, no codec is registered");
346 return rtc::Optional<CodecInst>(); 360 return rtc::Optional<CodecInst>();
347 } 361 }
348 return rtc::Optional<CodecInst>(send_codec_inst_); 362 return rtc::Optional<CodecInst>(send_codec_inst_);
349 } 363 }
350 364
351 bool CodecManager::SetCopyRed(bool enable) { 365 bool CodecManager::SetCopyRed(bool enable) {
352 if (enable && codec_fec_enabled_) { 366 if (enable && codec_fec_enabled_) {
353 WEBRTC_TRACE(webrtc::kTraceWarning, webrtc::kTraceAudioCoding, 0, 367 WEBRTC_TRACE(webrtc::kTraceWarning, webrtc::kTraceAudioCoding, 0,
354 "Codec internal FEC and RED cannot be co-enabled."); 368 "Codec internal FEC and RED cannot be co-enabled.");
355 return false; 369 return false;
356 } 370 }
357 if (enable && RedPayloadType(send_codec_inst_.plfreq) == -1) { 371 if (enable && RedPayloadType(send_codec_inst_.plfreq) == -1) {
358 WEBRTC_TRACE(webrtc::kTraceWarning, webrtc::kTraceAudioCoding, 0, 372 WEBRTC_TRACE(webrtc::kTraceWarning, webrtc::kTraceAudioCoding, 0,
359 "Cannot enable RED at %i Hz.", send_codec_inst_.plfreq); 373 "Cannot enable RED at %i Hz.", send_codec_inst_.plfreq);
360 return false; 374 return false;
361 } 375 }
362 if (red_enabled_ != enable) { 376 if (red_enabled_ != enable) {
363 red_enabled_ = enable; 377 red_enabled_ = enable;
364 if (codec_owner_.Encoder()) { 378 if (CurrentEncoder()) {
365 int cng_pt = dtx_enabled_ ? CngPayloadType(send_codec_inst_.plfreq) : -1; 379 rent_a_codec_.RentEncoderStack(
366 int red_pt = red_enabled_ ? RedPayloadType(send_codec_inst_.plfreq) : -1; 380 rent_a_codec_.GetEncoder(),
367 codec_owner_.ChangeCngAndRed(cng_pt, vad_mode_, red_pt); 381 dtx_enabled_
382 ? rtc::Optional<RentACodec::CngConfig>(RentACodec::CngConfig{
383 CngPayloadType(send_codec_inst_.plfreq), vad_mode_})
384 : rtc::Optional<RentACodec::CngConfig>(),
385 red_enabled_
386 ? rtc::Optional<int>(RedPayloadType(send_codec_inst_.plfreq))
387 : rtc::Optional<int>());
368 } 388 }
369 } 389 }
370 return true; 390 return true;
371 } 391 }
372 392
373 int CodecManager::SetVAD(bool enable, ACMVADMode mode) { 393 int CodecManager::SetVAD(bool enable, ACMVADMode mode) {
374 // Sanity check of the mode. 394 // Sanity check of the mode.
375 RTC_DCHECK(mode == VADNormal || mode == VADLowBitrate || mode == VADAggr || 395 RTC_DCHECK(mode == VADNormal || mode == VADLowBitrate || mode == VADAggr ||
376 mode == VADVeryAggr); 396 mode == VADVeryAggr);
377 397
378 // Check that the send codec is mono. We don't support VAD/DTX for stereo 398 // Check that the send codec is mono. We don't support VAD/DTX for stereo
379 // sending. 399 // sending.
380 const auto* enc = codec_owner_.Encoder(); 400 auto* enc = rent_a_codec_.GetEncoder();
381 const bool stereo_send = enc ? (enc->NumChannels() != 1) : false; 401 const bool stereo_send = enc ? (enc->NumChannels() != 1) : false;
382 if (enable && stereo_send) { 402 if (enable && stereo_send) {
383 WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, 0, 403 WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, 0,
384 "VAD/DTX not supported for stereo sending"); 404 "VAD/DTX not supported for stereo sending");
385 dtx_enabled_ = false; 405 dtx_enabled_ = false;
386 return -1; 406 return -1;
387 } 407 }
388 408
389 // If a send codec is registered, set VAD/DTX for the codec. 409 // If a send codec is registered, set VAD/DTX for the codec.
390 if (IsOpus(send_codec_inst_)) { 410 if (IsOpus(send_codec_inst_)) {
391 // VAD/DTX not supported. 411 // VAD/DTX not supported.
392 dtx_enabled_ = false; 412 dtx_enabled_ = false;
393 return 0; 413 return 0;
394 } 414 }
395 415
396 if (dtx_enabled_ != enable || vad_mode_ != mode) { 416 if (dtx_enabled_ != enable || vad_mode_ != mode) {
397 dtx_enabled_ = enable; 417 dtx_enabled_ = enable;
398 vad_mode_ = mode; 418 vad_mode_ = mode;
399 if (enc) { 419 if (enc) {
400 int cng_pt = dtx_enabled_ ? CngPayloadType(send_codec_inst_.plfreq) : -1; 420 rent_a_codec_.RentEncoderStack(
401 int red_pt = red_enabled_ ? RedPayloadType(send_codec_inst_.plfreq) : -1; 421 enc, dtx_enabled_
402 codec_owner_.ChangeCngAndRed(cng_pt, vad_mode_, red_pt); 422 ? rtc::Optional<RentACodec::CngConfig>(RentACodec::CngConfig{
423 CngPayloadType(send_codec_inst_.plfreq), vad_mode_})
424 : rtc::Optional<RentACodec::CngConfig>(),
425 red_enabled_
426 ? rtc::Optional<int>(RedPayloadType(send_codec_inst_.plfreq))
427 : rtc::Optional<int>());
403 } 428 }
404 } 429 }
405 return 0; 430 return 0;
406 } 431 }
407 432
408 void CodecManager::VAD(bool* dtx_enabled, 433 void CodecManager::VAD(bool* dtx_enabled,
409 bool* vad_enabled, 434 bool* vad_enabled,
410 ACMVADMode* mode) const { 435 ACMVADMode* mode) const {
411 *dtx_enabled = dtx_enabled_; 436 *dtx_enabled = dtx_enabled_;
412 *vad_enabled = dtx_enabled_; 437 *vad_enabled = dtx_enabled_;
413 *mode = vad_mode_; 438 *mode = vad_mode_;
414 } 439 }
415 440
416 int CodecManager::SetCodecFEC(bool enable_codec_fec) { 441 int CodecManager::SetCodecFEC(bool enable_codec_fec) {
417 if (enable_codec_fec == true && red_enabled_ == true) { 442 if (enable_codec_fec == true && red_enabled_ == true) {
418 WEBRTC_TRACE(webrtc::kTraceWarning, webrtc::kTraceAudioCoding, 0, 443 WEBRTC_TRACE(webrtc::kTraceWarning, webrtc::kTraceAudioCoding, 0,
419 "Codec internal FEC and RED cannot be co-enabled."); 444 "Codec internal FEC and RED cannot be co-enabled.");
420 return -1; 445 return -1;
421 } 446 }
422 447
423 RTC_CHECK(codec_owner_.Encoder()); 448 RTC_CHECK(CurrentEncoder());
424 codec_fec_enabled_ = 449 codec_fec_enabled_ =
425 codec_owner_.Encoder()->SetFec(enable_codec_fec) && enable_codec_fec; 450 CurrentEncoder()->SetFec(enable_codec_fec) && enable_codec_fec;
426 return codec_fec_enabled_ == enable_codec_fec ? 0 : -1; 451 return codec_fec_enabled_ == enable_codec_fec ? 0 : -1;
427 } 452 }
428 453
429 AudioDecoder* CodecManager::GetAudioDecoder(const CodecInst& codec) { 454 AudioDecoder* CodecManager::GetAudioDecoder(const CodecInst& codec) {
430 return IsIsac(codec) ? rent_a_codec_.RentIsacDecoder() : nullptr; 455 return IsIsac(codec) ? rent_a_codec_.RentIsacDecoder() : nullptr;
431 } 456 }
432 457
433 int CodecManager::CngPayloadType(int sample_rate_hz) const { 458 int CodecManager::CngPayloadType(int sample_rate_hz) const {
434 switch (sample_rate_hz) { 459 switch (sample_rate_hz) {
435 case 8000: 460 case 8000:
(...skipping 19 matching lines...) Expand all
455 case 48000: 480 case 48000:
456 return -1; 481 return -1;
457 default: 482 default:
458 FATAL() << sample_rate_hz << " Hz is not supported"; 483 FATAL() << sample_rate_hz << " Hz is not supported";
459 return -1; 484 return -1;
460 } 485 }
461 } 486 }
462 487
463 } // namespace acm2 488 } // namespace acm2
464 } // namespace webrtc 489 } // namespace webrtc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698