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