Home | History | Annotate | Download | only in media
      1 /*
      2  * libjingle
      3  * Copyright 2004 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/session/media/bundlefilter.h"
     29 #include "webrtc/base/gunit.h"
     30 
     31 using cricket::StreamParams;
     32 
     33 static const int kSsrc1 = 0x1111;
     34 static const int kSsrc2 = 0x2222;
     35 static const int kSsrc3 = 0x3333;
     36 static const int kPayloadType1 = 0x11;
     37 static const int kPayloadType2 = 0x22;
     38 static const int kPayloadType3 = 0x33;
     39 
     40 // SSRC = 0x1111, Payload type = 0x11
     41 static const unsigned char kRtpPacketPt1Ssrc1[] = {
     42     0x80, kPayloadType1, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11,
     43     0x11,
     44 };
     45 
     46 // SSRC = 0x2222, Payload type = 0x22
     47 static const unsigned char kRtpPacketPt2Ssrc2[] = {
     48     0x80, 0x80 + kPayloadType2, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     49     0x22, 0x22,
     50 };
     51 
     52 // SSRC = 0x2222, Payload type = 0x33
     53 static const unsigned char kRtpPacketPt3Ssrc2[] = {
     54     0x80, kPayloadType3, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22,
     55     0x22,
     56 };
     57 
     58 // PT = 200 = SR, len = 28, SSRC of sender = 0x0001
     59 // NTP TS = 0, RTP TS = 0, packet count = 0
     60 static const unsigned char kRtcpPacketSrSsrc01[] = {
     61     0x80, 0xC8, 0x00, 0x1B, 0x00, 0x00, 0x00, 0x01,
     62     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     63     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     64     0x00, 0x00, 0x00, 0x00,
     65 };
     66 
     67 // PT = 200 = SR, len = 28, SSRC of sender = 0x2222
     68 // NTP TS = 0, RTP TS = 0, packet count = 0
     69 static const unsigned char kRtcpPacketSrSsrc2[] = {
     70     0x80, 0xC8, 0x00, 0x1B, 0x00, 0x00, 0x22, 0x22,
     71     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     72     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     73     0x00, 0x00, 0x00, 0x00,
     74 };
     75 
     76 // First packet - SR = PT = 200, len = 0, SSRC of sender = 0x1111
     77 // NTP TS = 0, RTP TS = 0, packet count = 0
     78 // second packet - SDES = PT =  202, count = 0, SSRC = 0x1111, cname len = 0
     79 static const unsigned char kRtcpPacketCompoundSrSdesSsrc1[] = {
     80     0x80, 0xC8, 0x00, 0x01, 0x00, 0x00, 0x11, 0x11,
     81     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     82     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     83     0x00, 0x00, 0x00, 0x00,
     84     0x81, 0xCA, 0x00, 0x00, 0x00, 0x00, 0x11, 0x11, 0x01, 0x00,
     85 };
     86 
     87 // SDES = PT =  202, count = 0, SSRC = 0x2222, cname len = 0
     88 static const unsigned char kRtcpPacketSdesSsrc2[] = {
     89     0x81, 0xCA, 0x00, 0x00, 0x00, 0x00, 0x22, 0x22, 0x01, 0x00,
     90 };
     91 
     92 // Packet has only mandatory fixed RTCP header
     93 static const unsigned char kRtcpPacketFixedHeaderOnly[] = {
     94     0x80, 0xC8, 0x00, 0x00,
     95 };
     96 
     97 // Small packet for SSRC demux.
     98 static const unsigned char kRtcpPacketTooSmall[] = {
     99     0x80, 0xC8, 0x00, 0x00, 0x00, 0x00,
    100 };
    101 
    102 // PT = 206, FMT = 1, Sender SSRC  = 0x1111, Media SSRC = 0x1111
    103 // No FCI information is needed for PLI.
    104 static const unsigned char kRtcpPacketNonCompoundRtcpPliFeedback[] = {
    105     0x81, 0xCE, 0x00, 0x0C, 0x00, 0x00, 0x11, 0x11, 0x00, 0x00, 0x11, 0x11,
    106 };
    107 
    108 // An SCTP packet.
    109 static const unsigned char kSctpPacket[] = {
    110     0x00, 0x01, 0x00, 0x01,
    111     0xff, 0xff, 0xff, 0xff,
    112     0x00, 0x00, 0x00, 0x00,
    113     0x03, 0x00, 0x00, 0x04,
    114     0x00, 0x00, 0x00, 0x00,
    115 };
    116 
    117 TEST(BundleFilterTest, AddRemoveStreamTest) {
    118   cricket::BundleFilter bundle_filter;
    119   EXPECT_FALSE(bundle_filter.HasStreams());
    120   EXPECT_TRUE(bundle_filter.AddStream(StreamParams::CreateLegacy(kSsrc1)));
    121   StreamParams stream2;
    122   stream2.ssrcs.push_back(kSsrc2);
    123   stream2.ssrcs.push_back(kSsrc3);
    124   EXPECT_TRUE(bundle_filter.AddStream(stream2));
    125 
    126   EXPECT_TRUE(bundle_filter.HasStreams());
    127   EXPECT_TRUE(bundle_filter.FindStream(kSsrc1));
    128   EXPECT_TRUE(bundle_filter.FindStream(kSsrc2));
    129   EXPECT_TRUE(bundle_filter.FindStream(kSsrc3));
    130   EXPECT_TRUE(bundle_filter.RemoveStream(kSsrc1));
    131   EXPECT_FALSE(bundle_filter.FindStream(kSsrc1));
    132   EXPECT_TRUE(bundle_filter.RemoveStream(kSsrc3));
    133   EXPECT_FALSE(bundle_filter.RemoveStream(kSsrc2));  // Already removed.
    134   EXPECT_FALSE(bundle_filter.HasStreams());
    135 }
    136 
    137 TEST(BundleFilterTest, RtpPacketTest) {
    138   cricket::BundleFilter bundle_filter;
    139   bundle_filter.AddPayloadType(kPayloadType1);
    140   EXPECT_TRUE(bundle_filter.DemuxPacket(
    141       reinterpret_cast<const char*>(kRtpPacketPt1Ssrc1),
    142       sizeof(kRtpPacketPt1Ssrc1), false));
    143   bundle_filter.AddPayloadType(kPayloadType2);
    144   EXPECT_TRUE(bundle_filter.DemuxPacket(
    145       reinterpret_cast<const char*>(kRtpPacketPt2Ssrc2),
    146       sizeof(kRtpPacketPt2Ssrc2), false));
    147 
    148   // Payload type 0x33 is not added.
    149   EXPECT_FALSE(bundle_filter.DemuxPacket(
    150       reinterpret_cast<const char*>(kRtpPacketPt3Ssrc2),
    151       sizeof(kRtpPacketPt3Ssrc2), false));
    152   // Size is too small.
    153   EXPECT_FALSE(bundle_filter.DemuxPacket(
    154       reinterpret_cast<const char*>(kRtpPacketPt1Ssrc1), 11, false));
    155 
    156   bundle_filter.ClearAllPayloadTypes();
    157   EXPECT_FALSE(bundle_filter.DemuxPacket(
    158       reinterpret_cast<const char*>(kRtpPacketPt1Ssrc1),
    159       sizeof(kRtpPacketPt1Ssrc1), false));
    160   EXPECT_FALSE(bundle_filter.DemuxPacket(
    161       reinterpret_cast<const char*>(kRtpPacketPt2Ssrc2),
    162       sizeof(kRtpPacketPt2Ssrc2), false));
    163 }
    164 
    165 TEST(BundleFilterTest, RtcpPacketTest) {
    166   cricket::BundleFilter bundle_filter;
    167   EXPECT_TRUE(bundle_filter.AddStream(StreamParams::CreateLegacy(kSsrc1)));
    168   EXPECT_TRUE(bundle_filter.DemuxPacket(
    169       reinterpret_cast<const char*>(kRtcpPacketCompoundSrSdesSsrc1),
    170       sizeof(kRtcpPacketCompoundSrSdesSsrc1), true));
    171   EXPECT_TRUE(bundle_filter.AddStream(StreamParams::CreateLegacy(kSsrc2)));
    172   EXPECT_TRUE(bundle_filter.DemuxPacket(
    173       reinterpret_cast<const char*>(kRtcpPacketSrSsrc2),
    174       sizeof(kRtcpPacketSrSsrc2), true));
    175   EXPECT_TRUE(bundle_filter.DemuxPacket(
    176       reinterpret_cast<const char*>(kRtcpPacketSdesSsrc2),
    177       sizeof(kRtcpPacketSdesSsrc2), true));
    178   EXPECT_TRUE(bundle_filter.RemoveStream(kSsrc2));
    179   // RTCP Packets other than SR and RR are demuxed regardless of SSRC.
    180   EXPECT_TRUE(bundle_filter.DemuxPacket(
    181       reinterpret_cast<const char*>(kRtcpPacketSdesSsrc2),
    182       sizeof(kRtcpPacketSdesSsrc2), true));
    183   // RTCP Packets with 'special' SSRC 0x01 are demuxed also
    184   EXPECT_TRUE(bundle_filter.DemuxPacket(
    185       reinterpret_cast<const char*>(kRtcpPacketSrSsrc01),
    186       sizeof(kRtcpPacketSrSsrc01), true));
    187   EXPECT_FALSE(bundle_filter.DemuxPacket(
    188       reinterpret_cast<const char*>(kRtcpPacketSrSsrc2),
    189       sizeof(kRtcpPacketSrSsrc2), true));
    190   EXPECT_FALSE(bundle_filter.DemuxPacket(
    191       reinterpret_cast<const char*>(kRtcpPacketFixedHeaderOnly),
    192       sizeof(kRtcpPacketFixedHeaderOnly), true));
    193   EXPECT_FALSE(bundle_filter.DemuxPacket(
    194       reinterpret_cast<const char*>(kRtcpPacketTooSmall),
    195       sizeof(kRtcpPacketTooSmall), true));
    196   EXPECT_TRUE(bundle_filter.DemuxPacket(
    197       reinterpret_cast<const char*>(kRtcpPacketNonCompoundRtcpPliFeedback),
    198       sizeof(kRtcpPacketNonCompoundRtcpPliFeedback), true));
    199   // If the streams_ is empty, rtcp packet passes through
    200   EXPECT_TRUE(bundle_filter.RemoveStream(kSsrc1));
    201   EXPECT_FALSE(bundle_filter.HasStreams());
    202   EXPECT_TRUE(bundle_filter.DemuxPacket(
    203       reinterpret_cast<const char*>(kRtcpPacketSrSsrc2),
    204       sizeof(kRtcpPacketSrSsrc2), true));
    205 }
    206 
    207 TEST(BundleFilterTest, InvalidRtpPacket) {
    208   cricket::BundleFilter bundle_filter;
    209   EXPECT_TRUE(bundle_filter.AddStream(StreamParams::CreateLegacy(kSsrc1)));
    210   EXPECT_FALSE(bundle_filter.DemuxPacket(
    211       reinterpret_cast<const char*>(kSctpPacket),
    212       sizeof(kSctpPacket), false));
    213 }
    214