1868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 51320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "media/blink/buffered_data_source.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h" 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/callback_helpers.h" 91320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/single_thread_task_runner.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "media/base/media_log.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/net_errors.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)using blink::WebFrame; 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// BufferedDataSource has an intermediate buffer, this value governs the initial 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// size of that buffer. It is set to 32KB because this is a typical read size 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// of FFmpeg. 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kInitialReadBufferSize = 32768; 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Number of cache misses we allow for a single Read() before signaling an 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// error. 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kNumCacheMissRetries = 3; 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccinamespace media { 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class BufferedDataSource::ReadOperation { 312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public: 322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ReadOperation(int64 position, int size, uint8* data, 331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const DataSource::ReadCB& callback); 342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ~ReadOperation(); 352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Runs |callback_| with the given |result|, deleting the operation 372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // afterwards. 382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) static void Run(scoped_ptr<ReadOperation> read_op, int result); 392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // State for the number of times this read operation has been retried. 412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int retries() { return retries_; } 422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void IncrementRetries() { ++retries_; } 432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int64 position() { return position_; } 452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int size() { return size_; } 462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) uint8* data() { return data_; } 472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private: 492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int retries_; 502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const int64 position_; 522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const int size_; 532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) uint8* data_; 541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DataSource::ReadCB callback_; 552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DISALLOW_IMPLICIT_CONSTRUCTORS(ReadOperation); 572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)BufferedDataSource::ReadOperation::ReadOperation( 602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int64 position, int size, uint8* data, 611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const DataSource::ReadCB& callback) 622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : retries_(0), 632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) position_(position), 642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) size_(size), 652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) data_(data), 662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) callback_(callback) { 672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!callback_.is_null()); 682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)BufferedDataSource::ReadOperation::~ReadOperation() { 712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(callback_.is_null()); 722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// static 752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void BufferedDataSource::ReadOperation::Run( 762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<ReadOperation> read_op, int result) { 772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::ResetAndReturn(&read_op->callback_).Run(result); 782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BufferedDataSource::BufferedDataSource( 8146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) const GURL& url, 8246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) BufferedResourceLoader::CORSMode cors_mode, 831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const scoped_refptr<base::SingleThreadTaskRunner>& task_runner, 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WebFrame* frame, 851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci MediaLog* media_log, 86c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch BufferedDataSourceHost* host, 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const DownloadingCB& downloading_cb) 8846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) : url_(url), 8946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) cors_mode_(cors_mode), 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) total_bytes_(kPositionNotSpecified), 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) streaming_(false), 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) frame_(frame), 931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci intermediate_read_buffer_(kInitialReadBufferSize), 941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci render_task_runner_(task_runner), 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) stop_signal_received_(false), 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) media_has_played_(false), 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) preload_(AUTO), 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bitrate_(0), 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) playback_rate_(0.0), 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) media_log_(media_log), 101c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch host_(host), 102f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) downloading_cb_(downloading_cb), 103f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) weak_factory_(this) { 104c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch DCHECK(host_); 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!downloading_cb_.is_null()); 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BufferedDataSource::~BufferedDataSource() {} 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A factory method to create BufferedResourceLoader using the read parameters. 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This method can be overridden to inject mock BufferedResourceLoader object 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// for testing purpose. 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BufferedResourceLoader* BufferedDataSource::CreateResourceLoader( 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64 first_byte_position, int64 last_byte_position) { 1151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(render_task_runner_->BelongsToCurrentThread()); 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BufferedResourceLoader::DeferStrategy strategy = preload_ == METADATA ? 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BufferedResourceLoader::kReadThenDefer : 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BufferedResourceLoader::kCapacityDefer; 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return new BufferedResourceLoader(url_, 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cors_mode_, 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) first_byte_position, 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) last_byte_position, 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) strategy, 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bitrate_, 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) playback_rate_, 128868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) media_log_.get()); 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)void BufferedDataSource::Initialize(const InitializeCB& init_cb) { 1321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(render_task_runner_->BelongsToCurrentThread()); 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!init_cb.is_null()); 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!loader_.get()); 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) init_cb_ = init_cb; 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 13846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (url_.SchemeIsHTTPOrHTTPS()) { 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Do an unbounded range request starting at the beginning. If the server 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // responds with 200 instead of 206 we'll fall back into a streaming mode. 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) loader_.reset(CreateResourceLoader(0, kPositionNotSpecified)); 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // For all other protocols, assume they support range request. We fetch 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the full range of the resource to obtain the instance size because 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // we won't be served HTTP headers. 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) loader_.reset(CreateResourceLoader(kPositionNotSpecified, 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kPositionNotSpecified)); 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 15023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) base::WeakPtr<BufferedDataSource> weak_this = weak_factory_.GetWeakPtr(); 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) loader_->Start( 15223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) base::Bind(&BufferedDataSource::StartCallback, weak_this), 15323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) base::Bind(&BufferedDataSource::LoadingStateChangedCallback, weak_this), 15423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) base::Bind(&BufferedDataSource::ProgressCallback, weak_this), 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) frame_); 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BufferedDataSource::SetPreload(Preload preload) { 1591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(render_task_runner_->BelongsToCurrentThread()); 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) preload_ = preload; 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool BufferedDataSource::HasSingleOrigin() { 1641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(render_task_runner_->BelongsToCurrentThread()); 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(init_cb_.is_null() && loader_.get()) 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << "Initialize() must complete before calling HasSingleOrigin()"; 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return loader_->HasSingleOrigin(); 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool BufferedDataSource::DidPassCORSAccessCheck() const { 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return loader_.get() && loader_->DidPassCORSAccessCheck(); 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BufferedDataSource::Abort() { 1751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(render_task_runner_->BelongsToCurrentThread()); 1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { 1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::AutoLock auto_lock(lock_); 1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) StopInternal_Locked(); 1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) StopLoader(); 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) frame_ = NULL; 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1848bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void BufferedDataSource::MediaPlaybackRateChanged(float playback_rate) { 1851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(render_task_runner_->BelongsToCurrentThread()); 1864e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) DCHECK(loader_.get()); 1874e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1884e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) if (playback_rate < 0.0f) 1894e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) return; 1904e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1914e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) playback_rate_ = playback_rate; 1924e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) loader_->SetPlaybackRate(playback_rate); 1938bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)} 1944e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 1958bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void BufferedDataSource::MediaIsPlaying() { 1961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(render_task_runner_->BelongsToCurrentThread()); 1978bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) media_has_played_ = true; 1988bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) UpdateDeferStrategy(false); 1998bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)} 2008bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 2018bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void BufferedDataSource::MediaIsPaused() { 2021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(render_task_runner_->BelongsToCurrentThread()); 2038bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) UpdateDeferStrategy(true); 2044e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles)} 2054e180b6a0b4720a9b8e9e959a882386f690f08ffTorne (Richard Coles) 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)///////////////////////////////////////////////////////////////////////////// 2071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// DataSource implementation. 2085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)void BufferedDataSource::Stop() { 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::AutoLock auto_lock(lock_); 2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) StopInternal_Locked(); 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci render_task_runner_->PostTask( 21523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) FROM_HERE, 21623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) base::Bind(&BufferedDataSource::StopLoader, weak_factory_.GetWeakPtr())); 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BufferedDataSource::SetBitrate(int bitrate) { 2201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci render_task_runner_->PostTask(FROM_HERE, 22123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) base::Bind(&BufferedDataSource::SetBitrateTask, 22223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) weak_factory_.GetWeakPtr(), 22323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) bitrate)); 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BufferedDataSource::Read( 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64 position, int size, uint8* data, 2281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const DataSource::ReadCB& read_cb) { 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DVLOG(1) << "Read: " << position << " offset, " << size << " bytes"; 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!read_cb.is_null()); 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::AutoLock auto_lock(lock_); 2342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!read_op_); 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (stop_signal_received_) { 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) read_cb.Run(kReadError); 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) read_op_.reset(new ReadOperation(position, size, data, read_cb)); 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci render_task_runner_->PostTask( 24523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) FROM_HERE, 24623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) base::Bind(&BufferedDataSource::ReadTask, weak_factory_.GetWeakPtr())); 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool BufferedDataSource::GetSize(int64* size_out) { 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (total_bytes_ != kPositionNotSpecified) { 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *size_out = total_bytes_; 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *size_out = 0; 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool BufferedDataSource::IsStreaming() { 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return streaming_; 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)///////////////////////////////////////////////////////////////////////////// 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Render thread tasks. 2642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void BufferedDataSource::ReadTask() { 2651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(render_task_runner_->BelongsToCurrentThread()); 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReadInternal(); 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void BufferedDataSource::StopInternal_Locked() { 2702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) lock_.AssertAcquired(); 2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (stop_signal_received_) 2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) stop_signal_received_ = true; 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Initialize() isn't part of the DataSource interface so don't call it in 2772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // response to Stop(). 2782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) init_cb_.Reset(); 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (read_op_) 2812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ReadOperation::Run(read_op_.Pass(), kReadError); 2822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void BufferedDataSource::StopLoader() { 2851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(render_task_runner_->BelongsToCurrentThread()); 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 287b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) if (loader_) 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) loader_->Stop(); 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BufferedDataSource::SetBitrateTask(int bitrate) { 2921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(render_task_runner_->BelongsToCurrentThread()); 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(loader_.get()); 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bitrate_ = bitrate; 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) loader_->SetBitrate(bitrate); 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This method is the place where actual read happens, |loader_| must be valid 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// prior to make this method call. 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BufferedDataSource::ReadInternal() { 3021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(render_task_runner_->BelongsToCurrentThread()); 3032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int64 position = 0; 3042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int size = 0; 3052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) { 3062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::AutoLock auto_lock(lock_); 3072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (stop_signal_received_) 3082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 3092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) position = read_op_->position(); 3112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) size = read_op_->size(); 3122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // First we prepare the intermediate read buffer for BufferedResourceLoader 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // to write to. 3161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (static_cast<int>(intermediate_read_buffer_.size()) < size) 3171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci intermediate_read_buffer_.resize(size); 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Perform the actual read with BufferedResourceLoader. 3201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(!intermediate_read_buffer_.empty()); 32123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) loader_->Read(position, 32223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) size, 3231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci &intermediate_read_buffer_[0], 32423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) base::Bind(&BufferedDataSource::ReadCallback, 32523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) weak_factory_.GetWeakPtr())); 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)///////////////////////////////////////////////////////////////////////////// 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// BufferedResourceLoader callback methods. 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BufferedDataSource::StartCallback( 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BufferedResourceLoader::Status status) { 3331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(render_task_runner_->BelongsToCurrentThread()); 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(loader_.get()); 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool init_cb_is_null = false; 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::AutoLock auto_lock(lock_); 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) init_cb_is_null = init_cb_.is_null(); 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (init_cb_is_null) { 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) loader_->Stop(); 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // All responses must be successful. Resources that are assumed to be fully 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // buffered must have a known content length. 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool success = status == BufferedResourceLoader::kOk && 34946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) (!assume_fully_buffered() || 35046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) loader_->instance_size() != kPositionNotSpecified); 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (success) { 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) total_bytes_ = loader_->instance_size(); 35446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) streaming_ = 35546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) !assume_fully_buffered() && 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (total_bytes_ == kPositionNotSpecified || !loader_->range_supported()); 35758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 35858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) media_log_->SetDoubleProperty("total_bytes", 35958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) static_cast<double>(total_bytes_)); 36058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) media_log_->SetBooleanProperty("streaming", streaming_); 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) loader_->Stop(); 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(scherkus): we shouldn't have to lock to signal host(), see 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // http://crbug.com/113712 for details. 367c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::AutoLock auto_lock(lock_); 368c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (stop_signal_received_) 369c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 37158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) if (success) { 372c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (total_bytes_ != kPositionNotSpecified) { 373c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch host_->SetTotalBytes(total_bytes_); 37446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (assume_fully_buffered()) 375c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch host_->AddBufferedByteRange(0, total_bytes_); 376c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch } 377c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch 37858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) media_log_->SetBooleanProperty("single_origin", loader_->HasSingleOrigin()); 37958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) media_log_->SetBooleanProperty("passed_cors_access_check", 38058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) loader_->DidPassCORSAccessCheck()); 38158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) media_log_->SetBooleanProperty("range_header_supported", 38258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) loader_->range_supported()); 38358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 385c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::ResetAndReturn(&init_cb_).Run(success); 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BufferedDataSource::PartialReadStartCallback( 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BufferedResourceLoader::Status status) { 3901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(render_task_runner_->BelongsToCurrentThread()); 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(loader_.get()); 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (status == BufferedResourceLoader::kOk) { 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Once the request has started successfully, we can proceed with 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // reading from it. 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReadInternal(); 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Stop the resource loader since we have received an error. 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) loader_->Stop(); 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(scherkus): we shouldn't have to lock to signal host(), see 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // http://crbug.com/113712 for details. 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::AutoLock auto_lock(lock_); 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (stop_signal_received_) 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 4082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ReadOperation::Run(read_op_.Pass(), kReadError); 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BufferedDataSource::ReadCallback( 4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BufferedResourceLoader::Status status, 4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int bytes_read) { 4141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(render_task_runner_->BelongsToCurrentThread()); 4152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // TODO(scherkus): we shouldn't have to lock to signal host(), see 4172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // http://crbug.com/113712 for details. 4182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::AutoLock auto_lock(lock_); 4192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (stop_signal_received_) 4202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return; 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (status != BufferedResourceLoader::kOk) { 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Stop the resource load if it failed. 4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) loader_->Stop(); 4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (status == BufferedResourceLoader::kCacheMiss && 4272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) read_op_->retries() < kNumCacheMissRetries) { 4282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) read_op_->IncrementRetries(); 4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Recreate a loader starting from where we last left off until the 4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // end of the resource. 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) loader_.reset(CreateResourceLoader( 4332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) read_op_->position(), kPositionNotSpecified)); 43423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 43523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) base::WeakPtr<BufferedDataSource> weak_this = weak_factory_.GetWeakPtr(); 4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) loader_->Start( 43723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) base::Bind(&BufferedDataSource::PartialReadStartCallback, weak_this), 438c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::Bind(&BufferedDataSource::LoadingStateChangedCallback, 43923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) weak_this), 44023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) base::Bind(&BufferedDataSource::ProgressCallback, weak_this), 4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) frame_); 4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ReadOperation::Run(read_op_.Pass(), kReadError); 4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 4472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (bytes_read > 0) { 4501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(!intermediate_read_buffer_.empty()); 4511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci memcpy(read_op_->data(), &intermediate_read_buffer_[0], bytes_read); 4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (bytes_read == 0 && total_bytes_ == kPositionNotSpecified) { 4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We've reached the end of the file and we didn't know the total size 4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // before. Update the total size so Read()s past the end of the file will 4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // fail like they would if we had known the file size at the beginning. 4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) total_bytes_ = loader_->instance_size(); 4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 458c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch if (total_bytes_ != kPositionNotSpecified) { 459c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch host_->SetTotalBytes(total_bytes_); 460c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch host_->AddBufferedByteRange(loader_->first_byte_position(), 461c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch total_bytes_); 4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ReadOperation::Run(read_op_.Pass(), bytes_read); 4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BufferedDataSource::LoadingStateChangedCallback( 4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BufferedResourceLoader::LoadingState state) { 4691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(render_task_runner_->BelongsToCurrentThread()); 4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 47146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (assume_fully_buffered()) 4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool is_downloading_data; 4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (state) { 4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case BufferedResourceLoader::kLoading: 4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) is_downloading_data = true; 4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case BufferedResourceLoader::kLoadingDeferred: 4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case BufferedResourceLoader::kLoadingFinished: 4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) is_downloading_data = false; 4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(scherkus): we don't signal network activity changes when loads 4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // fail to preserve existing behaviour when deferring is toggled, however 4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // we should consider changing DownloadingCB to also propagate loading 4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // state. For example there isn't any signal today to notify the client that 4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // loading has failed (we only get errors on subsequent reads). 4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case BufferedResourceLoader::kLoadingFailed: 4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) downloading_cb_.Run(is_downloading_data); 4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void BufferedDataSource::ProgressCallback(int64 position) { 4971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DCHECK(render_task_runner_->BelongsToCurrentThread()); 4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 49946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) if (assume_fully_buffered()) 5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(scherkus): we shouldn't have to lock to signal host(), see 5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // http://crbug.com/113712 for details. 5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::AutoLock auto_lock(lock_); 5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (stop_signal_received_) 5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 508c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch host_->AddBufferedByteRange(loader_->first_byte_position(), position); 5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5118bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)void BufferedDataSource::UpdateDeferStrategy(bool paused) { 512f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // No need to aggressively buffer when we are assuming the resource is fully 513f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // buffered. 514f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (assume_fully_buffered()) { 5158bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) loader_->UpdateDeferStrategy(BufferedResourceLoader::kCapacityDefer); 5168bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return; 5178bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 5188bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 5198bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // If the playback has started (at which point the preload value is ignored) 5208bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // and we're paused, then try to load as much as possible (the loader will 5218bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // fall back to kCapacityDefer if it knows the current response won't be 5228bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) // useful from the cache in the future). 523f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) if (media_has_played_ && paused && loader_->range_supported()) { 5248bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) loader_->UpdateDeferStrategy(BufferedResourceLoader::kNeverDefer); 5258bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) return; 5268bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) } 5278bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 528f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // If media is currently playing or the page indicated preload=auto or the 529f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // the server does not support the byte range request or we do not want to go 530f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // too far ahead of the read head, use threshold strategy to enable/disable 531f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // deferring when the buffer is full/depleted. 5328bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) loader_->UpdateDeferStrategy(BufferedResourceLoader::kCapacityDefer); 5338bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles)} 5348bcbed890bc3ce4d7a057a8f32cab53fa534672eTorne (Richard Coles) 5351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} // namespace media 536