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 |