From d3edbe1718e3bef9d882510a81287c9454928957 Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Thu, 2 Jun 2005 09:42:02 +0000 Subject: [PATCH] gst/: Bufferalloc: return GstFlowReturn to more accuratly report why allocation failed. Original commit message from CVS: * gst/base/gstbasesink.c: (gst_basesink_pad_buffer_alloc), (gst_base_sink_buffer_alloc), (gst_basesink_preroll_queue_push), (gst_basesink_activate): * gst/base/gstbasesink.h: * gst/gstpad.c: (gst_pad_set_active), (gst_pad_link_prepare), (gst_pad_link), (gst_pad_accept_caps), (gst_pad_alloc_buffer), (gst_pad_query), (gst_pad_start_task): * gst/gstpad.h: * gst/gstqueue.c: (gst_queue_bufferalloc), (gst_queue_handle_sink_event), (gst_queue_chain): Bufferalloc: return GstFlowReturn to more accuratly report why allocation failed. --- ChangeLog | 15 +++++++++ gst/base/gstbasesink.c | 23 ++++++++------ gst/base/gstbasesink.h | 4 +-- gst/gstpad.c | 62 +++++++++++++++++++++++-------------- gst/gstpad.h | 19 ++++++------ gst/gstqueue.c | 23 +++++--------- libs/gst/base/gstbasesink.c | 23 ++++++++------ libs/gst/base/gstbasesink.h | 4 +-- plugins/elements/gstqueue.c | 23 +++++--------- 9 files changed, 107 insertions(+), 89 deletions(-) diff --git a/ChangeLog b/ChangeLog index 4627668146..52891f75aa 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,18 @@ +2005-06-02 Wim Taymans + + * gst/base/gstbasesink.c: (gst_basesink_pad_buffer_alloc), + (gst_base_sink_buffer_alloc), (gst_basesink_preroll_queue_push), + (gst_basesink_activate): + * gst/base/gstbasesink.h: + * gst/gstpad.c: (gst_pad_set_active), (gst_pad_link_prepare), + (gst_pad_link), (gst_pad_accept_caps), (gst_pad_alloc_buffer), + (gst_pad_query), (gst_pad_start_task): + * gst/gstpad.h: + * gst/gstqueue.c: (gst_queue_bufferalloc), + (gst_queue_handle_sink_event), (gst_queue_chain): + Bufferalloc: return GstFlowReturn to more accuratly report + why allocation failed. + 2005-06-02 Wim Taymans * gst/gstpipeline.c: (gst_pipeline_send_event): diff --git a/gst/base/gstbasesink.c b/gst/base/gstbasesink.c index b6dc5f2466..c06c9a3bb4 100644 --- a/gst/base/gstbasesink.c +++ b/gst/base/gstbasesink.c @@ -97,8 +97,8 @@ static void gst_basesink_get_property (GObject * object, guint prop_id, static GstCaps *gst_base_sink_get_caps (GstBaseSink * sink); static gboolean gst_base_sink_set_caps (GstBaseSink * sink, GstCaps * caps); -static GstBuffer *gst_base_sink_buffer_alloc (GstBaseSink * sink, - guint64 offset, guint size, GstCaps * caps); +static GstFlowReturn gst_base_sink_buffer_alloc (GstBaseSink * sink, + guint64 offset, guint size, GstCaps * caps, GstBuffer ** buf); static void gst_basesink_get_times (GstBaseSink * basesink, GstBuffer * buffer, GstClockTime * start, GstClockTime * end); @@ -202,21 +202,23 @@ gst_basesink_pad_setcaps (GstPad * pad, GstCaps * caps) return res; } -static GstBuffer * +static GstFlowReturn gst_basesink_pad_buffer_alloc (GstPad * pad, guint64 offset, guint size, - GstCaps * caps) + GstCaps * caps, GstBuffer ** buf) { GstBaseSinkClass *bclass; GstBaseSink *bsink; - GstBuffer *buffer = NULL; + GstFlowReturn result = GST_FLOW_OK; bsink = GST_BASESINK (GST_PAD_PARENT (pad)); bclass = GST_BASESINK_GET_CLASS (bsink); if (bclass->buffer_alloc) - buffer = bclass->buffer_alloc (bsink, offset, size, caps); + result = bclass->buffer_alloc (bsink, offset, size, caps, buf); + else + *buf = NULL; - return buffer; + return result; } static void @@ -363,11 +365,12 @@ gst_base_sink_set_caps (GstBaseSink * sink, GstCaps * caps) return TRUE; } -static GstBuffer * +static GstFlowReturn gst_base_sink_buffer_alloc (GstBaseSink * sink, guint64 offset, guint size, - GstCaps * caps) + GstCaps * caps, GstBuffer ** buf) { - return NULL; + *buf = NULL; + return GST_FLOW_OK; } /* with PREROLL_LOCK */ diff --git a/gst/base/gstbasesink.h b/gst/base/gstbasesink.h index a1ef93bc64..6af8ceebc8 100644 --- a/gst/base/gstbasesink.h +++ b/gst/base/gstbasesink.h @@ -77,8 +77,8 @@ struct _GstBaseSinkClass { gboolean (*set_caps) (GstBaseSink *sink, GstCaps *caps); /* allocate a new buffer with given caps */ - GstBuffer* (*buffer_alloc) (GstBaseSink *sink, guint64 offset, guint size, - GstCaps *caps); + GstFlowReturn (*buffer_alloc) (GstBaseSink *sink, guint64 offset, guint size, + GstCaps *caps, GstBuffer **buf); /* get the start and end times for syncing on this buffer */ void (*get_times) (GstBaseSink *sink, GstBuffer *buffer, diff --git a/gst/gstpad.c b/gst/gstpad.c index 2c34368135..8ff7d6d3ff 100644 --- a/gst/gstpad.c +++ b/gst/gstpad.c @@ -2216,6 +2216,7 @@ no_peer: * @offset: the offset of the new buffer in the stream * @size: the size of the new buffer * @caps: the caps of the new buffer + * @buf: a newly allocated buffer * * Allocates a new, empty buffer optimized to push to pad @pad. This * function only works if @pad is a source pad and a GST_REAL_PAD and @@ -2223,22 +2224,28 @@ no_peer: * You need to check the caps of the buffer after performing this * function and renegotiate to the format if needed. * - * Returns: a new, empty #GstBuffer, or NULL if wrong parameters - * were provided or the peer pad is not able to provide a buffer - * that can be handled by the caller. + * A new, empty #GstBuffer will be put in the @buf argument. + * + * Returns: a result code indicating success of the operation. Any + * result code other than GST_FLOW_OK is an error and @buf should + * not be used. + * An error can occur if the pad is not connected or when the downstream + * peer elements cannot provide an acceptable buffer. * * MT safe. */ -GstBuffer * -gst_pad_alloc_buffer (GstPad * pad, guint64 offset, gint size, GstCaps * caps) +GstFlowReturn +gst_pad_alloc_buffer (GstPad * pad, guint64 offset, gint size, GstCaps * caps, + GstBuffer ** buf) { GstRealPad *peer; - GstBuffer *result = NULL; + GstFlowReturn ret; GstPadBufferAllocFunction bufferallocfunc; gboolean caps_changed; - g_return_val_if_fail (GST_IS_REAL_PAD (pad), NULL); - g_return_val_if_fail (GST_PAD_IS_SRC (pad), NULL); + g_return_val_if_fail (GST_IS_REAL_PAD (pad), GST_FLOW_ERROR); + g_return_val_if_fail (GST_PAD_IS_SRC (pad), GST_FLOW_ERROR); + g_return_val_if_fail (buf != NULL, GST_FLOW_ERROR); GST_LOCK (pad); if (G_UNLIKELY ((peer = GST_RPAD_PEER (pad)) == NULL)) @@ -2247,9 +2254,8 @@ gst_pad_alloc_buffer (GstPad * pad, guint64 offset, gint size, GstCaps * caps) gst_object_ref (GST_OBJECT_CAST (peer)); GST_UNLOCK (pad); - if (G_LIKELY ((bufferallocfunc = peer->bufferallocfunc) == NULL)) { + if (G_LIKELY ((bufferallocfunc = peer->bufferallocfunc) == NULL)) goto fallback; - } GST_LOCK (peer); /* when the peer is flushing we cannot give a buffer */ @@ -2262,17 +2268,18 @@ gst_pad_alloc_buffer (GstPad * pad, guint64 offset, gint size, GstCaps * caps) &bufferallocfunc, GST_DEBUG_PAD_NAME (peer)); GST_UNLOCK (peer); - result = bufferallocfunc (GST_PAD_CAST (peer), offset, size, caps); + ret = bufferallocfunc (GST_PAD_CAST (peer), offset, size, caps, buf); - gst_object_unref (GST_OBJECT_CAST (peer)); - - if (G_UNLIKELY (result == NULL)) { + if (G_UNLIKELY (ret != GST_FLOW_OK)) + goto peer_error; + if (G_UNLIKELY (*buf == NULL)) goto fallback; - } do_caps: + gst_object_unref (GST_OBJECT_CAST (peer)); + /* FIXME, move capnego this into a base class? */ - caps = GST_BUFFER_CAPS (result); + caps = GST_BUFFER_CAPS (*buf); caps_changed = caps && caps != GST_RPAD_CAPS (pad); /* we got a new datatype on the pad, see if it can handle it */ if (G_UNLIKELY (caps_changed)) { @@ -2280,8 +2287,7 @@ do_caps: if (G_UNLIKELY (!gst_pad_configure_src (GST_PAD_CAST (pad), caps))) goto not_negotiated; } - - return result; + return ret; no_peer: { @@ -2290,24 +2296,27 @@ no_peer: "%s:%s called bufferallocfunc but had no peer, returning NULL", GST_DEBUG_PAD_NAME (pad)); GST_UNLOCK (pad); - return NULL; + return GST_FLOW_NOT_CONNECTED; } flushing: { /* peer was flushing */ GST_UNLOCK (peer); + gst_object_unref (GST_OBJECT_CAST (peer)); GST_CAT_DEBUG (GST_CAT_PADS, "%s:%s called bufferallocfunc but peer was flushing, returning NULL", GST_DEBUG_PAD_NAME (pad)); - return NULL; + return GST_FLOW_WRONG_STATE; } /* fallback case, allocate a buffer of our own, add pad caps. */ fallback: { GST_CAT_DEBUG (GST_CAT_PADS, "%s:%s fallback buffer alloc", GST_DEBUG_PAD_NAME (pad)); - result = gst_buffer_new_and_alloc (size); - gst_buffer_set_caps (result, caps); + *buf = gst_buffer_new_and_alloc (size); + gst_buffer_set_caps (*buf, caps); + + ret = GST_FLOW_OK; goto do_caps; } @@ -2315,7 +2324,14 @@ not_negotiated: { GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad, "alloc function retured unacceptable buffer"); - return NULL; + return GST_FLOW_NOT_NEGOTIATED; + } +peer_error: + { + gst_object_unref (GST_OBJECT_CAST (peer)); + GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad, + "alloc function retured error %d", ret); + return ret; } } diff --git a/gst/gstpad.h b/gst/gstpad.h index 915db75cdf..ba37118082 100644 --- a/gst/gstpad.h +++ b/gst/gstpad.h @@ -160,8 +160,8 @@ typedef GstCaps* (*GstPadGetCapsFunction) (GstPad *pad); typedef gboolean (*GstPadSetCapsFunction) (GstPad *pad, GstCaps *caps); typedef gboolean (*GstPadAcceptCapsFunction) (GstPad *pad, GstCaps *caps); typedef GstCaps* (*GstPadFixateCapsFunction) (GstPad *pad, GstCaps *caps); -typedef GstBuffer* (*GstPadBufferAllocFunction) (GstPad *pad, guint64 offset, guint size, - GstCaps *caps); +typedef GstFlowReturn (*GstPadBufferAllocFunction) (GstPad *pad, guint64 offset, guint size, + GstCaps *caps, GstBuffer **buf); /* misc */ typedef gboolean (*GstPadDispatcherFunction) (GstPad *pad, gpointer data); @@ -256,7 +256,7 @@ struct _GstRealPad { GstPadBufferAllocFunction bufferallocfunc; - GstProbeDispatcher probedisp; + GstProbeDispatcher probedisp; /*< private >*/ gpointer _gst_reserved[GST_PADDING]; @@ -471,8 +471,8 @@ gpointer gst_pad_get_element_private (GstPad *pad); GstPadTemplate* gst_pad_get_pad_template (GstPad *pad); void gst_pad_set_bufferalloc_function (GstPad *pad, GstPadBufferAllocFunction bufalloc); -GstBuffer* gst_pad_alloc_buffer (GstPad *pad, guint64 offset, gint size, - GstCaps *caps); +GstFlowReturn gst_pad_alloc_buffer (GstPad *pad, guint64 offset, gint size, + GstCaps *caps, GstBuffer **buf); /* data passing setup functions */ void gst_pad_set_activate_function (GstPad *pad, GstPadActivateFunction activate); @@ -553,12 +553,11 @@ gboolean gst_pad_query_default (GstPad *pad, GstQuery *query); /* misc helper functions */ gboolean gst_pad_dispatcher (GstPad *pad, GstPadDispatcherFunction dispatch, gpointer data); - /* probes */ -#define gst_pad_add_probe(pad, probe) \ - (gst_probe_dispatcher_add_probe (&(GST_PAD_REALIZE (pad)->probedisp), probe)) -#define gst_pad_remove_probe(pad, probe) \ - (gst_probe_dispatcher_remove_probe (&(GST_PAD_REALIZE (pad)->probedisp), probe)) +#define gst_pad_add_probe(pad, probe) \ + (gst_probe_dispatcher_add_probe (&(GST_PAD_REALIZE (pad)->probedisp), probe)) +#define gst_pad_remove_probe(pad, probe) \ + (gst_probe_dispatcher_remove_probe (&(GST_PAD_REALIZE (pad)->probedisp), probe)) #ifndef GST_DISABLE_LOADSAVE void gst_pad_load_and_link (xmlNodePtr self, GstObject *parent); diff --git a/gst/gstqueue.c b/gst/gstqueue.c index 299f3570f1..187e7c5f8c 100644 --- a/gst/gstqueue.c +++ b/gst/gstqueue.c @@ -126,8 +126,8 @@ static void gst_queue_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec); static GstFlowReturn gst_queue_chain (GstPad * pad, GstBuffer * buffer); -static GstBuffer *gst_queue_bufferalloc (GstPad * pad, guint64 offset, - guint size, GstCaps * caps); +static GstFlowReturn gst_queue_bufferalloc (GstPad * pad, guint64 offset, + guint size, GstCaps * caps, GstBuffer ** buf); static void gst_queue_loop (GstPad * pad); static gboolean gst_queue_handle_sink_event (GstPad * pad, GstEvent * event); @@ -411,25 +411,16 @@ gst_queue_link_src (GstPad * pad, GstPad * peer) return result; } -static GstBuffer * -gst_queue_bufferalloc (GstPad * pad, guint64 offset, guint size, GstCaps * caps) +static GstFlowReturn +gst_queue_bufferalloc (GstPad * pad, guint64 offset, guint size, GstCaps * caps, + GstBuffer ** buf) { GstQueue *queue; - GstPad *otherpeer; - GstBuffer *result = NULL; + GstFlowReturn result; queue = GST_QUEUE (GST_PAD_PARENT (pad)); - otherpeer = gst_pad_get_peer (queue->srcpad); - if (otherpeer == NULL || GST_RPAD_BUFFERALLOCFUNC (otherpeer) == NULL) { - /* let the default aloc function do the work */ - result = NULL; - } else { - result = - GST_RPAD_BUFFERALLOCFUNC (otherpeer) (otherpeer, offset, size, caps); - } - if (otherpeer) - gst_object_unref (GST_OBJECT (otherpeer)); + result = gst_pad_alloc_buffer (queue->srcpad, offset, size, caps, buf); return result; } diff --git a/libs/gst/base/gstbasesink.c b/libs/gst/base/gstbasesink.c index b6dc5f2466..c06c9a3bb4 100644 --- a/libs/gst/base/gstbasesink.c +++ b/libs/gst/base/gstbasesink.c @@ -97,8 +97,8 @@ static void gst_basesink_get_property (GObject * object, guint prop_id, static GstCaps *gst_base_sink_get_caps (GstBaseSink * sink); static gboolean gst_base_sink_set_caps (GstBaseSink * sink, GstCaps * caps); -static GstBuffer *gst_base_sink_buffer_alloc (GstBaseSink * sink, - guint64 offset, guint size, GstCaps * caps); +static GstFlowReturn gst_base_sink_buffer_alloc (GstBaseSink * sink, + guint64 offset, guint size, GstCaps * caps, GstBuffer ** buf); static void gst_basesink_get_times (GstBaseSink * basesink, GstBuffer * buffer, GstClockTime * start, GstClockTime * end); @@ -202,21 +202,23 @@ gst_basesink_pad_setcaps (GstPad * pad, GstCaps * caps) return res; } -static GstBuffer * +static GstFlowReturn gst_basesink_pad_buffer_alloc (GstPad * pad, guint64 offset, guint size, - GstCaps * caps) + GstCaps * caps, GstBuffer ** buf) { GstBaseSinkClass *bclass; GstBaseSink *bsink; - GstBuffer *buffer = NULL; + GstFlowReturn result = GST_FLOW_OK; bsink = GST_BASESINK (GST_PAD_PARENT (pad)); bclass = GST_BASESINK_GET_CLASS (bsink); if (bclass->buffer_alloc) - buffer = bclass->buffer_alloc (bsink, offset, size, caps); + result = bclass->buffer_alloc (bsink, offset, size, caps, buf); + else + *buf = NULL; - return buffer; + return result; } static void @@ -363,11 +365,12 @@ gst_base_sink_set_caps (GstBaseSink * sink, GstCaps * caps) return TRUE; } -static GstBuffer * +static GstFlowReturn gst_base_sink_buffer_alloc (GstBaseSink * sink, guint64 offset, guint size, - GstCaps * caps) + GstCaps * caps, GstBuffer ** buf) { - return NULL; + *buf = NULL; + return GST_FLOW_OK; } /* with PREROLL_LOCK */ diff --git a/libs/gst/base/gstbasesink.h b/libs/gst/base/gstbasesink.h index a1ef93bc64..6af8ceebc8 100644 --- a/libs/gst/base/gstbasesink.h +++ b/libs/gst/base/gstbasesink.h @@ -77,8 +77,8 @@ struct _GstBaseSinkClass { gboolean (*set_caps) (GstBaseSink *sink, GstCaps *caps); /* allocate a new buffer with given caps */ - GstBuffer* (*buffer_alloc) (GstBaseSink *sink, guint64 offset, guint size, - GstCaps *caps); + GstFlowReturn (*buffer_alloc) (GstBaseSink *sink, guint64 offset, guint size, + GstCaps *caps, GstBuffer **buf); /* get the start and end times for syncing on this buffer */ void (*get_times) (GstBaseSink *sink, GstBuffer *buffer, diff --git a/plugins/elements/gstqueue.c b/plugins/elements/gstqueue.c index 299f3570f1..187e7c5f8c 100644 --- a/plugins/elements/gstqueue.c +++ b/plugins/elements/gstqueue.c @@ -126,8 +126,8 @@ static void gst_queue_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec); static GstFlowReturn gst_queue_chain (GstPad * pad, GstBuffer * buffer); -static GstBuffer *gst_queue_bufferalloc (GstPad * pad, guint64 offset, - guint size, GstCaps * caps); +static GstFlowReturn gst_queue_bufferalloc (GstPad * pad, guint64 offset, + guint size, GstCaps * caps, GstBuffer ** buf); static void gst_queue_loop (GstPad * pad); static gboolean gst_queue_handle_sink_event (GstPad * pad, GstEvent * event); @@ -411,25 +411,16 @@ gst_queue_link_src (GstPad * pad, GstPad * peer) return result; } -static GstBuffer * -gst_queue_bufferalloc (GstPad * pad, guint64 offset, guint size, GstCaps * caps) +static GstFlowReturn +gst_queue_bufferalloc (GstPad * pad, guint64 offset, guint size, GstCaps * caps, + GstBuffer ** buf) { GstQueue *queue; - GstPad *otherpeer; - GstBuffer *result = NULL; + GstFlowReturn result; queue = GST_QUEUE (GST_PAD_PARENT (pad)); - otherpeer = gst_pad_get_peer (queue->srcpad); - if (otherpeer == NULL || GST_RPAD_BUFFERALLOCFUNC (otherpeer) == NULL) { - /* let the default aloc function do the work */ - result = NULL; - } else { - result = - GST_RPAD_BUFFERALLOCFUNC (otherpeer) (otherpeer, offset, size, caps); - } - if (otherpeer) - gst_object_unref (GST_OBJECT (otherpeer)); + result = gst_pad_alloc_buffer (queue->srcpad, offset, size, caps, buf); return result; }