Cast: Stop logging kVideoFrameSentToEncoder and rename a couple events.
[chromium-blink-merge.git] / media / cast / congestion_control / congestion_control.cc
blob39d68b39f01e23b5b590b9a3cf8fa89333ae9c06
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.
5 #include "media/cast/congestion_control/congestion_control.h"
7 #include "base/logging.h"
8 #include "media/cast/cast_config.h"
9 #include "media/cast/cast_defines.h"
11 namespace media {
12 namespace cast {
14 static const int64 kCongestionControlMinChangeIntervalMs = 10;
15 static const int64 kCongestionControlMaxChangeIntervalMs = 100;
17 // At 10 ms RTT TCP Reno would ramp 1500 * 8 * 100 = 1200 Kbit/s.
18 // NACK is sent after a maximum of 10 ms.
19 static const int kCongestionControlMaxBitrateIncreasePerMillisecond = 1200;
21 static const int64 kMaxElapsedTimeMs = kCongestionControlMaxChangeIntervalMs;
23 CongestionControl::CongestionControl(base::TickClock* clock,
24 float congestion_control_back_off,
25 uint32 max_bitrate_configured,
26 uint32 min_bitrate_configured,
27 uint32 start_bitrate)
28 : clock_(clock),
29 congestion_control_back_off_(congestion_control_back_off),
30 max_bitrate_configured_(max_bitrate_configured),
31 min_bitrate_configured_(min_bitrate_configured),
32 bitrate_(start_bitrate) {
33 DCHECK_GT(congestion_control_back_off, 0.0f) << "Invalid config";
34 DCHECK_LT(congestion_control_back_off, 1.0f) << "Invalid config";
35 DCHECK_GE(max_bitrate_configured, min_bitrate_configured) << "Invalid config";
36 DCHECK_GE(max_bitrate_configured, start_bitrate) << "Invalid config";
37 DCHECK_GE(start_bitrate, min_bitrate_configured) << "Invalid config";
40 CongestionControl::~CongestionControl() {}
42 bool CongestionControl::OnAck(base::TimeDelta rtt, uint32* new_bitrate) {
43 base::TimeTicks now = clock_->NowTicks();
45 // First feedback?
46 if (time_last_increase_.is_null()) {
47 time_last_increase_ = now;
48 time_last_decrease_ = now;
49 return false;
51 // Are we at the max bitrate?
52 if (max_bitrate_configured_ == bitrate_)
53 return false;
55 // Make sure RTT is never less than 1 ms.
56 rtt = std::max(rtt, base::TimeDelta::FromMilliseconds(1));
58 base::TimeDelta elapsed_time =
59 std::min(now - time_last_increase_,
60 base::TimeDelta::FromMilliseconds(kMaxElapsedTimeMs));
61 base::TimeDelta change_interval = std::max(
62 rtt,
63 base::TimeDelta::FromMilliseconds(kCongestionControlMinChangeIntervalMs));
64 change_interval = std::min(
65 change_interval,
66 base::TimeDelta::FromMilliseconds(kCongestionControlMaxChangeIntervalMs));
68 // Have enough time have passed?
69 if (elapsed_time < change_interval)
70 return false;
72 time_last_increase_ = now;
74 // One packet per RTT multiplied by the elapsed time fraction.
75 // 1500 * 8 * (1000 / rtt_ms) * (elapsed_time_ms / 1000) =>
76 // 1500 * 8 * elapsed_time_ms / rtt_ms.
77 uint32 bitrate_increase =
78 (1500 * 8 * elapsed_time.InMilliseconds()) / rtt.InMilliseconds();
79 uint32 max_bitrate_increase =
80 kCongestionControlMaxBitrateIncreasePerMillisecond *
81 elapsed_time.InMilliseconds();
82 bitrate_increase = std::min(max_bitrate_increase, bitrate_increase);
83 *new_bitrate = std::min(bitrate_increase + bitrate_, max_bitrate_configured_);
84 bitrate_ = *new_bitrate;
85 return true;
88 bool CongestionControl::OnNack(base::TimeDelta rtt, uint32* new_bitrate) {
89 base::TimeTicks now = clock_->NowTicks();
91 // First feedback?
92 if (time_last_decrease_.is_null()) {
93 time_last_increase_ = now;
94 time_last_decrease_ = now;
95 return false;
97 base::TimeDelta elapsed_time =
98 std::min(now - time_last_decrease_,
99 base::TimeDelta::FromMilliseconds(kMaxElapsedTimeMs));
100 base::TimeDelta change_interval = std::max(
101 rtt,
102 base::TimeDelta::FromMilliseconds(kCongestionControlMinChangeIntervalMs));
103 change_interval = std::min(
104 change_interval,
105 base::TimeDelta::FromMilliseconds(kCongestionControlMaxChangeIntervalMs));
107 // Have enough time have passed?
108 if (elapsed_time < change_interval)
109 return false;
111 time_last_decrease_ = now;
112 time_last_increase_ = now;
114 *new_bitrate =
115 std::max(static_cast<uint32>(bitrate_ * congestion_control_back_off_),
116 min_bitrate_configured_);
118 bitrate_ = *new_bitrate;
119 return true;
122 } // namespace cast
123 } // namespace media