From 4718b7ef09ba5b4c044f2f45160a40d3fd179107 Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Thu, 24 Dec 2009 15:25:14 +0100 Subject: [PATCH] collectpads: add ability to install clipping functions 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 | 3 + libs/gst/base/gstcollectpads.c | 60 ++++++++++++++ libs/gst/base/gstcollectpads.h | 109 ++++++++++++++++---------- win32/common/libgstbase.def | 1 + 4 files changed, 133 insertions(+), 40 deletions(-) diff --git a/docs/libs/gstreamer-libs-sections.txt b/docs/libs/gstreamer-libs-sections.txt index 151ca73dec..57a6c53bda 100644 --- a/docs/libs/gstreamer-libs-sections.txt +++ b/docs/libs/gstreamer-libs-sections.txt @@ -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 GstCollectPadsClass +GstCollectPadsPrivate GST_COLLECT_PADS GST_IS_COLLECT_PADS GST_TYPE_COLLECT_PADS diff --git a/libs/gst/base/gstcollectpads.c b/libs/gst/base/gstcollectpads.c index d27cff7c59..d795612edd 100644 --- a/libs/gst/base/gstcollectpads.c +++ b/libs/gst/base/gstcollectpads.c @@ -77,6 +77,15 @@ 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. * @@ -343,6 +360,32 @@ find_pad (GstCollectData * data, GstPad * pad) return 1; } +/** + * 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 @@ -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 diff --git a/libs/gst/base/gstcollectpads.h b/libs/gst/base/gstcollectpads.h index 9fae480af9..f5ced28370 100644 --- a/libs/gst/base/gstcollectpads.h +++ b/libs/gst/base/gstcollectpads.h @@ -26,15 +26,16 @@ 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; /** @@ -49,6 +50,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 @@ -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 diff --git a/win32/common/libgstbase.def b/win32/common/libgstbase.def index 6064a62c6c..eef6d7598e 100644 --- a/win32/common/libgstbase.def +++ b/win32/common/libgstbase.def @@ -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