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 |