blob: 257d26ebb50c3b8e6f25c99708a66137bf5c30c1 [file] [log] [blame]
deadbeefe814a0d2017-02-26 02:15:091/*
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 12:09:3313#include "pc/rtpparametersconversion.h"
Mirko Bonadei92ea95e2017-09-15 04:47:3114#include "rtc_base/gunit.h"
deadbeefe814a0d2017-02-26 02:15:0915
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 = {
Johannes Kron07ba2b92018-09-26 11:33:35282 {"http://example.com", 1},
283 {"urn:foo:bar", 14},
284 {"urn:first:two-byte-only:id", 15}};
deadbeefe814a0d2017-02-26 02:15:09285 auto result = ToCricketRtpHeaderExtensions(extensions);
286 ASSERT_TRUE(result.ok());
Johannes Kron07ba2b92018-09-26 11:33:35287 ASSERT_EQ(3u, result.value().size());
deadbeefe814a0d2017-02-26 02:15:09288 EXPECT_EQ("http://example.com", result.value()[0].uri);
289 EXPECT_EQ(1, result.value()[0].id);
290 EXPECT_EQ("urn:foo:bar", result.value()[1].uri);
291 EXPECT_EQ(14, result.value()[1].id);
Johannes Kron07ba2b92018-09-26 11:33:35292 EXPECT_EQ("urn:first:two-byte-only:id", result.value()[2].uri);
293 EXPECT_EQ(15, result.value()[2].id);
deadbeefe814a0d2017-02-26 02:15:09294}
295
296TEST(RtpParametersConversionTest, ToCricketRtpHeaderExtensionsErrors) {
Johannes Kron07ba2b92018-09-26 11:33:35297 // First, IDs outside the range 1-255.
deadbeefe814a0d2017-02-26 02:15:09298 std::vector<RtpHeaderExtensionParameters> extensions = {
299 {"http://example.com", 0}};
300 auto result = ToCricketRtpHeaderExtensions(extensions);
301 EXPECT_EQ(RTCErrorType::INVALID_RANGE, result.error().type());
302
Johannes Kron07ba2b92018-09-26 11:33:35303 extensions[0].id = 256;
deadbeefe814a0d2017-02-26 02:15:09304 result = ToCricketRtpHeaderExtensions(extensions);
305 EXPECT_EQ(RTCErrorType::INVALID_RANGE, result.error().type());
306
307 // Duplicate IDs.
308 extensions = {{"http://example.com", 1}, {"urn:foo:bar", 1}};
309 result = ToCricketRtpHeaderExtensions(extensions);
310 EXPECT_EQ(RTCErrorType::INVALID_PARAMETER, result.error().type());
311}
312
313TEST(RtpParametersConversionTest, ToCricketStreamParamsVecSimple) {
314 std::vector<RtpEncodingParameters> encodings;
315 RtpEncodingParameters encoding;
316 encoding.ssrc.emplace(0xbaadf00d);
317 encodings.push_back(encoding);
318 auto result = ToCricketStreamParamsVec(encodings);
319 ASSERT_TRUE(result.ok());
320 ASSERT_EQ(1u, result.value().size());
321 EXPECT_EQ(1u, result.value()[0].ssrcs.size());
322 EXPECT_EQ(0xbaadf00d, result.value()[0].first_ssrc());
323}
324
325TEST(RtpParametersConversionTest, ToCricketStreamParamsVecWithRtx) {
326 std::vector<RtpEncodingParameters> encodings;
327 RtpEncodingParameters encoding;
328 // Test a corner case SSRC of 0.
329 encoding.ssrc.emplace(0u);
330 encoding.rtx.emplace(0xdeadbeef);
331 encodings.push_back(encoding);
332 auto result = ToCricketStreamParamsVec(encodings);
333 ASSERT_TRUE(result.ok());
334 ASSERT_EQ(1u, result.value().size());
335 EXPECT_EQ(2u, result.value()[0].ssrcs.size());
336 EXPECT_EQ(0u, result.value()[0].first_ssrc());
337 uint32_t rtx_ssrc = 0;
338 EXPECT_TRUE(result.value()[0].GetFidSsrc(0u, &rtx_ssrc));
339 EXPECT_EQ(0xdeadbeef, rtx_ssrc);
340}
341
342// No encodings should be accepted; an endpoint may want to prepare a
343// decoder/encoder without having something to receive/send yet.
344TEST(RtpParametersConversionTest, ToCricketStreamParamsVecNoEncodings) {
345 std::vector<RtpEncodingParameters> encodings;
346 auto result = ToCricketStreamParamsVec(encodings);
347 ASSERT_TRUE(result.ok());
348 EXPECT_EQ(0u, result.value().size());
349}
350
351// An encoding without SSRCs should be accepted. This could be the case when
352// SSRCs aren't signaled and payload-type based demuxing is used.
353TEST(RtpParametersConversionTest, ToCricketStreamParamsVecMissingSsrcs) {
354 std::vector<RtpEncodingParameters> encodings = {{}};
355 // Creates RtxParameters with empty SSRC.
356 encodings[0].rtx.emplace();
357 auto result = ToCricketStreamParamsVec(encodings);
358 ASSERT_TRUE(result.ok());
359 EXPECT_EQ(0u, result.value().size());
360}
361
362// The media engine doesn't have a way of receiving an RTX SSRC that's known
363// with a primary SSRC that's unknown, so this should produce an error.
364TEST(RtpParametersConversionTest, ToStreamParamsWithPrimarySsrcSetAndRtxUnset) {
365 std::vector<RtpEncodingParameters> encodings = {{}};
366 encodings[0].rtx.emplace(0xdeadbeef);
367 EXPECT_EQ(RTCErrorType::UNSUPPORTED_PARAMETER,
368 ToCricketStreamParamsVec(encodings).error().type());
369}
370
371// TODO(deadbeef): Update this test when we support multiple encodings.
372TEST(RtpParametersConversionTest, ToCricketStreamParamsVecMultipleEncodings) {
373 std::vector<RtpEncodingParameters> encodings = {{}, {}};
374 auto result = ToCricketStreamParamsVec(encodings);
375 EXPECT_EQ(RTCErrorType::UNSUPPORTED_PARAMETER, result.error().type());
376}
377
378TEST(RtpParametersConversionTest, ToRtcpFeedback) {
Danil Chapovalov00c718362018-06-15 13:58:38379 absl::optional<RtcpFeedback> result = ToRtcpFeedback({"ccm", "fir"});
deadbeefe814a0d2017-02-26 02:15:09380 EXPECT_EQ(RtcpFeedback(RtcpFeedbackType::CCM, RtcpFeedbackMessageType::FIR),
381 *result);
382 result = ToRtcpFeedback(cricket::FeedbackParam("nack"));
383 EXPECT_EQ(RtcpFeedback(RtcpFeedbackType::NACK,
384 RtcpFeedbackMessageType::GENERIC_NACK),
385 *result);
386 result = ToRtcpFeedback({"nack", "pli"});
387 EXPECT_EQ(RtcpFeedback(RtcpFeedbackType::NACK, RtcpFeedbackMessageType::PLI),
388 *result);
389 result = ToRtcpFeedback(cricket::FeedbackParam("goog-remb"));
390 EXPECT_EQ(RtcpFeedback(RtcpFeedbackType::REMB), *result);
391 result = ToRtcpFeedback(cricket::FeedbackParam("transport-cc"));
392 EXPECT_EQ(RtcpFeedback(RtcpFeedbackType::TRANSPORT_CC), *result);
393}
394
395TEST(RtpParametersConversionTest, ToRtcpFeedbackErrors) {
396 // CCM with missing or invalid message type.
Danil Chapovalov00c718362018-06-15 13:58:38397 absl::optional<RtcpFeedback> result = ToRtcpFeedback({"ccm", "pli"});
deadbeefe814a0d2017-02-26 02:15:09398 EXPECT_FALSE(result);
399 result = ToRtcpFeedback(cricket::FeedbackParam("ccm"));
400 EXPECT_FALSE(result);
401 // NACK with missing or invalid message type.
402 result = ToRtcpFeedback({"nack", "fir"});
403 EXPECT_FALSE(result);
404 // REMB with message type (should be left empty).
405 result = ToRtcpFeedback({"goog-remb", "pli"});
406 EXPECT_FALSE(result);
407 // TRANSPORT_CC with message type (should be left empty).
408 result = ToRtcpFeedback({"transport-cc", "fir"});
409 EXPECT_FALSE(result);
410 // Unknown message type.
411 result = ToRtcpFeedback(cricket::FeedbackParam("foo"));
412 EXPECT_FALSE(result);
413}
414
415TEST(RtpParametersConversionTest, ToAudioRtpCodecCapability) {
416 cricket::AudioCodec cricket_codec;
417 cricket_codec.name = "foo";
418 cricket_codec.id = 50;
419 cricket_codec.clockrate = 22222;
420 cricket_codec.channels = 4;
421 cricket_codec.params["foo"] = "bar";
422 cricket_codec.feedback_params.Add(cricket::FeedbackParam("transport-cc"));
423 RtpCodecCapability codec = ToRtpCodecCapability(cricket_codec);
424
425 EXPECT_EQ("foo", codec.name);
426 EXPECT_EQ(cricket::MEDIA_TYPE_AUDIO, codec.kind);
Oskar Sundbomff610bd2017-11-16 09:57:44427 EXPECT_EQ(50, codec.preferred_payload_type);
428 EXPECT_EQ(22222, codec.clock_rate);
429 EXPECT_EQ(4, codec.num_channels);
deadbeefe814a0d2017-02-26 02:15:09430 ASSERT_EQ(1u, codec.parameters.size());
431 EXPECT_EQ("bar", codec.parameters["foo"]);
432 EXPECT_EQ(1u, codec.rtcp_feedback.size());
433 EXPECT_EQ(RtcpFeedback(RtcpFeedbackType::TRANSPORT_CC),
434 codec.rtcp_feedback[0]);
435}
436
437TEST(RtpParametersConversionTest, ToVideoRtpCodecCapability) {
438 cricket::VideoCodec cricket_codec;
439 cricket_codec.name = "VID";
440 cricket_codec.id = 101;
441 cricket_codec.clockrate = 80000;
442 cricket_codec.params["foo"] = "bar";
443 cricket_codec.params["ANOTHER"] = "param";
444 cricket_codec.feedback_params.Add(cricket::FeedbackParam("transport-cc"));
445 cricket_codec.feedback_params.Add({"nack", "pli"});
446 RtpCodecCapability codec = ToRtpCodecCapability(cricket_codec);
447
448 EXPECT_EQ("VID", codec.name);
449 EXPECT_EQ(cricket::MEDIA_TYPE_VIDEO, codec.kind);
Oskar Sundbomff610bd2017-11-16 09:57:44450 EXPECT_EQ(101, codec.preferred_payload_type);
451 EXPECT_EQ(80000, codec.clock_rate);
deadbeefe814a0d2017-02-26 02:15:09452 ASSERT_EQ(2u, codec.parameters.size());
453 EXPECT_EQ("bar", codec.parameters["foo"]);
454 EXPECT_EQ("param", codec.parameters["ANOTHER"]);
455 EXPECT_EQ(2u, codec.rtcp_feedback.size());
456 EXPECT_EQ(RtcpFeedback(RtcpFeedbackType::TRANSPORT_CC),
457 codec.rtcp_feedback[0]);
458 EXPECT_EQ(RtcpFeedback(RtcpFeedbackType::NACK, RtcpFeedbackMessageType::PLI),
459 codec.rtcp_feedback[1]);
460}
461
zhihuang24366392017-03-09 01:15:06462TEST(RtpParametersConversionTest, ToRtpEncodingsWithEmptyStreamParamsVec) {
463 cricket::StreamParamsVec streams;
464 auto rtp_encodings = ToRtpEncodings(streams);
465 ASSERT_EQ(0u, rtp_encodings.size());
466}
467
468TEST(RtpParametersConversionTest, ToRtpEncodingsWithMultipleStreamParams) {
469 cricket::StreamParamsVec streams;
470 cricket::StreamParams stream1;
471 stream1.ssrcs.push_back(1111u);
472 stream1.AddFidSsrc(1111u, 0xaaaaaaaa);
473
474 cricket::StreamParams stream2;
475 stream2.ssrcs.push_back(2222u);
476 stream2.AddFidSsrc(2222u, 0xaaaaaaab);
477
478 streams.push_back(stream1);
479 streams.push_back(stream2);
480
481 auto rtp_encodings = ToRtpEncodings(streams);
482 ASSERT_EQ(2u, rtp_encodings.size());
483 EXPECT_EQ(1111u, rtp_encodings[0].ssrc);
484 EXPECT_EQ(0xaaaaaaaa, rtp_encodings[0].rtx->ssrc);
485 EXPECT_EQ(2222u, rtp_encodings[1].ssrc);
486 EXPECT_EQ(0xaaaaaaab, rtp_encodings[1].rtx->ssrc);
487}
488
489TEST(RtpParametersConversionTest, ToAudioRtpCodecParameters) {
490 cricket::AudioCodec cricket_codec;
491 cricket_codec.name = "foo";
492 cricket_codec.id = 50;
493 cricket_codec.clockrate = 22222;
494 cricket_codec.channels = 4;
495 cricket_codec.params["foo"] = "bar";
496 cricket_codec.feedback_params.Add(cricket::FeedbackParam("transport-cc"));
497 RtpCodecParameters codec = ToRtpCodecParameters(cricket_codec);
498
499 EXPECT_EQ("foo", codec.name);
500 EXPECT_EQ(cricket::MEDIA_TYPE_AUDIO, codec.kind);
501 EXPECT_EQ(50, codec.payload_type);
Oskar Sundbomff610bd2017-11-16 09:57:44502 EXPECT_EQ(22222, codec.clock_rate);
503 EXPECT_EQ(4, codec.num_channels);
zhihuang24366392017-03-09 01:15:06504 ASSERT_EQ(1u, codec.parameters.size());
505 EXPECT_EQ("bar", codec.parameters["foo"]);
506 EXPECT_EQ(1u, codec.rtcp_feedback.size());
507 EXPECT_EQ(RtcpFeedback(RtcpFeedbackType::TRANSPORT_CC),
508 codec.rtcp_feedback[0]);
509}
510
511TEST(RtpParametersConversionTest, ToVideoRtpCodecParameters) {
512 cricket::VideoCodec cricket_codec;
513 cricket_codec.name = "VID";
514 cricket_codec.id = 101;
515 cricket_codec.clockrate = 80000;
516 cricket_codec.params["foo"] = "bar";
517 cricket_codec.params["ANOTHER"] = "param";
518 cricket_codec.feedback_params.Add(cricket::FeedbackParam("transport-cc"));
519 cricket_codec.feedback_params.Add({"nack", "pli"});
520 RtpCodecParameters codec = ToRtpCodecParameters(cricket_codec);
521
522 EXPECT_EQ("VID", codec.name);
523 EXPECT_EQ(cricket::MEDIA_TYPE_VIDEO, codec.kind);
524 EXPECT_EQ(101, codec.payload_type);
Oskar Sundbomff610bd2017-11-16 09:57:44525 EXPECT_EQ(80000, codec.clock_rate);
zhihuang24366392017-03-09 01:15:06526 ASSERT_EQ(2u, codec.parameters.size());
527 EXPECT_EQ("bar", codec.parameters["foo"]);
528 EXPECT_EQ("param", codec.parameters["ANOTHER"]);
529 EXPECT_EQ(2u, codec.rtcp_feedback.size());
530 EXPECT_EQ(RtcpFeedback(RtcpFeedbackType::TRANSPORT_CC),
531 codec.rtcp_feedback[0]);
532 EXPECT_EQ(RtcpFeedback(RtcpFeedbackType::NACK, RtcpFeedbackMessageType::PLI),
533 codec.rtcp_feedback[1]);
534}
535
deadbeefe814a0d2017-02-26 02:15:09536// An unknown feedback param should just be ignored.
537TEST(RtpParametersConversionTest, ToRtpCodecCapabilityUnknownFeedbackParam) {
538 cricket::AudioCodec cricket_codec;
539 cricket_codec.name = "foo";
540 cricket_codec.id = 50;
541 cricket_codec.clockrate = 22222;
542 cricket_codec.channels = 4;
543 cricket_codec.params["foo"] = "bar";
544 cricket_codec.feedback_params.Add({"unknown", "param"});
545 cricket_codec.feedback_params.Add(cricket::FeedbackParam("transport-cc"));
546 RtpCodecCapability codec = ToRtpCodecCapability(cricket_codec);
547
548 ASSERT_EQ(1u, codec.rtcp_feedback.size());
549 EXPECT_EQ(RtcpFeedback(RtcpFeedbackType::TRANSPORT_CC),
550 codec.rtcp_feedback[0]);
551}
552
553// Most of ToRtpCapabilities is tested by ToRtpCodecCapability, but we need to
554// test that the result of ToRtpCodecCapability ends up in the result, and that
555// the "fec" list is assembled correctly.
556TEST(RtpParametersConversionTest, ToRtpCapabilities) {
557 cricket::VideoCodec vp8;
558 vp8.name = "VP8";
559 vp8.id = 101;
560 vp8.clockrate = 90000;
561
562 cricket::VideoCodec red;
563 red.name = "red";
564 red.id = 102;
565 red.clockrate = 90000;
566
567 cricket::VideoCodec ulpfec;
568 ulpfec.name = "ulpfec";
569 ulpfec.id = 103;
570 ulpfec.clockrate = 90000;
571
572 cricket::VideoCodec flexfec;
573 flexfec.name = "flexfec-03";
574 flexfec.id = 102;
575 flexfec.clockrate = 90000;
576
577 RtpCapabilities capabilities = ToRtpCapabilities<cricket::VideoCodec>(
578 {vp8, ulpfec}, {{"uri", 1}, {"uri2", 3}});
579 ASSERT_EQ(2u, capabilities.codecs.size());
580 EXPECT_EQ("VP8", capabilities.codecs[0].name);
581 EXPECT_EQ("ulpfec", capabilities.codecs[1].name);
582 ASSERT_EQ(2u, capabilities.header_extensions.size());
583 EXPECT_EQ("uri", capabilities.header_extensions[0].uri);
584 EXPECT_EQ(1, capabilities.header_extensions[0].preferred_id);
585 EXPECT_EQ("uri2", capabilities.header_extensions[1].uri);
586 EXPECT_EQ(3, capabilities.header_extensions[1].preferred_id);
587 EXPECT_EQ(0u, capabilities.fec.size());
588
589 capabilities = ToRtpCapabilities<cricket::VideoCodec>(
590 {vp8, red, ulpfec}, cricket::RtpHeaderExtensions());
591 EXPECT_EQ(3u, capabilities.codecs.size());
592 EXPECT_EQ(2u, capabilities.fec.size());
593 EXPECT_NE(capabilities.fec.end(),
594 std::find(capabilities.fec.begin(), capabilities.fec.end(),
595 FecMechanism::RED));
596 EXPECT_NE(capabilities.fec.end(),
597 std::find(capabilities.fec.begin(), capabilities.fec.end(),
598 FecMechanism::RED_AND_ULPFEC));
599
600 capabilities = ToRtpCapabilities<cricket::VideoCodec>(
601 {vp8, red, flexfec}, cricket::RtpHeaderExtensions());
602 EXPECT_EQ(3u, capabilities.codecs.size());
603 EXPECT_EQ(2u, capabilities.fec.size());
604 EXPECT_NE(capabilities.fec.end(),
605 std::find(capabilities.fec.begin(), capabilities.fec.end(),
606 FecMechanism::RED));
607 EXPECT_NE(capabilities.fec.end(),
608 std::find(capabilities.fec.begin(), capabilities.fec.end(),
609 FecMechanism::FLEXFEC));
610}
611
zhihuang24366392017-03-09 01:15:06612TEST(RtpParametersConversionTest, ToRtpParameters) {
613 cricket::VideoCodec vp8;
614 vp8.name = "VP8";
615 vp8.id = 101;
616 vp8.clockrate = 90000;
617
618 cricket::VideoCodec red;
619 red.name = "red";
620 red.id = 102;
621 red.clockrate = 90000;
622
623 cricket::VideoCodec ulpfec;
624 ulpfec.name = "ulpfec";
625 ulpfec.id = 103;
626 ulpfec.clockrate = 90000;
627
628 cricket::StreamParamsVec streams;
629 cricket::StreamParams stream;
630 stream.ssrcs.push_back(1234u);
631 streams.push_back(stream);
632
633 RtpParameters rtp_parameters = ToRtpParameters<cricket::VideoCodec>(
634 {vp8, red, ulpfec}, {{"uri", 1}, {"uri2", 3}}, streams);
635 ASSERT_EQ(3u, rtp_parameters.codecs.size());
636 EXPECT_EQ("VP8", rtp_parameters.codecs[0].name);
637 EXPECT_EQ("red", rtp_parameters.codecs[1].name);
638 EXPECT_EQ("ulpfec", rtp_parameters.codecs[2].name);
639 ASSERT_EQ(2u, rtp_parameters.header_extensions.size());
640 EXPECT_EQ("uri", rtp_parameters.header_extensions[0].uri);
641 EXPECT_EQ(1, rtp_parameters.header_extensions[0].id);
642 EXPECT_EQ("uri2", rtp_parameters.header_extensions[1].uri);
643 EXPECT_EQ(3, rtp_parameters.header_extensions[1].id);
644 ASSERT_EQ(1u, rtp_parameters.encodings.size());
645 EXPECT_EQ(1234u, rtp_parameters.encodings[0].ssrc);
646}
647
deadbeefe814a0d2017-02-26 02:15:09648} // namespace webrtc