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.
This commit is contained in:
Wim Taymans 2005-06-02 09:42:02 +00:00
parent 5c026ec0db
commit d3edbe1718
9 changed files with 107 additions and 89 deletions

View file

@ -1,3 +1,18 @@
2005-06-02 Wim Taymans <wim@fluendo.com>
* 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 <wim@fluendo.com> 2005-06-02 Wim Taymans <wim@fluendo.com>
* gst/gstpipeline.c: (gst_pipeline_send_event): * gst/gstpipeline.c: (gst_pipeline_send_event):

View file

@ -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 GstCaps *gst_base_sink_get_caps (GstBaseSink * sink);
static gboolean gst_base_sink_set_caps (GstBaseSink * sink, GstCaps * caps); static gboolean gst_base_sink_set_caps (GstBaseSink * sink, GstCaps * caps);
static GstBuffer *gst_base_sink_buffer_alloc (GstBaseSink * sink, static GstFlowReturn gst_base_sink_buffer_alloc (GstBaseSink * sink,
guint64 offset, guint size, GstCaps * caps); guint64 offset, guint size, GstCaps * caps, GstBuffer ** buf);
static void gst_basesink_get_times (GstBaseSink * basesink, GstBuffer * buffer, static void gst_basesink_get_times (GstBaseSink * basesink, GstBuffer * buffer,
GstClockTime * start, GstClockTime * end); GstClockTime * start, GstClockTime * end);
@ -202,21 +202,23 @@ gst_basesink_pad_setcaps (GstPad * pad, GstCaps * caps)
return res; return res;
} }
static GstBuffer * static GstFlowReturn
gst_basesink_pad_buffer_alloc (GstPad * pad, guint64 offset, guint size, gst_basesink_pad_buffer_alloc (GstPad * pad, guint64 offset, guint size,
GstCaps * caps) GstCaps * caps, GstBuffer ** buf)
{ {
GstBaseSinkClass *bclass; GstBaseSinkClass *bclass;
GstBaseSink *bsink; GstBaseSink *bsink;
GstBuffer *buffer = NULL; GstFlowReturn result = GST_FLOW_OK;
bsink = GST_BASESINK (GST_PAD_PARENT (pad)); bsink = GST_BASESINK (GST_PAD_PARENT (pad));
bclass = GST_BASESINK_GET_CLASS (bsink); bclass = GST_BASESINK_GET_CLASS (bsink);
if (bclass->buffer_alloc) 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 static void
@ -363,11 +365,12 @@ gst_base_sink_set_caps (GstBaseSink * sink, GstCaps * caps)
return TRUE; return TRUE;
} }
static GstBuffer * static GstFlowReturn
gst_base_sink_buffer_alloc (GstBaseSink * sink, guint64 offset, guint size, 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 */ /* with PREROLL_LOCK */

View file

@ -77,8 +77,8 @@ struct _GstBaseSinkClass {
gboolean (*set_caps) (GstBaseSink *sink, GstCaps *caps); gboolean (*set_caps) (GstBaseSink *sink, GstCaps *caps);
/* allocate a new buffer with given caps */ /* allocate a new buffer with given caps */
GstBuffer* (*buffer_alloc) (GstBaseSink *sink, guint64 offset, guint size, GstFlowReturn (*buffer_alloc) (GstBaseSink *sink, guint64 offset, guint size,
GstCaps *caps); GstCaps *caps, GstBuffer **buf);
/* get the start and end times for syncing on this buffer */ /* get the start and end times for syncing on this buffer */
void (*get_times) (GstBaseSink *sink, GstBuffer *buffer, void (*get_times) (GstBaseSink *sink, GstBuffer *buffer,

View file

@ -2216,6 +2216,7 @@ no_peer:
* @offset: the offset of the new buffer in the stream * @offset: the offset of the new buffer in the stream
* @size: the size of the new buffer * @size: the size of the new buffer
* @caps: the caps 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 * 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 * 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 * You need to check the caps of the buffer after performing this
* function and renegotiate to the format if needed. * function and renegotiate to the format if needed.
* *
* Returns: a new, empty #GstBuffer, or NULL if wrong parameters * A new, empty #GstBuffer will be put in the @buf argument.
* were provided or the peer pad is not able to provide a buffer *
* that can be handled by the caller. * 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. * MT safe.
*/ */
GstBuffer * GstFlowReturn
gst_pad_alloc_buffer (GstPad * pad, guint64 offset, gint size, GstCaps * caps) gst_pad_alloc_buffer (GstPad * pad, guint64 offset, gint size, GstCaps * caps,
GstBuffer ** buf)
{ {
GstRealPad *peer; GstRealPad *peer;
GstBuffer *result = NULL; GstFlowReturn ret;
GstPadBufferAllocFunction bufferallocfunc; GstPadBufferAllocFunction bufferallocfunc;
gboolean caps_changed; gboolean caps_changed;
g_return_val_if_fail (GST_IS_REAL_PAD (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), NULL); 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); GST_LOCK (pad);
if (G_UNLIKELY ((peer = GST_RPAD_PEER (pad)) == NULL)) 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_object_ref (GST_OBJECT_CAST (peer));
GST_UNLOCK (pad); GST_UNLOCK (pad);
if (G_LIKELY ((bufferallocfunc = peer->bufferallocfunc) == NULL)) { if (G_LIKELY ((bufferallocfunc = peer->bufferallocfunc) == NULL))
goto fallback; goto fallback;
}
GST_LOCK (peer); GST_LOCK (peer);
/* when the peer is flushing we cannot give a buffer */ /* 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)); &bufferallocfunc, GST_DEBUG_PAD_NAME (peer));
GST_UNLOCK (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 (ret != GST_FLOW_OK))
goto peer_error;
if (G_UNLIKELY (result == NULL)) { if (G_UNLIKELY (*buf == NULL))
goto fallback; goto fallback;
}
do_caps: do_caps:
gst_object_unref (GST_OBJECT_CAST (peer));
/* FIXME, move capnego this into a base class? */ /* 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); caps_changed = caps && caps != GST_RPAD_CAPS (pad);
/* we got a new datatype on the pad, see if it can handle it */ /* we got a new datatype on the pad, see if it can handle it */
if (G_UNLIKELY (caps_changed)) { if (G_UNLIKELY (caps_changed)) {
@ -2280,8 +2287,7 @@ do_caps:
if (G_UNLIKELY (!gst_pad_configure_src (GST_PAD_CAST (pad), caps))) if (G_UNLIKELY (!gst_pad_configure_src (GST_PAD_CAST (pad), caps)))
goto not_negotiated; goto not_negotiated;
} }
return ret;
return result;
no_peer: no_peer:
{ {
@ -2290,24 +2296,27 @@ no_peer:
"%s:%s called bufferallocfunc but had no peer, returning NULL", "%s:%s called bufferallocfunc but had no peer, returning NULL",
GST_DEBUG_PAD_NAME (pad)); GST_DEBUG_PAD_NAME (pad));
GST_UNLOCK (pad); GST_UNLOCK (pad);
return NULL; return GST_FLOW_NOT_CONNECTED;
} }
flushing: flushing:
{ {
/* peer was flushing */ /* peer was flushing */
GST_UNLOCK (peer); GST_UNLOCK (peer);
gst_object_unref (GST_OBJECT_CAST (peer));
GST_CAT_DEBUG (GST_CAT_PADS, GST_CAT_DEBUG (GST_CAT_PADS,
"%s:%s called bufferallocfunc but peer was flushing, returning NULL", "%s:%s called bufferallocfunc but peer was flushing, returning NULL",
GST_DEBUG_PAD_NAME (pad)); GST_DEBUG_PAD_NAME (pad));
return NULL; return GST_FLOW_WRONG_STATE;
} }
/* fallback case, allocate a buffer of our own, add pad caps. */ /* fallback case, allocate a buffer of our own, add pad caps. */
fallback: fallback:
{ {
GST_CAT_DEBUG (GST_CAT_PADS, GST_CAT_DEBUG (GST_CAT_PADS,
"%s:%s fallback buffer alloc", GST_DEBUG_PAD_NAME (pad)); "%s:%s fallback buffer alloc", GST_DEBUG_PAD_NAME (pad));
result = gst_buffer_new_and_alloc (size); *buf = gst_buffer_new_and_alloc (size);
gst_buffer_set_caps (result, caps); gst_buffer_set_caps (*buf, caps);
ret = GST_FLOW_OK;
goto do_caps; goto do_caps;
} }
@ -2315,7 +2324,14 @@ not_negotiated:
{ {
GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad, GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad,
"alloc function retured unacceptable buffer"); "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;
} }
} }

