collectpads: add ability to install clipping functions
authorWim Taymans <wim.taymans@collabora.co.uk>
Thu, 24 Dec 2009 14:25:14 +0000 (15:25 +0100)
committerWim Taymans <wim@metal.(none)>
Thu, 24 Dec 2009 14:25:14 +0000 (15:25 +0100)
Add a method to install a clipping function that is called when a buffer is
received. Users of collectpads can then perform clipping on the incomming
buffers.

Also retab the header file a little.

See #590265

docs/libs/gstreamer-libs-sections.txt
libs/gst/base/gstcollectpads.c
libs/gst/base/gstcollectpads.h
win32/common/libgstbase.def

index 151ca73..57a6c53 100644 (file)
@@ -607,9 +607,11 @@ GST_BYTE_WRITER
 GstCollectData
 GstCollectPads
 GstCollectPadsFunction
+GstCollectPadsClipFunction
 GstCollectDataDestroyNotify
 gst_collect_pads_new
 gst_collect_pads_set_function
+gst_collect_pads_set_clip_function
 gst_collect_pads_add_pad
 gst_collect_pads_add_pad_full
 gst_collect_pads_remove_pad
@@ -628,6 +630,7 @@ gst_collect_pads_take_buffer
 gst_collect_pads_flush
 <SUBSECTION Standard>
 GstCollectPadsClass
+GstCollectPadsPrivate
 GST_COLLECT_PADS
 GST_IS_COLLECT_PADS
 GST_TYPE_COLLECT_PADS
index d27cff7..d795612 100644 (file)
 GST_DEBUG_CATEGORY_STATIC (collect_pads_debug);
 #define GST_CAT_DEFAULT collect_pads_debug
 
