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>
* 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 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 */

View file

@ -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,

View file

@ -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;
}
}

View file

@ -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);

View file

@ -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;
}

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 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 */

View file

@ -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,

View file

@ -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;
}