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/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", &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 
     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