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