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

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

Issue 1955363003: Configure VoE NACK through AudioSendStream::Config. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: rebase again 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 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
57 // -1 or 0 to select the default device. 57 // -1 or 0 to select the default device.
58 #ifdef WIN32 58 #ifdef WIN32
59 const int kDefaultAudioDeviceId = -1; 59 const int kDefaultAudioDeviceId = -1;
60 #elif !defined(WEBRTC_IOS) 60 #elif !defined(WEBRTC_IOS)
61 const int kDefaultAudioDeviceId = 0; 61 const int kDefaultAudioDeviceId = 0;
62 #endif 62 #endif
63 63
64 // Parameter used for NACK. 64 // Parameter used for NACK.
65 // This value is equivalent to 5 seconds of audio data at 20 ms per packet. 65 // This value is equivalent to 5 seconds of audio data at 20 ms per packet.
66 const int kNackMaxPackets = 250; 66 const int kNackMaxPackets = 250;
67 constexpr int kNackRtpHistoryMs = 5000;
67 68
68 // Codec parameters for Opus. 69 // Codec parameters for Opus.
69 // draft-spittka-payload-rtp-opus-03 70 // draft-spittka-payload-rtp-opus-03
70 71
71 // Recommended bitrates: 72 // Recommended bitrates:
72 // 8-12 kb/s for NB speech, 73 // 8-12 kb/s for NB speech,
73 // 16-20 kb/s for WB speech, 74 // 16-20 kb/s for WB speech,
74 // 28-40 kb/s for FB speech, 75 // 28-40 kb/s for FB speech,
75 // 48-64 kb/s for FB mono music, and 76 // 48-64 kb/s for FB mono music, and
76 // 64-128 kb/s for FB stereo music. 77 // 64-128 kb/s for FB stereo music.
(...skipping 377 matching lines...) Expand 10 before | Expand all | Expand 10 after
454 {kIlbcCodecName, 8000, 1, 102, false, {20, 30, 40, 60}}, 455 {kIlbcCodecName, 8000, 1, 102, false, {20, 30, 40, 60}},
455 {kPcmuCodecName, 8000, 1, 0, false, {10, 20, 30, 40, 50, 60}}, 456 {kPcmuCodecName, 8000, 1, 0, false, {10, 20, 30, 40, 50, 60}},
456 {kPcmaCodecName, 8000, 1, 8, false, {10, 20, 30, 40, 50, 60}}, 457 {kPcmaCodecName, 8000, 1, 8, false, {10, 20, 30, 40, 50, 60}},
457 {kCnCodecName, 32000, 1, 106, false, {}}, 458 {kCnCodecName, 32000, 1, 106, false, {}},
458 {kCnCodecName, 16000, 1, 105, false, {}}, 459 {kCnCodecName, 16000, 1, 105, false, {}},
459 {kCnCodecName, 8000, 1, 13, false, {}}, 460 {kCnCodecName, 8000, 1, 13, false, {}},
460 {kDtmfCodecName, 8000, 1, 126, false, {}} 461 {kDtmfCodecName, 8000, 1, 126, false, {}}
461 }; 462 };
462 } // namespace { 463 } // namespace {
463 464
465 bool SendCodecSpec::operator==(const SendCodecSpec& rhs) const {
466 if (nack_enabled != rhs.nack_enabled) {
467 return false;
468 }
469 if (transport_cc_enabled != rhs.transport_cc_enabled) {
470 return false;
471 }
472 if (enable_codec_fec != rhs.enable_codec_fec) {
473 return false;
474 }
475 if (enable_opus_dtx != rhs.enable_opus_dtx) {
476 return false;
477 }
478 if (opus_max_playback_rate != rhs.opus_max_playback_rate) {
479 return false;
480 }
481 if (red_payload_type != rhs.red_payload_type) {
482 return false;
483 }
484 if (cng_payload_type != rhs.cng_payload_type) {
485 return false;
486 }
487 if (cng_plfreq != rhs.cng_plfreq) {
488 return false;
489 }
490 if (codec_inst != rhs.codec_inst) {
491 return false;
492 }
493 return true;
494 }
495
496 bool SendCodecSpec::operator!=(const SendCodecSpec& rhs) const {
497 return !(*this == rhs);
498 }
499
464 bool WebRtcVoiceEngine::ToCodecInst(const AudioCodec& in, 500 bool WebRtcVoiceEngine::ToCodecInst(const AudioCodec& in,
465 webrtc::CodecInst* out) { 501 webrtc::CodecInst* out) {
466 return WebRtcVoiceCodecs::ToCodecInst(in, out); 502 return WebRtcVoiceCodecs::ToCodecInst(in, out);
467 } 503 }
468 504
469 WebRtcVoiceEngine::WebRtcVoiceEngine( 505 WebRtcVoiceEngine::WebRtcVoiceEngine(
470 webrtc::AudioDeviceModule* adm, 506 webrtc::AudioDeviceModule* adm,
471 const rtc::scoped_refptr<webrtc::AudioDecoderFactory>& decoder_factory) 507 const rtc::scoped_refptr<webrtc::AudioDecoderFactory>& decoder_factory)
472 : WebRtcVoiceEngine(adm, decoder_factory, new VoEWrapper()) { 508 : WebRtcVoiceEngine(adm, decoder_factory, new VoEWrapper()) {
473 audio_state_ = webrtc::AudioState::Create(MakeAudioStateConfig(voe())); 509 audio_state_ = webrtc::AudioState::Create(MakeAudioStateConfig(voe()));
(...skipping 588 matching lines...) Expand 10 before | Expand all | Expand 10 after
1062 return adm_; 1098 return adm_;
1063 } 1099 }
1064 1100
1065 class WebRtcVoiceMediaChannel::WebRtcAudioSendStream 1101 class WebRtcVoiceMediaChannel::WebRtcAudioSendStream
1066 : public AudioSource::Sink { 1102 : public AudioSource::Sink {
1067 public: 1103 public:
1068 WebRtcAudioSendStream(int ch, 1104 WebRtcAudioSendStream(int ch,
1069 webrtc::AudioTransport* voe_audio_transport, 1105 webrtc::AudioTransport* voe_audio_transport,
1070 uint32_t ssrc, 1106 uint32_t ssrc,
1071 const std::string& c_name, 1107 const std::string& c_name,
1108 const SendCodecSpec& send_codec_spec,
1072 const std::vector<webrtc::RtpExtension>& extensions, 1109 const std::vector<webrtc::RtpExtension>& extensions,
1073 webrtc::Call* call, 1110 webrtc::Call* call,
1074 webrtc::Transport* send_transport) 1111 webrtc::Transport* send_transport)
1075 : voe_audio_transport_(voe_audio_transport), 1112 : voe_audio_transport_(voe_audio_transport),
1076 call_(call), 1113 call_(call),
1077 config_(send_transport), 1114 config_(send_transport),
1078 rtp_parameters_(CreateRtpParametersWithOneEncoding()) { 1115 rtp_parameters_(CreateRtpParametersWithOneEncoding()) {
1079 RTC_DCHECK_GE(ch, 0); 1116 RTC_DCHECK_GE(ch, 0);
1080 // TODO(solenberg): Once we're not using FakeWebRtcVoiceEngine anymore: 1117 // TODO(solenberg): Once we're not using FakeWebRtcVoiceEngine anymore:
1081 // RTC_DCHECK(voe_audio_transport); 1118 // RTC_DCHECK(voe_audio_transport);
1082 RTC_DCHECK(call); 1119 RTC_DCHECK(call);
1083 audio_capture_thread_checker_.DetachFromThread(); 1120 audio_capture_thread_checker_.DetachFromThread();
1084 config_.rtp.ssrc = ssrc; 1121 config_.rtp.ssrc = ssrc;
1085 config_.rtp.c_name = c_name; 1122 config_.rtp.c_name = c_name;
1086 config_.voe_channel_id = ch; 1123 config_.voe_channel_id = ch;
1087 RecreateAudioSendStream(extensions); 1124 config_.rtp.extensions = extensions;
1125 RecreateAudioSendStream(send_codec_spec);
1088 } 1126 }
1089 1127
1090 ~WebRtcAudioSendStream() override { 1128 ~WebRtcAudioSendStream() override {
1091 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); 1129 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
1092 ClearSource(); 1130 ClearSource();
1093 call_->DestroyAudioSendStream(stream_); 1131 call_->DestroyAudioSendStream(stream_);
1094 } 1132 }
1095 1133
1134 void RecreateAudioSendStream(const SendCodecSpec& send_codec_spec) {
1135 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
1136 if (stream_) {
1137 call_->DestroyAudioSendStream(stream_);
1138 stream_ = nullptr;
1139 }
1140 config_.rtp.nack.rtp_history_ms =
1141 send_codec_spec.nack_enabled ? kNackRtpHistoryMs : 0;
1142 RTC_DCHECK(!stream_);
1143 stream_ = call_->CreateAudioSendStream(config_);
1144 RTC_CHECK(stream_);
1145 UpdateSendState();
1146 }
1147
1096 void RecreateAudioSendStream( 1148 void RecreateAudioSendStream(
1097 const std::vector<webrtc::RtpExtension>& extensions) { 1149 const std::vector<webrtc::RtpExtension>& extensions) {
1098 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); 1150 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
1099 if (stream_) { 1151 if (stream_) {
1100 call_->DestroyAudioSendStream(stream_); 1152 call_->DestroyAudioSendStream(stream_);
1101 stream_ = nullptr; 1153 stream_ = nullptr;
1102 } 1154 }
1103 config_.rtp.extensions = extensions; 1155 config_.rtp.extensions = extensions;
1104 RTC_DCHECK(!stream_); 1156 RTC_DCHECK(!stream_);
1105 stream_ = call_->CreateAudioSendStream(config_); 1157 stream_ = call_->CreateAudioSendStream(config_);
(...skipping 506 matching lines...) Expand 10 before | Expand all | Expand 10 after
1612 } 1664 }
1613 dtmf_payload_type_ = rtc::Optional<int>(codec.id); 1665 dtmf_payload_type_ = rtc::Optional<int>(codec.id);
1614 break; 1666 break;
1615 } 1667 }
1616 } 1668 }
1617 1669
1618 // Scan through the list to figure out the codec to use for sending, along 1670 // Scan through the list to figure out the codec to use for sending, along
1619 // with the proper configuration for VAD, CNG, NACK and Opus-specific 1671 // with the proper configuration for VAD, CNG, NACK and Opus-specific
1620 // parameters. 1672 // parameters.
1621 // TODO(solenberg): Refactor this logic once we create AudioEncoders here. 1673 // TODO(solenberg): Refactor this logic once we create AudioEncoders here.
1674 SendCodecSpec send_codec_spec;
1622 { 1675 {
1623 SendCodecSpec send_codec_spec;
1624 send_codec_spec.nack_enabled = send_codec_spec_.nack_enabled; 1676 send_codec_spec.nack_enabled = send_codec_spec_.nack_enabled;
1625 1677
1626 // Find send codec (the first non-telephone-event/CN codec). 1678 // Find send codec (the first non-telephone-event/CN codec).
1627 const AudioCodec* codec = WebRtcVoiceCodecs::GetPreferredCodec( 1679 const AudioCodec* codec = WebRtcVoiceCodecs::GetPreferredCodec(
1628 codecs, &send_codec_spec.codec_inst); 1680 codecs, &send_codec_spec.codec_inst);
1629 if (!codec) { 1681 if (!codec) {
1630 LOG(LS_WARNING) << "Received empty list of codecs."; 1682 LOG(LS_WARNING) << "Received empty list of codecs.";
1631 return false; 1683 return false;
1632 } 1684 }
1633 1685
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
1679 default: 1731 default:
1680 LOG(LS_WARNING) << "CN frequency " << codec.clockrate 1732 LOG(LS_WARNING) << "CN frequency " << codec.clockrate
1681 << " not supported."; 1733 << " not supported.";
1682 continue; 1734 continue;
1683 } 1735 }
1684 send_codec_spec.cng_payload_type = codec.id; 1736 send_codec_spec.cng_payload_type = codec.id;
1685 send_codec_spec.cng_plfreq = cng_plfreq; 1737 send_codec_spec.cng_plfreq = cng_plfreq;
1686 break; 1738 break;
1687 } 1739 }
1688 } 1740 }
1689
1690 // Latch in the new state.
1691 send_codec_spec_ = std::move(send_codec_spec);
1692 } 1741 }
1693 1742
1694 // Cache the codecs in order to configure the channel created later. 1743 // Apply new settings to all streams.
1695 for (const auto& ch : send_streams_) { 1744 if (send_codec_spec_ != send_codec_spec) {
1696 if (!SetSendCodecs(ch.second->channel(), ch.second->rtp_parameters())) { 1745 send_codec_spec_ = std::move(send_codec_spec);
1697 return false; 1746 for (const auto& kv : send_streams_) {
1747 kv.second->RecreateAudioSendStream(send_codec_spec_);
1748 if (!SetSendCodecs(kv.second->channel(), kv.second->rtp_parameters())) {
1749 return false;
1750 }
1698 } 1751 }
1699 } 1752 }
1700 1753
1701 // Set nack status on receive channels. 1754 // Set nack status on receive channels.
1702 for (const auto& kv : recv_streams_) { 1755 for (const auto& kv : recv_streams_) {
1703 SetNack(kv.second->channel(), send_codec_spec_.nack_enabled); 1756 SetNack(kv.second->channel(), send_codec_spec_.nack_enabled);
1704 } 1757 }
1705 1758
1706 // Check if the transport cc feedback has changed on the preferred send codec, 1759 // Check if the transport cc feedback has changed on the preferred send codec,
1707 // and in that case reconfigure all receive streams. 1760 // and in that case reconfigure all receive streams.
1708 if (recv_transport_cc_enabled_ != send_codec_spec_.transport_cc_enabled) { 1761 if (recv_transport_cc_enabled_ != send_codec_spec_.transport_cc_enabled) {
1709 LOG(LS_INFO) << "Recreate all the receive streams because the send " 1762 LOG(LS_INFO) << "Recreate all the receive streams because the send "
1710 "codec has changed."; 1763 "codec has changed.";
1711 recv_transport_cc_enabled_ = send_codec_spec_.transport_cc_enabled; 1764 recv_transport_cc_enabled_ = send_codec_spec_.transport_cc_enabled;
1712 for (auto& kv : recv_streams_) { 1765 for (auto& kv : recv_streams_) {
1713 kv.second->RecreateAudioReceiveStream(recv_transport_cc_enabled_); 1766 kv.second->RecreateAudioReceiveStream(recv_transport_cc_enabled_);
1714 } 1767 }
1715 } 1768 }
1716 1769
1717 send_codecs_ = codecs; 1770 send_codecs_ = codecs;
1718 return true; 1771 return true;
1719 } 1772 }
1720 1773
1721 // Apply current codec settings to a single voe::Channel used for sending. 1774 // Apply current codec settings to a single voe::Channel used for sending.
1722 bool WebRtcVoiceMediaChannel::SetSendCodecs( 1775 bool WebRtcVoiceMediaChannel::SetSendCodecs(
1723 int channel, 1776 int channel,
1724 const webrtc::RtpParameters& rtp_parameters) { 1777 const webrtc::RtpParameters& rtp_parameters) {
1725 // Disable VAD, NACK and FEC unless we know the other side wants them. 1778 // Disable VAD and FEC unless we know the other side wants them.
1726 engine()->voe()->codec()->SetVADStatus(channel, false); 1779 engine()->voe()->codec()->SetVADStatus(channel, false);
1727 engine()->voe()->rtp()->SetNACKStatus(channel, false, 0);
1728 engine()->voe()->codec()->SetFECStatus(channel, false); 1780 engine()->voe()->codec()->SetFECStatus(channel, false);
1729 1781
1730 SetNack(channel, send_codec_spec_.nack_enabled);
1731
1732 // Set the codec immediately, since SetVADStatus() depends on whether 1782 // Set the codec immediately, since SetVADStatus() depends on whether
1733 // the current codec is mono or stereo. 1783 // the current codec is mono or stereo.
1734 if (!SetSendCodec(channel, send_codec_spec_.codec_inst)) { 1784 if (!SetSendCodec(channel, send_codec_spec_.codec_inst)) {
1735 return false; 1785 return false;
1736 } 1786 }
1737 1787
1738 // FEC should be enabled after SetSendCodec. 1788 // FEC should be enabled after SetSendCodec.
1739 if (send_codec_spec_.enable_codec_fec) { 1789 if (send_codec_spec_.enable_codec_fec) {
1740 LOG(LS_INFO) << "Attempt to enable codec internal FEC on channel " 1790 LOG(LS_INFO) << "Attempt to enable codec internal FEC on channel "
1741 << channel; 1791 << channel;
(...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after
1970 if (channel == -1) { 2020 if (channel == -1) {
1971 return false; 2021 return false;
1972 } 2022 }
1973 2023
1974 // Save the channel to send_streams_, so that RemoveSendStream() can still 2024 // Save the channel to send_streams_, so that RemoveSendStream() can still
1975 // delete the channel in case failure happens below. 2025 // delete the channel in case failure happens below.
1976 webrtc::AudioTransport* audio_transport = 2026 webrtc::AudioTransport* audio_transport =
1977 engine()->voe()->base()->audio_transport(); 2027 engine()->voe()->base()->audio_transport();
1978 2028
1979 WebRtcAudioSendStream* stream = new WebRtcAudioSendStream( 2029 WebRtcAudioSendStream* stream = new WebRtcAudioSendStream(
1980 channel, audio_transport, ssrc, sp.cname, send_rtp_extensions_, call_, 2030 channel, audio_transport, ssrc, sp.cname, send_codec_spec_,
1981 this); 2031 send_rtp_extensions_, call_, this);
1982 send_streams_.insert(std::make_pair(ssrc, stream)); 2032 send_streams_.insert(std::make_pair(ssrc, stream));
1983 2033
1984 // Set the current codecs to be used for the new channel. We need to do this 2034 // Set the current codecs to be used for the new channel. We need to do this
1985 // after adding the channel to send_channels_, because of how max bitrate is 2035 // after adding the channel to send_channels_, because of how max bitrate is
1986 // currently being configured by SetSendCodec(). 2036 // currently being configured by SetSendCodec().
1987 if (HasSendCodec() && !SetSendCodecs(channel, stream->rtp_parameters())) { 2037 if (HasSendCodec() && !SetSendCodecs(channel, stream->rtp_parameters())) {
1988 RemoveSendStream(ssrc); 2038 RemoveSendStream(ssrc);
1989 return false; 2039 return false;
1990 } 2040 }
1991 2041
(...skipping 578 matching lines...) Expand 10 before | Expand all | Expand 10 after
2570 } 2620 }
2571 } else { 2621 } else {
2572 LOG(LS_INFO) << "Stopping playout for channel #" << channel; 2622 LOG(LS_INFO) << "Stopping playout for channel #" << channel;
2573 engine()->voe()->base()->StopPlayout(channel); 2623 engine()->voe()->base()->StopPlayout(channel);
2574 } 2624 }
2575 return true; 2625 return true;
2576 } 2626 }
2577 } // namespace cricket 2627 } // namespace cricket
2578 2628
2579 #endif // HAVE_WEBRTC_VOICE 2629 #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