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 const 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 431 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
508 {kPcmuCodecName, 8000, 1, 0, false, {10, 20, 30, 40, 50, 60}}, | 509 {kPcmuCodecName, 8000, 1, 0, false, {10, 20, 30, 40, 50, 60}}, |
509 {kPcmaCodecName, 8000, 1, 8, false, {10, 20, 30, 40, 50, 60}}, | 510 {kPcmaCodecName, 8000, 1, 8, false, {10, 20, 30, 40, 50, 60}}, |
510 {kCnCodecName, 32000, 1, 106, false, {}}, | 511 {kCnCodecName, 32000, 1, 106, false, {}}, |
511 {kCnCodecName, 16000, 1, 105, false, {}}, | 512 {kCnCodecName, 16000, 1, 105, false, {}}, |
512 {kCnCodecName, 8000, 1, 13, false, {}}, | 513 {kCnCodecName, 8000, 1, 13, false, {}}, |
513 {kRedCodecName, 8000, 1, 127, false, {}}, | 514 {kRedCodecName, 8000, 1, 127, false, {}}, |
514 {kDtmfCodecName, 8000, 1, 126, false, {}}, | 515 {kDtmfCodecName, 8000, 1, 126, false, {}}, |
515 }; | 516 }; |
516 } // namespace { | 517 } // namespace { |
517 | 518 |
| 519 bool SendCodecSpec::operator==(const SendCodecSpec& rhs) const { |
| 520 if (nack_enabled != rhs.nack_enabled) { |
| 521 return false; |
| 522 } |
| 523 if (transport_cc_enabled != rhs.transport_cc_enabled) { |
| 524 return false; |
| 525 } |
| 526 if (enable_codec_fec != rhs.enable_codec_fec) { |
| 527 return false; |
| 528 } |
| 529 if (enable_opus_dtx != rhs.enable_opus_dtx) { |
| 530 return false; |
| 531 } |
| 532 if (opus_max_playback_rate != rhs.opus_max_playback_rate) { |
| 533 return false; |
| 534 } |
| 535 if (red_payload_type != rhs.red_payload_type) { |
| 536 return false; |
| 537 } |
| 538 if (cng_payload_type != rhs.cng_payload_type) { |
| 539 return false; |
| 540 } |
| 541 if (cng_plfreq != rhs.cng_plfreq) { |
| 542 return false; |
| 543 } |
| 544 if (codec_inst != rhs.codec_inst) { |
| 545 return false; |
| 546 } |
| 547 return true; |
| 548 } |
| 549 |
| 550 bool SendCodecSpec::operator!=(const SendCodecSpec& rhs) const { |
| 551 return !(*this == rhs); |
| 552 } |
| 553 |
518 bool WebRtcVoiceEngine::ToCodecInst(const AudioCodec& in, | 554 bool WebRtcVoiceEngine::ToCodecInst(const AudioCodec& in, |
519 webrtc::CodecInst* out) { | 555 webrtc::CodecInst* out) { |
520 return WebRtcVoiceCodecs::ToCodecInst(in, out); | 556 return WebRtcVoiceCodecs::ToCodecInst(in, out); |
521 } | 557 } |
522 | 558 |
523 WebRtcVoiceEngine::WebRtcVoiceEngine(webrtc::AudioDeviceModule* adm) | 559 WebRtcVoiceEngine::WebRtcVoiceEngine(webrtc::AudioDeviceModule* adm) |
524 : WebRtcVoiceEngine(adm, new VoEWrapper()) { | 560 : WebRtcVoiceEngine(adm, new VoEWrapper()) { |
525 audio_state_ = webrtc::AudioState::Create(MakeAudioStateConfig(voe())); | 561 audio_state_ = webrtc::AudioState::Create(MakeAudioStateConfig(voe())); |
526 } | 562 } |
527 | 563 |
(...skipping 578 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1106 return adm_; | 1142 return adm_; |
1107 } | 1143 } |
1108 | 1144 |
1109 class WebRtcVoiceMediaChannel::WebRtcAudioSendStream | 1145 class WebRtcVoiceMediaChannel::WebRtcAudioSendStream |
1110 : public AudioSource::Sink { | 1146 : public AudioSource::Sink { |
1111 public: | 1147 public: |
1112 WebRtcAudioSendStream(int ch, | 1148 WebRtcAudioSendStream(int ch, |
1113 webrtc::AudioTransport* voe_audio_transport, | 1149 webrtc::AudioTransport* voe_audio_transport, |
1114 uint32_t ssrc, | 1150 uint32_t ssrc, |
1115 const std::string& c_name, | 1151 const std::string& c_name, |
| 1152 const SendCodecSpec& send_codec_spec, |
1116 const std::vector<webrtc::RtpExtension>& extensions, | 1153 const std::vector<webrtc::RtpExtension>& extensions, |
1117 webrtc::Call* call, | 1154 webrtc::Call* call, |
1118 webrtc::Transport* send_transport) | 1155 webrtc::Transport* send_transport) |
1119 : voe_audio_transport_(voe_audio_transport), | 1156 : voe_audio_transport_(voe_audio_transport), |
1120 call_(call), | 1157 call_(call), |
1121 config_(send_transport), | 1158 config_(send_transport), |
1122 rtp_parameters_(CreateRtpParametersWithOneEncoding()) { | 1159 rtp_parameters_(CreateRtpParametersWithOneEncoding()) { |
1123 RTC_DCHECK_GE(ch, 0); | 1160 RTC_DCHECK_GE(ch, 0); |
1124 // TODO(solenberg): Once we're not using FakeWebRtcVoiceEngine anymore: | 1161 // TODO(solenberg): Once we're not using FakeWebRtcVoiceEngine anymore: |
1125 // RTC_DCHECK(voe_audio_transport); | 1162 // RTC_DCHECK(voe_audio_transport); |
1126 RTC_DCHECK(call); | 1163 RTC_DCHECK(call); |
1127 audio_capture_thread_checker_.DetachFromThread(); | 1164 audio_capture_thread_checker_.DetachFromThread(); |
1128 config_.rtp.ssrc = ssrc; | 1165 config_.rtp.ssrc = ssrc; |
1129 config_.rtp.c_name = c_name; | 1166 config_.rtp.c_name = c_name; |
1130 config_.voe_channel_id = ch; | 1167 config_.voe_channel_id = ch; |
1131 RecreateAudioSendStream(extensions); | 1168 config_.rtp.extensions = extensions; |
| 1169 RecreateAudioSendStream(send_codec_spec); |
1132 } | 1170 } |
1133 | 1171 |
1134 ~WebRtcAudioSendStream() override { | 1172 ~WebRtcAudioSendStream() override { |
1135 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 1173 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
1136 ClearSource(); | 1174 ClearSource(); |
1137 call_->DestroyAudioSendStream(stream_); | 1175 call_->DestroyAudioSendStream(stream_); |
1138 } | 1176 } |
1139 | 1177 |
| 1178 void RecreateAudioSendStream(const SendCodecSpec& send_codec_spec) { |
| 1179 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
| 1180 if (stream_) { |
| 1181 call_->DestroyAudioSendStream(stream_); |
| 1182 stream_ = nullptr; |
| 1183 } |
| 1184 config_.rtp.nack.rtp_history_ms = |
| 1185 send_codec_spec.nack_enabled ? kNackRtpHistoryMs : 0; |
| 1186 RTC_DCHECK(!stream_); |
| 1187 stream_ = call_->CreateAudioSendStream(config_); |
| 1188 RTC_CHECK(stream_); |
| 1189 UpdateSendState(); |
| 1190 } |
| 1191 |
1140 void RecreateAudioSendStream( | 1192 void RecreateAudioSendStream( |
1141 const std::vector<webrtc::RtpExtension>& extensions) { | 1193 const std::vector<webrtc::RtpExtension>& extensions) { |
1142 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 1194 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
1143 if (stream_) { | 1195 if (stream_) { |
1144 call_->DestroyAudioSendStream(stream_); | 1196 call_->DestroyAudioSendStream(stream_); |
1145 stream_ = nullptr; | 1197 stream_ = nullptr; |
1146 } | 1198 } |
1147 config_.rtp.extensions = extensions; | 1199 config_.rtp.extensions = extensions; |
1148 RTC_DCHECK(!stream_); | 1200 RTC_DCHECK(!stream_); |
1149 stream_ = call_->CreateAudioSendStream(config_); | 1201 stream_ = call_->CreateAudioSendStream(config_); |
(...skipping 502 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1652 return false; | 1704 return false; |
1653 } | 1705 } |
1654 dtmf_payload_type_ = rtc::Optional<int>(codec.id); | 1706 dtmf_payload_type_ = rtc::Optional<int>(codec.id); |
1655 break; | 1707 break; |
1656 } | 1708 } |
1657 } | 1709 } |
1658 | 1710 |
1659 // Scan through the list to figure out the codec to use for sending, along | 1711 // Scan through the list to figure out the codec to use for sending, along |
1660 // with the proper configuration for VAD, CNG, RED, NACK and Opus-specific | 1712 // with the proper configuration for VAD, CNG, RED, NACK and Opus-specific |
1661 // parameters. | 1713 // parameters. |
| 1714 SendCodecSpec send_codec_spec; |
1662 { | 1715 { |
1663 SendCodecSpec send_codec_spec; | |
1664 send_codec_spec.nack_enabled = send_codec_spec_.nack_enabled; | 1716 send_codec_spec.nack_enabled = send_codec_spec_.nack_enabled; |
1665 | 1717 |
1666 // Find send codec (the first non-telephone-event/CN codec). | 1718 // Find send codec (the first non-telephone-event/CN codec). |
1667 const AudioCodec* codec = WebRtcVoiceCodecs::GetPreferredCodec( | 1719 const AudioCodec* codec = WebRtcVoiceCodecs::GetPreferredCodec( |
1668 codecs, &send_codec_spec.codec_inst, &send_codec_spec.red_payload_type); | 1720 codecs, &send_codec_spec.codec_inst, &send_codec_spec.red_payload_type); |
1669 if (!codec) { | 1721 if (!codec) { |
1670 LOG(LS_WARNING) << "Received empty list of codecs."; | 1722 LOG(LS_WARNING) << "Received empty list of codecs."; |
1671 return false; | 1723 return false; |
1672 } | 1724 } |
1673 | 1725 |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1725 default: | 1777 default: |
1726 LOG(LS_WARNING) << "CN frequency " << codec.clockrate | 1778 LOG(LS_WARNING) << "CN frequency " << codec.clockrate |
1727 << " not supported."; | 1779 << " not supported."; |
1728 continue; | 1780 continue; |
1729 } | 1781 } |
1730 send_codec_spec.cng_payload_type = codec.id; | 1782 send_codec_spec.cng_payload_type = codec.id; |
1731 send_codec_spec.cng_plfreq = cng_plfreq; | 1783 send_codec_spec.cng_plfreq = cng_plfreq; |
1732 break; | 1784 break; |
1733 } | 1785 } |
1734 } | 1786 } |
1735 | |
1736 // Latch in the new state. | |
1737 send_codec_spec_ = std::move(send_codec_spec); | |
1738 } | 1787 } |
1739 | 1788 |
1740 // Cache the codecs in order to configure the channel created later. | 1789 // Apply new settings to all streams. |
1741 for (const auto& ch : send_streams_) { | 1790 if (send_codec_spec_ != send_codec_spec) { |
1742 if (!SetSendCodecs(ch.second->channel(), ch.second->rtp_parameters())) { | 1791 send_codec_spec_ = std::move(send_codec_spec); |
1743 return false; | 1792 for (const auto& kv : send_streams_) { |
| 1793 kv.second->RecreateAudioSendStream(send_codec_spec_); |
| 1794 if (!SetSendCodecs(kv.second->channel(), kv.second->rtp_parameters())) { |
| 1795 return false; |
| 1796 } |
1744 } | 1797 } |
1745 } | 1798 } |
1746 | 1799 |
1747 // Set nack status on receive channels. | 1800 // Set nack status on receive channels. |
1748 for (const auto& kv : recv_streams_) { | 1801 for (const auto& kv : recv_streams_) { |
1749 SetNack(kv.second->channel(), send_codec_spec_.nack_enabled); | 1802 SetNack(kv.second->channel(), send_codec_spec_.nack_enabled); |
1750 } | 1803 } |
1751 | 1804 |
1752 // Check if the transport cc feedback has changed on the preferred send codec, | 1805 // Check if the transport cc feedback has changed on the preferred send codec, |
1753 // and in that case reconfigure all receive streams. | 1806 // and in that case reconfigure all receive streams. |
1754 if (recv_transport_cc_enabled_ != send_codec_spec_.transport_cc_enabled) { | 1807 if (recv_transport_cc_enabled_ != send_codec_spec_.transport_cc_enabled) { |
1755 LOG(LS_INFO) << "Recreate all the receive streams because the send " | 1808 LOG(LS_INFO) << "Recreate all the receive streams because the send " |
1756 "codec has changed."; | 1809 "codec has changed."; |
1757 recv_transport_cc_enabled_ = send_codec_spec_.transport_cc_enabled; | 1810 recv_transport_cc_enabled_ = send_codec_spec_.transport_cc_enabled; |
1758 for (auto& kv : recv_streams_) { | 1811 for (auto& kv : recv_streams_) { |
1759 kv.second->RecreateAudioReceiveStream(recv_transport_cc_enabled_); | 1812 kv.second->RecreateAudioReceiveStream(recv_transport_cc_enabled_); |
1760 } | 1813 } |
1761 } | 1814 } |
1762 | 1815 |
1763 send_codecs_ = codecs; | 1816 send_codecs_ = codecs; |
1764 return true; | 1817 return true; |
1765 } | 1818 } |
1766 | 1819 |
1767 // Apply current codec settings to a single voe::Channel used for sending. | 1820 // Apply current codec settings to a single voe::Channel used for sending. |
1768 bool WebRtcVoiceMediaChannel::SetSendCodecs( | 1821 bool WebRtcVoiceMediaChannel::SetSendCodecs( |
1769 int channel, | 1822 int channel, |
1770 const webrtc::RtpParameters& rtp_parameters) { | 1823 const webrtc::RtpParameters& rtp_parameters) { |
1771 // Disable VAD, FEC, and RED unless we know the other side wants them. | 1824 // Disable VAD, FEC, and RED unless we know the other side wants them. |
1772 engine()->voe()->codec()->SetVADStatus(channel, false); | 1825 engine()->voe()->codec()->SetVADStatus(channel, false); |
1773 engine()->voe()->rtp()->SetNACKStatus(channel, false, 0); | |
1774 engine()->voe()->rtp()->SetREDStatus(channel, false); | 1826 engine()->voe()->rtp()->SetREDStatus(channel, false); |
1775 engine()->voe()->codec()->SetFECStatus(channel, false); | 1827 engine()->voe()->codec()->SetFECStatus(channel, false); |
1776 | 1828 |
1777 if (send_codec_spec_.red_payload_type != -1) { | 1829 if (send_codec_spec_.red_payload_type != -1) { |
1778 // Enable redundant encoding of the specified codec. Treat any | 1830 // Enable redundant encoding of the specified codec. Treat any |
1779 // failure as a fatal internal error. | 1831 // failure as a fatal internal error. |
1780 LOG(LS_INFO) << "Enabling RED on channel " << channel; | 1832 LOG(LS_INFO) << "Enabling RED on channel " << channel; |
1781 if (engine()->voe()->rtp()->SetREDStatus(channel, true, | 1833 if (engine()->voe()->rtp()->SetREDStatus(channel, true, |
1782 send_codec_spec_.red_payload_type) == -1) { | 1834 send_codec_spec_.red_payload_type) == -1) { |
1783 LOG_RTCERR3(SetREDStatus, channel, true, | 1835 LOG_RTCERR3(SetREDStatus, channel, true, |
1784 send_codec_spec_.red_payload_type); | 1836 send_codec_spec_.red_payload_type); |
1785 return false; | 1837 return false; |
1786 } | 1838 } |
1787 } | 1839 } |
1788 | 1840 |
1789 SetNack(channel, send_codec_spec_.nack_enabled); | |
1790 | |
1791 // Set the codec immediately, since SetVADStatus() depends on whether | 1841 // Set the codec immediately, since SetVADStatus() depends on whether |
1792 // the current codec is mono or stereo. | 1842 // the current codec is mono or stereo. |
1793 if (!SetSendCodec(channel, send_codec_spec_.codec_inst)) { | 1843 if (!SetSendCodec(channel, send_codec_spec_.codec_inst)) { |
1794 return false; | 1844 return false; |
1795 } | 1845 } |
1796 | 1846 |
1797 // FEC should be enabled after SetSendCodec. | 1847 // FEC should be enabled after SetSendCodec. |
1798 if (send_codec_spec_.enable_codec_fec) { | 1848 if (send_codec_spec_.enable_codec_fec) { |
1799 LOG(LS_INFO) << "Attempt to enable codec internal FEC on channel " | 1849 LOG(LS_INFO) << "Attempt to enable codec internal FEC on channel " |
1800 << channel; | 1850 << channel; |
(...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2029 if (channel == -1) { | 2079 if (channel == -1) { |
2030 return false; | 2080 return false; |
2031 } | 2081 } |
2032 | 2082 |
2033 // Save the channel to send_streams_, so that RemoveSendStream() can still | 2083 // Save the channel to send_streams_, so that RemoveSendStream() can still |
2034 // delete the channel in case failure happens below. | 2084 // delete the channel in case failure happens below. |
2035 webrtc::AudioTransport* audio_transport = | 2085 webrtc::AudioTransport* audio_transport = |
2036 engine()->voe()->base()->audio_transport(); | 2086 engine()->voe()->base()->audio_transport(); |
2037 | 2087 |
2038 WebRtcAudioSendStream* stream = new WebRtcAudioSendStream( | 2088 WebRtcAudioSendStream* stream = new WebRtcAudioSendStream( |
2039 channel, audio_transport, ssrc, sp.cname, send_rtp_extensions_, call_, | 2089 channel, audio_transport, ssrc, sp.cname, send_codec_spec_, |
2040 this); | 2090 send_rtp_extensions_, call_, this); |
2041 send_streams_.insert(std::make_pair(ssrc, stream)); | 2091 send_streams_.insert(std::make_pair(ssrc, stream)); |
2042 | 2092 |
2043 // Set the current codecs to be used for the new channel. We need to do this | 2093 // Set the current codecs to be used for the new channel. We need to do this |
2044 // after adding the channel to send_channels_, because of how max bitrate is | 2094 // after adding the channel to send_channels_, because of how max bitrate is |
2045 // currently being configured by SetSendCodec(). | 2095 // currently being configured by SetSendCodec(). |
2046 if (HasSendCodec() && !SetSendCodecs(channel, stream->rtp_parameters())) { | 2096 if (HasSendCodec() && !SetSendCodecs(channel, stream->rtp_parameters())) { |
2047 RemoveSendStream(ssrc); | 2097 RemoveSendStream(ssrc); |
2048 return false; | 2098 return false; |
2049 } | 2099 } |
2050 | 2100 |
(...skipping 577 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2628 } | 2678 } |
2629 } else { | 2679 } else { |
2630 LOG(LS_INFO) << "Stopping playout for channel #" << channel; | 2680 LOG(LS_INFO) << "Stopping playout for channel #" << channel; |
2631 engine()->voe()->base()->StopPlayout(channel); | 2681 engine()->voe()->base()->StopPlayout(channel); |
2632 } | 2682 } |
2633 return true; | 2683 return true; |
2634 } | 2684 } |
2635 } // namespace cricket | 2685 } // namespace cricket |
2636 | 2686 |
2637 #endif // HAVE_WEBRTC_VOICE | 2687 #endif // HAVE_WEBRTC_VOICE |
OLD | NEW |