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