| 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 |