flowcombiner: passthrough the flow return if there are no pads

What may happen is that during the course of processing a buffer,
all of the pads in a flow combiner may disappear.  In this case, we
would return NOT_LINKED.  Instead return whatever the input flow return
was.
This commit is contained in:
Matthew Waters 2020-03-25 20:23:17 +11:00 committed by GStreamer Merge Bot
parent dcece2a878
commit b3afd1a2fc
2 changed files with 30 additions and 5 deletions

View file

@ -180,6 +180,8 @@ gst_flow_combiner_clear (GstFlowCombiner * combiner)
g_return_if_fail (combiner != NULL);
GST_DEBUG ("%p clearing", combiner);
while ((pad = g_queue_pop_head (&combiner->pads)))
gst_object_unref (pad);
combiner->last_ret = GST_FLOW_OK;
@ -200,7 +202,7 @@ gst_flow_combiner_reset (GstFlowCombiner * combiner)
g_return_if_fail (combiner != NULL);
GST_DEBUG ("Reset flow returns");
GST_DEBUG ("%p reset flow returns", combiner);
for (iter = combiner->pads.head; iter; iter = iter->next) {
GST_PAD_LAST_FLOW_RETURN (iter->data) = GST_FLOW_OK;
@ -217,13 +219,16 @@ gst_flow_combiner_get_flow (GstFlowCombiner * combiner)
gboolean all_notlinked = TRUE;
GList *iter;
GST_DEBUG ("Combining flow returns");
GST_DEBUG ("%p Combining flow returns", combiner);
for (iter = combiner->pads.head; iter; iter = iter->next) {
GstFlowReturn fret = GST_PAD_LAST_FLOW_RETURN (iter->data);
GST_TRACE ("%p pad %" GST_PTR_FORMAT " has flow return of %s (%d)",
combiner, iter->data, gst_flow_get_name (fret), fret);
if (fret <= GST_FLOW_NOT_NEGOTIATED || fret == GST_FLOW_FLUSHING) {
GST_DEBUG ("Error flow return found, returning");
GST_DEBUG ("%p Error flow return found, returning", combiner);
cret = fret;
goto done;
}
@ -240,7 +245,8 @@ gst_flow_combiner_get_flow (GstFlowCombiner * combiner)
cret = GST_FLOW_EOS;
done:
GST_DEBUG ("Combined flow return: %s (%d)", gst_flow_get_name (cret), cret);
GST_DEBUG ("%p Combined flow return: %s (%d)", combiner,
gst_flow_get_name (cret), cret);
return cret;
}
@ -266,11 +272,15 @@ gst_flow_combiner_update_flow (GstFlowCombiner * combiner, GstFlowReturn fret)
g_return_val_if_fail (combiner != NULL, GST_FLOW_ERROR);
GST_DEBUG ("%p updating combiner with flow %s (%d)", combiner,
gst_flow_get_name (fret), fret);
if (combiner->last_ret == fret) {
return fret;
}
if (fret <= GST_FLOW_NOT_NEGOTIATED || fret == GST_FLOW_FLUSHING) {
if (fret <= GST_FLOW_NOT_NEGOTIATED || fret == GST_FLOW_FLUSHING
|| !combiner->pads.head) {
ret = fret;
} else {
ret = gst_flow_combiner_get_flow (combiner);

View file

@ -232,6 +232,20 @@ GST_START_TEST (test_clear)
GST_END_TEST;
GST_START_TEST (test_no_pads_passthrough)
{
GstFlowCombiner *combiner = gst_flow_combiner_new ();
fail_unless_equals_int (GST_FLOW_FLUSHING,
gst_flow_combiner_update_flow (combiner, GST_FLOW_FLUSHING));
fail_unless_equals_int (GST_FLOW_OK,
gst_flow_combiner_update_flow (combiner, GST_FLOW_OK));
gst_flow_combiner_free (combiner);
}
GST_END_TEST;
static Suite *
flow_combiner_suite (void)
{
@ -241,6 +255,7 @@ flow_combiner_suite (void)
suite_add_tcase (s, tc_chain);
tcase_add_test (tc_chain, test_combined_flows);
tcase_add_test (tc_chain, test_clear);
tcase_add_test (tc_chain, test_no_pads_passthrough);
return s;
}