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 } // namespace { |
470 if (nack_enabled != rhs.nack_enabled) { | |
471 return false; | |
472 } | |
473 if (transport_cc_enabled != rhs.transport_cc_enabled) { | |
474 return false; | |
475 } | |
476 if (enable_codec_fec != rhs.enable_codec_fec) { | |
477 return false; | |
478 } | |
479 if (enable_opus_dtx != rhs.enable_opus_dtx) { | |
480 return false; | |
481 } | |
482 if (opus_max_playback_rate != rhs.opus_max_playback_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 } | |
499 | |
500 bool SendCodecSpec::operator!=(const SendCodecSpec& rhs) const { | |
501 return !(*this == rhs); | |
502 } | |
503 | 469 |
504 bool WebRtcVoiceEngine::ToCodecInst(const AudioCodec& in, | 470 bool WebRtcVoiceEngine::ToCodecInst(const AudioCodec& in, |
505 webrtc::CodecInst* out) { | 471 webrtc::CodecInst* out) { |
506 return WebRtcVoiceCodecs::ToCodecInst(in, out); | 472 return WebRtcVoiceCodecs::ToCodecInst(in, out); |
507 } | 473 } |
508 | 474 |
509 WebRtcVoiceEngine::WebRtcVoiceEngine( | 475 WebRtcVoiceEngine::WebRtcVoiceEngine( |
510 webrtc::AudioDeviceModule* adm, | 476 webrtc::AudioDeviceModule* adm, |
511 const rtc::scoped_refptr<webrtc::AudioDecoderFactory>& decoder_factory) | 477 const rtc::scoped_refptr<webrtc::AudioDecoderFactory>& decoder_factory) |
512 : WebRtcVoiceEngine(adm, decoder_factory, new VoEWrapper()) { | 478 : WebRtcVoiceEngine(adm, decoder_factory, new VoEWrapper()) { |
(...skipping 620 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1133 | 1099 |
1134 // Add telephone-event codec last | 1100 // Add telephone-event codec last |
1135 map_format({kDtmfCodecName, 8000, 1}); | 1101 map_format({kDtmfCodecName, 8000, 1}); |
1136 | 1102 |
1137 return out; | 1103 return out; |
1138 } | 1104 } |
1139 | 1105 |
1140 class WebRtcVoiceMediaChannel::WebRtcAudioSendStream | 1106 class WebRtcVoiceMediaChannel::WebRtcAudioSendStream |
1141 : public AudioSource::Sink { | 1107 : public AudioSource::Sink { |
1142 public: | 1108 public: |
1143 WebRtcAudioSendStream(int ch, | 1109 WebRtcAudioSendStream( |
1144 webrtc::AudioTransport* voe_audio_transport, | 1110 int ch, |
1145 uint32_t ssrc, | 1111 webrtc::AudioTransport* voe_audio_transport, |
1146 const std::string& c_name, | 1112 uint32_t ssrc, |
1147 const SendCodecSpec& send_codec_spec, | 1113 const std::string& c_name, |
1148 const std::vector<webrtc::RtpExtension>& extensions, | 1114 const webrtc::AudioSendStream::Config::SendCodecSpec& send_codec_spec, |
1149 webrtc::Call* call, | 1115 const std::vector<webrtc::RtpExtension>& extensions, |
1150 webrtc::Transport* send_transport) | 1116 webrtc::Call* call, |
1117 webrtc::Transport* send_transport) | |
1151 : voe_audio_transport_(voe_audio_transport), | 1118 : voe_audio_transport_(voe_audio_transport), |
1152 call_(call), | 1119 call_(call), |
1153 config_(send_transport), | 1120 config_(send_transport), |
1154 rtp_parameters_(CreateRtpParametersWithOneEncoding()) { | 1121 rtp_parameters_(CreateRtpParametersWithOneEncoding()), |
1122 max_send_bitrate_bps_(0) { | |
the sun
2016/10/13 13:15:05
remove line, init at declaration
| |
1155 RTC_DCHECK_GE(ch, 0); | 1123 RTC_DCHECK_GE(ch, 0); |
1156 // TODO(solenberg): Once we're not using FakeWebRtcVoiceEngine anymore: | 1124 // TODO(solenberg): Once we're not using FakeWebRtcVoiceEngine anymore: |
1157 // RTC_DCHECK(voe_audio_transport); | 1125 // RTC_DCHECK(voe_audio_transport); |
1158 RTC_DCHECK(call); | 1126 RTC_DCHECK(call); |
1159 config_.rtp.ssrc = ssrc; | 1127 config_.rtp.ssrc = ssrc; |
1160 config_.rtp.c_name = c_name; | 1128 config_.rtp.c_name = c_name; |
1161 config_.voe_channel_id = ch; | 1129 config_.voe_channel_id = ch; |
1162 config_.rtp.extensions = extensions; | 1130 config_.rtp.extensions = extensions; |
1163 RecreateAudioSendStream(send_codec_spec); | 1131 RecreateAudioSendStream(send_codec_spec); |
1164 } | 1132 } |
1165 | 1133 |
1166 ~WebRtcAudioSendStream() override { | 1134 ~WebRtcAudioSendStream() override { |
1167 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 1135 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
1168 ClearSource(); | 1136 ClearSource(); |
1169 call_->DestroyAudioSendStream(stream_); | 1137 call_->DestroyAudioSendStream(stream_); |
1170 } | 1138 } |
1171 | 1139 |
1172 void RecreateAudioSendStream(const SendCodecSpec& send_codec_spec) { | 1140 void RecreateAudioSendStream( |
1141 const webrtc::AudioSendStream::Config::SendCodecSpec& send_codec_spec) { | |
1173 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 1142 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
1174 if (stream_) { | 1143 if (stream_) { |
1175 call_->DestroyAudioSendStream(stream_); | 1144 call_->DestroyAudioSendStream(stream_); |
1176 stream_ = nullptr; | 1145 stream_ = nullptr; |
1177 } | 1146 } |
1178 config_.rtp.nack.rtp_history_ms = | 1147 config_.rtp.nack.rtp_history_ms = |
1179 send_codec_spec.nack_enabled ? kNackRtpHistoryMs : 0; | 1148 send_codec_spec.nack_enabled ? kNackRtpHistoryMs : 0; |
1149 config_.send_codec_spec = send_codec_spec; | |
1150 config_.send_codec_spec.codec_inst.rate = DecideSendBitrate(); | |
1180 RTC_DCHECK(!stream_); | 1151 RTC_DCHECK(!stream_); |
1181 stream_ = call_->CreateAudioSendStream(config_); | 1152 stream_ = call_->CreateAudioSendStream(config_); |
1182 RTC_CHECK(stream_); | 1153 RTC_CHECK(stream_); |
1183 UpdateSendState(); | 1154 UpdateSendState(); |
1184 } | 1155 } |
1185 | 1156 |
1186 void RecreateAudioSendStream( | 1157 void RecreateAudioSendStream( |
1187 const std::vector<webrtc::RtpExtension>& extensions) { | 1158 const std::vector<webrtc::RtpExtension>& extensions) { |
1188 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 1159 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
1189 if (stream_) { | 1160 if (stream_) { |
1190 call_->DestroyAudioSendStream(stream_); | 1161 call_->DestroyAudioSendStream(stream_); |
1191 stream_ = nullptr; | 1162 stream_ = nullptr; |
1192 } | 1163 } |
1193 config_.rtp.extensions = extensions; | 1164 config_.rtp.extensions = extensions; |
1194 if (webrtc::field_trial::FindFullName("WebRTC-AdaptAudioBitrate") == | 1165 if (webrtc::field_trial::FindFullName("WebRTC-AdaptAudioBitrate") == |
1195 "Enabled") { | 1166 "Enabled") { |
1196 // TODO(mflodman): Keep testing this and set proper values. | 1167 // TODO(mflodman): Keep testing this and set proper values. |
1197 // Note: This is an early experiment currently only supported by Opus. | 1168 // Note: This is an early experiment currently only supported by Opus. |
1198 config_.min_bitrate_kbps = kOpusMinBitrate; | 1169 config_.min_bitrate_kbps = kOpusMinBitrate; |
1199 config_.max_bitrate_kbps = kOpusBitrateFb; | 1170 config_.max_bitrate_kbps = kOpusBitrateFb; |
1200 } | 1171 } |
1201 | 1172 |
1202 RTC_DCHECK(!stream_); | 1173 RTC_DCHECK(!stream_); |
1203 stream_ = call_->CreateAudioSendStream(config_); | 1174 stream_ = call_->CreateAudioSendStream(config_); |
1204 RTC_CHECK(stream_); | 1175 RTC_CHECK(stream_); |
1205 UpdateSendState(); | 1176 UpdateSendState(); |
1206 } | 1177 } |
1207 | 1178 |
1179 void MaybeRecreateAudioSendStream(int bps) { | |
the sun
2016/10/13 13:15:05
I think you can drop the "Maybe" - the fact that w
minyue-webrtc
2016/10/17 07:41:59
I have changed this function quite a bit. Please t
| |
1180 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | |
1181 int new_max_send_bitrate_bps = | |
1182 MinPositive(bps, rtp_parameters_.encodings[0].max_bitrate_bps); | |
1183 if (max_send_bitrate_bps_ == new_max_send_bitrate_bps) | |
the sun
2016/10/13 13:15:05
{} even for one liners in this file, here and belo
minyue-webrtc
2016/10/17 07:41:59
Done.
| |
1184 return; | |
1185 max_send_bitrate_bps_ = new_max_send_bitrate_bps; | |
1186 | |
1187 int new_sent_bitrate_bps = DecideSendBitrate(); | |
1188 if (config_.send_codec_spec.codec_inst.rate == new_sent_bitrate_bps) | |
1189 return; | |
1190 config_.send_codec_spec.codec_inst.rate = new_sent_bitrate_bps; | |
1191 | |
1192 if (stream_) { | |
1193 call_->DestroyAudioSendStream(stream_); | |
1194 stream_ = nullptr; | |
1195 } | |
1196 RTC_DCHECK(!stream_); | |
1197 stream_ = call_->CreateAudioSendStream(config_); | |
1198 RTC_CHECK(stream_); | |
1199 UpdateSendState(); | |
1200 } | |
1201 | |
1208 bool SendTelephoneEvent(int payload_type, int event, int duration_ms) { | 1202 bool SendTelephoneEvent(int payload_type, int event, int duration_ms) { |
1209 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 1203 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
1210 RTC_DCHECK(stream_); | 1204 RTC_DCHECK(stream_); |
1211 return stream_->SendTelephoneEvent(payload_type, event, duration_ms); | 1205 return stream_->SendTelephoneEvent(payload_type, event, duration_ms); |
1212 } | 1206 } |
1213 | 1207 |
1214 void SetSend(bool send) { | 1208 void SetSend(bool send) { |
1215 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 1209 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
1216 send_ = send; | 1210 send_ = send; |
1217 UpdateSendState(); | 1211 UpdateSendState(); |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1293 return config_.voe_channel_id; | 1287 return config_.voe_channel_id; |
1294 } | 1288 } |
1295 | 1289 |
1296 const webrtc::RtpParameters& rtp_parameters() const { | 1290 const webrtc::RtpParameters& rtp_parameters() const { |
1297 return rtp_parameters_; | 1291 return rtp_parameters_; |
1298 } | 1292 } |
1299 | 1293 |
1300 void SetRtpParameters(const webrtc::RtpParameters& parameters) { | 1294 void SetRtpParameters(const webrtc::RtpParameters& parameters) { |
1301 RTC_CHECK_EQ(1UL, parameters.encodings.size()); | 1295 RTC_CHECK_EQ(1UL, parameters.encodings.size()); |
1302 rtp_parameters_ = parameters; | 1296 rtp_parameters_ = parameters; |
1297 | |
1298 // parameters.encodings[0].max_bitrate_bps could have changed. | |
the sun
2016/10/13 13:15:05
Thank you for adding that comment! I was just wond
| |
1299 MaybeRecreateAudioSendStream(max_send_bitrate_bps_); | |
1300 | |
1303 // parameters.encodings[0].active could have changed. | 1301 // parameters.encodings[0].active could have changed. |
1304 UpdateSendState(); | 1302 UpdateSendState(); |
1305 } | 1303 } |
1306 | 1304 |
1307 private: | 1305 private: |
1308 void UpdateSendState() { | 1306 void UpdateSendState() { |
1309 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 1307 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
1310 RTC_DCHECK(stream_); | 1308 RTC_DCHECK(stream_); |
1311 RTC_DCHECK_EQ(1UL, rtp_parameters_.encodings.size()); | 1309 RTC_DCHECK_EQ(1UL, rtp_parameters_.encodings.size()); |
1312 if (send_ && source_ != nullptr && rtp_parameters_.encodings[0].active) { | 1310 if (send_ && source_ != nullptr && rtp_parameters_.encodings[0].active) { |
1313 stream_->Start(); | 1311 stream_->Start(); |
1314 } else { // !send || source_ = nullptr | 1312 } else { // !send || source_ = nullptr |
1315 stream_->Stop(); | 1313 stream_->Stop(); |
1316 } | 1314 } |
1317 } | 1315 } |
1318 | 1316 |
1317 // Decide new send bit rate for config_.send_codec_spec.codec_inst. | |
1318 int DecideSendBitrate() const { | |
1319 const int current_rate = config_.send_codec_spec.codec_inst.rate; | |
1320 | |
1321 // Bitrate is auto by default. | |
1322 // TODO(bemasc): Fix this so that if SetMaxSendBandwidth(50) is followed by | |
1323 // SetMaxSendBandwith(0), the second call removes the previous limit. | |
1324 if (max_send_bitrate_bps_ <= 0) { | |
1325 return current_rate; | |
1326 } | |
1327 | |
1328 if (config_.send_codec_spec.codec_inst.pltype == -1) { | |
1329 LOG(LS_INFO) << "The send codec has not been set up yet. " | |
1330 << "The send bitrate setting will be applied later."; | |
1331 return current_rate; | |
1332 } | |
1333 | |
1334 if (WebRtcVoiceCodecs::IsCodecMultiRate( | |
1335 config_.send_codec_spec.codec_inst)) { | |
1336 // If codec is multi-rate then just set the bitrate. | |
1337 int max_bitrate_bps = | |
1338 WebRtcVoiceCodecs::MaxBitrateBps(config_.send_codec_spec.codec_inst); | |
1339 return std::min(max_send_bitrate_bps_, max_bitrate_bps); | |
1340 } | |
1341 | |
1342 // If codec is not multi-rate and |max_send_bit_rate_| is less than the | |
1343 // fixed bitrate then fail. If codec is not multi-rate and |bps| exceeds or | |
1344 // equal the fixed bitrate then ignore. | |
1345 if (max_send_bitrate_bps_ < config_.send_codec_spec.codec_inst.rate) { | |
1346 LOG(LS_ERROR) << "Failed to set codec " | |
1347 << config_.send_codec_spec.codec_inst.plname | |
1348 << " to bitrate " << max_send_bitrate_bps_ << " bps" | |
1349 << ", requires at least " | |
1350 << config_.send_codec_spec.codec_inst.rate << " bps."; | |
1351 } | |
1352 return current_rate; | |
1353 } | |
1354 | |
1319 rtc::ThreadChecker worker_thread_checker_; | 1355 rtc::ThreadChecker worker_thread_checker_; |
1320 rtc::RaceChecker audio_capture_race_checker_; | 1356 rtc::RaceChecker audio_capture_race_checker_; |
1321 webrtc::AudioTransport* const voe_audio_transport_ = nullptr; | 1357 webrtc::AudioTransport* const voe_audio_transport_ = nullptr; |
1322 webrtc::Call* call_ = nullptr; | 1358 webrtc::Call* call_ = nullptr; |
1323 webrtc::AudioSendStream::Config config_; | 1359 webrtc::AudioSendStream::Config config_; |
1324 // The stream is owned by WebRtcAudioSendStream and may be reallocated if | 1360 // The stream is owned by WebRtcAudioSendStream and may be reallocated if |
1325 // configuration changes. | 1361 // configuration changes. |
1326 webrtc::AudioSendStream* stream_ = nullptr; | 1362 webrtc::AudioSendStream* stream_ = nullptr; |
1327 | 1363 |
1328 // Raw pointer to AudioSource owned by LocalAudioTrackHandler. | 1364 // Raw pointer to AudioSource owned by LocalAudioTrackHandler. |
1329 // PeerConnection will make sure invalidating the pointer before the object | 1365 // PeerConnection will make sure invalidating the pointer before the object |
1330 // goes away. | 1366 // goes away. |
1331 AudioSource* source_ = nullptr; | 1367 AudioSource* source_ = nullptr; |
1332 bool send_ = false; | 1368 bool send_ = false; |
1333 bool muted_ = false; | 1369 bool muted_ = false; |
1334 webrtc::RtpParameters rtp_parameters_; | 1370 webrtc::RtpParameters rtp_parameters_; |
1371 int max_send_bitrate_bps_; | |
the sun
2016/10/13 13:15:05
= 0
minyue-webrtc
2016/10/14 13:32:56
we now force it be initialized as a ctor argument
| |
1335 | 1372 |
1336 RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(WebRtcAudioSendStream); | 1373 RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(WebRtcAudioSendStream); |
1337 }; | 1374 }; |
1338 | 1375 |
1339 class WebRtcVoiceMediaChannel::WebRtcAudioReceiveStream { | 1376 class WebRtcVoiceMediaChannel::WebRtcAudioReceiveStream { |
1340 public: | 1377 public: |
1341 WebRtcAudioReceiveStream( | 1378 WebRtcAudioReceiveStream( |
1342 int ch, | 1379 int ch, |
1343 uint32_t remote_ssrc, | 1380 uint32_t remote_ssrc, |
1344 uint32_t local_ssrc, | 1381 uint32_t local_ssrc, |
(...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1584 | 1621 |
1585 // TODO(deadbeef): Handle setting parameters with a list of codecs in a | 1622 // TODO(deadbeef): Handle setting parameters with a list of codecs in a |
1586 // different order (which should change the send codec). | 1623 // different order (which should change the send codec). |
1587 webrtc::RtpParameters current_parameters = GetRtpSendParameters(ssrc); | 1624 webrtc::RtpParameters current_parameters = GetRtpSendParameters(ssrc); |
1588 if (current_parameters.codecs != parameters.codecs) { | 1625 if (current_parameters.codecs != parameters.codecs) { |
1589 LOG(LS_ERROR) << "Using SetParameters to change the set of codecs " | 1626 LOG(LS_ERROR) << "Using SetParameters to change the set of codecs " |
1590 << "is not currently supported."; | 1627 << "is not currently supported."; |
1591 return false; | 1628 return false; |
1592 } | 1629 } |
1593 | 1630 |
1594 if (!SetChannelSendParameters(it->second->channel(), parameters)) { | 1631 // TODO(minyue): The following legacy actions go into |
the sun
2016/10/13 13:15:05
Remove comment?
minyue-webrtc
2016/10/17 07:41:59
Done.
| |
1595 LOG(LS_WARNING) << "Failed to set send RtpParameters."; | 1632 // |WebRtcAudioSendStream::SetRtpParameters()| which is called at the end, |
1596 return false; | 1633 // though there are two difference: |
1597 } | 1634 // 1. |WebRtcVoiceMediaChannel::SetChannelSendParameters()| only calls |
1635 // |SetSendCodec| while |WebRtcAudioSendStream::SetRtpParameters()| calls | |
1636 // |SetSendCodecs|. The outcome should be the same. | |
1637 // 2. AudioSendStream can be recreated. | |
1638 | |
1639 // if (!it->SetChannelSendParameters(it->second->channel(), parameters)) { | |
1640 // LOG(LS_WARNING) << "Failed to set send RtpParameters."; | |
1641 // return false; | |
1642 // } | |
1643 | |
1598 // Codecs are handled at the WebRtcVoiceMediaChannel level. | 1644 // Codecs are handled at the WebRtcVoiceMediaChannel level. |
1599 webrtc::RtpParameters reduced_params = parameters; | 1645 webrtc::RtpParameters reduced_params = parameters; |
1600 reduced_params.codecs.clear(); | 1646 reduced_params.codecs.clear(); |
1601 it->second->SetRtpParameters(reduced_params); | 1647 it->second->SetRtpParameters(reduced_params); |
1602 return true; | 1648 return true; |
1603 } | 1649 } |
1604 | 1650 |
1605 webrtc::RtpParameters WebRtcVoiceMediaChannel::GetRtpReceiveParameters( | 1651 webrtc::RtpParameters WebRtcVoiceMediaChannel::GetRtpReceiveParameters( |
1606 uint32_t ssrc) const { | 1652 uint32_t ssrc) const { |
1607 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 1653 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1761 } | 1807 } |
1762 dtmf_payload_type_ = rtc::Optional<int>(codec.id); | 1808 dtmf_payload_type_ = rtc::Optional<int>(codec.id); |
1763 break; | 1809 break; |
1764 } | 1810 } |
1765 } | 1811 } |
1766 | 1812 |
1767 // Scan through the list to figure out the codec to use for sending, along | 1813 // Scan through the list to figure out the codec to use for sending, along |
1768 // with the proper configuration for VAD, CNG, NACK and Opus-specific | 1814 // with the proper configuration for VAD, CNG, NACK and Opus-specific |
1769 // parameters. | 1815 // parameters. |
1770 // TODO(solenberg): Refactor this logic once we create AudioEncoders here. | 1816 // TODO(solenberg): Refactor this logic once we create AudioEncoders here. |
1771 SendCodecSpec send_codec_spec; | 1817 webrtc::AudioSendStream::Config::SendCodecSpec send_codec_spec; |
1772 { | 1818 { |
1773 send_codec_spec.nack_enabled = send_codec_spec_.nack_enabled; | 1819 send_codec_spec.nack_enabled = send_codec_spec_.nack_enabled; |
1774 | 1820 |
1775 // Find send codec (the first non-telephone-event/CN codec). | 1821 // Find send codec (the first non-telephone-event/CN codec). |
1776 const AudioCodec* codec = WebRtcVoiceCodecs::GetPreferredCodec( | 1822 const AudioCodec* codec = WebRtcVoiceCodecs::GetPreferredCodec( |
1777 codecs, &send_codec_spec.codec_inst); | 1823 codecs, &send_codec_spec.codec_inst); |
1778 if (!codec) { | 1824 if (!codec) { |
1779 LOG(LS_WARNING) << "Received empty list of codecs."; | 1825 LOG(LS_WARNING) << "Received empty list of codecs."; |
1780 return false; | 1826 return false; |
1781 } | 1827 } |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1835 break; | 1881 break; |
1836 } | 1882 } |
1837 } | 1883 } |
1838 } | 1884 } |
1839 | 1885 |
1840 // Apply new settings to all streams. | 1886 // Apply new settings to all streams. |
1841 if (send_codec_spec_ != send_codec_spec) { | 1887 if (send_codec_spec_ != send_codec_spec) { |
1842 send_codec_spec_ = std::move(send_codec_spec); | 1888 send_codec_spec_ = std::move(send_codec_spec); |
1843 for (const auto& kv : send_streams_) { | 1889 for (const auto& kv : send_streams_) { |
1844 kv.second->RecreateAudioSendStream(send_codec_spec_); | 1890 kv.second->RecreateAudioSendStream(send_codec_spec_); |
1845 if (!SetSendCodecs(kv.second->channel(), kv.second->rtp_parameters())) { | |
1846 return false; | |
1847 } | |
1848 } | 1891 } |
1849 } | 1892 } |
1850 | 1893 |
1851 // Check if the transport cc feedback or NACK status has changed on the | 1894 // Check if the transport cc feedback or NACK status has changed on the |
1852 // preferred send codec, and in that case reconfigure all receive streams. | 1895 // preferred send codec, and in that case reconfigure all receive streams. |
1853 if (recv_transport_cc_enabled_ != send_codec_spec_.transport_cc_enabled || | 1896 if (recv_transport_cc_enabled_ != send_codec_spec_.transport_cc_enabled || |
1854 recv_nack_enabled_ != send_codec_spec_.nack_enabled) { | 1897 recv_nack_enabled_ != send_codec_spec_.nack_enabled) { |
1855 LOG(LS_INFO) << "Recreate all the receive streams because the send " | 1898 LOG(LS_INFO) << "Recreate all the receive streams because the send " |
1856 "codec has changed."; | 1899 "codec has changed."; |
1857 recv_transport_cc_enabled_ = send_codec_spec_.transport_cc_enabled; | 1900 recv_transport_cc_enabled_ = send_codec_spec_.transport_cc_enabled; |
1858 recv_nack_enabled_ = send_codec_spec_.nack_enabled; | 1901 recv_nack_enabled_ = send_codec_spec_.nack_enabled; |
1859 for (auto& kv : recv_streams_) { | 1902 for (auto& kv : recv_streams_) { |
1860 kv.second->RecreateAudioReceiveStream(recv_transport_cc_enabled_, | 1903 kv.second->RecreateAudioReceiveStream(recv_transport_cc_enabled_, |
1861 recv_nack_enabled_); | 1904 recv_nack_enabled_); |
1862 } | 1905 } |
1863 } | 1906 } |
1864 | 1907 |
1865 send_codecs_ = codecs; | 1908 send_codecs_ = codecs; |
1866 return true; | 1909 return true; |
1867 } | 1910 } |
1868 | 1911 |
1869 // Apply current codec settings to a single voe::Channel used for sending. | |
1870 bool WebRtcVoiceMediaChannel::SetSendCodecs( | |
1871 int channel, | |
1872 const webrtc::RtpParameters& rtp_parameters) { | |
1873 // Disable VAD and FEC unless we know the other side wants them. | |
1874 engine()->voe()->codec()->SetVADStatus(channel, false); | |
1875 engine()->voe()->codec()->SetFECStatus(channel, false); | |
1876 | |
1877 // Set the codec immediately, since SetVADStatus() depends on whether | |
1878 // the current codec is mono or stereo. | |
1879 if (!SetSendCodec(channel, send_codec_spec_.codec_inst)) { | |
1880 return false; | |
1881 } | |
1882 | |
1883 // FEC should be enabled after SetSendCodec. | |
1884 if (send_codec_spec_.enable_codec_fec) { | |
1885 LOG(LS_INFO) << "Attempt to enable codec internal FEC on channel " | |
1886 << channel; | |
1887 if (engine()->voe()->codec()->SetFECStatus(channel, true) == -1) { | |
1888 // Enable codec internal FEC. Treat any failure as fatal internal error. | |
1889 LOG_RTCERR2(SetFECStatus, channel, true); | |
1890 return false; | |
1891 } | |
1892 } | |
1893 | |
1894 if (IsCodec(send_codec_spec_.codec_inst, kOpusCodecName)) { | |
1895 // DTX and maxplaybackrate should be set after SetSendCodec. Because current | |
1896 // send codec has to be Opus. | |
1897 | |
1898 // Set Opus internal DTX. | |
1899 LOG(LS_INFO) << "Attempt to " | |
1900 << (send_codec_spec_.enable_opus_dtx ? "enable" : "disable") | |
1901 << " Opus DTX on channel " | |
1902 << channel; | |
1903 if (engine()->voe()->codec()->SetOpusDtx(channel, | |
1904 send_codec_spec_.enable_opus_dtx)) { | |
1905 LOG_RTCERR2(SetOpusDtx, channel, send_codec_spec_.enable_opus_dtx); | |
1906 return false; | |
1907 } | |
1908 | |
1909 // If opus_max_playback_rate <= 0, the default maximum playback rate | |
1910 // (48 kHz) will be used. | |
1911 if (send_codec_spec_.opus_max_playback_rate > 0) { | |
1912 LOG(LS_INFO) << "Attempt to set maximum playback rate to " | |
1913 << send_codec_spec_.opus_max_playback_rate | |
1914 << " Hz on channel " | |
1915 << channel; | |
1916 if (engine()->voe()->codec()->SetOpusMaxPlaybackRate( | |
1917 channel, send_codec_spec_.opus_max_playback_rate) == -1) { | |
1918 LOG_RTCERR2(SetOpusMaxPlaybackRate, channel, | |
1919 send_codec_spec_.opus_max_playback_rate); | |
1920 return false; | |
1921 } | |
1922 } | |
1923 } | |
1924 // TODO(solenberg): SetMaxSendBitrate() yields another call to SetSendCodec(). | |
1925 // Check if it is possible to fuse with the previous call in this function. | |
1926 SetChannelSendParameters(channel, rtp_parameters); | |
1927 | |
1928 // Set the CN payloadtype and the VAD status. | |
1929 if (send_codec_spec_.cng_payload_type != -1) { | |
1930 // The CN payload type for 8000 Hz clockrate is fixed at 13. | |
1931 if (send_codec_spec_.cng_plfreq != 8000) { | |
1932 webrtc::PayloadFrequencies cn_freq; | |
1933 switch (send_codec_spec_.cng_plfreq) { | |
1934 case 16000: | |
1935 cn_freq = webrtc::kFreq16000Hz; | |
1936 break; | |
1937 case 32000: | |
1938 cn_freq = webrtc::kFreq32000Hz; | |
1939 break; | |
1940 default: | |
1941 RTC_NOTREACHED(); | |
1942 return false; | |
1943 } | |
1944 if (engine()->voe()->codec()->SetSendCNPayloadType( | |
1945 channel, send_codec_spec_.cng_payload_type, cn_freq) == -1) { | |
1946 LOG_RTCERR3(SetSendCNPayloadType, channel, | |
1947 send_codec_spec_.cng_payload_type, cn_freq); | |
1948 // TODO(ajm): This failure condition will be removed from VoE. | |
1949 // Restore the return here when we update to a new enough webrtc. | |
1950 // | |
1951 // Not returning false because the SetSendCNPayloadType will fail if | |
1952 // the channel is already sending. | |
1953 // This can happen if the remote description is applied twice, for | |
1954 // example in the case of ROAP on top of JSEP, where both side will | |
1955 // send the offer. | |
1956 } | |
1957 } | |
1958 | |
1959 // Only turn on VAD if we have a CN payload type that matches the | |
1960 // clockrate for the codec we are going to use. | |
1961 if (send_codec_spec_.cng_plfreq == send_codec_spec_.codec_inst.plfreq && | |
1962 send_codec_spec_.codec_inst.channels == 1) { | |
1963 // TODO(minyue): If CN frequency == 48000 Hz is allowed, consider the | |
1964 // interaction between VAD and Opus FEC. | |
1965 LOG(LS_INFO) << "Enabling VAD"; | |
1966 if (engine()->voe()->codec()->SetVADStatus(channel, true) == -1) { | |
1967 LOG_RTCERR2(SetVADStatus, channel, true); | |
1968 return false; | |
1969 } | |
1970 } | |
1971 } | |
1972 return true; | |
1973 } | |
1974 | |
1975 bool WebRtcVoiceMediaChannel::SetSendCodec( | |
1976 int channel, const webrtc::CodecInst& send_codec) { | |
1977 LOG(LS_INFO) << "Send channel " << channel << " selected voice codec " | |
1978 << ToString(send_codec) << ", bitrate=" << send_codec.rate; | |
1979 | |
1980 webrtc::CodecInst current_codec = {0}; | |
1981 if (engine()->voe()->codec()->GetSendCodec(channel, current_codec) == 0 && | |
1982 (send_codec == current_codec)) { | |
1983 // Codec is already configured, we can return without setting it again. | |
1984 return true; | |
1985 } | |
1986 | |
1987 if (engine()->voe()->codec()->SetSendCodec(channel, send_codec) == -1) { | |
1988 LOG_RTCERR2(SetSendCodec, channel, ToString(send_codec)); | |
1989 return false; | |
1990 } | |
1991 return true; | |
1992 } | |
1993 | |
1994 void WebRtcVoiceMediaChannel::SetPlayout(bool playout) { | 1912 void WebRtcVoiceMediaChannel::SetPlayout(bool playout) { |
1995 desired_playout_ = playout; | 1913 desired_playout_ = playout; |
1996 return ChangePlayout(desired_playout_); | 1914 return ChangePlayout(desired_playout_); |
1997 } | 1915 } |
1998 | 1916 |
1999 void WebRtcVoiceMediaChannel::ChangePlayout(bool playout) { | 1917 void WebRtcVoiceMediaChannel::ChangePlayout(bool playout) { |
2000 TRACE_EVENT0("webrtc", "WebRtcVoiceMediaChannel::ChangePlayout"); | 1918 TRACE_EVENT0("webrtc", "WebRtcVoiceMediaChannel::ChangePlayout"); |
2001 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 1919 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
2002 if (playout_ == playout) { | 1920 if (playout_ == playout) { |
2003 return; | 1921 return; |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2096 // Save the channel to send_streams_, so that RemoveSendStream() can still | 2014 // Save the channel to send_streams_, so that RemoveSendStream() can still |
2097 // delete the channel in case failure happens below. | 2015 // delete the channel in case failure happens below. |
2098 webrtc::AudioTransport* audio_transport = | 2016 webrtc::AudioTransport* audio_transport = |
2099 engine()->voe()->base()->audio_transport(); | 2017 engine()->voe()->base()->audio_transport(); |
2100 | 2018 |
2101 WebRtcAudioSendStream* stream = new WebRtcAudioSendStream( | 2019 WebRtcAudioSendStream* stream = new WebRtcAudioSendStream( |
2102 channel, audio_transport, ssrc, sp.cname, send_codec_spec_, | 2020 channel, audio_transport, ssrc, sp.cname, send_codec_spec_, |
2103 send_rtp_extensions_, call_, this); | 2021 send_rtp_extensions_, call_, this); |
2104 send_streams_.insert(std::make_pair(ssrc, stream)); | 2022 send_streams_.insert(std::make_pair(ssrc, stream)); |
2105 | 2023 |
2106 // Set the current codecs to be used for the new channel. We need to do this | |
2107 // after adding the channel to send_channels_, because of how max bitrate is | |
2108 // currently being configured by SetSendCodec(). | |
2109 if (HasSendCodec() && !SetSendCodecs(channel, stream->rtp_parameters())) { | |
2110 RemoveSendStream(ssrc); | |
2111 return false; | |
2112 } | |
2113 | |
2114 // At this point the stream's local SSRC has been updated. If it is the first | 2024 // At this point the stream's local SSRC has been updated. If it is the first |
2115 // send stream, make sure that all the receive streams are updated with the | 2025 // send stream, make sure that all the receive streams are updated with the |
2116 // same SSRC in order to send receiver reports. | 2026 // same SSRC in order to send receiver reports. |
2117 if (send_streams_.size() == 1) { | 2027 if (send_streams_.size() == 1) { |
2118 receiver_reports_ssrc_ = ssrc; | 2028 receiver_reports_ssrc_ = ssrc; |
2119 for (const auto& kv : recv_streams_) { | 2029 for (const auto& kv : recv_streams_) { |
2120 // TODO(solenberg): Allow applications to set the RTCP SSRC of receive | 2030 // TODO(solenberg): Allow applications to set the RTCP SSRC of receive |
2121 // streams instead, so we can avoid recreating the streams here. | 2031 // streams instead, so we can avoid recreating the streams here. |
2122 kv.second->RecreateAudioReceiveStream(ssrc); | 2032 kv.second->RecreateAudioReceiveStream(ssrc); |
2123 int recv_channel = kv.second->channel(); | 2033 int recv_channel = kv.second->channel(); |
(...skipping 352 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2476 | 2386 |
2477 webrtc::AudioProcessing* ap = engine()->voe()->base()->audio_processing(); | 2387 webrtc::AudioProcessing* ap = engine()->voe()->base()->audio_processing(); |
2478 if (ap) { | 2388 if (ap) { |
2479 ap->set_output_will_be_muted(all_muted); | 2389 ap->set_output_will_be_muted(all_muted); |
2480 } | 2390 } |
2481 return true; | 2391 return true; |
2482 } | 2392 } |
2483 | 2393 |
2484 bool WebRtcVoiceMediaChannel::SetMaxSendBitrate(int bps) { | 2394 bool WebRtcVoiceMediaChannel::SetMaxSendBitrate(int bps) { |
2485 LOG(LS_INFO) << "WebRtcVoiceMediaChannel::SetMaxSendBitrate."; | 2395 LOG(LS_INFO) << "WebRtcVoiceMediaChannel::SetMaxSendBitrate."; |
2486 max_send_bitrate_bps_ = bps; | 2396 for (const auto& kv : send_streams_) |
2487 | 2397 kv.second->MaybeRecreateAudioSendStream(bps); |
2488 for (const auto& kv : send_streams_) { | |
2489 if (!SetChannelSendParameters(kv.second->channel(), | |
2490 kv.second->rtp_parameters())) { | |
2491 return false; | |
2492 } | |
2493 } | |
2494 return true; | 2398 return true; |
2495 } | 2399 } |
2496 | 2400 |
2497 bool WebRtcVoiceMediaChannel::SetChannelSendParameters( | |
2498 int channel, | |
2499 const webrtc::RtpParameters& parameters) { | |
2500 RTC_CHECK_EQ(1UL, parameters.encodings.size()); | |
2501 // TODO(deadbeef): Handle setting parameters with a list of codecs in a | |
2502 // different order (which should change the send codec). | |
2503 return SetMaxSendBitrate( | |
2504 channel, MinPositive(max_send_bitrate_bps_, | |
2505 parameters.encodings[0].max_bitrate_bps)); | |
2506 } | |
2507 | |
2508 bool WebRtcVoiceMediaChannel::SetMaxSendBitrate(int channel, int bps) { | |
2509 // Bitrate is auto by default. | |
2510 // TODO(bemasc): Fix this so that if SetMaxSendBandwidth(50) is followed by | |
2511 // SetMaxSendBandwith(0), the second call removes the previous limit. | |
2512 if (bps <= 0) { | |
2513 return true; | |
2514 } | |
2515 | |
2516 if (!HasSendCodec()) { | |
2517 LOG(LS_INFO) << "The send codec has not been set up yet. " | |
2518 << "The send bitrate setting will be applied later."; | |
2519 return true; | |
2520 } | |
2521 | |
2522 webrtc::CodecInst codec = send_codec_spec_.codec_inst; | |
2523 bool is_multi_rate = WebRtcVoiceCodecs::IsCodecMultiRate(codec); | |
2524 | |
2525 if (is_multi_rate) { | |
2526 // If codec is multi-rate then just set the bitrate. | |
2527 int max_bitrate_bps = WebRtcVoiceCodecs::MaxBitrateBps(codec); | |
2528 codec.rate = std::min(bps, max_bitrate_bps); | |
2529 LOG(LS_INFO) << "Setting codec " << codec.plname << " to bitrate " << bps | |
2530 << " bps."; | |
2531 if (!SetSendCodec(channel, codec)) { | |
2532 LOG(LS_ERROR) << "Failed to set codec " << codec.plname << " to bitrate " | |
2533 << bps << " bps."; | |
2534 return false; | |
2535 } | |
2536 return true; | |
2537 } else { | |
2538 // If codec is not multi-rate and |bps| is less than the fixed bitrate | |
2539 // then fail. If codec is not multi-rate and |bps| exceeds or equal the | |
2540 // fixed bitrate then ignore. | |
2541 if (bps < codec.rate) { | |
2542 LOG(LS_ERROR) << "Failed to set codec " << codec.plname << " to bitrate " | |
2543 << bps << " bps" | |
2544 << ", requires at least " << codec.rate << " bps."; | |
2545 return false; | |
2546 } | |
2547 return true; | |
2548 } | |
2549 } | |
2550 | |
2551 void WebRtcVoiceMediaChannel::OnReadyToSend(bool ready) { | 2401 void WebRtcVoiceMediaChannel::OnReadyToSend(bool ready) { |
2552 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 2402 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
2553 LOG(LS_VERBOSE) << "OnReadyToSend: " << (ready ? "Ready." : "Not ready."); | 2403 LOG(LS_VERBOSE) << "OnReadyToSend: " << (ready ? "Ready." : "Not ready."); |
2554 call_->SignalChannelNetworkState( | 2404 call_->SignalChannelNetworkState( |
2555 webrtc::MediaType::AUDIO, | 2405 webrtc::MediaType::AUDIO, |
2556 ready ? webrtc::kNetworkUp : webrtc::kNetworkDown); | 2406 ready ? webrtc::kNetworkUp : webrtc::kNetworkDown); |
2557 } | 2407 } |
2558 | 2408 |
2559 bool WebRtcVoiceMediaChannel::GetStats(VoiceMediaInfo* info) { | 2409 bool WebRtcVoiceMediaChannel::GetStats(VoiceMediaInfo* info) { |
2560 TRACE_EVENT0("webrtc", "WebRtcVoiceMediaChannel::GetStats"); | 2410 TRACE_EVENT0("webrtc", "WebRtcVoiceMediaChannel::GetStats"); |
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2664 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 2514 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
2665 const auto it = send_streams_.find(ssrc); | 2515 const auto it = send_streams_.find(ssrc); |
2666 if (it != send_streams_.end()) { | 2516 if (it != send_streams_.end()) { |
2667 return it->second->channel(); | 2517 return it->second->channel(); |
2668 } | 2518 } |
2669 return -1; | 2519 return -1; |
2670 } | 2520 } |
2671 } // namespace cricket | 2521 } // namespace cricket |
2672 | 2522 |
2673 #endif // HAVE_WEBRTC_VOICE | 2523 #endif // HAVE_WEBRTC_VOICE |
OLD | NEW |