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 1459 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1470 bool use_nack, | 1470 bool use_nack, |
1471 const std::string& sync_group, | 1471 const std::string& sync_group, |
1472 const std::vector<webrtc::RtpExtension>& extensions, | 1472 const std::vector<webrtc::RtpExtension>& extensions, |
1473 webrtc::Call* call, | 1473 webrtc::Call* call, |
1474 webrtc::Transport* rtcp_send_transport, | 1474 webrtc::Transport* rtcp_send_transport, |
1475 const rtc::scoped_refptr<webrtc::AudioDecoderFactory>& decoder_factory) | 1475 const rtc::scoped_refptr<webrtc::AudioDecoderFactory>& decoder_factory) |
1476 : call_(call), config_() { | 1476 : call_(call), config_() { |
1477 RTC_DCHECK_GE(ch, 0); | 1477 RTC_DCHECK_GE(ch, 0); |
1478 RTC_DCHECK(call); | 1478 RTC_DCHECK(call); |
1479 config_.rtp.remote_ssrc = remote_ssrc; | 1479 config_.rtp.remote_ssrc = remote_ssrc; |
| 1480 config_.rtp.local_ssrc = local_ssrc; |
| 1481 config_.rtp.transport_cc = use_transport_cc; |
| 1482 config_.rtp.nack.rtp_history_ms = use_nack ? kNackRtpHistoryMs : 0; |
| 1483 config_.rtp.extensions = extensions; |
1480 config_.rtcp_send_transport = rtcp_send_transport; | 1484 config_.rtcp_send_transport = rtcp_send_transport; |
1481 config_.voe_channel_id = ch; | 1485 config_.voe_channel_id = ch; |
1482 config_.sync_group = sync_group; | 1486 config_.sync_group = sync_group; |
1483 config_.decoder_factory = decoder_factory; | 1487 config_.decoder_factory = decoder_factory; |
1484 RecreateAudioReceiveStream(local_ssrc, | 1488 RecreateAudioReceiveStream(); |
1485 use_transport_cc, | |
1486 use_nack, | |
1487 extensions); | |
1488 } | 1489 } |
1489 | 1490 |
1490 ~WebRtcAudioReceiveStream() { | 1491 ~WebRtcAudioReceiveStream() { |
1491 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 1492 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
1492 call_->DestroyAudioReceiveStream(stream_); | 1493 call_->DestroyAudioReceiveStream(stream_); |
1493 } | 1494 } |
1494 | 1495 |
1495 void RecreateAudioReceiveStream(uint32_t local_ssrc) { | 1496 void RecreateAudioReceiveStream(uint32_t local_ssrc) { |
1496 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 1497 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
1497 RecreateAudioReceiveStream(local_ssrc, | 1498 config_.rtp.local_ssrc = local_ssrc; |
1498 config_.rtp.transport_cc, | 1499 RecreateAudioReceiveStream(); |
1499 config_.rtp.nack.rtp_history_ms != 0, | |
1500 config_.rtp.extensions); | |
1501 } | 1500 } |
1502 | 1501 |
1503 void RecreateAudioReceiveStream(bool use_transport_cc, bool use_nack) { | 1502 void RecreateAudioReceiveStream(bool use_transport_cc, bool use_nack) { |
1504 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 1503 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
1505 RecreateAudioReceiveStream(config_.rtp.local_ssrc, | 1504 config_.rtp.transport_cc = use_transport_cc; |
1506 use_transport_cc, | 1505 config_.rtp.nack.rtp_history_ms = use_nack ? kNackRtpHistoryMs : 0; |
1507 use_nack, | 1506 RecreateAudioReceiveStream(); |
1508 config_.rtp.extensions); | |
1509 } | 1507 } |
1510 | 1508 |
1511 void RecreateAudioReceiveStream( | 1509 void RecreateAudioReceiveStream( |
1512 const std::vector<webrtc::RtpExtension>& extensions) { | 1510 const std::vector<webrtc::RtpExtension>& extensions) { |
1513 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 1511 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
1514 RecreateAudioReceiveStream(config_.rtp.local_ssrc, | 1512 config_.rtp.extensions = extensions; |
1515 config_.rtp.transport_cc, | 1513 RecreateAudioReceiveStream(); |
1516 config_.rtp.nack.rtp_history_ms != 0, | 1514 } |
1517 extensions); | 1515 |
| 1516 // Set a new payload type -> decoder map. The new map must be a superset of |
| 1517 // the old one. |
| 1518 void RecreateAudioReceiveStream( |
| 1519 const std::map<int, webrtc::SdpAudioFormat>& decoder_map) { |
| 1520 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
| 1521 RTC_DCHECK([&] { |
| 1522 for (const auto& item : config_.decoder_map) { |
| 1523 auto it = decoder_map.find(item.first); |
| 1524 if (it == decoder_map.end() || *it != item) { |
| 1525 return false; // The old map isn't a subset of the new map. |
| 1526 } |
| 1527 } |
| 1528 return true; |
| 1529 }()); |
| 1530 config_.decoder_map = decoder_map; |
| 1531 RecreateAudioReceiveStream(); |
1518 } | 1532 } |
1519 | 1533 |
1520 webrtc::AudioReceiveStream::Stats GetStats() const { | 1534 webrtc::AudioReceiveStream::Stats GetStats() const { |
1521 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 1535 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
1522 RTC_DCHECK(stream_); | 1536 RTC_DCHECK(stream_); |
1523 return stream_->GetStats(); | 1537 return stream_->GetStats(); |
1524 } | 1538 } |
1525 | 1539 |
1526 int channel() const { | 1540 int channel() const { |
1527 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 1541 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
(...skipping 17 matching lines...) Expand all Loading... |
1545 LOG(LS_INFO) << "Starting playout for channel #" << channel(); | 1559 LOG(LS_INFO) << "Starting playout for channel #" << channel(); |
1546 stream_->Start(); | 1560 stream_->Start(); |
1547 } else { | 1561 } else { |
1548 LOG(LS_INFO) << "Stopping playout for channel #" << channel(); | 1562 LOG(LS_INFO) << "Stopping playout for channel #" << channel(); |
1549 stream_->Stop(); | 1563 stream_->Stop(); |
1550 } | 1564 } |
1551 playout_ = playout; | 1565 playout_ = playout; |
1552 } | 1566 } |
1553 | 1567 |
1554 private: | 1568 private: |
1555 void RecreateAudioReceiveStream( | 1569 void RecreateAudioReceiveStream() { |
1556 uint32_t local_ssrc, | |
1557 bool use_transport_cc, | |
1558 bool use_nack, | |
1559 const std::vector<webrtc::RtpExtension>& extensions) { | |
1560 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 1570 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
1561 if (stream_) { | 1571 if (stream_) { |
1562 call_->DestroyAudioReceiveStream(stream_); | 1572 call_->DestroyAudioReceiveStream(stream_); |
1563 stream_ = nullptr; | |
1564 } | 1573 } |
1565 config_.rtp.local_ssrc = local_ssrc; | |
1566 config_.rtp.transport_cc = use_transport_cc; | |
1567 config_.rtp.nack.rtp_history_ms = use_nack ? kNackRtpHistoryMs : 0; | |
1568 config_.rtp.extensions = extensions; | |
1569 RTC_DCHECK(!stream_); | |
1570 stream_ = call_->CreateAudioReceiveStream(config_); | 1574 stream_ = call_->CreateAudioReceiveStream(config_); |
1571 RTC_CHECK(stream_); | 1575 RTC_CHECK(stream_); |
1572 SetPlayout(playout_); | 1576 SetPlayout(playout_); |
1573 } | 1577 } |
1574 | 1578 |
1575 rtc::ThreadChecker worker_thread_checker_; | 1579 rtc::ThreadChecker worker_thread_checker_; |
1576 webrtc::Call* call_ = nullptr; | 1580 webrtc::Call* call_ = nullptr; |
1577 webrtc::AudioReceiveStream::Config config_; | 1581 webrtc::AudioReceiveStream::Config config_; |
1578 // The stream is owned by WebRtcAudioReceiveStream and may be reallocated if | 1582 // The stream is owned by WebRtcAudioReceiveStream and may be reallocated if |
1579 // configuration changes. | 1583 // configuration changes. |
(...skipping 265 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1845 } else { | 1849 } else { |
1846 new_codecs.push_back(codec); | 1850 new_codecs.push_back(codec); |
1847 } | 1851 } |
1848 } | 1852 } |
1849 if (new_codecs.empty()) { | 1853 if (new_codecs.empty()) { |
1850 // There are no new codecs to configure. Already configured codecs are | 1854 // There are no new codecs to configure. Already configured codecs are |
1851 // never removed. | 1855 // never removed. |
1852 return true; | 1856 return true; |
1853 } | 1857 } |
1854 | 1858 |
| 1859 // Create a payload type -> SdpAudioFormat map with all the decoders. Fail |
| 1860 // unless the factory claims to support all decoders. |
| 1861 std::map<int, webrtc::SdpAudioFormat> decoder_map; |
| 1862 for (const AudioCodec& codec : codecs) { |
| 1863 auto format = AudioCodecToSdpAudioFormat(codec); |
| 1864 if (!IsCodec(codec, "cn") && !IsCodec(codec, "telephone-event") && |
| 1865 !engine()->decoder_factory_->IsSupportedDecoder(format)) { |
| 1866 LOG(LS_ERROR) << "Unsupported codec: " << format; |
| 1867 return false; |
| 1868 } |
| 1869 decoder_map.insert({codec.id, std::move(format)}); |
| 1870 } |
| 1871 |
1855 if (playout_) { | 1872 if (playout_) { |
1856 // Receive codecs can not be changed while playing. So we temporarily | 1873 // Receive codecs can not be changed while playing. So we temporarily |
1857 // pause playout. | 1874 // pause playout. |
1858 ChangePlayout(false); | 1875 ChangePlayout(false); |
1859 } | 1876 } |
1860 | 1877 |
1861 bool result = true; | 1878 for (auto& kv : recv_streams_) { |
1862 for (const AudioCodec& codec : new_codecs) { | 1879 kv.second->RecreateAudioReceiveStream(decoder_map); |
1863 webrtc::CodecInst voe_codec = {0}; | |
1864 if (WebRtcVoiceEngine::ToCodecInst(codec, &voe_codec)) { | |
1865 LOG(LS_INFO) << ToString(codec); | |
1866 voe_codec.pltype = codec.id; | |
1867 for (const auto& ch : recv_streams_) { | |
1868 if (engine()->voe()->codec()->SetRecPayloadType( | |
1869 ch.second->channel(), voe_codec) == -1) { | |
1870 LOG_RTCERR2(SetRecPayloadType, ch.second->channel(), | |
1871 ToString(voe_codec)); | |
1872 result = false; | |
1873 } | |
1874 } | |
1875 } else { | |
1876 LOG(LS_WARNING) << "Unknown codec " << ToString(codec); | |
1877 result = false; | |
1878 break; | |
1879 } | |
1880 } | 1880 } |
1881 if (result) { | 1881 recv_codecs_ = codecs; |
1882 recv_codecs_ = codecs; | |
1883 } | |
1884 | 1882 |
1885 if (desired_playout_ && !playout_) { | 1883 if (desired_playout_ && !playout_) { |
1886 ChangePlayout(desired_playout_); | 1884 ChangePlayout(desired_playout_); |
1887 } | 1885 } |
1888 return result; | 1886 return true; |
1889 } | 1887 } |
1890 | 1888 |
1891 // Utility function called from SetSendParameters() to extract current send | 1889 // Utility function called from SetSendParameters() to extract current send |
1892 // codec settings from the given list of codecs (originally from SDP). Both send | 1890 // codec settings from the given list of codecs (originally from SDP). Both send |
1893 // and receive streams may be reconfigured based on the new settings. | 1891 // and receive streams may be reconfigured based on the new settings. |
1894 bool WebRtcVoiceMediaChannel::SetSendCodecs( | 1892 bool WebRtcVoiceMediaChannel::SetSendCodecs( |
1895 const std::vector<AudioCodec>& codecs) { | 1893 const std::vector<AudioCodec>& codecs) { |
1896 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 1894 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
1897 dtmf_payload_type_ = rtc::Optional<int>(); | 1895 dtmf_payload_type_ = rtc::Optional<int>(); |
1898 dtmf_payload_freq_ = -1; | 1896 dtmf_payload_freq_ = -1; |
(...skipping 763 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2662 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 2660 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
2663 const auto it = send_streams_.find(ssrc); | 2661 const auto it = send_streams_.find(ssrc); |
2664 if (it != send_streams_.end()) { | 2662 if (it != send_streams_.end()) { |
2665 return it->second->channel(); | 2663 return it->second->channel(); |
2666 } | 2664 } |
2667 return -1; | 2665 return -1; |
2668 } | 2666 } |
2669 } // namespace cricket | 2667 } // namespace cricket |
2670 | 2668 |
2671 #endif // HAVE_WEBRTC_VOICE | 2669 #endif // HAVE_WEBRTC_VOICE |
OLD | NEW |