| 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 "media/cast/congestion_control/congestion_control.h" | 5 #include "media/cast/congestion_control/congestion_control.h" |
| 6 | 6 |
| 7 #include "base/logging.h" | 7 #include "base/logging.h" |
| 8 #include "media/cast/cast_config.h" | 8 #include "media/cast/cast_config.h" |
| 9 #include "media/cast/cast_defines.h" | 9 #include "media/cast/cast_defines.h" |
| 10 | 10 |
| (...skipping 19 matching lines...) Expand all Loading... |
| 30 max_bitrate_configured_(max_bitrate_configured), | 30 max_bitrate_configured_(max_bitrate_configured), |
| 31 min_bitrate_configured_(min_bitrate_configured), | 31 min_bitrate_configured_(min_bitrate_configured), |
| 32 bitrate_(start_bitrate) { | 32 bitrate_(start_bitrate) { |
| 33 DCHECK_GT(congestion_control_back_off, 0.0f) << "Invalid config"; | 33 DCHECK_GT(congestion_control_back_off, 0.0f) << "Invalid config"; |
| 34 DCHECK_LT(congestion_control_back_off, 1.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"; | 35 DCHECK_GE(max_bitrate_configured, min_bitrate_configured) << "Invalid config"; |
| 36 DCHECK_GE(max_bitrate_configured, start_bitrate) << "Invalid config"; | 36 DCHECK_GE(max_bitrate_configured, start_bitrate) << "Invalid config"; |
| 37 DCHECK_GE(start_bitrate, min_bitrate_configured) << "Invalid config"; | 37 DCHECK_GE(start_bitrate, min_bitrate_configured) << "Invalid config"; |
| 38 } | 38 } |
| 39 | 39 |
| 40 CongestionControl::~CongestionControl() { | 40 CongestionControl::~CongestionControl() {} |
| 41 } | |
| 42 | 41 |
| 43 bool CongestionControl::OnAck(base::TimeDelta rtt, uint32* new_bitrate) { | 42 bool CongestionControl::OnAck(base::TimeDelta rtt, uint32* new_bitrate) { |
| 44 base::TimeTicks now = clock_->NowTicks(); | 43 base::TimeTicks now = clock_->NowTicks(); |
| 45 | 44 |
| 46 // First feedback? | 45 // First feedback? |
| 47 if (time_last_increase_.is_null()) { | 46 if (time_last_increase_.is_null()) { |
| 48 time_last_increase_ = now; | 47 time_last_increase_ = now; |
| 49 time_last_decrease_ = now; | 48 time_last_decrease_ = now; |
| 50 return false; | 49 return false; |
| 51 } | 50 } |
| 52 // Are we at the max bitrate? | 51 // Are we at the max bitrate? |
| 53 if (max_bitrate_configured_ == bitrate_) return false; | 52 if (max_bitrate_configured_ == bitrate_) |
| 53 return false; |
| 54 | 54 |
| 55 // Make sure RTT is never less than 1 ms. | 55 // Make sure RTT is never less than 1 ms. |
| 56 rtt = std::max(rtt, base::TimeDelta::FromMilliseconds(1)); | 56 rtt = std::max(rtt, base::TimeDelta::FromMilliseconds(1)); |
| 57 | 57 |
| 58 base::TimeDelta elapsed_time = std::min(now - time_last_increase_, | 58 base::TimeDelta elapsed_time = |
| 59 base::TimeDelta::FromMilliseconds(kMaxElapsedTimeMs)); | 59 std::min(now - time_last_increase_, |
| 60 base::TimeDelta change_interval = std::max(rtt, | 60 base::TimeDelta::FromMilliseconds(kMaxElapsedTimeMs)); |
| 61 base::TimeDelta change_interval = std::max( |
| 62 rtt, |
| 61 base::TimeDelta::FromMilliseconds(kCongestionControlMinChangeIntervalMs)); | 63 base::TimeDelta::FromMilliseconds(kCongestionControlMinChangeIntervalMs)); |
| 62 change_interval = std::min(change_interval, | 64 change_interval = std::min( |
| 65 change_interval, |
| 63 base::TimeDelta::FromMilliseconds(kCongestionControlMaxChangeIntervalMs)); | 66 base::TimeDelta::FromMilliseconds(kCongestionControlMaxChangeIntervalMs)); |
| 64 | 67 |
| 65 // Have enough time have passed? | 68 // Have enough time have passed? |
| 66 if (elapsed_time < change_interval) return false; | 69 if (elapsed_time < change_interval) |
| 70 return false; |
| 67 | 71 |
| 68 time_last_increase_ = now; | 72 time_last_increase_ = now; |
| 69 | 73 |
| 70 // One packet per RTT multiplied by the elapsed time fraction. | 74 // One packet per RTT multiplied by the elapsed time fraction. |
| 71 // 1500 * 8 * (1000 / rtt_ms) * (elapsed_time_ms / 1000) => | 75 // 1500 * 8 * (1000 / rtt_ms) * (elapsed_time_ms / 1000) => |
| 72 // 1500 * 8 * elapsed_time_ms / rtt_ms. | 76 // 1500 * 8 * elapsed_time_ms / rtt_ms. |
| 73 uint32 bitrate_increase = (1500 * 8 * elapsed_time.InMilliseconds()) / | 77 uint32 bitrate_increase = |
| 74 rtt.InMilliseconds(); | 78 (1500 * 8 * elapsed_time.InMilliseconds()) / rtt.InMilliseconds(); |
| 75 uint32 max_bitrate_increase = | 79 uint32 max_bitrate_increase = |
| 76 kCongestionControlMaxBitrateIncreasePerMillisecond * | 80 kCongestionControlMaxBitrateIncreasePerMillisecond * |
| 77 elapsed_time.InMilliseconds(); | 81 elapsed_time.InMilliseconds(); |
| 78 bitrate_increase = std::min(max_bitrate_increase, bitrate_increase); | 82 bitrate_increase = std::min(max_bitrate_increase, bitrate_increase); |
| 79 *new_bitrate = std::min(bitrate_increase + bitrate_, max_bitrate_configured_); | 83 *new_bitrate = std::min(bitrate_increase + bitrate_, max_bitrate_configured_); |
| 80 bitrate_ = *new_bitrate; | 84 bitrate_ = *new_bitrate; |
| 81 return true; | 85 return true; |
| 82 } | 86 } |
| 83 | 87 |
| 84 bool CongestionControl::OnNack(base::TimeDelta rtt, uint32* new_bitrate) { | 88 bool CongestionControl::OnNack(base::TimeDelta rtt, uint32* new_bitrate) { |
| 85 base::TimeTicks now = clock_->NowTicks(); | 89 base::TimeTicks now = clock_->NowTicks(); |
| 86 | 90 |
| 87 // First feedback? | 91 // First feedback? |
| 88 if (time_last_decrease_.is_null()) { | 92 if (time_last_decrease_.is_null()) { |
| 89 time_last_increase_ = now; | 93 time_last_increase_ = now; |
| 90 time_last_decrease_ = now; | 94 time_last_decrease_ = now; |
| 91 return false; | 95 return false; |
| 92 } | 96 } |
| 93 base::TimeDelta elapsed_time = std::min(now - time_last_decrease_, | 97 base::TimeDelta elapsed_time = |
| 94 base::TimeDelta::FromMilliseconds(kMaxElapsedTimeMs)); | 98 std::min(now - time_last_decrease_, |
| 95 base::TimeDelta change_interval = std::max(rtt, | 99 base::TimeDelta::FromMilliseconds(kMaxElapsedTimeMs)); |
| 100 base::TimeDelta change_interval = std::max( |
| 101 rtt, |
| 96 base::TimeDelta::FromMilliseconds(kCongestionControlMinChangeIntervalMs)); | 102 base::TimeDelta::FromMilliseconds(kCongestionControlMinChangeIntervalMs)); |
| 97 change_interval = std::min(change_interval, | 103 change_interval = std::min( |
| 104 change_interval, |
| 98 base::TimeDelta::FromMilliseconds(kCongestionControlMaxChangeIntervalMs)); | 105 base::TimeDelta::FromMilliseconds(kCongestionControlMaxChangeIntervalMs)); |
| 99 | 106 |
| 100 // Have enough time have passed? | 107 // Have enough time have passed? |
| 101 if (elapsed_time < change_interval) return false; | 108 if (elapsed_time < change_interval) |
| 109 return false; |
| 102 | 110 |
| 103 time_last_decrease_ = now; | 111 time_last_decrease_ = now; |
| 104 time_last_increase_ = now; | 112 time_last_increase_ = now; |
| 105 | 113 |
| 106 *new_bitrate = std::max( | 114 *new_bitrate = |
| 107 static_cast<uint32>(bitrate_ * congestion_control_back_off_), | 115 std::max(static_cast<uint32>(bitrate_ * congestion_control_back_off_), |
| 108 min_bitrate_configured_); | 116 min_bitrate_configured_); |
| 109 | 117 |
| 110 bitrate_ = *new_bitrate; | 118 bitrate_ = *new_bitrate; |
| 111 return true; | 119 return true; |
| 112 } | 120 } |
| 113 | 121 |
| 114 } // namespace cast | 122 } // namespace cast |
| 115 } // namespace media | 123 } // namespace media |
| OLD | NEW |