pad: Ensure last flow return is set on sink pads in push mode
authorEdward Hervey <edward@centricular.com>
Wed, 18 Aug 2021 08:23:38 +0000 (10:23 +0200)
committerEdward Hervey <bilboed@bilboed.com>
Wed, 18 Aug 2021 08:25:08 +0000 (10:25 +0200)
The last flow return field was never updated on sink pads in push mode. This
fixes it and makes it consistent.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/868>

gst/gstpad.c
tests/check/gst/gstpad.c

index cfc197e..5197cd5 100644 (file)
@@ -4460,6 +4460,8 @@ gst_pad_chain_data_unchecked (GstPad * pad, GstPadProbeType type, void *data)
         GST_DEBUG_FUNCPTR_NAME (chainlistfunc), gst_flow_get_name (ret));
   }
 
         GST_DEBUG_FUNCPTR_NAME (chainlistfunc), gst_flow_get_name (ret));
   }
 
+  pad->ABI.abi.last_flowret = ret;
+
   RELEASE_PARENT (parent);
 
   GST_PAD_STREAM_UNLOCK (pad);
   RELEASE_PARENT (parent);
 
   GST_PAD_STREAM_UNLOCK (pad);
@@ -4471,6 +4473,7 @@ flushing:
   {
     GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad,
         "chaining, but pad was flushing");
   {
     GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad,
         "chaining, but pad was flushing");
+    pad->ABI.abi.last_flowret = GST_FLOW_FLUSHING;
     GST_OBJECT_UNLOCK (pad);
     GST_PAD_STREAM_UNLOCK (pad);
     gst_mini_object_unref (GST_MINI_OBJECT_CAST (data));
     GST_OBJECT_UNLOCK (pad);
     GST_PAD_STREAM_UNLOCK (pad);
     gst_mini_object_unref (GST_MINI_OBJECT_CAST (data));
@@ -4479,6 +4482,7 @@ flushing:
 eos:
   {
     GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad, "chaining, but pad was EOS");
 eos:
   {
     GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad, "chaining, but pad was EOS");
+    pad->ABI.abi.last_flowret = GST_FLOW_EOS;
     GST_OBJECT_UNLOCK (pad);
     GST_PAD_STREAM_UNLOCK (pad);
     gst_mini_object_unref (GST_MINI_OBJECT_CAST (data));
     GST_OBJECT_UNLOCK (pad);
     GST_PAD_STREAM_UNLOCK (pad);
     gst_mini_object_unref (GST_MINI_OBJECT_CAST (data));
