All pastes #1594203 Raw Edit

Anonymous

public text v1 · immutable
#1594203 ·published 2009-10-05 10:47 UTC
rendered paste body
From 61e4f1df20b69b1fbdfeeb8f52d34683c531a4bb Mon Sep 17 00:00:00 2001
From: Philippe Normand <pnormand@igalia.com>
Date: Fri, 2 Oct 2009 11:09:12 +0200
Subject: [PATCH] sink: replace the idle with a timeout

---
 .../platform/graphics/gtk/VideoSinkGStreamer.cpp   |   68 +++++++++++++------
 1 files changed, 46 insertions(+), 22 deletions(-)

diff --git a/WebCore/platform/graphics/gtk/VideoSinkGStreamer.cpp b/WebCore/platform/graphics/gtk/VideoSinkGStreamer.cpp
index bb269cd..c057a13 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,14 @@ struct _WebKitVideoSinkPrivate {
     int fps_d;
     int par_n;
     int par_d;
+    GAsyncQueue* timeout_ids_async_queue;
+};
+
+typedef struct _TimeoutData TimeoutData;
+
+struct _TimeoutData {
+    WebKitVideoSink* sink;
+    GstBuffer* buffer;
 };
 
 #define _do_init(bla) \
@@ -102,25 +109,31 @@ 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->timeout_ids_async_queue = g_async_queue_new();
+    g_object_set(sink, "render-delay", 100 * GST_MSECOND, NULL);
 }
 
 static gboolean
-webkit_video_sink_idle_func(gpointer data)
+webkit_video_sink_timeout_func(gpointer data)
 {
-    WebKitVideoSink* sink = reinterpret_cast<WebKitVideoSink*>(data);
+    TimeoutData* timeout_data = reinterpret_cast<TimeoutData*>(data);
+    WebKitVideoSink* sink = timeout_data->sink;
     WebKitVideoSinkPrivate* priv = sink->priv;
-    GstBuffer* buffer;
+    GstBuffer* buffer = timeout_data->buffer;
+    guint timeout_id;
     GstCaps* caps;
     GstVideoFormat* format;
     gint par_n, par_d;
     gfloat par;
     gint bwidth, bheight;
 
-    if (!priv->async_queue)
+    if (!priv->timeout_ids_async_queue)
         return FALSE;
 
-    buffer = (GstBuffer*)g_async_queue_try_pop(priv->async_queue);
+    timeout_id = (guint)g_async_queue_try_pop(priv->timeout_ids_async_queue);
+    g_source_remove(timeout_id);
+    g_async_queue_unref(priv->timeout_ids_async_queue);
+
     if (!buffer || G_UNLIKELY(!GST_IS_BUFFER(buffer)))
         return FALSE;
 
@@ -136,7 +149,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,23 +163,37 @@ 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);
 
     g_signal_emit(sink, webkit_video_sink_signals[REPAINT_REQUESTED], 0);
 
     return FALSE;
 }
 
+static void
+destroy_timeout_data(gpointer data)
+{
+    TimeoutData* timeout_data = reinterpret_cast<TimeoutData*>(data);
+    gst_buffer_unref(timeout_data->buffer);
+    g_slice_free(TimeoutData, timeout_data);
+}
+
 static GstFlowReturn
 webkit_video_sink_render(GstBaseSink* bsink, GstBuffer* buffer)
 {
     WebKitVideoSink* sink = WEBKIT_VIDEO_SINK(bsink);
     WebKitVideoSinkPrivate* priv = sink->priv;
+    TimeoutData* data = g_slice_new(TimeoutData);
+
+    data->sink = sink;
+    data->buffer = gst_buffer_ref(buffer);
+
+    // use HIGH_IDLE+20 priority, like Gtk+ for redrawing operations
+    guint timeout_id = g_timeout_add_full(G_PRIORITY_HIGH_IDLE + 20, 100,
+                                          webkit_video_sink_timeout_func,
+                                          data, destroy_timeout_data);
+    g_async_queue_ref(priv->timeout_ids_async_queue);
+    g_async_queue_push(priv->timeout_ids_async_queue, &timeout_id);
 
-    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);
 
     return GST_FLOW_OK;
 }
@@ -225,9 +251,9 @@ 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->timeout_ids_async_queue) {
+        g_async_queue_unref(priv->timeout_ids_async_queue);
+        priv->timeout_ids_async_queue = 0;
     }
 
     G_OBJECT_CLASS(parent_class)->dispose(object);
@@ -277,15 +303,13 @@ webkit_video_sink_stop(GstBaseSink* base_sink)
 {
     WebKitVideoSinkPrivate* priv = WEBKIT_VIDEO_SINK(base_sink)->priv;
 
-    g_async_queue_lock(priv->async_queue);
+    g_async_queue_lock(priv->timeout_ids_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);
+    while (guint timeout_id = (guint)g_async_queue_try_pop_unlocked(priv->timeout_ids_async_queue))
+        g_source_remove(timeout_id);
 
-    g_idle_remove_by_data(base_sink);
+    g_async_queue_unlock(priv->timeout_ids_async_queue);
 
     return TRUE;
 }
-- 
1.6.0.4