blob: 99d976abcd2a9acb5b0e1e86fe52272b99f82ba7 [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
Jonas Olssona4d87372019-07-05 19:08:33 +020011#include "pc/rtp_parameters_conversion.h"
12
deadbeefe814a0d2017-02-25 18:15:09 -080013#include <algorithm>
14
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020015#include "rtc_base/gunit.h"
Steve Anton64b626b2019-01-28 17:25:26 -080016#include "test/gmock.h"
17
18using ::testing::UnorderedElementsAre;
deadbeefe814a0d2017-02-25 18:15:09 -080019
20namespace webrtc {
21
22TEST(RtpParametersConversionTest, ToCricketFeedbackParam) {
23 auto result = ToCricketFeedbackParam(
24 {RtcpFeedbackType::CCM, RtcpFeedbackMessageType::FIR});
25 EXPECT_EQ(cricket::FeedbackParam("ccm", "fir"), result.value());
Elad Alonfadb1812019-05-24 13:40:02 +020026
27 result = ToCricketFeedbackParam(RtcpFeedback(RtcpFeedbackType::LNTF));
28 EXPECT_EQ(cricket::FeedbackParam("goog-lntf"), result.value());
29
deadbeefe814a0d2017-02-25 18:15:09 -080030 result = ToCricketFeedbackParam(
31 {RtcpFeedbackType::NACK, RtcpFeedbackMessageType::GENERIC_NACK});
32 EXPECT_EQ(cricket::FeedbackParam("nack"), result.value());
Elad Alonfadb1812019-05-24 13:40:02 +020033
deadbeefe814a0d2017-02-25 18:15:09 -080034 result = ToCricketFeedbackParam(
35 {RtcpFeedbackType::NACK, RtcpFeedbackMessageType::PLI});
36 EXPECT_EQ(cricket::FeedbackParam("nack", "pli"), result.value());
Elad Alonfadb1812019-05-24 13:40:02 +020037
deadbeefe814a0d2017-02-25 18:15:09 -080038 result = ToCricketFeedbackParam(RtcpFeedback(RtcpFeedbackType::REMB));
39 EXPECT_EQ(cricket::FeedbackParam("goog-remb"), result.value());
Elad Alonfadb1812019-05-24 13:40:02 +020040
deadbeefe814a0d2017-02-25 18:15:09 -080041 result = ToCricketFeedbackParam(RtcpFeedback(RtcpFeedbackType::TRANSPORT_CC));
42 EXPECT_EQ(cricket::FeedbackParam("transport-cc"), result.value());
43}
44
45TEST(RtpParametersConversionTest, ToCricketFeedbackParamErrors) {
46 // CCM with missing or invalid message type.
47 auto result = ToCricketFeedbackParam(RtcpFeedback(RtcpFeedbackType::CCM));
48 EXPECT_EQ(RTCErrorType::INVALID_PARAMETER, result.error().type());
Elad Alonfadb1812019-05-24 13:40:02 +020049
deadbeefe814a0d2017-02-25 18:15:09 -080050 result = ToCricketFeedbackParam(
51 {RtcpFeedbackType::CCM, RtcpFeedbackMessageType::PLI});
52 EXPECT_EQ(RTCErrorType::INVALID_PARAMETER, result.error().type());
Elad Alonfadb1812019-05-24 13:40:02 +020053
54 // LNTF with message type (should be left empty).
55 result = ToCricketFeedbackParam(
56 {RtcpFeedbackType::LNTF, RtcpFeedbackMessageType::GENERIC_NACK});
57 EXPECT_EQ(RTCErrorType::INVALID_PARAMETER, result.error().type());
58
deadbeefe814a0d2017-02-25 18:15:09 -080059 // NACK with missing or invalid message type.
60 result = ToCricketFeedbackParam(RtcpFeedback(RtcpFeedbackType::NACK));
61 EXPECT_EQ(RTCErrorType::INVALID_PARAMETER, result.error().type());
Elad Alonfadb1812019-05-24 13:40:02 +020062
deadbeefe814a0d2017-02-25 18:15:09 -080063 result = ToCricketFeedbackParam(
64 {RtcpFeedbackType::NACK, RtcpFeedbackMessageType::FIR});
65 EXPECT_EQ(RTCErrorType::INVALID_PARAMETER, result.error().type());
Elad Alonfadb1812019-05-24 13:40:02 +020066
deadbeefe814a0d2017-02-25 18:15:09 -080067 // REMB with message type (should be left empty).
68 result = ToCricketFeedbackParam(
69 {RtcpFeedbackType::REMB, RtcpFeedbackMessageType::GENERIC_NACK});
70 EXPECT_EQ(RTCErrorType::INVALID_PARAMETER, result.error().type());
Elad Alonfadb1812019-05-24 13:40:02 +020071
deadbeefe814a0d2017-02-25 18:15:09 -080072 // TRANSPORT_CC with message type (should be left empty).
73 result = ToCricketFeedbackParam(
74 {RtcpFeedbackType::TRANSPORT_CC, RtcpFeedbackMessageType::FIR});
75 EXPECT_EQ(RTCErrorType::INVALID_PARAMETER, result.error().type());
76}
77
78TEST(RtpParametersConversionTest, ToAudioCodec) {
79 RtpCodecParameters codec;
80 codec.name = "AuDiO";
81 codec.kind = cricket::MEDIA_TYPE_AUDIO;
82 codec.payload_type = 120;
83 codec.clock_rate.emplace(36000);
84 codec.num_channels.emplace(6);
85 codec.parameters["foo"] = "bar";
86 codec.rtcp_feedback.emplace_back(RtcpFeedbackType::TRANSPORT_CC);
87 auto result = ToCricketCodec<cricket::AudioCodec>(codec);
88 ASSERT_TRUE(result.ok());
89
90 EXPECT_EQ("AuDiO", result.value().name);
91 EXPECT_EQ(120, result.value().id);
92 EXPECT_EQ(36000, result.value().clockrate);
93 EXPECT_EQ(6u, result.value().channels);
94 ASSERT_EQ(1u, result.value().params.size());
95 EXPECT_EQ("bar", result.value().params["foo"]);
96 EXPECT_EQ(1u, result.value().feedback_params.params().size());
97 EXPECT_TRUE(result.value().feedback_params.Has(
98 cricket::FeedbackParam("transport-cc")));
99}
100
101TEST(RtpParametersConversionTest, ToVideoCodec) {
102 RtpCodecParameters codec;
103 codec.name = "coolcodec";
104 codec.kind = cricket::MEDIA_TYPE_VIDEO;
105 codec.payload_type = 101;
106 codec.clock_rate.emplace(90000);
107 codec.parameters["foo"] = "bar";
108 codec.parameters["PING"] = "PONG";
Elad Alonfadb1812019-05-24 13:40:02 +0200109 codec.rtcp_feedback.emplace_back(RtcpFeedbackType::LNTF);
deadbeefe814a0d2017-02-25 18:15:09 -0800110 codec.rtcp_feedback.emplace_back(RtcpFeedbackType::TRANSPORT_CC);
111 codec.rtcp_feedback.emplace_back(RtcpFeedbackType::NACK,
112 RtcpFeedbackMessageType::PLI);
113 auto result = ToCricketCodec<cricket::VideoCodec>(codec);
114 ASSERT_TRUE(result.ok());
115
116 EXPECT_EQ("coolcodec", result.value().name);
117 EXPECT_EQ(101, result.value().id);
118 EXPECT_EQ(90000, result.value().clockrate);
119 ASSERT_EQ(2u, result.value().params.size());
120 EXPECT_EQ("bar", result.value().params["foo"]);
121 EXPECT_EQ("PONG", result.value().params["PING"]);
Elad Alonfadb1812019-05-24 13:40:02 +0200122 EXPECT_EQ(3u, result.value().feedback_params.params().size());
123 EXPECT_TRUE(
124 result.value().feedback_params.Has(cricket::FeedbackParam("goog-lntf")));
deadbeefe814a0d2017-02-25 18:15:09 -0800125 EXPECT_TRUE(result.value().feedback_params.Has(
126 cricket::FeedbackParam("transport-cc")));
127 EXPECT_TRUE(result.value().feedback_params.Has(
128 cricket::FeedbackParam("nack", "pli")));
129}
130
131// Trying to convert to an AudioCodec if the kind is "video" should fail.
132TEST(RtpParametersConversionTest, ToCricketCodecInvalidKind) {
133 RtpCodecParameters audio_codec;
134 audio_codec.name = "opus";
135 audio_codec.kind = cricket::MEDIA_TYPE_VIDEO;
136 audio_codec.payload_type = 111;
137 audio_codec.clock_rate.emplace(48000);
138 audio_codec.num_channels.emplace(2);
139
140 RtpCodecParameters video_codec;
141 video_codec.name = "VP8";
142 video_codec.kind = cricket::MEDIA_TYPE_AUDIO;
143 video_codec.payload_type = 102;
144 video_codec.clock_rate.emplace(90000);
145
146 auto audio_result = ToCricketCodec<cricket::AudioCodec>(audio_codec);
147 EXPECT_EQ(RTCErrorType::INVALID_PARAMETER, audio_result.error().type());
148
149 auto video_result = ToCricketCodec<cricket::VideoCodec>(video_codec);
150 EXPECT_EQ(RTCErrorType::INVALID_PARAMETER, video_result.error().type());
151
152 // Sanity check that if the kind is correct, the conversion succeeds.
153 audio_codec.kind = cricket::MEDIA_TYPE_AUDIO;
154 video_codec.kind = cricket::MEDIA_TYPE_VIDEO;
155 audio_result = ToCricketCodec<cricket::AudioCodec>(audio_codec);
156 EXPECT_TRUE(audio_result.ok());
157 video_result = ToCricketCodec<cricket::VideoCodec>(video_codec);
158 EXPECT_TRUE(video_result.ok());
159}
160
161TEST(RtpParametersConversionTest, ToAudioCodecInvalidParameters) {
162 // Missing channels.
163 RtpCodecParameters codec;
164 codec.name = "opus";
165 codec.kind = cricket::MEDIA_TYPE_AUDIO;
166 codec.payload_type = 111;
167 codec.clock_rate.emplace(48000);
168 auto result = ToCricketCodec<cricket::AudioCodec>(codec);
169 EXPECT_EQ(RTCErrorType::INVALID_PARAMETER, result.error().type());
170
171 // Negative number of channels.
172 codec.num_channels.emplace(-1);
173 result = ToCricketCodec<cricket::AudioCodec>(codec);
174 EXPECT_EQ(RTCErrorType::INVALID_RANGE, result.error().type());
175
176 // Missing clock rate.
177 codec.num_channels.emplace(2);
178 codec.clock_rate.reset();
179 result = ToCricketCodec<cricket::AudioCodec>(codec);
180 EXPECT_EQ(RTCErrorType::INVALID_PARAMETER, result.error().type());
181
182 // Negative clock rate.
183 codec.clock_rate.emplace(-48000);
184 result = ToCricketCodec<cricket::AudioCodec>(codec);
185 EXPECT_EQ(RTCErrorType::INVALID_RANGE, result.error().type());
186
187 // Sanity check that conversion succeeds if these errors are fixed.
188 codec.clock_rate.emplace(48000);
189 result = ToCricketCodec<cricket::AudioCodec>(codec);
190 EXPECT_TRUE(result.ok());
191}
192
193TEST(RtpParametersConversionTest, ToVideoCodecInvalidParameters) {
194 // Missing clock rate.
195 RtpCodecParameters codec;
196 codec.name = "VP8";
197 codec.kind = cricket::MEDIA_TYPE_VIDEO;
198 codec.payload_type = 102;
199 auto result = ToCricketCodec<cricket::VideoCodec>(codec);
200 EXPECT_EQ(RTCErrorType::INVALID_PARAMETER, result.error().type());
201
202 // Invalid clock rate.
203 codec.clock_rate.emplace(48000);
204 result = ToCricketCodec<cricket::VideoCodec>(codec);
205 EXPECT_EQ(RTCErrorType::INVALID_PARAMETER, result.error().type());
206
207 // Channels set (should be unset).
208 codec.clock_rate.emplace(90000);
209 codec.num_channels.emplace(2);
210 result = ToCricketCodec<cricket::VideoCodec>(codec);
211 EXPECT_EQ(RTCErrorType::INVALID_PARAMETER, result.error().type());
212
213 // Sanity check that conversion succeeds if these errors are fixed.
214 codec.num_channels.reset();
215 result = ToCricketCodec<cricket::VideoCodec>(codec);
216 EXPECT_TRUE(result.ok());
217}
218
219TEST(RtpParametersConversionTest, ToCricketCodecInvalidPayloadType) {
220 RtpCodecParameters codec;
221 codec.name = "VP8";
222 codec.kind = cricket::MEDIA_TYPE_VIDEO;
223 codec.clock_rate.emplace(90000);
224
225 codec.payload_type = -1000;
226 auto result = ToCricketCodec<cricket::VideoCodec>(codec);
227 EXPECT_EQ(RTCErrorType::INVALID_RANGE, result.error().type());
228
229 // Max payload type is 127.
230 codec.payload_type = 128;
231 result = ToCricketCodec<cricket::VideoCodec>(codec);
232 EXPECT_EQ(RTCErrorType::INVALID_RANGE, result.error().type());
233
234 // Sanity check that conversion succeeds with a valid payload type.
235 codec.payload_type = 127;
236 result = ToCricketCodec<cricket::VideoCodec>(codec);
237 EXPECT_TRUE(result.ok());
238}
239
240// There are already tests for ToCricketFeedbackParam, but ensure that those
241// errors are propagated from ToCricketCodec.
242TEST(RtpParametersConversionTest, ToCricketCodecInvalidRtcpFeedback) {
243 RtpCodecParameters codec;
244 codec.name = "VP8";
245 codec.kind = cricket::MEDIA_TYPE_VIDEO;
246 codec.clock_rate.emplace(90000);
247 codec.payload_type = 99;
248 codec.rtcp_feedback.emplace_back(RtcpFeedbackType::CCM,
249 RtcpFeedbackMessageType::PLI);
250
251 auto result = ToCricketCodec<cricket::VideoCodec>(codec);
252 EXPECT_EQ(RTCErrorType::INVALID_PARAMETER, result.error().type());
253
254 // Sanity check that conversion succeeds without invalid feedback.
255 codec.rtcp_feedback.clear();
256 result = ToCricketCodec<cricket::VideoCodec>(codec);
257 EXPECT_TRUE(result.ok());
258}
259
260TEST(RtpParametersConversionTest, ToCricketCodecs) {
261 std::vector<RtpCodecParameters> codecs;
262 RtpCodecParameters codec;
263 codec.name = "VP8";
264 codec.kind = cricket::MEDIA_TYPE_VIDEO;
265 codec.clock_rate.emplace(90000);
266 codec.payload_type = 99;
267 codecs.push_back(codec);
268
269 codec.name = "VP9";
270 codec.payload_type = 100;
271 codecs.push_back(codec);
272
273 auto result = ToCricketCodecs<cricket::VideoCodec>(codecs);
274 ASSERT_TRUE(result.ok());
275 ASSERT_EQ(2u, result.value().size());
276 EXPECT_EQ("VP8", result.value()[0].name);
277 EXPECT_EQ(99, result.value()[0].id);
278 EXPECT_EQ("VP9", result.value()[1].name);
279 EXPECT_EQ(100, result.value()[1].id);
280}
281
282TEST(RtpParametersConversionTest, ToCricketCodecsDuplicatePayloadType) {
283 std::vector<RtpCodecParameters> codecs;
284 RtpCodecParameters codec;
285 codec.name = "VP8";
286 codec.kind = cricket::MEDIA_TYPE_VIDEO;
287 codec.clock_rate.emplace(90000);
288 codec.payload_type = 99;
289 codecs.push_back(codec);
290
291 codec.name = "VP9";
292 codec.payload_type = 99;
293 codecs.push_back(codec);
294
295 auto result = ToCricketCodecs<cricket::VideoCodec>(codecs);
296 EXPECT_EQ(RTCErrorType::INVALID_PARAMETER, result.error().type());
297
298 // Sanity check that this succeeds without the duplicate payload type.
299 codecs[1].payload_type = 120;
300 result = ToCricketCodecs<cricket::VideoCodec>(codecs);
301 EXPECT_TRUE(result.ok());
302}
303
deadbeefe814a0d2017-02-25 18:15:09 -0800304TEST(RtpParametersConversionTest, ToCricketStreamParamsVecSimple) {
305 std::vector<RtpEncodingParameters> encodings;
306 RtpEncodingParameters encoding;
307 encoding.ssrc.emplace(0xbaadf00d);
308 encodings.push_back(encoding);
309 auto result = ToCricketStreamParamsVec(encodings);
310 ASSERT_TRUE(result.ok());
311 ASSERT_EQ(1u, result.value().size());
312 EXPECT_EQ(1u, result.value()[0].ssrcs.size());
313 EXPECT_EQ(0xbaadf00d, result.value()[0].first_ssrc());
314}
315
deadbeefe814a0d2017-02-25 18:15:09 -0800316// No encodings should be accepted; an endpoint may want to prepare a
317// decoder/encoder without having something to receive/send yet.
318TEST(RtpParametersConversionTest, ToCricketStreamParamsVecNoEncodings) {
319 std::vector<RtpEncodingParameters> encodings;
320 auto result = ToCricketStreamParamsVec(encodings);
321 ASSERT_TRUE(result.ok());
322 EXPECT_EQ(0u, result.value().size());
323}
324
325// An encoding without SSRCs should be accepted. This could be the case when
326// SSRCs aren't signaled and payload-type based demuxing is used.
327TEST(RtpParametersConversionTest, ToCricketStreamParamsVecMissingSsrcs) {
328 std::vector<RtpEncodingParameters> encodings = {{}};
329 // Creates RtxParameters with empty SSRC.
deadbeefe814a0d2017-02-25 18:15:09 -0800330 auto result = ToCricketStreamParamsVec(encodings);
331 ASSERT_TRUE(result.ok());
332 EXPECT_EQ(0u, result.value().size());
333}
334
deadbeefe814a0d2017-02-25 18:15:09 -0800335// TODO(deadbeef): Update this test when we support multiple encodings.
336TEST(RtpParametersConversionTest, ToCricketStreamParamsVecMultipleEncodings) {
337 std::vector<RtpEncodingParameters> encodings = {{}, {}};
338 auto result = ToCricketStreamParamsVec(encodings);
339 EXPECT_EQ(RTCErrorType::UNSUPPORTED_PARAMETER, result.error().type());
340}
341
342TEST(RtpParametersConversionTest, ToRtcpFeedback) {
Danil Chapovalov00c71832018-06-15 15:58:38 +0200343 absl::optional<RtcpFeedback> result = ToRtcpFeedback({"ccm", "fir"});
deadbeefe814a0d2017-02-25 18:15:09 -0800344 EXPECT_EQ(RtcpFeedback(RtcpFeedbackType::CCM, RtcpFeedbackMessageType::FIR),
345 *result);
Elad Alonfadb1812019-05-24 13:40:02 +0200346
347 result = ToRtcpFeedback(cricket::FeedbackParam("goog-lntf"));
348 EXPECT_EQ(RtcpFeedback(RtcpFeedbackType::LNTF), *result);
349
deadbeefe814a0d2017-02-25 18:15:09 -0800350 result = ToRtcpFeedback(cricket::FeedbackParam("nack"));
351 EXPECT_EQ(RtcpFeedback(RtcpFeedbackType::NACK,
352 RtcpFeedbackMessageType::GENERIC_NACK),
353 *result);
Elad Alonfadb1812019-05-24 13:40:02 +0200354
deadbeefe814a0d2017-02-25 18:15:09 -0800355 result = ToRtcpFeedback({"nack", "pli"});
356 EXPECT_EQ(RtcpFeedback(RtcpFeedbackType::NACK, RtcpFeedbackMessageType::PLI),
357 *result);
Elad Alonfadb1812019-05-24 13:40:02 +0200358
deadbeefe814a0d2017-02-25 18:15:09 -0800359 result = ToRtcpFeedback(cricket::FeedbackParam("goog-remb"));
360 EXPECT_EQ(RtcpFeedback(RtcpFeedbackType::REMB), *result);
Elad Alonfadb1812019-05-24 13:40:02 +0200361
deadbeefe814a0d2017-02-25 18:15:09 -0800362 result = ToRtcpFeedback(cricket::FeedbackParam("transport-cc"));
363 EXPECT_EQ(RtcpFeedback(RtcpFeedbackType::TRANSPORT_CC), *result);
364}
365
366TEST(RtpParametersConversionTest, ToRtcpFeedbackErrors) {
367 // CCM with missing or invalid message type.
Danil Chapovalov00c71832018-06-15 15:58:38 +0200368 absl::optional<RtcpFeedback> result = ToRtcpFeedback({"ccm", "pli"});
deadbeefe814a0d2017-02-25 18:15:09 -0800369 EXPECT_FALSE(result);
Elad Alonfadb1812019-05-24 13:40:02 +0200370
deadbeefe814a0d2017-02-25 18:15:09 -0800371 result = ToRtcpFeedback(cricket::FeedbackParam("ccm"));
372 EXPECT_FALSE(result);
Elad Alonfadb1812019-05-24 13:40:02 +0200373
374 // LNTF with message type (should be left empty).
375 result = ToRtcpFeedback({"goog-lntf", "pli"});
376 EXPECT_FALSE(result);
377
deadbeefe814a0d2017-02-25 18:15:09 -0800378 // NACK with missing or invalid message type.
379 result = ToRtcpFeedback({"nack", "fir"});
380 EXPECT_FALSE(result);
Elad Alonfadb1812019-05-24 13:40:02 +0200381
deadbeefe814a0d2017-02-25 18:15:09 -0800382 // REMB with message type (should be left empty).
383 result = ToRtcpFeedback({"goog-remb", "pli"});
384 EXPECT_FALSE(result);
Elad Alonfadb1812019-05-24 13:40:02 +0200385
deadbeefe814a0d2017-02-25 18:15:09 -0800386 // TRANSPORT_CC with message type (should be left empty).
387 result = ToRtcpFeedback({"transport-cc", "fir"});
388 EXPECT_FALSE(result);
Elad Alonfadb1812019-05-24 13:40:02 +0200389
deadbeefe814a0d2017-02-25 18:15:09 -0800390 // Unknown message type.
391 result = ToRtcpFeedback(cricket::FeedbackParam("foo"));
392 EXPECT_FALSE(result);
393}
394
395TEST(RtpParametersConversionTest, ToAudioRtpCodecCapability) {
396 cricket::AudioCodec cricket_codec;
397 cricket_codec.name = "foo";
398 cricket_codec.id = 50;
399 cricket_codec.clockrate = 22222;
400 cricket_codec.channels = 4;
401 cricket_codec.params["foo"] = "bar";
402 cricket_codec.feedback_params.Add(cricket::FeedbackParam("transport-cc"));
403 RtpCodecCapability codec = ToRtpCodecCapability(cricket_codec);
404
405 EXPECT_EQ("foo", codec.name);
406 EXPECT_EQ(cricket::MEDIA_TYPE_AUDIO, codec.kind);
Oskar Sundbomff610bd2017-11-16 10:57:44 +0100407 EXPECT_EQ(50, codec.preferred_payload_type);
408 EXPECT_EQ(22222, codec.clock_rate);
409 EXPECT_EQ(4, codec.num_channels);
deadbeefe814a0d2017-02-25 18:15:09 -0800410 ASSERT_EQ(1u, codec.parameters.size());
411 EXPECT_EQ("bar", codec.parameters["foo"]);
412 EXPECT_EQ(1u, codec.rtcp_feedback.size());
413 EXPECT_EQ(RtcpFeedback(RtcpFeedbackType::TRANSPORT_CC),
414 codec.rtcp_feedback[0]);
415}
416
417TEST(RtpParametersConversionTest, ToVideoRtpCodecCapability) {
418 cricket::VideoCodec cricket_codec;
419 cricket_codec.name = "VID";
420 cricket_codec.id = 101;
421 cricket_codec.clockrate = 80000;
422 cricket_codec.params["foo"] = "bar";
423 cricket_codec.params["ANOTHER"] = "param";
424 cricket_codec.feedback_params.Add(cricket::FeedbackParam("transport-cc"));
Elad Alonfadb1812019-05-24 13:40:02 +0200425 cricket_codec.feedback_params.Add(cricket::FeedbackParam("goog-lntf"));
deadbeefe814a0d2017-02-25 18:15:09 -0800426 cricket_codec.feedback_params.Add({"nack", "pli"});
427 RtpCodecCapability codec = ToRtpCodecCapability(cricket_codec);
428
429 EXPECT_EQ("VID", codec.name);
430 EXPECT_EQ(cricket::MEDIA_TYPE_VIDEO, codec.kind);
Oskar Sundbomff610bd2017-11-16 10:57:44 +0100431 EXPECT_EQ(101, codec.preferred_payload_type);
432 EXPECT_EQ(80000, codec.clock_rate);
deadbeefe814a0d2017-02-25 18:15:09 -0800433 ASSERT_EQ(2u, codec.parameters.size());
434 EXPECT_EQ("bar", codec.parameters["foo"]);
435 EXPECT_EQ("param", codec.parameters["ANOTHER"]);
Elad Alonfadb1812019-05-24 13:40:02 +0200436 EXPECT_EQ(3u, codec.rtcp_feedback.size());
deadbeefe814a0d2017-02-25 18:15:09 -0800437 EXPECT_EQ(RtcpFeedback(RtcpFeedbackType::TRANSPORT_CC),
438 codec.rtcp_feedback[0]);
Elad Alonfadb1812019-05-24 13:40:02 +0200439 EXPECT_EQ(RtcpFeedback(RtcpFeedbackType::LNTF), codec.rtcp_feedback[1]);
deadbeefe814a0d2017-02-25 18:15:09 -0800440 EXPECT_EQ(RtcpFeedback(RtcpFeedbackType::NACK, RtcpFeedbackMessageType::PLI),
Elad Alonfadb1812019-05-24 13:40:02 +0200441 codec.rtcp_feedback[2]);
deadbeefe814a0d2017-02-25 18:15:09 -0800442}
443
zhihuang24366392017-03-08 17:15:06 -0800444TEST(RtpParametersConversionTest, ToRtpEncodingsWithEmptyStreamParamsVec) {
445 cricket::StreamParamsVec streams;
446 auto rtp_encodings = ToRtpEncodings(streams);
447 ASSERT_EQ(0u, rtp_encodings.size());
448}
449
450TEST(RtpParametersConversionTest, ToRtpEncodingsWithMultipleStreamParams) {
451 cricket::StreamParamsVec streams;
452 cricket::StreamParams stream1;
453 stream1.ssrcs.push_back(1111u);
zhihuang24366392017-03-08 17:15:06 -0800454
455 cricket::StreamParams stream2;
456 stream2.ssrcs.push_back(2222u);
zhihuang24366392017-03-08 17:15:06 -0800457
458 streams.push_back(stream1);
459 streams.push_back(stream2);
460
461 auto rtp_encodings = ToRtpEncodings(streams);
462 ASSERT_EQ(2u, rtp_encodings.size());
463 EXPECT_EQ(1111u, rtp_encodings[0].ssrc);
zhihuang24366392017-03-08 17:15:06 -0800464 EXPECT_EQ(2222u, rtp_encodings[1].ssrc);
zhihuang24366392017-03-08 17:15:06 -0800465}
466
467TEST(RtpParametersConversionTest, ToAudioRtpCodecParameters) {
468 cricket::AudioCodec cricket_codec;
469 cricket_codec.name = "foo";
470 cricket_codec.id = 50;
471 cricket_codec.clockrate = 22222;
472 cricket_codec.channels = 4;
473 cricket_codec.params["foo"] = "bar";
474 cricket_codec.feedback_params.Add(cricket::FeedbackParam("transport-cc"));
475 RtpCodecParameters codec = ToRtpCodecParameters(cricket_codec);
476
477 EXPECT_EQ("foo", codec.name);
478 EXPECT_EQ(cricket::MEDIA_TYPE_AUDIO, codec.kind);
479 EXPECT_EQ(50, codec.payload_type);
Oskar Sundbomff610bd2017-11-16 10:57:44 +0100480 EXPECT_EQ(22222, codec.clock_rate);
481 EXPECT_EQ(4, codec.num_channels);
zhihuang24366392017-03-08 17:15:06 -0800482 ASSERT_EQ(1u, codec.parameters.size());
483 EXPECT_EQ("bar", codec.parameters["foo"]);
484 EXPECT_EQ(1u, codec.rtcp_feedback.size());
485 EXPECT_EQ(RtcpFeedback(RtcpFeedbackType::TRANSPORT_CC),
486 codec.rtcp_feedback[0]);
487}
488
489TEST(RtpParametersConversionTest, ToVideoRtpCodecParameters) {
490 cricket::VideoCodec cricket_codec;
491 cricket_codec.name = "VID";
492 cricket_codec.id = 101;
493 cricket_codec.clockrate = 80000;
494 cricket_codec.params["foo"] = "bar";
495 cricket_codec.params["ANOTHER"] = "param";
496 cricket_codec.feedback_params.Add(cricket::FeedbackParam("transport-cc"));
Elad Alonfadb1812019-05-24 13:40:02 +0200497 cricket_codec.feedback_params.Add(cricket::FeedbackParam("goog-lntf"));
zhihuang24366392017-03-08 17:15:06 -0800498 cricket_codec.feedback_params.Add({"nack", "pli"});
499 RtpCodecParameters codec = ToRtpCodecParameters(cricket_codec);
500
501 EXPECT_EQ("VID", codec.name);
502 EXPECT_EQ(cricket::MEDIA_TYPE_VIDEO, codec.kind);
503 EXPECT_EQ(101, codec.payload_type);
Oskar Sundbomff610bd2017-11-16 10:57:44 +0100504 EXPECT_EQ(80000, codec.clock_rate);
zhihuang24366392017-03-08 17:15:06 -0800505 ASSERT_EQ(2u, codec.parameters.size());
506 EXPECT_EQ("bar", codec.parameters["foo"]);
507 EXPECT_EQ("param", codec.parameters["ANOTHER"]);
Elad Alonfadb1812019-05-24 13:40:02 +0200508 EXPECT_EQ(3u, codec.rtcp_feedback.size());
zhihuang24366392017-03-08 17:15:06 -0800509 EXPECT_EQ(RtcpFeedback(RtcpFeedbackType::TRANSPORT_CC),
510 codec.rtcp_feedback[0]);
Elad Alonfadb1812019-05-24 13:40:02 +0200511 EXPECT_EQ(RtcpFeedback(RtcpFeedbackType::LNTF), codec.rtcp_feedback[1]);
zhihuang24366392017-03-08 17:15:06 -0800512 EXPECT_EQ(RtcpFeedback(RtcpFeedbackType::NACK, RtcpFeedbackMessageType::PLI),
Elad Alonfadb1812019-05-24 13:40:02 +0200513 codec.rtcp_feedback[2]);
zhihuang24366392017-03-08 17:15:06 -0800514}
515
deadbeefe814a0d2017-02-25 18:15:09 -0800516// An unknown feedback param should just be ignored.
517TEST(RtpParametersConversionTest, ToRtpCodecCapabilityUnknownFeedbackParam) {
518 cricket::AudioCodec cricket_codec;
519 cricket_codec.name = "foo";
520 cricket_codec.id = 50;
521 cricket_codec.clockrate = 22222;
522 cricket_codec.channels = 4;
523 cricket_codec.params["foo"] = "bar";
524 cricket_codec.feedback_params.Add({"unknown", "param"});
525 cricket_codec.feedback_params.Add(cricket::FeedbackParam("transport-cc"));
526 RtpCodecCapability codec = ToRtpCodecCapability(cricket_codec);
527
528 ASSERT_EQ(1u, codec.rtcp_feedback.size());
529 EXPECT_EQ(RtcpFeedback(RtcpFeedbackType::TRANSPORT_CC),
530 codec.rtcp_feedback[0]);
531}
532
533// Most of ToRtpCapabilities is tested by ToRtpCodecCapability, but we need to
534// test that the result of ToRtpCodecCapability ends up in the result, and that
535// the "fec" list is assembled correctly.
536TEST(RtpParametersConversionTest, ToRtpCapabilities) {
537 cricket::VideoCodec vp8;
538 vp8.name = "VP8";
539 vp8.id = 101;
540 vp8.clockrate = 90000;
541
542 cricket::VideoCodec red;
543 red.name = "red";
544 red.id = 102;
545 red.clockrate = 90000;
546
547 cricket::VideoCodec ulpfec;
548 ulpfec.name = "ulpfec";
549 ulpfec.id = 103;
550 ulpfec.clockrate = 90000;
551
552 cricket::VideoCodec flexfec;
553 flexfec.name = "flexfec-03";
554 flexfec.id = 102;
555 flexfec.clockrate = 90000;
556
Florent Castelli5473a452018-11-06 17:27:21 +0100557 cricket::VideoCodec rtx;
558 rtx.name = "rtx";
559 rtx.id = 104;
560 rtx.params.insert({"apt", "101"});
561
562 cricket::VideoCodec rtx2;
563 rtx2.name = "rtx";
564 rtx2.id = 105;
565 rtx2.params.insert({"apt", "109"});
566
deadbeefe814a0d2017-02-25 18:15:09 -0800567 RtpCapabilities capabilities = ToRtpCapabilities<cricket::VideoCodec>(
Florent Castelli5473a452018-11-06 17:27:21 +0100568 {vp8, ulpfec, rtx, rtx2}, {{"uri", 1}, {"uri2", 3}});
569 ASSERT_EQ(3u, capabilities.codecs.size());
deadbeefe814a0d2017-02-25 18:15:09 -0800570 EXPECT_EQ("VP8", capabilities.codecs[0].name);
571 EXPECT_EQ("ulpfec", capabilities.codecs[1].name);
Florent Castelli5473a452018-11-06 17:27:21 +0100572 EXPECT_EQ("rtx", capabilities.codecs[2].name);
573 EXPECT_EQ(0u, capabilities.codecs[2].parameters.size());
deadbeefe814a0d2017-02-25 18:15:09 -0800574 ASSERT_EQ(2u, capabilities.header_extensions.size());
575 EXPECT_EQ("uri", capabilities.header_extensions[0].uri);
576 EXPECT_EQ(1, capabilities.header_extensions[0].preferred_id);
577 EXPECT_EQ("uri2", capabilities.header_extensions[1].uri);
578 EXPECT_EQ(3, capabilities.header_extensions[1].preferred_id);
579 EXPECT_EQ(0u, capabilities.fec.size());
580
581 capabilities = ToRtpCapabilities<cricket::VideoCodec>(
Florent Castelli5473a452018-11-06 17:27:21 +0100582 {vp8, red, ulpfec, rtx}, cricket::RtpHeaderExtensions());
583 EXPECT_EQ(4u, capabilities.codecs.size());
Steve Anton64b626b2019-01-28 17:25:26 -0800584 EXPECT_THAT(
585 capabilities.fec,
586 UnorderedElementsAre(FecMechanism::RED, FecMechanism::RED_AND_ULPFEC));
deadbeefe814a0d2017-02-25 18:15:09 -0800587
588 capabilities = ToRtpCapabilities<cricket::VideoCodec>(
589 {vp8, red, flexfec}, cricket::RtpHeaderExtensions());
590 EXPECT_EQ(3u, capabilities.codecs.size());
Steve Anton64b626b2019-01-28 17:25:26 -0800591 EXPECT_THAT(capabilities.fec,
592 UnorderedElementsAre(FecMechanism::RED, FecMechanism::FLEXFEC));
deadbeefe814a0d2017-02-25 18:15:09 -0800593}
594
zhihuang24366392017-03-08 17:15:06 -0800595TEST(RtpParametersConversionTest, ToRtpParameters) {
596 cricket::VideoCodec vp8;
597 vp8.name = "VP8";
598 vp8.id = 101;
599 vp8.clockrate = 90000;
600
601 cricket::VideoCodec red;
602 red.name = "red";
603 red.id = 102;
604 red.clockrate = 90000;
605
606 cricket::VideoCodec ulpfec;
607 ulpfec.name = "ulpfec";
608 ulpfec.id = 103;
609 ulpfec.clockrate = 90000;
610
611 cricket::StreamParamsVec streams;
612 cricket::StreamParams stream;
613 stream.ssrcs.push_back(1234u);
614 streams.push_back(stream);
615
616 RtpParameters rtp_parameters = ToRtpParameters<cricket::VideoCodec>(
617 {vp8, red, ulpfec}, {{"uri", 1}, {"uri2", 3}}, streams);
618 ASSERT_EQ(3u, rtp_parameters.codecs.size());
619 EXPECT_EQ("VP8", rtp_parameters.codecs[0].name);
620 EXPECT_EQ("red", rtp_parameters.codecs[1].name);
621 EXPECT_EQ("ulpfec", rtp_parameters.codecs[2].name);
622 ASSERT_EQ(2u, rtp_parameters.header_extensions.size());
623 EXPECT_EQ("uri", rtp_parameters.header_extensions[0].uri);
624 EXPECT_EQ(1, rtp_parameters.header_extensions[0].id);
625 EXPECT_EQ("uri2", rtp_parameters.header_extensions[1].uri);
626 EXPECT_EQ(3, rtp_parameters.header_extensions[1].id);
627 ASSERT_EQ(1u, rtp_parameters.encodings.size());
628 EXPECT_EQ(1234u, rtp_parameters.encodings[0].ssrc);
629}
630
deadbeefe814a0d2017-02-25 18:15:09 -0800631} // namespace webrtc