Title: [169198] releases/WebKitGTK/webkit-2.4/Source/WebCore
Revision
169198
Author
[email protected]
Date
2014-05-22 05:16:49 -0700 (Thu, 22 May 2014)

Log Message

Merge r168060 - [GStreamer] Use GstMetaVideo
https://bugs.webkit.org/show_bug.cgi?id=132247

Reviewed by Philippe Normand.

In WebKitVideoSink we announce the usage of GstMetaVideo, but we do
not use it when handling the video frames. This might break
some decoders and filters that rely on buffer's meta, rather
that in the caps structures.

This patch enables the use of GstMetaVideo through the GstVideoFrame
API. And it is used everywhere the buffer mapping is required.

Also this patch changes to nullptr where zeros were used.

Also, compile conditionally the video buffer conversion when it is
ARGB/BGRA, since it is only required for the Cairo backend.

No new tests, already covered by current tests.

* platform/graphics/gstreamer/GStreamerUtilities.cpp:
(WebCore::getVideoSizeAndFormatFromCaps): init the GstVideoInfo before
used and remove caps fixate check since it is done by
gst_video_info_from_caps().
* platform/graphics/gstreamer/ImageGStreamer.h:
* platform/graphics/gstreamer/ImageGStreamerCairo.cpp:
(ImageGStreamer::ImageGStreamer): use GstVideoFrame for buffer mapping
and unmapping.
(ImageGStreamer::~ImageGStreamer): ditto.
* platform/graphics/gstreamer/MediaPlayerPrivateGStreamerBase.cpp:
(WebCore::MediaPlayerPrivateGStreamerBase::updateTexture): ditto.
(WebCore::MediaPlayerPrivateGStreamerBase::currentVideoSinkCaps):
return nullptr if failed.
* platform/graphics/gstreamer/VideoSinkGStreamer.cpp:
(webkitVideoSinkRender): rely on GstVideoInfo rather than on the
caps. Use GstVideoFrame for buffer mapping and unmapping. Add guards
for buffer transformation, since it's only used by Cairo.
(webkitVideoSinkDispose): remove glib version guards.
(webkitVideoSinkSetCaps): update the value of the private
GstVideoInfo.

Modified Paths

Diff

Modified: releases/WebKitGTK/webkit-2.4/Source/WebCore/ChangeLog (169197 => 169198)


--- releases/WebKitGTK/webkit-2.4/Source/WebCore/ChangeLog	2014-05-22 12:01:32 UTC (rev 169197)
+++ releases/WebKitGTK/webkit-2.4/Source/WebCore/ChangeLog	2014-05-22 12:16:49 UTC (rev 169198)
@@ -1,3 +1,46 @@
+2014-04-30  Víctor Manuel Jáquez Leal  <[email protected]>
+
+        [GStreamer] Use GstMetaVideo
+        https://bugs.webkit.org/show_bug.cgi?id=132247
+
+        Reviewed by Philippe Normand.
+
+        In WebKitVideoSink we announce the usage of GstMetaVideo, but we do
+        not use it when handling the video frames. This might break
+        some decoders and filters that rely on buffer's meta, rather
+        that in the caps structures.
+
+        This patch enables the use of GstMetaVideo through the GstVideoFrame
+        API. And it is used everywhere the buffer mapping is required.
+
+        Also this patch changes to nullptr where zeros were used.
+
+        Also, compile conditionally the video buffer conversion when it is
+        ARGB/BGRA, since it is only required for the Cairo backend.
+
+        No new tests, already covered by current tests.
+
+        * platform/graphics/gstreamer/GStreamerUtilities.cpp:
+        (WebCore::getVideoSizeAndFormatFromCaps): init the GstVideoInfo before
+        used and remove caps fixate check since it is done by
+        gst_video_info_from_caps().
+        * platform/graphics/gstreamer/ImageGStreamer.h:
+        * platform/graphics/gstreamer/ImageGStreamerCairo.cpp:
+        (ImageGStreamer::ImageGStreamer): use GstVideoFrame for buffer mapping
+        and unmapping.
+        (ImageGStreamer::~ImageGStreamer): ditto.
+        * platform/graphics/gstreamer/MediaPlayerPrivateGStreamerBase.cpp:
+        (WebCore::MediaPlayerPrivateGStreamerBase::updateTexture): ditto.
+        (WebCore::MediaPlayerPrivateGStreamerBase::currentVideoSinkCaps):
+        return nullptr if failed.
+        * platform/graphics/gstreamer/VideoSinkGStreamer.cpp:
+        (webkitVideoSinkRender): rely on GstVideoInfo rather than on the
+        caps. Use GstVideoFrame for buffer mapping and unmapping. Add guards
+        for buffer transformation, since it's only used by Cairo.
+        (webkitVideoSinkDispose): remove glib version guards.
+        (webkitVideoSinkSetCaps): update the value of the private
+        GstVideoInfo.
+
 2014-05-06  Myles C. Maxfield  <[email protected]>
 
         Dragging text from one paragraph to another does not render as expected

Modified: releases/WebKitGTK/webkit-2.4/Source/WebCore/platform/graphics/gstreamer/GStreamerUtilities.cpp (169197 => 169198)


--- releases/WebKitGTK/webkit-2.4/Source/WebCore/platform/graphics/gstreamer/GStreamerUtilities.cpp	2014-05-22 12:01:32 UTC (rev 169197)
+++ releases/WebKitGTK/webkit-2.4/Source/WebCore/platform/graphics/gstreamer/GStreamerUtilities.cpp	2014-05-22 12:16:49 UTC (rev 169198)
@@ -52,7 +52,8 @@
 {
     GstVideoInfo info;
 
-    if (!gst_caps_is_fixed(caps) || !gst_video_info_from_caps(&info, caps))
+    gst_video_info_init(&info);
+    if (!gst_video_info_from_caps(&info, caps))
         return false;
 
     format = GST_VIDEO_INFO_FORMAT(&info);

Modified: releases/WebKitGTK/webkit-2.4/Source/WebCore/platform/graphics/gstreamer/ImageGStreamer.h (169197 => 169198)


--- releases/WebKitGTK/webkit-2.4/Source/WebCore/platform/graphics/gstreamer/ImageGStreamer.h	2014-05-22 12:01:32 UTC (rev 169197)
+++ releases/WebKitGTK/webkit-2.4/Source/WebCore/platform/graphics/gstreamer/ImageGStreamer.h	2014-05-22 12:16:49 UTC (rev 169198)
@@ -27,6 +27,7 @@
 #include "GRefPtrGStreamer.h"
 
 #include <gst/gst.h>
+#include <gst/video/video.h>
 
 #include <wtf/PassRefPtr.h>
 #include <wtf/RefCounted.h>
@@ -64,8 +65,7 @@
         FloatRect m_cropRect;
 
 #if USE(CAIRO)
-        GRefPtr<GstBuffer> m_buffer;
-        GstMapInfo m_mapInfo;
+        GstVideoFrame m_videoFrame;
 #endif
     };
 }

Modified: releases/WebKitGTK/webkit-2.4/Source/WebCore/platform/graphics/gstreamer/ImageGStreamerCairo.cpp (169197 => 169198)


--- releases/WebKitGTK/webkit-2.4/Source/WebCore/platform/graphics/gstreamer/ImageGStreamerCairo.cpp	2014-05-22 12:01:32 UTC (rev 169197)
+++ releases/WebKitGTK/webkit-2.4/Source/WebCore/platform/graphics/gstreamer/ImageGStreamerCairo.cpp	2014-05-22 12:16:49 UTC (rev 169198)
@@ -33,24 +33,32 @@
 using namespace WebCore;
 
 ImageGStreamer::ImageGStreamer(GstBuffer* buffer, GstCaps* caps)
-    : m_buffer(buffer)
 {
-    GstVideoFormat format;
-    IntSize size;
-    int pixelAspectRatioNumerator, pixelAspectRatioDenominator, stride;
-    getVideoSizeAndFormatFromCaps(caps, size, format, pixelAspectRatioNumerator, pixelAspectRatioDenominator, stride);
+    GstVideoInfo videoInfo;
+    gst_video_info_init(&videoInfo);
+    if (!gst_video_info_from_caps(&videoInfo, caps))
+        return;
 
-    gst_buffer_map(buffer, &m_mapInfo, GST_MAP_READ);
-    unsigned char* bufferData = reinterpret_cast<unsigned char*>(m_mapInfo.data);
+    // Right now the TextureMapper only supports chromas with one plane
+    ASSERT(GST_VIDEO_INFO_N_PLANES(&videoInfo) == 1);
 
+    if (!gst_video_frame_map(&m_videoFrame, &videoInfo, buffer, GST_MAP_READ))
+        return;
+
+    unsigned char* bufferData = reinterpret_cast<unsigned char*>(GST_VIDEO_FRAME_PLANE_DATA(&m_videoFrame, 0));
+
     cairo_format_t cairoFormat;
 #if G_BYTE_ORDER == G_LITTLE_ENDIAN
-    cairoFormat = (format == GST_VIDEO_FORMAT_BGRA) ? CAIRO_FORMAT_ARGB32 : CAIRO_FORMAT_RGB24;
+    cairoFormat = (GST_VIDEO_FRAME_FORMAT(&m_videoFrame) == GST_VIDEO_FORMAT_BGRA) ? CAIRO_FORMAT_ARGB32 : CAIRO_FORMAT_RGB24;
 #else
-    cairoFormat = (format == GST_VIDEO_FORMAT_ARGB) ? CAIRO_FORMAT_ARGB32 : CAIRO_FORMAT_RGB24;
+    cairoFormat = (GST_VIDEO_FRAME_FORMAT(&m_videoFrame) == GST_VIDEO_FORMAT_ARGB) ? CAIRO_FORMAT_ARGB32 : CAIRO_FORMAT_RGB24;
 #endif
 
-    RefPtr<cairo_surface_t> surface = adoptRef(cairo_image_surface_create_for_data(bufferData, cairoFormat, size.width(), size.height(), stride));
+    int stride = GST_VIDEO_FRAME_PLANE_STRIDE(&m_videoFrame, 0);
+    int width = GST_VIDEO_FRAME_WIDTH(&m_videoFrame);
+    int height = GST_VIDEO_FRAME_HEIGHT(&m_videoFrame);
+
+    RefPtr<cairo_surface_t> surface = adoptRef(cairo_image_surface_create_for_data(bufferData, cairoFormat, width, height, stride));
     ASSERT(cairo_surface_status(surface.get()) == CAIRO_STATUS_SUCCESS);
     m_image = BitmapImage::create(surface.release());
 
@@ -67,6 +75,6 @@
 
     // We keep the buffer memory mapped until the image is destroyed because the internal
     // cairo_surface_t was created using cairo_image_surface_create_for_data().
-    gst_buffer_unmap(m_buffer.get(), &m_mapInfo);
+    gst_video_frame_unmap(&m_videoFrame);
 }
 #endif // USE(GSTREAMER)

Modified: releases/WebKitGTK/webkit-2.4/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamerBase.cpp (169197 => 169198)


--- releases/WebKitGTK/webkit-2.4/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamerBase.cpp	2014-05-22 12:01:32 UTC (rev 169197)
+++ releases/WebKitGTK/webkit-2.4/Source/WebCore/platform/graphics/gstreamer/MediaPlayerPrivateGStreamerBase.cpp	2014-05-22 12:16:49 UTC (rev 169198)
@@ -42,6 +42,7 @@
 #include <wtf/text/CString.h>
 
 #include <gst/audio/streamvolume.h>
+#include <gst/video/gstvideometa.h>
 
 #if GST_CHECK_VERSION(1, 1, 0) && USE(ACCELERATED_COMPOSITING) && USE(TEXTURE_MAPPER_GL)
 #include "TextureMapperGL.h"
@@ -309,23 +310,20 @@
 {
     GMutexLocker lock(m_bufferMutex);
     if (!m_buffer)
-        return 0;
+        return nullptr;
 
-    const void* srcData = 0;
     GRefPtr<GstCaps> caps = currentVideoSinkCaps();
     if (!caps)
-        return 0;
+        return nullptr;
 
-    IntSize size;
-    GstVideoFormat format;
-    int pixelAspectRatioNumerator, pixelAspectRatioDenominator, stride;
-    if (!getVideoSizeAndFormatFromCaps(caps.get(), size, format, pixelAspectRatioNumerator, pixelAspectRatioDenominator, stride))
-        return 0;
+    GstVideoInfo videoInfo;
+    gst_video_info_init(&videoInfo);
+    if (!gst_video_info_from_caps(&videoInfo, caps.get()))
+        return nullptr;
 
-    const GstVideoFormatInfo* formatInfo = gst_video_format_get_info(format);
+    IntSize size = IntSize(GST_VIDEO_INFO_WIDTH(&videoInfo), GST_VIDEO_INFO_HEIGHT(&videoInfo));
+    RefPtr<BitmapTexture> texture = textureMapper->acquireTextureFromPool(size, GST_VIDEO_INFO_HAS_ALPHA(&videoInfo) ? BitmapTexture::SupportsAlpha : BitmapTexture::NoFlag);
 
-    RefPtr<BitmapTexture> texture = textureMapper->acquireTextureFromPool(size, GST_VIDEO_FORMAT_INFO_HAS_ALPHA(formatInfo) ? BitmapTexture::SupportsAlpha : BitmapTexture::NoFlag);
-
 #if GST_CHECK_VERSION(1, 1, 0)
     GstVideoGLTextureUploadMeta* meta;
     if ((meta = gst_buffer_get_video_gl_texture_upload_meta(m_buffer))) {
@@ -339,13 +337,18 @@
     }
 #endif
 
-    GstMapInfo srcInfo;
-    gst_buffer_map(m_buffer, &srcInfo, GST_MAP_READ);
-    srcData = srcInfo.data;
+    // Right now the TextureMapper only supports chromas with one plane
+    ASSERT(GST_VIDEO_INFO_N_PLANES(&videoInfo) == 1);
 
+    GstVideoFrame videoFrame;
+    if (!gst_video_frame_map(&videoFrame, &videoInfo, m_buffer, GST_MAP_READ))
+        return nullptr;
+
+    int stride = GST_VIDEO_FRAME_PLANE_STRIDE(&videoFrame, 0);
+    const void* srcData = GST_VIDEO_FRAME_PLANE_DATA(&videoFrame, 0);
     texture->updateContents(srcData, WebCore::IntRect(WebCore::IntPoint(0, 0), size), WebCore::IntPoint(0, 0), stride, BitmapTexture::UpdateCannotModifyOriginalImageData);
+    gst_video_frame_unmap(&videoFrame);
 
-    gst_buffer_unmap(m_buffer, &srcInfo);
     return texture;
 }
 #endif
