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