View file

@ -160,8 +160,8 @@ typedef GstCaps* (*GstPadGetCapsFunction) (GstPad *pad);
typedef gboolean (*GstPadSetCapsFunction) (GstPad *pad, GstCaps *caps); typedef gboolean (*GstPadSetCapsFunction) (GstPad *pad, GstCaps *caps);
typedef gboolean (*GstPadAcceptCapsFunction) (GstPad *pad, GstCaps *caps); typedef gboolean (*GstPadAcceptCapsFunction) (GstPad *pad, GstCaps *caps);
typedef GstCaps* (*GstPadFixateCapsFunction) (GstPad *pad, GstCaps *caps); typedef GstCaps* (*GstPadFixateCapsFunction) (GstPad *pad, GstCaps *caps);
typedef GstBuffer* (*GstPadBufferAllocFunction) (GstPad *pad, guint64 offset, guint size, typedef GstFlowReturn (*GstPadBufferAllocFunction) (GstPad *pad, guint64 offset, guint size,
GstCaps *caps); GstCaps *caps, GstBuffer **buf);
/* misc */ /* misc */
typedef gboolean (*GstPadDispatcherFunction) (GstPad *pad, gpointer data); typedef gboolean (*GstPadDispatcherFunction) (GstPad *pad, gpointer data);
@ -471,8 +471,8 @@ gpointer gst_pad_get_element_private (GstPad *pad);
GstPadTemplate* gst_pad_get_pad_template (GstPad *pad); GstPadTemplate* gst_pad_get_pad_template (GstPad *pad);
void gst_pad_set_bufferalloc_function (GstPad *pad, GstPadBufferAllocFunction bufalloc); void gst_pad_set_bufferalloc_function (GstPad *pad, GstPadBufferAllocFunction bufalloc);
GstBuffer* gst_pad_alloc_buffer (GstPad *pad, guint64 offset, gint size, GstFlowReturn gst_pad_alloc_buffer (GstPad *pad, guint64 offset, gint size,
GstCaps *caps); GstCaps *caps, GstBuffer **buf);
/* data passing setup functions */ /* data passing setup functions */
void gst_pad_set_activate_function (GstPad *pad, GstPadActivateFunction activate); void gst_pad_set_activate_function (GstPad *pad, GstPadActivateFunction activate);
@ -553,7 +553,6 @@ gboolean gst_pad_query_default (GstPad *pad, GstQuery *query);
/* misc helper functions */ /* misc helper functions */
gboolean gst_pad_dispatcher (GstPad *pad, GstPadDispatcherFunction dispatch, gboolean gst_pad_dispatcher (GstPad *pad, GstPadDispatcherFunction dispatch,
gpointer data); gpointer data);
/* probes */ /* probes */
#define gst_pad_add_probe(pad, probe) \ #define gst_pad_add_probe(pad, probe) \
(gst_probe_dispatcher_add_probe (&(GST_PAD_REALIZE (pad)->probedisp), probe)) (gst_probe_dispatcher_add_probe (&(GST_PAD_REALIZE (pad)->probedisp), probe))

