diff options
author | sandersd@chromium.org <sandersd@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-04-10 01:45:38 +0000 |
---|---|---|
committer | sandersd@chromium.org <sandersd@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-04-10 01:45:38 +0000 |
commit | 6683e1b251eb78a569fefcc15d1a64ca22a4421a (patch) | |
tree | 7285b3a75eaec9b5df51902b58d1f39598872daa /content/renderer/media | |
parent | c444768704686dcb3c243938bf91d48568ca91ce (diff) | |
download | chromium_src-6683e1b251eb78a569fefcc15d1a64ca22a4421a.zip chromium_src-6683e1b251eb78a569fefcc15d1a64ca22a4421a.tar.gz chromium_src-6683e1b251eb78a569fefcc15d1a64ca22a4421a.tar.bz2 |
Move DataSourceHost to BufferedDataSourceHost.
BUG=122071
Review URL: https://codereview.chromium.org/224093011
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@262892 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'content/renderer/media')
10 files changed, 238 insertions, 23 deletions
diff --git a/content/renderer/media/buffered_data_source.cc b/content/renderer/media/buffered_data_source.cc index c897499..8b2fc3a 100644 --- a/content/renderer/media/buffered_data_source.cc +++ b/content/renderer/media/buffered_data_source.cc @@ -7,6 +7,7 @@ #include "base/bind.h" #include "base/callback_helpers.h" #include "base/message_loop/message_loop_proxy.h" +#include "content/public/common/url_constants.h" #include "media/base/media_log.h" #include "net/base/net_errors.h" @@ -81,7 +82,7 @@ BufferedDataSource::BufferedDataSource( const scoped_refptr<base::MessageLoopProxy>& render_loop, WebFrame* frame, media::MediaLog* media_log, - media::DataSourceHost* host, + BufferedDataSourceHost* host, const DownloadingCB& downloading_cb) : cors_mode_(BufferedResourceLoader::kUnspecified), total_bytes_(kPositionNotSpecified), diff --git a/content/renderer/media/buffered_data_source.h b/content/renderer/media/buffered_data_source.h index 77b6278..40acdcd 100644 --- a/content/renderer/media/buffered_data_source.h +++ b/content/renderer/media/buffered_data_source.h @@ -27,6 +27,20 @@ class MediaLog; namespace content { +class CONTENT_EXPORT BufferedDataSourceHost { + public: + // Notify the host of the total size of the media file. + virtual void SetTotalBytes(int64 total_bytes) = 0; + + // Notify the host that byte range [start,end] has been buffered. + // TODO(fischman): remove this method when demuxing is push-based instead of + // pull-based. http://crbug.com/131444 + virtual void AddBufferedByteRange(int64 start, int64 end) = 0; + + protected: + virtual ~BufferedDataSourceHost() {}; +}; + // A data source capable of loading URLs and buffering the data using an // in-memory sliding window. // @@ -38,12 +52,10 @@ class CONTENT_EXPORT BufferedDataSource : public media::DataSource { // Buffered byte range changes will be reported to |host|. |downloading_cb| // will be called whenever the downloading/paused state of the source changes. - // TODO(sandersd): Move media::DataSourceHost to - // content::BufferedDataSourceHost. BufferedDataSource(const scoped_refptr<base::MessageLoopProxy>& render_loop, blink::WebFrame* frame, media::MediaLog* media_log, - media::DataSourceHost* host, + BufferedDataSourceHost* host, const DownloadingCB& downloading_cb); virtual ~BufferedDataSource(); @@ -206,7 +218,7 @@ class CONTENT_EXPORT BufferedDataSource : public media::DataSource { scoped_refptr<media::MediaLog> media_log_; // Host object to report buffered byte range changes to. - media::DataSourceHost* host_; + BufferedDataSourceHost* host_; DownloadingCB downloading_cb_; diff --git a/content/renderer/media/buffered_data_source_host_impl.cc b/content/renderer/media/buffered_data_source_host_impl.cc new file mode 100644 index 0000000..dd231f3 --- /dev/null +++ b/content/renderer/media/buffered_data_source_host_impl.cc @@ -0,0 +1,56 @@ +// Copyright 2014 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 "content/renderer/media/buffered_data_source_host_impl.h" + +namespace content { + +BufferedDataSourceHostImpl::BufferedDataSourceHostImpl() + : total_bytes_(0), + did_loading_progress_(false) { } + +BufferedDataSourceHostImpl::~BufferedDataSourceHostImpl() { } + +void BufferedDataSourceHostImpl::SetTotalBytes(int64 total_bytes) { + total_bytes_ = total_bytes; +} + +void BufferedDataSourceHostImpl::AddBufferedByteRange(int64 start, int64 end) { + buffered_byte_ranges_.Add(start, end); + did_loading_progress_ = true; +} + +static base::TimeDelta TimeForByteOffset( + int64 byte_offset, int64 total_bytes, base::TimeDelta duration) { + double position = static_cast<double>(byte_offset) / total_bytes; + // Snap to the beginning/end where the approximation can look especially bad. + if (position < 0.01) + return base::TimeDelta(); + if (position > 0.99) + return duration; + return base::TimeDelta::FromMilliseconds( + static_cast<int64>(position * duration.InMilliseconds())); +} + +void BufferedDataSourceHostImpl::AddBufferedTimeRanges( + media::Ranges<base::TimeDelta>* buffered_time_ranges, + base::TimeDelta media_duration) { + if (total_bytes_ && buffered_byte_ranges_.size()) { + for (size_t i = 0; i < buffered_byte_ranges_.size(); ++i) { + int64 start = buffered_byte_ranges_.start(i); + int64 end = buffered_byte_ranges_.end(i); + buffered_time_ranges->Add( + TimeForByteOffset(start, total_bytes_, media_duration), + TimeForByteOffset(end, total_bytes_, media_duration)); + } + } +} + +bool BufferedDataSourceHostImpl::DidLoadingProgress() const { + bool ret = did_loading_progress_; + did_loading_progress_ = false; + return ret; +} + +} // namespace content diff --git a/content/renderer/media/buffered_data_source_host_impl.h b/content/renderer/media/buffered_data_source_host_impl.h new file mode 100644 index 0000000..788050f --- /dev/null +++ b/content/renderer/media/buffered_data_source_host_impl.h @@ -0,0 +1,52 @@ +// Copyright 2014 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. + +#ifndef CONTENT_RENDERER_MEDIA_BUFFERED_DATA_SOURCE_HOST_IMPL_H_ +#define CONTENT_RENDERER_MEDIA_BUFFERED_DATA_SOURCE_HOST_IMPL_H_ + +#include "base/time/time.h" +#include "content/common/content_export.h" +#include "content/renderer/media/buffered_data_source.h" +#include "media/base/ranges.h" + +namespace content { + +// Provides an implementation of BufferedDataSourceHost that translates the +// buffered byte ranges into estimated time ranges. +class CONTENT_EXPORT BufferedDataSourceHostImpl + : public BufferedDataSourceHost { + public: + BufferedDataSourceHostImpl(); + virtual ~BufferedDataSourceHostImpl(); + + // BufferedDataSourceHost implementation. + virtual void SetTotalBytes(int64 total_bytes) OVERRIDE; + virtual void AddBufferedByteRange(int64 start, int64 end) OVERRIDE; + + // Translate the byte ranges to time ranges and append them to the list. + void AddBufferedTimeRanges( + media::Ranges<base::TimeDelta>* buffered_time_ranges, + base::TimeDelta media_duration); + + // TODO(sandersd): Change this to non-const along with Pipeline's version. + // http://crbug.com/360251 + bool DidLoadingProgress() const; + + private: + // Total size of the data source. + int64 total_bytes_; + + // List of buffered byte ranges for estimating buffered time. + media::Ranges<int64> buffered_byte_ranges_; + + // True when AddBufferedByteRange() has been called more recently than + // DidLoadingProgress(). + mutable bool did_loading_progress_; + + DISALLOW_COPY_AND_ASSIGN(BufferedDataSourceHostImpl); +}; + +} // namespace content + +#endif // CONTENT_RENDERER_MEDIA_BUFFERED_DATA_SOURCE_HOST_IMPL_H_ diff --git a/content/renderer/media/buffered_data_source_host_impl_unittest.cc b/content/renderer/media/buffered_data_source_host_impl_unittest.cc new file mode 100644 index 0000000..6b5a5ec --- /dev/null +++ b/content/renderer/media/buffered_data_source_host_impl_unittest.cc @@ -0,0 +1,75 @@ +// Copyright 2014 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 "content/renderer/media/buffered_data_source_host_impl.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace content { + +class BufferedDataSourceHostImplTest : public testing::Test { + public: + BufferedDataSourceHostImplTest() {} + + void Add() { + host_.AddBufferedTimeRanges(&ranges_, base::TimeDelta::FromSeconds(10)); + } + + protected: + BufferedDataSourceHostImpl host_; + media::Ranges<base::TimeDelta> ranges_; + + DISALLOW_COPY_AND_ASSIGN(BufferedDataSourceHostImplTest); +}; + +TEST_F(BufferedDataSourceHostImplTest, Empty) { + EXPECT_FALSE(host_.DidLoadingProgress()); + Add(); + EXPECT_EQ(0u, ranges_.size()); +} + +TEST_F(BufferedDataSourceHostImplTest, AddBufferedTimeRanges) { + host_.AddBufferedByteRange(10, 20); + host_.SetTotalBytes(100); + Add(); + EXPECT_EQ(1u, ranges_.size()); + EXPECT_EQ(base::TimeDelta::FromSeconds(1), ranges_.start(0)); + EXPECT_EQ(base::TimeDelta::FromSeconds(2), ranges_.end(0)); +} + +TEST_F(BufferedDataSourceHostImplTest, AddBufferedTimeRanges_Merges) { + ranges_.Add(base::TimeDelta::FromSeconds(0), base::TimeDelta::FromSeconds(1)); + host_.AddBufferedByteRange(10, 20); + host_.SetTotalBytes(100); + Add(); + EXPECT_EQ(1u, ranges_.size()); + EXPECT_EQ(base::TimeDelta::FromSeconds(0), ranges_.start(0)); + EXPECT_EQ(base::TimeDelta::FromSeconds(2), ranges_.end(0)); +} + +TEST_F(BufferedDataSourceHostImplTest, AddBufferedTimeRanges_Snaps) { + host_.AddBufferedByteRange(5, 995); + host_.SetTotalBytes(1000); + Add(); + EXPECT_EQ(1u, ranges_.size()); + EXPECT_EQ(base::TimeDelta::FromSeconds(0), ranges_.start(0)); + EXPECT_EQ(base::TimeDelta::FromSeconds(10), ranges_.end(0)); +} + +TEST_F(BufferedDataSourceHostImplTest, SetTotalBytes) { + host_.AddBufferedByteRange(10, 20); + Add(); + EXPECT_EQ(0u, ranges_.size()); + + host_.SetTotalBytes(100); + Add(); + EXPECT_EQ(1u, ranges_.size()); +} + +TEST_F(BufferedDataSourceHostImplTest, DidLoadingProgress) { + host_.AddBufferedByteRange(10, 20); + EXPECT_TRUE(host_.DidLoadingProgress()); + EXPECT_FALSE(host_.DidLoadingProgress()); +} + +} // namespace content diff --git a/content/renderer/media/buffered_data_source_unittest.cc b/content/renderer/media/buffered_data_source_unittest.cc index 9a25006..718fd21 100644 --- a/content/renderer/media/buffered_data_source_unittest.cc +++ b/content/renderer/media/buffered_data_source_unittest.cc @@ -4,12 +4,12 @@ #include "base/bind.h" #include "base/message_loop/message_loop.h" +#include "content/public/common/url_constants.h" #include "content/renderer/media/buffered_data_source.h" #include "content/renderer/media/test_response_generator.h" #include "content/test/mock_webframeclient.h" #include "content/test/mock_weburlloader.h" #include "media/base/media_log.h" -#include "media/base/mock_data_source_host.h" #include "media/base/mock_filters.h" #include "media/base/test_helpers.h" #include "third_party/WebKit/public/platform/WebURLResponse.h" @@ -31,6 +31,18 @@ using blink::WebView; namespace content { +class MockBufferedDataSourceHost : public BufferedDataSourceHost { + public: + MockBufferedDataSourceHost() {} + virtual ~MockBufferedDataSourceHost() {} + + MOCK_METHOD1(SetTotalBytes, void(int64 total_bytes)); + MOCK_METHOD2(AddBufferedByteRange, void(int64 start, int64 end)); + + private: + DISALLOW_COPY_AND_ASSIGN(MockBufferedDataSourceHost); +}; + // Overrides CreateResourceLoader() to permit injecting a MockWebURLLoader. // Also keeps track of whether said MockWebURLLoader is actively loading. class MockBufferedDataSource : public BufferedDataSource { @@ -38,7 +50,7 @@ class MockBufferedDataSource : public BufferedDataSource { MockBufferedDataSource( const scoped_refptr<base::MessageLoopProxy>& message_loop, WebFrame* frame, - media::DataSourceHost* host) + BufferedDataSourceHost* host) : BufferedDataSource(message_loop, frame, new media::MediaLog(), host, base::Bind(&MockBufferedDataSource::set_downloading, base::Unretained(this))), @@ -212,7 +224,7 @@ class BufferedDataSourceTest : public testing::Test { WebView* view_; WebFrame* frame_; - StrictMock<media::MockDataSourceHost> host_; + StrictMock<MockBufferedDataSourceHost> host_; base::MessageLoop message_loop_; private: diff --git a/content/renderer/media/buffered_resource_loader.cc b/content/renderer/media/buffered_resource_loader.cc index 3177209..1351298 100644 --- a/content/renderer/media/buffered_resource_loader.cc +++ b/content/renderer/media/buffered_resource_loader.cc @@ -9,6 +9,7 @@ #include "base/metrics/histogram.h" #include "base/strings/string_number_conversions.h" #include "base/strings/string_util.h" +#include "content/public/common/url_constants.h" #include "content/renderer/media/cache_util.h" #include "media/base/media_log.h" #include "net/http/http_byte_range.h" diff --git a/content/renderer/media/buffered_resource_loader.h b/content/renderer/media/buffered_resource_loader.h index ee4759d..3bdf138 100644 --- a/content/renderer/media/buffered_resource_loader.h +++ b/content/renderer/media/buffered_resource_loader.h @@ -28,9 +28,6 @@ namespace content { const int64 kPositionNotSpecified = -1; -const char kHttpScheme[] = "http"; -const char kHttpsScheme[] = "https"; - // BufferedResourceLoader is single threaded and must be accessed on the // render thread. It wraps a WebURLLoader and does in-memory buffering, // pausing resource loading when the in-memory buffer is full and resuming diff --git a/content/renderer/media/webmediaplayer_impl.cc b/content/renderer/media/webmediaplayer_impl.cc index 451317e..afce478 100644 --- a/content/renderer/media/webmediaplayer_impl.cc +++ b/content/renderer/media/webmediaplayer_impl.cc @@ -121,6 +121,8 @@ const char* kMediaEme = "Media.EME."; namespace content { +class BufferedDataSourceHostImpl; + #define COMPILE_ASSERT_MATCHING_ENUM(name) \ COMPILE_ASSERT(static_cast<int>(WebMediaPlayer::CORSMode ## name) == \ static_cast<int>(BufferedResourceLoader::k ## name), \ @@ -308,13 +310,11 @@ void WebMediaPlayerImpl::DoLoad(LoadType load_type, } // Otherwise it's a regular request which requires resolving the URL first. - // TODO(sandersd): Make WMPI a DataSourceHost and pass |this| instead of - // |&pipeline_|. data_source_.reset(new BufferedDataSource( main_loop_, frame_, media_log_.get(), - &pipeline_, + &buffered_data_source_host_, base::Bind(&WebMediaPlayerImpl::NotifyDownloading, AsWeakPtr()))); data_source_->Initialize( url, static_cast<BufferedResourceLoader::CORSMode>(cors_mode), @@ -497,10 +497,14 @@ WebMediaPlayer::ReadyState WebMediaPlayerImpl::readyState() const { const blink::WebTimeRanges& WebMediaPlayerImpl::buffered() { DCHECK(main_loop_->BelongsToCurrentThread()); - blink::WebTimeRanges web_ranges( - ConvertToWebTimeRanges(pipeline_.GetBufferedTimeRanges())); - buffered_.swap(web_ranges); - return buffered_; + media::Ranges<base::TimeDelta> buffered_time_ranges = + pipeline_.GetBufferedTimeRanges(); + buffered_data_source_host_.AddBufferedTimeRanges( + &buffered_time_ranges, pipeline_.GetMediaDuration()); + blink::WebTimeRanges buffered_web_time_ranges( + ConvertToWebTimeRanges(buffered_time_ranges)); + buffered_web_time_ranges_.swap(buffered_web_time_ranges); + return buffered_web_time_ranges_; } double WebMediaPlayerImpl::maxTimeSeekable() const { @@ -519,8 +523,9 @@ double WebMediaPlayerImpl::maxTimeSeekable() const { bool WebMediaPlayerImpl::didLoadingProgress() const { DCHECK(main_loop_->BelongsToCurrentThread()); - - return pipeline_.DidLoadingProgress(); + bool pipeline_progress = pipeline_.DidLoadingProgress(); + bool data_progress = buffered_data_source_host_.DidLoadingProgress(); + return pipeline_progress || data_progress; } void WebMediaPlayerImpl::paint(WebCanvas* canvas, diff --git a/content/renderer/media/webmediaplayer_impl.h b/content/renderer/media/webmediaplayer_impl.h index d59b7c2a..2a16e22 100644 --- a/content/renderer/media/webmediaplayer_impl.h +++ b/content/renderer/media/webmediaplayer_impl.h @@ -13,6 +13,7 @@ #include "base/memory/scoped_ptr.h" #include "base/memory/weak_ptr.h" #include "base/threading/thread.h" +#include "content/renderer/media/buffered_data_source_host_impl.h" #include "content/renderer/media/crypto/proxy_decryptor.h" #include "content/renderer/media/video_frame_compositor.h" #include "media/base/audio_renderer_sink.h" @@ -114,6 +115,8 @@ class WebMediaPlayerImpl virtual blink::WebMediaPlayer::NetworkState networkState() const; virtual blink::WebMediaPlayer::ReadyState readyState() const; + // TODO(sandersd): Change this to non-const in blink::WebMediaPlayer. + // http://crbug.com/360251 virtual bool didLoadingProgress() const; virtual bool hasSingleSecurityOrigin() const; @@ -244,9 +247,6 @@ class WebMediaPlayerImpl blink::WebMediaPlayer::NetworkState network_state_; blink::WebMediaPlayer::ReadyState ready_state_; - // Keep a list of buffered time ranges. - blink::WebTimeRanges buffered_; - // Message loops for posting tasks on Chrome's main thread. Also used // for DCHECKs so methods calls won't execute in the wrong thread. const scoped_refptr<base::MessageLoopProxy> main_loop_; @@ -320,6 +320,10 @@ class WebMediaPlayerImpl scoped_ptr<media::Demuxer> demuxer_; media::ChunkDemuxer* chunk_demuxer_; + BufferedDataSourceHostImpl buffered_data_source_host_; + // TODO(sandersd): Remove this cache. http://crbug.com/360254 + blink::WebTimeRanges buffered_web_time_ranges_; + // Temporary for EME v0.1. In the future the init data type should be passed // through GenerateKeyRequest() directly from WebKit. std::string init_data_type_; |