flowcombiner: passthrough the flow return if there are no pads
authorMatthew Waters <matthew@centricular.com>
Wed, 25 Mar 2020 09:23:17 +0000 (20:23 +1100)
committerGStreamer Merge Bot <gitlab-merge-bot@gstreamer-foundation.org>
Thu, 26 Mar 2020 02:31:52 +0000 (02:31 +0000)
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.

libs/gst/base/gstflowcombiner.c
tests/check/libs/flowcombiner.c

index 8b64a469c7edd450d58582ac9d606d1f11728a77..40c2dbe20bea0cd2f38a3b8a337e5bde95c27124 100644 (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);
index 6c634c17a432499d5e54a0ad9d4931c4cdacf8a8..dee5efe919d41d568e12dfb925dcd8a6318b454e 100644 (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;
 }