2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
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.
10 #include "webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_unittest_helper.h"
17 enum { kMtu = 1200, kAcceptedBitrateErrorBps = 50000u };
21 void TestBitrateObserver::OnReceiveBitrateChanged(
22 const std::vector<unsigned int>& ssrcs,
23 unsigned int bitrate) {
24 latest_bitrate_ = bitrate;
28 RtpStream::RtpStream(int fps,
31 unsigned int frequency,
32 uint32_t timestamp_offset,
33 int64_t rtcp_receive_time)
35 bitrate_bps_(bitrate_bps),
37 frequency_(frequency),
39 next_rtcp_time_(rtcp_receive_time),
40 rtp_timestamp_offset_(timestamp_offset),
41 kNtpFracPerMs(4.294967296E6) {
45 void RtpStream::set_rtp_timestamp_offset(uint32_t offset) {
46 rtp_timestamp_offset_ = offset;
49 // Generates a new frame for this stream. If called too soon after the
50 // previous frame, no frame will be generated. The frame is split into
52 int64_t RtpStream::GenerateFrame(int64_t time_now_us, PacketList* packets) {
53 if (time_now_us < next_rtp_time_) {
54 return next_rtp_time_;
56 assert(packets != NULL);
57 int bits_per_frame = (bitrate_bps_ + fps_ / 2) / fps_;
58 int n_packets = std::max((bits_per_frame + 4 * kMtu) / (8 * kMtu), 1);
59 int packet_size = (bits_per_frame + 4 * n_packets) / (8 * n_packets);
60 assert(n_packets >= 0);
61 for (int i = 0; i < n_packets; ++i) {
62 RtpPacket* packet = new RtpPacket;
63 packet->send_time = time_now_us + kSendSideOffsetUs;
64 packet->size = packet_size;
65 packet->rtp_timestamp = rtp_timestamp_offset_ + static_cast<uint32_t>(
66 ((frequency_ / 1000) * packet->send_time + 500) / 1000);
68 packets->push_back(packet);
70 next_rtp_time_ = time_now_us + (1000000 + fps_ / 2) / fps_;
71 return next_rtp_time_;
74 // The send-side time when the next frame can be generated.
75 double RtpStream::next_rtp_time() const {
76 return next_rtp_time_;
79 // Generates an RTCP packet.
80 RtpStream::RtcpPacket* RtpStream::Rtcp(int64_t time_now_us) {
81 if (time_now_us < next_rtcp_time_) {
84 RtcpPacket* rtcp = new RtcpPacket;
85 int64_t send_time_us = time_now_us + kSendSideOffsetUs;
86 rtcp->timestamp = rtp_timestamp_offset_ + static_cast<uint32_t>(
87 ((frequency_ / 1000) * send_time_us + 500) / 1000);
88 rtcp->ntp_secs = send_time_us / 1000000;
89 rtcp->ntp_frac = static_cast<int64_t>((send_time_us % 1000000) *
92 next_rtcp_time_ = time_now_us + kRtcpIntervalUs;
96 void RtpStream::set_bitrate_bps(int bitrate_bps) {
97 ASSERT_GE(bitrate_bps, 0);
98 bitrate_bps_ = bitrate_bps;
101 int RtpStream::bitrate_bps() const {
105 unsigned int RtpStream::ssrc() const {
109 bool RtpStream::Compare(const std::pair<unsigned int, RtpStream*>& left,
110 const std::pair<unsigned int, RtpStream*>& right) {
111 return left.second->next_rtp_time_ < right.second->next_rtp_time_;
114 StreamGenerator::StreamGenerator(int capacity, double time_now)
115 : capacity_(capacity),
116 prev_arrival_time_us_(time_now) {}
118 StreamGenerator::~StreamGenerator() {
119 for (StreamMap::iterator it = streams_.begin(); it != streams_.end();
127 void StreamGenerator::AddStream(RtpStream* stream) {
128 streams_[stream->ssrc()] = stream;
131 // Set the link capacity.
132 void StreamGenerator::set_capacity_bps(int capacity_bps) {
133 ASSERT_GT(capacity_bps, 0);
134 capacity_ = capacity_bps;
137 // Divides |bitrate_bps| among all streams. The allocated bitrate per stream
138 // is decided by the current allocation ratios.
139 void StreamGenerator::SetBitrateBps(int bitrate_bps) {
140 ASSERT_GE(streams_.size(), 0u);
141 int total_bitrate_before = 0;
142 for (StreamMap::iterator it = streams_.begin(); it != streams_.end(); ++it) {
143 total_bitrate_before += it->second->bitrate_bps();
145 int64_t bitrate_before = 0;
146 int total_bitrate_after = 0;
147 for (StreamMap::iterator it = streams_.begin(); it != streams_.end(); ++it) {
148 bitrate_before += it->second->bitrate_bps();
149 int64_t bitrate_after = (bitrate_before * bitrate_bps +
150 total_bitrate_before / 2) / total_bitrate_before;
151 it->second->set_bitrate_bps(bitrate_after - total_bitrate_after);
152 total_bitrate_after += it->second->bitrate_bps();
154 ASSERT_EQ(bitrate_before, total_bitrate_before);
155 EXPECT_EQ(total_bitrate_after, bitrate_bps);
158 // Set the RTP timestamp offset for the stream identified by |ssrc|.
159 void StreamGenerator::set_rtp_timestamp_offset(unsigned int ssrc,
161 streams_[ssrc]->set_rtp_timestamp_offset(offset);
164 // TODO(holmer): Break out the channel simulation part from this class to make
165 // it possible to simulate different types of channels.
166 int64_t StreamGenerator::GenerateFrame(RtpStream::PacketList* packets,
167 int64_t time_now_us) {
168 assert(packets != NULL);
169 assert(packets->empty());
170 assert(capacity_ > 0);
171 StreamMap::iterator it = std::min_element(streams_.begin(), streams_.end(),
173 (*it).second->GenerateFrame(time_now_us, packets);
175 for (RtpStream::PacketList::iterator packet_it = packets->begin();
176 packet_it != packets->end(); ++packet_it) {
177 int capacity_bpus = capacity_ / 1000;
178 int64_t required_network_time_us =
179 (8 * 1000 * (*packet_it)->size + capacity_bpus / 2) / capacity_bpus;
180 prev_arrival_time_us_ = std::max(time_now_us + required_network_time_us,
181 prev_arrival_time_us_ + required_network_time_us);
182 (*packet_it)->arrival_time = prev_arrival_time_us_;
185 it = std::min_element(streams_.begin(), streams_.end(), RtpStream::Compare);
186 return (*it).second->next_rtp_time();
188 } // namespace testing
190 RemoteBitrateEstimatorTest::RemoteBitrateEstimatorTest()
192 bitrate_observer_(new testing::TestBitrateObserver),
193 stream_generator_(new testing::StreamGenerator(
195 clock_.TimeInMicroseconds())) {}
197 RemoteBitrateEstimatorTest::~RemoteBitrateEstimatorTest() {}
199 void RemoteBitrateEstimatorTest::AddDefaultStream() {
200 stream_generator_->AddStream(new testing::RtpStream(
201 30, // Frames per second.
204 90000, // RTP frequency.
205 0xFFFFF000, // Timestamp offset.
206 0)); // RTCP receive time.
209 uint32_t RemoteBitrateEstimatorTest::AbsSendTime(int64_t t, int64_t denom) {
210 return (((t << 18) + (denom >> 1)) / denom) & 0x00fffffful;
213 uint32_t RemoteBitrateEstimatorTest::AddAbsSendTime(uint32_t t1, uint32_t t2) {
214 return (t1 + t2) & 0x00fffffful;
217 const unsigned int RemoteBitrateEstimatorTest::kDefaultSsrc = 1;
219 void RemoteBitrateEstimatorTest::IncomingPacket(uint32_t ssrc,
220 uint32_t payload_size,
221 int64_t arrival_time,
222 uint32_t rtp_timestamp,
223 uint32_t absolute_send_time) {
225 memset(&header, 0, sizeof(header));
227 header.timestamp = rtp_timestamp;
228 header.extension.hasAbsoluteSendTime = true;
229 header.extension.absoluteSendTime = absolute_send_time;
230 bitrate_estimator_->IncomingPacket(arrival_time + kArrivalTimeClockOffsetMs,
231 payload_size, header);
234 // Generates a frame of packets belonging to a stream at a given bitrate and
235 // with a given ssrc. The stream is pushed through a very simple simulated
236 // network, and is then given to the receive-side bandwidth estimator.
237 // Returns true if an over-use was seen, false otherwise.
238 // The StreamGenerator::updated() should be used to check for any changes in
239 // target bitrate after the call to this function.
240 bool RemoteBitrateEstimatorTest::GenerateAndProcessFrame(unsigned int ssrc,
241 unsigned int bitrate_bps) {
242 stream_generator_->SetBitrateBps(bitrate_bps);
243 testing::RtpStream::PacketList packets;
244 int64_t next_time_us = stream_generator_->GenerateFrame(
245 &packets, clock_.TimeInMicroseconds());
246 bool overuse = false;
247 while (!packets.empty()) {
248 testing::RtpStream::RtpPacket* packet = packets.front();
249 bitrate_observer_->Reset();
250 // The simulated clock should match the time of packet->arrival_time
251 // since both are used in IncomingPacket().
252 clock_.AdvanceTimeMicroseconds(packet->arrival_time -
253 clock_.TimeInMicroseconds());
254 IncomingPacket(packet->ssrc,
256 (packet->arrival_time + 500) / 1000,
257 packet->rtp_timestamp,
258 AbsSendTime(packet->send_time, 1000000));
259 if (bitrate_observer_->updated()) {
260 // Verify that new estimates only are triggered by an overuse and a
263 EXPECT_LE(bitrate_observer_->latest_bitrate(), bitrate_bps);
268 bitrate_estimator_->Process();
269 clock_.AdvanceTimeMicroseconds(next_time_us - clock_.TimeInMicroseconds());
273 // Run the bandwidth estimator with a stream of |number_of_frames| frames, or
274 // until it reaches |target_bitrate|.
275 // Can for instance be used to run the estimator for some time to get it
276 // into a steady state.
277 unsigned int RemoteBitrateEstimatorTest::SteadyStateRun(
279 int max_number_of_frames,
280 unsigned int start_bitrate,
281 unsigned int min_bitrate,
282 unsigned int max_bitrate,
283 unsigned int target_bitrate) {
284 unsigned int bitrate_bps = start_bitrate;
285 bool bitrate_update_seen = false;
286 // Produce |number_of_frames| frames and give them to the estimator.
287 for (int i = 0; i < max_number_of_frames; ++i) {
288 bool overuse = GenerateAndProcessFrame(ssrc, bitrate_bps);
290 EXPECT_LT(bitrate_observer_->latest_bitrate(), max_bitrate);
291 EXPECT_GT(bitrate_observer_->latest_bitrate(), min_bitrate);
292 bitrate_bps = bitrate_observer_->latest_bitrate();
293 bitrate_update_seen = true;
294 } else if (bitrate_observer_->updated()) {
295 bitrate_bps = bitrate_observer_->latest_bitrate();
296 bitrate_observer_->Reset();
298 if (bitrate_update_seen && bitrate_bps > target_bitrate) {
302 EXPECT_TRUE(bitrate_update_seen);
306 void RemoteBitrateEstimatorTest::InitialBehaviorTestHelper(
307 unsigned int expected_converge_bitrate) {
308 const int kFramerate = 50; // 50 fps to avoid rounding errors.
309 const int kFrameIntervalMs = 1000 / kFramerate;
310 const uint32_t kFrameIntervalAbsSendTime = AbsSendTime(1, kFramerate);
311 unsigned int bitrate_bps = 0;
312 uint32_t timestamp = 0;
313 uint32_t absolute_send_time = 0;
314 std::vector<unsigned int> ssrcs;
315 EXPECT_FALSE(bitrate_estimator_->LatestEstimate(&ssrcs, &bitrate_bps));
316 EXPECT_EQ(0u, ssrcs.size());
317 clock_.AdvanceTimeMilliseconds(1000);
318 bitrate_estimator_->Process();
319 EXPECT_FALSE(bitrate_estimator_->LatestEstimate(&ssrcs, &bitrate_bps));
320 EXPECT_FALSE(bitrate_observer_->updated());
321 bitrate_observer_->Reset();
322 clock_.AdvanceTimeMilliseconds(1000);
323 // Inserting a packet. Still no valid estimate. We need to wait 1 second.
324 IncomingPacket(kDefaultSsrc, kMtu, clock_.TimeInMilliseconds(), timestamp,
326 bitrate_estimator_->Process();
327 EXPECT_FALSE(bitrate_estimator_->LatestEstimate(&ssrcs, &bitrate_bps));
328 EXPECT_EQ(0u, ssrcs.size());
329 EXPECT_FALSE(bitrate_observer_->updated());
330 bitrate_observer_->Reset();
331 // Inserting packets for one second to get a valid estimate.
332 for (int i = 0; i < kFramerate; ++i) {
333 IncomingPacket(kDefaultSsrc, kMtu, clock_.TimeInMilliseconds(), timestamp,
335 clock_.AdvanceTimeMilliseconds(1000 / kFramerate);
336 timestamp += 90 * kFrameIntervalMs;
337 absolute_send_time = AddAbsSendTime(absolute_send_time,
338 kFrameIntervalAbsSendTime);
340 bitrate_estimator_->Process();
341 EXPECT_TRUE(bitrate_estimator_->LatestEstimate(&ssrcs, &bitrate_bps));
342 ASSERT_EQ(1u, ssrcs.size());
343 EXPECT_EQ(kDefaultSsrc, ssrcs.front());
344 EXPECT_NEAR(expected_converge_bitrate, bitrate_bps, kAcceptedBitrateErrorBps);
345 EXPECT_TRUE(bitrate_observer_->updated());
346 bitrate_observer_->Reset();
347 EXPECT_EQ(bitrate_observer_->latest_bitrate(), bitrate_bps);
348 bitrate_estimator_->RemoveStream(kDefaultSsrc);
349 EXPECT_TRUE(bitrate_estimator_->LatestEstimate(&ssrcs, &bitrate_bps));
350 ASSERT_EQ(0u, ssrcs.size());
351 EXPECT_EQ(0u, bitrate_bps);
354 void RemoteBitrateEstimatorTest::RateIncreaseReorderingTestHelper(
355 uint32_t expected_bitrate_bps) {
356 const int kFramerate = 50; // 50 fps to avoid rounding errors.
357 const int kFrameIntervalMs = 1000 / kFramerate;
358 const uint32_t kFrameIntervalAbsSendTime = AbsSendTime(1, kFramerate);
359 uint32_t timestamp = 0;
360 uint32_t absolute_send_time = 0;
361 IncomingPacket(kDefaultSsrc, 1000, clock_.TimeInMilliseconds(), timestamp,
363 bitrate_estimator_->Process();
364 EXPECT_FALSE(bitrate_observer_->updated()); // No valid estimate.
365 // Inserting packets for one second to get a valid estimate.
366 for (int i = 0; i < kFramerate; ++i) {
367 IncomingPacket(kDefaultSsrc, kMtu, clock_.TimeInMilliseconds(), timestamp,
369 clock_.AdvanceTimeMilliseconds(kFrameIntervalMs);
370 timestamp += 90 * kFrameIntervalMs;
371 absolute_send_time = AddAbsSendTime(absolute_send_time,
372 kFrameIntervalAbsSendTime);
374 bitrate_estimator_->Process();
375 EXPECT_TRUE(bitrate_observer_->updated());
376 EXPECT_NEAR(expected_bitrate_bps,
377 bitrate_observer_->latest_bitrate(),
378 kAcceptedBitrateErrorBps);
379 for (int i = 0; i < 10; ++i) {
380 clock_.AdvanceTimeMilliseconds(2 * kFrameIntervalMs);
381 timestamp += 2 * 90 * kFrameIntervalMs;
382 absolute_send_time = AddAbsSendTime(absolute_send_time,
383 2 * kFrameIntervalAbsSendTime);
384 IncomingPacket(kDefaultSsrc, 1000, clock_.TimeInMilliseconds(), timestamp,
386 IncomingPacket(kDefaultSsrc, 1000, clock_.TimeInMilliseconds(),
387 timestamp - 90 * kFrameIntervalMs,
388 AddAbsSendTime(absolute_send_time,
389 -int(kFrameIntervalAbsSendTime)));
391 bitrate_estimator_->Process();
392 EXPECT_TRUE(bitrate_observer_->updated());
393 EXPECT_NEAR(expected_bitrate_bps,
394 bitrate_observer_->latest_bitrate(),
395 kAcceptedBitrateErrorBps);
398 // Make sure we initially increase the bitrate as expected.
399 void RemoteBitrateEstimatorTest::RateIncreaseRtpTimestampsTestHelper(
400 int expected_iterations) {
401 // This threshold corresponds approximately to increasing linearly with
402 // bitrate(i) = 1.04 * bitrate(i-1) + 1000
403 // until bitrate(i) > 500000, with bitrate(1) ~= 30000.
404 unsigned int bitrate_bps = 30000;
407 // Feed the estimator with a stream of packets and verify that it reaches
408 // 500 kbps at the expected time.
409 while (bitrate_bps < 5e5) {
410 bool overuse = GenerateAndProcessFrame(kDefaultSsrc, bitrate_bps);
412 EXPECT_GT(bitrate_observer_->latest_bitrate(), bitrate_bps);
413 bitrate_bps = bitrate_observer_->latest_bitrate();
414 bitrate_observer_->Reset();
415 } else if (bitrate_observer_->updated()) {
416 bitrate_bps = bitrate_observer_->latest_bitrate();
417 bitrate_observer_->Reset();
420 ASSERT_LE(iterations, expected_iterations);
422 ASSERT_EQ(expected_iterations, iterations);
425 void RemoteBitrateEstimatorTest::CapacityDropTestHelper(
426 int number_of_streams,
427 bool wrap_time_stamp,
428 unsigned int expected_bitrate_drop_delta) {
429 const int kFramerate = 30;
430 const int kStartBitrate = 900e3;
431 const int kMinExpectedBitrate = 800e3;
432 const int kMaxExpectedBitrate = 1100e3;
433 const unsigned int kInitialCapacityBps = 1000e3;
434 const unsigned int kReducedCapacityBps = 500e3;
436 int steady_state_time = 0;
437 if (number_of_streams <= 1) {
438 steady_state_time = 10;
441 steady_state_time = 8 * number_of_streams;
443 int kBitrateDenom = number_of_streams * (number_of_streams - 1);
444 for (int i = 0; i < number_of_streams; i++) {
445 // First stream gets half available bitrate, while the rest share the
446 // remaining half i.e.: 1/2 = Sum[n/(N*(N-1))] for n=1..N-1 (rounded up)
447 int bitrate = kStartBitrate / 2;
449 bitrate = (kStartBitrate * i + kBitrateDenom / 2) / kBitrateDenom;
451 stream_generator_->AddStream(new testing::RtpStream(
452 kFramerate, // Frames per second.
454 kDefaultSsrc + i, // SSRC.
455 90000, // RTP frequency.
456 0xFFFFF000 ^ (~0 << (32 - i)), // Timestamp offset.
457 0)); // RTCP receive time.
458 bitrate_sum += bitrate;
460 ASSERT_EQ(bitrate_sum, kStartBitrate);
462 if (wrap_time_stamp) {
463 stream_generator_->set_rtp_timestamp_offset(kDefaultSsrc,
464 std::numeric_limits<uint32_t>::max() - steady_state_time * 90000);
467 // Run in steady state to make the estimator converge.
468 stream_generator_->set_capacity_bps(kInitialCapacityBps);
469 unsigned int bitrate_bps = SteadyStateRun(kDefaultSsrc,
470 steady_state_time * kFramerate,
474 kInitialCapacityBps);
475 EXPECT_NEAR(kInitialCapacityBps, bitrate_bps, 100000u);
476 bitrate_observer_->Reset();
478 // Reduce the capacity and verify the decrease time.
479 stream_generator_->set_capacity_bps(kReducedCapacityBps);
480 int64_t overuse_start_time = clock_.TimeInMilliseconds();
481 int64_t bitrate_drop_time = -1;
482 for (int i = 0; i < 100 * number_of_streams; ++i) {
483 GenerateAndProcessFrame(kDefaultSsrc, bitrate_bps);
484 // Check for either increase or decrease.
485 if (bitrate_observer_->updated()) {
486 if (bitrate_drop_time == -1 &&
487 bitrate_observer_->latest_bitrate() <= kReducedCapacityBps) {
488 bitrate_drop_time = clock_.TimeInMilliseconds();
490 bitrate_bps = bitrate_observer_->latest_bitrate();
491 bitrate_observer_->Reset();
495 EXPECT_EQ(expected_bitrate_drop_delta,
496 bitrate_drop_time - overuse_start_time);
498 // Remove stream one by one.
499 unsigned int latest_bps = 0;
500 std::vector<unsigned int> ssrcs;
501 for (int i = 0; i < number_of_streams; i++) {
502 EXPECT_TRUE(bitrate_estimator_->LatestEstimate(&ssrcs, &latest_bps));
503 EXPECT_EQ(number_of_streams - i, static_cast<int>(ssrcs.size()));
504 EXPECT_EQ(bitrate_bps, latest_bps);
505 for (int j = i; j < number_of_streams; j++) {
506 EXPECT_EQ(kDefaultSsrc + j, ssrcs[j - i]);
508 bitrate_estimator_->RemoveStream(kDefaultSsrc + i);
510 EXPECT_TRUE(bitrate_estimator_->LatestEstimate(&ssrcs, &latest_bps));
511 EXPECT_EQ(0u, ssrcs.size());
512 EXPECT_EQ(0u, latest_bps);
514 } // namespace webrtc