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

Side by Side Diff: webrtc/media/engine/webrtcvoiceengine.cc

Issue 1928233003: Remove RED support from WebRtcVoiceEngine/MediaChannel. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: rebase Created 4 years, 6 months 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) 2004 The WebRTC project authors. All Rights Reserved. 2 * Copyright (c) 2004 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 366 matching lines...) Expand 10 before | Expand all | Expand 10 after
377 codec->pacsize = (codec->plfreq / 1000) * packet_size_ms; 377 codec->pacsize = (codec->plfreq / 1000) * packet_size_ms;
378 return true; 378 return true;
379 } 379 }
380 } 380 }
381 } 381 }
382 return false; 382 return false;
383 } 383 }
384 384
385 static const AudioCodec* GetPreferredCodec( 385 static const AudioCodec* GetPreferredCodec(
386 const std::vector<AudioCodec>& codecs, 386 const std::vector<AudioCodec>& codecs,
387 webrtc::CodecInst* out, 387 webrtc::CodecInst* out) {
388 int* red_payload_type) {
389 RTC_DCHECK(out); 388 RTC_DCHECK(out);
390 RTC_DCHECK(red_payload_type);
391 // Select the preferred send codec (the first non-telephone-event/CN codec). 389 // Select the preferred send codec (the first non-telephone-event/CN codec).
392 for (const AudioCodec& codec : codecs) { 390 for (const AudioCodec& codec : codecs) {
393 *red_payload_type = -1;
394 if (IsCodec(codec, kDtmfCodecName) || IsCodec(codec, kCnCodecName)) { 391 if (IsCodec(codec, kDtmfCodecName) || IsCodec(codec, kCnCodecName)) {
395 // Skip telephone-event/CN codec, which will be handled later. 392 // Skip telephone-event/CN codec, which will be handled later.
396 continue; 393 continue;
397 } 394 }
398 395
399 // We'll use the first codec in the list to actually send audio data. 396 // We'll use the first codec in the list to actually send audio data.
400 // Be sure to use the payload type requested by the remote side. 397 // Be sure to use the payload type requested by the remote side.
401 // "red", for RED audio, is a special case where the actual codec to be
402 // used is specified in params.
403 const AudioCodec* found_codec = &codec;
404 if (IsCodec(*found_codec, kRedCodecName)) {
405 // Parse out the RED parameters. If we fail, just ignore RED;
406 // we don't support all possible params/usage scenarios.
407 *red_payload_type = codec.id;
408 found_codec = GetRedSendCodec(*found_codec, codecs);
409 if (!found_codec) {
410 continue;
411 }
412 }
413 // Ignore codecs we don't know about. The negotiation step should prevent 398 // Ignore codecs we don't know about. The negotiation step should prevent
414 // this, but double-check to be sure. 399 // this, but double-check to be sure.
415 webrtc::CodecInst voe_codec = {0}; 400 webrtc::CodecInst voe_codec = {0};
416 if (!ToCodecInst(*found_codec, &voe_codec)) { 401 if (!ToCodecInst(codec, &voe_codec)) {
417 LOG(LS_WARNING) << "Unknown codec " << ToString(*found_codec); 402 LOG(LS_WARNING) << "Unknown codec " << ToString(codec);
418 continue; 403 continue;
419 } 404 }
420 *out = voe_codec; 405 *out = voe_codec;
421 return found_codec; 406 return &codec;
422 } 407 }
423 return nullptr; 408 return nullptr;
424 } 409 }
425 410
426 private: 411 private:
427 static const int kMaxNumPacketSize = 6; 412 static const int kMaxNumPacketSize = 6;
428 struct CodecPref { 413 struct CodecPref {
429 const char* name; 414 const char* name;
430 int clockrate; 415 int clockrate;
431 size_t channels; 416 size_t channels;
432 int payload_type; 417 int payload_type;
433 bool is_multi_rate; 418 bool is_multi_rate;
434 int packet_sizes_ms[kMaxNumPacketSize]; 419 int packet_sizes_ms[kMaxNumPacketSize];
435 int max_bitrate_bps; 420 int max_bitrate_bps;
436 }; 421 };
437 // Note: keep the supported packet sizes in ascending order. 422 // Note: keep the supported packet sizes in ascending order.
438 static const CodecPref kCodecPrefs[12]; 423 static const CodecPref kCodecPrefs[11];
439 424
440 static int SelectPacketSize(const CodecPref& codec_pref, int ptime_ms) { 425 static int SelectPacketSize(const CodecPref& codec_pref, int ptime_ms) {
441 int selected_packet_size_ms = codec_pref.packet_sizes_ms[0]; 426 int selected_packet_size_ms = codec_pref.packet_sizes_ms[0];
442 for (int packet_size_ms : codec_pref.packet_sizes_ms) { 427 for (int packet_size_ms : codec_pref.packet_sizes_ms) {
443 if (packet_size_ms && packet_size_ms <= ptime_ms) { 428 if (packet_size_ms && packet_size_ms <= ptime_ms) {
444 selected_packet_size_ms = packet_size_ms; 429 selected_packet_size_ms = packet_size_ms;
445 } 430 }
446 } 431 }
447 return selected_packet_size_ms; 432 return selected_packet_size_ms;
448 } 433 }
449 434
450 // Changes RTP timestamp rate of G722. This is due to the "bug" in the RFC 435 // Changes RTP timestamp rate of G722. This is due to the "bug" in the RFC
451 // which says that G722 should be advertised as 8 kHz although it is a 16 kHz 436 // which says that G722 should be advertised as 8 kHz although it is a 16 kHz
452 // codec. 437 // codec.
453 static void MaybeFixupG722(webrtc::CodecInst* voe_codec, int new_plfreq) { 438 static void MaybeFixupG722(webrtc::CodecInst* voe_codec, int new_plfreq) {
454 if (IsCodec(*voe_codec, kG722CodecName)) { 439 if (IsCodec(*voe_codec, kG722CodecName)) {
455 // If the ASSERT triggers, the codec definition in WebRTC VoiceEngine 440 // If the ASSERT triggers, the codec definition in WebRTC VoiceEngine
456 // has changed, and this special case is no longer needed. 441 // has changed, and this special case is no longer needed.
457 RTC_DCHECK(voe_codec->plfreq != new_plfreq); 442 RTC_DCHECK(voe_codec->plfreq != new_plfreq);
458 voe_codec->plfreq = new_plfreq; 443 voe_codec->plfreq = new_plfreq;
459 } 444 }
460 } 445 }
461
462 static const AudioCodec* GetRedSendCodec(
463 const AudioCodec& red_codec,
464 const std::vector<AudioCodec>& all_codecs) {
465 // Get the RED encodings from the parameter with no name. This may
466 // change based on what is discussed on the Jingle list.
467 // The encoding parameter is of the form "a/b"; we only support where
468 // a == b. Verify this and parse out the value into red_pt.
469 // If the parameter value is absent (as it will be until we wire up the
470 // signaling of this message), use the second codec specified (i.e. the
471 // one after "red") as the encoding parameter.
472 int red_pt = -1;
473 std::string red_params;
474 CodecParameterMap::const_iterator it = red_codec.params.find("");
475 if (it != red_codec.params.end()) {
476 red_params = it->second;
477 std::vector<std::string> red_pts;
478 if (rtc::split(red_params, '/', &red_pts) != 2 ||
479 red_pts[0] != red_pts[1] || !rtc::FromString(red_pts[0], &red_pt)) {
480 LOG(LS_WARNING) << "RED params " << red_params << " not supported.";
481 return nullptr;
482 }
483 } else if (red_codec.params.empty()) {
484 LOG(LS_WARNING) << "RED params not present, using defaults";
485 if (all_codecs.size() > 1) {
486 red_pt = all_codecs[1].id;
487 }
488 }
489
490 // Try to find red_pt in |codecs|.
491 for (const AudioCodec& codec : all_codecs) {
492 if (codec.id == red_pt) {
493 return &codec;
494 }
495 }
496 LOG(LS_WARNING) << "RED params " << red_params << " are invalid.";
497 return nullptr;
498 }
499 }; 446 };
500 447
501 const WebRtcVoiceCodecs::CodecPref WebRtcVoiceCodecs::kCodecPrefs[12] = { 448 const WebRtcVoiceCodecs::CodecPref WebRtcVoiceCodecs::kCodecPrefs[11] = {
502 {kOpusCodecName, 48000, 2, 111, true, {10, 20, 40, 60}, kOpusMaxBitrate}, 449 {kOpusCodecName, 48000, 2, 111, true, {10, 20, 40, 60}, kOpusMaxBitrate},
503 {kIsacCodecName, 16000, 1, 103, true, {30, 60}, kIsacMaxBitrate}, 450 {kIsacCodecName, 16000, 1, 103, true, {30, 60}, kIsacMaxBitrate},
504 {kIsacCodecName, 32000, 1, 104, true, {30}, kIsacMaxBitrate}, 451 {kIsacCodecName, 32000, 1, 104, true, {30}, kIsacMaxBitrate},
505 // G722 should be advertised as 8000 Hz because of the RFC "bug". 452 // G722 should be advertised as 8000 Hz because of the RFC "bug".
506 {kG722CodecName, 8000, 1, 9, false, {10, 20, 30, 40, 50, 60}}, 453 {kG722CodecName, 8000, 1, 9, false, {10, 20, 30, 40, 50, 60}},
507 {kIlbcCodecName, 8000, 1, 102, false, {20, 30, 40, 60}}, 454 {kIlbcCodecName, 8000, 1, 102, false, {20, 30, 40, 60}},
508 {kPcmuCodecName, 8000, 1, 0, false, {10, 20, 30, 40, 50, 60}}, 455 {kPcmuCodecName, 8000, 1, 0, false, {10, 20, 30, 40, 50, 60}},
509 {kPcmaCodecName, 8000, 1, 8, false, {10, 20, 30, 40, 50, 60}}, 456 {kPcmaCodecName, 8000, 1, 8, false, {10, 20, 30, 40, 50, 60}},
510 {kCnCodecName, 32000, 1, 106, false, {}}, 457 {kCnCodecName, 32000, 1, 106, false, {}},
511 {kCnCodecName, 16000, 1, 105, false, {}}, 458 {kCnCodecName, 16000, 1, 105, false, {}},
512 {kCnCodecName, 8000, 1, 13, false, {}}, 459 {kCnCodecName, 8000, 1, 13, false, {}},
513 {kRedCodecName, 8000, 1, 127, false, {}}, 460 {kDtmfCodecName, 8000, 1, 126, false, {}}
514 {kDtmfCodecName, 8000, 1, 126, false, {}},
515 }; 461 };
516 } // namespace { 462 } // namespace {
517 463
518 bool WebRtcVoiceEngine::ToCodecInst(const AudioCodec& in, 464 bool WebRtcVoiceEngine::ToCodecInst(const AudioCodec& in,
519 webrtc::CodecInst* out) { 465 webrtc::CodecInst* out) {
520 return WebRtcVoiceCodecs::ToCodecInst(in, out); 466 return WebRtcVoiceCodecs::ToCodecInst(in, out);
521 } 467 }
522 468
523 WebRtcVoiceEngine::WebRtcVoiceEngine(webrtc::AudioDeviceModule* adm) 469 WebRtcVoiceEngine::WebRtcVoiceEngine(webrtc::AudioDeviceModule* adm)
524 : WebRtcVoiceEngine(adm, new VoEWrapper()) { 470 : WebRtcVoiceEngine(adm, new VoEWrapper()) {
(...skipping 1125 matching lines...) Expand 10 before | Expand all | Expand 10 after
1650 if (IsCodec(codec, kDtmfCodecName)) { 1596 if (IsCodec(codec, kDtmfCodecName)) {
1651 if (codec.id < kMinPayloadType || codec.id > kMaxPayloadType) { 1597 if (codec.id < kMinPayloadType || codec.id > kMaxPayloadType) {
1652 return false; 1598 return false;
1653 } 1599 }
1654 dtmf_payload_type_ = rtc::Optional<int>(codec.id); 1600 dtmf_payload_type_ = rtc::Optional<int>(codec.id);
1655 break; 1601 break;
1656 } 1602 }
1657 } 1603 }
1658 1604
1659 // Scan through the list to figure out the codec to use for sending, along 1605 // Scan through the list to figure out the codec to use for sending, along
1660 // with the proper configuration for VAD, CNG, RED, NACK and Opus-specific 1606 // with the proper configuration for VAD, CNG, NACK and Opus-specific
1661 // parameters. 1607 // parameters.
1608 // TODO(solenberg): Refactor this logic once we create AudioEncoders here.
1662 { 1609 {
1663 SendCodecSpec send_codec_spec; 1610 SendCodecSpec send_codec_spec;
1664 send_codec_spec.nack_enabled = send_codec_spec_.nack_enabled; 1611 send_codec_spec.nack_enabled = send_codec_spec_.nack_enabled;
1665 1612
1666 // Find send codec (the first non-telephone-event/CN codec). 1613 // Find send codec (the first non-telephone-event/CN codec).
1667 const AudioCodec* codec = WebRtcVoiceCodecs::GetPreferredCodec( 1614 const AudioCodec* codec = WebRtcVoiceCodecs::GetPreferredCodec(
1668 codecs, &send_codec_spec.codec_inst, &send_codec_spec.red_payload_type); 1615 codecs, &send_codec_spec.codec_inst);
1669 if (!codec) { 1616 if (!codec) {
1670 LOG(LS_WARNING) << "Received empty list of codecs."; 1617 LOG(LS_WARNING) << "Received empty list of codecs.";
1671 return false; 1618 return false;
1672 } 1619 }
1673 1620
1674 send_codec_spec.transport_cc_enabled = HasTransportCc(*codec); 1621 send_codec_spec.transport_cc_enabled = HasTransportCc(*codec);
1622 send_codec_spec.nack_enabled = HasNack(*codec);
1675 1623
1676 // This condition is apparently here because Opus does not support RED and 1624 // For Opus as the send codec, we are to determine inband FEC, maximum
1677 // FEC simultaneously. However, DTX and max playback rate shouldn't have 1625 // playback rate, and opus internal dtx.
1678 // such limitations. 1626 if (IsCodec(*codec, kOpusCodecName)) {
1679 // TODO(solenberg): Refactor this logic once we create AudioEncoders here. 1627 GetOpusConfig(*codec, &send_codec_spec.codec_inst,
1680 if (send_codec_spec.red_payload_type == -1) { 1628 &send_codec_spec.enable_codec_fec,
1681 send_codec_spec.nack_enabled = HasNack(*codec); 1629 &send_codec_spec.opus_max_playback_rate,
1682 // For Opus as the send codec, we are to determine inband FEC, maximum 1630 &send_codec_spec.enable_opus_dtx);
1683 // playback rate, and opus internal dtx. 1631 }
1684 if (IsCodec(*codec, kOpusCodecName)) {
1685 GetOpusConfig(*codec, &send_codec_spec.codec_inst,
1686 &send_codec_spec.enable_codec_fec,
1687 &send_codec_spec.opus_max_playback_rate,
1688 &send_codec_spec.enable_opus_dtx);
1689 }
1690 1632
1691 // Set packet size if the AudioCodec param kCodecParamPTime is set. 1633 // Set packet size if the AudioCodec param kCodecParamPTime is set.
1692 int ptime_ms = 0; 1634 int ptime_ms = 0;
1693 if (codec->GetParam(kCodecParamPTime, &ptime_ms)) { 1635 if (codec->GetParam(kCodecParamPTime, &ptime_ms)) {
1694 if (!WebRtcVoiceCodecs::SetPTimeAsPacketSize( 1636 if (!WebRtcVoiceCodecs::SetPTimeAsPacketSize(
1695 &send_codec_spec.codec_inst, ptime_ms)) { 1637 &send_codec_spec.codec_inst, ptime_ms)) {
1696 LOG(LS_WARNING) << "Failed to set packet size for codec " 1638 LOG(LS_WARNING) << "Failed to set packet size for codec "
1697 << send_codec_spec.codec_inst.plname; 1639 << send_codec_spec.codec_inst.plname;
1698 return false; 1640 return false;
1699 }
1700 } 1641 }
1701 } 1642 }
1702 1643
1703 // Loop through the codecs list again to find the CN codec. 1644 // Loop through the codecs list again to find the CN codec.
1704 // TODO(solenberg): Break out into a separate function? 1645 // TODO(solenberg): Break out into a separate function?
1705 for (const AudioCodec& codec : codecs) { 1646 for (const AudioCodec& codec : codecs) {
1706 // Ignore codecs we don't know about. The negotiation step should prevent 1647 // Ignore codecs we don't know about. The negotiation step should prevent
1707 // this, but double-check to be sure. 1648 // this, but double-check to be sure.
1708 webrtc::CodecInst voe_codec = {0}; 1649 webrtc::CodecInst voe_codec = {0};
1709 if (!WebRtcVoiceEngine::ToCodecInst(codec, &voe_codec)) { 1650 if (!WebRtcVoiceEngine::ToCodecInst(codec, &voe_codec)) {
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
1761 } 1702 }
1762 1703
1763 send_codecs_ = codecs; 1704 send_codecs_ = codecs;
1764 return true; 1705 return true;
1765 } 1706 }
1766 1707
1767 // Apply current codec settings to a single voe::Channel used for sending. 1708 // Apply current codec settings to a single voe::Channel used for sending.
1768 bool WebRtcVoiceMediaChannel::SetSendCodecs( 1709 bool WebRtcVoiceMediaChannel::SetSendCodecs(
1769 int channel, 1710 int channel,
1770 const webrtc::RtpParameters& rtp_parameters) { 1711 const webrtc::RtpParameters& rtp_parameters) {
1771 // Disable VAD, FEC, and RED unless we know the other side wants them. 1712 // Disable VAD, NACK and FEC unless we know the other side wants them.
1772 engine()->voe()->codec()->SetVADStatus(channel, false); 1713 engine()->voe()->codec()->SetVADStatus(channel, false);
1773 engine()->voe()->rtp()->SetNACKStatus(channel, false, 0); 1714 engine()->voe()->rtp()->SetNACKStatus(channel, false, 0);
1774 engine()->voe()->rtp()->SetREDStatus(channel, false);
1775 engine()->voe()->codec()->SetFECStatus(channel, false); 1715 engine()->voe()->codec()->SetFECStatus(channel, false);
1776 1716
1777 if (send_codec_spec_.red_payload_type != -1) {
1778 // Enable redundant encoding of the specified codec. Treat any
1779 // failure as a fatal internal error.
1780 LOG(LS_INFO) << "Enabling RED on channel " << channel;
1781 if (engine()->voe()->rtp()->SetREDStatus(channel, true,
1782 send_codec_spec_.red_payload_type) == -1) {
1783 LOG_RTCERR3(SetREDStatus, channel, true,
1784 send_codec_spec_.red_payload_type);
1785 return false;
1786 }
1787 }
1788
1789 SetNack(channel, send_codec_spec_.nack_enabled); 1717 SetNack(channel, send_codec_spec_.nack_enabled);
1790 1718
1791 // Set the codec immediately, since SetVADStatus() depends on whether 1719 // Set the codec immediately, since SetVADStatus() depends on whether
1792 // the current codec is mono or stereo. 1720 // the current codec is mono or stereo.
1793 if (!SetSendCodec(channel, send_codec_spec_.codec_inst)) { 1721 if (!SetSendCodec(channel, send_codec_spec_.codec_inst)) {
1794 return false; 1722 return false;
1795 } 1723 }
1796 1724
1797 // FEC should be enabled after SetSendCodec. 1725 // FEC should be enabled after SetSendCodec.
1798 if (send_codec_spec_.enable_codec_fec) { 1726 if (send_codec_spec_.enable_codec_fec) {
(...skipping 829 matching lines...) Expand 10 before | Expand all | Expand 10 after
2628 } 2556 }
2629 } else { 2557 } else {
2630 LOG(LS_INFO) << "Stopping playout for channel #" << channel; 2558 LOG(LS_INFO) << "Stopping playout for channel #" << channel;
2631 engine()->voe()->base()->StopPlayout(channel); 2559 engine()->voe()->base()->StopPlayout(channel);
2632 } 2560 }
2633 return true; 2561 return true;
2634 } 2562 }
2635 } // namespace cricket 2563 } // namespace cricket
2636 2564
2637 #endif // HAVE_WEBRTC_VOICE 2565 #endif // HAVE_WEBRTC_VOICE
OLDNEW
« no previous file with comments | « webrtc/media/engine/webrtcvoiceengine.h ('k') | webrtc/media/engine/webrtcvoiceengine_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698