[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:42:35 UTC 2009


The following commit has been merged in the webkit-1.1 branch:
commit ab21956ec608db58276443d373679f742d709063
Author: eric at webkit.org <eric at webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Fri Oct 9 19:37:40 2009 +0000

    2009-10-09  Philippe Normand  <pnormand at igalia.com>
    
            Reviewed by Gustavo Noronha.
    
            [GTK] QoS support in the video sink
            https://bugs.webkit.org/show_bug.cgi?id=29959
    
            Removed the async buffer queue from the sink. Synchronize the
            render method of the sink using a g_timeout_add() combined with a
            gcond triggered when the buffer has been rendered.
            Also fixed the video sink reference handling in the player, now
            that the idle is not there anymore to mess up things.
    
            * platform/graphics/gtk/MediaPlayerPrivateGStreamer.cpp:
            (WebCore::MediaPlayerPrivate::~MediaPlayerPrivate):
            (WebCore::MediaPlayerPrivate::createGSTPlayBin):
            * platform/graphics/gtk/VideoSinkGStreamer.cpp:
            (webkit_video_sink_init):
            (webkit_video_sink_timeout_func):
            (webkit_video_sink_render):
            (webkit_video_sink_dispose):
            (unlock_buffer_mutex):
            (webkit_video_sink_unlock):
            (webkit_video_sink_stop):
            (webkit_video_sink_class_init):
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@49401 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index 74db319..37ec86a 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -1,3 +1,29 @@
+2009-10-09  Philippe Normand  <pnormand at igalia.com>
+
+        Reviewed by Gustavo Noronha.
+
+        [GTK] QoS support in the video sink
+        https://bugs.webkit.org/show_bug.cgi?id=29959
+
+        Removed the async buffer queue from the sink. Synchronize the
+        render method of the sink using a g_timeout_add() combined with a
+        gcond triggered when the buffer has been rendered.
+        Also fixed the video sink reference handling in the player, now
+        that the idle is not there anymore to mess up things.
+
+        * platform/graphics/gtk/MediaPlayerPrivateGStreamer.cpp:
+        (WebCore::MediaPlayerPrivate::~MediaPlayerPrivate):
+        (WebCore::MediaPlayerPrivate::createGSTPlayBin):
+        * platform/graphics/gtk/VideoSinkGStreamer.cpp:
+        (webkit_video_sink_init):
+        (webkit_video_sink_timeout_func):
+        (webkit_video_sink_render):
+        (webkit_video_sink_dispose):
+        (unlock_buffer_mutex):
+        (webkit_video_sink_unlock):
+        (webkit_video_sink_stop):
+        (webkit_video_sink_class_init):
+
 2009-10-09  Dirk Schulze  <krit at webkit.org>
 
         Reviewed by Nikolas Zimmermann.
diff --git a/WebCore/platform/graphics/gtk/MediaPlayerPrivateGStreamer.cpp b/WebCore/platform/graphics/gtk/MediaPlayerPrivateGStreamer.cpp
index 65c64b4..ab54286 100644
--- a/WebCore/platform/graphics/gtk/MediaPlayerPrivateGStreamer.cpp
+++ b/WebCore/platform/graphics/gtk/MediaPlayerPrivateGStreamer.cpp
@@ -158,12 +158,6 @@ MediaPlayerPrivate::MediaPlayerPrivate(MediaPlayer* player)
     m_surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 640, 480);
 }
 
-static gboolean idleUnref(gpointer data)
-{
-    g_object_unref(reinterpret_cast<GObject*>(data));
-    return FALSE;
-}
-
 MediaPlayerPrivate::~MediaPlayerPrivate()
 {
     if (m_surface)
@@ -174,15 +168,8 @@ MediaPlayerPrivate::~MediaPlayerPrivate()
         gst_object_unref(GST_OBJECT(m_playBin));
     }
 
-    // FIXME: We should find a better way to handle the lifetime of this object; this is
-    // needed because the object is sometimes being destroyed inbetween a call to
-    // webkit_video_sink_render, and the idle it schedules. Adding a ref in
-    // webkit_video_sink_render that would be balanced by the idle is not an option,
-    // because in some cases the destruction of the sink may happen in time for the idle
-    // to be removed from the queue, so it may not run. It would also cause lots of ref
-    // counting churn (render/idle are called many times). This is an ugly race.
     if (m_videoSink) {
-        g_idle_add(idleUnref, m_videoSink);
+        g_object_unref(m_videoSink);
         m_videoSink = 0;
     }
 }
