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