Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(387)

Side by Side Diff: media/cast/sender/congestion_control.cc

Issue 1534273002: Switch to standard integer types in media/. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: more Created 5 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698