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

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

Issue 1841083008: WebRtcVoiceEngine refactoring - moving codec configuration code into Send/RecvStreams (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Created 4 years, 8 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
« no previous file with comments | « webrtc/media/engine/webrtcvoiceengine.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 1122 matching lines...) Expand 10 before | Expand all | Expand 10 after
1133 } 1133 }
1134 1134
1135 int WebRtcVoiceEngine::CreateVoEChannel() { 1135 int WebRtcVoiceEngine::CreateVoEChannel() {
1136 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); 1136 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
1137 return voe_wrapper_->base()->CreateChannel(voe_config_); 1137 return voe_wrapper_->base()->CreateChannel(voe_config_);
1138 } 1138 }
1139 1139
1140 class WebRtcVoiceMediaChannel::WebRtcAudioSendStream 1140 class WebRtcVoiceMediaChannel::WebRtcAudioSendStream
1141 : public AudioSource::Sink { 1141 : public AudioSource::Sink {
1142 public: 1142 public:
1143 WebRtcAudioSendStream(int ch, webrtc::AudioTransport* voe_audio_transport, 1143 WebRtcAudioSendStream(int ch,
1144 uint32_t ssrc, const std::string& c_name, 1144 WebRtcVoiceEngine* engine,
the sun 2016/04/01 08:29:06 WebRtcAudioReceive/SendStream should be thin proxy
1145 webrtc::AudioTransport* voe_audio_transport,
1146 uint32_t ssrc,
1147 const std::string& c_name,
1145 const std::vector<webrtc::RtpExtension>& extensions, 1148 const std::vector<webrtc::RtpExtension>& extensions,
1146 webrtc::Call* call) 1149 webrtc::Call* call)
1147 : voe_audio_transport_(voe_audio_transport), 1150 : engine_(engine),
1151 voe_audio_transport_(voe_audio_transport),
1148 call_(call), 1152 call_(call),
1149 config_(nullptr) { 1153 config_(nullptr) {
1150 RTC_DCHECK_GE(ch, 0); 1154 RTC_DCHECK_GE(ch, 0);
1151 // TODO(solenberg): Once we're not using FakeWebRtcVoiceEngine anymore: 1155 // TODO(solenberg): Once we're not using FakeWebRtcVoiceEngine anymore:
1152 // RTC_DCHECK(voe_audio_transport); 1156 // RTC_DCHECK(voe_audio_transport);
1153 RTC_DCHECK(call); 1157 RTC_DCHECK(call);
1154 audio_capture_thread_checker_.DetachFromThread(); 1158 audio_capture_thread_checker_.DetachFromThread();
1155 config_.rtp.ssrc = ssrc; 1159 config_.rtp.ssrc = ssrc;
1156 config_.rtp.c_name = c_name; 1160 config_.rtp.c_name = c_name;
1157 config_.voe_channel_id = ch; 1161 config_.voe_channel_id = ch;
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
1250 source_ = nullptr; 1254 source_ = nullptr;
1251 UpdateSendState(); 1255 UpdateSendState();
1252 } 1256 }
1253 1257
1254 // Accessor to the VoE channel ID. 1258 // Accessor to the VoE channel ID.
1255 int channel() const { 1259 int channel() const {
1256 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); 1260 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
1257 return config_.voe_channel_id; 1261 return config_.voe_channel_id;
1258 } 1262 }
1259 1263
1264 bool SetSendCodecs(const WebRtcVoiceMediaChannel::SendCodecSpec& spec);
1265 bool SetSendCodec(const webrtc::CodecInst& send_codec);
1266 void SetNack(bool nack_enabled);
1267
1260 private: 1268 private:
1269 WebRtcVoiceEngine* engine() { return engine_; }
1270 int GetLastEngineError() { return engine()->GetLastEngineError(); }
1271
1261 void UpdateSendState() { 1272 void UpdateSendState() {
1262 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); 1273 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
1263 RTC_DCHECK(stream_); 1274 RTC_DCHECK(stream_);
1264 if (send_ && source_ != nullptr) { 1275 if (send_ && source_ != nullptr) {
1265 stream_->Start(); 1276 stream_->Start();
1266 } else { // !send || source_ = nullptr 1277 } else { // !send || source_ = nullptr
1267 stream_->Stop(); 1278 stream_->Stop();
1268 } 1279 }
1269 } 1280 }
1270 1281
1271 rtc::ThreadChecker worker_thread_checker_; 1282 rtc::ThreadChecker worker_thread_checker_;
1272 rtc::ThreadChecker audio_capture_thread_checker_; 1283 rtc::ThreadChecker audio_capture_thread_checker_;
1284 WebRtcVoiceEngine* engine_ = nullptr;
1273 webrtc::AudioTransport* const voe_audio_transport_ = nullptr; 1285 webrtc::AudioTransport* const voe_audio_transport_ = nullptr;
1274 webrtc::Call* call_ = nullptr; 1286 webrtc::Call* call_ = nullptr;
1275 webrtc::AudioSendStream::Config config_; 1287 webrtc::AudioSendStream::Config config_;
1276 // The stream is owned by WebRtcAudioSendStream and may be reallocated if 1288 // The stream is owned by WebRtcAudioSendStream and may be reallocated if
1277 // configuration changes. 1289 // configuration changes.
1278 webrtc::AudioSendStream* stream_ = nullptr; 1290 webrtc::AudioSendStream* stream_ = nullptr;
1279 1291
1280 // Raw pointer to AudioSource owned by LocalAudioTrackHandler. 1292 // Raw pointer to AudioSource owned by LocalAudioTrackHandler.
1281 // PeerConnection will make sure invalidating the pointer before the object 1293 // PeerConnection will make sure invalidating the pointer before the object
1282 // goes away. 1294 // goes away.
1283 AudioSource* source_ = nullptr; 1295 AudioSource* source_ = nullptr;
1284 bool send_ = false; 1296 bool send_ = false;
1285 1297
1298
1286 RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(WebRtcAudioSendStream); 1299 RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(WebRtcAudioSendStream);
1287 }; 1300 };
1288 1301
1289 class WebRtcVoiceMediaChannel::WebRtcAudioReceiveStream { 1302 class WebRtcVoiceMediaChannel::WebRtcAudioReceiveStream {
1290 public: 1303 public:
1291 WebRtcAudioReceiveStream(int ch, 1304 WebRtcAudioReceiveStream(int ch,
1305 WebRtcVoiceEngine* engine,
1292 uint32_t remote_ssrc, 1306 uint32_t remote_ssrc,
1293 uint32_t local_ssrc, 1307 uint32_t local_ssrc,
1294 bool use_transport_cc, 1308 bool use_transport_cc,
1295 const std::string& sync_group, 1309 const std::string& sync_group,
1296 const std::vector<webrtc::RtpExtension>& extensions, 1310 const std::vector<webrtc::RtpExtension>& extensions,
1297 webrtc::Call* call) 1311 webrtc::Call* call)
1298 : call_(call), config_() { 1312 : engine_(engine), call_(call), config_() {
1299 RTC_DCHECK_GE(ch, 0); 1313 RTC_DCHECK_GE(ch, 0);
1300 RTC_DCHECK(call); 1314 RTC_DCHECK(call);
1301 config_.rtp.remote_ssrc = remote_ssrc; 1315 config_.rtp.remote_ssrc = remote_ssrc;
1302 config_.rtp.local_ssrc = local_ssrc; 1316 config_.rtp.local_ssrc = local_ssrc;
1303 config_.voe_channel_id = ch; 1317 config_.voe_channel_id = ch;
1304 config_.sync_group = sync_group; 1318 config_.sync_group = sync_group;
1305 RecreateAudioReceiveStream(use_transport_cc, extensions); 1319 RecreateAudioReceiveStream(use_transport_cc, extensions);
1306 } 1320 }
1307 1321
1308 ~WebRtcAudioReceiveStream() { 1322 ~WebRtcAudioReceiveStream() {
(...skipping 20 matching lines...) Expand all
1329 int channel() const { 1343 int channel() const {
1330 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); 1344 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
1331 return config_.voe_channel_id; 1345 return config_.voe_channel_id;
1332 } 1346 }
1333 1347
1334 void SetRawAudioSink(std::unique_ptr<webrtc::AudioSinkInterface> sink) { 1348 void SetRawAudioSink(std::unique_ptr<webrtc::AudioSinkInterface> sink) {
1335 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); 1349 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
1336 stream_->SetSink(std::move(sink)); 1350 stream_->SetSink(std::move(sink));
1337 } 1351 }
1338 1352
1353 void SetNack(bool nack_enabled);
1354
1339 private: 1355 private:
1356 WebRtcVoiceEngine* engine() { return engine_; }
1340 void RecreateAudioReceiveStream( 1357 void RecreateAudioReceiveStream(
1341 bool use_transport_cc, 1358 bool use_transport_cc,
1342 const std::vector<webrtc::RtpExtension>& extensions) { 1359 const std::vector<webrtc::RtpExtension>& extensions) {
1343 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); 1360 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
1344 if (stream_) { 1361 if (stream_) {
1345 call_->DestroyAudioReceiveStream(stream_); 1362 call_->DestroyAudioReceiveStream(stream_);
1346 stream_ = nullptr; 1363 stream_ = nullptr;
1347 } 1364 }
1348 config_.rtp.extensions = extensions; 1365 config_.rtp.extensions = extensions;
1349 config_.rtp.transport_cc = use_transport_cc; 1366 config_.rtp.transport_cc = use_transport_cc;
1350 RTC_DCHECK(!stream_); 1367 RTC_DCHECK(!stream_);
1351 stream_ = call_->CreateAudioReceiveStream(config_); 1368 stream_ = call_->CreateAudioReceiveStream(config_);
1352 RTC_CHECK(stream_); 1369 RTC_CHECK(stream_);
1353 } 1370 }
1354 1371
1355 rtc::ThreadChecker worker_thread_checker_; 1372 rtc::ThreadChecker worker_thread_checker_;
1373 WebRtcVoiceEngine* engine_ = nullptr;
1356 webrtc::Call* call_ = nullptr; 1374 webrtc::Call* call_ = nullptr;
1357 webrtc::AudioReceiveStream::Config config_; 1375 webrtc::AudioReceiveStream::Config config_;
1358 // The stream is owned by WebRtcAudioReceiveStream and may be reallocated if 1376 // The stream is owned by WebRtcAudioReceiveStream and may be reallocated if
1359 // configuration changes. 1377 // configuration changes.
1360 webrtc::AudioReceiveStream* stream_ = nullptr; 1378 webrtc::AudioReceiveStream* stream_ = nullptr;
1361 1379
1362 RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(WebRtcAudioReceiveStream); 1380 RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(WebRtcAudioReceiveStream);
1363 }; 1381 };
1364 1382
1365 WebRtcVoiceMediaChannel::WebRtcVoiceMediaChannel(WebRtcVoiceEngine* engine, 1383 WebRtcVoiceMediaChannel::WebRtcVoiceMediaChannel(WebRtcVoiceEngine* engine,
(...skipping 273 matching lines...) Expand 10 before | Expand all | Expand 10 after
1639 break; 1657 break;
1640 } 1658 }
1641 } 1659 }
1642 1660
1643 // Latch in the new state. 1661 // Latch in the new state.
1644 send_codec_spec_ = std::move(send_codec_spec); 1662 send_codec_spec_ = std::move(send_codec_spec);
1645 } 1663 }
1646 1664
1647 // Cache the codecs in order to configure the channel created later. 1665 // Cache the codecs in order to configure the channel created later.
1648 for (const auto& ch : send_streams_) { 1666 for (const auto& ch : send_streams_) {
1649 if (!SetSendCodecs(ch.second->channel())) { 1667 if (!ch.second->SetSendCodecs(send_codec_spec_)) {
1650 return false; 1668 return false;
1651 } 1669 }
1652 } 1670 }
1653 1671
1672 if (send_bitrate_setting_) {
1673 SetSendBitrateInternal(send_bitrate_bps_);
1674 }
1675
1654 // Set nack status on receive channels. 1676 // Set nack status on receive channels.
1655 if (!send_streams_.empty()) { 1677 if (!send_streams_.empty()) {
1656 for (const auto& kv : recv_streams_) { 1678 for (const auto& kv : recv_streams_) {
1657 SetNack(kv.second->channel(), send_codec_spec_.nack_enabled); 1679 kv.second->SetNack(send_codec_spec_.nack_enabled);
1658 } 1680 }
1659 } 1681 }
1660 1682
1661 // Check if the transport cc feedback has changed on the preferred send codec, 1683 // Check if the transport cc feedback has changed on the preferred send codec,
1662 // and in that case reconfigure all receive streams. 1684 // and in that case reconfigure all receive streams.
1663 if (recv_transport_cc_enabled_ != send_codec_spec_.transport_cc_enabled) { 1685 if (recv_transport_cc_enabled_ != send_codec_spec_.transport_cc_enabled) {
1664 LOG(LS_INFO) << "Recreate all the receive streams because the send " 1686 LOG(LS_INFO) << "Recreate all the receive streams because the send "
1665 "codec has changed."; 1687 "codec has changed.";
1666 recv_transport_cc_enabled_ = send_codec_spec_.transport_cc_enabled; 1688 recv_transport_cc_enabled_ = send_codec_spec_.transport_cc_enabled;
1667 for (auto& kv : recv_streams_) { 1689 for (auto& kv : recv_streams_) {
1668 kv.second->RecreateAudioReceiveStream(recv_transport_cc_enabled_); 1690 kv.second->RecreateAudioReceiveStream(recv_transport_cc_enabled_);
1669 } 1691 }
1670 } 1692 }
1671 1693
1672 return true; 1694 return true;
1673 } 1695 }
1674 1696
1675 // Apply current codec settings to a single voe::Channel used for sending.
1676 bool WebRtcVoiceMediaChannel::SetSendCodecs(int channel) {
1677 // Disable VAD, FEC, and RED unless we know the other side wants them.
1678 engine()->voe()->codec()->SetVADStatus(channel, false);
1679 engine()->voe()->rtp()->SetNACKStatus(channel, false, 0);
1680 engine()->voe()->rtp()->SetREDStatus(channel, false);
1681 engine()->voe()->codec()->SetFECStatus(channel, false);
1682
1683 if (send_codec_spec_.red_payload_type != -1) {
1684 // Enable redundant encoding of the specified codec. Treat any
1685 // failure as a fatal internal error.
1686 LOG(LS_INFO) << "Enabling RED on channel " << channel;
1687 if (engine()->voe()->rtp()->SetREDStatus(channel, true,
1688 send_codec_spec_.red_payload_type) == -1) {
1689 LOG_RTCERR3(SetREDStatus, channel, true,
1690 send_codec_spec_.red_payload_type);
1691 return false;
1692 }
1693 }
1694
1695 SetNack(channel, send_codec_spec_.nack_enabled);
1696
1697 // Set the codec immediately, since SetVADStatus() depends on whether
1698 // the current codec is mono or stereo.
1699 if (!SetSendCodec(channel, send_codec_spec_.codec_inst)) {
1700 return false;
1701 }
1702
1703 // FEC should be enabled after SetSendCodec.
1704 if (send_codec_spec_.enable_codec_fec) {
1705 LOG(LS_INFO) << "Attempt to enable codec internal FEC on channel "
1706 << channel;
1707 if (engine()->voe()->codec()->SetFECStatus(channel, true) == -1) {
1708 // Enable codec internal FEC. Treat any failure as fatal internal error.
1709 LOG_RTCERR2(SetFECStatus, channel, true);
1710 return false;
1711 }
1712 }
1713
1714 if (IsCodec(send_codec_spec_.codec_inst, kOpusCodecName)) {
1715 // DTX and maxplaybackrate should be set after SetSendCodec. Because current
1716 // send codec has to be Opus.
1717
1718 // Set Opus internal DTX.
1719 LOG(LS_INFO) << "Attempt to "
1720 << (send_codec_spec_.enable_opus_dtx ? "enable" : "disable")
1721 << " Opus DTX on channel "
1722 << channel;
1723 if (engine()->voe()->codec()->SetOpusDtx(channel,
1724 send_codec_spec_.enable_opus_dtx)) {
1725 LOG_RTCERR2(SetOpusDtx, channel, send_codec_spec_.enable_opus_dtx);
1726 return false;
1727 }
1728
1729 // If opus_max_playback_rate <= 0, the default maximum playback rate
1730 // (48 kHz) will be used.
1731 if (send_codec_spec_.opus_max_playback_rate > 0) {
1732 LOG(LS_INFO) << "Attempt to set maximum playback rate to "
1733 << send_codec_spec_.opus_max_playback_rate
1734 << " Hz on channel "
1735 << channel;
1736 if (engine()->voe()->codec()->SetOpusMaxPlaybackRate(
1737 channel, send_codec_spec_.opus_max_playback_rate) == -1) {
1738 LOG_RTCERR2(SetOpusMaxPlaybackRate, channel,
1739 send_codec_spec_.opus_max_playback_rate);
1740 return false;
1741 }
1742 }
1743 }
1744
1745 if (send_bitrate_setting_) {
1746 SetSendBitrateInternal(send_bitrate_bps_);
1747 }
1748
1749 // Set the CN payloadtype and the VAD status.
1750 if (send_codec_spec_.cng_payload_type != -1) {
1751 // The CN payload type for 8000 Hz clockrate is fixed at 13.
1752 if (send_codec_spec_.cng_plfreq != 8000) {
1753 webrtc::PayloadFrequencies cn_freq;
1754 switch (send_codec_spec_.cng_plfreq) {
1755 case 16000:
1756 cn_freq = webrtc::kFreq16000Hz;
1757 break;
1758 case 32000:
1759 cn_freq = webrtc::kFreq32000Hz;
1760 break;
1761 default:
1762 RTC_NOTREACHED();
1763 return false;
1764 }
1765 if (engine()->voe()->codec()->SetSendCNPayloadType(
1766 channel, send_codec_spec_.cng_payload_type, cn_freq) == -1) {
1767 LOG_RTCERR3(SetSendCNPayloadType, channel,
1768 send_codec_spec_.cng_payload_type, cn_freq);
1769 // TODO(ajm): This failure condition will be removed from VoE.
1770 // Restore the return here when we update to a new enough webrtc.
1771 //
1772 // Not returning false because the SetSendCNPayloadType will fail if
1773 // the channel is already sending.
1774 // This can happen if the remote description is applied twice, for
1775 // example in the case of ROAP on top of JSEP, where both side will
1776 // send the offer.
1777 }
1778 }
1779
1780 // Only turn on VAD if we have a CN payload type that matches the
1781 // clockrate for the codec we are going to use.
1782 if (send_codec_spec_.cng_plfreq == send_codec_spec_.codec_inst.plfreq &&
1783 send_codec_spec_.codec_inst.channels == 1) {
1784 // TODO(minyue): If CN frequency == 48000 Hz is allowed, consider the
1785 // interaction between VAD and Opus FEC.
1786 LOG(LS_INFO) << "Enabling VAD";
1787 if (engine()->voe()->codec()->SetVADStatus(channel, true) == -1) {
1788 LOG_RTCERR2(SetVADStatus, channel, true);
1789 return false;
1790 }
1791 }
1792 }
1793 return true;
1794 }
1795
1796 void WebRtcVoiceMediaChannel::SetNack(int channel, bool nack_enabled) {
1797 if (nack_enabled) {
1798 LOG(LS_INFO) << "Enabling NACK for channel " << channel;
1799 engine()->voe()->rtp()->SetNACKStatus(channel, true, kNackMaxPackets);
1800 } else {
1801 LOG(LS_INFO) << "Disabling NACK for channel " << channel;
1802 engine()->voe()->rtp()->SetNACKStatus(channel, false, 0);
1803 }
1804 }
1805
1806 bool WebRtcVoiceMediaChannel::SetSendCodec(
1807 int channel, const webrtc::CodecInst& send_codec) {
1808 LOG(LS_INFO) << "Send channel " << channel << " selected voice codec "
1809 << ToString(send_codec) << ", bitrate=" << send_codec.rate;
1810
1811 webrtc::CodecInst current_codec = {0};
1812 if (engine()->voe()->codec()->GetSendCodec(channel, current_codec) == 0 &&
1813 (send_codec == current_codec)) {
1814 // Codec is already configured, we can return without setting it again.
1815 return true;
1816 }
1817
1818 if (engine()->voe()->codec()->SetSendCodec(channel, send_codec) == -1) {
1819 LOG_RTCERR2(SetSendCodec, channel, ToString(send_codec));
1820 return false;
1821 }
1822 return true;
1823 }
1824
1825 bool WebRtcVoiceMediaChannel::SetPlayout(bool playout) { 1697 bool WebRtcVoiceMediaChannel::SetPlayout(bool playout) {
1826 desired_playout_ = playout; 1698 desired_playout_ = playout;
1827 return ChangePlayout(desired_playout_); 1699 return ChangePlayout(desired_playout_);
1828 } 1700 }
1829 1701
1830 bool WebRtcVoiceMediaChannel::PausePlayout() { 1702 bool WebRtcVoiceMediaChannel::PausePlayout() {
1831 return ChangePlayout(false); 1703 return ChangePlayout(false);
1832 } 1704 }
1833 1705
1834 bool WebRtcVoiceMediaChannel::ResumePlayout() { 1706 bool WebRtcVoiceMediaChannel::ResumePlayout() {
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
1932 // Create a new channel for sending audio data. 1804 // Create a new channel for sending audio data.
1933 int channel = CreateVoEChannel(); 1805 int channel = CreateVoEChannel();
1934 if (channel == -1) { 1806 if (channel == -1) {
1935 return false; 1807 return false;
1936 } 1808 }
1937 1809
1938 // Save the channel to send_streams_, so that RemoveSendStream() can still 1810 // Save the channel to send_streams_, so that RemoveSendStream() can still
1939 // delete the channel in case failure happens below. 1811 // delete the channel in case failure happens below.
1940 webrtc::AudioTransport* audio_transport = 1812 webrtc::AudioTransport* audio_transport =
1941 engine()->voe()->base()->audio_transport(); 1813 engine()->voe()->base()->audio_transport();
1942 send_streams_.insert(std::make_pair(ssrc, new WebRtcAudioSendStream( 1814 WebRtcAudioSendStream* send_stream =
1943 channel, audio_transport, ssrc, sp.cname, send_rtp_extensions_, call_))); 1815 new WebRtcAudioSendStream(channel, engine(), audio_transport, ssrc,
1816 sp.cname, send_rtp_extensions_, call_);
1817 send_streams_.insert(std::make_pair(ssrc, send_stream));
1944 1818
1945 // Set the current codecs to be used for the new channel. We need to do this 1819 // Set the current codecs to be used for the new channel. We need to do this
1946 // after adding the channel to send_channels_, because of how max bitrate is 1820 // after adding the channel to send_channels_, because of how max bitrate is
1947 // currently being configured by SetSendCodec(). 1821 // currently being configured by SetSendCodec().
1948 if (HasSendCodec() && !SetSendCodecs(channel)) { 1822 if (HasSendCodec() && !send_stream->SetSendCodecs(send_codec_spec_)) {
1949 RemoveSendStream(ssrc); 1823 RemoveSendStream(ssrc);
1950 return false; 1824 return false;
1951 } 1825 }
1952 1826
1827 if (send_bitrate_setting_) {
1828 SetSendBitrateInternal(send_bitrate_bps_);
1829 }
1830
1953 // At this point the channel's local SSRC has been updated. If the channel is 1831 // At this point the channel's local SSRC has been updated. If the channel is
1954 // the first send channel make sure that all the receive channels are updated 1832 // the first send channel make sure that all the receive channels are updated
1955 // with the same SSRC in order to send receiver reports. 1833 // with the same SSRC in order to send receiver reports.
1956 if (send_streams_.size() == 1) { 1834 if (send_streams_.size() == 1) {
1957 receiver_reports_ssrc_ = ssrc; 1835 receiver_reports_ssrc_ = ssrc;
1958 for (const auto& stream : recv_streams_) { 1836 for (const auto& stream : recv_streams_) {
1959 int recv_channel = stream.second->channel(); 1837 int recv_channel = stream.second->channel();
1960 if (engine()->voe()->rtp()->SetLocalSSRC(recv_channel, ssrc) != 0) { 1838 if (engine()->voe()->rtp()->SetLocalSSRC(recv_channel, ssrc) != 0) {
1961 LOG_RTCERR2(SetLocalSSRC, recv_channel, ssrc); 1839 LOG_RTCERR2(SetLocalSSRC, recv_channel, ssrc);
1962 return false; 1840 return false;
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
2059 1937
2060 const int send_channel = GetSendChannelId(receiver_reports_ssrc_); 1938 const int send_channel = GetSendChannelId(receiver_reports_ssrc_);
2061 if (send_channel != -1) { 1939 if (send_channel != -1) {
2062 // Associate receive channel with first send channel (so the receive channel 1940 // Associate receive channel with first send channel (so the receive channel
2063 // can obtain RTT from the send channel) 1941 // can obtain RTT from the send channel)
2064 engine()->voe()->base()->AssociateSendChannel(channel, send_channel); 1942 engine()->voe()->base()->AssociateSendChannel(channel, send_channel);
2065 LOG(LS_INFO) << "VoiceEngine channel #" << channel 1943 LOG(LS_INFO) << "VoiceEngine channel #" << channel
2066 << " is associated with channel #" << send_channel << "."; 1944 << " is associated with channel #" << send_channel << ".";
2067 } 1945 }
2068 1946
2069 recv_streams_.insert(std::make_pair( 1947 WebRtcAudioReceiveStream* recv_stream = new WebRtcAudioReceiveStream(
2070 ssrc, new WebRtcAudioReceiveStream(channel, ssrc, receiver_reports_ssrc_, 1948 channel, engine(), ssrc, receiver_reports_ssrc_,
2071 recv_transport_cc_enabled_, 1949 recv_transport_cc_enabled_, sp.sync_label, recv_rtp_extensions_, call_);
2072 sp.sync_label, recv_rtp_extensions_, 1950 recv_streams_.insert(std::make_pair(ssrc, recv_stream));
2073 call_)));
2074 1951
2075 SetNack(channel, send_codec_spec_.nack_enabled); 1952 recv_stream->SetNack(send_codec_spec_.nack_enabled);
2076 SetPlayout(channel, playout_); 1953 SetPlayout(channel, playout_);
2077 1954
2078 return true; 1955 return true;
2079 } 1956 }
2080 1957
2081 bool WebRtcVoiceMediaChannel::RemoveRecvStream(uint32_t ssrc) { 1958 bool WebRtcVoiceMediaChannel::RemoveRecvStream(uint32_t ssrc) {
2082 TRACE_EVENT0("webrtc", "WebRtcVoiceMediaChannel::RemoveRecvStream"); 1959 TRACE_EVENT0("webrtc", "WebRtcVoiceMediaChannel::RemoveRecvStream");
2083 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); 1960 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
2084 LOG(LS_INFO) << "RemoveRecvStream: " << ssrc; 1961 LOG(LS_INFO) << "RemoveRecvStream: " << ssrc;
2085 1962
(...skipping 308 matching lines...) Expand 10 before | Expand all | Expand 10 after
2394 if (bps <= 0) 2271 if (bps <= 0)
2395 return true; 2272 return true;
2396 2273
2397 webrtc::CodecInst codec = send_codec_spec_.codec_inst; 2274 webrtc::CodecInst codec = send_codec_spec_.codec_inst;
2398 bool is_multi_rate = WebRtcVoiceCodecs::IsCodecMultiRate(codec); 2275 bool is_multi_rate = WebRtcVoiceCodecs::IsCodecMultiRate(codec);
2399 2276
2400 if (is_multi_rate) { 2277 if (is_multi_rate) {
2401 // If codec is multi-rate then just set the bitrate. 2278 // If codec is multi-rate then just set the bitrate.
2402 codec.rate = bps; 2279 codec.rate = bps;
2403 for (const auto& ch : send_streams_) { 2280 for (const auto& ch : send_streams_) {
2404 if (!SetSendCodec(ch.second->channel(), codec)) { 2281 if (!ch.second->SetSendCodec(codec)) {
2405 LOG(LS_INFO) << "Failed to set codec " << codec.plname 2282 LOG(LS_INFO) << "Failed to set codec " << codec.plname
2406 << " to bitrate " << bps << " bps."; 2283 << " to bitrate " << bps << " bps.";
2407 return false; 2284 return false;
2408 } 2285 }
2409 } 2286 }
2410 return true; 2287 return true;
2411 } else { 2288 } else {
2412 // If codec is not multi-rate and |bps| is less than the fixed bitrate 2289 // If codec is not multi-rate and |bps| is less than the fixed bitrate
2413 // then fail. If codec is not multi-rate and |bps| exceeds or equal the 2290 // then fail. If codec is not multi-rate and |bps| exceeds or equal the
2414 // fixed bitrate then ignore. 2291 // fixed bitrate then ignore.
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after
2548 if (engine()->voe()->base()->StartPlayout(channel) == -1) { 2425 if (engine()->voe()->base()->StartPlayout(channel) == -1) {
2549 LOG_RTCERR1(StartPlayout, channel); 2426 LOG_RTCERR1(StartPlayout, channel);
2550 return false; 2427 return false;
2551 } 2428 }
2552 } else { 2429 } else {
2553 LOG(LS_INFO) << "Stopping playout for channel #" << channel; 2430 LOG(LS_INFO) << "Stopping playout for channel #" << channel;
2554 engine()->voe()->base()->StopPlayout(channel); 2431 engine()->voe()->base()->StopPlayout(channel);
2555 } 2432 }
2556 return true; 2433 return true;
2557 } 2434 }
2435
2436 // Apply current codec settings to a single voe::Channel used for sending.
2437 bool WebRtcVoiceMediaChannel::WebRtcAudioSendStream::SetSendCodecs(
2438 const WebRtcVoiceMediaChannel::SendCodecSpec& send_codec_spec) {
2439 // Disable VAD, FEC, and RED unless we know the other side wants them.
2440 engine()->voe()->codec()->SetVADStatus(channel(), false);
2441 engine()->voe()->rtp()->SetNACKStatus(channel(), false, 0);
2442 engine()->voe()->rtp()->SetREDStatus(channel(), false);
2443 engine()->voe()->codec()->SetFECStatus(channel(), false);
2444
2445 if (send_codec_spec.red_payload_type != -1) {
2446 // Enable redundant encoding of the specified codec. Treat any
2447 // failure as a fatal internal error.
2448 LOG(LS_INFO) << "Enabling RED on channel " << channel();
2449 if (engine()->voe()->rtp()->SetREDStatus(
2450 channel(), true, send_codec_spec.red_payload_type) == -1) {
2451 LOG_RTCERR3(SetREDStatus, channel(), true,
2452 send_codec_spec.red_payload_type);
2453 return false;
2454 }
2455 }
2456
2457 SetNack(send_codec_spec.nack_enabled);
2458
2459 // Set the codec immediately, since SetVADStatus() depends on whether
2460 // the current codec is mono or stereo.
2461 if (!SetSendCodec(send_codec_spec.codec_inst)) {
2462 return false;
2463 }
2464
2465 // FEC should be enabled after SetSendCodec.
2466 if (send_codec_spec.enable_codec_fec) {
2467 LOG(LS_INFO) << "Attempt to enable codec internal FEC on channel "
2468 << channel();
2469 if (engine()->voe()->codec()->SetFECStatus(channel(), true) == -1) {
2470 // Enable codec internal FEC. Treat any failure as fatal internal error.
2471 LOG_RTCERR2(SetFECStatus, channel(), true);
2472 return false;
2473 }
2474 }
2475
2476 if (IsCodec(send_codec_spec.codec_inst, kOpusCodecName)) {
2477 // DTX and maxplaybackrate should be set after SetSendCodec. Because current
2478 // send codec has to be Opus.
2479
2480 // Set Opus internal DTX.
2481 LOG(LS_INFO) << "Attempt to "
2482 << (send_codec_spec.enable_opus_dtx ? "enable" : "disable")
2483 << " Opus DTX on channel " << channel();
2484 if (engine()->voe()->codec()->SetOpusDtx(
2485 channel(), send_codec_spec.enable_opus_dtx)) {
2486 LOG_RTCERR2(SetOpusDtx, channel(), send_codec_spec.enable_opus_dtx);
2487 return false;
2488 }
2489
2490 // If opus_max_playback_rate <= 0, the default maximum playback rate
2491 // (48 kHz) will be used.
2492 if (send_codec_spec.opus_max_playback_rate > 0) {
2493 LOG(LS_INFO) << "Attempt to set maximum playback rate to "
2494 << send_codec_spec.opus_max_playback_rate
2495 << " Hz on channel " << channel();
2496 if (engine()->voe()->codec()->SetOpusMaxPlaybackRate(
2497 channel(), send_codec_spec.opus_max_playback_rate) == -1) {
2498 LOG_RTCERR2(SetOpusMaxPlaybackRate, channel(),
2499 send_codec_spec.opus_max_playback_rate);
2500 return false;
2501 }
2502 }
2503 }
2504
2505 // Set the CN payloadtype and the VAD status.
2506 if (send_codec_spec.cng_payload_type != -1) {
2507 // The CN payload type for 8000 Hz clockrate is fixed at 13.
2508 if (send_codec_spec.cng_plfreq != 8000) {
2509 webrtc::PayloadFrequencies cn_freq;
2510 switch (send_codec_spec.cng_plfreq) {
2511 case 16000:
2512 cn_freq = webrtc::kFreq16000Hz;
2513 break;
2514 case 32000:
2515 cn_freq = webrtc::kFreq32000Hz;
2516 break;
2517 default:
2518 RTC_NOTREACHED();
2519 return false;
2520 }
2521 if (engine()->voe()->codec()->SetSendCNPayloadType(
2522 channel(), send_codec_spec.cng_payload_type, cn_freq) == -1) {
2523 LOG_RTCERR3(SetSendCNPayloadType, channel(),
2524 send_codec_spec.cng_payload_type, cn_freq);
2525 // TODO(ajm): This failure condition will be removed from VoE.
2526 // Restore the return here when we update to a new enough webrtc.
2527 //
2528 // Not returning false because the SetSendCNPayloadType will fail if
2529 // the channel is already sending.
2530 // This can happen if the remote description is applied twice, for
2531 // example in the case of ROAP on top of JSEP, where both side will
2532 // send the offer.
2533 }
2534 }
2535
2536 // Only turn on VAD if we have a CN payload type that matches the
2537 // clockrate for the codec we are going to use.
2538 if (send_codec_spec.cng_plfreq == send_codec_spec.codec_inst.plfreq &&
2539 send_codec_spec.codec_inst.channels == 1) {
2540 // TODO(minyue): If CN frequency == 48000 Hz is allowed, consider the
2541 // interaction between VAD and Opus FEC.
2542 LOG(LS_INFO) << "Enabling VAD";
2543 if (engine()->voe()->codec()->SetVADStatus(channel(), true) == -1) {
2544 LOG_RTCERR2(SetVADStatus, channel(), true);
2545 return false;
2546 }
2547 }
2548 }
2549 return true;
2550 }
2551
2552 bool WebRtcVoiceMediaChannel::WebRtcAudioSendStream::SetSendCodec(
2553 const webrtc::CodecInst& send_codec) {
2554 LOG(LS_INFO) << "Send channel " << channel() << " selected voice codec "
2555 << ToString(send_codec) << ", bitrate=" << send_codec.rate;
2556
2557 webrtc::CodecInst current_codec = {0};
2558 if (engine()->voe()->codec()->GetSendCodec(channel(), current_codec) == 0 &&
2559 (send_codec == current_codec)) {
2560 // Codec is already configured, we can return without setting it again.
2561 return true;
2562 }
2563
2564 if (engine()->voe()->codec()->SetSendCodec(channel(), send_codec) == -1) {
2565 LOG_RTCERR2(SetSendCodec, channel(), ToString(send_codec));
2566 return false;
2567 }
2568 return true;
2569 }
2570
2571 void WebRtcVoiceMediaChannel::WebRtcAudioSendStream::SetNack(
2572 bool nack_enabled) {
2573 if (nack_enabled) {
2574 LOG(LS_INFO) << "Enabling NACK for channel " << channel();
2575 engine()->voe()->rtp()->SetNACKStatus(channel(), true, kNackMaxPackets);
2576 } else {
2577 LOG(LS_INFO) << "Disabling NACK for channel " << channel();
2578 engine()->voe()->rtp()->SetNACKStatus(channel(), false, 0);
2579 }
2580 }
2581
2582 void WebRtcVoiceMediaChannel::WebRtcAudioReceiveStream::SetNack(
2583 bool nack_enabled) {
2584 if (nack_enabled) {
2585 LOG(LS_INFO) << "Enabling NACK for channel " << channel();
2586 engine()->voe()->rtp()->SetNACKStatus(channel(), true, kNackMaxPackets);
2587 } else {
2588 LOG(LS_INFO) << "Disabling NACK for channel " << channel();
2589 engine()->voe()->rtp()->SetNACKStatus(channel(), false, 0);
2590 }
2591 }
2592
2558 } // namespace cricket 2593 } // namespace cricket
2559 2594
2560 #endif // HAVE_WEBRTC_VOICE 2595 #endif // HAVE_WEBRTC_VOICE
OLDNEW
« no previous file with comments | « webrtc/media/engine/webrtcvoiceengine.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698