OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 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 // The purpose of this file is determine what bitrate to use for mirroring. | 5 // The purpose of this file is determine what bitrate to use for mirroring. |
6 // Ideally this should be as much as possible, without causing any frames to | 6 // Ideally this should be as much as possible, without causing any frames to |
7 // arrive late. | 7 // arrive late. |
8 | 8 |
9 // The current algorithm is to measure how much bandwidth we've been using | 9 // The current algorithm is to measure how much bandwidth we've been using |
10 // recently. We also keep track of how much data has been queued up for sending | 10 // recently. We also keep track of how much data has been queued up for sending |
(...skipping 20 matching lines...) Expand all Loading... |
31 AdaptiveCongestionControl(base::TickClock* clock, | 31 AdaptiveCongestionControl(base::TickClock* clock, |
32 int max_bitrate_configured, | 32 int max_bitrate_configured, |
33 int min_bitrate_configured, | 33 int min_bitrate_configured, |
34 double max_frame_rate); | 34 double max_frame_rate); |
35 | 35 |
36 ~AdaptiveCongestionControl() final; | 36 ~AdaptiveCongestionControl() final; |
37 | 37 |
38 // CongestionControl implementation. | 38 // CongestionControl implementation. |
39 void UpdateRtt(base::TimeDelta rtt) final; | 39 void UpdateRtt(base::TimeDelta rtt) final; |
40 void UpdateTargetPlayoutDelay(base::TimeDelta delay) final; | 40 void UpdateTargetPlayoutDelay(base::TimeDelta delay) final; |
41 void SendFrameToTransport(uint32 frame_id, | 41 void SendFrameToTransport(uint32_t frame_id, |
42 size_t frame_size_in_bits, | 42 size_t frame_size_in_bits, |
43 base::TimeTicks when) final; | 43 base::TimeTicks when) final; |
44 void AckFrame(uint32 frame_id, base::TimeTicks when) final; | 44 void AckFrame(uint32_t frame_id, base::TimeTicks when) final; |
45 int GetBitrate(base::TimeTicks playout_time, | 45 int GetBitrate(base::TimeTicks playout_time, |
46 base::TimeDelta playout_delay, | 46 base::TimeDelta playout_delay, |
47 int soft_max_bitrate) final; | 47 int soft_max_bitrate) final; |
48 | 48 |
49 private: | 49 private: |
50 struct FrameStats { | 50 struct FrameStats { |
51 FrameStats(); | 51 FrameStats(); |
52 // Time this frame was first enqueued for transport. | 52 // Time this frame was first enqueued for transport. |
53 base::TimeTicks enqueue_time; | 53 base::TimeTicks enqueue_time; |
54 // Time this frame was acked. | 54 // Time this frame was acked. |
55 base::TimeTicks ack_time; | 55 base::TimeTicks ack_time; |
56 // Size of encoded frame in bits. | 56 // Size of encoded frame in bits. |
57 size_t frame_size_in_bits; | 57 size_t frame_size_in_bits; |
58 }; | 58 }; |
59 | 59 |
60 // Calculate how much "dead air" (idle time) there is between two frames. | 60 // Calculate how much "dead air" (idle time) there is between two frames. |
61 static base::TimeDelta DeadTime(const FrameStats& a, const FrameStats& b); | 61 static base::TimeDelta DeadTime(const FrameStats& a, const FrameStats& b); |
62 // Get the FrameStats for a given |frame_id|. Never returns nullptr. | 62 // Get the FrameStats for a given |frame_id|. Never returns nullptr. |
63 // Note: Older FrameStats will be removed automatically. | 63 // Note: Older FrameStats will be removed automatically. |
64 FrameStats* GetFrameStats(uint32 frame_id); | 64 FrameStats* GetFrameStats(uint32_t frame_id); |
65 // Discard old FrameStats. | 65 // Discard old FrameStats. |
66 void PruneFrameStats(); | 66 void PruneFrameStats(); |
67 // Calculate a safe bitrate. This is based on how much we've been | 67 // Calculate a safe bitrate. This is based on how much we've been |
68 // sending in the past. | 68 // sending in the past. |
69 double CalculateSafeBitrate(); | 69 double CalculateSafeBitrate(); |
70 | 70 |
71 // Estimate when the transport will start sending the data for a given frame. | 71 // Estimate when the transport will start sending the data for a given frame. |
72 // |estimated_bitrate| is the current estimated transmit bitrate in bits per | 72 // |estimated_bitrate| is the current estimated transmit bitrate in bits per |
73 // second. | 73 // second. |
74 base::TimeTicks EstimatedSendingTime(uint32 frame_id, | 74 base::TimeTicks EstimatedSendingTime(uint32_t frame_id, |
75 double estimated_bitrate); | 75 double estimated_bitrate); |
76 | 76 |
77 base::TickClock* const clock_; // Not owned by this class. | 77 base::TickClock* const clock_; // Not owned by this class. |
78 const int max_bitrate_configured_; | 78 const int max_bitrate_configured_; |
79 const int min_bitrate_configured_; | 79 const int min_bitrate_configured_; |
80 const double max_frame_rate_; | 80 const double max_frame_rate_; |
81 std::deque<FrameStats> frame_stats_; | 81 std::deque<FrameStats> frame_stats_; |
82 uint32 last_frame_stats_; | 82 uint32_t last_frame_stats_; |
83 uint32 last_acked_frame_; | 83 uint32_t last_acked_frame_; |
84 uint32 last_enqueued_frame_; | 84 uint32_t last_enqueued_frame_; |
85 base::TimeDelta rtt_; | 85 base::TimeDelta rtt_; |
86 size_t history_size_; | 86 size_t history_size_; |
87 size_t acked_bits_in_history_; | 87 size_t acked_bits_in_history_; |
88 base::TimeDelta dead_time_in_history_; | 88 base::TimeDelta dead_time_in_history_; |
89 | 89 |
90 DISALLOW_COPY_AND_ASSIGN(AdaptiveCongestionControl); | 90 DISALLOW_COPY_AND_ASSIGN(AdaptiveCongestionControl); |
91 }; | 91 }; |
92 | 92 |
93 class FixedCongestionControl : public CongestionControl { | 93 class FixedCongestionControl : public CongestionControl { |
94 public: | 94 public: |
95 explicit FixedCongestionControl(int bitrate) : bitrate_(bitrate) {} | 95 explicit FixedCongestionControl(int bitrate) : bitrate_(bitrate) {} |
96 ~FixedCongestionControl() final {} | 96 ~FixedCongestionControl() final {} |
97 | 97 |
98 // CongestionControl implementation. | 98 // CongestionControl implementation. |
99 void UpdateRtt(base::TimeDelta rtt) final {} | 99 void UpdateRtt(base::TimeDelta rtt) final {} |
100 void UpdateTargetPlayoutDelay(base::TimeDelta delay) final {} | 100 void UpdateTargetPlayoutDelay(base::TimeDelta delay) final {} |
101 void SendFrameToTransport(uint32 frame_id, | 101 void SendFrameToTransport(uint32_t frame_id, |
102 size_t frame_size_in_bits, | 102 size_t frame_size_in_bits, |
103 base::TimeTicks when) final {} | 103 base::TimeTicks when) final {} |
104 void AckFrame(uint32 frame_id, base::TimeTicks when) final {} | 104 void AckFrame(uint32_t frame_id, base::TimeTicks when) final {} |
105 int GetBitrate(base::TimeTicks playout_time, | 105 int GetBitrate(base::TimeTicks playout_time, |
106 base::TimeDelta playout_delay, | 106 base::TimeDelta playout_delay, |
107 int soft_max_bitrate) final { | 107 int soft_max_bitrate) final { |
108 return bitrate_; | 108 return bitrate_; |
109 } | 109 } |
110 | 110 |
111 private: | 111 private: |
112 const int bitrate_; | 112 const int bitrate_; |
113 | 113 |
114 DISALLOW_COPY_AND_ASSIGN(FixedCongestionControl); | 114 DISALLOW_COPY_AND_ASSIGN(FixedCongestionControl); |
(...skipping 21 matching lines...) Expand all Loading... |
136 // congestion control more aggressive. | 136 // congestion control more aggressive. |
137 static const double kTargetEmptyBufferFraction = 0.9; | 137 static const double kTargetEmptyBufferFraction = 0.9; |
138 | 138 |
139 // This is the size of our history in frames. Larger values makes the | 139 // This is the size of our history in frames. Larger values makes the |
140 // congestion control adapt slower. | 140 // congestion control adapt slower. |
141 static const size_t kHistorySize = 100; | 141 static const size_t kHistorySize = 100; |
142 | 142 |
143 AdaptiveCongestionControl::FrameStats::FrameStats() : frame_size_in_bits(0) { | 143 AdaptiveCongestionControl::FrameStats::FrameStats() : frame_size_in_bits(0) { |
144 } | 144 } |
145 | 145 |
146 AdaptiveCongestionControl::AdaptiveCongestionControl( | 146 AdaptiveCongestionControl::AdaptiveCongestionControl(base::TickClock* clock, |
147 base::TickClock* clock, | 147 int max_bitrate_configured, |
148 int max_bitrate_configured, | 148 int min_bitrate_configured, |
149 int min_bitrate_configured, | 149 double max_frame_rate) |
150 double max_frame_rate) | |
151 : clock_(clock), | 150 : clock_(clock), |
152 max_bitrate_configured_(max_bitrate_configured), | 151 max_bitrate_configured_(max_bitrate_configured), |
153 min_bitrate_configured_(min_bitrate_configured), | 152 min_bitrate_configured_(min_bitrate_configured), |
154 max_frame_rate_(max_frame_rate), | 153 max_frame_rate_(max_frame_rate), |
155 last_frame_stats_(static_cast<uint32>(-1)), | 154 last_frame_stats_(static_cast<uint32_t>(-1)), |
156 last_acked_frame_(static_cast<uint32>(-1)), | 155 last_acked_frame_(static_cast<uint32_t>(-1)), |
157 last_enqueued_frame_(static_cast<uint32>(-1)), | 156 last_enqueued_frame_(static_cast<uint32_t>(-1)), |
158 history_size_(kHistorySize), | 157 history_size_(kHistorySize), |
159 acked_bits_in_history_(0) { | 158 acked_bits_in_history_(0) { |
160 DCHECK_GE(max_bitrate_configured, min_bitrate_configured) << "Invalid config"; | 159 DCHECK_GE(max_bitrate_configured, min_bitrate_configured) << "Invalid config"; |
161 DCHECK_GT(min_bitrate_configured, 0); | 160 DCHECK_GT(min_bitrate_configured, 0); |
162 frame_stats_.resize(2); | 161 frame_stats_.resize(2); |
163 base::TimeTicks now = clock->NowTicks(); | 162 base::TimeTicks now = clock->NowTicks(); |
164 frame_stats_[0].ack_time = now; | 163 frame_stats_[0].ack_time = now; |
165 frame_stats_[0].enqueue_time = now; | 164 frame_stats_[0].enqueue_time = now; |
166 frame_stats_[1].ack_time = now; | 165 frame_stats_[1].ack_time = now; |
167 DCHECK(!frame_stats_[0].ack_time.is_null()); | 166 DCHECK(!frame_stats_[0].ack_time.is_null()); |
(...skipping 30 matching lines...) Expand all Loading... |
198 double transmit_time = | 197 double transmit_time = |
199 (GetFrameStats(last_acked_frame_)->ack_time - | 198 (GetFrameStats(last_acked_frame_)->ack_time - |
200 frame_stats_.front().enqueue_time - dead_time_in_history_).InSecondsF(); | 199 frame_stats_.front().enqueue_time - dead_time_in_history_).InSecondsF(); |
201 | 200 |
202 if (acked_bits_in_history_ == 0 || transmit_time <= 0.0) { | 201 if (acked_bits_in_history_ == 0 || transmit_time <= 0.0) { |
203 return min_bitrate_configured_; | 202 return min_bitrate_configured_; |
204 } | 203 } |
205 return acked_bits_in_history_ / std::max(transmit_time, 1E-3); | 204 return acked_bits_in_history_ / std::max(transmit_time, 1E-3); |
206 } | 205 } |
207 | 206 |
208 AdaptiveCongestionControl::FrameStats* | 207 AdaptiveCongestionControl::FrameStats* AdaptiveCongestionControl::GetFrameStats( |
209 AdaptiveCongestionControl::GetFrameStats(uint32 frame_id) { | 208 uint32_t frame_id) { |
210 int32 offset = static_cast<int32>(frame_id - last_frame_stats_); | 209 int32_t offset = static_cast<int32_t>(frame_id - last_frame_stats_); |
211 DCHECK_LT(offset, static_cast<int32>(kHistorySize)); | 210 DCHECK_LT(offset, static_cast<int32_t>(kHistorySize)); |
212 if (offset > 0) { | 211 if (offset > 0) { |
213 frame_stats_.resize(frame_stats_.size() + offset); | 212 frame_stats_.resize(frame_stats_.size() + offset); |
214 last_frame_stats_ += offset; | 213 last_frame_stats_ += offset; |
215 offset = 0; | 214 offset = 0; |
216 } | 215 } |
217 PruneFrameStats(); | 216 PruneFrameStats(); |
218 offset += frame_stats_.size() - 1; | 217 offset += frame_stats_.size() - 1; |
219 // TODO(miu): Change the following to DCHECK once crash fix is confirmed. | 218 // TODO(miu): Change the following to DCHECK once crash fix is confirmed. |
220 // http://crbug.com/517145 | 219 // http://crbug.com/517145 |
221 CHECK(offset >= 0 && offset < static_cast<int32>(frame_stats_.size())); | 220 CHECK(offset >= 0 && offset < static_cast<int32_t>(frame_stats_.size())); |
222 return &frame_stats_[offset]; | 221 return &frame_stats_[offset]; |
223 } | 222 } |
224 | 223 |
225 void AdaptiveCongestionControl::PruneFrameStats() { | 224 void AdaptiveCongestionControl::PruneFrameStats() { |
226 while (frame_stats_.size() > history_size_) { | 225 while (frame_stats_.size() > history_size_) { |
227 DCHECK_GT(frame_stats_.size(), 1UL); | 226 DCHECK_GT(frame_stats_.size(), 1UL); |
228 DCHECK(!frame_stats_[0].ack_time.is_null()); | 227 DCHECK(!frame_stats_[0].ack_time.is_null()); |
229 acked_bits_in_history_ -= frame_stats_[0].frame_size_in_bits; | 228 acked_bits_in_history_ -= frame_stats_[0].frame_size_in_bits; |
230 dead_time_in_history_ -= DeadTime(frame_stats_[0], frame_stats_[1]); | 229 dead_time_in_history_ -= DeadTime(frame_stats_[0], frame_stats_[1]); |
231 DCHECK_GE(acked_bits_in_history_, 0UL); | 230 DCHECK_GE(acked_bits_in_history_, 0UL); |
232 VLOG(2) << "DT: " << dead_time_in_history_.InSecondsF(); | 231 VLOG(2) << "DT: " << dead_time_in_history_.InSecondsF(); |
233 DCHECK_GE(dead_time_in_history_.InSecondsF(), 0.0); | 232 DCHECK_GE(dead_time_in_history_.InSecondsF(), 0.0); |
234 frame_stats_.pop_front(); | 233 frame_stats_.pop_front(); |
235 } | 234 } |
236 } | 235 } |
237 | 236 |
238 void AdaptiveCongestionControl::AckFrame(uint32 frame_id, | 237 void AdaptiveCongestionControl::AckFrame(uint32_t frame_id, |
239 base::TimeTicks when) { | 238 base::TimeTicks when) { |
240 FrameStats* frame_stats = GetFrameStats(last_acked_frame_); | 239 FrameStats* frame_stats = GetFrameStats(last_acked_frame_); |
241 while (IsNewerFrameId(frame_id, last_acked_frame_)) { | 240 while (IsNewerFrameId(frame_id, last_acked_frame_)) { |
242 FrameStats* last_frame_stats = frame_stats; | 241 FrameStats* last_frame_stats = frame_stats; |
243 frame_stats = GetFrameStats(last_acked_frame_ + 1); | 242 frame_stats = GetFrameStats(last_acked_frame_ + 1); |
244 if (frame_stats->enqueue_time.is_null()) { | 243 if (frame_stats->enqueue_time.is_null()) { |
245 // Can't ack a frame that hasn't been sent yet. | 244 // Can't ack a frame that hasn't been sent yet. |
246 return; | 245 return; |
247 } | 246 } |
248 last_acked_frame_++; | 247 last_acked_frame_++; |
249 if (when < frame_stats->enqueue_time) | 248 if (when < frame_stats->enqueue_time) |
250 when = frame_stats->enqueue_time; | 249 when = frame_stats->enqueue_time; |
251 | 250 |
252 frame_stats->ack_time = when; | 251 frame_stats->ack_time = when; |
253 acked_bits_in_history_ += frame_stats->frame_size_in_bits; | 252 acked_bits_in_history_ += frame_stats->frame_size_in_bits; |
254 dead_time_in_history_ += DeadTime(*last_frame_stats, *frame_stats); | 253 dead_time_in_history_ += DeadTime(*last_frame_stats, *frame_stats); |
255 } | 254 } |
256 } | 255 } |
257 | 256 |
258 void AdaptiveCongestionControl::SendFrameToTransport(uint32 frame_id, | 257 void AdaptiveCongestionControl::SendFrameToTransport(uint32_t frame_id, |
259 size_t frame_size_in_bits, | 258 size_t frame_size_in_bits, |
260 base::TimeTicks when) { | 259 base::TimeTicks when) { |
261 last_enqueued_frame_ = frame_id; | 260 last_enqueued_frame_ = frame_id; |
262 FrameStats* frame_stats = GetFrameStats(frame_id); | 261 FrameStats* frame_stats = GetFrameStats(frame_id); |
263 frame_stats->enqueue_time = when; | 262 frame_stats->enqueue_time = when; |
264 frame_stats->frame_size_in_bits = frame_size_in_bits; | 263 frame_stats->frame_size_in_bits = frame_size_in_bits; |
265 } | 264 } |
266 | 265 |
267 base::TimeTicks AdaptiveCongestionControl::EstimatedSendingTime( | 266 base::TimeTicks AdaptiveCongestionControl::EstimatedSendingTime( |
268 uint32 frame_id, | 267 uint32_t frame_id, |
269 double estimated_bitrate) { | 268 double estimated_bitrate) { |
270 const base::TimeTicks now = clock_->NowTicks(); | 269 const base::TimeTicks now = clock_->NowTicks(); |
271 | 270 |
272 // Starting with the time of the latest acknowledgement, extrapolate forward | 271 // Starting with the time of the latest acknowledgement, extrapolate forward |
273 // to determine an estimated sending time for |frame_id|. | 272 // to determine an estimated sending time for |frame_id|. |
274 // | 273 // |
275 // |estimated_sending_time| will contain the estimated sending time for each | 274 // |estimated_sending_time| will contain the estimated sending time for each |
276 // frame after the last ACK'ed frame. It is possible for multiple frames to | 275 // frame after the last ACK'ed frame. It is possible for multiple frames to |
277 // be in-flight; and therefore it is common for the |estimated_sending_time| | 276 // be in-flight; and therefore it is common for the |estimated_sending_time| |
278 // for those frames to be before |now|. | 277 // for those frames to be before |now|. |
279 base::TimeTicks estimated_sending_time; | 278 base::TimeTicks estimated_sending_time; |
280 for (uint32 f = last_acked_frame_; IsNewerFrameId(frame_id, f); ++f) { | 279 for (uint32_t f = last_acked_frame_; IsNewerFrameId(frame_id, f); ++f) { |
281 FrameStats* const stats = GetFrameStats(f); | 280 FrameStats* const stats = GetFrameStats(f); |
282 | 281 |
283 // |estimated_ack_time| is the local time when the sender receives the ACK, | 282 // |estimated_ack_time| is the local time when the sender receives the ACK, |
284 // and not the time when the ACK left the receiver. | 283 // and not the time when the ACK left the receiver. |
285 base::TimeTicks estimated_ack_time = stats->ack_time; | 284 base::TimeTicks estimated_ack_time = stats->ack_time; |
286 | 285 |
287 // If |estimated_ack_time| is not null, then we already have the actual ACK | 286 // If |estimated_ack_time| is not null, then we already have the actual ACK |
288 // time, so we'll just use it. Otherwise, we need to estimate when the ACK | 287 // time, so we'll just use it. Otherwise, we need to estimate when the ACK |
289 // will arrive. | 288 // will arrive. |
290 if (estimated_ack_time.is_null()) { | 289 if (estimated_ack_time.is_null()) { |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
365 empty_buffer_fraction); | 364 empty_buffer_fraction); |
366 bits_per_second = std::min(bits_per_second, soft_max_bitrate); | 365 bits_per_second = std::min(bits_per_second, soft_max_bitrate); |
367 bits_per_second = std::max(bits_per_second, min_bitrate_configured_); | 366 bits_per_second = std::max(bits_per_second, min_bitrate_configured_); |
368 bits_per_second = std::min(bits_per_second, max_bitrate_configured_); | 367 bits_per_second = std::min(bits_per_second, max_bitrate_configured_); |
369 | 368 |
370 return bits_per_second; | 369 return bits_per_second; |
371 } | 370 } |
372 | 371 |
373 } // namespace cast | 372 } // namespace cast |
374 } // namespace media | 373 } // namespace media |
OLD | NEW |