diff options
author | danakj@chromium.org <danakj@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-03-23 03:29:51 +0000 |
---|---|---|
committer | danakj@chromium.org <danakj@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-03-23 03:29:51 +0000 |
commit | 21c3f7507002a55fbc3f1b1d5533416fbaab95d5 (patch) | |
tree | bc6dee6b3ad543c338169ba40deb097ff804a9ca /webkit/media | |
parent | 20717bdd1d1c198522b83c4917f5a036f1099321 (diff) | |
download | chromium_src-21c3f7507002a55fbc3f1b1d5533416fbaab95d5.zip chromium_src-21c3f7507002a55fbc3f1b1d5533416fbaab95d5.tar.gz chromium_src-21c3f7507002a55fbc3f1b1d5533416fbaab95d5.tar.bz2 |
Move ownership of cc:VideoLayer to webkit/media
Currently the cc::VideoLayer is created and owned by the WebMediaPlayerClientImpl
in WebKit. Communication with the cc::VideoLayerImpl then must be done though the
WebVideoFrame and WebStreamTextureClient APIs.
This CL moves the creation and ownership of the cc::Video layer to the
WebMediaPlayer implementations in webkit/media, but does so behind a compiler
flag until the WebKit side to match it lands and enables the flag.
Then the communication between the WebMediaPlayer and cc::VideoLayerImpl can be
done directly through the cc::VideoFrameProvider interface. This interface is
implemented in the various implementations of WebMediaPlayer behind the
compiler flag as well, to be enabled when WebMediaPlayerClientImpl stops
implementing cc::VideoFrameProvider via WebVideoFrameProvider.
Once the WebKit side lands and rolls, we can completely remove all mention of
WebVideoFrame, WebVideoFrameProvider, and WebStreamTextureClientImpl.
R=jamesr
BUG=196810
Review URL: https://codereview.chromium.org/12676004
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@189979 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'webkit/media')
-rw-r--r-- | webkit/media/android/stream_texture_factory_android.h | 7 | ||||
-rw-r--r-- | webkit/media/android/webmediaplayer_android.cc | 70 | ||||
-rw-r--r-- | webkit/media/android/webmediaplayer_android.h | 31 | ||||
-rw-r--r-- | webkit/media/webkit_media.gypi | 1 | ||||
-rw-r--r-- | webkit/media/webmediaplayer_impl.cc | 57 | ||||
-rw-r--r-- | webkit/media/webmediaplayer_impl.h | 25 | ||||
-rw-r--r-- | webkit/media/webmediaplayer_ms.cc | 46 | ||||
-rw-r--r-- | webkit/media/webmediaplayer_ms.h | 31 |
8 files changed, 244 insertions, 24 deletions
diff --git a/webkit/media/android/stream_texture_factory_android.h b/webkit/media/android/stream_texture_factory_android.h index 749e0bb..dffcb8b 100644 --- a/webkit/media/android/stream_texture_factory_android.h +++ b/webkit/media/android/stream_texture_factory_android.h @@ -5,6 +5,9 @@ #ifndef WEBKIT_MEDIA_ANDROID_STREAM_TEXTURE_FACTORY_ANDROID_H_ #define WEBKIT_MEDIA_ANDROID_STREAM_TEXTURE_FACTORY_ANDROID_H_ +#include "cc/layers/video_frame_provider.h" +#include "third_party/WebKit/Source/Platform/chromium/public/WebVideoFrame.h" + namespace WebKit { class WebStreamTextureClient; } @@ -25,7 +28,11 @@ class StreamTextureProxy { // Setting the target for callback when a frame is available. This function // could be called on both the main thread and the compositor thread. +#ifndef REMOVE_WEBVIDEOFRAME virtual void SetClient(WebKit::WebStreamTextureClient* client) = 0; +#else + virtual void SetClient(cc::VideoFrameProvider::Client* client) = 0; +#endif }; diff --git a/webkit/media/android/webmediaplayer_android.cc b/webkit/media/android/webmediaplayer_android.cc index 1b65211..2bcaecd 100644 --- a/webkit/media/android/webmediaplayer_android.cc +++ b/webkit/media/android/webmediaplayer_android.cc @@ -7,10 +7,12 @@ #include "base/command_line.h" #include "base/files/file_path.h" #include "base/logging.h" +#include "cc/layers/video_layer.h" #include "media/base/android/media_player_bridge.h" #include "media/base/video_frame.h" #include "net/base/mime_util.h" #include "third_party/WebKit/Source/WebKit/chromium/public/WebMediaPlayerClient.h" +#include "webkit/compositor_bindings/web_layer_impl.h" #include "webkit/media/android/stream_texture_factory_android.h" #include "webkit/media/android/webmediaplayer_manager_android.h" #include "webkit/media/media_switches.h" @@ -47,7 +49,8 @@ WebMediaPlayerAndroid::WebMediaPlayerAndroid( needs_establish_peer_(true), has_size_info_(false), stream_texture_factory_(factory), - needs_external_surface_(false) { + needs_external_surface_(false), + video_frame_provider_client_(NULL) { main_loop_->AddDestructionObserver(this); if (manager_) player_id_ = manager_->RegisterMediaPlayer(this); @@ -65,6 +68,11 @@ WebMediaPlayerAndroid::WebMediaPlayerAndroid( } WebMediaPlayerAndroid::~WebMediaPlayerAndroid() { +#ifdef REMOVE_WEBVIDEOFRAME + SetVideoFrameProviderClient(NULL); + client_->setWebLayer(NULL); +#endif + if (stream_id_) stream_texture_factory_->DestroyStreamTexture(texture_id_); @@ -288,12 +296,22 @@ void WebMediaPlayerAndroid::OnMediaPrepared(base::TimeDelta duration) { if (ready_state_ != WebMediaPlayer::ReadyStateHaveEnoughData) { UpdateReadyState(WebMediaPlayer::ReadyStateHaveMetadata); UpdateReadyState(WebMediaPlayer::ReadyStateHaveEnoughData); +#ifndef REMOVE_WEBVIDEOFRAME } else { // If the status is already set to ReadyStateHaveEnoughData, set it again // to make sure that Videolayerchromium will get created. UpdateReadyState(WebMediaPlayer::ReadyStateHaveEnoughData); +#endif } +#ifdef REMOVE_WEBVIDEOFRAME + if (hasVideo() && !video_weblayer_ && client->needsWebLayerForVideo()) { + video_weblayer_.reset( + new webkit::WebLayerImpl(cc::VideoLayer::Create(this))); + client_->setWebLayer(video_weblayer_.get()); + } +#endif + // In we have skipped loading, we have to update webkit about the new // duration. if (duration_ != duration) { @@ -407,7 +425,7 @@ void WebMediaPlayerAndroid::Detach() { stream_id_ = 0; } - web_video_frame_.reset(); + current_frame_ = NULL; manager_ = NULL; } @@ -416,35 +434,35 @@ void WebMediaPlayerAndroid::ReallocateVideoFrame() { if (needs_external_surface_) { // VideoFrame::CreateHoleFrame is only defined under GOOGLE_TV. #if defined(GOOGLE_TV) - if (!natural_size_.isEmpty()) { - web_video_frame_.reset(new WebVideoFrameImpl(VideoFrame::CreateHoleFrame( - natural_size_))); - } + if (!natural_size_.isEmpty()) + current_frame_ = VideoFrame::CreateHoleFrame(natural_size_); #else NOTIMPLEMENTED() << "Hole punching not supported outside of Google TV"; #endif } else if (texture_id_) { - web_video_frame_.reset(new WebVideoFrameImpl(VideoFrame::WrapNativeTexture( + current_frame_ = VideoFrame::WrapNativeTexture( texture_id_, kGLTextureExternalOES, natural_size_, gfx::Rect(natural_size_), natural_size_, base::TimeDelta(), VideoFrame::ReadPixelsCB(), - base::Closure()))); + base::Closure()); } } +#ifndef REMOVE_WEBVIDEOFRAME WebVideoFrame* WebMediaPlayerAndroid::getCurrentFrame() { - if (stream_texture_proxy_.get() && !stream_texture_proxy_->IsInitialized() - && stream_id_ && !needs_external_surface_) { - gfx::Size natural_size = web_video_frame_->video_frame->natural_size(); + if (stream_texture_proxy_ && !stream_texture_proxy_->IsInitialized() && + stream_id_ && !needs_external_surface_) { + gfx::Size natural_size = current_frame_->natural_size(); stream_texture_proxy_->Initialize( stream_id_, natural_size.width(), natural_size.height()); } - return web_video_frame_.get(); + return new WebVideoFrameImpl(current_frame_); } void WebMediaPlayerAndroid::putCurrentFrame( WebVideoFrame* web_video_frame) { + delete web_video_frame; } void WebMediaPlayerAndroid::setStreamTextureClient( @@ -452,6 +470,34 @@ void WebMediaPlayerAndroid::setStreamTextureClient( if (stream_texture_proxy_.get()) stream_texture_proxy_->SetClient(client); } +#else +void WebMediaPlayerAndroid::SetVideoFrameProviderClient( + cc::VideoFrameProvider::Client* client) { + // This is called from both the main renderer thread and the compositor + // thread (when the main thread is blocked). + if (video_frame_provider_client_) + video_frame_provider_client_->StopUsingProvider(); + video_frame_provider_client_ = client; + + // Set the callback target when a frame is produced. + if (stream_texture_proxy_) + stream_texture_proxy_->SetClient(client); +} + +scoped_refptr<media::VideoFrame> WebMediaPlayerAndroid::GetCurrentFrame() { + if (stream_texture_proxy_ && !stream_texture_proxy_->IsInitialized() && + stream_id_ && !needs_external_surface_) { + gfx::Size natural_size = current_frame_->natural_size(); + stream_texture_proxy_->Initialize( + stream_id_, natural_size.width(), natural_size.height()); + } + return current_frame_; +} + +void WebMediaPlayerAndroid::PutCurrentFrame( + const scoped_refptr<media::VideoFrame>& frame) { +} +#endif void WebMediaPlayerAndroid::EstablishSurfaceTexturePeer() { if (stream_texture_factory_.get() && stream_id_) diff --git a/webkit/media/android/webmediaplayer_android.h b/webkit/media/android/webmediaplayer_android.h index ef53520..fb5fae1 100644 --- a/webkit/media/android/webmediaplayer_android.h +++ b/webkit/media/android/webmediaplayer_android.h @@ -8,9 +8,11 @@ #include <jni.h> #include "base/basictypes.h" -#include "base/message_loop.h" +#include "base/memory/ref_counted.h" #include "base/memory/scoped_ptr.h" +#include "base/message_loop.h" #include "base/time.h" +#include "cc/layers/video_frame_provider.h" #include "third_party/WebKit/Source/Platform/chromium/public/WebSize.h" #include "third_party/WebKit/Source/Platform/chromium/public/WebURL.h" #include "third_party/WebKit/Source/WebKit/chromium/public/WebMediaPlayer.h" @@ -19,6 +21,10 @@ namespace WebKit { class WebVideoFrame; } +namespace webkit { +class WebLayerImpl; +} + namespace webkit_media { class StreamTextureFactory; @@ -30,6 +36,9 @@ class WebVideoFrameImpl; // WebKit::WebMediaPlayer on Android. class WebMediaPlayerAndroid : public WebKit::WebMediaPlayer, +#ifdef REMOVE_WEBVIDEOFRAME + public cc::VideoFrameProvider, +#endif public MessageLoop::DestructionObserver { public: // Resource loading. @@ -94,6 +103,7 @@ class WebMediaPlayerAndroid virtual unsigned audioDecodedByteCount() const; virtual unsigned videoDecodedByteCount() const; +#ifndef REMOVE_WEBVIDEOFRAME // Methods called from VideoLayerChromium. These methods are running on the // compositor thread. virtual WebKit::WebVideoFrame* getCurrentFrame(); @@ -102,6 +112,15 @@ class WebMediaPlayerAndroid // This gets called both on compositor and main thread to set the callback // target when a frame is produced. virtual void setStreamTextureClient(WebKit::WebStreamTextureClient* client); +#else + // cc::VideoFrameProvider implementation. These methods are running on the + // compositor thread. + virtual void SetVideoFrameProviderClient( + cc::VideoFrameProvider::Client* client) OVERRIDE; + virtual scoped_refptr<media::VideoFrame> GetCurrentFrame() OVERRIDE; + virtual void PutCurrentFrame(const scoped_refptr<media::VideoFrame>& frame) + OVERRIDE; +#endif // Media player callback handlers. virtual void OnMediaPrepared(base::TimeDelta duration); @@ -195,8 +214,8 @@ class WebMediaPlayerAndroid // Size of the video. WebKit::WebSize natural_size_; - // The video frame object used for renderering by WebKit. - scoped_ptr<WebVideoFrameImpl> web_video_frame_; + // The video frame object used for rendering by the compositor. + scoped_refptr<media::VideoFrame> current_frame_; // Message loop for main renderer thread. MessageLoop* main_loop_; @@ -251,6 +270,12 @@ class WebMediaPlayerAndroid // Whether media player needs external surface. bool needs_external_surface_; + // A pointer back to the compositor to inform it about state changes. This is + // not NULL while the compositor is actively using this webmediaplayer. + cc::VideoFrameProvider::Client* video_frame_provider_client_; + + scoped_ptr<webkit::WebLayerImpl> video_weblayer_; + DISALLOW_COPY_AND_ASSIGN(WebMediaPlayerAndroid); }; diff --git a/webkit/media/webkit_media.gypi b/webkit/media/webkit_media.gypi index 5941990..37a069e 100644 --- a/webkit/media/webkit_media.gypi +++ b/webkit/media/webkit_media.gypi @@ -39,6 +39,7 @@ '<(DEPTH)/media/media.gyp:yuv_convert', '<(DEPTH)/skia/skia.gyp:skia', '<(DEPTH)/third_party/widevine/cdm/widevine_cdm.gyp:widevine_cdm_version_h', + '<(DEPTH)/webkit/compositor_bindings/compositor_bindings.gyp:webkit_compositor_bindings', '<(webkit_src_dir)/Source/WebKit/chromium/WebKit.gyp:webkit', ], 'sources': [ diff --git a/webkit/media/webmediaplayer_impl.cc b/webkit/media/webmediaplayer_impl.cc index 7ccb522..37af4aa 100644 --- a/webkit/media/webmediaplayer_impl.cc +++ b/webkit/media/webmediaplayer_impl.cc @@ -15,6 +15,7 @@ #include "base/metrics/histogram.h" #include "base/string_number_conversions.h" #include "base/synchronization/waitable_event.h" +#include "cc/layers/video_layer.h" #include "gpu/GLES2/gl2extchromium.h" #include "media/audio/null_audio_sink.h" #include "media/base/bind_to_loop.h" @@ -34,6 +35,7 @@ #include "third_party/WebKit/Source/WebKit/chromium/public/WebRuntimeFeatures.h" #include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h" #include "v8/include/v8.h" +#include "webkit/compositor_bindings/web_layer_impl.h" #include "webkit/media/buffered_data_source.h" #include "webkit/media/filter_helpers.h" #include "webkit/media/webaudiosourceprovider_impl.h" @@ -145,7 +147,8 @@ WebMediaPlayerImpl::WebMediaPlayerImpl( is_local_source_(false), supports_save_(true), starting_(false), - pending_repaint_(false) { + pending_repaint_(false), + video_frame_provider_client_(NULL) { media_log_->AddEvent( media_log_->CreateEvent(media::MediaLogEvent::WEBMEDIAPLAYER_CREATED)); @@ -216,6 +219,11 @@ WebMediaPlayerImpl::WebMediaPlayerImpl( } WebMediaPlayerImpl::~WebMediaPlayerImpl() { +#ifdef REMOVE_WEBVIDEOFRAME + SetVideoFrameProviderClient(NULL); + GetClient()->setWebLayer(NULL); +#endif + DCHECK(main_loop_->BelongsToCurrentThread()); Destroy(); media_log_->AddEvent( @@ -661,6 +669,7 @@ unsigned WebMediaPlayerImpl::videoDecodedByteCount() const { return stats.video_bytes_decoded; } +#ifndef REMOVE_WEBVIDEOFRAME WebKit::WebVideoFrame* WebMediaPlayerImpl::getCurrentFrame() { base::AutoLock auto_lock(lock_); if (current_frame_) @@ -677,6 +686,30 @@ void WebMediaPlayerImpl::putCurrentFrame( } delete web_video_frame; } +#else +void WebMediaPlayerImpl::SetVideoFrameProviderClient( + cc::VideoFrameProvider::Client* client) { + // This is called from both the main renderer thread and the compositor + // thread (when the main thread is blocked). + if (video_frame_provider_client_) + video_frame_provider_client_->StopUsingProvider(); + video_frame_provider_client_ = client; +} + +scoped_refptr<media::VideoFrame> WebMediaPlayerImpl::GetCurrentFrame() { + base::AutoLock auto_lock(lock_); + return current_frame_; +} + +void WebMediaPlayerImpl::PutCurrentFrame( + const scoped_refptr<media::VideoFrame>& frame) { + if (!accelerated_compositing_reported_) { + accelerated_compositing_reported_ = true; + DCHECK(frame_->view()->isAcceleratedCompositingActive()); + UMA_HISTOGRAM_BOOLEAN("Media.AcceleratedCompositingActive", true); + } +} +#endif bool WebMediaPlayerImpl::copyVideoTextureToPlatformTexture( WebKit::WebGraphicsContext3D* web_graphics_context, @@ -967,6 +1000,15 @@ void WebMediaPlayerImpl::OnPipelineBufferingState( switch (buffering_state) { case media::Pipeline::kHaveMetadata: SetReadyState(WebMediaPlayer::ReadyStateHaveMetadata); + +#ifdef REMOVE_WEBVIDEOFRAME + if (hasVideo() && GetClient()->needsWebLayerForVideo()) { + DCHECK(!video_weblayer_); + video_weblayer_.reset( + new webkit::WebLayerImpl(cc::VideoLayer::Create(this))); + GetClient()->setWebLayer(video_weblayer_.get()); + } +#endif break; case media::Pipeline::kPrerollCompleted: SetReadyState(WebMediaPlayer::ReadyStateHaveEnoughData); @@ -1119,16 +1161,17 @@ void WebMediaPlayerImpl::SetReadyState(WebMediaPlayer::ReadyState state) { DCHECK(main_loop_->BelongsToCurrentThread()); DVLOG(1) << "SetReadyState: " << state; +#ifndef REMOVE_WEBVIDEOFRAME if (ready_state_ == WebMediaPlayer::ReadyStateHaveNothing && state >= WebMediaPlayer::ReadyStateHaveMetadata) { if (!hasVideo()) GetClient()->disableAcceleratedCompositing(); - } else if (state == WebMediaPlayer::ReadyStateHaveEnoughData) { - if (is_local_source_ && - network_state_ == WebMediaPlayer::NetworkStateLoading) { - SetNetworkState(WebMediaPlayer::NetworkStateLoaded); - } - } + } else +#endif + if (state == WebMediaPlayer::ReadyStateHaveEnoughData && + is_local_source_ && + network_state_ == WebMediaPlayer::NetworkStateLoading) + SetNetworkState(WebMediaPlayer::NetworkStateLoaded); ready_state_ = state; // Always notify to ensure client has the latest value. diff --git a/webkit/media/webmediaplayer_impl.h b/webkit/media/webmediaplayer_impl.h index 2826e90..57afd6b 100644 --- a/webkit/media/webmediaplayer_impl.h +++ b/webkit/media/webmediaplayer_impl.h @@ -26,6 +26,7 @@ #include "base/memory/scoped_ptr.h" #include "base/memory/weak_ptr.h" #include "base/threading/thread.h" +#include "cc/layers/video_frame_provider.h" #include "googleurl/src/gurl.h" #include "media/base/audio_renderer_sink.h" #include "media/base/decryptor.h" @@ -54,6 +55,10 @@ class ChunkDemuxer; class MediaLog; } +namespace webkit { +class WebLayerImpl; +} + namespace webkit_media { class BufferedDataSource; @@ -64,6 +69,9 @@ class WebMediaPlayerParams; class WebMediaPlayerImpl : public WebKit::WebMediaPlayer, +#ifdef REMOVE_WEBVIDEOFRAME + public cc::VideoFrameProvider, +#endif public MessageLoop::DestructionObserver, public base::SupportsWeakPtr<WebMediaPlayerImpl> { public: @@ -141,8 +149,17 @@ class WebMediaPlayerImpl virtual unsigned audioDecodedByteCount() const; virtual unsigned videoDecodedByteCount() const; +#ifndef REMOVE_WEBVIDEOFRAME virtual WebKit::WebVideoFrame* getCurrentFrame(); virtual void putCurrentFrame(WebKit::WebVideoFrame* web_video_frame); +#else + // cc::VideoFrameProvider implementation. + virtual void SetVideoFrameProviderClient( + cc::VideoFrameProvider::Client* client) OVERRIDE; + virtual scoped_refptr<media::VideoFrame> GetCurrentFrame() OVERRIDE; + virtual void PutCurrentFrame(const scoped_refptr<media::VideoFrame>& frame) + OVERRIDE; +#endif virtual bool copyVideoTextureToPlatformTexture( WebKit::WebGraphicsContext3D* web_graphics_context, @@ -341,6 +358,14 @@ class WebMediaPlayerImpl scoped_refptr<media::VideoFrame> current_frame_; bool pending_repaint_; + // The compositor layer for displaying the video content when using composited + // playback. + scoped_ptr<webkit::WebLayerImpl> video_weblayer_; + + // A pointer back to the compositor to inform it about state changes. This is + // not NULL while the compositor is actively using this webmediaplayer. + cc::VideoFrameProvider::Client* video_frame_provider_client_; + DISALLOW_COPY_AND_ASSIGN(WebMediaPlayerImpl); }; diff --git a/webkit/media/webmediaplayer_ms.cc b/webkit/media/webmediaplayer_ms.cc index fc21a3a..a79594e 100644 --- a/webkit/media/webmediaplayer_ms.cc +++ b/webkit/media/webmediaplayer_ms.cc @@ -10,6 +10,7 @@ #include "base/callback.h" #include "base/message_loop.h" #include "base/metrics/histogram.h" +#include "cc/layers/video_layer.h" #include "media/base/media_log.h" #include "media/base/video_frame.h" #include "third_party/WebKit/Source/Platform/chromium/public/WebRect.h" @@ -19,6 +20,7 @@ #include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h" #include "third_party/WebKit/Source/WebKit/chromium/public/WebMediaPlayerClient.h" #include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h" +#include "webkit/compositor_bindings/web_layer_impl.h" #include "webkit/media/media_stream_audio_renderer.h" #include "webkit/media/media_stream_client.h" #include "webkit/media/video_frame_provider.h" @@ -49,6 +51,7 @@ WebMediaPlayerMS::WebMediaPlayerMS( paused_(true), current_frame_used_(false), pending_repaint_(false), + video_frame_provider_client_(NULL), received_first_frame_(false), sequence_started_(false), total_frame_count_(0), @@ -63,6 +66,12 @@ WebMediaPlayerMS::WebMediaPlayerMS( WebMediaPlayerMS::~WebMediaPlayerMS() { DVLOG(1) << "WebMediaPlayerMS::dtor"; DCHECK(thread_checker_.CalledOnValidThread()); + +#ifdef REMOVE_WEBVIDEOFRAME + SetVideoFrameProviderClient(NULL); + GetClient()->setWebLayer(NULL); +#endif + if (video_frame_provider_) { video_frame_provider_->Stop(); } @@ -358,6 +367,7 @@ unsigned WebMediaPlayerMS::videoDecodedByteCount() const { return 0; } +#ifndef REMOVE_WEBVIDEOFRAME WebKit::WebVideoFrame* WebMediaPlayerMS::getCurrentFrame() { DVLOG(3) << "WebMediaPlayerMS::getCurrentFrame"; base::AutoLock auto_lock(current_frame_lock_); @@ -380,6 +390,34 @@ void WebMediaPlayerMS::putCurrentFrame( delete web_video_frame; } } +#else +void WebMediaPlayerMS::SetVideoFrameProviderClient( + cc::VideoFrameProvider::Client* client) { + // This is called from both the main renderer thread and the compositor + // thread (when the main thread is blocked). + if (video_frame_provider_client_) + video_frame_provider_client_->StopUsingProvider(); + video_frame_provider_client_ = client; +} + +scoped_refptr<media::VideoFrame> WebMediaPlayerMS::GetCurrentFrame() { + DVLOG(3) << "WebMediaPlayerMS::GetCurrentFrame"; + base::AutoLock auto_lock(current_frame_lock_); + DCHECK(!pending_repaint_); + if (!current_frame_) + return NULL; + pending_repaint_ = true; + current_frame_used_ = true; + return current_frame_; +} + +void WebMediaPlayerMS::PutCurrentFrame( + const scoped_refptr<media::VideoFrame>& frame) { + DVLOG(3) << "WebMediaPlayerMS::PutCurrentFrame"; + DCHECK(pending_repaint_); + pending_repaint_ = false; +} +#endif void WebMediaPlayerMS::OnFrameAvailable( const scoped_refptr<media::VideoFrame>& frame) { @@ -397,6 +435,14 @@ void WebMediaPlayerMS::OnFrameAvailable( SetReadyState(WebMediaPlayer::ReadyStateHaveMetadata); SetReadyState(WebMediaPlayer::ReadyStateHaveEnoughData); GetClient()->sizeChanged(); + +#ifdef REMOVE_WEBVIDEOFRAME + if (video_frame_provider_ && GetClient()->needsWebLayerForVideo()) { + video_weblayer_.reset( + new webkit::WebLayerImpl(cc::VideoLayer::Create(this))); + GetClient()->setWebLayer(video_weblayer_.get()); + } +#endif } // Do not update |current_frame_| when paused. diff --git a/webkit/media/webmediaplayer_ms.h b/webkit/media/webmediaplayer_ms.h index 9d2d43e..7fe508e 100644 --- a/webkit/media/webmediaplayer_ms.h +++ b/webkit/media/webmediaplayer_ms.h @@ -9,6 +9,7 @@ #include "base/memory/scoped_ptr.h" #include "base/memory/weak_ptr.h" #include "base/synchronization/lock.h" +#include "cc/layers/video_frame_provider.h" #include "googleurl/src/gurl.h" #include "media/filters/skcanvas_video_renderer.h" #include "skia/ext/platform_canvas.h" @@ -24,6 +25,10 @@ namespace media { class MediaLog; } +namespace webkit { +class WebLayerImpl; +} + namespace webkit_media { class MediaStreamAudioRenderer; @@ -47,6 +52,9 @@ class WebMediaPlayerDelegate; // WebKit client of this media player object. class WebMediaPlayerMS : public WebKit::WebMediaPlayer, +#ifdef REMOVE_WEBVIDEOFRAME + public cc::VideoFrameProvider, +#endif public base::SupportsWeakPtr<WebMediaPlayerMS> { public: // Construct a WebMediaPlayerMS with reference to the client, and @@ -120,8 +128,17 @@ class WebMediaPlayerMS virtual unsigned audioDecodedByteCount() const OVERRIDE; virtual unsigned videoDecodedByteCount() const OVERRIDE; +#ifndef REMOVE_WEBVIDEOFRAME virtual WebKit::WebVideoFrame* getCurrentFrame() OVERRIDE; virtual void putCurrentFrame(WebKit::WebVideoFrame* web_video_frame) OVERRIDE; +#else + // VideoFrameProvider implementation. + virtual void SetVideoFrameProviderClient( + cc::VideoFrameProvider::Client* client) OVERRIDE; + virtual scoped_refptr<media::VideoFrame> GetCurrentFrame() OVERRIDE; + virtual void PutCurrentFrame(const scoped_refptr<media::VideoFrame>& frame) + OVERRIDE; +#endif private: // The callback for VideoFrameProvider to signal a new frame is available. @@ -155,9 +172,12 @@ class WebMediaPlayerMS base::WeakPtr<WebMediaPlayerDelegate> delegate_; MediaStreamClient* media_stream_client_; - scoped_refptr<VideoFrameProvider> video_frame_provider_; + scoped_refptr<webkit_media::VideoFrameProvider> video_frame_provider_; bool paused_; - // |current_frame_| is updated only on main thread. + + // |current_frame_| is updated only on main thread. The object it holds + // can be freed on the compositor thread if it is the last to hold a + // reference but media::VideoFrame is a thread-safe ref-pointer. scoped_refptr<media::VideoFrame> current_frame_; // |current_frame_used_| is updated on both main and compositing thread. // It's used to track whether |current_frame_| was painted for detecting @@ -165,6 +185,13 @@ class WebMediaPlayerMS bool current_frame_used_; base::Lock current_frame_lock_; bool pending_repaint_; + + scoped_ptr<webkit::WebLayerImpl> video_weblayer_; + + // A pointer back to the compositor to inform it about state changes. This is + // not NULL while the compositor is actively using this webmediaplayer. + cc::VideoFrameProvider::Client* video_frame_provider_client_; + bool received_first_frame_; bool sequence_started_; base::TimeDelta start_time_; |