blob: 50d90e1c30e826220441ac3cd282714acc024728 [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
Harald Alvestrandc24a2182022-02-23 13:44:59 +000013#include <cstdint>
14#include <map>
15#include <string>
deadbeefe814a0d2017-02-25 18:15:09 -080016
Harald Alvestrandc24a2182022-02-23 13:44:59 +000017#include "api/media_types.h"
Steve Anton64b626b2019-01-28 17:25:26 -080018#include "test/gmock.h"
Harald Alvestrandc24a2182022-02-23 13:44:59 +000019#include "test/gtest.h"
Steve Anton64b626b2019-01-28 17:25:26 -080020
21using ::testing::UnorderedElementsAre;
deadbeefe814a0d2017-02-25 18:15:09 -080022
23namespace webrtc {
24
25TEST(RtpParametersConversionTest, ToCricketFeedbackParam) {
26 auto result = ToCricketFeedbackParam(
27 {RtcpFeedbackType::CCM, RtcpFeedbackMessageType::FIR});
28 EXPECT_EQ(cricket::FeedbackParam("ccm", "fir"), result.value());
Elad Alonfadb1812019-05-24 13:40:02 +020029
30 result = ToCricketFeedbackParam(RtcpFeedback(RtcpFeedbackType::LNTF));
31 EXPECT_EQ(cricket::FeedbackParam("goog-lntf"), result.value());
32
deadbeefe814a0d2017-02-25 18:15:09 -080033 result = ToCricketFeedbackParam(
34 {RtcpFeedbackType::NACK, RtcpFeedbackMessageType::GENERIC_NACK});
35 EXPECT_EQ(cricket::FeedbackParam("nack"), result.value());
Elad Alonfadb1812019-05-24 13:40:02 +020036
deadbeefe814a0d2017-02-25 18:15:09 -080037 result = ToCricketFeedbackParam(
38 {RtcpFeedbackType::NACK, RtcpFeedbackMessageType::PLI});
39 EXPECT_EQ(cricket::FeedbackParam("nack", "pli"), result.value());
Elad Alonfadb1812019-05-24 13:40:02 +020040
deadbeefe814a0d2017-02-25 18:15:09 -080041 result = ToCricketFeedbackParam(RtcpFeedback(RtcpFeedbackType::REMB));
42 EXPECT_EQ(cricket::FeedbackParam("goog-remb"), result.value());
Elad Alonfadb1812019-05-24 13:40:02 +020043
deadbeefe814a0d2017-02-25 18:15:09 -080044 result = ToCricketFeedbackParam(RtcpFeedback(RtcpFeedbackType::TRANSPORT_CC));
45 EXPECT_EQ(cricket::FeedbackParam("transport-cc"), result.value());
46}
47
48TEST(RtpParametersConversionTest, ToCricketFeedbackParamErrors) {
49 // CCM with missing or invalid message type.
50 auto result = ToCricketFeedbackParam(RtcpFeedback(RtcpFeedbackType::CCM));
51 EXPECT_EQ(RTCErrorType::INVALID_PARAMETER, result.error().type());
Elad Alonfadb1812019-05-24 13:40:02 +020052
deadbeefe814a0d2017-02-25 18:15:09 -080053 result = ToCricketFeedbackParam(
54 {RtcpFeedbackType::CCM, RtcpFeedbackMessageType::PLI});
55 EXPECT_EQ(RTCErrorType::INVALID_PARAMETER, result.error().type());
Elad Alonfadb1812019-05-24 13:40:02 +020056
57 // LNTF with message type (should be left empty).
58 result = ToCricketFeedbackParam(
59 {RtcpFeedbackType::LNTF, RtcpFeedbackMessageType::GENERIC_NACK});
60 EXPECT_EQ(RTCErrorType::INVALID_PARAMETER, result.error().type());
61
deadbeefe814a0d2017-02-25 18:15:09 -080062 // NACK with missing or invalid message type.
63 result = ToCricketFeedbackParam(RtcpFeedback(RtcpFeedbackType::NACK));
64 EXPECT_EQ(RTCErrorType::INVALID_PARAMETER, result.error().type());
Elad Alonfadb1812019-05-24 13:40:02 +020065
deadbeefe814a0d2017-02-25 18:15:09 -080066 result = ToCricketFeedbackParam(
67 {RtcpFeedbackType::NACK, RtcpFeedbackMessageType::FIR});
68 EXPECT_EQ(RTCErrorType::INVALID_PARAMETER, result.error().type());
Elad Alonfadb1812019-05-24 13:40:02 +020069
deadbeefe814a0d2017-02-25 18:15:09 -080070 // REMB with message type (should be left empty).
71 result = ToCricketFeedbackParam(
72 {RtcpFeedbackType::REMB, RtcpFeedbackMessageType::GENERIC_NACK});
73 EXPECT_EQ(RTCErrorType::INVALID_PARAMETER, result.error().type());
Elad Alonfadb1812019-05-24 13:40:02 +020074
deadbeefe814a0d2017-02-25 18:15:09 -080075 // TRANSPORT_CC with message type (should be left empty).
76 result = ToCricketFeedbackParam(
77 {RtcpFeedbackType::TRANSPORT_CC, RtcpFeedbackMessageType::FIR});
78 EXPECT_EQ(RTCErrorType::INVALID_PARAMETER, result.error().type());
79}
80
81TEST(RtpParametersConversionTest, ToAudioCodec) {
82 RtpCodecParameters codec;
83 codec.name = "AuDiO";
84 codec.kind = cricket::MEDIA_TYPE_AUDIO;
85 codec.payload_type = 120;
86 codec.clock_rate.emplace(36000);
87 codec.num_channels.emplace(6);
88 codec.parameters["foo"] = "bar";
89 codec.rtcp_feedback.emplace_back(RtcpFeedbackType::TRANSPORT_CC);
90 auto result = ToCricketCodec<cricket::AudioCodec>(codec);
91 ASSERT_TRUE(result.ok());
92
93 EXPECT_EQ("AuDiO", result.value().name);
94 EXPECT_EQ(120, result.value().id);
95 EXPECT_EQ(36000, result.value().clockrate);
96 EXPECT_EQ(6u, result.value().channels);
97 ASSERT_EQ(1u, result.value().params.size());
98 EXPECT_EQ("bar", result.value().params["foo"]);
99 EXPECT_EQ(1u, result.value().feedback_params.params().size());
100 EXPECT_TRUE(result.value().feedback_params.Has(
101 cricket::FeedbackParam("transport-cc")));
102}
103
104TEST(RtpParametersConversionTest, ToVideoCodec) {
105 RtpCodecParameters codec;
106 codec.name = "coolcodec";
107 codec.kind = cricket::MEDIA_TYPE_VIDEO;
108 codec.payload_type = 101;
109 codec.clock_rate.emplace(90000);
110 codec.parameters["foo"] = "bar";
111 codec.parameters["PING"] = "PONG";
Elad Alonfadb1812019-05-24 13:40:02 +0200112 codec.rtcp_feedback.emplace_back(RtcpFeedbackType::LNTF);
deadbeefe814a0d2017-02-25 18:15:09 -0800113 codec.rtcp_feedback.emplace_back(RtcpFeedbackType::TRANSPORT_CC);
114 codec.rtcp_feedback.emplace_back(RtcpFeedbackType::NACK,
115 RtcpFeedbackMessageType::PLI);
116 auto result = ToCricketCodec<cricket::VideoCodec>(codec);
117 ASSERT_TRUE(result.ok());
118
119 EXPECT_EQ("coolcodec", result.value().name);
120 EXPECT_EQ(101, result.value().id);
121 EXPECT_EQ(90000, result.value().clockrate);
122 ASSERT_EQ(2u, result.value().params.size());
123 EXPECT_EQ("bar", result.value().params["foo"]);
124 EXPECT_EQ("PONG", result.value().params["PING"]);
Elad Alonfadb1812019-05-24 13:40:02 +0200125 EXPECT_EQ(3u, result.value().feedback_params.params().size());
126 EXPECT_TRUE(
127 result.value().feedback_params.Has(cricket::FeedbackParam("goog-lntf")));
deadbeefe814a0d2017-02-25 18:15:09 -0800128 EXPECT_TRUE(result.value().feedback_params.Has(
129 cricket::FeedbackParam("transport-cc")));
130 EXPECT_TRUE(result.value().feedback_params.Has(
131 cricket::FeedbackParam("nack", "pli")));
132}
133
134// Trying to convert to an AudioCodec if the kind is "video" should fail.
135TEST(RtpParametersConversionTest, ToCricketCodecInvalidKind) {
136 RtpCodecParameters audio_codec;
137 audio_codec.name = "opus";
138 audio_codec.kind = cricket::MEDIA_TYPE_VIDEO;
139 audio_codec.payload_type = 111;
140 audio_codec.clock_rate.emplace(48000);
141 audio_codec.num_channels.emplace(2);
142
143 RtpCodecParameters video_codec;
144 video_codec.name = "VP8";
145 video_codec.kind = cricket::MEDIA_TYPE_AUDIO;
146 video_codec.payload_type = 102;
147 video_codec.clock_rate.emplace(90000);
148
149 auto audio_result = ToCricketCodec<cricket::AudioCodec>(audio_codec);
150 EXPECT_EQ(RTCErrorType::INVALID_PARAMETER, audio_result.error().type());
151
152 auto video_result = ToCricketCodec<cricket::VideoCodec>(video_codec);
153 EXPECT_EQ(RTCErrorType::INVALID_PARAMETER, video_result.error().type());
154
155 // Sanity check that if the kind is correct, the conversion succeeds.
156 audio_codec.kind = cricket::MEDIA_TYPE_AUDIO;
157 video_codec.kind = cricket::MEDIA_TYPE_VIDEO;
158 audio_result = ToCricketCodec<cricket::AudioCodec>(audio_codec);
159 EXPECT_TRUE(audio_result.ok());
160 video_result = ToCricketCodec<cricket::VideoCodec>(video_codec);
161 EXPECT_TRUE(video_result.ok());
162}
163
164TEST(RtpParametersConversionTest, ToAudioCodecInvalidParameters) {
165 // Missing channels.
166 RtpCodecParameters codec;
167 codec.name = "opus";
168 codec.kind = cricket::MEDIA_TYPE_AUDIO;
169 codec.payload_type = 111;
170 codec.clock_rate.emplace(48000);
171 auto result = ToCricketCodec<cricket::AudioCodec>(codec);
172 EXPECT_EQ(RTCErrorType::INVALID_PARAMETER, result.error().type());
173
174 // Negative number of channels.
175 codec.num_channels.emplace(-1);
176 result = ToCricketCodec<cricket::AudioCodec>(codec);
177 EXPECT_EQ(RTCErrorType::INVALID_RANGE, result.error().type());
178
179 // Missing clock rate.
180 codec.num_channels.emplace(2);
181 codec.clock_rate.reset();
182 result = ToCricketCodec<cricket::AudioCodec>(codec);
183 EXPECT_EQ(RTCErrorType::INVALID_PARAMETER, result.error().type());
184
185 // Negative clock rate.
186 codec.clock_rate.emplace(-48000);
187 result = ToCricketCodec<cricket::AudioCodec>(codec);
188 EXPECT_EQ(RTCErrorType::INVALID_RANGE, result.error().type());
189
190 // Sanity check that conversion succeeds if these errors are fixed.
191 codec.clock_rate.emplace(48000);
192 result = ToCricketCodec<cricket::AudioCodec>(codec);
193 EXPECT_TRUE(result.ok());
194}
195
196TEST(RtpParametersConversionTest, ToVideoCodecInvalidParameters) {
197 // Missing clock rate.
198 RtpCodecParameters codec;
199 codec.name = "VP8";
200 codec.kind = cricket::MEDIA_TYPE_VIDEO;
201 codec.payload_type = 102;
202 auto result = ToCricketCodec<cricket::VideoCodec>(codec);
203 EXPECT_EQ(RTCErrorType::INVALID_PARAMETER, result.error().type());
204
205 // Invalid clock rate.
206 codec.clock_rate.emplace(48000);
207 result = ToCricketCodec<cricket::VideoCodec>(codec);
208 EXPECT_EQ(RTCErrorType::INVALID_PARAMETER, result.error().type());
209
210 // Channels set (should be unset).
211 codec.clock_rate.emplace(90000);
212 codec.num_channels.emplace(2);
213 result = ToCricketCodec<cricket::VideoCodec>(codec);
214 EXPECT_EQ(RTCErrorType::INVALID_PARAMETER, result.error().type());
215
216 // Sanity check that conversion succeeds if these errors are fixed.
217 codec.num_channels.reset();
218 result = ToCricketCodec<cricket::VideoCodec>(codec);
219 EXPECT_TRUE(result.ok());
220}
221
222TEST(RtpParametersConversionTest, ToCricketCodecInvalidPayloadType) {
223 RtpCodecParameters codec;
224 codec.name = "VP8";
225 codec.kind = cricket::MEDIA_TYPE_VIDEO;
226 codec.clock_rate.emplace(90000);
227
228 codec.payload_type = -1000;
229 auto result = ToCricketCodec<cricket::VideoCodec>(codec);
230 EXPECT_EQ(RTCErrorType::INVALID_RANGE, result.error().type());
231
232 // Max payload type is 127.
233 codec.payload_type = 128;
234 result = ToCricketCodec<cricket::VideoCodec>(codec);
235 EXPECT_EQ(RTCErrorType::INVALID_RANGE, result.error().type());
236
237 // Sanity check that conversion succeeds with a valid payload type.
238 codec.payload_type = 127;
239 result = ToCricketCodec<cricket::VideoCodec>(codec);
240 EXPECT_TRUE(result.ok());
241}
242
243// There are already tests for ToCricketFeedbackParam, but ensure that those
244// errors are propagated from ToCricketCodec.
245TEST(RtpParametersConversionTest, ToCricketCodecInvalidRtcpFeedback) {
246 RtpCodecParameters codec;
247 codec.name = "VP8";
248 codec.kind = cricket::MEDIA_TYPE_VIDEO;
249 codec.clock_rate.emplace(90000);
250 codec.payload_type = 99;
251 codec.rtcp_feedback.emplace_back(RtcpFeedbackType::CCM,
252 RtcpFeedbackMessageType::PLI);
253
254 auto result = ToCricketCodec<cricket::VideoCodec>(codec);
255 EXPECT_EQ(RTCErrorType::INVALID_PARAMETER, result.error().type());
256
257 // Sanity check that conversion succeeds without invalid feedback.
258 codec.rtcp_feedback.clear();
259 result = ToCricketCodec<cricket::VideoCodec>(codec);
260 EXPECT_TRUE(result.ok());
261}
262
263TEST(RtpParametersConversionTest, ToCricketCodecs) {
264 std::vector<RtpCodecParameters> codecs;
265 RtpCodecParameters codec;
266 codec.name = "VP8";
267 codec.kind = cricket::MEDIA_TYPE_VIDEO;
268 codec.clock_rate.emplace(90000);
269 codec.payload_type = 99;
270 codecs.push_back(codec);
271
272 codec.name = "VP9";
273 codec.payload_type = 100;
274 codecs.push_back(codec);
275
276 auto result = ToCricketCodecs<cricket::VideoCodec>(codecs);
277 ASSERT_TRUE(result.ok());
278 ASSERT_EQ(2u, result.value().size());
279 EXPECT_EQ("VP8", result.value()[0].name);
280 EXPECT_EQ(99, result.value()[0].id);
281 EXPECT_EQ("VP9", result.value()[1].name);
282 EXPECT_EQ(100, result.value()[1].id);
283}
284
285TEST(RtpParametersConversionTest, ToCricketCodecsDuplicatePayloadType) {
286 std::vector<RtpCodecParameters> codecs;
287 RtpCodecParameters codec;
288 codec.name = "VP8";
289 codec.kind = cricket::MEDIA_TYPE_VIDEO;
290 codec.clock_rate.emplace(90000);
291 codec.payload_type = 99;
292 codecs.push_back(codec);
293
294 codec.name = "VP9";
295 codec.payload_type = 99;
296 codecs.push_back(codec);
297
298 auto result = ToCricketCodecs<cricket::VideoCodec>(codecs);
299 EXPECT_EQ(RTCErrorType::INVALID_PARAMETER, result.error().type());
300
301 // Sanity check that this succeeds without the duplicate payload type.
302 codecs[1].payload_type = 120;
303 result = ToCricketCodecs<cricket::VideoCodec>(codecs);
304 EXPECT_TRUE(result.ok());
305}
306
deadbeefe814a0d2017-02-25 18:15:09 -0800307TEST(RtpParametersConversionTest, ToCricketStreamParamsVecSimple) {
308 std::vector<RtpEncodingParameters> encodings;
309 RtpEncodingParameters encoding;
310 encoding.ssrc.emplace(0xbaadf00d);
311 encodings.push_back(encoding);
312 auto result = ToCricketStreamParamsVec(encodings);
313 ASSERT_TRUE(result.ok());
314 ASSERT_EQ(1u, result.value().size());
315 EXPECT_EQ(1u, result.value()[0].ssrcs.size());
316 EXPECT_EQ(0xbaadf00d, result.value()[0].first_ssrc());
317}
318
deadbeefe814a0d2017-02-25 18:15:09 -0800319// No encodings should be accepted; an endpoint may want to prepare a
320// decoder/encoder without having something to receive/send yet.
321TEST(RtpParametersConversionTest, ToCricketStreamParamsVecNoEncodings) {
322 std::vector<RtpEncodingParameters> encodings;
323 auto result = ToCricketStreamParamsVec(encodings);
324 ASSERT_TRUE(result.ok());
325 EXPECT_EQ(0u, result.value().size());
326}
327
328// An encoding without SSRCs should be accepted. This could be the case when
329// SSRCs aren't signaled and payload-type based demuxing is used.
330TEST(RtpParametersConversionTest, ToCricketStreamParamsVecMissingSsrcs) {
331 std::vector<RtpEncodingParameters> encodings = {{}};
332 // Creates RtxParameters with empty SSRC.
deadbeefe814a0d2017-02-25 18:15:09 -0800333 auto result = ToCricketStreamParamsVec(encodings);
334 ASSERT_TRUE(result.ok());
335 EXPECT_EQ(0u, result.value().size());
336}
337
deadbeefe814a0d2017-02-25 18:15:09 -0800338// TODO(deadbeef): Update this test when we support multiple encodings.
339TEST(RtpParametersConversionTest, ToCricketStreamParamsVecMultipleEncodings) {
340 std::vector<RtpEncodingParameters> encodings = {{}, {}};
341 auto result = ToCricketStreamParamsVec(encodings);
342 EXPECT_EQ(RTCErrorType::UNSUPPORTED_PARAMETER, result.error().type());
343}
344
345TEST(RtpParametersConversionTest, ToRtcpFeedback) {
Danil Chapovalov00c71832018-06-15 15:58:38 +0200346 absl::optional<RtcpFeedback> result = ToRtcpFeedback({"ccm", "fir"});
deadbeefe814a0d2017-02-25 18:15:09 -0800347 EXPECT_EQ(RtcpFeedback(RtcpFeedbackType::CCM, RtcpFeedbackMessageType::FIR),
348 *result);
Elad Alonfadb1812019-05-24 13:40:02 +0200349
350 result = ToRtcpFeedback(cricket::FeedbackParam("goog-lntf"));
351 EXPECT_EQ(RtcpFeedback(RtcpFeedbackType::LNTF), *result);
352
deadbeefe814a0d2017-02-25 18:15:09 -0800353 result = ToRtcpFeedback(cricket::FeedbackParam("nack"));
354 EXPECT_EQ(RtcpFeedback(RtcpFeedbackType::NACK,
355 RtcpFeedbackMessageType::GENERIC_NACK),
356 *result);
Elad Alonfadb1812019-05-24 13:40:02 +0200357
deadbeefe814a0d2017-02-25 18:15:09 -0800358 result = ToRtcpFeedback({"nack", "pli"});
359 EXPECT_EQ(RtcpFeedback(RtcpFeedbackType::NACK, RtcpFeedbackMessageType::PLI),
360 *result);
Elad Alonfadb1812019-05-24 13:40:02 +0200361
deadbeefe814a0d2017-02-25 18:15:09 -0800362 result = ToRtcpFeedback(cricket::FeedbackParam("goog-remb"));
363 EXPECT_EQ(RtcpFeedback(RtcpFeedbackType::REMB), *result);
Elad Alonfadb1812019-05-24 13:40:02 +0200364
deadbeefe814a0d2017-02-25 18:15:09 -0800365 result = ToRtcpFeedback(cricket::FeedbackParam("transport-cc"));
366 EXPECT_EQ(RtcpFeedback(RtcpFeedbackType::TRANSPORT_CC), *result);
367}
368
369TEST(RtpParametersConversionTest, ToRtcpFeedbackErrors) {
370 // CCM with missing or invalid message type.
Danil Chapovalov00c71832018-06-15 15:58:38 +0200371 absl::optional<RtcpFeedback> result = ToRtcpFeedback({"ccm", "pli"});
deadbeefe814a0d2017-02-25 18:15:09 -0800372 EXPECT_FALSE(result);
Elad Alonfadb1812019-05-24 13:40:02 +0200373
deadbeefe814a0d2017-02-25 18:15:09 -0800374 result = ToRtcpFeedback(cricket::FeedbackParam("ccm"));
375 EXPECT_FALSE(result);
Elad Alonfadb1812019-05-24 13:40:02 +0200376
377 // LNTF with message type (should be left empty).
378 result = ToRtcpFeedback({"goog-lntf", "pli"});
379 EXPECT_FALSE(result);
380
deadbeefe814a0d2017-02-25 18:15:09 -0800381 // NACK with missing or invalid message type.
382 result = ToRtcpFeedback({"nack", "fir"});
383 EXPECT_FALSE(result);
Elad Alonfadb1812019-05-24 13:40:02 +0200384
deadbeefe814a0d2017-02-25 18:15:09 -0800385 // REMB with message type (should be left empty).
386 result = ToRtcpFeedback({"goog-remb", "pli"});
387 EXPECT_FALSE(result);
Elad Alonfadb1812019-05-24 13:40:02 +0200388
deadbeefe814a0d2017-02-25 18:15:09 -0800389 // TRANSPORT_CC with message type (should be left empty).
390 result = ToRtcpFeedback({"transport-cc", "fir"});
391 EXPECT_FALSE(result);
Elad Alonfadb1812019-05-24 13:40:02 +0200392
deadbeefe814a0d2017-02-25 18:15:09 -0800393 // Unknown message type.
394 result = ToRtcpFeedback(cricket::FeedbackParam("foo"));
395 EXPECT_FALSE(result);
396}
397
398TEST(RtpParametersConversionTest, ToAudioRtpCodecCapability) {
399 cricket::AudioCodec cricket_codec;
400 cricket_codec.name = "foo";
401 cricket_codec.id = 50;
402 cricket_codec.clockrate = 22222;
403 cricket_codec.channels = 4;
404 cricket_codec.params["foo"] = "bar";
405 cricket_codec.feedback_params.Add(cricket::FeedbackParam("transport-cc"));
406 RtpCodecCapability codec = ToRtpCodecCapability(cricket_codec);
407
408 EXPECT_EQ("foo", codec.name);
409 EXPECT_EQ(cricket::MEDIA_TYPE_AUDIO, codec.kind);
Oskar Sundbomff610bd2017-11-16 10:57:44 +0100410 EXPECT_EQ(50, codec.preferred_payload_type);
411 EXPECT_EQ(22222, codec.clock_rate);
412 EXPECT_EQ(4, codec.num_channels);
deadbeefe814a0d2017-02-25 18:15:09 -0800413 ASSERT_EQ(1u, codec.parameters.size());
414 EXPECT_EQ("bar", codec.parameters["foo"]);
415 EXPECT_EQ(1u, codec.rtcp_feedback.size());
416 EXPECT_EQ(RtcpFeedback(RtcpFeedbackType::TRANSPORT_CC),
417 codec.rtcp_feedback[0]);
418}
419
420TEST(RtpParametersConversionTest, ToVideoRtpCodecCapability) {
421 cricket::VideoCodec cricket_codec;
422 cricket_codec.name = "VID";
423 cricket_codec.id = 101;
424 cricket_codec.clockrate = 80000;
425 cricket_codec.params["foo"] = "bar";
426 cricket_codec.params["ANOTHER"] = "param";
427 cricket_codec.feedback_params.Add(cricket::FeedbackParam("transport-cc"));
Elad Alonfadb1812019-05-24 13:40:02 +0200428 cricket_codec.feedback_params.Add(cricket::FeedbackParam("goog-lntf"));
deadbeefe814a0d2017-02-25 18:15:09 -0800429 cricket_codec.feedback_params.Add({"nack", "pli"});
430 RtpCodecCapability codec = ToRtpCodecCapability(cricket_codec);
431
432 EXPECT_EQ("VID", codec.name);
433 EXPECT_EQ(cricket::MEDIA_TYPE_VIDEO, codec.kind);
Oskar Sundbomff610bd2017-11-16 10:57:44 +0100434 EXPECT_EQ(101, codec.preferred_payload_type);
435 EXPECT_EQ(80000, codec.clock_rate);
deadbeefe814a0d2017-02-25 18:15:09 -0800436 ASSERT_EQ(2u, codec.parameters.size());
437 EXPECT_EQ("bar", codec.parameters["foo"]);
438 EXPECT_EQ("param", codec.parameters["ANOTHER"]);
Elad Alonfadb1812019-05-24 13:40:02 +0200439 EXPECT_EQ(3u, codec.rtcp_feedback.size());
deadbeefe814a0d2017-02-25 18:15:09 -0800440 EXPECT_EQ(RtcpFeedback(RtcpFeedbackType::TRANSPORT_CC),
441 codec.rtcp_feedback[0]);
Elad Alonfadb1812019-05-24 13:40:02 +0200442 EXPECT_EQ(RtcpFeedback(RtcpFeedbackType::LNTF), codec.rtcp_feedback[1]);
deadbeefe814a0d2017-02-25 18:15:09 -0800443 EXPECT_EQ(RtcpFeedback(RtcpFeedbackType::NACK, RtcpFeedbackMessageType::PLI),
Elad Alonfadb1812019-05-24 13:40:02 +0200444 codec.rtcp_feedback[2]);
deadbeefe814a0d2017-02-25 18:15:09 -0800445}
446
zhihuang24366392017-03-08 17:15:06 -0800447TEST(RtpParametersConversionTest, ToRtpEncodingsWithEmptyStreamParamsVec) {
448 cricket::StreamParamsVec streams;
449 auto rtp_encodings = ToRtpEncodings(streams);
450 ASSERT_EQ(0u, rtp_encodings.size());
451}
452
453TEST(RtpParametersConversionTest, ToRtpEncodingsWithMultipleStreamParams) {
454 cricket::StreamParamsVec streams;
455 cricket::StreamParams stream1;
456 stream1.ssrcs.push_back(1111u);
zhihuang24366392017-03-08 17:15:06 -0800457
458 cricket::StreamParams stream2;
459 stream2.ssrcs.push_back(2222u);
zhihuang24366392017-03-08 17:15:06 -0800460
461 streams.push_back(stream1);
462 streams.push_back(stream2);
463
464 auto rtp_encodings = ToRtpEncodings(streams);
465 ASSERT_EQ(2u, rtp_encodings.size());
466 EXPECT_EQ(1111u, rtp_encodings[0].ssrc);
zhihuang24366392017-03-08 17:15:06 -0800467 EXPECT_EQ(2222u, rtp_encodings[1].ssrc);
zhihuang24366392017-03-08 17:15:06 -0800468}
469
470TEST(RtpParametersConversionTest, ToAudioRtpCodecParameters) {
471 cricket::AudioCodec cricket_codec;
472 cricket_codec.name = "foo";
473 cricket_codec.id = 50;
474 cricket_codec.clockrate = 22222;
475 cricket_codec.channels = 4;
476 cricket_codec.params["foo"] = "bar";
477 cricket_codec.feedback_params.Add(cricket::FeedbackParam("transport-cc"));
478 RtpCodecParameters codec = ToRtpCodecParameters(cricket_codec);
479
480 EXPECT_EQ("foo", codec.name);
481 EXPECT_EQ(cricket::MEDIA_TYPE_AUDIO, codec.kind);
482 EXPECT_EQ(50, codec.payload_type);
Oskar Sundbomff610bd2017-11-16 10:57:44 +0100483 EXPECT_EQ(22222, codec.clock_rate);
484 EXPECT_EQ(4, codec.num_channels);
zhihuang24366392017-03-08 17:15:06 -0800485 ASSERT_EQ(1u, codec.parameters.size());
486 EXPECT_EQ("bar", codec.parameters["foo"]);
487 EXPECT_EQ(1u, codec.rtcp_feedback.size());
488 EXPECT_EQ(RtcpFeedback(RtcpFeedbackType::TRANSPORT_CC),
489 codec.rtcp_feedback[0]);
490}
491
492TEST(RtpParametersConversionTest, ToVideoRtpCodecParameters) {
493 cricket::VideoCodec cricket_codec;
494 cricket_codec.name = "VID";
495 cricket_codec.id = 101;
496 cricket_codec.clockrate = 80000;
497 cricket_codec.params["foo"] = "bar";
498 cricket_codec.params["ANOTHER"] = "param";
499 cricket_codec.feedback_params.Add(cricket::FeedbackParam("transport-cc"));
Elad Alonfadb1812019-05-24 13:40:02 +0200500 cricket_codec.feedback_params.Add(cricket::FeedbackParam("goog-lntf"));
zhihuang24366392017-03-08 17:15:06 -0800501 cricket_codec.feedback_params.Add({"nack", "pli"});
502 RtpCodecParameters codec = ToRtpCodecParameters(cricket_codec);
503
504 EXPECT_EQ("VID", codec.name);
505 EXPECT_EQ(cricket::MEDIA_TYPE_VIDEO, codec.kind);
506 EXPECT_EQ(101, codec.payload_type);
Oskar Sundbomff610bd2017-11-16 10:57:44 +0100507 EXPECT_EQ(80000, codec.clock_rate);
zhihuang24366392017-03-08 17:15:06 -0800508 ASSERT_EQ(2u, codec.parameters.size());
509 EXPECT_EQ("bar", codec.parameters["foo"]);
510 EXPECT_EQ("param", codec.parameters["ANOTHER"]);
Elad Alonfadb1812019-05-24 13:40:02 +0200511 EXPECT_EQ(3u, codec.rtcp_feedback.size());
zhihuang24366392017-03-08 17:15:06 -0800512 EXPECT_EQ(RtcpFeedback(RtcpFeedbackType::TRANSPORT_CC),
513 codec.rtcp_feedback[0]);
Elad Alonfadb1812019-05-24 13:40:02 +0200514 EXPECT_EQ(RtcpFeedback(RtcpFeedbackType::LNTF), codec.rtcp_feedback[1]);
zhihuang24366392017-03-08 17:15:06 -0800515 EXPECT_EQ(RtcpFeedback(RtcpFeedbackType::NACK, RtcpFeedbackMessageType::PLI),
Elad Alonfadb1812019-05-24 13:40:02 +0200516 codec.rtcp_feedback[2]);
zhihuang24366392017-03-08 17:15:06 -0800517}
518
deadbeefe814a0d2017-02-25 18:15:09 -0800519// An unknown feedback param should just be ignored.
520TEST(RtpParametersConversionTest, ToRtpCodecCapabilityUnknownFeedbackParam) {
521 cricket::AudioCodec cricket_codec;
522 cricket_codec.name = "foo";
523 cricket_codec.id = 50;
524 cricket_codec.clockrate = 22222;
525 cricket_codec.channels = 4;
526 cricket_codec.params["foo"] = "bar";
527 cricket_codec.feedback_params.Add({"unknown", "param"});
528 cricket_codec.feedback_params.Add(cricket::FeedbackParam("transport-cc"));
529 RtpCodecCapability codec = ToRtpCodecCapability(cricket_codec);
530
531 ASSERT_EQ(1u, codec.rtcp_feedback.size());
532 EXPECT_EQ(RtcpFeedback(RtcpFeedbackType::TRANSPORT_CC),
533 codec.rtcp_feedback[0]);
534}
535
536// Most of ToRtpCapabilities is tested by ToRtpCodecCapability, but we need to
537// test that the result of ToRtpCodecCapability ends up in the result, and that
538// the "fec" list is assembled correctly.
539TEST(RtpParametersConversionTest, ToRtpCapabilities) {
540 cricket::VideoCodec vp8;
541 vp8.name = "VP8";
542 vp8.id = 101;
543 vp8.clockrate = 90000;
544
545 cricket::VideoCodec red;
546 red.name = "red";
547 red.id = 102;
548 red.clockrate = 90000;
549
550 cricket::VideoCodec ulpfec;
551 ulpfec.name = "ulpfec";
552 ulpfec.id = 103;
553 ulpfec.clockrate = 90000;
554
555 cricket::VideoCodec flexfec;
556 flexfec.name = "flexfec-03";
557 flexfec.id = 102;
558 flexfec.clockrate = 90000;
559
Florent Castelli5473a452018-11-06 17:27:21 +0100560 cricket::VideoCodec rtx;
561 rtx.name = "rtx";
562 rtx.id = 104;
563 rtx.params.insert({"apt", "101"});
564
565 cricket::VideoCodec rtx2;
566 rtx2.name = "rtx";
567 rtx2.id = 105;
568 rtx2.params.insert({"apt", "109"});
569
deadbeefe814a0d2017-02-25 18:15:09 -0800570 RtpCapabilities capabilities = ToRtpCapabilities<cricket::VideoCodec>(
Florent Castelli5473a452018-11-06 17:27:21 +0100571 {vp8, ulpfec, rtx, rtx2}, {{"uri", 1}, {"uri2", 3}});
572 ASSERT_EQ(3u, capabilities.codecs.size());
deadbeefe814a0d2017-02-25 18:15:09 -0800573 EXPECT_EQ("VP8", capabilities.codecs[0].name);
574 EXPECT_EQ("ulpfec", capabilities.codecs[1].name);
Florent Castelli5473a452018-11-06 17:27:21 +0100575 EXPECT_EQ("rtx", capabilities.codecs[2].name);
576 EXPECT_EQ(0u, capabilities.codecs[2].parameters.size());
deadbeefe814a0d2017-02-25 18:15:09 -0800577 ASSERT_EQ(2u, capabilities.header_extensions.size());
578 EXPECT_EQ("uri", capabilities.header_extensions[0].uri);
579 EXPECT_EQ(1, capabilities.header_extensions[0].preferred_id);
580 EXPECT_EQ("uri2", capabilities.header_extensions[1].uri);
581 EXPECT_EQ(3, capabilities.header_extensions[1].preferred_id);
582 EXPECT_EQ(0u, capabilities.fec.size());
583
584 capabilities = ToRtpCapabilities<cricket::VideoCodec>(
Florent Castelli5473a452018-11-06 17:27:21 +0100585 {vp8, red, ulpfec, rtx}, cricket::RtpHeaderExtensions());
586 EXPECT_EQ(4u, capabilities.codecs.size());
Steve Anton64b626b2019-01-28 17:25:26 -0800587 EXPECT_THAT(
588 capabilities.fec,
589 UnorderedElementsAre(FecMechanism::RED, FecMechanism::RED_AND_ULPFEC));
deadbeefe814a0d2017-02-25 18:15:09 -0800590
591 capabilities = ToRtpCapabilities<cricket::VideoCodec>(
592 {vp8, red, flexfec}, cricket::RtpHeaderExtensions());
593 EXPECT_EQ(3u, capabilities.codecs.size());
Steve Anton64b626b2019-01-28 17:25:26 -0800594 EXPECT_THAT(capabilities.fec,
595 UnorderedElementsAre(FecMechanism::RED, FecMechanism::FLEXFEC));
deadbeefe814a0d2017-02-25 18:15:09 -0800596}
597
zhihuang24366392017-03-08 17:15:06 -0800598TEST(RtpParametersConversionTest, ToRtpParameters) {
599 cricket::VideoCodec vp8;
600 vp8.name = "VP8";
601 vp8.id = 101;
602 vp8.clockrate = 90000;
603
604 cricket::VideoCodec red;
605 red.name = "red";
606 red.id = 102;
607 red.clockrate = 90000;
608
609 cricket::VideoCodec ulpfec;
610 ulpfec.name = "ulpfec";
611 ulpfec.id = 103;
612 ulpfec.clockrate = 90000;
613
614 cricket::StreamParamsVec streams;
615 cricket::StreamParams stream;
616 stream.ssrcs.push_back(1234u);
617 streams.push_back(stream);
618
619 RtpParameters rtp_parameters = ToRtpParameters<cricket::VideoCodec>(
620 {vp8, red, ulpfec}, {{"uri", 1}, {"uri2", 3}}, streams);
621 ASSERT_EQ(3u, rtp_parameters.codecs.size());
622 EXPECT_EQ("VP8", rtp_parameters.codecs[0].name);
623 EXPECT_EQ("red", rtp_parameters.codecs[1].name);
624 EXPECT_EQ("ulpfec", rtp_parameters.codecs[2].name);
625 ASSERT_EQ(2u, rtp_parameters.header_extensions.size());
626 EXPECT_EQ("uri", rtp_parameters.header_extensions[0].uri);
627 EXPECT_EQ(1, rtp_parameters.header_extensions[0].id);
628 EXPECT_EQ("uri2", rtp_parameters.header_extensions[1].uri);
629 EXPECT_EQ(3, rtp_parameters.header_extensions[1].id);
630 ASSERT_EQ(1u, rtp_parameters.encodings.size());
631 EXPECT_EQ(1234u, rtp_parameters.encodings[0].ssrc);
632}
633
deadbeefe814a0d2017-02-25 18:15:09 -0800634} // namespace webrtc