| Index: webkit/glue/media/buffered_resource_loader.cc
|
| diff --git a/webkit/glue/media/buffered_resource_loader.cc b/webkit/glue/media/buffered_resource_loader.cc
|
| index 5adb76f8a3bc06ddb7ea3290e458436e30220cd2..d88c6548aa6727ba9226ae5c14a1a1b226621c7b 100644
|
| --- a/webkit/glue/media/buffered_resource_loader.cc
|
| +++ b/webkit/glue/media/buffered_resource_loader.cc
|
| @@ -50,7 +50,7 @@ BufferedResourceLoader::BufferedResourceLoader(
|
| int64 last_byte_position)
|
| : buffer_(new media::SeekableBuffer(kBackwardCapcity, kForwardCapacity)),
|
| deferred_(false),
|
| - defer_allowed_(true),
|
| + defer_strategy_(kReadThenDefer),
|
| completed_(false),
|
| range_requested_(false),
|
| partial_response_(false),
|
| @@ -180,10 +180,15 @@ void BufferedResourceLoader::Read(int64 position,
|
| // If we can serve the request now, do the actual read.
|
| if (CanFulfillRead()) {
|
| ReadInternal();
|
| - DisableDeferIfNeeded();
|
| + UpdateDeferBehavior();
|
| return;
|
| }
|
|
|
| + // If you're deferred and you can't fulfill the read because you don't have
|
| + // enough data, you will never fulfill the read.
|
| + // Update defer behavior to re-enable deferring if need be.
|
| + UpdateDeferBehavior();
|
| +
|
| // If we expected the read request to be fulfilled later, returns
|
| // immediately and let more data to flow in.
|
| if (WillFulfillRead())
|
| @@ -199,11 +204,6 @@ int64 BufferedResourceLoader::GetBufferedPosition() {
|
| return kPositionNotSpecified;
|
| }
|
|
|
| -void BufferedResourceLoader::SetAllowDefer(bool is_allowed) {
|
| - defer_allowed_ = is_allowed;
|
| - DisableDeferIfNeeded();
|
| -}
|
| -
|
| int64 BufferedResourceLoader::content_length() {
|
| return content_length_;
|
| }
|
| @@ -344,21 +344,19 @@ void BufferedResourceLoader::didReceiveData2(
|
| buffer_->Append(reinterpret_cast<const uint8*>(data), data_length);
|
|
|
| // If there is an active read request, try to fulfill the request.
|
| - if (HasPendingRead() && CanFulfillRead()) {
|
| + if (HasPendingRead() && CanFulfillRead())
|
| ReadInternal();
|
| - } else if (!defer_allowed_) {
|
| - // If we're not allowed to defer, slide the buffer window forward instead
|
| - // of deferring.
|
| - if (buffer_->forward_bytes() > buffer_->forward_capacity()) {
|
| - size_t excess = buffer_->forward_bytes() - buffer_->forward_capacity();
|
| - bool success = buffer_->Seek(excess);
|
| - DCHECK(success);
|
| - offset_ += first_offset_ + excess;
|
| - }
|
| - }
|
|
|
| // At last see if the buffer is full and we need to defer the downloading.
|
| - EnableDeferIfNeeded();
|
| + UpdateDeferBehavior();
|
| +
|
| + // Consume excess bytes from our in-memory buffer if necessary.
|
| + if (buffer_->forward_bytes() > buffer_->forward_capacity()) {
|
| + size_t excess = buffer_->forward_bytes() - buffer_->forward_capacity();
|
| + bool success = buffer_->Seek(excess);
|
| + DCHECK(success);
|
| + offset_ += first_offset_ + excess;
|
| + }
|
|
|
| // Notify that we have received some data.
|
| NotifyNetworkEvent();
|
| @@ -441,32 +439,83 @@ bool BufferedResourceLoader::HasSingleOrigin() const {
|
|
|
| /////////////////////////////////////////////////////////////////////////////
|
| // Helper methods.
|
| -void BufferedResourceLoader::EnableDeferIfNeeded() {
|
| - if (!defer_allowed_)
|
| +void BufferedResourceLoader::UpdateDeferBehavior() {
|
| + if (!url_loader_.get() || !buffer_.get())
|
| return;
|
|
|
| - if (!deferred_ &&
|
| - buffer_->forward_bytes() >= buffer_->forward_capacity()) {
|
| - deferred_ = true;
|
| + if ((deferred_ && ShouldDisableDefer()) ||
|
| + (!deferred_ && ShouldEnableDefer())) {
|
| + bool eventOccurred = ToggleDeferring();
|
| + if (eventOccurred)
|
| + NotifyNetworkEvent();
|
| + }
|
| +}
|
| +
|
| +void BufferedResourceLoader::UpdateDeferStrategy(DeferStrategy strategy) {
|
| + defer_strategy_ = strategy;
|
| + UpdateDeferBehavior();
|
| +}
|
| +
|
| +bool BufferedResourceLoader::ShouldEnableDefer() {
|
| + // If we're already deferring, then enabling makes no sense.
|
| + if (deferred_)
|
| + return false;
|
| +
|
| + switch(defer_strategy_) {
|
| + // Never defer at all, so never enable defer.
|
| + case kNeverDefer:
|
| + return false;
|
|
|
| - if (url_loader_.get())
|
| - url_loader_->setDefersLoading(true);
|
| + // Defer if nothing is being requested.
|
| + case kReadThenDefer:
|
| + return !read_callback_.get();
|
|
|
| - NotifyNetworkEvent();
|
| + // Defer if we've reached the max capacity of the threshold.
|
| + case kThresholdDefer:
|
| + return buffer_->forward_bytes() >= buffer_->forward_capacity();
|
| }
|
| + // Otherwise don't enable defer.
|
| + return false;
|
| }
|
|
|
| -void BufferedResourceLoader::DisableDeferIfNeeded() {
|
| - if (deferred_ &&
|
| - (!defer_allowed_ ||
|
| - buffer_->forward_bytes() < buffer_->forward_capacity() / 2)) {
|
| - deferred_ = false;
|
| +bool BufferedResourceLoader::ShouldDisableDefer() {
|
| + // If we're not deferring, then disabling makes no sense.
|
| + if (!deferred_)
|
| + return false;
|
|
|
| - if (url_loader_.get())
|
| - url_loader_->setDefersLoading(false);
|
| + switch(defer_strategy_) {
|
| + // Always disable deferring.
|
| + case kNeverDefer:
|
| + return true;
|
| +
|
| + // We have an outstanding read request, and we have not buffered enough
|
| + // yet to fulfill the request; disable defer to get more data.
|
| + case kReadThenDefer: {
|
| + size_t amount_buffered = buffer_->forward_bytes();
|
| + size_t amount_to_read = static_cast<size_t>(read_size_);
|
| + return read_callback_.get() && amount_buffered < amount_to_read;
|
| + }
|
| +
|
| + // We have less than half the capacity of our threshold, so
|
| + // disable defer to get more data.
|
| + case kThresholdDefer: {
|
| + size_t amount_buffered = buffer_->forward_bytes();
|
| + size_t half_capacity = buffer_->forward_capacity() / 2;
|
| + return amount_buffered < half_capacity;
|
| + }
|
| + }
|
| +
|
| + // Otherwise keep deferring.
|
| + return false;
|
| +}
|
|
|
| - NotifyNetworkEvent();
|
| +bool BufferedResourceLoader::ToggleDeferring() {
|
| + deferred_ = !deferred_;
|
| + if (url_loader_.get()) {
|
| + url_loader_->setDefersLoading(deferred_);
|
| + return true;
|
| }
|
| + return false;
|
| }
|
|
|
| bool BufferedResourceLoader::CanFulfillRead() {
|
|
|