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 1449 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1460 bool use_nack, | 1460 bool use_nack, |
1461 const std::string& sync_group, | 1461 const std::string& sync_group, |
1462 const std::vector<webrtc::RtpExtension>& extensions, | 1462 const std::vector<webrtc::RtpExtension>& extensions, |
1463 webrtc::Call* call, | 1463 webrtc::Call* call, |
1464 webrtc::Transport* rtcp_send_transport, | 1464 webrtc::Transport* rtcp_send_transport, |
1465 const rtc::scoped_refptr<webrtc::AudioDecoderFactory>& decoder_factory) | 1465 const rtc::scoped_refptr<webrtc::AudioDecoderFactory>& decoder_factory) |
1466 : call_(call), config_() { | 1466 : call_(call), config_() { |
1467 RTC_DCHECK_GE(ch, 0); | 1467 RTC_DCHECK_GE(ch, 0); |
1468 RTC_DCHECK(call); | 1468 RTC_DCHECK(call); |
1469 config_.rtp.remote_ssrc = remote_ssrc; | 1469 config_.rtp.remote_ssrc = remote_ssrc; |
1470 config_.rtp.local_ssrc = local_ssrc; | |
1471 config_.rtp.transport_cc = use_transport_cc; | |
1472 config_.rtp.nack.rtp_history_ms = use_nack ? kNackRtpHistoryMs : 0; | |
1473 config_.rtp.extensions = extensions; | |
1470 config_.rtcp_send_transport = rtcp_send_transport; | 1474 config_.rtcp_send_transport = rtcp_send_transport; |
1471 config_.voe_channel_id = ch; | 1475 config_.voe_channel_id = ch; |
1472 config_.sync_group = sync_group; | 1476 config_.sync_group = sync_group; |
1473 config_.decoder_factory = decoder_factory; | 1477 config_.decoder_factory = decoder_factory; |
1474 RecreateAudioReceiveStream(local_ssrc, | 1478 RecreateAudioReceiveStream(); |
the sun
2016/12/14 08:58:24
Thanks for fixing this btw!
| |
1475 use_transport_cc, | |
1476 use_nack, | |
1477 extensions); | |
1478 } | 1479 } |
1479 | 1480 |
1480 ~WebRtcAudioReceiveStream() { | 1481 ~WebRtcAudioReceiveStream() { |
1481 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 1482 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
1482 call_->DestroyAudioReceiveStream(stream_); | 1483 call_->DestroyAudioReceiveStream(stream_); |
1483 } | 1484 } |
1484 | 1485 |
1485 void RecreateAudioReceiveStream(uint32_t local_ssrc) { | 1486 void RecreateAudioReceiveStream(uint32_t local_ssrc) { |
1486 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 1487 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
1487 RecreateAudioReceiveStream(local_ssrc, | 1488 config_.rtp.local_ssrc = local_ssrc; |
1488 config_.rtp.transport_cc, | 1489 RecreateAudioReceiveStream(); |
1489 config_.rtp.nack.rtp_history_ms != 0, | |
1490 config_.rtp.extensions); | |
1491 } | 1490 } |
1492 | 1491 |
1493 void RecreateAudioReceiveStream(bool use_transport_cc, bool use_nack) { | 1492 void RecreateAudioReceiveStream(bool use_transport_cc, bool use_nack) { |
1494 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 1493 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
1495 RecreateAudioReceiveStream(config_.rtp.local_ssrc, | 1494 config_.rtp.transport_cc = use_transport_cc; |
1496 use_transport_cc, | 1495 config_.rtp.nack.rtp_history_ms = use_nack ? kNackRtpHistoryMs : 0; |
1497 use_nack, | 1496 RecreateAudioReceiveStream(); |
1498 config_.rtp.extensions); | |
1499 } | 1497 } |
1500 | 1498 |
1501 void RecreateAudioReceiveStream( | 1499 void RecreateAudioReceiveStream( |
1502 const std::vector<webrtc::RtpExtension>& extensions) { | 1500 const std::vector<webrtc::RtpExtension>& extensions) { |
1503 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 1501 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
1504 RecreateAudioReceiveStream(config_.rtp.local_ssrc, | 1502 config_.rtp.extensions = extensions; |
1505 config_.rtp.transport_cc, | 1503 RecreateAudioReceiveStream(); |
1506 config_.rtp.nack.rtp_history_ms != 0, | 1504 } |
1507 extensions); | 1505 |
1506 // Set a new payload type -> decoder map. The new map must be a superset of | |
1507 // the old one. | |
1508 void RecreateAudioReceiveStream( | |
1509 const std::map<int, webrtc::SdpAudioFormat>& decoder_map) { | |
1510 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | |
1511 RTC_DCHECK([&] { | |
1512 for (const auto& item : config_.decoder_map) { | |
1513 auto it = decoder_map.find(item.first); | |
1514 if (it == decoder_map.end() || *it != item) { | |
1515 return false; // The old map isn't a subset of the new map. | |
1516 } | |
1517 } | |
1518 return true; | |
1519 }()); | |
1520 config_.decoder_map = decoder_map; | |
1521 RecreateAudioReceiveStream(); | |
1508 } | 1522 } |
1509 | 1523 |
1510 webrtc::AudioReceiveStream::Stats GetStats() const { | 1524 webrtc::AudioReceiveStream::Stats GetStats() const { |
1511 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 1525 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
1512 RTC_DCHECK(stream_); | 1526 RTC_DCHECK(stream_); |
1513 return stream_->GetStats(); | 1527 return stream_->GetStats(); |
1514 } | 1528 } |
1515 | 1529 |
1516 int channel() const { | 1530 int channel() const { |
1517 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 1531 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
(...skipping 17 matching lines...) Expand all Loading... | |
1535 LOG(LS_INFO) << "Starting playout for channel #" << channel(); | 1549 LOG(LS_INFO) << "Starting playout for channel #" << channel(); |
1536 stream_->Start(); | 1550 stream_->Start(); |
1537 } else { | 1551 } else { |
1538 LOG(LS_INFO) << "Stopping playout for channel #" << channel(); | 1552 LOG(LS_INFO) << "Stopping playout for channel #" << channel(); |
1539 stream_->Stop(); | 1553 stream_->Stop(); |
1540 } | 1554 } |
1541 playout_ = playout; | 1555 playout_ = playout; |
1542 } | 1556 } |
1543 | 1557 |
1544 private: | 1558 private: |
1545 void RecreateAudioReceiveStream( | 1559 void RecreateAudioReceiveStream() { |
1546 uint32_t local_ssrc, | |
1547 bool use_transport_cc, | |
1548 bool use_nack, | |
1549 const std::vector<webrtc::RtpExtension>& extensions) { | |
1550 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 1560 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
1551 if (stream_) { | 1561 if (stream_) { |
1552 call_->DestroyAudioReceiveStream(stream_); | 1562 call_->DestroyAudioReceiveStream(stream_); |
1553 stream_ = nullptr; | |
1554 } | 1563 } |
1555 config_.rtp.local_ssrc = local_ssrc; | |
1556 config_.rtp.transport_cc = use_transport_cc; | |
1557 config_.rtp.nack.rtp_history_ms = use_nack ? kNackRtpHistoryMs : 0; | |
1558 config_.rtp.extensions = extensions; | |
1559 RTC_DCHECK(!stream_); | |
1560 stream_ = call_->CreateAudioReceiveStream(config_); | 1564 stream_ = call_->CreateAudioReceiveStream(config_); |
1561 RTC_CHECK(stream_); | 1565 RTC_CHECK(stream_); |
1562 SetPlayout(playout_); | 1566 SetPlayout(playout_); |
1563 } | 1567 } |
1564 | 1568 |
1565 rtc::ThreadChecker worker_thread_checker_; | 1569 rtc::ThreadChecker worker_thread_checker_; |
1566 webrtc::Call* call_ = nullptr; | 1570 webrtc::Call* call_ = nullptr; |
1567 webrtc::AudioReceiveStream::Config config_; | 1571 webrtc::AudioReceiveStream::Config config_; |
1568 // The stream is owned by WebRtcAudioReceiveStream and may be reallocated if | 1572 // The stream is owned by WebRtcAudioReceiveStream and may be reallocated if |
1569 // configuration changes. | 1573 // configuration changes. |
(...skipping 264 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1834 } else { | 1838 } else { |
1835 new_codecs.push_back(codec); | 1839 new_codecs.push_back(codec); |
1836 } | 1840 } |
1837 } | 1841 } |
1838 if (new_codecs.empty()) { | 1842 if (new_codecs.empty()) { |
1839 // There are no new codecs to configure. Already configured codecs are | 1843 // There are no new codecs to configure. Already configured codecs are |
1840 // never removed. | 1844 // never removed. |
1841 return true; | 1845 return true; |
1842 } | 1846 } |
1843 | 1847 |
1848 // Create a payload type -> SdpAudioFormat map with all the decoders. Fail | |
1849 // unless the factory claims to support all decoders. | |
1850 std::map<int, webrtc::SdpAudioFormat> decoder_map; | |
1851 for (const AudioCodec& codec : codecs) { | |
1852 auto saf = AudioCodecToSdpAudioFormat(codec); | |
the sun
2016/12/14 08:58:21
How about "format" instead of "saf"?
kwiberg-webrtc
2016/12/14 13:09:36
Done.
| |
1853 if (!IsCodec(codec, "cn") && !IsCodec(codec, "telephone-event") && | |
1854 !engine()->decoder_factory_->IsSupportedDecoder(saf)) { | |
1855 LOG(LS_ERROR) << "Unsupported codec: " << saf; | |
1856 return false; | |
1857 } | |
1858 decoder_map.insert({codec.id, std::move(saf)}); | |
1859 } | |
1860 | |
1844 if (playout_) { | 1861 if (playout_) { |
1845 // Receive codecs can not be changed while playing. So we temporarily | 1862 // Receive codecs can not be changed while playing. So we temporarily |
1846 // pause playout. | 1863 // pause playout. |
1847 ChangePlayout(false); | 1864 ChangePlayout(false); |
1848 } | 1865 } |
1849 | 1866 |
1850 bool result = true; | 1867 for (auto& kv : recv_streams_) { |
1851 for (const AudioCodec& codec : new_codecs) { | 1868 kv.second->RecreateAudioReceiveStream(decoder_map); |
1852 webrtc::CodecInst voe_codec = {0}; | |
1853 if (WebRtcVoiceEngine::ToCodecInst(codec, &voe_codec)) { | |
the sun
2016/12/14 08:58:21
What about the other logic that ToCodecInst() has,
kwiberg-webrtc
2016/12/14 13:09:36
There's a bunch of logic to handle G722's clock ra
| |
1854 LOG(LS_INFO) << ToString(codec); | |
1855 voe_codec.pltype = codec.id; | |
1856 for (const auto& ch : recv_streams_) { | |
1857 if (engine()->voe()->codec()->SetRecPayloadType( | |
1858 ch.second->channel(), voe_codec) == -1) { | |
1859 LOG_RTCERR2(SetRecPayloadType, ch.second->channel(), | |
1860 ToString(voe_codec)); | |
1861 result = false; | |
1862 } | |
1863 } | |
1864 } else { | |
1865 LOG(LS_WARNING) << "Unknown codec " << ToString(codec); | |
1866 result = false; | |
1867 break; | |
1868 } | |
1869 } | 1869 } |
1870 if (result) { | 1870 recv_codecs_ = codecs; |
1871 recv_codecs_ = codecs; | |
1872 } | |
1873 | 1871 |
1874 if (desired_playout_ && !playout_) { | 1872 if (desired_playout_ && !playout_) { |
1875 ChangePlayout(desired_playout_); | 1873 ChangePlayout(desired_playout_); |
1876 } | 1874 } |
1877 return result; | 1875 return true; |
1878 } | 1876 } |
1879 | 1877 |
1880 // Utility function called from SetSendParameters() to extract current send | 1878 // Utility function called from SetSendParameters() to extract current send |
1881 // codec settings from the given list of codecs (originally from SDP). Both send | 1879 // codec settings from the given list of codecs (originally from SDP). Both send |
1882 // and receive streams may be reconfigured based on the new settings. | 1880 // and receive streams may be reconfigured based on the new settings. |
1883 bool WebRtcVoiceMediaChannel::SetSendCodecs( | 1881 bool WebRtcVoiceMediaChannel::SetSendCodecs( |
1884 const std::vector<AudioCodec>& codecs) { | 1882 const std::vector<AudioCodec>& codecs) { |
1885 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 1883 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
1886 dtmf_payload_type_ = rtc::Optional<int>(); | 1884 dtmf_payload_type_ = rtc::Optional<int>(); |
1887 dtmf_payload_freq_ = -1; | 1885 dtmf_payload_freq_ = -1; |
(...skipping 331 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2219 // Create a new channel for receiving audio data. | 2217 // Create a new channel for receiving audio data. |
2220 const int channel = CreateVoEChannel(); | 2218 const int channel = CreateVoEChannel(); |
2221 if (channel == -1) { | 2219 if (channel == -1) { |
2222 return false; | 2220 return false; |
2223 } | 2221 } |
2224 | 2222 |
2225 // Turn off all supported codecs. | 2223 // Turn off all supported codecs. |
2226 // TODO(solenberg): Remove once "no codecs" is the default state of a stream. | 2224 // TODO(solenberg): Remove once "no codecs" is the default state of a stream. |
2227 for (webrtc::CodecInst voe_codec : webrtc::acm2::RentACodec::Database()) { | 2225 for (webrtc::CodecInst voe_codec : webrtc::acm2::RentACodec::Database()) { |
2228 voe_codec.pltype = -1; | 2226 voe_codec.pltype = -1; |
2229 if (engine()->voe()->codec()->SetRecPayloadType(channel, voe_codec) == -1) { | 2227 if (engine()->voe()->codec()->SetRecPayloadType(channel, voe_codec) == -1) { |
the sun
2016/12/14 10:37:38
We should be able to remove these calls to SetRecP
kwiberg-webrtc
2016/12/14 13:09:36
Maybe. But removing this for loop breaks a half-do
| |
2230 LOG_RTCERR2(SetRecPayloadType, channel, ToString(voe_codec)); | 2228 LOG_RTCERR2(SetRecPayloadType, channel, ToString(voe_codec)); |
2231 DeleteVoEChannel(channel); | 2229 DeleteVoEChannel(channel); |
2232 return false; | 2230 return false; |
2233 } | 2231 } |
2234 } | 2232 } |
2235 | 2233 |
2236 // Only enable those configured for this channel. | 2234 // Only enable those configured for this channel. |
2237 for (const auto& codec : recv_codecs_) { | 2235 for (const auto& codec : recv_codecs_) { |
2238 webrtc::CodecInst voe_codec = {0}; | 2236 webrtc::CodecInst voe_codec = {0}; |
2239 if (WebRtcVoiceEngine::ToCodecInst(codec, &voe_codec)) { | 2237 if (WebRtcVoiceEngine::ToCodecInst(codec, &voe_codec)) { |
(...skipping 411 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2651 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 2649 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
2652 const auto it = send_streams_.find(ssrc); | 2650 const auto it = send_streams_.find(ssrc); |
2653 if (it != send_streams_.end()) { | 2651 if (it != send_streams_.end()) { |
2654 return it->second->channel(); | 2652 return it->second->channel(); |
2655 } | 2653 } |
2656 return -1; | 2654 return -1; |
2657 } | 2655 } |
2658 } // namespace cricket | 2656 } // namespace cricket |
2659 | 2657 |
2660 #endif // HAVE_WEBRTC_VOICE | 2658 #endif // HAVE_WEBRTC_VOICE |
OLD | NEW |