1/*
2 *  Copyright (c) 2012 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#ifndef WEBRTC_MODULES_REMOTE_BITRATE_ESTIMATOR_REMOTE_BITRATE_ESTIMATOR_UNITTEST_HELPER_H_
12#define WEBRTC_MODULES_REMOTE_BITRATE_ESTIMATOR_REMOTE_BITRATE_ESTIMATOR_UNITTEST_HELPER_H_
13
14#include <list>
15#include <map>
16#include <utility>
17#include <vector>
18
19#include "testing/gtest/include/gtest/gtest.h"
20#include "webrtc/base/constructormagic.h"
21#include "webrtc/base/scoped_ptr.h"
22#include "webrtc/modules/remote_bitrate_estimator/include/remote_bitrate_estimator.h"
23#include "webrtc/system_wrappers/include/clock.h"
24
25namespace webrtc {
26namespace testing {
27
28class TestBitrateObserver : public RemoteBitrateObserver {
29 public:
30  TestBitrateObserver() : updated_(false), latest_bitrate_(0) {}
31  virtual ~TestBitrateObserver() {}
32
33  void OnReceiveBitrateChanged(const std::vector<unsigned int>& ssrcs,
34                               unsigned int bitrate) override;
35
36  void Reset() { updated_ = false; }
37
38  bool updated() const { return updated_; }
39
40  unsigned int latest_bitrate() const { return latest_bitrate_; }
41
42 private:
43  bool updated_;
44  unsigned int latest_bitrate_;
45};
46
47class RtpStream {
48 public:
49  struct RtpPacket {
50    int64_t send_time;
51    int64_t arrival_time;
52    uint32_t rtp_timestamp;
53    size_t size;
54    unsigned int ssrc;
55  };
56
57  struct RtcpPacket {
58    uint32_t ntp_secs;
59    uint32_t ntp_frac;
60    uint32_t timestamp;
61    unsigned int ssrc;
62  };
63
64  typedef std::list<RtpPacket*> PacketList;
65
66  enum { kSendSideOffsetUs = 1000000 };
67
68  RtpStream(int fps, int bitrate_bps, unsigned int ssrc, unsigned int frequency,
69      uint32_t timestamp_offset, int64_t rtcp_receive_time);
70  void set_rtp_timestamp_offset(uint32_t offset);
71
72  // Generates a new frame for this stream. If called too soon after the
73  // previous frame, no frame will be generated. The frame is split into
74  // packets.
75  int64_t GenerateFrame(int64_t time_now_us, PacketList* packets);
76
77  // The send-side time when the next frame can be generated.
78  double next_rtp_time() const;
79
80  // Generates an RTCP packet.
81  RtcpPacket* Rtcp(int64_t time_now_us);
82
83  void set_bitrate_bps(int bitrate_bps);
84
85  int bitrate_bps() const;
86
87  unsigned int ssrc() const;
88
89  static bool Compare(const std::pair<unsigned int, RtpStream*>& left,
90                      const std::pair<unsigned int, RtpStream*>& right);
91
92 private:
93  enum { kRtcpIntervalUs = 1000000 };
94
95  int fps_;
96  int bitrate_bps_;
97  unsigned int ssrc_;
98  unsigned int frequency_;
99  int64_t next_rtp_time_;
100  int64_t next_rtcp_time_;
101  uint32_t rtp_timestamp_offset_;
102  const double kNtpFracPerMs;
103
104  RTC_DISALLOW_COPY_AND_ASSIGN(RtpStream);
105};
106
107class StreamGenerator {
108 public:
109  typedef std::list<RtpStream::RtcpPacket*> RtcpList;
110
111  StreamGenerator(int capacity, double time_now);
112
113  ~StreamGenerator();
114
115  // Add a new stream.
116  void AddStream(RtpStream* stream);
117
118  // Set the link capacity.
119  void set_capacity_bps(int capacity_bps);
120
121  // Divides |bitrate_bps| among all streams. The allocated bitrate per stream
122  // is decided by the initial allocation ratios.
123  void SetBitrateBps(int bitrate_bps);
124
125  // Set the RTP timestamp offset for the stream identified by |ssrc|.
126  void set_rtp_timestamp_offset(unsigned int ssrc, uint32_t offset);
127
128  // TODO(holmer): Break out the channel simulation part from this class to make
129  // it possible to simulate different types of channels.
130  int64_t GenerateFrame(RtpStream::PacketList* packets, int64_t time_now_us);
131
132 private:
133  typedef std::map<unsigned int, RtpStream*> StreamMap;
134
135  // Capacity of the simulated channel in bits per second.
136  int capacity_;
137  // The time when the last packet arrived.
138  int64_t prev_arrival_time_us_;
139  // All streams being transmitted on this simulated channel.
140  StreamMap streams_;
141
142  RTC_DISALLOW_COPY_AND_ASSIGN(StreamGenerator);
143};
144}  // namespace testing
145
146class RemoteBitrateEstimatorTest : public ::testing::Test {
147 public:
148  RemoteBitrateEstimatorTest();
149  virtual ~RemoteBitrateEstimatorTest();
150
151 protected:
152  virtual void SetUp() = 0;
153
154  void AddDefaultStream();
155
156  // Helper to convert some time format to resolution used in absolute send time
157  // header extension, rounded upwards. |t| is the time to convert, in some
158  // resolution. |denom| is the value to divide |t| by to get whole seconds,
159  // e.g. |denom| = 1000 if |t| is in milliseconds.
160  static uint32_t AbsSendTime(int64_t t, int64_t denom);
161
162  // Helper to add two absolute send time values and keep it less than 1<<24.
163  static uint32_t AddAbsSendTime(uint32_t t1, uint32_t t2);
164
165  // Helper to create a WebRtcRTPHeader containing the relevant data for the
166  // estimator (all other fields are cleared) and call IncomingPacket on the
167  // estimator.
168  void IncomingPacket(uint32_t ssrc,
169                      size_t payload_size,
170                      int64_t arrival_time,
171                      uint32_t rtp_timestamp,
172                      uint32_t absolute_send_time,
173                      bool was_paced);
174
175  // Generates a frame of packets belonging to a stream at a given bitrate and
176  // with a given ssrc. The stream is pushed through a very simple simulated
177  // network, and is then given to the receive-side bandwidth estimator.
178  // Returns true if an over-use was seen, false otherwise.
179  // The StreamGenerator::updated() should be used to check for any changes in
180  // target bitrate after the call to this function.
181  bool GenerateAndProcessFrame(unsigned int ssrc, unsigned int bitrate_bps);
182
183  // Run the bandwidth estimator with a stream of |number_of_frames| frames, or
184  // until it reaches |target_bitrate|.
185  // Can for instance be used to run the estimator for some time to get it
186  // into a steady state.
187  unsigned int SteadyStateRun(unsigned int ssrc,
188                              int number_of_frames,
189                              unsigned int start_bitrate,
190                              unsigned int min_bitrate,
191                              unsigned int max_bitrate,
192                              unsigned int target_bitrate);
193
194  void TestTimestampGroupingTestHelper();
195
196  void TestGetStatsHelper();
197
198  void TestWrappingHelper(int silence_time_s);
199
200  void InitialBehaviorTestHelper(unsigned int expected_converge_bitrate);
201  void RateIncreaseReorderingTestHelper(unsigned int expected_bitrate);
202  void RateIncreaseRtpTimestampsTestHelper(int expected_iterations);
203  void CapacityDropTestHelper(int number_of_streams,
204                              bool wrap_time_stamp,
205                              unsigned int expected_bitrate_drop_delta);
206
207  static const unsigned int kDefaultSsrc;
208  static const int kArrivalTimeClockOffsetMs = 60000;
209
210  SimulatedClock clock_;  // Time at the receiver.
211  rtc::scoped_ptr<testing::TestBitrateObserver> bitrate_observer_;
212  rtc::scoped_ptr<RemoteBitrateEstimator> bitrate_estimator_;
213  rtc::scoped_ptr<testing::StreamGenerator> stream_generator_;
214
215  RTC_DISALLOW_COPY_AND_ASSIGN(RemoteBitrateEstimatorTest);
216};
217}  // namespace webrtc
218
219#endif  // WEBRTC_MODULES_REMOTE_BITRATE_ESTIMATOR_REMOTE_BITRATE_ESTIMATOR_UNITTEST_HELPER_H_
220