static GstFlowReturn clutter_gst_video_sink_render (GstBaseSink *bsink, GstBuffer *buffer) { ClutterGstVideoSink *sink; ClutterGstVideoSinkPrivate *priv; sink = CLUTTER_GST_VIDEO_SINK (bsink); priv = sink->priv; g_mutex_lock (priv->buffer_lock); if (priv->buffer) { gst_buffer_unref (priv->buffer); } priv->buffer = gst_buffer_ref (buffer); if (priv->idle_id == 0) { priv->idle_id = clutter_threads_add_idle_full (G_PRIORITY_HIGH_IDLE, clutter_gst_video_sink_idle_func, sink, NULL); /* the lock must be held when adding this idle, if it is not the idle * callback would be invoked before priv->idle_id had been assigned */ } g_mutex_unlock (priv->buffer_lock); return GST_FLOW_OK; }
static void do_something_very_slow (void) { TestThreadData *data; gint i; data = (TestThreadData *) g_static_private_get (&test_thread_data); if (data->cancelled) return; for (i = 0; i < 100; i++) { gint msecs; msecs = 1 + (int) (100.0 * rand () / ((RAND_MAX + 1.0) / 3)); /* sleep for a while */ g_usleep (msecs * 1000); if ((i % 10) == 0) { TestUpdate *update; update = g_new (TestUpdate, 1); update->count = i; update->thread_data = data; clutter_threads_add_idle_full (G_PRIORITY_DEFAULT + 30, update_label_idle, update, NULL); } } }
static gpointer test_thread_func (gpointer user_data) { TestThreadData *data; data = user_data; g_static_private_set (&test_thread_data, data, NULL); do_something_very_slow (); clutter_threads_add_idle_full (G_PRIORITY_DEFAULT + 30, test_thread_done_idle, data, NULL); return NULL; }
/* fakesink handoff callback */ void on_gst_buffer (GstElement * element, GstBuffer * buf, GstPad * pad, ClutterActor * texture_actor) { GAsyncQueue *queue_input_buf = NULL; GAsyncQueue *queue_output_buf = NULL; /* ref then push buffer to use it in clutter */ gst_buffer_ref (buf); queue_input_buf = g_object_get_data (G_OBJECT (texture_actor), "queue_input_buf"); g_async_queue_push (queue_input_buf, buf); if (g_async_queue_length (queue_input_buf) > 2) clutter_threads_add_idle_full (G_PRIORITY_HIGH, update_texture_actor, texture_actor, NULL); /* pop then unref buffer we have finished to use in clutter */ queue_output_buf = g_object_get_data (G_OBJECT (texture_actor), "queue_output_buf"); if (g_async_queue_length (queue_output_buf) > 2) { GstBuffer *buf_old = g_async_queue_pop (queue_output_buf); gst_buffer_unref (buf_old); } }