@@ -4488,6 +4492,7 @@ wrong_mode:
   {
     g_critical ("chain on pad %s:%s but it was not in push mode",
         GST_DEBUG_PAD_NAME (pad));
   {
     g_critical ("chain on pad %s:%s but it was not in push mode",
         GST_DEBUG_PAD_NAME (pad));
+    pad->ABI.abi.last_flowret = GST_FLOW_ERROR;
     GST_OBJECT_UNLOCK (pad);
     GST_PAD_STREAM_UNLOCK (pad);
     gst_mini_object_unref (GST_MINI_OBJECT_CAST (data));
     GST_OBJECT_UNLOCK (pad);
     GST_PAD_STREAM_UNLOCK (pad);
     gst_mini_object_unref (GST_MINI_OBJECT_CAST (data));
@@ -4498,8 +4503,6 @@ probe_handled:
   /* PASSTHROUGH */
 probe_stopped:
   {
   /* PASSTHROUGH */
 probe_stopped:
   {
-    GST_OBJECT_UNLOCK (pad);
-    GST_PAD_STREAM_UNLOCK (pad);
     /* We unref the buffer, except if the probe handled it (CUSTOM_SUCCESS_1) */
     if (!handled)
       gst_mini_object_unref (GST_MINI_OBJECT_CAST (data));
     /* We unref the buffer, except if the probe handled it (CUSTOM_SUCCESS_1) */
     if (!handled)
       gst_mini_object_unref (GST_MINI_OBJECT_CAST (data));
@@ -4514,11 +4517,15 @@ probe_stopped:
         GST_DEBUG_OBJECT (pad, "an error occurred %s", gst_flow_get_name (ret));
         break;
     }
         GST_DEBUG_OBJECT (pad, "an error occurred %s", gst_flow_get_name (ret));
         break;
     }
+    pad->ABI.abi.last_flowret = ret;
+    GST_OBJECT_UNLOCK (pad);
+    GST_PAD_STREAM_UNLOCK (pad);
     return ret;
   }
 no_parent:
   {
     GST_DEBUG_OBJECT (pad, "No parent when chaining %" GST_PTR_FORMAT, data);
     return ret;
   }
 no_parent:
   {
     GST_DEBUG_OBJECT (pad, "No parent when chaining %" GST_PTR_FORMAT, data);
+    pad->ABI.abi.last_flowret = GST_FLOW_FLUSHING;
     gst_mini_object_unref (GST_MINI_OBJECT_CAST (data));
     GST_OBJECT_UNLOCK (pad);
     GST_PAD_STREAM_UNLOCK (pad);
     gst_mini_object_unref (GST_MINI_OBJECT_CAST (data));
     GST_OBJECT_UNLOCK (pad);
     GST_PAD_STREAM_UNLOCK (pad);
@@ -4526,6 +4533,7 @@ no_parent:
   }
 no_function:
   {
   }
 no_function:
   {
+    pad->ABI.abi.last_flowret = GST_FLOW_NOT_SUPPORTED;
     RELEASE_PARENT (parent);
     gst_mini_object_unref (GST_MINI_OBJECT_CAST (data));
     g_critical ("chain on pad %s:%s but it has no chainfunction",
     RELEASE_PARENT (parent);
     gst_mini_object_unref (GST_MINI_OBJECT_CAST (data));
     g_critical ("chain on pad %s:%s but it has no chainfunction",
index 3a4ee0d..1b1afe6 100644 (file)
@@ -2699,11 +2699,13 @@ GST_START_TEST (test_last_flow_return_push)
 
   /* initial value is flushing */
   fail_unless (gst_pad_get_last_flow_return (srcpad) == GST_FLOW_FLUSHING);
 
   /* initial value is flushing */
   fail_unless (gst_pad_get_last_flow_return (srcpad) == GST_FLOW_FLUSHING);
+  fail_unless (gst_pad_get_last_flow_return (sinkpad) == GST_FLOW_FLUSHING);
 
   /* when active it goes to ok */
   gst_pad_set_active (srcpad, TRUE);
   fail_unless (gst_pad_get_last_flow_return (srcpad) == GST_FLOW_OK);
   gst_pad_set_active (sinkpad, TRUE);
 
   /* when active it goes to ok */
   gst_pad_set_active (srcpad, TRUE);
   fail_unless (gst_pad_get_last_flow_return (srcpad) == GST_FLOW_OK);
   gst_pad_set_active (sinkpad, TRUE);
+  fail_unless (gst_pad_get_last_flow_return (sinkpad) == GST_FLOW_OK);
 
   /* startup events */
   gst_pad_push_event (srcpad, gst_event_new_stream_start ("test"));
 
   /* startup events */
   gst_pad_push_event (srcpad, gst_event_new_stream_start ("test"));
@@ -2715,11 +2717,13 @@ GST_START_TEST (test_last_flow_return_push)
   next_return = GST_FLOW_OK;
   fail_unless (gst_pad_push (srcpad, gst_buffer_new ()) == GST_FLOW_OK);
   fail_unless (gst_pad_get_last_flow_return (srcpad) == GST_FLOW_OK);
   next_return = GST_FLOW_OK;
   fail_unless (gst_pad_push (srcpad, gst_buffer_new ()) == GST_FLOW_OK);
   fail_unless (gst_pad_get_last_flow_return (srcpad) == GST_FLOW_OK);
+  fail_unless (gst_pad_get_last_flow_return (sinkpad) == GST_FLOW_OK);
 
   /* push not-linked */
   next_return = GST_FLOW_NOT_LINKED;
   fail_unless (gst_pad_push (srcpad, gst_buffer_new ()) == GST_FLOW_NOT_LINKED);
   fail_unless (gst_pad_get_last_flow_return (srcpad) == GST_FLOW_NOT_LINKED);
 
   /* push not-linked */
   next_return = GST_FLOW_NOT_LINKED;
   fail_unless (gst_pad_push (srcpad, gst_buffer_new ()) == GST_FLOW_NOT_LINKED);
   fail_unless (gst_pad_get_last_flow_return (srcpad) == GST_FLOW_NOT_LINKED);
+  fail_unless (gst_pad_get_last_flow_return (sinkpad) == GST_FLOW_NOT_LINKED);
 
   /* push not-linked */
   next_return = GST_FLOW_NOT_NEGOTIATED;
 
   /* push not-linked */
   next_return = GST_FLOW_NOT_NEGOTIATED;
@@ -2727,25 +2731,32 @@ GST_START_TEST (test_last_flow_return_push)
           gst_buffer_new ()) == GST_FLOW_NOT_NEGOTIATED);
   fail_unless (gst_pad_get_last_flow_return (srcpad) ==
       GST_FLOW_NOT_NEGOTIATED);
           gst_buffer_new ()) == GST_FLOW_NOT_NEGOTIATED);
   fail_unless (gst_pad_get_last_flow_return (srcpad) ==
       GST_FLOW_NOT_NEGOTIATED);
