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 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
57 // -1 or 0 to select the default device. | 57 // -1 or 0 to select the default device. |
58 #ifdef WIN32 | 58 #ifdef WIN32 |
59 const int kDefaultAudioDeviceId = -1; | 59 const int kDefaultAudioDeviceId = -1; |
60 #elif !defined(WEBRTC_IOS) | 60 #elif !defined(WEBRTC_IOS) |
61 const int kDefaultAudioDeviceId = 0; | 61 const int kDefaultAudioDeviceId = 0; |
62 #endif | 62 #endif |
63 | 63 |
64 // Parameter used for NACK. | 64 // Parameter used for NACK. |
65 // This value is equivalent to 5 seconds of audio data at 20 ms per packet. | 65 // This value is equivalent to 5 seconds of audio data at 20 ms per packet. |
66 const int kNackMaxPackets = 250; | 66 const int kNackMaxPackets = 250; |
| 67 constexpr int kNackRtpHistoryMs = 5000; |
67 | 68 |
68 // Codec parameters for Opus. | 69 // Codec parameters for Opus. |
69 // draft-spittka-payload-rtp-opus-03 | 70 // draft-spittka-payload-rtp-opus-03 |
70 | 71 |
71 // Recommended bitrates: | 72 // Recommended bitrates: |
72 // 8-12 kb/s for NB speech, | 73 // 8-12 kb/s for NB speech, |
73 // 16-20 kb/s for WB speech, | 74 // 16-20 kb/s for WB speech, |
74 // 28-40 kb/s for FB speech, | 75 // 28-40 kb/s for FB speech, |
75 // 48-64 kb/s for FB mono music, and | 76 // 48-64 kb/s for FB mono music, and |
76 // 64-128 kb/s for FB stereo music. | 77 // 64-128 kb/s for FB stereo music. |
(...skipping 377 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
454 {kIlbcCodecName, 8000, 1, 102, false, {20, 30, 40, 60}}, | 455 {kIlbcCodecName, 8000, 1, 102, false, {20, 30, 40, 60}}, |
455 {kPcmuCodecName, 8000, 1, 0, false, {10, 20, 30, 40, 50, 60}}, | 456 {kPcmuCodecName, 8000, 1, 0, false, {10, 20, 30, 40, 50, 60}}, |
456 {kPcmaCodecName, 8000, 1, 8, false, {10, 20, 30, 40, 50, 60}}, | 457 {kPcmaCodecName, 8000, 1, 8, false, {10, 20, 30, 40, 50, 60}}, |
457 {kCnCodecName, 32000, 1, 106, false, {}}, | 458 {kCnCodecName, 32000, 1, 106, false, {}}, |
458 {kCnCodecName, 16000, 1, 105, false, {}}, | 459 {kCnCodecName, 16000, 1, 105, false, {}}, |
459 {kCnCodecName, 8000, 1, 13, false, {}}, | 460 {kCnCodecName, 8000, 1, 13, false, {}}, |
460 {kDtmfCodecName, 8000, 1, 126, false, {}} | 461 {kDtmfCodecName, 8000, 1, 126, false, {}} |
461 }; | 462 }; |
462 } // namespace { | 463 } // namespace { |
463 | 464 |
| 465 bool SendCodecSpec::operator==(const SendCodecSpec& rhs) const { |
| 466 if (nack_enabled != rhs.nack_enabled) { |
| 467 return false; |
| 468 } |
| 469 if (transport_cc_enabled != rhs.transport_cc_enabled) { |
| 470 return false; |
| 471 } |
| 472 if (enable_codec_fec != rhs.enable_codec_fec) { |
| 473 return false; |
| 474 } |
| 475 if (enable_opus_dtx != rhs.enable_opus_dtx) { |
| 476 return false; |
| 477 } |
| 478 if (opus_max_playback_rate != rhs.opus_max_playback_rate) { |
| 479 return false; |
| 480 } |
| 481 if (red_payload_type != rhs.red_payload_type) { |
| 482 return false; |
| 483 } |
| 484 if (cng_payload_type != rhs.cng_payload_type) { |
| 485 return false; |
| 486 } |
| 487 if (cng_plfreq != rhs.cng_plfreq) { |
| 488 return false; |
| 489 } |
| 490 if (codec_inst != rhs.codec_inst) { |
| 491 return false; |
| 492 } |
| 493 return true; |
| 494 } |
| 495 |
| 496 bool SendCodecSpec::operator!=(const SendCodecSpec& rhs) const { |
| 497 return !(*this == rhs); |
| 498 } |
| 499 |
464 bool WebRtcVoiceEngine::ToCodecInst(const AudioCodec& in, | 500 bool WebRtcVoiceEngine::ToCodecInst(const AudioCodec& in, |
465 webrtc::CodecInst* out) { | 501 webrtc::CodecInst* out) { |
466 return WebRtcVoiceCodecs::ToCodecInst(in, out); | 502 return WebRtcVoiceCodecs::ToCodecInst(in, out); |
467 } | 503 } |
468 | 504 |
469 WebRtcVoiceEngine::WebRtcVoiceEngine( | 505 WebRtcVoiceEngine::WebRtcVoiceEngine( |
470 webrtc::AudioDeviceModule* adm, | 506 webrtc::AudioDeviceModule* adm, |
471 const rtc::scoped_refptr<webrtc::AudioDecoderFactory>& decoder_factory) | 507 const rtc::scoped_refptr<webrtc::AudioDecoderFactory>& decoder_factory) |
472 : WebRtcVoiceEngine(adm, decoder_factory, new VoEWrapper()) { | 508 : WebRtcVoiceEngine(adm, decoder_factory, new VoEWrapper()) { |
473 audio_state_ = webrtc::AudioState::Create(MakeAudioStateConfig(voe())); | 509 audio_state_ = webrtc::AudioState::Create(MakeAudioStateConfig(voe())); |
(...skipping 588 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1062 return adm_; | 1098 return adm_; |
1063 } | 1099 } |
1064 | 1100 |
1065 class WebRtcVoiceMediaChannel::WebRtcAudioSendStream | 1101 class WebRtcVoiceMediaChannel::WebRtcAudioSendStream |
1066 : public AudioSource::Sink { | 1102 : public AudioSource::Sink { |
1067 public: | 1103 public: |
1068 WebRtcAudioSendStream(int ch, | 1104 WebRtcAudioSendStream(int ch, |
1069 webrtc::AudioTransport* voe_audio_transport, | 1105 webrtc::AudioTransport* voe_audio_transport, |
1070 uint32_t ssrc, | 1106 uint32_t ssrc, |
1071 const std::string& c_name, | 1107 const std::string& c_name, |
| 1108 const SendCodecSpec& send_codec_spec, |
1072 const std::vector<webrtc::RtpExtension>& extensions, | 1109 const std::vector<webrtc::RtpExtension>& extensions, |
1073 webrtc::Call* call, | 1110 webrtc::Call* call, |
1074 webrtc::Transport* send_transport) | 1111 webrtc::Transport* send_transport) |
1075 : voe_audio_transport_(voe_audio_transport), | 1112 : voe_audio_transport_(voe_audio_transport), |
1076 call_(call), | 1113 call_(call), |
1077 config_(send_transport), | 1114 config_(send_transport), |
1078 rtp_parameters_(CreateRtpParametersWithOneEncoding()) { | 1115 rtp_parameters_(CreateRtpParametersWithOneEncoding()) { |
1079 RTC_DCHECK_GE(ch, 0); | 1116 RTC_DCHECK_GE(ch, 0); |
1080 // TODO(solenberg): Once we're not using FakeWebRtcVoiceEngine anymore: | 1117 // TODO(solenberg): Once we're not using FakeWebRtcVoiceEngine anymore: |
1081 // RTC_DCHECK(voe_audio_transport); | 1118 // RTC_DCHECK(voe_audio_transport); |
1082 RTC_DCHECK(call); | 1119 RTC_DCHECK(call); |
1083 audio_capture_thread_checker_.DetachFromThread(); | 1120 audio_capture_thread_checker_.DetachFromThread(); |
1084 config_.rtp.ssrc = ssrc; | 1121 config_.rtp.ssrc = ssrc; |
1085 config_.rtp.c_name = c_name; | 1122 config_.rtp.c_name = c_name; |
1086 config_.voe_channel_id = ch; | 1123 config_.voe_channel_id = ch; |
1087 RecreateAudioSendStream(extensions); | 1124 config_.rtp.extensions = extensions; |
| 1125 RecreateAudioSendStream(send_codec_spec); |
1088 } | 1126 } |
1089 | 1127 |
1090 ~WebRtcAudioSendStream() override { | 1128 ~WebRtcAudioSendStream() override { |
1091 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 1129 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
1092 ClearSource(); | 1130 ClearSource(); |
1093 call_->DestroyAudioSendStream(stream_); | 1131 call_->DestroyAudioSendStream(stream_); |
1094 } | 1132 } |
1095 | 1133 |
| 1134 void RecreateAudioSendStream(const SendCodecSpec& send_codec_spec) { |
| 1135 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
| 1136 if (stream_) { |
| 1137 call_->DestroyAudioSendStream(stream_); |
| 1138 stream_ = nullptr; |
| 1139 } |
| 1140 config_.rtp.nack.rtp_history_ms = |
| 1141 send_codec_spec.nack_enabled ? kNackRtpHistoryMs : 0; |
| 1142 RTC_DCHECK(!stream_); |
| 1143 stream_ = call_->CreateAudioSendStream(config_); |
| 1144 RTC_CHECK(stream_); |
| 1145 UpdateSendState(); |
| 1146 } |
| 1147 |
1096 void RecreateAudioSendStream( | 1148 void RecreateAudioSendStream( |
1097 const std::vector<webrtc::RtpExtension>& extensions) { | 1149 const std::vector<webrtc::RtpExtension>& extensions) { |
1098 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 1150 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
1099 if (stream_) { | 1151 if (stream_) { |
1100 call_->DestroyAudioSendStream(stream_); | 1152 call_->DestroyAudioSendStream(stream_); |
1101 stream_ = nullptr; | 1153 stream_ = nullptr; |
1102 } | 1154 } |
1103 config_.rtp.extensions = extensions; | 1155 config_.rtp.extensions = extensions; |
1104 RTC_DCHECK(!stream_); | 1156 RTC_DCHECK(!stream_); |
1105 stream_ = call_->CreateAudioSendStream(config_); | 1157 stream_ = call_->CreateAudioSendStream(config_); |
(...skipping 506 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1612 } | 1664 } |
1613 dtmf_payload_type_ = rtc::Optional<int>(codec.id); | 1665 dtmf_payload_type_ = rtc::Optional<int>(codec.id); |
1614 break; | 1666 break; |
1615 } | 1667 } |
1616 } | 1668 } |
1617 | 1669 |
1618 // Scan through the list to figure out the codec to use for sending, along | 1670 // Scan through the list to figure out the codec to use for sending, along |
1619 // with the proper configuration for VAD, CNG, NACK and Opus-specific | 1671 // with the proper configuration for VAD, CNG, NACK and Opus-specific |
1620 // parameters. | 1672 // parameters. |
1621 // TODO(solenberg): Refactor this logic once we create AudioEncoders here. | 1673 // TODO(solenberg): Refactor this logic once we create AudioEncoders here. |
| 1674 SendCodecSpec send_codec_spec; |
1622 { | 1675 { |
1623 SendCodecSpec send_codec_spec; | |
1624 send_codec_spec.nack_enabled = send_codec_spec_.nack_enabled; | 1676 send_codec_spec.nack_enabled = send_codec_spec_.nack_enabled; |
1625 | 1677 |
1626 // Find send codec (the first non-telephone-event/CN codec). | 1678 // Find send codec (the first non-telephone-event/CN codec). |
1627 const AudioCodec* codec = WebRtcVoiceCodecs::GetPreferredCodec( | 1679 const AudioCodec* codec = WebRtcVoiceCodecs::GetPreferredCodec( |
1628 codecs, &send_codec_spec.codec_inst); | 1680 codecs, &send_codec_spec.codec_inst); |
1629 if (!codec) { | 1681 if (!codec) { |
1630 LOG(LS_WARNING) << "Received empty list of codecs."; | 1682 LOG(LS_WARNING) << "Received empty list of codecs."; |
1631 return false; | 1683 return false; |
1632 } | 1684 } |
1633 | 1685 |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1679 default: | 1731 default: |
1680 LOG(LS_WARNING) << "CN frequency " << codec.clockrate | 1732 LOG(LS_WARNING) << "CN frequency " << codec.clockrate |
1681 << " not supported."; | 1733 << " not supported."; |
1682 continue; | 1734 continue; |
1683 } | 1735 } |
1684 send_codec_spec.cng_payload_type = codec.id; | 1736 send_codec_spec.cng_payload_type = codec.id; |
1685 send_codec_spec.cng_plfreq = cng_plfreq; | 1737 send_codec_spec.cng_plfreq = cng_plfreq; |
1686 break; | 1738 break; |
1687 } | 1739 } |
1688 } | 1740 } |
1689 | |
1690 // Latch in the new state. | |
1691 send_codec_spec_ = std::move(send_codec_spec); | |
1692 } | 1741 } |
1693 | 1742 |
1694 // Cache the codecs in order to configure the channel created later. | 1743 // Apply new settings to all streams. |
1695 for (const auto& ch : send_streams_) { | 1744 if (send_codec_spec_ != send_codec_spec) { |
1696 if (!SetSendCodecs(ch.second->channel(), ch.second->rtp_parameters())) { | 1745 send_codec_spec_ = std::move(send_codec_spec); |
1697 return false; | 1746 for (const auto& kv : send_streams_) { |
| 1747 kv.second->RecreateAudioSendStream(send_codec_spec_); |
| 1748 if (!SetSendCodecs(kv.second->channel(), kv.second->rtp_parameters())) { |
| 1749 return false; |
| 1750 } |
1698 } | 1751 } |
1699 } | 1752 } |
1700 | 1753 |
1701 // Set nack status on receive channels. | 1754 // Set nack status on receive channels. |
1702 for (const auto& kv : recv_streams_) { | 1755 for (const auto& kv : recv_streams_) { |
1703 SetNack(kv.second->channel(), send_codec_spec_.nack_enabled); | 1756 SetNack(kv.second->channel(), send_codec_spec_.nack_enabled); |
1704 } | 1757 } |
1705 | 1758 |
1706 // Check if the transport cc feedback has changed on the preferred send codec, | 1759 // Check if the transport cc feedback has changed on the preferred send codec, |
1707 // and in that case reconfigure all receive streams. | 1760 // and in that case reconfigure all receive streams. |
1708 if (recv_transport_cc_enabled_ != send_codec_spec_.transport_cc_enabled) { | 1761 if (recv_transport_cc_enabled_ != send_codec_spec_.transport_cc_enabled) { |
1709 LOG(LS_INFO) << "Recreate all the receive streams because the send " | 1762 LOG(LS_INFO) << "Recreate all the receive streams because the send " |
1710 "codec has changed."; | 1763 "codec has changed."; |
1711 recv_transport_cc_enabled_ = send_codec_spec_.transport_cc_enabled; | 1764 recv_transport_cc_enabled_ = send_codec_spec_.transport_cc_enabled; |
1712 for (auto& kv : recv_streams_) { | 1765 for (auto& kv : recv_streams_) { |
1713 kv.second->RecreateAudioReceiveStream(recv_transport_cc_enabled_); | 1766 kv.second->RecreateAudioReceiveStream(recv_transport_cc_enabled_); |
1714 } | 1767 } |
1715 } | 1768 } |
1716 | 1769 |
1717 send_codecs_ = codecs; | 1770 send_codecs_ = codecs; |
1718 return true; | 1771 return true; |
1719 } | 1772 } |
1720 | 1773 |
1721 // Apply current codec settings to a single voe::Channel used for sending. | 1774 // Apply current codec settings to a single voe::Channel used for sending. |
1722 bool WebRtcVoiceMediaChannel::SetSendCodecs( | 1775 bool WebRtcVoiceMediaChannel::SetSendCodecs( |
1723 int channel, | 1776 int channel, |
1724 const webrtc::RtpParameters& rtp_parameters) { | 1777 const webrtc::RtpParameters& rtp_parameters) { |
1725 // Disable VAD, NACK and FEC unless we know the other side wants them. | 1778 // Disable VAD and FEC unless we know the other side wants them. |
1726 engine()->voe()->codec()->SetVADStatus(channel, false); | 1779 engine()->voe()->codec()->SetVADStatus(channel, false); |
1727 engine()->voe()->rtp()->SetNACKStatus(channel, false, 0); | |
1728 engine()->voe()->codec()->SetFECStatus(channel, false); | 1780 engine()->voe()->codec()->SetFECStatus(channel, false); |
1729 | 1781 |
1730 SetNack(channel, send_codec_spec_.nack_enabled); | |
1731 | |
1732 // Set the codec immediately, since SetVADStatus() depends on whether | 1782 // Set the codec immediately, since SetVADStatus() depends on whether |
1733 // the current codec is mono or stereo. | 1783 // the current codec is mono or stereo. |
1734 if (!SetSendCodec(channel, send_codec_spec_.codec_inst)) { | 1784 if (!SetSendCodec(channel, send_codec_spec_.codec_inst)) { |
1735 return false; | 1785 return false; |
1736 } | 1786 } |
1737 | 1787 |
1738 // FEC should be enabled after SetSendCodec. | 1788 // FEC should be enabled after SetSendCodec. |
1739 if (send_codec_spec_.enable_codec_fec) { | 1789 if (send_codec_spec_.enable_codec_fec) { |
1740 LOG(LS_INFO) << "Attempt to enable codec internal FEC on channel " | 1790 LOG(LS_INFO) << "Attempt to enable codec internal FEC on channel " |
1741 << channel; | 1791 << channel; |
(...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1970 if (channel == -1) { | 2020 if (channel == -1) { |
1971 return false; | 2021 return false; |
1972 } | 2022 } |
1973 | 2023 |
1974 // Save the channel to send_streams_, so that RemoveSendStream() can still | 2024 // Save the channel to send_streams_, so that RemoveSendStream() can still |
1975 // delete the channel in case failure happens below. | 2025 // delete the channel in case failure happens below. |
1976 webrtc::AudioTransport* audio_transport = | 2026 webrtc::AudioTransport* audio_transport = |
1977 engine()->voe()->base()->audio_transport(); | 2027 engine()->voe()->base()->audio_transport(); |
1978 | 2028 |
1979 WebRtcAudioSendStream* stream = new WebRtcAudioSendStream( | 2029 WebRtcAudioSendStream* stream = new WebRtcAudioSendStream( |
1980 channel, audio_transport, ssrc, sp.cname, send_rtp_extensions_, call_, | 2030 channel, audio_transport, ssrc, sp.cname, send_codec_spec_, |
1981 this); | 2031 send_rtp_extensions_, call_, this); |
1982 send_streams_.insert(std::make_pair(ssrc, stream)); | 2032 send_streams_.insert(std::make_pair(ssrc, stream)); |
1983 | 2033 |
1984 // Set the current codecs to be used for the new channel. We need to do this | 2034 // Set the current codecs to be used for the new channel. We need to do this |
1985 // after adding the channel to send_channels_, because of how max bitrate is | 2035 // after adding the channel to send_channels_, because of how max bitrate is |
1986 // currently being configured by SetSendCodec(). | 2036 // currently being configured by SetSendCodec(). |
1987 if (HasSendCodec() && !SetSendCodecs(channel, stream->rtp_parameters())) { | 2037 if (HasSendCodec() && !SetSendCodecs(channel, stream->rtp_parameters())) { |
1988 RemoveSendStream(ssrc); | 2038 RemoveSendStream(ssrc); |
1989 return false; | 2039 return false; |
1990 } | 2040 } |
1991 | 2041 |
(...skipping 578 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2570 } | 2620 } |
2571 } else { | 2621 } else { |
2572 LOG(LS_INFO) << "Stopping playout for channel #" << channel; | 2622 LOG(LS_INFO) << "Stopping playout for channel #" << channel; |
2573 engine()->voe()->base()->StopPlayout(channel); | 2623 engine()->voe()->base()->StopPlayout(channel); |
2574 } | 2624 } |
2575 return true; | 2625 return true; |
2576 } | 2626 } |
2577 } // namespace cricket | 2627 } // namespace cricket |
2578 | 2628 |
2579 #endif // HAVE_WEBRTC_VOICE | 2629 #endif // HAVE_WEBRTC_VOICE |
OLD | NEW |