WebCore: Render textures in video frame directly.
authorhclam@chromium.org <hclam@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 6 Oct 2010 00:52:59 +0000 (00:52 +0000)
committerhclam@chromium.org <hclam@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 6 Oct 2010 00:52:59 +0000 (00:52 +0000)
https://bugs.webkit.org/show_bug.cgi?id=46765

Reviewed by NOBODY (OOPS!).

Render textures in VideoLayerChromium directly if the video frame type
is GL texture. In the future VideoLayerChromium will not allocate
textures and perform textures upload as those operations will be done
in Chromium to minimize memory copy. This patch will help moving toward
this direction and facilitate hardware video decoding.

* platform/graphics/chromium/VideoFrameChromium.h:
* platform/graphics/chromium/VideoFrameProvider.h:
(WebCore::VideoFrameProvider::~VideoFrameProvider):
* platform/graphics/chromium/VideoLayerChromium.cpp:
(WebCore::VideoLayerChromium::VideoLayerChromium):
(WebCore::VideoLayerChromium::~VideoLayerChromium):
(WebCore::VideoLayerChromium::updateContents):
(WebCore::VideoLayerChromium::draw):
(WebCore::VideoLayerChromium::releaseCurrentFrame):
(WebCore::VideoLayerChromium::resetFrameParameters):
(WebCore::VideoLayerChromium::saveCurrentFrame):
* platform/graphics/chromium/VideoLayerChromium.h:
(WebCore::VideoLayerChromium::SharedValues::initialized):

WebKit/chromium: Add getter for accessing textures stored in VideoFrameChromium and WebVideoFrame.
Also explicitly instruct VideoLayerChromium to release video frame when the owner
of video frame is going away.

Reviewed by NOBODY (OOPS!).

* public/WebVideoFrame.h:
* src/AssertMatchingEnums.cpp:
* src/VideoFrameChromiumImpl.cpp:
(WebKit::VideoFrameChromiumImpl::texture):
* src/VideoFrameChromiumImpl.h:
* src/WebMediaPlayerClientImpl.cpp:
(WebKit::WebMediaPlayerClientImpl::~WebMediaPlayerClientImpl):
(WebKit::WebMediaPlayerClientImpl::load):
* src/WebMediaPlayerClientImpl.h:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@69163 268f45cc-cd09-0410-ab3c-d52691b4dbfc

12 files changed:
WebCore/ChangeLog
WebCore/platform/graphics/chromium/VideoFrameChromium.h
WebCore/platform/graphics/chromium/VideoFrameProvider.h
WebCore/platform/graphics/chromium/VideoLayerChromium.cpp
WebCore/platform/graphics/chromium/VideoLayerChromium.h
WebKit/chromium/ChangeLog
WebKit/chromium/public/WebVideoFrame.h
WebKit/chromium/src/AssertMatchingEnums.cpp
WebKit/chromium/src/VideoFrameChromiumImpl.cpp
WebKit/chromium/src/VideoFrameChromiumImpl.h
WebKit/chromium/src/WebMediaPlayerClientImpl.cpp
WebKit/chromium/src/WebMediaPlayerClientImpl.h

index 1fde569..53dc2da 100644 (file)
@@ -1,3 +1,30 @@
+2010-09-29  Alpha Lam  <hclam@chromium.org>
+
+        Reviewed by James Robinson.
+
+        Render textures in video frame directly.
+        https://bugs.webkit.org/show_bug.cgi?id=46765
+
+        Render textures in VideoLayerChromium directly if the video frame type
+        is GL texture. In the future VideoLayerChromium will not allocate
+        textures and perform textures upload as those operations will be done
+        in Chromium to minimize memory copy. This patch will help moving toward
+        this direction and facilitate hardware video decoding.
+
+        * platform/graphics/chromium/VideoFrameChromium.h:
+        * platform/graphics/chromium/VideoFrameProvider.h:
+        (WebCore::VideoFrameProvider::~VideoFrameProvider):
+        * platform/graphics/chromium/VideoLayerChromium.cpp:
+        (WebCore::VideoLayerChromium::VideoLayerChromium):
+        (WebCore::VideoLayerChromium::~VideoLayerChromium):
+        (WebCore::VideoLayerChromium::updateContents):
+        (WebCore::VideoLayerChromium::draw):
+        (WebCore::VideoLayerChromium::releaseCurrentFrame):
+        (WebCore::VideoLayerChromium::resetFrameParameters):
+        (WebCore::VideoLayerChromium::saveCurrentFrame):
+        * platform/graphics/chromium/VideoLayerChromium.h:
+        (WebCore::VideoLayerChromium::SharedValues::initialized):
+
 2010-10-05  Fady Samuel  <fsamuel@chromium.org>
 
         Reviewed by Darin Adler.
