Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(203)

Side by Side Diff: webrtc/media/engine/webrtcvoiceengine.cc

Issue 2831333002: Allow a received audio codec's payload type to change. (Closed)
Patch Set: Simplifying code, adding comments. Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698