| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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_data_source.h" | 5 #include "webkit/media/buffered_data_source.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/callback_helpers.h" |
| 8 #include "base/message_loop.h" | 9 #include "base/message_loop.h" |
| 9 #include "media/base/media_log.h" | 10 #include "media/base/media_log.h" |
| 10 #include "net/base/net_errors.h" | 11 #include "net/base/net_errors.h" |
| 11 | 12 |
| 12 using WebKit::WebFrame; | 13 using WebKit::WebFrame; |
| 13 | 14 |
| 14 namespace { | 15 namespace { |
| 15 | 16 |
| 16 // BufferedDataSource has an intermediate buffer, this value governs the initial | 17 // BufferedDataSource has an intermediate buffer, this value governs the initial |
| 17 // size of that buffer. It is set to 32KB because this is a typical read size | 18 // size of that buffer. It is set to 32KB because this is a typical read size |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 82 | 83 |
| 83 if (loader_.get()) { | 84 if (loader_.get()) { |
| 84 base::AutoLock auto_lock(lock_); | 85 base::AutoLock auto_lock(lock_); |
| 85 UpdateHostState_Locked(); | 86 UpdateHostState_Locked(); |
| 86 } | 87 } |
| 87 } | 88 } |
| 88 | 89 |
| 89 void BufferedDataSource::Initialize( | 90 void BufferedDataSource::Initialize( |
| 90 const GURL& url, | 91 const GURL& url, |
| 91 BufferedResourceLoader::CORSMode cors_mode, | 92 BufferedResourceLoader::CORSMode cors_mode, |
| 92 const media::PipelineStatusCB& initialize_cb) { | 93 const InitializeCB& init_cb) { |
| 93 DCHECK(MessageLoop::current() == render_loop_); | 94 DCHECK(MessageLoop::current() == render_loop_); |
| 94 DCHECK(!initialize_cb.is_null()); | 95 DCHECK(!init_cb.is_null()); |
| 95 DCHECK(!loader_.get()); | 96 DCHECK(!loader_.get()); |
| 96 url_ = url; | 97 url_ = url; |
| 97 cors_mode_ = cors_mode; | 98 cors_mode_ = cors_mode; |
| 98 | 99 |
| 99 initialize_cb_ = initialize_cb; | 100 init_cb_ = init_cb; |
| 100 | 101 |
| 101 if (url_.SchemeIs(kHttpScheme) || url_.SchemeIs(kHttpsScheme)) { | 102 if (url_.SchemeIs(kHttpScheme) || url_.SchemeIs(kHttpsScheme)) { |
| 102 // Do an unbounded range request starting at the beginning. If the server | 103 // Do an unbounded range request starting at the beginning. If the server |
| 103 // responds with 200 instead of 206 we'll fall back into a streaming mode. | 104 // responds with 200 instead of 206 we'll fall back into a streaming mode. |
| 104 loader_.reset(CreateResourceLoader(0, kPositionNotSpecified)); | 105 loader_.reset(CreateResourceLoader(0, kPositionNotSpecified)); |
| 105 } else { | 106 } else { |
| 106 // For all other protocols, assume they support range request. We fetch | 107 // For all other protocols, assume they support range request. We fetch |
| 107 // the full range of the resource to obtain the instance size because | 108 // the full range of the resource to obtain the instance size because |
| 108 // we won't be served HTTP headers. | 109 // we won't be served HTTP headers. |
| 109 loader_.reset(CreateResourceLoader(kPositionNotSpecified, | 110 loader_.reset(CreateResourceLoader(kPositionNotSpecified, |
| 110 kPositionNotSpecified)); | 111 kPositionNotSpecified)); |
| 111 assume_fully_buffered_ = true; | 112 assume_fully_buffered_ = true; |
| 112 } | 113 } |
| 113 | 114 |
| 114 loader_->Start( | 115 loader_->Start( |
| 115 base::Bind(&BufferedDataSource::StartCallback, this), | 116 base::Bind(&BufferedDataSource::StartCallback, this), |
| 116 base::Bind(&BufferedDataSource::LoadingStateChangedCallback, this), | 117 base::Bind(&BufferedDataSource::LoadingStateChangedCallback, this), |
| 117 base::Bind(&BufferedDataSource::ProgressCallback, this), | 118 base::Bind(&BufferedDataSource::ProgressCallback, this), |
| 118 frame_); | 119 frame_); |
| 119 } | 120 } |
| 120 | 121 |
| 121 void BufferedDataSource::SetPreload(Preload preload) { | 122 void BufferedDataSource::SetPreload(Preload preload) { |
| 122 DCHECK(MessageLoop::current() == render_loop_); | 123 DCHECK(MessageLoop::current() == render_loop_); |
| 123 preload_ = preload; | 124 preload_ = preload; |
| 124 } | 125 } |
| 125 | 126 |
| 126 bool BufferedDataSource::HasSingleOrigin() { | 127 bool BufferedDataSource::HasSingleOrigin() { |
| 127 DCHECK(MessageLoop::current() == render_loop_); | 128 DCHECK(MessageLoop::current() == render_loop_); |
| 128 DCHECK(initialize_cb_.is_null() && loader_.get()) | 129 DCHECK(init_cb_.is_null() && loader_.get()) |
| 129 << "Initialize() must complete before calling HasSingleOrigin()"; | 130 << "Initialize() must complete before calling HasSingleOrigin()"; |
| 130 return loader_->HasSingleOrigin(); | 131 return loader_->HasSingleOrigin(); |
| 131 } | 132 } |
| 132 | 133 |
| 133 bool BufferedDataSource::DidPassCORSAccessCheck() const { | 134 bool BufferedDataSource::DidPassCORSAccessCheck() const { |
| 134 return loader_.get() && loader_->DidPassCORSAccessCheck(); | 135 return loader_.get() && loader_->DidPassCORSAccessCheck(); |
| 135 } | 136 } |
| 136 | 137 |
| 137 void BufferedDataSource::Abort() { | 138 void BufferedDataSource::Abort() { |
| 138 DCHECK(MessageLoop::current() == render_loop_); | 139 DCHECK(MessageLoop::current() == render_loop_); |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 225 | 226 |
| 226 // Call to read internal to perform the actual read. | 227 // Call to read internal to perform the actual read. |
| 227 ReadInternal(); | 228 ReadInternal(); |
| 228 } | 229 } |
| 229 | 230 |
| 230 void BufferedDataSource::CleanupTask() { | 231 void BufferedDataSource::CleanupTask() { |
| 231 DCHECK(MessageLoop::current() == render_loop_); | 232 DCHECK(MessageLoop::current() == render_loop_); |
| 232 | 233 |
| 233 { | 234 { |
| 234 base::AutoLock auto_lock(lock_); | 235 base::AutoLock auto_lock(lock_); |
| 235 initialize_cb_.Reset(); | 236 init_cb_.Reset(); |
| 236 if (stopped_on_render_loop_) | 237 if (stopped_on_render_loop_) |
| 237 return; | 238 return; |
| 238 | 239 |
| 239 // Signal that stop task has finished execution. | 240 // Signal that stop task has finished execution. |
| 240 // NOTE: it's vital that this be set under lock, as that's how Read() tests | 241 // NOTE: it's vital that this be set under lock, as that's how Read() tests |
| 241 // before registering a new |read_cb_| (which is cleared below). | 242 // before registering a new |read_cb_| (which is cleared below). |
| 242 stopped_on_render_loop_ = true; | 243 stopped_on_render_loop_ = true; |
| 243 | 244 |
| 244 if (!read_cb_.is_null()) | 245 if (!read_cb_.is_null()) |
| 245 DoneRead_Locked(kReadError); | 246 DoneRead_Locked(kReadError); |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 315 DCHECK(!read_cb_.is_null()); | 316 DCHECK(!read_cb_.is_null()); |
| 316 DCHECK(bytes_read >= 0 || bytes_read == kReadError); | 317 DCHECK(bytes_read >= 0 || bytes_read == kReadError); |
| 317 lock_.AssertAcquired(); | 318 lock_.AssertAcquired(); |
| 318 | 319 |
| 319 read_cb_.Run(bytes_read); | 320 read_cb_.Run(bytes_read); |
| 320 read_cb_.Reset(); | 321 read_cb_.Reset(); |
| 321 read_size_ = 0; | 322 read_size_ = 0; |
| 322 read_buffer_ = 0; | 323 read_buffer_ = 0; |
| 323 } | 324 } |
| 324 | 325 |
| 325 void BufferedDataSource::DoneInitialization_Locked( | |
| 326 media::PipelineStatus status) { | |
| 327 DCHECK(MessageLoop::current() == render_loop_); | |
| 328 DCHECK(!initialize_cb_.is_null()); | |
| 329 lock_.AssertAcquired(); | |
| 330 | |
| 331 initialize_cb_.Run(status); | |
| 332 initialize_cb_.Reset(); | |
| 333 } | |
| 334 | |
| 335 ///////////////////////////////////////////////////////////////////////////// | 326 ///////////////////////////////////////////////////////////////////////////// |
| 336 // BufferedResourceLoader callback methods. | 327 // BufferedResourceLoader callback methods. |
| 337 void BufferedDataSource::StartCallback( | 328 void BufferedDataSource::StartCallback( |
| 338 BufferedResourceLoader::Status status) { | 329 BufferedResourceLoader::Status status) { |
| 339 DCHECK(MessageLoop::current() == render_loop_); | 330 DCHECK(MessageLoop::current() == render_loop_); |
| 340 DCHECK(loader_.get()); | 331 DCHECK(loader_.get()); |
| 341 | 332 |
| 342 bool initialize_cb_is_null = false; | 333 bool init_cb_is_null = false; |
| 343 { | 334 { |
| 344 base::AutoLock auto_lock(lock_); | 335 base::AutoLock auto_lock(lock_); |
| 345 initialize_cb_is_null = initialize_cb_.is_null(); | 336 init_cb_is_null = init_cb_.is_null(); |
| 346 } | 337 } |
| 347 if (initialize_cb_is_null) { | 338 if (init_cb_is_null) { |
| 348 loader_->Stop(); | 339 loader_->Stop(); |
| 349 return; | 340 return; |
| 350 } | 341 } |
| 351 | 342 |
| 352 // All responses must be successful. Resources that are assumed to be fully | 343 // All responses must be successful. Resources that are assumed to be fully |
| 353 // buffered must have a known content length. | 344 // buffered must have a known content length. |
| 354 bool success = status == BufferedResourceLoader::kOk && | 345 bool success = status == BufferedResourceLoader::kOk && |
| 355 (!assume_fully_buffered_ || | 346 (!assume_fully_buffered_ || |
| 356 loader_->instance_size() != kPositionNotSpecified); | 347 loader_->instance_size() != kPositionNotSpecified); |
| 357 | 348 |
| 358 if (success) { | 349 if (success) { |
| 359 total_bytes_ = loader_->instance_size(); | 350 total_bytes_ = loader_->instance_size(); |
| 360 streaming_ = !assume_fully_buffered_ && | 351 streaming_ = !assume_fully_buffered_ && |
| 361 (total_bytes_ == kPositionNotSpecified || !loader_->range_supported()); | 352 (total_bytes_ == kPositionNotSpecified || !loader_->range_supported()); |
| 362 } else { | 353 } else { |
| 363 loader_->Stop(); | 354 loader_->Stop(); |
| 364 } | 355 } |
| 365 | 356 |
| 366 // TODO(scherkus): we shouldn't have to lock to signal host(), see | 357 // TODO(scherkus): we shouldn't have to lock to signal host(), see |
| 367 // http://crbug.com/113712 for details. | 358 // http://crbug.com/113712 for details. |
| 368 scoped_refptr<BufferedDataSource> destruction_guard(this); | 359 scoped_refptr<BufferedDataSource> destruction_guard(this); |
| 369 { | 360 { |
| 370 base::AutoLock auto_lock(lock_); | 361 base::AutoLock auto_lock(lock_); |
| 371 if (stop_signal_received_) | 362 if (stop_signal_received_) |
| 372 return; | 363 return; |
| 373 | 364 |
| 374 if (!success) { | 365 if (success) |
| 375 DoneInitialization_Locked(media::PIPELINE_ERROR_NETWORK); | 366 UpdateHostState_Locked(); |
| 376 return; | |
| 377 } | |
| 378 | 367 |
| 379 UpdateHostState_Locked(); | 368 base::ResetAndReturn(&init_cb_).Run(success); |
| 380 DoneInitialization_Locked(media::PIPELINE_OK); | |
| 381 } | 369 } |
| 382 } | 370 } |
| 383 | 371 |
| 384 void BufferedDataSource::PartialReadStartCallback( | 372 void BufferedDataSource::PartialReadStartCallback( |
| 385 BufferedResourceLoader::Status status) { | 373 BufferedResourceLoader::Status status) { |
| 386 DCHECK(MessageLoop::current() == render_loop_); | 374 DCHECK(MessageLoop::current() == render_loop_); |
| 387 DCHECK(loader_.get()); | 375 DCHECK(loader_.get()); |
| 388 | 376 |
| 389 if (status == BufferedResourceLoader::kOk) { | 377 if (status == BufferedResourceLoader::kOk) { |
| 390 // Once the request has started successfully, we can proceed with | 378 // Once the request has started successfully, we can proceed with |
| (...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 511 if (total_bytes_ == kPositionNotSpecified) | 499 if (total_bytes_ == kPositionNotSpecified) |
| 512 return; | 500 return; |
| 513 | 501 |
| 514 host()->SetTotalBytes(total_bytes_); | 502 host()->SetTotalBytes(total_bytes_); |
| 515 | 503 |
| 516 if (assume_fully_buffered_) | 504 if (assume_fully_buffered_) |
| 517 host()->AddBufferedByteRange(0, total_bytes_); | 505 host()->AddBufferedByteRange(0, total_bytes_); |
| 518 } | 506 } |
| 519 | 507 |
| 520 } // namespace webkit_media | 508 } // namespace webkit_media |
| OLD | NEW |