index 34e922b..e176b0c 100644 (file)
@@ -63,10 +63,7 @@ public:
 
     enum SurfaceType {
         TypeSystemMemory,
-        TypeOMXBufferHead,
-        TypeEGLImage,
-        TypeMFBuffer,
-        TypeDirect3DSurface
+        TypeTexture,
     };
 
     virtual SurfaceType surfaceType() const = 0;
@@ -76,6 +73,7 @@ public:
     virtual unsigned planes() const = 0;
     virtual int stride(unsigned plane) const = 0;
     virtual const void* data(unsigned plane) const = 0;
+    virtual unsigned texture(unsigned plane) const = 0;
     virtual const IntSize requiredTextureSize(unsigned plane) const = 0;
 };
 
index f0bad08..c596f87 100644 (file)
@@ -37,6 +37,8 @@ namespace WebCore {
 
 class VideoFrameProvider {
 public:
+    virtual ~VideoFrameProvider() { }
+
     // This function returns a pointer to a VideoFrameChromium, which is
     // the WebCore wrapper for a video frame in Chromium. getCurrentFrame()
     // places a lock on the frame in Chromium. Calls to this method should
index 56c6d8d..8781084 100644 (file)
@@ -175,18 +175,16 @@ VideoLayerChromium::VideoLayerChromium(GraphicsLayerChromium* owner, VideoFrameP
     , m_skipsDraw(true)
     , m_frameFormat(VideoFrameChromium::Invalid)
     , m_provider(provider)
+    , m_currentFrame(0)
 {
-    for (unsigned plane = 0; plane < VideoFrameChromium::maxPlanes; plane++) {
-        m_textures[plane] = 0;
-        m_textureSizes[plane] = IntSize();
-        m_frameSizes[plane] = IntSize();
-    }
+    resetFrameParameters();
 }
 
 VideoLayerChromium::~VideoLayerChromium()
 {
-    ASSERT(layerRenderer());
+    releaseCurrentFrame();
 
+    ASSERT(layerRenderer());
     GraphicsContext3D* context = layerRendererContext();
     for (unsigned plane = 0; plane < VideoFrameChromium::maxPlanes; plane++) {
         if (m_textures[plane])
@@ -220,6 +218,14 @@ void VideoLayerChromium::updateContents()
         return;
     }
 
+    if (frame->surfaceType() == VideoFrameChromium::TypeTexture) {
+        releaseCurrentFrame();
+        saveCurrentFrame(frame);
+        m_dirtyRect.setSize(FloatSize());
+        m_contentsDirty = false;
+        return;
+    }
+
     // Allocate textures for planes if they are not allocated already, or
     // reallocate textures that are the wrong size for the frame.
     GraphicsContext3D* context = layerRendererContext();
@@ -238,6 +244,7 @@ void VideoLayerChromium::updateContents()
 
     m_dirtyRect.setSize(FloatSize());
     m_contentsDirty = false;
+
     m_provider->putCurrentFrame(frame);
 }
 
@@ -321,6 +328,17 @@ void VideoLayerChromium::draw()
         notImplemented();
         break;
     }
+    releaseCurrentFrame();
+}
+
+void VideoLayerChromium::releaseCurrentFrame()
+{
+    if (!m_currentFrame)
+        return;
+
+    m_provider->putCurrentFrame(m_currentFrame);
+    m_currentFrame = 0;
+    resetFrameParameters();
 }
 
 void VideoLayerChromium::drawYUV(const SharedValues* sv)
@@ -372,6 +390,26 @@ void VideoLayerChromium::drawRGBA(const SharedValues* sv)
                      sv->rgbaShaderMatrixLocation(), sv->rgbaAlphaLocation());
 }
 
+void VideoLayerChromium::resetFrameParameters()
+{
+    for (unsigned plane = 0; plane < VideoFrameChromium::maxPlanes; plane++) {
+        m_textures[plane] = 0;
+        m_textureSizes[plane] = IntSize();
+        m_frameSizes[plane] = IntSize();
+    }
+}
+
+void VideoLayerChromium::saveCurrentFrame(VideoFrameChromium* frame)
+{
+    ASSERT(!m_currentFrame);
+    m_currentFrame = frame;
+    for (unsigned plane = 0; plane < frame->planes(); plane++) {
+        m_textures[plane] = frame->texture(plane);
+        m_textureSizes[plane] = frame->requiredTextureSize(plane);
+        m_frameSizes[plane] = m_textureSizes[plane];
+    }
+}
+
 } // namespace WebCore
 
 #endif // USE(ACCELERATED_COMPOSITING)
index 620d1a7..92b6fc2 100644 (file)
@@ -49,6 +49,10 @@ public:
     virtual bool drawsContent() { return true; }
     virtual void draw();
 
+    // This function is called by VideoFrameProvider. When this method is called
+    // putCurrentFrame() must be called to return the frame currently held.
+    void releaseCurrentFrame();
+
     class SharedValues {
     public:
         explicit SharedValues(GraphicsContext3D*);
@@ -66,7 +70,7 @@ public:
         int rgbaAlphaLocation() const { return m_rgbaAlphaLocation; }
         int rgbaTextureLocation() const { return m_rgbaTextureLocation; }
         int ccMatrixLocation() const { return m_ccMatrixLocation; }
-        bool initialized() const { return m_initialized; };
+        bool initialized() const { return m_initialized; }
     private:
         GraphicsContext3D* m_context;
         unsigned m_yuvShaderProgram;
@@ -95,12 +99,16 @@ private:
     void updateTexture(GraphicsContext3D*, unsigned textureId, const IntSize& dimensions, unsigned textureFormat, const void* data);
     void drawYUV(const SharedValues*);
     void drawRGBA(const SharedValues*);
+    void resetFrameParameters();
+    void saveCurrentFrame(VideoFrameChromium*);
 
     static const float yuv2RGB[9];
 
     bool m_skipsDraw;
     VideoFrameChromium::Format m_frameFormat;
-    OwnPtr<VideoFrameProvider> m_provider;
+    VideoFrameProvider* m_provider;
+    VideoFrameChromium* m_currentFrame;
+
     unsigned m_textures[3];
     IntSize m_textureSizes[3];
     IntSize m_frameSizes[3];
index 8daf635..d884ab6 100644 (file)
@@ -1,3 +1,24 @@
+2010-09-29  Alpha Lam  <hclam@chromium.org>
+
+        Reviewed by James Robinson.
+
+        Render textures in video frame directly.
+        https://bugs.webkit.org/show_bug.cgi?id=46765
+
+        Add getter for accessing textures stored in VideoFrameChromium and WebVideoFrame.
+        Also explicitly instruct VideoLayerChromium to release video frame when the owner
+        of video frame is going away.
+
+        * public/WebVideoFrame.h:
+        * src/AssertMatchingEnums.cpp:
+        * src/VideoFrameChromiumImpl.cpp:
+        (WebKit::VideoFrameChromiumImpl::texture):
+        * src/VideoFrameChromiumImpl.h:
+        * src/WebMediaPlayerClientImpl.cpp:
+        (WebKit::WebMediaPlayerClientImpl::~WebMediaPlayerClientImpl):
+        (WebKit::WebMediaPlayerClientImpl::load):
+        * src/WebMediaPlayerClientImpl.h:
+
 2010-10-05  Nat Duca  <nduca@chromium.org>
 
         Reviewed by James Robinson.
index 5e34f2a..58f1111 100644 (file)
@@ -53,10 +53,7 @@ public:
 
     enum SurfaceType {
         SurfaceTypeSystemMemory,
-        SurfaceTypeOMXBufferHead,
-        SurfaceTypeEGLImage,
-        SurfaceTypeMFBuffer,
-        SurfaceTypeDirect3DSurface
+        SurfaceTypeTexture,
     };
 
     virtual SurfaceType surfaceType() const = 0;
@@ -66,6 +63,7 @@ public:
     virtual unsigned planes() const = 0;
     virtual int stride(unsigned plane) const = 0;
     virtual const void* data(unsigned plane) const = 0;
+    virtual unsigned texture(unsigned plane) const = 0;
 };
 
 } // namespace WebKit
