From f0abd316e2aaf42b7d8639a72648794364df5fec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alicia=20Boya=20Garc=C3=ADa?= Date: Sun, 17 Feb 2019 15:38:53 +0100 Subject: [PATCH] gst-validate-scenario: Make waits optional in appsrc-push While in many cases it's desirable to wait for a buffer to be pushed downstream when using appsrc-push, in some cases this is not possible as such pushing action is dependent on following actions that would not be executed if we wait. An example for this is prerolling: appsrc ! qtdemux ! video/x-h264 ! decodebin name=dec ! %(videosink)s description, seek=false, handles-states=true appsrc-push, target-element-name=appsrc0, file-name="raw_h264.0.mp4" set-state, state=playing appsrc-eos, target-element-name=appsrc0 In order for the preroll to occur, both the appsrc needs to push the buffer and the state needs to reach PLAYING. But `set-state` cannot finish if the buffer has not been pushed (the state transition does not finish) and conversely pushing the buffer will not finish until the state has reached. Making appsrc-push not wait for the buffer solves this problem. This patch makes appsrc-push aware of this issue by only waiting for the buffer to be pushed if the pipeline is in a state that allows buffers to flow. --- validate/gst/validate/gst-validate-scenario.c | 30 +++++++++++++++++-- validate/gst/validate/gst-validate-scenario.h | 2 ++ 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/validate/gst/validate/gst-validate-scenario.c b/validate/gst/validate/gst-validate-scenario.c index ec8a14482e..2c592205e5 100644 --- a/validate/gst/validate/gst-validate-scenario.c +++ b/validate/gst/validate/gst-validate-scenario.c @@ -345,6 +345,12 @@ gst_validate_action_init (GstValidateAction * action) g_weak_ref_init (&action->priv->scenario, NULL); } +void +gst_validate_action_ref (GstValidateAction * action) +{ + gst_mini_object_ref (GST_MINI_OBJECT (action)); +} + void gst_validate_action_unref (GstValidateAction * action) { @@ -2659,6 +2665,7 @@ appsrc_push_chain_wrapper (GstPad * pad, GstObject * parent, GstBuffer * buffer, GST_VALIDATE_SCENARIO_EOS_HANDLING_LOCK (scenario); ret = pad->chainfunc (pad, parent, buffer); gst_validate_action_set_done (action); + gst_validate_action_unref (action); *remove_wrapper = TRUE; GST_VALIDATE_SCENARIO_EOS_HANDLING_UNLOCK (scenario); g_object_unref (scenario); @@ -2698,6 +2705,12 @@ _execute_appsrc_push (GstValidateScenario * scenario, guint64 offset = 0; guint64 size = -1; gint push_buffer_ret; + gboolean wait; + + /* We will only wait for the the buffer to be pushed if we are in a state + * that allows flow of buffers (>=PAUSED). Otherwise the buffer will just + * be enqueued. */ + wait = scenario->priv->target_state >= GST_STATE_PAUSED; target = _get_target_element (scenario, action); if (target == NULL) { @@ -2759,6 +2772,9 @@ _execute_appsrc_push (GstValidateScenario * scenario, gst_object_unref (peer_pad); } + /* Keep the action alive until set done is called. */ + gst_validate_action_ref (action); + g_signal_emit_by_name (target, "push-buffer", buffer, &push_buffer_ret); if (push_buffer_ret != GST_FLOW_OK) { gchar *structure_string = gst_structure_to_string (action->structure); @@ -2770,7 +2786,14 @@ _execute_appsrc_push (GstValidateScenario * scenario, g_free (file_name); gst_object_unref (target); - return GST_VALIDATE_EXECUTE_ACTION_ASYNC; + + if (wait) { + return GST_VALIDATE_EXECUTE_ACTION_ASYNC; + } else { + gst_validate_printf (NULL, + "Pipeline is not ready to push buffers, interlacing appsrc-push action..."); + return GST_VALIDATE_EXECUTE_ACTION_INTERLACED; + } } static gint @@ -3357,6 +3380,9 @@ _load_scenario_file (GstValidateScenario * scenario, gst_structure_get_boolean (structure, "handles-states", &priv->handles_state); + if (!priv->handles_state) + priv->target_state = GST_STATE_PLAYING; + pipeline_name = gst_structure_get_string (structure, "pipeline-name"); if (pipeline_name) { g_free (priv->pipeline_name); @@ -5072,7 +5098,7 @@ init_scenarios (void) }, {NULL} }), - "Queues a buffer from an appsrc and waits for it to be handled by downstream elements in the same streaming thread.", + "Queues a buffer in an appsrc. If the pipeline state allows flow of buffers, the next action is not run until the buffer has been pushed.", GST_VALIDATE_ACTION_TYPE_NONE); REGISTER_ACTION_TYPE ("appsrc-eos", _execute_appsrc_eos, diff --git a/validate/gst/validate/gst-validate-scenario.h b/validate/gst/validate/gst-validate-scenario.h index 39ac4886e2..963c517d37 100644 --- a/validate/gst/validate/gst-validate-scenario.h +++ b/validate/gst/validate/gst-validate-scenario.h @@ -126,6 +126,8 @@ GstValidateAction * gst_validate_action_new (GstValidateScenario * sc GstStructure *structure, gboolean add_to_lists); GST_VALIDATE_API +void gst_validate_action_ref (GstValidateAction * action); +GST_VALIDATE_API void gst_validate_action_unref (GstValidateAction * action); #define GST_TYPE_VALIDATE_ACTION (gst_validate_action_get_type ())