OLD | NEW |
---|---|
1 /* | 1 /* |
2 * libjingle | 2 * libjingle |
3 * Copyright 2004 Google Inc. | 3 * Copyright 2004 Google Inc. |
4 * | 4 * |
5 * Redistribution and use in source and binary forms, with or without | 5 * Redistribution and use in source and binary forms, with or without |
6 * modification, are permitted provided that the following conditions are met: | 6 * modification, are permitted provided that the following conditions are met: |
7 * | 7 * |
8 * 1. Redistributions of source code must retain the above copyright notice, | 8 * 1. Redistributions of source code must retain the above copyright notice, |
9 * this list of conditions and the following disclaimer. | 9 * this list of conditions and the following disclaimer. |
10 * 2. Redistributions in binary form must reproduce the above copyright notice, | 10 * 2. Redistributions in binary form must reproduce the above copyright notice, |
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
141 // NOTE(ajm): Don't use hardcoded paths on platforms not explicitly specified | 141 // NOTE(ajm): Don't use hardcoded paths on platforms not explicitly specified |
142 // below. | 142 // below. |
143 #if defined(CHROMEOS) | 143 #if defined(CHROMEOS) |
144 const char kAecDumpByAudioOptionFilename[] = "/tmp/audio.aecdump"; | 144 const char kAecDumpByAudioOptionFilename[] = "/tmp/audio.aecdump"; |
145 #elif defined(ANDROID) | 145 #elif defined(ANDROID) |
146 const char kAecDumpByAudioOptionFilename[] = "/sdcard/audio.aecdump"; | 146 const char kAecDumpByAudioOptionFilename[] = "/sdcard/audio.aecdump"; |
147 #else | 147 #else |
148 const char kAecDumpByAudioOptionFilename[] = "audio.aecdump"; | 148 const char kAecDumpByAudioOptionFilename[] = "audio.aecdump"; |
149 #endif | 149 #endif |
150 | 150 |
151 // See: https://code.google.com/p/webrtc/issues/detail?id=4740 | |
152 const int kDefaultRtcpReceiverReportSsrc = 1; | |
153 | |
151 bool ValidateStreamParams(const StreamParams& sp) { | 154 bool ValidateStreamParams(const StreamParams& sp) { |
152 if (sp.ssrcs.empty()) { | 155 if (sp.ssrcs.empty()) { |
153 LOG(LS_ERROR) << "No SSRCs in stream parameters: " << sp.ToString(); | 156 LOG(LS_ERROR) << "No SSRCs in stream parameters: " << sp.ToString(); |
154 return false; | 157 return false; |
155 } | 158 } |
156 if (sp.ssrcs.size() > 1) { | 159 if (sp.ssrcs.size() > 1) { |
157 LOG(LS_ERROR) << "Multiple SSRCs in stream parameters: " << sp.ToString(); | 160 LOG(LS_ERROR) << "Multiple SSRCs in stream parameters: " << sp.ToString(); |
158 return false; | 161 return false; |
159 } | 162 } |
160 return true; | 163 return true; |
(...skipping 423 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
584 LOG(LS_INFO) << "WebRtcVoiceEngine::Terminate"; | 587 LOG(LS_INFO) << "WebRtcVoiceEngine::Terminate"; |
585 initialized_ = false; | 588 initialized_ = false; |
586 | 589 |
587 StopAecDump(); | 590 StopAecDump(); |
588 | 591 |
589 voe_wrapper_->base()->Terminate(); | 592 voe_wrapper_->base()->Terminate(); |
590 } | 593 } |
591 | 594 |
592 VoiceMediaChannel* WebRtcVoiceEngine::CreateChannel(webrtc::Call* call, | 595 VoiceMediaChannel* WebRtcVoiceEngine::CreateChannel(webrtc::Call* call, |
593 const AudioOptions& options) { | 596 const AudioOptions& options) { |
594 WebRtcVoiceMediaChannel* ch = | 597 return new WebRtcVoiceMediaChannel(this, options, call); |
595 new WebRtcVoiceMediaChannel(this, options, call); | |
596 if (!ch->valid()) { | |
597 delete ch; | |
598 return nullptr; | |
599 } | |
600 return ch; | |
601 } | 598 } |
602 | 599 |
603 bool WebRtcVoiceEngine::SetOptions(const AudioOptions& options) { | 600 bool WebRtcVoiceEngine::SetOptions(const AudioOptions& options) { |
604 if (!ApplyOptions(options)) { | 601 if (!ApplyOptions(options)) { |
605 return false; | 602 return false; |
606 } | 603 } |
607 options_ = options; | 604 options_ = options; |
608 return true; | 605 return true; |
609 } | 606 } |
610 | 607 |
(...skipping 682 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1293 if (is_dumping_aec_) { | 1290 if (is_dumping_aec_) { |
1294 // Stop dumping AEC when we are dumping. | 1291 // Stop dumping AEC when we are dumping. |
1295 if (voe_wrapper_->processing()->StopDebugRecording() != | 1292 if (voe_wrapper_->processing()->StopDebugRecording() != |
1296 webrtc::AudioProcessing::kNoError) { | 1293 webrtc::AudioProcessing::kNoError) { |
1297 LOG_RTCERR0(StopDebugRecording); | 1294 LOG_RTCERR0(StopDebugRecording); |
1298 } | 1295 } |
1299 is_dumping_aec_ = false; | 1296 is_dumping_aec_ = false; |
1300 } | 1297 } |
1301 } | 1298 } |
1302 | 1299 |
1303 int WebRtcVoiceEngine::CreateVoiceChannel(VoEWrapper* voice_engine_wrapper) { | 1300 int WebRtcVoiceEngine::CreateVoEChannel() { |
1304 return voice_engine_wrapper->base()->CreateChannel(voe_config_); | 1301 return voe_wrapper_->base()->CreateChannel(voe_config_); |
1305 } | |
1306 | |
1307 int WebRtcVoiceEngine::CreateMediaVoiceChannel() { | |
1308 return CreateVoiceChannel(voe_wrapper_.get()); | |
1309 } | 1302 } |
1310 | 1303 |
1311 class WebRtcVoiceMediaChannel::WebRtcVoiceChannelRenderer | 1304 class WebRtcVoiceMediaChannel::WebRtcVoiceChannelRenderer |
1312 : public AudioRenderer::Sink { | 1305 : public AudioRenderer::Sink { |
1313 public: | 1306 public: |
1314 WebRtcVoiceChannelRenderer(int ch, | 1307 WebRtcVoiceChannelRenderer(int ch, |
1315 webrtc::AudioTransport* voe_audio_transport) | 1308 webrtc::AudioTransport* voe_audio_transport) |
1316 : channel_(ch), | 1309 : channel_(ch), |
1317 voe_audio_transport_(voe_audio_transport), | 1310 voe_audio_transport_(voe_audio_transport), |
1318 renderer_(NULL) {} | 1311 renderer_(NULL) {} |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1382 | 1375 |
1383 // Protects |renderer_| in Start(), Stop() and OnClose(). | 1376 // Protects |renderer_| in Start(), Stop() and OnClose(). |
1384 rtc::CriticalSection lock_; | 1377 rtc::CriticalSection lock_; |
1385 }; | 1378 }; |
1386 | 1379 |
1387 // WebRtcVoiceMediaChannel | 1380 // WebRtcVoiceMediaChannel |
1388 WebRtcVoiceMediaChannel::WebRtcVoiceMediaChannel(WebRtcVoiceEngine* engine, | 1381 WebRtcVoiceMediaChannel::WebRtcVoiceMediaChannel(WebRtcVoiceEngine* engine, |
1389 const AudioOptions& options, | 1382 const AudioOptions& options, |
1390 webrtc::Call* call) | 1383 webrtc::Call* call) |
1391 : engine_(engine), | 1384 : engine_(engine), |
1392 default_send_channel_id_(engine->CreateMediaVoiceChannel()), | |
1393 send_bitrate_setting_(false), | 1385 send_bitrate_setting_(false), |
1394 send_bitrate_bps_(0), | 1386 send_bitrate_bps_(0), |
1395 options_(), | 1387 options_(), |
1396 dtmf_allowed_(false), | 1388 dtmf_allowed_(false), |
1397 desired_playout_(false), | 1389 desired_playout_(false), |
1398 nack_enabled_(false), | 1390 nack_enabled_(false), |
1399 playout_(false), | 1391 playout_(false), |
1400 typing_noise_detected_(false), | 1392 typing_noise_detected_(false), |
1401 desired_send_(SEND_NOTHING), | 1393 desired_send_(SEND_NOTHING), |
1402 send_(SEND_NOTHING), | 1394 send_(SEND_NOTHING), |
1403 call_(call) { | 1395 call_(call) { |
1404 RTC_DCHECK(thread_checker_.CalledOnValidThread()); | 1396 RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
1397 LOG(LS_VERBOSE) << "WebRtcVoiceMediaChannel::WebRtcVoiceMediaChannel"; | |
1398 RTC_DCHECK(nullptr != call); | |
1405 engine->RegisterChannel(this); | 1399 engine->RegisterChannel(this); |
1406 LOG(LS_VERBOSE) << "WebRtcVoiceMediaChannel::WebRtcVoiceMediaChannel " | |
1407 << default_send_channel_id(); | |
1408 RTC_DCHECK(nullptr != call); | |
1409 ConfigureSendChannel(default_send_channel_id()); | |
1410 SetOptions(options); | 1400 SetOptions(options); |
1411 } | 1401 } |
1412 | 1402 |
1413 WebRtcVoiceMediaChannel::~WebRtcVoiceMediaChannel() { | 1403 WebRtcVoiceMediaChannel::~WebRtcVoiceMediaChannel() { |
1414 RTC_DCHECK(thread_checker_.CalledOnValidThread()); | 1404 RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
1415 LOG(LS_VERBOSE) << "WebRtcVoiceMediaChannel::~WebRtcVoiceMediaChannel " | 1405 LOG(LS_VERBOSE) << "WebRtcVoiceMediaChannel::~WebRtcVoiceMediaChannel"; |
1416 << default_send_channel_id(); | |
1417 | 1406 |
1418 // Remove any remaining send streams, the default channel will be deleted | 1407 // Remove any remaining send streams. |
1419 // later. | |
1420 while (!send_channels_.empty()) { | 1408 while (!send_channels_.empty()) { |
1421 RemoveSendStream(send_channels_.begin()->first); | 1409 RemoveSendStream(send_channels_.begin()->first); |
1422 } | 1410 } |
1423 | 1411 |
1424 // Unregister ourselves from the engine. | 1412 // Remove any remaining receive streams. |
1425 engine()->UnregisterChannel(this); | |
1426 | |
1427 // Remove any remaining streams. | |
1428 while (!receive_channels_.empty()) { | 1413 while (!receive_channels_.empty()) { |
1429 RemoveRecvStream(receive_channels_.begin()->first); | 1414 RemoveRecvStream(receive_channels_.begin()->first); |
1430 } | 1415 } |
1431 RTC_DCHECK(receive_streams_.empty()); | 1416 RTC_DCHECK(receive_streams_.empty()); |
1432 | 1417 |
1433 // Delete the default channel. | 1418 // Unregister ourselves from the engine. |
1434 DeleteChannel(default_send_channel_id()); | 1419 engine()->UnregisterChannel(this); |
1435 } | 1420 } |
1436 | 1421 |
1437 bool WebRtcVoiceMediaChannel::SetSendParameters( | 1422 bool WebRtcVoiceMediaChannel::SetSendParameters( |
1438 const AudioSendParameters& params) { | 1423 const AudioSendParameters& params) { |
1439 RTC_DCHECK(thread_checker_.CalledOnValidThread()); | 1424 RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
1440 // TODO(pthatcher): Refactor this to be more clean now that we have | 1425 // TODO(pthatcher): Refactor this to be more clean now that we have |
1441 // all the information at once. | 1426 // all the information at once. |
1442 return (SetSendCodecs(params.codecs) && | 1427 return (SetSendCodecs(params.codecs) && |
1443 SetSendRtpHeaderExtensions(params.extensions) && | 1428 SetSendRtpHeaderExtensions(params.extensions) && |
1444 SetMaxSendBandwidth(params.max_bandwidth_bps) && | 1429 SetMaxSendBandwidth(params.max_bandwidth_bps) && |
(...skipping 318 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1763 | 1748 |
1764 // Cache the codecs in order to configure the channel created later. | 1749 // Cache the codecs in order to configure the channel created later. |
1765 send_codecs_ = codecs; | 1750 send_codecs_ = codecs; |
1766 for (const auto& ch : send_channels_) { | 1751 for (const auto& ch : send_channels_) { |
1767 if (!SetSendCodecs(ch.second->channel(), codecs)) { | 1752 if (!SetSendCodecs(ch.second->channel(), codecs)) { |
1768 return false; | 1753 return false; |
1769 } | 1754 } |
1770 } | 1755 } |
1771 | 1756 |
1772 // Set nack status on receive channels and update |nack_enabled_|. | 1757 // Set nack status on receive channels and update |nack_enabled_|. |
1773 SetNack(receive_channels_, nack_enabled_); | 1758 for (const auto& ch : receive_channels_) { |
1759 SetNack(ch.second->channel(), nack_enabled_); | |
1760 } | |
1761 | |
1774 return true; | 1762 return true; |
1775 } | 1763 } |
1776 | 1764 |
1777 void WebRtcVoiceMediaChannel::SetNack(const ChannelMap& channels, | |
1778 bool nack_enabled) { | |
1779 for (const auto& ch : channels) { | |
1780 SetNack(ch.second->channel(), nack_enabled); | |
1781 } | |
1782 } | |
1783 | |
1784 void WebRtcVoiceMediaChannel::SetNack(int channel, bool nack_enabled) { | 1765 void WebRtcVoiceMediaChannel::SetNack(int channel, bool nack_enabled) { |
1785 if (nack_enabled) { | 1766 if (nack_enabled) { |
1786 LOG(LS_INFO) << "Enabling NACK for channel " << channel; | 1767 LOG(LS_INFO) << "Enabling NACK for channel " << channel; |
1787 engine()->voe()->rtp()->SetNACKStatus(channel, true, kNackMaxPackets); | 1768 engine()->voe()->rtp()->SetNACKStatus(channel, true, kNackMaxPackets); |
1788 } else { | 1769 } else { |
1789 LOG(LS_INFO) << "Disabling NACK for channel " << channel; | 1770 LOG(LS_INFO) << "Disabling NACK for channel " << channel; |
1790 engine()->voe()->rtp()->SetNACKStatus(channel, false, 0); | 1771 engine()->voe()->rtp()->SetNACKStatus(channel, false, 0); |
1791 } | 1772 } |
1792 } | 1773 } |
1793 | 1774 |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1883 return true; | 1864 return true; |
1884 } | 1865 } |
1885 | 1866 |
1886 bool WebRtcVoiceMediaChannel::SetSendRtpHeaderExtensions( | 1867 bool WebRtcVoiceMediaChannel::SetSendRtpHeaderExtensions( |
1887 const std::vector<RtpHeaderExtension>& extensions) { | 1868 const std::vector<RtpHeaderExtension>& extensions) { |
1888 RTC_DCHECK(thread_checker_.CalledOnValidThread()); | 1869 RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
1889 if (send_extensions_ == extensions) { | 1870 if (send_extensions_ == extensions) { |
1890 return true; | 1871 return true; |
1891 } | 1872 } |
1892 | 1873 |
1893 // The default channel may or may not be in |send_channels_|. Set the rtp | |
1894 // header extensions for default channel regardless. | |
1895 | |
1896 if (!SetChannelSendRtpHeaderExtensions(default_send_channel_id(), | |
1897 extensions)) { | |
1898 return false; | |
1899 } | |
1900 | |
1901 // Loop through all send channels and enable/disable the extensions. | |
1902 for (const auto& ch : send_channels_) { | 1874 for (const auto& ch : send_channels_) { |
1903 if (!SetChannelSendRtpHeaderExtensions(ch.second->channel(), extensions)) { | 1875 if (!SetChannelSendRtpHeaderExtensions(ch.second->channel(), extensions)) { |
1904 return false; | 1876 return false; |
1905 } | 1877 } |
1906 } | 1878 } |
1907 | 1879 |
1908 send_extensions_ = extensions; | 1880 send_extensions_ = extensions; |
1909 return true; | 1881 return true; |
1910 } | 1882 } |
1911 | 1883 |
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2033 } | 2005 } |
2034 if (!MuteStream(ssrc, !enable)) { | 2006 if (!MuteStream(ssrc, !enable)) { |
2035 return false; | 2007 return false; |
2036 } | 2008 } |
2037 if (enable && options) { | 2009 if (enable && options) { |
2038 return SetOptions(*options); | 2010 return SetOptions(*options); |
2039 } | 2011 } |
2040 return true; | 2012 return true; |
2041 } | 2013 } |
2042 | 2014 |
2043 // TODO(ronghuawu): Change this method to return bool. | 2015 int WebRtcVoiceMediaChannel::CreateVoEChannel() { |
2044 void WebRtcVoiceMediaChannel::ConfigureSendChannel(int channel) { | 2016 int id = engine()->CreateVoEChannel(); |
2045 if (engine()->voe()->network()->RegisterExternalTransport( | 2017 if (id == -1) { |
2046 channel, *this) == -1) { | 2018 LOG_RTCERR0(CreateVoEChannel); |
2047 LOG_RTCERR2(RegisterExternalTransport, channel, this); | 2019 return -1; |
2048 } | 2020 } |
2049 | 2021 if (engine()->voe()->network()->RegisterExternalTransport(id, *this) == -1) { |
2050 // Enable RTCP (for quality stats and feedback messages) | 2022 LOG_RTCERR2(RegisterExternalTransport, id, this); |
2051 EnableRtcp(channel); | 2023 engine()->voe()->base()->DeleteChannel(id); |
2052 | 2024 return -1; |
2053 // Set RTP header extension for the new channel. | 2025 } |
2054 SetChannelSendRtpHeaderExtensions(channel, send_extensions_); | 2026 return id; |
2055 } | 2027 } |
2056 | 2028 |
2057 bool WebRtcVoiceMediaChannel::DeleteChannel(int channel) { | 2029 bool WebRtcVoiceMediaChannel::DeleteChannel(int channel) { |
2058 if (engine()->voe()->network()->DeRegisterExternalTransport(channel) == -1) { | 2030 if (engine()->voe()->network()->DeRegisterExternalTransport(channel) == -1) { |
2059 LOG_RTCERR1(DeRegisterExternalTransport, channel); | 2031 LOG_RTCERR1(DeRegisterExternalTransport, channel); |
2060 } | 2032 } |
2061 | |
2062 if (engine()->voe()->base()->DeleteChannel(channel) == -1) { | 2033 if (engine()->voe()->base()->DeleteChannel(channel) == -1) { |
2063 LOG_RTCERR1(DeleteChannel, channel); | 2034 LOG_RTCERR1(DeleteChannel, channel); |
2064 return false; | 2035 return false; |
2065 } | 2036 } |
2066 | |
2067 return true; | 2037 return true; |
2068 } | 2038 } |
2069 | 2039 |
2070 bool WebRtcVoiceMediaChannel::AddSendStream(const StreamParams& sp) { | 2040 bool WebRtcVoiceMediaChannel::AddSendStream(const StreamParams& sp) { |
2071 RTC_DCHECK(thread_checker_.CalledOnValidThread()); | 2041 RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
2072 // If the default channel is already used for sending create a new channel | 2042 uint32_t ssrc = sp.first_ssrc(); |
2073 // otherwise use the default channel for sending. | 2043 RTC_DCHECK(0 != ssrc); |
2074 int channel = GetSendChannelId(sp.first_ssrc()); | 2044 |
2075 if (channel != -1) { | 2045 if (GetSendChannelId(ssrc) != -1) { |
2076 LOG(LS_ERROR) << "Stream already exists with ssrc " << sp.first_ssrc(); | 2046 LOG(LS_ERROR) << "Stream already exists with ssrc " << ssrc; |
2077 return false; | 2047 return false; |
2078 } | 2048 } |
2079 | 2049 |
2080 bool default_channel_is_available = true; | 2050 // Create a new channel for sending audio data. |
2081 for (const auto& ch : send_channels_) { | 2051 int channel = CreateVoEChannel(); |
2082 if (IsDefaultChannel(ch.second->channel())) { | 2052 if (channel == -1) { |
2083 default_channel_is_available = false; | 2053 return false; |
pthatcher1
2015/10/15 05:15:04
This could use a LOG(LS_ERROR).
the sun
2015/10/15 12:07:12
Added LOG(LS_INFO) at start of AddSendStream() ins
| |
2084 break; | |
2085 } | |
2086 } | 2054 } |
2087 if (default_channel_is_available) { | |
2088 channel = default_send_channel_id(); | |
2089 } else { | |
2090 // Create a new channel for sending audio data. | |
2091 channel = engine()->CreateMediaVoiceChannel(); | |
2092 if (channel == -1) { | |
2093 LOG_RTCERR0(CreateChannel); | |
2094 return false; | |
2095 } | |
2096 | 2055 |
2097 ConfigureSendChannel(channel); | 2056 // Enable RTCP (for quality stats and feedback messages). |
2057 if (engine()->voe()->rtp()->SetRTCPStatus(channel, true) == -1) { | |
2058 LOG_RTCERR2(SetRTCPStatus, channel, 1); | |
2059 } | |
2060 | |
2061 SetChannelSendRtpHeaderExtensions(channel, send_extensions_); | |
2062 | |
2063 // Set the local (send) SSRC. | |
2064 if (engine()->voe()->rtp()->SetLocalSSRC(channel, ssrc) == -1) { | |
2065 LOG_RTCERR2(SetLocalSSRC, channel, ssrc); | |
2066 DeleteChannel(channel); | |
2067 return false; | |
2068 } | |
2069 | |
2070 if (engine()->voe()->rtp()->SetRTCP_CNAME(channel, sp.cname.c_str()) == -1) { | |
2071 LOG_RTCERR2(SetRTCP_CNAME, channel, sp.cname); | |
2072 DeleteChannel(channel); | |
2073 return false; | |
2098 } | 2074 } |
2099 | 2075 |
2100 // Save the channel to send_channels_, so that RemoveSendStream() can still | 2076 // Save the channel to send_channels_, so that RemoveSendStream() can still |
2101 // delete the channel in case failure happens below. | 2077 // delete the channel in case failure happens below. |
2102 webrtc::AudioTransport* audio_transport = | 2078 webrtc::AudioTransport* audio_transport = |
2103 engine()->voe()->base()->audio_transport(); | 2079 engine()->voe()->base()->audio_transport(); |
2104 send_channels_.insert( | 2080 send_channels_.insert( |
2105 std::make_pair(sp.first_ssrc(), | 2081 std::make_pair(ssrc, |
2106 new WebRtcVoiceChannelRenderer(channel, audio_transport))); | 2082 new WebRtcVoiceChannelRenderer(channel, audio_transport))); |
2107 | 2083 |
2108 // Set the send (local) SSRC. | 2084 // Set the current codecs to be used for the new channel. |
2109 // If there are multiple send SSRCs, we can only set the first one here, and | 2085 if (!send_codecs_.empty() && !SetSendCodecs(channel, send_codecs_)) { |
2110 // the rest of the SSRC(s) need to be set after SetSendCodec has been called | 2086 RemoveSendStream(ssrc); |
2111 // (with a codec requires multiple SSRC(s)). | |
2112 if (engine()->voe()->rtp()->SetLocalSSRC(channel, sp.first_ssrc()) == -1) { | |
2113 LOG_RTCERR2(SetSendSSRC, channel, sp.first_ssrc()); | |
2114 return false; | 2087 return false; |
2115 } | 2088 } |
pthatcher1
2015/10/15 05:15:04
Why do we do "add and then remove if SetSendCodecs
the sun
2015/10/15 12:07:12
Added comment.
| |
2116 | 2089 |
2117 // At this point the channel's local SSRC has been updated. If the channel is | 2090 // At this point the channel's local SSRC has been updated. If the channel is |
2118 // the default channel make sure that all the receive channels are updated as | 2091 // the first send channel make sure that all the receive channels are updated |
2119 // well. Receive channels have to have the same SSRC as the default channel in | 2092 // with the same SSRC in order to send receiver reports. |
2120 // order to send receiver reports with this SSRC. | 2093 if (send_channels_.size() == 1) { |
2121 if (IsDefaultChannel(channel)) { | 2094 first_send_ssrc_ = ssrc; |
pthatcher1
2015/10/15 05:15:04
Would it make sense to call this "receiver_reports
the sun
2015/10/15 12:07:12
Good idea, makes the logic clearer.
| |
2122 for (const auto& ch : receive_channels_) { | 2095 for (const auto& ch : receive_channels_) { |
2123 if (engine()->voe()->rtp()->SetLocalSSRC(ch.second->channel(), | 2096 int recv_channel = ch.second->channel(); |
2124 sp.first_ssrc()) != 0) { | 2097 if (engine()->voe()->rtp()->SetLocalSSRC(recv_channel, ssrc) != 0) { |
2125 LOG_RTCERR2(SetLocalSSRC, ch.second->channel(), sp.first_ssrc()); | 2098 LOG_RTCERR2(SetLocalSSRC, ch.second->channel(), ssrc); |
2126 return false; | 2099 return false; |
2127 } | 2100 } |
2101 engine()->voe()->base()->AssociateSendChannel(recv_channel, channel); | |
2102 LOG(LS_INFO) << "VoiceEngine channel #" << recv_channel | |
2103 << " is associated with channel #" << channel << "."; | |
2128 } | 2104 } |
2129 } | 2105 } |
2130 | 2106 |
2131 if (engine()->voe()->rtp()->SetRTCP_CNAME(channel, sp.cname.c_str()) == -1) { | |
2132 LOG_RTCERR2(SetRTCP_CNAME, channel, sp.cname); | |
2133 return false; | |
2134 } | |
2135 | |
2136 // Set the current codecs to be used for the new channel. | |
2137 if (!send_codecs_.empty() && !SetSendCodecs(channel, send_codecs_)) | |
2138 return false; | |
2139 | |
2140 return ChangeSend(channel, desired_send_); | 2107 return ChangeSend(channel, desired_send_); |
2141 } | 2108 } |
2142 | 2109 |
2143 bool WebRtcVoiceMediaChannel::RemoveSendStream(uint32_t ssrc) { | 2110 bool WebRtcVoiceMediaChannel::RemoveSendStream(uint32_t ssrc) { |
2111 RTC_DCHECK(thread_checker_.CalledOnValidThread()); | |
2144 ChannelMap::iterator it = send_channels_.find(ssrc); | 2112 ChannelMap::iterator it = send_channels_.find(ssrc); |
2145 if (it == send_channels_.end()) { | 2113 if (it == send_channels_.end()) { |
2146 LOG(LS_WARNING) << "Try to remove stream with ssrc " << ssrc | 2114 LOG(LS_WARNING) << "Try to remove stream with ssrc " << ssrc |
2147 << " which doesn't exist."; | 2115 << " which doesn't exist."; |
2148 return false; | 2116 return false; |
2149 } | 2117 } |
2150 | 2118 |
2151 int channel = it->second->channel(); | 2119 int channel = it->second->channel(); |
2152 ChangeSend(channel, SEND_NOTHING); | 2120 ChangeSend(channel, SEND_NOTHING); |
2153 | 2121 |
2154 // Delete the WebRtcVoiceChannelRenderer object connected to the channel, | 2122 // Delete the WebRtcVoiceChannelRenderer object connected to the channel, |
2155 // this will disconnect the audio renderer with the send channel. | 2123 // this will disconnect the audio renderer with the send channel. |
2156 delete it->second; | 2124 delete it->second; |
2157 send_channels_.erase(it); | 2125 send_channels_.erase(it); |
2158 | 2126 |
2159 if (IsDefaultChannel(channel)) { | 2127 // Clean up and delete the send channel. |
2160 // Do not delete the default channel since the receive channels depend on | 2128 LOG(LS_INFO) << "Removing audio send stream " << ssrc |
2161 // the default channel, recycle it instead. | 2129 << " with VoiceEngine channel #" << channel << "."; |
2162 ChangeSend(channel, SEND_NOTHING); | 2130 if (!DeleteChannel(channel)) { |
2163 } else { | 2131 return false; |
2164 // Clean up and delete the send channel. | |
2165 LOG(LS_INFO) << "Removing audio send stream " << ssrc | |
2166 << " with VoiceEngine channel #" << channel << "."; | |
2167 if (!DeleteChannel(channel)) | |
2168 return false; | |
2169 } | 2132 } |
2170 | 2133 if (send_channels_.empty()) { |
2171 if (send_channels_.empty()) | |
2172 ChangeSend(SEND_NOTHING); | 2134 ChangeSend(SEND_NOTHING); |
2173 | 2135 } |
2174 return true; | 2136 return true; |
2175 } | 2137 } |
2176 | 2138 |
2177 bool WebRtcVoiceMediaChannel::AddRecvStream(const StreamParams& sp) { | 2139 bool WebRtcVoiceMediaChannel::AddRecvStream(const StreamParams& sp) { |
2178 RTC_DCHECK(thread_checker_.CalledOnValidThread()); | 2140 RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
2179 LOG(LS_INFO) << "AddRecvStream: " << sp.ToString(); | 2141 LOG(LS_INFO) << "AddRecvStream: " << sp.ToString(); |
2180 | 2142 |
2181 if (!ValidateStreamParams(sp)) { | 2143 if (!ValidateStreamParams(sp)) { |
2182 return false; | 2144 return false; |
2183 } | 2145 } |
(...skipping 10 matching lines...) Expand all Loading... | |
2194 RemoveRecvStream(ssrc); | 2156 RemoveRecvStream(ssrc); |
2195 } | 2157 } |
2196 | 2158 |
2197 if (receive_channels_.find(ssrc) != receive_channels_.end()) { | 2159 if (receive_channels_.find(ssrc) != receive_channels_.end()) { |
2198 LOG(LS_ERROR) << "Stream already exists with ssrc " << ssrc; | 2160 LOG(LS_ERROR) << "Stream already exists with ssrc " << ssrc; |
2199 return false; | 2161 return false; |
2200 } | 2162 } |
2201 RTC_DCHECK(receive_stream_params_.find(ssrc) == receive_stream_params_.end()); | 2163 RTC_DCHECK(receive_stream_params_.find(ssrc) == receive_stream_params_.end()); |
2202 | 2164 |
2203 // Create a new channel for receiving audio data. | 2165 // Create a new channel for receiving audio data. |
2204 int channel = engine()->CreateMediaVoiceChannel(); | 2166 int channel = CreateVoEChannel(); |
2205 if (channel == -1) { | 2167 if (channel == -1) { |
2206 LOG_RTCERR0(CreateChannel); | |
2207 return false; | 2168 return false; |
2208 } | 2169 } |
2209 if (!ConfigureRecvChannel(channel)) { | 2170 if (!ConfigureRecvChannel(channel)) { |
2210 DeleteChannel(channel); | 2171 DeleteChannel(channel); |
2211 return false; | 2172 return false; |
2212 } | 2173 } |
2213 | 2174 |
2214 webrtc::AudioTransport* audio_transport = | 2175 webrtc::AudioTransport* audio_transport = |
2215 engine()->voe()->base()->audio_transport(); | 2176 engine()->voe()->base()->audio_transport(); |
2216 WebRtcVoiceChannelRenderer* channel_renderer = | 2177 WebRtcVoiceChannelRenderer* channel_renderer = |
2217 new WebRtcVoiceChannelRenderer(channel, audio_transport); | 2178 new WebRtcVoiceChannelRenderer(channel, audio_transport); |
2218 receive_channels_.insert(std::make_pair(ssrc, channel_renderer)); | 2179 receive_channels_.insert(std::make_pair(ssrc, channel_renderer)); |
2219 receive_stream_params_[ssrc] = sp; | 2180 receive_stream_params_[ssrc] = sp; |
2220 AddAudioReceiveStream(ssrc); | 2181 AddAudioReceiveStream(ssrc); |
2221 | 2182 |
2222 LOG(LS_INFO) << "New audio stream " << ssrc | 2183 LOG(LS_INFO) << "New audio stream " << ssrc |
2223 << " registered to VoiceEngine channel #" | 2184 << " registered to VoiceEngine channel #" |
2224 << channel << "."; | 2185 << channel << "."; |
2225 return true; | 2186 return true; |
2226 } | 2187 } |
2227 | 2188 |
2228 bool WebRtcVoiceMediaChannel::ConfigureRecvChannel(int channel) { | 2189 bool WebRtcVoiceMediaChannel::ConfigureRecvChannel(int channel) { |
2229 RTC_DCHECK(thread_checker_.CalledOnValidThread()); | 2190 RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
2230 // Configure to use external transport. | 2191 |
2231 if (engine()->voe()->network()->RegisterExternalTransport( | 2192 uint32_t rtcp_ssrc = kDefaultRtcpReceiverReportSsrc; |
2232 channel, *this) == -1) { | 2193 if (send_channels_.size() > 0) { |
2233 LOG_RTCERR2(SetExternalTransport, channel, this); | 2194 rtcp_ssrc = first_send_ssrc_; |
2195 | |
2196 // Associate receive channel with first send channel (so the receive channel | |
2197 // can obtain RTT from the send channel) | |
2198 int send_channel = send_channels_[first_send_ssrc_]->channel(); | |
2199 engine()->voe()->base()->AssociateSendChannel(channel, send_channel); | |
2200 LOG(LS_INFO) << "VoiceEngine channel #" << channel | |
2201 << " is associated with channel #" << send_channel << "."; | |
2202 } | |
2203 if (engine()->voe()->rtp()->SetLocalSSRC(channel, rtcp_ssrc) == -1) { | |
2204 LOG_RTCERR1(SetLocalSSRC, channel); | |
2234 return false; | 2205 return false; |
2235 } | 2206 } |
2236 | 2207 |
2237 // Use the same SSRC as our default send channel, so the RTCP reports are | |
2238 // correct. | |
2239 unsigned int send_ssrc = 0; | |
2240 webrtc::VoERTP_RTCP* rtp = engine()->voe()->rtp(); | |
2241 if (rtp->GetLocalSSRC(default_send_channel_id(), send_ssrc) == -1) { | |
2242 LOG_RTCERR1(GetSendSSRC, channel); | |
2243 return false; | |
2244 } | |
2245 if (rtp->SetLocalSSRC(channel, send_ssrc) == -1) { | |
2246 LOG_RTCERR1(SetSendSSRC, channel); | |
2247 return false; | |
2248 } | |
2249 | |
2250 // Associate receive channel to default send channel (so the receive channel | |
2251 // can obtain RTT from the send channel). | |
2252 engine()->voe()->base()->AssociateSendChannel(channel, | |
2253 default_send_channel_id()); | |
2254 LOG(LS_INFO) << "VoiceEngine channel #" | |
2255 << channel << " is associated with channel #" | |
2256 << default_send_channel_id() << "."; | |
2257 | |
2258 // Turn off all supported codecs. | 2208 // Turn off all supported codecs. |
2259 int ncodecs = engine()->voe()->codec()->NumOfCodecs(); | 2209 int ncodecs = engine()->voe()->codec()->NumOfCodecs(); |
2260 for (int i = 0; i < ncodecs; ++i) { | 2210 for (int i = 0; i < ncodecs; ++i) { |
2261 webrtc::CodecInst voe_codec; | 2211 webrtc::CodecInst voe_codec; |
2262 if (engine()->voe()->codec()->GetCodec(i, voe_codec) != -1) { | 2212 if (engine()->voe()->codec()->GetCodec(i, voe_codec) != -1) { |
2263 voe_codec.pltype = -1; | 2213 voe_codec.pltype = -1; |
2264 if (engine()->voe()->codec()->SetRecPayloadType( | 2214 if (engine()->voe()->codec()->SetRecPayloadType( |
2265 channel, voe_codec) == -1) { | 2215 channel, voe_codec) == -1) { |
2266 LOG_RTCERR2(SetRecPayloadType, channel, ToString(voe_codec)); | 2216 LOG_RTCERR2(SetRecPayloadType, channel, ToString(voe_codec)); |
2267 return false; | 2217 return false; |
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2420 } | 2370 } |
2421 | 2371 |
2422 bool WebRtcVoiceMediaChannel::CanInsertDtmf() { | 2372 bool WebRtcVoiceMediaChannel::CanInsertDtmf() { |
2423 return dtmf_allowed_; | 2373 return dtmf_allowed_; |
2424 } | 2374 } |
2425 | 2375 |
2426 bool WebRtcVoiceMediaChannel::InsertDtmf(uint32_t ssrc, | 2376 bool WebRtcVoiceMediaChannel::InsertDtmf(uint32_t ssrc, |
2427 int event, | 2377 int event, |
2428 int duration, | 2378 int duration, |
2429 int flags) { | 2379 int flags) { |
2380 RTC_DCHECK(thread_checker_.CalledOnValidThread()); | |
2430 if (!dtmf_allowed_) { | 2381 if (!dtmf_allowed_) { |
2431 return false; | 2382 return false; |
2432 } | 2383 } |
2433 | 2384 |
2434 // Send the event. | 2385 // Send the event. |
2435 if (flags & cricket::DF_SEND) { | 2386 if (flags & cricket::DF_SEND) { |
2436 int channel = -1; | 2387 int channel = -1; |
2437 if (ssrc == 0) { | 2388 if (ssrc == 0) { |
2438 bool default_channel_is_inuse = false; | 2389 if (send_channels_.size() > 0) { |
2439 for (const auto& ch : send_channels_) { | |
2440 if (IsDefaultChannel(ch.second->channel())) { | |
2441 default_channel_is_inuse = true; | |
2442 break; | |
2443 } | |
2444 } | |
2445 if (default_channel_is_inuse) { | |
2446 channel = default_send_channel_id(); | |
2447 } else if (!send_channels_.empty()) { | |
2448 channel = send_channels_.begin()->second->channel(); | 2390 channel = send_channels_.begin()->second->channel(); |
2449 } | 2391 } |
2450 } else { | 2392 } else { |
2451 channel = GetSendChannelId(ssrc); | 2393 channel = GetSendChannelId(ssrc); |
2452 } | 2394 } |
2453 if (channel == -1) { | 2395 if (channel == -1) { |
2454 LOG(LS_WARNING) << "InsertDtmf - The specified ssrc " | 2396 LOG(LS_WARNING) << "InsertDtmf - The specified ssrc " |
2455 << ssrc << " is not in use."; | 2397 << ssrc << " is not in use."; |
2456 return false; | 2398 return false; |
2457 } | 2399 } |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2555 // SR may continue RR and any RR entry may correspond to any one of the send | 2497 // SR may continue RR and any RR entry may correspond to any one of the send |
2556 // channels. So all RTCP packets must be forwarded all send channels. VoE | 2498 // channels. So all RTCP packets must be forwarded all send channels. VoE |
2557 // will filter out RR internally. | 2499 // will filter out RR internally. |
2558 for (const auto& ch : send_channels_) { | 2500 for (const auto& ch : send_channels_) { |
2559 engine()->voe()->network()->ReceivedRTCPPacket( | 2501 engine()->voe()->network()->ReceivedRTCPPacket( |
2560 ch.second->channel(), packet->data(), packet->size()); | 2502 ch.second->channel(), packet->data(), packet->size()); |
2561 } | 2503 } |
2562 } | 2504 } |
2563 | 2505 |
2564 bool WebRtcVoiceMediaChannel::MuteStream(uint32_t ssrc, bool muted) { | 2506 bool WebRtcVoiceMediaChannel::MuteStream(uint32_t ssrc, bool muted) { |
2565 int channel = | 2507 RTC_DCHECK(thread_checker_.CalledOnValidThread()); |
2566 (ssrc == 0) ? default_send_channel_id() : GetSendChannelId(ssrc); | 2508 int channel = GetSendChannelId(ssrc); |
2567 if (channel == -1) { | 2509 if (channel == -1) { |
2568 LOG(LS_WARNING) << "The specified ssrc " << ssrc << " is not in use."; | 2510 LOG(LS_WARNING) << "The specified ssrc " << ssrc << " is not in use."; |
2569 return false; | 2511 return false; |
2570 } | 2512 } |
2571 if (engine()->voe()->volume()->SetInputMute(channel, muted) == -1) { | 2513 if (engine()->voe()->volume()->SetInputMute(channel, muted) == -1) { |
2572 LOG_RTCERR2(SetInputMute, channel, muted); | 2514 LOG_RTCERR2(SetInputMute, channel, muted); |
2573 return false; | 2515 return false; |
2574 } | 2516 } |
2575 // We set the AGC to mute state only when all the channels are muted. | 2517 // We set the AGC to mute state only when all the channels are muted. |
2576 // This implementation is not ideal, instead we should signal the AGC when | 2518 // This implementation is not ideal, instead we should signal the AGC when |
2577 // the mic channel is muted/unmuted. We can't do it today because there | 2519 // the mic channel is muted/unmuted. We can't do it today because there |
2578 // is no good way to know which stream is mapping to the mic channel. | 2520 // is no good way to know which stream is mapping to the mic channel. |
2579 bool all_muted = muted; | 2521 bool all_muted = muted; |
2580 for (const auto& ch : send_channels_) { | 2522 for (const auto& ch : send_channels_) { |
2581 if (!all_muted) { | 2523 if (!all_muted) { |
2582 break; | 2524 break; |
2583 } | 2525 } |
2584 if (engine()->voe()->volume()->GetInputMute(ch.second->channel(), | 2526 if (engine()->voe()->volume()->GetInputMute(ch.second->channel(), |
2585 all_muted)) { | 2527 all_muted)) { |
2586 LOG_RTCERR1(GetInputMute, ch.second->channel()); | 2528 LOG_RTCERR1(GetInputMute, ch.second->channel()); |
2587 return false; | 2529 return false; |
2588 } | 2530 } |
2589 } | 2531 } |
2590 | 2532 |
2591 webrtc::AudioProcessing* ap = engine()->voe()->base()->audio_processing(); | 2533 webrtc::AudioProcessing* ap = engine()->voe()->base()->audio_processing(); |
2592 if (ap) | 2534 if (ap) { |
2593 ap->set_output_will_be_muted(all_muted); | 2535 ap->set_output_will_be_muted(all_muted); |
2536 } | |
2594 return true; | 2537 return true; |
2595 } | 2538 } |
2596 | 2539 |
2597 // TODO(minyue): SetMaxSendBandwidth() is subject to be renamed to | 2540 // TODO(minyue): SetMaxSendBandwidth() is subject to be renamed to |
2598 // SetMaxSendBitrate() in future. | 2541 // SetMaxSendBitrate() in future. |
2599 bool WebRtcVoiceMediaChannel::SetMaxSendBandwidth(int bps) { | 2542 bool WebRtcVoiceMediaChannel::SetMaxSendBandwidth(int bps) { |
2600 LOG(LS_INFO) << "WebRtcVoiceMediaChannel::SetMaxSendBandwidth."; | 2543 LOG(LS_INFO) << "WebRtcVoiceMediaChannel::SetMaxSendBandwidth."; |
2601 | |
2602 return SetSendBitrateInternal(bps); | 2544 return SetSendBitrateInternal(bps); |
2603 } | 2545 } |
2604 | 2546 |
2605 bool WebRtcVoiceMediaChannel::SetSendBitrateInternal(int bps) { | 2547 bool WebRtcVoiceMediaChannel::SetSendBitrateInternal(int bps) { |
2606 LOG(LS_INFO) << "WebRtcVoiceMediaChannel::SetSendBitrateInternal."; | 2548 LOG(LS_INFO) << "WebRtcVoiceMediaChannel::SetSendBitrateInternal."; |
2607 | 2549 |
2608 send_bitrate_setting_ = true; | 2550 send_bitrate_setting_ = true; |
2609 send_bitrate_bps_ = bps; | 2551 send_bitrate_bps_ = bps; |
2610 | 2552 |
2611 if (!send_codec_) { | 2553 if (!send_codec_) { |
(...skipping 286 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2898 return true; | 2840 return true; |
2899 } else { | 2841 } else { |
2900 break; | 2842 break; |
2901 } | 2843 } |
2902 } | 2844 } |
2903 } | 2845 } |
2904 LOG(LS_WARNING) << "RED params " << red_params << " are invalid."; | 2846 LOG(LS_WARNING) << "RED params " << red_params << " are invalid."; |
2905 return false; | 2847 return false; |
2906 } | 2848 } |
2907 | 2849 |
2908 bool WebRtcVoiceMediaChannel::EnableRtcp(int channel) { | |
2909 if (engine()->voe()->rtp()->SetRTCPStatus(channel, true) == -1) { | |
2910 LOG_RTCERR2(SetRTCPStatus, channel, 1); | |
2911 return false; | |
2912 } | |
2913 // TODO(juberti): Enable VQMon and RTCP XR reports, once we know what | |
2914 // what we want to do with them. | |
2915 // engine()->voe().EnableVQMon(default_send_channel_id(), true); | |
2916 // engine()->voe().EnableRTCP_XR(default_send_channel_id(), true); | |
2917 return true; | |
2918 } | |
2919 | |
2920 bool WebRtcVoiceMediaChannel::SetPlayout(int channel, bool playout) { | 2850 bool WebRtcVoiceMediaChannel::SetPlayout(int channel, bool playout) { |
2921 if (playout) { | 2851 if (playout) { |
2922 LOG(LS_INFO) << "Starting playout for channel #" << channel; | 2852 LOG(LS_INFO) << "Starting playout for channel #" << channel; |
2923 if (engine()->voe()->base()->StartPlayout(channel) == -1) { | 2853 if (engine()->voe()->base()->StartPlayout(channel) == -1) { |
2924 LOG_RTCERR1(StartPlayout, channel); | 2854 LOG_RTCERR1(StartPlayout, channel); |
2925 return false; | 2855 return false; |
2926 } | 2856 } |
2927 } else { | 2857 } else { |
2928 LOG(LS_INFO) << "Stopping playout for channel #" << channel; | 2858 LOG(LS_INFO) << "Stopping playout for channel #" << channel; |
2929 engine()->voe()->base()->StopPlayout(channel); | 2859 engine()->voe()->base()->StopPlayout(channel); |
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3037 LOG(LS_WARNING) << "Unknown codec " << ToString(codec); | 2967 LOG(LS_WARNING) << "Unknown codec " << ToString(codec); |
3038 return false; | 2968 return false; |
3039 } | 2969 } |
3040 } | 2970 } |
3041 return true; | 2971 return true; |
3042 } | 2972 } |
3043 | 2973 |
3044 } // namespace cricket | 2974 } // namespace cricket |
3045 | 2975 |
3046 #endif // HAVE_WEBRTC_VOICE | 2976 #endif // HAVE_WEBRTC_VOICE |
OLD | NEW |