| 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 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 86 *out_backward_capacity = std::max( | 86 *out_backward_capacity = std::max( |
| 87 kTargetSecondsBufferedBehind * bytes_per_second, kMinBufferCapacity); | 87 kTargetSecondsBufferedBehind * bytes_per_second, kMinBufferCapacity); |
| 88 | 88 |
| 89 *out_forward_capacity = std::min(*out_forward_capacity, kMaxBufferCapacity); | 89 *out_forward_capacity = std::min(*out_forward_capacity, kMaxBufferCapacity); |
| 90 *out_backward_capacity = std::min(*out_backward_capacity, kMaxBufferCapacity); | 90 *out_backward_capacity = std::min(*out_backward_capacity, kMaxBufferCapacity); |
| 91 | 91 |
| 92 if (backward_playback) | 92 if (backward_playback) |
| 93 std::swap(*out_forward_capacity, *out_backward_capacity); | 93 std::swap(*out_forward_capacity, *out_backward_capacity); |
| 94 } | 94 } |
| 95 | 95 |
| 96 | |
| 97 BufferedResourceLoader::BufferedResourceLoader( | 96 BufferedResourceLoader::BufferedResourceLoader( |
| 98 const GURL& url, | 97 const GURL& url, |
| 99 int64 first_byte_position, | 98 int64 first_byte_position, |
| 100 int64 last_byte_position, | 99 int64 last_byte_position, |
| 101 DeferStrategy strategy, | 100 DeferStrategy strategy, |
| 102 int bitrate, | 101 int bitrate, |
| 103 float playback_rate, | 102 float playback_rate, |
| 104 media::MediaLog* media_log) | 103 media::MediaLog* media_log) |
| 105 : deferred_(false), | 104 : defer_strategy_(strategy), |
| 106 defer_strategy_(strategy), | |
| 107 completed_(false), | |
| 108 range_requested_(false), | 105 range_requested_(false), |
| 109 range_supported_(false), | 106 range_supported_(false), |
| 110 saved_forward_capacity_(0), | 107 saved_forward_capacity_(0), |
| 111 url_(url), | 108 url_(url), |
| 112 first_byte_position_(first_byte_position), | 109 first_byte_position_(first_byte_position), |
| 113 last_byte_position_(last_byte_position), | 110 last_byte_position_(last_byte_position), |
| 114 single_origin_(true), | 111 single_origin_(true), |
| 115 start_callback_(NULL), | 112 start_callback_(NULL), |
| 116 offset_(0), | 113 offset_(0), |
| 117 content_length_(kPositionNotSpecified), | 114 content_length_(kPositionNotSpecified), |
| 118 instance_size_(kPositionNotSpecified), | 115 instance_size_(kPositionNotSpecified), |
| 119 read_callback_(NULL), | 116 read_callback_(NULL), |
| 120 read_position_(0), | 117 read_position_(0), |
| 121 read_size_(0), | 118 read_size_(0), |
| 122 read_buffer_(NULL), | 119 read_buffer_(NULL), |
| 123 first_offset_(0), | 120 first_offset_(0), |
| 124 last_offset_(0), | 121 last_offset_(0), |
| 125 keep_test_loader_(false), | |
| 126 bitrate_(bitrate), | 122 bitrate_(bitrate), |
| 127 playback_rate_(playback_rate), | 123 playback_rate_(playback_rate), |
| 128 media_log_(media_log) { | 124 media_log_(media_log) { |
| 129 | 125 |
| 130 size_t backward_capacity; | 126 size_t backward_capacity; |
| 131 size_t forward_capacity; | 127 size_t forward_capacity; |
| 132 ComputeTargetBufferWindow( | 128 ComputeTargetBufferWindow( |
| 133 playback_rate_, bitrate_, &backward_capacity, &forward_capacity); | 129 playback_rate_, bitrate_, &backward_capacity, &forward_capacity); |
| 134 buffer_.reset(new media::SeekableBuffer(backward_capacity, forward_capacity)); | 130 buffer_.reset(new media::SeekableBuffer(backward_capacity, forward_capacity)); |
| 135 } | 131 } |
| 136 | 132 |
| 137 BufferedResourceLoader::~BufferedResourceLoader() { | 133 BufferedResourceLoader::~BufferedResourceLoader() {} |
| 138 if (!completed_ && url_loader_.get()) | |
| 139 url_loader_->cancel(); | |
| 140 } | |
| 141 | 134 |
| 142 void BufferedResourceLoader::Start(net::OldCompletionCallback* start_callback, | 135 void BufferedResourceLoader::Start(net::OldCompletionCallback* start_callback, |
| 143 const base::Closure& event_callback, | 136 const base::Closure& event_callback, |
| 144 WebFrame* frame) { | 137 WebFrame* frame) { |
| 145 // Make sure we have not started. | 138 // Make sure we have not started. |
| 146 DCHECK(!start_callback_.get()); | 139 DCHECK(!start_callback_.get()); |
| 147 DCHECK(event_callback_.is_null()); | 140 DCHECK(event_callback_.is_null()); |
| 148 DCHECK(start_callback); | 141 DCHECK(start_callback); |
| 149 DCHECK(!event_callback.is_null()); | 142 DCHECK(!event_callback.is_null()); |
| 150 CHECK(frame); | 143 CHECK(frame); |
| 151 | 144 |
| 152 start_callback_.reset(start_callback); | 145 start_callback_.reset(start_callback); |
| 153 event_callback_ = event_callback; | 146 event_callback_ = event_callback; |
| 154 | 147 |
| 155 if (first_byte_position_ != kPositionNotSpecified) { | 148 if (first_byte_position_ != kPositionNotSpecified) { |
| 156 // TODO(hclam): server may not support range request so |offset_| may not | 149 // TODO(hclam): server may not support range request so |offset_| may not |
| 157 // equal to |first_byte_position_|. | 150 // equal to |first_byte_position_|. |
| 158 offset_ = first_byte_position_; | 151 offset_ = first_byte_position_; |
| 159 } | 152 } |
| 160 | 153 |
| 161 // Increment the reference count right before we start the request. This | |
| 162 // reference will be release when this request has ended. | |
| 163 AddRef(); | |
| 164 | |
| 165 // Prepare the request. | 154 // Prepare the request. |
| 166 WebURLRequest request(url_); | 155 WebURLRequest request(url_); |
| 167 request.setTargetType(WebURLRequest::TargetIsMedia); | 156 request.setTargetType(WebURLRequest::TargetIsMedia); |
| 168 | 157 |
| 169 if (IsRangeRequest()) { | 158 if (IsRangeRequest()) { |
| 170 range_requested_ = true; | 159 range_requested_ = true; |
| 171 request.setHTTPHeaderField( | 160 request.setHTTPHeaderField( |
| 172 WebString::fromUTF8(net::HttpRequestHeaders::kRange), | 161 WebString::fromUTF8(net::HttpRequestHeaders::kRange), |
| 173 WebString::fromUTF8(GenerateHeaders(first_byte_position_, | 162 WebString::fromUTF8(GenerateHeaders(first_byte_position_, |
| 174 last_byte_position_))); | 163 last_byte_position_))); |
| 175 } | 164 } |
| 176 frame->setReferrerForRequest(request, WebKit::WebURL()); | 165 frame->setReferrerForRequest(request, WebKit::WebURL()); |
| 177 | 166 |
| 178 // Disable compression, compression for audio/video doesn't make sense... | 167 // Disable compression, compression for audio/video doesn't make sense... |
| 179 request.setHTTPHeaderField( | 168 request.setHTTPHeaderField( |
| 180 WebString::fromUTF8(net::HttpRequestHeaders::kAcceptEncoding), | 169 WebString::fromUTF8(net::HttpRequestHeaders::kAcceptEncoding), |
| 181 WebString::fromUTF8("identity;q=1, *;q=0")); | 170 WebString::fromUTF8("identity;q=1, *;q=0")); |
| 182 | 171 |
| 183 // This flag is for unittests as we don't want to reset |url_loader| | 172 // Check for our test WebURLLoader. |
| 184 if (!keep_test_loader_) { | 173 WebURLLoader* loader = NULL; |
| 174 if (test_loader_.get()) { |
| 175 loader = test_loader_.release(); |
| 176 } else { |
| 185 WebURLLoaderOptions options; | 177 WebURLLoaderOptions options; |
| 186 options.allowCredentials = true; | 178 options.allowCredentials = true; |
| 187 options.crossOriginRequestPolicy = | 179 options.crossOriginRequestPolicy = |
| 188 WebURLLoaderOptions::CrossOriginRequestPolicyAllow; | 180 WebURLLoaderOptions::CrossOriginRequestPolicyAllow; |
| 189 url_loader_.reset(frame->createAssociatedURLLoader(options)); | 181 loader = frame->createAssociatedURLLoader(options); |
| 190 } | 182 } |
| 191 | 183 |
| 192 // Start the resource loading. | 184 // Start the resource loading. |
| 193 url_loader_->loadAsynchronously(request, this); | 185 loader->loadAsynchronously(request, this); |
| 186 active_loader_.reset(new ActiveLoader(this, loader)); |
| 194 } | 187 } |
| 195 | 188 |
| 196 void BufferedResourceLoader::Stop() { | 189 void BufferedResourceLoader::Stop() { |
| 197 // Reset callbacks. | 190 // Reset callbacks. |
| 198 start_callback_.reset(); | 191 start_callback_.reset(); |
| 199 event_callback_.Reset(); | 192 event_callback_.Reset(); |
| 200 read_callback_.reset(); | 193 read_callback_.reset(); |
| 201 | 194 |
| 202 // Use the internal buffer to signal that we have been stopped. | 195 // Use the internal buffer to signal that we have been stopped. |
| 203 // TODO(hclam): Not so pretty to do this. | 196 // TODO(hclam): Not so pretty to do this. |
| 204 if (!buffer_.get()) | 197 if (!buffer_.get()) |
| 205 return; | 198 return; |
| 206 | 199 |
| 207 // Destroy internal buffer. | 200 // Destroy internal buffer. |
| 208 buffer_.reset(); | 201 buffer_.reset(); |
| 209 | 202 |
| 210 if (url_loader_.get()) { | 203 // Cancel and reset any active loaders. |
| 211 if (deferred_) | 204 active_loader_.reset(); |
| 212 url_loader_->setDefersLoading(false); | |
| 213 deferred_ = false; | |
| 214 | |
| 215 if (!completed_) { | |
| 216 url_loader_->cancel(); | |
| 217 completed_ = true; | |
| 218 } | |
| 219 } | |
| 220 } | 205 } |
| 221 | 206 |
| 222 void BufferedResourceLoader::Read(int64 position, | 207 void BufferedResourceLoader::Read(int64 position, |
| 223 int read_size, | 208 int read_size, |
| 224 uint8* buffer, | 209 uint8* buffer, |
| 225 net::OldCompletionCallback* read_callback) { | 210 net::OldCompletionCallback* read_callback) { |
| 211 DCHECK(!start_callback_.get()); |
| 226 DCHECK(!read_callback_.get()); | 212 DCHECK(!read_callback_.get()); |
| 227 DCHECK(buffer_.get()); | 213 DCHECK(buffer_.get()); |
| 228 DCHECK(read_callback); | 214 DCHECK(read_callback); |
| 229 DCHECK(buffer); | 215 DCHECK(buffer); |
| 230 DCHECK_GT(read_size, 0); | 216 DCHECK_GT(read_size, 0); |
| 231 | 217 |
| 232 // Save the parameter of reading. | 218 // Save the parameter of reading. |
| 233 read_callback_.reset(read_callback); | 219 read_callback_.reset(read_callback); |
| 234 read_position_ = position; | 220 read_position_ = position; |
| 235 read_size_ = read_size; | 221 read_size_ = read_size; |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 285 // capacity. | 271 // capacity. |
| 286 // | 272 // |
| 287 // This can happen when reading in a large seek index or when the | 273 // This can happen when reading in a large seek index or when the |
| 288 // first byte of a read request falls within kForwardWaitThreshold. | 274 // first byte of a read request falls within kForwardWaitThreshold. |
| 289 if (last_offset_ > static_cast<int>(buffer_->forward_capacity())) { | 275 if (last_offset_ > static_cast<int>(buffer_->forward_capacity())) { |
| 290 saved_forward_capacity_ = buffer_->forward_capacity(); | 276 saved_forward_capacity_ = buffer_->forward_capacity(); |
| 291 buffer_->set_forward_capacity(last_offset_); | 277 buffer_->set_forward_capacity(last_offset_); |
| 292 } | 278 } |
| 293 | 279 |
| 294 // Make sure we stop deferring now that there's additional capacity. | 280 // Make sure we stop deferring now that there's additional capacity. |
| 295 // | 281 if (active_loader_->deferred()) |
| 296 // XXX: can we DCHECK(url_loader_.get()) at this point in time? | |
| 297 if (deferred_) | |
| 298 SetDeferred(false); | 282 SetDeferred(false); |
| 299 | 283 |
| 300 DCHECK(!ShouldEnableDefer()) | 284 DCHECK(!ShouldEnableDefer()) |
| 301 << "Capacity was not adjusted properly to prevent deferring."; | 285 << "Capacity was not adjusted properly to prevent deferring."; |
| 302 | 286 |
| 303 return; | 287 return; |
| 304 } | 288 } |
| 305 | 289 |
| 306 // Make a callback to report failure. | 290 // Make a callback to report failure. |
| 307 DoneRead(net::ERR_CACHE_MISS); | 291 DoneRead(net::ERR_CACHE_MISS); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 319 | 303 |
| 320 int64 BufferedResourceLoader::instance_size() { | 304 int64 BufferedResourceLoader::instance_size() { |
| 321 return instance_size_; | 305 return instance_size_; |
| 322 } | 306 } |
| 323 | 307 |
| 324 bool BufferedResourceLoader::range_supported() { | 308 bool BufferedResourceLoader::range_supported() { |
| 325 return range_supported_; | 309 return range_supported_; |
| 326 } | 310 } |
| 327 | 311 |
| 328 bool BufferedResourceLoader::is_downloading_data() { | 312 bool BufferedResourceLoader::is_downloading_data() { |
| 329 return !completed_ && !deferred_; | 313 return active_loader_.get() && !active_loader_->deferred(); |
| 330 } | 314 } |
| 331 | 315 |
| 332 const GURL& BufferedResourceLoader::url() { | 316 const GURL& BufferedResourceLoader::url() { |
| 333 return url_; | 317 return url_; |
| 334 } | 318 } |
| 335 | 319 |
| 336 void BufferedResourceLoader::SetURLLoaderForTest(WebURLLoader* mock_loader) { | 320 void BufferedResourceLoader::SetURLLoaderForTest(WebURLLoader* test_loader) { |
| 337 url_loader_.reset(mock_loader); | 321 test_loader_.reset(test_loader); |
| 338 keep_test_loader_ = true; | |
| 339 } | 322 } |
| 340 | 323 |
| 341 ///////////////////////////////////////////////////////////////////////////// | 324 ///////////////////////////////////////////////////////////////////////////// |
| 342 // WebKit::WebURLLoaderClient implementation. | 325 // WebKit::WebURLLoaderClient implementation. |
| 343 void BufferedResourceLoader::willSendRequest( | 326 void BufferedResourceLoader::willSendRequest( |
| 344 WebURLLoader* loader, | 327 WebURLLoader* loader, |
| 345 WebURLRequest& newRequest, | 328 WebURLRequest& newRequest, |
| 346 const WebURLResponse& redirectResponse) { | 329 const WebURLResponse& redirectResponse) { |
| 347 | 330 |
| 348 // The load may have been stopped and |start_callback| is destroyed. | 331 // The load may have been stopped and |start_callback| is destroyed. |
| (...skipping 15 matching lines...) Expand all Loading... |
| 364 WebURLLoader* loader, | 347 WebURLLoader* loader, |
| 365 unsigned long long bytes_sent, | 348 unsigned long long bytes_sent, |
| 366 unsigned long long total_bytes_to_be_sent) { | 349 unsigned long long total_bytes_to_be_sent) { |
| 367 NOTIMPLEMENTED(); | 350 NOTIMPLEMENTED(); |
| 368 } | 351 } |
| 369 | 352 |
| 370 void BufferedResourceLoader::didReceiveResponse( | 353 void BufferedResourceLoader::didReceiveResponse( |
| 371 WebURLLoader* loader, | 354 WebURLLoader* loader, |
| 372 const WebURLResponse& response) { | 355 const WebURLResponse& response) { |
| 373 VLOG(1) << "didReceiveResponse: " << response.httpStatusCode(); | 356 VLOG(1) << "didReceiveResponse: " << response.httpStatusCode(); |
| 357 DCHECK(active_loader_.get()); |
| 374 | 358 |
| 375 // The loader may have been stopped and |start_callback| is destroyed. | 359 // The loader may have been stopped and |start_callback| is destroyed. |
| 376 // In this case we shouldn't do anything. | 360 // In this case we shouldn't do anything. |
| 377 if (!start_callback_.get()) | 361 if (!start_callback_.get()) |
| 378 return; | 362 return; |
| 379 | 363 |
| 380 bool partial_response = false; | 364 bool partial_response = false; |
| 381 | 365 |
| 382 // We make a strong assumption that when we reach here we have either | 366 // 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 | 367 // received a response from HTTP/HTTPS protocol or the request was |
| (...skipping 17 matching lines...) Expand all Loading... |
| 401 range_supported_ = true; | 385 range_supported_ = true; |
| 402 else | 386 else |
| 403 error = net::ERR_INVALID_RESPONSE; | 387 error = net::ERR_INVALID_RESPONSE; |
| 404 } else if (response.httpStatusCode() != kHttpOK) { | 388 } else if (response.httpStatusCode() != kHttpOK) { |
| 405 // We didn't request a range but server didn't reply with "200 OK". | 389 // We didn't request a range but server didn't reply with "200 OK". |
| 406 error = net::ERR_FAILED; | 390 error = net::ERR_FAILED; |
| 407 } | 391 } |
| 408 | 392 |
| 409 if (error != net::OK) { | 393 if (error != net::OK) { |
| 410 DoneStart(error); | 394 DoneStart(error); |
| 411 Stop(); | |
| 412 return; | 395 return; |
| 413 } | 396 } |
| 414 } else { | 397 } else { |
| 415 // For any protocol other than HTTP and HTTPS, assume range request is | 398 // For any protocol other than HTTP and HTTPS, assume range request is |
| 416 // always fulfilled. | 399 // always fulfilled. |
| 417 partial_response = range_requested_; | 400 partial_response = range_requested_; |
| 418 } | 401 } |
| 419 | 402 |
| 420 // Expected content length can be |kPositionNotSpecified|, in that case | 403 // Expected content length can be |kPositionNotSpecified|, in that case |
| 421 // |content_length_| is not specified and this is a streaming response. | 404 // |content_length_| is not specified and this is a streaming response. |
| 422 content_length_ = response.expectedContentLength(); | 405 content_length_ = response.expectedContentLength(); |
| 423 | 406 |
| 424 // If we have not requested a range, then the size of the instance is equal | 407 // If we have not requested a range, then the size of the instance is equal |
| 425 // to the content length. | 408 // to the content length. |
| 426 if (!partial_response) | 409 if (!partial_response) |
| 427 instance_size_ = content_length_; | 410 instance_size_ = content_length_; |
| 428 | 411 |
| 429 // Calls with a successful response. | 412 // Calls with a successful response. |
| 430 DoneStart(net::OK); | 413 DoneStart(net::OK); |
| 431 } | 414 } |
| 432 | 415 |
| 433 void BufferedResourceLoader::didReceiveData( | 416 void BufferedResourceLoader::didReceiveData( |
| 434 WebURLLoader* loader, | 417 WebURLLoader* loader, |
| 435 const char* data, | 418 const char* data, |
| 436 int data_length, | 419 int data_length, |
| 437 int encoded_data_length) { | 420 int encoded_data_length) { |
| 438 VLOG(1) << "didReceiveData: " << data_length << " bytes"; | 421 VLOG(1) << "didReceiveData: " << data_length << " bytes"; |
| 439 | 422 DCHECK(active_loader_.get()); |
| 440 DCHECK(!completed_); | |
| 441 DCHECK_GT(data_length, 0); | 423 DCHECK_GT(data_length, 0); |
| 442 | 424 |
| 443 // If this loader has been stopped, |buffer_| would be destroyed. | 425 // If this loader has been stopped, |buffer_| would be destroyed. |
| 444 // In this case we shouldn't do anything. | 426 // In this case we shouldn't do anything. |
| 445 if (!buffer_.get()) | 427 if (!buffer_.get()) |
| 446 return; | 428 return; |
| 447 | 429 |
| 448 // Writes more data to |buffer_|. | 430 // Writes more data to |buffer_|. |
| 449 buffer_->Append(reinterpret_cast<const uint8*>(data), data_length); | 431 buffer_->Append(reinterpret_cast<const uint8*>(data), data_length); |
| 450 | 432 |
| (...skipping 27 matching lines...) Expand all Loading... |
| 478 WebURLLoader* loader, | 460 WebURLLoader* loader, |
| 479 const char* data, | 461 const char* data, |
| 480 int data_length) { | 462 int data_length) { |
| 481 NOTIMPLEMENTED(); | 463 NOTIMPLEMENTED(); |
| 482 } | 464 } |
| 483 | 465 |
| 484 void BufferedResourceLoader::didFinishLoading( | 466 void BufferedResourceLoader::didFinishLoading( |
| 485 WebURLLoader* loader, | 467 WebURLLoader* loader, |
| 486 double finishTime) { | 468 double finishTime) { |
| 487 VLOG(1) << "didFinishLoading"; | 469 VLOG(1) << "didFinishLoading"; |
| 470 DCHECK(active_loader_.get()); |
| 488 | 471 |
| 489 DCHECK(!completed_); | 472 // We're done with the loader. |
| 490 completed_ = true; | 473 active_loader_.reset(); |
| 474 NotifyNetworkEvent(); |
| 491 | 475 |
| 492 // If we didn't know the |instance_size_| we do now. | 476 // If we didn't know the |instance_size_| we do now. |
| 493 if (instance_size_ == kPositionNotSpecified) { | 477 if (instance_size_ == kPositionNotSpecified) { |
| 494 instance_size_ = offset_ + buffer_->forward_bytes(); | 478 instance_size_ = offset_ + buffer_->forward_bytes(); |
| 495 } | 479 } |
| 496 | 480 |
| 497 // If there is a start callback, calls it. | 481 // If there is a start callback, call it. |
| 498 if (start_callback_.get()) { | 482 if (start_callback_.get()) { |
| 483 DCHECK(read_callback_.get()) |
| 484 << "Shouldn't have a read callback during start"; |
| 499 DoneStart(net::OK); | 485 DoneStart(net::OK); |
| 486 return; |
| 500 } | 487 } |
| 501 | 488 |
| 502 // If there is a pending read but the request has ended, returns with what | 489 // If there is a pending read but the request has ended, return with what |
| 503 // we have. | 490 // we have. |
| 504 if (HasPendingRead()) { | 491 if (HasPendingRead()) { |
| 505 // Make sure we have a valid buffer before we satisfy a read request. | 492 // Make sure we have a valid buffer before we satisfy a read request. |
| 506 DCHECK(buffer_.get()); | 493 DCHECK(buffer_.get()); |
| 507 | 494 |
| 508 // Try to fulfill with what is in the buffer. | 495 // Try to fulfill with what is in the buffer. |
| 509 if (CanFulfillRead()) | 496 if (CanFulfillRead()) |
| 510 ReadInternal(); | 497 ReadInternal(); |
| 511 else | 498 else |
| 512 DoneRead(net::ERR_CACHE_MISS); | 499 DoneRead(net::ERR_CACHE_MISS); |
| 513 } | 500 } |
| 514 | 501 |
| 515 // There must not be any outstanding read request. | 502 // There must not be any outstanding read request. |
| 516 DCHECK(!HasPendingRead()); | 503 DCHECK(!HasPendingRead()); |
| 517 | |
| 518 // Notify that network response is completed. | |
| 519 NotifyNetworkEvent(); | |
| 520 | |
| 521 url_loader_.reset(); | |
| 522 Release(); | |
| 523 } | 504 } |
| 524 | 505 |
| 525 void BufferedResourceLoader::didFail( | 506 void BufferedResourceLoader::didFail( |
| 526 WebURLLoader* loader, | 507 WebURLLoader* loader, |
| 527 const WebURLError& error) { | 508 const WebURLError& error) { |
| 528 VLOG(1) << "didFail: " << error.reason; | 509 VLOG(1) << "didFail: " << error.reason; |
| 510 DCHECK(active_loader_.get()); |
| 529 | 511 |
| 530 DCHECK(!completed_); | 512 // We don't need to continue loading after failure. |
| 531 completed_ = true; | 513 active_loader_->Cancel(); |
| 514 NotifyNetworkEvent(); |
| 532 | 515 |
| 533 // If there is a start callback, calls it. | 516 // Don't leave start callbacks hanging around. |
| 534 if (start_callback_.get()) { | 517 if (start_callback_.get()) { |
| 518 DCHECK(read_callback_.get()) |
| 519 << "Shouldn't have a read callback during start"; |
| 535 DoneStart(error.reason); | 520 DoneStart(error.reason); |
| 521 return; |
| 536 } | 522 } |
| 537 | 523 |
| 538 // If there is a pending read but the request failed, return with the | 524 // Don't leave read callbacks hanging around. |
| 539 // reason for the error. | |
| 540 if (HasPendingRead()) { | 525 if (HasPendingRead()) { |
| 541 DoneRead(error.reason); | 526 DoneRead(error.reason); |
| 542 } | 527 } |
| 543 | |
| 544 // Notify that network response is completed. | |
| 545 NotifyNetworkEvent(); | |
| 546 | |
| 547 url_loader_.reset(); | |
| 548 Release(); | |
| 549 } | 528 } |
| 550 | 529 |
| 551 bool BufferedResourceLoader::HasSingleOrigin() const { | 530 bool BufferedResourceLoader::HasSingleOrigin() const { |
| 552 return single_origin_; | 531 return single_origin_; |
| 553 } | 532 } |
| 554 | 533 |
| 555 void BufferedResourceLoader::UpdateDeferStrategy(DeferStrategy strategy) { | 534 void BufferedResourceLoader::UpdateDeferStrategy(DeferStrategy strategy) { |
| 556 defer_strategy_ = strategy; | 535 defer_strategy_ = strategy; |
| 557 UpdateDeferBehavior(); | 536 UpdateDeferBehavior(); |
| 558 } | 537 } |
| (...skipping 28 matching lines...) Expand all Loading... |
| 587 playback_rate_, bitrate_, &backward_capacity, &forward_capacity); | 566 playback_rate_, bitrate_, &backward_capacity, &forward_capacity); |
| 588 | 567 |
| 589 // This does not evict data from the buffer if the new capacities are less | 568 // This does not evict data from the buffer if the new capacities are less |
| 590 // than the current capacities; the new limits will be enforced after the | 569 // than the current capacities; the new limits will be enforced after the |
| 591 // existing excess buffered data is consumed. | 570 // existing excess buffered data is consumed. |
| 592 buffer_->set_backward_capacity(backward_capacity); | 571 buffer_->set_backward_capacity(backward_capacity); |
| 593 buffer_->set_forward_capacity(forward_capacity); | 572 buffer_->set_forward_capacity(forward_capacity); |
| 594 } | 573 } |
| 595 | 574 |
| 596 void BufferedResourceLoader::UpdateDeferBehavior() { | 575 void BufferedResourceLoader::UpdateDeferBehavior() { |
| 597 if (!url_loader_.get() || !buffer_.get()) | 576 if (!active_loader_.get() || !buffer_.get()) |
| 598 return; | 577 return; |
| 599 | 578 |
| 600 // If necessary, toggle defer state and continue/pause downloading data | 579 // If necessary, toggle defer state and continue/pause downloading data |
| 601 // accordingly. | 580 // accordingly. |
| 602 if (ShouldEnableDefer() || ShouldDisableDefer()) | 581 if (ShouldEnableDefer() || ShouldDisableDefer()) |
| 603 SetDeferred(!deferred_); | 582 SetDeferred(!active_loader_->deferred()); |
| 604 } | 583 } |
| 605 | 584 |
| 606 void BufferedResourceLoader::SetDeferred(bool deferred) { | 585 void BufferedResourceLoader::SetDeferred(bool deferred) { |
| 607 deferred_ = deferred; | 586 active_loader_->SetDeferred(deferred); |
| 608 if (url_loader_.get()) { | 587 NotifyNetworkEvent(); |
| 609 url_loader_->setDefersLoading(deferred); | |
| 610 NotifyNetworkEvent(); | |
| 611 } | |
| 612 } | 588 } |
| 613 | 589 |
| 614 bool BufferedResourceLoader::ShouldEnableDefer() { | 590 bool BufferedResourceLoader::ShouldEnableDefer() const { |
| 615 // If we're already deferring, then enabling makes no sense. | 591 // If we're already deferring, then enabling makes no sense. |
| 616 if (deferred_) | 592 if (active_loader_->deferred()) |
| 617 return false; | 593 return false; |
| 618 | 594 |
| 619 switch(defer_strategy_) { | 595 switch(defer_strategy_) { |
| 620 // Never defer at all, so never enable defer. | 596 // Never defer at all, so never enable defer. |
| 621 case kNeverDefer: | 597 case kNeverDefer: |
| 622 return false; | 598 return false; |
| 623 | 599 |
| 624 // Defer if nothing is being requested. | 600 // Defer if nothing is being requested. |
| 625 case kReadThenDefer: | 601 case kReadThenDefer: |
| 626 return !read_callback_.get(); | 602 return !read_callback_.get(); |
| 627 | 603 |
| 628 // Defer if we've reached the max capacity of the threshold. | 604 // Defer if we've reached the max capacity of the threshold. |
| 629 case kThresholdDefer: | 605 case kThresholdDefer: |
| 630 return buffer_->forward_bytes() >= buffer_->forward_capacity(); | 606 return buffer_->forward_bytes() >= buffer_->forward_capacity(); |
| 631 } | 607 } |
| 632 // Otherwise don't enable defer. | 608 // Otherwise don't enable defer. |
| 633 return false; | 609 return false; |
| 634 } | 610 } |
| 635 | 611 |
| 636 bool BufferedResourceLoader::ShouldDisableDefer() { | 612 bool BufferedResourceLoader::ShouldDisableDefer() const { |
| 637 // If we're not deferring, then disabling makes no sense. | 613 // If we're not deferring, then disabling makes no sense. |
| 638 if (!deferred_) | 614 if (!active_loader_->deferred()) |
| 639 return false; | 615 return false; |
| 640 | 616 |
| 641 switch(defer_strategy_) { | 617 switch(defer_strategy_) { |
| 642 // Always disable deferring. | 618 // Always disable deferring. |
| 643 case kNeverDefer: | 619 case kNeverDefer: |
| 644 return true; | 620 return true; |
| 645 | 621 |
| 646 // We have an outstanding read request, and we have not buffered enough | 622 // We have an outstanding read request, and we have not buffered enough |
| 647 // yet to fulfill the request; disable defer to get more data. | 623 // yet to fulfill the request; disable defer to get more data. |
| 648 case kReadThenDefer: | 624 case kReadThenDefer: |
| 649 return read_callback_.get() && | 625 return read_callback_.get() && |
| 650 last_offset_ > static_cast<int>(buffer_->forward_bytes()); | 626 last_offset_ > static_cast<int>(buffer_->forward_bytes()); |
| 651 | 627 |
| 652 // We have less than half the capacity of our threshold, so | 628 // We have less than half the capacity of our threshold, so |
| 653 // disable defer to get more data. | 629 // disable defer to get more data. |
| 654 case kThresholdDefer: { | 630 case kThresholdDefer: { |
| 655 size_t amount_buffered = buffer_->forward_bytes(); | 631 size_t amount_buffered = buffer_->forward_bytes(); |
| 656 size_t half_capacity = buffer_->forward_capacity() / 2; | 632 size_t half_capacity = buffer_->forward_capacity() / 2; |
| 657 return amount_buffered < half_capacity; | 633 return amount_buffered < half_capacity; |
| 658 } | 634 } |
| 659 } | 635 } |
| 660 | 636 |
| 661 // Otherwise keep deferring. | 637 // Otherwise keep deferring. |
| 662 return false; | 638 return false; |
| 663 } | 639 } |
| 664 | 640 |
| 665 bool BufferedResourceLoader::CanFulfillRead() { | 641 bool BufferedResourceLoader::CanFulfillRead() const { |
| 666 // If we are reading too far in the backward direction. | 642 // If we are reading too far in the backward direction. |
| 667 if (first_offset_ < 0 && | 643 if (first_offset_ < 0 && |
| 668 first_offset_ + static_cast<int>(buffer_->backward_bytes()) < 0) | 644 first_offset_ + static_cast<int>(buffer_->backward_bytes()) < 0) |
| 669 return false; | 645 return false; |
| 670 | 646 |
| 671 // If the start offset is too far ahead. | 647 // If the start offset is too far ahead. |
| 672 if (first_offset_ >= static_cast<int>(buffer_->forward_bytes())) | 648 if (first_offset_ >= static_cast<int>(buffer_->forward_bytes())) |
| 673 return false; | 649 return false; |
| 674 | 650 |
| 675 // At the point, we verified that first byte requested is within the buffer. | 651 // At the point, we verified that first byte requested is within the buffer. |
| 676 // If the request has completed, then just returns with what we have now. | 652 // If the request has completed, then just returns with what we have now. |
| 677 if (completed_) | 653 if (!active_loader_.get()) |
| 678 return true; | 654 return true; |
| 679 | 655 |
| 680 // If the resource request is still active, make sure the whole requested | 656 // If the resource request is still active, make sure the whole requested |
| 681 // range is covered. | 657 // range is covered. |
| 682 if (last_offset_ > static_cast<int>(buffer_->forward_bytes())) | 658 if (last_offset_ > static_cast<int>(buffer_->forward_bytes())) |
| 683 return false; | 659 return false; |
| 684 | 660 |
| 685 return true; | 661 return true; |
| 686 } | 662 } |
| 687 | 663 |
| 688 bool BufferedResourceLoader::WillFulfillRead() { | 664 bool BufferedResourceLoader::WillFulfillRead() const { |
| 689 // Trying to read too far behind. | 665 // Trying to read too far behind. |
| 690 if (first_offset_ < 0 && | 666 if (first_offset_ < 0 && |
| 691 first_offset_ + static_cast<int>(buffer_->backward_bytes()) < 0) | 667 first_offset_ + static_cast<int>(buffer_->backward_bytes()) < 0) |
| 692 return false; | 668 return false; |
| 693 | 669 |
| 694 // Trying to read too far ahead. | 670 // Trying to read too far ahead. |
| 695 if (first_offset_ - static_cast<int>(buffer_->forward_bytes()) >= | 671 if (first_offset_ - static_cast<int>(buffer_->forward_bytes()) >= |
| 696 kForwardWaitThreshold) | 672 kForwardWaitThreshold) |
| 697 return false; | 673 return false; |
| 698 | 674 |
| 699 // The resource request has completed, there's no way we can fulfill the | 675 // The resource request has completed, there's no way we can fulfill the |
| 700 // read request. | 676 // read request. |
| 701 if (completed_) | 677 if (!active_loader_.get()) |
| 702 return false; | 678 return false; |
| 703 | 679 |
| 704 return true; | 680 return true; |
| 705 } | 681 } |
| 706 | 682 |
| 707 void BufferedResourceLoader::ReadInternal() { | 683 void BufferedResourceLoader::ReadInternal() { |
| 708 // Seek to the first byte requested. | 684 // Seek to the first byte requested. |
| 709 bool ret = buffer_->Seek(first_offset_); | 685 bool ret = buffer_->Seek(first_offset_); |
| 710 DCHECK(ret); | 686 DCHECK(ret); |
| 711 | 687 |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 757 } else if (first_byte_position > kPositionNotSpecified) { | 733 } else if (first_byte_position > kPositionNotSpecified) { |
| 758 header = base::StringPrintf("bytes=%" PRId64 "-", | 734 header = base::StringPrintf("bytes=%" PRId64 "-", |
| 759 first_byte_position); | 735 first_byte_position); |
| 760 } else if (last_byte_position > kPositionNotSpecified) { | 736 } else if (last_byte_position > kPositionNotSpecified) { |
| 761 NOTIMPLEMENTED() << "Suffix range not implemented"; | 737 NOTIMPLEMENTED() << "Suffix range not implemented"; |
| 762 } | 738 } |
| 763 return header; | 739 return header; |
| 764 } | 740 } |
| 765 | 741 |
| 766 void BufferedResourceLoader::DoneRead(int error) { | 742 void BufferedResourceLoader::DoneRead(int error) { |
| 767 read_callback_->RunWithParams(Tuple1<int>(error)); | |
| 768 read_callback_.reset(); | |
| 769 if (buffer_.get() && saved_forward_capacity_) { | 743 if (buffer_.get() && saved_forward_capacity_) { |
| 770 buffer_->set_forward_capacity(saved_forward_capacity_); | 744 buffer_->set_forward_capacity(saved_forward_capacity_); |
| 771 saved_forward_capacity_ = 0; | 745 saved_forward_capacity_ = 0; |
| 772 } | 746 } |
| 773 read_position_ = 0; | 747 read_position_ = 0; |
| 774 read_size_ = 0; | 748 read_size_ = 0; |
| 775 read_buffer_ = NULL; | 749 read_buffer_ = NULL; |
| 776 first_offset_ = 0; | 750 first_offset_ = 0; |
| 777 last_offset_ = 0; | 751 last_offset_ = 0; |
| 778 Log(); | 752 Log(); |
| 753 |
| 754 scoped_ptr<net::OldCompletionCallback> read_callback; |
| 755 read_callback.swap(read_callback_); |
| 756 read_callback->RunWithParams(Tuple1<int>(error)); |
| 779 } | 757 } |
| 780 | 758 |
| 781 void BufferedResourceLoader::DoneStart(int error) { | 759 void BufferedResourceLoader::DoneStart(int error) { |
| 782 start_callback_->RunWithParams(Tuple1<int>(error)); | 760 scoped_ptr<net::OldCompletionCallback> start_callback; |
| 783 start_callback_.reset(); | 761 start_callback.swap(start_callback_); |
| 762 start_callback->RunWithParams(Tuple1<int>(error)); |
| 784 } | 763 } |
| 785 | 764 |
| 786 void BufferedResourceLoader::NotifyNetworkEvent() { | 765 void BufferedResourceLoader::NotifyNetworkEvent() { |
| 787 if (!event_callback_.is_null()) | 766 if (!event_callback_.is_null()) |
| 788 event_callback_.Run(); | 767 event_callback_.Run(); |
| 789 } | 768 } |
| 790 | 769 |
| 791 bool BufferedResourceLoader::IsRangeRequest() const { | 770 bool BufferedResourceLoader::IsRangeRequest() const { |
| 792 return first_byte_position_ != kPositionNotSpecified; | 771 return first_byte_position_ != kPositionNotSpecified; |
| 793 } | 772 } |
| 794 | 773 |
| 795 void BufferedResourceLoader::Log() { | 774 void BufferedResourceLoader::Log() { |
| 796 if (buffer_.get()) { | 775 if (buffer_.get()) { |
| 797 media_log_->AddEvent( | 776 media_log_->AddEvent( |
| 798 media_log_->CreateBufferedExtentsChangedEvent( | 777 media_log_->CreateBufferedExtentsChangedEvent( |
| 799 offset_ - buffer_->backward_bytes(), | 778 offset_ - buffer_->backward_bytes(), |
| 800 offset_, | 779 offset_, |
| 801 offset_ + buffer_->forward_bytes())); | 780 offset_ + buffer_->forward_bytes())); |
| 802 } | 781 } |
| 803 } | 782 } |
| 804 | 783 |
| 805 } // namespace webkit_media | 784 } // namespace webkit_media |
| OLD | NEW |