#define GST_BUFFER_OFFSET(buf) (GST_BUFFER(buf)->offset)
#define GST_BUFFER_MAXSIZE(buf) (GST_BUFFER(buf)->maxsize)
#define GST_BUFFER_TIMESTAMP(buf) (GST_BUFFER(buf)->timestamp)
+#define GST_BUFFER_BUFFERPOOL(buf) (GST_BUFFER(buf)->pool)
+#define GST_BUFFER_POOL_PRIVATE(buf) (GST_BUFFER(buf)->pool_private)
#define GST_BUFFER_LOCK(buf) (g_mutex_lock(GST_BUFFER(buf)->lock))
/* this is a pointer to the buffer pool (if any) */
GstBufferPool *pool;
+ gpointer pool_private;
};
/* initialisation */
*
* Decrease the refcount of this caps structure,
* destroying it when the refcount is 0
+ *
+ * Retruns: caps or NULL if the refcount reached 0
*/
-void
+GstCaps*
gst_caps_unref (GstCaps *caps)
{
gboolean zero;
- GstCaps *next;
+ GstCaps **next;
- g_return_if_fail (caps != NULL);
+ g_return_val_if_fail (caps != NULL, NULL);
+ g_return_val_if_fail (caps->refcount > 0, NULL);
GST_CAPS_LOCK (caps);
caps->refcount--;
zero = (caps->refcount == 0);
- next = caps->next;
+ next = &caps->next;
GST_CAPS_UNLOCK (caps);
- if (next)
- gst_caps_unref (next);
+ if (*next)
+ *next = gst_caps_unref (*next);
- if (zero)
+ if (zero) {
gst_caps_destroy (caps);
+ caps = NULL;
+ }
+ return caps;
}
/**
* @caps: the caps to ref
*
* Increase the refcount of this caps structure
+ *
+ * Returnns: the caps with the refcount incremented
*/
-void
+GstCaps*
gst_caps_ref (GstCaps *caps)
{
- g_return_if_fail (caps != NULL);
+ g_return_val_if_fail (caps != NULL, NULL);
GST_CAPS_LOCK (caps);
caps->refcount++;
GST_CAPS_UNLOCK (caps);
+
+ return caps;
}
/**
}
/**
+ * gst_caps_chain:
+ * @caps: a capabilty
+ * @...: more capabilities
+ *
+ * chains the given capabilities
+ *
+ * Returns: the new capability
+ */
+GstCaps*
+gst_caps_chain (GstCaps *caps, ...)
+{
+ GstCaps *orig = caps;
+ va_list var_args;
+
+ va_start (var_args, caps);
+
+ while (caps) {
+ GstCaps *toadd;
+
+ toadd = va_arg (var_args, GstCaps*);
+ gst_caps_append (caps, toadd);
+
+ caps = toadd;
+ }
+ va_end (var_args);
+
+ return orig;
+}
+
+/**
* gst_caps_append:
* @caps: a capabilty
* @capstoadd: the capability to append
GstCaps *next;
};
+#define GST_CAPS_NEW(name, type, a...) \
+gst_caps_new ( \
+ name, \
+ type, \
+ gst_props_new ( \
+ ##a, \
+ NULL))
+
+#define GST_CAPS_FACTORY(factoryname, a...) \
+static GstCaps* \
+factoryname (void) \
+{ \
+ static GstCaps *caps = NULL; \
+ if (!caps) { \
+ caps = gst_caps_chain (##a, NULL); \
+ } \
+ return caps; \
+}
+
+#define GST_CAPS_GET(fact) (fact)()
+
+
/* initialize the subsystem */
void _gst_caps_initialize (void);
GstCaps* gst_caps_new (const gchar *name, const gchar *mime, GstProps *props);
-void gst_caps_unref (GstCaps *caps);
-void gst_caps_ref (GstCaps *caps);
+GstCaps* gst_caps_unref (GstCaps *caps);
+GstCaps* gst_caps_ref (GstCaps *caps);
void gst_caps_destroy (GstCaps *caps);
GstCaps* gst_caps_copy (GstCaps *caps);
GstCaps* gst_caps_get_by_name (GstCaps *caps, const gchar *name);
+GstCaps* gst_caps_chain (GstCaps *caps, ...);
GstCaps* gst_caps_append (GstCaps *caps, GstCaps *capstoadd);
GstCaps* gst_caps_prepend (GstCaps *caps, GstCaps *capstoadd);
pad->pullfunc = NULL;
pad->pullregionfunc = NULL;
+ pad->bufferpoolfunc = NULL;
pad->ghostpads = NULL;
pad->caps = NULL;
}
GST_DEBUG_PAD_NAME(pad),pad,&GST_RPAD_NEWCAPSFUNC(pad),newcaps);
}
+/**
+ * gst_pad_set_bufferpool_function:
+ * @pad: the pad to set the bufferpool function for
+ * @newcaps: the bufferpool function
+ *
+ * Set the given bufferpool function for the pad.
+ */
+void
+gst_pad_set_bufferpool_function (GstPad *pad,
+ GstPadBufferPoolFunction bufpool)
+{
+ g_return_if_fail (pad != NULL);
+ g_return_if_fail (GST_IS_REAL_PAD (pad));
+ GST_RPAD_BUFFERPOOLFUNC (pad) = bufpool;
+ GST_DEBUG (0,"bufferpoolfunc for %s:%s(@%p) at %p is set to %p\n",
+ GST_DEBUG_PAD_NAME (pad), pad, &GST_RPAD_BUFFERPOOLFUNC (pad), bufpool);
+}
static void
gst_pad_push_func(GstPad *pad, GstBuffer *buf)
gst_pad_set_caps (GstPad *pad,
GstCaps *caps)
{
+ GstCaps *oldcaps;
+
g_return_val_if_fail (pad != NULL, FALSE);
g_return_val_if_fail (GST_IS_REAL_PAD (pad), FALSE); // NOTE this restriction
+ GST_INFO (GST_CAT_CAPS, "setting caps %p on pad %s:%s",
+ caps, GST_DEBUG_PAD_NAME(pad));
+
if (!gst_caps_check_compatibility (caps, gst_pad_get_padtemplate_caps (pad))) {
g_warning ("pad %s:%s tried to set caps incompatible with its padtemplate\n",
GST_DEBUG_PAD_NAME (pad));
//return FALSE;
}
- if (GST_PAD_CAPS (pad))
- gst_caps_unref (GST_PAD_CAPS (pad));
+ oldcaps = GST_PAD_CAPS (pad);
if (caps)
gst_caps_ref (caps);
GST_PAD_CAPS(pad) = caps;
+ if (oldcaps)
+ gst_caps_unref (oldcaps);
+
return gst_pad_renegotiate (pad);
}
return GST_PAD(GST_PAD_PEER(pad));
}
+GstBufferPool*
+gst_pad_get_bufferpool (GstPad *pad)
+{
+ GstRealPad *peer;
+
+ g_return_val_if_fail (pad != NULL, NULL);
+ g_return_val_if_fail (GST_IS_PAD (pad), NULL);
+
+ peer = GST_RPAD_PEER(pad);
+
+ g_return_val_if_fail (peer != NULL, NULL);
+
+ GST_DEBUG_ENTER("(%s:%s)",GST_DEBUG_PAD_NAME(pad));
+
+ if (peer->bufferpoolfunc) {
+ GST_DEBUG (0,"calling bufferpoolfunc &%s (@%p) of peer pad %s:%s\n",
+ GST_DEBUG_FUNCPTR_NAME(peer->bufferpoolfunc),&peer->bufferpoolfunc,GST_DEBUG_PAD_NAME(((GstPad*)peer)));
+ return (peer->bufferpoolfunc)(((GstPad*)peer));
+ } else {
+ GST_DEBUG (0,"no bufferpoolfunc for peer pad %s:%s at %p\n",GST_DEBUG_PAD_NAME(((GstPad*)peer)),&peer->bufferpoolfunc);
+ return NULL;
+ }
+}
+
+
// FIXME this needs to be rethought soon
static void
gst_real_pad_destroy (GtkObject *object)
GST_DEBUG (GST_CAT_NEGOTIATION, "pads aggreed on caps :)\n");
/* here we have some sort of aggreement of the caps */
- GST_PAD_CAPS (currentpad) = newcaps;
+ GST_PAD_CAPS (currentpad) = gst_caps_ref (newcaps);
if (GST_RPAD_NEWCAPSFUNC (currentpad))
GST_RPAD_NEWCAPSFUNC (currentpad) (GST_PAD (currentpad), newcaps);
- GST_PAD_CAPS (otherpad) = newcaps;
+ GST_PAD_CAPS (otherpad) = gst_caps_ref (newcaps);
if (GST_RPAD_NEWCAPSFUNC (otherpad))
GST_RPAD_NEWCAPSFUNC (otherpad) (GST_PAD (otherpad), newcaps);
}
typedef gboolean (*GstPadEOSFunction) (GstPad *pad);
typedef GstPadNegotiateReturn (*GstPadNegotiateFunction) (GstPad *pad, GstCaps **caps, gpointer *data);
typedef void (*GstPadNewCapsFunction) (GstPad *pad, GstCaps *caps);
+typedef GstBufferPool* (*GstPadBufferPoolFunction) (GstPad *pad);
typedef enum {
GST_PAD_UNKNOWN,
GstPadNegotiateFunction negotiatefunc;
GstPadNewCapsFunction newcapsfunc;
+ GstPadBufferPoolFunction bufferpoolfunc;
GList *ghostpads;
};
#define GST_RPAD_EOSFUNC(pad) (((GstRealPad *)(pad))->eosfunc)
#define GST_RPAD_NEGOTIATEFUNC(pad) (((GstRealPad *)(pad))->negotiatefunc)
#define GST_RPAD_NEWCAPSFUNC(pad) (((GstRealPad *)(pad))->newcapsfunc)
+#define GST_RPAD_BUFFERPOOLFUNC(pad) (((GstRealPad *)(pad))->bufferpoolfunc)
#define GST_RPAD_REGIONTYPE(pad) (((GstRealPad *)(pad))->regiontype)
#define GST_RPAD_OFFSET(pad) (((GstRealPad *)(pad))->offset)
void (*pad_created) (GstPadTemplate *templ, GstPad *pad);
};
+#define GST_PADTEMPLATE_NEW(padname, dir, pres, a...) \
+ gst_padtemplate_new ( \
+ padname, \
+ dir, \
+ pres, \
+ ##a, \
+ NULL)
+
+#define GST_PADTEMPLATE_FACTORY(name, padname, dir, pres, a...) \
+static GstPadTemplate* \
+name (void) \
+{ \
+ static GstPadTemplate *templ = NULL; \
+ if (!templ) { \
+ templ = GST_PADTEMPLATE_NEW ( \
+ padname, \
+ dir, \
+ pres, \
+ ##a); \
+ } \
+ return templ; \
+}
+
+#define GST_PADTEMPLATE_GET(fact) (fact)()
+
GtkType gst_pad_get_type (void);
GtkType gst_real_pad_get_type (void);
void gst_pad_set_eos_function (GstPad *pad, GstPadEOSFunction eos);
void gst_pad_set_negotiate_function (GstPad *pad, GstPadNegotiateFunction nego);
void gst_pad_set_newcaps_function (GstPad *pad, GstPadNewCapsFunction newcaps);
+void gst_pad_set_bufferpool_function (GstPad *pad, GstPadBufferPoolFunction bufpool);
gboolean gst_pad_set_caps (GstPad *pad, GstCaps *caps);
GstCaps* gst_pad_get_caps (GstPad *pad);
GstPad* gst_pad_get_peer (GstPad *pad);
+GstBufferPool* gst_pad_get_bufferpool (GstPad *pad);
+
gboolean gst_pad_connect (GstPad *srcpad, GstPad *sinkpad);
void gst_pad_disconnect (GstPad *srcpad, GstPad *sinkpad);
static GstPadNegotiateReturn gst_queue_handle_negotiate_sink (GstPad *pad, GstCaps **caps, gpointer *data);
static void gst_queue_chain (GstPad *pad, GstBuffer *buf);
static GstBuffer * gst_queue_get (GstPad *pad);
-
+static GstBufferPool* gst_queue_get_bufferpool (GstPad *pad);
+
static void gst_queue_flush (GstQueue *queue);
static GstElementStateReturn gst_queue_change_state (GstElement *element);
gst_element_add_pad (GST_ELEMENT (queue), queue->sinkpad);
gst_pad_set_eos_function (queue->sinkpad, gst_queue_handle_eos);
gst_pad_set_negotiate_function (queue->sinkpad, gst_queue_handle_negotiate_sink);
+ gst_pad_set_bufferpool_function (queue->sinkpad, gst_queue_get_bufferpool);
queue->srcpad = gst_pad_new ("src", GST_PAD_SRC);
gst_pad_set_get_function (queue->srcpad, GST_DEBUG_FUNCPTR(gst_queue_get));
queue->fullcond = g_cond_new ();
}
+static GstBufferPool*
+gst_queue_get_bufferpool (GstPad *pad)
+{
+ GstQueue *queue;
+
+ queue = GST_QUEUE (GST_OBJECT_PARENT (pad));
+
+ return gst_pad_get_bufferpool (queue->srcpad);
+}
+
static GstPadNegotiateReturn
gst_queue_handle_negotiate_src (GstPad *pad, GstCaps **caps, gpointer *data)
{
static GstPadNegotiateReturn gst_queue_handle_negotiate_sink (GstPad *pad, GstCaps **caps, gpointer *data);
static void gst_queue_chain (GstPad *pad, GstBuffer *buf);
static GstBuffer * gst_queue_get (GstPad *pad);
-
+static GstBufferPool* gst_queue_get_bufferpool (GstPad *pad);
+
static void gst_queue_flush (GstQueue *queue);
static GstElementStateReturn gst_queue_change_state (GstElement *element);
gst_element_add_pad (GST_ELEMENT (queue), queue->sinkpad);
gst_pad_set_eos_function (queue->sinkpad, gst_queue_handle_eos);
gst_pad_set_negotiate_function (queue->sinkpad, gst_queue_handle_negotiate_sink);
+ gst_pad_set_bufferpool_function (queue->sinkpad, gst_queue_get_bufferpool);
queue->srcpad = gst_pad_new ("src", GST_PAD_SRC);
gst_pad_set_get_function (queue->srcpad, GST_DEBUG_FUNCPTR(gst_queue_get));
queue->fullcond = g_cond_new ();
}
+static GstBufferPool*
+gst_queue_get_bufferpool (GstPad *pad)
+{
+ GstQueue *queue;
+
+ queue = GST_QUEUE (GST_OBJECT_PARENT (pad));
+
+ return gst_pad_get_bufferpool (queue->srcpad);
+}
+
static GstPadNegotiateReturn
gst_queue_handle_negotiate_src (GstPad *pad, GstCaps **caps, gpointer *data)
{