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: 42 CodecTest() {} 43 }; 44 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", ¶m_value0)); 55 EXPECT_TRUE(c1.GetParam("a", ¶m_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 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 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 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 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 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 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 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 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 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 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