rtp_header_extension_map.cc (6121B)
1 /* 2 * Copyright (c) 2012 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 "modules/rtp_rtcp/include/rtp_header_extension_map.h" 12 13 #include <cstdint> 14 15 #include "absl/strings/string_view.h" 16 #include "api/array_view.h" 17 #include "api/rtp_parameters.h" 18 #include "modules/rtp_rtcp/include/rtp_rtcp_defines.h" 19 #include "modules/rtp_rtcp/source/corruption_detection_extension.h" 20 #include "modules/rtp_rtcp/source/rtp_dependency_descriptor_extension.h" 21 #include "modules/rtp_rtcp/source/rtp_generic_frame_descriptor_extension.h" 22 #include "modules/rtp_rtcp/source/rtp_header_extensions.h" 23 #include "modules/rtp_rtcp/source/rtp_video_layers_allocation_extension.h" 24 #include "rtc_base/checks.h" 25 #include "rtc_base/logging.h" 26 27 namespace webrtc { 28 namespace { 29 30 struct ExtensionInfo { 31 RTPExtensionType type; 32 absl::string_view uri; 33 }; 34 35 template <typename Extension> 36 constexpr ExtensionInfo CreateExtensionInfo() { 37 return {Extension::kId, Extension::Uri()}; 38 } 39 40 constexpr ExtensionInfo kExtensions[] = { 41 CreateExtensionInfo<TransmissionOffset>(), 42 CreateExtensionInfo<AudioLevelExtension>(), 43 CreateExtensionInfo<CsrcAudioLevel>(), 44 CreateExtensionInfo<AbsoluteSendTime>(), 45 CreateExtensionInfo<AbsoluteCaptureTimeExtension>(), 46 CreateExtensionInfo<VideoOrientation>(), 47 CreateExtensionInfo<TransportSequenceNumber>(), 48 CreateExtensionInfo<TransportSequenceNumberV2>(), 49 CreateExtensionInfo<PlayoutDelayLimits>(), 50 CreateExtensionInfo<VideoContentTypeExtension>(), 51 CreateExtensionInfo<RtpVideoLayersAllocationExtension>(), 52 CreateExtensionInfo<VideoTimingExtension>(), 53 CreateExtensionInfo<RtpStreamId>(), 54 CreateExtensionInfo<RepairedRtpStreamId>(), 55 CreateExtensionInfo<RtpMid>(), 56 CreateExtensionInfo<RtpGenericFrameDescriptorExtension00>(), 57 CreateExtensionInfo<RtpDependencyDescriptorExtension>(), 58 CreateExtensionInfo<ColorSpaceExtension>(), 59 CreateExtensionInfo<InbandComfortNoiseExtension>(), 60 CreateExtensionInfo<VideoFrameTrackingIdExtension>(), 61 CreateExtensionInfo<CorruptionDetectionExtension>(), 62 }; 63 64 // Because of kRtpExtensionNone, NumberOfExtension is 1 bigger than the actual 65 // number of known extensions. 66 static_assert(std::ssize(kExtensions) == 67 static_cast<int>(kRtpExtensionNumberOfExtensions) - 1, 68 "kExtensions expect to list all known extensions"); 69 70 } // namespace 71 72 RtpHeaderExtensionMap::RtpHeaderExtensionMap() : RtpHeaderExtensionMap(false) {} 73 74 RtpHeaderExtensionMap::RtpHeaderExtensionMap(bool extmap_allow_mixed) 75 : extmap_allow_mixed_(extmap_allow_mixed) { 76 for (auto& id : ids_) 77 id = kInvalidId; 78 } 79 80 RtpHeaderExtensionMap::RtpHeaderExtensionMap( 81 ArrayView<const RtpExtension> extensions) 82 : RtpHeaderExtensionMap(false) { 83 for (const RtpExtension& extension : extensions) 84 RegisterByUri(extension.id, extension.uri); 85 } 86 87 void RtpHeaderExtensionMap::Reset(ArrayView<const RtpExtension> extensions) { 88 for (auto& id : ids_) 89 id = kInvalidId; 90 for (const RtpExtension& extension : extensions) 91 RegisterByUri(extension.id, extension.uri); 92 } 93 94 bool RtpHeaderExtensionMap::RegisterByType(int id, RTPExtensionType type) { 95 for (const ExtensionInfo& extension : kExtensions) 96 if (type == extension.type) 97 return Register(id, extension.type, extension.uri); 98 RTC_DCHECK_NOTREACHED(); 99 return false; 100 } 101 102 bool RtpHeaderExtensionMap::RegisterByUri(int id, absl::string_view uri) { 103 for (const ExtensionInfo& extension : kExtensions) 104 if (uri == extension.uri) 105 return Register(id, extension.type, extension.uri); 106 RTC_LOG(LS_WARNING) << "Unknown extension uri:'" << uri << "', id: " << id 107 << '.'; 108 return false; 109 } 110 111 RTPExtensionType RtpHeaderExtensionMap::GetType(int id) const { 112 RTC_DCHECK_GE(id, RtpExtension::kMinId); 113 RTC_DCHECK_LE(id, RtpExtension::kMaxId); 114 for (int type = kRtpExtensionNone + 1; type < kRtpExtensionNumberOfExtensions; 115 ++type) { 116 if (ids_[type] == id) { 117 return static_cast<RTPExtensionType>(type); 118 } 119 } 120 return kInvalidType; 121 } 122 123 void RtpHeaderExtensionMap::Deregister(absl::string_view uri) { 124 for (const ExtensionInfo& extension : kExtensions) { 125 if (extension.uri == uri) { 126 ids_[extension.type] = kInvalidId; 127 break; 128 } 129 } 130 } 131 132 bool RtpHeaderExtensionMap::Register(int id, 133 RTPExtensionType type, 134 absl::string_view uri) { 135 RTC_DCHECK_GT(type, kRtpExtensionNone); 136 RTC_DCHECK_LT(type, kRtpExtensionNumberOfExtensions); 137 138 if (id < RtpExtension::kMinId || id > RtpExtension::kMaxId) { 139 RTC_LOG(LS_WARNING) << "Failed to register extension uri:'" << uri 140 << "' with invalid id:" << id << "."; 141 return false; 142 } 143 144 RTPExtensionType registered_type = GetType(id); 145 if (registered_type == type) { // Same type/id pair already registered. 146 RTC_LOG(LS_VERBOSE) << "Reregistering extension uri:'" << uri 147 << "', id:" << id; 148 return true; 149 } 150 151 if (registered_type != 152 kInvalidType) { // `id` used by another extension type. 153 RTC_LOG(LS_WARNING) << "Failed to register extension uri:'" << uri 154 << "', id:" << id 155 << ". Id already in use by extension type " 156 << static_cast<int>(registered_type); 157 return false; 158 } 159 if (IsRegistered(type)) { 160 RTC_LOG(LS_WARNING) << "Illegal reregistration for uri: " << uri 161 << " is previously registered with id " << GetId(type) 162 << " and cannot be reregistered with id " << id; 163 return false; 164 } 165 166 // There is a run-time check above id fits into uint8_t. 167 ids_[type] = static_cast<uint8_t>(id); 168 return true; 169 } 170 171 } // namespace webrtc