[SCM] WebKit Debian packaging branch, webkit-1.1, updated. upstream/1.1.16-1409-g5afdf4d
eric at webkit.org
eric at webkit.org
Thu Dec 3 13:22:48 UTC 2009
The following commit has been merged in the webkit-1.1 branch:
commit 2f5c78fd34f275c841dad308fa145f6fa1a9c077
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