• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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/media/base/codec.h"
29 #include "webrtc/base/gunit.h"
30 
31 using cricket::AudioCodec;
32 using cricket::Codec;
33 using cricket::DataCodec;
34 using cricket::FeedbackParam;
35 using cricket::VideoCodec;
36 using cricket::kCodecParamAssociatedPayloadType;
37 using cricket::kCodecParamMaxBitrate;
38 using cricket::kCodecParamMinBitrate;
39 
40 class CodecTest : public testing::Test {
41  public:
CodecTest()42   CodecTest() {}
43 };
44 
TEST_F(CodecTest,TestCodecOperators)45 TEST_F(CodecTest, TestCodecOperators) {
46   Codec c0(96, "D", 1000, 0);
47   c0.SetParam("a", 1);
48 
49   Codec c1 = c0;
50   EXPECT_TRUE(c1 == c0);
51 
52   int param_value0;
53   int param_value1;
54   EXPECT_TRUE(c0.GetParam("a", &param_value0));
55   EXPECT_TRUE(c1.GetParam("a", &param_value1));
56   EXPECT_EQ(param_value0, param_value1);
57 
58   c1.id = 86;
59   EXPECT_TRUE(c0 != c1);
60 
61   c1 = c0;
62   c1.name = "x";
63   EXPECT_TRUE(c0 != c1);
64 
65   c1 = c0;
66   c1.clockrate = 2000;
67   EXPECT_TRUE(c0 != c1);
68 
69   c1 = c0;
70   c1.preference = 1;
71   EXPECT_TRUE(c0 != c1);
72 
73   c1 = c0;
74   c1.SetParam("a", 2);
75   EXPECT_TRUE(c0 != c1);
76 
77   Codec c5;
78   Codec c6(0, "", 0, 0);
79   EXPECT_TRUE(c5 == c6);
80 }
81 
TEST_F(CodecTest,TestAudioCodecOperators)82 TEST_F(CodecTest, TestAudioCodecOperators) {
83   AudioCodec c0(96, "A", 44100, 20000, 2, 3);
84   AudioCodec c1(95, "A", 44100, 20000, 2, 3);
85   AudioCodec c2(96, "x", 44100, 20000, 2, 3);
86   AudioCodec c3(96, "A", 48000, 20000, 2, 3);
87   AudioCodec c4(96, "A", 44100, 10000, 2, 3);
88   AudioCodec c5(96, "A", 44100, 20000, 1, 3);
89   AudioCodec c6(96, "A", 44100, 20000, 2, 1);
90   EXPECT_TRUE(c0 != c1);
91   EXPECT_TRUE(c0 != c2);
92   EXPECT_TRUE(c0 != c3);
93   EXPECT_TRUE(c0 != c4);
94   EXPECT_TRUE(c0 != c5);
95   EXPECT_TRUE(c0 != c6);
96 
97   AudioCodec c7;
98   AudioCodec c8(0, "", 0, 0, 0, 0);
99   AudioCodec c9 = c0;
100   EXPECT_TRUE(c8 == c7);
101   EXPECT_TRUE(c9 != c7);
102   EXPECT_TRUE(c9 == c0);
103 
104   AudioCodec c10(c0);
105   AudioCodec c11(c0);
106   AudioCodec c12(c0);
107   AudioCodec c13(c0);
108   c10.params["x"] = "abc";
109   c11.params["x"] = "def";
110   c12.params["y"] = "abc";
111   c13.params["x"] = "abc";
112   EXPECT_TRUE(c10 != c0);
113   EXPECT_TRUE(c11 != c0);
114   EXPECT_TRUE(c11 != c10);
115   EXPECT_TRUE(c12 != c0);
116   EXPECT_TRUE(c12 != c10);
117   EXPECT_TRUE(c12 != c11);
118   EXPECT_TRUE(c13 == c10);
119 }
120 
TEST_F(CodecTest,TestAudioCodecMatches)121 TEST_F(CodecTest, TestAudioCodecMatches) {
122   // Test a codec with a static payload type.
123   AudioCodec c0(95, "A", 44100, 20000, 1, 3);
124   EXPECT_TRUE(c0.Matches(AudioCodec(95, "", 44100, 20000, 1, 0)));
125   EXPECT_TRUE(c0.Matches(AudioCodec(95, "", 44100, 20000, 0, 0)));
126   EXPECT_TRUE(c0.Matches(AudioCodec(95, "", 44100, 0, 0, 0)));
127   EXPECT_TRUE(c0.Matches(AudioCodec(95, "", 0, 0, 0, 0)));
128   EXPECT_FALSE(c0.Matches(AudioCodec(96, "", 44100, 20000, 1, 0)));
129   EXPECT_FALSE(c0.Matches(AudioCodec(95, "", 55100, 20000, 1, 0)));
130   EXPECT_FALSE(c0.Matches(AudioCodec(95, "", 44100, 30000, 1, 0)));
131   EXPECT_FALSE(c0.Matches(AudioCodec(95, "", 44100, 20000, 2, 0)));
132   EXPECT_FALSE(c0.Matches(AudioCodec(95, "", 55100, 30000, 2, 0)));
133 
134   // Test a codec with a dynamic payload type.
135   AudioCodec c1(96, "A", 44100, 20000, 1, 3);
136   EXPECT_TRUE(c1.Matches(AudioCodec(96, "A", 0, 0, 0, 0)));
137   EXPECT_TRUE(c1.Matches(AudioCodec(97, "A", 0, 0, 0, 0)));
138   EXPECT_TRUE(c1.Matches(AudioCodec(96, "a", 0, 0, 0, 0)));
139   EXPECT_TRUE(c1.Matches(AudioCodec(97, "a", 0, 0, 0, 0)));
140   EXPECT_FALSE(c1.Matches(AudioCodec(95, "A", 0, 0, 0, 0)));
141   EXPECT_FALSE(c1.Matches(AudioCodec(96, "", 44100, 20000, 2, 0)));
142   EXPECT_FALSE(c1.Matches(AudioCodec(96, "A", 55100, 30000, 1, 0)));
143 
144   // Test a codec with a dynamic payload type, and auto bitrate.
145   AudioCodec c2(97, "A", 16000, 0, 1, 3);
146   // Use default bitrate.
147   EXPECT_TRUE(c2.Matches(AudioCodec(97, "A", 16000, 0, 1, 0)));
148   EXPECT_TRUE(c2.Matches(AudioCodec(97, "A", 16000, 0, 0, 0)));
149   // Use explicit bitrate.
150   EXPECT_TRUE(c2.Matches(AudioCodec(97, "A", 16000, 32000, 1, 0)));
151   // Backward compatibility with clients that might send "-1" (for default).
152   EXPECT_TRUE(c2.Matches(AudioCodec(97, "A", 16000, -1, 1, 0)));
153 
154   // Stereo doesn't match channels = 0.
155   AudioCodec c3(96, "A", 44100, 20000, 2, 3);
156   EXPECT_TRUE(c3.Matches(AudioCodec(96, "A", 44100, 20000, 2, 3)));
157   EXPECT_FALSE(c3.Matches(AudioCodec(96, "A", 44100, 20000, 1, 3)));
158   EXPECT_FALSE(c3.Matches(AudioCodec(96, "A", 44100, 20000, 0, 3)));
159 }
160 
TEST_F(CodecTest,TestVideoCodecOperators)161 TEST_F(CodecTest, TestVideoCodecOperators) {
162   VideoCodec c0(96, "V", 320, 200, 30, 3);
163   VideoCodec c1(95, "V", 320, 200, 30, 3);
164   VideoCodec c2(96, "x", 320, 200, 30, 3);
165   VideoCodec c3(96, "V", 120, 200, 30, 3);
166   VideoCodec c4(96, "V", 320, 100, 30, 3);
167   VideoCodec c5(96, "V", 320, 200, 10, 3);
168   VideoCodec c6(96, "V", 320, 200, 30, 1);
169   EXPECT_TRUE(c0 != c1);
170   EXPECT_TRUE(c0 != c2);
171   EXPECT_TRUE(c0 != c3);
172   EXPECT_TRUE(c0 != c4);
173   EXPECT_TRUE(c0 != c5);
174   EXPECT_TRUE(c0 != c6);
175 
176   VideoCodec c7;
177   VideoCodec c8(0, "", 0, 0, 0, 0);
178   VideoCodec c9 = c0;
179   EXPECT_TRUE(c8 == c7);
180   EXPECT_TRUE(c9 != c7);
181   EXPECT_TRUE(c9 == c0);
182 
183   VideoCodec c10(c0);
184   VideoCodec c11(c0);
185   VideoCodec c12(c0);
186   VideoCodec c13(c0);
187   c10.params["x"] = "abc";
188   c11.params["x"] = "def";
189   c12.params["y"] = "abc";
190   c13.params["x"] = "abc";
191   EXPECT_TRUE(c10 != c0);
192   EXPECT_TRUE(c11 != c0);
193   EXPECT_TRUE(c11 != c10);
194   EXPECT_TRUE(c12 != c0);
195   EXPECT_TRUE(c12 != c10);
196   EXPECT_TRUE(c12 != c11);
197   EXPECT_TRUE(c13 == c10);
198 }
199 
TEST_F(CodecTest,TestVideoCodecMatches)200 TEST_F(CodecTest, TestVideoCodecMatches) {
201   // Test a codec with a static payload type.
202   VideoCodec c0(95, "V", 320, 200, 30, 3);
203   EXPECT_TRUE(c0.Matches(VideoCodec(95, "", 640, 400, 15, 0)));
204   EXPECT_FALSE(c0.Matches(VideoCodec(96, "", 320, 200, 30, 0)));
205 
206   // Test a codec with a dynamic payload type.
207   VideoCodec c1(96, "V", 320, 200, 30, 3);
208   EXPECT_TRUE(c1.Matches(VideoCodec(96, "V", 640, 400, 15, 0)));
209   EXPECT_TRUE(c1.Matches(VideoCodec(97, "V", 640, 400, 15, 0)));
210   EXPECT_TRUE(c1.Matches(VideoCodec(96, "v", 640, 400, 15, 0)));
211   EXPECT_TRUE(c1.Matches(VideoCodec(97, "v", 640, 400, 15, 0)));
212   EXPECT_FALSE(c1.Matches(VideoCodec(96, "", 320, 200, 30, 0)));
213   EXPECT_FALSE(c1.Matches(VideoCodec(95, "V", 640, 400, 15, 0)));
214 }
215 
TEST_F(CodecTest,TestDataCodecMatches)216 TEST_F(CodecTest, TestDataCodecMatches) {
217   // Test a codec with a static payload type.
218   DataCodec c0(95, "D", 0);
219   EXPECT_TRUE(c0.Matches(DataCodec(95, "", 0)));
220   EXPECT_FALSE(c0.Matches(DataCodec(96, "", 0)));
221 
222   // Test a codec with a dynamic payload type.
223   DataCodec c1(96, "D", 3);
224   EXPECT_TRUE(c1.Matches(DataCodec(96, "D", 0)));
225   EXPECT_TRUE(c1.Matches(DataCodec(97, "D", 0)));
226   EXPECT_TRUE(c1.Matches(DataCodec(96, "d", 0)));
227   EXPECT_TRUE(c1.Matches(DataCodec(97, "d", 0)));
228   EXPECT_FALSE(c1.Matches(DataCodec(96, "", 0)));
229   EXPECT_FALSE(c1.Matches(DataCodec(95, "D", 0)));
230 }
231 
TEST_F(CodecTest,TestSetParamGetParamAndRemoveParam)232 TEST_F(CodecTest, TestSetParamGetParamAndRemoveParam) {
233   AudioCodec codec;
234   codec.SetParam("a", "1");
235   codec.SetParam("b", "x");
236 
237   int int_value = 0;
238   EXPECT_TRUE(codec.GetParam("a", &int_value));
239   EXPECT_EQ(1, int_value);
240   EXPECT_FALSE(codec.GetParam("b", &int_value));
241   EXPECT_FALSE(codec.GetParam("c", &int_value));
242 
243   std::string str_value;
244   EXPECT_TRUE(codec.GetParam("a", &str_value));
245   EXPECT_EQ("1", str_value);
246   EXPECT_TRUE(codec.GetParam("b", &str_value));
247   EXPECT_EQ("x", str_value);
248   EXPECT_FALSE(codec.GetParam("c", &str_value));
249   EXPECT_TRUE(codec.RemoveParam("a"));
250   EXPECT_FALSE(codec.RemoveParam("c"));
251 }
252 
TEST_F(CodecTest,TestIntersectFeedbackParams)253 TEST_F(CodecTest, TestIntersectFeedbackParams) {
254   const FeedbackParam a1("a", "1");
255   const FeedbackParam b2("b", "2");
256   const FeedbackParam b3("b", "3");
257   const FeedbackParam c3("c", "3");
258   Codec c1;
259   c1.AddFeedbackParam(a1); // Only match with c2.
260   c1.AddFeedbackParam(b2); // Same param different values.
261   c1.AddFeedbackParam(c3); // Not in c2.
262   Codec c2;
263   c2.AddFeedbackParam(a1);
264   c2.AddFeedbackParam(b3);
265 
266   c1.IntersectFeedbackParams(c2);
267   EXPECT_TRUE(c1.HasFeedbackParam(a1));
268   EXPECT_FALSE(c1.HasFeedbackParam(b2));
269   EXPECT_FALSE(c1.HasFeedbackParam(c3));
270 }
271 
TEST_F(CodecTest,TestGetCodecType)272 TEST_F(CodecTest, TestGetCodecType) {
273   // Codec type comparison should be case insenstive on names.
274   const VideoCodec codec(96, "V", 320, 200, 30, 3);
275   const VideoCodec rtx_codec(96, "rTx", 320, 200, 30, 3);
276   const VideoCodec ulpfec_codec(96, "ulpFeC", 320, 200, 30, 3);
277   const VideoCodec red_codec(96, "ReD", 320, 200, 30, 3);
278   EXPECT_EQ(VideoCodec::CODEC_VIDEO, codec.GetCodecType());
279   EXPECT_EQ(VideoCodec::CODEC_RTX, rtx_codec.GetCodecType());
280   EXPECT_EQ(VideoCodec::CODEC_ULPFEC, ulpfec_codec.GetCodecType());
281   EXPECT_EQ(VideoCodec::CODEC_RED, red_codec.GetCodecType());
282 }
283 
TEST_F(CodecTest,TestCreateRtxCodec)284 TEST_F(CodecTest, TestCreateRtxCodec) {
285   VideoCodec rtx_codec = VideoCodec::CreateRtxCodec(96, 120);
286   EXPECT_EQ(96, rtx_codec.id);
287   EXPECT_EQ(VideoCodec::CODEC_RTX, rtx_codec.GetCodecType());
288   int associated_payload_type;
289   ASSERT_TRUE(rtx_codec.GetParam(kCodecParamAssociatedPayloadType,
290                                  &associated_payload_type));
291   EXPECT_EQ(120, associated_payload_type);
292 }
293 
TEST_F(CodecTest,TestValidateCodecFormat)294 TEST_F(CodecTest, TestValidateCodecFormat) {
295   const VideoCodec codec(96, "V", 320, 200, 30, 3);
296   ASSERT_TRUE(codec.ValidateCodecFormat());
297 
298   // Accept 0-127 as payload types.
299   VideoCodec low_payload_type = codec;
300   low_payload_type.id = 0;
301   VideoCodec high_payload_type = codec;
302   high_payload_type.id = 127;
303   ASSERT_TRUE(low_payload_type.ValidateCodecFormat());
304   EXPECT_TRUE(high_payload_type.ValidateCodecFormat());
305 
306   // Reject negative payloads.
307   VideoCodec negative_payload_type = codec;
308   negative_payload_type.id = -1;
309   EXPECT_FALSE(negative_payload_type.ValidateCodecFormat());
310 
311   // Reject too-high payloads.
312   VideoCodec too_high_payload_type = codec;
313   too_high_payload_type.id = 128;
314   EXPECT_FALSE(too_high_payload_type.ValidateCodecFormat());
315 
316   // Reject zero-width codecs.
317   VideoCodec zero_width = codec;
318   zero_width.width = 0;
319   EXPECT_FALSE(zero_width.ValidateCodecFormat());
320 
321   // Reject zero-height codecs.
322   VideoCodec zero_height = codec;
323   zero_height.height = 0;
324   EXPECT_FALSE(zero_height.ValidateCodecFormat());
325 
326   // Accept non-video codecs with zero dimensions.
327   VideoCodec zero_width_rtx_codec = VideoCodec::CreateRtxCodec(96, 120);
328   zero_width_rtx_codec.width = 0;
329   EXPECT_TRUE(zero_width_rtx_codec.ValidateCodecFormat());
330 
331   // Reject codecs with min bitrate > max bitrate.
332   VideoCodec incorrect_bitrates = codec;
333   incorrect_bitrates.params[kCodecParamMinBitrate] = "100";
334   incorrect_bitrates.params[kCodecParamMaxBitrate] = "80";
335   EXPECT_FALSE(incorrect_bitrates.ValidateCodecFormat());
336 
337   // Accept min bitrate == max bitrate.
338   VideoCodec equal_bitrates = codec;
339   equal_bitrates.params[kCodecParamMinBitrate] = "100";
340   equal_bitrates.params[kCodecParamMaxBitrate] = "100";
341   EXPECT_TRUE(equal_bitrates.ValidateCodecFormat());
342 
343   // Accept min bitrate < max bitrate.
344   VideoCodec different_bitrates = codec;
345   different_bitrates.params[kCodecParamMinBitrate] = "99";
346   different_bitrates.params[kCodecParamMaxBitrate] = "100";
347   EXPECT_TRUE(different_bitrates.ValidateCodecFormat());
348 }
349