| Index: media/blink/buffered_data_source.cc
|
| diff --git a/media/blink/buffered_data_source.cc b/media/blink/buffered_data_source.cc
|
| deleted file mode 100644
|
| index 4894f3782967ae9fbcb979fd155c3b5642046f4a..0000000000000000000000000000000000000000
|
| --- a/media/blink/buffered_data_source.cc
|
| +++ /dev/null
|
| @@ -1,634 +0,0 @@
|
| -// Copyright 2013 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 "media/blink/buffered_data_source.h"
|
| -
|
| -#include <utility>
|
| -
|
| -#include "base/bind.h"
|
| -#include "base/callback_helpers.h"
|
| -#include "base/location.h"
|
| -#include "base/macros.h"
|
| -#include "base/single_thread_task_runner.h"
|
| -#include "build/build_config.h"
|
| -#include "media/base/media_log.h"
|
| -#include "net/base/net_errors.h"
|
| -
|
| -using blink::WebFrame;
|
| -
|
| -namespace {
|
| -
|
| -// 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.
|
| -const int kInitialReadBufferSize = 32768;
|
| -
|
| -// The number of milliseconds to wait before retrying a failed load.
|
| -const int kLoaderFailedRetryDelayMs = 250;
|
| -
|
| -// Each retry, add this many MS to the delay.
|
| -// total delay is:
|
| -// (kLoaderPartialRetryDelayMs +
|
| -// kAdditionalDelayPerRetryMs * (kMaxRetries - 1) / 2) * kLoaderRetries
|
| -// = 29250 ms
|
| -const int kAdditionalDelayPerRetryMs = 50;
|
| -
|
| -} // namespace
|
| -
|
| -namespace media {
|
| -
|
| -class BufferedDataSource::ReadOperation {
|
| - public:
|
| - ReadOperation(int64_t position,
|
| - int size,
|
| - uint8_t* data,
|
| - const DataSource::ReadCB& callback);
|
| - ~ReadOperation();
|
| -
|
| - // Runs |callback_| with the given |result|, deleting the operation
|
| - // afterwards.
|
| - static void Run(std::unique_ptr<ReadOperation> read_op, int result);
|
| -
|
| - // State for the number of times this read operation has been retried.
|
| - int retries() { return retries_; }
|
| - void IncrementRetries() { ++retries_; }
|
| -
|
| - int64_t position() { return position_; }
|
| - int size() { return size_; }
|
| - uint8_t* data() { return data_; }
|
| -
|
| - private:
|
| - int retries_;
|
| -
|
| - const int64_t position_;
|
| - const int size_;
|
| - uint8_t* data_;
|
| - DataSource::ReadCB callback_;
|
| -
|
| - DISALLOW_IMPLICIT_CONSTRUCTORS(ReadOperation);
|
| -};
|
| -
|
| -BufferedDataSource::ReadOperation::ReadOperation(
|
| - int64_t position,
|
| - int size,
|
| - uint8_t* data,
|
| - const DataSource::ReadCB& callback)
|
| - : retries_(0),
|
| - position_(position),
|
| - size_(size),
|
| - data_(data),
|
| - callback_(callback) {
|
| - DCHECK(!callback_.is_null());
|
| -}
|
| -
|
| -BufferedDataSource::ReadOperation::~ReadOperation() {
|
| - DCHECK(callback_.is_null());
|
| -}
|
| -
|
| -// static
|
| -void BufferedDataSource::ReadOperation::Run(
|
| - std::unique_ptr<ReadOperation> read_op,
|
| - int result) {
|
| - base::ResetAndReturn(&read_op->callback_).Run(result);
|
| -}
|
| -
|
| -BufferedDataSource::BufferedDataSource(
|
| - const GURL& url,
|
| - BufferedResourceLoader::CORSMode cors_mode,
|
| - const scoped_refptr<base::SingleThreadTaskRunner>& task_runner,
|
| - WebFrame* frame,
|
| - MediaLog* media_log,
|
| - BufferedDataSourceHost* host,
|
| - const DownloadingCB& downloading_cb)
|
| - : url_(url),
|
| - cors_mode_(cors_mode),
|
| - total_bytes_(kPositionNotSpecified),
|
| - streaming_(false),
|
| - frame_(frame),
|
| - intermediate_read_buffer_(kInitialReadBufferSize),
|
| - render_task_runner_(task_runner),
|
| - stop_signal_received_(false),
|
| - media_has_played_(false),
|
| - buffering_strategy_(BUFFERING_STRATEGY_NORMAL),
|
| - preload_(AUTO),
|
| - bitrate_(0),
|
| - playback_rate_(0.0),
|
| - media_log_(media_log),
|
| - host_(host),
|
| - downloading_cb_(downloading_cb),
|
| - weak_factory_(this) {
|
| - weak_ptr_ = weak_factory_.GetWeakPtr();
|
| - DCHECK(host_);
|
| - DCHECK(!downloading_cb_.is_null());
|
| - DCHECK(render_task_runner_->BelongsToCurrentThread());
|
| -}
|
| -
|
| -BufferedDataSource::~BufferedDataSource() {
|
| - DCHECK(render_task_runner_->BelongsToCurrentThread());
|
| -}
|
| -
|
| -bool BufferedDataSource::media_has_played() const {
|
| - return media_has_played_;
|
| -}
|
| -
|
| -bool BufferedDataSource::assume_fully_buffered() {
|
| - return !url_.SchemeIsHTTPOrHTTPS();
|
| -}
|
| -
|
| -// A factory method to create BufferedResourceLoader using the read parameters.
|
| -// This method can be overridden to inject mock BufferedResourceLoader object
|
| -// for testing purpose.
|
| -BufferedResourceLoader* BufferedDataSource::CreateResourceLoader(
|
| - int64_t first_byte_position,
|
| - int64_t last_byte_position) {
|
| - DCHECK(render_task_runner_->BelongsToCurrentThread());
|
| -
|
| - BufferedResourceLoader::DeferStrategy strategy = preload_ == METADATA ?
|
| - BufferedResourceLoader::kReadThenDefer :
|
| - BufferedResourceLoader::kCapacityDefer;
|
| -
|
| - return new BufferedResourceLoader(url_,
|
| - cors_mode_,
|
| - first_byte_position,
|
| - last_byte_position,
|
| - strategy,
|
| - bitrate_,
|
| - playback_rate_,
|
| - media_log_.get());
|
| -}
|
| -
|
| -void BufferedDataSource::Initialize(const InitializeCB& init_cb) {
|
| - DCHECK(render_task_runner_->BelongsToCurrentThread());
|
| - DCHECK(!init_cb.is_null());
|
| - DCHECK(!loader_.get());
|
| -
|
| - init_cb_ = init_cb;
|
| -
|
| - if (url_.SchemeIsHTTPOrHTTPS()) {
|
| - // 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_.reset(CreateResourceLoader(0, kPositionNotSpecified));
|
| - } 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_.reset(CreateResourceLoader(kPositionNotSpecified,
|
| - kPositionNotSpecified));
|
| - }
|
| -
|
| - base::WeakPtr<BufferedDataSource> weak_this = weak_factory_.GetWeakPtr();
|
| - loader_->Start(
|
| - base::Bind(&BufferedDataSource::StartCallback, weak_this),
|
| - base::Bind(&BufferedDataSource::LoadingStateChangedCallback, weak_this),
|
| - base::Bind(&BufferedDataSource::ProgressCallback, weak_this),
|
| - frame_);
|
| -}
|
| -
|
| -void BufferedDataSource::SetPreload(Preload preload) {
|
| - DCHECK(render_task_runner_->BelongsToCurrentThread());
|
| - preload_ = preload;
|
| -}
|
| -
|
| -void BufferedDataSource::SetBufferingStrategy(
|
| - BufferingStrategy buffering_strategy) {
|
| - DCHECK(render_task_runner_->BelongsToCurrentThread());
|
| - buffering_strategy_ = buffering_strategy;
|
| - UpdateDeferStrategy();
|
| -}
|
| -
|
| -bool BufferedDataSource::HasSingleOrigin() {
|
| - DCHECK(render_task_runner_->BelongsToCurrentThread());
|
| - DCHECK(init_cb_.is_null() && loader_.get())
|
| - << "Initialize() must complete before calling HasSingleOrigin()";
|
| - return loader_->HasSingleOrigin();
|
| -}
|
| -
|
| -bool BufferedDataSource::DidPassCORSAccessCheck() const {
|
| - return loader_.get() && loader_->DidPassCORSAccessCheck();
|
| -}
|
| -
|
| -void BufferedDataSource::Abort() {
|
| - DCHECK(render_task_runner_->BelongsToCurrentThread());
|
| - {
|
| - base::AutoLock auto_lock(lock_);
|
| - StopInternal_Locked();
|
| - }
|
| - StopLoader();
|
| - frame_ = NULL;
|
| -}
|
| -
|
| -void BufferedDataSource::MediaPlaybackRateChanged(double playback_rate) {
|
| - DCHECK(render_task_runner_->BelongsToCurrentThread());
|
| - DCHECK(loader_.get());
|
| -
|
| - if (playback_rate < 0.0)
|
| - return;
|
| -
|
| - playback_rate_ = playback_rate;
|
| - loader_->SetPlaybackRate(playback_rate);
|
| -}
|
| -
|
| -void BufferedDataSource::MediaIsPlaying() {
|
| - DCHECK(render_task_runner_->BelongsToCurrentThread());
|
| - media_has_played_ = true;
|
| - UpdateDeferStrategy();
|
| -}
|
| -
|
| -/////////////////////////////////////////////////////////////////////////////
|
| -// DataSource implementation.
|
| -void BufferedDataSource::Stop() {
|
| - {
|
| - base::AutoLock auto_lock(lock_);
|
| - StopInternal_Locked();
|
| - }
|
| -
|
| - render_task_runner_->PostTask(
|
| - FROM_HERE,
|
| - base::Bind(&BufferedDataSource::StopLoader, weak_factory_.GetWeakPtr()));
|
| -}
|
| -
|
| -void BufferedDataSource::SetBitrate(int bitrate) {
|
| - render_task_runner_->PostTask(FROM_HERE,
|
| - base::Bind(&BufferedDataSource::SetBitrateTask,
|
| - weak_factory_.GetWeakPtr(),
|
| - bitrate));
|
| -}
|
| -
|
| -void BufferedDataSource::OnBufferingHaveEnough(bool always_cancel) {
|
| - DCHECK(render_task_runner_->BelongsToCurrentThread());
|
| - if (loader_ && (always_cancel || (preload_ == METADATA &&
|
| - !media_has_played_ && !IsStreaming()))) {
|
| - loader_->CancelUponDeferral();
|
| - }
|
| -}
|
| -
|
| -int64_t BufferedDataSource::GetMemoryUsage() const {
|
| - DCHECK(render_task_runner_->BelongsToCurrentThread());
|
| - return loader_ ? loader_->GetMemoryUsage() : 0;
|
| -}
|
| -
|
| -GURL BufferedDataSource::GetUrlAfterRedirects() const {
|
| - return response_original_url_;
|
| -}
|
| -
|
| -void BufferedDataSource::Read(int64_t position,
|
| - int size,
|
| - uint8_t* data,
|
| - const DataSource::ReadCB& read_cb) {
|
| - DVLOG(1) << "Read: " << position << " offset, " << size << " bytes";
|
| - DCHECK(!read_cb.is_null());
|
| -
|
| - {
|
| - base::AutoLock auto_lock(lock_);
|
| - DCHECK(!read_op_);
|
| -
|
| - if (stop_signal_received_) {
|
| - read_cb.Run(kReadError);
|
| - return;
|
| - }
|
| -
|
| - read_op_.reset(new ReadOperation(position, size, data, read_cb));
|
| - }
|
| -
|
| - render_task_runner_->PostTask(
|
| - FROM_HERE,
|
| - base::Bind(&BufferedDataSource::ReadTask, weak_factory_.GetWeakPtr()));
|
| -}
|
| -
|
| -bool BufferedDataSource::GetSize(int64_t* size_out) {
|
| - if (total_bytes_ != kPositionNotSpecified) {
|
| - *size_out = total_bytes_;
|
| - return true;
|
| - }
|
| - *size_out = 0;
|
| - return false;
|
| -}
|
| -
|
| -bool BufferedDataSource::IsStreaming() {
|
| - return streaming_;
|
| -}
|
| -
|
| -/////////////////////////////////////////////////////////////////////////////
|
| -// Render thread tasks.
|
| -void BufferedDataSource::ReadTask() {
|
| - DCHECK(render_task_runner_->BelongsToCurrentThread());
|
| - ReadInternal();
|
| -}
|
| -
|
| -void BufferedDataSource::StopInternal_Locked() {
|
| - lock_.AssertAcquired();
|
| - if (stop_signal_received_)
|
| - return;
|
| -
|
| - stop_signal_received_ = true;
|
| -
|
| - // Initialize() isn't part of the DataSource interface so don't call it in
|
| - // response to Stop().
|
| - init_cb_.Reset();
|
| -
|
| - if (read_op_)
|
| - ReadOperation::Run(std::move(read_op_), kReadError);
|
| -}
|
| -
|
| -void BufferedDataSource::StopLoader() {
|
| - DCHECK(render_task_runner_->BelongsToCurrentThread());
|
| -
|
| - if (loader_)
|
| - loader_->Stop();
|
| -}
|
| -
|
| -void BufferedDataSource::SetBitrateTask(int bitrate) {
|
| - DCHECK(render_task_runner_->BelongsToCurrentThread());
|
| - DCHECK(loader_.get());
|
| -
|
| - bitrate_ = bitrate;
|
| - loader_->SetBitrate(bitrate);
|
| -}
|
| -
|
| -// This method is the place where actual read happens, |loader_| must be valid
|
| -// prior to make this method call.
|
| -void BufferedDataSource::ReadInternal() {
|
| - DCHECK(render_task_runner_->BelongsToCurrentThread());
|
| - int64_t position = 0;
|
| - int size = 0;
|
| - {
|
| - base::AutoLock auto_lock(lock_);
|
| - if (stop_signal_received_)
|
| - return;
|
| -
|
| - position = read_op_->position();
|
| - size = read_op_->size();
|
| - }
|
| -
|
| - // First we prepare the intermediate read buffer for BufferedResourceLoader
|
| - // to write to.
|
| - if (static_cast<int>(intermediate_read_buffer_.size()) < size)
|
| - intermediate_read_buffer_.resize(size);
|
| -
|
| - // Perform the actual read with BufferedResourceLoader.
|
| - DCHECK(!intermediate_read_buffer_.empty());
|
| - loader_->Read(position,
|
| - size,
|
| - &intermediate_read_buffer_[0],
|
| - base::Bind(&BufferedDataSource::ReadCallback,
|
| - weak_factory_.GetWeakPtr()));
|
| -}
|
| -
|
| -
|
| -/////////////////////////////////////////////////////////////////////////////
|
| -// BufferedResourceLoader callback methods.
|
| -void BufferedDataSource::StartCallback(
|
| - BufferedResourceLoader::Status status) {
|
| - DCHECK(render_task_runner_->BelongsToCurrentThread());
|
| - DCHECK(loader_.get());
|
| -
|
| - bool init_cb_is_null = false;
|
| - {
|
| - base::AutoLock auto_lock(lock_);
|
| - init_cb_is_null = init_cb_.is_null();
|
| - }
|
| - if (init_cb_is_null) {
|
| - loader_->Stop();
|
| - return;
|
| - }
|
| -
|
| - response_original_url_ = loader_->response_original_url();
|
| -#if defined(OS_ANDROID)
|
| - // The response original url is the URL of this resource after following
|
| - // redirects. Update |url_| to this so that we only follow redirects once.
|
| - // We do this on Android only to preserve the behavior we had before the
|
| - // unified media pipeline. This behavior will soon exist on all platforms
|
| - // as we switch to MultiBufferDataSource (http://crbug.com/514719).
|
| - // If the response URL is empty (which happens when it's from a Service
|
| - // Worker), keep the original one.
|
| - if (!response_original_url_.is_empty())
|
| - url_ = response_original_url_;
|
| -#endif // defined(OS_ANDROID)
|
| -
|
| - // All responses must be successful. Resources that are assumed to be fully
|
| - // buffered must have a known content length.
|
| - bool success = status == BufferedResourceLoader::kOk &&
|
| - (!assume_fully_buffered() ||
|
| - loader_->instance_size() != kPositionNotSpecified);
|
| -
|
| - if (success) {
|
| - total_bytes_ = loader_->instance_size();
|
| - streaming_ =
|
| - !assume_fully_buffered() &&
|
| - (total_bytes_ == kPositionNotSpecified || !loader_->range_supported());
|
| -
|
| - media_log_->SetDoubleProperty("total_bytes",
|
| - static_cast<double>(total_bytes_));
|
| - media_log_->SetBooleanProperty("streaming", streaming_);
|
| - } else {
|
| - loader_->Stop();
|
| - }
|
| -
|
| - // TODO(scherkus): we shouldn't have to lock to signal host(), see
|
| - // http://crbug.com/113712 for details.
|
| - base::AutoLock auto_lock(lock_);
|
| - if (stop_signal_received_)
|
| - return;
|
| -
|
| - if (success) {
|
| - if (total_bytes_ != kPositionNotSpecified) {
|
| - host_->SetTotalBytes(total_bytes_);
|
| - if (assume_fully_buffered())
|
| - host_->AddBufferedByteRange(0, total_bytes_);
|
| - }
|
| -
|
| - media_log_->SetBooleanProperty("single_origin", loader_->HasSingleOrigin());
|
| - media_log_->SetBooleanProperty("passed_cors_access_check",
|
| - loader_->DidPassCORSAccessCheck());
|
| - media_log_->SetBooleanProperty("range_header_supported",
|
| - loader_->range_supported());
|
| - }
|
| -
|
| - render_task_runner_->PostTask(
|
| - FROM_HERE, base::Bind(base::ResetAndReturn(&init_cb_), success));
|
| -}
|
| -
|
| -void BufferedDataSource::PartialReadStartCallback(
|
| - BufferedResourceLoader::Status status) {
|
| - DCHECK(render_task_runner_->BelongsToCurrentThread());
|
| - DCHECK(loader_.get());
|
| - if (status == BufferedResourceLoader::kOk &&
|
| - CheckPartialResponseURL(loader_->response_original_url())) {
|
| - // 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();
|
| -
|
| - // TODO(scherkus): we shouldn't have to lock to signal host(), see
|
| - // http://crbug.com/113712 for details.
|
| - base::AutoLock auto_lock(lock_);
|
| - if (stop_signal_received_)
|
| - return;
|
| - ReadOperation::Run(std::move(read_op_), kReadError);
|
| -}
|
| -
|
| -bool BufferedDataSource::CheckPartialResponseURL(
|
| - const GURL& partial_response_original_url) const {
|
| - // We check the redirected URL of partial responses in case malicious
|
| - // attackers scan the bytes of other origin resources by mixing their
|
| - // generated bytes and the target response. See http://crbug.com/489060#c32
|
| - // for details.
|
| - // If the origin of the new response is different from the first response we
|
| - // deny the redirected response unless the crossorigin attribute has been set.
|
| - if ((response_original_url_.GetOrigin() ==
|
| - partial_response_original_url.GetOrigin()) ||
|
| - DidPassCORSAccessCheck()) {
|
| - return true;
|
| - }
|
| -
|
| - MEDIA_LOG(ERROR, media_log_) << "BufferedDataSource: origin has changed";
|
| - return false;
|
| -}
|
| -
|
| -void BufferedDataSource::ReadCallback(
|
| - BufferedResourceLoader::Status status,
|
| - int bytes_read) {
|
| - DCHECK(render_task_runner_->BelongsToCurrentThread());
|
| -
|
| - // TODO(scherkus): we shouldn't have to lock to signal host(), see
|
| - // http://crbug.com/113712 for details.
|
| - base::AutoLock auto_lock(lock_);
|
| - if (stop_signal_received_)
|
| - return;
|
| -
|
| - if (status != BufferedResourceLoader::kOk) {
|
| - // Stop the resource load if it failed.
|
| - loader_->Stop();
|
| -
|
| - if (read_op_->retries() < kLoaderRetries) {
|
| - // Allow some resiliency against sporadic network failures or intentional
|
| - // cancellations due to a system suspend / resume. Here we treat failed
|
| - // reads as a cache miss so long as we haven't exceeded max retries.
|
| - if (status == BufferedResourceLoader::kFailed) {
|
| - render_task_runner_->PostDelayedTask(
|
| - FROM_HERE, base::Bind(&BufferedDataSource::ReadCallback,
|
| - weak_factory_.GetWeakPtr(),
|
| - BufferedResourceLoader::kCacheMiss, 0),
|
| - base::TimeDelta::FromMilliseconds(kLoaderFailedRetryDelayMs +
|
| - read_op_->retries() *
|
| - kAdditionalDelayPerRetryMs));
|
| - return;
|
| - }
|
| -
|
| - read_op_->IncrementRetries();
|
| -
|
| - // Recreate a loader starting from where we last left off until the
|
| - // end of the resource.
|
| - loader_.reset(CreateResourceLoader(
|
| - read_op_->position(), kPositionNotSpecified));
|
| -
|
| - base::WeakPtr<BufferedDataSource> weak_this = weak_factory_.GetWeakPtr();
|
| - loader_->Start(
|
| - base::Bind(&BufferedDataSource::PartialReadStartCallback, weak_this),
|
| - base::Bind(&BufferedDataSource::LoadingStateChangedCallback,
|
| - weak_this),
|
| - base::Bind(&BufferedDataSource::ProgressCallback, weak_this),
|
| - frame_);
|
| - return;
|
| - }
|
| -
|
| - ReadOperation::Run(std::move(read_op_), kReadError);
|
| - return;
|
| - }
|
| -
|
| - if (bytes_read > 0) {
|
| - DCHECK(!intermediate_read_buffer_.empty());
|
| - memcpy(read_op_->data(), &intermediate_read_buffer_[0], bytes_read);
|
| - } else if (bytes_read == 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 (total_bytes_ != kPositionNotSpecified) {
|
| - host_->SetTotalBytes(total_bytes_);
|
| - host_->AddBufferedByteRange(loader_->first_byte_position(),
|
| - total_bytes_);
|
| - }
|
| - }
|
| - ReadOperation::Run(std::move(read_op_), bytes_read);
|
| -}
|
| -
|
| -void BufferedDataSource::LoadingStateChangedCallback(
|
| - BufferedResourceLoader::LoadingState state) {
|
| - DCHECK(render_task_runner_->BelongsToCurrentThread());
|
| -
|
| - if (assume_fully_buffered())
|
| - return;
|
| -
|
| - bool is_downloading_data = false;
|
| - switch (state) {
|
| - case BufferedResourceLoader::kLoading:
|
| - is_downloading_data = true;
|
| - break;
|
| - case BufferedResourceLoader::kLoadingDeferred:
|
| - case BufferedResourceLoader::kLoadingFinished:
|
| - is_downloading_data = false;
|
| - break;
|
| -
|
| - // TODO(scherkus): we don't signal network activity changes when loads
|
| - // fail to preserve existing behaviour when deferring is toggled, however
|
| - // we should consider changing DownloadingCB to also propagate loading
|
| - // state. For example there isn't any signal today to notify the client that
|
| - // loading has failed (we only get errors on subsequent reads).
|
| - case BufferedResourceLoader::kLoadingFailed:
|
| - return;
|
| - }
|
| -
|
| - downloading_cb_.Run(is_downloading_data);
|
| -}
|
| -
|
| -void BufferedDataSource::ProgressCallback(int64_t position) {
|
| - DCHECK(render_task_runner_->BelongsToCurrentThread());
|
| -
|
| - if (assume_fully_buffered())
|
| - return;
|
| -
|
| - // TODO(scherkus): we shouldn't have to lock to signal host(), see
|
| - // http://crbug.com/113712 for details.
|
| - base::AutoLock auto_lock(lock_);
|
| - if (stop_signal_received_)
|
| - return;
|
| -
|
| - host_->AddBufferedByteRange(loader_->first_byte_position(), position);
|
| -}
|
| -
|
| -void BufferedDataSource::UpdateDeferStrategy() {
|
| - if (!loader_)
|
| - return;
|
| -
|
| - // No need to aggressively buffer when we are assuming the resource is fully
|
| - // buffered.
|
| - if (assume_fully_buffered()) {
|
| - loader_->UpdateDeferStrategy(BufferedResourceLoader::kCapacityDefer);
|
| - return;
|
| - }
|
| -
|
| - // If the playback has started (at which point the preload value is ignored)
|
| - // and the strategy is aggressive, then try to load as much as possible (the
|
| - // loader will fall back to kCapacityDefer if it knows the current response
|
| - // won't be useful from the cache in the future).
|
| - bool aggressive = (buffering_strategy_ == BUFFERING_STRATEGY_AGGRESSIVE);
|
| - if (media_has_played_ && aggressive && loader_->range_supported()) {
|
| - loader_->UpdateDeferStrategy(BufferedResourceLoader::kNeverDefer);
|
| - return;
|
| - }
|
| -
|
| - // If media is currently playing or the page indicated preload=auto or the
|
| - // the server does not support the byte range request or we do not want to go
|
| - // too far ahead of the read head, use threshold strategy to enable/disable
|
| - // deferring when the buffer is full/depleted.
|
| - loader_->UpdateDeferStrategy(BufferedResourceLoader::kCapacityDefer);
|
| -}
|
| -
|
| -} // namespace media
|
|
|