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