blob: a3468803973373893b6a9aabc9b1c01f9cd75bcf [file] [log] [blame]
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001/*
kjellander1afca732016-02-07 20:46:45 -08002 * Copyright (c) 2009 The WebRTC project authors. All Rights Reserved.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003 *
kjellander1afca732016-02-07 20:46:45 -08004 * 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.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00009 */
10
buildbot@webrtc.orga09a9992014-08-13 17:26:08 +000011#include "webrtc/base/gunit.h"
kjellandera96e2d72016-02-04 23:52:28 -080012#include "webrtc/media/base/codec.h"
henrike@webrtc.org28e20752013-07-10 00:45:36 +000013
14using cricket::AudioCodec;
15using cricket::Codec;
16using cricket::DataCodec;
17using cricket::FeedbackParam;
18using cricket::VideoCodec;
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +000019using cricket::kCodecParamAssociatedPayloadType;
20using cricket::kCodecParamMaxBitrate;
21using cricket::kCodecParamMinBitrate;
henrike@webrtc.org28e20752013-07-10 00:45:36 +000022
23class CodecTest : public testing::Test {
24 public:
25 CodecTest() {}
26};
27
jiayl@webrtc.org9c16c392014-05-01 18:30:30 +000028TEST_F(CodecTest, TestCodecOperators) {
deadbeef67cf2c12016-04-13 10:07:16 -070029 Codec c0(96, "D", 1000);
jiayl@webrtc.org9c16c392014-05-01 18:30:30 +000030 c0.SetParam("a", 1);
31
32 Codec c1 = c0;
33 EXPECT_TRUE(c1 == c0);
34
35 int param_value0;
36 int param_value1;
37 EXPECT_TRUE(c0.GetParam("a", &param_value0));
38 EXPECT_TRUE(c1.GetParam("a", &param_value1));
39 EXPECT_EQ(param_value0, param_value1);
40
41 c1.id = 86;
42 EXPECT_TRUE(c0 != c1);
43
44 c1 = c0;
45 c1.name = "x";
46 EXPECT_TRUE(c0 != c1);
47
48 c1 = c0;
49 c1.clockrate = 2000;
50 EXPECT_TRUE(c0 != c1);
51
52 c1 = c0;
jiayl@webrtc.org9c16c392014-05-01 18:30:30 +000053 c1.SetParam("a", 2);
54 EXPECT_TRUE(c0 != c1);
55
56 Codec c5;
deadbeef67cf2c12016-04-13 10:07:16 -070057 Codec c6(0, "", 0);
jiayl@webrtc.org9c16c392014-05-01 18:30:30 +000058 EXPECT_TRUE(c5 == c6);
59}
60
henrike@webrtc.org28e20752013-07-10 00:45:36 +000061TEST_F(CodecTest, TestAudioCodecOperators) {
deadbeef67cf2c12016-04-13 10:07:16 -070062 AudioCodec c0(96, "A", 44100, 20000, 2);
63 AudioCodec c1(95, "A", 44100, 20000, 2);
64 AudioCodec c2(96, "x", 44100, 20000, 2);
65 AudioCodec c3(96, "A", 48000, 20000, 2);
66 AudioCodec c4(96, "A", 44100, 10000, 2);
67 AudioCodec c5(96, "A", 44100, 20000, 1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +000068 EXPECT_TRUE(c0 != c1);
69 EXPECT_TRUE(c0 != c2);
70 EXPECT_TRUE(c0 != c3);
71 EXPECT_TRUE(c0 != c4);
72 EXPECT_TRUE(c0 != c5);
henrike@webrtc.org28e20752013-07-10 00:45:36 +000073
74 AudioCodec c7;
deadbeef67cf2c12016-04-13 10:07:16 -070075 AudioCodec c8(0, "", 0, 0, 0);
henrike@webrtc.org28e20752013-07-10 00:45:36 +000076 AudioCodec c9 = c0;
77 EXPECT_TRUE(c8 == c7);
78 EXPECT_TRUE(c9 != c7);
79 EXPECT_TRUE(c9 == c0);
80
81 AudioCodec c10(c0);
82 AudioCodec c11(c0);
83 AudioCodec c12(c0);
84 AudioCodec c13(c0);
85 c10.params["x"] = "abc";
86 c11.params["x"] = "def";
87 c12.params["y"] = "abc";
88 c13.params["x"] = "abc";
89 EXPECT_TRUE(c10 != c0);
90 EXPECT_TRUE(c11 != c0);
91 EXPECT_TRUE(c11 != c10);
92 EXPECT_TRUE(c12 != c0);
93 EXPECT_TRUE(c12 != c10);
94 EXPECT_TRUE(c12 != c11);
95 EXPECT_TRUE(c13 == c10);
96}
97
98TEST_F(CodecTest, TestAudioCodecMatches) {
99 // Test a codec with a static payload type.
deadbeef67cf2c12016-04-13 10:07:16 -0700100 AudioCodec c0(95, "A", 44100, 20000, 1);
101 EXPECT_TRUE(c0.Matches(AudioCodec(95, "", 44100, 20000, 1)));
102 EXPECT_TRUE(c0.Matches(AudioCodec(95, "", 44100, 20000, 0)));
103 EXPECT_TRUE(c0.Matches(AudioCodec(95, "", 44100, 0, 0)));
104 EXPECT_TRUE(c0.Matches(AudioCodec(95, "", 0, 0, 0)));
105 EXPECT_FALSE(c0.Matches(AudioCodec(96, "", 44100, 20000, 1)));
106 EXPECT_FALSE(c0.Matches(AudioCodec(95, "", 55100, 20000, 1)));
107 EXPECT_FALSE(c0.Matches(AudioCodec(95, "", 44100, 30000, 1)));
108 EXPECT_FALSE(c0.Matches(AudioCodec(95, "", 44100, 20000, 2)));
109 EXPECT_FALSE(c0.Matches(AudioCodec(95, "", 55100, 30000, 2)));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000110
111 // Test a codec with a dynamic payload type.
deadbeef67cf2c12016-04-13 10:07:16 -0700112 AudioCodec c1(96, "A", 44100, 20000, 1);
113 EXPECT_TRUE(c1.Matches(AudioCodec(96, "A", 0, 0, 0)));
114 EXPECT_TRUE(c1.Matches(AudioCodec(97, "A", 0, 0, 0)));
115 EXPECT_TRUE(c1.Matches(AudioCodec(96, "a", 0, 0, 0)));
116 EXPECT_TRUE(c1.Matches(AudioCodec(97, "a", 0, 0, 0)));
117 EXPECT_FALSE(c1.Matches(AudioCodec(95, "A", 0, 0, 0)));
118 EXPECT_FALSE(c1.Matches(AudioCodec(96, "", 44100, 20000, 2)));
119 EXPECT_FALSE(c1.Matches(AudioCodec(96, "A", 55100, 30000, 1)));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000120
121 // Test a codec with a dynamic payload type, and auto bitrate.
deadbeef67cf2c12016-04-13 10:07:16 -0700122 AudioCodec c2(97, "A", 16000, 0, 1);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000123 // Use default bitrate.
deadbeef67cf2c12016-04-13 10:07:16 -0700124 EXPECT_TRUE(c2.Matches(AudioCodec(97, "A", 16000, 0, 1)));
125 EXPECT_TRUE(c2.Matches(AudioCodec(97, "A", 16000, 0, 0)));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000126 // Use explicit bitrate.
deadbeef67cf2c12016-04-13 10:07:16 -0700127 EXPECT_TRUE(c2.Matches(AudioCodec(97, "A", 16000, 32000, 1)));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000128 // Backward compatibility with clients that might send "-1" (for default).
deadbeef67cf2c12016-04-13 10:07:16 -0700129 EXPECT_TRUE(c2.Matches(AudioCodec(97, "A", 16000, -1, 1)));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000130
131 // Stereo doesn't match channels = 0.
deadbeef67cf2c12016-04-13 10:07:16 -0700132 AudioCodec c3(96, "A", 44100, 20000, 2);
133 EXPECT_TRUE(c3.Matches(AudioCodec(96, "A", 44100, 20000, 2)));
134 EXPECT_FALSE(c3.Matches(AudioCodec(96, "A", 44100, 20000, 1)));
135 EXPECT_FALSE(c3.Matches(AudioCodec(96, "A", 44100, 20000, 0)));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000136}
137
138TEST_F(CodecTest, TestVideoCodecOperators) {
deadbeef67cf2c12016-04-13 10:07:16 -0700139 VideoCodec c0(96, "V", 320, 200, 30);
140 VideoCodec c1(95, "V", 320, 200, 30);
141 VideoCodec c2(96, "x", 320, 200, 30);
142 VideoCodec c3(96, "V", 120, 200, 30);
143 VideoCodec c4(96, "V", 320, 100, 30);
144 VideoCodec c5(96, "V", 320, 200, 10);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000145 EXPECT_TRUE(c0 != c1);
146 EXPECT_TRUE(c0 != c2);
147 EXPECT_TRUE(c0 != c3);
148 EXPECT_TRUE(c0 != c4);
149 EXPECT_TRUE(c0 != c5);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000150
151 VideoCodec c7;
deadbeef67cf2c12016-04-13 10:07:16 -0700152 VideoCodec c8(0, "", 0, 0, 0);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000153 VideoCodec c9 = c0;
154 EXPECT_TRUE(c8 == c7);
155 EXPECT_TRUE(c9 != c7);
156 EXPECT_TRUE(c9 == c0);
157
158 VideoCodec c10(c0);
159 VideoCodec c11(c0);
160 VideoCodec c12(c0);
161 VideoCodec c13(c0);
162 c10.params["x"] = "abc";
163 c11.params["x"] = "def";
164 c12.params["y"] = "abc";
165 c13.params["x"] = "abc";
166 EXPECT_TRUE(c10 != c0);
167 EXPECT_TRUE(c11 != c0);
168 EXPECT_TRUE(c11 != c10);
169 EXPECT_TRUE(c12 != c0);
170 EXPECT_TRUE(c12 != c10);
171 EXPECT_TRUE(c12 != c11);
172 EXPECT_TRUE(c13 == c10);
173}
174
175TEST_F(CodecTest, TestVideoCodecMatches) {
176 // Test a codec with a static payload type.
deadbeef67cf2c12016-04-13 10:07:16 -0700177 VideoCodec c0(95, "V", 320, 200, 30);
178 EXPECT_TRUE(c0.Matches(VideoCodec(95, "", 640, 400, 15)));
179 EXPECT_FALSE(c0.Matches(VideoCodec(96, "", 320, 200, 30)));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000180
181 // Test a codec with a dynamic payload type.
deadbeef67cf2c12016-04-13 10:07:16 -0700182 VideoCodec c1(96, "V", 320, 200, 30);
183 EXPECT_TRUE(c1.Matches(VideoCodec(96, "V", 640, 400, 15)));
184 EXPECT_TRUE(c1.Matches(VideoCodec(97, "V", 640, 400, 15)));
185 EXPECT_TRUE(c1.Matches(VideoCodec(96, "v", 640, 400, 15)));
186 EXPECT_TRUE(c1.Matches(VideoCodec(97, "v", 640, 400, 15)));
187 EXPECT_FALSE(c1.Matches(VideoCodec(96, "", 320, 200, 30)));
188 EXPECT_FALSE(c1.Matches(VideoCodec(95, "V", 640, 400, 15)));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000189}
190
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000191TEST_F(CodecTest, TestDataCodecMatches) {
192 // Test a codec with a static payload type.
deadbeef67cf2c12016-04-13 10:07:16 -0700193 DataCodec c0(95, "D");
194 EXPECT_TRUE(c0.Matches(DataCodec(95, "")));
195 EXPECT_FALSE(c0.Matches(DataCodec(96, "")));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000196
197 // Test a codec with a dynamic payload type.
deadbeef67cf2c12016-04-13 10:07:16 -0700198 DataCodec c1(96, "D");
199 EXPECT_TRUE(c1.Matches(DataCodec(96, "D")));
200 EXPECT_TRUE(c1.Matches(DataCodec(97, "D")));
201 EXPECT_TRUE(c1.Matches(DataCodec(96, "d")));
202 EXPECT_TRUE(c1.Matches(DataCodec(97, "d")));
203 EXPECT_FALSE(c1.Matches(DataCodec(96, "")));
204 EXPECT_FALSE(c1.Matches(DataCodec(95, "D")));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000205}
206
buildbot@webrtc.orgfbd13282014-06-19 19:50:55 +0000207TEST_F(CodecTest, TestSetParamGetParamAndRemoveParam) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000208 AudioCodec codec;
209 codec.SetParam("a", "1");
210 codec.SetParam("b", "x");
211
212 int int_value = 0;
213 EXPECT_TRUE(codec.GetParam("a", &int_value));
214 EXPECT_EQ(1, int_value);
215 EXPECT_FALSE(codec.GetParam("b", &int_value));
216 EXPECT_FALSE(codec.GetParam("c", &int_value));
217
218 std::string str_value;
219 EXPECT_TRUE(codec.GetParam("a", &str_value));
220 EXPECT_EQ("1", str_value);
221 EXPECT_TRUE(codec.GetParam("b", &str_value));
222 EXPECT_EQ("x", str_value);
223 EXPECT_FALSE(codec.GetParam("c", &str_value));
buildbot@webrtc.orgfbd13282014-06-19 19:50:55 +0000224 EXPECT_TRUE(codec.RemoveParam("a"));
225 EXPECT_FALSE(codec.RemoveParam("c"));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000226}
227
228TEST_F(CodecTest, TestIntersectFeedbackParams) {
229 const FeedbackParam a1("a", "1");
230 const FeedbackParam b2("b", "2");
231 const FeedbackParam b3("b", "3");
232 const FeedbackParam c3("c", "3");
233 Codec c1;
234 c1.AddFeedbackParam(a1); // Only match with c2.
235 c1.AddFeedbackParam(b2); // Same param different values.
236 c1.AddFeedbackParam(c3); // Not in c2.
237 Codec c2;
238 c2.AddFeedbackParam(a1);
239 c2.AddFeedbackParam(b3);
240
241 c1.IntersectFeedbackParams(c2);
242 EXPECT_TRUE(c1.HasFeedbackParam(a1));
243 EXPECT_FALSE(c1.HasFeedbackParam(b2));
244 EXPECT_FALSE(c1.HasFeedbackParam(c3));
245}
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000246
247TEST_F(CodecTest, TestGetCodecType) {
248 // Codec type comparison should be case insenstive on names.
deadbeef67cf2c12016-04-13 10:07:16 -0700249 const VideoCodec codec(96, "V", 320, 200, 30);
250 const VideoCodec rtx_codec(96, "rTx", 320, 200, 30);
251 const VideoCodec ulpfec_codec(96, "ulpFeC", 320, 200, 30);
252 const VideoCodec red_codec(96, "ReD", 320, 200, 30);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000253 EXPECT_EQ(VideoCodec::CODEC_VIDEO, codec.GetCodecType());
254 EXPECT_EQ(VideoCodec::CODEC_RTX, rtx_codec.GetCodecType());
255 EXPECT_EQ(VideoCodec::CODEC_ULPFEC, ulpfec_codec.GetCodecType());
256 EXPECT_EQ(VideoCodec::CODEC_RED, red_codec.GetCodecType());
257}
258
259TEST_F(CodecTest, TestCreateRtxCodec) {
260 VideoCodec rtx_codec = VideoCodec::CreateRtxCodec(96, 120);
261 EXPECT_EQ(96, rtx_codec.id);
262 EXPECT_EQ(VideoCodec::CODEC_RTX, rtx_codec.GetCodecType());
263 int associated_payload_type;
264 ASSERT_TRUE(rtx_codec.GetParam(kCodecParamAssociatedPayloadType,
265 &associated_payload_type));
266 EXPECT_EQ(120, associated_payload_type);
267}
268
269TEST_F(CodecTest, TestValidateCodecFormat) {
deadbeef67cf2c12016-04-13 10:07:16 -0700270 const VideoCodec codec(96, "V", 320, 200, 30);
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000271 ASSERT_TRUE(codec.ValidateCodecFormat());
272
273 // Accept 0-127 as payload types.
274 VideoCodec low_payload_type = codec;
275 low_payload_type.id = 0;
276 VideoCodec high_payload_type = codec;
277 high_payload_type.id = 127;
278 ASSERT_TRUE(low_payload_type.ValidateCodecFormat());
279 EXPECT_TRUE(high_payload_type.ValidateCodecFormat());
280
281 // Reject negative payloads.
282 VideoCodec negative_payload_type = codec;
283 negative_payload_type.id = -1;
284 EXPECT_FALSE(negative_payload_type.ValidateCodecFormat());
285
286 // Reject too-high payloads.
287 VideoCodec too_high_payload_type = codec;
288 too_high_payload_type.id = 128;
289 EXPECT_FALSE(too_high_payload_type.ValidateCodecFormat());
290
291 // Reject zero-width codecs.
292 VideoCodec zero_width = codec;
293 zero_width.width = 0;
294 EXPECT_FALSE(zero_width.ValidateCodecFormat());
295
296 // Reject zero-height codecs.
297 VideoCodec zero_height = codec;
298 zero_height.height = 0;
299 EXPECT_FALSE(zero_height.ValidateCodecFormat());
300
301 // Accept non-video codecs with zero dimensions.
302 VideoCodec zero_width_rtx_codec = VideoCodec::CreateRtxCodec(96, 120);
303 zero_width_rtx_codec.width = 0;
304 EXPECT_TRUE(zero_width_rtx_codec.ValidateCodecFormat());
305
306 // Reject codecs with min bitrate > max bitrate.
307 VideoCodec incorrect_bitrates = codec;
308 incorrect_bitrates.params[kCodecParamMinBitrate] = "100";
309 incorrect_bitrates.params[kCodecParamMaxBitrate] = "80";
310 EXPECT_FALSE(incorrect_bitrates.ValidateCodecFormat());
311
312 // Accept min bitrate == max bitrate.
313 VideoCodec equal_bitrates = codec;
314 equal_bitrates.params[kCodecParamMinBitrate] = "100";
315 equal_bitrates.params[kCodecParamMaxBitrate] = "100";
316 EXPECT_TRUE(equal_bitrates.ValidateCodecFormat());
317
318 // Accept min bitrate < max bitrate.
319 VideoCodec different_bitrates = codec;
320 different_bitrates.params[kCodecParamMinBitrate] = "99";
321 different_bitrates.params[kCodecParamMaxBitrate] = "100";
322 EXPECT_TRUE(different_bitrates.ValidateCodecFormat());
323}
Taylor Brandstetterdb0cd9e2016-05-16 11:40:30 -0700324
325TEST_F(CodecTest, TestToCodecParameters) {
326 const VideoCodec v(96, "V", 320, 200, 30);
327 webrtc::RtpCodecParameters codec_params_1 = v.ToCodecParameters();
328 EXPECT_EQ(96, codec_params_1.payload_type);
329 EXPECT_EQ("V", codec_params_1.mime_type);
330 EXPECT_EQ(cricket::kVideoCodecClockrate, codec_params_1.clock_rate);
331 EXPECT_EQ(1, codec_params_1.channels);
332
333 const AudioCodec a(97, "A", 44100, 20000, 2);
334 webrtc::RtpCodecParameters codec_params_2 = a.ToCodecParameters();
335 EXPECT_EQ(97, codec_params_2.payload_type);
336 EXPECT_EQ("A", codec_params_2.mime_type);
337 EXPECT_EQ(44100, codec_params_2.clock_rate);
338 EXPECT_EQ(2, codec_params_2.channels);
339}