From 61e4f1df20b69b1fbdfeeb8f52d34683c531a4bb Mon Sep 17 00:00:00 2001 From: Philippe Normand 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(data); + TimeoutData* timeout_data = reinterpret_cast(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(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