Chromium Code Reviews| OLD | NEW | 
|---|---|
| 1 /* | 1 /* | 
| 2 * Copyright (c) 2004 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2004 The WebRTC project authors. All Rights Reserved. | 
| 3 * | 3 * | 
| 4 * Use of this source code is governed by a BSD-style license | 4 * Use of this source code is governed by a BSD-style license | 
| 5 * that can be found in the LICENSE file in the root of the source | 5 * that can be found in the LICENSE file in the root of the source | 
| 6 * tree. An additional intellectual property rights grant can be found | 6 * tree. An additional intellectual property rights grant can be found | 
| 7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may | 
| 8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. | 
| 9 */ | 9 */ | 
| 10 | 10 | 
| (...skipping 446 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 457 // G722 should be advertised as 8000 Hz because of the RFC "bug". | 457 // G722 should be advertised as 8000 Hz because of the RFC "bug". | 
| 458 {kG722CodecName, 8000, 1, 9, false, {10, 20, 30, 40, 50, 60}}, | 458 {kG722CodecName, 8000, 1, 9, false, {10, 20, 30, 40, 50, 60}}, | 
| 459 {kIlbcCodecName, 8000, 1, 102, false, {20, 30, 40, 60}}, | 459 {kIlbcCodecName, 8000, 1, 102, false, {20, 30, 40, 60}}, | 
| 460 {kPcmuCodecName, 8000, 1, 0, false, {10, 20, 30, 40, 50, 60}}, | 460 {kPcmuCodecName, 8000, 1, 0, false, {10, 20, 30, 40, 50, 60}}, | 
| 461 {kPcmaCodecName, 8000, 1, 8, false, {10, 20, 30, 40, 50, 60}}, | 461 {kPcmaCodecName, 8000, 1, 8, false, {10, 20, 30, 40, 50, 60}}, | 
| 462 {kCnCodecName, 32000, 1, 106, false, {}}, | 462 {kCnCodecName, 32000, 1, 106, false, {}}, | 
| 463 {kCnCodecName, 16000, 1, 105, false, {}}, | 463 {kCnCodecName, 16000, 1, 105, false, {}}, | 
| 464 {kCnCodecName, 8000, 1, 13, false, {}}, | 464 {kCnCodecName, 8000, 1, 13, false, {}}, | 
| 465 {kDtmfCodecName, 8000, 1, 126, false, {}} | 465 {kDtmfCodecName, 8000, 1, 126, false, {}} | 
| 466 }; | 466 }; | 
| 467 } // namespace { | |
| 468 | 467 | 
| 469 bool SendCodecSpec::operator==(const SendCodecSpec& rhs) const { | 468 rtc::Optional<int> ComputeSendBitrate(int max_send_bitrate_bps, | 
| 470 if (nack_enabled != rhs.nack_enabled) { | 469 int rtp_max_bitrate_bps, | 
| 471 return false; | 470 const webrtc::CodecInst& codec_inst) { | 
| 471 const int bps = MinPositive(max_send_bitrate_bps, rtp_max_bitrate_bps); | |
| 472 const int codec_rate = codec_inst.rate; | |
| 473 | |
| 474 // Bitrate is auto by default. | |
| 475 // TODO(bemasc): Fix this so that if SetMaxSendBitrate(50) is followed by | |
| 
 
the sun
2016/10/19 19:37:52
Isn't this already fixed with your change?
 
minyue-webrtc
2016/10/20 08:47:12
I think so, but it seems that this has been fixed
 
 | |
| 476 // SetMaxSendBitrate(0), the second call removes the previous limit. | |
| 477 if (bps <= 0) { | |
| 478 return rtc::Optional<int>(codec_rate); | |
| 472 } | 479 } | 
| 473 if (transport_cc_enabled != rhs.transport_cc_enabled) { | 480 | 
| 474 return false; | 481 if (codec_inst.pltype == -1) { | 
| 482 return rtc::Optional<int>(codec_rate); | |
| 483 ; | |
| 
 
the sun
2016/10/19 19:37:52
remove
 
minyue-webrtc
2016/10/20 08:47:12
oh, yes.
 
 | |
| 475 } | 484 } | 
| 476 if (enable_codec_fec != rhs.enable_codec_fec) { | 485 | 
| 477 return false; | 486 if (WebRtcVoiceCodecs::IsCodecMultiRate(codec_inst)) { | 
| 487 // If codec is multi-rate then just set the bitrate. | |
| 488 return rtc::Optional<int>( | |
| 489 std::min(bps, WebRtcVoiceCodecs::MaxBitrateBps(codec_inst))); | |
| 478 } | 490 } | 
| 479 if (enable_opus_dtx != rhs.enable_opus_dtx) { | 491 | 
| 480 return false; | 492 if (bps < codec_inst.rate) { | 
| 493 // If codec is not multi-rate and |bps| is less than the fixed bitrate then | |
| 494 // fail. If codec is not multi-rate and |bps| exceeds or equal the fixed | |
| 495 // bitrate then ignore. | |
| 496 LOG(LS_ERROR) << "Failed to set codec " << codec_inst.plname | |
| 497 << " to bitrate " << bps << " bps" | |
| 498 << ", requires at least " << codec_inst.rate << " bps."; | |
| 499 return rtc::Optional<int>(); | |
| 481 } | 500 } | 
| 482 if (opus_max_playback_rate != rhs.opus_max_playback_rate) { | 501 return rtc::Optional<int>(codec_rate); | 
| 483 return false; | |
| 484 } | |
| 485 if (red_payload_type != rhs.red_payload_type) { | |
| 486 return false; | |
| 487 } | |
| 488 if (cng_payload_type != rhs.cng_payload_type) { | |
| 489 return false; | |
| 490 } | |
| 491 if (cng_plfreq != rhs.cng_plfreq) { | |
| 492 return false; | |
| 493 } | |
| 494 if (codec_inst != rhs.codec_inst) { | |
| 495 return false; | |
| 496 } | |
| 497 return true; | |
| 498 } | 502 } | 
| 499 | 503 | 
| 500 bool SendCodecSpec::operator!=(const SendCodecSpec& rhs) const { | 504 } // namespace { | 
| 501 return !(*this == rhs); | |
| 502 } | |
| 503 | 505 | 
| 504 bool WebRtcVoiceEngine::ToCodecInst(const AudioCodec& in, | 506 bool WebRtcVoiceEngine::ToCodecInst(const AudioCodec& in, | 
| 505 webrtc::CodecInst* out) { | 507 webrtc::CodecInst* out) { | 
| 506 return WebRtcVoiceCodecs::ToCodecInst(in, out); | 508 return WebRtcVoiceCodecs::ToCodecInst(in, out); | 
| 507 } | 509 } | 
| 508 | 510 | 
| 509 WebRtcVoiceEngine::WebRtcVoiceEngine( | 511 WebRtcVoiceEngine::WebRtcVoiceEngine( | 
| 510 webrtc::AudioDeviceModule* adm, | 512 webrtc::AudioDeviceModule* adm, | 
| 511 const rtc::scoped_refptr<webrtc::AudioDecoderFactory>& decoder_factory) | 513 const rtc::scoped_refptr<webrtc::AudioDecoderFactory>& decoder_factory) | 
| 512 : WebRtcVoiceEngine(adm, decoder_factory, new VoEWrapper()) { | 514 : WebRtcVoiceEngine(adm, decoder_factory, new VoEWrapper()) { | 
| (...skipping 620 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1133 | 1135 | 
| 1134 // Add telephone-event codec last | 1136 // Add telephone-event codec last | 
| 1135 map_format({kDtmfCodecName, 8000, 1}); | 1137 map_format({kDtmfCodecName, 8000, 1}); | 
| 1136 | 1138 | 
| 1137 return out; | 1139 return out; | 
| 1138 } | 1140 } | 
| 1139 | 1141 | 
| 1140 class WebRtcVoiceMediaChannel::WebRtcAudioSendStream | 1142 class WebRtcVoiceMediaChannel::WebRtcAudioSendStream | 
| 1141 : public AudioSource::Sink { | 1143 : public AudioSource::Sink { | 
| 1142 public: | 1144 public: | 
| 1143 WebRtcAudioSendStream(int ch, | 1145 WebRtcAudioSendStream( | 
| 1144 webrtc::AudioTransport* voe_audio_transport, | 1146 int ch, | 
| 1145 uint32_t ssrc, | 1147 webrtc::AudioTransport* voe_audio_transport, | 
| 1146 const std::string& c_name, | 1148 uint32_t ssrc, | 
| 1147 const SendCodecSpec& send_codec_spec, | 1149 const std::string& c_name, | 
| 1148 const std::vector<webrtc::RtpExtension>& extensions, | 1150 const webrtc::AudioSendStream::Config::SendCodecSpec& send_codec_spec, | 
| 1149 webrtc::Call* call, | 1151 const std::vector<webrtc::RtpExtension>& extensions, | 
| 1150 webrtc::Transport* send_transport) | 1152 int max_send_bitrate_bps, | 
| 1153 webrtc::Call* call, | |
| 1154 webrtc::Transport* send_transport) | |
| 1151 : voe_audio_transport_(voe_audio_transport), | 1155 : voe_audio_transport_(voe_audio_transport), | 
| 1152 call_(call), | 1156 call_(call), | 
| 1153 config_(send_transport), | 1157 config_(send_transport), | 
| 1158 max_send_bitrate_bps_(max_send_bitrate_bps), | |
| 1154 rtp_parameters_(CreateRtpParametersWithOneEncoding()) { | 1159 rtp_parameters_(CreateRtpParametersWithOneEncoding()) { | 
| 1155 RTC_DCHECK_GE(ch, 0); | 1160 RTC_DCHECK_GE(ch, 0); | 
| 1156 // TODO(solenberg): Once we're not using FakeWebRtcVoiceEngine anymore: | 1161 // TODO(solenberg): Once we're not using FakeWebRtcVoiceEngine anymore: | 
| 1157 // RTC_DCHECK(voe_audio_transport); | 1162 // RTC_DCHECK(voe_audio_transport); | 
| 1158 RTC_DCHECK(call); | 1163 RTC_DCHECK(call); | 
| 1159 config_.rtp.ssrc = ssrc; | 1164 config_.rtp.ssrc = ssrc; | 
| 1160 config_.rtp.c_name = c_name; | 1165 config_.rtp.c_name = c_name; | 
| 1161 config_.voe_channel_id = ch; | 1166 config_.voe_channel_id = ch; | 
| 1162 config_.rtp.extensions = extensions; | 1167 config_.rtp.extensions = extensions; | 
| 1163 RecreateAudioSendStream(send_codec_spec); | 1168 RecreateAudioSendStream(send_codec_spec); | 
| 1164 } | 1169 } | 
| 1165 | 1170 | 
| 1166 ~WebRtcAudioSendStream() override { | 1171 ~WebRtcAudioSendStream() override { | 
| 1167 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 1172 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 
| 1168 ClearSource(); | 1173 ClearSource(); | 
| 1169 call_->DestroyAudioSendStream(stream_); | 1174 call_->DestroyAudioSendStream(stream_); | 
| 1170 } | 1175 } | 
| 1171 | 1176 | 
| 1172 void RecreateAudioSendStream(const SendCodecSpec& send_codec_spec) { | 1177 void RecreateAudioSendStream( | 
| 1178 const webrtc::AudioSendStream::Config::SendCodecSpec& send_codec_spec) { | |
| 1173 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 1179 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 
| 1180 auto send_rate = ComputeSendBitrate( | |
| 1181 max_send_bitrate_bps_, rtp_parameters_.encodings[0].max_bitrate_bps, | |
| 1182 send_codec_spec.codec_inst); | |
| 1183 RTC_CHECK(send_rate); | |
| 
 
the sun
2016/10/19 19:37:52
DCHECK - this is not a runtime error, it's a logic
 
 | |
| 1184 send_codec_spec_ = send_codec_spec; | |
| 1174 config_.rtp.nack.rtp_history_ms = | 1185 config_.rtp.nack.rtp_history_ms = | 
| 1175 send_codec_spec.nack_enabled ? kNackRtpHistoryMs : 0; | 1186 send_codec_spec_.nack_enabled ? kNackRtpHistoryMs : 0; | 
| 1187 config_.send_codec_spec = send_codec_spec_; | |
| 1188 config_.send_codec_spec.codec_inst.rate = *send_rate; | |
| 1176 RecreateAudioSendStream(); | 1189 RecreateAudioSendStream(); | 
| 1177 } | 1190 } | 
| 1178 | 1191 | 
| 1179 void RecreateAudioSendStream( | 1192 void RecreateAudioSendStream( | 
| 1180 const std::vector<webrtc::RtpExtension>& extensions) { | 1193 const std::vector<webrtc::RtpExtension>& extensions) { | 
| 1181 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 1194 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 
| 1182 config_.rtp.extensions = extensions; | 1195 config_.rtp.extensions = extensions; | 
| 1183 RecreateAudioSendStream(); | 1196 RecreateAudioSendStream(); | 
| 1184 } | 1197 } | 
| 1185 | 1198 | 
| 1199 bool SetMaxSendBitrate(int bps) { | |
| 1200 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | |
| 1201 auto send_rate = | |
| 1202 ComputeSendBitrate(bps, rtp_parameters_.encodings[0].max_bitrate_bps, | |
| 1203 send_codec_spec_.codec_inst); | |
| 1204 if (!send_rate) { | |
| 1205 return false; | |
| 1206 } | |
| 1207 | |
| 1208 max_send_bitrate_bps_ = bps; | |
| 1209 | |
| 1210 if (config_.send_codec_spec.codec_inst.rate != *send_rate) { | |
| 1211 // Recreate AudioSendStream with new bit rate. | |
| 1212 config_.send_codec_spec.codec_inst.rate = *send_rate; | |
| 1213 RecreateAudioSendStream(); | |
| 1214 } | |
| 1215 return true; | |
| 1216 } | |
| 1217 | |
| 1186 bool SendTelephoneEvent(int payload_type, int event, int duration_ms) { | 1218 bool SendTelephoneEvent(int payload_type, int event, int duration_ms) { | 
| 1187 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 1219 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 
| 1188 RTC_DCHECK(stream_); | 1220 RTC_DCHECK(stream_); | 
| 1189 return stream_->SendTelephoneEvent(payload_type, event, duration_ms); | 1221 return stream_->SendTelephoneEvent(payload_type, event, duration_ms); | 
| 1190 } | 1222 } | 
| 1191 | 1223 | 
| 1192 void SetSend(bool send) { | 1224 void SetSend(bool send) { | 
| 1193 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 1225 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 
| 1194 send_ = send; | 1226 send_ = send; | 
| 1195 UpdateSendState(); | 1227 UpdateSendState(); | 
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1268 // Accessor to the VoE channel ID. | 1300 // Accessor to the VoE channel ID. | 
| 1269 int channel() const { | 1301 int channel() const { | 
| 1270 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 1302 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 
| 1271 return config_.voe_channel_id; | 1303 return config_.voe_channel_id; | 
| 1272 } | 1304 } | 
| 1273 | 1305 | 
| 1274 const webrtc::RtpParameters& rtp_parameters() const { | 1306 const webrtc::RtpParameters& rtp_parameters() const { | 
| 1275 return rtp_parameters_; | 1307 return rtp_parameters_; | 
| 1276 } | 1308 } | 
| 1277 | 1309 | 
| 1278 void SetRtpParameters(const webrtc::RtpParameters& parameters) { | 1310 bool SetRtpParameters(const webrtc::RtpParameters& parameters) { | 
| 1279 RTC_CHECK_EQ(1UL, parameters.encodings.size()); | 1311 RTC_CHECK_EQ(1UL, parameters.encodings.size()); | 
| 1312 auto send_rate = ComputeSendBitrate(max_send_bitrate_bps_, | |
| 1313 parameters.encodings[0].max_bitrate_bps, | |
| 1314 send_codec_spec_.codec_inst); | |
| 1315 if (!send_rate) { | |
| 1316 return false; | |
| 1317 } | |
| 1318 | |
| 1280 rtp_parameters_ = parameters; | 1319 rtp_parameters_ = parameters; | 
| 1281 // parameters.encodings[0].active could have changed. | 1320 | 
| 1282 UpdateSendState(); | 1321 // parameters.encodings[0].encodings[0].max_bitrate_bps could have changed. | 
| 1322 if (config_.send_codec_spec.codec_inst.rate != *send_rate) { | |
| 1323 // Recreate AudioSendStream with new bit rate. | |
| 1324 config_.send_codec_spec.codec_inst.rate = *send_rate; | |
| 1325 RecreateAudioSendStream(); | |
| 1326 } else { | |
| 1327 // parameters.encodings[0].active could have changed. | |
| 1328 UpdateSendState(); | |
| 1329 } | |
| 1330 return true; | |
| 1283 } | 1331 } | 
| 1284 | 1332 | 
| 1285 private: | 1333 private: | 
| 1286 void UpdateSendState() { | 1334 void UpdateSendState() { | 
| 1287 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 1335 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 
| 1288 RTC_DCHECK(stream_); | 1336 RTC_DCHECK(stream_); | 
| 1289 RTC_DCHECK_EQ(1UL, rtp_parameters_.encodings.size()); | 1337 RTC_DCHECK_EQ(1UL, rtp_parameters_.encodings.size()); | 
| 1290 if (send_ && source_ != nullptr && rtp_parameters_.encodings[0].active) { | 1338 if (send_ && source_ != nullptr && rtp_parameters_.encodings[0].active) { | 
| 1291 stream_->Start(); | 1339 stream_->Start(); | 
| 1292 } else { // !send || source_ = nullptr | 1340 } else { // !send || source_ = nullptr | 
| (...skipping 28 matching lines...) Expand all Loading... | |
| 1321 // The stream is owned by WebRtcAudioSendStream and may be reallocated if | 1369 // The stream is owned by WebRtcAudioSendStream and may be reallocated if | 
| 1322 // configuration changes. | 1370 // configuration changes. | 
| 1323 webrtc::AudioSendStream* stream_ = nullptr; | 1371 webrtc::AudioSendStream* stream_ = nullptr; | 
| 1324 | 1372 | 
| 1325 // Raw pointer to AudioSource owned by LocalAudioTrackHandler. | 1373 // Raw pointer to AudioSource owned by LocalAudioTrackHandler. | 
| 1326 // PeerConnection will make sure invalidating the pointer before the object | 1374 // PeerConnection will make sure invalidating the pointer before the object | 
| 1327 // goes away. | 1375 // goes away. | 
| 1328 AudioSource* source_ = nullptr; | 1376 AudioSource* source_ = nullptr; | 
| 1329 bool send_ = false; | 1377 bool send_ = false; | 
| 1330 bool muted_ = false; | 1378 bool muted_ = false; | 
| 1379 int max_send_bitrate_bps_; | |
| 1331 webrtc::RtpParameters rtp_parameters_; | 1380 webrtc::RtpParameters rtp_parameters_; | 
| 1381 webrtc::AudioSendStream::Config::SendCodecSpec send_codec_spec_; | |
| 
 
minyue-webrtc
2016/10/19 14:39:19
On renaming current_rate to codec_rate. I figured
 
the sun
2016/10/19 19:37:52
Acknowledged.
 
 | |
| 1332 | 1382 | 
| 1333 RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(WebRtcAudioSendStream); | 1383 RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(WebRtcAudioSendStream); | 
| 1334 }; | 1384 }; | 
| 1335 | 1385 | 
| 1336 class WebRtcVoiceMediaChannel::WebRtcAudioReceiveStream { | 1386 class WebRtcVoiceMediaChannel::WebRtcAudioReceiveStream { | 
| 1337 public: | 1387 public: | 
| 1338 WebRtcAudioReceiveStream( | 1388 WebRtcAudioReceiveStream( | 
| 1339 int ch, | 1389 int ch, | 
| 1340 uint32_t remote_ssrc, | 1390 uint32_t remote_ssrc, | 
| 1341 uint32_t local_ssrc, | 1391 uint32_t local_ssrc, | 
| (...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1581 | 1631 | 
| 1582 // TODO(deadbeef): Handle setting parameters with a list of codecs in a | 1632 // TODO(deadbeef): Handle setting parameters with a list of codecs in a | 
| 1583 // different order (which should change the send codec). | 1633 // different order (which should change the send codec). | 
| 1584 webrtc::RtpParameters current_parameters = GetRtpSendParameters(ssrc); | 1634 webrtc::RtpParameters current_parameters = GetRtpSendParameters(ssrc); | 
| 1585 if (current_parameters.codecs != parameters.codecs) { | 1635 if (current_parameters.codecs != parameters.codecs) { | 
| 1586 LOG(LS_ERROR) << "Using SetParameters to change the set of codecs " | 1636 LOG(LS_ERROR) << "Using SetParameters to change the set of codecs " | 
| 1587 << "is not currently supported."; | 1637 << "is not currently supported."; | 
| 1588 return false; | 1638 return false; | 
| 1589 } | 1639 } | 
| 1590 | 1640 | 
| 1591 if (!SetChannelSendParameters(it->second->channel(), parameters)) { | 1641 // TODO(minyue): The following legacy actions go into | 
| 1592 LOG(LS_WARNING) << "Failed to set send RtpParameters."; | 1642 // |WebRtcAudioSendStream::SetRtpParameters()| which is called at the end, | 
| 1593 return false; | 1643 // though there are two difference: | 
| 1594 } | 1644 // 1. |WebRtcVoiceMediaChannel::SetChannelSendParameters()| only calls | 
| 1645 // |SetSendCodec| while |WebRtcAudioSendStream::SetRtpParameters()| calls | |
| 1646 // |SetSendCodecs|. The outcome should be the same. | |
| 1647 // 2. AudioSendStream can be recreated. | |
| 1648 | |
| 1595 // Codecs are handled at the WebRtcVoiceMediaChannel level. | 1649 // Codecs are handled at the WebRtcVoiceMediaChannel level. | 
| 1596 webrtc::RtpParameters reduced_params = parameters; | 1650 webrtc::RtpParameters reduced_params = parameters; | 
| 1597 reduced_params.codecs.clear(); | 1651 reduced_params.codecs.clear(); | 
| 1598 it->second->SetRtpParameters(reduced_params); | 1652 return it->second->SetRtpParameters(reduced_params); | 
| 1599 return true; | |
| 1600 } | 1653 } | 
| 1601 | 1654 | 
| 1602 webrtc::RtpParameters WebRtcVoiceMediaChannel::GetRtpReceiveParameters( | 1655 webrtc::RtpParameters WebRtcVoiceMediaChannel::GetRtpReceiveParameters( | 
| 1603 uint32_t ssrc) const { | 1656 uint32_t ssrc) const { | 
| 1604 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 1657 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 
| 1605 auto it = recv_streams_.find(ssrc); | 1658 auto it = recv_streams_.find(ssrc); | 
| 1606 if (it == recv_streams_.end()) { | 1659 if (it == recv_streams_.end()) { | 
| 1607 LOG(LS_WARNING) << "Attempting to get RTP receive parameters for stream " | 1660 LOG(LS_WARNING) << "Attempting to get RTP receive parameters for stream " | 
| 1608 << "with ssrc " << ssrc << " which doesn't exist."; | 1661 << "with ssrc " << ssrc << " which doesn't exist."; | 
| 1609 return webrtc::RtpParameters(); | 1662 return webrtc::RtpParameters(); | 
| (...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1749 } | 1802 } | 
| 1750 dtmf_payload_type_ = rtc::Optional<int>(codec.id); | 1803 dtmf_payload_type_ = rtc::Optional<int>(codec.id); | 
| 1751 break; | 1804 break; | 
| 1752 } | 1805 } | 
| 1753 } | 1806 } | 
| 1754 | 1807 | 
| 1755 // Scan through the list to figure out the codec to use for sending, along | 1808 // Scan through the list to figure out the codec to use for sending, along | 
| 1756 // with the proper configuration for VAD, CNG, NACK and Opus-specific | 1809 // with the proper configuration for VAD, CNG, NACK and Opus-specific | 
| 1757 // parameters. | 1810 // parameters. | 
| 1758 // TODO(solenberg): Refactor this logic once we create AudioEncoders here. | 1811 // TODO(solenberg): Refactor this logic once we create AudioEncoders here. | 
| 1759 SendCodecSpec send_codec_spec; | 1812 webrtc::AudioSendStream::Config::SendCodecSpec send_codec_spec; | 
| 1760 { | 1813 { | 
| 1761 send_codec_spec.nack_enabled = send_codec_spec_.nack_enabled; | 1814 send_codec_spec.nack_enabled = send_codec_spec_.nack_enabled; | 
| 1762 | 1815 | 
| 1763 // Find send codec (the first non-telephone-event/CN codec). | 1816 // Find send codec (the first non-telephone-event/CN codec). | 
| 1764 const AudioCodec* codec = WebRtcVoiceCodecs::GetPreferredCodec( | 1817 const AudioCodec* codec = WebRtcVoiceCodecs::GetPreferredCodec( | 
| 1765 codecs, &send_codec_spec.codec_inst); | 1818 codecs, &send_codec_spec.codec_inst); | 
| 1766 if (!codec) { | 1819 if (!codec) { | 
| 1767 LOG(LS_WARNING) << "Received empty list of codecs."; | 1820 LOG(LS_WARNING) << "Received empty list of codecs."; | 
| 1768 return false; | 1821 return false; | 
| 1769 } | 1822 } | 
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1823 break; | 1876 break; | 
| 1824 } | 1877 } | 
| 1825 } | 1878 } | 
| 1826 } | 1879 } | 
| 1827 | 1880 | 
| 1828 // Apply new settings to all streams. | 1881 // Apply new settings to all streams. | 
| 1829 if (send_codec_spec_ != send_codec_spec) { | 1882 if (send_codec_spec_ != send_codec_spec) { | 
| 1830 send_codec_spec_ = std::move(send_codec_spec); | 1883 send_codec_spec_ = std::move(send_codec_spec); | 
| 1831 for (const auto& kv : send_streams_) { | 1884 for (const auto& kv : send_streams_) { | 
| 1832 kv.second->RecreateAudioSendStream(send_codec_spec_); | 1885 kv.second->RecreateAudioSendStream(send_codec_spec_); | 
| 1833 if (!SetSendCodecs(kv.second->channel(), kv.second->rtp_parameters())) { | |
| 1834 return false; | |
| 1835 } | |
| 1836 } | 1886 } | 
| 1837 } | 1887 } | 
| 1838 | 1888 | 
| 1839 // Check if the transport cc feedback or NACK status has changed on the | 1889 // Check if the transport cc feedback or NACK status has changed on the | 
| 1840 // preferred send codec, and in that case reconfigure all receive streams. | 1890 // preferred send codec, and in that case reconfigure all receive streams. | 
| 1841 if (recv_transport_cc_enabled_ != send_codec_spec_.transport_cc_enabled || | 1891 if (recv_transport_cc_enabled_ != send_codec_spec_.transport_cc_enabled || | 
| 1842 recv_nack_enabled_ != send_codec_spec_.nack_enabled) { | 1892 recv_nack_enabled_ != send_codec_spec_.nack_enabled) { | 
| 1843 LOG(LS_INFO) << "Recreate all the receive streams because the send " | 1893 LOG(LS_INFO) << "Recreate all the receive streams because the send " | 
| 1844 "codec has changed."; | 1894 "codec has changed."; | 
| 1845 recv_transport_cc_enabled_ = send_codec_spec_.transport_cc_enabled; | 1895 recv_transport_cc_enabled_ = send_codec_spec_.transport_cc_enabled; | 
| 1846 recv_nack_enabled_ = send_codec_spec_.nack_enabled; | 1896 recv_nack_enabled_ = send_codec_spec_.nack_enabled; | 
| 1847 for (auto& kv : recv_streams_) { | 1897 for (auto& kv : recv_streams_) { | 
| 1848 kv.second->RecreateAudioReceiveStream(recv_transport_cc_enabled_, | 1898 kv.second->RecreateAudioReceiveStream(recv_transport_cc_enabled_, | 
| 1849 recv_nack_enabled_); | 1899 recv_nack_enabled_); | 
| 1850 } | 1900 } | 
| 1851 } | 1901 } | 
| 1852 | 1902 | 
| 1853 send_codecs_ = codecs; | 1903 send_codecs_ = codecs; | 
| 1854 return true; | 1904 return true; | 
| 1855 } | 1905 } | 
| 1856 | 1906 | 
| 1857 // Apply current codec settings to a single voe::Channel used for sending. | |
| 1858 bool WebRtcVoiceMediaChannel::SetSendCodecs( | |
| 1859 int channel, | |
| 1860 const webrtc::RtpParameters& rtp_parameters) { | |
| 1861 // Disable VAD and FEC unless we know the other side wants them. | |
| 1862 engine()->voe()->codec()->SetVADStatus(channel, false); | |
| 1863 engine()->voe()->codec()->SetFECStatus(channel, false); | |
| 1864 | |
| 1865 // Set the codec immediately, since SetVADStatus() depends on whether | |
| 1866 // the current codec is mono or stereo. | |
| 1867 if (!SetSendCodec(channel, send_codec_spec_.codec_inst)) { | |
| 1868 return false; | |
| 1869 } | |
| 1870 | |
| 1871 // FEC should be enabled after SetSendCodec. | |
| 1872 if (send_codec_spec_.enable_codec_fec) { | |
| 1873 LOG(LS_INFO) << "Attempt to enable codec internal FEC on channel " | |
| 1874 << channel; | |
| 1875 if (engine()->voe()->codec()->SetFECStatus(channel, true) == -1) { | |
| 1876 // Enable codec internal FEC. Treat any failure as fatal internal error. | |
| 1877 LOG_RTCERR2(SetFECStatus, channel, true); | |
| 1878 return false; | |
| 1879 } | |
| 1880 } | |
| 1881 | |
| 1882 if (IsCodec(send_codec_spec_.codec_inst, kOpusCodecName)) { | |
| 1883 // DTX and maxplaybackrate should be set after SetSendCodec. Because current | |
| 1884 // send codec has to be Opus. | |
| 1885 | |
| 1886 // Set Opus internal DTX. | |
| 1887 LOG(LS_INFO) << "Attempt to " | |
| 1888 << (send_codec_spec_.enable_opus_dtx ? "enable" : "disable") | |
| 1889 << " Opus DTX on channel " | |
| 1890 << channel; | |
| 1891 if (engine()->voe()->codec()->SetOpusDtx(channel, | |
| 1892 send_codec_spec_.enable_opus_dtx)) { | |
| 1893 LOG_RTCERR2(SetOpusDtx, channel, send_codec_spec_.enable_opus_dtx); | |
| 1894 return false; | |
| 1895 } | |
| 1896 | |
| 1897 // If opus_max_playback_rate <= 0, the default maximum playback rate | |
| 1898 // (48 kHz) will be used. | |
| 1899 if (send_codec_spec_.opus_max_playback_rate > 0) { | |
| 1900 LOG(LS_INFO) << "Attempt to set maximum playback rate to " | |
| 1901 << send_codec_spec_.opus_max_playback_rate | |
| 1902 << " Hz on channel " | |
| 1903 << channel; | |
| 1904 if (engine()->voe()->codec()->SetOpusMaxPlaybackRate( | |
| 1905 channel, send_codec_spec_.opus_max_playback_rate) == -1) { | |
| 1906 LOG_RTCERR2(SetOpusMaxPlaybackRate, channel, | |
| 1907 send_codec_spec_.opus_max_playback_rate); | |
| 1908 return false; | |
| 1909 } | |
| 1910 } | |
| 1911 } | |
| 1912 // TODO(solenberg): SetMaxSendBitrate() yields another call to SetSendCodec(). | |
| 1913 // Check if it is possible to fuse with the previous call in this function. | |
| 1914 SetChannelSendParameters(channel, rtp_parameters); | |
| 1915 | |
| 1916 // Set the CN payloadtype and the VAD status. | |
| 1917 if (send_codec_spec_.cng_payload_type != -1) { | |
| 1918 // The CN payload type for 8000 Hz clockrate is fixed at 13. | |
| 1919 if (send_codec_spec_.cng_plfreq != 8000) { | |
| 1920 webrtc::PayloadFrequencies cn_freq; | |
| 1921 switch (send_codec_spec_.cng_plfreq) { | |
| 1922 case 16000: | |
| 1923 cn_freq = webrtc::kFreq16000Hz; | |
| 1924 break; | |
| 1925 case 32000: | |
| 1926 cn_freq = webrtc::kFreq32000Hz; | |
| 1927 break; | |
| 1928 default: | |
| 1929 RTC_NOTREACHED(); | |
| 1930 return false; | |
| 1931 } | |
| 1932 if (engine()->voe()->codec()->SetSendCNPayloadType( | |
| 1933 channel, send_codec_spec_.cng_payload_type, cn_freq) == -1) { | |
| 1934 LOG_RTCERR3(SetSendCNPayloadType, channel, | |
| 1935 send_codec_spec_.cng_payload_type, cn_freq); | |
| 1936 // TODO(ajm): This failure condition will be removed from VoE. | |
| 1937 // Restore the return here when we update to a new enough webrtc. | |
| 1938 // | |
| 1939 // Not returning false because the SetSendCNPayloadType will fail if | |
| 1940 // the channel is already sending. | |
| 1941 // This can happen if the remote description is applied twice, for | |
| 1942 // example in the case of ROAP on top of JSEP, where both side will | |
| 1943 // send the offer. | |
| 1944 } | |
| 1945 } | |
| 1946 | |
| 1947 // Only turn on VAD if we have a CN payload type that matches the | |
| 1948 // clockrate for the codec we are going to use. | |
| 1949 if (send_codec_spec_.cng_plfreq == send_codec_spec_.codec_inst.plfreq && | |
| 1950 send_codec_spec_.codec_inst.channels == 1) { | |
| 1951 // TODO(minyue): If CN frequency == 48000 Hz is allowed, consider the | |
| 1952 // interaction between VAD and Opus FEC. | |
| 1953 LOG(LS_INFO) << "Enabling VAD"; | |
| 1954 if (engine()->voe()->codec()->SetVADStatus(channel, true) == -1) { | |
| 1955 LOG_RTCERR2(SetVADStatus, channel, true); | |
| 1956 return false; | |
| 1957 } | |
| 1958 } | |
| 1959 } | |
| 1960 return true; | |
| 1961 } | |
| 1962 | |
| 1963 bool WebRtcVoiceMediaChannel::SetSendCodec( | |
| 1964 int channel, const webrtc::CodecInst& send_codec) { | |
| 1965 LOG(LS_INFO) << "Send channel " << channel << " selected voice codec " | |
| 1966 << ToString(send_codec) << ", bitrate=" << send_codec.rate; | |
| 1967 | |
| 1968 webrtc::CodecInst current_codec = {0}; | |
| 1969 if (engine()->voe()->codec()->GetSendCodec(channel, current_codec) == 0 && | |
| 1970 (send_codec == current_codec)) { | |
| 1971 // Codec is already configured, we can return without setting it again. | |
| 1972 return true; | |
| 1973 } | |
| 1974 | |
| 1975 if (engine()->voe()->codec()->SetSendCodec(channel, send_codec) == -1) { | |
| 1976 LOG_RTCERR2(SetSendCodec, channel, ToString(send_codec)); | |
| 1977 return false; | |
| 1978 } | |
| 1979 return true; | |
| 1980 } | |
| 1981 | |
| 1982 void WebRtcVoiceMediaChannel::SetPlayout(bool playout) { | 1907 void WebRtcVoiceMediaChannel::SetPlayout(bool playout) { | 
| 1983 TRACE_EVENT0("webrtc", "WebRtcVoiceMediaChannel::SetPlayout"); | 1908 TRACE_EVENT0("webrtc", "WebRtcVoiceMediaChannel::SetPlayout"); | 
| 1984 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 1909 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 
| 1985 if (playout_ == playout) { | 1910 if (playout_ == playout) { | 
| 1986 return; | 1911 return; | 
| 1987 } | 1912 } | 
| 1988 | 1913 | 
| 1989 for (const auto& kv : recv_streams_) { | 1914 for (const auto& kv : recv_streams_) { | 
| 1990 kv.second->SetPlayout(playout); | 1915 kv.second->SetPlayout(playout); | 
| 1991 } | 1916 } | 
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2076 return false; | 2001 return false; | 
| 2077 } | 2002 } | 
| 2078 | 2003 | 
| 2079 // Save the channel to send_streams_, so that RemoveSendStream() can still | 2004 // Save the channel to send_streams_, so that RemoveSendStream() can still | 
| 2080 // delete the channel in case failure happens below. | 2005 // delete the channel in case failure happens below. | 
| 2081 webrtc::AudioTransport* audio_transport = | 2006 webrtc::AudioTransport* audio_transport = | 
| 2082 engine()->voe()->base()->audio_transport(); | 2007 engine()->voe()->base()->audio_transport(); | 
| 2083 | 2008 | 
| 2084 WebRtcAudioSendStream* stream = new WebRtcAudioSendStream( | 2009 WebRtcAudioSendStream* stream = new WebRtcAudioSendStream( | 
| 2085 channel, audio_transport, ssrc, sp.cname, send_codec_spec_, | 2010 channel, audio_transport, ssrc, sp.cname, send_codec_spec_, | 
| 2086 send_rtp_extensions_, call_, this); | 2011 send_rtp_extensions_, max_send_bitrate_bps_, call_, this); | 
| 2087 send_streams_.insert(std::make_pair(ssrc, stream)); | 2012 send_streams_.insert(std::make_pair(ssrc, stream)); | 
| 2088 | 2013 | 
| 2089 // Set the current codecs to be used for the new channel. We need to do this | |
| 2090 // after adding the channel to send_channels_, because of how max bitrate is | |
| 2091 // currently being configured by SetSendCodec(). | |
| 2092 if (HasSendCodec() && !SetSendCodecs(channel, stream->rtp_parameters())) { | |
| 2093 RemoveSendStream(ssrc); | |
| 2094 return false; | |
| 2095 } | |
| 2096 | |
| 2097 // At this point the stream's local SSRC has been updated. If it is the first | 2014 // At this point the stream's local SSRC has been updated. If it is the first | 
| 2098 // send stream, make sure that all the receive streams are updated with the | 2015 // send stream, make sure that all the receive streams are updated with the | 
| 2099 // same SSRC in order to send receiver reports. | 2016 // same SSRC in order to send receiver reports. | 
| 2100 if (send_streams_.size() == 1) { | 2017 if (send_streams_.size() == 1) { | 
| 2101 receiver_reports_ssrc_ = ssrc; | 2018 receiver_reports_ssrc_ = ssrc; | 
| 2102 for (const auto& kv : recv_streams_) { | 2019 for (const auto& kv : recv_streams_) { | 
| 2103 // TODO(solenberg): Allow applications to set the RTCP SSRC of receive | 2020 // TODO(solenberg): Allow applications to set the RTCP SSRC of receive | 
| 2104 // streams instead, so we can avoid recreating the streams here. | 2021 // streams instead, so we can avoid recreating the streams here. | 
| 2105 kv.second->RecreateAudioReceiveStream(ssrc); | 2022 kv.second->RecreateAudioReceiveStream(ssrc); | 
| 2106 int recv_channel = kv.second->channel(); | 2023 int recv_channel = kv.second->channel(); | 
| (...skipping 353 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2460 webrtc::AudioProcessing* ap = engine()->voe()->base()->audio_processing(); | 2377 webrtc::AudioProcessing* ap = engine()->voe()->base()->audio_processing(); | 
| 2461 if (ap) { | 2378 if (ap) { | 
| 2462 ap->set_output_will_be_muted(all_muted); | 2379 ap->set_output_will_be_muted(all_muted); | 
| 2463 } | 2380 } | 
| 2464 return true; | 2381 return true; | 
| 2465 } | 2382 } | 
| 2466 | 2383 | 
| 2467 bool WebRtcVoiceMediaChannel::SetMaxSendBitrate(int bps) { | 2384 bool WebRtcVoiceMediaChannel::SetMaxSendBitrate(int bps) { | 
| 2468 LOG(LS_INFO) << "WebRtcVoiceMediaChannel::SetMaxSendBitrate."; | 2385 LOG(LS_INFO) << "WebRtcVoiceMediaChannel::SetMaxSendBitrate."; | 
| 2469 max_send_bitrate_bps_ = bps; | 2386 max_send_bitrate_bps_ = bps; | 
| 2470 | 2387 bool success = true; | 
| 2471 for (const auto& kv : send_streams_) { | 2388 for (const auto& kv : send_streams_) { | 
| 2472 if (!SetChannelSendParameters(kv.second->channel(), | 2389 if (!kv.second->SetMaxSendBitrate(max_send_bitrate_bps_)) { | 
| 2473 kv.second->rtp_parameters())) { | 2390 success = false; | 
| 2474 return false; | |
| 2475 } | 2391 } | 
| 2476 } | 2392 } | 
| 2477 return true; | 2393 return success; | 
| 2478 } | |
| 2479 | |
| 2480 bool WebRtcVoiceMediaChannel::SetChannelSendParameters( | |
| 2481 int channel, | |
| 2482 const webrtc::RtpParameters& parameters) { | |
| 2483 RTC_CHECK_EQ(1UL, parameters.encodings.size()); | |
| 2484 // TODO(deadbeef): Handle setting parameters with a list of codecs in a | |
| 2485 // different order (which should change the send codec). | |
| 2486 return SetMaxSendBitrate( | |
| 2487 channel, MinPositive(max_send_bitrate_bps_, | |
| 2488 parameters.encodings[0].max_bitrate_bps)); | |
| 2489 } | |
| 2490 | |
| 2491 bool WebRtcVoiceMediaChannel::SetMaxSendBitrate(int channel, int bps) { | |
| 2492 // Bitrate is auto by default. | |
| 2493 // TODO(bemasc): Fix this so that if SetMaxSendBandwidth(50) is followed by | |
| 2494 // SetMaxSendBandwith(0), the second call removes the previous limit. | |
| 2495 if (bps <= 0) { | |
| 2496 return true; | |
| 2497 } | |
| 2498 | |
| 2499 if (!HasSendCodec()) { | |
| 2500 LOG(LS_INFO) << "The send codec has not been set up yet. " | |
| 2501 << "The send bitrate setting will be applied later."; | |
| 2502 return true; | |
| 2503 } | |
| 2504 | |
| 2505 webrtc::CodecInst codec = send_codec_spec_.codec_inst; | |
| 2506 bool is_multi_rate = WebRtcVoiceCodecs::IsCodecMultiRate(codec); | |
| 2507 | |
| 2508 if (is_multi_rate) { | |
| 2509 // If codec is multi-rate then just set the bitrate. | |
| 2510 int max_bitrate_bps = WebRtcVoiceCodecs::MaxBitrateBps(codec); | |
| 2511 codec.rate = std::min(bps, max_bitrate_bps); | |
| 2512 LOG(LS_INFO) << "Setting codec " << codec.plname << " to bitrate " << bps | |
| 2513 << " bps."; | |
| 2514 if (!SetSendCodec(channel, codec)) { | |
| 2515 LOG(LS_ERROR) << "Failed to set codec " << codec.plname << " to bitrate " | |
| 2516 << bps << " bps."; | |
| 2517 return false; | |
| 2518 } | |
| 2519 return true; | |
| 2520 } else { | |
| 2521 // If codec is not multi-rate and |bps| is less than the fixed bitrate | |
| 2522 // then fail. If codec is not multi-rate and |bps| exceeds or equal the | |
| 2523 // fixed bitrate then ignore. | |
| 2524 if (bps < codec.rate) { | |
| 2525 LOG(LS_ERROR) << "Failed to set codec " << codec.plname << " to bitrate " | |
| 2526 << bps << " bps" | |
| 2527 << ", requires at least " << codec.rate << " bps."; | |
| 2528 return false; | |
| 2529 } | |
| 2530 return true; | |
| 2531 } | |
| 2532 } | 2394 } | 
| 2533 | 2395 | 
| 2534 void WebRtcVoiceMediaChannel::OnReadyToSend(bool ready) { | 2396 void WebRtcVoiceMediaChannel::OnReadyToSend(bool ready) { | 
| 2535 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 2397 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 
| 2536 LOG(LS_VERBOSE) << "OnReadyToSend: " << (ready ? "Ready." : "Not ready."); | 2398 LOG(LS_VERBOSE) << "OnReadyToSend: " << (ready ? "Ready." : "Not ready."); | 
| 2537 call_->SignalChannelNetworkState( | 2399 call_->SignalChannelNetworkState( | 
| 2538 webrtc::MediaType::AUDIO, | 2400 webrtc::MediaType::AUDIO, | 
| 2539 ready ? webrtc::kNetworkUp : webrtc::kNetworkDown); | 2401 ready ? webrtc::kNetworkUp : webrtc::kNetworkDown); | 
| 2540 } | 2402 } | 
| 2541 | 2403 | 
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2647 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 2509 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 
| 2648 const auto it = send_streams_.find(ssrc); | 2510 const auto it = send_streams_.find(ssrc); | 
| 2649 if (it != send_streams_.end()) { | 2511 if (it != send_streams_.end()) { | 
| 2650 return it->second->channel(); | 2512 return it->second->channel(); | 
| 2651 } | 2513 } | 
| 2652 return -1; | 2514 return -1; | 
| 2653 } | 2515 } | 
| 2654 } // namespace cricket | 2516 } // namespace cricket | 
| 2655 | 2517 | 
| 2656 #endif // HAVE_WEBRTC_VOICE | 2518 #endif // HAVE_WEBRTC_VOICE | 
| OLD | NEW |