View file

@ -126,8 +126,8 @@ static void gst_queue_get_property (GObject * object,
guint prop_id, GValue * value, GParamSpec * pspec); guint prop_id, GValue * value, GParamSpec * pspec);
static GstFlowReturn gst_queue_chain (GstPad * pad, GstBuffer * buffer); static GstFlowReturn gst_queue_chain (GstPad * pad, GstBuffer * buffer);
static GstBuffer *gst_queue_bufferalloc (GstPad * pad, guint64 offset, static GstFlowReturn gst_queue_bufferalloc (GstPad * pad, guint64 offset,
guint size, GstCaps * caps); guint size, GstCaps * caps, GstBuffer ** buf);
static void gst_queue_loop (GstPad * pad); static void gst_queue_loop (GstPad * pad);
static gboolean gst_queue_handle_sink_event (GstPad * pad, GstEvent * event); 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; return result;
} }
static GstBuffer * static GstFlowReturn
gst_queue_bufferalloc (GstPad * pad, guint64 offset, guint size, GstCaps * caps) gst_queue_bufferalloc (GstPad * pad, guint64 offset, guint size, GstCaps * caps,
GstBuffer ** buf)
{ {
GstQueue *queue; GstQueue *queue;
GstPad *otherpeer; GstFlowReturn result;
GstBuffer *result = NULL;
queue = GST_QUEUE (GST_PAD_PARENT (pad)); queue = GST_QUEUE (GST_PAD_PARENT (pad));
otherpeer = gst_pad_get_peer (queue->srcpad); result = gst_pad_alloc_buffer (queue->srcpad, offset, size, caps, buf);
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));
return result; return result;
} }

View file

