3 * Copyright 2009 Google Inc.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met:
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.
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.
28 #include "talk/base/gunit.h"
29 #include "talk/media/base/codec.h"
31 using cricket::AudioCodec;
33 using cricket::DataCodec;
34 using cricket::FeedbackParam;
35 using cricket::VideoCodec;
36 using cricket::VideoEncoderConfig;
37 using cricket::kCodecParamAssociatedPayloadType;
38 using cricket::kCodecParamMaxBitrate;
39 using cricket::kCodecParamMinBitrate;
41 class CodecTest : public testing::Test {
46 TEST_F(CodecTest, TestCodecOperators) {
47 Codec c0(96, "D", 1000, 0);
51 EXPECT_TRUE(c1 == c0);
55 EXPECT_TRUE(c0.GetParam("a", ¶m_value0));
56 EXPECT_TRUE(c1.GetParam("a", ¶m_value1));
57 EXPECT_EQ(param_value0, param_value1);
60 EXPECT_TRUE(c0 != c1);
64 EXPECT_TRUE(c0 != c1);
68 EXPECT_TRUE(c0 != c1);
72 EXPECT_TRUE(c0 != c1);
76 EXPECT_TRUE(c0 != c1);
79 Codec c6(0, "", 0, 0);
80 EXPECT_TRUE(c5 == c6);
83 TEST_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);
99 AudioCodec c8(0, "", 0, 0, 0, 0);
101 EXPECT_TRUE(c8 == c7);
102 EXPECT_TRUE(c9 != c7);
103 EXPECT_TRUE(c9 == 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);
122 TEST_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)));
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)));
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)));
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)));
162 TEST_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);
178 VideoCodec c8(0, "", 0, 0, 0, 0);
180 EXPECT_TRUE(c8 == c7);
181 EXPECT_TRUE(c9 != c7);
182 EXPECT_TRUE(c9 == 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);
201 TEST_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)));
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)));
217 TEST_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);
246 VideoEncoderConfig c10;
247 VideoEncoderConfig c11(VideoCodec(
249 VideoEncoderConfig c12(VideoCodec(
251 VideoEncoderConfig::kDefaultMaxThreads,
252 VideoEncoderConfig::kDefaultCpuProfile);
253 VideoEncoderConfig c13 = c1;
254 VideoEncoderConfig c14(VideoCodec(
255 0, "", 0, 0, 0, 0), 0, 0);
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);
265 TEST_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)));
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)));
281 TEST_F(CodecTest, TestSetParamAndGetParam) {
283 codec.SetParam("a", "1");
284 codec.SetParam("b", "x");
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));
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));
300 TEST_F(CodecTest, TestIntersectFeedbackParams) {
301 const FeedbackParam a1("a", "1");
302 const FeedbackParam b2("b", "2");
303 const FeedbackParam b3("b", "3");
304 const FeedbackParam c3("c", "3");
306 c1.AddFeedbackParam(a1); // Only match with c2.
307 c1.AddFeedbackParam(b2); // Same param different values.
308 c1.AddFeedbackParam(c3); // Not in c2.
310 c2.AddFeedbackParam(a1);
311 c2.AddFeedbackParam(b3);
313 c1.IntersectFeedbackParams(c2);
314 EXPECT_TRUE(c1.HasFeedbackParam(a1));
315 EXPECT_FALSE(c1.HasFeedbackParam(b2));
316 EXPECT_FALSE(c1.HasFeedbackParam(c3));
319 TEST_F(CodecTest, TestGetCodecType) {
320 // Codec type comparison should be case insenstive on names.
321 const VideoCodec codec(96, "V", 320, 200, 30, 3);
322 const VideoCodec rtx_codec(96, "rTx", 320, 200, 30, 3);
323 const VideoCodec ulpfec_codec(96, "ulpFeC", 320, 200, 30, 3);
324 const VideoCodec red_codec(96, "ReD", 320, 200, 30, 3);
325 EXPECT_EQ(VideoCodec::CODEC_VIDEO, codec.GetCodecType());
326 EXPECT_EQ(VideoCodec::CODEC_RTX, rtx_codec.GetCodecType());
327 EXPECT_EQ(VideoCodec::CODEC_ULPFEC, ulpfec_codec.GetCodecType());
328 EXPECT_EQ(VideoCodec::CODEC_RED, red_codec.GetCodecType());
331 TEST_F(CodecTest, TestCreateRtxCodec) {
332 VideoCodec rtx_codec = VideoCodec::CreateRtxCodec(96, 120);
333 EXPECT_EQ(96, rtx_codec.id);
334 EXPECT_EQ(VideoCodec::CODEC_RTX, rtx_codec.GetCodecType());
335 int associated_payload_type;
336 ASSERT_TRUE(rtx_codec.GetParam(kCodecParamAssociatedPayloadType,
337 &associated_payload_type));
338 EXPECT_EQ(120, associated_payload_type);
341 TEST_F(CodecTest, TestValidateCodecFormat) {
342 const VideoCodec codec(96, "V", 320, 200, 30, 3);
343 ASSERT_TRUE(codec.ValidateCodecFormat());
345 // Accept 0-127 as payload types.
346 VideoCodec low_payload_type = codec;
347 low_payload_type.id = 0;
348 VideoCodec high_payload_type = codec;
349 high_payload_type.id = 127;
350 ASSERT_TRUE(low_payload_type.ValidateCodecFormat());
351 EXPECT_TRUE(high_payload_type.ValidateCodecFormat());
353 // Reject negative payloads.
354 VideoCodec negative_payload_type = codec;
355 negative_payload_type.id = -1;
356 EXPECT_FALSE(negative_payload_type.ValidateCodecFormat());
358 // Reject too-high payloads.
359 VideoCodec too_high_payload_type = codec;
360 too_high_payload_type.id = 128;
361 EXPECT_FALSE(too_high_payload_type.ValidateCodecFormat());
363 // Reject zero-width codecs.
364 VideoCodec zero_width = codec;
365 zero_width.width = 0;
366 EXPECT_FALSE(zero_width.ValidateCodecFormat());
368 // Reject zero-height codecs.
369 VideoCodec zero_height = codec;
370 zero_height.height = 0;
371 EXPECT_FALSE(zero_height.ValidateCodecFormat());
373 // Accept non-video codecs with zero dimensions.
374 VideoCodec zero_width_rtx_codec = VideoCodec::CreateRtxCodec(96, 120);
375 zero_width_rtx_codec.width = 0;
376 EXPECT_TRUE(zero_width_rtx_codec.ValidateCodecFormat());
378 // Reject codecs with min bitrate > max bitrate.
379 VideoCodec incorrect_bitrates = codec;
380 incorrect_bitrates.params[kCodecParamMinBitrate] = "100";
381 incorrect_bitrates.params[kCodecParamMaxBitrate] = "80";
382 EXPECT_FALSE(incorrect_bitrates.ValidateCodecFormat());
384 // Accept min bitrate == max bitrate.
385 VideoCodec equal_bitrates = codec;
386 equal_bitrates.params[kCodecParamMinBitrate] = "100";
387 equal_bitrates.params[kCodecParamMaxBitrate] = "100";
388 EXPECT_TRUE(equal_bitrates.ValidateCodecFormat());
390 // Accept min bitrate < max bitrate.
391 VideoCodec different_bitrates = codec;
392 different_bitrates.params[kCodecParamMinBitrate] = "99";
393 different_bitrates.params[kCodecParamMaxBitrate] = "100";
394 EXPECT_TRUE(different_bitrates.ValidateCodecFormat());