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 21namespace { 22 23class 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 103class 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 144TEST_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 160TEST_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 180TEST_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 191TEST_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 217TEST_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