| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include <stdint.h> | 5 #include <stdint.h> |
| 6 | 6 |
| 7 #include "base/test/simple_test_tick_clock.h" | 7 #include "base/test/simple_test_tick_clock.h" |
| 8 #include "media/cast/cast_defines.h" | 8 #include "media/cast/cast_defines.h" |
| 9 #include "media/cast/congestion_control/congestion_control.h" | 9 #include "media/cast/congestion_control/congestion_control.h" |
| 10 #include "media/cast/test/fake_single_thread_task_runner.h" |
| 10 #include "testing/gtest/include/gtest/gtest.h" | 11 #include "testing/gtest/include/gtest/gtest.h" |
| 11 | 12 |
| 12 namespace media { | 13 namespace media { |
| 13 namespace cast { | 14 namespace cast { |
| 14 | 15 |
| 15 static const uint32 kMaxBitrateConfigured = 5000000; | 16 static const uint32 kMaxBitrateConfigured = 5000000; |
| 16 static const uint32 kMinBitrateConfigured = 500000; | 17 static const uint32 kMinBitrateConfigured = 500000; |
| 17 static const uint32 kStartBitrate = 2000000; | |
| 18 static const int64 kStartMillisecond = INT64_C(12345678900000); | 18 static const int64 kStartMillisecond = INT64_C(12345678900000); |
| 19 static const int64 kRttMs = 20; | 19 static const double kTargetEmptyBufferFraction = 0.9; |
| 20 static const int64 kAckRateMs = 33; | |
| 21 | 20 |
| 22 class CongestionControlTest : public ::testing::Test { | 21 class CongestionControlTest : public ::testing::Test { |
| 23 protected: | 22 protected: |
| 24 CongestionControlTest() | 23 CongestionControlTest() |
| 25 : congestion_control_(&testing_clock_, | 24 : task_runner_(new test::FakeSingleThreadTaskRunner(&testing_clock_)) { |
| 26 kDefaultCongestionControlBackOff, | |
| 27 kMaxBitrateConfigured, | |
| 28 kMinBitrateConfigured, | |
| 29 kStartBitrate) { | |
| 30 testing_clock_.Advance( | 25 testing_clock_.Advance( |
| 31 base::TimeDelta::FromMilliseconds(kStartMillisecond)); | 26 base::TimeDelta::FromMilliseconds(kStartMillisecond)); |
| 27 congestion_control_.reset(new CongestionControl( |
| 28 &testing_clock_, kMaxBitrateConfigured, kMinBitrateConfigured, 10)); |
| 32 } | 29 } |
| 33 | 30 |
| 34 // Returns the last bitrate of the run. | 31 void AckFrame(uint32 frame_id) { |
| 35 uint32 RunWithOneLossEventPerSecond(int fps, | 32 congestion_control_->AckFrame(frame_id, testing_clock_.NowTicks()); |
| 36 int rtt_ms, | 33 } |
| 37 int runtime_in_seconds) { | |
| 38 const base::TimeDelta rtt = base::TimeDelta::FromMilliseconds(rtt_ms); | |
| 39 const base::TimeDelta ack_rate = | |
| 40 base::TimeDelta::FromMilliseconds(INT64_C(1000) / fps); | |
| 41 uint32 new_bitrate = 0; | |
| 42 EXPECT_FALSE(congestion_control_.OnAck(rtt, &new_bitrate)); | |
| 43 | 34 |
| 44 for (int seconds = 0; seconds < runtime_in_seconds; ++seconds) { | 35 void Run(uint32 frames, |
| 45 for (int i = 1; i < fps; ++i) { | 36 size_t frame_size, |
| 46 testing_clock_.Advance(ack_rate); | 37 base::TimeDelta rtt, |
| 47 congestion_control_.OnAck(rtt, &new_bitrate); | 38 base::TimeDelta frame_delay, |
| 48 } | 39 base::TimeDelta ack_time) { |
| 49 EXPECT_TRUE(congestion_control_.OnNack(rtt, &new_bitrate)); | 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 } | 50 } |
| 51 return new_bitrate; | |
| 52 } | 51 } |
| 53 | 52 |
| 54 base::SimpleTestTickClock testing_clock_; | 53 base::SimpleTestTickClock testing_clock_; |
| 55 CongestionControl congestion_control_; | 54 scoped_ptr<CongestionControl> congestion_control_; |
| 55 scoped_refptr<test::FakeSingleThreadTaskRunner> task_runner_; |
| 56 uint32 frame_id_; |
| 56 | 57 |
| 57 DISALLOW_COPY_AND_ASSIGN(CongestionControlTest); | 58 DISALLOW_COPY_AND_ASSIGN(CongestionControlTest); |
| 58 }; | 59 }; |
| 59 | 60 |
| 60 TEST_F(CongestionControlTest, Max) { | 61 TEST_F(CongestionControlTest, SimpleRun) { |
| 61 uint32 new_bitrate = 0; | 62 uint32 frame_delay = 33; |
| 62 const base::TimeDelta rtt = base::TimeDelta::FromMilliseconds(kRttMs); | 63 uint32 frame_size = 10000 * 8; |
| 63 const base::TimeDelta ack_rate = | 64 Run(500, |
| 64 base::TimeDelta::FromMilliseconds(kAckRateMs); | 65 frame_size, |
| 65 EXPECT_FALSE(congestion_control_.OnAck(rtt, &new_bitrate)); | 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)); |
| 66 | 71 |
| 67 uint32 expected_increase_bitrate = 0; | 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); |
| 68 | 78 |
| 69 // Expected time is 5 seconds. 500000 - 2000000 = 5 * 1500 * 8 * (1000 / 20). | 79 bitrate = congestion_control_->GetBitrate( |
| 70 for (int i = 0; i < 151; ++i) { | 80 testing_clock_.NowTicks() + base::TimeDelta::FromMilliseconds(200), |
| 71 testing_clock_.Advance(ack_rate); | 81 base::TimeDelta::FromMilliseconds(300)); |
| 72 EXPECT_TRUE(congestion_control_.OnAck(rtt, &new_bitrate)); | 82 EXPECT_NEAR(safe_bitrate / kTargetEmptyBufferFraction * 2 / 3, |
| 73 expected_increase_bitrate += 1500 * 8 * kAckRateMs / kRttMs; | 83 bitrate, |
| 74 EXPECT_EQ(kStartBitrate + expected_increase_bitrate, new_bitrate); | 84 safe_bitrate * 0.05); |
| 75 } | 85 |
| 76 testing_clock_.Advance(ack_rate); | 86 bitrate = congestion_control_->GetBitrate( |
| 77 EXPECT_TRUE(congestion_control_.OnAck(rtt, &new_bitrate)); | 87 testing_clock_.NowTicks() + base::TimeDelta::FromMilliseconds(100), |
| 78 EXPECT_EQ(kMaxBitrateConfigured, new_bitrate); | 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); |
| 79 } | 116 } |
| 80 | 117 |
| 81 TEST_F(CongestionControlTest, Min) { | |
| 82 uint32 new_bitrate = 0; | |
| 83 const base::TimeDelta rtt = base::TimeDelta::FromMilliseconds(kRttMs); | |
| 84 const base::TimeDelta ack_rate = | |
| 85 base::TimeDelta::FromMilliseconds(kAckRateMs); | |
| 86 EXPECT_FALSE(congestion_control_.OnNack(rtt, &new_bitrate)); | |
| 87 | |
| 88 uint32 expected_decrease_bitrate = kStartBitrate; | |
| 89 | |
| 90 // Expected number is 10. 2000 * 0.875^10 <= 500. | |
| 91 for (int i = 0; i < 10; ++i) { | |
| 92 testing_clock_.Advance(ack_rate); | |
| 93 EXPECT_TRUE(congestion_control_.OnNack(rtt, &new_bitrate)); | |
| 94 expected_decrease_bitrate = static_cast<uint32>( | |
| 95 expected_decrease_bitrate * kDefaultCongestionControlBackOff); | |
| 96 EXPECT_EQ(expected_decrease_bitrate, new_bitrate); | |
| 97 } | |
| 98 testing_clock_.Advance(ack_rate); | |
| 99 EXPECT_TRUE(congestion_control_.OnNack(rtt, &new_bitrate)); | |
| 100 EXPECT_EQ(kMinBitrateConfigured, new_bitrate); | |
| 101 } | |
| 102 | |
| 103 TEST_F(CongestionControlTest, Timing) { | |
| 104 const base::TimeDelta rtt = base::TimeDelta::FromMilliseconds(kRttMs); | |
| 105 const base::TimeDelta ack_rate = | |
| 106 base::TimeDelta::FromMilliseconds(kAckRateMs); | |
| 107 uint32 new_bitrate = 0; | |
| 108 uint32 expected_bitrate = kStartBitrate; | |
| 109 | |
| 110 EXPECT_FALSE(congestion_control_.OnAck(rtt, &new_bitrate)); | |
| 111 | |
| 112 testing_clock_.Advance(ack_rate); | |
| 113 EXPECT_TRUE(congestion_control_.OnAck(rtt, &new_bitrate)); | |
| 114 expected_bitrate += 1500 * 8 * kAckRateMs / kRttMs; | |
| 115 EXPECT_EQ(expected_bitrate, new_bitrate); | |
| 116 | |
| 117 // We should back immediately. | |
| 118 EXPECT_TRUE(congestion_control_.OnNack(rtt, &new_bitrate)); | |
| 119 expected_bitrate = | |
| 120 static_cast<uint32>(expected_bitrate * kDefaultCongestionControlBackOff); | |
| 121 EXPECT_EQ(expected_bitrate, new_bitrate); | |
| 122 | |
| 123 // Less than one RTT have passed don't back again. | |
| 124 testing_clock_.Advance(base::TimeDelta::FromMilliseconds(10)); | |
| 125 EXPECT_FALSE(congestion_control_.OnNack(rtt, &new_bitrate)); | |
| 126 | |
| 127 testing_clock_.Advance(base::TimeDelta::FromMilliseconds(10)); | |
| 128 EXPECT_TRUE(congestion_control_.OnNack(rtt, &new_bitrate)); | |
| 129 expected_bitrate = | |
| 130 static_cast<uint32>(expected_bitrate * kDefaultCongestionControlBackOff); | |
| 131 EXPECT_EQ(expected_bitrate, new_bitrate); | |
| 132 | |
| 133 testing_clock_.Advance(base::TimeDelta::FromMilliseconds(10)); | |
| 134 EXPECT_FALSE(congestion_control_.OnAck(rtt, &new_bitrate)); | |
| 135 testing_clock_.Advance(base::TimeDelta::FromMilliseconds(10)); | |
| 136 EXPECT_TRUE(congestion_control_.OnAck(rtt, &new_bitrate)); | |
| 137 expected_bitrate += 1500 * 8 * 20 / kRttMs; | |
| 138 EXPECT_EQ(expected_bitrate, new_bitrate); | |
| 139 | |
| 140 testing_clock_.Advance(base::TimeDelta::FromMilliseconds(10)); | |
| 141 EXPECT_FALSE(congestion_control_.OnAck(rtt, &new_bitrate)); | |
| 142 testing_clock_.Advance(base::TimeDelta::FromMilliseconds(10)); | |
| 143 EXPECT_TRUE(congestion_control_.OnAck(rtt, &new_bitrate)); | |
| 144 expected_bitrate += 1500 * 8 * 20 / kRttMs; | |
| 145 EXPECT_EQ(expected_bitrate, new_bitrate); | |
| 146 | |
| 147 // Test long elapsed time (300 ms). | |
| 148 testing_clock_.Advance(base::TimeDelta::FromMilliseconds(300)); | |
| 149 EXPECT_TRUE(congestion_control_.OnAck(rtt, &new_bitrate)); | |
| 150 expected_bitrate += 1500 * 8 * 100 / kRttMs; | |
| 151 EXPECT_EQ(expected_bitrate, new_bitrate); | |
| 152 | |
| 153 // Test many short elapsed time (1 ms). | |
| 154 for (int i = 0; i < 19; ++i) { | |
| 155 testing_clock_.Advance(base::TimeDelta::FromMilliseconds(1)); | |
| 156 EXPECT_FALSE(congestion_control_.OnAck(rtt, &new_bitrate)); | |
| 157 } | |
| 158 testing_clock_.Advance(base::TimeDelta::FromMilliseconds(1)); | |
| 159 EXPECT_TRUE(congestion_control_.OnAck(rtt, &new_bitrate)); | |
| 160 expected_bitrate += 1500 * 8 * 20 / kRttMs; | |
| 161 EXPECT_EQ(expected_bitrate, new_bitrate); | |
| 162 } | |
| 163 | |
| 164 TEST_F(CongestionControlTest, Convergence24fps) { | |
| 165 EXPECT_GE(RunWithOneLossEventPerSecond(24, kRttMs, 100), UINT32_C(3000000)); | |
| 166 } | |
| 167 | |
| 168 TEST_F(CongestionControlTest, Convergence24fpsLongRtt) { | |
| 169 EXPECT_GE(RunWithOneLossEventPerSecond(24, 100, 100), UINT32_C(500000)); | |
| 170 } | |
| 171 | |
| 172 TEST_F(CongestionControlTest, Convergence60fps) { | |
| 173 EXPECT_GE(RunWithOneLossEventPerSecond(60, kRttMs, 100), UINT32_C(3500000)); | |
| 174 } | |
| 175 | |
| 176 TEST_F(CongestionControlTest, Convergence60fpsLongRtt) { | |
| 177 EXPECT_GE(RunWithOneLossEventPerSecond(60, 100, 100), UINT32_C(500000)); | |
| 178 } | |
| 179 | 118 |
| 180 } // namespace cast | 119 } // namespace cast |
| 181 } // namespace media | 120 } // namespace media |
| OLD | NEW |