@@ -442,7 +445,7 @@
 GRefPtr<GstCaps> MediaPlayerPrivateGStreamerBase::currentVideoSinkCaps() const
 {
     if (!m_webkitVideoSink)
-        return 0;
+        return nullptr;
 
     GRefPtr<GstCaps> currentCaps;
     g_object_get(G_OBJECT(m_webkitVideoSink.get()), "current-caps", &currentCaps.outPtr(), NULL);

Modified: releases/WebKitGTK/webkit-2.4/Source/WebCore/platform/graphics/gstreamer/VideoSinkGStreamer.cpp (169197 => 169198)


--- releases/WebKitGTK/webkit-2.4/Source/WebCore/platform/graphics/gstreamer/VideoSinkGStreamer.cpp	2014-05-22 12:01:32 UTC (rev 169197)
+++ releases/WebKitGTK/webkit-2.4/Source/WebCore/platform/graphics/gstreamer/VideoSinkGStreamer.cpp	2014-05-22 12:16:49 UTC (rev 169198)
@@ -147,21 +147,14 @@
 
     priv->buffer = gst_buffer_ref(buffer);
 
-    GRefPtr<GstCaps> caps;
     // The video info structure is valid only if the sink handled an allocation query.
-    if (GST_VIDEO_INFO_FORMAT(&priv->info) != GST_VIDEO_FORMAT_UNKNOWN)
-        caps = adoptGRef(gst_video_info_to_caps(&priv->info));
-    else
-        caps = priv->currentCaps;
-
-    GstVideoFormat format;
-    WebCore::IntSize size;
-    int pixelAspectRatioNumerator, pixelAspectRatioDenominator, stride;
-    if (!getVideoSizeAndFormatFromCaps(caps.get(), size, format, pixelAspectRatioNumerator, pixelAspectRatioDenominator, stride)) {
+    GstVideoFormat format = GST_VIDEO_INFO_FORMAT(&priv->info);
+    if (format == GST_VIDEO_FORMAT_UNKNOWN) {
         gst_buffer_unref(buffer);
         return GST_FLOW_ERROR;
     }
 
+#if !(USE(TEXTURE_MAPPER_GL) && !USE(COORDINATED_GRAPHICS))
     // Cairo's ARGB has pre-multiplied alpha while GStreamer's doesn't.
     // Here we convert to Cairo's ARGB.
     if (format == GST_VIDEO_FORMAT_ARGB || format == GST_VIDEO_FORMAT_BGRA) {
@@ -173,22 +166,35 @@
         GstBuffer* newBuffer = WebCore::createGstBuffer(buffer);
 
         // Check if allocation failed.
-        if (UNLIKELY(!newBuffer))
+        if (UNLIKELY(!newBuffer)) {
+            gst_buffer_unref(buffer);
             return GST_FLOW_ERROR;
+        }
 
         // We don't use Color::premultipliedARGBFromColor() here because
         // one function call per video pixel is just too expensive:
         // For 720p/PAL for example this means 1280*720*25=23040000
         // function calls per second!
-        GstMapInfo sourceInfo;
-        GstMapInfo destinationInfo;
-        gst_buffer_map(buffer, &sourceInfo, GST_MAP_READ);
-        const guint8* source = const_cast<guint8*>(sourceInfo.data);
-        gst_buffer_map(newBuffer, &destinationInfo, GST_MAP_WRITE);
-        guint8* destination = static_cast<guint8*>(destinationInfo.data);
+        GstVideoFrame sourceFrame;
+        GstVideoFrame destinationFrame;
 
-        for (int x = 0; x < size.height(); x++) {
-            for (int y = 0; y < size.width(); y++) {
+        if (!gst_video_frame_map(&sourceFrame, &priv->info, buffer, GST_MAP_READ)) {
+            gst_buffer_unref(buffer);
+            gst_buffer_unref(newBuffer);
+            return GST_FLOW_ERROR;
+        }
+        if (!gst_video_frame_map(&destinationFrame, &priv->info, newBuffer, GST_MAP_WRITE)) {
+            gst_video_frame_unmap(&sourceFrame);
+            gst_buffer_unref(buffer);
+            gst_buffer_unref(newBuffer);
+            return GST_FLOW_ERROR;
+        }
+
+        const guint8* source = static_cast<guint8*>(GST_VIDEO_FRAME_PLANE_DATA(&sourceFrame, 0));
+        guint8* destination = static_cast<guint8*>(GST_VIDEO_FRAME_PLANE_DATA(&destinationFrame, 0));
+
+        for (int x = 0; x < GST_VIDEO_FRAME_HEIGHT(&sourceFrame); x++) {
+            for (int y = 0; y < GST_VIDEO_FRAME_WIDTH(&sourceFrame); y++) {
 #if G_BYTE_ORDER == G_LITTLE_ENDIAN
                 unsigned short alpha = source[3];
                 destination[0] = (source[0] * alpha + 128) / 255;
@@ -207,11 +213,12 @@
             }
         }
 
-        gst_buffer_unmap(buffer, &sourceInfo);
-        gst_buffer_unmap(newBuffer, &destinationInfo);
+        gst_video_frame_unmap(&sourceFrame);
+        gst_video_frame_unmap(&destinationFrame);
         gst_buffer_unref(buffer);
         buffer = priv->buffer = newBuffer;
     }
+#endif
 
     // This should likely use a lower priority, but glib currently starves
     // lower priority sources.
@@ -335,12 +342,14 @@
 
     GST_DEBUG_OBJECT(sink, "Current caps %" GST_PTR_FORMAT ", setting caps %" GST_PTR_FORMAT, priv->currentCaps, caps);
 
-    GstVideoInfo info;
-    if (!gst_video_info_from_caps(&info, caps)) {
+    GstVideoInfo videoInfo;
+    gst_video_info_init(&videoInfo);
+    if (!gst_video_info_from_caps(&videoInfo, caps)) {
         GST_ERROR_OBJECT(sink, "Invalid caps %" GST_PTR_FORMAT, caps);
         return FALSE;
     }
 
+    priv->info = videoInfo;
     gst_caps_replace(&priv->currentCaps, caps);
     return TRUE;
 }
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to