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

Side by Side Diff: webkit/media/buffered_data_source.cc

Issue 10451049: Track buffered byte ranges correctly in media::Pipeline. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: . Created 8 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 | Annotate | Revision Log
« no previous file with comments | « webkit/media/buffered_data_source.h ('k') | webkit/media/buffered_data_source_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) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 "webkit/media/buffered_data_source.h" 5 #include "webkit/media/buffered_data_source.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/message_loop.h" 8 #include "base/message_loop.h"
9 #include "media/base/media_log.h" 9 #include "media/base/media_log.h"
10 #include "net/base/net_errors.h" 10 #include "net/base/net_errors.h"
(...skipping 14 matching lines...) Expand all
25 BufferedDataSource::BufferedDataSource( 25 BufferedDataSource::BufferedDataSource(
26 MessageLoop* render_loop, 26 MessageLoop* render_loop,
27 WebFrame* frame, 27 WebFrame* frame,
28 media::MediaLog* media_log) 28 media::MediaLog* media_log)
29 : total_bytes_(kPositionNotSpecified), 29 : total_bytes_(kPositionNotSpecified),
30 buffered_bytes_(0), 30 buffered_bytes_(0),
31 streaming_(false), 31 streaming_(false),
32 frame_(frame), 32 frame_(frame),
33 loader_(NULL), 33 loader_(NULL),
34 is_downloading_data_(false), 34 is_downloading_data_(false),
35 read_position_(0),
36 read_size_(0), 35 read_size_(0),
37 read_buffer_(NULL), 36 read_buffer_(NULL),
37 last_read_start_(0),
38 intermediate_read_buffer_(new uint8[kInitialReadBufferSize]), 38 intermediate_read_buffer_(new uint8[kInitialReadBufferSize]),
39 intermediate_read_buffer_size_(kInitialReadBufferSize), 39 intermediate_read_buffer_size_(kInitialReadBufferSize),
40 render_loop_(render_loop), 40 render_loop_(render_loop),
41 stop_signal_received_(false), 41 stop_signal_received_(false),
42 stopped_on_render_loop_(false), 42 stopped_on_render_loop_(false),
43 media_has_played_(false), 43 media_has_played_(false),
44 preload_(AUTO), 44 preload_(AUTO),
45 cache_miss_retries_left_(kNumCacheMissRetries), 45 cache_miss_retries_left_(kNumCacheMissRetries),
46 bitrate_(0), 46 bitrate_(0),
47 playback_rate_(0.0), 47 playback_rate_(0.0),
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after
200 DCHECK(MessageLoop::current() == render_loop_); 200 DCHECK(MessageLoop::current() == render_loop_);
201 { 201 {
202 base::AutoLock auto_lock(lock_); 202 base::AutoLock auto_lock(lock_);
203 if (stopped_on_render_loop_) 203 if (stopped_on_render_loop_)
204 return; 204 return;
205 205
206 DCHECK(!read_cb_.is_null()); 206 DCHECK(!read_cb_.is_null());
207 } 207 }
208 208
209 // Saves the read parameters. 209 // Saves the read parameters.
210 read_position_ = position; 210 last_read_start_ = position;
211 read_size_ = read_size; 211 read_size_ = read_size;
212 read_buffer_ = buffer; 212 read_buffer_ = buffer;
213 cache_miss_retries_left_ = kNumCacheMissRetries; 213 cache_miss_retries_left_ = kNumCacheMissRetries;
214 214
215 // Call to read internal to perform the actual read. 215 // Call to read internal to perform the actual read.
216 ReadInternal(); 216 ReadInternal();
217 } 217 }
218 218
219 void BufferedDataSource::CleanupTask() { 219 void BufferedDataSource::CleanupTask() {
220 DCHECK(MessageLoop::current() == render_loop_); 220 DCHECK(MessageLoop::current() == render_loop_);
(...skipping 11 matching lines...) Expand all
232 232
233 if (!read_cb_.is_null()) 233 if (!read_cb_.is_null())
234 DoneRead_Locked(kReadError); 234 DoneRead_Locked(kReadError);
235 } 235 }
236 236
237 // We just need to stop the loader, so it stops activity. 237 // We just need to stop the loader, so it stops activity.
238 if (loader_.get()) 238 if (loader_.get())
239 loader_->Stop(); 239 loader_->Stop();
240 240
241 // Reset the parameters of the current read request. 241 // Reset the parameters of the current read request.
242 read_position_ = 0;
243 read_size_ = 0; 242 read_size_ = 0;
244 read_buffer_ = 0; 243 read_buffer_ = 0;
245 } 244 }
246 245
247 void BufferedDataSource::RestartLoadingTask() { 246 void BufferedDataSource::RestartLoadingTask() {
248 DCHECK(MessageLoop::current() == render_loop_); 247 DCHECK(MessageLoop::current() == render_loop_);
249 if (stopped_on_render_loop_) 248 if (stopped_on_render_loop_)
250 return; 249 return;
251 250
252 { 251 {
253 // If there's no outstanding read then return early. 252 // If there's no outstanding read then return early.
254 base::AutoLock auto_lock(lock_); 253 base::AutoLock auto_lock(lock_);
255 if (read_cb_.is_null()) 254 if (read_cb_.is_null())
256 return; 255 return;
257 } 256 }
258 257
259 loader_.reset(CreateResourceLoader(read_position_, kPositionNotSpecified)); 258 loader_.reset(
259 CreateResourceLoader(last_read_start_, kPositionNotSpecified));
260 loader_->Start( 260 loader_->Start(
261 base::Bind(&BufferedDataSource::PartialReadStartCallback, this), 261 base::Bind(&BufferedDataSource::PartialReadStartCallback, this),
262 base::Bind(&BufferedDataSource::NetworkEventCallback, this), 262 base::Bind(&BufferedDataSource::NetworkEventCallback, this),
263 frame_); 263 frame_);
264 } 264 }
265 265
266 void BufferedDataSource::SetPlaybackRateTask(float playback_rate) { 266 void BufferedDataSource::SetPlaybackRateTask(float playback_rate) {
267 DCHECK(MessageLoop::current() == render_loop_); 267 DCHECK(MessageLoop::current() == render_loop_);
268 DCHECK(loader_.get()); 268 DCHECK(loader_.get());
269 269
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
306 DCHECK(MessageLoop::current() == render_loop_); 306 DCHECK(MessageLoop::current() == render_loop_);
307 DCHECK(loader_.get()); 307 DCHECK(loader_.get());
308 308
309 // First we prepare the intermediate read buffer for BufferedResourceLoader 309 // First we prepare the intermediate read buffer for BufferedResourceLoader
310 // to write to. 310 // to write to.
311 if (read_size_ > intermediate_read_buffer_size_) { 311 if (read_size_ > intermediate_read_buffer_size_) {
312 intermediate_read_buffer_.reset(new uint8[read_size_]); 312 intermediate_read_buffer_.reset(new uint8[read_size_]);
313 } 313 }
314 314
315 // Perform the actual read with BufferedResourceLoader. 315 // Perform the actual read with BufferedResourceLoader.
316 loader_->Read(read_position_, read_size_, intermediate_read_buffer_.get(), 316 loader_->Read(
317 base::Bind(&BufferedDataSource::ReadCallback, this)); 317 last_read_start_, read_size_, intermediate_read_buffer_.get(),
318 base::Bind(&BufferedDataSource::ReadCallback, this));
318 } 319 }
319 320
320 void BufferedDataSource::DoneRead_Locked(int bytes_read) { 321 void BufferedDataSource::DoneRead_Locked(int bytes_read) {
321 DVLOG(1) << "DoneRead: " << bytes_read << " bytes"; 322 DVLOG(1) << "DoneRead: " << bytes_read << " bytes";
322 DCHECK(MessageLoop::current() == render_loop_); 323 DCHECK(MessageLoop::current() == render_loop_);
323 DCHECK(!read_cb_.is_null()); 324 DCHECK(!read_cb_.is_null());
324 DCHECK(bytes_read >= 0 || bytes_read == kReadError); 325 DCHECK(bytes_read >= 0 || bytes_read == kReadError);
325 lock_.AssertAcquired(); 326 lock_.AssertAcquired();
326 327
327 read_cb_.Run(bytes_read); 328 read_cb_.Run(bytes_read);
328 read_cb_.Reset(); 329 read_cb_.Reset();
329 read_position_ = 0;
330 read_size_ = 0; 330 read_size_ = 0;
331 read_buffer_ = 0; 331 read_buffer_ = 0;
332 } 332 }
333 333
334 void BufferedDataSource::DoneInitialization_Locked( 334 void BufferedDataSource::DoneInitialization_Locked(
335 media::PipelineStatus status) { 335 media::PipelineStatus status) {
336 DCHECK(MessageLoop::current() == render_loop_); 336 DCHECK(MessageLoop::current() == render_loop_);
337 DCHECK(!initialize_cb_.is_null()); 337 DCHECK(!initialize_cb_.is_null());
338 lock_.AssertAcquired(); 338 lock_.AssertAcquired();
339 339
(...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after
519 if (bytes_read > 0) { 519 if (bytes_read > 0) {
520 memcpy(read_buffer_, intermediate_read_buffer_.get(), bytes_read); 520 memcpy(read_buffer_, intermediate_read_buffer_.get(), bytes_read);
521 } else if (bytes_read == 0 && total_bytes_ == kPositionNotSpecified) { 521 } else if (bytes_read == 0 && total_bytes_ == kPositionNotSpecified) {
522 // We've reached the end of the file and we didn't know the total size 522 // We've reached the end of the file and we didn't know the total size
523 // before. Update the total size so Read()s past the end of the file will 523 // before. Update the total size so Read()s past the end of the file will
524 // fail like they would if we had known the file size at the beginning. 524 // fail like they would if we had known the file size at the beginning.
525 total_bytes_ = loader_->instance_size(); 525 total_bytes_ = loader_->instance_size();
526 526
527 if (host() && total_bytes_ != kPositionNotSpecified) { 527 if (host() && total_bytes_ != kPositionNotSpecified) {
528 host()->SetTotalBytes(total_bytes_); 528 host()->SetTotalBytes(total_bytes_);
529 host()->SetBufferedBytes(total_bytes_); 529 host()->AddBufferedByteRange(last_read_start_, total_bytes_);
530 } 530 }
531 } 531 }
532 DoneRead_Locked(bytes_read); 532 DoneRead_Locked(bytes_read);
533 } 533 }
534 534
535 void BufferedDataSource::NetworkEventCallback() { 535 void BufferedDataSource::NetworkEventCallback() {
536 DCHECK(MessageLoop::current() == render_loop_); 536 DCHECK(MessageLoop::current() == render_loop_);
537 DCHECK(loader_.get()); 537 DCHECK(loader_.get());
538 538
539 // In case of non-HTTP request we don't need to report network events, 539 // In case of non-HTTP request we don't need to report network events,
540 // so return immediately. 540 // so return immediately.
541 if (!url_.SchemeIs(kHttpScheme) && !url_.SchemeIs(kHttpsScheme)) 541 if (!url_.SchemeIs(kHttpScheme) && !url_.SchemeIs(kHttpsScheme))
542 return; 542 return;
543 543
544 bool is_downloading_data = loader_->is_downloading_data(); 544 bool is_downloading_data = loader_->is_downloading_data();
545 int64 buffered_position = loader_->GetBufferedPosition(); 545 int64 current_buffered_position = loader_->GetBufferedPosition();
546 546
547 // If we get an unspecified value, return immediately. 547 // If we get an unspecified value, return immediately.
548 if (buffered_position == kPositionNotSpecified) 548 if (current_buffered_position == kPositionNotSpecified)
549 return; 549 return;
550 550
551 // We need to prevent calling to filter host and running the callback if 551 // We need to prevent calling to filter host and running the callback if
552 // we have received the stop signal. We need to lock down the whole callback 552 // we have received the stop signal. We need to lock down the whole callback
553 // method to prevent bad things from happening. The reason behind this is 553 // method to prevent bad things from happening. The reason behind this is
554 // that we cannot guarantee tasks on render thread have completely stopped 554 // that we cannot guarantee tasks on render thread have completely stopped
555 // when we receive the Stop() method call. So only way to solve this is to 555 // when we receive the Stop() method call. So only way to solve this is to
556 // let tasks on render thread to run but make sure they don't call outside 556 // let tasks on render thread to run but make sure they don't call outside
557 // this object when Stop() method is ever called. Locking this method is safe 557 // this object when Stop() method is ever called. Locking this method is safe
558 // because |lock_| is only acquired in tasks on render thread. 558 // because |lock_| is only acquired in tasks on render thread.
559 base::AutoLock auto_lock(lock_); 559 base::AutoLock auto_lock(lock_);
560 if (stop_signal_received_) 560 if (stop_signal_received_)
561 return; 561 return;
562 562
563 if (is_downloading_data != is_downloading_data_) { 563 if (is_downloading_data != is_downloading_data_) {
564 is_downloading_data_ = is_downloading_data; 564 is_downloading_data_ = is_downloading_data;
565 if (host()) 565 if (host())
566 host()->SetNetworkActivity(is_downloading_data); 566 host()->SetNetworkActivity(is_downloading_data);
567 } 567 }
568 568
569 buffered_bytes_ = buffered_position + 1; 569 if (host() && current_buffered_position > last_read_start_)
570 if (host()) 570 host()->AddBufferedByteRange(last_read_start_, current_buffered_position);
571 host()->SetBufferedBytes(buffered_bytes_);
572 } 571 }
573 572
574 void BufferedDataSource::UpdateHostState_Locked() { 573 void BufferedDataSource::UpdateHostState_Locked() {
575 // Called from various threads, under lock. 574 // Called from various threads, under lock.
576 lock_.AssertAcquired(); 575 lock_.AssertAcquired();
577 576
578 if (!host()) 577 if (!host())
579 return; 578 return;
580 579
581 if (total_bytes_ != kPositionNotSpecified) 580 if (total_bytes_ != kPositionNotSpecified)
582 host()->SetTotalBytes(total_bytes_); 581 host()->SetTotalBytes(total_bytes_);
583 host()->SetBufferedBytes(buffered_bytes_); 582 if (buffered_bytes_ > last_read_start_)
583 host()->AddBufferedByteRange(last_read_start_, buffered_bytes_);
584 } 584 }
585 585
586 } // namespace webkit_media 586 } // namespace webkit_media
OLDNEW
« no previous file with comments | « webkit/media/buffered_data_source.h ('k') | webkit/media/buffered_data_source_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698