| 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 395 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 406 // this, but double-check to be sure. | 406 // this, but double-check to be sure. |
| 407 if (!ToCodecInst(codec, out)) { | 407 if (!ToCodecInst(codec, out)) { |
| 408 LOG(LS_WARNING) << "Unknown codec " << ToString(codec); | 408 LOG(LS_WARNING) << "Unknown codec " << ToString(codec); |
| 409 continue; | 409 continue; |
| 410 } | 410 } |
| 411 return &codec; | 411 return &codec; |
| 412 } | 412 } |
| 413 return nullptr; | 413 return nullptr; |
| 414 } | 414 } |
| 415 | 415 |
| 416 static void SetAudioSendStreamConfig( |
| 417 webrtc::AudioSendStream::Config* config) { |
| 418 RTC_DCHECK_EQ(arraysize(kCodecPrefs), arraysize(config->codec_prefs)); |
| 419 for (size_t i = 0; i < arraysize(kCodecPrefs); ++i) { |
| 420 config->codec_prefs[i].name = kCodecPrefs[i].name; |
| 421 config->codec_prefs[i].clockrate = kCodecPrefs[i].clockrate; |
| 422 config->codec_prefs[i].is_multi_rate = kCodecPrefs[i].is_multi_rate; |
| 423 config->codec_prefs[i].max_bitrate_bps = kCodecPrefs[i].max_bitrate_bps; |
| 424 } |
| 425 } |
| 426 |
| 416 private: | 427 private: |
| 417 static const int kMaxNumPacketSize = 6; | 428 static const int kMaxNumPacketSize = 6; |
| 418 struct CodecPref { | 429 struct CodecPref { |
| 419 const char* name; | 430 const char* name; |
| 420 int clockrate; | 431 int clockrate; |
| 421 size_t channels; | 432 size_t channels; |
| 422 int payload_type; | 433 int payload_type; |
| 423 bool is_multi_rate; | 434 bool is_multi_rate; |
| 424 int packet_sizes_ms[kMaxNumPacketSize]; | 435 int packet_sizes_ms[kMaxNumPacketSize]; |
| 425 int max_bitrate_bps; | 436 int max_bitrate_bps; |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 457 // G722 should be advertised as 8000 Hz because of the RFC "bug". | 468 // G722 should be advertised as 8000 Hz because of the RFC "bug". |
| 458 {kG722CodecName, 8000, 1, 9, false, {10, 20, 30, 40, 50, 60}}, | 469 {kG722CodecName, 8000, 1, 9, false, {10, 20, 30, 40, 50, 60}}, |
| 459 {kIlbcCodecName, 8000, 1, 102, false, {20, 30, 40, 60}}, | 470 {kIlbcCodecName, 8000, 1, 102, false, {20, 30, 40, 60}}, |
| 460 {kPcmuCodecName, 8000, 1, 0, false, {10, 20, 30, 40, 50, 60}}, | 471 {kPcmuCodecName, 8000, 1, 0, false, {10, 20, 30, 40, 50, 60}}, |
| 461 {kPcmaCodecName, 8000, 1, 8, false, {10, 20, 30, 40, 50, 60}}, | 472 {kPcmaCodecName, 8000, 1, 8, false, {10, 20, 30, 40, 50, 60}}, |
| 462 {kCnCodecName, 32000, 1, 106, false, {}}, | 473 {kCnCodecName, 32000, 1, 106, false, {}}, |
| 463 {kCnCodecName, 16000, 1, 105, false, {}}, | 474 {kCnCodecName, 16000, 1, 105, false, {}}, |
| 464 {kCnCodecName, 8000, 1, 13, false, {}}, | 475 {kCnCodecName, 8000, 1, 13, false, {}}, |
| 465 {kDtmfCodecName, 8000, 1, 126, false, {}} | 476 {kDtmfCodecName, 8000, 1, 126, false, {}} |
| 466 }; | 477 }; |
| 467 } // namespace { | |
| 468 | 478 |
| 469 bool SendCodecSpec::operator==(const SendCodecSpec& rhs) const { | 479 } // 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 | 480 |
| 504 bool WebRtcVoiceEngine::ToCodecInst(const AudioCodec& in, | 481 bool WebRtcVoiceEngine::ToCodecInst(const AudioCodec& in, |
| 505 webrtc::CodecInst* out) { | 482 webrtc::CodecInst* out) { |
| 506 return WebRtcVoiceCodecs::ToCodecInst(in, out); | 483 return WebRtcVoiceCodecs::ToCodecInst(in, out); |
| 507 } | 484 } |
| 508 | 485 |
| 509 WebRtcVoiceEngine::WebRtcVoiceEngine( | 486 WebRtcVoiceEngine::WebRtcVoiceEngine( |
| 510 webrtc::AudioDeviceModule* adm, | 487 webrtc::AudioDeviceModule* adm, |
| 511 const rtc::scoped_refptr<webrtc::AudioDecoderFactory>& decoder_factory) | 488 const rtc::scoped_refptr<webrtc::AudioDecoderFactory>& decoder_factory) |
| 512 : WebRtcVoiceEngine(adm, decoder_factory, new VoEWrapper()) { | 489 : WebRtcVoiceEngine(adm, decoder_factory, new VoEWrapper()) { |
| (...skipping 620 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1133 | 1110 |
| 1134 // Add telephone-event codec last | 1111 // Add telephone-event codec last |
| 1135 map_format({kDtmfCodecName, 8000, 1}); | 1112 map_format({kDtmfCodecName, 8000, 1}); |
| 1136 | 1113 |
| 1137 return out; | 1114 return out; |
| 1138 } | 1115 } |
| 1139 | 1116 |
| 1140 class WebRtcVoiceMediaChannel::WebRtcAudioSendStream | 1117 class WebRtcVoiceMediaChannel::WebRtcAudioSendStream |
| 1141 : public AudioSource::Sink { | 1118 : public AudioSource::Sink { |
| 1142 public: | 1119 public: |
| 1143 WebRtcAudioSendStream(int ch, | 1120 WebRtcAudioSendStream( |
| 1144 webrtc::AudioTransport* voe_audio_transport, | 1121 int ch, |
| 1145 uint32_t ssrc, | 1122 webrtc::AudioTransport* voe_audio_transport, |
| 1146 const std::string& c_name, | 1123 uint32_t ssrc, |
| 1147 const SendCodecSpec& send_codec_spec, | 1124 const std::string& c_name, |
| 1148 const std::vector<webrtc::RtpExtension>& extensions, | 1125 const webrtc::AudioSendStream::Config::SendCodecSpec& send_codec_spec, |
| 1149 webrtc::Call* call, | 1126 const std::vector<webrtc::RtpExtension>& extensions, |
| 1150 webrtc::Transport* send_transport) | 1127 webrtc::Call* call, |
| 1128 webrtc::Transport* send_transport) |
| 1151 : voe_audio_transport_(voe_audio_transport), | 1129 : voe_audio_transport_(voe_audio_transport), |
| 1152 call_(call), | 1130 call_(call), |
| 1153 config_(send_transport), | 1131 config_(send_transport), |
| 1154 rtp_parameters_(CreateRtpParametersWithOneEncoding()) { | 1132 rtp_parameters_(CreateRtpParametersWithOneEncoding()) { |
| 1155 RTC_DCHECK_GE(ch, 0); | 1133 RTC_DCHECK_GE(ch, 0); |
| 1156 // TODO(solenberg): Once we're not using FakeWebRtcVoiceEngine anymore: | 1134 // TODO(solenberg): Once we're not using FakeWebRtcVoiceEngine anymore: |
| 1157 // RTC_DCHECK(voe_audio_transport); | 1135 // RTC_DCHECK(voe_audio_transport); |
| 1158 RTC_DCHECK(call); | 1136 RTC_DCHECK(call); |
| 1159 config_.rtp.ssrc = ssrc; | 1137 config_.rtp.ssrc = ssrc; |
| 1160 config_.rtp.c_name = c_name; | 1138 config_.rtp.c_name = c_name; |
| 1161 config_.voe_channel_id = ch; | 1139 config_.voe_channel_id = ch; |
| 1162 config_.rtp.extensions = extensions; | 1140 config_.rtp.extensions = extensions; |
| 1141 WebRtcVoiceCodecs::SetAudioSendStreamConfig(&config_); |
| 1163 RecreateAudioSendStream(send_codec_spec); | 1142 RecreateAudioSendStream(send_codec_spec); |
| 1164 } | 1143 } |
| 1165 | 1144 |
| 1166 ~WebRtcAudioSendStream() override { | 1145 ~WebRtcAudioSendStream() override { |
| 1167 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 1146 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
| 1168 ClearSource(); | 1147 ClearSource(); |
| 1169 call_->DestroyAudioSendStream(stream_); | 1148 call_->DestroyAudioSendStream(stream_); |
| 1170 } | 1149 } |
| 1171 | 1150 |
| 1172 void RecreateAudioSendStream(const SendCodecSpec& send_codec_spec) { | 1151 void RecreateAudioSendStream( |
| 1152 const webrtc::AudioSendStream::Config::SendCodecSpec& send_codec_spec) { |
| 1173 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 1153 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
| 1174 if (stream_) { | 1154 if (stream_) { |
| 1175 call_->DestroyAudioSendStream(stream_); | 1155 call_->DestroyAudioSendStream(stream_); |
| 1176 stream_ = nullptr; | 1156 stream_ = nullptr; |
| 1177 } | 1157 } |
| 1178 config_.rtp.nack.rtp_history_ms = | 1158 config_.rtp.nack.rtp_history_ms = |
| 1179 send_codec_spec.nack_enabled ? kNackRtpHistoryMs : 0; | 1159 send_codec_spec.nack_enabled ? kNackRtpHistoryMs : 0; |
| 1160 config_.send_codec_spec = send_codec_spec; |
| 1180 RTC_DCHECK(!stream_); | 1161 RTC_DCHECK(!stream_); |
| 1181 stream_ = call_->CreateAudioSendStream(config_); | 1162 stream_ = call_->CreateAudioSendStream(config_); |
| 1182 RTC_CHECK(stream_); | 1163 RTC_CHECK(stream_); |
| 1183 UpdateSendState(); | 1164 UpdateSendState(); |
| 1184 } | 1165 } |
| 1185 | 1166 |
| 1186 void RecreateAudioSendStream( | 1167 void RecreateAudioSendStream( |
| 1187 const std::vector<webrtc::RtpExtension>& extensions) { | 1168 const std::vector<webrtc::RtpExtension>& extensions) { |
| 1188 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 1169 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
| 1189 if (stream_) { | 1170 if (stream_) { |
| 1190 call_->DestroyAudioSendStream(stream_); | 1171 call_->DestroyAudioSendStream(stream_); |
| 1191 stream_ = nullptr; | 1172 stream_ = nullptr; |
| 1192 } | 1173 } |
| 1193 config_.rtp.extensions = extensions; | 1174 config_.rtp.extensions = extensions; |
| 1194 if (webrtc::field_trial::FindFullName("WebRTC-AdaptAudioBitrate") == | 1175 if (webrtc::field_trial::FindFullName("WebRTC-AdaptAudioBitrate") == |
| 1195 "Enabled") { | 1176 "Enabled") { |
| 1196 // TODO(mflodman): Keep testing this and set proper values. | 1177 // TODO(mflodman): Keep testing this and set proper values. |
| 1197 // Note: This is an early experiment currently only supported by Opus. | 1178 // Note: This is an early experiment currently only supported by Opus. |
| 1198 config_.min_bitrate_kbps = kOpusMinBitrate; | 1179 config_.min_bitrate_kbps = kOpusMinBitrate; |
| 1199 config_.max_bitrate_kbps = kOpusBitrateFb; | 1180 config_.max_bitrate_kbps = kOpusBitrateFb; |
| 1200 } | 1181 } |
| 1201 | 1182 |
| 1202 RTC_DCHECK(!stream_); | 1183 RTC_DCHECK(!stream_); |
| 1203 stream_ = call_->CreateAudioSendStream(config_); | 1184 stream_ = call_->CreateAudioSendStream(config_); |
| 1204 RTC_CHECK(stream_); | 1185 RTC_CHECK(stream_); |
| 1205 UpdateSendState(); | 1186 UpdateSendState(); |
| 1206 } | 1187 } |
| 1207 | 1188 |
| 1189 void MaybeRecreateAudioSendStream(int bps) { |
| 1190 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
| 1191 int new_max_send_bitrate_bps = |
| 1192 MinPositive(bps, rtp_parameters_.encodings[0].max_bitrate_bps); |
| 1193 |
| 1194 if (config_.max_send_bitrate_bps == new_max_send_bitrate_bps) |
| 1195 return; |
| 1196 |
| 1197 if (stream_) { |
| 1198 call_->DestroyAudioSendStream(stream_); |
| 1199 stream_ = nullptr; |
| 1200 } |
| 1201 RTC_DCHECK(!stream_); |
| 1202 config_.max_send_bitrate_bps = new_max_send_bitrate_bps; |
| 1203 stream_ = call_->CreateAudioSendStream(config_); |
| 1204 RTC_CHECK(stream_); |
| 1205 UpdateSendState(); |
| 1206 } |
| 1207 |
| 1208 bool SendTelephoneEvent(int payload_type, int event, int duration_ms) { | 1208 bool SendTelephoneEvent(int payload_type, int event, int duration_ms) { |
| 1209 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 1209 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
| 1210 RTC_DCHECK(stream_); | 1210 RTC_DCHECK(stream_); |
| 1211 return stream_->SendTelephoneEvent(payload_type, event, duration_ms); | 1211 return stream_->SendTelephoneEvent(payload_type, event, duration_ms); |
| 1212 } | 1212 } |
| 1213 | 1213 |
| 1214 void SetSend(bool send) { | 1214 void SetSend(bool send) { |
| 1215 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 1215 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
| 1216 send_ = send; | 1216 send_ = send; |
| 1217 UpdateSendState(); | 1217 UpdateSendState(); |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1293 return config_.voe_channel_id; | 1293 return config_.voe_channel_id; |
| 1294 } | 1294 } |
| 1295 | 1295 |
| 1296 const webrtc::RtpParameters& rtp_parameters() const { | 1296 const webrtc::RtpParameters& rtp_parameters() const { |
| 1297 return rtp_parameters_; | 1297 return rtp_parameters_; |
| 1298 } | 1298 } |
| 1299 | 1299 |
| 1300 void SetRtpParameters(const webrtc::RtpParameters& parameters) { | 1300 void SetRtpParameters(const webrtc::RtpParameters& parameters) { |
| 1301 RTC_CHECK_EQ(1UL, parameters.encodings.size()); | 1301 RTC_CHECK_EQ(1UL, parameters.encodings.size()); |
| 1302 rtp_parameters_ = parameters; | 1302 rtp_parameters_ = parameters; |
| 1303 |
| 1304 // parameters.encodings[0].max_bitrate_bps could have changed. |
| 1305 MaybeRecreateAudioSendStream(config_.max_send_bitrate_bps); |
| 1306 |
| 1303 // parameters.encodings[0].active could have changed. | 1307 // parameters.encodings[0].active could have changed. |
| 1304 UpdateSendState(); | 1308 UpdateSendState(); |
| 1305 } | 1309 } |
| 1306 | 1310 |
| 1307 private: | 1311 private: |
| 1308 void UpdateSendState() { | 1312 void UpdateSendState() { |
| 1309 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 1313 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
| 1310 RTC_DCHECK(stream_); | 1314 RTC_DCHECK(stream_); |
| 1311 RTC_DCHECK_EQ(1UL, rtp_parameters_.encodings.size()); | 1315 RTC_DCHECK_EQ(1UL, rtp_parameters_.encodings.size()); |
| 1312 if (send_ && source_ != nullptr && rtp_parameters_.encodings[0].active) { | 1316 if (send_ && source_ != nullptr && rtp_parameters_.encodings[0].active) { |
| (...skipping 271 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1584 | 1588 |
| 1585 // TODO(deadbeef): Handle setting parameters with a list of codecs in a | 1589 // TODO(deadbeef): Handle setting parameters with a list of codecs in a |
| 1586 // different order (which should change the send codec). | 1590 // different order (which should change the send codec). |
| 1587 webrtc::RtpParameters current_parameters = GetRtpSendParameters(ssrc); | 1591 webrtc::RtpParameters current_parameters = GetRtpSendParameters(ssrc); |
| 1588 if (current_parameters.codecs != parameters.codecs) { | 1592 if (current_parameters.codecs != parameters.codecs) { |
| 1589 LOG(LS_ERROR) << "Using SetParameters to change the set of codecs " | 1593 LOG(LS_ERROR) << "Using SetParameters to change the set of codecs " |
| 1590 << "is not currently supported."; | 1594 << "is not currently supported."; |
| 1591 return false; | 1595 return false; |
| 1592 } | 1596 } |
| 1593 | 1597 |
| 1594 if (!SetChannelSendParameters(it->second->channel(), parameters)) { | 1598 // TODO(minyue): The following legacy actions go into |
| 1595 LOG(LS_WARNING) << "Failed to set send RtpParameters."; | 1599 // |WebRtcAudioSendStream::SetRtpParameters()| which is called at the end, |
| 1596 return false; | 1600 // though there are two difference: |
| 1597 } | 1601 // 1. |WebRtcVoiceMediaChannel::SetChannelSendParameters()| only calls |
| 1602 // |SetSendCodec| while |WebRtcAudioSendStream::SetRtpParameters()| calls |
| 1603 // |SetSendCodecs|. The outcome should be the same. |
| 1604 // 2. AudioSendStream can be recreated. |
| 1605 |
| 1606 // if (!it->SetChannelSendParameters(it->second->channel(), parameters)) { |
| 1607 // LOG(LS_WARNING) << "Failed to set send RtpParameters."; |
| 1608 // return false; |
| 1609 // } |
| 1610 |
| 1598 // Codecs are handled at the WebRtcVoiceMediaChannel level. | 1611 // Codecs are handled at the WebRtcVoiceMediaChannel level. |
| 1599 webrtc::RtpParameters reduced_params = parameters; | 1612 webrtc::RtpParameters reduced_params = parameters; |
| 1600 reduced_params.codecs.clear(); | 1613 reduced_params.codecs.clear(); |
| 1601 it->second->SetRtpParameters(reduced_params); | 1614 it->second->SetRtpParameters(reduced_params); |
| 1602 return true; | 1615 return true; |
| 1603 } | 1616 } |
| 1604 | 1617 |
| 1605 webrtc::RtpParameters WebRtcVoiceMediaChannel::GetRtpReceiveParameters( | 1618 webrtc::RtpParameters WebRtcVoiceMediaChannel::GetRtpReceiveParameters( |
| 1606 uint32_t ssrc) const { | 1619 uint32_t ssrc) const { |
| 1607 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 1620 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
| (...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1761 } | 1774 } |
| 1762 dtmf_payload_type_ = rtc::Optional<int>(codec.id); | 1775 dtmf_payload_type_ = rtc::Optional<int>(codec.id); |
| 1763 break; | 1776 break; |
| 1764 } | 1777 } |
| 1765 } | 1778 } |
| 1766 | 1779 |
| 1767 // Scan through the list to figure out the codec to use for sending, along | 1780 // 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 | 1781 // with the proper configuration for VAD, CNG, NACK and Opus-specific |
| 1769 // parameters. | 1782 // parameters. |
| 1770 // TODO(solenberg): Refactor this logic once we create AudioEncoders here. | 1783 // TODO(solenberg): Refactor this logic once we create AudioEncoders here. |
| 1771 SendCodecSpec send_codec_spec; | 1784 webrtc::AudioSendStream::Config::SendCodecSpec send_codec_spec; |
| 1772 { | 1785 { |
| 1773 send_codec_spec.nack_enabled = send_codec_spec_.nack_enabled; | 1786 send_codec_spec.nack_enabled = send_codec_spec_.nack_enabled; |
| 1774 | 1787 |
| 1775 // Find send codec (the first non-telephone-event/CN codec). | 1788 // Find send codec (the first non-telephone-event/CN codec). |
| 1776 const AudioCodec* codec = WebRtcVoiceCodecs::GetPreferredCodec( | 1789 const AudioCodec* codec = WebRtcVoiceCodecs::GetPreferredCodec( |
| 1777 codecs, &send_codec_spec.codec_inst); | 1790 codecs, &send_codec_spec.codec_inst); |
| 1778 if (!codec) { | 1791 if (!codec) { |
| 1779 LOG(LS_WARNING) << "Received empty list of codecs."; | 1792 LOG(LS_WARNING) << "Received empty list of codecs."; |
| 1780 return false; | 1793 return false; |
| 1781 } | 1794 } |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1835 break; | 1848 break; |
| 1836 } | 1849 } |
| 1837 } | 1850 } |
| 1838 } | 1851 } |
| 1839 | 1852 |
| 1840 // Apply new settings to all streams. | 1853 // Apply new settings to all streams. |
| 1841 if (send_codec_spec_ != send_codec_spec) { | 1854 if (send_codec_spec_ != send_codec_spec) { |
| 1842 send_codec_spec_ = std::move(send_codec_spec); | 1855 send_codec_spec_ = std::move(send_codec_spec); |
| 1843 for (const auto& kv : send_streams_) { | 1856 for (const auto& kv : send_streams_) { |
| 1844 kv.second->RecreateAudioSendStream(send_codec_spec_); | 1857 kv.second->RecreateAudioSendStream(send_codec_spec_); |
| 1845 if (!SetSendCodecs(kv.second->channel(), kv.second->rtp_parameters())) { | |
| 1846 return false; | |
| 1847 } | |
| 1848 } | 1858 } |
| 1849 } | 1859 } |
| 1850 | 1860 |
| 1851 // Check if the transport cc feedback or NACK status has changed on the | 1861 // 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. | 1862 // preferred send codec, and in that case reconfigure all receive streams. |
| 1853 if (recv_transport_cc_enabled_ != send_codec_spec_.transport_cc_enabled || | 1863 if (recv_transport_cc_enabled_ != send_codec_spec_.transport_cc_enabled || |
| 1854 recv_nack_enabled_ != send_codec_spec_.nack_enabled) { | 1864 recv_nack_enabled_ != send_codec_spec_.nack_enabled) { |
| 1855 LOG(LS_INFO) << "Recreate all the receive streams because the send " | 1865 LOG(LS_INFO) << "Recreate all the receive streams because the send " |
| 1856 "codec has changed."; | 1866 "codec has changed."; |
| 1857 recv_transport_cc_enabled_ = send_codec_spec_.transport_cc_enabled; | 1867 recv_transport_cc_enabled_ = send_codec_spec_.transport_cc_enabled; |
| 1858 recv_nack_enabled_ = send_codec_spec_.nack_enabled; | 1868 recv_nack_enabled_ = send_codec_spec_.nack_enabled; |
| 1859 for (auto& kv : recv_streams_) { | 1869 for (auto& kv : recv_streams_) { |
| 1860 kv.second->RecreateAudioReceiveStream(recv_transport_cc_enabled_, | 1870 kv.second->RecreateAudioReceiveStream(recv_transport_cc_enabled_, |
| 1861 recv_nack_enabled_); | 1871 recv_nack_enabled_); |
| 1862 } | 1872 } |
| 1863 } | 1873 } |
| 1864 | 1874 |
| 1865 send_codecs_ = codecs; | 1875 send_codecs_ = codecs; |
| 1866 return true; | 1876 return true; |
| 1867 } | 1877 } |
| 1868 | 1878 |
| 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) { | 1879 void WebRtcVoiceMediaChannel::SetPlayout(bool playout) { |
| 1995 desired_playout_ = playout; | 1880 desired_playout_ = playout; |
| 1996 return ChangePlayout(desired_playout_); | 1881 return ChangePlayout(desired_playout_); |
| 1997 } | 1882 } |
| 1998 | 1883 |
| 1999 void WebRtcVoiceMediaChannel::ChangePlayout(bool playout) { | 1884 void WebRtcVoiceMediaChannel::ChangePlayout(bool playout) { |
| 2000 TRACE_EVENT0("webrtc", "WebRtcVoiceMediaChannel::ChangePlayout"); | 1885 TRACE_EVENT0("webrtc", "WebRtcVoiceMediaChannel::ChangePlayout"); |
| 2001 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 1886 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
| 2002 if (playout_ == playout) { | 1887 if (playout_ == playout) { |
| 2003 return; | 1888 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 | 1981 // Save the channel to send_streams_, so that RemoveSendStream() can still |
| 2097 // delete the channel in case failure happens below. | 1982 // delete the channel in case failure happens below. |
| 2098 webrtc::AudioTransport* audio_transport = | 1983 webrtc::AudioTransport* audio_transport = |
| 2099 engine()->voe()->base()->audio_transport(); | 1984 engine()->voe()->base()->audio_transport(); |
| 2100 | 1985 |
| 2101 WebRtcAudioSendStream* stream = new WebRtcAudioSendStream( | 1986 WebRtcAudioSendStream* stream = new WebRtcAudioSendStream( |
| 2102 channel, audio_transport, ssrc, sp.cname, send_codec_spec_, | 1987 channel, audio_transport, ssrc, sp.cname, send_codec_spec_, |
| 2103 send_rtp_extensions_, call_, this); | 1988 send_rtp_extensions_, call_, this); |
| 2104 send_streams_.insert(std::make_pair(ssrc, stream)); | 1989 send_streams_.insert(std::make_pair(ssrc, stream)); |
| 2105 | 1990 |
| 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 | 1991 // 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 | 1992 // send stream, make sure that all the receive streams are updated with the |
| 2116 // same SSRC in order to send receiver reports. | 1993 // same SSRC in order to send receiver reports. |
| 2117 if (send_streams_.size() == 1) { | 1994 if (send_streams_.size() == 1) { |
| 2118 receiver_reports_ssrc_ = ssrc; | 1995 receiver_reports_ssrc_ = ssrc; |
| 2119 for (const auto& kv : recv_streams_) { | 1996 for (const auto& kv : recv_streams_) { |
| 2120 // TODO(solenberg): Allow applications to set the RTCP SSRC of receive | 1997 // TODO(solenberg): Allow applications to set the RTCP SSRC of receive |
| 2121 // streams instead, so we can avoid recreating the streams here. | 1998 // streams instead, so we can avoid recreating the streams here. |
| 2122 kv.second->RecreateAudioReceiveStream(ssrc); | 1999 kv.second->RecreateAudioReceiveStream(ssrc); |
| 2123 int recv_channel = kv.second->channel(); | 2000 int recv_channel = kv.second->channel(); |
| (...skipping 353 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2477 webrtc::AudioProcessing* ap = engine()->voe()->base()->audio_processing(); | 2354 webrtc::AudioProcessing* ap = engine()->voe()->base()->audio_processing(); |
| 2478 if (ap) { | 2355 if (ap) { |
| 2479 ap->set_output_will_be_muted(all_muted); | 2356 ap->set_output_will_be_muted(all_muted); |
| 2480 } | 2357 } |
| 2481 return true; | 2358 return true; |
| 2482 } | 2359 } |
| 2483 | 2360 |
| 2484 bool WebRtcVoiceMediaChannel::SetMaxSendBitrate(int bps) { | 2361 bool WebRtcVoiceMediaChannel::SetMaxSendBitrate(int bps) { |
| 2485 LOG(LS_INFO) << "WebRtcVoiceMediaChannel::SetMaxSendBitrate."; | 2362 LOG(LS_INFO) << "WebRtcVoiceMediaChannel::SetMaxSendBitrate."; |
| 2486 max_send_bitrate_bps_ = bps; | 2363 max_send_bitrate_bps_ = bps; |
| 2487 | 2364 for (const auto& kv : send_streams_) |
| 2488 for (const auto& kv : send_streams_) { | 2365 kv.second->MaybeRecreateAudioSendStream(max_send_bitrate_bps_); |
| 2489 if (!SetChannelSendParameters(kv.second->channel(), | |
| 2490 kv.second->rtp_parameters())) { | |
| 2491 return false; | |
| 2492 } | |
| 2493 } | |
| 2494 return true; | 2366 return true; |
| 2495 } | 2367 } |
| 2496 | 2368 |
| 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) { | 2369 void WebRtcVoiceMediaChannel::OnReadyToSend(bool ready) { |
| 2552 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 2370 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
| 2553 LOG(LS_VERBOSE) << "OnReadyToSend: " << (ready ? "Ready." : "Not ready."); | 2371 LOG(LS_VERBOSE) << "OnReadyToSend: " << (ready ? "Ready." : "Not ready."); |
| 2554 call_->SignalChannelNetworkState( | 2372 call_->SignalChannelNetworkState( |
| 2555 webrtc::MediaType::AUDIO, | 2373 webrtc::MediaType::AUDIO, |
| 2556 ready ? webrtc::kNetworkUp : webrtc::kNetworkDown); | 2374 ready ? webrtc::kNetworkUp : webrtc::kNetworkDown); |
| 2557 } | 2375 } |
| 2558 | 2376 |
| 2559 bool WebRtcVoiceMediaChannel::GetStats(VoiceMediaInfo* info) { | 2377 bool WebRtcVoiceMediaChannel::GetStats(VoiceMediaInfo* info) { |
| 2560 TRACE_EVENT0("webrtc", "WebRtcVoiceMediaChannel::GetStats"); | 2378 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()); | 2482 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
| 2665 const auto it = send_streams_.find(ssrc); | 2483 const auto it = send_streams_.find(ssrc); |
| 2666 if (it != send_streams_.end()) { | 2484 if (it != send_streams_.end()) { |
| 2667 return it->second->channel(); | 2485 return it->second->channel(); |
| 2668 } | 2486 } |
| 2669 return -1; | 2487 return -1; |
| 2670 } | 2488 } |
| 2671 } // namespace cricket | 2489 } // namespace cricket |
| 2672 | 2490 |
| 2673 #endif // HAVE_WEBRTC_VOICE | 2491 #endif // HAVE_WEBRTC_VOICE |
| OLD | NEW |