Home | History | Annotate | Download | only in automated
      1 /*
      2  *  Copyright (c) 2014 The WebRTC project authors. All Rights Reserved.
      3  *
      4  *  Use of this source code is governed by a BSD-style license
      5  *  that can be found in the LICENSE file in the root of the source
      6  *  tree. An additional intellectual property rights grant can be found
      7  *  in the file PATENTS.  All contributing project authors may
      8  *  be found in the AUTHORS file in the root of the source tree.
      9  */
     10 
     11 #include <stdio.h>
     12 
     13 #include "gflags/gflags.h"
     14 #include "testing/gtest/include/gtest/gtest.h"
     15 #include "webrtc/modules/rtp_rtcp/source/rtp_utility.h"
     16 #include "webrtc/video_engine/test/auto_test/interface/vie_autotest.h"
     17 #include "webrtc/video_engine/test/libvietest/include/tb_interfaces.h"
     18 #include "webrtc/system_wrappers/interface/sleep.h"
     19 #include "webrtc/system_wrappers/interface/tick_util.h"
     20 
     21 namespace {
     22 
     23 class RtcpCollectorTransport : public webrtc::Transport {
     24  public:
     25   RtcpCollectorTransport() : packets_() {}
     26   virtual ~RtcpCollectorTransport() {}
     27 
     28   virtual int SendPacket(int /*channel*/, const void* /*data*/, int /*len*/) {
     29     EXPECT_TRUE(false);
     30     return 0;
     31   }
     32   virtual int SendRTCPPacket(int channel, const void* data, int len) {
     33     const uint8_t* buf = static_cast<const uint8_t*>(data);
     34     webrtc::RtpUtility::RtpHeaderParser parser(buf, len);
     35     if (parser.RTCP()) {
     36       Packet p;
     37       p.channel = channel;
     38       p.length = len;
     39       if (parser.ParseRtcp(&p.header)) {
     40         if (p.header.payloadType == 201) {
     41           buf += 20;
     42           len -= 20;
     43         } else {
     44           return 0;
     45         }
     46         if (TryParseREMB(buf, len, &p)) {
     47           packets_.push_back(p);
     48         }
     49       }
     50     }
     51     return 0;
     52   }
     53 
     54   bool FindREMBFor(uint32_t ssrc, double min_rate) const {
     55     for (std::vector<Packet>::const_iterator it = packets_.begin();
     56         it != packets_.end(); ++it) {
     57       if (it->remb_bitrate >= min_rate && it->remb_ssrc.end() !=
     58           std::find(it->remb_ssrc.begin(), it->remb_ssrc.end(), ssrc)) {
     59         return true;
     60       }
     61     }
     62     return false;
     63   }
     64 
     65  private:
     66   struct Packet {
     67     Packet() : channel(-1), length(0), header(), remb_bitrate(0), remb_ssrc() {}
     68     int channel;
     69     int length;
     70     webrtc::RTPHeader header;
     71     double remb_bitrate;
     72     std::vector<uint32_t> remb_ssrc;
     73   };
     74 
     75   bool TryParseREMB(const uint8_t* buf, int length, Packet* p) {
     76     if (length < 8) {
     77       return false;
     78     }
     79     if (buf[0] != 'R' || buf[1] != 'E' || buf[2] != 'M' || buf[3] != 'B') {
     80       return false;
     81     }
     82     uint8_t ssrcs = buf[4];
     83     uint8_t exp = buf[5] >> 2;
     84     uint32_t mantissa = ((buf[5] & 0x03) << 16) + (buf[6] << 8) + buf[7];
     85     double bitrate = mantissa * static_cast<double>(1 << exp);
     86     p->remb_bitrate = bitrate;
     87 
     88     if (length < (8 + 4 * ssrcs)) {
     89       return false;
     90     }
     91     buf += 8;
     92     for (uint8_t i = 0; i < ssrcs; ++i) {
     93       uint32_t ssrc = (buf[0] << 24) + (buf[1] << 16) + (buf[2] << 8) + buf[3];
     94       p->remb_ssrc.push_back(ssrc);
     95       buf += 4;
     96     }
     97     return true;
     98   }
     99 
    100   std::vector<Packet> packets_;
    101 };
    102 
    103 class ViENetworkTest : public testing::Test {
    104  protected:
    105   ViENetworkTest() : vie_("ViENetworkTest"), channel_(-1), transport() {}
    106   virtual ~ViENetworkTest() {}
    107 
    108   virtual void SetUp() {
    109     EXPECT_EQ(0, vie_.base->CreateChannel(channel_));
    110     EXPECT_EQ(0, vie_.rtp_rtcp->SetRembStatus(channel_, false, true));
    111     EXPECT_EQ(0, vie_.network->RegisterSendTransport(channel_, transport));
    112   }
    113 
    114   virtual void TearDown() {
    115     EXPECT_EQ(0, vie_.network->DeregisterSendTransport(channel_));
    116   }
    117 
    118   void ReceiveASTPacketsForBWE() {
    119     for (int i = 0; i < kPacketCount; ++i) {
    120       int64_t time = webrtc::TickTime::MillisecondTimestamp();
    121       webrtc::RTPHeader header;
    122       header.ssrc = kSsrc1;
    123       header.timestamp = i * 45000;
    124       header.extension.hasAbsoluteSendTime = true;
    125       header.extension.absoluteSendTime = i << (18 - 6);
    126       EXPECT_EQ(0, vie_.network->ReceivedBWEPacket(channel_, time, kPacketSize,
    127                                                    header));
    128       webrtc::SleepMs(kIntervalMs);
    129     }
    130   }
    131 
    132   enum {
    133     kSsrc1 = 667,
    134     kSsrc2 = 668,
    135     kPacketCount = 100,
    136     kPacketSize = 1000,
    137     kIntervalMs = 22
    138   };
    139   TbInterfaces vie_;
    140   int channel_;
    141   RtcpCollectorTransport transport;
    142 };
    143 
    144 TEST_F(ViENetworkTest, ReceiveBWEPacket_NoExtension)  {
    145   for (int i = 0; i < kPacketCount; ++i) {
    146     int64_t time = webrtc::TickTime::MillisecondTimestamp();
    147     webrtc::RTPHeader header;
    148     header.ssrc = kSsrc1;
    149     header.timestamp = i * 45000;
    150     EXPECT_EQ(0, vie_.network->ReceivedBWEPacket(channel_, time, kPacketSize,
    151                                                  header));
    152     webrtc::SleepMs(kIntervalMs);
    153   }
    154   EXPECT_FALSE(transport.FindREMBFor(kSsrc1, 0.0));
    155   unsigned int bandwidth = 0;
    156   EXPECT_EQ(0, vie_.rtp_rtcp->GetEstimatedReceiveBandwidth(channel_,
    157                                                            &bandwidth));
    158 }
    159 
    160 TEST_F(ViENetworkTest, ReceiveBWEPacket_TOF)  {
    161   EXPECT_EQ(0, vie_.rtp_rtcp->SetReceiveTimestampOffsetStatus(channel_, true,
    162                                                               1));
    163   for (int i = 0; i < kPacketCount; ++i) {
    164     int64_t time = webrtc::TickTime::MillisecondTimestamp();
    165     webrtc::RTPHeader header;
    166     header.ssrc = kSsrc1;
    167     header.timestamp = i * 45000;
    168     header.extension.hasTransmissionTimeOffset = true;
    169     header.extension.transmissionTimeOffset = 17;
    170     EXPECT_EQ(0, vie_.network->ReceivedBWEPacket(channel_, time, kPacketSize,
    171                                                  header));
    172     webrtc::SleepMs(kIntervalMs);
    173   }
    174   EXPECT_FALSE(transport.FindREMBFor(kSsrc1, 0.0));
    175   unsigned int bandwidth = 0;
    176   EXPECT_EQ(0, vie_.rtp_rtcp->GetEstimatedReceiveBandwidth(channel_,
    177                                                            &bandwidth));
    178 }
    179 
    180 TEST_F(ViENetworkTest, ReceiveBWEPacket_AST)  {
    181   EXPECT_EQ(0, vie_.rtp_rtcp->SetReceiveAbsoluteSendTimeStatus(channel_, true,
    182                                                                1));
    183   ReceiveASTPacketsForBWE();
    184   EXPECT_TRUE(transport.FindREMBFor(kSsrc1, 100000.0));
    185   unsigned int bandwidth = 0;
    186   EXPECT_EQ(0, vie_.rtp_rtcp->GetEstimatedReceiveBandwidth(channel_,
    187                                                            &bandwidth));
    188   EXPECT_GT(bandwidth, 0u);
    189 }
    190 
    191 TEST_F(ViENetworkTest, ReceiveBWEPacket_ASTx2)  {
    192   EXPECT_EQ(0, vie_.rtp_rtcp->SetReceiveAbsoluteSendTimeStatus(channel_, true,
    193                                                                1));
    194   for (int i = 0; i < kPacketCount; ++i) {
    195     int64_t time = webrtc::TickTime::MillisecondTimestamp();
    196     webrtc::RTPHeader header;
    197     header.ssrc = kSsrc1;
    198     header.timestamp = i * 45000;
    199     header.extension.hasAbsoluteSendTime = true;
    200     header.extension.absoluteSendTime = i << (18 - 6);
    201     EXPECT_EQ(0, vie_.network->ReceivedBWEPacket(channel_, time, kPacketSize,
    202                                                  header));
    203     header.ssrc = kSsrc2;
    204     header.timestamp += 171717;
    205     EXPECT_EQ(0, vie_.network->ReceivedBWEPacket(channel_, time, kPacketSize,
    206                                                  header));
    207     webrtc::SleepMs(kIntervalMs);
    208   }
    209   EXPECT_TRUE(transport.FindREMBFor(kSsrc1, 200000.0));
    210   EXPECT_TRUE(transport.FindREMBFor(kSsrc2, 200000.0));
    211   unsigned int bandwidth = 0;
    212   EXPECT_EQ(0, vie_.rtp_rtcp->GetEstimatedReceiveBandwidth(channel_,
    213                                                            &bandwidth));
    214   EXPECT_GT(bandwidth, 0u);
    215 }
    216 
    217 TEST_F(ViENetworkTest, ReceiveBWEPacket_AST_DisabledReceive)  {
    218   EXPECT_EQ(0, vie_.rtp_rtcp->SetReceiveAbsoluteSendTimeStatus(channel_, false,
    219                                                                1));
    220   ReceiveASTPacketsForBWE();
    221   EXPECT_FALSE(transport.FindREMBFor(kSsrc1, 0.0));
    222   unsigned int bandwidth = 0;
    223   EXPECT_EQ(0, vie_.rtp_rtcp->GetEstimatedReceiveBandwidth(channel_,
    224                                                            &bandwidth));
    225 }
    226 }  // namespace
    227