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

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

Issue 2908003: Video Buffering: Caches data to disk when paused (resubmit) (Closed)
Patch Set: Added bug number to valgrind bug, also fixed spacing issue Created 10 years, 5 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
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 #include "base/callback.h" 5 #include "base/callback.h"
6 #include "base/compiler_specific.h" 6 #include "base/compiler_specific.h"
7 #include "base/message_loop.h" 7 #include "base/message_loop.h"
8 #include "base/process_util.h" 8 #include "base/process_util.h"
9 #include "base/stl_util-inl.h" 9 #include "base/stl_util-inl.h"
10 #include "base/string_util.h" 10 #include "base/string_util.h"
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
62 return url.SchemeIs(kHttpScheme) || url.SchemeIs(kHttpsScheme); 62 return url.SchemeIs(kHttpScheme) || url.SchemeIs(kHttpsScheme);
63 } 63 }
64 64
65 bool IsDataProtocol(const GURL& url) { 65 bool IsDataProtocol(const GURL& url) {
66 return url.SchemeIs(kDataScheme); 66 return url.SchemeIs(kDataScheme);
67 } 67 }
68 68
69 } // namespace 69 } // namespace
70 70
71 namespace webkit_glue { 71 namespace webkit_glue {
72
73 ///////////////////////////////////////////////////////////////////////////// 72 /////////////////////////////////////////////////////////////////////////////
74 // BufferedResourceLoader 73 // BufferedResourceLoader
75 BufferedResourceLoader::BufferedResourceLoader( 74 BufferedResourceLoader::BufferedResourceLoader(
76 webkit_glue::MediaResourceLoaderBridgeFactory* bridge_factory, 75 webkit_glue::MediaResourceLoaderBridgeFactory* bridge_factory,
77 const GURL& url, 76 const GURL& url,
78 int64 first_byte_position, 77 int64 first_byte_position,
79 int64 last_byte_position) 78 int64 last_byte_position)
80 : buffer_(new media::SeekableBuffer(kBackwardCapcity, kForwardCapacity)), 79 : buffer_(new media::SeekableBuffer(kBackwardCapcity, kForwardCapacity)),
81 deferred_(false), 80 deferred_(false),
81 defer_allowed_(true),
82 completed_(false), 82 completed_(false),
83 range_requested_(false), 83 range_requested_(false),
84 partial_response_(false), 84 partial_response_(false),
85 bridge_factory_(bridge_factory), 85 bridge_factory_(bridge_factory),
86 url_(url), 86 url_(url),
87 first_byte_position_(first_byte_position), 87 first_byte_position_(first_byte_position),
88 last_byte_position_(last_byte_position), 88 last_byte_position_(last_byte_position),
89 start_callback_(NULL), 89 start_callback_(NULL),
90 bridge_(NULL), 90 bridge_(NULL),
91 offset_(0), 91 offset_(0),
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after
218 return offset_ - static_cast<int>(buffer_->backward_bytes()); 218 return offset_ - static_cast<int>(buffer_->backward_bytes());
219 return kPositionNotSpecified; 219 return kPositionNotSpecified;
220 } 220 }
221 221
222 int64 BufferedResourceLoader::GetBufferedLastBytePosition() { 222 int64 BufferedResourceLoader::GetBufferedLastBytePosition() {
223 if (buffer_.get()) 223 if (buffer_.get())
224 return offset_ + static_cast<int>(buffer_->forward_bytes()) - 1; 224 return offset_ + static_cast<int>(buffer_->forward_bytes()) - 1;
225 return kPositionNotSpecified; 225 return kPositionNotSpecified;
226 } 226 }
227 227
228 void BufferedResourceLoader::SetAllowDefer(bool is_allowed) {
229 defer_allowed_ = is_allowed;
230 DisableDeferIfNeeded();
231 }
232
228 ///////////////////////////////////////////////////////////////////////////// 233 /////////////////////////////////////////////////////////////////////////////
229 // BufferedResourceLoader, 234 // BufferedResourceLoader,
230 // webkit_glue::ResourceLoaderBridge::Peer implementations 235 // webkit_glue::ResourceLoaderBridge::Peer implementations
231 bool BufferedResourceLoader::OnReceivedRedirect( 236 bool BufferedResourceLoader::OnReceivedRedirect(
232 const GURL& new_url, 237 const GURL& new_url,
233 const webkit_glue::ResourceLoaderBridge::ResponseInfo& info, 238 const webkit_glue::ResourceLoaderBridge::ResponseInfo& info,
234 bool* has_new_first_party_for_cookies, 239 bool* has_new_first_party_for_cookies,
235 GURL* new_first_party_for_cookies) { 240 GURL* new_first_party_for_cookies) {
236 DCHECK(bridge_.get()); 241 DCHECK(bridge_.get());
237 242
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
319 // In this case we shouldn't do anything. 324 // In this case we shouldn't do anything.
320 if (!buffer_.get()) 325 if (!buffer_.get())
321 return; 326 return;
322 327
323 // Writes more data to |buffer_|. 328 // Writes more data to |buffer_|.
324 buffer_->Append(reinterpret_cast<const uint8*>(data), len); 329 buffer_->Append(reinterpret_cast<const uint8*>(data), len);
325 330
326 // If there is an active read request, try to fulfill the request. 331 // If there is an active read request, try to fulfill the request.
327 if (HasPendingRead() && CanFulfillRead()) { 332 if (HasPendingRead() && CanFulfillRead()) {
328 ReadInternal(); 333 ReadInternal();
334 } else if (!defer_allowed_) {
335 // If we're not allowed to defer, slide the buffer window forward instead
336 // of deferring.
337 if (buffer_->forward_bytes() > buffer_->forward_capacity()) {
338 size_t excess = buffer_->forward_bytes() - buffer_->forward_capacity();
339 bool success = buffer_->Seek(excess);
340 DCHECK(success);
341 offset_ += first_offset_ + excess;
342 }
329 } 343 }
330 344
331 // At last see if the buffer is full and we need to defer the downloading. 345 // At last see if the buffer is full and we need to defer the downloading.
332 EnableDeferIfNeeded(); 346 EnableDeferIfNeeded();
333 347
334 // Notify that we have received some data. 348 // Notify that we have received some data.
335 NotifyNetworkEvent(); 349 NotifyNetworkEvent();
336 } 350 }
337 351
338 void BufferedResourceLoader::OnCompletedRequest( 352 void BufferedResourceLoader::OnCompletedRequest(
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
374 // We incremented the reference count when the loader was started. We balance 388 // We incremented the reference count when the loader was started. We balance
375 // that reference here so that we get destroyed. This is also the only safe 389 // that reference here so that we get destroyed. This is also the only safe
376 // place to destroy the ResourceLoaderBridge. 390 // place to destroy the ResourceLoaderBridge.
377 bridge_.reset(); 391 bridge_.reset();
378 Release(); 392 Release();
379 } 393 }
380 394
381 ///////////////////////////////////////////////////////////////////////////// 395 /////////////////////////////////////////////////////////////////////////////
382 // BufferedResourceLoader, private 396 // BufferedResourceLoader, private
383 void BufferedResourceLoader::EnableDeferIfNeeded() { 397 void BufferedResourceLoader::EnableDeferIfNeeded() {
398 if (!defer_allowed_)
399 return;
400
384 if (!deferred_ && 401 if (!deferred_ &&
385 buffer_->forward_bytes() >= buffer_->forward_capacity()) { 402 buffer_->forward_bytes() >= buffer_->forward_capacity()) {
386 deferred_ = true; 403 deferred_ = true;
387 404
388 if (bridge_.get()) 405 if (bridge_.get())
389 bridge_->SetDefersLoading(true); 406 bridge_->SetDefersLoading(true);
390 407
391 NotifyNetworkEvent(); 408 NotifyNetworkEvent();
392 } 409 }
393 } 410 }
394 411
395 void BufferedResourceLoader::DisableDeferIfNeeded() { 412 void BufferedResourceLoader::DisableDeferIfNeeded() {
396 if (deferred_ && 413 if (deferred_ &&
397 buffer_->forward_bytes() < buffer_->forward_capacity() / 2) { 414 (!defer_allowed_ ||
415 buffer_->forward_bytes() < buffer_->forward_capacity() / 2)) {
398 deferred_ = false; 416 deferred_ = false;
399 417
400 if (bridge_.get()) 418 if (bridge_.get())
401 bridge_->SetDefersLoading(false); 419 bridge_->SetDefersLoading(false);
402 420
403 NotifyNetworkEvent(); 421 NotifyNetworkEvent();
404 } 422 }
405 } 423 }
406 424
407 bool BufferedResourceLoader::CanFulfillRead() { 425 bool BufferedResourceLoader::CanFulfillRead() {
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after
532 initialize_callback_(NULL), 550 initialize_callback_(NULL),
533 read_callback_(NULL), 551 read_callback_(NULL),
534 read_position_(0), 552 read_position_(0),
535 read_size_(0), 553 read_size_(0),
536 read_buffer_(NULL), 554 read_buffer_(NULL),
537 read_attempts_(0), 555 read_attempts_(0),
538 intermediate_read_buffer_(new uint8[kInitialReadBufferSize]), 556 intermediate_read_buffer_(new uint8[kInitialReadBufferSize]),
539 intermediate_read_buffer_size_(kInitialReadBufferSize), 557 intermediate_read_buffer_size_(kInitialReadBufferSize),
540 render_loop_(render_loop), 558 render_loop_(render_loop),
541 stop_signal_received_(false), 559 stop_signal_received_(false),
542 stopped_on_render_loop_(false) { 560 stopped_on_render_loop_(false),
561 media_is_paused_(true) {
543 } 562 }
544 563
545 BufferedDataSource::~BufferedDataSource() { 564 BufferedDataSource::~BufferedDataSource() {
546 } 565 }
547 566
548 // A factory method to create BufferedResourceLoader using the read parameters. 567 // A factory method to create BufferedResourceLoader using the read parameters.
549 // This method can be overrided to inject mock BufferedResourceLoader object 568 // This method can be overrided to inject mock BufferedResourceLoader object
550 // for testing purpose. 569 // for testing purpose.
551 BufferedResourceLoader* BufferedDataSource::CreateResourceLoader( 570 BufferedResourceLoader* BufferedDataSource::CreateResourceLoader(
552 int64 first_byte_position, int64 last_byte_position) { 571 int64 first_byte_position, int64 last_byte_position) {
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
598 stop_signal_received_ = true; 617 stop_signal_received_ = true;
599 } 618 }
600 if (callback) { 619 if (callback) {
601 callback->Run(); 620 callback->Run();
602 delete callback; 621 delete callback;
603 } 622 }
604 render_loop_->PostTask(FROM_HERE, 623 render_loop_->PostTask(FROM_HERE,
605 NewRunnableMethod(this, &BufferedDataSource::CleanupTask)); 624 NewRunnableMethod(this, &BufferedDataSource::CleanupTask));
606 } 625 }
607 626
627 void BufferedDataSource::SetPlaybackRate(float playback_rate) {
628 render_loop_->PostTask(FROM_HERE,
629 NewRunnableMethod(this, &BufferedDataSource::SetPlaybackRateTask,
630 playback_rate));
631 }
632
608 ///////////////////////////////////////////////////////////////////////////// 633 /////////////////////////////////////////////////////////////////////////////
609 // BufferedDataSource, media::DataSource implementation 634 // BufferedDataSource, media::DataSource implementation
610 void BufferedDataSource::Read(int64 position, size_t size, uint8* data, 635 void BufferedDataSource::Read(int64 position, size_t size, uint8* data,
611 media::DataSource::ReadCallback* read_callback) { 636 media::DataSource::ReadCallback* read_callback) {
612 render_loop_->PostTask(FROM_HERE, 637 render_loop_->PostTask(FROM_HERE,
613 NewRunnableMethod(this, &BufferedDataSource::ReadTask, 638 NewRunnableMethod(this, &BufferedDataSource::ReadTask,
614 position, static_cast<int>(size), data, read_callback)); 639 position, static_cast<int>(size), data, read_callback));
615 } 640 }
616 641
617 bool BufferedDataSource::GetSize(int64* size_out) { 642 bool BufferedDataSource::GetSize(int64* size_out) {
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
723 // 3. CleanupTask() is executed. 748 // 3. CleanupTask() is executed.
724 // 4. RestartLoadingTask() is executed. 749 // 4. RestartLoadingTask() is executed.
725 if (stopped_on_render_loop_) 750 if (stopped_on_render_loop_)
726 return; 751 return;
727 752
728 // If there's no outstanding read then return early. 753 // If there's no outstanding read then return early.
729 if (!read_callback_.get()) 754 if (!read_callback_.get())
730 return; 755 return;
731 756
732 loader_ = CreateResourceLoader(read_position_, -1); 757 loader_ = CreateResourceLoader(read_position_, -1);
758 loader_->SetAllowDefer(!media_is_paused_);
733 loader_->Start( 759 loader_->Start(
734 NewCallback(this, &BufferedDataSource::PartialReadStartCallback), 760 NewCallback(this, &BufferedDataSource::PartialReadStartCallback),
735 NewCallback(this, &BufferedDataSource::NetworkEventCallback)); 761 NewCallback(this, &BufferedDataSource::NetworkEventCallback));
736 } 762 }
737 763
738 void BufferedDataSource::WatchDogTask() { 764 void BufferedDataSource::WatchDogTask() {
739 DCHECK(MessageLoop::current() == render_loop_); 765 DCHECK(MessageLoop::current() == render_loop_);
740 DCHECK(!stopped_on_render_loop_); 766 DCHECK(!stopped_on_render_loop_);
741 767
742 // We only care if there is an active read request. 768 // We only care if there is an active read request.
(...skipping 10 matching lines...) Expand all
753 if (read_attempts_ >= kReadTrials) 779 if (read_attempts_ >= kReadTrials)
754 return; 780 return;
755 781
756 ++read_attempts_; 782 ++read_attempts_;
757 read_submitted_time_ = base::Time::Now(); 783 read_submitted_time_ = base::Time::Now();
758 784
759 // Stops the current loader and creates a new resource loader and 785 // Stops the current loader and creates a new resource loader and
760 // retry the request. 786 // retry the request.
761 loader_->Stop(); 787 loader_->Stop();
762 loader_ = CreateResourceLoader(read_position_, -1); 788 loader_ = CreateResourceLoader(read_position_, -1);
789 loader_->SetAllowDefer(!media_is_paused_);
763 loader_->Start( 790 loader_->Start(
764 NewCallback(this, &BufferedDataSource::PartialReadStartCallback), 791 NewCallback(this, &BufferedDataSource::PartialReadStartCallback),
765 NewCallback(this, &BufferedDataSource::NetworkEventCallback)); 792 NewCallback(this, &BufferedDataSource::NetworkEventCallback));
766 } 793 }
767 794
795 void BufferedDataSource::SetPlaybackRateTask(float playback_rate) {
796 DCHECK(MessageLoop::current() == render_loop_);
797 DCHECK(loader_.get());
798
799 bool previously_paused = media_is_paused_;
800 media_is_paused_ = (playback_rate == 0.0);
801
802 // Disallow deferring data when we are pausing, allow deferring data
803 // when we resume playing.
804 if (previously_paused && !media_is_paused_) {
805 loader_->SetAllowDefer(true);
806 } else if (!previously_paused && media_is_paused_) {
807 loader_->SetAllowDefer(false);
808 }
809 }
810
768 // This method is the place where actual read happens, |loader_| must be valid 811 // This method is the place where actual read happens, |loader_| must be valid
769 // prior to make this method call. 812 // prior to make this method call.
770 void BufferedDataSource::ReadInternal() { 813 void BufferedDataSource::ReadInternal() {
771 DCHECK(MessageLoop::current() == render_loop_); 814 DCHECK(MessageLoop::current() == render_loop_);
772 DCHECK(loader_.get()); 815 DCHECK(loader_.get());
773 816
774 // First we prepare the intermediate read buffer for BufferedResourceLoader 817 // First we prepare the intermediate read buffer for BufferedResourceLoader
775 // to write to. 818 // to write to.
776 if (read_size_ > intermediate_read_buffer_size_) { 819 if (read_size_ > intermediate_read_buffer_size_) {
777 intermediate_read_buffer_.reset(new uint8[read_size_]); 820 intermediate_read_buffer_.reset(new uint8[read_size_]);
(...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after
1000 return; 1043 return;
1001 1044
1002 if (network_activity != network_activity_) { 1045 if (network_activity != network_activity_) {
1003 network_activity_ = network_activity; 1046 network_activity_ = network_activity;
1004 host()->SetNetworkActivity(network_activity); 1047 host()->SetNetworkActivity(network_activity);
1005 } 1048 }
1006 host()->SetBufferedBytes(buffered_last_byte_position + 1); 1049 host()->SetBufferedBytes(buffered_last_byte_position + 1);
1007 } 1050 }
1008 1051
1009 } // namespace webkit_glue 1052 } // namespace webkit_glue
OLDNEW
« no previous file with comments | « webkit/glue/media/buffered_data_source.h ('k') | webkit/glue/media/buffered_data_source_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698