Home | History | Annotate | Download | only in congestion_control
      1 // Copyright 2013 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include <stdint.h>
      6 
      7 #include "base/test/simple_test_tick_clock.h"
      8 #include "media/cast/cast_defines.h"
      9 #include "media/cast/congestion_control/congestion_control.h"
     10 #include "media/cast/test/fake_single_thread_task_runner.h"
     11 #include "testing/gtest/include/gtest/gtest.h"
     12 
     13 namespace media {
     14 namespace cast {
     15 
     16 static const uint32 kMaxBitrateConfigured = 5000000;
     17 static const uint32 kMinBitrateConfigured = 500000;
     18 static const int64 kStartMillisecond = INT64_C(12345678900000);
     19 static const double kTargetEmptyBufferFraction = 0.9;
     20 
     21 class CongestionControlTest : public ::testing::Test {
     22  protected:
     23   CongestionControlTest()
     24       : task_runner_(new test::FakeSingleThreadTaskRunner(&testing_clock_)) {
     25     testing_clock_.Advance(
     26         base::TimeDelta::FromMilliseconds(kStartMillisecond));
     27     congestion_control_.reset(new CongestionControl(
     28         &testing_clock_, kMaxBitrateConfigured, kMinBitrateConfigured, 10));
     29   }
     30 
     31   void AckFrame(uint32 frame_id) {
     32     congestion_control_->AckFrame(frame_id, testing_clock_.NowTicks());
     33   }
     34 
     35   void Run(uint32 frames,
     36            size_t frame_size,
     37            base::TimeDelta rtt,
     38            base::TimeDelta frame_delay,
     39            base::TimeDelta ack_time) {
     40     for (frame_id_ = 0; frame_id_ < frames; frame_id_++) {
     41       congestion_control_->UpdateRtt(rtt);
     42       congestion_control_->SendFrameToTransport(
     43           frame_id_, frame_size, testing_clock_.NowTicks());
     44       task_runner_->PostDelayedTask(FROM_HERE,
     45                                     base::Bind(&CongestionControlTest::AckFrame,
     46                                                base::Unretained(this),
     47                                                frame_id_),
     48                                     ack_time);
     49       task_runner_->Sleep(frame_delay);
     50     }
     51   }
     52 
     53   base::SimpleTestTickClock testing_clock_;
     54   scoped_ptr<CongestionControl> congestion_control_;
     55   scoped_refptr<test::FakeSingleThreadTaskRunner> task_runner_;
     56   uint32 frame_id_;
     57 
     58   DISALLOW_COPY_AND_ASSIGN(CongestionControlTest);
     59 };
     60 
     61 TEST_F(CongestionControlTest, SimpleRun) {
     62   uint32 frame_delay = 33;
     63   uint32 frame_size = 10000 * 8;
     64   Run(500,
     65       frame_size,
     66       base::TimeDelta::FromMilliseconds(10),
     67       base::TimeDelta::FromMilliseconds(frame_delay),
     68       base::TimeDelta::FromMilliseconds(45));
     69   // Empty the buffer.
     70   task_runner_->Sleep(base::TimeDelta::FromMilliseconds(100));
     71 
     72   uint32 safe_bitrate = frame_size * 1000 / frame_delay;
     73   uint32 bitrate = congestion_control_->GetBitrate(
     74       testing_clock_.NowTicks() + base::TimeDelta::FromMilliseconds(300),
     75       base::TimeDelta::FromMilliseconds(300));
     76   EXPECT_NEAR(
     77       safe_bitrate / kTargetEmptyBufferFraction, bitrate, safe_bitrate * 0.05);
     78 
     79   bitrate = congestion_control_->GetBitrate(
     80       testing_clock_.NowTicks() + base::TimeDelta::FromMilliseconds(200),
     81       base::TimeDelta::FromMilliseconds(300));
     82   EXPECT_NEAR(safe_bitrate / kTargetEmptyBufferFraction * 2 / 3,
     83               bitrate,
     84               safe_bitrate * 0.05);
     85 
     86   bitrate = congestion_control_->GetBitrate(
     87       testing_clock_.NowTicks() + base::TimeDelta::FromMilliseconds(100),
     88       base::TimeDelta::FromMilliseconds(300));
     89   EXPECT_NEAR(safe_bitrate / kTargetEmptyBufferFraction * 1 / 3,
     90               bitrate,
     91               safe_bitrate * 0.05);
     92 
     93   // Add a large (100ms) frame.
     94   congestion_control_->SendFrameToTransport(
     95       frame_id_++, safe_bitrate * 100 / 1000, testing_clock_.NowTicks());
     96 
     97   // Results should show that we have ~200ms to send
     98   bitrate = congestion_control_->GetBitrate(
     99       testing_clock_.NowTicks() + base::TimeDelta::FromMilliseconds(300),
    100       base::TimeDelta::FromMilliseconds(300));
    101   EXPECT_NEAR(safe_bitrate / kTargetEmptyBufferFraction * 2 / 3,
    102               bitrate,
    103               safe_bitrate * 0.05);
    104 
    105   // Add another large (100ms) frame.
    106   congestion_control_->SendFrameToTransport(
    107       frame_id_++, safe_bitrate * 100 / 1000, testing_clock_.NowTicks());
    108 
    109   // Resulst should show that we have ~100ms to send
    110   bitrate = congestion_control_->GetBitrate(
    111       testing_clock_.NowTicks() + base::TimeDelta::FromMilliseconds(300),
    112       base::TimeDelta::FromMilliseconds(300));
    113   EXPECT_NEAR(safe_bitrate / kTargetEmptyBufferFraction * 1 / 3,
    114               bitrate,
    115               safe_bitrate * 0.05);
    116 }
    117 
    118 
    119 }  // namespace cast
    120 }  // namespace media
    121