mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-19 06:46:38 +00:00
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:
parent
f4f4fa5e8f
commit
aaba029298
1 changed files with 43 additions and 69 deletions
112
gst/gstpad.c
112
gst/gstpad.c
|
@ -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 gboolean gst_pad_activate_default (GstPad * pad);
|
||||
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 guint gst_pad_signals[LAST_SIGNAL] = { 0 };
|
||||
|
@ -145,6 +147,7 @@ static GParamSpec *pspec_caps = NULL;
|
|||
|
||||
/* quarks for probe signals */
|
||||
static GQuark buffer_quark;
|
||||
static GQuark buffer_list_quark;
|
||||
static GQuark event_quark;
|
||||
|
||||
typedef struct
|
||||
|
@ -217,6 +220,7 @@ gst_flow_to_quark (GstFlowReturn ret)
|
|||
gint i; \
|
||||
\
|
||||
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"); \
|
||||
\
|
||||
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_iterate_internal_links_default);
|
||||
GST_DEBUG_REGISTER_FUNCPTR (gst_pad_acceptcaps_default);
|
||||
GST_DEBUG_REGISTER_FUNCPTR (gst_pad_chain_list_default);
|
||||
|
||||
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_QUERYFUNC (pad) = gst_pad_query_default;
|
||||
GST_PAD_ITERINTLINKFUNC (pad) = gst_pad_iterate_internal_links_default;
|
||||
|
||||
GST_PAD_ACCEPTCAPSFUNC (pad) = gst_pad_acceptcaps_default;
|
||||
GST_PAD_CHAINLISTFUNC (pad) = gst_pad_chain_list_default;
|
||||
|
||||
GST_PAD_SET_FLUSHING (pad);
|
||||
|
||||
|
@ -3669,8 +3674,12 @@ gst_pad_emit_have_data_signal (GstPad * pad, GstMiniObject * obj)
|
|||
|
||||
if (GST_IS_EVENT (obj))
|
||||
detail = event_quark;
|
||||
else
|
||||
else if (GST_IS_BUFFER (obj))
|
||||
detail = buffer_quark;
|
||||
else if (GST_IS_BUFFER_LIST (obj))
|
||||
detail = buffer_list_quark;
|
||||
else
|
||||
detail = 0;
|
||||
|
||||
/* actually emit */
|
||||
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 */
|
||||
if (G_UNLIKELY (emit_signal)) {
|
||||
cache = NULL;
|
||||
if (G_LIKELY (is_buffer)) {
|
||||
if (!gst_pad_emit_have_data_signal (pad, GST_MINI_OBJECT_CAST (data)))
|
||||
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;
|
||||
}
|
||||
if (!gst_pad_emit_have_data_signal (pad, GST_MINI_OBJECT_CAST (data)))
|
||||
goto dropping;
|
||||
}
|
||||
|
||||
/* NOTE: we read the chainfunc unlocked.
|
||||
|
@ -3764,7 +3767,7 @@ gst_pad_chain_data_unchecked (GstPad * pad, gboolean is_buffer, void *data,
|
|||
GstPadChainListFunction chainlistfunc;
|
||||
|
||||
if (G_UNLIKELY ((chainlistfunc = GST_PAD_CHAINLISTFUNC (pad)) == NULL))
|
||||
goto chain_groups;
|
||||
goto no_function;
|
||||
|
||||
GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad,
|
||||
"calling chainlistfunction &%s",
|
||||
|
@ -3781,33 +3784,6 @@ gst_pad_chain_data_unchecked (GstPad * pad, gboolean is_buffer, void *data,
|
|||
|
||||
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 */
|
||||
flushing:
|
||||
{
|
||||
|
@ -3883,6 +3859,30 @@ gst_pad_chain (GstPad * pad, GstBuffer * buffer)
|
|||
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:
|
||||
* @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 */
|
||||
GST_OBJECT_UNLOCK (pad);
|
||||
|
||||
if (G_LIKELY (is_buffer)) {
|
||||
/* if the signal handler returned FALSE, it means we should just drop the
|
||||
* buffer */
|
||||
if (!gst_pad_emit_have_data_signal (pad, GST_MINI_OBJECT_CAST (data)))
|
||||
goto dropped;
|
||||
} else {
|
||||
/* push all buffers in the list */
|
||||
goto push_groups;
|
||||
}
|
||||
/* if the signal handler returned FALSE, it means we should just drop the
|
||||
* buffer */
|
||||
if (!gst_pad_emit_have_data_signal (pad, GST_MINI_OBJECT_CAST (data)))
|
||||
goto dropped;
|
||||
|
||||
GST_OBJECT_LOCK (pad);
|
||||
}
|
||||
|
||||
|
@ -3969,28 +3965,6 @@ gst_pad_push_data (GstPad * pad, gboolean is_buffer, void *data,
|
|||
|
||||
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 */
|
||||
flushed:
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue