Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(307)

Side by Side Diff: webrtc/modules/congestion_controller/delay_based_bwe_unittest_helper.cc

Issue 2126793002: Reset InterArrival if arrival time clock makes a jump. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Fix a few test issues. Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 /*
2 * Copyright (c) 2016 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/congestion_controller/delay_based_bwe_unittest_helper.h "
11
12 #include <algorithm>
13 #include <limits>
14 #include <utility>
15
16 #include "webrtc/base/checks.h"
17 #include "webrtc/modules/congestion_controller/delay_based_bwe.h"
18
19 namespace webrtc {
20
21 const size_t kMtu = 1200;
22 const uint32_t kAcceptedBitrateErrorBps = 50000;
23
24 // Number of packets needed before we have a valid estimate.
25 const int kNumInitialPackets = 2;
26
27 namespace test {
28
29 void TestBitrateObserver::OnReceiveBitrateChanged(
30 const std::vector<uint32_t>& ssrcs,
31 uint32_t bitrate) {
32 latest_bitrate_ = bitrate;
33 updated_ = true;
34 }
35
36 RtpStream::RtpStream(int fps, int bitrate_bps)
37 : fps_(fps),
38 bitrate_bps_(bitrate_bps),
39 next_rtp_time_(0),
40 sequence_number_(0) {
41 RTC_CHECK_GT(fps_, 0);
42 }
43
44 // Generates a new frame for this stream. If called too soon after the
45 // previous frame, no frame will be generated. The frame is split into
46 // packets.
47 int64_t RtpStream::GenerateFrame(int64_t time_now_us,
48 std::vector<PacketInfo>* packets) {
49 if (time_now_us < next_rtp_time_) {
50 return next_rtp_time_;
51 }
52 RTC_CHECK(packets != NULL);
53 size_t bits_per_frame = (bitrate_bps_ + fps_ / 2) / fps_;
54 size_t n_packets =
55 std::max<size_t>((bits_per_frame + 4 * kMtu) / (8 * kMtu), 1u);
56 size_t payload_size = (bits_per_frame + 4 * n_packets) / (8 * n_packets);
57 for (size_t i = 0; i < n_packets; ++i) {
58 PacketInfo packet(-1, sequence_number_++);
59 packet.send_time_ms = (time_now_us + kSendSideOffsetUs) / 1000;
60 packet.payload_size = payload_size;
61 packet.probe_cluster_id = PacketInfo::kNotAProbe;
62 packets->push_back(packet);
63 }
64 next_rtp_time_ = time_now_us + (1000000 + fps_ / 2) / fps_;
65 return next_rtp_time_;
66 }
67
68 // The send-side time when the next frame can be generated.
69 int64_t RtpStream::next_rtp_time() const {
70 return next_rtp_time_;
71 }
72
73 void RtpStream::set_bitrate_bps(int bitrate_bps) {
74 ASSERT_GE(bitrate_bps, 0);
75 bitrate_bps_ = bitrate_bps;
76 }
77
78 int RtpStream::bitrate_bps() const {
79 return bitrate_bps_;
80 }
81
82 bool RtpStream::Compare(const std::unique_ptr<RtpStream>& lhs,
83 const std::unique_ptr<RtpStream>& rhs) {
84 return lhs->next_rtp_time_ < rhs->next_rtp_time_;
85 }
86
87 StreamGenerator::StreamGenerator(int capacity, int64_t time_now)
88 : capacity_(capacity), prev_arrival_time_us_(time_now) {}
89
90 // Add a new stream.
91 void StreamGenerator::AddStream(RtpStream* stream) {
92 streams_.push_back(std::unique_ptr<RtpStream>(stream));
93 }
94
95 // Set the link capacity.
96 void StreamGenerator::set_capacity_bps(int capacity_bps) {
97 ASSERT_GT(capacity_bps, 0);
98 capacity_ = capacity_bps;
99 }
100
101 // Divides |bitrate_bps| among all streams. The allocated bitrate per stream
102 // is decided by the current allocation ratios.
103 void StreamGenerator::SetBitrateBps(int bitrate_bps) {
104 ASSERT_GE(streams_.size(), 0u);
105 int total_bitrate_before = 0;
106 for (const auto& stream : streams_) {
107 total_bitrate_before += stream->bitrate_bps();
108 }
109 int64_t bitrate_before = 0;
110 int total_bitrate_after = 0;
111 for (const auto& stream : streams_) {
112 bitrate_before += stream->bitrate_bps();
113 int64_t bitrate_after =
114 (bitrate_before * bitrate_bps + total_bitrate_before / 2) /
115 total_bitrate_before;
116 stream->set_bitrate_bps(bitrate_after - total_bitrate_after);
117 total_bitrate_after += stream->bitrate_bps();
118 }
119 ASSERT_EQ(bitrate_before, total_bitrate_before);
120 EXPECT_EQ(total_bitrate_after, bitrate_bps);
121 }
122
123 // TODO(holmer): Break out the channel simulation part from this class to make
124 // it possible to simulate different types of channels.
125 int64_t StreamGenerator::GenerateFrame(std::vector<PacketInfo>* packets,
126 int64_t time_now_us) {
127 RTC_CHECK(packets != NULL);
128 RTC_CHECK(packets->empty());
129 RTC_CHECK_GT(capacity_, 0);
130 auto it =
131 std::min_element(streams_.begin(), streams_.end(), RtpStream::Compare);
132 (*it)->GenerateFrame(time_now_us, packets);
133 int i = 0;
134 for (PacketInfo& packet : *packets) {
135 int capacity_bpus = capacity_ / 1000;
136 int64_t required_network_time_us =
137 (8 * 1000 * packet.payload_size + capacity_bpus / 2) / capacity_bpus;
138 prev_arrival_time_us_ =
139 std::max(time_now_us + required_network_time_us,
140 prev_arrival_time_us_ + required_network_time_us);
141 packet.arrival_time_ms = prev_arrival_time_us_ / 1000;
142 ++i;
143 }
144 it = std::min_element(streams_.begin(), streams_.end(), RtpStream::Compare);
145 return std::max((*it)->next_rtp_time(), time_now_us);
146 }
147 } // namespace test
148
149 DelayBasedBweTest::DelayBasedBweTest()
150 : clock_(100000000),
151 bitrate_observer_(new test::TestBitrateObserver),
152 bitrate_estimator_(new DelayBasedBwe(bitrate_observer_.get(), &clock_)),
153 stream_generator_(
154 new test::StreamGenerator(1e6, // Capacity.
155 clock_.TimeInMicroseconds())),
156 arrival_time_offset_ms_(0) {}
157
158 DelayBasedBweTest::~DelayBasedBweTest() {}
159
160 void DelayBasedBweTest::AddDefaultStream() {
161 stream_generator_->AddStream(new test::RtpStream(30, 3e5));
162 }
163
164 const uint32_t DelayBasedBweTest::kDefaultSsrc = 0;
165
166 void DelayBasedBweTest::IncomingFeedback(int64_t arrival_time_ms,
167 int64_t send_time_ms,
168 uint16_t sequence_number,
169 size_t payload_size) {
170 IncomingFeedback(arrival_time_ms, send_time_ms, sequence_number, payload_size,
171 0);
172 }
173
174 void DelayBasedBweTest::IncomingFeedback(int64_t arrival_time_ms,
175 int64_t send_time_ms,
176 uint16_t sequence_number,
177 size_t payload_size,
178 int probe_cluster_id) {
179 RTC_CHECK_GE(arrival_time_ms + arrival_time_offset_ms_, 0);
180 PacketInfo packet(arrival_time_ms + arrival_time_offset_ms_, send_time_ms,
181 sequence_number, payload_size, probe_cluster_id);
182 std::vector<PacketInfo> packets;
183 packets.push_back(packet);
184 bitrate_estimator_->IncomingPacketFeedbackVector(packets);
185 }
186
187 // Generates a frame of packets belonging to a stream at a given bitrate and
188 // with a given ssrc. The stream is pushed through a very simple simulated
189 // network, and is then given to the receive-side bandwidth estimator.
190 // Returns true if an over-use was seen, false otherwise.
191 // The StreamGenerator::updated() should be used to check for any changes in
192 // target bitrate after the call to this function.
193 bool DelayBasedBweTest::GenerateAndProcessFrame(uint32_t ssrc,
194 uint32_t bitrate_bps) {
195 stream_generator_->SetBitrateBps(bitrate_bps);
196 std::vector<PacketInfo> packets;
197 int64_t next_time_us =
198 stream_generator_->GenerateFrame(&packets, clock_.TimeInMicroseconds());
199 if (packets.empty())
200 return false;
201
202 bool overuse = false;
203 bitrate_observer_->Reset();
204 clock_.AdvanceTimeMicroseconds(1000 * packets.back().arrival_time_ms -
205 clock_.TimeInMicroseconds());
206 for (auto& packet : packets) {
207 RTC_CHECK_GE(packet.arrival_time_ms + arrival_time_offset_ms_, 0);
208 packet.arrival_time_ms += arrival_time_offset_ms_;
209 }
210 bitrate_estimator_->IncomingPacketFeedbackVector(packets);
211
212 if (bitrate_observer_->updated()) {
213 if (bitrate_observer_->latest_bitrate() < bitrate_bps)
214 overuse = true;
215 }
216
217 clock_.AdvanceTimeMicroseconds(next_time_us - clock_.TimeInMicroseconds());
218 return overuse;
219 }
220
221 // Run the bandwidth estimator with a stream of |number_of_frames| frames, or
222 // until it reaches |target_bitrate|.
223 // Can for instance be used to run the estimator for some time to get it
224 // into a steady state.
225 uint32_t DelayBasedBweTest::SteadyStateRun(uint32_t ssrc,
226 int max_number_of_frames,
227 uint32_t start_bitrate,
228 uint32_t min_bitrate,
229 uint32_t max_bitrate,
230 uint32_t target_bitrate) {
231 uint32_t bitrate_bps = start_bitrate;
232 bool bitrate_update_seen = false;
233 // Produce |number_of_frames| frames and give them to the estimator.
234 for (int i = 0; i < max_number_of_frames; ++i) {
235 bool overuse = GenerateAndProcessFrame(ssrc, bitrate_bps);
236 if (overuse) {
237 EXPECT_LT(bitrate_observer_->latest_bitrate(), max_bitrate);
238 EXPECT_GT(bitrate_observer_->latest_bitrate(), min_bitrate);
239 bitrate_bps = bitrate_observer_->latest_bitrate();
240 bitrate_update_seen = true;
241 } else if (bitrate_observer_->updated()) {
242 bitrate_bps = bitrate_observer_->latest_bitrate();
243 bitrate_observer_->Reset();
244 }
245 if (bitrate_update_seen && bitrate_bps > target_bitrate) {
246 break;
247 }
248 }
249 EXPECT_TRUE(bitrate_update_seen);
250 return bitrate_bps;
251 }
252
253 void DelayBasedBweTest::InitialBehaviorTestHelper(
254 uint32_t expected_converge_bitrate) {
255 const int kFramerate = 50; // 50 fps to avoid rounding errors.
256 const int kFrameIntervalMs = 1000 / kFramerate;
257 uint32_t bitrate_bps = 0;
258 int64_t send_time_ms = 0;
259 uint16_t sequence_number = 0;
260 std::vector<uint32_t> ssrcs;
261 EXPECT_FALSE(bitrate_estimator_->LatestEstimate(&ssrcs, &bitrate_bps));
262 EXPECT_EQ(0u, ssrcs.size());
263 clock_.AdvanceTimeMilliseconds(1000);
264 bitrate_estimator_->Process();
265 EXPECT_FALSE(bitrate_estimator_->LatestEstimate(&ssrcs, &bitrate_bps));
266 EXPECT_FALSE(bitrate_observer_->updated());
267 bitrate_observer_->Reset();
268 clock_.AdvanceTimeMilliseconds(1000);
269 // Inserting packets for 5 seconds to get a valid estimate.
270 for (int i = 0; i < 5 * kFramerate + 1 + kNumInitialPackets; ++i) {
271 if (i == kNumInitialPackets) {
272 bitrate_estimator_->Process();
273 EXPECT_FALSE(bitrate_estimator_->LatestEstimate(&ssrcs, &bitrate_bps));
274 EXPECT_EQ(0u, ssrcs.size());
275 EXPECT_FALSE(bitrate_observer_->updated());
276 bitrate_observer_->Reset();
277 }
278
279 IncomingFeedback(clock_.TimeInMilliseconds(), send_time_ms,
280 sequence_number++, kMtu);
281 clock_.AdvanceTimeMilliseconds(1000 / kFramerate);
282 send_time_ms += kFrameIntervalMs;
283 }
284 bitrate_estimator_->Process();
285 EXPECT_TRUE(bitrate_estimator_->LatestEstimate(&ssrcs, &bitrate_bps));
286 ASSERT_EQ(1u, ssrcs.size());
287 EXPECT_EQ(kDefaultSsrc, ssrcs.front());
288 EXPECT_NEAR(expected_converge_bitrate, bitrate_bps, kAcceptedBitrateErrorBps);
289 EXPECT_TRUE(bitrate_observer_->updated());
290 bitrate_observer_->Reset();
291 EXPECT_EQ(bitrate_observer_->latest_bitrate(), bitrate_bps);
292 bitrate_estimator_->RemoveStream(kDefaultSsrc);
293 EXPECT_TRUE(bitrate_estimator_->LatestEstimate(&ssrcs, &bitrate_bps));
294 ASSERT_EQ(0u, ssrcs.size());
295 EXPECT_EQ(0u, bitrate_bps);
296 }
297
298 void DelayBasedBweTest::RateIncreaseReorderingTestHelper(
299 uint32_t expected_bitrate_bps) {
300 const int kFramerate = 50; // 50 fps to avoid rounding errors.
301 const int kFrameIntervalMs = 1000 / kFramerate;
302 int64_t send_time_ms = 0;
303 uint16_t sequence_number = 0;
304 // Inserting packets for five seconds to get a valid estimate.
305 for (int i = 0; i < 5 * kFramerate + 1 + kNumInitialPackets; ++i) {
306 // TODO(sprang): Remove this hack once the single stream estimator is gone,
307 // as it doesn't do anything in Process().
308 if (i == kNumInitialPackets) {
309 // Process after we have enough frames to get a valid input rate estimate.
310 bitrate_estimator_->Process();
311 EXPECT_FALSE(bitrate_observer_->updated()); // No valid estimate.
312 }
313
314 IncomingFeedback(clock_.TimeInMilliseconds(), send_time_ms,
315 sequence_number++, kMtu);
316 clock_.AdvanceTimeMilliseconds(kFrameIntervalMs);
317 send_time_ms += kFrameIntervalMs;
318 }
319 bitrate_estimator_->Process();
320 EXPECT_TRUE(bitrate_observer_->updated());
321 EXPECT_NEAR(expected_bitrate_bps, bitrate_observer_->latest_bitrate(),
322 kAcceptedBitrateErrorBps);
323 for (int i = 0; i < 10; ++i) {
324 clock_.AdvanceTimeMilliseconds(2 * kFrameIntervalMs);
325 send_time_ms += 2 * kFrameIntervalMs;
326 IncomingFeedback(clock_.TimeInMilliseconds(), send_time_ms,
327 sequence_number + 2, 1000);
328 IncomingFeedback(clock_.TimeInMilliseconds(),
329 send_time_ms - kFrameIntervalMs, sequence_number + 1,
330 1000);
331 sequence_number += 2;
332 }
333 bitrate_estimator_->Process();
334 EXPECT_TRUE(bitrate_observer_->updated());
335 EXPECT_NEAR(expected_bitrate_bps, bitrate_observer_->latest_bitrate(),
336 kAcceptedBitrateErrorBps);
337 }
338
339 // Make sure we initially increase the bitrate as expected.
340 void DelayBasedBweTest::RateIncreaseRtpTimestampsTestHelper(
341 int expected_iterations) {
342 // This threshold corresponds approximately to increasing linearly with
343 // bitrate(i) = 1.04 * bitrate(i-1) + 1000
344 // until bitrate(i) > 500000, with bitrate(1) ~= 30000.
345 uint32_t bitrate_bps = 30000;
346 int iterations = 0;
347 AddDefaultStream();
348 // Feed the estimator with a stream of packets and verify that it reaches
349 // 500 kbps at the expected time.
350 while (bitrate_bps < 5e5) {
351 bool overuse = GenerateAndProcessFrame(kDefaultSsrc, bitrate_bps);
352 if (overuse) {
353 EXPECT_GT(bitrate_observer_->latest_bitrate(), bitrate_bps);
354 bitrate_bps = bitrate_observer_->latest_bitrate();
355 bitrate_observer_->Reset();
356 } else if (bitrate_observer_->updated()) {
357 bitrate_bps = bitrate_observer_->latest_bitrate();
358 bitrate_observer_->Reset();
359 }
360 ++iterations;
361 ASSERT_LE(iterations, expected_iterations);
362 }
363 ASSERT_EQ(expected_iterations, iterations);
364 }
365
366 void DelayBasedBweTest::CapacityDropTestHelper(
367 int number_of_streams,
368 bool wrap_time_stamp,
369 uint32_t expected_bitrate_drop_delta,
370 int64_t receiver_clock_offset_change_ms) {
371 const int kFramerate = 30;
372 const int kStartBitrate = 900e3;
373 const int kMinExpectedBitrate = 800e3;
374 const int kMaxExpectedBitrate = 1100e3;
375 const uint32_t kInitialCapacityBps = 1000e3;
376 const uint32_t kReducedCapacityBps = 500e3;
377
378 int steady_state_time = 0;
379 if (number_of_streams <= 1) {
380 steady_state_time = 10;
381 AddDefaultStream();
382 } else {
383 steady_state_time = 10 * number_of_streams;
384 int bitrate_sum = 0;
385 int kBitrateDenom = number_of_streams * (number_of_streams - 1);
386 for (int i = 0; i < number_of_streams; i++) {
387 // First stream gets half available bitrate, while the rest share the
388 // remaining half i.e.: 1/2 = Sum[n/(N*(N-1))] for n=1..N-1 (rounded up)
389 int bitrate = kStartBitrate / 2;
390 if (i > 0) {
391 bitrate = (kStartBitrate * i + kBitrateDenom / 2) / kBitrateDenom;
392 }
393 stream_generator_->AddStream(new test::RtpStream(kFramerate, bitrate));
394 bitrate_sum += bitrate;
395 }
396 ASSERT_EQ(bitrate_sum, kStartBitrate);
397 }
398
399 // Run in steady state to make the estimator converge.
400 stream_generator_->set_capacity_bps(kInitialCapacityBps);
401 uint32_t bitrate_bps = SteadyStateRun(
402 kDefaultSsrc, steady_state_time * kFramerate, kStartBitrate,
403 kMinExpectedBitrate, kMaxExpectedBitrate, kInitialCapacityBps);
404 EXPECT_NEAR(kInitialCapacityBps, bitrate_bps, 130000u);
405 bitrate_observer_->Reset();
406
407 // Add an offset to make sure the BWE can handle it.
408 arrival_time_offset_ms_ += receiver_clock_offset_change_ms;
409
410 // Reduce the capacity and verify the decrease time.
411 stream_generator_->set_capacity_bps(kReducedCapacityBps);
412 int64_t overuse_start_time = clock_.TimeInMilliseconds();
413 int64_t bitrate_drop_time = -1;
414 for (int i = 0; i < 100 * number_of_streams; ++i) {
415 GenerateAndProcessFrame(kDefaultSsrc, bitrate_bps);
416 if (bitrate_drop_time == -1 &&
417 bitrate_observer_->latest_bitrate() <= kReducedCapacityBps) {
418 bitrate_drop_time = clock_.TimeInMilliseconds();
419 }
420 if (bitrate_observer_->updated())
421 bitrate_bps = bitrate_observer_->latest_bitrate();
422 }
423
424 EXPECT_NEAR(expected_bitrate_drop_delta,
425 bitrate_drop_time - overuse_start_time, 33);
426 }
427
428 void DelayBasedBweTest::TestTimestampGroupingTestHelper() {
429 const int kFramerate = 50; // 50 fps to avoid rounding errors.
430 const int kFrameIntervalMs = 1000 / kFramerate;
431 int64_t send_time_ms = 0;
432 uint16_t sequence_number = 0;
433 // Initial set of frames to increase the bitrate. 6 seconds to have enough
434 // time for the first estimate to be generated and for Process() to be called.
435 for (int i = 0; i <= 6 * kFramerate; ++i) {
436 IncomingFeedback(clock_.TimeInMilliseconds(), send_time_ms,
437 sequence_number++, 1000);
438
439 bitrate_estimator_->Process();
440 clock_.AdvanceTimeMilliseconds(kFrameIntervalMs);
441 send_time_ms += kFrameIntervalMs;
442 }
443 EXPECT_TRUE(bitrate_observer_->updated());
444 EXPECT_GE(bitrate_observer_->latest_bitrate(), 400000u);
445
446 // Insert batches of frames which were sent very close in time. Also simulate
447 // capacity over-use to see that we back off correctly.
448 const int kTimestampGroupLength = 15;
449 for (int i = 0; i < 100; ++i) {
450 for (int j = 0; j < kTimestampGroupLength; ++j) {
451 // Insert |kTimestampGroupLength| frames with just 1 timestamp ticks in
452 // between. Should be treated as part of the same group by the estimator.
453 IncomingFeedback(clock_.TimeInMilliseconds(), send_time_ms,
454 sequence_number++, 100);
455 clock_.AdvanceTimeMilliseconds(kFrameIntervalMs / kTimestampGroupLength);
456 send_time_ms += 1;
457 }
458 // Increase time until next batch to simulate over-use.
459 clock_.AdvanceTimeMilliseconds(10);
460 send_time_ms += kFrameIntervalMs - kTimestampGroupLength;
461 bitrate_estimator_->Process();
462 }
463 EXPECT_TRUE(bitrate_observer_->updated());
464 // Should have reduced the estimate.
465 EXPECT_LT(bitrate_observer_->latest_bitrate(), 400000u);
466 }
467
468 void DelayBasedBweTest::TestWrappingHelper(int silence_time_s) {
469 const int kFramerate = 100;
470 const int kFrameIntervalMs = 1000 / kFramerate;
471 int64_t send_time_ms = 0;
472 uint16_t sequence_number = 0;
473
474 for (size_t i = 0; i < 3000; ++i) {
475 IncomingFeedback(clock_.TimeInMilliseconds(), send_time_ms,
476 sequence_number++, 1000);
477 clock_.AdvanceTimeMilliseconds(kFrameIntervalMs);
478 send_time_ms += kFrameIntervalMs;
479 bitrate_estimator_->Process();
480 }
481 uint32_t bitrate_before = 0;
482 std::vector<uint32_t> ssrcs;
483 bitrate_estimator_->LatestEstimate(&ssrcs, &bitrate_before);
484
485 clock_.AdvanceTimeMilliseconds(silence_time_s * 1000);
486 send_time_ms += silence_time_s * 1000;
487 bitrate_estimator_->Process();
488
489 for (size_t i = 0; i < 21; ++i) {
490 IncomingFeedback(clock_.TimeInMilliseconds(), send_time_ms,
491 sequence_number++, 1000);
492 clock_.AdvanceTimeMilliseconds(2 * kFrameIntervalMs);
493 send_time_ms += kFrameIntervalMs;
494 bitrate_estimator_->Process();
495 }
496 uint32_t bitrate_after = 0;
497 bitrate_estimator_->LatestEstimate(&ssrcs, &bitrate_after);
498 EXPECT_LT(bitrate_after, bitrate_before);
499 }
500 } // namespace webrtc
OLDNEW
« no previous file with comments | « webrtc/modules/congestion_controller/delay_based_bwe_unittest_helper.h ('k') | webrtc/modules/modules.gyp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698