| 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 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 54 // devices (old Wave Audio style default and Default Communications Device). | 54 // devices (old Wave Audio style default and Default Communications Device). |
| 55 // | 55 // |
| 56 // On Windows systems which only support Wave Audio style default, uses either | 56 // On Windows systems which only support Wave Audio style default, uses either |
| 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. | |
| 65 // This value is equivalent to 5 seconds of audio data at 20 ms per packet. | |
| 66 const int kNackMaxPackets = 250; | |
| 67 constexpr int kNackRtpHistoryMs = 5000; | 64 constexpr int kNackRtpHistoryMs = 5000; |
| 68 | 65 |
| 69 // Codec parameters for Opus. | 66 // Codec parameters for Opus. |
| 70 // draft-spittka-payload-rtp-opus-03 | 67 // draft-spittka-payload-rtp-opus-03 |
| 71 | 68 |
| 72 // Recommended bitrates: | 69 // Recommended bitrates: |
| 73 // 8-12 kb/s for NB speech, | 70 // 8-12 kb/s for NB speech, |
| 74 // 16-20 kb/s for WB speech, | 71 // 16-20 kb/s for WB speech, |
| 75 // 28-40 kb/s for FB speech, | 72 // 28-40 kb/s for FB speech, |
| 76 // 48-64 kb/s for FB mono music, and | 73 // 48-64 kb/s for FB mono music, and |
| (...skipping 1183 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1260 RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(WebRtcAudioSendStream); | 1257 RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(WebRtcAudioSendStream); |
| 1261 }; | 1258 }; |
| 1262 | 1259 |
| 1263 class WebRtcVoiceMediaChannel::WebRtcAudioReceiveStream { | 1260 class WebRtcVoiceMediaChannel::WebRtcAudioReceiveStream { |
| 1264 public: | 1261 public: |
| 1265 WebRtcAudioReceiveStream( | 1262 WebRtcAudioReceiveStream( |
| 1266 int ch, | 1263 int ch, |
| 1267 uint32_t remote_ssrc, | 1264 uint32_t remote_ssrc, |
| 1268 uint32_t local_ssrc, | 1265 uint32_t local_ssrc, |
| 1269 bool use_transport_cc, | 1266 bool use_transport_cc, |
| 1267 bool use_nack, |
| 1270 const std::string& sync_group, | 1268 const std::string& sync_group, |
| 1271 const std::vector<webrtc::RtpExtension>& extensions, | 1269 const std::vector<webrtc::RtpExtension>& extensions, |
| 1272 webrtc::Call* call, | 1270 webrtc::Call* call, |
| 1273 webrtc::Transport* rtcp_send_transport, | 1271 webrtc::Transport* rtcp_send_transport, |
| 1274 const rtc::scoped_refptr<webrtc::AudioDecoderFactory>& decoder_factory) | 1272 const rtc::scoped_refptr<webrtc::AudioDecoderFactory>& decoder_factory) |
| 1275 : call_(call), config_() { | 1273 : call_(call), config_() { |
| 1276 RTC_DCHECK_GE(ch, 0); | 1274 RTC_DCHECK_GE(ch, 0); |
| 1277 RTC_DCHECK(call); | 1275 RTC_DCHECK(call); |
| 1278 config_.rtp.remote_ssrc = remote_ssrc; | 1276 config_.rtp.remote_ssrc = remote_ssrc; |
| 1279 config_.rtp.local_ssrc = local_ssrc; | 1277 config_.rtp.local_ssrc = local_ssrc; |
| 1280 config_.rtcp_send_transport = rtcp_send_transport; | 1278 config_.rtcp_send_transport = rtcp_send_transport; |
| 1281 config_.voe_channel_id = ch; | 1279 config_.voe_channel_id = ch; |
| 1282 config_.sync_group = sync_group; | 1280 config_.sync_group = sync_group; |
| 1283 config_.decoder_factory = decoder_factory; | 1281 config_.decoder_factory = decoder_factory; |
| 1284 RecreateAudioReceiveStream(use_transport_cc, extensions); | 1282 RecreateAudioReceiveStream(use_transport_cc, use_nack, extensions); |
| 1285 } | 1283 } |
| 1286 | 1284 |
| 1287 ~WebRtcAudioReceiveStream() { | 1285 ~WebRtcAudioReceiveStream() { |
| 1288 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 1286 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
| 1289 call_->DestroyAudioReceiveStream(stream_); | 1287 call_->DestroyAudioReceiveStream(stream_); |
| 1290 } | 1288 } |
| 1291 | 1289 |
| 1292 void RecreateAudioReceiveStream( | 1290 void RecreateAudioReceiveStream( |
| 1293 const std::vector<webrtc::RtpExtension>& extensions) { | 1291 const std::vector<webrtc::RtpExtension>& extensions) { |
| 1294 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 1292 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
| 1295 RecreateAudioReceiveStream(config_.rtp.transport_cc, extensions); | 1293 RecreateAudioReceiveStream(config_.rtp.transport_cc, |
| 1294 config_.rtp.nack.rtp_history_ms != 0, |
| 1295 extensions); |
| 1296 } | 1296 } |
| 1297 void RecreateAudioReceiveStream(bool use_transport_cc) { | 1297 |
| 1298 void RecreateAudioReceiveStream(bool use_transport_cc, bool use_nack) { |
| 1298 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 1299 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
| 1299 RecreateAudioReceiveStream(use_transport_cc, config_.rtp.extensions); | 1300 RecreateAudioReceiveStream(use_transport_cc, |
| 1301 use_nack, |
| 1302 config_.rtp.extensions); |
| 1300 } | 1303 } |
| 1301 | 1304 |
| 1302 webrtc::AudioReceiveStream::Stats GetStats() const { | 1305 webrtc::AudioReceiveStream::Stats GetStats() const { |
| 1303 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 1306 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
| 1304 RTC_DCHECK(stream_); | 1307 RTC_DCHECK(stream_); |
| 1305 return stream_->GetStats(); | 1308 return stream_->GetStats(); |
| 1306 } | 1309 } |
| 1307 | 1310 |
| 1308 int channel() const { | 1311 int channel() const { |
| 1309 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 1312 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
| 1310 return config_.voe_channel_id; | 1313 return config_.voe_channel_id; |
| 1311 } | 1314 } |
| 1312 | 1315 |
| 1313 void SetRawAudioSink(std::unique_ptr<webrtc::AudioSinkInterface> sink) { | 1316 void SetRawAudioSink(std::unique_ptr<webrtc::AudioSinkInterface> sink) { |
| 1314 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 1317 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
| 1315 stream_->SetSink(std::move(sink)); | 1318 stream_->SetSink(std::move(sink)); |
| 1316 } | 1319 } |
| 1317 | 1320 |
| 1318 private: | 1321 private: |
| 1319 void RecreateAudioReceiveStream( | 1322 void RecreateAudioReceiveStream( |
| 1320 bool use_transport_cc, | 1323 bool use_transport_cc, |
| 1324 bool use_nack, |
| 1321 const std::vector<webrtc::RtpExtension>& extensions) { | 1325 const std::vector<webrtc::RtpExtension>& extensions) { |
| 1322 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 1326 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
| 1323 if (stream_) { | 1327 if (stream_) { |
| 1324 call_->DestroyAudioReceiveStream(stream_); | 1328 call_->DestroyAudioReceiveStream(stream_); |
| 1325 stream_ = nullptr; | 1329 stream_ = nullptr; |
| 1326 } | 1330 } |
| 1331 config_.rtp.transport_cc = use_transport_cc; |
| 1332 config_.rtp.nack.rtp_history_ms = use_nack ? kNackRtpHistoryMs : 0; |
| 1327 config_.rtp.extensions = extensions; | 1333 config_.rtp.extensions = extensions; |
| 1328 config_.rtp.transport_cc = use_transport_cc; | |
| 1329 RTC_DCHECK(!stream_); | 1334 RTC_DCHECK(!stream_); |
| 1330 stream_ = call_->CreateAudioReceiveStream(config_); | 1335 stream_ = call_->CreateAudioReceiveStream(config_); |
| 1331 RTC_CHECK(stream_); | 1336 RTC_CHECK(stream_); |
| 1332 } | 1337 } |
| 1333 | 1338 |
| 1334 rtc::ThreadChecker worker_thread_checker_; | 1339 rtc::ThreadChecker worker_thread_checker_; |
| 1335 webrtc::Call* call_ = nullptr; | 1340 webrtc::Call* call_ = nullptr; |
| 1336 webrtc::AudioReceiveStream::Config config_; | 1341 webrtc::AudioReceiveStream::Config config_; |
| 1337 // The stream is owned by WebRtcAudioReceiveStream and may be reallocated if | 1342 // The stream is owned by WebRtcAudioReceiveStream and may be reallocated if |
| 1338 // configuration changes. | 1343 // configuration changes. |
| (...skipping 384 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1723 if (send_codec_spec_ != send_codec_spec) { | 1728 if (send_codec_spec_ != send_codec_spec) { |
| 1724 send_codec_spec_ = std::move(send_codec_spec); | 1729 send_codec_spec_ = std::move(send_codec_spec); |
| 1725 for (const auto& kv : send_streams_) { | 1730 for (const auto& kv : send_streams_) { |
| 1726 kv.second->RecreateAudioSendStream(send_codec_spec_); | 1731 kv.second->RecreateAudioSendStream(send_codec_spec_); |
| 1727 if (!SetSendCodecs(kv.second->channel(), kv.second->rtp_parameters())) { | 1732 if (!SetSendCodecs(kv.second->channel(), kv.second->rtp_parameters())) { |
| 1728 return false; | 1733 return false; |
| 1729 } | 1734 } |
| 1730 } | 1735 } |
| 1731 } | 1736 } |
| 1732 | 1737 |
| 1733 // Set nack status on receive channels. | 1738 // Check if the transport cc feedback or NACK status has changed on the |
| 1734 for (const auto& kv : recv_streams_) { | 1739 // preferred send codec, and in that case reconfigure all receive streams. |
| 1735 SetNack(kv.second->channel(), send_codec_spec_.nack_enabled); | 1740 if (recv_transport_cc_enabled_ != send_codec_spec_.transport_cc_enabled || |
| 1736 } | 1741 recv_nack_enabled_ != send_codec_spec_.nack_enabled) { |
| 1737 | |
| 1738 // Check if the transport cc feedback has changed on the preferred send codec, | |
| 1739 // and in that case reconfigure all receive streams. | |
| 1740 if (recv_transport_cc_enabled_ != send_codec_spec_.transport_cc_enabled) { | |
| 1741 LOG(LS_INFO) << "Recreate all the receive streams because the send " | 1742 LOG(LS_INFO) << "Recreate all the receive streams because the send " |
| 1742 "codec has changed."; | 1743 "codec has changed."; |
| 1743 recv_transport_cc_enabled_ = send_codec_spec_.transport_cc_enabled; | 1744 recv_transport_cc_enabled_ = send_codec_spec_.transport_cc_enabled; |
| 1745 recv_nack_enabled_ = send_codec_spec_.nack_enabled; |
| 1744 for (auto& kv : recv_streams_) { | 1746 for (auto& kv : recv_streams_) { |
| 1745 kv.second->RecreateAudioReceiveStream(recv_transport_cc_enabled_); | 1747 kv.second->RecreateAudioReceiveStream(recv_transport_cc_enabled_, |
| 1748 recv_nack_enabled_); |
| 1746 } | 1749 } |
| 1747 } | 1750 } |
| 1748 | 1751 |
| 1749 send_codecs_ = codecs; | 1752 send_codecs_ = codecs; |
| 1750 return true; | 1753 return true; |
| 1751 } | 1754 } |
| 1752 | 1755 |
| 1753 // Apply current codec settings to a single voe::Channel used for sending. | 1756 // Apply current codec settings to a single voe::Channel used for sending. |
| 1754 bool WebRtcVoiceMediaChannel::SetSendCodecs( | 1757 bool WebRtcVoiceMediaChannel::SetSendCodecs( |
| 1755 int channel, | 1758 int channel, |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1849 LOG(LS_INFO) << "Enabling VAD"; | 1852 LOG(LS_INFO) << "Enabling VAD"; |
| 1850 if (engine()->voe()->codec()->SetVADStatus(channel, true) == -1) { | 1853 if (engine()->voe()->codec()->SetVADStatus(channel, true) == -1) { |
| 1851 LOG_RTCERR2(SetVADStatus, channel, true); | 1854 LOG_RTCERR2(SetVADStatus, channel, true); |
| 1852 return false; | 1855 return false; |
| 1853 } | 1856 } |
| 1854 } | 1857 } |
| 1855 } | 1858 } |
| 1856 return true; | 1859 return true; |
| 1857 } | 1860 } |
| 1858 | 1861 |
| 1859 void WebRtcVoiceMediaChannel::SetNack(int channel, bool nack_enabled) { | |
| 1860 if (nack_enabled) { | |
| 1861 LOG(LS_INFO) << "Enabling NACK for channel " << channel; | |
| 1862 engine()->voe()->rtp()->SetNACKStatus(channel, true, kNackMaxPackets); | |
| 1863 } else { | |
| 1864 LOG(LS_INFO) << "Disabling NACK for channel " << channel; | |
| 1865 engine()->voe()->rtp()->SetNACKStatus(channel, false, 0); | |
| 1866 } | |
| 1867 } | |
| 1868 | |
| 1869 bool WebRtcVoiceMediaChannel::SetSendCodec( | 1862 bool WebRtcVoiceMediaChannel::SetSendCodec( |
| 1870 int channel, const webrtc::CodecInst& send_codec) { | 1863 int channel, const webrtc::CodecInst& send_codec) { |
| 1871 LOG(LS_INFO) << "Send channel " << channel << " selected voice codec " | 1864 LOG(LS_INFO) << "Send channel " << channel << " selected voice codec " |
| 1872 << ToString(send_codec) << ", bitrate=" << send_codec.rate; | 1865 << ToString(send_codec) << ", bitrate=" << send_codec.rate; |
| 1873 | 1866 |
| 1874 webrtc::CodecInst current_codec = {0}; | 1867 webrtc::CodecInst current_codec = {0}; |
| 1875 if (engine()->voe()->codec()->GetSendCodec(channel, current_codec) == 0 && | 1868 if (engine()->voe()->codec()->GetSendCodec(channel, current_codec) == 0 && |
| 1876 (send_codec == current_codec)) { | 1869 (send_codec == current_codec)) { |
| 1877 // Codec is already configured, we can return without setting it again. | 1870 // Codec is already configured, we can return without setting it again. |
| 1878 return true; | 1871 return true; |
| (...skipping 251 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2130 // Associate receive channel with first send channel (so the receive channel | 2123 // Associate receive channel with first send channel (so the receive channel |
| 2131 // can obtain RTT from the send channel) | 2124 // can obtain RTT from the send channel) |
| 2132 engine()->voe()->base()->AssociateSendChannel(channel, send_channel); | 2125 engine()->voe()->base()->AssociateSendChannel(channel, send_channel); |
| 2133 LOG(LS_INFO) << "VoiceEngine channel #" << channel | 2126 LOG(LS_INFO) << "VoiceEngine channel #" << channel |
| 2134 << " is associated with channel #" << send_channel << "."; | 2127 << " is associated with channel #" << send_channel << "."; |
| 2135 } | 2128 } |
| 2136 | 2129 |
| 2137 recv_streams_.insert(std::make_pair( | 2130 recv_streams_.insert(std::make_pair( |
| 2138 ssrc, new WebRtcAudioReceiveStream(channel, ssrc, receiver_reports_ssrc_, | 2131 ssrc, new WebRtcAudioReceiveStream(channel, ssrc, receiver_reports_ssrc_, |
| 2139 recv_transport_cc_enabled_, | 2132 recv_transport_cc_enabled_, |
| 2133 recv_nack_enabled_, |
| 2140 sp.sync_label, recv_rtp_extensions_, | 2134 sp.sync_label, recv_rtp_extensions_, |
| 2141 call_, this, | 2135 call_, this, |
| 2142 engine()->decoder_factory_))); | 2136 engine()->decoder_factory_))); |
| 2143 | |
| 2144 SetNack(channel, send_codec_spec_.nack_enabled); | |
| 2145 SetPlayout(channel, playout_); | 2137 SetPlayout(channel, playout_); |
| 2146 | 2138 |
| 2147 return true; | 2139 return true; |
| 2148 } | 2140 } |
| 2149 | 2141 |
| 2150 bool WebRtcVoiceMediaChannel::RemoveRecvStream(uint32_t ssrc) { | 2142 bool WebRtcVoiceMediaChannel::RemoveRecvStream(uint32_t ssrc) { |
| 2151 TRACE_EVENT0("webrtc", "WebRtcVoiceMediaChannel::RemoveRecvStream"); | 2143 TRACE_EVENT0("webrtc", "WebRtcVoiceMediaChannel::RemoveRecvStream"); |
| 2152 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 2144 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
| 2153 LOG(LS_INFO) << "RemoveRecvStream: " << ssrc; | 2145 LOG(LS_INFO) << "RemoveRecvStream: " << ssrc; |
| 2154 | 2146 |
| (...skipping 444 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2599 } | 2591 } |
| 2600 } else { | 2592 } else { |
| 2601 LOG(LS_INFO) << "Stopping playout for channel #" << channel; | 2593 LOG(LS_INFO) << "Stopping playout for channel #" << channel; |
| 2602 engine()->voe()->base()->StopPlayout(channel); | 2594 engine()->voe()->base()->StopPlayout(channel); |
| 2603 } | 2595 } |
| 2604 return true; | 2596 return true; |
| 2605 } | 2597 } |
| 2606 } // namespace cricket | 2598 } // namespace cricket |
| 2607 | 2599 |
| 2608 #endif // HAVE_WEBRTC_VOICE | 2600 #endif // HAVE_WEBRTC_VOICE |
| OLD | NEW |