| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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 "media/blink/buffered_resource_loader.h" | 5 #include "media/blink/buffered_resource_loader.h" |
| 6 | 6 |
| 7 #include <stdint.h> |
| 8 |
| 9 #include <limits> |
| 10 |
| 7 #include "base/bits.h" | 11 #include "base/bits.h" |
| 8 #include "base/callback_helpers.h" | 12 #include "base/callback_helpers.h" |
| 9 #include "base/metrics/histogram.h" | 13 #include "base/metrics/histogram.h" |
| 10 #include "base/strings/string_number_conversions.h" | 14 #include "base/strings/string_number_conversions.h" |
| 11 #include "base/strings/string_util.h" | 15 #include "base/strings/string_util.h" |
| 12 #include "media/base/media_log.h" | 16 #include "media/base/media_log.h" |
| 13 #include "media/blink/cache_util.h" | 17 #include "media/blink/cache_util.h" |
| 14 #include "net/http/http_byte_range.h" | 18 #include "net/http/http_byte_range.h" |
| 15 #include "net/http/http_request_headers.h" | 19 #include "net/http/http_request_headers.h" |
| 16 #include "third_party/WebKit/public/platform/WebString.h" | 20 #include "third_party/WebKit/public/platform/WebString.h" |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 87 *out_backward_capacity = std::max( | 91 *out_backward_capacity = std::max( |
| 88 kTargetSecondsBufferedBehind * bytes_per_second, kMinBufferCapacity); | 92 kTargetSecondsBufferedBehind * bytes_per_second, kMinBufferCapacity); |
| 89 | 93 |
| 90 *out_forward_capacity = std::min(*out_forward_capacity, kMaxBufferCapacity); | 94 *out_forward_capacity = std::min(*out_forward_capacity, kMaxBufferCapacity); |
| 91 *out_backward_capacity = std::min(*out_backward_capacity, kMaxBufferCapacity); | 95 *out_backward_capacity = std::min(*out_backward_capacity, kMaxBufferCapacity); |
| 92 | 96 |
| 93 if (backward_playback) | 97 if (backward_playback) |
| 94 std::swap(*out_forward_capacity, *out_backward_capacity); | 98 std::swap(*out_forward_capacity, *out_backward_capacity); |
| 95 } | 99 } |
| 96 | 100 |
| 97 BufferedResourceLoader::BufferedResourceLoader( | 101 BufferedResourceLoader::BufferedResourceLoader(const GURL& url, |
| 98 const GURL& url, | 102 CORSMode cors_mode, |
| 99 CORSMode cors_mode, | 103 int64_t first_byte_position, |
| 100 int64 first_byte_position, | 104 int64_t last_byte_position, |
| 101 int64 last_byte_position, | 105 DeferStrategy strategy, |
| 102 DeferStrategy strategy, | 106 int bitrate, |
| 103 int bitrate, | 107 double playback_rate, |
| 104 double playback_rate, | 108 MediaLog* media_log) |
| 105 MediaLog* media_log) | |
| 106 : buffer_(kMinBufferCapacity, kMinBufferCapacity), | 109 : buffer_(kMinBufferCapacity, kMinBufferCapacity), |
| 107 loader_failed_(false), | 110 loader_failed_(false), |
| 108 defer_strategy_(strategy), | 111 defer_strategy_(strategy), |
| 109 might_be_reused_from_cache_in_future_(true), | 112 might_be_reused_from_cache_in_future_(true), |
| 110 range_supported_(false), | 113 range_supported_(false), |
| 111 saved_forward_capacity_(0), | 114 saved_forward_capacity_(0), |
| 112 url_(url), | 115 url_(url), |
| 113 cors_mode_(cors_mode), | 116 cors_mode_(cors_mode), |
| 114 first_byte_position_(first_byte_position), | 117 first_byte_position_(first_byte_position), |
| 115 last_byte_position_(last_byte_position), | 118 last_byte_position_(last_byte_position), |
| 116 single_origin_(true), | 119 single_origin_(true), |
| 117 offset_(0), | 120 offset_(0), |
| 118 content_length_(kPositionNotSpecified), | 121 content_length_(kPositionNotSpecified), |
| 119 instance_size_(kPositionNotSpecified), | 122 instance_size_(kPositionNotSpecified), |
| 120 read_position_(0), | 123 read_position_(0), |
| 121 read_size_(0), | 124 read_size_(0), |
| 122 read_buffer_(NULL), | 125 read_buffer_(NULL), |
| 123 first_offset_(0), | 126 first_offset_(0), |
| 124 last_offset_(0), | 127 last_offset_(0), |
| 125 bitrate_(bitrate), | 128 bitrate_(bitrate), |
| 126 playback_rate_(playback_rate), | 129 playback_rate_(playback_rate), |
| 127 media_log_(media_log), | 130 media_log_(media_log), |
| 128 cancel_upon_deferral_(false) { | 131 cancel_upon_deferral_(false) { |
| 129 | |
| 130 // Set the initial capacity of |buffer_| based on |bitrate_| and | 132 // Set the initial capacity of |buffer_| based on |bitrate_| and |
| 131 // |playback_rate_|. | 133 // |playback_rate_|. |
| 132 UpdateBufferWindow(); | 134 UpdateBufferWindow(); |
| 133 } | 135 } |
| 134 | 136 |
| 135 BufferedResourceLoader::~BufferedResourceLoader() {} | 137 BufferedResourceLoader::~BufferedResourceLoader() {} |
| 136 | 138 |
| 137 void BufferedResourceLoader::Start( | 139 void BufferedResourceLoader::Start( |
| 138 const StartCB& start_cb, | 140 const StartCB& start_cb, |
| 139 const LoadingStateChangedCB& loading_cb, | 141 const LoadingStateChangedCB& loading_cb, |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 209 // Reset callbacks. | 211 // Reset callbacks. |
| 210 start_cb_.Reset(); | 212 start_cb_.Reset(); |
| 211 loading_cb_.Reset(); | 213 loading_cb_.Reset(); |
| 212 progress_cb_.Reset(); | 214 progress_cb_.Reset(); |
| 213 read_cb_.Reset(); | 215 read_cb_.Reset(); |
| 214 | 216 |
| 215 // Cancel and reset any active loaders. | 217 // Cancel and reset any active loaders. |
| 216 active_loader_.reset(); | 218 active_loader_.reset(); |
| 217 } | 219 } |
| 218 | 220 |
| 219 void BufferedResourceLoader::Read( | 221 void BufferedResourceLoader::Read(int64_t position, |
| 220 int64 position, | 222 int read_size, |
| 221 int read_size, | 223 uint8_t* buffer, |
| 222 uint8* buffer, | 224 const ReadCB& read_cb) { |
| 223 const ReadCB& read_cb) { | |
| 224 DCHECK(start_cb_.is_null()); | 225 DCHECK(start_cb_.is_null()); |
| 225 DCHECK(read_cb_.is_null()); | 226 DCHECK(read_cb_.is_null()); |
| 226 DCHECK(!read_cb.is_null()); | 227 DCHECK(!read_cb.is_null()); |
| 227 DCHECK(buffer); | 228 DCHECK(buffer); |
| 228 DCHECK_GT(read_size, 0); | 229 DCHECK_GT(read_size, 0); |
| 229 | 230 |
| 230 // Save the parameter of reading. | 231 // Save the parameter of reading. |
| 231 read_cb_ = read_cb; | 232 read_cb_ = read_cb; |
| 232 read_position_ = position; | 233 read_position_ = position; |
| 233 read_size_ = read_size; | 234 read_size_ = read_size; |
| (...skipping 13 matching lines...) Expand all Loading... |
| 247 // of the file. | 248 // of the file. |
| 248 if (instance_size_ != kPositionNotSpecified && | 249 if (instance_size_ != kPositionNotSpecified && |
| 249 instance_size_ <= read_position_) { | 250 instance_size_ <= read_position_) { |
| 250 DVLOG(1) << "Appear to have seeked beyond EOS; returning 0."; | 251 DVLOG(1) << "Appear to have seeked beyond EOS; returning 0."; |
| 251 DoneRead(kOk, 0); | 252 DoneRead(kOk, 0); |
| 252 return; | 253 return; |
| 253 } | 254 } |
| 254 | 255 |
| 255 // Make sure |offset_| and |read_position_| does not differ by a large | 256 // Make sure |offset_| and |read_position_| does not differ by a large |
| 256 // amount. | 257 // amount. |
| 257 if (read_position_ > offset_ + kint32max || | 258 if (read_position_ > offset_ + std::numeric_limits<int32_t>::max() || |
| 258 read_position_ < offset_ + kint32min) { | 259 read_position_ < offset_ + std::numeric_limits<int32_t>::min()) { |
| 259 DoneRead(kCacheMiss, 0); | 260 DoneRead(kCacheMiss, 0); |
| 260 return; | 261 return; |
| 261 } | 262 } |
| 262 | 263 |
| 263 // Make sure |read_size_| is not too large for the buffer to ever be able to | 264 // Make sure |read_size_| is not too large for the buffer to ever be able to |
| 264 // fulfill the read request. | 265 // fulfill the read request. |
| 265 if (read_size_ > kMaxBufferCapacity) { | 266 if (read_size_ > kMaxBufferCapacity) { |
| 266 DoneRead(kFailed, 0); | 267 DoneRead(kFailed, 0); |
| 267 return; | 268 return; |
| 268 } | 269 } |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 305 << "Capacity was not adjusted properly to prevent deferring."; | 306 << "Capacity was not adjusted properly to prevent deferring."; |
| 306 UpdateDeferBehavior(); | 307 UpdateDeferBehavior(); |
| 307 | 308 |
| 308 return; | 309 return; |
| 309 } | 310 } |
| 310 | 311 |
| 311 // Make a callback to report failure. | 312 // Make a callback to report failure. |
| 312 DoneRead(kCacheMiss, 0); | 313 DoneRead(kCacheMiss, 0); |
| 313 } | 314 } |
| 314 | 315 |
| 315 int64 BufferedResourceLoader::content_length() { | 316 int64_t BufferedResourceLoader::content_length() { |
| 316 return content_length_; | 317 return content_length_; |
| 317 } | 318 } |
| 318 | 319 |
| 319 int64 BufferedResourceLoader::instance_size() { | 320 int64_t BufferedResourceLoader::instance_size() { |
| 320 return instance_size_; | 321 return instance_size_; |
| 321 } | 322 } |
| 322 | 323 |
| 323 bool BufferedResourceLoader::range_supported() { | 324 bool BufferedResourceLoader::range_supported() { |
| 324 return range_supported_; | 325 return range_supported_; |
| 325 } | 326 } |
| 326 | 327 |
| 327 ///////////////////////////////////////////////////////////////////////////// | 328 ///////////////////////////////////////////////////////////////////////////// |
| 328 // blink::WebURLLoaderClient implementation. | 329 // blink::WebURLLoaderClient implementation. |
| 329 void BufferedResourceLoader::willFollowRedirect( | 330 void BufferedResourceLoader::willFollowRedirect( |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 372 DCHECK(active_loader_.get()); | 373 DCHECK(active_loader_.get()); |
| 373 response_original_url_ = response.wasFetchedViaServiceWorker() | 374 response_original_url_ = response.wasFetchedViaServiceWorker() |
| 374 ? response.originalURLViaServiceWorker() | 375 ? response.originalURLViaServiceWorker() |
| 375 : response.url(); | 376 : response.url(); |
| 376 | 377 |
| 377 // The loader may have been stopped and |start_cb| is destroyed. | 378 // The loader may have been stopped and |start_cb| is destroyed. |
| 378 // In this case we shouldn't do anything. | 379 // In this case we shouldn't do anything. |
| 379 if (start_cb_.is_null()) | 380 if (start_cb_.is_null()) |
| 380 return; | 381 return; |
| 381 | 382 |
| 382 uint32 reasons = GetReasonsForUncacheability(response); | 383 uint32_t reasons = GetReasonsForUncacheability(response); |
| 383 might_be_reused_from_cache_in_future_ = reasons == 0; | 384 might_be_reused_from_cache_in_future_ = reasons == 0; |
| 384 UMA_HISTOGRAM_BOOLEAN("Media.CacheUseful", reasons == 0); | 385 UMA_HISTOGRAM_BOOLEAN("Media.CacheUseful", reasons == 0); |
| 385 int shift = 0; | 386 int shift = 0; |
| 386 int max_enum = base::bits::Log2Ceiling(kMaxReason); | 387 int max_enum = base::bits::Log2Ceiling(kMaxReason); |
| 387 while (reasons) { | 388 while (reasons) { |
| 388 DCHECK_LT(shift, max_enum); // Sanity check. | 389 DCHECK_LT(shift, max_enum); // Sanity check. |
| 389 if (reasons & 0x1) { | 390 if (reasons & 0x1) { |
| 390 UMA_HISTOGRAM_ENUMERATION("Media.UncacheableReason", | 391 UMA_HISTOGRAM_ENUMERATION("Media.UncacheableReason", |
| 391 shift, | 392 shift, |
| 392 max_enum); // PRESUBMIT_IGNORE_UMA_MAX | 393 max_enum); // PRESUBMIT_IGNORE_UMA_MAX |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 461 | 462 |
| 462 void BufferedResourceLoader::didReceiveData( | 463 void BufferedResourceLoader::didReceiveData( |
| 463 WebURLLoader* loader, | 464 WebURLLoader* loader, |
| 464 const char* data, | 465 const char* data, |
| 465 int data_length, | 466 int data_length, |
| 466 int encoded_data_length) { | 467 int encoded_data_length) { |
| 467 DVLOG(1) << "didReceiveData: " << data_length << " bytes"; | 468 DVLOG(1) << "didReceiveData: " << data_length << " bytes"; |
| 468 DCHECK(active_loader_.get()); | 469 DCHECK(active_loader_.get()); |
| 469 DCHECK_GT(data_length, 0); | 470 DCHECK_GT(data_length, 0); |
| 470 | 471 |
| 471 buffer_.Append(reinterpret_cast<const uint8*>(data), data_length); | 472 buffer_.Append(reinterpret_cast<const uint8_t*>(data), data_length); |
| 472 | 473 |
| 473 // If there is an active read request, try to fulfill the request. | 474 // If there is an active read request, try to fulfill the request. |
| 474 if (HasPendingRead() && CanFulfillRead()) | 475 if (HasPendingRead() && CanFulfillRead()) |
| 475 ReadInternal(); | 476 ReadInternal(); |
| 476 | 477 |
| 477 // At last see if the buffer is full and we need to defer the downloading. | 478 // At last see if the buffer is full and we need to defer the downloading. |
| 478 UpdateDeferBehavior(); | 479 UpdateDeferBehavior(); |
| 479 | 480 |
| 480 // Consume excess bytes from our in-memory buffer if necessary. | 481 // Consume excess bytes from our in-memory buffer if necessary. |
| 481 if (buffer_.forward_bytes() > buffer_.forward_capacity()) { | 482 if (buffer_.forward_bytes() > buffer_.forward_capacity()) { |
| (...skipping 226 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 708 DCHECK(ret); | 709 DCHECK(ret); |
| 709 | 710 |
| 710 // Then do the read. | 711 // Then do the read. |
| 711 int read = buffer_.Read(read_buffer_, read_size_); | 712 int read = buffer_.Read(read_buffer_, read_size_); |
| 712 offset_ += first_offset_ + read; | 713 offset_ += first_offset_ + read; |
| 713 | 714 |
| 714 // And report with what we have read. | 715 // And report with what we have read. |
| 715 DoneRead(kOk, read); | 716 DoneRead(kOk, read); |
| 716 } | 717 } |
| 717 | 718 |
| 718 int64 BufferedResourceLoader::first_byte_position() const { | 719 int64_t BufferedResourceLoader::first_byte_position() const { |
| 719 return first_byte_position_; | 720 return first_byte_position_; |
| 720 } | 721 } |
| 721 | 722 |
| 722 // static | 723 // static |
| 723 bool BufferedResourceLoader::ParseContentRange( | 724 bool BufferedResourceLoader::ParseContentRange( |
| 724 const std::string& content_range_str, int64* first_byte_position, | 725 const std::string& content_range_str, |
| 725 int64* last_byte_position, int64* instance_size) { | 726 int64_t* first_byte_position, |
| 727 int64_t* last_byte_position, |
| 728 int64_t* instance_size) { |
| 726 const std::string kUpThroughBytesUnit = "bytes "; | 729 const std::string kUpThroughBytesUnit = "bytes "; |
| 727 if (content_range_str.find(kUpThroughBytesUnit) != 0) | 730 if (content_range_str.find(kUpThroughBytesUnit) != 0) |
| 728 return false; | 731 return false; |
| 729 std::string range_spec = | 732 std::string range_spec = |
| 730 content_range_str.substr(kUpThroughBytesUnit.length()); | 733 content_range_str.substr(kUpThroughBytesUnit.length()); |
| 731 size_t dash_offset = range_spec.find("-"); | 734 size_t dash_offset = range_spec.find("-"); |
| 732 size_t slash_offset = range_spec.find("/"); | 735 size_t slash_offset = range_spec.find("/"); |
| 733 | 736 |
| 734 if (dash_offset == std::string::npos || slash_offset == std::string::npos || | 737 if (dash_offset == std::string::npos || slash_offset == std::string::npos || |
| 735 slash_offset < dash_offset || slash_offset + 1 == range_spec.length()) { | 738 slash_offset < dash_offset || slash_offset + 1 == range_spec.length()) { |
| (...skipping 29 matching lines...) Expand all Loading... |
| 765 if (active_loader_ && active_loader_->deferred()) | 768 if (active_loader_ && active_loader_->deferred()) |
| 766 active_loader_.reset(); | 769 active_loader_.reset(); |
| 767 } | 770 } |
| 768 | 771 |
| 769 int64_t BufferedResourceLoader::GetMemoryUsage() const { | 772 int64_t BufferedResourceLoader::GetMemoryUsage() const { |
| 770 return buffer_.forward_bytes() + buffer_.backward_bytes(); | 773 return buffer_.forward_bytes() + buffer_.backward_bytes(); |
| 771 } | 774 } |
| 772 | 775 |
| 773 bool BufferedResourceLoader::VerifyPartialResponse( | 776 bool BufferedResourceLoader::VerifyPartialResponse( |
| 774 const WebURLResponse& response) { | 777 const WebURLResponse& response) { |
| 775 int64 first_byte_position, last_byte_position, instance_size; | 778 int64_t first_byte_position, last_byte_position, instance_size; |
| 776 if (!ParseContentRange(response.httpHeaderField("Content-Range").utf8(), | 779 if (!ParseContentRange(response.httpHeaderField("Content-Range").utf8(), |
| 777 &first_byte_position, &last_byte_position, | 780 &first_byte_position, &last_byte_position, |
| 778 &instance_size)) { | 781 &instance_size)) { |
| 779 return false; | 782 return false; |
| 780 } | 783 } |
| 781 | 784 |
| 782 if (instance_size != kPositionNotSpecified) { | 785 if (instance_size != kPositionNotSpecified) { |
| 783 instance_size_ = instance_size; | 786 instance_size_ = instance_size; |
| 784 } | 787 } |
| 785 | 788 |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 819 | 822 |
| 820 void BufferedResourceLoader::Log() { | 823 void BufferedResourceLoader::Log() { |
| 821 media_log_->AddEvent( | 824 media_log_->AddEvent( |
| 822 media_log_->CreateBufferedExtentsChangedEvent( | 825 media_log_->CreateBufferedExtentsChangedEvent( |
| 823 offset_ - buffer_.backward_bytes(), | 826 offset_ - buffer_.backward_bytes(), |
| 824 offset_, | 827 offset_, |
| 825 offset_ + buffer_.forward_bytes())); | 828 offset_ + buffer_.forward_bytes())); |
| 826 } | 829 } |
| 827 | 830 |
| 828 } // namespace media | 831 } // namespace media |
| OLD | NEW |