@ -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 GstCaps *gst_base_sink_get_caps (GstBaseSink * sink);
static gboolean gst_base_sink_set_caps (GstBaseSink * sink, GstCaps * caps); static gboolean gst_base_sink_set_caps (GstBaseSink * sink, GstCaps * caps);
static GstBuffer *gst_base_sink_buffer_alloc (GstBaseSink * sink, static GstFlowReturn gst_base_sink_buffer_alloc (GstBaseSink * sink,
guint64 offset, guint size, GstCaps * caps); guint64 offset, guint size, GstCaps * caps, GstBuffer ** buf);
static void gst_basesink_get_times (GstBaseSink * basesink, GstBuffer * buffer, static void gst_basesink_get_times (GstBaseSink * basesink, GstBuffer * buffer,
GstClockTime * start, GstClockTime * end); GstClockTime * start, GstClockTime * end);
@ -202,21 +202,23 @@ gst_basesink_pad_setcaps (GstPad * pad, GstCaps * caps)
return res; return res;
} }
static GstBuffer * static GstFlowReturn
gst_basesink_pad_buffer_alloc (GstPad * pad, guint64 offset, guint size, gst_basesink_pad_buffer_alloc (GstPad * pad, guint64 offset, guint size,
GstCaps * caps) GstCaps * caps, GstBuffer ** buf)
{ {
GstBaseSinkClass *bclass; GstBaseSinkClass *bclass;
GstBaseSink *bsink; GstBaseSink *bsink;
GstBuffer *buffer = NULL; GstFlowReturn result = GST_FLOW_OK;
bsink = GST_BASESINK (GST_PAD_PARENT (pad)); bsink = GST_BASESINK (GST_PAD_PARENT (pad));
bclass = GST_BASESINK_GET_CLASS (bsink); bclass = GST_BASESINK_GET_CLASS (bsink);
if (bclass->buffer_alloc) 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 static void
@ -363,11 +365,12 @@ gst_base_sink_set_caps (GstBaseSink * sink, GstCaps * caps)
return TRUE; return TRUE;
} }
static GstBuffer * static GstFlowReturn
gst_base_sink_buffer_alloc (GstBaseSink * sink, guint64 offset, guint size, 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 */ /* with PREROLL_LOCK */

View file

@ -77,8 +77,8 @@ struct _GstBaseSinkClass {
gboolean (*set_caps) (GstBaseSink *sink, GstCaps *caps); gboolean (*set_caps) (GstBaseSink *sink, GstCaps *caps);
/* allocate a new buffer with given caps */ /* allocate a new buffer with given caps */
GstBuffer* (*buffer_alloc) (GstBaseSink *sink, guint64 offset, guint size, GstFlowReturn (*buffer_alloc) (GstBaseSink *sink, guint64 offset, guint size,
GstCaps *caps); GstCaps *caps, GstBuffer **buf);
/* get the start and end times for syncing on this buffer */ /* get the start and end times for syncing on this buffer */
void (*get_times) (GstBaseSink *sink, GstBuffer *buffer, void (*get_times) (GstBaseSink *sink, GstBuffer *buffer,

View file

@ -126,8 +126,8 @@ static void gst_queue_get_property (GObject * object,
guint prop_id, GValue * value, GParamSpec * pspec); guint prop_id, GValue * value, GParamSpec * pspec);
static GstFlowReturn gst_queue_chain (GstPad * pad, GstBuffer * buffer); static GstFlowReturn gst_queue_chain (GstPad * pad, GstBuffer * buffer);
static GstBuffer *gst_queue_bufferalloc (GstPad * pad, guint64 offset, static GstFlowReturn gst_queue_bufferalloc (GstPad * pad, guint64 offset,
guint size, GstCaps * caps); guint size, GstCaps * caps, GstBuffer ** buf);
static void gst_queue_loop (GstPad * pad); static void gst_queue_loop (GstPad * pad);
static gboolean gst_queue_handle_sink_event (GstPad * pad, GstEvent * event); 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; return result;
} }
static GstBuffer * static GstFlowReturn
gst_queue_bufferalloc (GstPad * pad, guint64 offset, guint size, GstCaps * caps) gst_queue_bufferalloc (GstPad * pad, guint64 offset, guint size, GstCaps * caps,
GstBuffer ** buf)
{ {
GstQueue *queue; GstQueue *queue;
GstPad *otherpeer; GstFlowReturn result;
GstBuffer *result = NULL;
queue = GST_QUEUE (GST_PAD_PARENT (pad)); queue = GST_QUEUE (GST_PAD_PARENT (pad));
otherpeer = gst_pad_get_peer (queue->srcpad); result = gst_pad_alloc_buffer (queue->srcpad, offset, size, caps, buf);
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));
return result; return result;
} }