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

Side by Side Diff: media/base/pipeline_impl.cc

Issue 2085012: Reporting a more accurate buffered time for the video tag (Closed)
Patch Set: Added checks to fix some edgecase bugs. Created 10 years, 6 months 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
« no previous file with comments | « media/base/pipeline_impl.h ('k') | media/base/pipeline_impl_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2010 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 // TODO(scherkus): clean up PipelineImpl... too many crazy function names, 5 // TODO(scherkus): clean up PipelineImpl... too many crazy function names,
6 // potential deadlocks, etc... 6 // potential deadlocks, etc...
7 7
8 #include "base/callback.h" 8 #include "base/callback.h"
9 #include "base/compiler_specific.h" 9 #include "base/compiler_specific.h"
10 #include "base/condition_variable.h" 10 #include "base/condition_variable.h"
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
70 } 70 }
71 } 71 }
72 72
73 } // namespace 73 } // namespace
74 74
75 PipelineImpl::PipelineImpl(MessageLoop* message_loop) 75 PipelineImpl::PipelineImpl(MessageLoop* message_loop)
76 : message_loop_(message_loop), 76 : message_loop_(message_loop),
77 clock_(&base::Time::Now), 77 clock_(&base::Time::Now),
78 waiting_for_clock_update_(false), 78 waiting_for_clock_update_(false),
79 state_(kCreated), 79 state_(kCreated),
80 remaining_transitions_(0) { 80 remaining_transitions_(0),
81 current_bytes_(0) {
81 ResetState(); 82 ResetState();
82 } 83 }
83 84
84 PipelineImpl::~PipelineImpl() { 85 PipelineImpl::~PipelineImpl() {
85 AutoLock auto_lock(lock_); 86 AutoLock auto_lock(lock_);
86 DCHECK(!running_) << "Stop() must complete before destroying object"; 87 DCHECK(!running_) << "Stop() must complete before destroying object";
87 } 88 }
88 89
89 // Creates the PipelineInternal and calls it's start method. 90 // Creates the PipelineInternal and calls it's start method.
90 bool PipelineImpl::Start(FilterFactory* factory, 91 bool PipelineImpl::Start(FilterFactory* factory,
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after
213 // is set/get under the lock, because this is breaching the contract that 214 // is set/get under the lock, because this is breaching the contract that
214 // |state_| is only accessed on |message_loop_|. 215 // |state_| is only accessed on |message_loop_|.
215 AutoLock auto_lock(lock_); 216 AutoLock auto_lock(lock_);
216 base::TimeDelta elapsed = clock_.Elapsed(); 217 base::TimeDelta elapsed = clock_.Elapsed();
217 if (state_ == kEnded || elapsed > duration_) { 218 if (state_ == kEnded || elapsed > duration_) {
218 return duration_; 219 return duration_;
219 } 220 }
220 return elapsed; 221 return elapsed;
221 } 222 }
222 223
223 base::TimeDelta PipelineImpl::GetBufferedTime() const { 224
225 base::TimeDelta PipelineImpl::GetBufferedTime() {
226 DCHECK(buffered_bytes_ >= current_bytes_);
224 AutoLock auto_lock(lock_); 227 AutoLock auto_lock(lock_);
225 228
226 // If buffered time was set, we report that value directly. 229 // If buffered time was set, we report that value directly.
227 if (buffered_time_.ToInternalValue() > 0) 230 if (buffered_time_.ToInternalValue() > 0)
228 return buffered_time_; 231 return buffered_time_;
229 232
230 // If buffered time was not set, we use duration and buffered bytes to 233 if (total_bytes_ == 0 || current_bytes_ == 0)
231 // estimate the buffered time.
232 // TODO(hclam): The estimation is based on linear interpolation which is
233 // not accurate enough. We should find a better way to estimate the value.
234 if (total_bytes_ == 0)
235 return base::TimeDelta(); 234 return base::TimeDelta();
236 235
237 double ratio = static_cast<double>(buffered_bytes_); 236 // If buffered time was not set, we use current time, current bytes, and
238 ratio /= total_bytes_; 237 // buffered bytes to estimate the buffered time.
238 double current_time = static_cast<double>(current_bytes_) / total_bytes_ *
239 duration_.InMilliseconds();
240 double rate = current_time / current_bytes_;
241 double buffered_time = rate * (buffered_bytes_ - current_bytes_) +
242 current_time;
243
244 // Only print the max buffered time for smooth buffering.
245 if (buffered_time > max_buffered_time_)
246 max_buffered_time_ = buffered_time;
247
239 return base::TimeDelta::FromMilliseconds( 248 return base::TimeDelta::FromMilliseconds(
240 static_cast<int64>(duration_.InMilliseconds() * ratio)); 249 static_cast<int64>(max_buffered_time_));
241 } 250 }
242 251
243 base::TimeDelta PipelineImpl::GetMediaDuration() const { 252 base::TimeDelta PipelineImpl::GetMediaDuration() const {
244 AutoLock auto_lock(lock_); 253 AutoLock auto_lock(lock_);
245 return duration_; 254 return duration_;
246 } 255 }
247 256
248 int64 PipelineImpl::GetBufferedBytes() const { 257 int64 PipelineImpl::GetBufferedBytes() const {
249 AutoLock auto_lock(lock_); 258 AutoLock auto_lock(lock_);
250 return buffered_bytes_; 259 return buffered_bytes_;
(...skipping 20 matching lines...) Expand all
271 bool PipelineImpl::IsLoaded() const { 280 bool PipelineImpl::IsLoaded() const {
272 AutoLock auto_lock(lock_); 281 AutoLock auto_lock(lock_);
273 return loaded_; 282 return loaded_;
274 } 283 }
275 284
276 PipelineError PipelineImpl::GetError() const { 285 PipelineError PipelineImpl::GetError() const {
277 AutoLock auto_lock(lock_); 286 AutoLock auto_lock(lock_);
278 return error_; 287 return error_;
279 } 288 }
280 289
290 void PipelineImpl::SetCurrentReadPosition(int64 offset) {
291 AutoLock auto_lock(lock_);
292 current_bytes_ = offset;
293 }
294
295 int64 PipelineImpl::GetCurrentReadPosition() {
296 AutoLock auto_lock(lock_);
297 return current_bytes_;
298 }
299
281 void PipelineImpl::SetPipelineEndedCallback(PipelineCallback* ended_callback) { 300 void PipelineImpl::SetPipelineEndedCallback(PipelineCallback* ended_callback) {
282 DCHECK(!IsRunning()) 301 DCHECK(!IsRunning())
283 << "Permanent callbacks should be set before the pipeline has started"; 302 << "Permanent callbacks should be set before the pipeline has started";
284 ended_callback_.reset(ended_callback); 303 ended_callback_.reset(ended_callback);
285 } 304 }
286 305
287 void PipelineImpl::SetPipelineErrorCallback(PipelineCallback* error_callback) { 306 void PipelineImpl::SetPipelineErrorCallback(PipelineCallback* error_callback) {
288 DCHECK(!IsRunning()) 307 DCHECK(!IsRunning())
289 << "Permanent callbacks should be set before the pipeline has started"; 308 << "Permanent callbacks should be set before the pipeline has started";
290 error_callback_.reset(error_callback); 309 error_callback_.reset(error_callback);
(...skipping 699 matching lines...) Expand 10 before | Expand all | Expand 10 after
990 1009
991 // Reset the pipeline, which will decrement a reference to this object. 1010 // Reset the pipeline, which will decrement a reference to this object.
992 // We will get destroyed as soon as the remaining tasks finish executing. 1011 // We will get destroyed as soon as the remaining tasks finish executing.
993 // To be safe, we'll set our pipeline reference to NULL. 1012 // To be safe, we'll set our pipeline reference to NULL.
994 filters_.clear(); 1013 filters_.clear();
995 filter_types_.clear(); 1014 filter_types_.clear();
996 STLDeleteElements(&filter_threads_); 1015 STLDeleteElements(&filter_threads_);
997 } 1016 }
998 1017
999 } // namespace media 1018 } // namespace media
OLDNEW
« no previous file with comments | « media/base/pipeline_impl.h ('k') | media/base/pipeline_impl_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698