Home | History | Annotate | Download | only in base
      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/base/gunit.h"
     29 #include "talk/media/base/codec.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::VideoEncoderConfig;
     37 using cricket::kCodecParamAssociatedPayloadType;
     38 using cricket::kCodecParamMaxBitrate;
     39 using cricket::kCodecParamMinBitrate;
     40 
     41 class CodecTest : public testing::Test {
     42  public:
     43   CodecTest() {}
     44 };
     45 
     46 TEST_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 
     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);
     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 
    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)));
    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 
    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);
    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 
    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)));
    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 
    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);
    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 
    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)));
    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 
    281 TEST_F(CodecTest, TestSetParamAndGetParam) {
    282   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));
    298 }
    299 
    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");
    305   Codec c1;
    306   c1.AddFeedbackParam(a1); // Only match with c2.
    307   c1.AddFeedbackParam(b2); // Same param different values.
    308   c1.AddFeedbackParam(c3); // Not in c2.
    309   Codec c2;
    310   c2.AddFeedbackParam(a1);
    311   c2.AddFeedbackParam(b3);
    312 
    313   c1.IntersectFeedbackParams(c2);
    314   EXPECT_TRUE(c1.HasFeedbackParam(a1));
    315   EXPECT_FALSE(c1.HasFeedbackParam(b2));
    316   EXPECT_FALSE(c1.HasFeedbackParam(c3));
    317 }
    318 
    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());
    329 }
    330 
    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);
    339 }
    340 
    341 TEST_F(CodecTest, TestValidateCodecFormat) {
    342   const VideoCodec codec(96, "V", 320, 200, 30, 3);
    343   ASSERT_TRUE(codec.ValidateCodecFormat());
    344 
    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());
    352 
    353   // Reject negative payloads.
    354   VideoCodec negative_payload_type = codec;
    355   negative_payload_type.id = -1;
    356   EXPECT_FALSE(negative_payload_type.ValidateCodecFormat());
    357 
    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());
    362 
    363   // Reject zero-width codecs.
    364   VideoCodec zero_width = codec;
    365   zero_width.width = 0;
    366   EXPECT_FALSE(zero_width.ValidateCodecFormat());
    367 
    368   // Reject zero-height codecs.
    369   VideoCodec zero_height = codec;
    370   zero_height.height = 0;
    371   EXPECT_FALSE(zero_height.ValidateCodecFormat());
    372 
    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());
    377 
    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());
    383 
    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());
    389 
    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());
    395 }
    396