Chromium Code Reviews| OLD | NEW |
|---|---|
| 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_resource_loader.h" | 5 #include "webkit/media/buffered_resource_loader.h" |
| 6 | 6 |
| 7 #include "base/bits.h" | 7 #include "base/bits.h" |
| 8 #include "base/callback_helpers.h" | 8 #include "base/callback_helpers.h" |
| 9 #include "base/format_macros.h" | 9 #include "base/format_macros.h" |
| 10 #include "base/metrics/histogram.h" | 10 #include "base/metrics/histogram.h" |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 46 // effectively the largest single read the code path can handle. | 46 // effectively the largest single read the code path can handle. |
| 47 // 20MB is an arbitrary limit; it just seems to be "good enough" in practice. | 47 // 20MB is an arbitrary limit; it just seems to be "good enough" in practice. |
| 48 static const int kMaxBufferCapacity = 20 * kMegabyte; | 48 static const int kMaxBufferCapacity = 20 * kMegabyte; |
| 49 | 49 |
| 50 // Maximum number of bytes outside the buffer we will wait for in order to | 50 // Maximum number of bytes outside the buffer we will wait for in order to |
| 51 // fulfill a read. If a read starts more than 2MB away from the data we | 51 // fulfill a read. If a read starts more than 2MB away from the data we |
| 52 // currently have in the buffer, we will not wait for buffer to reach the read's | 52 // currently have in the buffer, we will not wait for buffer to reach the read's |
| 53 // location and will instead reset the request. | 53 // location and will instead reset the request. |
| 54 static const int kForwardWaitThreshold = 2 * kMegabyte; | 54 static const int kForwardWaitThreshold = 2 * kMegabyte; |
| 55 | 55 |
| 56 // The lower bound on our buffer (expressed as a fraction of the buffer size) | |
| 57 // where we'll disable deferring and continue downloading data. | |
| 58 // | |
| 59 // TODO(scherkus): refer to http://crbug.com/124719 for more discussion on | |
| 60 // how we could improve our buffering logic. | |
| 61 static const double kDisableDeferThreshold = 0.9; | |
| 62 | |
| 63 // Computes the suggested backward and forward capacity for the buffer | 56 // Computes the suggested backward and forward capacity for the buffer |
| 64 // if one wants to play at |playback_rate| * the natural playback speed. | 57 // if one wants to play at |playback_rate| * the natural playback speed. |
| 65 // Use a value of 0 for |bitrate| if it is unknown. | 58 // Use a value of 0 for |bitrate| if it is unknown. |
| 66 static void ComputeTargetBufferWindow(float playback_rate, int bitrate, | 59 static void ComputeTargetBufferWindow(float playback_rate, int bitrate, |
| 67 int* out_backward_capacity, | 60 int* out_backward_capacity, |
| 68 int* out_forward_capacity) { | 61 int* out_forward_capacity) { |
| 69 static const int kDefaultBitrate = 200 * 1024 * 8; // 200 Kbps. | 62 static const int kDefaultBitrate = 200 * 1024 * 8; // 200 Kbps. |
| 70 static const int kMaxBitrate = 20 * kMegabyte * 8; // 20 Mbps. | 63 static const int kMaxBitrate = 20 * kMegabyte * 8; // 20 Mbps. |
| 71 static const float kMaxPlaybackRate = 25.0; | 64 static const float kMaxPlaybackRate = 25.0; |
| 72 static const int kTargetSecondsBufferedAhead = 10; | 65 static const int kTargetSecondsBufferedAhead = 10; |
| (...skipping 495 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 568 } | 561 } |
| 569 | 562 |
| 570 bool BufferedResourceLoader::DidPassCORSAccessCheck() const { | 563 bool BufferedResourceLoader::DidPassCORSAccessCheck() const { |
| 571 DCHECK(start_cb_.is_null()) | 564 DCHECK(start_cb_.is_null()) |
| 572 << "Start() must complete before calling DidPassCORSAccessCheck()"; | 565 << "Start() must complete before calling DidPassCORSAccessCheck()"; |
| 573 return !loader_failed_ && cors_mode_ != kUnspecified; | 566 return !loader_failed_ && cors_mode_ != kUnspecified; |
| 574 } | 567 } |
| 575 | 568 |
| 576 void BufferedResourceLoader::UpdateDeferStrategy(DeferStrategy strategy) { | 569 void BufferedResourceLoader::UpdateDeferStrategy(DeferStrategy strategy) { |
| 577 if (!might_be_reused_from_cache_in_future_ && strategy == kNeverDefer) | 570 if (!might_be_reused_from_cache_in_future_ && strategy == kNeverDefer) |
| 578 strategy = kThresholdDefer; | 571 strategy = kCapacityDefer; |
| 579 defer_strategy_ = strategy; | 572 defer_strategy_ = strategy; |
| 580 UpdateDeferBehavior(); | 573 UpdateDeferBehavior(); |
| 581 } | 574 } |
| 582 | 575 |
| 583 void BufferedResourceLoader::SetPlaybackRate(float playback_rate) { | 576 void BufferedResourceLoader::SetPlaybackRate(float playback_rate) { |
| 584 playback_rate_ = playback_rate; | 577 playback_rate_ = playback_rate; |
| 585 | 578 |
| 586 // This is a pause so don't bother updating the buffer window as we'll likely | 579 // This is a pause so don't bother updating the buffer window as we'll likely |
| 587 // get unpaused in the future. | 580 // get unpaused in the future. |
| 588 if (playback_rate_ == 0.0) | 581 if (playback_rate_ == 0.0) |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 635 | 628 |
| 636 switch(defer_strategy_) { | 629 switch(defer_strategy_) { |
| 637 // Never defer at all, so never enable defer. | 630 // Never defer at all, so never enable defer. |
| 638 case kNeverDefer: | 631 case kNeverDefer: |
| 639 return false; | 632 return false; |
| 640 | 633 |
| 641 // Defer if nothing is being requested. | 634 // Defer if nothing is being requested. |
| 642 case kReadThenDefer: | 635 case kReadThenDefer: |
| 643 return read_cb_.is_null(); | 636 return read_cb_.is_null(); |
| 644 | 637 |
| 645 // Defer if we've reached the max capacity of the threshold. | 638 // Defer if we've reached max capacity. |
| 646 case kThresholdDefer: | 639 case kCapacityDefer: |
| 647 return buffer_.forward_bytes() >= buffer_.forward_capacity(); | 640 return buffer_.forward_bytes() >= buffer_.forward_capacity(); |
| 648 } | 641 } |
| 649 // Otherwise don't enable defer. | 642 // Otherwise don't enable defer. |
| 650 return false; | 643 return false; |
| 651 } | 644 } |
| 652 | 645 |
| 653 bool BufferedResourceLoader::ShouldDisableDefer() const { | 646 bool BufferedResourceLoader::ShouldDisableDefer() const { |
|
Ami GONE FROM CHROMIUM
2012/07/11 05:05:58
Didn't notice until now, but it's hilarious that w
scherkus (not reviewing)
2012/07/11 18:15:38
lol.
see http://codereview.chromium.org/10694138/
| |
| 654 // If we're not deferring, then disabling makes no sense. | 647 // If we're not deferring, then disabling makes no sense. |
| 655 if (!active_loader_->deferred()) | 648 if (!active_loader_->deferred()) |
| 656 return false; | 649 return false; |
| 657 | 650 |
| 658 switch(defer_strategy_) { | 651 switch(defer_strategy_) { |
| 659 // Always disable deferring. | 652 // Always disable deferring. |
| 660 case kNeverDefer: | 653 case kNeverDefer: |
| 661 return true; | 654 return true; |
| 662 | 655 |
| 663 // We have an outstanding read request, and we have not buffered enough | 656 // We have an outstanding read request, and we have not buffered enough |
| 664 // yet to fulfill the request; disable defer to get more data. | 657 // yet to fulfill the request; disable defer to get more data. |
| 665 case kReadThenDefer: | 658 case kReadThenDefer: |
| 666 return !read_cb_.is_null() && last_offset_ > buffer_.forward_bytes(); | 659 return !read_cb_.is_null() && last_offset_ > buffer_.forward_bytes(); |
| 667 | 660 |
| 668 // Disable deferring whenever our forward-buffered amount falls beneath our | 661 // Disable deferring whenever our forward-buffered amount falls beneath our |
| 669 // threshold. | 662 // capacity. |
| 670 // | 663 case kCapacityDefer: |
| 671 // TODO(scherkus): refer to http://crbug.com/124719 for more discussion on | 664 return buffer_.forward_bytes() < buffer_.forward_capacity(); |
| 672 // how we could improve our buffering logic. | |
| 673 case kThresholdDefer: { | |
| 674 int buffered = buffer_.forward_bytes(); | |
| 675 int threshold = buffer_.forward_capacity() * kDisableDeferThreshold; | |
| 676 return buffered < threshold; | |
| 677 } | |
| 678 } | 665 } |
| 679 | 666 |
| 680 // Otherwise keep deferring. | 667 // Otherwise keep deferring. |
| 681 return false; | 668 return false; |
| 682 } | 669 } |
| 683 | 670 |
| 684 bool BufferedResourceLoader::CanFulfillRead() const { | 671 bool BufferedResourceLoader::CanFulfillRead() const { |
| 685 // If we are reading too far in the backward direction. | 672 // If we are reading too far in the backward direction. |
| 686 if (first_offset_ < 0 && (first_offset_ + buffer_.backward_bytes()) < 0) | 673 if (first_offset_ < 0 && (first_offset_ + buffer_.backward_bytes()) < 0) |
| 687 return false; | 674 return false; |
| (...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 848 | 835 |
| 849 void BufferedResourceLoader::Log() { | 836 void BufferedResourceLoader::Log() { |
| 850 media_log_->AddEvent( | 837 media_log_->AddEvent( |
| 851 media_log_->CreateBufferedExtentsChangedEvent( | 838 media_log_->CreateBufferedExtentsChangedEvent( |
| 852 offset_ - buffer_.backward_bytes(), | 839 offset_ - buffer_.backward_bytes(), |
| 853 offset_, | 840 offset_, |
| 854 offset_ + buffer_.forward_bytes())); | 841 offset_ + buffer_.forward_bytes())); |
| 855 } | 842 } |
| 856 | 843 |
| 857 } // namespace webkit_media | 844 } // namespace webkit_media |
| OLD | NEW |