blob: ea7a1311223c64fb4a7ab74a05f7b429ecf7269e [file] [log] [blame]
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001/*
2 * libjingle
3 * Copyright 2009 Google Inc.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright notice,
11 * this list of conditions and the following disclaimer in the documentation
12 * and/or other materials provided with the distribution.
13 * 3. The name of the author may not be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
19 * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
22 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28#include "talk/base/gunit.h"
29#include "talk/media/base/codec.h"
30
31using cricket::AudioCodec;
32using cricket::Codec;
33using cricket::DataCodec;
34using cricket::FeedbackParam;
35using cricket::VideoCodec;
36using cricket::VideoEncoderConfig;
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +000037using cricket::kCodecParamAssociatedPayloadType;
38using cricket::kCodecParamMaxBitrate;
39using cricket::kCodecParamMinBitrate;
henrike@webrtc.org28e20752013-07-10 00:45:36 +000040
41class CodecTest : public testing::Test {
42 public:
43 CodecTest() {}
44};
45
jiayl@webrtc.org9c16c392014-05-01 18:30:30 +000046TEST_F(CodecTest, TestCodecOperators) {
47 Codec c0(96, "D", 1000, 0);
48 c0.SetParam("a", 1);
49
50 Codec c1 = c0;
51 EXPECT_TRUE(c1 == c0);
52
53 int param_value0;
54 int param_value1;
55 EXPECT_TRUE(c0.GetParam("a", &param_value0));
56 EXPECT_TRUE(c1.GetParam("a", &param_value1));
57 EXPECT_EQ(param_value0, param_value1);
58
59 c1.id = 86;
60 EXPECT_TRUE(c0 != c1);
61
62 c1 = c0;
63 c1.name = "x";
64 EXPECT_TRUE(c0 != c1);
65
66 c1 = c0;
67 c1.clockrate = 2000;
68 EXPECT_TRUE(c0 != c1);
69
70 c1 = c0;
71 c1.preference = 1;
72 EXPECT_TRUE(c0 != c1);
73
74 c1 = c0;
75 c1.SetParam("a", 2);
76 EXPECT_TRUE(c0 != c1);
77
78 Codec c5;
79 Codec c6(0, "", 0, 0);
80 EXPECT_TRUE(c5 == c6);
81}
82
henrike@webrtc.org28e20752013-07-10 00:45:36 +000083TEST_F(CodecTest, TestAudioCodecOperators) {
84 AudioCodec c0(96, "A", 44100, 20000, 2, 3);
85 AudioCodec c1(95, "A", 44100, 20000, 2, 3);
86 AudioCodec c2(96, "x", 44100, 20000, 2, 3);
87 AudioCodec c3(96, "A", 48000, 20000, 2, 3);
88 AudioCodec c4(96, "A", 44100, 10000, 2, 3);
89 AudioCodec c5(96, "A", 44100, 20000, 1, 3);
90 AudioCodec c6(96, "A", 44100, 20000, 2, 1);
91 EXPECT_TRUE(c0 != c1);
92 EXPECT_TRUE(c0 != c2);
93 EXPECT_TRUE(c0 != c3);
94 EXPECT_TRUE(c0 != c4);
95 EXPECT_TRUE(c0 != c5);
96 EXPECT_TRUE(c0 != c6);
97
98 AudioCodec c7;
99 AudioCodec c8(0, "", 0, 0, 0, 0);
100 AudioCodec c9 = c0;
101 EXPECT_TRUE(c8 == c7);
102 EXPECT_TRUE(c9 != c7);
103 EXPECT_TRUE(c9 == c0);
104
105 AudioCodec c10(c0);
106 AudioCodec c11(c0);
107 AudioCodec c12(c0);
108 AudioCodec c13(c0);
109 c10.params["x"] = "abc";
110 c11.params["x"] = "def";
111 c12.params["y"] = "abc";
112 c13.params["x"] = "abc";
113 EXPECT_TRUE(c10 != c0);
114 EXPECT_TRUE(c11 != c0);
115 EXPECT_TRUE(c11 != c10);
116 EXPECT_TRUE(c12 != c0);
117 EXPECT_TRUE(c12 != c10);
118 EXPECT_TRUE(c12 != c11);
119 EXPECT_TRUE(c13 == c10);
120}
121
122TEST_F(CodecTest, TestAudioCodecMatches) {
123 // Test a codec with a static payload type.
124 AudioCodec c0(95, "A", 44100, 20000, 1, 3);
125 EXPECT_TRUE(c0.Matches(AudioCodec(95, "", 44100, 20000, 1, 0)));
126 EXPECT_TRUE(c0.Matches(AudioCodec(95, "", 44100, 20000, 0, 0)));
127 EXPECT_TRUE(c0.Matches(AudioCodec(95, "", 44100, 0, 0, 0)));
128 EXPECT_TRUE(c0.Matches(AudioCodec(95, "", 0, 0, 0, 0)));
129 EXPECT_FALSE(c0.Matches(AudioCodec(96, "", 44100, 20000, 1, 0)));
130 EXPECT_FALSE(c0.Matches(AudioCodec(95, "", 55100, 20000, 1, 0)));
131 EXPECT_FALSE(c0.Matches(AudioCodec(95, "", 44100, 30000, 1, 0)));
132 EXPECT_FALSE(c0.Matches(AudioCodec(95, "", 44100, 20000, 2, 0)));
133 EXPECT_FALSE(c0.Matches(AudioCodec(95, "", 55100, 30000, 2, 0)));
134
135 // Test a codec with a dynamic payload type.
136 AudioCodec c1(96, "A", 44100, 20000, 1, 3);
137 EXPECT_TRUE(c1.Matches(AudioCodec(96, "A", 0, 0, 0, 0)));
138 EXPECT_TRUE(c1.Matches(AudioCodec(97, "A", 0, 0, 0, 0)));
139 EXPECT_TRUE(c1.Matches(AudioCodec(96, "a", 0, 0, 0, 0)));
140 EXPECT_TRUE(c1.Matches(AudioCodec(97, "a", 0, 0, 0, 0)));
141 EXPECT_FALSE(c1.Matches(AudioCodec(95, "A", 0, 0, 0, 0)));
142 EXPECT_FALSE(c1.Matches(AudioCodec(96, "", 44100, 20000, 2, 0)));
143 EXPECT_FALSE(c1.Matches(AudioCodec(96, "A", 55100, 30000, 1, 0)));
144
145 // Test a codec with a dynamic payload type, and auto bitrate.
146 AudioCodec c2(97, "A", 16000, 0, 1, 3);
147 // Use default bitrate.
148 EXPECT_TRUE(c2.Matches(AudioCodec(97, "A", 16000, 0, 1, 0)));
149 EXPECT_TRUE(c2.Matches(AudioCodec(97, "A", 16000, 0, 0, 0)));
150 // Use explicit bitrate.
151 EXPECT_TRUE(c2.Matches(AudioCodec(97, "A", 16000, 32000, 1, 0)));
152 // Backward compatibility with clients that might send "-1" (for default).
153 EXPECT_TRUE(c2.Matches(AudioCodec(97, "A", 16000, -1, 1, 0)));
154
155 // Stereo doesn't match channels = 0.
156 AudioCodec c3(96, "A", 44100, 20000, 2, 3);
157 EXPECT_TRUE(c3.Matches(AudioCodec(96, "A", 44100, 20000, 2, 3)));
158 EXPECT_FALSE(c3.Matches(AudioCodec(96, "A", 44100, 20000, 1, 3)));
159 EXPECT_FALSE(c3.Matches(AudioCodec(96, "A", 44100, 20000, 0, 3)));
160}
161
162TEST_F(CodecTest, TestVideoCodecOperators) {
163 VideoCodec c0(96, "V", 320, 200, 30, 3);
164 VideoCodec c1(95, "V", 320, 200, 30, 3);
165 VideoCodec c2(96, "x", 320, 200, 30, 3);
166 VideoCodec c3(96, "V", 120, 200, 30, 3);
167 VideoCodec c4(96, "V", 320, 100, 30, 3);
168 VideoCodec c5(96, "V", 320, 200, 10, 3);
169 VideoCodec c6(96, "V", 320, 200, 30, 1);
170 EXPECT_TRUE(c0 != c1);
171 EXPECT_TRUE(c0 != c2);
172 EXPECT_TRUE(c0 != c3);
173 EXPECT_TRUE(c0 != c4);
174 EXPECT_TRUE(c0 != c5);
175 EXPECT_TRUE(c0 != c6);
176
177 VideoCodec c7;
178 VideoCodec c8(0, "", 0, 0, 0, 0);
179 VideoCodec c9 = c0;
180 EXPECT_TRUE(c8 == c7);
181 EXPECT_TRUE(c9 != c7);
182 EXPECT_TRUE(c9 == c0);
183
184 VideoCodec c10(c0);
185 VideoCodec c11(c0);
186 VideoCodec c12(c0);
187 VideoCodec c13(c0);
188 c10.params["x"] = "abc";
189 c11.params["x"] = "def";
190 c12.params["y"] = "abc";
191 c13.params["x"] = "abc";
192 EXPECT_TRUE(c10 != c0);
193 EXPECT_TRUE(c11 != c0);
194 EXPECT_TRUE(c11 != c10);
195 EXPECT_TRUE(c12 != c0);
196 EXPECT_TRUE(c12 != c10);
197 EXPECT_TRUE(c12 != c11);
198 EXPECT_TRUE(c13 == c10);
199}
200
201TEST_F(CodecTest, TestVideoCodecMatches) {
202 // Test a codec with a static payload type.
203 VideoCodec c0(95, "V", 320, 200, 30, 3);
204 EXPECT_TRUE(c0.Matches(VideoCodec(95, "", 640, 400, 15, 0)));
205 EXPECT_FALSE(c0.Matches(VideoCodec(96, "", 320, 200, 30, 0)));
206
207 // Test a codec with a dynamic payload type.
208 VideoCodec c1(96, "V", 320, 200, 30, 3);
209 EXPECT_TRUE(c1.Matches(VideoCodec(96, "V", 640, 400, 15, 0)));
210 EXPECT_TRUE(c1.Matches(VideoCodec(97, "V", 640, 400, 15, 0)));
211 EXPECT_TRUE(c1.Matches(VideoCodec(96, "v", 640, 400, 15, 0)));
212 EXPECT_TRUE(c1.Matches(VideoCodec(97, "v", 640, 400, 15, 0)));
213 EXPECT_FALSE(c1.Matches(VideoCodec(96, "", 320, 200, 30, 0)));
214 EXPECT_FALSE(c1.Matches(VideoCodec(95, "V", 640, 400, 15, 0)));
215}
216
217TEST_F(CodecTest, TestVideoEncoderConfigOperators) {
218 VideoEncoderConfig c1(VideoCodec(
219 96, "SVC", 320, 200, 30, 3), 1, 2);
220 VideoEncoderConfig c2(VideoCodec(
221 95, "SVC", 320, 200, 30, 3), 1, 2);
222 VideoEncoderConfig c3(VideoCodec(
223 96, "xxx", 320, 200, 30, 3), 1, 2);
224 VideoEncoderConfig c4(VideoCodec(
225 96, "SVC", 120, 200, 30, 3), 1, 2);
226 VideoEncoderConfig c5(VideoCodec(
227 96, "SVC", 320, 100, 30, 3), 1, 2);
228 VideoEncoderConfig c6(VideoCodec(
229 96, "SVC", 320, 200, 10, 3), 1, 2);
230 VideoEncoderConfig c7(VideoCodec(
231 96, "SVC", 320, 200, 30, 1), 1, 2);
232 VideoEncoderConfig c8(VideoCodec(
233 96, "SVC", 320, 200, 30, 3), 0, 2);
234 VideoEncoderConfig c9(VideoCodec(
235 96, "SVC", 320, 200, 30, 3), 1, 1);
236 EXPECT_TRUE(c1 != c2);
237 EXPECT_TRUE(c1 != c2);
238 EXPECT_TRUE(c1 != c3);
239 EXPECT_TRUE(c1 != c4);
240 EXPECT_TRUE(c1 != c5);
241 EXPECT_TRUE(c1 != c6);
242 EXPECT_TRUE(c1 != c7);
243 EXPECT_TRUE(c1 != c8);
244 EXPECT_TRUE(c1 != c9);
245
246 VideoEncoderConfig c10;
247 VideoEncoderConfig c11(VideoCodec(
248 0, "", 0, 0, 0, 0));
249 VideoEncoderConfig c12(VideoCodec(
250 0, "", 0, 0, 0, 0),
251 VideoEncoderConfig::kDefaultMaxThreads,
252 VideoEncoderConfig::kDefaultCpuProfile);
253 VideoEncoderConfig c13 = c1;
254 VideoEncoderConfig c14(VideoCodec(
255 0, "", 0, 0, 0, 0), 0, 0);
256
257 EXPECT_TRUE(c11 == c10);
258 EXPECT_TRUE(c12 == c10);
259 EXPECT_TRUE(c13 != c10);
260 EXPECT_TRUE(c13 == c1);
261 EXPECT_TRUE(c14 != c11);
262 EXPECT_TRUE(c14 != c12);
263}
264
265TEST_F(CodecTest, TestDataCodecMatches) {
266 // Test a codec with a static payload type.
267 DataCodec c0(95, "D", 0);
268 EXPECT_TRUE(c0.Matches(DataCodec(95, "", 0)));
269 EXPECT_FALSE(c0.Matches(DataCodec(96, "", 0)));
270
271 // Test a codec with a dynamic payload type.
272 DataCodec c1(96, "D", 3);
273 EXPECT_TRUE(c1.Matches(DataCodec(96, "D", 0)));
274 EXPECT_TRUE(c1.Matches(DataCodec(97, "D", 0)));
275 EXPECT_TRUE(c1.Matches(DataCodec(96, "d", 0)));
276 EXPECT_TRUE(c1.Matches(DataCodec(97, "d", 0)));
277 EXPECT_FALSE(c1.Matches(DataCodec(96, "", 0)));
278 EXPECT_FALSE(c1.Matches(DataCodec(95, "D", 0)));
279}
280
buildbot@webrtc.orgfbd13282014-06-19 19:50:55 +0000281TEST_F(CodecTest, TestSetParamGetParamAndRemoveParam) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000282 AudioCodec codec;
283 codec.SetParam("a", "1");
284 codec.SetParam("b", "x");
285
286 int int_value = 0;
287 EXPECT_TRUE(codec.GetParam("a", &int_value));
288 EXPECT_EQ(1, int_value);
289 EXPECT_FALSE(codec.GetParam("b", &int_value));
290 EXPECT_FALSE(codec.GetParam("c", &int_value));
291
292 std::string str_value;
293 EXPECT_TRUE(codec.GetParam("a", &str_value));
294 EXPECT_EQ("1", str_value);
295 EXPECT_TRUE(codec.GetParam("b", &str_value));
296 EXPECT_EQ("x", str_value);
297 EXPECT_FALSE(codec.GetParam("c", &str_value));
buildbot@webrtc.orgfbd13282014-06-19 19:50:55 +0000298 EXPECT_TRUE(codec.RemoveParam("a"));
299 EXPECT_FALSE(codec.RemoveParam("c"));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000300}
301
302TEST_F(CodecTest, TestIntersectFeedbackParams) {
303 const FeedbackParam a1("a", "1");
304 const FeedbackParam b2("b", "2");
305 const FeedbackParam b3("b", "3");
306 const FeedbackParam c3("c", "3");
307 Codec c1;
308 c1.AddFeedbackParam(a1); // Only match with c2.
309 c1.AddFeedbackParam(b2); // Same param different values.
310 c1.AddFeedbackParam(c3); // Not in c2.
311 Codec c2;
312 c2.AddFeedbackParam(a1);
313 c2.AddFeedbackParam(b3);
314
315 c1.IntersectFeedbackParams(c2);
316 EXPECT_TRUE(c1.HasFeedbackParam(a1));
317 EXPECT_FALSE(c1.HasFeedbackParam(b2));
318 EXPECT_FALSE(c1.HasFeedbackParam(c3));
319}
pbos@webrtc.orgb5a22b12014-05-13 11:07:01 +0000320
321TEST_F(CodecTest, TestGetCodecType) {
322 // Codec type comparison should be case insenstive on names.
323 const VideoCodec codec(96, "V", 320, 200, 30, 3);
324 const VideoCodec rtx_codec(96, "rTx", 320, 200, 30, 3);
325 const VideoCodec ulpfec_codec(96, "ulpFeC", 320, 200, 30, 3);
326 const VideoCodec red_codec(96, "ReD", 320, 200, 30, 3);
327 EXPECT_EQ(VideoCodec::CODEC_VIDEO, codec.GetCodecType());
328 EXPECT_EQ(VideoCodec::CODEC_RTX, rtx_codec.GetCodecType());
329 EXPECT_EQ(VideoCodec::CODEC_ULPFEC, ulpfec_codec.GetCodecType());
330 EXPECT_EQ(VideoCodec::CODEC_RED, red_codec.GetCodecType());
331}
332
333TEST_F(CodecTest, TestCreateRtxCodec) {
334 VideoCodec rtx_codec = VideoCodec::CreateRtxCodec(96, 120);
335 EXPECT_EQ(96, rtx_codec.id);
336 EXPECT_EQ(VideoCodec::CODEC_RTX, rtx_codec.GetCodecType());
337 int associated_payload_type;
338 ASSERT_TRUE(rtx_codec.GetParam(kCodecParamAssociatedPayloadType,
339 &associated_payload_type));
340 EXPECT_EQ(120, associated_payload_type);
341}
342
343TEST_F(CodecTest, TestValidateCodecFormat) {
344 const VideoCodec codec(96, "V", 320, 200, 30, 3);
345 ASSERT_TRUE(codec.ValidateCodecFormat());
346
347 // Accept 0-127 as payload types.
348 VideoCodec low_payload_type = codec;
349 low_payload_type.id = 0;
350 VideoCodec high_payload_type = codec;
351 high_payload_type.id = 127;
352 ASSERT_TRUE(low_payload_type.ValidateCodecFormat());
353 EXPECT_TRUE(high_payload_type.ValidateCodecFormat());
354
355 // Reject negative payloads.
356 VideoCodec negative_payload_type = codec;
357 negative_payload_type.id = -1;
358 EXPECT_FALSE(negative_payload_type.ValidateCodecFormat());
359
360 // Reject too-high payloads.
361 VideoCodec too_high_payload_type = codec;
362 too_high_payload_type.id = 128;
363 EXPECT_FALSE(too_high_payload_type.ValidateCodecFormat());
364
365 // Reject zero-width codecs.
366 VideoCodec zero_width = codec;
367 zero_width.width = 0;
368 EXPECT_FALSE(zero_width.ValidateCodecFormat());
369
370 // Reject zero-height codecs.
371 VideoCodec zero_height = codec;
372 zero_height.height = 0;
373 EXPECT_FALSE(zero_height.ValidateCodecFormat());
374
375 // Accept non-video codecs with zero dimensions.
376 VideoCodec zero_width_rtx_codec = VideoCodec::CreateRtxCodec(96, 120);
377 zero_width_rtx_codec.width = 0;
378 EXPECT_TRUE(zero_width_rtx_codec.ValidateCodecFormat());
379
380 // Reject codecs with min bitrate > max bitrate.
381 VideoCodec incorrect_bitrates = codec;
382 incorrect_bitrates.params[kCodecParamMinBitrate] = "100";
383 incorrect_bitrates.params[kCodecParamMaxBitrate] = "80";
384 EXPECT_FALSE(incorrect_bitrates.ValidateCodecFormat());
385
386 // Accept min bitrate == max bitrate.
387 VideoCodec equal_bitrates = codec;
388 equal_bitrates.params[kCodecParamMinBitrate] = "100";
389 equal_bitrates.params[kCodecParamMaxBitrate] = "100";
390 EXPECT_TRUE(equal_bitrates.ValidateCodecFormat());
391
392 // Accept min bitrate < max bitrate.
393 VideoCodec different_bitrates = codec;
394 different_bitrates.params[kCodecParamMinBitrate] = "99";
395 different_bitrates.params[kCodecParamMaxBitrate] = "100";
396 EXPECT_TRUE(different_bitrates.ValidateCodecFormat());
397}