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/glue/media/buffered_data_source.h" | 5 #include "webkit/glue/media/buffered_data_source.h" |
6 | 6 |
7 #include "media/base/filter_host.h" | 7 #include "media/base/filter_host.h" |
8 #include "media/base/media_log.h" | 8 #include "media/base/media_log.h" |
9 #include "net/base/net_errors.h" | 9 #include "net/base/net_errors.h" |
10 #include "webkit/glue/media/web_data_source_factory.h" | 10 #include "webkit/glue/media/web_data_source_factory.h" |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
78 | 78 |
79 return new BufferedResourceLoader(url_, | 79 return new BufferedResourceLoader(url_, |
80 first_byte_position, | 80 first_byte_position, |
81 last_byte_position, | 81 last_byte_position, |
82 media_log_); | 82 media_log_); |
83 } | 83 } |
84 | 84 |
85 void BufferedDataSource::set_host(media::FilterHost* host) { | 85 void BufferedDataSource::set_host(media::FilterHost* host) { |
86 DataSource::set_host(host); | 86 DataSource::set_host(host); |
87 | 87 |
88 if (loader_.get()) | 88 if (loader_.get()) { |
89 UpdateHostState(); | 89 base::AutoLock auto_lock(lock_); |
| 90 UpdateHostState_Locked(); |
| 91 } |
90 } | 92 } |
91 | 93 |
92 void BufferedDataSource::Initialize(const std::string& url, | 94 void BufferedDataSource::Initialize(const std::string& url, |
93 const media::PipelineStatusCB& callback) { | 95 const media::PipelineStatusCB& callback) { |
94 // Saves the url. | 96 // Saves the url. |
95 url_ = GURL(url); | 97 url_ = GURL(url); |
96 | 98 |
97 // This data source doesn't support data:// protocol so reject it. | 99 // This data source doesn't support data:// protocol so reject it. |
98 if (url_.SchemeIs(kDataScheme)) { | 100 if (url_.SchemeIs(kDataScheme)) { |
99 callback.Run(media::DATASOURCE_ERROR_URL_NOT_SUPPORTED); | 101 callback.Run(media::DATASOURCE_ERROR_URL_NOT_SUPPORTED); |
100 return; | 102 return; |
101 } else if (!IsProtocolSupportedForMedia(url_)) { | 103 } else if (!IsProtocolSupportedForMedia(url_)) { |
102 callback.Run(media::PIPELINE_ERROR_NETWORK); | 104 callback.Run(media::PIPELINE_ERROR_NETWORK); |
103 return; | 105 return; |
104 } | 106 } |
105 | 107 |
106 DCHECK(!callback.is_null()); | 108 DCHECK(!callback.is_null()); |
107 initialize_cb_ = callback; | 109 { |
| 110 base::AutoLock auto_lock(lock_); |
| 111 initialize_cb_ = callback; |
| 112 } |
108 | 113 |
109 // Post a task to complete the initialization task. | 114 // Post a task to complete the initialization task. |
110 render_loop_->PostTask(FROM_HERE, | 115 render_loop_->PostTask(FROM_HERE, |
111 NewRunnableMethod(this, &BufferedDataSource::InitializeTask)); | 116 NewRunnableMethod(this, &BufferedDataSource::InitializeTask)); |
112 } | 117 } |
113 | 118 |
114 void BufferedDataSource::CancelInitialize() { | 119 void BufferedDataSource::CancelInitialize() { |
115 base::AutoLock auto_lock(lock_); | 120 base::AutoLock auto_lock(lock_); |
116 DCHECK(!initialize_cb_.is_null()); | 121 DCHECK(!initialize_cb_.is_null()); |
117 | 122 |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
198 | 203 |
199 CleanupTask(); | 204 CleanupTask(); |
200 frame_ = NULL; | 205 frame_ = NULL; |
201 } | 206 } |
202 | 207 |
203 ///////////////////////////////////////////////////////////////////////////// | 208 ///////////////////////////////////////////////////////////////////////////// |
204 // Render thread tasks. | 209 // Render thread tasks. |
205 void BufferedDataSource::InitializeTask() { | 210 void BufferedDataSource::InitializeTask() { |
206 DCHECK(MessageLoop::current() == render_loop_); | 211 DCHECK(MessageLoop::current() == render_loop_); |
207 DCHECK(!loader_.get()); | 212 DCHECK(!loader_.get()); |
208 if (stopped_on_render_loop_ || initialize_cb_.is_null()) | 213 |
209 return; | 214 { |
| 215 base::AutoLock auto_lock(lock_); |
| 216 if (stopped_on_render_loop_ || initialize_cb_.is_null() || |
| 217 stop_signal_received_) { |
| 218 return; |
| 219 } |
| 220 } |
210 | 221 |
211 if (url_.SchemeIs(kHttpScheme) || url_.SchemeIs(kHttpsScheme)) { | 222 if (url_.SchemeIs(kHttpScheme) || url_.SchemeIs(kHttpsScheme)) { |
212 // Do an unbounded range request starting at the beginning. If the server | 223 // Do an unbounded range request starting at the beginning. If the server |
213 // responds with 200 instead of 206 we'll fall back into a streaming mode. | 224 // responds with 200 instead of 206 we'll fall back into a streaming mode. |
214 loader_ = CreateResourceLoader(0, kPositionNotSpecified); | 225 loader_ = CreateResourceLoader(0, kPositionNotSpecified); |
215 loader_->Start( | 226 loader_->Start( |
216 NewCallback(this, &BufferedDataSource::HttpInitialStartCallback), | 227 NewCallback(this, &BufferedDataSource::HttpInitialStartCallback), |
217 NewCallback(this, &BufferedDataSource::NetworkEventCallback), | 228 NewCallback(this, &BufferedDataSource::NetworkEventCallback), |
218 frame_); | 229 frame_); |
219 } else { | 230 } else { |
(...skipping 30 matching lines...) Expand all Loading... |
250 | 261 |
251 // Call to read internal to perform the actual read. | 262 // Call to read internal to perform the actual read. |
252 ReadInternal(); | 263 ReadInternal(); |
253 } | 264 } |
254 | 265 |
255 void BufferedDataSource::CleanupTask() { | 266 void BufferedDataSource::CleanupTask() { |
256 DCHECK(MessageLoop::current() == render_loop_); | 267 DCHECK(MessageLoop::current() == render_loop_); |
257 | 268 |
258 { | 269 { |
259 base::AutoLock auto_lock(lock_); | 270 base::AutoLock auto_lock(lock_); |
| 271 initialize_cb_.Reset(); |
260 if (stopped_on_render_loop_) | 272 if (stopped_on_render_loop_) |
261 return; | 273 return; |
262 | 274 |
263 // Signal that stop task has finished execution. | 275 // Signal that stop task has finished execution. |
264 // NOTE: it's vital that this be set under lock, as that's how Read() tests | 276 // NOTE: it's vital that this be set under lock, as that's how Read() tests |
265 // before registering a new |read_callback_| (which is cleared below). | 277 // before registering a new |read_callback_| (which is cleared below). |
266 stopped_on_render_loop_ = true; | 278 stopped_on_render_loop_ = true; |
267 | 279 |
268 if (read_callback_.get()) | 280 if (read_callback_.get()) |
269 DoneRead_Locked(net::ERR_FAILED); | 281 DoneRead_Locked(net::ERR_FAILED); |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
314 loader_->UpdateDeferStrategy(strategy); | 326 loader_->UpdateDeferStrategy(strategy); |
315 } | 327 } |
316 | 328 |
317 void BufferedDataSource::SetPreloadTask(media::Preload preload) { | 329 void BufferedDataSource::SetPreloadTask(media::Preload preload) { |
318 DCHECK(MessageLoop::current() == render_loop_); | 330 DCHECK(MessageLoop::current() == render_loop_); |
319 preload_ = preload; | 331 preload_ = preload; |
320 } | 332 } |
321 | 333 |
322 BufferedResourceLoader::DeferStrategy | 334 BufferedResourceLoader::DeferStrategy |
323 BufferedDataSource::ChooseDeferStrategy() { | 335 BufferedDataSource::ChooseDeferStrategy() { |
| 336 DCHECK(MessageLoop::current() == render_loop_); |
324 // If the user indicates preload=metadata, then just load exactly | 337 // If the user indicates preload=metadata, then just load exactly |
325 // what is needed for starting the pipeline and prerolling frames. | 338 // what is needed for starting the pipeline and prerolling frames. |
326 if (preload_ == media::METADATA && !media_has_played_) | 339 if (preload_ == media::METADATA && !media_has_played_) |
327 return BufferedResourceLoader::kReadThenDefer; | 340 return BufferedResourceLoader::kReadThenDefer; |
328 | 341 |
329 // In general, we want to try to buffer the entire video when the video | 342 // In general, we want to try to buffer the entire video when the video |
330 // is paused. But we don't want to do this if the video hasn't played yet | 343 // is paused. But we don't want to do this if the video hasn't played yet |
331 // and preload!=auto. | 344 // and preload!=auto. |
332 if (media_is_paused_ && | 345 if (media_is_paused_ && |
333 (preload_ == media::AUTO || media_has_played_)) { | 346 (preload_ == media::AUTO || media_has_played_)) { |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
391 | 404 |
392 ///////////////////////////////////////////////////////////////////////////// | 405 ///////////////////////////////////////////////////////////////////////////// |
393 // BufferedResourceLoader callback methods. | 406 // BufferedResourceLoader callback methods. |
394 void BufferedDataSource::HttpInitialStartCallback(int error) { | 407 void BufferedDataSource::HttpInitialStartCallback(int error) { |
395 DCHECK(MessageLoop::current() == render_loop_); | 408 DCHECK(MessageLoop::current() == render_loop_); |
396 DCHECK(loader_.get()); | 409 DCHECK(loader_.get()); |
397 | 410 |
398 int64 instance_size = loader_->instance_size(); | 411 int64 instance_size = loader_->instance_size(); |
399 bool success = error == net::OK; | 412 bool success = error == net::OK; |
400 | 413 |
401 if (initialize_cb_.is_null()) { | 414 |
| 415 bool initialize_cb_is_null = false; |
| 416 { |
| 417 base::AutoLock auto_lock(lock_); |
| 418 initialize_cb_is_null = initialize_cb_.is_null(); |
| 419 } |
| 420 if (initialize_cb_is_null) { |
402 loader_->Stop(); | 421 loader_->Stop(); |
403 return; | 422 return; |
404 } | 423 } |
405 | 424 |
406 if (success) { | 425 if (success) { |
407 // TODO(hclam): Needs more thinking about supporting servers without range | 426 // TODO(hclam): Needs more thinking about supporting servers without range |
408 // request or their partial response is not complete. | 427 // request or their partial response is not complete. |
409 total_bytes_ = instance_size; | 428 total_bytes_ = instance_size; |
410 loaded_ = false; | 429 loaded_ = false; |
411 streaming_ = (instance_size == kPositionNotSpecified) || | 430 streaming_ = (instance_size == kPositionNotSpecified) || |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
445 // safe because |lock_| is only acquired in tasks on render thread. | 464 // safe because |lock_| is only acquired in tasks on render thread. |
446 base::AutoLock auto_lock(lock_); | 465 base::AutoLock auto_lock(lock_); |
447 if (stop_signal_received_) | 466 if (stop_signal_received_) |
448 return; | 467 return; |
449 | 468 |
450 if (!success) { | 469 if (!success) { |
451 DoneInitialization_Locked(media::PIPELINE_ERROR_NETWORK); | 470 DoneInitialization_Locked(media::PIPELINE_ERROR_NETWORK); |
452 return; | 471 return; |
453 } | 472 } |
454 | 473 |
455 UpdateHostState(); | 474 UpdateHostState_Locked(); |
456 DoneInitialization_Locked(media::PIPELINE_OK); | 475 DoneInitialization_Locked(media::PIPELINE_OK); |
457 } | 476 } |
458 } | 477 } |
459 | 478 |
460 void BufferedDataSource::NonHttpInitialStartCallback(int error) { | 479 void BufferedDataSource::NonHttpInitialStartCallback(int error) { |
461 DCHECK(MessageLoop::current() == render_loop_); | 480 DCHECK(MessageLoop::current() == render_loop_); |
462 DCHECK(loader_.get()); | 481 DCHECK(loader_.get()); |
463 | 482 |
464 if (initialize_cb_.is_null()) { | 483 bool initialize_cb_is_null = false; |
| 484 { |
| 485 base::AutoLock auto_lock(lock_); |
| 486 initialize_cb_is_null = initialize_cb_.is_null(); |
| 487 } |
| 488 if (initialize_cb_is_null) { |
465 loader_->Stop(); | 489 loader_->Stop(); |
466 return; | 490 return; |
467 } | 491 } |
468 | 492 |
469 int64 instance_size = loader_->instance_size(); | 493 int64 instance_size = loader_->instance_size(); |
470 bool success = error == net::OK && instance_size != kPositionNotSpecified; | 494 bool success = error == net::OK && instance_size != kPositionNotSpecified; |
471 | 495 |
472 if (success) { | 496 if (success) { |
473 total_bytes_ = instance_size; | 497 total_bytes_ = instance_size; |
474 buffered_bytes_ = total_bytes_; | 498 buffered_bytes_ = total_bytes_; |
(...skipping 19 matching lines...) Expand all Loading... |
494 // safe because |lock_| is only acquired in tasks on render thread. | 518 // safe because |lock_| is only acquired in tasks on render thread. |
495 base::AutoLock auto_lock(lock_); | 519 base::AutoLock auto_lock(lock_); |
496 if (stop_signal_received_ || initialize_cb_.is_null()) | 520 if (stop_signal_received_ || initialize_cb_.is_null()) |
497 return; | 521 return; |
498 | 522 |
499 if (!success) { | 523 if (!success) { |
500 DoneInitialization_Locked(media::PIPELINE_ERROR_NETWORK); | 524 DoneInitialization_Locked(media::PIPELINE_ERROR_NETWORK); |
501 return; | 525 return; |
502 } | 526 } |
503 | 527 |
504 UpdateHostState(); | 528 UpdateHostState_Locked(); |
505 DoneInitialization_Locked(media::PIPELINE_OK); | 529 DoneInitialization_Locked(media::PIPELINE_OK); |
506 } | 530 } |
507 } | 531 } |
508 | 532 |
509 void BufferedDataSource::PartialReadStartCallback(int error) { | 533 void BufferedDataSource::PartialReadStartCallback(int error) { |
510 DCHECK(MessageLoop::current() == render_loop_); | 534 DCHECK(MessageLoop::current() == render_loop_); |
511 DCHECK(loader_.get()); | 535 DCHECK(loader_.get()); |
512 | 536 |
513 if (error == net::OK) { | 537 if (error == net::OK) { |
514 // Once the request has started successfully, we can proceed with | 538 // Once the request has started successfully, we can proceed with |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
611 network_activity_ = network_activity; | 635 network_activity_ = network_activity; |
612 if (host()) | 636 if (host()) |
613 host()->SetNetworkActivity(network_activity); | 637 host()->SetNetworkActivity(network_activity); |
614 } | 638 } |
615 | 639 |
616 buffered_bytes_ = buffered_position + 1; | 640 buffered_bytes_ = buffered_position + 1; |
617 if (host()) | 641 if (host()) |
618 host()->SetBufferedBytes(buffered_bytes_); | 642 host()->SetBufferedBytes(buffered_bytes_); |
619 } | 643 } |
620 | 644 |
621 void BufferedDataSource::UpdateHostState() { | 645 void BufferedDataSource::UpdateHostState_Locked() { |
| 646 // Called from various threads, under lock. |
| 647 lock_.AssertAcquired(); |
| 648 |
622 media::FilterHost* filter_host = host(); | 649 media::FilterHost* filter_host = host(); |
623 if (!filter_host) | 650 if (!filter_host) |
624 return; | 651 return; |
625 | 652 |
626 filter_host->SetLoaded(loaded_); | 653 filter_host->SetLoaded(loaded_); |
627 | 654 |
628 if (streaming_) { | 655 if (streaming_) { |
629 filter_host->SetStreaming(true); | 656 filter_host->SetStreaming(true); |
630 } else { | 657 } else { |
631 filter_host->SetTotalBytes(total_bytes_); | 658 filter_host->SetTotalBytes(total_bytes_); |
632 filter_host->SetBufferedBytes(buffered_bytes_); | 659 filter_host->SetBufferedBytes(buffered_bytes_); |
633 } | 660 } |
634 } | 661 } |
635 | 662 |
636 } // namespace webkit_glue | 663 } // namespace webkit_glue |
OLD | NEW |