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 << " mapped to a second payload type (" |
| 1854 << codec.id << ", was already mapped to " << old_codec.id |
| 1855 << ")"; |
| 1856 } |
1883 auto format = AudioCodecToSdpAudioFormat(codec); | 1857 auto format = AudioCodecToSdpAudioFormat(codec); |
1884 if (!IsCodec(codec, "cn") && !IsCodec(codec, "telephone-event") && | 1858 if (!IsCodec(codec, "cn") && !IsCodec(codec, "telephone-event") && |
1885 !engine()->decoder_factory_->IsSupportedDecoder(format)) { | 1859 !engine()->decoder_factory_->IsSupportedDecoder(format)) { |
1886 LOG(LS_ERROR) << "Unsupported codec: " << format; | 1860 LOG(LS_ERROR) << "Unsupported codec: " << format; |
1887 return false; | 1861 return false; |
1888 } | 1862 } |
| 1863 // We allow adding new codecs but don't allow changing the payload type of |
| 1864 // codecs that are already configured since we might already be receiving |
| 1865 // packets with that payload type. See RFC3264, Section 8.3.2. |
| 1866 // TODO(deadbeef): Also need to check for clashes with previously mapped |
| 1867 // payload types, and not just currently mapped ones. For example, this |
| 1868 // should be illegal: |
| 1869 // 1. {100: opus/48000/2, 101: ISAC/16000} |
| 1870 // 2. {100: opus/48000/2} |
| 1871 // 3. {100: opus/48000/2, 101: ISAC/32000} |
| 1872 // Though this check really should happen at a higher level, since this |
| 1873 // conflict could happen between audio and video codecs. |
| 1874 auto existing = decoder_map_.find(codec.id); |
| 1875 if (existing != decoder_map_.end() && !existing->second.Matches(format)) { |
| 1876 LOG(LS_ERROR) << "Attempting to use payload type " << codec.id << " for " |
| 1877 << codec.name << ", but it is already used for " |
| 1878 << existing->second.name; |
| 1879 return false; |
| 1880 } |
1889 decoder_map.insert({codec.id, std::move(format)}); | 1881 decoder_map.insert({codec.id, std::move(format)}); |
1890 } | 1882 } |
1891 | 1883 |
| 1884 if (decoder_map == decoder_map_) { |
| 1885 // There's nothing new to configure. |
| 1886 return true; |
| 1887 } |
| 1888 |
1892 if (playout_) { | 1889 if (playout_) { |
1893 // Receive codecs can not be changed while playing. So we temporarily | 1890 // Receive codecs can not be changed while playing. So we temporarily |
1894 // pause playout. | 1891 // pause playout. |
1895 ChangePlayout(false); | 1892 ChangePlayout(false); |
1896 } | 1893 } |
1897 | 1894 |
1898 decoder_map_ = std::move(decoder_map); | 1895 decoder_map_ = std::move(decoder_map); |
1899 for (auto& kv : recv_streams_) { | 1896 for (auto& kv : recv_streams_) { |
1900 kv.second->RecreateAudioReceiveStream(decoder_map_); | 1897 kv.second->RecreateAudioReceiveStream(decoder_map_); |
1901 } | 1898 } |
(...skipping 762 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2664 ssrc); | 2661 ssrc); |
2665 if (it != unsignaled_recv_ssrcs_.end()) { | 2662 if (it != unsignaled_recv_ssrcs_.end()) { |
2666 unsignaled_recv_ssrcs_.erase(it); | 2663 unsignaled_recv_ssrcs_.erase(it); |
2667 return true; | 2664 return true; |
2668 } | 2665 } |
2669 return false; | 2666 return false; |
2670 } | 2667 } |
2671 } // namespace cricket | 2668 } // namespace cricket |
2672 | 2669 |
2673 #endif // HAVE_WEBRTC_VOICE | 2670 #endif // HAVE_WEBRTC_VOICE |
OLD | NEW |