OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |