[SCM] WebKit Debian packaging branch, webkit-1.1, updated. upstream/1.1.15.1-1414-gc69ee75
eric at webkit.org
eric at webkit.org
Thu Oct 29 20:43:15 UTC 2009
The following commit has been merged in the webkit-1.1 branch:
commit 64d9264da3c8321212904c13fd1ba0affd8b4dec
Author: eric at webkit.org <eric at webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date: Mon Oct 12 14:18:48 2009 +0000
2009-10-12 Sebastian Dröge <sebastian.droege at collabora.co.uk>
Reviewed by Gustavo Noronha.
https://bugs.webkit.org/show_bug.cgi?id=29997
Fixes double memcpy of all rendered video frames.
* platform/graphics/gtk/MediaPlayerPrivateGStreamer.cpp:
(WebCore::mediaPlayerPrivateRepaintCallback):
(WebCore::MediaPlayerPrivate::MediaPlayerPrivate):
(WebCore::MediaPlayerPrivate::~MediaPlayerPrivate):
(WebCore::MediaPlayerPrivate::duration):
* platform/graphics/gtk/MediaPlayerPrivateGStreamer.h:
* platform/graphics/gtk/VideoSinkGStreamer.cpp:
(webkit_video_sink_timeout_func):
(webkit_video_sink_dispose):
(unlock_buffer_mutex):
(webkit_video_sink_unlock):
(marshal_VOID__MINIOBJECT):
(webkit_video_sink_class_init):
(webkit_video_sink_new):
* platform/graphics/gtk/VideoSinkGStreamer.h:
Directly pass the buffers up to the MediaPlayerPrivate::paint()
method instead of rendering them first to an intermediate cairo
surface. This should increase performance and peak memory usage.
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@49438 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index 6e1404f..7300cf3 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -1,3 +1,30 @@
+2009-10-12 Sebastian Dröge <sebastian.droege at collabora.co.uk>
+
+ Reviewed by Gustavo Noronha.
+
+ https://bugs.webkit.org/show_bug.cgi?id=29997
+
+ Fixes double memcpy of all rendered video frames.
+
+ * platform/graphics/gtk/MediaPlayerPrivateGStreamer.cpp:
+ (WebCore::mediaPlayerPrivateRepaintCallback):
+ (WebCore::MediaPlayerPrivate::MediaPlayerPrivate):
+ (WebCore::MediaPlayerPrivate::~MediaPlayerPrivate):
+ (WebCore::MediaPlayerPrivate::duration):
+ * platform/graphics/gtk/MediaPlayerPrivateGStreamer.h:
+ * platform/graphics/gtk/VideoSinkGStreamer.cpp:
+ (webkit_video_sink_timeout_func):
+ (webkit_video_sink_dispose):
+ (unlock_buffer_mutex):
+ (webkit_video_sink_unlock):
+ (marshal_VOID__MINIOBJECT):
+ (webkit_video_sink_class_init):
+ (webkit_video_sink_new):
+ * platform/graphics/gtk/VideoSinkGStreamer.h:
+ Directly pass the buffers up to the MediaPlayerPrivate::paint()
+ method instead of rendering them first to an intermediate cairo
+ surface. This should increase performance and peak memory usage.
+
2009-10-11 Daniel Bates <dbates at webkit.org>
Reviewed by Adam Barth.
diff --git a/WebCore/platform/graphics/gtk/MediaPlayerPrivateGStreamer.cpp b/WebCore/platform/graphics/gtk/MediaPlayerPrivateGStreamer.cpp
index ab54286..de48226 100644
--- a/WebCore/platform/graphics/gtk/MediaPlayerPrivateGStreamer.cpp
+++ b/WebCore/platform/graphics/gtk/MediaPlayerPrivateGStreamer.cpp
@@ -39,7 +39,6 @@
#include "Widget.h"
#include "TimeRanges.h"
-#include <gst/base/gstbasesrc.h>
#include <gst/gst.h>
#include <gst/interfaces/mixer.h>
#include <gst/interfaces/xoverlay.h>
@@ -105,8 +104,10 @@ gboolean mediaPlayerPrivateBufferingCallback(GstBus* bus, GstMessage* message, g
return true;
}
-static void mediaPlayerPrivateRepaintCallback(WebKitVideoSink*, MediaPlayerPrivate* playerPrivate)
+void mediaPlayerPrivateRepaintCallback(WebKitVideoSink*, GstBuffer *buffer, MediaPlayerPrivate* playerPrivate)
{
+ g_return_if_fail(GST_IS_BUFFER(buffer));
+ gst_buffer_replace(&playerPrivate->m_buffer, buffer);
playerPrivate->repaint();
}
@@ -148,20 +149,19 @@ MediaPlayerPrivate::MediaPlayerPrivate(MediaPlayer* player)
, m_isStreaming(false)
, m_size(IntSize())
, m_visible(true)
+ , m_buffer(0)
, m_paused(true)
, m_seeking(false)
, m_errorOccured(false)
{
do_gst_init();
-
- // FIXME: The size shouldn't be fixed here, this is just a quick hack.
- m_surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 640, 480);
}
MediaPlayerPrivate::~MediaPlayerPrivate()
{
- if (m_surface)
- cairo_surface_destroy(m_surface);
+ if (m_buffer)
+ gst_buffer_unref(m_buffer);
+ m_buffer = 0;
if (m_playBin) {
gst_element_set_state(m_playBin, GST_STATE_NULL);
@@ -327,14 +327,16 @@ IntSize MediaPlayerPrivate::naturalSize() const
// https://bugzilla.gnome.org/show_bug.cgi?id=596326
int width = 0, height = 0;
if (GstPad* pad = gst_element_get_static_pad(m_videoSink, "sink")) {
- gst_video_get_size(GST_PAD(pad), &width, &height);
GstCaps* caps = GST_PAD_CAPS(pad);
gfloat pixelAspectRatio;
gint pixelAspectRatioNumerator, pixelAspectRatioDenominator;
- if (!gst_video_parse_caps_pixel_aspect_ratio(caps, &pixelAspectRatioNumerator,
- &pixelAspectRatioDenominator))
- pixelAspectRatioNumerator = pixelAspectRatioDenominator = 1;
+ if (!gst_video_format_parse_caps(caps, NULL, &width, &height) ||
+ !gst_video_parse_caps_pixel_aspect_ratio(caps, &pixelAspectRatioNumerator,
+ &pixelAspectRatioDenominator)) {
+ gst_object_unref(GST_OBJECT(pad));
+ return IntSize();
+ }
pixelAspectRatio = (gfloat) pixelAspectRatioNumerator / (gfloat) pixelAspectRatioDenominator;
width *= pixelAspectRatio;
@@ -626,18 +628,7 @@ void MediaPlayerPrivate::loadingFailed(MediaPlayer::NetworkState error)
void MediaPlayerPrivate::setSize(const IntSize& size)
{
- // Destroy and re-create the cairo surface only if the size
- // changed.
- if (size != m_size) {
- if (m_surface)
- cairo_surface_destroy(m_surface);
- m_surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, size.width(),
- size.height());
- g_object_set(m_videoSink, "surface", m_surface, 0);
- }
-
m_size = size;
-
}
void MediaPlayerPrivate::setVisible(bool visible)
@@ -657,8 +648,30 @@ void MediaPlayerPrivate::paint(GraphicsContext* context, const IntRect& rect)
if (!m_visible)
return;
+ if (!m_buffer)
+ return;
+
+ int width = 0, height = 0;
+ int pixelAspectRatioNumerator = 0;
+ int pixelAspectRatioDenominator = 0;
+ double doublePixelAspectRatioNumerator = 0;
+ double doublePixelAspectRatioDenominator = 0;
+ 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)) {
+ gst_caps_unref(caps);
+ return;
+ }
+
+ doublePixelAspectRatioNumerator = pixelAspectRatioNumerator;
+ doublePixelAspectRatioDenominator = pixelAspectRatioDenominator;
cairo_t* cr = context->platformContext();
+ cairo_surface_t* src = cairo_image_surface_create_for_data(GST_BUFFER_DATA(m_buffer),
+ CAIRO_FORMAT_RGB24,
+ width, height,
+ 4 * width);
cairo_save(cr);
cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
@@ -666,9 +679,14 @@ void MediaPlayerPrivate::paint(GraphicsContext* context, const IntRect& rect)
// paint the rectangle on the context and draw the surface inside.
cairo_translate(cr, rect.x(), rect.y());
cairo_rectangle(cr, 0, 0, rect.width(), rect.height());
- cairo_set_source_surface(cr, m_surface, 0, 0);
+ cairo_scale(cr, doublePixelAspectRatioNumerator / doublePixelAspectRatioDenominator,
+ doublePixelAspectRatioDenominator / doublePixelAspectRatioNumerator);
+ cairo_set_source_surface(cr, src, 0, 0);
cairo_fill(cr);
cairo_restore(cr);
+
+ cairo_surface_destroy(src);
+ gst_caps_unref(caps);
}
static HashSet<String> mimeTypeCache()
@@ -800,7 +818,7 @@ void MediaPlayerPrivate::createGSTPlayBin(String url)
g_object_set(G_OBJECT(m_playBin), "uri", url.utf8().data(), NULL);
- m_videoSink = webkit_video_sink_new(m_surface);
+ m_videoSink = webkit_video_sink_new();
g_object_ref_sink(m_videoSink);
g_object_set(m_playBin, "video-sink", m_videoSink, NULL);
diff --git a/WebCore/platform/graphics/gtk/MediaPlayerPrivateGStreamer.h b/WebCore/platform/graphics/gtk/MediaPlayerPrivateGStreamer.h
index d305759..11e59a6 100644
--- a/WebCore/platform/graphics/gtk/MediaPlayerPrivateGStreamer.h
+++ b/WebCore/platform/graphics/gtk/MediaPlayerPrivateGStreamer.h
@@ -30,8 +30,10 @@
#include <cairo.h>
#include <glib.h>
-typedef struct _GstElement GstElement;
+typedef struct _WebKitVideoSink WebKitVideoSink;
+typedef struct _GstBuffer GstBuffer;
typedef struct _GstMessage GstMessage;
+typedef struct _GstElement GstElement;
typedef struct _GstBus GstBus;
namespace WebCore {
@@ -49,6 +51,7 @@ namespace WebCore {
friend gboolean mediaPlayerPrivateErrorCallback(GstBus* bus, GstMessage* message, gpointer data);
friend gboolean mediaPlayerPrivateEOSCallback(GstBus* bus, GstMessage* message, gpointer data);
friend gboolean mediaPlayerPrivateStateCallback(GstBus* bus, GstMessage* message, gpointer data);
+ friend void mediaPlayerPrivateRepaintCallback(WebKitVideoSink*, GstBuffer *buffer, MediaPlayerPrivate* playerPrivate);
public:
static void registerMediaEngine(MediaEngineRegistrar);
@@ -136,7 +139,7 @@ namespace WebCore {
mutable bool m_isStreaming;
IntSize m_size;
bool m_visible;
- cairo_surface_t* m_surface;
+ GstBuffer* m_buffer;
bool m_paused;
bool m_seeking;
diff --git a/WebCore/platform/graphics/gtk/VideoSinkGStreamer.cpp b/WebCore/platform/graphics/gtk/VideoSinkGStreamer.cpp
index aba853a..59c56de 100644
--- a/WebCore/platform/graphics/gtk/VideoSinkGStreamer.cpp
+++ b/WebCore/platform/graphics/gtk/VideoSinkGStreamer.cpp
@@ -21,8 +21,9 @@
* SECTION:webkit-video-sink
* @short_description: GStreamer video sink
*
- * #WebKitVideoSink is a GStreamer sink element that sends
- * data to a #cairo_surface_t.
+ * #WebKitVideoSink is a GStreamer sink element that triggers
+ * repaints in the WebKit GStreamer media player for the
+ * current video buffer.
*/
#include "config.h"
@@ -57,21 +58,12 @@ enum {
};
enum {
- PROP_0,
- PROP_SURFACE
+ PROP_0
};
static guint webkit_video_sink_signals[LAST_SIGNAL] = { 0, };
struct _WebKitVideoSinkPrivate {
- cairo_surface_t* surface;
- gboolean rgb_ordering;
- int width;
- int height;
- int fps_n;
- int fps_d;
- int par_n;
- int par_d;
GstBuffer* buffer;
guint timeout_id;
GMutex* buffer_mutex;
@@ -115,14 +107,10 @@ webkit_video_sink_timeout_func(gpointer data)
WebKitVideoSink* sink = reinterpret_cast<WebKitVideoSink*>(data);
WebKitVideoSinkPrivate* priv = sink->priv;
GstBuffer* buffer;
- GstCaps* caps;
- GstVideoFormat format;
- gint par_n, par_d;
- gfloat par;
- gint bwidth, bheight;
g_mutex_lock(priv->buffer_mutex);
buffer = priv->buffer;
+ priv->buffer = 0;
priv->timeout_id = 0;
if (!buffer || G_UNLIKELY(!GST_IS_BUFFER(buffer))) {
@@ -131,39 +119,13 @@ webkit_video_sink_timeout_func(gpointer data)
return FALSE;
}
- caps = GST_BUFFER_CAPS(buffer);
- if (!gst_video_format_parse_caps(caps, &format, &bwidth, &bheight)) {
- GST_ERROR_OBJECT(sink, "Unknown video format in buffer caps '%s'",
- gst_caps_to_string(caps));
- g_cond_signal(priv->data_cond);
- g_mutex_unlock(priv->buffer_mutex);
- 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)));
}
- if (!gst_video_parse_caps_pixel_aspect_ratio(caps, &par_n, &par_d))
- par_n = par_d = 1;
-
- par = (gfloat) par_n / (gfloat) par_d;
-
- cairo_surface_t* src = cairo_image_surface_create_for_data(GST_BUFFER_DATA(buffer),
- CAIRO_FORMAT_RGB24,
- bwidth, bheight,
- 4 * bwidth);
-
- // TODO: We copy the data twice right now. This could be easily improved.
- cairo_t* cr = cairo_create(priv->surface);
- cairo_scale(cr, par, 1.0 / par);
- cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
- cairo_set_source_surface(cr, src, 0, 0);
- cairo_surface_destroy(src);
- cairo_rectangle(cr, 0, 0, priv->width, priv->height);
- cairo_fill(cr);
- cairo_destroy(cr);
-
+ g_signal_emit(sink, webkit_video_sink_signals[REPAINT_REQUESTED], 0, buffer);
gst_buffer_unref(buffer);
- priv->buffer = 0;
-
- g_signal_emit(sink, webkit_video_sink_signals[REPAINT_REQUESTED], 0);
g_cond_signal(priv->data_cond);
g_mutex_unlock(priv->buffer_mutex);
@@ -190,59 +152,12 @@ webkit_video_sink_render(GstBaseSink* bsink, GstBuffer* buffer)
return GST_FLOW_OK;
}
-static gboolean
-webkit_video_sink_set_caps(GstBaseSink* bsink, GstCaps* caps)
-{
- WebKitVideoSink* sink = WEBKIT_VIDEO_SINK(bsink);
- WebKitVideoSinkPrivate* priv = sink->priv;
- GstStructure* structure;
- gboolean ret;
- gint width, height, fps_n, fps_d;
- int red_mask;
-
- GstCaps* intersection = gst_caps_intersect(gst_static_pad_template_get_caps(&sinktemplate), caps);
-
- if (gst_caps_is_empty(intersection))
- return FALSE;
-
- gst_caps_unref(intersection);
-
- structure = gst_caps_get_structure(caps, 0);
-
- ret = gst_structure_get_int(structure, "width", &width);
- ret &= gst_structure_get_int(structure, "height", &height);
-
- /* We dont yet use fps but handy to have */
- ret &= gst_structure_get_fraction(structure, "framerate",
- &fps_n, &fps_d);
- g_return_val_if_fail(ret, FALSE);
-
- priv->width = width;
- priv->height = height;
- priv->fps_n = fps_n;
- priv->fps_d = fps_d;
-
- if (!gst_structure_get_fraction(structure, "pixel-aspect-ratio",
- &priv->par_n, &priv->par_d))
- priv->par_n = priv->par_d = 1;
-
- gst_structure_get_int(structure, "red_mask", &red_mask);
- priv->rgb_ordering = (red_mask == static_cast<int>(0xff000000));
-
- return TRUE;
-}
-
static void
webkit_video_sink_dispose(GObject* object)
{
WebKitVideoSink* sink = WEBKIT_VIDEO_SINK(object);
WebKitVideoSinkPrivate* priv = sink->priv;
- if (priv->surface) {
- cairo_surface_destroy(priv->surface);
- priv->surface = 0;
- }
-
if (priv->data_cond) {
g_cond_free(priv->data_cond);
priv->data_cond = 0;
@@ -268,49 +183,16 @@ unlock_buffer_mutex(WebKitVideoSinkPrivate* priv)
g_cond_signal(priv->data_cond);
g_mutex_unlock(priv->buffer_mutex);
-
}
static gboolean
webkit_video_sink_unlock(GstBaseSink* object)
{
WebKitVideoSink* sink = WEBKIT_VIDEO_SINK(object);
- unlock_buffer_mutex(sink->priv);
- GST_CALL_PARENT_WITH_DEFAULT(GST_BASE_SINK_CLASS, unlock,
- (object), TRUE);
-}
-static void
-webkit_video_sink_set_property(GObject* object, guint prop_id, const GValue* value, GParamSpec* pspec)
-{
- WebKitVideoSink* sink = WEBKIT_VIDEO_SINK(object);
- WebKitVideoSinkPrivate* priv = sink->priv;
-
- switch (prop_id) {
- case PROP_SURFACE:
- if (priv->surface)
- cairo_surface_destroy(priv->surface);
- priv->surface = cairo_surface_reference((cairo_surface_t*)g_value_get_pointer(value));
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
- break;
- }
-}
-
-static void
-webkit_video_sink_get_property(GObject* object, guint prop_id, GValue* value, GParamSpec* pspec)
-{
- WebKitVideoSink* sink = WEBKIT_VIDEO_SINK(object);
-
- switch (prop_id) {
- case PROP_SURFACE:
- g_value_set_pointer(value, sink->priv->surface);
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
- break;
- }
+ unlock_buffer_mutex(sink->priv);
+ return GST_CALL_PARENT_WITH_DEFAULT(GST_BASE_SINK_CLASS, unlock,
+ (object), TRUE);
}
static gboolean
@@ -322,6 +204,30 @@ webkit_video_sink_stop(GstBaseSink* base_sink)
}
static void
+marshal_VOID__MINIOBJECT(GClosure * closure, GValue * return_value,
+ guint n_param_values, const GValue * param_values,
+ gpointer invocation_hint, gpointer marshal_data)
+{
+ typedef void (*marshalfunc_VOID__MINIOBJECT) (gpointer obj, gpointer arg1, gpointer data2);
+ marshalfunc_VOID__MINIOBJECT callback;
+ GCClosure *cc = (GCClosure *) closure;
+ gpointer data1, data2;
+
+ g_return_if_fail(n_param_values == 2);
+
+ if (G_CCLOSURE_SWAP_DATA(closure)) {
+ data1 = closure->data;
+ data2 = g_value_peek_pointer(param_values + 0);
+ } else {
+ data1 = g_value_peek_pointer(param_values + 0);
+ data2 = closure->data;
+ }
+ callback = (marshalfunc_VOID__MINIOBJECT) (marshal_data ? marshal_data : cc->callback);
+
+ callback(data1, gst_value_get_mini_object(param_values + 1), data2);
+}
+
+static void
webkit_video_sink_class_init(WebKitVideoSinkClass* klass)
{
GObjectClass* gobject_class = G_OBJECT_CLASS(klass);
@@ -329,16 +235,12 @@ webkit_video_sink_class_init(WebKitVideoSinkClass* klass)
g_type_class_add_private(klass, sizeof(WebKitVideoSinkPrivate));
- gobject_class->set_property = webkit_video_sink_set_property;
- gobject_class->get_property = webkit_video_sink_get_property;
-
gobject_class->dispose = webkit_video_sink_dispose;
gstbase_sink_class->unlock = webkit_video_sink_unlock;
gstbase_sink_class->render = webkit_video_sink_render;
gstbase_sink_class->preroll = webkit_video_sink_render;
gstbase_sink_class->stop = webkit_video_sink_stop;
- gstbase_sink_class->set_caps = webkit_video_sink_set_caps;
webkit_video_sink_signals[REPAINT_REQUESTED] = g_signal_new("repaint-requested",
G_TYPE_FROM_CLASS(klass),
@@ -346,37 +248,20 @@ webkit_video_sink_class_init(WebKitVideoSinkClass* klass)
0,
0,
0,
- g_cclosure_marshal_VOID__VOID,
- G_TYPE_NONE, 0);
-
- g_object_class_install_property(
- gobject_class, PROP_SURFACE,
- g_param_spec_pointer("surface", "surface", "Target cairo_surface_t*",
- (GParamFlags)(G_PARAM_READWRITE)));
+ marshal_VOID__MINIOBJECT,
+ G_TYPE_NONE, 1, GST_TYPE_BUFFER);
}
/**
* webkit_video_sink_new:
- * @surface: a #cairo_surface_t
*
- * Creates a new GStreamer video sink which uses @surface as the target
- * for sinking a video stream from GStreamer.
+ * Creates a new GStreamer video sink.
*
* Return value: a #GstElement for the newly created video sink
*/
GstElement*
-webkit_video_sink_new(cairo_surface_t* surface)
+webkit_video_sink_new(void)
{
- return (GstElement*)g_object_new(WEBKIT_TYPE_VIDEO_SINK, "surface", surface, 0);
+ return (GstElement*)g_object_new(WEBKIT_TYPE_VIDEO_SINK, 0);
}
-void
-webkit_video_sink_set_surface(WebKitVideoSink* sink, cairo_surface_t* surface)
-{
- WebKitVideoSinkPrivate* priv;
-
- sink->priv = priv = G_TYPE_INSTANCE_GET_PRIVATE(sink, WEBKIT_TYPE_VIDEO_SINK, WebKitVideoSinkPrivate);
- if (priv->surface)
- cairo_surface_destroy(priv->surface);
- priv->surface = cairo_surface_reference(surface);
-}
diff --git a/WebCore/platform/graphics/gtk/VideoSinkGStreamer.h b/WebCore/platform/graphics/gtk/VideoSinkGStreamer.h
index e7a2f81..7ea7d91 100644
--- a/WebCore/platform/graphics/gtk/VideoSinkGStreamer.h
+++ b/WebCore/platform/graphics/gtk/VideoSinkGStreamer.h
@@ -72,9 +72,7 @@ struct _WebKitVideoSinkClass {
};
GType webkit_video_sink_get_type(void) G_GNUC_CONST;
-GstElement *webkit_video_sink_new(cairo_surface_t *surface);
-
-void webkit_video_sink_set_surface(WebKitVideoSink *sink, cairo_surface_t *surface);
+GstElement *webkit_video_sink_new(void);
G_END_DECLS
--
WebKit Debian packaging
More information about the Pkg-webkit-commits
mailing list