summaryrefslogtreecommitdiffstats
path: root/webkit/media
diff options
context:
space:
mode:
authordanakj@chromium.org <danakj@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-03-23 03:29:51 +0000
committerdanakj@chromium.org <danakj@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-03-23 03:29:51 +0000
commit21c3f7507002a55fbc3f1b1d5533416fbaab95d5 (patch)
treebc6dee6b3ad543c338169ba40deb097ff804a9ca /webkit/media
parent20717bdd1d1c198522b83c4917f5a036f1099321 (diff)
downloadchromium_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.h7
-rw-r--r--webkit/media/android/webmediaplayer_android.cc70
-rw-r--r--webkit/media/android/webmediaplayer_android.h31
-rw-r--r--webkit/media/webkit_media.gypi1
-rw-r--r--webkit/media/webmediaplayer_impl.cc57
-rw-r--r--webkit/media/webmediaplayer_impl.h25
-rw-r--r--webkit/media/webmediaplayer_ms.cc46
-rw-r--r--webkit/media/webmediaplayer_ms.h31
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_;