+  fail_unless (gst_pad_get_last_flow_return (sinkpad) ==
+      GST_FLOW_NOT_NEGOTIATED);
 
   /* push error */
   next_return = GST_FLOW_ERROR;
   fail_unless (gst_pad_push (srcpad, gst_buffer_new ()) == GST_FLOW_ERROR);
   fail_unless (gst_pad_get_last_flow_return (srcpad) == GST_FLOW_ERROR);
 
   /* push error */
   next_return = GST_FLOW_ERROR;
   fail_unless (gst_pad_push (srcpad, gst_buffer_new ()) == GST_FLOW_ERROR);
   fail_unless (gst_pad_get_last_flow_return (srcpad) == GST_FLOW_ERROR);
+  fail_unless (gst_pad_get_last_flow_return (sinkpad) == GST_FLOW_ERROR);
 
   /* back to ok */
   next_return = GST_FLOW_OK;
   fail_unless (gst_pad_push (srcpad, gst_buffer_new ()) == GST_FLOW_OK);
   fail_unless (gst_pad_get_last_flow_return (srcpad) == GST_FLOW_OK);
 
   /* back to ok */
   next_return = GST_FLOW_OK;
   fail_unless (gst_pad_push (srcpad, gst_buffer_new ()) == GST_FLOW_OK);
   fail_unless (gst_pad_get_last_flow_return (srcpad) == GST_FLOW_OK);
+  fail_unless (gst_pad_get_last_flow_return (sinkpad) == GST_FLOW_OK);
 
   /* unlinked push */
   gst_pad_unlink (srcpad, sinkpad);
   fail_unless (gst_pad_push (srcpad, gst_buffer_new ()) == GST_FLOW_NOT_LINKED);
   fail_unless (gst_pad_get_last_flow_return (srcpad) == GST_FLOW_NOT_LINKED);
 
   /* unlinked push */
   gst_pad_unlink (srcpad, sinkpad);
   fail_unless (gst_pad_push (srcpad, gst_buffer_new ()) == GST_FLOW_NOT_LINKED);
   fail_unless (gst_pad_get_last_flow_return (srcpad) == GST_FLOW_NOT_LINKED);
