blob: 64830dab70f128ff2939e4ecb536c152de5eb28d [file] [log] [blame]
stefan@webrtc.org686a4472012-11-07 18:35:30 +00001/*
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
stefan@webrtc.org686a4472012-11-07 18:35:30 +000014#include <list>
15#include <map>
16#include <utility>
17
pbos@webrtc.orgd5d709e2013-05-27 12:41:33 +000018#include "testing/gtest/include/gtest/gtest.h"
stefan@webrtc.org2a5dbce2013-02-01 14:33:42 +000019#include "webrtc/modules/remote_bitrate_estimator/include/remote_bitrate_estimator.h"
20#include "webrtc/system_wrappers/interface/clock.h"
21#include "webrtc/system_wrappers/interface/constructor_magic.h"
22#include "webrtc/system_wrappers/interface/scoped_ptr.h"
stefan@webrtc.org686a4472012-11-07 18:35:30 +000023
24namespace webrtc {
stefan@webrtc.org686a4472012-11-07 18:35:30 +000025namespace testing {
26
27class TestBitrateObserver : public RemoteBitrateObserver {
28 public:
29 TestBitrateObserver() : updated_(false), latest_bitrate_(0) {}
solenberg@webrtc.orgb7716d82013-05-22 19:04:19 +000030 virtual ~TestBitrateObserver() {}
stefan@webrtc.org686a4472012-11-07 18:35:30 +000031
solenberg@webrtc.orgb7716d82013-05-22 19:04:19 +000032 virtual void OnReceiveBitrateChanged(const std::vector<unsigned int>& ssrcs,
pbos@webrtc.org988a5b32013-07-31 15:16:52 +000033 unsigned int bitrate) OVERRIDE;
stefan@webrtc.org686a4472012-11-07 18:35:30 +000034
pbos@webrtc.org988a5b32013-07-31 15:16:52 +000035 void Reset() { updated_ = false; }
stefan@webrtc.org686a4472012-11-07 18:35:30 +000036
pbos@webrtc.org988a5b32013-07-31 15:16:52 +000037 bool updated() const { return updated_; }
stefan@webrtc.org686a4472012-11-07 18:35:30 +000038
pbos@webrtc.org988a5b32013-07-31 15:16:52 +000039 unsigned int latest_bitrate() const { return latest_bitrate_; }
stefan@webrtc.org686a4472012-11-07 18:35:30 +000040
41 private:
42 bool updated_;
43 unsigned int latest_bitrate_;
44};
45
stefan@webrtc.org686a4472012-11-07 18:35:30 +000046class RtpStream {
47 public:
48 struct RtpPacket {
49 int64_t send_time;
50 int64_t arrival_time;
51 uint32_t rtp_timestamp;
52 unsigned int size;
53 unsigned int ssrc;
54 };
55
56 struct RtcpPacket {
57 uint32_t ntp_secs;
58 uint32_t ntp_frac;
59 uint32_t timestamp;
60 unsigned int ssrc;
61 };
62
63 typedef std::list<RtpPacket*> PacketList;
64
stefan@webrtc.org2a5dbce2013-02-01 14:33:42 +000065 enum { kSendSideOffsetUs = 1000000 };
stefan@webrtc.org686a4472012-11-07 18:35:30 +000066
67 RtpStream(int fps, int bitrate_bps, unsigned int ssrc, unsigned int frequency,
68 uint32_t timestamp_offset, int64_t rtcp_receive_time);
69 void set_rtp_timestamp_offset(uint32_t offset);
70
71 // Generates a new frame for this stream. If called too soon after the
72 // previous frame, no frame will be generated. The frame is split into
73 // packets.
stefan@webrtc.org2a5dbce2013-02-01 14:33:42 +000074 int64_t GenerateFrame(int64_t time_now_us, PacketList* packets);
stefan@webrtc.org686a4472012-11-07 18:35:30 +000075
76 // The send-side time when the next frame can be generated.
77 double next_rtp_time() const;
78
79 // Generates an RTCP packet.
stefan@webrtc.org2a5dbce2013-02-01 14:33:42 +000080 RtcpPacket* Rtcp(int64_t time_now_us);
stefan@webrtc.org686a4472012-11-07 18:35:30 +000081
82 void set_bitrate_bps(int bitrate_bps);
83
84 int bitrate_bps() const;
85
86 unsigned int ssrc() const;
87
88 static bool Compare(const std::pair<unsigned int, RtpStream*>& left,
89 const std::pair<unsigned int, RtpStream*>& right);
90
91 private:
stefan@webrtc.org2a5dbce2013-02-01 14:33:42 +000092 enum { kRtcpIntervalUs = 1000000 };
stefan@webrtc.org686a4472012-11-07 18:35:30 +000093
94 int fps_;
95 int bitrate_bps_;
96 unsigned int ssrc_;
97 unsigned int frequency_;
stefan@webrtc.org2a5dbce2013-02-01 14:33:42 +000098 int64_t next_rtp_time_;
99 int64_t next_rtcp_time_;
stefan@webrtc.org686a4472012-11-07 18:35:30 +0000100 uint32_t rtp_timestamp_offset_;
101 const double kNtpFracPerMs;
102
103 DISALLOW_COPY_AND_ASSIGN(RtpStream);
104};
105
106class StreamGenerator {
107 public:
108 typedef std::list<RtpStream::RtcpPacket*> RtcpList;
109
110 StreamGenerator(int capacity, double time_now);
111
112 ~StreamGenerator();
113
114 // Add a new stream.
115 void AddStream(RtpStream* stream);
116
117 // Set the link capacity.
118 void set_capacity_bps(int capacity_bps);
119
120 // Divides |bitrate_bps| among all streams. The allocated bitrate per stream
121 // is decided by the initial allocation ratios.
solenberg@webrtc.orgb7716d82013-05-22 19:04:19 +0000122 void SetBitrateBps(int bitrate_bps);
stefan@webrtc.org686a4472012-11-07 18:35:30 +0000123
124 // Set the RTP timestamp offset for the stream identified by |ssrc|.
125 void set_rtp_timestamp_offset(unsigned int ssrc, uint32_t offset);
126
127 // TODO(holmer): Break out the channel simulation part from this class to make
128 // it possible to simulate different types of channels.
stefan@webrtc.org2a5dbce2013-02-01 14:33:42 +0000129 int64_t GenerateFrame(RtpStream::PacketList* packets, int64_t time_now_us);
stefan@webrtc.org686a4472012-11-07 18:35:30 +0000130
stefan@webrtc.org686a4472012-11-07 18:35:30 +0000131 private:
132 typedef std::map<unsigned int, RtpStream*> StreamMap;
133
134 // Capacity of the simulated channel in bits per second.
135 int capacity_;
136 // The time when the last packet arrived.
stefan@webrtc.org2a5dbce2013-02-01 14:33:42 +0000137 int64_t prev_arrival_time_us_;
stefan@webrtc.org686a4472012-11-07 18:35:30 +0000138 // All streams being transmitted on this simulated channel.
139 StreamMap streams_;
140
141 DISALLOW_COPY_AND_ASSIGN(StreamGenerator);
142};
143} // namespace testing
144
145class RemoteBitrateEstimatorTest : public ::testing::Test {
146 public:
147 RemoteBitrateEstimatorTest();
pbos@webrtc.org988a5b32013-07-31 15:16:52 +0000148 virtual ~RemoteBitrateEstimatorTest();
stefan@webrtc.org686a4472012-11-07 18:35:30 +0000149
150 protected:
solenberg@webrtc.orgb7716d82013-05-22 19:04:19 +0000151 virtual void SetUp() = 0;
stefan@webrtc.org686a4472012-11-07 18:35:30 +0000152
153 void AddDefaultStream();
154
solenberg@webrtc.orgb7716d82013-05-22 19:04:19 +0000155 // Helper to convert some time format to resolution used in absolute send time
156 // header extension, rounded upwards. |t| is the time to convert, in some
157 // resolution. |denom| is the value to divide |t| by to get whole seconds,
158 // e.g. |denom| = 1000 if |t| is in milliseconds.
159 static uint32_t AbsSendTime(int64_t t, int64_t denom);
160
161 // Helper to add two absolute send time values and keep it less than 1<<24.
162 static uint32_t AddAbsSendTime(uint32_t t1, uint32_t t2);
163
164 // Helper to create a WebRtcRTPHeader containing the relevant data for the
165 // estimator (all other fields are cleared) and call IncomingPacket on the
166 // estimator.
167 void IncomingPacket(uint32_t ssrc,
168 uint32_t payload_size,
169 int64_t arrival_time,
170 uint32_t rtp_timestamp,
171 uint32_t absolute_send_time);
172
stefan@webrtc.org686a4472012-11-07 18:35:30 +0000173 // Generates a frame of packets belonging to a stream at a given bitrate and
174 // with a given ssrc. The stream is pushed through a very simple simulated
175 // network, and is then given to the receive-side bandwidth estimator.
176 // Returns true if an over-use was seen, false otherwise.
177 // The StreamGenerator::updated() should be used to check for any changes in
178 // target bitrate after the call to this function.
179 bool GenerateAndProcessFrame(unsigned int ssrc, unsigned int bitrate_bps);
180
stefan@webrtc.org2a5dbce2013-02-01 14:33:42 +0000181 // Run the bandwidth estimator with a stream of |number_of_frames| frames, or
182 // until it reaches |target_bitrate|.
stefan@webrtc.org686a4472012-11-07 18:35:30 +0000183 // Can for instance be used to run the estimator for some time to get it
184 // into a steady state.
185 unsigned int SteadyStateRun(unsigned int ssrc,
186 int number_of_frames,
187 unsigned int start_bitrate,
188 unsigned int min_bitrate,
stefan@webrtc.org2a5dbce2013-02-01 14:33:42 +0000189 unsigned int max_bitrate,
190 unsigned int target_bitrate);
stefan@webrtc.org686a4472012-11-07 18:35:30 +0000191
solenberg@webrtc.orgb7716d82013-05-22 19:04:19 +0000192 void InitialBehaviorTestHelper(unsigned int expected_converge_bitrate);
193 void RateIncreaseReorderingTestHelper();
194 void RateIncreaseRtpTimestampsTestHelper();
195 void CapacityDropTestHelper(int number_of_streams,
196 bool wrap_time_stamp,
197 unsigned int expected_converge_bitrate,
198 unsigned int expected_bitrate_drop_delta);
199
pbos@webrtc.org98b20112013-05-07 12:36:21 +0000200 static const unsigned int kDefaultSsrc;
stefan@webrtc.org686a4472012-11-07 18:35:30 +0000201
stefan@webrtc.org2a5dbce2013-02-01 14:33:42 +0000202 SimulatedClock clock_; // Time at the receiver.
stefan@webrtc.org686a4472012-11-07 18:35:30 +0000203 scoped_ptr<testing::TestBitrateObserver> bitrate_observer_;
solenberg@webrtc.orgb7716d82013-05-22 19:04:19 +0000204 scoped_ptr<RemoteBitrateEstimator> bitrate_estimator_;
stefan@webrtc.org686a4472012-11-07 18:35:30 +0000205 scoped_ptr<testing::StreamGenerator> stream_generator_;
stefan@webrtc.org686a4472012-11-07 18:35:30 +0000206
207 DISALLOW_COPY_AND_ASSIGN(RemoteBitrateEstimatorTest);
208};
solenberg@webrtc.orgb7716d82013-05-22 19:04:19 +0000209} // namespace webrtc
stefan@webrtc.org686a4472012-11-07 18:35:30 +0000210
211#endif // WEBRTC_MODULES_REMOTE_BITRATE_ESTIMATOR_REMOTE_BITRATE_ESTIMATOR_UNITTEST_HELPER_H_