[SCM] WebKit Debian packaging branch, webkit-1.2, updated. upstream/1.1.90-6072-g9a69373

eric at webkit.org eric at webkit.org
Wed Apr 7 23:14:46 UTC 2010


The following commit has been merged in the webkit-1.2 branch:
commit 7b682334db46af2193d1504954e6b5fa0f370d1b
Author: eric at webkit.org <eric at webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Thu Oct 29 17:50:49 2009 +0000

    2009-10-29  Sebastian Dröge  <sebastian.droege at collabora.co.uk>
    
            Reviewed by Gustavo Noronha.
    
            https://bugs.webkit.org/show_bug.cgi?id=30308
    
            Add support for ARGB videos.
    
            * platform/graphics/gtk/MediaPlayerPrivateGStreamer.cpp:
            (WebCore::MediaPlayerPrivate::paint):
            Create the Cairo image surface for ARGB32 or RGB24
            depending on the buffer's caps.
    
            * platform/graphics/gtk/VideoSinkGStreamer.cpp:
            (webkit_video_sink_timeout_func):
            (webkit_video_sink_render):
            Handle ARGB video and convert GStreamer's ARGB to
            Cairo's for displaying.
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@50284 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index 019523e..df29ee7 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -1,3 +1,22 @@
+2009-10-29  Sebastian Dröge  <sebastian.droege at collabora.co.uk>
+
+        Reviewed by Gustavo Noronha.
+
+        https://bugs.webkit.org/show_bug.cgi?id=30308
+        
+        Add support for ARGB videos.
+
+        * platform/graphics/gtk/MediaPlayerPrivateGStreamer.cpp:
+        (WebCore::MediaPlayerPrivate::paint):
+        Create the Cairo image surface for ARGB32 or RGB24
+        depending on the buffer's caps.
+        
+        * platform/graphics/gtk/VideoSinkGStreamer.cpp:
+        (webkit_video_sink_timeout_func):
+        (webkit_video_sink_render):
+        Handle ARGB video and convert GStreamer's ARGB to
+        Cairo's for displaying.
+
 2009-10-29  Anton Muhin  <antonm at chromium.org>
 
         Reviewed by David Levin.
diff --git a/WebCore/platform/graphics/gtk/MediaPlayerPrivateGStreamer.cpp b/WebCore/platform/graphics/gtk/MediaPlayerPrivateGStreamer.cpp
index 8d1d261..f08bc78 100644
--- a/WebCore/platform/graphics/gtk/MediaPlayerPrivateGStreamer.cpp
+++ b/WebCore/platform/graphics/gtk/MediaPlayerPrivateGStreamer.cpp
@@ -631,11 +631,12 @@ void MediaPlayerPrivate::paint(GraphicsContext* context, const IntRect& rect)
     double displayWidth;
     double displayHeight;
     double scale, gapHeight, gapWidth;
+    GstVideoFormat format;
 
     GstCaps *caps = gst_buffer_get_caps(m_buffer);
 
-    if (!gst_video_format_parse_caps(caps, NULL, &width, &height) ||
-        !gst_video_parse_caps_pixel_aspect_ratio(caps, &pixelAspectRatioNumerator, &pixelAspectRatioDenominator)) {
+    if (G_UNLIKELY(!gst_video_format_parse_caps(caps, &format, &width, &height) ||
+        !gst_video_parse_caps_pixel_aspect_ratio(caps, &pixelAspectRatioNumerator, &pixelAspectRatioDenominator))) {
       gst_caps_unref(caps);
       return;
     }
@@ -645,9 +646,15 @@ void MediaPlayerPrivate::paint(GraphicsContext* context, const IntRect& rect)
     doublePixelAspectRatioNumerator = pixelAspectRatioNumerator;
     doublePixelAspectRatioDenominator = pixelAspectRatioDenominator;
 
+    cairo_format_t cairoFormat;
+    if (format == GST_VIDEO_FORMAT_ARGB || format == GST_VIDEO_FORMAT_BGRA)
+        cairoFormat = CAIRO_FORMAT_ARGB32;
+    else
+        cairoFormat = CAIRO_FORMAT_RGB24;
+
     cairo_t* cr = context->platformContext();
     cairo_surface_t* src = cairo_image_surface_create_for_data(GST_BUFFER_DATA(m_buffer),
-                                                               CAIRO_FORMAT_RGB24,
+                                                               cairoFormat,
                                                                width, height,
                                                                4 * width);
 
diff --git a/WebCore/platform/graphics/gtk/VideoSinkGStreamer.cpp b/WebCore/platform/graphics/gtk/VideoSinkGStreamer.cpp
index b5e1a8b..e6065e6 100644
--- a/WebCore/platform/graphics/gtk/VideoSinkGStreamer.cpp
+++ b/WebCore/platform/graphics/gtk/VideoSinkGStreamer.cpp
@@ -37,9 +37,9 @@ static GstStaticPadTemplate sinktemplate = GST_STATIC_PAD_TEMPLATE("sink",
                                                                    GST_PAD_SINK, GST_PAD_ALWAYS,
 // CAIRO_FORMAT_RGB24 used to render the video buffers is little/big endian dependant.
 #if G_BYTE_ORDER == G_LITTLE_ENDIAN
-                                                                   GST_STATIC_CAPS(GST_VIDEO_CAPS_BGRx)
+                                                                   GST_STATIC_CAPS(GST_VIDEO_CAPS_BGRx ";" GST_VIDEO_CAPS_BGRA)
 #else
-                                                                   GST_STATIC_CAPS(GST_VIDEO_CAPS_xRGB)
+                                                                   GST_STATIC_CAPS(GST_VIDEO_CAPS_xRGB ";" GST_VIDEO_CAPS_ARGB)
 #endif
 );
 
@@ -129,11 +129,6 @@ webkit_video_sink_timeout_func(gpointer data)
         return FALSE;
     }
 
-    if (G_UNLIKELY(!GST_BUFFER_CAPS(buffer))) {
-        buffer = gst_buffer_make_metadata_writable(buffer);
-        gst_buffer_set_caps(buffer, GST_PAD_CAPS(GST_BASE_SINK_PAD(sink)));
-    }
-
     g_signal_emit(sink, webkit_video_sink_signals[REPAINT_REQUESTED], 0, buffer);
     gst_buffer_unref(buffer);
     g_cond_signal(priv->data_cond);
@@ -157,6 +152,71 @@ webkit_video_sink_render(GstBaseSink* bsink, GstBuffer* buffer)
 
     priv->buffer = gst_buffer_ref(buffer);
 
+    // For the unlikely case where the buffer has no caps, the caps
+    // are implicitely the caps of the pad. This shouldn't happen.
+    if (G_UNLIKELY(!GST_BUFFER_CAPS(buffer))) {
+        buffer = priv->buffer = gst_buffer_make_metadata_writable(priv->buffer);
+        gst_buffer_set_caps(priv->buffer, GST_PAD_CAPS(GST_BASE_SINK_PAD(bsink)));
+    }
+
+    GstCaps *caps = GST_BUFFER_CAPS(buffer);
+    GstVideoFormat format;
+    int width, height;
+    if (G_UNLIKELY(!gst_video_format_parse_caps(caps, &format, &width, &height))) {
+        gst_buffer_unref(buffer);
+        g_mutex_unlock(priv->buffer_mutex);
+        return GST_FLOW_ERROR;
+    }
+
+    // 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) {
+        // Because GstBaseSink::render() only owns the buffer reference in the
+        // method scope we can't use gst_buffer_make_writable() here. Also
+        // The buffer content should not be changed here because the same buffer
+        // could be passed multiple times to this method (in theory)
+        GstBuffer *newBuffer = gst_buffer_try_new_and_alloc(GST_BUFFER_SIZE(buffer));
+
+        // Check if allocation failed
+        if (G_UNLIKELY(!newBuffer)) {
+            gst_buffer_unref(buffer);
+            g_mutex_unlock(priv->buffer_mutex);
+            return GST_FLOW_ERROR;
+        }
+
+        gst_buffer_copy_metadata(newBuffer, buffer, (GstBufferCopyFlags) GST_BUFFER_COPY_ALL);
+
+        // 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!
+        unsigned short alpha;
+        const guint8 *source = GST_BUFFER_DATA(buffer);
+        guint8 *destination = GST_BUFFER_DATA(newBuffer);
+
+        for (int x = 0; x < height; x++) {
+            for (int y = 0; y < width; y++) {
+#if G_BYTE_ORDER == G_LITTLE_ENDIAN
+                alpha = source[3];
+                destination[0] = (source[0] * alpha + 128) / 255;
+                destination[1] = (source[1] * alpha + 128) / 255;
+                destination[2] = (source[2] * alpha + 128) / 255;
+                destination[3] = alpha;
+#else
+                alpha = source[0];
+                destination[0] = alpha;
+                destination[1] = (source[1] * alpha + 128) / 255;
+                destination[2] = (source[2] * alpha + 128) / 255;
+                destination[3] = (source[3] * alpha + 128) / 255;
+#endif
+                source += 4;
+                destination += 4;
+            }
+        }
+        gst_buffer_unref(buffer);
+        buffer = priv->buffer = newBuffer;
+    }
+
     // Use HIGH_IDLE+20 priority, like Gtk+ for redrawing operations.
     priv->timeout_id = g_timeout_add_full(G_PRIORITY_HIGH_IDLE + 20, 0,
                                           webkit_video_sink_timeout_func,

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list