+  /* The last flow ret from the peer pad shouldn't have changed */
+  fail_unless (gst_pad_get_last_flow_return (sinkpad) == GST_FLOW_OK);
 
   gst_pad_link (srcpad, sinkpad);
   fail_unless (gst_pad_push_event (srcpad, gst_event_new_eos ()));
   fail_unless (gst_pad_get_last_flow_return (srcpad) == GST_FLOW_EOS);
 
   gst_pad_link (srcpad, sinkpad);
   fail_unless (gst_pad_push_event (srcpad, gst_event_new_eos ()));
   fail_unless (gst_pad_get_last_flow_return (srcpad) == GST_FLOW_EOS);
+  fail_unless (gst_pad_get_last_flow_return (sinkpad) == GST_FLOW_EOS);
 
   gst_object_unref (srcpad);
   gst_object_unref (sinkpad);
 
   gst_object_unref (srcpad);
   gst_object_unref (sinkpad);
@@ -2784,17 +2795,20 @@ GST_START_TEST (test_last_flow_return_pull)
   gst_pad_link (srcpad, sinkpad);
 
   /* initial value is flushing */
   gst_pad_link (srcpad, sinkpad);
 
   /* initial value is flushing */
+  fail_unless (gst_pad_get_last_flow_return (srcpad) == GST_FLOW_FLUSHING);
   fail_unless (gst_pad_get_last_flow_return (sinkpad) == GST_FLOW_FLUSHING);
 
   /* when active it goes to ok */
   gst_pad_set_active (sinkpad, TRUE);
   fail_unless (gst_pad_get_last_flow_return (sinkpad) == GST_FLOW_OK);
   gst_pad_set_active (srcpad, TRUE);
   fail_unless (gst_pad_get_last_flow_return (sinkpad) == GST_FLOW_FLUSHING);
 
   /* when active it goes to ok */
   gst_pad_set_active (sinkpad, TRUE);
   fail_unless (gst_pad_get_last_flow_return (sinkpad) == GST_FLOW_OK);
   gst_pad_set_active (srcpad, TRUE);
+  fail_unless (gst_pad_get_last_flow_return (srcpad) == GST_FLOW_OK);
 
   /* pull Ok */
   next_return = GST_FLOW_OK;
   fail_unless (gst_pad_pull_range (sinkpad, 0, 1, &buf) == GST_FLOW_OK);
   fail_unless (gst_pad_get_last_flow_return (sinkpad) == GST_FLOW_OK);
 
   /* pull Ok */
   next_return = GST_FLOW_OK;
   fail_unless (gst_pad_pull_range (sinkpad, 0, 1, &buf) == GST_FLOW_OK);
   fail_unless (gst_pad_get_last_flow_return (sinkpad) == GST_FLOW_OK);
+  fail_unless (gst_pad_get_last_flow_return (srcpad) == GST_FLOW_OK);
   gst_buffer_unref (buf);
   buf = NULL;
 
   gst_buffer_unref (buf);
   buf = NULL;
 
@@ -2802,11 +2816,13 @@ GST_START_TEST (test_last_flow_return_pull)
   next_return = GST_FLOW_NOT_LINKED;
   fail_unless (gst_pad_pull_range (sinkpad, 0, 1, &buf) == GST_FLOW_NOT_LINKED);
   fail_unless (gst_pad_get_last_flow_return (sinkpad) == GST_FLOW_NOT_LINKED);
   next_return = GST_FLOW_NOT_LINKED;
   fail_unless (gst_pad_pull_range (sinkpad, 0, 1, &buf) == GST_FLOW_NOT_LINKED);
   fail_unless (gst_pad_get_last_flow_return (sinkpad) == GST_FLOW_NOT_LINKED);
+  fail_unless (gst_pad_get_last_flow_return (srcpad) == GST_FLOW_NOT_LINKED);
 
   /* pull error */
   next_return = GST_FLOW_ERROR;
   fail_unless (gst_pad_pull_range (sinkpad, 0, 1, &buf) == GST_FLOW_ERROR);
   fail_unless (gst_pad_get_last_flow_return (sinkpad) == GST_FLOW_ERROR);
 
   /* pull error */
   next_return = GST_FLOW_ERROR;
   fail_unless (gst_pad_pull_range (sinkpad, 0, 1, &buf) == GST_FLOW_ERROR);
   fail_unless (gst_pad_get_last_flow_return (sinkpad) == GST_FLOW_ERROR);
