| 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/media/buffered_resource_loader.h" | 5 #include "webkit/media/buffered_resource_loader.h" |
| 6 | 6 |
| 7 #include "base/format_macros.h" | 7 #include "base/format_macros.h" |
| 8 #include "base/stringprintf.h" | 8 #include "base/stringprintf.h" |
| 9 #include "base/string_util.h" | 9 #include "base/string_util.h" |
| 10 #include "media/base/media_log.h" | 10 #include "media/base/media_log.h" |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 105 : deferred_(false), | 105 : deferred_(false), |
| 106 defer_strategy_(strategy), | 106 defer_strategy_(strategy), |
| 107 completed_(false), | 107 completed_(false), |
| 108 range_requested_(false), | 108 range_requested_(false), |
| 109 range_supported_(false), | 109 range_supported_(false), |
| 110 saved_forward_capacity_(0), | 110 saved_forward_capacity_(0), |
| 111 url_(url), | 111 url_(url), |
| 112 first_byte_position_(first_byte_position), | 112 first_byte_position_(first_byte_position), |
| 113 last_byte_position_(last_byte_position), | 113 last_byte_position_(last_byte_position), |
| 114 single_origin_(true), | 114 single_origin_(true), |
| 115 start_callback_(NULL), | |
| 116 offset_(0), | 115 offset_(0), |
| 117 content_length_(kPositionNotSpecified), | 116 content_length_(kPositionNotSpecified), |
| 118 instance_size_(kPositionNotSpecified), | 117 instance_size_(kPositionNotSpecified), |
| 119 read_callback_(NULL), | |
| 120 read_position_(0), | 118 read_position_(0), |
| 121 read_size_(0), | 119 read_size_(0), |
| 122 read_buffer_(NULL), | 120 read_buffer_(NULL), |
| 123 first_offset_(0), | 121 first_offset_(0), |
| 124 last_offset_(0), | 122 last_offset_(0), |
| 125 keep_test_loader_(false), | 123 keep_test_loader_(false), |
| 126 bitrate_(bitrate), | 124 bitrate_(bitrate), |
| 127 playback_rate_(playback_rate), | 125 playback_rate_(playback_rate), |
| 128 media_log_(media_log) { | 126 media_log_(media_log) { |
| 129 | 127 |
| 130 size_t backward_capacity; | 128 size_t backward_capacity; |
| 131 size_t forward_capacity; | 129 size_t forward_capacity; |
| 132 ComputeTargetBufferWindow( | 130 ComputeTargetBufferWindow( |
| 133 playback_rate_, bitrate_, &backward_capacity, &forward_capacity); | 131 playback_rate_, bitrate_, &backward_capacity, &forward_capacity); |
| 134 buffer_.reset(new media::SeekableBuffer(backward_capacity, forward_capacity)); | 132 buffer_.reset(new media::SeekableBuffer(backward_capacity, forward_capacity)); |
| 135 } | 133 } |
| 136 | 134 |
| 137 BufferedResourceLoader::~BufferedResourceLoader() { | 135 BufferedResourceLoader::~BufferedResourceLoader() { |
| 138 if (!completed_ && url_loader_.get()) | 136 if (!completed_ && url_loader_.get()) |
| 139 url_loader_->cancel(); | 137 url_loader_->cancel(); |
| 140 } | 138 } |
| 141 | 139 |
| 142 void BufferedResourceLoader::Start(net::OldCompletionCallback* start_callback, | 140 void BufferedResourceLoader::Start( |
| 143 const base::Closure& event_callback, | 141 const net::CompletionCallback& start_callback, |
| 144 WebFrame* frame) { | 142 const base::Closure& event_callback, |
| 143 WebFrame* frame) { |
| 145 // Make sure we have not started. | 144 // Make sure we have not started. |
| 146 DCHECK(!start_callback_.get()); | 145 DCHECK(start_callback_.is_null()); |
| 147 DCHECK(event_callback_.is_null()); | 146 DCHECK(event_callback_.is_null()); |
| 148 DCHECK(start_callback); | 147 DCHECK(!start_callback.is_null()); |
| 149 DCHECK(!event_callback.is_null()); | 148 DCHECK(!event_callback.is_null()); |
| 150 CHECK(frame); | 149 CHECK(frame); |
| 151 | 150 |
| 152 start_callback_.reset(start_callback); | 151 start_callback_ = start_callback; |
| 153 event_callback_ = event_callback; | 152 event_callback_ = event_callback; |
| 154 | 153 |
| 155 if (first_byte_position_ != kPositionNotSpecified) { | 154 if (first_byte_position_ != kPositionNotSpecified) { |
| 156 // TODO(hclam): server may not support range request so |offset_| may not | 155 // TODO(hclam): server may not support range request so |offset_| may not |
| 157 // equal to |first_byte_position_|. | 156 // equal to |first_byte_position_|. |
| 158 offset_ = first_byte_position_; | 157 offset_ = first_byte_position_; |
| 159 } | 158 } |
| 160 | 159 |
| 161 // Increment the reference count right before we start the request. This | 160 // Increment the reference count right before we start the request. This |
| 162 // reference will be release when this request has ended. | 161 // reference will be release when this request has ended. |
| (...skipping 25 matching lines...) Expand all Loading... |
| 188 WebURLLoaderOptions::CrossOriginRequestPolicyAllow; | 187 WebURLLoaderOptions::CrossOriginRequestPolicyAllow; |
| 189 url_loader_.reset(frame->createAssociatedURLLoader(options)); | 188 url_loader_.reset(frame->createAssociatedURLLoader(options)); |
| 190 } | 189 } |
| 191 | 190 |
| 192 // Start the resource loading. | 191 // Start the resource loading. |
| 193 url_loader_->loadAsynchronously(request, this); | 192 url_loader_->loadAsynchronously(request, this); |
| 194 } | 193 } |
| 195 | 194 |
| 196 void BufferedResourceLoader::Stop() { | 195 void BufferedResourceLoader::Stop() { |
| 197 // Reset callbacks. | 196 // Reset callbacks. |
| 198 start_callback_.reset(); | 197 start_callback_.Reset(); |
| 199 event_callback_.Reset(); | 198 event_callback_.Reset(); |
| 200 read_callback_.reset(); | 199 read_callback_.Reset(); |
| 201 | 200 |
| 202 // Use the internal buffer to signal that we have been stopped. | 201 // Use the internal buffer to signal that we have been stopped. |
| 203 // TODO(hclam): Not so pretty to do this. | 202 // TODO(hclam): Not so pretty to do this. |
| 204 if (!buffer_.get()) | 203 if (!buffer_.get()) |
| 205 return; | 204 return; |
| 206 | 205 |
| 207 // Destroy internal buffer. | 206 // Destroy internal buffer. |
| 208 buffer_.reset(); | 207 buffer_.reset(); |
| 209 | 208 |
| 210 if (url_loader_.get()) { | 209 if (url_loader_.get()) { |
| 211 if (deferred_) | 210 if (deferred_) |
| 212 url_loader_->setDefersLoading(false); | 211 url_loader_->setDefersLoading(false); |
| 213 deferred_ = false; | 212 deferred_ = false; |
| 214 | 213 |
| 215 if (!completed_) { | 214 if (!completed_) { |
| 216 url_loader_->cancel(); | 215 url_loader_->cancel(); |
| 217 completed_ = true; | 216 completed_ = true; |
| 218 } | 217 } |
| 219 } | 218 } |
| 220 } | 219 } |
| 221 | 220 |
| 222 void BufferedResourceLoader::Read(int64 position, | 221 void BufferedResourceLoader::Read( |
| 223 int read_size, | 222 int64 position, |
| 224 uint8* buffer, | 223 int read_size, |
| 225 net::OldCompletionCallback* read_callback) { | 224 uint8* buffer, |
| 226 DCHECK(!read_callback_.get()); | 225 const net::CompletionCallback& read_callback) { |
| 226 DCHECK(read_callback_.is_null()); |
| 227 DCHECK(buffer_.get()); | 227 DCHECK(buffer_.get()); |
| 228 DCHECK(read_callback); | 228 DCHECK(!read_callback.is_null()); |
| 229 DCHECK(buffer); | 229 DCHECK(buffer); |
| 230 DCHECK_GT(read_size, 0); | 230 DCHECK_GT(read_size, 0); |
| 231 | 231 |
| 232 // Save the parameter of reading. | 232 // Save the parameter of reading. |
| 233 read_callback_.reset(read_callback); | 233 read_callback_ = read_callback; |
| 234 read_position_ = position; | 234 read_position_ = position; |
| 235 read_size_ = read_size; | 235 read_size_ = read_size; |
| 236 read_buffer_ = buffer; | 236 read_buffer_ = buffer; |
| 237 | 237 |
| 238 // If read position is beyond the instance size, we cannot read there. | 238 // If read position is beyond the instance size, we cannot read there. |
| 239 if (instance_size_ != kPositionNotSpecified && | 239 if (instance_size_ != kPositionNotSpecified && |
| 240 instance_size_ <= read_position_) { | 240 instance_size_ <= read_position_) { |
| 241 DoneRead(0); | 241 DoneRead(0); |
| 242 return; | 242 return; |
| 243 } | 243 } |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 340 | 340 |
| 341 ///////////////////////////////////////////////////////////////////////////// | 341 ///////////////////////////////////////////////////////////////////////////// |
| 342 // WebKit::WebURLLoaderClient implementation. | 342 // WebKit::WebURLLoaderClient implementation. |
| 343 void BufferedResourceLoader::willSendRequest( | 343 void BufferedResourceLoader::willSendRequest( |
| 344 WebURLLoader* loader, | 344 WebURLLoader* loader, |
| 345 WebURLRequest& newRequest, | 345 WebURLRequest& newRequest, |
| 346 const WebURLResponse& redirectResponse) { | 346 const WebURLResponse& redirectResponse) { |
| 347 | 347 |
| 348 // The load may have been stopped and |start_callback| is destroyed. | 348 // The load may have been stopped and |start_callback| is destroyed. |
| 349 // In this case we shouldn't do anything. | 349 // In this case we shouldn't do anything. |
| 350 if (!start_callback_.get()) { | 350 if (start_callback_.is_null()) { |
| 351 // Set the url in the request to an invalid value (empty url). | 351 // Set the url in the request to an invalid value (empty url). |
| 352 newRequest.setURL(WebKit::WebURL()); | 352 newRequest.setURL(WebKit::WebURL()); |
| 353 return; | 353 return; |
| 354 } | 354 } |
| 355 | 355 |
| 356 // Only allow |single_origin_| if we haven't seen a different origin yet. | 356 // Only allow |single_origin_| if we haven't seen a different origin yet. |
| 357 if (single_origin_) | 357 if (single_origin_) |
| 358 single_origin_ = url_.GetOrigin() == GURL(newRequest.url()).GetOrigin(); | 358 single_origin_ = url_.GetOrigin() == GURL(newRequest.url()).GetOrigin(); |
| 359 | 359 |
| 360 url_ = newRequest.url(); | 360 url_ = newRequest.url(); |
| 361 } | 361 } |
| 362 | 362 |
| 363 void BufferedResourceLoader::didSendData( | 363 void BufferedResourceLoader::didSendData( |
| 364 WebURLLoader* loader, | 364 WebURLLoader* loader, |
| 365 unsigned long long bytes_sent, | 365 unsigned long long bytes_sent, |
| 366 unsigned long long total_bytes_to_be_sent) { | 366 unsigned long long total_bytes_to_be_sent) { |
| 367 NOTIMPLEMENTED(); | 367 NOTIMPLEMENTED(); |
| 368 } | 368 } |
| 369 | 369 |
| 370 void BufferedResourceLoader::didReceiveResponse( | 370 void BufferedResourceLoader::didReceiveResponse( |
| 371 WebURLLoader* loader, | 371 WebURLLoader* loader, |
| 372 const WebURLResponse& response) { | 372 const WebURLResponse& response) { |
| 373 VLOG(1) << "didReceiveResponse: " << response.httpStatusCode(); | 373 VLOG(1) << "didReceiveResponse: " << response.httpStatusCode(); |
| 374 | 374 |
| 375 // The loader may have been stopped and |start_callback| is destroyed. | 375 // The loader may have been stopped and |start_callback| is destroyed. |
| 376 // In this case we shouldn't do anything. | 376 // In this case we shouldn't do anything. |
| 377 if (!start_callback_.get()) | 377 if (start_callback_.is_null()) |
| 378 return; | 378 return; |
| 379 | 379 |
| 380 bool partial_response = false; | 380 bool partial_response = false; |
| 381 | 381 |
| 382 // We make a strong assumption that when we reach here we have either | 382 // We make a strong assumption that when we reach here we have either |
| 383 // received a response from HTTP/HTTPS protocol or the request was | 383 // received a response from HTTP/HTTPS protocol or the request was |
| 384 // successful (in particular range request). So we only verify the partial | 384 // successful (in particular range request). So we only verify the partial |
| 385 // response for HTTP and HTTPS protocol. | 385 // response for HTTP and HTTPS protocol. |
| 386 if (url_.SchemeIs(kHttpScheme) || url_.SchemeIs(kHttpsScheme)) { | 386 if (url_.SchemeIs(kHttpScheme) || url_.SchemeIs(kHttpsScheme)) { |
| 387 int error = net::OK; | 387 int error = net::OK; |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 487 VLOG(1) << "didFinishLoading"; | 487 VLOG(1) << "didFinishLoading"; |
| 488 | 488 |
| 489 DCHECK(!completed_); | 489 DCHECK(!completed_); |
| 490 completed_ = true; | 490 completed_ = true; |
| 491 | 491 |
| 492 // If we didn't know the |instance_size_| we do now. | 492 // If we didn't know the |instance_size_| we do now. |
| 493 if (instance_size_ == kPositionNotSpecified) { | 493 if (instance_size_ == kPositionNotSpecified) { |
| 494 instance_size_ = offset_ + buffer_->forward_bytes(); | 494 instance_size_ = offset_ + buffer_->forward_bytes(); |
| 495 } | 495 } |
| 496 | 496 |
| 497 // If there is a start callback, calls it. | 497 // If there is a start callback, run it. |
| 498 if (start_callback_.get()) { | 498 if (!start_callback_.is_null()) { |
| 499 DoneStart(net::OK); | 499 DoneStart(net::OK); |
| 500 } | 500 } |
| 501 | 501 |
| 502 // If there is a pending read but the request has ended, returns with what | 502 // If there is a pending read but the request has ended, returns with what |
| 503 // we have. | 503 // we have. |
| 504 if (HasPendingRead()) { | 504 if (HasPendingRead()) { |
| 505 // Make sure we have a valid buffer before we satisfy a read request. | 505 // Make sure we have a valid buffer before we satisfy a read request. |
| 506 DCHECK(buffer_.get()); | 506 DCHECK(buffer_.get()); |
| 507 | 507 |
| 508 // Try to fulfill with what is in the buffer. | 508 // Try to fulfill with what is in the buffer. |
| (...skipping 14 matching lines...) Expand all Loading... |
| 523 } | 523 } |
| 524 | 524 |
| 525 void BufferedResourceLoader::didFail( | 525 void BufferedResourceLoader::didFail( |
| 526 WebURLLoader* loader, | 526 WebURLLoader* loader, |
| 527 const WebURLError& error) { | 527 const WebURLError& error) { |
| 528 VLOG(1) << "didFail: " << error.reason; | 528 VLOG(1) << "didFail: " << error.reason; |
| 529 | 529 |
| 530 DCHECK(!completed_); | 530 DCHECK(!completed_); |
| 531 completed_ = true; | 531 completed_ = true; |
| 532 | 532 |
| 533 // If there is a start callback, calls it. | 533 // If there is a start callback, run it. |
| 534 if (start_callback_.get()) { | 534 if (!start_callback_.is_null()) { |
| 535 DoneStart(error.reason); | 535 DoneStart(error.reason); |
| 536 } | 536 } |
| 537 | 537 |
| 538 // If there is a pending read but the request failed, return with the | 538 // If there is a pending read but the request failed, return with the |
| 539 // reason for the error. | 539 // reason for the error. |
| 540 if (HasPendingRead()) { | 540 if (HasPendingRead()) { |
| 541 DoneRead(error.reason); | 541 DoneRead(error.reason); |
| 542 } | 542 } |
| 543 | 543 |
| 544 // Notify that network response is completed. | 544 // Notify that network response is completed. |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 616 if (deferred_) | 616 if (deferred_) |
| 617 return false; | 617 return false; |
| 618 | 618 |
| 619 switch(defer_strategy_) { | 619 switch(defer_strategy_) { |
| 620 // Never defer at all, so never enable defer. | 620 // Never defer at all, so never enable defer. |
| 621 case kNeverDefer: | 621 case kNeverDefer: |
| 622 return false; | 622 return false; |
| 623 | 623 |
| 624 // Defer if nothing is being requested. | 624 // Defer if nothing is being requested. |
| 625 case kReadThenDefer: | 625 case kReadThenDefer: |
| 626 return !read_callback_.get(); | 626 return read_callback_.is_null(); |
| 627 | 627 |
| 628 // Defer if we've reached the max capacity of the threshold. | 628 // Defer if we've reached the max capacity of the threshold. |
| 629 case kThresholdDefer: | 629 case kThresholdDefer: |
| 630 return buffer_->forward_bytes() >= buffer_->forward_capacity(); | 630 return buffer_->forward_bytes() >= buffer_->forward_capacity(); |
| 631 } | 631 } |
| 632 // Otherwise don't enable defer. | 632 // Otherwise don't enable defer. |
| 633 return false; | 633 return false; |
| 634 } | 634 } |
| 635 | 635 |
| 636 bool BufferedResourceLoader::ShouldDisableDefer() { | 636 bool BufferedResourceLoader::ShouldDisableDefer() { |
| 637 // If we're not deferring, then disabling makes no sense. | 637 // If we're not deferring, then disabling makes no sense. |
| 638 if (!deferred_) | 638 if (!deferred_) |
| 639 return false; | 639 return false; |
| 640 | 640 |
| 641 switch(defer_strategy_) { | 641 switch(defer_strategy_) { |
| 642 // Always disable deferring. | 642 // Always disable deferring. |
| 643 case kNeverDefer: | 643 case kNeverDefer: |
| 644 return true; | 644 return true; |
| 645 | 645 |
| 646 // We have an outstanding read request, and we have not buffered enough | 646 // We have an outstanding read request, and we have not buffered enough |
| 647 // yet to fulfill the request; disable defer to get more data. | 647 // yet to fulfill the request; disable defer to get more data. |
| 648 case kReadThenDefer: | 648 case kReadThenDefer: |
| 649 return read_callback_.get() && | 649 return !read_callback_.is_null() && |
| 650 last_offset_ > static_cast<int>(buffer_->forward_bytes()); | 650 last_offset_ > static_cast<int>(buffer_->forward_bytes()); |
| 651 | 651 |
| 652 // We have less than half the capacity of our threshold, so | 652 // We have less than half the capacity of our threshold, so |
| 653 // disable defer to get more data. | 653 // disable defer to get more data. |
| 654 case kThresholdDefer: { | 654 case kThresholdDefer: { |
| 655 size_t amount_buffered = buffer_->forward_bytes(); | 655 size_t amount_buffered = buffer_->forward_bytes(); |
| 656 size_t half_capacity = buffer_->forward_capacity() / 2; | 656 size_t half_capacity = buffer_->forward_capacity() / 2; |
| 657 return amount_buffered < half_capacity; | 657 return amount_buffered < half_capacity; |
| 658 } | 658 } |
| 659 } | 659 } |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 757 } else if (first_byte_position > kPositionNotSpecified) { | 757 } else if (first_byte_position > kPositionNotSpecified) { |
| 758 header = base::StringPrintf("bytes=%" PRId64 "-", | 758 header = base::StringPrintf("bytes=%" PRId64 "-", |
| 759 first_byte_position); | 759 first_byte_position); |
| 760 } else if (last_byte_position > kPositionNotSpecified) { | 760 } else if (last_byte_position > kPositionNotSpecified) { |
| 761 NOTIMPLEMENTED() << "Suffix range not implemented"; | 761 NOTIMPLEMENTED() << "Suffix range not implemented"; |
| 762 } | 762 } |
| 763 return header; | 763 return header; |
| 764 } | 764 } |
| 765 | 765 |
| 766 void BufferedResourceLoader::DoneRead(int error) { | 766 void BufferedResourceLoader::DoneRead(int error) { |
| 767 read_callback_->RunWithParams(Tuple1<int>(error)); | 767 read_callback_.Run(error); |
| 768 read_callback_.reset(); | 768 read_callback_.Reset(); |
| 769 if (buffer_.get() && saved_forward_capacity_) { | 769 if (buffer_.get() && saved_forward_capacity_) { |
| 770 buffer_->set_forward_capacity(saved_forward_capacity_); | 770 buffer_->set_forward_capacity(saved_forward_capacity_); |
| 771 saved_forward_capacity_ = 0; | 771 saved_forward_capacity_ = 0; |
| 772 } | 772 } |
| 773 read_position_ = 0; | 773 read_position_ = 0; |
| 774 read_size_ = 0; | 774 read_size_ = 0; |
| 775 read_buffer_ = NULL; | 775 read_buffer_ = NULL; |
| 776 first_offset_ = 0; | 776 first_offset_ = 0; |
| 777 last_offset_ = 0; | 777 last_offset_ = 0; |
| 778 Log(); | 778 Log(); |
| 779 } | 779 } |
| 780 | 780 |
| 781 void BufferedResourceLoader::DoneStart(int error) { | 781 void BufferedResourceLoader::DoneStart(int error) { |
| 782 start_callback_->RunWithParams(Tuple1<int>(error)); | 782 start_callback_.Run(error); |
| 783 start_callback_.reset(); | 783 start_callback_.Reset(); |
| 784 } | 784 } |
| 785 | 785 |
| 786 void BufferedResourceLoader::NotifyNetworkEvent() { | 786 void BufferedResourceLoader::NotifyNetworkEvent() { |
| 787 if (!event_callback_.is_null()) | 787 if (!event_callback_.is_null()) |
| 788 event_callback_.Run(); | 788 event_callback_.Run(); |
| 789 } | 789 } |
| 790 | 790 |
| 791 bool BufferedResourceLoader::IsRangeRequest() const { | 791 bool BufferedResourceLoader::IsRangeRequest() const { |
| 792 return first_byte_position_ != kPositionNotSpecified; | 792 return first_byte_position_ != kPositionNotSpecified; |
| 793 } | 793 } |
| 794 | 794 |
| 795 void BufferedResourceLoader::Log() { | 795 void BufferedResourceLoader::Log() { |
| 796 if (buffer_.get()) { | 796 if (buffer_.get()) { |
| 797 media_log_->AddEvent( | 797 media_log_->AddEvent( |
| 798 media_log_->CreateBufferedExtentsChangedEvent( | 798 media_log_->CreateBufferedExtentsChangedEvent( |
| 799 offset_ - buffer_->backward_bytes(), | 799 offset_ - buffer_->backward_bytes(), |
| 800 offset_, | 800 offset_, |
| 801 offset_ + buffer_->forward_bytes())); | 801 offset_ + buffer_->forward_bytes())); |
| 802 } | 802 } |
| 803 } | 803 } |
| 804 | 804 |
| 805 } // namespace webkit_media | 805 } // namespace webkit_media |
| OLD | NEW |