index f3b8f5a..9647a44 100644 (file)
@@ -321,10 +321,7 @@ COMPILE_ASSERT_MATCHING_ENUM(WebVideoFrame::FormatEmpty, VideoFrameChromium::Emp
 COMPILE_ASSERT_MATCHING_ENUM(WebVideoFrame::FormatASCII, VideoFrameChromium::ASCII);
 
 COMPILE_ASSERT_MATCHING_ENUM(WebVideoFrame::SurfaceTypeSystemMemory, VideoFrameChromium::TypeSystemMemory);
-COMPILE_ASSERT_MATCHING_ENUM(WebVideoFrame::SurfaceTypeOMXBufferHead, VideoFrameChromium::TypeOMXBufferHead);
-COMPILE_ASSERT_MATCHING_ENUM(WebVideoFrame::SurfaceTypeEGLImage, VideoFrameChromium::TypeEGLImage);
-COMPILE_ASSERT_MATCHING_ENUM(WebVideoFrame::SurfaceTypeMFBuffer, VideoFrameChromium::TypeMFBuffer);
-COMPILE_ASSERT_MATCHING_ENUM(WebVideoFrame::SurfaceTypeDirect3DSurface, VideoFrameChromium::TypeDirect3DSurface);
+COMPILE_ASSERT_MATCHING_ENUM(WebVideoFrame::SurfaceTypeTexture, VideoFrameChromium::TypeTexture);
 #endif
 
 #if ENABLE(NOTIFICATIONS)
index a60fe28..99e3e1e 100644 (file)
@@ -100,6 +100,13 @@ const void* VideoFrameChromiumImpl::data(unsigned plane) const
     return 0;
 }
 
+unsigned VideoFrameChromiumImpl::texture(unsigned plane) const
+{
+    if (m_webVideoFrame)
+        return m_webVideoFrame->texture(plane);
+    return 0;
+}
+
 const IntSize VideoFrameChromiumImpl::requiredTextureSize(unsigned plane) const
 {
     switch (format()) {
index 042cd7e..f86ee1c 100644 (file)
@@ -56,6 +56,7 @@ public:
     virtual unsigned planes() const;
     virtual int stride(unsigned plane) const;
     virtual const void* data(unsigned plane) const;
+    virtual unsigned texture(unsigned plane) const;
     virtual const IntSize requiredTextureSize(unsigned plane) const;
 
 private:
index 87ad963..e19308a 100644 (file)
@@ -95,6 +95,14 @@ WebMediaPlayer* WebMediaPlayerClientImpl::mediaPlayer() const
 
 // WebMediaPlayerClient --------------------------------------------------------
 
+WebMediaPlayerClientImpl::~WebMediaPlayerClientImpl()
+{
+    // VideoLayerChromium may outlive this object so make sure all frames are
+    // released.
+    if (m_videoLayer.get())
+        m_videoLayer->releaseCurrentFrame();
+}
+
 void WebMediaPlayerClientImpl::networkStateChanged()
 {
     ASSERT(m_mediaPlayer);
@@ -175,6 +183,11 @@ void WebMediaPlayerClientImpl::load(const String& url)
     Frame* frame = static_cast<HTMLMediaElement*>(
         m_mediaPlayer->mediaPlayerClient())->document()->frame();
 
+    // Video frame object is owned by WebMediaPlayer. Before destroying
+    // WebMediaPlayer all frames need to be released.
+    if (m_videoLayer.get())
+        m_videoLayer->releaseCurrentFrame();
+
     m_webMediaPlayer.set(createWebMediaPlayer(this, frame));
     if (m_webMediaPlayer.get())
         m_webMediaPlayer->load(KURL(ParsedURLString, url));
index e014871..6535094 100644 (file)
@@ -36,6 +36,7 @@
 #include "MediaPlayerPrivate.h"
 #include "VideoFrameChromium.h"
 #include "VideoFrameProvider.h"
+#include "VideoLayerChromium.h"
 #include "WebMediaPlayerClient.h"
 #include <wtf/OwnPtr.h>
 
@@ -61,6 +62,7 @@ public:
     WebMediaPlayer* mediaPlayer() const;
 
     // WebMediaPlayerClient methods:
+    virtual ~WebMediaPlayerClientImpl();
     virtual void networkStateChanged();
     virtual void readyStateChanged();
     virtual void volumeChanged(float);
@@ -129,7 +131,7 @@ private:
     WebCore::MediaPlayer* m_mediaPlayer;
     OwnPtr<WebMediaPlayer> m_webMediaPlayer;
 #if USE(ACCELERATED_COMPOSITING)
-    RefPtr<WebCore::PlatformLayer> m_videoLayer;
+    RefPtr<WebCore::VideoLayerChromium> m_videoLayer;
     bool m_supportsAcceleratedCompositing;
 #endif
     static bool m_isEnabled;