@@ -815,10 +802,7 @@ void MediaPlayerPrivate::createGSTPlayBin(String url)
 
     m_videoSink = webkit_video_sink_new(m_surface);
 
-    // This ref is to protect the sink from being destroyed before we stop the idle it
-    // creates internally. See the comment in ~MediaPlayerPrivate.
-    g_object_ref(m_videoSink);
-
+    g_object_ref_sink(m_videoSink);
     g_object_set(m_playBin, "video-sink", m_videoSink, NULL);
 
     g_signal_connect(m_videoSink, "repaint-requested", G_CALLBACK(mediaPlayerPrivateRepaintCallback), this);
diff --git a/WebCore/platform/graphics/gtk/VideoSinkGStreamer.cpp b/WebCore/platform/graphics/gtk/VideoSinkGStreamer.cpp
index fb86fe9..aba853a 100644
--- a/WebCore/platform/graphics/gtk/VideoSinkGStreamer.cpp
+++ b/WebCore/platform/graphics/gtk/VideoSinkGStreamer.cpp
@@ -65,7 +65,6 @@ static guint webkit_video_sink_signals[LAST_SIGNAL] = { 0, };
 
 struct _WebKitVideoSinkPrivate {
     cairo_surface_t* surface;
-    GAsyncQueue* async_queue;
     gboolean rgb_ordering;
     int width;
     int height;
@@ -73,6 +72,10 @@ struct _WebKitVideoSinkPrivate {
     int fps_d;
     int par_n;
     int par_d;
+    GstBuffer* buffer;
+    guint timeout_id;
+    GMutex* buffer_mutex;
+    GCond* data_cond;
 };
 
 #define _do_init(bla) \
@@ -83,8 +86,8 @@ struct _WebKitVideoSinkPrivate {
 
 GST_BOILERPLATE_FULL(WebKitVideoSink,
                      webkit_video_sink,
-                     GstBaseSink,
-                     GST_TYPE_BASE_SINK,
+                     GstVideoSink,
+                     GST_TYPE_VIDEO_SINK,
                      _do_init);
 
 static void
@@ -102,11 +105,12 @@ webkit_video_sink_init(WebKitVideoSink* sink, WebKitVideoSinkClass* klass)
     WebKitVideoSinkPrivate* priv;
 
     sink->priv = priv = G_TYPE_INSTANCE_GET_PRIVATE(sink, WEBKIT_TYPE_VIDEO_SINK, WebKitVideoSinkPrivate);
-    priv->async_queue = g_async_queue_new();
+    priv->data_cond = g_cond_new();
+    priv->buffer_mutex = g_mutex_new();
 }
 
 static gboolean
-webkit_video_sink_idle_func(gpointer data)
+webkit_video_sink_timeout_func(gpointer data)
 {
     WebKitVideoSink* sink = reinterpret_cast<WebKitVideoSink*>(data);
     WebKitVideoSinkPrivate* priv = sink->priv;
@@ -117,17 +121,22 @@ webkit_video_sink_idle_func(gpointer data)
     gfloat par;
     gint bwidth, bheight;
 
-    if (!priv->async_queue)
-        return FALSE;
+    g_mutex_lock(priv->buffer_mutex);
+    buffer = priv->buffer;
+    priv->timeout_id = 0;
 
-    buffer = (GstBuffer*)g_async_queue_try_pop(priv->async_queue);
-    if (!buffer || G_UNLIKELY(!GST_IS_BUFFER(buffer)))
+    if (!buffer || G_UNLIKELY(!GST_IS_BUFFER(buffer))) {
+        g_cond_signal(priv->data_cond);
+        g_mutex_unlock(priv->buffer_mutex);
         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;
     }
 
@@ -136,7 +145,6 @@ webkit_video_sink_idle_func(gpointer data)
 
     par = (gfloat) par_n / (gfloat) par_d;
 
-    // TODO: consider priv->rgb_ordering?
     cairo_surface_t* src = cairo_image_surface_create_for_data(GST_BUFFER_DATA(buffer),
                                                                CAIRO_FORMAT_RGB24,
                                                                bwidth, bheight,
@@ -151,10 +159,13 @@ webkit_video_sink_idle_func(gpointer data)
     cairo_rectangle(cr, 0, 0, priv->width, priv->height);
     cairo_fill(cr);
     cairo_destroy(cr);
+
     gst_buffer_unref(buffer);
-    g_async_queue_unref(priv->async_queue);
+    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);
 
     return FALSE;
 }
@@ -165,10 +176,17 @@ webkit_video_sink_render(GstBaseSink* bsink, GstBuffer* buffer)
     WebKitVideoSink* sink = WEBKIT_VIDEO_SINK(bsink);
     WebKitVideoSinkPrivate* priv = sink->priv;
 
-    g_async_queue_ref(priv->async_queue);
-    g_async_queue_push(priv->async_queue, gst_buffer_ref(buffer));
-    g_idle_add_full(G_PRIORITY_HIGH_IDLE, webkit_video_sink_idle_func, sink, 0);
+    g_mutex_lock(priv->buffer_mutex);
+    priv->buffer = gst_buffer_ref(buffer);
+
+    // 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,
+                                          gst_object_ref(sink),
+                                          (GDestroyNotify)gst_object_unref);
 
