| 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 1524 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1535 bool use_nack, | 1535 bool use_nack, |
| 1536 const std::string& sync_group, | 1536 const std::string& sync_group, |
| 1537 const std::vector<webrtc::RtpExtension>& extensions, | 1537 const std::vector<webrtc::RtpExtension>& extensions, |
| 1538 webrtc::Call* call, | 1538 webrtc::Call* call, |
| 1539 webrtc::Transport* rtcp_send_transport, | 1539 webrtc::Transport* rtcp_send_transport, |
| 1540 const rtc::scoped_refptr<webrtc::AudioDecoderFactory>& decoder_factory) | 1540 const rtc::scoped_refptr<webrtc::AudioDecoderFactory>& decoder_factory) |
| 1541 : call_(call), config_() { | 1541 : call_(call), config_() { |
| 1542 RTC_DCHECK_GE(ch, 0); | 1542 RTC_DCHECK_GE(ch, 0); |
| 1543 RTC_DCHECK(call); | 1543 RTC_DCHECK(call); |
| 1544 config_.rtp.remote_ssrc = remote_ssrc; | 1544 config_.rtp.remote_ssrc = remote_ssrc; |
| 1545 config_.rtp.local_ssrc = local_ssrc; |
| 1546 config_.rtp.transport_cc = use_transport_cc; |
| 1547 config_.rtp.nack.rtp_history_ms = use_nack ? kNackRtpHistoryMs : 0; |
| 1548 config_.rtp.extensions = extensions; |
| 1545 config_.rtcp_send_transport = rtcp_send_transport; | 1549 config_.rtcp_send_transport = rtcp_send_transport; |
| 1546 config_.voe_channel_id = ch; | 1550 config_.voe_channel_id = ch; |
| 1547 config_.sync_group = sync_group; | 1551 config_.sync_group = sync_group; |
| 1548 config_.decoder_factory = decoder_factory; | 1552 config_.decoder_factory = decoder_factory; |
| 1549 RecreateAudioReceiveStream(local_ssrc, | 1553 RecreateAudioReceiveStream(); |
| 1550 use_transport_cc, | |
| 1551 use_nack, | |
| 1552 extensions); | |
| 1553 } | 1554 } |
| 1554 | 1555 |
| 1555 ~WebRtcAudioReceiveStream() { | 1556 ~WebRtcAudioReceiveStream() { |
| 1556 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 1557 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
| 1557 call_->DestroyAudioReceiveStream(stream_); | 1558 call_->DestroyAudioReceiveStream(stream_); |
| 1558 } | 1559 } |
| 1559 | 1560 |
| 1560 void RecreateAudioReceiveStream(uint32_t local_ssrc) { | 1561 void RecreateAudioReceiveStream(uint32_t local_ssrc) { |
| 1561 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 1562 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
| 1562 RecreateAudioReceiveStream(local_ssrc, | 1563 config_.rtp.local_ssrc = local_ssrc; |
| 1563 config_.rtp.transport_cc, | 1564 RecreateAudioReceiveStream(); |
| 1564 config_.rtp.nack.rtp_history_ms != 0, | |
| 1565 config_.rtp.extensions); | |
| 1566 } | 1565 } |
| 1567 | 1566 |
| 1568 void RecreateAudioReceiveStream(bool use_transport_cc, bool use_nack) { | 1567 void RecreateAudioReceiveStream(bool use_transport_cc, bool use_nack) { |
| 1569 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 1568 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
| 1570 RecreateAudioReceiveStream(config_.rtp.local_ssrc, | 1569 config_.rtp.transport_cc = use_transport_cc; |
| 1571 use_transport_cc, | 1570 config_.rtp.nack.rtp_history_ms = use_nack ? kNackRtpHistoryMs : 0; |
| 1572 use_nack, | 1571 RecreateAudioReceiveStream(); |
| 1573 config_.rtp.extensions); | |
| 1574 } | 1572 } |
| 1575 | 1573 |
| 1576 void RecreateAudioReceiveStream( | 1574 void RecreateAudioReceiveStream( |
| 1577 const std::vector<webrtc::RtpExtension>& extensions) { | 1575 const std::vector<webrtc::RtpExtension>& extensions) { |
| 1578 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 1576 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
| 1579 RecreateAudioReceiveStream(config_.rtp.local_ssrc, | 1577 config_.rtp.extensions = extensions; |
| 1580 config_.rtp.transport_cc, | 1578 RecreateAudioReceiveStream(); |
| 1581 config_.rtp.nack.rtp_history_ms != 0, | 1579 } |
| 1582 extensions); | 1580 |
| 1581 // Set a new payload type -> decoder map. The new map must be a superset of |
| 1582 // the old one. |
| 1583 void RecreateAudioReceiveStream( |
| 1584 const std::map<int, webrtc::SdpAudioFormat>& decoder_map) { |
| 1585 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
| 1586 RTC_DCHECK([&] { |
| 1587 for (const auto& item : config_.decoder_map) { |
| 1588 auto it = decoder_map.find(item.first); |
| 1589 if (it == decoder_map.end() || *it != item) { |
| 1590 return false; // The old map isn't a subset of the new map. |
| 1591 } |
| 1592 } |
| 1593 return true; |
| 1594 }()); |
| 1595 config_.decoder_map = decoder_map; |
| 1596 RecreateAudioReceiveStream(); |
| 1583 } | 1597 } |
| 1584 | 1598 |
| 1585 webrtc::AudioReceiveStream::Stats GetStats() const { | 1599 webrtc::AudioReceiveStream::Stats GetStats() const { |
| 1586 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 1600 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
| 1587 RTC_DCHECK(stream_); | 1601 RTC_DCHECK(stream_); |
| 1588 return stream_->GetStats(); | 1602 return stream_->GetStats(); |
| 1589 } | 1603 } |
| 1590 | 1604 |
| 1591 int channel() const { | 1605 int channel() const { |
| 1592 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 1606 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
| (...skipping 17 matching lines...) Expand all Loading... |
| 1610 LOG(LS_INFO) << "Starting playout for channel #" << channel(); | 1624 LOG(LS_INFO) << "Starting playout for channel #" << channel(); |
| 1611 stream_->Start(); | 1625 stream_->Start(); |
| 1612 } else { | 1626 } else { |
| 1613 LOG(LS_INFO) << "Stopping playout for channel #" << channel(); | 1627 LOG(LS_INFO) << "Stopping playout for channel #" << channel(); |
| 1614 stream_->Stop(); | 1628 stream_->Stop(); |
| 1615 } | 1629 } |
| 1616 playout_ = playout; | 1630 playout_ = playout; |
| 1617 } | 1631 } |
| 1618 | 1632 |
| 1619 private: | 1633 private: |
| 1620 void RecreateAudioReceiveStream( | 1634 void RecreateAudioReceiveStream() { |
| 1621 uint32_t local_ssrc, | |
| 1622 bool use_transport_cc, | |
| 1623 bool use_nack, | |
| 1624 const std::vector<webrtc::RtpExtension>& extensions) { | |
| 1625 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 1635 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
| 1626 if (stream_) { | 1636 if (stream_) { |
| 1627 call_->DestroyAudioReceiveStream(stream_); | 1637 call_->DestroyAudioReceiveStream(stream_); |
| 1628 stream_ = nullptr; | |
| 1629 } | 1638 } |
| 1630 config_.rtp.local_ssrc = local_ssrc; | |
| 1631 config_.rtp.transport_cc = use_transport_cc; | |
| 1632 config_.rtp.nack.rtp_history_ms = use_nack ? kNackRtpHistoryMs : 0; | |
| 1633 config_.rtp.extensions = extensions; | |
| 1634 RTC_DCHECK(!stream_); | |
| 1635 stream_ = call_->CreateAudioReceiveStream(config_); | 1639 stream_ = call_->CreateAudioReceiveStream(config_); |
| 1636 RTC_CHECK(stream_); | 1640 RTC_CHECK(stream_); |
| 1637 SetPlayout(playout_); | 1641 SetPlayout(playout_); |
| 1638 } | 1642 } |
| 1639 | 1643 |
| 1640 rtc::ThreadChecker worker_thread_checker_; | 1644 rtc::ThreadChecker worker_thread_checker_; |
| 1641 webrtc::Call* call_ = nullptr; | 1645 webrtc::Call* call_ = nullptr; |
| 1642 webrtc::AudioReceiveStream::Config config_; | 1646 webrtc::AudioReceiveStream::Config config_; |
| 1643 // The stream is owned by WebRtcAudioReceiveStream and may be reallocated if | 1647 // The stream is owned by WebRtcAudioReceiveStream and may be reallocated if |
| 1644 // configuration changes. | 1648 // configuration changes. |
| (...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1894 } else { | 1898 } else { |
| 1895 new_codecs.push_back(codec); | 1899 new_codecs.push_back(codec); |
| 1896 } | 1900 } |
| 1897 } | 1901 } |
| 1898 if (new_codecs.empty()) { | 1902 if (new_codecs.empty()) { |
| 1899 // There are no new codecs to configure. Already configured codecs are | 1903 // There are no new codecs to configure. Already configured codecs are |
| 1900 // never removed. | 1904 // never removed. |
| 1901 return true; | 1905 return true; |
| 1902 } | 1906 } |
| 1903 | 1907 |
| 1908 // Create a payload type -> SdpAudioFormat map with all the decoders. Fail |
| 1909 // unless the factory claims to support all decoders. |
| 1910 std::map<int, webrtc::SdpAudioFormat> decoder_map; |
| 1911 for (const AudioCodec& codec : codecs) { |
| 1912 auto format = AudioCodecToSdpAudioFormat(codec); |
| 1913 if (!IsCodec(codec, "cn") && !IsCodec(codec, "telephone-event") && |
| 1914 !engine()->decoder_factory_->IsSupportedDecoder(format)) { |
| 1915 LOG(LS_ERROR) << "Unsupported codec: " << format; |
| 1916 return false; |
| 1917 } |
| 1918 decoder_map.insert({codec.id, std::move(format)}); |
| 1919 } |
| 1920 |
| 1904 if (playout_) { | 1921 if (playout_) { |
| 1905 // Receive codecs can not be changed while playing. So we temporarily | 1922 // Receive codecs can not be changed while playing. So we temporarily |
| 1906 // pause playout. | 1923 // pause playout. |
| 1907 ChangePlayout(false); | 1924 ChangePlayout(false); |
| 1908 } | 1925 } |
| 1909 | 1926 |
| 1910 bool result = true; | 1927 for (auto& kv : recv_streams_) { |
| 1911 for (const AudioCodec& codec : new_codecs) { | 1928 kv.second->RecreateAudioReceiveStream(decoder_map); |
| 1912 webrtc::CodecInst voe_codec = {0}; | |
| 1913 if (WebRtcVoiceEngine::ToCodecInst(codec, &voe_codec)) { | |
| 1914 LOG(LS_INFO) << ToString(codec); | |
| 1915 voe_codec.pltype = codec.id; | |
| 1916 for (const auto& ch : recv_streams_) { | |
| 1917 if (engine()->voe()->codec()->SetRecPayloadType( | |
| 1918 ch.second->channel(), voe_codec) == -1) { | |
| 1919 LOG_RTCERR2(SetRecPayloadType, ch.second->channel(), | |
| 1920 ToString(voe_codec)); | |
| 1921 result = false; | |
| 1922 } | |
| 1923 } | |
| 1924 } else { | |
| 1925 LOG(LS_WARNING) << "Unknown codec " << ToString(codec); | |
| 1926 result = false; | |
| 1927 break; | |
| 1928 } | |
| 1929 } | 1929 } |
| 1930 if (result) { | 1930 recv_codecs_ = codecs; |
| 1931 recv_codecs_ = codecs; | |
| 1932 } | |
| 1933 | 1931 |
| 1934 if (desired_playout_ && !playout_) { | 1932 if (desired_playout_ && !playout_) { |
| 1935 ChangePlayout(desired_playout_); | 1933 ChangePlayout(desired_playout_); |
| 1936 } | 1934 } |
| 1937 return result; | 1935 return true; |
| 1938 } | 1936 } |
| 1939 | 1937 |
| 1940 // Utility function called from SetSendParameters() to extract current send | 1938 // Utility function called from SetSendParameters() to extract current send |
| 1941 // codec settings from the given list of codecs (originally from SDP). Both send | 1939 // codec settings from the given list of codecs (originally from SDP). Both send |
| 1942 // and receive streams may be reconfigured based on the new settings. | 1940 // and receive streams may be reconfigured based on the new settings. |
| 1943 bool WebRtcVoiceMediaChannel::SetSendCodecs( | 1941 bool WebRtcVoiceMediaChannel::SetSendCodecs( |
| 1944 const std::vector<AudioCodec>& codecs) { | 1942 const std::vector<AudioCodec>& codecs) { |
| 1945 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 1943 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
| 1946 dtmf_payload_type_ = rtc::Optional<int>(); | 1944 dtmf_payload_type_ = rtc::Optional<int>(); |
| 1947 dtmf_payload_freq_ = -1; | 1945 dtmf_payload_freq_ = -1; |
| (...skipping 765 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2713 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 2711 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
| 2714 const auto it = send_streams_.find(ssrc); | 2712 const auto it = send_streams_.find(ssrc); |
| 2715 if (it != send_streams_.end()) { | 2713 if (it != send_streams_.end()) { |
| 2716 return it->second->channel(); | 2714 return it->second->channel(); |
| 2717 } | 2715 } |
| 2718 return -1; | 2716 return -1; |
| 2719 } | 2717 } |
| 2720 } // namespace cricket | 2718 } // namespace cricket |
| 2721 | 2719 |
| 2722 #endif // HAVE_WEBRTC_VOICE | 2720 #endif // HAVE_WEBRTC_VOICE |
| OLD | NEW |