OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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/glue/media/buffered_resource_loader.h" | 5 #include "webkit/glue/media/buffered_resource_loader.h" |
6 | 6 |
7 #include "base/format_macros.h" | 7 #include "base/format_macros.h" |
8 #include "base/string_util.h" | 8 #include "base/string_util.h" |
9 #include "net/base/net_errors.h" | 9 #include "net/base/net_errors.h" |
10 #include "third_party/WebKit/Source/WebKit/chromium/public/WebKit.h" | 10 #include "third_party/WebKit/Source/WebKit/chromium/public/WebKit.h" |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
43 // number to be 2MB. | 43 // number to be 2MB. |
44 // TODO(hclam): determine a better value for this. | 44 // TODO(hclam): determine a better value for this. |
45 static const int kForwardWaitThreshold = 2 * kMegabyte; | 45 static const int kForwardWaitThreshold = 2 * kMegabyte; |
46 | 46 |
47 BufferedResourceLoader::BufferedResourceLoader( | 47 BufferedResourceLoader::BufferedResourceLoader( |
48 const GURL& url, | 48 const GURL& url, |
49 int64 first_byte_position, | 49 int64 first_byte_position, |
50 int64 last_byte_position) | 50 int64 last_byte_position) |
51 : buffer_(new media::SeekableBuffer(kBackwardCapcity, kForwardCapacity)), | 51 : buffer_(new media::SeekableBuffer(kBackwardCapcity, kForwardCapacity)), |
52 deferred_(false), | 52 deferred_(false), |
53 defer_allowed_(true), | 53 defer_strategy_(kReadThenDefer), |
54 completed_(false), | 54 completed_(false), |
55 range_requested_(false), | 55 range_requested_(false), |
56 partial_response_(false), | 56 partial_response_(false), |
57 url_(url), | 57 url_(url), |
58 first_byte_position_(first_byte_position), | 58 first_byte_position_(first_byte_position), |
59 last_byte_position_(last_byte_position), | 59 last_byte_position_(last_byte_position), |
60 single_origin_(true), | 60 single_origin_(true), |
61 start_callback_(NULL), | 61 start_callback_(NULL), |
62 offset_(0), | 62 offset_(0), |
63 content_length_(kPositionNotSpecified), | 63 content_length_(kPositionNotSpecified), |
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
173 return; | 173 return; |
174 } | 174 } |
175 | 175 |
176 // Prepare the parameters. | 176 // Prepare the parameters. |
177 first_offset_ = static_cast<int>(read_position_ - offset_); | 177 first_offset_ = static_cast<int>(read_position_ - offset_); |
178 last_offset_ = first_offset_ + read_size_; | 178 last_offset_ = first_offset_ + read_size_; |
179 | 179 |
180 // If we can serve the request now, do the actual read. | 180 // If we can serve the request now, do the actual read. |
181 if (CanFulfillRead()) { | 181 if (CanFulfillRead()) { |
182 ReadInternal(); | 182 ReadInternal(); |
183 DisableDeferIfNeeded(); | 183 UpdateDeferBehavior(); |
184 return; | 184 return; |
185 } | 185 } |
186 | 186 |
| 187 // If you're deferred and you can't fulfill the read because you don't have |
| 188 // enough data, you will never fulfill the read. |
| 189 // Update defer behavior to re-enable deferring if need be. |
| 190 UpdateDeferBehavior(); |
| 191 |
187 // If we expected the read request to be fulfilled later, returns | 192 // If we expected the read request to be fulfilled later, returns |
188 // immediately and let more data to flow in. | 193 // immediately and let more data to flow in. |
189 if (WillFulfillRead()) | 194 if (WillFulfillRead()) |
190 return; | 195 return; |
191 | 196 |
192 // Make a callback to report failure. | 197 // Make a callback to report failure. |
193 DoneRead(net::ERR_CACHE_MISS); | 198 DoneRead(net::ERR_CACHE_MISS); |
194 } | 199 } |
195 | 200 |
196 int64 BufferedResourceLoader::GetBufferedPosition() { | 201 int64 BufferedResourceLoader::GetBufferedPosition() { |
197 if (buffer_.get()) | 202 if (buffer_.get()) |
198 return offset_ + static_cast<int>(buffer_->forward_bytes()) - 1; | 203 return offset_ + static_cast<int>(buffer_->forward_bytes()) - 1; |
199 return kPositionNotSpecified; | 204 return kPositionNotSpecified; |
200 } | 205 } |
201 | 206 |
202 void BufferedResourceLoader::SetAllowDefer(bool is_allowed) { | |
203 defer_allowed_ = is_allowed; | |
204 DisableDeferIfNeeded(); | |
205 } | |
206 | |
207 int64 BufferedResourceLoader::content_length() { | 207 int64 BufferedResourceLoader::content_length() { |
208 return content_length_; | 208 return content_length_; |
209 } | 209 } |
210 | 210 |
211 int64 BufferedResourceLoader::instance_size() { | 211 int64 BufferedResourceLoader::instance_size() { |
212 return instance_size_; | 212 return instance_size_; |
213 } | 213 } |
214 | 214 |
215 bool BufferedResourceLoader::partial_response() { | 215 bool BufferedResourceLoader::partial_response() { |
216 return partial_response_; | 216 return partial_response_; |
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
337 | 337 |
338 // If this loader has been stopped, |buffer_| would be destroyed. | 338 // If this loader has been stopped, |buffer_| would be destroyed. |
339 // In this case we shouldn't do anything. | 339 // In this case we shouldn't do anything. |
340 if (!buffer_.get()) | 340 if (!buffer_.get()) |
341 return; | 341 return; |
342 | 342 |
343 // Writes more data to |buffer_|. | 343 // Writes more data to |buffer_|. |
344 buffer_->Append(reinterpret_cast<const uint8*>(data), data_length); | 344 buffer_->Append(reinterpret_cast<const uint8*>(data), data_length); |
345 | 345 |
346 // If there is an active read request, try to fulfill the request. | 346 // If there is an active read request, try to fulfill the request. |
347 if (HasPendingRead() && CanFulfillRead()) { | 347 if (HasPendingRead() && CanFulfillRead()) |
348 ReadInternal(); | 348 ReadInternal(); |
349 } else if (!defer_allowed_) { | |
350 // If we're not allowed to defer, slide the buffer window forward instead | |
351 // of deferring. | |
352 if (buffer_->forward_bytes() > buffer_->forward_capacity()) { | |
353 size_t excess = buffer_->forward_bytes() - buffer_->forward_capacity(); | |
354 bool success = buffer_->Seek(excess); | |
355 DCHECK(success); | |
356 offset_ += first_offset_ + excess; | |
357 } | |
358 } | |
359 | 349 |
360 // At last see if the buffer is full and we need to defer the downloading. | 350 // At last see if the buffer is full and we need to defer the downloading. |
361 EnableDeferIfNeeded(); | 351 UpdateDeferBehavior(); |
| 352 |
| 353 // Consume excess bytes from our in-memory buffer if necessary. |
| 354 if (buffer_->forward_bytes() > buffer_->forward_capacity()) { |
| 355 size_t excess = buffer_->forward_bytes() - buffer_->forward_capacity(); |
| 356 bool success = buffer_->Seek(excess); |
| 357 DCHECK(success); |
| 358 offset_ += first_offset_ + excess; |
| 359 } |
362 | 360 |
363 // Notify that we have received some data. | 361 // Notify that we have received some data. |
364 NotifyNetworkEvent(); | 362 NotifyNetworkEvent(); |
365 } | 363 } |
366 | 364 |
367 void BufferedResourceLoader::didDownloadData( | 365 void BufferedResourceLoader::didDownloadData( |
368 WebKit::WebURLLoader* loader, | 366 WebKit::WebURLLoader* loader, |
369 int dataLength) { | 367 int dataLength) { |
370 NOTIMPLEMENTED(); | 368 NOTIMPLEMENTED(); |
371 } | 369 } |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
434 url_loader_.reset(); | 432 url_loader_.reset(); |
435 Release(); | 433 Release(); |
436 } | 434 } |
437 | 435 |
438 bool BufferedResourceLoader::HasSingleOrigin() const { | 436 bool BufferedResourceLoader::HasSingleOrigin() const { |
439 return single_origin_; | 437 return single_origin_; |
440 } | 438 } |
441 | 439 |
442 ///////////////////////////////////////////////////////////////////////////// | 440 ///////////////////////////////////////////////////////////////////////////// |
443 // Helper methods. | 441 // Helper methods. |
444 void BufferedResourceLoader::EnableDeferIfNeeded() { | 442 void BufferedResourceLoader::UpdateDeferBehavior() { |
445 if (!defer_allowed_) | 443 if (!url_loader_.get() || !buffer_.get()) |
446 return; | 444 return; |
447 | 445 |
448 if (!deferred_ && | 446 if ((deferred_ && ShouldDisableDefer()) || |
449 buffer_->forward_bytes() >= buffer_->forward_capacity()) { | 447 (!deferred_ && ShouldEnableDefer())) { |
450 deferred_ = true; | 448 bool eventOccurred = ToggleDeferring(); |
451 | 449 if (eventOccurred) |
452 if (url_loader_.get()) | 450 NotifyNetworkEvent(); |
453 url_loader_->setDefersLoading(true); | |
454 | |
455 NotifyNetworkEvent(); | |
456 } | 451 } |
457 } | 452 } |
458 | 453 |
459 void BufferedResourceLoader::DisableDeferIfNeeded() { | 454 void BufferedResourceLoader::UpdateDeferStrategy(DeferStrategy strategy) { |
460 if (deferred_ && | 455 defer_strategy_ = strategy; |
461 (!defer_allowed_ || | 456 UpdateDeferBehavior(); |
462 buffer_->forward_bytes() < buffer_->forward_capacity() / 2)) { | 457 } |
463 deferred_ = false; | |
464 | 458 |
465 if (url_loader_.get()) | 459 bool BufferedResourceLoader::ShouldEnableDefer() { |
466 url_loader_->setDefersLoading(false); | 460 // If we're already deferring, then enabling makes no sense. |
| 461 if (deferred_) |
| 462 return false; |
467 | 463 |
468 NotifyNetworkEvent(); | 464 switch(defer_strategy_) { |
| 465 // Never defer at all, so never enable defer. |
| 466 case kNeverDefer: |
| 467 return false; |
| 468 |
| 469 // Defer if nothing is being requested. |
| 470 case kReadThenDefer: |
| 471 return !read_callback_.get(); |
| 472 |
| 473 // Defer if we've reached the max capacity of the threshold. |
| 474 case kThresholdDefer: |
| 475 return buffer_->forward_bytes() >= buffer_->forward_capacity(); |
469 } | 476 } |
| 477 // Otherwise don't enable defer. |
| 478 return false; |
| 479 } |
| 480 |
| 481 bool BufferedResourceLoader::ShouldDisableDefer() { |
| 482 // If we're not deferring, then disabling makes no sense. |
| 483 if (!deferred_) |
| 484 return false; |
| 485 |
| 486 switch(defer_strategy_) { |
| 487 // Always disable deferring. |
| 488 case kNeverDefer: |
| 489 return true; |
| 490 |
| 491 // We have an outstanding read request, and we have not buffered enough |
| 492 // yet to fulfill the request; disable defer to get more data. |
| 493 case kReadThenDefer: { |
| 494 size_t amount_buffered = buffer_->forward_bytes(); |
| 495 size_t amount_to_read = static_cast<size_t>(read_size_); |
| 496 return read_callback_.get() && amount_buffered < amount_to_read; |
| 497 } |
| 498 |
| 499 // We have less than half the capacity of our threshold, so |
| 500 // disable defer to get more data. |
| 501 case kThresholdDefer: { |
| 502 size_t amount_buffered = buffer_->forward_bytes(); |
| 503 size_t half_capacity = buffer_->forward_capacity() / 2; |
| 504 return amount_buffered < half_capacity; |
| 505 } |
| 506 } |
| 507 |
| 508 // Otherwise keep deferring. |
| 509 return false; |
| 510 } |
| 511 |
| 512 bool BufferedResourceLoader::ToggleDeferring() { |
| 513 deferred_ = !deferred_; |
| 514 if (url_loader_.get()) { |
| 515 url_loader_->setDefersLoading(deferred_); |
| 516 return true; |
| 517 } |
| 518 return false; |
470 } | 519 } |
471 | 520 |
472 bool BufferedResourceLoader::CanFulfillRead() { | 521 bool BufferedResourceLoader::CanFulfillRead() { |
473 // If we are reading too far in the backward direction. | 522 // If we are reading too far in the backward direction. |
474 if (first_offset_ < 0 && | 523 if (first_offset_ < 0 && |
475 first_offset_ + static_cast<int>(buffer_->backward_bytes()) < 0) | 524 first_offset_ + static_cast<int>(buffer_->backward_bytes()) < 0) |
476 return false; | 525 return false; |
477 | 526 |
478 // If the start offset is too far ahead. | 527 // If the start offset is too far ahead. |
479 if (first_offset_ >= static_cast<int>(buffer_->forward_bytes())) | 528 if (first_offset_ >= static_cast<int>(buffer_->forward_bytes())) |
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
583 start_callback_->RunWithParams(Tuple1<int>(error)); | 632 start_callback_->RunWithParams(Tuple1<int>(error)); |
584 start_callback_.reset(); | 633 start_callback_.reset(); |
585 } | 634 } |
586 | 635 |
587 void BufferedResourceLoader::NotifyNetworkEvent() { | 636 void BufferedResourceLoader::NotifyNetworkEvent() { |
588 if (event_callback_.get()) | 637 if (event_callback_.get()) |
589 event_callback_->Run(); | 638 event_callback_->Run(); |
590 } | 639 } |
591 | 640 |
592 } // namespace webkit_glue | 641 } // namespace webkit_glue |
OLD | NEW |