blob: 54132bcdbbcc833522131d9baf7696769b9d82fe [file] [log] [blame]
Stefan Holmer1acbd682017-09-01 13:29:281/*
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 */
Steve Anton10542f22019-01-11 17:11:0010#include "api/rtp_parameters.h"
Stefan Holmer1acbd682017-09-01 13:29:2811
12#include <algorithm>
Stefan Holmer1acbd682017-09-01 13:29:2813#include <string>
Tomas Gunnarssonc69453d2022-01-06 12:36:0414#include <tuple>
Markus Handelldfeb0df2020-03-16 21:20:4715#include <utility>
Stefan Holmer1acbd682017-09-01 13:29:2816
Yves Gerey988cc082018-10-23 10:03:0117#include "api/array_view.h"
Jonas Olsson866d6dc2018-05-14 15:30:2218#include "rtc_base/strings/string_builder.h"
Stefan Holmer1acbd682017-09-01 13:29:2819
20namespace webrtc {
21
Henrik Boströmf0eef122020-05-28 14:22:4222const char* DegradationPreferenceToString(
23 DegradationPreference degradation_preference) {
24 switch (degradation_preference) {
25 case DegradationPreference::DISABLED:
26 return "disabled";
27 case DegradationPreference::MAINTAIN_FRAMERATE:
28 return "maintain-framerate";
29 case DegradationPreference::MAINTAIN_RESOLUTION:
30 return "maintain-resolution";
31 case DegradationPreference::BALANCED:
32 return "balanced";
33 }
Karl Wibergc95b9392020-11-07 23:49:3734 RTC_CHECK_NOTREACHED();
Henrik Boströmf0eef122020-05-28 14:22:4235}
36
Seth Hampsonf32795e2017-12-19 19:37:4137const double kDefaultBitratePriority = 1.0;
38
Mirko Bonadei2ffed6d2018-07-20 09:09:3239RtcpFeedback::RtcpFeedback() = default;
Stefan Holmer1acbd682017-09-01 13:29:2840RtcpFeedback::RtcpFeedback(RtcpFeedbackType type) : type(type) {}
41RtcpFeedback::RtcpFeedback(RtcpFeedbackType type,
42 RtcpFeedbackMessageType message_type)
43 : type(type), message_type(message_type) {}
Mirko Bonadei2ffed6d2018-07-20 09:09:3244RtcpFeedback::RtcpFeedback(const RtcpFeedback& rhs) = default;
45RtcpFeedback::~RtcpFeedback() = default;
Stefan Holmer1acbd682017-09-01 13:29:2846
Florent Castelli0a4a9842023-04-03 17:25:2947RtpCodec::RtpCodec() = default;
48RtpCodec::RtpCodec(const RtpCodec&) = default;
49RtpCodec::~RtpCodec() = default;
Mirko Bonadei2ffed6d2018-07-20 09:09:3250RtpCodecCapability::RtpCodecCapability() = default;
51RtpCodecCapability::~RtpCodecCapability() = default;
Stefan Holmer1acbd682017-09-01 13:29:2852
Mirko Bonadei2ffed6d2018-07-20 09:09:3253RtpHeaderExtensionCapability::RtpHeaderExtensionCapability() = default;
Stefan Holmer1acbd682017-09-01 13:29:2854RtpHeaderExtensionCapability::RtpHeaderExtensionCapability(
Danil Chapovalov2b4ec9e2020-03-25 16:23:3755 absl::string_view uri)
56 : uri(uri) {}
57RtpHeaderExtensionCapability::RtpHeaderExtensionCapability(
58 absl::string_view uri,
59 int preferred_id)
60 : uri(uri), preferred_id(preferred_id) {}
61RtpHeaderExtensionCapability::RtpHeaderExtensionCapability(
62 absl::string_view uri,
Markus Handell0357b3e2020-03-16 12:40:5163 int preferred_id,
64 RtpTransceiverDirection direction)
Danil Chapovalov2b4ec9e2020-03-25 16:23:3765 : uri(uri), preferred_id(preferred_id), direction(direction) {}
Mirko Bonadei2ffed6d2018-07-20 09:09:3266RtpHeaderExtensionCapability::~RtpHeaderExtensionCapability() = default;
Stefan Holmer1acbd682017-09-01 13:29:2867
Mirko Bonadei2ffed6d2018-07-20 09:09:3268RtpExtension::RtpExtension() = default;
Danil Chapovalov2b4ec9e2020-03-25 16:23:3769RtpExtension::RtpExtension(absl::string_view uri, int id) : uri(uri), id(id) {}
70RtpExtension::RtpExtension(absl::string_view uri, int id, bool encrypt)
71 : uri(uri), id(id), encrypt(encrypt) {}
Mirko Bonadei2ffed6d2018-07-20 09:09:3272RtpExtension::~RtpExtension() = default;
Stefan Holmer1acbd682017-09-01 13:29:2873
Mirko Bonadei2ffed6d2018-07-20 09:09:3274RtpFecParameters::RtpFecParameters() = default;
Stefan Holmer1acbd682017-09-01 13:29:2875RtpFecParameters::RtpFecParameters(FecMechanism mechanism)
76 : mechanism(mechanism) {}
77RtpFecParameters::RtpFecParameters(FecMechanism mechanism, uint32_t ssrc)
78 : ssrc(ssrc), mechanism(mechanism) {}
Mirko Bonadei2ffed6d2018-07-20 09:09:3279RtpFecParameters::RtpFecParameters(const RtpFecParameters& rhs) = default;
80RtpFecParameters::~RtpFecParameters() = default;
Stefan Holmer1acbd682017-09-01 13:29:2881
Mirko Bonadei2ffed6d2018-07-20 09:09:3282RtpRtxParameters::RtpRtxParameters() = default;
Stefan Holmer1acbd682017-09-01 13:29:2883RtpRtxParameters::RtpRtxParameters(uint32_t ssrc) : ssrc(ssrc) {}
Mirko Bonadei2ffed6d2018-07-20 09:09:3284RtpRtxParameters::RtpRtxParameters(const RtpRtxParameters& rhs) = default;
85RtpRtxParameters::~RtpRtxParameters() = default;
Stefan Holmer1acbd682017-09-01 13:29:2886
Mirko Bonadei2ffed6d2018-07-20 09:09:3287RtpEncodingParameters::RtpEncodingParameters() = default;
88RtpEncodingParameters::RtpEncodingParameters(const RtpEncodingParameters& rhs) =
89 default;
90RtpEncodingParameters::~RtpEncodingParameters() = default;
Stefan Holmer1acbd682017-09-01 13:29:2891
Mirko Bonadei2ffed6d2018-07-20 09:09:3292RtpCodecParameters::RtpCodecParameters() = default;
93RtpCodecParameters::RtpCodecParameters(const RtpCodecParameters& rhs) = default;
94RtpCodecParameters::~RtpCodecParameters() = default;
Stefan Holmer1acbd682017-09-01 13:29:2895
Mirko Bonadei2ffed6d2018-07-20 09:09:3296RtpCapabilities::RtpCapabilities() = default;
97RtpCapabilities::~RtpCapabilities() = default;
Stefan Holmer1acbd682017-09-01 13:29:2898
Mirko Bonadei2ffed6d2018-07-20 09:09:3299RtcpParameters::RtcpParameters() = default;
100RtcpParameters::RtcpParameters(const RtcpParameters& rhs) = default;
101RtcpParameters::~RtcpParameters() = default;
Florent Castellidacec712018-05-24 14:24:21102
Mirko Bonadei2ffed6d2018-07-20 09:09:32103RtpParameters::RtpParameters() = default;
104RtpParameters::RtpParameters(const RtpParameters& rhs) = default;
105RtpParameters::~RtpParameters() = default;
Stefan Holmer1acbd682017-09-01 13:29:28106
107std::string RtpExtension::ToString() const {
Jonas Olsson866d6dc2018-05-14 15:30:22108 char buf[256];
109 rtc::SimpleStringBuilder sb(buf);
110 sb << "{uri: " << uri;
111 sb << ", id: " << id;
Stefan Holmer1acbd682017-09-01 13:29:28112 if (encrypt) {
Jonas Olsson866d6dc2018-05-14 15:30:22113 sb << ", encrypt";
Stefan Holmer1acbd682017-09-01 13:29:28114 }
Jonas Olsson866d6dc2018-05-14 15:30:22115 sb << '}';
116 return sb.str();
Stefan Holmer1acbd682017-09-01 13:29:28117}
118
Danil Chapovalov418cfee2020-03-25 10:02:37119constexpr char RtpExtension::kEncryptHeaderExtensionsUri[];
120constexpr char RtpExtension::kAudioLevelUri[];
121constexpr char RtpExtension::kTimestampOffsetUri[];
122constexpr char RtpExtension::kAbsSendTimeUri[];
123constexpr char RtpExtension::kAbsoluteCaptureTimeUri[];
124constexpr char RtpExtension::kVideoRotationUri[];
125constexpr char RtpExtension::kVideoContentTypeUri[];
126constexpr char RtpExtension::kVideoTimingUri[];
Danil Chapovalov418cfee2020-03-25 10:02:37127constexpr char RtpExtension::kGenericFrameDescriptorUri00[];
Danil Chapovalov418cfee2020-03-25 10:02:37128constexpr char RtpExtension::kDependencyDescriptorUri[];
Per Kjellander70c89452020-10-21 11:35:07129constexpr char RtpExtension::kVideoLayersAllocationUri[];
Danil Chapovalov418cfee2020-03-25 10:02:37130constexpr char RtpExtension::kTransportSequenceNumberUri[];
131constexpr char RtpExtension::kTransportSequenceNumberV2Uri[];
132constexpr char RtpExtension::kPlayoutDelayUri[];
133constexpr char RtpExtension::kColorSpaceUri[];
134constexpr char RtpExtension::kMidUri[];
135constexpr char RtpExtension::kRidUri[];
136constexpr char RtpExtension::kRepairedRidUri[];
Jeremy Leconteb258c562021-03-18 12:50:42137constexpr char RtpExtension::kVideoFrameTrackingIdUri[];
Danil Chapovalovd0321c52021-09-14 10:58:51138constexpr char RtpExtension::kCsrcAudioLevelsUri[];
Stefan Holmer1acbd682017-09-01 13:29:28139
Johannes Kron07ba2b92018-09-26 11:33:35140constexpr int RtpExtension::kMinId;
141constexpr int RtpExtension::kMaxId;
Johannes Kron78cdde32018-10-05 08:00:46142constexpr int RtpExtension::kMaxValueSize;
Johannes Kron07ba2b92018-09-26 11:33:35143constexpr int RtpExtension::kOneByteHeaderExtensionMaxId;
Johannes Kron78cdde32018-10-05 08:00:46144constexpr int RtpExtension::kOneByteHeaderExtensionMaxValueSize;
Stefan Holmer1acbd682017-09-01 13:29:28145
Markus Handelldfeb0df2020-03-16 21:20:47146bool RtpExtension::IsSupportedForAudio(absl::string_view uri) {
Stefan Holmer1acbd682017-09-01 13:29:28147 return uri == webrtc::RtpExtension::kAudioLevelUri ||
Sebastian Jansson46bbdec2019-07-23 18:55:49148 uri == webrtc::RtpExtension::kAbsSendTimeUri ||
Minyue Li74dadc12020-03-05 10:33:13149 uri == webrtc::RtpExtension::kAbsoluteCaptureTimeUri ||
Steve Antonbb50ce52018-03-26 17:24:32150 uri == webrtc::RtpExtension::kTransportSequenceNumberUri ||
Johannes Kronce8e8672019-02-22 12:06:44151 uri == webrtc::RtpExtension::kTransportSequenceNumberV2Uri ||
Amit Hilbuch77938e62018-12-21 17:23:38152 uri == webrtc::RtpExtension::kMidUri ||
153 uri == webrtc::RtpExtension::kRidUri ||
154 uri == webrtc::RtpExtension::kRepairedRidUri;
Stefan Holmer1acbd682017-09-01 13:29:28155}
156
Markus Handelldfeb0df2020-03-16 21:20:47157bool RtpExtension::IsSupportedForVideo(absl::string_view uri) {
Stefan Holmer1acbd682017-09-01 13:29:28158 return uri == webrtc::RtpExtension::kTimestampOffsetUri ||
159 uri == webrtc::RtpExtension::kAbsSendTimeUri ||
Minyue Li74dadc12020-03-05 10:33:13160 uri == webrtc::RtpExtension::kAbsoluteCaptureTimeUri ||
Stefan Holmer1acbd682017-09-01 13:29:28161 uri == webrtc::RtpExtension::kVideoRotationUri ||
162 uri == webrtc::RtpExtension::kTransportSequenceNumberUri ||
Johannes Kronce8e8672019-02-22 12:06:44163 uri == webrtc::RtpExtension::kTransportSequenceNumberV2Uri ||
Stefan Holmer1acbd682017-09-01 13:29:28164 uri == webrtc::RtpExtension::kPlayoutDelayUri ||
165 uri == webrtc::RtpExtension::kVideoContentTypeUri ||
Steve Antonbb50ce52018-03-26 17:24:32166 uri == webrtc::RtpExtension::kVideoTimingUri ||
Johnny Leee0c8b232018-09-11 20:50:49167 uri == webrtc::RtpExtension::kMidUri ||
Elad Alonccb9b752019-02-19 12:01:31168 uri == webrtc::RtpExtension::kGenericFrameDescriptorUri00 ||
Danil Chapovalov2272f202020-02-18 11:09:43169 uri == webrtc::RtpExtension::kDependencyDescriptorUri ||
Amit Hilbuch77938e62018-12-21 17:23:38170 uri == webrtc::RtpExtension::kColorSpaceUri ||
171 uri == webrtc::RtpExtension::kRidUri ||
Per Kjellander70c89452020-10-21 11:35:07172 uri == webrtc::RtpExtension::kRepairedRidUri ||
Jeremy Leconteb258c562021-03-18 12:50:42173 uri == webrtc::RtpExtension::kVideoLayersAllocationUri ||
174 uri == webrtc::RtpExtension::kVideoFrameTrackingIdUri;
Stefan Holmer1acbd682017-09-01 13:29:28175}
176
Markus Handelldfeb0df2020-03-16 21:20:47177bool RtpExtension::IsEncryptionSupported(absl::string_view uri) {
Lennart Grahl0d0ed762021-05-17 14:06:37178 return
179#if defined(ENABLE_EXTERNAL_AUTH)
180 // TODO(jbauch): Figure out a way to always allow "kAbsSendTimeUri"
181 // here and filter out later if external auth is really used in
182 // srtpfilter. External auth is used by Chromium and replaces the
183 // extension header value of "kAbsSendTimeUri", so it must not be
184 // encrypted (which can't be done by Chromium).
185 uri != webrtc::RtpExtension::kAbsSendTimeUri &&
Stefan Holmer1acbd682017-09-01 13:29:28186#endif
Lennart Grahl0d0ed762021-05-17 14:06:37187 uri != webrtc::RtpExtension::kEncryptHeaderExtensionsUri;
188}
189
190// Returns whether a header extension with the given URI exists.
191// Note: This does not differentiate between encrypted and non-encrypted
192// extensions, so use with care!
193static bool HeaderExtensionWithUriExists(
194 const std::vector<RtpExtension>& extensions,
195 absl::string_view uri) {
196 for (const auto& extension : extensions) {
197 if (extension.uri == uri) {
198 return true;
199 }
200 }
201 return false;
202}
203
204const RtpExtension* RtpExtension::FindHeaderExtensionByUri(
205 const std::vector<RtpExtension>& extensions,
206 absl::string_view uri,
207 Filter filter) {
208 const webrtc::RtpExtension* fallback_extension = nullptr;
209 for (const auto& extension : extensions) {
210 if (extension.uri != uri) {
211 continue;
212 }
213
214 switch (filter) {
215 case kDiscardEncryptedExtension:
216 // We only accept an unencrypted extension.
217 if (!extension.encrypt) {
218 return &extension;
219 }
220 break;
221
222 case kPreferEncryptedExtension:
223 // We prefer an encrypted extension but we can fall back to an
224 // unencrypted extension.
225 if (extension.encrypt) {
226 return &extension;
227 } else {
228 fallback_extension = &extension;
229 }
230 break;
231
232 case kRequireEncryptedExtension:
233 // We only accept an encrypted extension.
234 if (extension.encrypt) {
235 return &extension;
236 }
237 break;
238 }
239 }
240
241 // Returning fallback extension (if any)
242 return fallback_extension;
Lennart Grahla7433032021-04-09 20:05:06243}
244
Lennart Grahl0d0ed762021-05-17 14:06:37245const RtpExtension* RtpExtension::FindHeaderExtensionByUriAndEncryption(
246 const std::vector<RtpExtension>& extensions,
247 absl::string_view uri,
248 bool encrypt) {
Lennart Grahla7433032021-04-09 20:05:06249 for (const auto& extension : extensions) {
Lennart Grahl0d0ed762021-05-17 14:06:37250 if (extension.uri == uri && extension.encrypt == encrypt) {
Stefan Holmer1acbd682017-09-01 13:29:28251 return &extension;
252 }
253 }
254 return nullptr;
255}
256
Lennart Grahl0d0ed762021-05-17 14:06:37257const std::vector<RtpExtension> RtpExtension::DeduplicateHeaderExtensions(
258 const std::vector<RtpExtension>& extensions,
259 Filter filter) {
Stefan Holmer1acbd682017-09-01 13:29:28260 std::vector<RtpExtension> filtered;
Stefan Holmer1acbd682017-09-01 13:29:28261
Lennart Grahl0d0ed762021-05-17 14:06:37262 // If we do not discard encrypted extensions, add them first
263 if (filter != kDiscardEncryptedExtension) {
264 for (const auto& extension : extensions) {
265 if (!extension.encrypt) {
266 continue;
267 }
268 if (!HeaderExtensionWithUriExists(filtered, extension.uri)) {
269 filtered.push_back(extension);
270 }
Stefan Holmer1acbd682017-09-01 13:29:28271 }
272 }
Lennart Grahl0d0ed762021-05-17 14:06:37273
274 // If we do not require encrypted extensions, add missing, non-encrypted
275 // extensions.
276 if (filter != kRequireEncryptedExtension) {
277 for (const auto& extension : extensions) {
278 if (extension.encrypt) {
279 continue;
280 }
281 if (!HeaderExtensionWithUriExists(filtered, extension.uri)) {
282 filtered.push_back(extension);
283 }
284 }
285 }
286
Tomas Gunnarssonc69453d2022-01-06 12:36:04287 // Sort the returned vector to make comparisons of header extensions reliable.
288 // In order of priority, we sort by uri first, then encrypt and id last.
289 std::sort(filtered.begin(), filtered.end(),
290 [](const RtpExtension& a, const RtpExtension& b) {
291 return std::tie(a.uri, a.encrypt, a.id) <
292 std::tie(b.uri, b.encrypt, b.id);
293 });
294
Stefan Holmer1acbd682017-09-01 13:29:28295 return filtered;
296}
297} // namespace webrtc