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

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: Extract subroutine 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 RentEncoderStack(enc, send_codec.plfreq);
267 enc, dtx_enabled_ ? CngPayloadType(send_codec.plfreq) : -1, 267 RTC_DCHECK(CurrentEncoder());
268 vad_mode_, red_enabled_ ? RedPayloadType(send_codec.plfreq) : -1);
269 RTC_DCHECK(codec_owner_.Encoder());
270 268
271 codec_fec_enabled_ = codec_fec_enabled_ && 269 codec_fec_enabled_ = codec_fec_enabled_ &&
272 enc->SetFec(codec_fec_enabled_); 270 enc->SetFec(codec_fec_enabled_);
273 271
274 send_codec_inst_ = send_codec; 272 send_codec_inst_ = send_codec;
275 return 0; 273 return 0;
276 } 274 }
277 275
278 // This is an existing codec; re-create it if any parameters have changed. 276 // This is an existing codec; re-create it if any parameters have changed.
279 if (send_codec_inst_.plfreq != send_codec.plfreq || 277 if (send_codec_inst_.plfreq != send_codec.plfreq ||
280 send_codec_inst_.pacsize != send_codec.pacsize || 278 send_codec_inst_.pacsize != send_codec.pacsize ||
281 send_codec_inst_.channels != send_codec.channels) { 279 send_codec_inst_.channels != send_codec.channels) {
282 AudioEncoder* enc = rent_a_codec_.RentEncoder(send_codec); 280 AudioEncoder* enc = rent_a_codec_.RentEncoder(send_codec);
283 if (!enc) 281 if (!enc)
284 return -1; 282 return -1;
285 codec_owner_.SetEncoders( 283 RentEncoderStack(enc, send_codec.plfreq);
286 enc, dtx_enabled_ ? CngPayloadType(send_codec.plfreq) : -1, 284 RTC_DCHECK(CurrentEncoder());
287 vad_mode_, red_enabled_ ? RedPayloadType(send_codec.plfreq) : -1);
288 RTC_DCHECK(codec_owner_.Encoder());
289 } 285 }
290 send_codec_inst_.plfreq = send_codec.plfreq; 286 send_codec_inst_.plfreq = send_codec.plfreq;
291 send_codec_inst_.pacsize = send_codec.pacsize; 287 send_codec_inst_.pacsize = send_codec.pacsize;
292 send_codec_inst_.channels = send_codec.channels; 288 send_codec_inst_.channels = send_codec.channels;
293 send_codec_inst_.pltype = send_codec.pltype; 289 send_codec_inst_.pltype = send_codec.pltype;
294 290
295 // Check if a change in Rate is required. 291 // Check if a change in Rate is required.
296 if (send_codec.rate != send_codec_inst_.rate) { 292 if (send_codec.rate != send_codec_inst_.rate) {
297 codec_owner_.Encoder()->SetTargetBitrate(send_codec.rate); 293 CurrentEncoder()->SetTargetBitrate(send_codec.rate);
298 send_codec_inst_.rate = send_codec.rate; 294 send_codec_inst_.rate = send_codec.rate;
299 } 295 }
300 296
301 codec_fec_enabled_ = 297 codec_fec_enabled_ =
302 codec_fec_enabled_ && codec_owner_.Encoder()->SetFec(codec_fec_enabled_); 298 codec_fec_enabled_ && CurrentEncoder()->SetFec(codec_fec_enabled_);
303 299
304 return 0; 300 return 0;
305 } 301 }
306 302
307 void CodecManager::RegisterEncoder(AudioEncoder* external_speech_encoder) { 303 void CodecManager::RegisterEncoder(AudioEncoder* external_speech_encoder) {
308 // Make up a CodecInst. 304 // Make up a CodecInst.
309 send_codec_inst_.channels = external_speech_encoder->NumChannels(); 305 send_codec_inst_.channels = external_speech_encoder->NumChannels();
310 send_codec_inst_.plfreq = external_speech_encoder->SampleRateHz(); 306 send_codec_inst_.plfreq = external_speech_encoder->SampleRateHz();
311 send_codec_inst_.pacsize = rtc::CheckedDivExact( 307 send_codec_inst_.pacsize = rtc::CheckedDivExact(
312 static_cast<int>(external_speech_encoder->Max10MsFramesInAPacket() * 308 static_cast<int>(external_speech_encoder->Max10MsFramesInAPacket() *
313 send_codec_inst_.plfreq), 309 send_codec_inst_.plfreq),
314 100); 310 100);
315 send_codec_inst_.pltype = -1; // Not valid. 311 send_codec_inst_.pltype = -1; // Not valid.
316 send_codec_inst_.rate = -1; // Not valid. 312 send_codec_inst_.rate = -1; // Not valid.
317 static const char kName[] = "external"; 313 static const char kName[] = "external";
318 memcpy(send_codec_inst_.plname, kName, sizeof(kName)); 314 memcpy(send_codec_inst_.plname, kName, sizeof(kName));
319 315
320 if (send_codec_inst_.channels != 1) 316 if (send_codec_inst_.channels != 1)
321 dtx_enabled_ = false; 317 dtx_enabled_ = false;
322 if (codec_fec_enabled_) { 318 if (codec_fec_enabled_) {
323 // Switch FEC on. On failure, remember that FEC is off. 319 // Switch FEC on. On failure, remember that FEC is off.
324 if (!external_speech_encoder->SetFec(true)) 320 if (!external_speech_encoder->SetFec(true))
325 codec_fec_enabled_ = false; 321 codec_fec_enabled_ = false;
326 } else { 322 } else {
327 // Switch FEC off. This shouldn't fail. 323 // Switch FEC off. This shouldn't fail.
328 const bool success = external_speech_encoder->SetFec(false); 324 const bool success = external_speech_encoder->SetFec(false);
329 RTC_DCHECK(success); 325 RTC_DCHECK(success);
330 } 326 }
331 int cng_pt = dtx_enabled_ 327
332 ? CngPayloadType(external_speech_encoder->SampleRateHz()) 328 RentEncoderStack(external_speech_encoder,
333 : -1; 329 external_speech_encoder->SampleRateHz());
334 int red_pt = red_enabled_ ? RedPayloadType(send_codec_inst_.plfreq) : -1;
335 codec_owner_.SetEncoders(external_speech_encoder, cng_pt, vad_mode_, red_pt);
336 } 330 }
337 331
338 rtc::Optional<CodecInst> CodecManager::GetCodecInst() const { 332 rtc::Optional<CodecInst> CodecManager::GetCodecInst() const {
339 int dummy_id = 0; 333 int dummy_id = 0;
340 WEBRTC_TRACE(webrtc::kTraceStream, webrtc::kTraceAudioCoding, dummy_id, 334 WEBRTC_TRACE(webrtc::kTraceStream, webrtc::kTraceAudioCoding, dummy_id,
341 "SendCodec()"); 335 "SendCodec()");
342 336
343 if (!codec_owner_.Encoder()) { 337 if (!CurrentEncoder()) {
344 WEBRTC_TRACE(webrtc::kTraceStream, webrtc::kTraceAudioCoding, dummy_id, 338 WEBRTC_TRACE(webrtc::kTraceStream, webrtc::kTraceAudioCoding, dummy_id,
345 "SendCodec Failed, no codec is registered"); 339 "SendCodec Failed, no codec is registered");
346 return rtc::Optional<CodecInst>(); 340 return rtc::Optional<CodecInst>();
347 } 341 }
348 return rtc::Optional<CodecInst>(send_codec_inst_); 342 return rtc::Optional<CodecInst>(send_codec_inst_);
349 } 343 }
350 344
351 bool CodecManager::SetCopyRed(bool enable) { 345 bool CodecManager::SetCopyRed(bool enable) {
352 if (enable && codec_fec_enabled_) { 346 if (enable && codec_fec_enabled_) {
353 WEBRTC_TRACE(webrtc::kTraceWarning, webrtc::kTraceAudioCoding, 0, 347 WEBRTC_TRACE(webrtc::kTraceWarning, webrtc::kTraceAudioCoding, 0,
354 "Codec internal FEC and RED cannot be co-enabled."); 348 "Codec internal FEC and RED cannot be co-enabled.");
355 return false; 349 return false;
356 } 350 }
357 if (enable && RedPayloadType(send_codec_inst_.plfreq) == -1) { 351 if (enable && RedPayloadType(send_codec_inst_.plfreq) == -1) {
358 WEBRTC_TRACE(webrtc::kTraceWarning, webrtc::kTraceAudioCoding, 0, 352 WEBRTC_TRACE(webrtc::kTraceWarning, webrtc::kTraceAudioCoding, 0,
359 "Cannot enable RED at %i Hz.", send_codec_inst_.plfreq); 353 "Cannot enable RED at %i Hz.", send_codec_inst_.plfreq);
360 return false; 354 return false;
361 } 355 }
362 if (red_enabled_ != enable) { 356 if (red_enabled_ != enable) {
363 red_enabled_ = enable; 357 red_enabled_ = enable;
364 if (codec_owner_.Encoder()) { 358 if (CurrentEncoder())
365 int cng_pt = dtx_enabled_ ? CngPayloadType(send_codec_inst_.plfreq) : -1; 359 RentEncoderStack(rent_a_codec_.GetEncoder(), send_codec_inst_.plfreq);
366 int red_pt = red_enabled_ ? RedPayloadType(send_codec_inst_.plfreq) : -1;
367 codec_owner_.ChangeCngAndRed(cng_pt, vad_mode_, red_pt);
368 }
369 } 360 }
370 return true; 361 return true;
371 } 362 }
372 363
373 int CodecManager::SetVAD(bool enable, ACMVADMode mode) { 364 int CodecManager::SetVAD(bool enable, ACMVADMode mode) {
374 // Sanity check of the mode. 365 // Sanity check of the mode.
375 RTC_DCHECK(mode == VADNormal || mode == VADLowBitrate || mode == VADAggr || 366 RTC_DCHECK(mode == VADNormal || mode == VADLowBitrate || mode == VADAggr ||
376 mode == VADVeryAggr); 367 mode == VADVeryAggr);
377 368
378 // Check that the send codec is mono. We don't support VAD/DTX for stereo 369 // Check that the send codec is mono. We don't support VAD/DTX for stereo
379 // sending. 370 // sending.
380 const auto* enc = codec_owner_.Encoder(); 371 auto* enc = rent_a_codec_.GetEncoder();
381 const bool stereo_send = enc ? (enc->NumChannels() != 1) : false; 372 const bool stereo_send = enc ? (enc->NumChannels() != 1) : false;
382 if (enable && stereo_send) { 373 if (enable && stereo_send) {
383 WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, 0, 374 WEBRTC_TRACE(webrtc::kTraceError, webrtc::kTraceAudioCoding, 0,
384 "VAD/DTX not supported for stereo sending"); 375 "VAD/DTX not supported for stereo sending");
385 dtx_enabled_ = false; 376 dtx_enabled_ = false;
386 return -1; 377 return -1;
387 } 378 }
388 379
389 // If a send codec is registered, set VAD/DTX for the codec. 380 // If a send codec is registered, set VAD/DTX for the codec.
390 if (IsOpus(send_codec_inst_)) { 381 if (IsOpus(send_codec_inst_)) {
391 // VAD/DTX not supported. 382 // VAD/DTX not supported.
392 dtx_enabled_ = false; 383 dtx_enabled_ = false;
393 return 0; 384 return 0;
394 } 385 }
395 386
396 if (dtx_enabled_ != enable || vad_mode_ != mode) { 387 if (dtx_enabled_ != enable || vad_mode_ != mode) {
397 dtx_enabled_ = enable; 388 dtx_enabled_ = enable;
398 vad_mode_ = mode; 389 vad_mode_ = mode;
399 if (enc) { 390 if (enc)
400 int cng_pt = dtx_enabled_ ? CngPayloadType(send_codec_inst_.plfreq) : -1; 391 RentEncoderStack(enc, send_codec_inst_.plfreq);
401 int red_pt = red_enabled_ ? RedPayloadType(send_codec_inst_.plfreq) : -1;
402 codec_owner_.ChangeCngAndRed(cng_pt, vad_mode_, red_pt);
403 }
404 } 392 }
405 return 0; 393 return 0;
406 } 394 }
407 395
408 void CodecManager::VAD(bool* dtx_enabled, 396 void CodecManager::VAD(bool* dtx_enabled,
409 bool* vad_enabled, 397 bool* vad_enabled,
410 ACMVADMode* mode) const { 398 ACMVADMode* mode) const {
411 *dtx_enabled = dtx_enabled_; 399 *dtx_enabled = dtx_enabled_;
412 *vad_enabled = dtx_enabled_; 400 *vad_enabled = dtx_enabled_;
413 *mode = vad_mode_; 401 *mode = vad_mode_;
414 } 402 }
415 403
416 int CodecManager::SetCodecFEC(bool enable_codec_fec) { 404 int CodecManager::SetCodecFEC(bool enable_codec_fec) {
417 if (enable_codec_fec == true && red_enabled_ == true) { 405 if (enable_codec_fec == true && red_enabled_ == true) {
418 WEBRTC_TRACE(webrtc::kTraceWarning, webrtc::kTraceAudioCoding, 0, 406 WEBRTC_TRACE(webrtc::kTraceWarning, webrtc::kTraceAudioCoding, 0,
419 "Codec internal FEC and RED cannot be co-enabled."); 407 "Codec internal FEC and RED cannot be co-enabled.");
420 return -1; 408 return -1;
421 } 409 }
422 410
423 RTC_CHECK(codec_owner_.Encoder()); 411 RTC_CHECK(CurrentEncoder());
424 codec_fec_enabled_ = 412 codec_fec_enabled_ =
425 codec_owner_.Encoder()->SetFec(enable_codec_fec) && enable_codec_fec; 413 CurrentEncoder()->SetFec(enable_codec_fec) && enable_codec_fec;
426 return codec_fec_enabled_ == enable_codec_fec ? 0 : -1; 414 return codec_fec_enabled_ == enable_codec_fec ? 0 : -1;
427 } 415 }
428 416
429 AudioDecoder* CodecManager::GetAudioDecoder(const CodecInst& codec) { 417 AudioDecoder* CodecManager::GetAudioDecoder(const CodecInst& codec) {
430 return IsIsac(codec) ? rent_a_codec_.RentIsacDecoder() : nullptr; 418 return IsIsac(codec) ? rent_a_codec_.RentIsacDecoder() : nullptr;
431 } 419 }
432 420
433 int CodecManager::CngPayloadType(int sample_rate_hz) const { 421 int CodecManager::CngPayloadType(int sample_rate_hz) const {
434 switch (sample_rate_hz) { 422 switch (sample_rate_hz) {
435 case 8000: 423 case 8000:
(...skipping 17 matching lines...) Expand all
453 case 16000: 441 case 16000:
454 case 32000: 442 case 32000:
455 case 48000: 443 case 48000:
456 return -1; 444 return -1;
457 default: 445 default:
458 FATAL() << sample_rate_hz << " Hz is not supported"; 446 FATAL() << sample_rate_hz << " Hz is not supported";
459 return -1; 447 return -1;
460 } 448 }
461 } 449 }
462 450
451 void CodecManager::RentEncoderStack(AudioEncoder* speech_encoder,
452 int sample_rate_hz) {
hlundin-webrtc 2015/11/16 12:28:06 I'd argue that the name should be rtp_timestamp_ra
453 auto cng_config =
454 dtx_enabled_ ? rtc::Optional<RentACodec::CngConfig>(RentACodec::CngConfig{
455 CngPayloadType(sample_rate_hz), vad_mode_})
456 : rtc::Optional<RentACodec::CngConfig>();
457 auto red_pt = red_enabled_
458 ? rtc::Optional<int>(RedPayloadType(sample_rate_hz))
459 : rtc::Optional<int>();
460 rent_a_codec_.RentEncoderStack(speech_encoder, cng_config, red_pt);
461 }
462
463 } // namespace acm2 463 } // namespace acm2
464 } // namespace webrtc 464 } // namespace webrtc
OLDNEW
« no previous file with comments | « webrtc/modules/audio_coding/main/acm2/codec_manager.h ('k') | webrtc/modules/audio_coding/main/acm2/codec_owner.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698