diff options
author | scherkus@chromium.org <scherkus@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-01-19 19:55:20 +0000 |
---|---|---|
committer | scherkus@chromium.org <scherkus@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-01-19 19:55:20 +0000 |
commit | a9415292f9aedca5c528532f1260118ad384aaed (patch) | |
tree | df6dde3058efb3594a77ef78ce904c624f78da30 /webkit/media | |
parent | d2353452f11b73f763ea0be9f1a608d03cfddeac (diff) | |
download | chromium_src-a9415292f9aedca5c528532f1260118ad384aaed.zip chromium_src-a9415292f9aedca5c528532f1260118ad384aaed.tar.gz chromium_src-a9415292f9aedca5c528532f1260118ad384aaed.tar.bz2 |
Replace DataSourceFactory with explicitly initialized DataSources.
BUG=107324
TEST=layout tests
Review URL: https://chromiumcodereview.appspot.com/9243016
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@118338 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'webkit/media')
-rw-r--r-- | webkit/media/buffered_data_source.cc | 34 | ||||
-rw-r--r-- | webkit/media/buffered_data_source.h | 14 | ||||
-rw-r--r-- | webkit/media/buffered_data_source_unittest.cc | 2 | ||||
-rw-r--r-- | webkit/media/filter_helpers.cc | 81 | ||||
-rw-r--r-- | webkit/media/filter_helpers.h | 53 | ||||
-rw-r--r-- | webkit/media/simple_data_source.cc | 38 | ||||
-rw-r--r-- | webkit/media/simple_data_source.h | 14 | ||||
-rw-r--r-- | webkit/media/simple_data_source_unittest.cc | 6 | ||||
-rw-r--r-- | webkit/media/web_data_source.h | 27 | ||||
-rw-r--r-- | webkit/media/web_data_source_factory.cc | 105 | ||||
-rw-r--r-- | webkit/media/web_data_source_factory.h | 56 | ||||
-rw-r--r-- | webkit/media/webkit_media.gypi | 6 | ||||
-rw-r--r-- | webkit/media/webmediaplayer_impl.cc | 154 | ||||
-rw-r--r-- | webkit/media/webmediaplayer_impl.h | 16 | ||||
-rw-r--r-- | webkit/media/webmediaplayer_proxy.cc | 37 | ||||
-rw-r--r-- | webkit/media/webmediaplayer_proxy.h | 17 |
16 files changed, 263 insertions, 397 deletions
diff --git a/webkit/media/buffered_data_source.cc b/webkit/media/buffered_data_source.cc index 20b9b7a..70c29cd 100644 --- a/webkit/media/buffered_data_source.cc +++ b/webkit/media/buffered_data_source.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 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. @@ -7,7 +7,6 @@ #include "base/bind.h" #include "media/base/media_log.h" #include "net/base/net_errors.h" -#include "webkit/media/web_data_source_factory.h" using WebKit::WebFrame; @@ -22,22 +21,6 @@ static const int kInitialReadBufferSize = 32768; // error. static const int kNumCacheMissRetries = 3; -static WebDataSource* NewBufferedDataSource(MessageLoop* render_loop, - WebKit::WebFrame* frame, - media::MediaLog* media_log) { - return new BufferedDataSource(render_loop, frame, media_log); -} - -// static -media::DataSourceFactory* BufferedDataSource::CreateFactory( - MessageLoop* render_loop, - WebKit::WebFrame* frame, - media::MediaLog* media_log, - const WebDataSourceBuildObserverHack& build_observer) { - return new WebDataSourceFactory(render_loop, frame, media_log, - &NewBufferedDataSource, build_observer); -} - BufferedDataSource::BufferedDataSource( MessageLoop* render_loop, WebFrame* frame, @@ -93,10 +76,9 @@ void BufferedDataSource::set_host(media::DataSourceHost* host) { } } -void BufferedDataSource::Initialize(const std::string& url, +void BufferedDataSource::Initialize(const GURL& url, const media::PipelineStatusCB& callback) { - // Saves the url. - url_ = GURL(url); + url_ = url; // This data source doesn't support data:// protocol so reject it. if (url_.SchemeIs(kDataScheme)) { @@ -115,16 +97,6 @@ void BufferedDataSource::Initialize(const std::string& url, base::Bind(&BufferedDataSource::InitializeTask, this)); } -void BufferedDataSource::CancelInitialize() { - base::AutoLock auto_lock(lock_); - DCHECK(!initialize_cb_.is_null()); - - initialize_cb_.Reset(); - - render_loop_->PostTask( - FROM_HERE, base::Bind(&BufferedDataSource::CleanupTask, this)); -} - ///////////////////////////////////////////////////////////////////////////// // media::Filter implementation. void BufferedDataSource::Stop(const base::Closure& callback) { diff --git a/webkit/media/buffered_data_source.h b/webkit/media/buffered_data_source.h index eac8e13..8e4215f 100644 --- a/webkit/media/buffered_data_source.h +++ b/webkit/media/buffered_data_source.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 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. @@ -10,7 +10,7 @@ #include "base/callback.h" #include "base/memory/scoped_ptr.h" #include "base/synchronization/lock.h" -#include "media/base/filter_factories.h" +#include "googleurl/src/gurl.h" #include "media/base/data_source.h" #include "webkit/media/buffered_resource_loader.h" @@ -24,13 +24,6 @@ namespace webkit_media { // thread as well as media-specific threads. class BufferedDataSource : public WebDataSource { public: - // Creates a DataSourceFactory for building BufferedDataSource objects. - static media::DataSourceFactory* CreateFactory( - MessageLoop* render_loop, - WebKit::WebFrame* frame, - media::MediaLog* media_log, - const WebDataSourceBuildObserverHack& build_observer); - BufferedDataSource(MessageLoop* render_loop, WebKit::WebFrame* frame, media::MediaLog* media_log); @@ -54,9 +47,8 @@ class BufferedDataSource : public WebDataSource { virtual void SetBitrate(int bitrate) OVERRIDE; // webkit_glue::WebDataSource implementation. - virtual void Initialize(const std::string& url, + virtual void Initialize(const GURL& url, const media::PipelineStatusCB& callback) OVERRIDE; - virtual void CancelInitialize() OVERRIDE; virtual bool HasSingleOrigin() OVERRIDE; virtual void Abort() OVERRIDE; diff --git a/webkit/media/buffered_data_source_unittest.cc b/webkit/media/buffered_data_source_unittest.cc index f1d60e2..6680633 100644 --- a/webkit/media/buffered_data_source_unittest.cc +++ b/webkit/media/buffered_data_source_unittest.cc @@ -92,7 +92,7 @@ class BufferedDataSourceTest : public testing::Test { void Initialize(media::PipelineStatus expected) { ExpectCreateResourceLoader(); - data_source_->Initialize(response_generator_.gurl().spec(), + data_source_->Initialize(response_generator_.gurl(), media::NewExpectedStatusCB(expected)); message_loop_->RunAllPending(); } diff --git a/webkit/media/filter_helpers.cc b/webkit/media/filter_helpers.cc new file mode 100644 index 0000000..f31e5f2 --- /dev/null +++ b/webkit/media/filter_helpers.cc @@ -0,0 +1,81 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "webkit/media/filter_helpers.h" + +#include "media/base/filter_collection.h" +#include "media/base/message_loop_factory.h" +#include "media/filters/chunk_demuxer_factory.h" +#include "media/filters/dummy_demuxer_factory.h" +#include "media/filters/ffmpeg_audio_decoder.h" +#include "media/filters/ffmpeg_demuxer_factory.h" +#include "media/filters/ffmpeg_video_decoder.h" +#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebURL.h" +#include "webkit/media/media_stream_client.h" + +namespace webkit_media { + +// Constructs and adds the default audio/video decoders to |filter_collection|. +static void AddDefaultDecodersToCollection( + media::MessageLoopFactory* message_loop_factory, + media::FilterCollection* filter_collection) { + filter_collection->AddAudioDecoder(new media::FFmpegAudioDecoder( + message_loop_factory->GetMessageLoop("AudioDecoderThread"))); + filter_collection->AddVideoDecoder(new media::FFmpegVideoDecoder( + message_loop_factory->GetMessageLoop("VideoDecoderThread"))); +} + +bool BuildMediaStreamCollection(const WebKit::WebURL& url, + MediaStreamClient* client, + media::MessageLoopFactory* message_loop_factory, + media::FilterCollection* filter_collection) { + if (!client) + return false; + + scoped_refptr<media::VideoDecoder> video_decoder = client->GetVideoDecoder( + url, message_loop_factory); + if (!video_decoder) + return false; + + filter_collection->AddVideoDecoder(video_decoder); + + // TODO(vrk/wjia): Setting true for local_source is under the assumption + // that the MediaStream represents a local webcam. This will need to + // change in the future when GetVideoDecoder is no longer hardcoded to + // only return CaptureVideoDecoders. + scoped_ptr<media::DemuxerFactory> demuxer_factory( + new media::DummyDemuxerFactory(true, false, true)); + filter_collection->SetDemuxerFactory(demuxer_factory.Pass()); + + return true; +} + +bool BuildMediaSourceCollection(const WebKit::WebURL& url, + const WebKit::WebURL& media_source_url, + media::ChunkDemuxerClient* client, + media::MessageLoopFactory* message_loop_factory, + media::FilterCollection* filter_collection) { + if (media_source_url.isEmpty() || url != media_source_url) + return false; + + scoped_ptr<media::DemuxerFactory> demuxer_factory( + new media::ChunkDemuxerFactory(client)); + filter_collection->SetDemuxerFactory(demuxer_factory.Pass()); + + AddDefaultDecodersToCollection(message_loop_factory, filter_collection); + return true; +} + +void BuildDefaultCollection(const scoped_refptr<media::DataSource>& data_source, + media::MessageLoopFactory* message_loop_factory, + media::FilterCollection* filter_collection) { + scoped_ptr<media::DemuxerFactory> demuxer_factory( + new media::FFmpegDemuxerFactory( + data_source, message_loop_factory->GetMessageLoop("PipelineThread"))); + filter_collection->SetDemuxerFactory(demuxer_factory.Pass()); + + AddDefaultDecodersToCollection(message_loop_factory, filter_collection); +} + +} // webkit_media diff --git a/webkit/media/filter_helpers.h b/webkit/media/filter_helpers.h new file mode 100644 index 0000000..9370d98 --- /dev/null +++ b/webkit/media/filter_helpers.h @@ -0,0 +1,53 @@ +// Copyright (c) 2012 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 WEBKIT_MEDIA_FILTER_HELPERS_H_ +#define WEBKIT_MEDIA_FILTER_HELPERS_H_ + +#include "base/basictypes.h" +#include "base/memory/ref_counted.h" + +namespace media { +class ChunkDemuxerClient; +class DataSource; +class FilterCollection; +class MessageLoopFactory; +} + +namespace WebKit { +class WebURL; +} + +namespace webkit_media { + +class MediaStreamClient; + +// Builds the required filters for handling media stream URLs and adds them to +// |filter_collection| returning true if successful. +// +// |filter_collection| is not modified if this method returns false. +bool BuildMediaStreamCollection(const WebKit::WebURL& url, + MediaStreamClient* client, + media::MessageLoopFactory* message_loop_factory, + media::FilterCollection* filter_collection); + +// Builds the required filters for handling media source URLs and adds them to +// |filter_collection| returning true if successful. +// +// |filter_collection| is not modified if this method returns false. +bool BuildMediaSourceCollection(const WebKit::WebURL& url, + const WebKit::WebURL& media_source_url, + media::ChunkDemuxerClient* client, + media::MessageLoopFactory* message_loop_factory, + media::FilterCollection* filter_collection); + +// Builds the required filters for handling regular URLs and adds them to +// |filter_collection|. +void BuildDefaultCollection(const scoped_refptr<media::DataSource>& data_source, + media::MessageLoopFactory* message_loop_factory, + media::FilterCollection* filter_collection); + +} // webkit_media + +#endif // WEBKIT_MEDIA_FILTER_HELPERS_H_ diff --git a/webkit/media/simple_data_source.cc b/webkit/media/simple_data_source.cc index cc950dc..d521b32 100644 --- a/webkit/media/simple_data_source.cc +++ b/webkit/media/simple_data_source.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 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. @@ -16,7 +16,6 @@ #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebKitPlatformSupport.h" #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebString.h" #include "third_party/WebKit/Source/WebKit/chromium/public/WebURLLoaderOptions.h" -#include "webkit/media/web_data_source_factory.h" using WebKit::WebString; using WebKit::WebURLLoaderOptions; @@ -25,22 +24,6 @@ namespace webkit_media { static const char kDataScheme[] = "data"; -static WebDataSource* NewSimpleDataSource(MessageLoop* render_loop, - WebKit::WebFrame* frame, - media::MediaLog* media_log) { - return new SimpleDataSource(render_loop, frame); -} - -// static -media::DataSourceFactory* SimpleDataSource::CreateFactory( - MessageLoop* render_loop, - WebKit::WebFrame* frame, - media::MediaLog* media_log, - const WebDataSourceBuildObserverHack& build_observer) { - return new WebDataSourceFactory(render_loop, frame, media_log, - &NewSimpleDataSource, build_observer); -} - SimpleDataSource::SimpleDataSource( MessageLoop* render_loop, WebKit::WebFrame* frame) @@ -79,7 +62,7 @@ void SimpleDataSource::Stop(const base::Closure& callback) { } void SimpleDataSource::Initialize( - const std::string& url, + const GURL& url, const media::PipelineStatusCB& callback) { // Reference to prevent destruction while inside the |initialize_cb_| // call. This is a temporary fix to prevent crashes caused by holding the @@ -93,7 +76,7 @@ void SimpleDataSource::Initialize( initialize_cb_ = callback; // Validate the URL. - url_ = GURL(url); + url_ = url; if (!url_.is_valid()) { DoneInitialization_Locked(false); return; @@ -105,17 +88,6 @@ void SimpleDataSource::Initialize( } } -void SimpleDataSource::CancelInitialize() { - base::AutoLock auto_lock(lock_); - DCHECK(!initialize_cb_.is_null()); - state_ = STOPPED; - initialize_cb_.Reset(); - - // Post a task to the render thread to cancel loading the resource. - render_loop_->PostTask(FROM_HERE, - base::Bind(&SimpleDataSource::CancelTask, this)); -} - void SimpleDataSource::Read(int64 position, size_t size, uint8* data, @@ -263,6 +235,10 @@ bool SimpleDataSource::HasSingleOrigin() { void SimpleDataSource::Abort() { DCHECK(MessageLoop::current() == render_loop_); + base::AutoLock auto_lock(lock_); + state_ = STOPPED; + initialize_cb_.Reset(); + CancelTask(); frame_ = NULL; } diff --git a/webkit/media/simple_data_source.h b/webkit/media/simple_data_source.h index e905be9..94f144f 100644 --- a/webkit/media/simple_data_source.h +++ b/webkit/media/simple_data_source.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 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. @@ -15,7 +15,7 @@ #include "base/memory/scoped_ptr.h" #include "base/message_loop.h" -#include "media/base/filter_factories.h" +#include "googleurl/src/gurl.h" #include "media/base/data_source.h" #include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h" #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebURLLoader.h" @@ -36,13 +36,6 @@ class SimpleDataSource : public WebDataSource, public WebKit::WebURLLoaderClient { public: - // Creates a DataSourceFactory for building SimpleDataSource objects. - static media::DataSourceFactory* CreateFactory( - MessageLoop* render_loop, - WebKit::WebFrame* frame, - media::MediaLog* media_log, - const WebDataSourceBuildObserverHack& build_observer); - SimpleDataSource(MessageLoop* render_loop, WebKit::WebFrame* frame); virtual ~SimpleDataSource(); @@ -92,9 +85,8 @@ class SimpleDataSource const WebKit::WebURLError&); // webkit_glue::WebDataSource implementation. - virtual void Initialize(const std::string& url, + virtual void Initialize(const GURL& url, const media::PipelineStatusCB& callback) OVERRIDE; - virtual void CancelInitialize() OVERRIDE; virtual bool HasSingleOrigin() OVERRIDE; virtual void Abort() OVERRIDE; diff --git a/webkit/media/simple_data_source_unittest.cc b/webkit/media/simple_data_source_unittest.cc index a21135f..becef10 100644 --- a/webkit/media/simple_data_source_unittest.cc +++ b/webkit/media/simple_data_source_unittest.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 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. @@ -80,7 +80,7 @@ class SimpleDataSourceTest : public testing::Test { data_source_->set_host(&host_); data_source_->SetURLLoaderForTest(url_loader_); - data_source_->Initialize(url, callback); + data_source_->Initialize(gurl_, callback); MessageLoop::current()->RunAllPending(); } @@ -197,7 +197,7 @@ TEST_F(SimpleDataSourceTest, InitializeData) { EXPECT_CALL(host_, SetTotalBytes(sizeof(kDataUrlDecoded))); EXPECT_CALL(host_, SetBufferedBytes(sizeof(kDataUrlDecoded))); - data_source_->Initialize(kDataUrl, + data_source_->Initialize(GURL(kDataUrl), media::NewExpectedStatusCB(media::PIPELINE_OK)); MessageLoop::current()->RunAllPending(); diff --git a/webkit/media/web_data_source.h b/webkit/media/web_data_source.h index e492e88..260e003 100644 --- a/webkit/media/web_data_source.h +++ b/webkit/media/web_data_source.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 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. @@ -9,6 +9,8 @@ #include "media/base/data_source.h" #include "media/base/pipeline_status.h" +class GURL; + namespace webkit_media { // An interface that allows WebMediaPlayerImpl::Proxy to communicate with the @@ -20,23 +22,17 @@ class WebDataSource : public media::DataSource { // Initialize this object using |url|. This object calls |callback| when // initialization has completed. - virtual void Initialize(const std::string& url, + virtual void Initialize(const GURL& url, const media::PipelineStatusCB& callback) = 0; - // Called to cancel initialization. The callback passed in Initialize() will - // be destroyed and will not be called after this method returns. Once this - // method returns, the object will be in an uninitialized state and - // Initialize() cannot be called again. The caller is expected to release - // its handle to this object and never call it again. - virtual void CancelInitialize() = 0; - // Returns true if the media resource has a single origin, false otherwise. // // Method called on the render thread. virtual bool HasSingleOrigin() = 0; - // This method is used to unblock any read calls that would cause the - // media pipeline to stall. + // Cancels initialization, any pending loaders, and any pending read calls + // from the demuxer. The caller is expected to release its reference to this + // object and never call it again. // // Method called on the render thread. virtual void Abort() = 0; @@ -45,15 +41,6 @@ class WebDataSource : public media::DataSource { DISALLOW_COPY_AND_ASSIGN(WebDataSource); }; -// Temporary hack to allow WebMediaPlayerImpl::Proxy::AddDataSource() to -// be called when WebDataSource objects are created. This can be removed -// once WebMediaPlayerImpl::Proxy is fixed so it doesn't have to track -// WebDataSources. Proxy only has to track WebDataSources so it can call Abort() -// on them at shutdown. Once cancellation is added to DataSource and pause -// support in Demuxers cancel pending reads, Proxy shouldn't have to keep -// a WebDataSource list or call Abort(). -typedef base::Callback<void(WebDataSource*)> WebDataSourceBuildObserverHack; - } // namespace webkit_media #endif // WEBKIT_MEDIA_WEB_DATA_SOURCE_H_ diff --git a/webkit/media/web_data_source_factory.cc b/webkit/media/web_data_source_factory.cc deleted file mode 100644 index c522ab6..0000000 --- a/webkit/media/web_data_source_factory.cc +++ /dev/null @@ -1,105 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "webkit/media/web_data_source_factory.h" - -#include "base/bind.h" -#include "base/logging.h" -#include "media/base/media_log.h" - -namespace webkit_media { - -class WebDataSourceFactory::BuildRequest - : public media::AsyncDataSourceFactoryBase::BuildRequest { - public: - BuildRequest(const std::string& url, const BuildCallback& callback, - WebDataSource* data_source, - const WebDataSourceBuildObserverHack& build_observer); - virtual ~BuildRequest(); - - protected: - // AsyncDataSourceFactoryBase::BuildRequest method. - virtual void DoStart(); - - private: - void InitDone(media::PipelineStatus status); - - scoped_refptr<WebDataSource> data_source_; - WebDataSourceBuildObserverHack build_observer_; - - DISALLOW_COPY_AND_ASSIGN(BuildRequest); -}; - -WebDataSourceFactory::WebDataSourceFactory( - MessageLoop* render_loop, - WebKit::WebFrame* frame, - media::MediaLog* media_log, - FactoryFunction factory_function, - const WebDataSourceBuildObserverHack& build_observer) - : render_loop_(render_loop), - frame_(frame), - media_log_(media_log), - factory_function_(factory_function), - build_observer_(build_observer) { - DCHECK(render_loop_); - DCHECK(frame_); - DCHECK(media_log_); - DCHECK(factory_function_); -} - -WebDataSourceFactory::~WebDataSourceFactory() {} - -bool WebDataSourceFactory::AllowRequests() const { - return true; -} - -media::AsyncDataSourceFactoryBase::BuildRequest* -WebDataSourceFactory::CreateRequest(const std::string& url, - const BuildCallback& callback) { - WebDataSource* data_source = factory_function_(render_loop_, frame_, - media_log_); - - return new WebDataSourceFactory::BuildRequest(url, callback, data_source, - build_observer_); -} - -WebDataSourceFactory::BuildRequest::BuildRequest( - const std::string& url, - const BuildCallback& callback, - WebDataSource* data_source, - const WebDataSourceBuildObserverHack& build_observer) - : AsyncDataSourceFactoryBase::BuildRequest(url, callback), - data_source_(data_source), - build_observer_(build_observer) { -} - -WebDataSourceFactory::BuildRequest::~BuildRequest() { - if (data_source_.get()) { - data_source_->CancelInitialize(); - data_source_ = NULL; - } -} - -void WebDataSourceFactory::BuildRequest::DoStart() { - data_source_->Initialize(url(), base::Bind(&BuildRequest::InitDone, - base::Unretained(this))); -} - -void WebDataSourceFactory::BuildRequest::InitDone( - media::PipelineStatus status) { - scoped_refptr<WebDataSource> data_source; - - data_source = (status == media::PIPELINE_OK) ? data_source_ : NULL; - data_source_ = NULL; - - if (!build_observer_.is_null() && data_source.get()) { - build_observer_.Run(data_source.get()); - } - - RequestComplete(status, data_source); - // Don't do anything after this line. This object is deleted by - // RequestComplete(). -} - -} // namespace webkit_media diff --git a/webkit/media/web_data_source_factory.h b/webkit/media/web_data_source_factory.h deleted file mode 100644 index 0eb577e..0000000 --- a/webkit/media/web_data_source_factory.h +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright (c) 2012 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 WEBKIT_MEDIA_WEB_DATA_SOURCE_FACTORY_H_ -#define WEBKIT_MEDIA_WEB_DATA_SOURCE_FACTORY_H_ - -#include "base/memory/ref_counted.h" -#include "media/base/async_filter_factory_base.h" -#include "webkit/media/web_data_source.h" - -class MessageLoop; - -namespace media { -class MediaLog; -} - -namespace WebKit { -class WebFrame; -} - -namespace webkit_media { - -class WebDataSourceFactory : public media::AsyncDataSourceFactoryBase { - public: - typedef WebDataSource* (*FactoryFunction)(MessageLoop* render_loop, - WebKit::WebFrame* frame, - media::MediaLog* media_log); - - WebDataSourceFactory(MessageLoop* render_loop, WebKit::WebFrame* frame, - media::MediaLog* media_log, - FactoryFunction factory_function, - const WebDataSourceBuildObserverHack& build_observer); - virtual ~WebDataSourceFactory(); - - protected: - // AsyncDataSourceFactoryBase methods. - virtual bool AllowRequests() const OVERRIDE; - virtual AsyncDataSourceFactoryBase::BuildRequest* CreateRequest( - const std::string& url, const BuildCallback& callback) OVERRIDE; - - private: - class BuildRequest; - - MessageLoop* render_loop_; - WebKit::WebFrame* frame_; - scoped_refptr<media::MediaLog> media_log_; - FactoryFunction factory_function_; - WebDataSourceBuildObserverHack build_observer_; - - DISALLOW_COPY_AND_ASSIGN(WebDataSourceFactory); -}; - -} // namespace webkit_media - -#endif // WEBKIT_MEDIA_WEB_DATA_SOURCE_FACTORY_H_ diff --git a/webkit/media/webkit_media.gypi b/webkit/media/webkit_media.gypi index 1f691c3..3f567be 100644 --- a/webkit/media/webkit_media.gypi +++ b/webkit/media/webkit_media.gypi @@ -1,4 +1,4 @@ -# Copyright (c) 2011 The Chromium Authors. All rights reserved. +# Copyright (c) 2012 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. @@ -23,14 +23,14 @@ 'buffered_data_source.h', 'buffered_resource_loader.cc', 'buffered_resource_loader.h', + 'filter_helpers.cc', + 'filter_helpers.h', 'media_stream_client.h', 'simple_data_source.cc', 'simple_data_source.h', 'skcanvas_video_renderer.cc', 'skcanvas_video_renderer.h', 'web_data_source.cc', - 'web_data_source_factory.cc', - 'web_data_source_factory.h', 'web_data_source.h', 'webmediaplayer_delegate.h', 'webmediaplayer_impl.cc', diff --git a/webkit/media/webmediaplayer_impl.cc b/webkit/media/webmediaplayer_impl.cc index 706ab8f..011e630 100644 --- a/webkit/media/webmediaplayer_impl.cc +++ b/webkit/media/webmediaplayer_impl.cc @@ -11,18 +11,12 @@ #include "base/callback.h" #include "base/command_line.h" #include "base/metrics/histogram.h" -#include "media/base/composite_data_source_factory.h" #include "media/base/filter_collection.h" #include "media/base/limits.h" #include "media/base/media_log.h" #include "media/base/media_switches.h" #include "media/base/pipeline.h" #include "media/base/video_frame.h" -#include "media/filters/chunk_demuxer_factory.h" -#include "media/filters/dummy_demuxer_factory.h" -#include "media/filters/ffmpeg_audio_decoder.h" -#include "media/filters/ffmpeg_demuxer_factory.h" -#include "media/filters/ffmpeg_video_decoder.h" #include "media/filters/null_audio_renderer.h" #include "media/filters/video_renderer_base.h" #include "third_party/WebKit/Source/WebKit/chromium/public/WebVideoFrame.h" @@ -32,7 +26,7 @@ #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebURL.h" #include "v8/include/v8.h" #include "webkit/media/buffered_data_source.h" -#include "webkit/media/media_stream_client.h" +#include "webkit/media/filter_helpers.h" #include "webkit/media/simple_data_source.h" #include "webkit/media/webmediaplayer_delegate.h" #include "webkit/media/webmediaplayer_proxy.h" @@ -107,10 +101,12 @@ WebMediaPlayerImpl::WebMediaPlayerImpl( media::MessageLoopFactory* message_loop_factory, MediaStreamClient* media_stream_client, media::MediaLog* media_log) - : network_state_(WebKit::WebMediaPlayer::Empty), + : frame_(frame), + network_state_(WebKit::WebMediaPlayer::Empty), ready_state_(WebKit::WebMediaPlayer::HaveNothing), main_loop_(MessageLoop::current()), filter_collection_(collection), + started_(false), message_loop_factory_(message_loop_factory), paused_(true), seeking_(false), @@ -165,41 +161,7 @@ WebMediaPlayerImpl::WebMediaPlayerImpl( filter_collection_->AddVideoRenderer(video_renderer); proxy_->set_frame_provider(video_renderer); - // A simple data source that keeps all data in memory. - scoped_ptr<media::DataSourceFactory> simple_data_source_factory( - SimpleDataSource::CreateFactory(MessageLoop::current(), frame, - media_log_, - proxy_->GetBuildObserver())); - - // A sophisticated data source that does memory caching. - scoped_ptr<media::DataSourceFactory> buffered_data_source_factory( - BufferedDataSource::CreateFactory(MessageLoop::current(), frame, - media_log_, - proxy_->GetBuildObserver())); - - scoped_ptr<media::CompositeDataSourceFactory> data_source_factory( - new media::CompositeDataSourceFactory()); - data_source_factory->AddFactory(buffered_data_source_factory.Pass()); - data_source_factory->AddFactory(simple_data_source_factory.Pass()); - - scoped_ptr<media::DemuxerFactory> demuxer_factory( - new media::FFmpegDemuxerFactory(scoped_ptr<media::DataSourceFactory>( - data_source_factory.release()), pipeline_message_loop)); - - std::string source_url = GetClient()->sourceURL().spec(); - if (!source_url.empty()) { - demuxer_factory.reset( - new media::ChunkDemuxerFactory(source_url, - demuxer_factory.Pass(), - proxy_)); - } - filter_collection_->SetDemuxerFactory(demuxer_factory.Pass()); - - // Add in the default filter factories. - filter_collection_->AddAudioDecoder(new media::FFmpegAudioDecoder( - message_loop_factory_->GetMessageLoop("AudioDecoderThread"))); - filter_collection_->AddVideoDecoder(new media::FFmpegVideoDecoder( - message_loop_factory_->GetMessageLoop("VideoDecoderThread"))); + // Create default audio renderer. filter_collection_->AddAudioRenderer(new media::NullAudioRenderer()); } @@ -254,47 +216,44 @@ URLSchemeForHistogram URLScheme(const GURL& url) { void WebMediaPlayerImpl::load(const WebKit::WebURL& url) { DCHECK_EQ(main_loop_, MessageLoop::current()); - UMA_HISTOGRAM_ENUMERATION("Media.URLScheme", URLScheme(url), kMaxURLScheme); - - if (media_stream_client_) { - bool has_video = false; - bool has_audio = false; - scoped_refptr<media::VideoDecoder> new_decoder = - media_stream_client_->GetVideoDecoder(url, message_loop_factory_.get()); - if (new_decoder.get()) { - // Remove the default decoder. - scoped_refptr<media::VideoDecoder> old_videodecoder; - filter_collection_->SelectVideoDecoder(&old_videodecoder); - filter_collection_->AddVideoDecoder(new_decoder.get()); - has_video = true; - } - - // TODO(wjia): add audio decoder handling when it's available. - if (has_video || has_audio) { - // TODO(vrk/wjia): Setting true for local_source is under the assumption - // that the MediaStream represents a local webcam. This will need to - // change in the future when GetVideoDecoder is no longer hardcoded to - // only return CaptureVideoDecoders. - filter_collection_->SetDemuxerFactory(scoped_ptr<media::DemuxerFactory>( - new media::DummyDemuxerFactory(has_video, has_audio, true))); - } - } + GURL gurl(url); + UMA_HISTOGRAM_ENUMERATION("Media.URLScheme", URLScheme(gurl), kMaxURLScheme); - // Handle any volume changes that occured before load(). + // Handle any volume/preload changes that occured before load(). setVolume(GetClient()->volume()); - // Get the preload value. setPreload(GetClient()->preload()); - // Initialize the pipeline. SetNetworkState(WebKit::WebMediaPlayer::Loading); SetReadyState(WebKit::WebMediaPlayer::HaveNothing); - pipeline_->Start( - filter_collection_.Pass(), - url.spec(), - base::Bind(&WebMediaPlayerProxy::PipelineInitializationCallback, - proxy_.get())); - media_log_->AddEvent(media_log_->CreateLoadEvent(url.spec())); + + // Media streams pipelines can start immediately. + if (BuildMediaStreamCollection(url, media_stream_client_, + message_loop_factory_.get(), + filter_collection_.get())) { + StartPipeline(gurl); + return; + } + + // Media source pipelines can start immediately. + if (BuildMediaSourceCollection(url, GetClient()->sourceURL(), proxy_, + message_loop_factory_.get(), + filter_collection_.get())) { + StartPipeline(gurl); + return; + } + + // Otherwise it's a regular request which requires resolving the URL first. + scoped_refptr<WebDataSource> data_source; + if (gurl.SchemeIs(kDataScheme)) { + data_source = new SimpleDataSource(main_loop_, frame_); + } else { + data_source = new BufferedDataSource(main_loop_, frame_, media_log_); + } + proxy_->set_data_source(data_source); + data_source->Initialize(url, base::Bind( + &WebMediaPlayerImpl::DataSourceInitialized, + base::Unretained(this), gurl)); } void WebMediaPlayerImpl::cancelLoad() { @@ -856,6 +815,32 @@ void WebMediaPlayerImpl::SetOpaque(bool opaque) { GetClient()->setOpaque(opaque); } +void WebMediaPlayerImpl::DataSourceInitialized( + const GURL& gurl, + media::PipelineStatus status) { + DCHECK_EQ(main_loop_, MessageLoop::current()); + + if (status != media::PIPELINE_OK) { + SetNetworkState(WebKit::WebMediaPlayer::FormatError); + Repaint(); + return; + } + + BuildDefaultCollection(proxy_->data_source(), + message_loop_factory_.get(), + filter_collection_.get()); + StartPipeline(gurl); +} + +void WebMediaPlayerImpl::StartPipeline(const GURL& gurl) { + started_ = true; + pipeline_->Start( + filter_collection_.Pass(), + gurl.spec(), + base::Bind(&WebMediaPlayerProxy::PipelineInitializationCallback, + proxy_.get())); +} + void WebMediaPlayerImpl::SetNetworkState( WebKit::WebMediaPlayer::NetworkState state) { DCHECK_EQ(main_loop_, MessageLoop::current()); @@ -878,22 +863,23 @@ void WebMediaPlayerImpl::Destroy() { // Tell the data source to abort any pending reads so that the pipeline is // not blocked when issuing stop commands to the other filters. if (proxy_) { - proxy_->AbortDataSources(); + proxy_->AbortDataSource(); proxy_->DemuxerShutdown(); } // Make sure to kill the pipeline so there's no more media threads running. // Note: stopping the pipeline might block for a long time. - if (pipeline_) { + if (started_) { media::PipelineStatusNotification note; pipeline_->Stop(note.Callback()); note.Wait(); + started_ = false; + } - // Let V8 know we are not using extra resources anymore. - if (incremented_externally_allocated_memory_) { - v8::V8::AdjustAmountOfExternalAllocatedMemory(-kPlayerExtraMemory); - incremented_externally_allocated_memory_ = false; - } + // Let V8 know we are not using extra resources anymore. + if (incremented_externally_allocated_memory_) { + v8::V8::AdjustAmountOfExternalAllocatedMemory(-kPlayerExtraMemory); + incremented_externally_allocated_memory_ = false; } message_loop_factory_.reset(); diff --git a/webkit/media/webmediaplayer_impl.h b/webkit/media/webmediaplayer_impl.h index b3b2b42..fea3b92 100644 --- a/webkit/media/webmediaplayer_impl.h +++ b/webkit/media/webmediaplayer_impl.h @@ -52,6 +52,7 @@ #include "base/memory/scoped_ptr.h" #include "base/memory/weak_ptr.h" #include "base/message_loop.h" +#include "googleurl/src/gurl.h" #include "media/base/audio_renderer_sink.h" #include "media/base/filters.h" #include "media/base/message_loop_factory.h" @@ -191,6 +192,12 @@ class WebMediaPlayerImpl void SetOpaque(bool); private: + // Called after asynchronous initialization of a data source completed. + void DataSourceInitialized(const GURL& gurl, media::PipelineStatus status); + + // Finishes starting the pipeline due to a call to load(). + void StartPipeline(const GURL& gurl); + // Helpers that set the network/ready state and notifies the client if // they've changed. void SetNetworkState(WebKit::WebMediaPlayer::NetworkState state); @@ -205,6 +212,8 @@ class WebMediaPlayerImpl // Lets V8 know that player uses extra resources not managed by V8. void IncrementExternallyAllocatedMemory(); + WebKit::WebFrame* frame_; + // TODO(hclam): get rid of these members and read from the pipeline directly. WebKit::WebMediaPlayer::NetworkState network_state_; WebKit::WebMediaPlayer::ReadyState ready_state_; @@ -219,8 +228,13 @@ class WebMediaPlayerImpl // A collection of filters. scoped_ptr<media::FilterCollection> filter_collection_; - // The actual pipeline and the thread it runs on. + // The media pipeline and a bool tracking whether we have started it yet. + // + // TODO(scherkus): replace |started_| with a pointer check for |pipeline_| and + // have WebMediaPlayerImpl return the default values to WebKit instead of + // relying on Pipeline to take care of default values. scoped_refptr<media::Pipeline> pipeline_; + bool started_; scoped_ptr<media::MessageLoopFactory> message_loop_factory_; diff --git a/webkit/media/webmediaplayer_proxy.cc b/webkit/media/webmediaplayer_proxy.cc index 2271878..4a2d929 100644 --- a/webkit/media/webmediaplayer_proxy.cc +++ b/webkit/media/webmediaplayer_proxy.cc @@ -50,10 +50,6 @@ void WebMediaPlayerProxy::SetOpaque(bool opaque) { &WebMediaPlayerProxy::SetOpaqueTask, this, opaque)); } -WebDataSourceBuildObserverHack WebMediaPlayerProxy::GetBuildObserver() { - return base::Bind(&WebMediaPlayerProxy::AddDataSource, this); -} - void WebMediaPlayerProxy::Paint(SkCanvas* canvas, const gfx::Rect& dest_rect) { DCHECK(MessageLoop::current() == render_loop_); if (frame_provider_) { @@ -66,38 +62,22 @@ void WebMediaPlayerProxy::Paint(SkCanvas* canvas, const gfx::Rect& dest_rect) { bool WebMediaPlayerProxy::HasSingleOrigin() { DCHECK(MessageLoop::current() == render_loop_); - - base::AutoLock auto_lock(data_sources_lock_); - - for (DataSourceList::iterator itr = data_sources_.begin(); - itr != data_sources_.end(); - itr++) { - if (!(*itr)->HasSingleOrigin()) - return false; - } + if (data_source_) + return data_source_->HasSingleOrigin(); return true; } -void WebMediaPlayerProxy::AbortDataSources() { +void WebMediaPlayerProxy::AbortDataSource() { DCHECK(MessageLoop::current() == render_loop_); - base::AutoLock auto_lock(data_sources_lock_); - - for (DataSourceList::iterator itr = data_sources_.begin(); - itr != data_sources_.end(); - itr++) { - (*itr)->Abort(); - } + if (data_source_) + data_source_->Abort(); } void WebMediaPlayerProxy::Detach() { DCHECK(MessageLoop::current() == render_loop_); webmediaplayer_ = NULL; + data_source_ = NULL; frame_provider_ = NULL; - - { - base::AutoLock auto_lock(data_sources_lock_); - data_sources_.clear(); - } } void WebMediaPlayerProxy::PipelineInitializationCallback( @@ -127,11 +107,6 @@ void WebMediaPlayerProxy::NetworkEventCallback(NetworkEvent type) { &WebMediaPlayerProxy::NetworkEventTask, this, type)); } -void WebMediaPlayerProxy::AddDataSource(WebDataSource* data_source) { - base::AutoLock auto_lock(data_sources_lock_); - data_sources_.push_back(make_scoped_refptr(data_source)); -} - void WebMediaPlayerProxy::RepaintTask() { DCHECK(MessageLoop::current() == render_loop_); { diff --git a/webkit/media/webmediaplayer_proxy.h b/webkit/media/webmediaplayer_proxy.h index e974f5a..da0ec50 100644 --- a/webkit/media/webmediaplayer_proxy.h +++ b/webkit/media/webmediaplayer_proxy.h @@ -38,6 +38,12 @@ class WebMediaPlayerProxy public: WebMediaPlayerProxy(MessageLoop* render_loop, WebMediaPlayerImpl* webmediaplayer); + const scoped_refptr<WebDataSource>& data_source() { + return data_source_; + } + void set_data_source(const scoped_refptr<WebDataSource>& data_source) { + data_source_ = data_source; + } // TODO(scherkus): remove this once VideoRendererBase::PaintCB passes // ownership of the VideoFrame http://crbug.com/108435 @@ -48,7 +54,6 @@ class WebMediaPlayerProxy // Methods for Filter -> WebMediaPlayerImpl communication. void Repaint(); void SetOpaque(bool opaque); - WebDataSourceBuildObserverHack GetBuildObserver(); // Methods for WebMediaPlayerImpl -> Filter communication. void Paint(SkCanvas* canvas, const gfx::Rect& dest_rect); @@ -56,7 +61,7 @@ class WebMediaPlayerProxy void GetCurrentFrame(scoped_refptr<media::VideoFrame>* frame_out); void PutCurrentFrame(scoped_refptr<media::VideoFrame> frame); bool HasSingleOrigin(); - void AbortDataSources(); + void AbortDataSource(); // Methods for Pipeline -> WebMediaPlayerImpl communication. void PipelineInitializationCallback(media::PipelineStatus status); @@ -85,9 +90,6 @@ class WebMediaPlayerProxy friend class base::RefCountedThreadSafe<WebMediaPlayerProxy>; virtual ~WebMediaPlayerProxy(); - // Adds a data source to data_sources_. - void AddDataSource(WebDataSource* data_source); - // Invoke |webmediaplayer_| to perform a repaint. void RepaintTask(); @@ -114,10 +116,7 @@ class WebMediaPlayerProxy MessageLoop* render_loop_; WebMediaPlayerImpl* webmediaplayer_; - base::Lock data_sources_lock_; - typedef std::list<scoped_refptr<WebDataSource> > DataSourceList; - DataSourceList data_sources_; - + scoped_refptr<WebDataSource> data_source_; scoped_refptr<media::VideoRendererBase> frame_provider_; SkCanvasVideoRenderer video_renderer_; |