| 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/message_loop.h" | 8 #include "base/message_loop.h" |
| 9 #include "media/base/media_log.h" | 9 #include "media/base/media_log.h" |
| 10 #include "net/base/net_errors.h" | 10 #include "net/base/net_errors.h" |
| 11 | 11 |
| 12 using WebKit::WebFrame; | 12 using WebKit::WebFrame; |
| 13 | 13 |
| 14 namespace webkit_media { | 14 namespace webkit_media { |
| 15 | 15 |
| 16 // BufferedDataSource has an intermediate buffer, this value governs the initial | 16 // 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 | 17 // size of that buffer. It is set to 32KB because this is a typical read size |
| 18 // of FFmpeg. | 18 // of FFmpeg. |
| 19 static const int kInitialReadBufferSize = 32768; | 19 static const int kInitialReadBufferSize = 32768; |
| 20 | 20 |
| 21 // Number of cache misses we allow for a single Read() before signalling an | 21 // Number of cache misses we allow for a single Read() before signalling an |
| 22 // error. | 22 // error. |
| 23 static const int kNumCacheMissRetries = 3; | 23 static const int kNumCacheMissRetries = 3; |
| 24 | 24 |
| 25 BufferedDataSource::BufferedDataSource( | 25 BufferedDataSource::BufferedDataSource( |
| 26 MessageLoop* render_loop, | 26 MessageLoop* render_loop, |
| 27 WebFrame* frame, | 27 WebFrame* frame, |
| 28 media::MediaLog* media_log) | 28 media::MediaLog* media_log, |
| 29 const DownloadingCB& downloading_cb) |
| 29 : total_bytes_(kPositionNotSpecified), | 30 : total_bytes_(kPositionNotSpecified), |
| 30 buffered_bytes_(0), | 31 buffered_bytes_(0), |
| 31 streaming_(false), | 32 streaming_(false), |
| 32 frame_(frame), | 33 frame_(frame), |
| 33 loader_(NULL), | 34 loader_(NULL), |
| 34 is_downloading_data_(false), | |
| 35 read_size_(0), | 35 read_size_(0), |
| 36 read_buffer_(NULL), | 36 read_buffer_(NULL), |
| 37 last_read_start_(0), | 37 last_read_start_(0), |
| 38 intermediate_read_buffer_(new uint8[kInitialReadBufferSize]), | 38 intermediate_read_buffer_(new uint8[kInitialReadBufferSize]), |
| 39 intermediate_read_buffer_size_(kInitialReadBufferSize), | 39 intermediate_read_buffer_size_(kInitialReadBufferSize), |
| 40 render_loop_(render_loop), | 40 render_loop_(render_loop), |
| 41 stop_signal_received_(false), | 41 stop_signal_received_(false), |
| 42 stopped_on_render_loop_(false), | 42 stopped_on_render_loop_(false), |
| 43 media_has_played_(false), | 43 media_has_played_(false), |
| 44 preload_(AUTO), | 44 preload_(AUTO), |
| 45 cache_miss_retries_left_(kNumCacheMissRetries), | 45 cache_miss_retries_left_(kNumCacheMissRetries), |
| 46 bitrate_(0), | 46 bitrate_(0), |
| 47 playback_rate_(0.0), | 47 playback_rate_(0.0), |
| 48 media_log_(media_log) { | 48 media_log_(media_log), |
| 49 downloading_cb_(downloading_cb) { |
| 50 DCHECK(!downloading_cb_.is_null()); |
| 49 } | 51 } |
| 50 | 52 |
| 51 BufferedDataSource::~BufferedDataSource() {} | 53 BufferedDataSource::~BufferedDataSource() {} |
| 52 | 54 |
| 53 // A factory method to create BufferedResourceLoader using the read parameters. | 55 // A factory method to create BufferedResourceLoader using the read parameters. |
| 54 // This method can be overrided to inject mock BufferedResourceLoader object | 56 // This method can be overrided to inject mock BufferedResourceLoader object |
| 55 // for testing purpose. | 57 // for testing purpose. |
| 56 BufferedResourceLoader* BufferedDataSource::CreateResourceLoader( | 58 BufferedResourceLoader* BufferedDataSource::CreateResourceLoader( |
| 57 int64 first_byte_position, int64 last_byte_position) { | 59 int64 first_byte_position, int64 last_byte_position) { |
| 58 DCHECK(MessageLoop::current() == render_loop_); | 60 DCHECK(MessageLoop::current() == render_loop_); |
| (...skipping 483 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 542 | 544 |
| 543 void BufferedDataSource::NetworkEventCallback() { | 545 void BufferedDataSource::NetworkEventCallback() { |
| 544 DCHECK(MessageLoop::current() == render_loop_); | 546 DCHECK(MessageLoop::current() == render_loop_); |
| 545 DCHECK(loader_.get()); | 547 DCHECK(loader_.get()); |
| 546 | 548 |
| 547 // In case of non-HTTP request we don't need to report network events, | 549 // In case of non-HTTP request we don't need to report network events, |
| 548 // so return immediately. | 550 // so return immediately. |
| 549 if (!url_.SchemeIs(kHttpScheme) && !url_.SchemeIs(kHttpsScheme)) | 551 if (!url_.SchemeIs(kHttpScheme) && !url_.SchemeIs(kHttpsScheme)) |
| 550 return; | 552 return; |
| 551 | 553 |
| 552 bool is_downloading_data = loader_->is_downloading_data(); | 554 downloading_cb_.Run(loader_->is_downloading_data()); |
| 555 |
| 553 int64 current_buffered_position = loader_->GetBufferedPosition(); | 556 int64 current_buffered_position = loader_->GetBufferedPosition(); |
| 554 | 557 |
| 555 // If we get an unspecified value, return immediately. | 558 // If we get an unspecified value, return immediately. |
| 556 if (current_buffered_position == kPositionNotSpecified) | 559 if (current_buffered_position == kPositionNotSpecified) |
| 557 return; | 560 return; |
| 558 | 561 |
| 559 // We need to prevent calling to filter host and running the callback if | 562 // We need to prevent calling to filter host and running the callback if |
| 560 // we have received the stop signal. We need to lock down the whole callback | 563 // we have received the stop signal. We need to lock down the whole callback |
| 561 // method to prevent bad things from happening. The reason behind this is | 564 // method to prevent bad things from happening. The reason behind this is |
| 562 // that we cannot guarantee tasks on render thread have completely stopped | 565 // that we cannot guarantee tasks on render thread have completely stopped |
| 563 // when we receive the Stop() method call. So only way to solve this is to | 566 // when we receive the Stop() method call. So only way to solve this is to |
| 564 // let tasks on render thread to run but make sure they don't call outside | 567 // let tasks on render thread to run but make sure they don't call outside |
| 565 // this object when Stop() method is ever called. Locking this method is safe | 568 // this object when Stop() method is ever called. Locking this method is safe |
| 566 // because |lock_| is only acquired in tasks on render thread. | 569 // because |lock_| is only acquired in tasks on render thread. |
| 567 base::AutoLock auto_lock(lock_); | 570 base::AutoLock auto_lock(lock_); |
| 568 if (stop_signal_received_) | 571 if (stop_signal_received_) |
| 569 return; | 572 return; |
| 570 | 573 |
| 571 if (is_downloading_data != is_downloading_data_) { | |
| 572 is_downloading_data_ = is_downloading_data; | |
| 573 if (host()) | |
| 574 host()->SetNetworkActivity(is_downloading_data); | |
| 575 } | |
| 576 | |
| 577 int64 start = loader_->first_byte_position(); | 574 int64 start = loader_->first_byte_position(); |
| 578 if (host() && current_buffered_position > start) | 575 if (host() && current_buffered_position > start) |
| 579 host()->AddBufferedByteRange(start, current_buffered_position); | 576 host()->AddBufferedByteRange(start, current_buffered_position); |
| 580 } | 577 } |
| 581 | 578 |
| 582 void BufferedDataSource::UpdateHostState_Locked() { | 579 void BufferedDataSource::UpdateHostState_Locked() { |
| 583 // Called from various threads, under lock. | 580 // Called from various threads, under lock. |
| 584 lock_.AssertAcquired(); | 581 lock_.AssertAcquired(); |
| 585 | 582 |
| 586 if (!host()) | 583 if (!host()) |
| 587 return; | 584 return; |
| 588 | 585 |
| 589 if (total_bytes_ != kPositionNotSpecified) | 586 if (total_bytes_ != kPositionNotSpecified) |
| 590 host()->SetTotalBytes(total_bytes_); | 587 host()->SetTotalBytes(total_bytes_); |
| 591 int64 start = loader_->first_byte_position(); | 588 int64 start = loader_->first_byte_position(); |
| 592 if (buffered_bytes_ > start) | 589 if (buffered_bytes_ > start) |
| 593 host()->AddBufferedByteRange(start, buffered_bytes_); | 590 host()->AddBufferedByteRange(start, buffered_bytes_); |
| 594 } | 591 } |
| 595 | 592 |
| 596 } // namespace webkit_media | 593 } // namespace webkit_media |
| OLD | NEW |