blob: 649fe9719160e00deed64bfef7f5f29412064970 [file] [log] [blame]
deadbeefe814a0d2017-02-25 18:15:09 -08001/*
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 <algorithm>
12
Florent Castelli72b751a2018-06-28 14:09:33 +020013#include "pc/rtpparametersconversion.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020014#include "rtc_base/gunit.h"
deadbeefe814a0d2017-02-25 18:15:09 -080015
16namespace webrtc {
17
18TEST(RtpParametersConversionTest, ToCricketFeedbackParam) {
19 auto result = ToCricketFeedbackParam(
20 {RtcpFeedbackType::CCM, RtcpFeedbackMessageType::FIR});
21 EXPECT_EQ(cricket::FeedbackParam("ccm", "fir"), result.value());
22 result = ToCricketFeedbackParam(
23 {RtcpFeedbackType::NACK, RtcpFeedbackMessageType::GENERIC_NACK});
24 EXPECT_EQ(cricket::FeedbackParam("nack"), result.value());
25 result = ToCricketFeedbackParam(
26 {RtcpFeedbackType::NACK, RtcpFeedbackMessageType::PLI});
27 EXPECT_EQ(cricket::FeedbackParam("nack", "pli"), result.value());
28 result = ToCricketFeedbackParam(RtcpFeedback(RtcpFeedbackType::REMB));
29 EXPECT_EQ(cricket::FeedbackParam("goog-remb"), result.value());
30 result = ToCricketFeedbackParam(RtcpFeedback(RtcpFeedbackType::TRANSPORT_CC));
31 EXPECT_EQ(cricket::FeedbackParam("transport-cc"), result.value());
32}
33
34TEST(RtpParametersConversionTest, ToCricketFeedbackParamErrors) {
35 // CCM with missing or invalid message type.
36 auto result = ToCricketFeedbackParam(RtcpFeedback(RtcpFeedbackType::CCM));
37 EXPECT_EQ(RTCErrorType::INVALID_PARAMETER, result.error().type());
38 result = ToCricketFeedbackParam(
39 {RtcpFeedbackType::CCM, RtcpFeedbackMessageType::PLI});
40 EXPECT_EQ(RTCErrorType::INVALID_PARAMETER, result.error().type());
41 // NACK with missing or invalid message type.
42 result = ToCricketFeedbackParam(RtcpFeedback(RtcpFeedbackType::NACK));
43 EXPECT_EQ(RTCErrorType::INVALID_PARAMETER, result.error().type());
44 result = ToCricketFeedbackParam(
45 {RtcpFeedbackType::NACK, RtcpFeedbackMessageType::FIR});
46 EXPECT_EQ(RTCErrorType::INVALID_PARAMETER, result.error().type());
47 // REMB with message type (should be left empty).
48 result = ToCricketFeedbackParam(
49 {RtcpFeedbackType::REMB, RtcpFeedbackMessageType::GENERIC_NACK});
50 EXPECT_EQ(RTCErrorType::INVALID_PARAMETER, result.error().type());
51 // TRANSPORT_CC with message type (should be left empty).
52 result = ToCricketFeedbackParam(
53 {RtcpFeedbackType::TRANSPORT_CC, RtcpFeedbackMessageType::FIR});
54 EXPECT_EQ(RTCErrorType::INVALID_PARAMETER, result.error().type());
55}
56
57TEST(RtpParametersConversionTest, ToAudioCodec) {
58 RtpCodecParameters codec;
59 codec.name = "AuDiO";
60 codec.kind = cricket::MEDIA_TYPE_AUDIO;
61 codec.payload_type = 120;
62 codec.clock_rate.emplace(36000);
63 codec.num_channels.emplace(6);
64 codec.parameters["foo"] = "bar";
65 codec.rtcp_feedback.emplace_back(RtcpFeedbackType::TRANSPORT_CC);
66 auto result = ToCricketCodec<cricket::AudioCodec>(codec);
67 ASSERT_TRUE(result.ok());
68
69 EXPECT_EQ("AuDiO", result.value().name);
70 EXPECT_EQ(120, result.value().id);
71 EXPECT_EQ(36000, result.value().clockrate);
72 EXPECT_EQ(6u, result.value().channels);
73 ASSERT_EQ(1u, result.value().params.size());
74 EXPECT_EQ("bar", result.value().params["foo"]);
75 EXPECT_EQ(1u, result.value().feedback_params.params().size());
76 EXPECT_TRUE(result.value().feedback_params.Has(
77 cricket::FeedbackParam("transport-cc")));
78}
79
80TEST(RtpParametersConversionTest, ToVideoCodec) {
81 RtpCodecParameters codec;
82 codec.name = "coolcodec";
83 codec.kind = cricket::MEDIA_TYPE_VIDEO;
84 codec.payload_type = 101;
85 codec.clock_rate.emplace(90000);
86 codec.parameters["foo"] = "bar";
87 codec.parameters["PING"] = "PONG";
88 codec.rtcp_feedback.emplace_back(RtcpFeedbackType::TRANSPORT_CC);
89 codec.rtcp_feedback.emplace_back(RtcpFeedbackType::NACK,
90 RtcpFeedbackMessageType::PLI);
91 auto result = ToCricketCodec<cricket::VideoCodec>(codec);
92 ASSERT_TRUE(result.ok());
93
94 EXPECT_EQ("coolcodec", result.value().name);
95 EXPECT_EQ(101, result.value().id);
96 EXPECT_EQ(90000, result.value().clockrate);
97 ASSERT_EQ(2u, result.value().params.size());
98 EXPECT_EQ("bar", result.value().params["foo"]);
99 EXPECT_EQ("PONG", result.value().params["PING"]);
100 EXPECT_EQ(2u, result.value().feedback_params.params().size());
101 EXPECT_TRUE(result.value().feedback_params.Has(
102 cricket::FeedbackParam("transport-cc")));
103 EXPECT_TRUE(result.value().feedback_params.Has(
104 cricket::FeedbackParam("nack", "pli")));
105}
106
107// Trying to convert to an AudioCodec if the kind is "video" should fail.
108TEST(RtpParametersConversionTest, ToCricketCodecInvalidKind) {
109 RtpCodecParameters audio_codec;
110 audio_codec.name = "opus";
111 audio_codec.kind = cricket::MEDIA_TYPE_VIDEO;
112 audio_codec.payload_type = 111;
113 audio_codec.clock_rate.emplace(48000);
114 audio_codec.num_channels.emplace(2);
115
116 RtpCodecParameters video_codec;
117 video_codec.name = "VP8";
118 video_codec.kind = cricket::MEDIA_TYPE_AUDIO;
119 video_codec.payload_type = 102;
120 video_codec.clock_rate.emplace(90000);
121
122 auto audio_result = ToCricketCodec<cricket::AudioCodec>(audio_codec);
123 EXPECT_EQ(RTCErrorType::INVALID_PARAMETER, audio_result.error().type());
124
125 auto video_result = ToCricketCodec<cricket::VideoCodec>(video_codec);
126 EXPECT_EQ(RTCErrorType::INVALID_PARAMETER, video_result.error().type());
127
128 // Sanity check that if the kind is correct, the conversion succeeds.
129 audio_codec.kind = cricket::MEDIA_TYPE_AUDIO;
130 video_codec.kind = cricket::MEDIA_TYPE_VIDEO;
131 audio_result = ToCricketCodec<cricket::AudioCodec>(audio_codec);
132 EXPECT_TRUE(audio_result.ok());
133 video_result = ToCricketCodec<cricket::VideoCodec>(video_codec);
134 EXPECT_TRUE(video_result.ok());
135}
136
137TEST(RtpParametersConversionTest, ToAudioCodecInvalidParameters) {
138 // Missing channels.
139 RtpCodecParameters codec;
140 codec.name = "opus";
141 codec.kind = cricket::MEDIA_TYPE_AUDIO;
142 codec.payload_type = 111;
143 codec.clock_rate.emplace(48000);
144 auto result = ToCricketCodec<cricket::AudioCodec>(codec);
145 EXPECT_EQ(RTCErrorType::INVALID_PARAMETER, result.error().type());
146
147 // Negative number of channels.
148 codec.num_channels.emplace(-1);
149 result = ToCricketCodec<cricket::AudioCodec>(codec);
150 EXPECT_EQ(RTCErrorType::INVALID_RANGE, result.error().type());
151
152 // Missing clock rate.
153 codec.num_channels.emplace(2);
154 codec.clock_rate.reset();
155 result = ToCricketCodec<cricket::AudioCodec>(codec);
156 EXPECT_EQ(RTCErrorType::INVALID_PARAMETER, result.error().type());
157
158 // Negative clock rate.
159 codec.clock_rate.emplace(-48000);
160 result = ToCricketCodec<cricket::AudioCodec>(codec);
161 EXPECT_EQ(RTCErrorType::INVALID_RANGE, result.error().type());
162
163 // Sanity check that conversion succeeds if these errors are fixed.
164 codec.clock_rate.emplace(48000);
165 result = ToCricketCodec<cricket::AudioCodec>(codec);
166 EXPECT_TRUE(result.ok());
167}
168
169TEST(RtpParametersConversionTest, ToVideoCodecInvalidParameters) {
170 // Missing clock rate.
171 RtpCodecParameters codec;
172 codec.name = "VP8";
173 codec.kind = cricket::MEDIA_TYPE_VIDEO;
174 codec.payload_type = 102;
175 auto result = ToCricketCodec<cricket::VideoCodec>(codec);
176 EXPECT_EQ(RTCErrorType::INVALID_PARAMETER, result.error().type());
177
178 // Invalid clock rate.
179 codec.clock_rate.emplace(48000);
180 result = ToCricketCodec<cricket::VideoCodec>(codec);
181 EXPECT_EQ(RTCErrorType::INVALID_PARAMETER, result.error().type());
182
183 // Channels set (should be unset).
184 codec.clock_rate.emplace(90000);
185 codec.num_channels.emplace(2);
186 result = ToCricketCodec<cricket::VideoCodec>(codec);
187 EXPECT_EQ(RTCErrorType::INVALID_PARAMETER, result.error().type());
188
189 // Sanity check that conversion succeeds if these errors are fixed.
190 codec.num_channels.reset();
191 result = ToCricketCodec<cricket::VideoCodec>(codec);
192 EXPECT_TRUE(result.ok());
193}
194
195TEST(RtpParametersConversionTest, ToCricketCodecInvalidPayloadType) {
196 RtpCodecParameters codec;
197 codec.name = "VP8";
198 codec.kind = cricket::MEDIA_TYPE_VIDEO;
199 codec.clock_rate.emplace(90000);
200
201 codec.payload_type = -1000;
202 auto result = ToCricketCodec<cricket::VideoCodec>(codec);
203 EXPECT_EQ(RTCErrorType::INVALID_RANGE, result.error().type());
204
205 // Max payload type is 127.
206 codec.payload_type = 128;
207 result = ToCricketCodec<cricket::VideoCodec>(codec);
208 EXPECT_EQ(RTCErrorType::INVALID_RANGE, result.error().type());
209
210 // Sanity check that conversion succeeds with a valid payload type.
211 codec.payload_type = 127;
212 result = ToCricketCodec<cricket::VideoCodec>(codec);
213 EXPECT_TRUE(result.ok());
214}
215
216// There are already tests for ToCricketFeedbackParam, but ensure that those
217// errors are propagated from ToCricketCodec.
218TEST(RtpParametersConversionTest, ToCricketCodecInvalidRtcpFeedback) {
219 RtpCodecParameters codec;
220 codec.name = "VP8";
221 codec.kind = cricket::MEDIA_TYPE_VIDEO;
222 codec.clock_rate.emplace(90000);
223 codec.payload_type = 99;
224 codec.rtcp_feedback.emplace_back(RtcpFeedbackType::CCM,
225 RtcpFeedbackMessageType::PLI);
226
227 auto result = ToCricketCodec<cricket::VideoCodec>(codec);
228 EXPECT_EQ(RTCErrorType::INVALID_PARAMETER, result.error().type());
229
230 // Sanity check that conversion succeeds without invalid feedback.
231 codec.rtcp_feedback.clear();
232 result = ToCricketCodec<cricket::VideoCodec>(codec);
233 EXPECT_TRUE(result.ok());
234}
235
236TEST(RtpParametersConversionTest, ToCricketCodecs) {
237 std::vector<RtpCodecParameters> codecs;
238 RtpCodecParameters codec;
239 codec.name = "VP8";
240 codec.kind = cricket::MEDIA_TYPE_VIDEO;
241 codec.clock_rate.emplace(90000);
242 codec.payload_type = 99;
243 codecs.push_back(codec);
244
245 codec.name = "VP9";
246 codec.payload_type = 100;
247 codecs.push_back(codec);
248
249 auto result = ToCricketCodecs<cricket::VideoCodec>(codecs);
250 ASSERT_TRUE(result.ok());
251 ASSERT_EQ(2u, result.value().size());
252 EXPECT_EQ("VP8", result.value()[0].name);
253 EXPECT_EQ(99, result.value()[0].id);
254 EXPECT_EQ("VP9", result.value()[1].name);
255 EXPECT_EQ(100, result.value()[1].id);
256}
257
258TEST(RtpParametersConversionTest, ToCricketCodecsDuplicatePayloadType) {
259 std::vector<RtpCodecParameters> codecs;
260 RtpCodecParameters codec;
261 codec.name = "VP8";
262 codec.kind = cricket::MEDIA_TYPE_VIDEO;
263 codec.clock_rate.emplace(90000);
264 codec.payload_type = 99;
265 codecs.push_back(codec);
266
267 codec.name = "VP9";
268 codec.payload_type = 99;
269 codecs.push_back(codec);
270
271 auto result = ToCricketCodecs<cricket::VideoCodec>(codecs);
272 EXPECT_EQ(RTCErrorType::INVALID_PARAMETER, result.error().type());
273
274 // Sanity check that this succeeds without the duplicate payload type.
275 codecs[1].payload_type = 120;
276 result = ToCricketCodecs<cricket::VideoCodec>(codecs);
277 EXPECT_TRUE(result.ok());
278}
279
280TEST(RtpParametersConversionTest, ToCricketRtpHeaderExtensions) {
281 std::vector<RtpHeaderExtensionParameters> extensions = {
282 {"http://example.com", 1}, {"urn:foo:bar", 14}};
283 auto result = ToCricketRtpHeaderExtensions(extensions);
284 ASSERT_TRUE(result.ok());
285 ASSERT_EQ(2u, result.value().size());
286 EXPECT_EQ("http://example.com", result.value()[0].uri);
287 EXPECT_EQ(1, result.value()[0].id);
288 EXPECT_EQ("urn:foo:bar", result.value()[1].uri);
289 EXPECT_EQ(14, result.value()[1].id);
290}
291
292TEST(RtpParametersConversionTest, ToCricketRtpHeaderExtensionsErrors) {
293 // First, IDs outside the range 1-14.
294 std::vector<RtpHeaderExtensionParameters> extensions = {
295 {"http://example.com", 0}};
296 auto result = ToCricketRtpHeaderExtensions(extensions);
297 EXPECT_EQ(RTCErrorType::INVALID_RANGE, result.error().type());
298
299 extensions[0].id = 15;
300 result = ToCricketRtpHeaderExtensions(extensions);
301 EXPECT_EQ(RTCErrorType::INVALID_RANGE, result.error().type());
302
303 // Duplicate IDs.
304 extensions = {{"http://example.com", 1}, {"urn:foo:bar", 1}};
305 result = ToCricketRtpHeaderExtensions(extensions);
306 EXPECT_EQ(RTCErrorType::INVALID_PARAMETER, result.error().type());
307}
308
309TEST(RtpParametersConversionTest, ToCricketStreamParamsVecSimple) {
310 std::vector<RtpEncodingParameters> encodings;
311 RtpEncodingParameters encoding;
312 encoding.ssrc.emplace(0xbaadf00d);
313 encodings.push_back(encoding);
314 auto result = ToCricketStreamParamsVec(encodings);
315 ASSERT_TRUE(result.ok());
316 ASSERT_EQ(1u, result.value().size());
317 EXPECT_EQ(1u, result.value()[0].ssrcs.size());
318 EXPECT_EQ(0xbaadf00d, result.value()[0].first_ssrc());
319}
320
321TEST(RtpParametersConversionTest, ToCricketStreamParamsVecWithRtx) {
322 std::vector<RtpEncodingParameters> encodings;
323 RtpEncodingParameters encoding;
324 // Test a corner case SSRC of 0.
325 encoding.ssrc.emplace(0u);
326 encoding.rtx.emplace(0xdeadbeef);
327 encodings.push_back(encoding);
328 auto result = ToCricketStreamParamsVec(encodings);
329 ASSERT_TRUE(result.ok());
330 ASSERT_EQ(1u, result.value().size());
331 EXPECT_EQ(2u, result.value()[0].ssrcs.size());
332 EXPECT_EQ(0u, result.value()[0].first_ssrc());
333 uint32_t rtx_ssrc = 0;
334 EXPECT_TRUE(result.value()[0].GetFidSsrc(0u, &rtx_ssrc));
335 EXPECT_EQ(0xdeadbeef, rtx_ssrc);
336}
337
338// No encodings should be accepted; an endpoint may want to prepare a
339// decoder/encoder without having something to receive/send yet.
340TEST(RtpParametersConversionTest, ToCricketStreamParamsVecNoEncodings) {
341 std::vector<RtpEncodingParameters> encodings;
342 auto result = ToCricketStreamParamsVec(encodings);
343 ASSERT_TRUE(result.ok());
344 EXPECT_EQ(0u, result.value().size());
345}
346
347// An encoding without SSRCs should be accepted. This could be the case when
348// SSRCs aren't signaled and payload-type based demuxing is used.
349TEST(RtpParametersConversionTest, ToCricketStreamParamsVecMissingSsrcs) {
350 std::vector<RtpEncodingParameters> encodings = {{}};
351 // Creates RtxParameters with empty SSRC.
352 encodings[0].rtx.emplace();
353 auto result = ToCricketStreamParamsVec(encodings);
354 ASSERT_TRUE(result.ok());
355 EXPECT_EQ(0u, result.value().size());
356}
357
358// The media engine doesn't have a way of receiving an RTX SSRC that's known
359// with a primary SSRC that's unknown, so this should produce an error.
360TEST(RtpParametersConversionTest, ToStreamParamsWithPrimarySsrcSetAndRtxUnset) {
361 std::vector<RtpEncodingParameters> encodings = {{}};
362 encodings[0].rtx.emplace(0xdeadbeef);
363 EXPECT_EQ(RTCErrorType::UNSUPPORTED_PARAMETER,
364 ToCricketStreamParamsVec(encodings).error().type());
365}
366
367// TODO(deadbeef): Update this test when we support multiple encodings.
368TEST(RtpParametersConversionTest, ToCricketStreamParamsVecMultipleEncodings) {
369 std::vector<RtpEncodingParameters> encodings = {{}, {}};
370 auto result = ToCricketStreamParamsVec(encodings);
371 EXPECT_EQ(RTCErrorType::UNSUPPORTED_PARAMETER, result.error().type());
372}
373
374TEST(RtpParametersConversionTest, ToRtcpFeedback) {
Danil Chapovalov00c71832018-06-15 15:58:38 +0200375 absl::optional<RtcpFeedback> result = ToRtcpFeedback({"ccm", "fir"});
deadbeefe814a0d2017-02-25 18:15:09 -0800376 EXPECT_EQ(RtcpFeedback(RtcpFeedbackType::CCM, RtcpFeedbackMessageType::FIR),
377 *result);
378 result = ToRtcpFeedback(cricket::FeedbackParam("nack"));
379 EXPECT_EQ(RtcpFeedback(RtcpFeedbackType::NACK,
380 RtcpFeedbackMessageType::GENERIC_NACK),
381 *result);
382 result = ToRtcpFeedback({"nack", "pli"});
383 EXPECT_EQ(RtcpFeedback(RtcpFeedbackType::NACK, RtcpFeedbackMessageType::PLI),
384 *result);
385 result = ToRtcpFeedback(cricket::FeedbackParam("goog-remb"));
386 EXPECT_EQ(RtcpFeedback(RtcpFeedbackType::REMB), *result);
387 result = ToRtcpFeedback(cricket::FeedbackParam("transport-cc"));
388 EXPECT_EQ(RtcpFeedback(RtcpFeedbackType::TRANSPORT_CC), *result);
389}
390
391TEST(RtpParametersConversionTest, ToRtcpFeedbackErrors) {
392 // CCM with missing or invalid message type.
Danil Chapovalov00c71832018-06-15 15:58:38 +0200393 absl::optional<RtcpFeedback> result = ToRtcpFeedback({"ccm", "pli"});
deadbeefe814a0d2017-02-25 18:15:09 -0800394 EXPECT_FALSE(result);
395 result = ToRtcpFeedback(cricket::FeedbackParam("ccm"));
396 EXPECT_FALSE(result);
397 // NACK with missing or invalid message type.
398 result = ToRtcpFeedback({"nack", "fir"});
399 EXPECT_FALSE(result);
400 // REMB with message type (should be left empty).
401 result = ToRtcpFeedback({"goog-remb", "pli"});
402 EXPECT_FALSE(result);
403 // TRANSPORT_CC with message type (should be left empty).
404 result = ToRtcpFeedback({"transport-cc", "fir"});
405 EXPECT_FALSE(result);
406 // Unknown message type.
407 result = ToRtcpFeedback(cricket::FeedbackParam("foo"));
408 EXPECT_FALSE(result);
409}
410
411TEST(RtpParametersConversionTest, ToAudioRtpCodecCapability) {
412 cricket::AudioCodec cricket_codec;
413 cricket_codec.name = "foo";
414 cricket_codec.id = 50;
415 cricket_codec.clockrate = 22222;
416 cricket_codec.channels = 4;
417 cricket_codec.params["foo"] = "bar";
418 cricket_codec.feedback_params.Add(cricket::FeedbackParam("transport-cc"));
419 RtpCodecCapability codec = ToRtpCodecCapability(cricket_codec);
420
421 EXPECT_EQ("foo", codec.name);
422 EXPECT_EQ(cricket::MEDIA_TYPE_AUDIO, codec.kind);
Oskar Sundbomff610bd2017-11-16 10:57:44 +0100423 EXPECT_EQ(50, codec.preferred_payload_type);
424 EXPECT_EQ(22222, codec.clock_rate);
425 EXPECT_EQ(4, codec.num_channels);
deadbeefe814a0d2017-02-25 18:15:09 -0800426 ASSERT_EQ(1u, codec.parameters.size());
427 EXPECT_EQ("bar", codec.parameters["foo"]);
428 EXPECT_EQ(1u, codec.rtcp_feedback.size());
429 EXPECT_EQ(RtcpFeedback(RtcpFeedbackType::TRANSPORT_CC),
430 codec.rtcp_feedback[0]);
431}
432
433TEST(RtpParametersConversionTest, ToVideoRtpCodecCapability) {
434 cricket::VideoCodec cricket_codec;
435 cricket_codec.name = "VID";
436 cricket_codec.id = 101;
437 cricket_codec.clockrate = 80000;
438 cricket_codec.params["foo"] = "bar";
439 cricket_codec.params["ANOTHER"] = "param";
440 cricket_codec.feedback_params.Add(cricket::FeedbackParam("transport-cc"));
441 cricket_codec.feedback_params.Add({"nack", "pli"});
442 RtpCodecCapability codec = ToRtpCodecCapability(cricket_codec);
443
444 EXPECT_EQ("VID", codec.name);
445 EXPECT_EQ(cricket::MEDIA_TYPE_VIDEO, codec.kind);
Oskar Sundbomff610bd2017-11-16 10:57:44 +0100446 EXPECT_EQ(101, codec.preferred_payload_type);
447 EXPECT_EQ(80000, codec.clock_rate);
deadbeefe814a0d2017-02-25 18:15:09 -0800448 ASSERT_EQ(2u, codec.parameters.size());
449 EXPECT_EQ("bar", codec.parameters["foo"]);
450 EXPECT_EQ("param", codec.parameters["ANOTHER"]);
451 EXPECT_EQ(2u, codec.rtcp_feedback.size());
452 EXPECT_EQ(RtcpFeedback(RtcpFeedbackType::TRANSPORT_CC),
453 codec.rtcp_feedback[0]);
454 EXPECT_EQ(RtcpFeedback(RtcpFeedbackType::NACK, RtcpFeedbackMessageType::PLI),
455 codec.rtcp_feedback[1]);
456}
457
zhihuang24366392017-03-08 17:15:06 -0800458TEST(RtpParametersConversionTest, ToRtpEncodingsWithEmptyStreamParamsVec) {
459 cricket::StreamParamsVec streams;
460 auto rtp_encodings = ToRtpEncodings(streams);
461 ASSERT_EQ(0u, rtp_encodings.size());
462}
463
464TEST(RtpParametersConversionTest, ToRtpEncodingsWithMultipleStreamParams) {
465 cricket::StreamParamsVec streams;
466 cricket::StreamParams stream1;
467 stream1.ssrcs.push_back(1111u);
468 stream1.AddFidSsrc(1111u, 0xaaaaaaaa);
469
470 cricket::StreamParams stream2;
471 stream2.ssrcs.push_back(2222u);
472 stream2.AddFidSsrc(2222u, 0xaaaaaaab);
473
474 streams.push_back(stream1);
475 streams.push_back(stream2);
476
477 auto rtp_encodings = ToRtpEncodings(streams);
478 ASSERT_EQ(2u, rtp_encodings.size());
479 EXPECT_EQ(1111u, rtp_encodings[0].ssrc);
480 EXPECT_EQ(0xaaaaaaaa, rtp_encodings[0].rtx->ssrc);
481 EXPECT_EQ(2222u, rtp_encodings[1].ssrc);
482 EXPECT_EQ(0xaaaaaaab, rtp_encodings[1].rtx->ssrc);
483}
484
485TEST(RtpParametersConversionTest, ToAudioRtpCodecParameters) {
486 cricket::AudioCodec cricket_codec;
487 cricket_codec.name = "foo";
488 cricket_codec.id = 50;
489 cricket_codec.clockrate = 22222;
490 cricket_codec.channels = 4;
491 cricket_codec.params["foo"] = "bar";
492 cricket_codec.feedback_params.Add(cricket::FeedbackParam("transport-cc"));
493 RtpCodecParameters codec = ToRtpCodecParameters(cricket_codec);
494
495 EXPECT_EQ("foo", codec.name);
496 EXPECT_EQ(cricket::MEDIA_TYPE_AUDIO, codec.kind);
497 EXPECT_EQ(50, codec.payload_type);
Oskar Sundbomff610bd2017-11-16 10:57:44 +0100498 EXPECT_EQ(22222, codec.clock_rate);
499 EXPECT_EQ(4, codec.num_channels);
zhihuang24366392017-03-08 17:15:06 -0800500 ASSERT_EQ(1u, codec.parameters.size());
501 EXPECT_EQ("bar", codec.parameters["foo"]);
502 EXPECT_EQ(1u, codec.rtcp_feedback.size());
503 EXPECT_EQ(RtcpFeedback(RtcpFeedbackType::TRANSPORT_CC),
504 codec.rtcp_feedback[0]);
505}
506
507TEST(RtpParametersConversionTest, ToVideoRtpCodecParameters) {
508 cricket::VideoCodec cricket_codec;
509 cricket_codec.name = "VID";
510 cricket_codec.id = 101;
511 cricket_codec.clockrate = 80000;
512 cricket_codec.params["foo"] = "bar";
513 cricket_codec.params["ANOTHER"] = "param";
514 cricket_codec.feedback_params.Add(cricket::FeedbackParam("transport-cc"));
515 cricket_codec.feedback_params.Add({"nack", "pli"});
516 RtpCodecParameters codec = ToRtpCodecParameters(cricket_codec);
517
518 EXPECT_EQ("VID", codec.name);
519 EXPECT_EQ(cricket::MEDIA_TYPE_VIDEO, codec.kind);
520 EXPECT_EQ(101, codec.payload_type);
Oskar Sundbomff610bd2017-11-16 10:57:44 +0100521 EXPECT_EQ(80000, codec.clock_rate);
zhihuang24366392017-03-08 17:15:06 -0800522 ASSERT_EQ(2u, codec.parameters.size());
523 EXPECT_EQ("bar", codec.parameters["foo"]);
524 EXPECT_EQ("param", codec.parameters["ANOTHER"]);
525 EXPECT_EQ(2u, codec.rtcp_feedback.size());
526 EXPECT_EQ(RtcpFeedback(RtcpFeedbackType::TRANSPORT_CC),
527 codec.rtcp_feedback[0]);
528 EXPECT_EQ(RtcpFeedback(RtcpFeedbackType::NACK, RtcpFeedbackMessageType::PLI),
529 codec.rtcp_feedback[1]);
530}
531
deadbeefe814a0d2017-02-25 18:15:09 -0800532// An unknown feedback param should just be ignored.
533TEST(RtpParametersConversionTest, ToRtpCodecCapabilityUnknownFeedbackParam) {
534 cricket::AudioCodec cricket_codec;
535 cricket_codec.name = "foo";
536 cricket_codec.id = 50;
537 cricket_codec.clockrate = 22222;
538 cricket_codec.channels = 4;
539 cricket_codec.params["foo"] = "bar";
540 cricket_codec.feedback_params.Add({"unknown", "param"});
541 cricket_codec.feedback_params.Add(cricket::FeedbackParam("transport-cc"));
542 RtpCodecCapability codec = ToRtpCodecCapability(cricket_codec);
543
544 ASSERT_EQ(1u, codec.rtcp_feedback.size());
545 EXPECT_EQ(RtcpFeedback(RtcpFeedbackType::TRANSPORT_CC),
546 codec.rtcp_feedback[0]);
547}
548
549// Most of ToRtpCapabilities is tested by ToRtpCodecCapability, but we need to
550// test that the result of ToRtpCodecCapability ends up in the result, and that
551// the "fec" list is assembled correctly.
552TEST(RtpParametersConversionTest, ToRtpCapabilities) {
553 cricket::VideoCodec vp8;
554 vp8.name = "VP8";
555 vp8.id = 101;
556 vp8.clockrate = 90000;
557
558 cricket::VideoCodec red;
559 red.name = "red";
560 red.id = 102;
561 red.clockrate = 90000;
562
563 cricket::VideoCodec ulpfec;
564 ulpfec.name = "ulpfec";
565 ulpfec.id = 103;
566 ulpfec.clockrate = 90000;
567
568 cricket::VideoCodec flexfec;
569 flexfec.name = "flexfec-03";
570 flexfec.id = 102;
571 flexfec.clockrate = 90000;
572
573 RtpCapabilities capabilities = ToRtpCapabilities<cricket::VideoCodec>(
574 {vp8, ulpfec}, {{"uri", 1}, {"uri2", 3}});
575 ASSERT_EQ(2u, capabilities.codecs.size());
576 EXPECT_EQ("VP8", capabilities.codecs[0].name);
577 EXPECT_EQ("ulpfec", capabilities.codecs[1].name);
578 ASSERT_EQ(2u, capabilities.header_extensions.size());
579 EXPECT_EQ("uri", capabilities.header_extensions[0].uri);
580 EXPECT_EQ(1, capabilities.header_extensions[0].preferred_id);
581 EXPECT_EQ("uri2", capabilities.header_extensions[1].uri);
582 EXPECT_EQ(3, capabilities.header_extensions[1].preferred_id);
583 EXPECT_EQ(0u, capabilities.fec.size());
584
585 capabilities = ToRtpCapabilities<cricket::VideoCodec>(
586 {vp8, red, ulpfec}, cricket::RtpHeaderExtensions());
587 EXPECT_EQ(3u, capabilities.codecs.size());
588 EXPECT_EQ(2u, capabilities.fec.size());
589 EXPECT_NE(capabilities.fec.end(),
590 std::find(capabilities.fec.begin(), capabilities.fec.end(),
591 FecMechanism::RED));
592 EXPECT_NE(capabilities.fec.end(),
593 std::find(capabilities.fec.begin(), capabilities.fec.end(),
594 FecMechanism::RED_AND_ULPFEC));
595
596 capabilities = ToRtpCapabilities<cricket::VideoCodec>(
597 {vp8, red, flexfec}, cricket::RtpHeaderExtensions());
598 EXPECT_EQ(3u, capabilities.codecs.size());
599 EXPECT_EQ(2u, capabilities.fec.size());
600 EXPECT_NE(capabilities.fec.end(),
601 std::find(capabilities.fec.begin(), capabilities.fec.end(),
602 FecMechanism::RED));
603 EXPECT_NE(capabilities.fec.end(),
604 std::find(capabilities.fec.begin(), capabilities.fec.end(),
605 FecMechanism::FLEXFEC));
606}
607
zhihuang24366392017-03-08 17:15:06 -0800608TEST(RtpParametersConversionTest, ToRtpParameters) {
609 cricket::VideoCodec vp8;
610 vp8.name = "VP8";
611 vp8.id = 101;
612 vp8.clockrate = 90000;
613
614 cricket::VideoCodec red;
615 red.name = "red";
616 red.id = 102;
617 red.clockrate = 90000;
618
619 cricket::VideoCodec ulpfec;
620 ulpfec.name = "ulpfec";
621 ulpfec.id = 103;
622 ulpfec.clockrate = 90000;
623
624 cricket::StreamParamsVec streams;
625 cricket::StreamParams stream;
626 stream.ssrcs.push_back(1234u);
627 streams.push_back(stream);
628
629 RtpParameters rtp_parameters = ToRtpParameters<cricket::VideoCodec>(
630 {vp8, red, ulpfec}, {{"uri", 1}, {"uri2", 3}}, streams);
631 ASSERT_EQ(3u, rtp_parameters.codecs.size());
632 EXPECT_EQ("VP8", rtp_parameters.codecs[0].name);
633 EXPECT_EQ("red", rtp_parameters.codecs[1].name);
634 EXPECT_EQ("ulpfec", rtp_parameters.codecs[2].name);
635 ASSERT_EQ(2u, rtp_parameters.header_extensions.size());
636 EXPECT_EQ("uri", rtp_parameters.header_extensions[0].uri);
637 EXPECT_EQ(1, rtp_parameters.header_extensions[0].id);
638 EXPECT_EQ("uri2", rtp_parameters.header_extensions[1].uri);
639 EXPECT_EQ(3, rtp_parameters.header_extensions[1].id);
640 ASSERT_EQ(1u, rtp_parameters.encodings.size());
641 EXPECT_EQ(1234u, rtp_parameters.encodings[0].ssrc);
642}
643
deadbeefe814a0d2017-02-25 18:15:09 -0800644} // namespace webrtc