| 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 |