video: Add a destroy notify parameter to gst_video_convert_frame_async()
authorSebastian Dröge <sebastian.droege@collabora.co.uk>
Wed, 15 Sep 2010 09:26:48 +0000 (11:26 +0200)
committerSebastian Dröge <sebastian.droege@collabora.co.uk>
Wed, 15 Sep 2010 09:26:48 +0000 (11:26 +0200)
Binding generators apparently need this as they can't really know
that the callback is guaranteed to be called exactly once and that
the user_data can be freed at the end of it.

gst-libs/gst/video/convertframe.c
gst-libs/gst/video/video.h
tests/check/libs/video.c

index fe3b672..a969cc4 100644 (file)
@@ -369,6 +369,7 @@ typedef struct
   GstElement *pipeline;
   GstVideoConvertFrameCallback callback;
   gpointer user_data;
+  GDestroyNotify destroy_notify;
   GMainContext *context;
   GstBuffer *buffer;
   gulong timeout_id;
@@ -381,6 +382,7 @@ typedef struct
   GstBuffer *buffer;
   GError *error;
   gpointer user_data;
+  GDestroyNotify destroy_notify;
 
   GstVideoConvertFrameContext *context;
 } GstVideoConvertFrameCallbackContext;
@@ -418,6 +420,9 @@ convert_frame_dispatch_callback (GstVideoConvertFrameCallbackContext * ctx)
 {
   ctx->callback (ctx->buffer, ctx->error, ctx->user_data);
 
+  if (ctx->destroy_notify)
+    ctx->destroy_notify (ctx->user_data);
+
   return FALSE;
 }
 
@@ -435,6 +440,7 @@ convert_frame_finish (GstVideoConvertFrameContext * context, GstBuffer * buffer,
   ctx = g_slice_new (GstVideoConvertFrameCallbackContext);
   ctx->callback = context->callback;
   ctx->user_data = context->user_data;
+  ctx->destroy_notify = context->destroy_notify;
   ctx->buffer = buffer;
   ctx->error = error;
   ctx->context = context;
@@ -571,6 +577,7 @@ done:
  * @to_caps: the #GstCaps to convert to
  * @timeout: the maximum amount of time allowed for the processing.
  * @callback: %GstVideoConvertFrameCallback that will be called after conversion.
+ * @destroy_notify: %GDestroyNotify to be called after @user_data is not needed anymore
  *
  * Converts a raw video buffer into the specified output caps.
  *
@@ -583,13 +590,16 @@ done:
  * %GMainContext, see g_main_context_get_thread_default(). If GLib before 2.22 is used,
  * this will always be the global default main context.
  *
+ * @destroy_notify will be called after the callback was called and @user_data is not needed
+ * anymore.
+ *
  * Since: 0.10.31
  *
  */
 void
 gst_video_convert_frame_async (GstBuffer * buf, const GstCaps * to_caps,
     GstClockTime timeout, GstVideoConvertFrameCallback callback,
-    gpointer user_data)
+    gpointer user_data, GDestroyNotify destroy_notify)
 {
   GMainContext *context = NULL;
   GError *error = NULL;
@@ -603,6 +613,7 @@ gst_video_convert_frame_async (GstBuffer * buf, const GstCaps * to_caps,
   g_return_if_fail (buf != NULL);
   g_return_if_fail (to_caps != NULL);
   g_return_if_fail (GST_BUFFER_CAPS (buf) != NULL);
+  g_return_if_fail (callback != NULL);
 
 #if GLIB_CHECK_VERSION(2,22,0)
   context = g_main_context_get_thread_default ();
@@ -635,6 +646,7 @@ gst_video_convert_frame_async (GstBuffer * buf, const GstCaps * to_caps,
   ctx->buffer = gst_buffer_ref (buf);
   ctx->callback = callback;
   ctx->user_data = user_data;
+  ctx->destroy_notify = destroy_notify;
   ctx->context = g_main_context_ref (context);
   ctx->finished = FALSE;
   ctx->pipeline = pipeline;
@@ -675,6 +687,7 @@ no_pipeline:
     ctx = g_slice_new0 (GstVideoConvertFrameCallbackContext);
     ctx->callback = callback;
     ctx->user_data = user_data;
+    ctx->destroy_notify = destroy_notify;
     ctx->buffer = NULL;
     ctx->error = error;
 
index ba8ac98..d009a4c 100644 (file)
@@ -421,7 +421,7 @@ GstBuffer *gst_video_convert_frame(GstBuffer *buf, const GstCaps *to_caps,
 typedef void (*GstVideoConvertFrameCallback) (GstBuffer *buf, GError *error, gpointer user_data);
 void gst_video_convert_frame_async(GstBuffer *buf, const GstCaps *to_caps,
                                   GstClockTime timeout, GstVideoConvertFrameCallback callback,
-                                   gpointer user_data);
+                                   gpointer user_data, GDestroyNotify destroy_notify);
 
 G_END_DECLS
 
index 96cd7a3..796f33c 100644 (file)
@@ -680,7 +680,8 @@ GST_START_TEST (test_convert_frame_async)
   loop = cf_data.loop = g_main_loop_new (NULL, FALSE);
 
   gst_video_convert_frame_async (from_buffer, to_caps, GST_CLOCK_TIME_NONE,
-      (GstVideoConvertFrameCallback) convert_frame_async_callback, &cf_data);
+      (GstVideoConvertFrameCallback) convert_frame_async_callback, &cf_data,
+      NULL);
 
   g_main_loop_run (loop);
 
@@ -693,7 +694,8 @@ GST_START_TEST (test_convert_frame_async)
   to_caps =
       gst_video_format_new_caps (GST_VIDEO_FORMAT_I420, 240, 320, 25, 1, 1, 2);
   gst_video_convert_frame_async (from_buffer, to_caps, GST_CLOCK_TIME_NONE,
-      (GstVideoConvertFrameCallback) convert_frame_async_callback, &cf_data);
+      (GstVideoConvertFrameCallback) convert_frame_async_callback, &cf_data,
+      NULL);
   g_main_loop_run (loop);
   fail_unless (cf_data.buffer != NULL);
   fail_unless (gst_caps_can_intersect (to_caps,