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 1497 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1508 RecreateAudioReceiveStream(); | 1508 RecreateAudioReceiveStream(); |
1509 } | 1509 } |
1510 | 1510 |
1511 void RecreateAudioReceiveStream( | 1511 void RecreateAudioReceiveStream( |
1512 const std::vector<webrtc::RtpExtension>& extensions) { | 1512 const std::vector<webrtc::RtpExtension>& extensions) { |
1513 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 1513 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
1514 config_.rtp.extensions = extensions; | 1514 config_.rtp.extensions = extensions; |
1515 RecreateAudioReceiveStream(); | 1515 RecreateAudioReceiveStream(); |
1516 } | 1516 } |
1517 | 1517 |
1518 // Set a new payload type -> decoder map. The new map must be a superset of | 1518 // Set a new payload type -> decoder map. |
1519 // the old one. | |
1520 void RecreateAudioReceiveStream( | 1519 void RecreateAudioReceiveStream( |
1521 const std::map<int, webrtc::SdpAudioFormat>& decoder_map) { | 1520 const std::map<int, webrtc::SdpAudioFormat>& decoder_map) { |
1522 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 1521 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
1523 RTC_DCHECK([&] { | |
1524 for (const auto& item : config_.decoder_map) { | |
1525 auto it = decoder_map.find(item.first); | |
1526 if (it == decoder_map.end() || *it != item) { | |
1527 return false; // The old map isn't a subset of the new map. | |
1528 } | |
1529 } | |
1530 return true; | |
1531 }()); | |
1532 config_.decoder_map = decoder_map; | 1522 config_.decoder_map = decoder_map; |
1533 RecreateAudioReceiveStream(); | 1523 RecreateAudioReceiveStream(); |
1534 } | 1524 } |
1535 | 1525 |
1536 void MaybeRecreateAudioReceiveStream(const std::string& sync_group) { | 1526 void MaybeRecreateAudioReceiveStream(const std::string& sync_group) { |
1537 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 1527 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
1538 if (config_.sync_group != sync_group) { | 1528 if (config_.sync_group != sync_group) { |
1539 config_.sync_group = sync_group; | 1529 config_.sync_group = sync_group; |
1540 RecreateAudioReceiveStream(); | 1530 RecreateAudioReceiveStream(); |
1541 } | 1531 } |
(...skipping 302 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1844 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); | 1834 RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); |
1845 | 1835 |
1846 // Set the payload types to be used for incoming media. | 1836 // Set the payload types to be used for incoming media. |
1847 LOG(LS_INFO) << "Setting receive voice codecs."; | 1837 LOG(LS_INFO) << "Setting receive voice codecs."; |
1848 | 1838 |
1849 if (!VerifyUniquePayloadTypes(codecs)) { | 1839 if (!VerifyUniquePayloadTypes(codecs)) { |
1850 LOG(LS_ERROR) << "Codec payload types overlap."; | 1840 LOG(LS_ERROR) << "Codec payload types overlap."; |
1851 return false; | 1841 return false; |
1852 } | 1842 } |
1853 | 1843 |
1854 std::vector<AudioCodec> new_codecs; | |
1855 // Find all new codecs. We allow adding new codecs but don't allow changing | |
1856 // the payload type of codecs that is already configured since we might | |
1857 // already be receiving packets with that payload type. | |
1858 for (const AudioCodec& codec : codecs) { | |
1859 AudioCodec old_codec; | |
1860 // TODO(solenberg): This isn't strictly correct. It should be possible to | |
1861 // add an additional payload type for a codec. That would result in a new | |
1862 // decoder object being allocated. What shouldn't work is to remove a PT | |
1863 // mapping that was previously configured. | |
1864 if (FindCodec(recv_codecs_, codec, &old_codec)) { | |
1865 if (old_codec.id != codec.id) { | |
1866 LOG(LS_ERROR) << codec.name << " payload type changed."; | |
1867 return false; | |
1868 } | |
1869 } else { | |
1870 new_codecs.push_back(codec); | |
1871 } | |
1872 } | |
1873 if (new_codecs.empty()) { | |
1874 // There are no new codecs to configure. Already configured codecs are | |
1875 // never removed. | |
1876 return true; | |
1877 } | |
1878 | |
1879 // Create a payload type -> SdpAudioFormat map with all the decoders. Fail | 1844 // Create a payload type -> SdpAudioFormat map with all the decoders. Fail |
1880 // unless the factory claims to support all decoders. | 1845 // unless the factory claims to support all decoders. |
1881 std::map<int, webrtc::SdpAudioFormat> decoder_map; | 1846 std::map<int, webrtc::SdpAudioFormat> decoder_map; |
1882 for (const AudioCodec& codec : codecs) { | 1847 for (const AudioCodec& codec : codecs) { |
1848 // Log a warning if a codec's payload type is changing. This used to be | |
1849 // treated as an error. It's abnormal, but not really illegal. | |
1850 AudioCodec old_codec; | |
1851 if (FindCodec(recv_codecs_, codec, &old_codec) && | |
1852 old_codec.id != codec.id) { | |
1853 LOG(LS_WARNING) << codec.name << " payload type changed."; | |
the sun
2017/04/26 07:44:10
Logging the previous and current PTs would probabl
Taylor Brandstetter
2017/04/26 23:04:40
That was suggested by Karl too; done.
| |
1854 } | |
1883 auto format = AudioCodecToSdpAudioFormat(codec); | 1855 auto format = AudioCodecToSdpAudioFormat(codec); |
1884 if (!IsCodec(codec, "cn") && !IsCodec(codec, "telephone-event") && | 1856 if (!IsCodec(codec, "cn") && !IsCodec(codec, "telephone-event") && |
1885 !engine()->decoder_factory_->IsSupportedDecoder(format)) { | 1857 !engine()->decoder_factory_->IsSupportedDecoder(format)) { |
1886 LOG(LS_ERROR) << "Unsupported codec: " << format; | 1858 LOG(LS_ERROR) << "Unsupported codec: " << format; |
1887 return false; | 1859 return false; |
1888 } | 1860 } |
1861 // We allow adding new codecs but don't allow changing the payload type of | |
1862 // codecs that are already configured since we might already be receiving | |
1863 // packets with that payload type. See RFC3264, Section 8.3.2. | |
1864 // TODO(deadbeef): Also need to check for clashes with previously mapped | |
1865 // payload types, and not just currently mapped ones. For example, this | |
1866 // should be illegal: | |
1867 // 1. {100: opus/48000/2, 101: ISAC/16000} | |
1868 // 2. {100: opus/48000/2} | |
1869 // 3. {100: opus/48000/2, 101: ISAC/32000} | |
1870 // Though this check really should happen at a higher level, since this | |
the sun
2017/04/26 07:44:10
Would that mean that all validation at this level
Taylor Brandstetter
2017/04/26 23:04:40
That's the approach I had in mind. We should only
| |
1871 // conflict could happen between audio and video codecs. | |
1872 auto existing = decoder_map_.find(codec.id); | |
1873 if (existing != decoder_map_.end() && !existing->second.Matches(format)) { | |
1874 LOG(LS_ERROR) << "Attempting to use payload type " << codec.id << " for " | |
1875 << codec.name << ", but it is already used for " | |
1876 << existing->second.name; | |
1877 return false; | |
1878 } | |
1889 decoder_map.insert({codec.id, std::move(format)}); | 1879 decoder_map.insert({codec.id, std::move(format)}); |
1890 } | 1880 } |
1891 | 1881 |
1882 if (decoder_map == decoder_map_) { | |
1883 // There's nothing new to configure. | |
1884 return true; | |
1885 } | |
1886 | |
1892 if (playout_) { | 1887 if (playout_) { |
1893 // Receive codecs can not be changed while playing. So we temporarily | 1888 // Receive codecs can not be changed while playing. So we temporarily |
1894 // pause playout. | 1889 // pause playout. |
1895 ChangePlayout(false); | 1890 ChangePlayout(false); |
1896 } | 1891 } |
1897 | 1892 |
1898 decoder_map_ = std::move(decoder_map); | 1893 decoder_map_ = std::move(decoder_map); |
1899 for (auto& kv : recv_streams_) { | 1894 for (auto& kv : recv_streams_) { |
1900 kv.second->RecreateAudioReceiveStream(decoder_map_); | 1895 kv.second->RecreateAudioReceiveStream(decoder_map_); |
1901 } | 1896 } |
(...skipping 762 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2664 ssrc); | 2659 ssrc); |
2665 if (it != unsignaled_recv_ssrcs_.end()) { | 2660 if (it != unsignaled_recv_ssrcs_.end()) { |
2666 unsignaled_recv_ssrcs_.erase(it); | 2661 unsignaled_recv_ssrcs_.erase(it); |
2667 return true; | 2662 return true; |
2668 } | 2663 } |
2669 return false; | 2664 return false; |
2670 } | 2665 } |
2671 } // namespace cricket | 2666 } // namespace cricket |
2672 | 2667 |
2673 #endif // HAVE_WEBRTC_VOICE | 2668 #endif // HAVE_WEBRTC_VOICE |
OLD | NEW |