pad: simplify handling of buffer lists

Implement a default buffer-list function in case the element doesn't implement
one.
Also pass buffer-lists to the have-data signal, this allows us to remove some
backward compatibility code.
This commit is contained in:
Wim Taymans 2011-05-26 16:48:14 +02:00
parent f4f4fa5e8f
commit aaba029298

View file

@ -137,6 +137,8 @@ static GstCaps *gst_pad_get_caps_unlocked (GstPad * pad, GstCaps * filter);
static void gst_pad_set_pad_template (GstPad * pad, GstPadTemplate * templ); static void gst_pad_set_pad_template (GstPad * pad, GstPadTemplate * templ);
static gboolean gst_pad_activate_default (GstPad * pad); static gboolean gst_pad_activate_default (GstPad * pad);
static gboolean gst_pad_acceptcaps_default (GstPad * pad, GstCaps * caps); static gboolean gst_pad_acceptcaps_default (GstPad * pad, GstCaps * caps);
static GstFlowReturn gst_pad_chain_list_default (GstPad * pad,
GstBufferList * list);
static GstObjectClass *parent_class = NULL; static GstObjectClass *parent_class = NULL;
static guint gst_pad_signals[LAST_SIGNAL] = { 0 }; static guint gst_pad_signals[LAST_SIGNAL] = { 0 };
@ -145,6 +147,7 @@ static GParamSpec *pspec_caps = NULL;
/* quarks for probe signals */ /* quarks for probe signals */
static GQuark buffer_quark; static GQuark buffer_quark;
static GQuark buffer_list_quark;
static GQuark event_quark; static GQuark event_quark;
typedef struct typedef struct
@ -217,6 +220,7 @@ gst_flow_to_quark (GstFlowReturn ret)
gint i; \ gint i; \
\ \
buffer_quark = g_quark_from_static_string ("buffer"); \ buffer_quark = g_quark_from_static_string ("buffer"); \
buffer_list_quark = g_quark_from_static_string ("bufferlist"); \
event_quark = g_quark_from_static_string ("event"); \ event_quark = g_quark_from_static_string ("event"); \
\ \
for (i = 0; i < G_N_ELEMENTS (flow_quarks); i++) { \ for (i = 0; i < G_N_ELEMENTS (flow_quarks); i++) { \
@ -341,6 +345,7 @@ gst_pad_class_init (GstPadClass * klass)
GST_DEBUG_REGISTER_FUNCPTR (gst_pad_query_default); GST_DEBUG_REGISTER_FUNCPTR (gst_pad_query_default);
GST_DEBUG_REGISTER_FUNCPTR (gst_pad_iterate_internal_links_default); GST_DEBUG_REGISTER_FUNCPTR (gst_pad_iterate_internal_links_default);
GST_DEBUG_REGISTER_FUNCPTR (gst_pad_acceptcaps_default); GST_DEBUG_REGISTER_FUNCPTR (gst_pad_acceptcaps_default);
GST_DEBUG_REGISTER_FUNCPTR (gst_pad_chain_list_default);
klass->have_data = default_have_data; klass->have_data = default_have_data;
} }
@ -357,8 +362,8 @@ gst_pad_init (GstPad * pad)
GST_PAD_QUERYTYPEFUNC (pad) = gst_pad_get_query_types_default; GST_PAD_QUERYTYPEFUNC (pad) = gst_pad_get_query_types_default;
GST_PAD_QUERYFUNC (pad) = gst_pad_query_default; GST_PAD_QUERYFUNC (pad) = gst_pad_query_default;
GST_PAD_ITERINTLINKFUNC (pad) = gst_pad_iterate_internal_links_default; GST_PAD_ITERINTLINKFUNC (pad) = gst_pad_iterate_internal_links_default;
GST_PAD_ACCEPTCAPSFUNC (pad) = gst_pad_acceptcaps_default; GST_PAD_ACCEPTCAPSFUNC (pad) = gst_pad_acceptcaps_default;
GST_PAD_CHAINLISTFUNC (pad) = gst_pad_chain_list_default;
GST_PAD_SET_FLUSHING (pad); GST_PAD_SET_FLUSHING (pad);
@ -3669,8 +3674,12 @@ gst_pad_emit_have_data_signal (GstPad * pad, GstMiniObject * obj)
if (GST_IS_EVENT (obj)) if (GST_IS_EVENT (obj))
detail = event_quark; detail = event_quark;
else else if (GST_IS_BUFFER (obj))
detail = buffer_quark; detail = buffer_quark;
else if (GST_IS_BUFFER_LIST (obj))
detail = buffer_list_quark;
else
detail = 0;
/* actually emit */ /* actually emit */
g_signal_emitv (args, gst_pad_signals[PAD_HAVE_DATA], detail, &ret); g_signal_emitv (args, gst_pad_signals[PAD_HAVE_DATA], detail, &ret);
@ -3726,14 +3735,8 @@ gst_pad_chain_data_unchecked (GstPad * pad, gboolean is_buffer, void *data,
/* see if the signal should be emited */ /* see if the signal should be emited */
if (G_UNLIKELY (emit_signal)) { if (G_UNLIKELY (emit_signal)) {
cache = NULL; cache = NULL;
if (G_LIKELY (is_buffer)) { if (!gst_pad_emit_have_data_signal (pad, GST_MINI_OBJECT_CAST (data)))
if (!gst_pad_emit_have_data_signal (pad, GST_MINI_OBJECT_CAST (data))) goto dropping;
goto dropping;
} else {
/* chain all groups in the buffer list one by one to avoid problems with
* buffer probes that push buffers or events */
goto chain_groups;
}
} }
/* NOTE: we read the chainfunc unlocked. /* NOTE: we read the chainfunc unlocked.
@ -3764,7 +3767,7 @@ gst_pad_chain_data_unchecked (GstPad * pad, gboolean is_buffer, void *data,
GstPadChainListFunction chainlistfunc; GstPadChainListFunction chainlistfunc;
if (G_UNLIKELY ((chainlistfunc = GST_PAD_CHAINLISTFUNC (pad)) == NULL)) if (G_UNLIKELY ((chainlistfunc = GST_PAD_CHAINLISTFUNC (pad)) == NULL))
goto chain_groups; goto no_function;
GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad, GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad,
"calling chainlistfunction &%s", "calling chainlistfunction &%s",
@ -3781,33 +3784,6 @@ gst_pad_chain_data_unchecked (GstPad * pad, gboolean is_buffer, void *data,
return ret; return ret;
chain_groups:
{
GstBufferList *list;
guint i, len;
GstBuffer *buffer;
GST_PAD_STREAM_UNLOCK (pad);
GST_INFO_OBJECT (pad, "chaining each group in list as a merged buffer");
list = GST_BUFFER_LIST_CAST (data);
len = gst_buffer_list_len (list);
ret = GST_FLOW_OK;
for (i = 0; i < len; i++) {
buffer = gst_buffer_list_get (list, i);
ret =
gst_pad_chain_data_unchecked (pad, TRUE, gst_buffer_ref (buffer),
NULL);
if (ret != GST_FLOW_OK)
break;
}
gst_buffer_list_unref (list);
return ret;
}
/* ERRORS */ /* ERRORS */
flushing: flushing:
{ {
@ -3883,6 +3859,30 @@ gst_pad_chain (GstPad * pad, GstBuffer * buffer)
return gst_pad_chain_data_unchecked (pad, TRUE, buffer, NULL); return gst_pad_chain_data_unchecked (pad, TRUE, buffer, NULL);
} }
static GstFlowReturn
gst_pad_chain_list_default (GstPad * pad, GstBufferList * list)
{
guint i, len;
GstBuffer *buffer;
GstFlowReturn ret;
GST_INFO_OBJECT (pad, "chaining each group in list as a merged buffer");
len = gst_buffer_list_len (list);
ret = GST_FLOW_OK;
for (i = 0; i < len; i++) {
buffer = gst_buffer_list_get (list, i);
ret =
gst_pad_chain_data_unchecked (pad, TRUE, gst_buffer_ref (buffer), NULL);
if (ret != GST_FLOW_OK)
break;
}
gst_buffer_list_unref (list);
return ret;
}
/** /**
* gst_pad_chain_list: * gst_pad_chain_list:
* @pad: a sink #GstPad, returns GST_FLOW_ERROR if not. * @pad: a sink #GstPad, returns GST_FLOW_ERROR if not.
@ -3944,15 +3944,11 @@ gst_pad_push_data (GstPad * pad, gboolean is_buffer, void *data,
/* unlock before emitting */ /* unlock before emitting */
GST_OBJECT_UNLOCK (pad); GST_OBJECT_UNLOCK (pad);
if (G_LIKELY (is_buffer)) { /* if the signal handler returned FALSE, it means we should just drop the
/* if the signal handler returned FALSE, it means we should just drop the * buffer */
* buffer */ if (!gst_pad_emit_have_data_signal (pad, GST_MINI_OBJECT_CAST (data)))
if (!gst_pad_emit_have_data_signal (pad, GST_MINI_OBJECT_CAST (data))) goto dropped;
goto dropped;
} else {
/* push all buffers in the list */
goto push_groups;
}
GST_OBJECT_LOCK (pad); GST_OBJECT_LOCK (pad);
} }
@ -3969,28 +3965,6 @@ gst_pad_push_data (GstPad * pad, gboolean is_buffer, void *data,
return ret; return ret;
push_groups:
{
GstBufferList *list;
guint i, len;
GstBuffer *buffer;
GST_INFO_OBJECT (pad, "pushing each group in list as a merged buffer");
list = GST_BUFFER_LIST_CAST (data);
len = gst_buffer_list_len (list);
for (i = 0; i < len; i++) {
buffer = gst_buffer_list_get (list, i);
ret = gst_pad_push_data (pad, TRUE, gst_buffer_ref (buffer), NULL);
if (ret != GST_FLOW_OK)
break;
}
gst_buffer_list_unref (list);
return ret;
}
/* ERROR recovery here */ /* ERROR recovery here */
flushed: flushed:
{ {