+#define GST_COLLECT_PADS_GET_PRIVATE(obj)  \
+  (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GST_TYPE_COLLECT_PADS, GstCollectPadsPrivate))
+
+struct _GstCollectPadsPrivate
+{
+  GstCollectPadsClipFunction clipfunc;
+  gpointer clipfunc_user_data;
+};
+
 GST_BOILERPLATE (GstCollectPads, gst_collect_pads, GstObject, GST_TYPE_OBJECT);
 
 static void gst_collect_pads_clear (GstCollectPads * pads,
@@ -101,6 +110,8 @@ gst_collect_pads_class_init (GstCollectPadsClass * klass)
 {
   GObjectClass *gobject_class = (GObjectClass *) klass;
 
+  g_type_class_add_private (klass, sizeof (GstCollectPadsPrivate));
+
   GST_DEBUG_CATEGORY_INIT (collect_pads_debug, "collectpads", 0,
       "GstCollectPads");
 
@@ -110,6 +121,8 @@ gst_collect_pads_class_init (GstCollectPadsClass * klass)
 static void
 gst_collect_pads_init (GstCollectPads * pads, GstCollectPadsClass * g_class)
 {
+  pads->abidata.ABI.priv = GST_COLLECT_PADS_GET_PRIVATE (pads);
+
   pads->cond = g_cond_new ();
   pads->data = NULL;
   pads->cookie = 0;
@@ -238,6 +251,10 @@ unref_data (GstCollectData * data)
  * gst_collect_pads_remove_pad() to remove the pad from the collection
  * again.
  *
+ * This function will override the chain and event functions of the pad
+ * along with the element_private data, which is used to store private
+ * information for the collectpads.
+ *
  * You specify a size for the returned #GstCollectData structure
  * so that you can use it to store additional information.
  *
@@ -344,6 +361,32 @@ find_pad (GstCollectData * data, GstPad * pad)
 }
 
 /**
+ * gst_collect_pads_set_clip_function:
+ * @pads: the collectspads to use
+ * @clipfunc: clip function to install
+ * @user_data: user data to pass to @clip_func
+ *
+ * Install a clipping function that is called right after a buffer is received
+ * on a pad managed by @pads. See #GstCollectDataClipFunction for more info.
+ *
+ * Since: 0.10.26
+ */
+void
+gst_collect_pads_set_clip_function (GstCollectPads * pads,
+    GstCollectPadsClipFunction clipfunc, gpointer user_data)
+{
+  GstCollectPadsPrivate *priv;
+
+  g_return_if_fail (pads != NULL);
+  g_return_if_fail (GST_IS_COLLECT_PADS (pads));
+
+  priv = pads->abidata.ABI.priv;
+
+  priv->clipfunc = clipfunc;
+  priv->clipfunc_user_data = user_data;
+}
+
+/**
  * gst_collect_pads_remove_pad:
  * @pads: the collectspads to use
  * @pad: the pad to remove
@@ -1257,6 +1300,7 @@ gst_collect_pads_chain (GstPad * pad, GstBuffer * buffer)
 {
   GstCollectData *data;
   GstCollectPads *pads;
+  GstCollectPadsPrivate *priv;
   GstFlowReturn ret;
   GstBuffer **buffer_p;
 
@@ -1271,6 +1315,7 @@ gst_collect_pads_chain (GstPad * pad, GstBuffer * buffer)
   GST_OBJECT_UNLOCK (pad);
 
   pads = data->collect;
+  priv = pads->abidata.ABI.priv;
 
   GST_OBJECT_LOCK (pads);
   /* if not started, bail out */
@@ -1283,6 +1328,14 @@ gst_collect_pads_chain (GstPad * pad, GstBuffer * buffer)
   if (G_UNLIKELY (data->abidata.ABI.eos))
     goto unexpected;
 
+  /* see if we need to clip */
+  if (priv->clipfunc) {
+    buffer = priv->clipfunc (pads, data, buffer, priv->clipfunc_user_data);
+
+    if (G_UNLIKELY (buffer == NULL))
+      goto clipped;
+  }
+
   GST_DEBUG ("Queuing buffer %p for pad %s:%s", buffer,
       GST_DEBUG_PAD_NAME (pad));
 
@@ -1387,6 +1440,13 @@ unexpected:
     ret = GST_FLOW_UNEXPECTED;
     goto unlock_done;
   }
+clipped:
+  {
+    GST_DEBUG ("clipped buffer on pad %s:%s", GST_DEBUG_PAD_NAME (pad));
+    GST_OBJECT_UNLOCK (pads);
+    unref_data (data);
+    return GST_FLOW_OK;
+  }
 error:
   {
     /* we print the error, the element should post a reasonable error
index 9fae480..f5ced28 100644 (file)
 
 G_BEGIN_DECLS
 
-#define GST_TYPE_COLLECT_PADS                   (gst_collect_pads_get_type())
-#define GST_COLLECT_PADS(obj)                   (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_COLLECT_PADS,GstCollectPads))
-#define GST_COLLECT_PADS_CLASS(klass)   (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_COLLECT_PADS,GstCollectPadsClass))
+#define GST_TYPE_COLLECT_PADS            (gst_collect_pads_get_type())
+#define GST_COLLECT_PADS(obj)            (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_COLLECT_PADS,GstCollectPads))
+#define GST_COLLECT_PADS_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_COLLECT_PADS,GstCollectPadsClass))
 #define GST_COLLECT_PADS_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj),GST_TYPE_COLLECT_PADS,GstCollectPadsClass))
-#define GST_IS_COLLECT_PADS(obj)        (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_COLLECT_PADS))
+#define GST_IS_COLLECT_PADS(obj)         (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_COLLECT_PADS))
 #define GST_IS_COLLECT_PADS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_COLLECT_PADS))
 
 typedef struct _GstCollectData GstCollectData;
 typedef struct _GstCollectPads GstCollectPads;
+typedef struct _GstCollectPadsPrivate GstCollectPadsPrivate;
 typedef struct _GstCollectPadsClass GstCollectPadsClass;
 
 /**
@@ -50,6 +51,29 @@ typedef struct _GstCollectPadsClass GstCollectPadsClass;
 typedef void (*GstCollectDataDestroyNotify) (GstCollectData *data);
 
 /**
+ * GstCollectPadsClipFunction:
+ * @pads: a #GstCollectPads 
+ * @data: a #GstCollectData 
+ * @buffer: a #GstBuffer 
+ * @user_data: user data 
+ *
+ * A function that will be called when @buffer is received on the pad managed
+ * by @data in the collecpad object @pads.
+ *
+ * The function should use the segment of @data and the negotiated media type on
+ * the pad to perform clipping of @buffer. 
+ *
+ * This function takes ownership of @buffer.
+ *
+ * Returns: a #GstBuffer that contains the clipped data of @buffer or NULL when
+ * the buffer has been clipped completely.
+ *
+ * Since: 0.10.26
+ */
+typedef GstBuffer * (*GstCollectPadsClipFunction) (GstCollectPads *pads, GstCollectData *data,
+                                                   GstBuffer *buffer, gpointer user_data);
+
+/**
  * GstCollectData:
  * @collect: owner #GstCollectPads
  * @pad: #GstPad managed by this data
@@ -62,10 +86,10 @@ typedef void (*GstCollectDataDestroyNotify) (GstCollectData *data);
 struct _GstCollectData
 {
   /* with LOCK of @collect */
-  GstCollectPads       *collect;
-  GstPad               *pad;
-  GstBuffer            *buffer;
-  guint                         pos;
+  GstCollectPads        *collect;
+  GstPad                *pad;
+  GstBuffer             *buffer;
+  guint                  pos;
   GstSegment             segment;
 
   /*< private >*/
@@ -111,31 +135,32 @@ struct _GstCollectPads {
   GstObject      object;
 
   /*< public >*/ /* with LOCK */
-  GSList       *data;                  /* list of CollectData items */
+  GSList        *data;                  /* list of CollectData items */
 
   /*< private >*/
-  guint32       cookie;                /* @data list cookie */
+  guint32        cookie;                /* @data list cookie */
 
   /* with LOCK */
-  GCond                *cond;                  /* to signal removal of data */
+  GCond         *cond;                  /* to signal removal of data */
 
-  GstCollectPadsFunction func;         /* function and user_data for callback */
-  gpointer      user_data;
+  GstCollectPadsFunction func;          /* function and user_data for callback */
+  gpointer       user_data;
 
-  guint                 numpads;               /* number of pads in @data */
-  guint                 queuedpads;            /* number of pads with a buffer */
-  guint                 eospads;               /* number of pads that are EOS */
+  guint          numpads;               /* number of pads in @data */
+  guint          queuedpads;            /* number of pads with a buffer */
+  guint          eospads;               /* number of pads that are EOS */
 
   /* with LOCK and PAD_LOCK*/
-  gboolean      started;
+  gboolean       started;
 
   /*< private >*/
   union {
     struct {
       /* since 0.10.6 */ /* with PAD_LOCK */
-      GMutex    *pad_lock;             /* used to serialize add/remove */
+      GMutex    *pad_lock;              /* used to serialize add/remove */
       GSList    *pad_list;              /* updated pad list */
-      guint32   pad_cookie;            /* updated cookie */
+      guint32    pad_cookie;            /* updated cookie */
+      GstCollectPadsPrivate  *priv;
     } ABI;
     /* adding + 0 to mark ABI change to be undone later */
     gpointer _gst_reserved[GST_PADDING + 0];
@@ -152,40 +177,44 @@ struct _GstCollectPadsClass {
 GType gst_collect_pads_get_type(void);
 
 /* creating the object */
-GstCollectPads*        gst_collect_pads_new            (void);
+GstCollectPads* gst_collect_pads_new            (void);
 
-/* set the callback */
-void           gst_collect_pads_set_function   (GstCollectPads *pads, GstCollectPadsFunction func,
-                                                gpointer user_data);
+/* set the callbacks */
+void            gst_collect_pads_set_function      (GstCollectPads *pads, GstCollectPadsFunction func,
+                                                    gpointer user_data);
+void            gst_collect_pads_set_clip_function (GstCollectPads *pads, GstCollectPadsClipFunction clipfunc,
+                                                    gpointer user_data);
 
 /* pad management */
-GstCollectData*        gst_collect_pads_add_pad        (GstCollectPads *pads, GstPad *pad, guint size);
+GstCollectData* gst_collect_pads_add_pad        (GstCollectPads *pads, GstPad *pad, guint size);
 GstCollectData* gst_collect_pads_add_pad_full   (GstCollectPads *pads, GstPad *pad, guint size, GstCollectDataDestroyNotify destroy_notify);
-gboolean       gst_collect_pads_remove_pad     (GstCollectPads *pads, GstPad *pad);
-gboolean       gst_collect_pads_is_active      (GstCollectPads *pads, GstPad *pad);
+
+
+gboolean        gst_collect_pads_remove_pad     (GstCollectPads *pads, GstPad *pad);
+gboolean        gst_collect_pads_is_active      (GstCollectPads *pads, GstPad *pad);
 
 /* start/stop collection */
-GstFlowReturn  gst_collect_pads_collect        (GstCollectPads *pads);
-GstFlowReturn  gst_collect_pads_collect_range  (GstCollectPads *pads, guint64 offset, guint length);
+GstFlowReturn   gst_collect_pads_collect        (GstCollectPads *pads);
+GstFlowReturn   gst_collect_pads_collect_range  (GstCollectPads *pads, guint64 offset, guint length);
 
-void           gst_collect_pads_start          (GstCollectPads *pads);
-void           gst_collect_pads_stop           (GstCollectPads *pads);
-void           gst_collect_pads_set_flushing   (GstCollectPads *pads, gboolean flushing);
+void            gst_collect_pads_start          (GstCollectPads *pads);
+void            gst_collect_pads_stop           (GstCollectPads *pads);
+void            gst_collect_pads_set_flushing   (GstCollectPads *pads, gboolean flushing);
 
 /* get collected buffers */
-GstBuffer*     gst_collect_pads_peek           (GstCollectPads *pads, GstCollectData *data);
-GstBuffer*     gst_collect_pads_pop            (GstCollectPads *pads, GstCollectData *data);
+GstBuffer*      gst_collect_pads_peek           (GstCollectPads *pads, GstCollectData *data);
+GstBuffer*      gst_collect_pads_pop            (GstCollectPads *pads, GstCollectData *data);
 
 /* get collected bytes */
-guint          gst_collect_pads_available      (GstCollectPads *pads);
-guint          gst_collect_pads_read           (GstCollectPads *pads, GstCollectData *data,
-                                                guint8 **bytes, guint size);
+guint           gst_collect_pads_available      (GstCollectPads *pads);
+guint           gst_collect_pads_read           (GstCollectPads *pads, GstCollectData *data,
+                                                 guint8 **bytes, guint size);
 GstBuffer *     gst_collect_pads_read_buffer    (GstCollectPads * pads, GstCollectData * data,
-                                                guint size);
+                                                 guint size);
 GstBuffer *     gst_collect_pads_take_buffer    (GstCollectPads * pads, GstCollectData * data,
-                                                guint size);
-guint          gst_collect_pads_flush          (GstCollectPads *pads, GstCollectData *data,
-                                                guint size);
+                                                 guint size);
+guint           gst_collect_pads_flush          (GstCollectPads *pads, GstCollectData *data,
+                                                 guint size);
 
 G_END_DECLS
 
index 6064a62..eef6d75 100644 (file)
@@ -197,6 +197,7 @@ EXPORTS
        gst_collect_pads_read
        gst_collect_pads_read_buffer
        gst_collect_pads_remove_pad
+       gst_collect_pads_set_clip_function
        gst_collect_pads_set_flushing
        gst_collect_pads_set_function
        gst_collect_pads_start