+    g_cond_wait(priv->data_cond, priv->buffer_mutex);
+    g_mutex_unlock(priv->buffer_mutex);
     return GST_FLOW_OK;
 }
 
@@ -225,18 +243,41 @@ webkit_video_sink_dispose(GObject* object)
         priv->surface = 0;
     }
 
-    if (priv->async_queue) {
-        g_async_queue_unref(priv->async_queue);
-        priv->async_queue = 0;
+    if (priv->data_cond) {
+        g_cond_free(priv->data_cond);
+        priv->data_cond = 0;
+    }
+
+    if (priv->buffer_mutex) {
+        g_mutex_free(priv->buffer_mutex);
+        priv->buffer_mutex = 0;
     }
 
     G_OBJECT_CLASS(parent_class)->dispose(object);
 }
 
 static void
-webkit_video_sink_finalize(GObject* object)
+unlock_buffer_mutex(WebKitVideoSinkPrivate* priv)
 {
-    G_OBJECT_CLASS(parent_class)->finalize(object);
+    g_mutex_lock(priv->buffer_mutex);
+
+    if (priv->buffer) {
+        gst_buffer_unref(priv->buffer);
+        priv->buffer = 0;
+    }
+
+    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
@@ -276,17 +317,7 @@ static gboolean
 webkit_video_sink_stop(GstBaseSink* base_sink)
 {
     WebKitVideoSinkPrivate* priv = WEBKIT_VIDEO_SINK(base_sink)->priv;
-
-    g_async_queue_lock(priv->async_queue);
-
-    /* Remove all remaining objects from the queue */
-    while (GstBuffer* buffer = (GstBuffer*)g_async_queue_try_pop_unlocked(priv->async_queue))
-        gst_buffer_unref(buffer);
-
-    g_async_queue_unlock(priv->async_queue);
-
-    g_idle_remove_by_data(base_sink);
-
+    unlock_buffer_mutex(priv);
     return TRUE;
 }
 
@@ -302,8 +333,8 @@ webkit_video_sink_class_init(WebKitVideoSinkClass* klass)
     gobject_class->get_property = webkit_video_sink_get_property;
 
     gobject_class->dispose = webkit_video_sink_dispose;
-    gobject_class->finalize = webkit_video_sink_finalize;
 
+    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;
diff --git a/WebCore/platform/graphics/gtk/VideoSinkGStreamer.h b/WebCore/platform/graphics/gtk/VideoSinkGStreamer.h
index be2c94c..e7a2f81 100644
--- a/WebCore/platform/graphics/gtk/VideoSinkGStreamer.h
+++ b/WebCore/platform/graphics/gtk/VideoSinkGStreamer.h
@@ -22,7 +22,7 @@
 
 #include <cairo.h>
 #include <glib-object.h>
-#include <gst/base/gstbasesink.h>
+#include <gst/video/gstvideosink.h>
 
 G_BEGIN_DECLS
 
@@ -54,13 +54,13 @@ typedef struct _WebKitVideoSinkPrivate WebKitVideoSinkPrivate;
 
 struct _WebKitVideoSink {
     /*< private >*/
-    GstBaseSink parent;
+    GstVideoSink parent;
     WebKitVideoSinkPrivate *priv;
 };
 
 struct _WebKitVideoSinkClass {
     /*< private >*/
-    GstBaseSinkClass parent_class;
+    GstVideoSinkClass parent_class;
 
     /* Future padding */
     void (* _webkit_reserved1)(void);

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list