diff options
Diffstat (limited to 'webkit')
-rw-r--r-- | webkit/glue/webmediaplayer_impl.cc | 128 | ||||
-rw-r--r-- | webkit/glue/webmediaplayer_impl.h | 38 |
2 files changed, 131 insertions, 35 deletions
diff --git a/webkit/glue/webmediaplayer_impl.cc b/webkit/glue/webmediaplayer_impl.cc index 62af5bb..76a9909 100644 --- a/webkit/glue/webmediaplayer_impl.cc +++ b/webkit/glue/webmediaplayer_impl.cc @@ -16,6 +16,7 @@ #include "media/base/pipeline_impl.h" #include "media/base/video_frame.h" #include "media/filters/adaptive_demuxer.h" +#include "media/filters/chunk_demuxer_factory.h" #include "media/filters/ffmpeg_audio_decoder.h" #include "media/filters/ffmpeg_demuxer_factory.h" #include "media/filters/ffmpeg_video_decoder.h" @@ -265,6 +266,52 @@ void WebMediaPlayerImpl::Proxy::PutCurrentFrame( video_renderer_->PutCurrentFrame(frame); } +void WebMediaPlayerImpl::Proxy::DemuxerOpened(media::ChunkDemuxer* demuxer) { + render_loop_->PostTask(FROM_HERE, NewRunnableMethod( + this, &WebMediaPlayerImpl::Proxy::DemuxerOpenedTask, + scoped_refptr<media::ChunkDemuxer>(demuxer))); +} + +void WebMediaPlayerImpl::Proxy::DemuxerClosed() { + render_loop_->PostTask(FROM_HERE, NewRunnableMethod( + this, &WebMediaPlayerImpl::Proxy::DemuxerClosedTask)); +} + +void WebMediaPlayerImpl::Proxy::DemuxerFlush() { + if (chunk_demuxer_.get()) + chunk_demuxer_->FlushData(); +} + +bool WebMediaPlayerImpl::Proxy::DemuxerAppend(const uint8* data, + size_t length) { + if (chunk_demuxer_.get()) + return chunk_demuxer_->AppendData(data, length); + return false; +} + +void WebMediaPlayerImpl::Proxy::DemuxerEndOfStream( + media::PipelineStatus status) { + if (chunk_demuxer_.get()) + chunk_demuxer_->EndOfStream(status); +} + +void WebMediaPlayerImpl::Proxy::DemuxerShutdown() { + if (chunk_demuxer_.get()) + chunk_demuxer_->Shutdown(); +} + +void WebMediaPlayerImpl::Proxy::DemuxerOpenedTask( + const scoped_refptr<media::ChunkDemuxer>& demuxer) { + DCHECK(MessageLoop::current() == render_loop_); + chunk_demuxer_ = demuxer; + if (webmediaplayer_) + webmediaplayer_->OnDemuxerOpened(); +} + +void WebMediaPlayerImpl::Proxy::DemuxerClosedTask() { + chunk_demuxer_ = NULL; +} + ///////////////////////////////////////////////////////////////////////////// // WebMediaPlayerImpl implementation @@ -341,17 +388,25 @@ bool WebMediaPlayerImpl::Initialize( data_source_factory->AddFactory(simple_data_source_factory.release()); } - if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kEnableAdaptive)) { - chunk_demuxer_factory_.reset(new media::ChunkDemuxerFactory()); - } - scoped_ptr<media::DemuxerFactory> demuxer_factory( new media::FFmpegDemuxerFactory(data_source_factory.release(), pipeline_message_loop)); if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kEnableAdaptive)) { demuxer_factory.reset(new media::AdaptiveDemuxerFactory( demuxer_factory.release())); - chunk_demuxer_factory_.reset(new media::ChunkDemuxerFactory()); + + std::string sourceUrl; + + // TODO(acolwell): Uncomment once WebKit changes are checked in. + // https://bugs.webkit.org/show_bug.cgi?id=64731 + //sourceUrl = GetClient()->sourceURL().spec(); + + if (!sourceUrl.empty()) { + demuxer_factory.reset( + new media::ChunkDemuxerFactory(sourceUrl, + demuxer_factory.release(), + proxy_)); + } } filter_collection_->SetDemuxerFactory(demuxer_factory.release()); @@ -390,12 +445,6 @@ void WebMediaPlayerImpl::load(const WebKit::WebURL& url) { } } - if (chunk_demuxer_factory_.get() && - chunk_demuxer_factory_->IsUrlSupported(url.spec())) { - media_data_sink_.reset(chunk_demuxer_factory_->CreateMediaDataSink()); - filter_collection_->SetDemuxerFactory(chunk_demuxer_factory_.release()); - } - // Handle any volume changes that occured before load(). setVolume(GetClient()->volume()); // Get the preload value. @@ -430,16 +479,6 @@ void WebMediaPlayerImpl::pause() { paused_time_ = pipeline_->GetCurrentTime(); } -bool WebMediaPlayerImpl::appendData(const unsigned char* data, - unsigned length) { - DCHECK(MessageLoop::current() == main_loop_); - - if (!media_data_sink_.get()) - return false; - - return media_data_sink_->AppendData(data, length); -} - bool WebMediaPlayerImpl::supportsFullscreen() const { DCHECK(MessageLoop::current() == main_loop_); return true; @@ -474,8 +513,7 @@ void WebMediaPlayerImpl::seek(float seconds) { seeking_ = true; - if (media_data_sink_.get()) - media_data_sink_->Flush(); + proxy_->DemuxerFlush(); // Kick off the asynchronous seek! pipeline_->Seek( @@ -788,6 +826,35 @@ void WebMediaPlayerImpl::putCurrentFrame( } } +// TODO(acolwell): Uncomment once WebKit changes are checked in. +// https://bugs.webkit.org/show_bug.cgi?id=64731 +/* +bool WebMediaPlayerImpl::sourceAppend(const unsigned char* data, + unsigned length) { + DCHECK(MessageLoop::current() == main_loop_); + return proxy_->DemuxerAppend(data, length); +} + +void WebMediaPlayerImpl::sourceEndOfStream( + WebKit::WebMediaPlayer::EndOfStreamStatus status) { + DCHECK(MessageLoop::current() == main_loop_); + media::PipelineStatus pipeline_status = media::PIPELINE_OK; + + switch(status) { + case WebKit::WebMediaPlayer::EosNetworkError: + pipeline_status = media::PIPELINE_ERROR_NETWORK; + break; + case WebKit::WebMediaPlayer::EosDecodeError: + pipeline_status = media::PIPELINE_ERROR_DECODE; + break; + default: + NOTIMPLEMENTED(); + } + + proxy_->DemuxerEndOfStream(pipeline_status); +} +*/ + void WebMediaPlayerImpl::WillDestroyCurrentMessageLoop() { Destroy(); main_loop_ = NULL; @@ -908,6 +975,14 @@ void WebMediaPlayerImpl::OnNetworkEvent(PipelineStatus status) { } } +void WebMediaPlayerImpl::OnDemuxerOpened() { + DCHECK(MessageLoop::current() == main_loop_); + + // TODO(acolwell): Uncomment once WebKit changes are checked in. + // https://bugs.webkit.org/show_bug.cgi?id=64731 + //GetClient()->sourceOpened(); +} + void WebMediaPlayerImpl::SetNetworkState( WebKit::WebMediaPlayer::NetworkState state) { DCHECK(MessageLoop::current() == main_loop_); @@ -929,11 +1004,10 @@ 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_) + if (proxy_) { proxy_->AbortDataSources(); - - if (media_data_sink_.get()) - media_data_sink_->Shutdown(); + 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. diff --git a/webkit/glue/webmediaplayer_impl.h b/webkit/glue/webmediaplayer_impl.h index 49ede0d..6ab8398 100644 --- a/webkit/glue/webmediaplayer_impl.h +++ b/webkit/glue/webmediaplayer_impl.h @@ -59,7 +59,8 @@ #include "base/threading/thread.h" #include "base/synchronization/lock.h" #include "base/synchronization/waitable_event.h" -#include "media/filters/chunk_demuxer_factory.h" +#include "media/filters/chunk_demuxer.h" +#include "media/filters/chunk_demuxer_client.h" #include "media/base/filters.h" #include "media/base/message_loop_factory.h" #include "media/base/pipeline.h" @@ -82,8 +83,9 @@ class MediaResourceLoaderBridgeFactory; class MediaStreamClient; class WebVideoRenderer; -class WebMediaPlayerImpl : public WebKit::WebMediaPlayer, - public MessageLoop::DestructionObserver { +class WebMediaPlayerImpl + : public WebKit::WebMediaPlayer, + public MessageLoop::DestructionObserver { public: // A proxy class that dispatches method calls from the media pipeline to // WebKit. Since there are multiple threads in the media pipeline and there's @@ -93,7 +95,9 @@ class WebMediaPlayerImpl : public WebKit::WebMediaPlayer, // on the render thread. // Because of the nature of this object that it works with different threads, // it is made ref-counted. - class Proxy : public base::RefCountedThreadSafe<Proxy> { + class Proxy + : public base::RefCountedThreadSafe<Proxy>, + public media::ChunkDemuxerClient { public: Proxy(MessageLoop* render_loop, WebMediaPlayerImpl* webmediaplayer); @@ -119,6 +123,19 @@ class WebMediaPlayerImpl : public WebKit::WebMediaPlayer, void PipelineErrorCallback(media::PipelineStatus error); void NetworkEventCallback(media::PipelineStatus status); + // Methods for ChunkDemuxerClient interface. + virtual void DemuxerOpened(media::ChunkDemuxer* demuxer); + virtual void DemuxerClosed(); + + // Methods for Demuxer communication. + void DemuxerFlush(); + bool DemuxerAppend(const uint8* data, size_t length); + void DemuxerEndOfStream(media::PipelineStatus status); + void DemuxerShutdown(); + + void DemuxerOpenedTask(const scoped_refptr<media::ChunkDemuxer>& demuxer); + void DemuxerClosedTask(); + // Returns the message loop used by the proxy. MessageLoop* message_loop() { return render_loop_; } @@ -162,6 +179,8 @@ class WebMediaPlayerImpl : public WebKit::WebMediaPlayer, base::Lock lock_; int outstanding_repaints_; + + scoped_refptr<media::ChunkDemuxer> chunk_demuxer_; }; // Construct a WebMediaPlayerImpl with reference to the client, and media @@ -204,7 +223,6 @@ class WebMediaPlayerImpl : public WebKit::WebMediaPlayer, // Playback controls. virtual void play(); virtual void pause(); - virtual bool appendData(const unsigned char* data, unsigned length); virtual bool supportsFullscreen() const; virtual bool supportsSave() const; virtual void seek(float seconds); @@ -260,6 +278,11 @@ class WebMediaPlayerImpl : public WebKit::WebMediaPlayer, virtual WebKit::WebVideoFrame* getCurrentFrame(); virtual void putCurrentFrame(WebKit::WebVideoFrame* web_video_frame); + // TODO(acolwell): Uncomment once WebKit changes are checked in. + // https://bugs.webkit.org/show_bug.cgi?id=64731 + //virtual bool sourceAppend(const unsigned char* data, unsigned length); + //virtual void sourceEndOfStream(EndOfStreamStatus status); + // As we are closing the tab or even the browser, |main_loop_| is destroyed // even before this object gets destructed, so we need to know when // |main_loop_| is being destroyed and we can stop posting repaint task @@ -278,6 +301,8 @@ class WebMediaPlayerImpl : public WebKit::WebMediaPlayer, void OnNetworkEvent(media::PipelineStatus status); + void OnDemuxerOpened(); + private: // Helpers that set the network/ready state and notifies the client if // they've changed. @@ -330,9 +355,6 @@ class WebMediaPlayerImpl : public WebKit::WebMediaPlayer, scoped_refptr<Proxy> proxy_; - scoped_ptr<media::ChunkDemuxerFactory> chunk_demuxer_factory_; - scoped_ptr<media::MediaDataSink> media_data_sink_; - MediaStreamClient* media_stream_client_; #if WEBKIT_USING_CG |