Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(713)

Side by Side Diff: webrtc/ortc/rtpparametersconversion.cc

Issue 2675173003: Adding "adapter" ORTC objects on top of ChannelManager/BaseChannel/etc. (Closed)
Patch Set: Add memcheck suppression for end-to-end tests. Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « webrtc/ortc/rtpparametersconversion.h ('k') | webrtc/ortc/rtpparametersconversion_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 /*
2 * Copyright 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
11 #include "webrtc/ortc/rtpparametersconversion.h"
12
13 #include <set>
14 #include <sstream>
15 #include <utility>
16
17 #include "webrtc/media/base/rtputils.h"
18
19 namespace webrtc {
20
21 RTCErrorOr<cricket::FeedbackParam> ToCricketFeedbackParam(
22 const RtcpFeedback& feedback) {
23 switch (feedback.type) {
24 case RtcpFeedbackType::CCM:
25 if (!feedback.message_type) {
26 LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER,
27 "Missing message type in CCM RtcpFeedback.");
28 } else if (*feedback.message_type != RtcpFeedbackMessageType::FIR) {
29 LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER,
30 "Invalid message type in CCM RtcpFeedback.");
31 }
32 return cricket::FeedbackParam(cricket::kRtcpFbParamCcm,
33 cricket::kRtcpFbCcmParamFir);
34 case RtcpFeedbackType::NACK:
35 if (!feedback.message_type) {
36 LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER,
37 "Missing message type in NACK RtcpFeedback.");
38 }
39 switch (*feedback.message_type) {
40 case RtcpFeedbackMessageType::GENERIC_NACK:
41 return cricket::FeedbackParam(cricket::kRtcpFbParamNack);
42 case RtcpFeedbackMessageType::PLI:
43 return cricket::FeedbackParam(cricket::kRtcpFbParamNack,
44 cricket::kRtcpFbNackParamPli);
45 default:
46 LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER,
47 "Invalid message type in NACK RtcpFeedback.");
48 }
49 case RtcpFeedbackType::REMB:
50 if (feedback.message_type) {
51 LOG_AND_RETURN_ERROR(
52 RTCErrorType::INVALID_PARAMETER,
53 "Didn't expect message type in REMB RtcpFeedback.");
54 }
55 return cricket::FeedbackParam(cricket::kRtcpFbParamRemb);
56 case RtcpFeedbackType::TRANSPORT_CC:
57 if (feedback.message_type) {
58 LOG_AND_RETURN_ERROR(
59 RTCErrorType::INVALID_PARAMETER,
60 "Didn't expect message type in transport-cc RtcpFeedback.");
61 }
62 return cricket::FeedbackParam(cricket::kRtcpFbParamTransportCc);
63 }
64 // Not reached; avoids compile warning.
65 FATAL();
66 }
67
68 template <typename C>
69 static RTCError ToCricketCodecTypeSpecific(const RtpCodecParameters& codec,
70 C* cricket_codec);
71
72 template <>
73 RTCError ToCricketCodecTypeSpecific<cricket::AudioCodec>(
74 const RtpCodecParameters& codec,
75 cricket::AudioCodec* cricket_codec) {
76 if (codec.kind != cricket::MEDIA_TYPE_AUDIO) {
77 LOG_AND_RETURN_ERROR(
78 RTCErrorType::INVALID_PARAMETER,
79 "Can't use video codec with audio sender or receiver.");
80 }
81 if (!codec.num_channels) {
82 LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER,
83 "Missing number of channels for audio codec.");
84 }
85 if (*codec.num_channels <= 0) {
86 LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_RANGE,
87 "Number of channels must be positive.");
88 }
89 cricket_codec->channels = *codec.num_channels;
90 if (!codec.clock_rate) {
91 LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER,
92 "Missing codec clock rate.");
93 }
94 if (*codec.clock_rate <= 0) {
95 LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_RANGE,
96 "Clock rate must be positive.");
97 }
98 cricket_codec->clockrate = *codec.clock_rate;
99 return RTCError::OK();
100 }
101
102 // Video codecs don't use num_channels or clock_rate, but they should at least
103 // be validated to ensure the application isn't trying to do something it
104 // doesn't intend to.
105 template <>
106 RTCError ToCricketCodecTypeSpecific<cricket::VideoCodec>(
107 const RtpCodecParameters& codec,
108 cricket::VideoCodec*) {
109 if (codec.kind != cricket::MEDIA_TYPE_VIDEO) {
110 LOG_AND_RETURN_ERROR(
111 RTCErrorType::INVALID_PARAMETER,
112 "Can't use audio codec with video sender or receiver.");
113 }
114 if (codec.num_channels) {
115 LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER,
116 "Video codec shouldn't have num_channels.");
117 }
118 if (!codec.clock_rate) {
119 LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER,
120 "Missing codec clock rate.");
121 }
122 if (*codec.clock_rate != cricket::kVideoCodecClockrate) {
123 LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER,
124 "Video clock rate must be 90000.");
125 }
126 return RTCError::OK();
127 }
128
129 template <typename C>
130 RTCErrorOr<C> ToCricketCodec(const RtpCodecParameters& codec) {
131 C cricket_codec;
132 // Start with audio/video specific conversion.
133 RTCError err = ToCricketCodecTypeSpecific(codec, &cricket_codec);
134 if (!err.ok()) {
135 return std::move(err);
136 }
137 cricket_codec.name = codec.name;
138 if (!cricket::IsValidRtpPayloadType(codec.payload_type)) {
139 std::ostringstream oss;
140 oss << "Invalid payload type: " << codec.payload_type;
141 LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_RANGE, oss.str());
142 }
143 cricket_codec.id = codec.payload_type;
144 for (const RtcpFeedback& feedback : codec.rtcp_feedback) {
145 auto result = ToCricketFeedbackParam(feedback);
146 if (!result.ok()) {
147 return result.MoveError();
148 }
149 cricket_codec.AddFeedbackParam(result.MoveValue());
150 }
151 cricket_codec.params.insert(codec.parameters.begin(), codec.parameters.end());
152 return std::move(cricket_codec);
153 }
154
155 template RTCErrorOr<cricket::AudioCodec> ToCricketCodec(
156 const RtpCodecParameters& codec);
157 template RTCErrorOr<cricket::VideoCodec> ToCricketCodec(
158 const RtpCodecParameters& codec);
159
160 template <typename C>
161 RTCErrorOr<std::vector<C>> ToCricketCodecs(
162 const std::vector<RtpCodecParameters>& codecs) {
163 std::vector<C> cricket_codecs;
164 std::set<int> seen_payload_types;
165 for (const RtpCodecParameters& codec : codecs) {
166 auto result = ToCricketCodec<C>(codec);
167 if (!result.ok()) {
168 return result.MoveError();
169 }
170 if (!seen_payload_types.insert(codec.payload_type).second) {
171 std::ostringstream oss;
172 oss << "Duplicate payload type: " << codec.payload_type;
173 LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER, oss.str());
174 }
175 cricket_codecs.push_back(result.MoveValue());
176 }
177 return std::move(cricket_codecs);
178 }
179
180 template RTCErrorOr<std::vector<cricket::AudioCodec>> ToCricketCodecs<
181 cricket::AudioCodec>(const std::vector<RtpCodecParameters>& codecs);
182
183 template RTCErrorOr<std::vector<cricket::VideoCodec>> ToCricketCodecs<
184 cricket::VideoCodec>(const std::vector<RtpCodecParameters>& codecs);
185
186 RTCErrorOr<cricket::RtpHeaderExtensions> ToCricketRtpHeaderExtensions(
187 const std::vector<RtpHeaderExtensionParameters>& extensions) {
188 cricket::RtpHeaderExtensions cricket_extensions;
189 std::ostringstream err_writer;
190 std::set<int> seen_header_extension_ids;
191 for (const RtpHeaderExtensionParameters& extension : extensions) {
192 if (extension.id < RtpHeaderExtensionParameters::kMinId ||
193 extension.id > RtpHeaderExtensionParameters::kMaxId) {
194 err_writer << "Invalid header extension id: " << extension.id;
195 LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_RANGE, err_writer.str());
196 }
197 if (!seen_header_extension_ids.insert(extension.id).second) {
198 err_writer << "Duplicate header extension id: " << extension.id;
199 LOG_AND_RETURN_ERROR(RTCErrorType::INVALID_PARAMETER, err_writer.str());
200 }
201 cricket_extensions.push_back(extension);
202 }
203 return std::move(cricket_extensions);
204 }
205
206 RTCErrorOr<cricket::StreamParamsVec> ToCricketStreamParamsVec(
207 const std::vector<RtpEncodingParameters>& encodings) {
208 if (encodings.size() > 1u) {
209 LOG_AND_RETURN_ERROR(RTCErrorType::UNSUPPORTED_PARAMETER,
210 "ORTC API implementation doesn't currently "
211 "support simulcast or layered encodings.");
212 } else if (encodings.empty()) {
213 return cricket::StreamParamsVec();
214 }
215 cricket::StreamParamsVec cricket_streams;
216 const RtpEncodingParameters& encoding = encodings[0];
217 if (encoding.rtx && encoding.rtx->ssrc && !encoding.ssrc) {
218 LOG_AND_RETURN_ERROR(RTCErrorType::UNSUPPORTED_PARAMETER,
219 "Setting an RTX SSRC explicitly while leaving the "
220 "primary SSRC unset is not currently supported.");
221 }
222 if (encoding.ssrc) {
223 cricket::StreamParams stream_params;
224 stream_params.add_ssrc(*encoding.ssrc);
225 if (encoding.rtx && encoding.rtx->ssrc) {
226 stream_params.AddFidSsrc(*encoding.ssrc, *encoding.rtx->ssrc);
227 }
228 cricket_streams.push_back(std::move(stream_params));
229 }
230 return std::move(cricket_streams);
231 }
232
233 rtc::Optional<RtcpFeedback> ToRtcpFeedback(
234 const cricket::FeedbackParam& cricket_feedback) {
235 if (cricket_feedback.id() == cricket::kRtcpFbParamCcm) {
236 if (cricket_feedback.param() == cricket::kRtcpFbCcmParamFir) {
237 return rtc::Optional<RtcpFeedback>(
238 {RtcpFeedbackType::CCM, RtcpFeedbackMessageType::FIR});
239 } else {
240 LOG(LS_WARNING) << "Unsupported parameter for CCM RTCP feedback: "
241 << cricket_feedback.param();
242 return rtc::Optional<RtcpFeedback>();
243 }
244 } else if (cricket_feedback.id() == cricket::kRtcpFbParamNack) {
245 if (cricket_feedback.param().empty()) {
246 return rtc::Optional<RtcpFeedback>(
247 {RtcpFeedbackType::NACK, RtcpFeedbackMessageType::GENERIC_NACK});
248 } else if (cricket_feedback.param() == cricket::kRtcpFbNackParamPli) {
249 return rtc::Optional<RtcpFeedback>(
250 {RtcpFeedbackType::NACK, RtcpFeedbackMessageType::PLI});
251 } else {
252 LOG(LS_WARNING) << "Unsupported parameter for NACK RTCP feedback: "
253 << cricket_feedback.param();
254 return rtc::Optional<RtcpFeedback>();
255 }
256 } else if (cricket_feedback.id() == cricket::kRtcpFbParamRemb) {
257 if (!cricket_feedback.param().empty()) {
258 LOG(LS_WARNING) << "Unsupported parameter for REMB RTCP feedback: "
259 << cricket_feedback.param();
260 return rtc::Optional<RtcpFeedback>();
261 } else {
262 return rtc::Optional<RtcpFeedback>(RtcpFeedback(RtcpFeedbackType::REMB));
263 }
264 } else if (cricket_feedback.id() == cricket::kRtcpFbParamTransportCc) {
265 if (!cricket_feedback.param().empty()) {
266 LOG(LS_WARNING)
267 << "Unsupported parameter for transport-cc RTCP feedback: "
268 << cricket_feedback.param();
269 return rtc::Optional<RtcpFeedback>();
270 } else {
271 return rtc::Optional<RtcpFeedback>(
272 RtcpFeedback(RtcpFeedbackType::TRANSPORT_CC));
273 }
274 }
275 LOG(LS_WARNING) << "Unsupported RTCP feedback type: "
276 << cricket_feedback.id();
277 return rtc::Optional<RtcpFeedback>();
278 }
279
280 template <typename C>
281 cricket::MediaType KindOfCodec();
282
283 template <>
284 cricket::MediaType KindOfCodec<cricket::AudioCodec>() {
285 return cricket::MEDIA_TYPE_AUDIO;
286 }
287
288 template <>
289 cricket::MediaType KindOfCodec<cricket::VideoCodec>() {
290 return cricket::MEDIA_TYPE_VIDEO;
291 }
292
293 template <typename C>
294 static void ToRtpCodecCapabilityTypeSpecific(const C& cricket_codec,
295 RtpCodecCapability* codec);
296
297 template <>
298 void ToRtpCodecCapabilityTypeSpecific<cricket::AudioCodec>(
299 const cricket::AudioCodec& cricket_codec,
300 RtpCodecCapability* codec) {
301 codec->num_channels =
302 rtc::Optional<int>(static_cast<int>(cricket_codec.channels));
303 }
304
305 template <>
306 void ToRtpCodecCapabilityTypeSpecific<cricket::VideoCodec>(
307 const cricket::VideoCodec& cricket_codec,
308 RtpCodecCapability* codec) {}
309
310 template <typename C>
311 RtpCodecCapability ToRtpCodecCapability(const C& cricket_codec) {
312 RtpCodecCapability codec;
313 codec.name = cricket_codec.name;
314 codec.kind = KindOfCodec<C>();
315 codec.clock_rate.emplace(cricket_codec.clockrate);
316 codec.preferred_payload_type.emplace(cricket_codec.id);
317 for (const cricket::FeedbackParam& cricket_feedback :
318 cricket_codec.feedback_params.params()) {
319 rtc::Optional<RtcpFeedback> feedback = ToRtcpFeedback(cricket_feedback);
320 if (feedback) {
321 codec.rtcp_feedback.push_back(feedback.MoveValue());
322 }
323 }
324 ToRtpCodecCapabilityTypeSpecific(cricket_codec, &codec);
325 codec.parameters.insert(cricket_codec.params.begin(),
326 cricket_codec.params.end());
327 return codec;
328 }
329
330 template RtpCodecCapability ToRtpCodecCapability<cricket::AudioCodec>(
331 const cricket::AudioCodec& cricket_codec);
332 template RtpCodecCapability ToRtpCodecCapability<cricket::VideoCodec>(
333 const cricket::VideoCodec& cricket_codec);
334
335 template <class C>
336 RtpCapabilities ToRtpCapabilities(
337 const std::vector<C>& cricket_codecs,
338 const cricket::RtpHeaderExtensions& cricket_extensions) {
339 RtpCapabilities capabilities;
340 bool have_red = false;
341 bool have_ulpfec = false;
342 bool have_flexfec = false;
343 for (const C& cricket_codec : cricket_codecs) {
344 if (cricket_codec.name == cricket::kRedCodecName) {
345 have_red = true;
346 } else if (cricket_codec.name == cricket::kUlpfecCodecName) {
347 have_ulpfec = true;
348 } else if (cricket_codec.name == cricket::kFlexfecCodecName) {
349 have_flexfec = true;
350 }
351 capabilities.codecs.push_back(ToRtpCodecCapability(cricket_codec));
352 }
353 for (const RtpExtension& cricket_extension : cricket_extensions) {
354 capabilities.header_extensions.emplace_back(cricket_extension.uri,
355 cricket_extension.id);
356 }
357 if (have_red) {
358 capabilities.fec.push_back(FecMechanism::RED);
359 }
360 if (have_red && have_ulpfec) {
361 capabilities.fec.push_back(FecMechanism::RED_AND_ULPFEC);
362 }
363 if (have_flexfec) {
364 capabilities.fec.push_back(FecMechanism::FLEXFEC);
365 }
366 return capabilities;
367 }
368
369 template RtpCapabilities ToRtpCapabilities<cricket::AudioCodec>(
370 const std::vector<cricket::AudioCodec>& cricket_codecs,
371 const cricket::RtpHeaderExtensions& cricket_extensions);
372 template RtpCapabilities ToRtpCapabilities<cricket::VideoCodec>(
373 const std::vector<cricket::VideoCodec>& cricket_codecs,
374 const cricket::RtpHeaderExtensions& cricket_extensions);
375
376 } // namespace webrtc
OLDNEW
« no previous file with comments | « webrtc/ortc/rtpparametersconversion.h ('k') | webrtc/ortc/rtpparametersconversion_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698