+  fail_unless (gst_pad_get_last_flow_return (srcpad) == GST_FLOW_ERROR);
 
   /* pull not-nego */
   next_return = GST_FLOW_NOT_NEGOTIATED;
 
   /* pull not-nego */
   next_return = GST_FLOW_NOT_NEGOTIATED;
@@ -2814,11 +2830,14 @@ GST_START_TEST (test_last_flow_return_pull)
           &buf) == GST_FLOW_NOT_NEGOTIATED);
   fail_unless (gst_pad_get_last_flow_return (sinkpad) ==
       GST_FLOW_NOT_NEGOTIATED);
           &buf) == GST_FLOW_NOT_NEGOTIATED);
   fail_unless (gst_pad_get_last_flow_return (sinkpad) ==
       GST_FLOW_NOT_NEGOTIATED);
+  fail_unless (gst_pad_get_last_flow_return (srcpad) ==
+      GST_FLOW_NOT_NEGOTIATED);
 
   /* pull ok again */
   next_return = GST_FLOW_OK;
   fail_unless (gst_pad_pull_range (sinkpad, 0, 1, &buf) == GST_FLOW_OK);
   fail_unless (gst_pad_get_last_flow_return (sinkpad) == GST_FLOW_OK);
 
   /* pull ok again */
   next_return = GST_FLOW_OK;
   fail_unless (gst_pad_pull_range (sinkpad, 0, 1, &buf) == GST_FLOW_OK);
   fail_unless (gst_pad_get_last_flow_return (sinkpad) == GST_FLOW_OK);
+  fail_unless (gst_pad_get_last_flow_return (srcpad) == GST_FLOW_OK);
   gst_buffer_unref (buf);
   buf = NULL;
 
   gst_buffer_unref (buf);
   buf = NULL;
 
@@ -2826,12 +2845,15 @@ GST_START_TEST (test_last_flow_return_pull)
   gst_pad_unlink (srcpad, sinkpad);
   fail_unless (gst_pad_pull_range (sinkpad, 0, 1, &buf) == GST_FLOW_NOT_LINKED);
   fail_unless (gst_pad_get_last_flow_return (sinkpad) == GST_FLOW_NOT_LINKED);
   gst_pad_unlink (srcpad, sinkpad);
   fail_unless (gst_pad_pull_range (sinkpad, 0, 1, &buf) == GST_FLOW_NOT_LINKED);
   fail_unless (gst_pad_get_last_flow_return (sinkpad) == GST_FLOW_NOT_LINKED);
+  /* Return value for the remote pad didn't change */
+  fail_unless (gst_pad_get_last_flow_return (srcpad) == GST_FLOW_OK);
 
   /* eos */
   gst_pad_link (srcpad, sinkpad);
   next_return = GST_FLOW_EOS;
   fail_unless (gst_pad_pull_range (sinkpad, 0, 1, &buf) == GST_FLOW_EOS);
   fail_unless (gst_pad_get_last_flow_return (sinkpad) == GST_FLOW_EOS);
 
   /* eos */
   gst_pad_link (srcpad, sinkpad);
   next_return = GST_FLOW_EOS;
   fail_unless (gst_pad_pull_range (sinkpad, 0, 1, &buf) == GST_FLOW_EOS);
   fail_unless (gst_pad_get_last_flow_return (sinkpad) == GST_FLOW_EOS);
+  fail_unless (gst_pad_get_last_flow_return (srcpad) == GST_FLOW_EOS);
 
   gst_object_unref (srcpad);
   gst_object_unref (sinkpad);
 
   gst_object_unref (srcpad);
   gst_object_unref (sinkpad);