Chromium Code Reviews| 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 |