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 const int kNackRtpHistoryMs = 5000; | 64 const 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 1247 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1324 | 1321 |
1325 RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(WebRtcAudioSendStream); | 1322 RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(WebRtcAudioSendStream); |
1326 }; | 1323 }; |
1327 | 1324 |
1328 class WebRtcVoiceMediaChannel::WebRtcAudioReceiveStream { | 1325 class WebRtcVoiceMediaChannel::WebRtcAudioReceiveStream { |
1329 public: | 1326 public: |
1330 WebRtcAudioReceiveStream(int ch, | 1327 WebRtcAudioReceiveStream(int ch, |
1331 uint32_t remote_ssrc, | 1328 uint32_t remote_ssrc, |
1332 uint32_t local_ssrc, | 1329 uint32_t local_ssrc, |
1333 bool use_transport_cc, | 1330 bool use_transport_cc, |
| 1331 bool use_nack, |
1334 const std::string& sync_group, | 1332 const std::string& sync_group, |
1335 const std::vector<webrtc::RtpExtension>& extensions, | 1333 const std::vector<webrtc::RtpExtension>& extensions, |
1336 webrtc::Call* call, | 1334 webrtc::Call* call, |
1337 webrtc::Transport* rtcp_send_transport) | 1335 webrtc::Transport* rtcp_send_transport) |
1338 : call_(call), config_() { | 1336 : call_(call), config_() { |
1339 RTC_DCHECK_GE(ch, 0); | 1337 RTC_DCHECK_GE(ch, 0); |
1340 RTC_DCHECK(call); | 1338 RTC_DCHECK(call); |
1341 config_.rtp.remote_ssrc = remote_ssrc; | 1339 config_.rtp.remote_ssrc = remote_ssrc; |
1342 config_.rtp.local_ssrc = local_ssrc; | 1340 config_.rtp.local_ssrc = local_ssrc; |
1343 config_.rtcp_send_transport = rtcp_send_transport; | 1341 config_.rtcp_send_transport = rtcp_send_transport; |
1344 config_.voe_channel_id = ch; | 1342 config_.voe_channel_id = ch; |
1345 config_.sync_group = sync_group; | 1343 config_.sync_group = sync_group; |
1346 RecreateAudioReceiveStream(use_transport_cc, extensions); | 1344 RecreateAudioReceiveStream(use_transport_cc, use_nack, extensions); |
1347 } | 1345 } |
1348 | 1346 |
1349 ~WebRtcAudioReceiveStream() { | 1347 ~WebRtcAudioReceiveStream() { |
1350 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 1348 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
1351 call_->DestroyAudioReceiveStream(stream_); | 1349 call_->DestroyAudioReceiveStream(stream_); |
1352 } | 1350 } |
1353 | 1351 |
1354 void RecreateAudioReceiveStream( | 1352 void RecreateAudioReceiveStream( |
1355 const std::vector<webrtc::RtpExtension>& extensions) { | 1353 const std::vector<webrtc::RtpExtension>& extensions) { |
1356 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 1354 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
1357 RecreateAudioReceiveStream(config_.rtp.transport_cc, extensions); | 1355 RecreateAudioReceiveStream(config_.rtp.transport_cc, |
| 1356 config_.rtp.nack.rtp_history_ms, |
| 1357 extensions); |
1358 } | 1358 } |
1359 void RecreateAudioReceiveStream(bool use_transport_cc) { | 1359 |
| 1360 void RecreateAudioReceiveStream(bool use_transport_cc, bool use_nack) { |
1360 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 1361 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
1361 RecreateAudioReceiveStream(use_transport_cc, config_.rtp.extensions); | 1362 RecreateAudioReceiveStream(use_transport_cc, |
| 1363 use_nack, |
| 1364 config_.rtp.extensions); |
1362 } | 1365 } |
1363 | 1366 |
1364 webrtc::AudioReceiveStream::Stats GetStats() const { | 1367 webrtc::AudioReceiveStream::Stats GetStats() const { |
1365 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 1368 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
1366 RTC_DCHECK(stream_); | 1369 RTC_DCHECK(stream_); |
1367 return stream_->GetStats(); | 1370 return stream_->GetStats(); |
1368 } | 1371 } |
1369 | 1372 |
1370 int channel() const { | 1373 int channel() const { |
1371 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 1374 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
1372 return config_.voe_channel_id; | 1375 return config_.voe_channel_id; |
1373 } | 1376 } |
1374 | 1377 |
1375 void SetRawAudioSink(std::unique_ptr<webrtc::AudioSinkInterface> sink) { | 1378 void SetRawAudioSink(std::unique_ptr<webrtc::AudioSinkInterface> sink) { |
1376 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 1379 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
1377 stream_->SetSink(std::move(sink)); | 1380 stream_->SetSink(std::move(sink)); |
1378 } | 1381 } |
1379 | 1382 |
1380 private: | 1383 private: |
1381 void RecreateAudioReceiveStream( | 1384 void RecreateAudioReceiveStream( |
1382 bool use_transport_cc, | 1385 bool use_transport_cc, |
| 1386 bool use_nack, |
1383 const std::vector<webrtc::RtpExtension>& extensions) { | 1387 const std::vector<webrtc::RtpExtension>& extensions) { |
1384 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 1388 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
1385 if (stream_) { | 1389 if (stream_) { |
1386 call_->DestroyAudioReceiveStream(stream_); | 1390 call_->DestroyAudioReceiveStream(stream_); |
1387 stream_ = nullptr; | 1391 stream_ = nullptr; |
1388 } | 1392 } |
| 1393 config_.rtp.transport_cc = use_transport_cc; |
| 1394 config_.rtp.nack.rtp_history_ms = use_nack ? kNackRtpHistoryMs : 0; |
1389 config_.rtp.extensions = extensions; | 1395 config_.rtp.extensions = extensions; |
1390 config_.rtp.transport_cc = use_transport_cc; | |
1391 RTC_DCHECK(!stream_); | 1396 RTC_DCHECK(!stream_); |
1392 stream_ = call_->CreateAudioReceiveStream(config_); | 1397 stream_ = call_->CreateAudioReceiveStream(config_); |
1393 RTC_CHECK(stream_); | 1398 RTC_CHECK(stream_); |
1394 } | 1399 } |
1395 | 1400 |
1396 rtc::ThreadChecker worker_thread_checker_; | 1401 rtc::ThreadChecker worker_thread_checker_; |
1397 webrtc::Call* call_ = nullptr; | 1402 webrtc::Call* call_ = nullptr; |
1398 webrtc::AudioReceiveStream::Config config_; | 1403 webrtc::AudioReceiveStream::Config config_; |
1399 // The stream is owned by WebRtcAudioReceiveStream and may be reallocated if | 1404 // The stream is owned by WebRtcAudioReceiveStream and may be reallocated if |
1400 // configuration changes. | 1405 // configuration changes. |
(...skipping 389 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1790 if (send_codec_spec_ != send_codec_spec) { | 1795 if (send_codec_spec_ != send_codec_spec) { |
1791 send_codec_spec_ = std::move(send_codec_spec); | 1796 send_codec_spec_ = std::move(send_codec_spec); |
1792 for (const auto& kv : send_streams_) { | 1797 for (const auto& kv : send_streams_) { |
1793 kv.second->RecreateAudioSendStream(send_codec_spec_); | 1798 kv.second->RecreateAudioSendStream(send_codec_spec_); |
1794 if (!SetSendCodecs(kv.second->channel(), kv.second->rtp_parameters())) { | 1799 if (!SetSendCodecs(kv.second->channel(), kv.second->rtp_parameters())) { |
1795 return false; | 1800 return false; |
1796 } | 1801 } |
1797 } | 1802 } |
1798 } | 1803 } |
1799 | 1804 |
1800 // Set nack status on receive channels. | 1805 // Check if the transport cc feedback or NACK status has changed on the |
1801 for (const auto& kv : recv_streams_) { | 1806 // preferred send codec, and in that case reconfigure all receive streams. |
1802 SetNack(kv.second->channel(), send_codec_spec_.nack_enabled); | 1807 if (recv_transport_cc_enabled_ != send_codec_spec_.transport_cc_enabled || |
1803 } | 1808 recv_nack_enabled_ != send_codec_spec_.nack_enabled) { |
1804 | |
1805 // Check if the transport cc feedback has changed on the preferred send codec, | |
1806 // and in that case reconfigure all receive streams. | |
1807 if (recv_transport_cc_enabled_ != send_codec_spec_.transport_cc_enabled) { | |
1808 LOG(LS_INFO) << "Recreate all the receive streams because the send " | 1809 LOG(LS_INFO) << "Recreate all the receive streams because the send " |
1809 "codec has changed."; | 1810 "codec has changed."; |
1810 recv_transport_cc_enabled_ = send_codec_spec_.transport_cc_enabled; | 1811 recv_transport_cc_enabled_ = send_codec_spec_.transport_cc_enabled; |
| 1812 recv_nack_enabled_ = send_codec_spec_.nack_enabled; |
1811 for (auto& kv : recv_streams_) { | 1813 for (auto& kv : recv_streams_) { |
1812 kv.second->RecreateAudioReceiveStream(recv_transport_cc_enabled_); | 1814 kv.second->RecreateAudioReceiveStream(recv_transport_cc_enabled_, |
| 1815 recv_nack_enabled_); |
1813 } | 1816 } |
1814 } | 1817 } |
1815 | 1818 |
1816 send_codecs_ = codecs; | 1819 send_codecs_ = codecs; |
1817 return true; | 1820 return true; |
1818 } | 1821 } |
1819 | 1822 |
1820 // Apply current codec settings to a single voe::Channel used for sending. | 1823 // Apply current codec settings to a single voe::Channel used for sending. |
1821 bool WebRtcVoiceMediaChannel::SetSendCodecs( | 1824 bool WebRtcVoiceMediaChannel::SetSendCodecs( |
1822 int channel, | 1825 int channel, |
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1929 LOG(LS_INFO) << "Enabling VAD"; | 1932 LOG(LS_INFO) << "Enabling VAD"; |
1930 if (engine()->voe()->codec()->SetVADStatus(channel, true) == -1) { | 1933 if (engine()->voe()->codec()->SetVADStatus(channel, true) == -1) { |
1931 LOG_RTCERR2(SetVADStatus, channel, true); | 1934 LOG_RTCERR2(SetVADStatus, channel, true); |
1932 return false; | 1935 return false; |
1933 } | 1936 } |
1934 } | 1937 } |
1935 } | 1938 } |
1936 return true; | 1939 return true; |
1937 } | 1940 } |
1938 | 1941 |
1939 void WebRtcVoiceMediaChannel::SetNack(int channel, bool nack_enabled) { | |
1940 if (nack_enabled) { | |
1941 LOG(LS_INFO) << "Enabling NACK for channel " << channel; | |
1942 engine()->voe()->rtp()->SetNACKStatus(channel, true, kNackMaxPackets); | |
1943 } else { | |
1944 LOG(LS_INFO) << "Disabling NACK for channel " << channel; | |
1945 engine()->voe()->rtp()->SetNACKStatus(channel, false, 0); | |
1946 } | |
1947 } | |
1948 | |
1949 bool WebRtcVoiceMediaChannel::SetSendCodec( | 1942 bool WebRtcVoiceMediaChannel::SetSendCodec( |
1950 int channel, const webrtc::CodecInst& send_codec) { | 1943 int channel, const webrtc::CodecInst& send_codec) { |
1951 LOG(LS_INFO) << "Send channel " << channel << " selected voice codec " | 1944 LOG(LS_INFO) << "Send channel " << channel << " selected voice codec " |
1952 << ToString(send_codec) << ", bitrate=" << send_codec.rate; | 1945 << ToString(send_codec) << ", bitrate=" << send_codec.rate; |
1953 | 1946 |
1954 webrtc::CodecInst current_codec = {0}; | 1947 webrtc::CodecInst current_codec = {0}; |
1955 if (engine()->voe()->codec()->GetSendCodec(channel, current_codec) == 0 && | 1948 if (engine()->voe()->codec()->GetSendCodec(channel, current_codec) == 0 && |
1956 (send_codec == current_codec)) { | 1949 (send_codec == current_codec)) { |
1957 // Codec is already configured, we can return without setting it again. | 1950 // Codec is already configured, we can return without setting it again. |
1958 return true; | 1951 return true; |
(...skipping 251 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2210 // Associate receive channel with first send channel (so the receive channel | 2203 // Associate receive channel with first send channel (so the receive channel |
2211 // can obtain RTT from the send channel) | 2204 // can obtain RTT from the send channel) |
2212 engine()->voe()->base()->AssociateSendChannel(channel, send_channel); | 2205 engine()->voe()->base()->AssociateSendChannel(channel, send_channel); |
2213 LOG(LS_INFO) << "VoiceEngine channel #" << channel | 2206 LOG(LS_INFO) << "VoiceEngine channel #" << channel |
2214 << " is associated with channel #" << send_channel << "."; | 2207 << " is associated with channel #" << send_channel << "."; |
2215 } | 2208 } |
2216 | 2209 |
2217 recv_streams_.insert(std::make_pair( | 2210 recv_streams_.insert(std::make_pair( |
2218 ssrc, new WebRtcAudioReceiveStream(channel, ssrc, receiver_reports_ssrc_, | 2211 ssrc, new WebRtcAudioReceiveStream(channel, ssrc, receiver_reports_ssrc_, |
2219 recv_transport_cc_enabled_, | 2212 recv_transport_cc_enabled_, |
| 2213 recv_nack_enabled_, |
2220 sp.sync_label, recv_rtp_extensions_, | 2214 sp.sync_label, recv_rtp_extensions_, |
2221 call_, this))); | 2215 call_, this))); |
2222 | |
2223 SetNack(channel, send_codec_spec_.nack_enabled); | |
2224 SetPlayout(channel, playout_); | 2216 SetPlayout(channel, playout_); |
2225 | 2217 |
2226 return true; | 2218 return true; |
2227 } | 2219 } |
2228 | 2220 |
2229 bool WebRtcVoiceMediaChannel::RemoveRecvStream(uint32_t ssrc) { | 2221 bool WebRtcVoiceMediaChannel::RemoveRecvStream(uint32_t ssrc) { |
2230 TRACE_EVENT0("webrtc", "WebRtcVoiceMediaChannel::RemoveRecvStream"); | 2222 TRACE_EVENT0("webrtc", "WebRtcVoiceMediaChannel::RemoveRecvStream"); |
2231 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 2223 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
2232 LOG(LS_INFO) << "RemoveRecvStream: " << ssrc; | 2224 LOG(LS_INFO) << "RemoveRecvStream: " << ssrc; |
2233 | 2225 |
(...skipping 444 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2678 } | 2670 } |
2679 } else { | 2671 } else { |
2680 LOG(LS_INFO) << "Stopping playout for channel #" << channel; | 2672 LOG(LS_INFO) << "Stopping playout for channel #" << channel; |
2681 engine()->voe()->base()->StopPlayout(channel); | 2673 engine()->voe()->base()->StopPlayout(channel); |
2682 } | 2674 } |
2683 return true; | 2675 return true; |
2684 } | 2676 } |
2685 } // namespace cricket | 2677 } // namespace cricket |
2686 | 2678 |
2687 #endif // HAVE_WEBRTC_VOICE | 2679 #endif // HAVE_WEBRTC_VOICE |
OLD | NEW |