codec_list.cc (4489B)
1 /* 2 * Copyright (c) 2024 The WebRTC project authors. All Rights Reserved. 3 * 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 6 * tree. An additional intellectual property rights grant can be found 7 * in the file PATENTS. All contributing project authors may 8 * be found in the AUTHORS file in the root of the source tree. 9 */ 10 11 #include "media/base/codec_list.h" 12 13 #include <cstddef> 14 #include <map> 15 #include <vector> 16 17 #include "api/rtc_error.h" 18 #include "media/base/codec.h" 19 #include "media/base/media_constants.h" 20 #include "rtc_base/checks.h" 21 #include "rtc_base/logging.h" 22 #include "rtc_base/string_encode.h" 23 24 namespace webrtc { 25 26 27 namespace { 28 29 RTCError CheckInputConsistency(const std::vector<Codec>& codecs) { 30 std::map<int, int> pt_to_index; 31 // Create a map of payload type to index, and ensure 32 // that there are no duplicates. 33 for (size_t i = 0; i < codecs.size(); i++) { 34 const Codec& codec = codecs[i]; 35 if (codec.id != Codec::kIdNotSet) { 36 auto [it, success] = pt_to_index.insert({codec.id, i}); 37 if (!success) { 38 RTC_LOG(LS_ERROR) << "Duplicate payload type in codec list, " << codec 39 << " and " << codecs[it->second] 40 << " have the same ID"; 41 LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER, 42 "Duplicate payload type in codec list"); 43 } 44 } 45 } 46 for (const Codec& codec : codecs) { 47 switch (codec.GetResiliencyType()) { 48 case Codec::ResiliencyType::kRed: 49 // Check that the target codec exists 50 break; 51 case Codec::ResiliencyType::kRtx: { 52 // Check that the target codec exists 53 const auto apt_it = codec.params.find(kCodecParamAssociatedPayloadType); 54 // Not true - there's a test that deliberately injects a wrong 55 // RTX codec (MediaSessionDescriptionFactoryTest.RtxWithoutApt) 56 // TODO: https://issues.webrtc.org/384756622 - reject codec earlier and 57 // enable check. RTC_DCHECK(apt_it != codec.params.end()); Until that is 58 // fixed: 59 if (codec.id == Codec::kIdNotSet) { 60 // Should not have an apt parameter. 61 if (apt_it != codec.params.end()) { 62 RTC_LOG(LS_WARNING) << "Surprising condition: RTX codec without " 63 << "PT has an apt parameter"; 64 } 65 // Stop checking the associated PT. 66 break; 67 } 68 if (apt_it == codec.params.end()) { 69 RTC_LOG(LS_WARNING) << "Surprising condition: RTX codec without" 70 << " apt parameter: " << codec; 71 break; 72 } 73 int associated_pt; 74 if (!(FromString(apt_it->second, &associated_pt))) { 75 RTC_LOG(LS_ERROR) << "Non-numeric argument to rtx apt: " << codec 76 << " apt=" << apt_it->second; 77 LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER, 78 "Non-numeric argument to rtx apt parameter"); 79 } 80 if (codec.id != Codec::kIdNotSet && 81 pt_to_index.count(associated_pt) != 1) { 82 RTC_LOG(LS_WARNING) 83 << "Surprising condition: RTX codec APT not found: " << codec 84 << " points to a PT that occurs " 85 << pt_to_index.count(associated_pt) << " times"; 86 LOG_AND_RETURN_ERROR( 87 RTCErrorType::INVALID_PARAMETER, 88 "PT pointed to by rtx apt parameter does not exist"); 89 } 90 // const Codec& referred_codec = codecs[pt_to_index[associated_pt]]; 91 // Not true: 92 // RTC_DCHECK(referred_codec.type == Codec::Type::kVideo); 93 // Not true: 94 // RTC_DCHECK(referred_codec.GetResiliencyType() == 95 // Codec::ResiliencyType::kNone); 96 // TODO: https://issues.webrtc.org/384756623 - figure out if this is 97 // expected or not. 98 break; 99 } 100 case Codec::ResiliencyType::kNone: 101 break; // nothing to see here 102 default: 103 break; // don't know what to check yet 104 } 105 } 106 return RTCError::OK(); 107 } 108 109 } // namespace 110 111 // static 112 RTCErrorOr<CodecList> CodecList::Create(const std::vector<Codec>& codecs) { 113 RTCError error = CheckInputConsistency(codecs); 114 if (!error.ok()) { 115 return error; 116 } 117 return CodecList(codecs); 118 } 119 120 void CodecList::CheckConsistency() { 121 RTC_DCHECK(CheckInputConsistency(codecs_).ok()); 122 } 123 124 } // namespace webrtc