Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(303)

Side by Side Diff: webrtc/media/engine/webrtcvoiceengine.cc

Issue 2397573006: Using AudioOption to enable audio network adaptor. (Closed)
Patch Set: Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 168 matching lines...) Expand 10 before | Expand all | Expand 10 after
179 auto it = std::unique(payload_types.begin(), payload_types.end()); 179 auto it = std::unique(payload_types.begin(), payload_types.end());
180 return it == payload_types.end(); 180 return it == payload_types.end();
181 } 181 }
182 182
183 // Return true if codec.params[feature] == "1", false otherwise. 183 // Return true if codec.params[feature] == "1", false otherwise.
184 bool IsCodecFeatureEnabled(const AudioCodec& codec, const char* feature) { 184 bool IsCodecFeatureEnabled(const AudioCodec& codec, const char* feature) {
185 int value; 185 int value;
186 return codec.GetParam(feature, &value) && value == 1; 186 return codec.GetParam(feature, &value) && value == 1;
187 } 187 }
188 188
189 // Returns integer parameter params[feature] if it is defined. Returns
190 // |default_value| otherwise.
191 int GetCodecFeatureInt(const AudioCodec& codec,
192 const char* feature,
193 int default_value) {
194 int value;
195 if (codec.GetParam(feature, &value)) {
196 return value;
197 }
198 return default_value;
199 }
200
189 // Use params[kCodecParamMaxAverageBitrate] if it is defined, use codec.bitrate 201 // Use params[kCodecParamMaxAverageBitrate] if it is defined, use codec.bitrate
190 // otherwise. If the value (either from params or codec.bitrate) <=0, use the 202 // otherwise. If the value (either from params or codec.bitrate) <=0, use the
191 // default configuration. If the value is beyond feasible bit rate of Opus, 203 // default configuration. If the value is beyond feasible bit rate of Opus,
192 // clamp it. Returns the Opus bit rate for operation. 204 // clamp it. Returns the Opus bit rate for operation.
193 int GetOpusBitrate(const AudioCodec& codec, int max_playback_rate) { 205 int GetOpusBitrate(const AudioCodec& codec, int max_playback_rate) {
194 int bitrate = 0; 206 int bitrate = 0;
195 bool use_param = true; 207 bool use_param = true;
196 if (!codec.GetParam(kCodecParamMaxAverageBitrate, &bitrate)) { 208 if (!codec.GetParam(kCodecParamMaxAverageBitrate, &bitrate)) {
197 bitrate = codec.bitrate; 209 bitrate = codec.bitrate;
198 use_param = false; 210 use_param = false;
(...skipping 15 matching lines...) Expand all
214 std::string rate_source = 226 std::string rate_source =
215 use_param ? "Codec parameter \"maxaveragebitrate\"" : 227 use_param ? "Codec parameter \"maxaveragebitrate\"" :
216 "Supplied Opus bitrate"; 228 "Supplied Opus bitrate";
217 LOG(LS_WARNING) << rate_source 229 LOG(LS_WARNING) << rate_source
218 << " is invalid and is replaced by: " 230 << " is invalid and is replaced by: "
219 << bitrate; 231 << bitrate;
220 } 232 }
221 return bitrate; 233 return bitrate;
222 } 234 }
223 235
224 // Returns kOpusDefaultPlaybackRate if params[kCodecParamMaxPlaybackRate] is not 236 void GetOpusConfig(const AudioCodec& codec,
225 // defined. Returns the value of params[kCodecParamMaxPlaybackRate] otherwise. 237 webrtc::CodecInst* voe_codec,
226 int GetOpusMaxPlaybackRate(const AudioCodec& codec) { 238 bool* enable_codec_fec,
227 int value; 239 int* max_playback_rate,
228 if (codec.GetParam(kCodecParamMaxPlaybackRate, &value)) { 240 bool* enable_codec_dtx,
229 return value; 241 int* min_ptime_ms,
230 } 242 int* max_ptime_ms) {
231 return kOpusDefaultMaxPlaybackRate;
232 }
233
234 void GetOpusConfig(const AudioCodec& codec, webrtc::CodecInst* voe_codec,
235 bool* enable_codec_fec, int* max_playback_rate,
236 bool* enable_codec_dtx) {
237 *enable_codec_fec = IsCodecFeatureEnabled(codec, kCodecParamUseInbandFec); 243 *enable_codec_fec = IsCodecFeatureEnabled(codec, kCodecParamUseInbandFec);
238 *enable_codec_dtx = IsCodecFeatureEnabled(codec, kCodecParamUseDtx); 244 *enable_codec_dtx = IsCodecFeatureEnabled(codec, kCodecParamUseDtx);
239 *max_playback_rate = GetOpusMaxPlaybackRate(codec); 245 *max_playback_rate = GetCodecFeatureInt(codec, kCodecParamMaxPlaybackRate,
246 kOpusDefaultMaxPlaybackRate);
247 *max_ptime_ms =
248 GetCodecFeatureInt(codec, kCodecParamMaxPTime, kOpusDefaultMaxPTime);
249 *min_ptime_ms =
250 GetCodecFeatureInt(codec, kCodecParamMinPTime, kOpusDefaultMinPTime);
240 251
241 // If OPUS, change what we send according to the "stereo" codec 252 // If OPUS, change what we send according to the "stereo" codec
242 // parameter, and not the "channels" parameter. We set 253 // parameter, and not the "channels" parameter. We set
243 // voe_codec.channels to 2 if "stereo=1" and 1 otherwise. If 254 // voe_codec.channels to 2 if "stereo=1" and 1 otherwise. If
244 // the bitrate is not specified, i.e. is <= zero, we set it to the 255 // the bitrate is not specified, i.e. is <= zero, we set it to the
245 // appropriate default value for mono or stereo Opus. 256 // appropriate default value for mono or stereo Opus.
246
247 voe_codec->channels = IsCodecFeatureEnabled(codec, kCodecParamStereo) ? 2 : 1; 257 voe_codec->channels = IsCodecFeatureEnabled(codec, kCodecParamStereo) ? 2 : 1;
248 voe_codec->rate = GetOpusBitrate(codec, *max_playback_rate); 258 voe_codec->rate = GetOpusBitrate(codec, *max_playback_rate);
249 } 259 }
250 260
251 webrtc::AudioState::Config MakeAudioStateConfig(VoEWrapper* voe_wrapper) { 261 webrtc::AudioState::Config MakeAudioStateConfig(VoEWrapper* voe_wrapper) {
252 webrtc::AudioState::Config config; 262 webrtc::AudioState::Config config;
253 config.voice_engine = voe_wrapper->engine(); 263 config.voice_engine = voe_wrapper->engine();
254 return config; 264 return config;
255 } 265 }
256 266
(...skipping 564 matching lines...) Expand 10 before | Expand all | Expand 10 after
821 } 831 }
822 } 832 }
823 833
824 if (options.adjust_agc_delta) { 834 if (options.adjust_agc_delta) {
825 LOG(LS_INFO) << "Adjust agc delta is " << *options.adjust_agc_delta; 835 LOG(LS_INFO) << "Adjust agc delta is " << *options.adjust_agc_delta;
826 if (!AdjustAgcLevel(*options.adjust_agc_delta)) { 836 if (!AdjustAgcLevel(*options.adjust_agc_delta)) {
827 return false; 837 return false;
828 } 838 }
829 } 839 }
830 840
841 if (options.audio_network_adaptor_config) {
842 channel_config_.acm_config.audio_network_adaptor_enabled = true;
843 channel_config_.acm_config.audio_network_adaptor_config =
844 *options.audio_network_adaptor_config;
845 }
846
831 webrtc::Config config; 847 webrtc::Config config;
832 848
833 if (options.delay_agnostic_aec) 849 if (options.delay_agnostic_aec)
834 delay_agnostic_aec_ = options.delay_agnostic_aec; 850 delay_agnostic_aec_ = options.delay_agnostic_aec;
835 if (delay_agnostic_aec_) { 851 if (delay_agnostic_aec_) {
836 LOG(LS_INFO) << "Delay agnostic aec is enabled? " << *delay_agnostic_aec_; 852 LOG(LS_INFO) << "Delay agnostic aec is enabled? " << *delay_agnostic_aec_;
837 config.Set<webrtc::DelayAgnostic>( 853 config.Set<webrtc::DelayAgnostic>(
838 new webrtc::DelayAgnostic(*delay_agnostic_aec_)); 854 new webrtc::DelayAgnostic(*delay_agnostic_aec_));
839 } 855 }
840 856
(...skipping 456 matching lines...) Expand 10 before | Expand all | Expand 10 after
1297 return rtp_parameters_; 1313 return rtp_parameters_;
1298 } 1314 }
1299 1315
1300 void SetRtpParameters(const webrtc::RtpParameters& parameters) { 1316 void SetRtpParameters(const webrtc::RtpParameters& parameters) {
1301 RTC_CHECK_EQ(1UL, parameters.encodings.size()); 1317 RTC_CHECK_EQ(1UL, parameters.encodings.size());
1302 rtp_parameters_ = parameters; 1318 rtp_parameters_ = parameters;
1303 // parameters.encodings[0].active could have changed. 1319 // parameters.encodings[0].active could have changed.
1304 UpdateSendState(); 1320 UpdateSendState();
1305 } 1321 }
1306 1322
1323 bool EnableAudioNetworkAdaptor(const std::string& config_string) {
1324 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
1325 RTC_DCHECK(stream_);
1326 return stream_->EnableAudioNetworkAdaptor(config_string);
1327 }
1328
1329 void DisableAudioNetworkAdaptor() {
1330 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
1331 RTC_DCHECK(stream_);
1332 stream_->DisableAudioNetworkAdaptor();
1333 }
1334
1335 void SetReceiverFrameLengthRange(int min_frame_length_ms,
michaelt 2016/10/19 13:32:55 Will you add a interface for ana_dump as well ?
1336 int max_frame_length_ms) {
1337 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
1338 RTC_DCHECK(stream_);
1339 stream_->SetReceiverFrameLengthRange(min_frame_length_ms,
1340 max_frame_length_ms);
1341 }
1342
1307 private: 1343 private:
1308 void UpdateSendState() { 1344 void UpdateSendState() {
1309 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); 1345 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
1310 RTC_DCHECK(stream_); 1346 RTC_DCHECK(stream_);
1311 RTC_DCHECK_EQ(1UL, rtp_parameters_.encodings.size()); 1347 RTC_DCHECK_EQ(1UL, rtp_parameters_.encodings.size());
1312 if (send_ && source_ != nullptr && rtp_parameters_.encodings[0].active) { 1348 if (send_ && source_ != nullptr && rtp_parameters_.encodings[0].active) {
1313 stream_->Start(); 1349 stream_->Start();
1314 } else { // !send || source_ = nullptr 1350 } else { // !send || source_ = nullptr
1315 stream_->Stop(); 1351 stream_->Stop();
1316 } 1352 }
(...skipping 462 matching lines...) Expand 10 before | Expand all | Expand 10 after
1779 1815
1780 send_codec_spec.transport_cc_enabled = HasTransportCc(*codec); 1816 send_codec_spec.transport_cc_enabled = HasTransportCc(*codec);
1781 send_codec_spec.nack_enabled = HasNack(*codec); 1817 send_codec_spec.nack_enabled = HasNack(*codec);
1782 1818
1783 // For Opus as the send codec, we are to determine inband FEC, maximum 1819 // For Opus as the send codec, we are to determine inband FEC, maximum
1784 // playback rate, and opus internal dtx. 1820 // playback rate, and opus internal dtx.
1785 if (IsCodec(*codec, kOpusCodecName)) { 1821 if (IsCodec(*codec, kOpusCodecName)) {
1786 GetOpusConfig(*codec, &send_codec_spec.codec_inst, 1822 GetOpusConfig(*codec, &send_codec_spec.codec_inst,
1787 &send_codec_spec.enable_codec_fec, 1823 &send_codec_spec.enable_codec_fec,
1788 &send_codec_spec.opus_max_playback_rate, 1824 &send_codec_spec.opus_max_playback_rate,
1789 &send_codec_spec.enable_opus_dtx); 1825 &send_codec_spec.enable_opus_dtx,
1826 &send_codec_spec.min_ptime_ms,
1827 &send_codec_spec.max_ptime_ms);
1790 } 1828 }
1791 1829
1792 // Set packet size if the AudioCodec param kCodecParamPTime is set. 1830 // Set packet size if the AudioCodec param kCodecParamPTime is set.
1793 int ptime_ms = 0; 1831 int ptime_ms = 0;
1794 if (codec->GetParam(kCodecParamPTime, &ptime_ms)) { 1832 if (codec->GetParam(kCodecParamPTime, &ptime_ms)) {
1795 if (!WebRtcVoiceCodecs::SetPTimeAsPacketSize( 1833 if (!WebRtcVoiceCodecs::SetPTimeAsPacketSize(
1796 &send_codec_spec.codec_inst, ptime_ms)) { 1834 &send_codec_spec.codec_inst, ptime_ms)) {
1797 LOG(LS_WARNING) << "Failed to set packet size for codec " 1835 LOG(LS_WARNING) << "Failed to set packet size for codec "
1798 << send_codec_spec.codec_inst.plname; 1836 << send_codec_spec.codec_inst.plname;
1799 return false; 1837 return false;
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
1832 break; 1870 break;
1833 } 1871 }
1834 } 1872 }
1835 } 1873 }
1836 1874
1837 // Apply new settings to all streams. 1875 // Apply new settings to all streams.
1838 if (send_codec_spec_ != send_codec_spec) { 1876 if (send_codec_spec_ != send_codec_spec) {
1839 send_codec_spec_ = std::move(send_codec_spec); 1877 send_codec_spec_ = std::move(send_codec_spec);
1840 for (const auto& kv : send_streams_) { 1878 for (const auto& kv : send_streams_) {
1841 kv.second->RecreateAudioSendStream(send_codec_spec_); 1879 kv.second->RecreateAudioSendStream(send_codec_spec_);
1842 if (!SetSendCodecs(kv.second->channel(), kv.second->rtp_parameters())) { 1880 if (!SetSendCodecs(kv.first, kv.second->rtp_parameters())) {
1843 return false; 1881 return false;
1844 } 1882 }
1845 } 1883 }
1846 } 1884 }
1847 1885
1848 // Check if the transport cc feedback or NACK status has changed on the 1886 // Check if the transport cc feedback or NACK status has changed on the
1849 // preferred send codec, and in that case reconfigure all receive streams. 1887 // preferred send codec, and in that case reconfigure all receive streams.
1850 if (recv_transport_cc_enabled_ != send_codec_spec_.transport_cc_enabled || 1888 if (recv_transport_cc_enabled_ != send_codec_spec_.transport_cc_enabled ||
1851 recv_nack_enabled_ != send_codec_spec_.nack_enabled) { 1889 recv_nack_enabled_ != send_codec_spec_.nack_enabled) {
1852 LOG(LS_INFO) << "Recreate all the receive streams because the send " 1890 LOG(LS_INFO) << "Recreate all the receive streams because the send "
1853 "codec has changed."; 1891 "codec has changed.";
1854 recv_transport_cc_enabled_ = send_codec_spec_.transport_cc_enabled; 1892 recv_transport_cc_enabled_ = send_codec_spec_.transport_cc_enabled;
1855 recv_nack_enabled_ = send_codec_spec_.nack_enabled; 1893 recv_nack_enabled_ = send_codec_spec_.nack_enabled;
1856 for (auto& kv : recv_streams_) { 1894 for (auto& kv : recv_streams_) {
1857 kv.second->RecreateAudioReceiveStream(recv_transport_cc_enabled_, 1895 kv.second->RecreateAudioReceiveStream(recv_transport_cc_enabled_,
1858 recv_nack_enabled_); 1896 recv_nack_enabled_);
1859 } 1897 }
1860 } 1898 }
1861 1899
1862 send_codecs_ = codecs; 1900 send_codecs_ = codecs;
1863 return true; 1901 return true;
1864 } 1902 }
1865 1903
1866 // Apply current codec settings to a single voe::Channel used for sending. 1904 // Apply current codec settings to a single voe::Channel used for sending.
1867 bool WebRtcVoiceMediaChannel::SetSendCodecs( 1905 bool WebRtcVoiceMediaChannel::SetSendCodecs(
1868 int channel, 1906 uint32_t ssrc,
1869 const webrtc::RtpParameters& rtp_parameters) { 1907 const webrtc::RtpParameters& rtp_parameters) {
1908 int channel = GetSendChannelId(ssrc);
1909
1870 // Disable VAD and FEC unless we know the other side wants them. 1910 // Disable VAD and FEC unless we know the other side wants them.
1871 engine()->voe()->codec()->SetVADStatus(channel, false); 1911 engine()->voe()->codec()->SetVADStatus(channel, false);
1872 engine()->voe()->codec()->SetFECStatus(channel, false); 1912 engine()->voe()->codec()->SetFECStatus(channel, false);
1873 1913
1874 // Set the codec immediately, since SetVADStatus() depends on whether 1914 // Set the codec immediately, since SetVADStatus() depends on whether
1875 // the current codec is mono or stereo. 1915 // the current codec is mono or stereo.
1876 if (!SetSendCodec(channel, send_codec_spec_.codec_inst)) { 1916 if (!SetSendCodec(channel, send_codec_spec_.codec_inst)) {
1877 return false; 1917 return false;
1878 } 1918 }
1879 1919
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
1959 send_codec_spec_.codec_inst.channels == 1) { 1999 send_codec_spec_.codec_inst.channels == 1) {
1960 // TODO(minyue): If CN frequency == 48000 Hz is allowed, consider the 2000 // TODO(minyue): If CN frequency == 48000 Hz is allowed, consider the
1961 // interaction between VAD and Opus FEC. 2001 // interaction between VAD and Opus FEC.
1962 LOG(LS_INFO) << "Enabling VAD"; 2002 LOG(LS_INFO) << "Enabling VAD";
1963 if (engine()->voe()->codec()->SetVADStatus(channel, true) == -1) { 2003 if (engine()->voe()->codec()->SetVADStatus(channel, true) == -1) {
1964 LOG_RTCERR2(SetVADStatus, channel, true); 2004 LOG_RTCERR2(SetVADStatus, channel, true);
1965 return false; 2005 return false;
1966 } 2006 }
1967 } 2007 }
1968 } 2008 }
2009
2010 auto it = send_streams_.find(ssrc);
2011 RTC_CHECK(it != send_streams_.end());
2012 const auto acm_config = engine()->channel_config_.acm_config;
2013 if (acm_config.audio_network_adaptor_enabled) {
2014 if (IsCodec(send_codec_spec_.codec_inst, kOpusCodecName)) {
2015 // Audio network adaptor is only allowed for Opus currently.
2016 if (it->second->EnableAudioNetworkAdaptor(
michaelt 2016/10/19 13:32:55 You will have to change the order of Enable and se
2017 acm_config.audio_network_adaptor_config)) {
the sun 2016/10/06 08:03:46 If this information is already propagated to the C
2018 LOG(LS_ERROR) << "Audio network adaptor cannot be enabled on SSRC "
2019 << ssrc;
2020 return false;
2021 }
2022 LOG(LS_INFO) << "Audio network adaptor enabled on SSRC " << ssrc;
2023 it->second->SetReceiverFrameLengthRange(send_codec_spec_.min_ptime_ms,
2024 send_codec_spec_.max_ptime_ms);
2025 }
2026 } else {
2027 it->second->DisableAudioNetworkAdaptor();
2028 }
1969 return true; 2029 return true;
1970 } 2030 }
1971 2031
1972 bool WebRtcVoiceMediaChannel::SetSendCodec( 2032 bool WebRtcVoiceMediaChannel::SetSendCodec(
1973 int channel, const webrtc::CodecInst& send_codec) { 2033 int channel, const webrtc::CodecInst& send_codec) {
1974 LOG(LS_INFO) << "Send channel " << channel << " selected voice codec " 2034 LOG(LS_INFO) << "Send channel " << channel << " selected voice codec "
1975 << ToString(send_codec) << ", bitrate=" << send_codec.rate; 2035 << ToString(send_codec) << ", bitrate=" << send_codec.rate;
1976 2036
1977 webrtc::CodecInst current_codec = {0}; 2037 webrtc::CodecInst current_codec = {0};
1978 if (engine()->voe()->codec()->GetSendCodec(channel, current_codec) == 0 && 2038 if (engine()->voe()->codec()->GetSendCodec(channel, current_codec) == 0 &&
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
2096 engine()->voe()->base()->audio_transport(); 2156 engine()->voe()->base()->audio_transport();
2097 2157
2098 WebRtcAudioSendStream* stream = new WebRtcAudioSendStream( 2158 WebRtcAudioSendStream* stream = new WebRtcAudioSendStream(
2099 channel, audio_transport, ssrc, sp.cname, send_codec_spec_, 2159 channel, audio_transport, ssrc, sp.cname, send_codec_spec_,
2100 send_rtp_extensions_, call_, this); 2160 send_rtp_extensions_, call_, this);
2101 send_streams_.insert(std::make_pair(ssrc, stream)); 2161 send_streams_.insert(std::make_pair(ssrc, stream));
2102 2162
2103 // Set the current codecs to be used for the new channel. We need to do this 2163 // Set the current codecs to be used for the new channel. We need to do this
2104 // after adding the channel to send_channels_, because of how max bitrate is 2164 // after adding the channel to send_channels_, because of how max bitrate is
2105 // currently being configured by SetSendCodec(). 2165 // currently being configured by SetSendCodec().
2106 if (HasSendCodec() && !SetSendCodecs(channel, stream->rtp_parameters())) { 2166 if (HasSendCodec() && !SetSendCodecs(ssrc, stream->rtp_parameters())) {
2107 RemoveSendStream(ssrc); 2167 RemoveSendStream(ssrc);
2108 return false; 2168 return false;
2109 } 2169 }
2110 2170
2111 // At this point the stream's local SSRC has been updated. If it is the first 2171 // At this point the stream's local SSRC has been updated. If it is the first
2112 // send stream, make sure that all the receive streams are updated with the 2172 // send stream, make sure that all the receive streams are updated with the
2113 // same SSRC in order to send receiver reports. 2173 // same SSRC in order to send receiver reports.
2114 if (send_streams_.size() == 1) { 2174 if (send_streams_.size() == 1) {
2115 receiver_reports_ssrc_ = ssrc; 2175 receiver_reports_ssrc_ = ssrc;
2116 for (const auto& kv : recv_streams_) { 2176 for (const auto& kv : recv_streams_) {
(...skipping 544 matching lines...) Expand 10 before | Expand all | Expand 10 after
2661 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); 2721 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread());
2662 const auto it = send_streams_.find(ssrc); 2722 const auto it = send_streams_.find(ssrc);
2663 if (it != send_streams_.end()) { 2723 if (it != send_streams_.end()) {
2664 return it->second->channel(); 2724 return it->second->channel();
2665 } 2725 }
2666 return -1; 2726 return -1;
2667 } 2727 }
2668 } // namespace cricket 2728 } // namespace cricket
2669 2729
2670 #endif // HAVE_WEBRTC_VOICE 2730 #endif // HAVE_WEBRTC_VOICE
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698