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 <string>
14 #include <utility>
15 
16 #include "api/array_view.h"
17 #include "rtc_base/strings/string_builder.h"
18 
19 namespace webrtc {
20 
DegradationPreferenceToString(DegradationPreference degradation_preference)21 const char* DegradationPreferenceToString(
22     DegradationPreference degradation_preference) {
23   switch (degradation_preference) {
24     case DegradationPreference::DISABLED:
25       return "disabled";
26     case DegradationPreference::MAINTAIN_FRAMERATE:
27       return "maintain-framerate";
28     case DegradationPreference::MAINTAIN_RESOLUTION:
29       return "maintain-resolution";
30     case DegradationPreference::BALANCED:
31       return "balanced";
32   }
33 }
34 
35 const double kDefaultBitratePriority = 1.0;
36 
37 RtcpFeedback::RtcpFeedback() = default;
RtcpFeedback(RtcpFeedbackType type)38 RtcpFeedback::RtcpFeedback(RtcpFeedbackType type) : type(type) {}
RtcpFeedback(RtcpFeedbackType type,RtcpFeedbackMessageType message_type)39 RtcpFeedback::RtcpFeedback(RtcpFeedbackType type,
40                            RtcpFeedbackMessageType message_type)
41     : type(type), message_type(message_type) {}
42 RtcpFeedback::RtcpFeedback(const RtcpFeedback& rhs) = default;
43 RtcpFeedback::~RtcpFeedback() = default;
44 
45 RtpCodecCapability::RtpCodecCapability() = default;
46 RtpCodecCapability::~RtpCodecCapability() = default;
47 
48 RtpHeaderExtensionCapability::RtpHeaderExtensionCapability() = default;
RtpHeaderExtensionCapability(absl::string_view uri)49 RtpHeaderExtensionCapability::RtpHeaderExtensionCapability(
50     absl::string_view uri)
51     : uri(uri) {}
RtpHeaderExtensionCapability(absl::string_view uri,int preferred_id)52 RtpHeaderExtensionCapability::RtpHeaderExtensionCapability(
53     absl::string_view uri,
54     int preferred_id)
55     : uri(uri), preferred_id(preferred_id) {}
RtpHeaderExtensionCapability(absl::string_view uri,int preferred_id,RtpTransceiverDirection direction)56 RtpHeaderExtensionCapability::RtpHeaderExtensionCapability(
57     absl::string_view uri,
58     int preferred_id,
59     RtpTransceiverDirection direction)
60     : uri(uri), preferred_id(preferred_id), direction(direction) {}
61 RtpHeaderExtensionCapability::~RtpHeaderExtensionCapability() = default;
62 
63 RtpExtension::RtpExtension() = default;
RtpExtension(absl::string_view uri,int id)64 RtpExtension::RtpExtension(absl::string_view uri, int id) : uri(uri), id(id) {}
RtpExtension(absl::string_view uri,int id,bool encrypt)65 RtpExtension::RtpExtension(absl::string_view uri, int id, bool encrypt)
66     : uri(uri), id(id), encrypt(encrypt) {}
67 RtpExtension::~RtpExtension() = default;
68 
69 RtpFecParameters::RtpFecParameters() = default;
RtpFecParameters(FecMechanism mechanism)70 RtpFecParameters::RtpFecParameters(FecMechanism mechanism)
71     : mechanism(mechanism) {}
RtpFecParameters(FecMechanism mechanism,uint32_t ssrc)72 RtpFecParameters::RtpFecParameters(FecMechanism mechanism, uint32_t ssrc)
73     : ssrc(ssrc), mechanism(mechanism) {}
74 RtpFecParameters::RtpFecParameters(const RtpFecParameters& rhs) = default;
75 RtpFecParameters::~RtpFecParameters() = default;
76 
77 RtpRtxParameters::RtpRtxParameters() = default;
RtpRtxParameters(uint32_t ssrc)78 RtpRtxParameters::RtpRtxParameters(uint32_t ssrc) : ssrc(ssrc) {}
79 RtpRtxParameters::RtpRtxParameters(const RtpRtxParameters& rhs) = default;
80 RtpRtxParameters::~RtpRtxParameters() = default;
81 
82 RtpEncodingParameters::RtpEncodingParameters() = default;
83 RtpEncodingParameters::RtpEncodingParameters(const RtpEncodingParameters& rhs) =
84     default;
85 RtpEncodingParameters::~RtpEncodingParameters() = default;
86 
87 RtpCodecParameters::RtpCodecParameters() = default;
88 RtpCodecParameters::RtpCodecParameters(const RtpCodecParameters& rhs) = default;
89 RtpCodecParameters::~RtpCodecParameters() = default;
90 
91 RtpCapabilities::RtpCapabilities() = default;
92 RtpCapabilities::~RtpCapabilities() = default;
93 
94 RtcpParameters::RtcpParameters() = default;
95 RtcpParameters::RtcpParameters(const RtcpParameters& rhs) = default;
96 RtcpParameters::~RtcpParameters() = default;
97 
98 RtpParameters::RtpParameters() = default;
99 RtpParameters::RtpParameters(const RtpParameters& rhs) = default;
100 RtpParameters::~RtpParameters() = default;
101 
ToString() const102 std::string RtpExtension::ToString() const {
103   char buf[256];
104   rtc::SimpleStringBuilder sb(buf);
105   sb << "{uri: " << uri;
106   sb << ", id: " << id;
107   if (encrypt) {
108     sb << ", encrypt";
109   }
110   sb << '}';
111   return sb.str();
112 }
113 
114 constexpr char RtpExtension::kEncryptHeaderExtensionsUri[];
115 constexpr char RtpExtension::kAudioLevelUri[];
116 constexpr char RtpExtension::kTimestampOffsetUri[];
117 constexpr char RtpExtension::kAbsSendTimeUri[];
118 constexpr char RtpExtension::kAbsoluteCaptureTimeUri[];
119 constexpr char RtpExtension::kVideoRotationUri[];
120 constexpr char RtpExtension::kVideoContentTypeUri[];
121 constexpr char RtpExtension::kVideoTimingUri[];
122 constexpr char RtpExtension::kGenericFrameDescriptorUri00[];
123 constexpr char RtpExtension::kDependencyDescriptorUri[];
124 constexpr char RtpExtension::kTransportSequenceNumberUri[];
125 constexpr char RtpExtension::kTransportSequenceNumberV2Uri[];
126 constexpr char RtpExtension::kPlayoutDelayUri[];
127 constexpr char RtpExtension::kColorSpaceUri[];
128 constexpr char RtpExtension::kMidUri[];
129 constexpr char RtpExtension::kRidUri[];
130 constexpr char RtpExtension::kRepairedRidUri[];
131 
132 constexpr int RtpExtension::kMinId;
133 constexpr int RtpExtension::kMaxId;
134 constexpr int RtpExtension::kMaxValueSize;
135 constexpr int RtpExtension::kOneByteHeaderExtensionMaxId;
136 constexpr int RtpExtension::kOneByteHeaderExtensionMaxValueSize;
137 
IsSupportedForAudio(absl::string_view uri)138 bool RtpExtension::IsSupportedForAudio(absl::string_view uri) {
139   return uri == webrtc::RtpExtension::kAudioLevelUri ||
140          uri == webrtc::RtpExtension::kAbsSendTimeUri ||
141          uri == webrtc::RtpExtension::kAbsoluteCaptureTimeUri ||
142          uri == webrtc::RtpExtension::kTransportSequenceNumberUri ||
143          uri == webrtc::RtpExtension::kTransportSequenceNumberV2Uri ||
144          uri == webrtc::RtpExtension::kMidUri ||
145          uri == webrtc::RtpExtension::kRidUri ||
146          uri == webrtc::RtpExtension::kRepairedRidUri;
147 }
148 
IsSupportedForVideo(absl::string_view uri)149 bool RtpExtension::IsSupportedForVideo(absl::string_view uri) {
150   return uri == webrtc::RtpExtension::kTimestampOffsetUri ||
151          uri == webrtc::RtpExtension::kAbsSendTimeUri ||
152          uri == webrtc::RtpExtension::kAbsoluteCaptureTimeUri ||
153          uri == webrtc::RtpExtension::kVideoRotationUri ||
154          uri == webrtc::RtpExtension::kTransportSequenceNumberUri ||
155          uri == webrtc::RtpExtension::kTransportSequenceNumberV2Uri ||
156          uri == webrtc::RtpExtension::kPlayoutDelayUri ||
157          uri == webrtc::RtpExtension::kVideoContentTypeUri ||
158          uri == webrtc::RtpExtension::kVideoTimingUri ||
159          uri == webrtc::RtpExtension::kMidUri ||
160          uri == webrtc::RtpExtension::kGenericFrameDescriptorUri00 ||
161          uri == webrtc::RtpExtension::kDependencyDescriptorUri ||
162          uri == webrtc::RtpExtension::kColorSpaceUri ||
163          uri == webrtc::RtpExtension::kRidUri ||
164          uri == webrtc::RtpExtension::kRepairedRidUri;
165 }
166 
IsEncryptionSupported(absl::string_view uri)167 bool RtpExtension::IsEncryptionSupported(absl::string_view uri) {
168   return uri == webrtc::RtpExtension::kAudioLevelUri ||
169          uri == webrtc::RtpExtension::kTimestampOffsetUri ||
170 #if !defined(ENABLE_EXTERNAL_AUTH)
171          // TODO(jbauch): Figure out a way to always allow "kAbsSendTimeUri"
172          // here and filter out later if external auth is really used in
173          // srtpfilter. External auth is used by Chromium and replaces the
174          // extension header value of "kAbsSendTimeUri", so it must not be
175          // encrypted (which can't be done by Chromium).
176          uri == webrtc::RtpExtension::kAbsSendTimeUri ||
177 #endif
178          uri == webrtc::RtpExtension::kAbsoluteCaptureTimeUri ||
179          uri == webrtc::RtpExtension::kVideoRotationUri ||
180          uri == webrtc::RtpExtension::kTransportSequenceNumberUri ||
181          uri == webrtc::RtpExtension::kTransportSequenceNumberV2Uri ||
182          uri == webrtc::RtpExtension::kPlayoutDelayUri ||
183          uri == webrtc::RtpExtension::kVideoContentTypeUri ||
184          uri == webrtc::RtpExtension::kMidUri ||
185          uri == webrtc::RtpExtension::kRidUri ||
186          uri == webrtc::RtpExtension::kRepairedRidUri;
187 }
188 
FindHeaderExtensionByUri(const std::vector<RtpExtension> & extensions,absl::string_view uri)189 const RtpExtension* RtpExtension::FindHeaderExtensionByUri(
190     const std::vector<RtpExtension>& extensions,
191     absl::string_view uri) {
192   for (const auto& extension : extensions) {
193     if (extension.uri == uri) {
194       return &extension;
195     }
196   }
197   return nullptr;
198 }
199 
FilterDuplicateNonEncrypted(const std::vector<RtpExtension> & extensions)200 std::vector<RtpExtension> RtpExtension::FilterDuplicateNonEncrypted(
201     const std::vector<RtpExtension>& extensions) {
202   std::vector<RtpExtension> filtered;
203   for (auto extension = extensions.begin(); extension != extensions.end();
204        ++extension) {
205     if (extension->encrypt) {
206       filtered.push_back(*extension);
207       continue;
208     }
209 
210     // Only add non-encrypted extension if no encrypted with the same URI
211     // is also present...
212     if (std::any_of(extension + 1, extensions.end(),
213                     [&](const RtpExtension& check) {
214                       return extension->uri == check.uri;
215                     })) {
216       continue;
217     }
218 
219     // ...and has not been added before.
220     if (!FindHeaderExtensionByUri(filtered, extension->uri)) {
221       filtered.push_back(*extension);
222     }
223   }
224   return filtered;
225 }
226 }  // namespace webrtc
227