Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(676)

Unified Diff: media/blink/buffered_data_source.cc

Issue 2272163002: Delete now deprecated BufferedDataSource and friends. (Closed)
Patch Set: Delete BufferedResourceLoader too. Created 4 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « media/blink/buffered_data_source.h ('k') | media/blink/buffered_data_source_host_impl.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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
« no previous file with comments | « media/blink/buffered_data_source.h ('k') | media/blink/buffered_data_source_host_impl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698