blob: 88ffe061b99ad42927e54d09ead7f4a7527b89e6 [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#include "webrtc/modules/remote_bitrate_estimator/remote_bitrate_estimator_unittest_helper.h"
11
12#include <algorithm>
13#include <utility>
14
15namespace webrtc {
solenberg@webrtc.orgb7716d82013-05-22 19:04:19 +000016
17enum { kMtu = 1200 };
18
stefan@webrtc.org686a4472012-11-07 18:35:30 +000019namespace testing {
20
pbos@webrtc.org988a5b32013-07-31 15:16:52 +000021void TestBitrateObserver::OnReceiveBitrateChanged(
22 const std::vector<unsigned int>& ssrcs,
23 unsigned int bitrate) {
24 latest_bitrate_ = bitrate;
25 updated_ = true;
26}
27
stefan@webrtc.org686a4472012-11-07 18:35:30 +000028RtpStream::RtpStream(int fps,
29 int bitrate_bps,
30 unsigned int ssrc,
31 unsigned int frequency,
32 uint32_t timestamp_offset,
33 int64_t rtcp_receive_time)
34 : fps_(fps),
35 bitrate_bps_(bitrate_bps),
36 ssrc_(ssrc),
37 frequency_(frequency),
38 next_rtp_time_(0),
39 next_rtcp_time_(rtcp_receive_time),
40 rtp_timestamp_offset_(timestamp_offset),
41 kNtpFracPerMs(4.294967296E6) {
42 assert(fps_ > 0);
43}
44
45void RtpStream::set_rtp_timestamp_offset(uint32_t offset) {
46 rtp_timestamp_offset_ = offset;
47}
48
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
51// packets.
stefan@webrtc.org2a5dbce2013-02-01 14:33:42 +000052int64_t RtpStream::GenerateFrame(int64_t time_now_us, PacketList* packets) {
53 if (time_now_us < next_rtp_time_) {
stefan@webrtc.org686a4472012-11-07 18:35:30 +000054 return next_rtp_time_;
55 }
56 assert(packets != NULL);
57 int bits_per_frame = (bitrate_bps_ + fps_ / 2) / fps_;
stefan@webrtc.org2a5dbce2013-02-01 14:33:42 +000058 int n_packets = std::max((bits_per_frame + 4 * kMtu) / (8 * kMtu), 1);
stefan@webrtc.org686a4472012-11-07 18:35:30 +000059 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;
stefan@webrtc.org2a5dbce2013-02-01 14:33:42 +000063 packet->send_time = time_now_us + kSendSideOffsetUs;
stefan@webrtc.org686a4472012-11-07 18:35:30 +000064 packet->size = packet_size;
65 packet->rtp_timestamp = rtp_timestamp_offset_ + static_cast<uint32_t>(
stefan@webrtc.org2a5dbce2013-02-01 14:33:42 +000066 ((frequency_ / 1000) * packet->send_time + 500) / 1000);
stefan@webrtc.org686a4472012-11-07 18:35:30 +000067 packet->ssrc = ssrc_;
68 packets->push_back(packet);
69 }
stefan@webrtc.org2a5dbce2013-02-01 14:33:42 +000070 next_rtp_time_ = time_now_us + (1000000 + fps_ / 2) / fps_;
stefan@webrtc.org686a4472012-11-07 18:35:30 +000071 return next_rtp_time_;
72}
73
74// The send-side time when the next frame can be generated.
75double RtpStream::next_rtp_time() const {
76 return next_rtp_time_;
77}
78
79// Generates an RTCP packet.
stefan@webrtc.org2a5dbce2013-02-01 14:33:42 +000080RtpStream::RtcpPacket* RtpStream::Rtcp(int64_t time_now_us) {
81 if (time_now_us < next_rtcp_time_) {
stefan@webrtc.org686a4472012-11-07 18:35:30 +000082 return NULL;
83 }
84 RtcpPacket* rtcp = new RtcpPacket;
solenberg@webrtc.orgde0b5fa2013-05-22 20:53:42 +000085 int64_t send_time_us = time_now_us + kSendSideOffsetUs;
stefan@webrtc.org686a4472012-11-07 18:35:30 +000086 rtcp->timestamp = rtp_timestamp_offset_ + static_cast<uint32_t>(
solenberg@webrtc.orgde0b5fa2013-05-22 20:53:42 +000087 ((frequency_ / 1000) * send_time_us + 500) / 1000);
stefan@webrtc.org2a5dbce2013-02-01 14:33:42 +000088 rtcp->ntp_secs = send_time_us / 1000000;
solenberg@webrtc.orgde0b5fa2013-05-22 20:53:42 +000089 rtcp->ntp_frac = static_cast<int64_t>((send_time_us % 1000000) *
90 kNtpFracPerMs);
stefan@webrtc.org686a4472012-11-07 18:35:30 +000091 rtcp->ssrc = ssrc_;
stefan@webrtc.org2a5dbce2013-02-01 14:33:42 +000092 next_rtcp_time_ = time_now_us + kRtcpIntervalUs;
stefan@webrtc.org686a4472012-11-07 18:35:30 +000093 return rtcp;
94}
95
96void RtpStream::set_bitrate_bps(int bitrate_bps) {
97 ASSERT_GE(bitrate_bps, 0);
98 bitrate_bps_ = bitrate_bps;
99}
100
101int RtpStream::bitrate_bps() const {
102 return bitrate_bps_;
103}
104
105unsigned int RtpStream::ssrc() const {
106 return ssrc_;
107}
108
109bool 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_;
112}
113
114StreamGenerator::StreamGenerator(int capacity, double time_now)
115 : capacity_(capacity),
stefan@webrtc.org2a5dbce2013-02-01 14:33:42 +0000116 prev_arrival_time_us_(time_now) {}
stefan@webrtc.org686a4472012-11-07 18:35:30 +0000117
118StreamGenerator::~StreamGenerator() {
119 for (StreamMap::iterator it = streams_.begin(); it != streams_.end();
120 ++it) {
121 delete it->second;
122 }
123 streams_.clear();
124}
125
126// Add a new stream.
127void StreamGenerator::AddStream(RtpStream* stream) {
128 streams_[stream->ssrc()] = stream;
129}
130
131// Set the link capacity.
132void StreamGenerator::set_capacity_bps(int capacity_bps) {
133 ASSERT_GT(capacity_bps, 0);
134 capacity_ = capacity_bps;
135}
136
137// Divides |bitrate_bps| among all streams. The allocated bitrate per stream
solenberg@webrtc.orgb7716d82013-05-22 19:04:19 +0000138// is decided by the current allocation ratios.
139void StreamGenerator::SetBitrateBps(int bitrate_bps) {
stefan@webrtc.org686a4472012-11-07 18:35:30 +0000140 ASSERT_GE(streams_.size(), 0u);
solenberg@webrtc.orgb7716d82013-05-22 19:04:19 +0000141 int total_bitrate_before = 0;
142 for (StreamMap::iterator it = streams_.begin(); it != streams_.end(); ++it) {
stefan@webrtc.org686a4472012-11-07 18:35:30 +0000143 total_bitrate_before += it->second->bitrate_bps();
144 }
solenberg@webrtc.orgb7716d82013-05-22 19:04:19 +0000145 int64_t bitrate_before = 0;
stefan@webrtc.org686a4472012-11-07 18:35:30 +0000146 int total_bitrate_after = 0;
solenberg@webrtc.orgb7716d82013-05-22 19:04:19 +0000147 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);
stefan@webrtc.org686a4472012-11-07 18:35:30 +0000152 total_bitrate_after += it->second->bitrate_bps();
153 }
solenberg@webrtc.orgb7716d82013-05-22 19:04:19 +0000154 ASSERT_EQ(bitrate_before, total_bitrate_before);
155 EXPECT_EQ(total_bitrate_after, bitrate_bps);
stefan@webrtc.org686a4472012-11-07 18:35:30 +0000156}
157
158// Set the RTP timestamp offset for the stream identified by |ssrc|.
159void StreamGenerator::set_rtp_timestamp_offset(unsigned int ssrc,
160 uint32_t offset) {
161 streams_[ssrc]->set_rtp_timestamp_offset(offset);
162}
163
164// TODO(holmer): Break out the channel simulation part from this class to make
165// it possible to simulate different types of channels.
stefan@webrtc.org2a5dbce2013-02-01 14:33:42 +0000166int64_t StreamGenerator::GenerateFrame(RtpStream::PacketList* packets,
167 int64_t time_now_us) {
stefan@webrtc.org686a4472012-11-07 18:35:30 +0000168 assert(packets != NULL);
169 assert(packets->empty());
170 assert(capacity_ > 0);
171 StreamMap::iterator it = std::min_element(streams_.begin(), streams_.end(),
172 RtpStream::Compare);
stefan@webrtc.org2a5dbce2013-02-01 14:33:42 +0000173 (*it).second->GenerateFrame(time_now_us, packets);
174 int i = 0;
stefan@webrtc.org686a4472012-11-07 18:35:30 +0000175 for (RtpStream::PacketList::iterator packet_it = packets->begin();
176 packet_it != packets->end(); ++packet_it) {
stefan@webrtc.org2a5dbce2013-02-01 14:33:42 +0000177 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_;
183 ++i;
stefan@webrtc.org686a4472012-11-07 18:35:30 +0000184 }
185 it = std::min_element(streams_.begin(), streams_.end(), RtpStream::Compare);
186 return (*it).second->next_rtp_time();
187}
stefan@webrtc.org686a4472012-11-07 18:35:30 +0000188} // namespace testing
189
190RemoteBitrateEstimatorTest::RemoteBitrateEstimatorTest()
stefan@webrtc.org2a5dbce2013-02-01 14:33:42 +0000191 : clock_(0),
solenberg@webrtc.orgb7716d82013-05-22 19:04:19 +0000192 bitrate_observer_(new testing::TestBitrateObserver),
193 stream_generator_(new testing::StreamGenerator(
194 1e6, // Capacity.
195 clock_.TimeInMicroseconds())) {}
stefan@webrtc.org686a4472012-11-07 18:35:30 +0000196
pbos@webrtc.org988a5b32013-07-31 15:16:52 +0000197RemoteBitrateEstimatorTest::~RemoteBitrateEstimatorTest() {}
198
stefan@webrtc.org686a4472012-11-07 18:35:30 +0000199void RemoteBitrateEstimatorTest::AddDefaultStream() {
200 stream_generator_->AddStream(new testing::RtpStream(
201 30, // Frames per second.
202 3e5, // Bitrate.
203 1, // SSRC.
204 90000, // RTP frequency.
205 0xFFFFF000, // Timestamp offset.
206 0)); // RTCP receive time.
207}
208
solenberg@webrtc.orgb7716d82013-05-22 19:04:19 +0000209uint32_t RemoteBitrateEstimatorTest::AbsSendTime(int64_t t, int64_t denom) {
210 return (((t << 18) + (denom >> 1)) / denom) & 0x00fffffful;
211}
212
213uint32_t RemoteBitrateEstimatorTest::AddAbsSendTime(uint32_t t1, uint32_t t2) {
214 return (t1 + t2) & 0x00fffffful;
215}
216
pbos@webrtc.org98b20112013-05-07 12:36:21 +0000217const unsigned int RemoteBitrateEstimatorTest::kDefaultSsrc = 1;
218
solenberg@webrtc.orgb7716d82013-05-22 19:04:19 +0000219void 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) {
stefan@webrtc.orgd8ecee52013-06-04 12:15:40 +0000224 RTPHeader header;
solenberg@webrtc.orgb7716d82013-05-22 19:04:19 +0000225 memset(&header, 0, sizeof(header));
stefan@webrtc.orgd8ecee52013-06-04 12:15:40 +0000226 header.ssrc = ssrc;
227 header.timestamp = rtp_timestamp;
228 header.extension.absoluteSendTime = absolute_send_time;
solenberg@webrtc.orgb7716d82013-05-22 19:04:19 +0000229 bitrate_estimator_->IncomingPacket(arrival_time, payload_size, header);
230}
231
stefan@webrtc.org686a4472012-11-07 18:35:30 +0000232// Generates a frame of packets belonging to a stream at a given bitrate and
233// with a given ssrc. The stream is pushed through a very simple simulated
234// network, and is then given to the receive-side bandwidth estimator.
235// Returns true if an over-use was seen, false otherwise.
236// The StreamGenerator::updated() should be used to check for any changes in
237// target bitrate after the call to this function.
238bool RemoteBitrateEstimatorTest::GenerateAndProcessFrame(unsigned int ssrc,
239 unsigned int bitrate_bps) {
solenberg@webrtc.orgb7716d82013-05-22 19:04:19 +0000240 stream_generator_->SetBitrateBps(bitrate_bps);
stefan@webrtc.org686a4472012-11-07 18:35:30 +0000241 testing::RtpStream::PacketList packets;
stefan@webrtc.org2a5dbce2013-02-01 14:33:42 +0000242 int64_t next_time_us = stream_generator_->GenerateFrame(
243 &packets, clock_.TimeInMicroseconds());
stefan@webrtc.org686a4472012-11-07 18:35:30 +0000244 bool overuse = false;
245 while (!packets.empty()) {
246 testing::RtpStream::RtpPacket* packet = packets.front();
stefan@webrtc.org686a4472012-11-07 18:35:30 +0000247 bitrate_observer_->Reset();
solenberg@webrtc.orgb7716d82013-05-22 19:04:19 +0000248 IncomingPacket(packet->ssrc,
249 packet->size,
250 (packet->arrival_time + 500) / 1000,
251 packet->rtp_timestamp,
252 AbsSendTime(packet->send_time, 1000000));
stefan@webrtc.org686a4472012-11-07 18:35:30 +0000253 if (bitrate_observer_->updated()) {
254 // Verify that new estimates only are triggered by an overuse and a
255 // rate decrease.
256 overuse = true;
257 EXPECT_LE(bitrate_observer_->latest_bitrate(), bitrate_bps);
stefan@webrtc.org686a4472012-11-07 18:35:30 +0000258 }
stefan@webrtc.org2a5dbce2013-02-01 14:33:42 +0000259 clock_.AdvanceTimeMicroseconds(packet->arrival_time -
260 clock_.TimeInMicroseconds());
stefan@webrtc.org686a4472012-11-07 18:35:30 +0000261 delete packet;
262 packets.pop_front();
263 }
stefan@webrtc.org2a5dbce2013-02-01 14:33:42 +0000264 bitrate_estimator_->Process();
265 clock_.AdvanceTimeMicroseconds(next_time_us - clock_.TimeInMicroseconds());
stefan@webrtc.org686a4472012-11-07 18:35:30 +0000266 return overuse;
267}
268
stefan@webrtc.org2a5dbce2013-02-01 14:33:42 +0000269// Run the bandwidth estimator with a stream of |number_of_frames| frames, or
270// until it reaches |target_bitrate|.
stefan@webrtc.org686a4472012-11-07 18:35:30 +0000271// Can for instance be used to run the estimator for some time to get it
272// into a steady state.
273unsigned int RemoteBitrateEstimatorTest::SteadyStateRun(
274 unsigned int ssrc,
stefan@webrtc.org2a5dbce2013-02-01 14:33:42 +0000275 int max_number_of_frames,
stefan@webrtc.org686a4472012-11-07 18:35:30 +0000276 unsigned int start_bitrate,
277 unsigned int min_bitrate,
stefan@webrtc.org2a5dbce2013-02-01 14:33:42 +0000278 unsigned int max_bitrate,
279 unsigned int target_bitrate) {
stefan@webrtc.org686a4472012-11-07 18:35:30 +0000280 unsigned int bitrate_bps = start_bitrate;
281 bool bitrate_update_seen = false;
282 // Produce |number_of_frames| frames and give them to the estimator.
stefan@webrtc.org2a5dbce2013-02-01 14:33:42 +0000283 for (int i = 0; i < max_number_of_frames; ++i) {
stefan@webrtc.org686a4472012-11-07 18:35:30 +0000284 bool overuse = GenerateAndProcessFrame(ssrc, bitrate_bps);
285 if (overuse) {
286 EXPECT_LT(bitrate_observer_->latest_bitrate(), max_bitrate);
287 EXPECT_GT(bitrate_observer_->latest_bitrate(), min_bitrate);
288 bitrate_bps = bitrate_observer_->latest_bitrate();
289 bitrate_update_seen = true;
290 } else if (bitrate_observer_->updated()) {
291 bitrate_bps = bitrate_observer_->latest_bitrate();
292 bitrate_observer_->Reset();
293 }
stefan@webrtc.org2a5dbce2013-02-01 14:33:42 +0000294 if (bitrate_update_seen && bitrate_bps > target_bitrate) {
295 break;
296 }
stefan@webrtc.org686a4472012-11-07 18:35:30 +0000297 }
298 EXPECT_TRUE(bitrate_update_seen);
299 return bitrate_bps;
300}
solenberg@webrtc.orgb7716d82013-05-22 19:04:19 +0000301
302void RemoteBitrateEstimatorTest::InitialBehaviorTestHelper(
303 unsigned int expected_converge_bitrate) {
304 const int kFramerate = 50; // 50 fps to avoid rounding errors.
305 const int kFrameIntervalMs = 1000 / kFramerate;
306 const uint32_t kFrameIntervalAbsSendTime = AbsSendTime(1, kFramerate);
307 unsigned int bitrate_bps = 0;
308 uint32_t timestamp = 0;
309 uint32_t absolute_send_time = 0;
310 std::vector<unsigned int> ssrcs;
311 EXPECT_FALSE(bitrate_estimator_->LatestEstimate(&ssrcs, &bitrate_bps));
312 EXPECT_EQ(0u, ssrcs.size());
313 clock_.AdvanceTimeMilliseconds(1000);
314 bitrate_estimator_->Process();
315 EXPECT_FALSE(bitrate_estimator_->LatestEstimate(&ssrcs, &bitrate_bps));
316 EXPECT_FALSE(bitrate_observer_->updated());
317 bitrate_observer_->Reset();
318 clock_.AdvanceTimeMilliseconds(1000);
319 // Inserting a packet. Still no valid estimate. We need to wait 1 second.
320 IncomingPacket(kDefaultSsrc, kMtu, clock_.TimeInMilliseconds(), timestamp,
321 absolute_send_time);
322 bitrate_estimator_->Process();
323 EXPECT_FALSE(bitrate_estimator_->LatestEstimate(&ssrcs, &bitrate_bps));
324 EXPECT_EQ(0u, ssrcs.size());
325 EXPECT_FALSE(bitrate_observer_->updated());
326 bitrate_observer_->Reset();
327 // Inserting packets for one second to get a valid estimate.
328 for (int i = 0; i < kFramerate; ++i) {
329 IncomingPacket(kDefaultSsrc, kMtu, clock_.TimeInMilliseconds(), timestamp,
330 absolute_send_time);
331 clock_.AdvanceTimeMilliseconds(1000 / kFramerate);
332 timestamp += 90 * kFrameIntervalMs;
333 absolute_send_time = AddAbsSendTime(absolute_send_time,
334 kFrameIntervalAbsSendTime);
335 }
336 bitrate_estimator_->Process();
337 EXPECT_TRUE(bitrate_estimator_->LatestEstimate(&ssrcs, &bitrate_bps));
338 ASSERT_EQ(1u, ssrcs.size());
339 EXPECT_EQ(kDefaultSsrc, ssrcs.front());
340 EXPECT_EQ(expected_converge_bitrate, bitrate_bps);
341 EXPECT_TRUE(bitrate_observer_->updated());
342 bitrate_observer_->Reset();
343 EXPECT_EQ(bitrate_observer_->latest_bitrate(), bitrate_bps);
344}
345
346void RemoteBitrateEstimatorTest::RateIncreaseReorderingTestHelper() {
347 const int kFramerate = 50; // 50 fps to avoid rounding errors.
348 const int kFrameIntervalMs = 1000 / kFramerate;
349 const uint32_t kFrameIntervalAbsSendTime = AbsSendTime(1, kFramerate);
350 uint32_t timestamp = 0;
351 uint32_t absolute_send_time = 0;
352 IncomingPacket(kDefaultSsrc, 1000, clock_.TimeInMilliseconds(), timestamp,
353 absolute_send_time);
354 bitrate_estimator_->Process();
355 EXPECT_FALSE(bitrate_observer_->updated()); // No valid estimate.
356 // Inserting packets for one second to get a valid estimate.
357 for (int i = 0; i < kFramerate; ++i) {
358 IncomingPacket(kDefaultSsrc, kMtu, clock_.TimeInMilliseconds(), timestamp,
359 absolute_send_time);
360 clock_.AdvanceTimeMilliseconds(kFrameIntervalMs);
361 timestamp += 90 * kFrameIntervalMs;
362 absolute_send_time = AddAbsSendTime(absolute_send_time,
363 kFrameIntervalAbsSendTime);
364 }
365 bitrate_estimator_->Process();
366 EXPECT_TRUE(bitrate_observer_->updated());
367 EXPECT_EQ(498136u, bitrate_observer_->latest_bitrate());
368 for (int i = 0; i < 10; ++i) {
369 clock_.AdvanceTimeMilliseconds(2 * kFrameIntervalMs);
370 timestamp += 2 * 90 * kFrameIntervalMs;
371 absolute_send_time = AddAbsSendTime(absolute_send_time,
372 2 * kFrameIntervalAbsSendTime);
373 IncomingPacket(kDefaultSsrc, 1000, clock_.TimeInMilliseconds(), timestamp,
374 absolute_send_time);
375 IncomingPacket(kDefaultSsrc, 1000, clock_.TimeInMilliseconds(),
376 timestamp - 90 * kFrameIntervalMs,
377 AddAbsSendTime(absolute_send_time,
378 -int(kFrameIntervalAbsSendTime)));
379 }
380 bitrate_estimator_->Process();
381 EXPECT_TRUE(bitrate_observer_->updated());
382 EXPECT_EQ(498136u, bitrate_observer_->latest_bitrate());
383}
384
385// Make sure we initially increase the bitrate as expected.
386void RemoteBitrateEstimatorTest::RateIncreaseRtpTimestampsTestHelper() {
387 // This threshold corresponds approximately to increasing linearly with
388 // bitrate(i) = 1.04 * bitrate(i-1) + 1000
389 // until bitrate(i) > 500000, with bitrate(1) ~= 30000.
390 const int kExpectedIterations = 1621;
391 unsigned int bitrate_bps = 30000;
392 int iterations = 0;
393 AddDefaultStream();
394 // Feed the estimator with a stream of packets and verify that it reaches
395 // 500 kbps at the expected time.
396 while (bitrate_bps < 5e5) {
397 bool overuse = GenerateAndProcessFrame(kDefaultSsrc, bitrate_bps);
398 if (overuse) {
399 EXPECT_GT(bitrate_observer_->latest_bitrate(), bitrate_bps);
400 bitrate_bps = bitrate_observer_->latest_bitrate();
401 bitrate_observer_->Reset();
402 } else if (bitrate_observer_->updated()) {
403 bitrate_bps = bitrate_observer_->latest_bitrate();
404 bitrate_observer_->Reset();
405 }
406 ++iterations;
407 ASSERT_LE(iterations, kExpectedIterations);
408 }
409 ASSERT_EQ(kExpectedIterations, iterations);
410}
411
412void RemoteBitrateEstimatorTest::CapacityDropTestHelper(
413 int number_of_streams,
414 bool wrap_time_stamp,
415 unsigned int expected_converge_bitrate,
416 unsigned int expected_bitrate_drop_delta) {
417 const int kFramerate = 30;
418 const int kStartBitrate = 900e3;
419 const int kMinExpectedBitrate = 800e3;
420 const int kMaxExpectedBitrate = 1100e3;
421 const unsigned int kInitialCapacityBps = 1000e3;
422 const unsigned int kReducedCapacityBps = 500e3;
423
424 int steady_state_time = 0;
425 int expected_overuse_start_time = 0;
426 if (number_of_streams <= 1) {
427 steady_state_time = 10;
428 expected_overuse_start_time = 10000;
429 AddDefaultStream();
430 } else {
431 steady_state_time = 8 * number_of_streams;
432 expected_overuse_start_time = 8000;
433 int bitrate_sum = 0;
434 int kBitrateDenom = number_of_streams * (number_of_streams - 1);
435 for (int i = 0; i < number_of_streams; i++) {
436 // First stream gets half available bitrate, while the rest share the
437 // remaining half i.e.: 1/2 = Sum[n/(N*(N-1))] for n=1..N-1 (rounded up)
438 int bitrate = kStartBitrate / 2;
439 if (i > 0) {
440 bitrate = (kStartBitrate * i + kBitrateDenom / 2) / kBitrateDenom;
441 }
442 stream_generator_->AddStream(new testing::RtpStream(
443 kFramerate, // Frames per second.
444 bitrate, // Bitrate.
445 kDefaultSsrc + i, // SSRC.
446 90000, // RTP frequency.
447 0xFFFFF000 ^ (~0 << (32 - i)), // Timestamp offset.
448 0)); // RTCP receive time.
449 bitrate_sum += bitrate;
450 }
451 ASSERT_EQ(bitrate_sum, kStartBitrate);
452 }
453 if (wrap_time_stamp) {
454 stream_generator_->set_rtp_timestamp_offset(kDefaultSsrc,
455 std::numeric_limits<uint32_t>::max() - steady_state_time * 90000);
456 }
457
458 // Run in steady state to make the estimator converge.
459 stream_generator_->set_capacity_bps(kInitialCapacityBps);
460 unsigned int bitrate_bps = SteadyStateRun(kDefaultSsrc,
461 steady_state_time * kFramerate,
462 kStartBitrate,
463 kMinExpectedBitrate,
464 kMaxExpectedBitrate,
465 kInitialCapacityBps);
466 EXPECT_EQ(expected_converge_bitrate, bitrate_bps);
467 bitrate_observer_->Reset();
468
469 // Reduce the capacity and verify the decrease time.
470 stream_generator_->set_capacity_bps(kReducedCapacityBps);
471 int64_t overuse_start_time = clock_.TimeInMilliseconds();
472 EXPECT_EQ(expected_overuse_start_time, overuse_start_time);
473 int64_t bitrate_drop_time = -1;
474 for (int i = 0; i < 100 * number_of_streams; ++i) {
475 GenerateAndProcessFrame(kDefaultSsrc, bitrate_bps);
476 // Check for either increase or decrease.
477 if (bitrate_observer_->updated()) {
478 if (bitrate_drop_time == -1 &&
479 bitrate_observer_->latest_bitrate() <= kReducedCapacityBps) {
480 bitrate_drop_time = clock_.TimeInMilliseconds();
481 }
482 bitrate_bps = bitrate_observer_->latest_bitrate();
483 bitrate_observer_->Reset();
484 }
485 }
486
487 EXPECT_EQ(expected_bitrate_drop_delta,
488 bitrate_drop_time - overuse_start_time);
489}
stefan@webrtc.org686a4472012-11-07 18:35:30 +0000490} // namespace webrtc