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 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
203 | 208 |
204 CleanupTask(); | 209 CleanupTask(); |
205 frame_ = NULL; | 210 frame_ = NULL; |
206 } | 211 } |
207 | 212 |
208 ///////////////////////////////////////////////////////////////////////////// | 213 ///////////////////////////////////////////////////////////////////////////// |
209 // Render thread tasks. | 214 // Render thread tasks. |
210 void BufferedDataSource::InitializeTask() { | 215 void BufferedDataSource::InitializeTask() { |
211 DCHECK(MessageLoop::current() == render_loop_); | 216 DCHECK(MessageLoop::current() == render_loop_); |
212 DCHECK(!loader_.get()); | 217 DCHECK(!loader_.get()); |
213 if (stopped_on_render_loop_ || initialize_cb_.is_null()) | 218 |
214 return; | 219 { |
220 base::AutoLock auto_lock(lock_); | |
221 if (stopped_on_render_loop_ || initialize_cb_.is_null() || | |
222 stop_signal_received_) { | |
223 return; | |
224 } | |
225 } | |
215 | 226 |
216 if (url_.SchemeIs(kHttpScheme) || url_.SchemeIs(kHttpsScheme)) { | 227 if (url_.SchemeIs(kHttpScheme) || url_.SchemeIs(kHttpsScheme)) { |
217 // Do an unbounded range request starting at the beginning. If the server | 228 // Do an unbounded range request starting at the beginning. If the server |
218 // responds with 200 instead of 206 we'll fall back into a streaming mode. | 229 // responds with 200 instead of 206 we'll fall back into a streaming mode. |
219 loader_ = CreateResourceLoader(0, kPositionNotSpecified); | 230 loader_ = CreateResourceLoader(0, kPositionNotSpecified); |
220 loader_->Start( | 231 loader_->Start( |
221 NewCallback(this, &BufferedDataSource::HttpInitialStartCallback), | 232 NewCallback(this, &BufferedDataSource::HttpInitialStartCallback), |
222 NewCallback(this, &BufferedDataSource::NetworkEventCallback), | 233 NewCallback(this, &BufferedDataSource::NetworkEventCallback), |
223 frame_); | 234 frame_); |
224 } else { | 235 } else { |
(...skipping 30 matching lines...) Expand all Loading... | |
255 | 266 |
256 // Call to read internal to perform the actual read. | 267 // Call to read internal to perform the actual read. |
257 ReadInternal(); | 268 ReadInternal(); |
258 } | 269 } |
259 | 270 |
260 void BufferedDataSource::CleanupTask() { | 271 void BufferedDataSource::CleanupTask() { |
261 DCHECK(MessageLoop::current() == render_loop_); | 272 DCHECK(MessageLoop::current() == render_loop_); |
262 | 273 |
263 { | 274 { |
264 base::AutoLock auto_lock(lock_); | 275 base::AutoLock auto_lock(lock_); |
276 initialize_cb_.Reset(); | |
265 if (stopped_on_render_loop_) | 277 if (stopped_on_render_loop_) |
266 return; | 278 return; |
267 | 279 |
268 // Signal that stop task has finished execution. | 280 // Signal that stop task has finished execution. |
269 // NOTE: it's vital that this be set under lock, as that's how Read() tests | 281 // NOTE: it's vital that this be set under lock, as that's how Read() tests |
270 // before registering a new |read_callback_| (which is cleared below). | 282 // before registering a new |read_callback_| (which is cleared below). |
271 stopped_on_render_loop_ = true; | 283 stopped_on_render_loop_ = true; |
272 | 284 |
273 if (read_callback_.get()) | 285 if (read_callback_.get()) |
274 DoneRead_Locked(net::ERR_FAILED); | 286 DoneRead_Locked(net::ERR_FAILED); |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
327 } | 339 } |
328 | 340 |
329 void BufferedDataSource::SetBitrateTask(int bitrate) { | 341 void BufferedDataSource::SetBitrateTask(int bitrate) { |
330 DCHECK(MessageLoop::current() == render_loop_); | 342 DCHECK(MessageLoop::current() == render_loop_); |
331 DCHECK(loader_.get()); | 343 DCHECK(loader_.get()); |
332 loader_->SetBitrate(bitrate); | 344 loader_->SetBitrate(bitrate); |
333 } | 345 } |
334 | 346 |
335 BufferedResourceLoader::DeferStrategy | 347 BufferedResourceLoader::DeferStrategy |
336 BufferedDataSource::ChooseDeferStrategy() { | 348 BufferedDataSource::ChooseDeferStrategy() { |
349 DCHECK(MessageLoop::current() == render_loop_); | |
337 // If the user indicates preload=metadata, then just load exactly | 350 // If the user indicates preload=metadata, then just load exactly |
338 // what is needed for starting the pipeline and prerolling frames. | 351 // what is needed for starting the pipeline and prerolling frames. |
339 if (preload_ == media::METADATA && !media_has_played_) | 352 if (preload_ == media::METADATA && !media_has_played_) |
340 return BufferedResourceLoader::kReadThenDefer; | 353 return BufferedResourceLoader::kReadThenDefer; |
341 | 354 |
342 // In general, we want to try to buffer the entire video when the video | 355 // In general, we want to try to buffer the entire video when the video |
343 // is paused. But we don't want to do this if the video hasn't played yet | 356 // is paused. But we don't want to do this if the video hasn't played yet |
344 // and preload!=auto. | 357 // and preload!=auto. |
345 if (media_is_paused_ && | 358 if (media_is_paused_ && |
346 (preload_ == media::AUTO || media_has_played_)) { | 359 (preload_ == media::AUTO || media_has_played_)) { |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
404 | 417 |
405 ///////////////////////////////////////////////////////////////////////////// | 418 ///////////////////////////////////////////////////////////////////////////// |
406 // BufferedResourceLoader callback methods. | 419 // BufferedResourceLoader callback methods. |
407 void BufferedDataSource::HttpInitialStartCallback(int error) { | 420 void BufferedDataSource::HttpInitialStartCallback(int error) { |
408 DCHECK(MessageLoop::current() == render_loop_); | 421 DCHECK(MessageLoop::current() == render_loop_); |
409 DCHECK(loader_.get()); | 422 DCHECK(loader_.get()); |
410 | 423 |
411 int64 instance_size = loader_->instance_size(); | 424 int64 instance_size = loader_->instance_size(); |
412 bool success = error == net::OK; | 425 bool success = error == net::OK; |
413 | 426 |
414 if (initialize_cb_.is_null()) { | 427 |
428 bool initialize_cb_is_null = false; | |
429 { | |
430 base::AutoLock auto_lock(lock_); | |
431 initialize_cb_is_null = initialize_cb_.is_null(); | |
432 } | |
433 if (initialize_cb_is_null) { | |
415 loader_->Stop(); | 434 loader_->Stop(); |
416 return; | 435 return; |
417 } | 436 } |
418 | 437 |
419 if (success) { | 438 if (success) { |
420 // TODO(hclam): Needs more thinking about supporting servers without range | 439 // TODO(hclam): Needs more thinking about supporting servers without range |
421 // request or their partial response is not complete. | 440 // request or their partial response is not complete. |
422 total_bytes_ = instance_size; | 441 total_bytes_ = instance_size; |
423 loaded_ = false; | 442 loaded_ = false; |
424 streaming_ = (instance_size == kPositionNotSpecified) || | 443 streaming_ = (instance_size == kPositionNotSpecified) || |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
458 // safe because |lock_| is only acquired in tasks on render thread. | 477 // safe because |lock_| is only acquired in tasks on render thread. |
459 base::AutoLock auto_lock(lock_); | 478 base::AutoLock auto_lock(lock_); |
460 if (stop_signal_received_) | 479 if (stop_signal_received_) |
461 return; | 480 return; |
462 | 481 |
463 if (!success) { | 482 if (!success) { |
464 DoneInitialization_Locked(media::PIPELINE_ERROR_NETWORK); | 483 DoneInitialization_Locked(media::PIPELINE_ERROR_NETWORK); |
465 return; | 484 return; |
466 } | 485 } |
467 | 486 |
468 UpdateHostState(); | 487 UpdateHostState_Locked(); |
469 DoneInitialization_Locked(media::PIPELINE_OK); | 488 DoneInitialization_Locked(media::PIPELINE_OK); |
470 } | 489 } |
471 } | 490 } |
472 | 491 |
473 void BufferedDataSource::NonHttpInitialStartCallback(int error) { | 492 void BufferedDataSource::NonHttpInitialStartCallback(int error) { |
474 DCHECK(MessageLoop::current() == render_loop_); | 493 DCHECK(MessageLoop::current() == render_loop_); |
475 DCHECK(loader_.get()); | 494 DCHECK(loader_.get()); |
476 | 495 |
477 if (initialize_cb_.is_null()) { | 496 bool initialize_cb_is_null = false; |
497 { | |
498 base::AutoLock auto_lock(lock_); | |
499 initialize_cb_is_null = initialize_cb_.is_null(); | |
500 } | |
501 if (initialize_cb_is_null) { | |
478 loader_->Stop(); | 502 loader_->Stop(); |
479 return; | 503 return; |
480 } | 504 } |
481 | 505 |
482 int64 instance_size = loader_->instance_size(); | 506 int64 instance_size = loader_->instance_size(); |
483 bool success = error == net::OK && instance_size != kPositionNotSpecified; | 507 bool success = error == net::OK && instance_size != kPositionNotSpecified; |
484 | 508 |
485 if (success) { | 509 if (success) { |
486 total_bytes_ = instance_size; | 510 total_bytes_ = instance_size; |
487 buffered_bytes_ = total_bytes_; | 511 buffered_bytes_ = total_bytes_; |
(...skipping 19 matching lines...) Expand all Loading... | |
507 // safe because |lock_| is only acquired in tasks on render thread. | 531 // safe because |lock_| is only acquired in tasks on render thread. |
508 base::AutoLock auto_lock(lock_); | 532 base::AutoLock auto_lock(lock_); |
509 if (stop_signal_received_ || initialize_cb_.is_null()) | 533 if (stop_signal_received_ || initialize_cb_.is_null()) |
510 return; | 534 return; |
511 | 535 |
512 if (!success) { | 536 if (!success) { |
513 DoneInitialization_Locked(media::PIPELINE_ERROR_NETWORK); | 537 DoneInitialization_Locked(media::PIPELINE_ERROR_NETWORK); |
514 return; | 538 return; |
515 } | 539 } |
516 | 540 |
517 UpdateHostState(); | 541 UpdateHostState_Locked(); |
518 DoneInitialization_Locked(media::PIPELINE_OK); | 542 DoneInitialization_Locked(media::PIPELINE_OK); |
519 } | 543 } |
520 } | 544 } |
521 | 545 |
522 void BufferedDataSource::PartialReadStartCallback(int error) { | 546 void BufferedDataSource::PartialReadStartCallback(int error) { |
523 DCHECK(MessageLoop::current() == render_loop_); | 547 DCHECK(MessageLoop::current() == render_loop_); |
524 DCHECK(loader_.get()); | 548 DCHECK(loader_.get()); |
525 | 549 |
526 if (error == net::OK) { | 550 if (error == net::OK) { |
527 // Once the request has started successfully, we can proceed with | 551 // Once the request has started successfully, we can proceed with |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
624 network_activity_ = network_activity; | 648 network_activity_ = network_activity; |
625 if (host()) | 649 if (host()) |
626 host()->SetNetworkActivity(network_activity); | 650 host()->SetNetworkActivity(network_activity); |
627 } | 651 } |
628 | 652 |
629 buffered_bytes_ = buffered_position + 1; | 653 buffered_bytes_ = buffered_position + 1; |
630 if (host()) | 654 if (host()) |
631 host()->SetBufferedBytes(buffered_bytes_); | 655 host()->SetBufferedBytes(buffered_bytes_); |
632 } | 656 } |
633 | 657 |
634 void BufferedDataSource::UpdateHostState() { | 658 void BufferedDataSource::UpdateHostState_Locked() { |
659 // Called from various threads. | |
acolwell GONE FROM CHROMIUM
2011/09/27 16:57:15
nit: Add lock_.AssertAcquired() here.
| |
660 | |
635 media::FilterHost* filter_host = host(); | 661 media::FilterHost* filter_host = host(); |
636 if (!filter_host) | 662 if (!filter_host) |
637 return; | 663 return; |
638 | 664 |
639 filter_host->SetLoaded(loaded_); | 665 filter_host->SetLoaded(loaded_); |
640 | 666 |
641 if (streaming_) { | 667 if (streaming_) { |
642 filter_host->SetStreaming(true); | 668 filter_host->SetStreaming(true); |
643 } else { | 669 } else { |
644 filter_host->SetTotalBytes(total_bytes_); | 670 filter_host->SetTotalBytes(total_bytes_); |
645 filter_host->SetBufferedBytes(buffered_bytes_); | 671 filter_host->SetBufferedBytes(buffered_bytes_); |
646 } | 672 } |
647 } | 673 } |
648 | 674 |
649 } // namespace webkit_glue | 675 } // namespace webkit_glue |
OLD | NEW |