| Index: webkit/glue/media/buffered_data_source.cc
|
| diff --git a/webkit/glue/media/buffered_data_source.cc b/webkit/glue/media/buffered_data_source.cc
|
| deleted file mode 100644
|
| index a3f43cf5d2bb218d092bfcb8f9b73a0c512215db..0000000000000000000000000000000000000000
|
| --- a/webkit/glue/media/buffered_data_source.cc
|
| +++ /dev/null
|
| @@ -1,672 +0,0 @@
|
| -// Copyright (c) 2011 The Chromium Authors. All rights reserved.
|
| -// Use of this source code is governed by a BSD-style license that can be
|
| -// found in the LICENSE file.
|
| -
|
| -#include "webkit/glue/media/buffered_data_source.h"
|
| -
|
| -#include "base/bind.h"
|
| -#include "media/base/filter_host.h"
|
| -#include "media/base/media_log.h"
|
| -#include "net/base/net_errors.h"
|
| -#include "webkit/glue/media/web_data_source_factory.h"
|
| -#include "webkit/glue/webkit_glue.h"
|
| -
|
| -using WebKit::WebFrame;
|
| -
|
| -namespace webkit_glue {
|
| -
|
| -// BufferedDataSource has an intermediate buffer, this value governs the initial
|
| -// size of that buffer. It is set to 32KB because this is a typical read size
|
| -// of FFmpeg.
|
| -static const int kInitialReadBufferSize = 32768;
|
| -
|
| -// Number of cache misses we allow for a single Read() before signalling an
|
| -// error.
|
| -static const int kNumCacheMissRetries = 3;
|
| -
|
| -static WebDataSource* NewBufferedDataSource(MessageLoop* render_loop,
|
| - WebKit::WebFrame* frame,
|
| - media::MediaLog* media_log) {
|
| - return new BufferedDataSource(render_loop, frame, media_log);
|
| -}
|
| -
|
| -// static
|
| -media::DataSourceFactory* BufferedDataSource::CreateFactory(
|
| - MessageLoop* render_loop,
|
| - WebKit::WebFrame* frame,
|
| - media::MediaLog* media_log,
|
| - const WebDataSourceBuildObserverHack& build_observer) {
|
| - return new WebDataSourceFactory(render_loop, frame, media_log,
|
| - &NewBufferedDataSource, build_observer);
|
| -}
|
| -
|
| -BufferedDataSource::BufferedDataSource(
|
| - MessageLoop* render_loop,
|
| - WebFrame* frame,
|
| - media::MediaLog* media_log)
|
| - : total_bytes_(kPositionNotSpecified),
|
| - buffered_bytes_(0),
|
| - loaded_(false),
|
| - streaming_(false),
|
| - frame_(frame),
|
| - loader_(NULL),
|
| - is_downloading_data_(false),
|
| - read_position_(0),
|
| - read_size_(0),
|
| - read_buffer_(NULL),
|
| - intermediate_read_buffer_(new uint8[kInitialReadBufferSize]),
|
| - intermediate_read_buffer_size_(kInitialReadBufferSize),
|
| - render_loop_(render_loop),
|
| - stop_signal_received_(false),
|
| - stopped_on_render_loop_(false),
|
| - media_is_paused_(true),
|
| - media_has_played_(false),
|
| - preload_(media::AUTO),
|
| - using_range_request_(true),
|
| - cache_miss_retries_left_(kNumCacheMissRetries),
|
| - bitrate_(0),
|
| - playback_rate_(0.0),
|
| - media_log_(media_log) {
|
| -}
|
| -
|
| -BufferedDataSource::~BufferedDataSource() {}
|
| -
|
| -// A factory method to create BufferedResourceLoader using the read parameters.
|
| -// This method can be overrided to inject mock BufferedResourceLoader object
|
| -// for testing purpose.
|
| -BufferedResourceLoader* BufferedDataSource::CreateResourceLoader(
|
| - int64 first_byte_position, int64 last_byte_position) {
|
| - DCHECK(MessageLoop::current() == render_loop_);
|
| -
|
| - return new BufferedResourceLoader(url_,
|
| - first_byte_position,
|
| - last_byte_position,
|
| - ChooseDeferStrategy(),
|
| - bitrate_,
|
| - playback_rate_,
|
| - media_log_);
|
| -}
|
| -
|
| -void BufferedDataSource::set_host(media::FilterHost* host) {
|
| - DataSource::set_host(host);
|
| -
|
| - if (loader_.get()) {
|
| - base::AutoLock auto_lock(lock_);
|
| - UpdateHostState_Locked();
|
| - }
|
| -}
|
| -
|
| -void BufferedDataSource::Initialize(const std::string& url,
|
| - const media::PipelineStatusCB& callback) {
|
| - // Saves the url.
|
| - url_ = GURL(url);
|
| -
|
| - // This data source doesn't support data:// protocol so reject it.
|
| - if (url_.SchemeIs(kDataScheme)) {
|
| - callback.Run(media::DATASOURCE_ERROR_URL_NOT_SUPPORTED);
|
| - return;
|
| - } else if (!IsProtocolSupportedForMedia(url_)) {
|
| - callback.Run(media::PIPELINE_ERROR_NETWORK);
|
| - return;
|
| - }
|
| -
|
| - DCHECK(!callback.is_null());
|
| - {
|
| - base::AutoLock auto_lock(lock_);
|
| - initialize_cb_ = callback;
|
| - }
|
| -
|
| - // Post a task to complete the initialization task.
|
| - render_loop_->PostTask(FROM_HERE,
|
| - base::Bind(&BufferedDataSource::InitializeTask, this));
|
| -}
|
| -
|
| -void BufferedDataSource::CancelInitialize() {
|
| - base::AutoLock auto_lock(lock_);
|
| - DCHECK(!initialize_cb_.is_null());
|
| -
|
| - initialize_cb_.Reset();
|
| -
|
| - render_loop_->PostTask(
|
| - FROM_HERE, base::Bind(&BufferedDataSource::CleanupTask, this));
|
| -}
|
| -
|
| -/////////////////////////////////////////////////////////////////////////////
|
| -// media::Filter implementation.
|
| -void BufferedDataSource::Stop(const base::Closure& callback) {
|
| - {
|
| - base::AutoLock auto_lock(lock_);
|
| - stop_signal_received_ = true;
|
| - }
|
| - if (!callback.is_null())
|
| - callback.Run();
|
| -
|
| - render_loop_->PostTask(FROM_HERE,
|
| - base::Bind(&BufferedDataSource::CleanupTask, this));
|
| -}
|
| -
|
| -void BufferedDataSource::SetPlaybackRate(float playback_rate) {
|
| - render_loop_->PostTask(FROM_HERE, base::Bind(
|
| - &BufferedDataSource::SetPlaybackRateTask, this, playback_rate));
|
| -}
|
| -
|
| -void BufferedDataSource::SetPreload(media::Preload preload) {
|
| - render_loop_->PostTask(FROM_HERE, base::Bind(
|
| - &BufferedDataSource::SetPreloadTask, this, preload));
|
| -}
|
| -
|
| -void BufferedDataSource::SetBitrate(int bitrate) {
|
| - render_loop_->PostTask(FROM_HERE, base::Bind(
|
| - &BufferedDataSource::SetBitrateTask, this, bitrate));
|
| -}
|
| -
|
| -/////////////////////////////////////////////////////////////////////////////
|
| -// media::DataSource implementation.
|
| -void BufferedDataSource::Read(
|
| - int64 position, size_t size, uint8* data,
|
| - const media::DataSource::ReadCallback& read_callback) {
|
| - VLOG(1) << "Read: " << position << " offset, " << size << " bytes";
|
| - DCHECK(!read_callback.is_null());
|
| -
|
| - {
|
| - base::AutoLock auto_lock(lock_);
|
| - DCHECK(read_callback_.is_null());
|
| -
|
| - if (stop_signal_received_ || stopped_on_render_loop_) {
|
| - read_callback.Run(kReadError);
|
| - return;
|
| - }
|
| -
|
| - read_callback_ = read_callback;
|
| - }
|
| -
|
| - render_loop_->PostTask(FROM_HERE, base::Bind(
|
| - &BufferedDataSource::ReadTask, this,
|
| - position, static_cast<int>(size), data));
|
| -}
|
| -
|
| -bool BufferedDataSource::GetSize(int64* size_out) {
|
| - if (total_bytes_ != kPositionNotSpecified) {
|
| - *size_out = total_bytes_;
|
| - return true;
|
| - }
|
| - *size_out = 0;
|
| - return false;
|
| -}
|
| -
|
| -bool BufferedDataSource::IsStreaming() {
|
| - return streaming_;
|
| -}
|
| -
|
| -bool BufferedDataSource::HasSingleOrigin() {
|
| - DCHECK(MessageLoop::current() == render_loop_);
|
| - return loader_.get() ? loader_->HasSingleOrigin() : true;
|
| -}
|
| -
|
| -void BufferedDataSource::Abort() {
|
| - DCHECK(MessageLoop::current() == render_loop_);
|
| -
|
| - CleanupTask();
|
| - frame_ = NULL;
|
| -}
|
| -
|
| -/////////////////////////////////////////////////////////////////////////////
|
| -// Render thread tasks.
|
| -void BufferedDataSource::InitializeTask() {
|
| - DCHECK(MessageLoop::current() == render_loop_);
|
| - DCHECK(!loader_.get());
|
| -
|
| - {
|
| - base::AutoLock auto_lock(lock_);
|
| - if (stopped_on_render_loop_ || initialize_cb_.is_null() ||
|
| - stop_signal_received_) {
|
| - return;
|
| - }
|
| - }
|
| -
|
| - if (url_.SchemeIs(kHttpScheme) || url_.SchemeIs(kHttpsScheme)) {
|
| - // Do an unbounded range request starting at the beginning. If the server
|
| - // responds with 200 instead of 206 we'll fall back into a streaming mode.
|
| - loader_ = CreateResourceLoader(0, kPositionNotSpecified);
|
| - loader_->Start(
|
| - NewCallback(this, &BufferedDataSource::HttpInitialStartCallback),
|
| - base::Bind(&BufferedDataSource::NetworkEventCallback, this),
|
| - frame_);
|
| - } else {
|
| - // For all other protocols, assume they support range request. We fetch
|
| - // the full range of the resource to obtain the instance size because
|
| - // we won't be served HTTP headers.
|
| - loader_ = CreateResourceLoader(kPositionNotSpecified,
|
| - kPositionNotSpecified);
|
| - loader_->Start(
|
| - NewCallback(this, &BufferedDataSource::NonHttpInitialStartCallback),
|
| - base::Bind(&BufferedDataSource::NetworkEventCallback, this),
|
| - frame_);
|
| - }
|
| -}
|
| -
|
| -void BufferedDataSource::ReadTask(
|
| - int64 position,
|
| - int read_size,
|
| - uint8* buffer) {
|
| - DCHECK(MessageLoop::current() == render_loop_);
|
| - {
|
| - base::AutoLock auto_lock(lock_);
|
| - if (stopped_on_render_loop_)
|
| - return;
|
| -
|
| - DCHECK(!read_callback_.is_null());
|
| - }
|
| -
|
| - // Saves the read parameters.
|
| - read_position_ = position;
|
| - read_size_ = read_size;
|
| - read_buffer_ = buffer;
|
| - cache_miss_retries_left_ = kNumCacheMissRetries;
|
| -
|
| - // Call to read internal to perform the actual read.
|
| - ReadInternal();
|
| -}
|
| -
|
| -void BufferedDataSource::CleanupTask() {
|
| - DCHECK(MessageLoop::current() == render_loop_);
|
| -
|
| - {
|
| - base::AutoLock auto_lock(lock_);
|
| - initialize_cb_.Reset();
|
| - if (stopped_on_render_loop_)
|
| - return;
|
| -
|
| - // Signal that stop task has finished execution.
|
| - // NOTE: it's vital that this be set under lock, as that's how Read() tests
|
| - // before registering a new |read_callback_| (which is cleared below).
|
| - stopped_on_render_loop_ = true;
|
| -
|
| - if (!read_callback_.is_null())
|
| - DoneRead_Locked(net::ERR_FAILED);
|
| - }
|
| -
|
| - // We just need to stop the loader, so it stops activity.
|
| - if (loader_.get())
|
| - loader_->Stop();
|
| -
|
| - // Reset the parameters of the current read request.
|
| - read_position_ = 0;
|
| - read_size_ = 0;
|
| - read_buffer_ = 0;
|
| -}
|
| -
|
| -void BufferedDataSource::RestartLoadingTask() {
|
| - DCHECK(MessageLoop::current() == render_loop_);
|
| - if (stopped_on_render_loop_)
|
| - return;
|
| -
|
| - {
|
| - // If there's no outstanding read then return early.
|
| - base::AutoLock auto_lock(lock_);
|
| - if (read_callback_.is_null())
|
| - return;
|
| - }
|
| -
|
| - loader_ = CreateResourceLoader(read_position_, kPositionNotSpecified);
|
| - loader_->Start(
|
| - NewCallback(this, &BufferedDataSource::PartialReadStartCallback),
|
| - base::Bind(&BufferedDataSource::NetworkEventCallback, this),
|
| - frame_);
|
| -}
|
| -
|
| -void BufferedDataSource::SetPlaybackRateTask(float playback_rate) {
|
| - DCHECK(MessageLoop::current() == render_loop_);
|
| - DCHECK(loader_.get());
|
| -
|
| - playback_rate_ = playback_rate;
|
| - loader_->SetPlaybackRate(playback_rate);
|
| -
|
| - bool previously_paused = media_is_paused_;
|
| - media_is_paused_ = (playback_rate == 0.0);
|
| -
|
| - if (!media_has_played_ && previously_paused && !media_is_paused_)
|
| - media_has_played_ = true;
|
| -
|
| - BufferedResourceLoader::DeferStrategy strategy = ChooseDeferStrategy();
|
| - loader_->UpdateDeferStrategy(strategy);
|
| -}
|
| -
|
| -void BufferedDataSource::SetPreloadTask(media::Preload preload) {
|
| - DCHECK(MessageLoop::current() == render_loop_);
|
| - preload_ = preload;
|
| -}
|
| -
|
| -void BufferedDataSource::SetBitrateTask(int bitrate) {
|
| - DCHECK(MessageLoop::current() == render_loop_);
|
| - DCHECK(loader_.get());
|
| -
|
| - bitrate_ = bitrate;
|
| - loader_->SetBitrate(bitrate);
|
| -}
|
| -
|
| -BufferedResourceLoader::DeferStrategy
|
| -BufferedDataSource::ChooseDeferStrategy() {
|
| - DCHECK(MessageLoop::current() == render_loop_);
|
| - // If the page indicated preload=metadata, then load exactly what is needed
|
| - // needed for starting playback.
|
| - if (!media_has_played_ && preload_ == media::METADATA)
|
| - return BufferedResourceLoader::kReadThenDefer;
|
| -
|
| - // If the playback has started (at which point the preload value is ignored)
|
| - // and we're paused, then try to load as much as possible.
|
| - if (media_has_played_ && media_is_paused_)
|
| - return BufferedResourceLoader::kNeverDefer;
|
| -
|
| - // If media is currently playing or the page indicated preload=auto,
|
| - // use threshold strategy to enable/disable deferring when the buffer
|
| - // is full/depleted.
|
| - return BufferedResourceLoader::kThresholdDefer;
|
| -}
|
| -
|
| -// This method is the place where actual read happens, |loader_| must be valid
|
| -// prior to make this method call.
|
| -void BufferedDataSource::ReadInternal() {
|
| - DCHECK(MessageLoop::current() == render_loop_);
|
| - DCHECK(loader_);
|
| -
|
| - // First we prepare the intermediate read buffer for BufferedResourceLoader
|
| - // to write to.
|
| - if (read_size_ > intermediate_read_buffer_size_) {
|
| - intermediate_read_buffer_.reset(new uint8[read_size_]);
|
| - }
|
| -
|
| - // Perform the actual read with BufferedResourceLoader.
|
| - loader_->Read(read_position_, read_size_, intermediate_read_buffer_.get(),
|
| - NewCallback(this, &BufferedDataSource::ReadCallback));
|
| -}
|
| -
|
| -// Method to report the results of the current read request. Also reset all
|
| -// the read parameters.
|
| -void BufferedDataSource::DoneRead_Locked(int error) {
|
| - VLOG(1) << "DoneRead: " << error << " bytes";
|
| -
|
| - DCHECK(MessageLoop::current() == render_loop_);
|
| - DCHECK(!read_callback_.is_null());
|
| - lock_.AssertAcquired();
|
| -
|
| - if (error >= 0) {
|
| - read_callback_.Run(static_cast<size_t>(error));
|
| - } else {
|
| - read_callback_.Run(kReadError);
|
| - }
|
| -
|
| - read_callback_.Reset();
|
| - read_position_ = 0;
|
| - read_size_ = 0;
|
| - read_buffer_ = 0;
|
| -}
|
| -
|
| -void BufferedDataSource::DoneInitialization_Locked(
|
| - media::PipelineStatus status) {
|
| - DCHECK(MessageLoop::current() == render_loop_);
|
| - DCHECK(!initialize_cb_.is_null());
|
| - lock_.AssertAcquired();
|
| -
|
| - initialize_cb_.Run(status);
|
| - initialize_cb_.Reset();
|
| -}
|
| -
|
| -/////////////////////////////////////////////////////////////////////////////
|
| -// BufferedResourceLoader callback methods.
|
| -void BufferedDataSource::HttpInitialStartCallback(int error) {
|
| - DCHECK(MessageLoop::current() == render_loop_);
|
| - DCHECK(loader_.get());
|
| -
|
| - int64 instance_size = loader_->instance_size();
|
| - bool success = error == net::OK;
|
| -
|
| - bool initialize_cb_is_null = false;
|
| - {
|
| - base::AutoLock auto_lock(lock_);
|
| - initialize_cb_is_null = initialize_cb_.is_null();
|
| - }
|
| - if (initialize_cb_is_null) {
|
| - loader_->Stop();
|
| - return;
|
| - }
|
| -
|
| - if (success) {
|
| - // TODO(hclam): Needs more thinking about supporting servers without range
|
| - // request or their partial response is not complete.
|
| - total_bytes_ = instance_size;
|
| - loaded_ = false;
|
| - streaming_ = (instance_size == kPositionNotSpecified) ||
|
| - !loader_->range_supported();
|
| - } else {
|
| - // TODO(hclam): In case of failure, we can retry several times.
|
| - loader_->Stop();
|
| - }
|
| -
|
| - if (error == net::ERR_INVALID_RESPONSE && using_range_request_) {
|
| - // Assuming that the Range header was causing the problem. Retry without
|
| - // the Range header.
|
| - using_range_request_ = false;
|
| - loader_ = CreateResourceLoader(kPositionNotSpecified,
|
| - kPositionNotSpecified);
|
| - loader_->Start(
|
| - NewCallback(this, &BufferedDataSource::HttpInitialStartCallback),
|
| - base::Bind(&BufferedDataSource::NetworkEventCallback, this),
|
| - frame_);
|
| - return;
|
| - }
|
| -
|
| - // Reference to prevent destruction while inside the |initialize_cb_|
|
| - // call. This is a temporary fix to prevent crashes caused by holding the
|
| - // lock and running the destructor.
|
| - // TODO: Review locking in this class and figure out a way to run the callback
|
| - // w/o the lock.
|
| - scoped_refptr<BufferedDataSource> destruction_guard(this);
|
| - {
|
| - // We need to prevent calling to filter host and running the callback if
|
| - // we have received the stop signal. We need to lock down the whole callback
|
| - // method to prevent bad things from happening. The reason behind this is
|
| - // that we cannot guarantee tasks on render thread have completely stopped
|
| - // when we receive the Stop() method call. The only way to solve this is to
|
| - // let tasks on render thread to run but make sure they don't call outside
|
| - // this object when Stop() method is ever called. Locking this method is
|
| - // safe because |lock_| is only acquired in tasks on render thread.
|
| - base::AutoLock auto_lock(lock_);
|
| - if (stop_signal_received_)
|
| - return;
|
| -
|
| - if (!success) {
|
| - DoneInitialization_Locked(media::PIPELINE_ERROR_NETWORK);
|
| - return;
|
| - }
|
| -
|
| - UpdateHostState_Locked();
|
| - DoneInitialization_Locked(media::PIPELINE_OK);
|
| - }
|
| -}
|
| -
|
| -void BufferedDataSource::NonHttpInitialStartCallback(int error) {
|
| - DCHECK(MessageLoop::current() == render_loop_);
|
| - DCHECK(loader_.get());
|
| -
|
| - bool initialize_cb_is_null = false;
|
| - {
|
| - base::AutoLock auto_lock(lock_);
|
| - initialize_cb_is_null = initialize_cb_.is_null();
|
| - }
|
| - if (initialize_cb_is_null) {
|
| - loader_->Stop();
|
| - return;
|
| - }
|
| -
|
| - int64 instance_size = loader_->instance_size();
|
| - bool success = error == net::OK && instance_size != kPositionNotSpecified;
|
| -
|
| - if (success) {
|
| - total_bytes_ = instance_size;
|
| - buffered_bytes_ = total_bytes_;
|
| - loaded_ = true;
|
| - } else {
|
| - loader_->Stop();
|
| - }
|
| -
|
| - // Reference to prevent destruction while inside the |initialize_cb_|
|
| - // call. This is a temporary fix to prevent crashes caused by holding the
|
| - // lock and running the destructor.
|
| - // TODO: Review locking in this class and figure out a way to run the callback
|
| - // w/o the lock.
|
| - scoped_refptr<BufferedDataSource> destruction_guard(this);
|
| - {
|
| - // We need to prevent calling to filter host and running the callback if
|
| - // we have received the stop signal. We need to lock down the whole callback
|
| - // method to prevent bad things from happening. The reason behind this is
|
| - // that we cannot guarantee tasks on render thread have completely stopped
|
| - // when we receive the Stop() method call. The only way to solve this is to
|
| - // let tasks on render thread to run but make sure they don't call outside
|
| - // this object when Stop() method is ever called. Locking this method is
|
| - // safe because |lock_| is only acquired in tasks on render thread.
|
| - base::AutoLock auto_lock(lock_);
|
| - if (stop_signal_received_ || initialize_cb_.is_null())
|
| - return;
|
| -
|
| - if (!success) {
|
| - DoneInitialization_Locked(media::PIPELINE_ERROR_NETWORK);
|
| - return;
|
| - }
|
| -
|
| - UpdateHostState_Locked();
|
| - DoneInitialization_Locked(media::PIPELINE_OK);
|
| - }
|
| -}
|
| -
|
| -void BufferedDataSource::PartialReadStartCallback(int error) {
|
| - DCHECK(MessageLoop::current() == render_loop_);
|
| - DCHECK(loader_.get());
|
| -
|
| - if (error == net::OK) {
|
| - // Once the request has started successfully, we can proceed with
|
| - // reading from it.
|
| - ReadInternal();
|
| - return;
|
| - }
|
| -
|
| - // Stop the resource loader since we have received an error.
|
| - loader_->Stop();
|
| -
|
| - // We need to prevent calling to filter host and running the callback if
|
| - // we have received the stop signal. We need to lock down the whole callback
|
| - // method to prevent bad things from happening. The reason behind this is
|
| - // that we cannot guarantee tasks on render thread have completely stopped
|
| - // when we receive the Stop() method call. So only way to solve this is to
|
| - // let tasks on render thread to run but make sure they don't call outside
|
| - // this object when Stop() method is ever called. Locking this method is
|
| - // safe because |lock_| is only acquired in tasks on render thread.
|
| - base::AutoLock auto_lock(lock_);
|
| - if (stop_signal_received_)
|
| - return;
|
| - DoneRead_Locked(net::ERR_INVALID_RESPONSE);
|
| -}
|
| -
|
| -void BufferedDataSource::ReadCallback(int error) {
|
| - DCHECK(MessageLoop::current() == render_loop_);
|
| -
|
| - if (error < 0) {
|
| - DCHECK(loader_.get());
|
| -
|
| - // Stop the resource load if it failed.
|
| - loader_->Stop();
|
| -
|
| - if (error == net::ERR_CACHE_MISS && cache_miss_retries_left_ > 0) {
|
| - cache_miss_retries_left_--;
|
| - render_loop_->PostTask(FROM_HERE,
|
| - base::Bind(&BufferedDataSource::RestartLoadingTask, this));
|
| - return;
|
| - }
|
| - }
|
| -
|
| - // We need to prevent calling to filter host and running the callback if
|
| - // we have received the stop signal. We need to lock down the whole callback
|
| - // method to prevent bad things from happening. The reason behind this is
|
| - // that we cannot guarantee tasks on render thread have completely stopped
|
| - // when we receive the Stop() method call. So only way to solve this is to
|
| - // let tasks on render thread to run but make sure they don't call outside
|
| - // this object when Stop() method is ever called. Locking this method is safe
|
| - // because |lock_| is only acquired in tasks on render thread.
|
| - base::AutoLock auto_lock(lock_);
|
| - if (stop_signal_received_)
|
| - return;
|
| -
|
| - if (error > 0) {
|
| - // If a position error code is received, read was successful. So copy
|
| - // from intermediate read buffer to the target read buffer.
|
| - memcpy(read_buffer_, intermediate_read_buffer_.get(), error);
|
| - } else if (error == 0 && total_bytes_ == kPositionNotSpecified) {
|
| - // We've reached the end of the file and we didn't know the total size
|
| - // before. Update the total size so Read()s past the end of the file will
|
| - // fail like they would if we had known the file size at the beginning.
|
| - total_bytes_ = loader_->instance_size();
|
| -
|
| - if (host() && total_bytes_ != kPositionNotSpecified)
|
| - host()->SetTotalBytes(total_bytes_);
|
| - }
|
| - DoneRead_Locked(error);
|
| -}
|
| -
|
| -void BufferedDataSource::NetworkEventCallback() {
|
| - DCHECK(MessageLoop::current() == render_loop_);
|
| - DCHECK(loader_.get());
|
| -
|
| - // In case of non-HTTP request we don't need to report network events,
|
| - // so return immediately.
|
| - if (loaded_)
|
| - return;
|
| -
|
| - bool is_downloading_data = loader_->is_downloading_data();
|
| - int64 buffered_position = loader_->GetBufferedPosition();
|
| -
|
| - // If we get an unspecified value, return immediately.
|
| - if (buffered_position == kPositionNotSpecified)
|
| - return;
|
| -
|
| - // We need to prevent calling to filter host and running the callback if
|
| - // we have received the stop signal. We need to lock down the whole callback
|
| - // method to prevent bad things from happening. The reason behind this is
|
| - // that we cannot guarantee tasks on render thread have completely stopped
|
| - // when we receive the Stop() method call. So only way to solve this is to
|
| - // let tasks on render thread to run but make sure they don't call outside
|
| - // this object when Stop() method is ever called. Locking this method is safe
|
| - // because |lock_| is only acquired in tasks on render thread.
|
| - base::AutoLock auto_lock(lock_);
|
| - if (stop_signal_received_)
|
| - return;
|
| -
|
| - if (is_downloading_data != is_downloading_data_) {
|
| - is_downloading_data_ = is_downloading_data;
|
| - if (host())
|
| - host()->SetNetworkActivity(is_downloading_data);
|
| - }
|
| -
|
| - buffered_bytes_ = buffered_position + 1;
|
| - if (host())
|
| - host()->SetBufferedBytes(buffered_bytes_);
|
| -}
|
| -
|
| -void BufferedDataSource::UpdateHostState_Locked() {
|
| - // Called from various threads, under lock.
|
| - lock_.AssertAcquired();
|
| -
|
| - media::FilterHost* filter_host = host();
|
| - if (!filter_host)
|
| - return;
|
| -
|
| - filter_host->SetLoaded(loaded_);
|
| -
|
| - if (streaming_) {
|
| - filter_host->SetStreaming(true);
|
| - } else {
|
| - filter_host->SetTotalBytes(total_bytes_);
|
| - filter_host->SetBufferedBytes(buffered_bytes_);
|
| - }
|
| -}
|
| -
|
| -} // namespace webkit_glue
|
|
|