mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2025-04-26 06:54:49 +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 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:
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue