rtp_parameters.cc (10241B)
1 /* 2 * Copyright (c) 2017 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 #include "api/rtp_parameters.h" 11 12 #include <algorithm> 13 #include <cstdint> 14 #include <string> 15 #include <tuple> 16 #include <vector> 17 18 #include "absl/strings/string_view.h" 19 #include "api/array_view.h" 20 #include "api/rtp_transceiver_direction.h" 21 #include "media/base/media_constants.h" 22 #include "rtc_base/checks.h" 23 #include "rtc_base/strings/string_builder.h" 24 25 namespace webrtc { 26 27 const char* DegradationPreferenceToString( 28 DegradationPreference degradation_preference) { 29 switch (degradation_preference) { 30 case DegradationPreference::DISABLED: 31 return "disabled"; 32 case DegradationPreference::MAINTAIN_FRAMERATE: 33 return "maintain-framerate"; 34 case DegradationPreference::MAINTAIN_RESOLUTION: 35 return "maintain-resolution"; 36 case DegradationPreference::BALANCED: 37 return "balanced"; 38 } 39 RTC_CHECK_NOTREACHED(); 40 } 41 42 const double kDefaultBitratePriority = 1.0; 43 44 RtcpFeedback::RtcpFeedback() = default; 45 RtcpFeedback::RtcpFeedback(RtcpFeedbackType type) : type(type) {} 46 RtcpFeedback::RtcpFeedback(RtcpFeedbackType type, 47 RtcpFeedbackMessageType message_type) 48 : type(type), message_type(message_type) {} 49 RtcpFeedback::RtcpFeedback(const RtcpFeedback& rhs) = default; 50 RtcpFeedback::~RtcpFeedback() = default; 51 52 RtpCodec::RtpCodec() = default; 53 RtpCodec::RtpCodec(const RtpCodec&) = default; 54 RtpCodec::~RtpCodec() = default; 55 bool RtpCodec::IsResiliencyCodec() const { 56 return name == kRtxCodecName || name == kRedCodecName || 57 name == kUlpfecCodecName || name == kFlexfecCodecName; 58 } 59 bool RtpCodec::IsMediaCodec() const { 60 return !IsResiliencyCodec() && name != kComfortNoiseCodecName; 61 } 62 RtpCodecCapability::RtpCodecCapability() = default; 63 RtpCodecCapability::~RtpCodecCapability() = default; 64 65 RtpHeaderExtensionCapability::RtpHeaderExtensionCapability() = default; 66 RtpHeaderExtensionCapability::RtpHeaderExtensionCapability( 67 absl::string_view uri) 68 : uri(uri) {} 69 RtpHeaderExtensionCapability::RtpHeaderExtensionCapability( 70 absl::string_view uri, 71 int preferred_id) 72 : uri(uri), preferred_id(preferred_id) {} 73 RtpHeaderExtensionCapability::RtpHeaderExtensionCapability( 74 absl::string_view uri, 75 int preferred_id, 76 RtpTransceiverDirection direction) 77 : uri(uri), preferred_id(preferred_id), direction(direction) {} 78 RtpHeaderExtensionCapability::RtpHeaderExtensionCapability( 79 absl::string_view uri, 80 int preferred_id, 81 bool preferred_encrypt, 82 RtpTransceiverDirection direction) 83 : uri(uri), 84 preferred_id(preferred_id), 85 preferred_encrypt(preferred_encrypt), 86 direction(direction) {} 87 RtpHeaderExtensionCapability::~RtpHeaderExtensionCapability() = default; 88 89 RtpExtension::RtpExtension() = default; 90 RtpExtension::RtpExtension(absl::string_view uri, int id) : uri(uri), id(id) {} 91 RtpExtension::RtpExtension(absl::string_view uri, int id, bool encrypt) 92 : uri(uri), id(id), encrypt(encrypt) {} 93 RtpExtension::~RtpExtension() = default; 94 95 RtpFecParameters::RtpFecParameters() = default; 96 RtpFecParameters::RtpFecParameters(FecMechanism mechanism) 97 : mechanism(mechanism) {} 98 RtpFecParameters::RtpFecParameters(FecMechanism mechanism, uint32_t ssrc) 99 : ssrc(ssrc), mechanism(mechanism) {} 100 RtpFecParameters::RtpFecParameters(const RtpFecParameters& rhs) = default; 101 RtpFecParameters::~RtpFecParameters() = default; 102 103 RtpRtxParameters::RtpRtxParameters() = default; 104 RtpRtxParameters::RtpRtxParameters(uint32_t ssrc) : ssrc(ssrc) {} 105 RtpRtxParameters::RtpRtxParameters(const RtpRtxParameters& rhs) = default; 106 RtpRtxParameters::~RtpRtxParameters() = default; 107 108 RtpEncodingParameters::RtpEncodingParameters() = default; 109 RtpEncodingParameters::RtpEncodingParameters(const RtpEncodingParameters& rhs) = 110 default; 111 RtpEncodingParameters::~RtpEncodingParameters() = default; 112 113 RtpCodecParameters::RtpCodecParameters() = default; 114 RtpCodecParameters::RtpCodecParameters(const RtpCodecParameters& rhs) = default; 115 RtpCodecParameters::~RtpCodecParameters() = default; 116 117 RtpCapabilities::RtpCapabilities() = default; 118 RtpCapabilities::~RtpCapabilities() = default; 119 120 RtcpParameters::RtcpParameters() = default; 121 RtcpParameters::RtcpParameters(const RtcpParameters& rhs) = default; 122 RtcpParameters::~RtcpParameters() = default; 123 124 RtpParameters::RtpParameters() = default; 125 RtpParameters::RtpParameters(const RtpParameters& rhs) = default; 126 RtpParameters::~RtpParameters() = default; 127 128 std::string RtpExtension::ToString() const { 129 char buf[256]; 130 SimpleStringBuilder sb(buf); 131 sb << "{uri: " << uri; 132 sb << ", id: " << id; 133 if (encrypt) { 134 sb << ", encrypt"; 135 } 136 sb << '}'; 137 return sb.str(); 138 } 139 140 bool RtpExtension::IsSupportedForAudio(absl::string_view uri) { 141 return uri == RtpExtension::kAudioLevelUri || 142 uri == RtpExtension::kAbsSendTimeUri || 143 uri == RtpExtension::kAbsoluteCaptureTimeUri || 144 uri == RtpExtension::kTransportSequenceNumberUri || 145 uri == RtpExtension::kTransportSequenceNumberV2Uri || 146 uri == RtpExtension::kMidUri || uri == RtpExtension::kRidUri || 147 uri == RtpExtension::kRepairedRidUri || 148 uri == RtpExtension::kCsrcAudioLevelsUri; 149 } 150 151 bool RtpExtension::IsSupportedForVideo(absl::string_view uri) { 152 return uri == RtpExtension::kTimestampOffsetUri || 153 uri == RtpExtension::kAbsSendTimeUri || 154 uri == RtpExtension::kAbsoluteCaptureTimeUri || 155 uri == RtpExtension::kVideoRotationUri || 156 uri == RtpExtension::kTransportSequenceNumberUri || 157 uri == RtpExtension::kTransportSequenceNumberV2Uri || 158 uri == RtpExtension::kPlayoutDelayUri || 159 uri == RtpExtension::kVideoContentTypeUri || 160 uri == RtpExtension::kVideoTimingUri || uri == RtpExtension::kMidUri || 161 uri == RtpExtension::kGenericFrameDescriptorUri00 || 162 uri == RtpExtension::kDependencyDescriptorUri || 163 uri == RtpExtension::kColorSpaceUri || uri == RtpExtension::kRidUri || 164 uri == RtpExtension::kRepairedRidUri || 165 uri == RtpExtension::kVideoLayersAllocationUri || 166 uri == RtpExtension::kVideoFrameTrackingIdUri || 167 uri == RtpExtension::kCorruptionDetectionUri; 168 } 169 170 bool RtpExtension::IsEncryptionSupported(absl::string_view uri) { 171 return 172 #if defined(ENABLE_EXTERNAL_AUTH) 173 // TODO(jbauch): Figure out a way to always allow "kAbsSendTimeUri" 174 // here and filter out later if external auth is really used in 175 // srtpfilter. External auth is used by Chromium and replaces the 176 // extension header value of "kAbsSendTimeUri", so it must not be 177 // encrypted (which can't be done by Chromium). 178 uri != RtpExtension::kAbsSendTimeUri && 179 #endif 180 uri != RtpExtension::kEncryptHeaderExtensionsUri; 181 } 182 183 // Returns whether a header extension with the given URI exists. 184 // Note: This does not differentiate between encrypted and non-encrypted 185 // extensions, so use with care! 186 static bool HeaderExtensionWithUriExists( 187 const std::vector<RtpExtension>& extensions, 188 absl::string_view uri) { 189 for (const auto& extension : extensions) { 190 if (extension.uri == uri) { 191 return true; 192 } 193 } 194 return false; 195 } 196 197 const RtpExtension* RtpExtension::FindHeaderExtensionByUri( 198 const std::vector<RtpExtension>& extensions, 199 absl::string_view uri, 200 Filter filter) { 201 const RtpExtension* fallback_extension = nullptr; 202 for (const auto& extension : extensions) { 203 if (extension.uri != uri) { 204 continue; 205 } 206 207 switch (filter) { 208 case kDiscardEncryptedExtension: 209 // We only accept an unencrypted extension. 210 if (!extension.encrypt) { 211 return &extension; 212 } 213 break; 214 215 case kPreferEncryptedExtension: 216 // We prefer an encrypted extension but we can fall back to an 217 // unencrypted extension. 218 if (extension.encrypt) { 219 return &extension; 220 } else { 221 fallback_extension = &extension; 222 } 223 break; 224 225 case kRequireEncryptedExtension: 226 // We only accept an encrypted extension. 227 if (extension.encrypt) { 228 return &extension; 229 } 230 break; 231 } 232 } 233 234 // Returning fallback extension (if any) 235 return fallback_extension; 236 } 237 238 const RtpExtension* RtpExtension::FindHeaderExtensionByUriAndEncryption( 239 const std::vector<RtpExtension>& extensions, 240 absl::string_view uri, 241 bool encrypt) { 242 for (const auto& extension : extensions) { 243 if (extension.uri == uri && extension.encrypt == encrypt) { 244 return &extension; 245 } 246 } 247 return nullptr; 248 } 249 250 const std::vector<RtpExtension> RtpExtension::DeduplicateHeaderExtensions( 251 const std::vector<RtpExtension>& extensions, 252 Filter filter) { 253 std::vector<RtpExtension> filtered; 254 255 // If we do not discard encrypted extensions, add them first 256 if (filter != kDiscardEncryptedExtension) { 257 for (const auto& extension : extensions) { 258 if (!extension.encrypt) { 259 continue; 260 } 261 if (!HeaderExtensionWithUriExists(filtered, extension.uri)) { 262 filtered.push_back(extension); 263 } 264 } 265 } 266 267 // If we do not require encrypted extensions, add missing, non-encrypted 268 // extensions. 269 if (filter != kRequireEncryptedExtension) { 270 for (const auto& extension : extensions) { 271 if (extension.encrypt) { 272 continue; 273 } 274 if (!HeaderExtensionWithUriExists(filtered, extension.uri)) { 275 filtered.push_back(extension); 276 } 277 } 278 } 279 280 // Sort the returned vector to make comparisons of header extensions reliable. 281 // In order of priority, we sort by uri first, then encrypt and id last. 282 std::sort(filtered.begin(), filtered.end(), 283 [](const RtpExtension& a, const RtpExtension& b) { 284 return std::tie(a.uri, a.encrypt, a.id) < 285 std::tie(b.uri, b.encrypt, b.id); 286 }); 287 288 return filtered; 289 } 290 } // namespace webrtc