From 5069e0347cc40fd2a4673cc1c7b68b9d10e667fd Mon Sep 17 00:00:00 2001 From: Thibault Saunier Date: Sat, 13 Dec 2014 23:16:27 +0100 Subject: [PATCH] validate:scenario; Advertise action types that will be executed on addition Adding a flag to the action type And make that code thread safe. https://bugzilla.gnome.org/show_bug.cgi?id=743994 --- validate/gst/validate/gst-validate-scenario.c | 61 ++++++++++++++----- validate/gst/validate/gst-validate-scenario.h | 4 ++ 2 files changed, 51 insertions(+), 14 deletions(-) diff --git a/validate/gst/validate/gst-validate-scenario.c b/validate/gst/validate/gst-validate-scenario.c index e15f6727cb..be27a282f9 100644 --- a/validate/gst/validate/gst-validate-scenario.c +++ b/validate/gst/validate/gst-validate-scenario.c @@ -96,6 +96,8 @@ struct _GstValidateScenarioPrivate GList *actions; GList *interlaced_actions; + GList *on_addition_actions; + /* List of action that need parsing when reaching ASYNC_DONE * most probably to be able to query duration */ GList *needs_parsing; @@ -306,6 +308,20 @@ _set_variable_func (const gchar * name, double *value, gpointer user_data) return FALSE; } +static void +_check_scenario_is_done (GstValidateScenario * scenario) +{ + SCENARIO_LOCK (scenario); + if (!scenario->priv->actions && !scenario->priv->interlaced_actions + && !scenario->priv->on_addition_actions) { + SCENARIO_UNLOCK (scenario); + + g_signal_emit (scenario, scenario_signals[DONE], 0); + } else { + SCENARIO_UNLOCK (scenario); + } +} + /** * gst_validate_action_get_clocktime: * @scenario: The #GstValidateScenario from which to get a time @@ -971,7 +987,7 @@ get_position (GstValidateScenario * scenario) if (scenario->priv->actions) { act = scenario->priv->actions->data; } else { - g_signal_emit (scenario, scenario_signals[DONE], 0); + _check_scenario_is_done (scenario); act = NULL; } } else if (act->state == GST_VALIDATE_EXECUTE_ACTION_ASYNC) { @@ -1062,7 +1078,7 @@ get_position (GstValidateScenario * scenario) } if (priv->actions == NULL) - g_signal_emit (scenario, scenario_signals[DONE], 0); + _check_scenario_is_done (scenario); g_list_free (tmp); @@ -1401,12 +1417,14 @@ message_cb (GstBus * bus, GstMessage * message, GstValidateScenario * scenario) case GST_MESSAGE_EOS: { SCENARIO_LOCK (scenario); - if (scenario->priv->actions || scenario->priv->interlaced_actions) { - GList *tmp; + if (scenario->priv->actions || scenario->priv->interlaced_actions || + scenario->priv->on_addition_actions) { guint nb_actions = 0; gchar *actions = g_strdup (""), *tmpconcat; - GList *all_actions = g_list_concat (scenario->priv->actions, + GList *tmp = g_list_concat (scenario->priv->actions, scenario->priv->interlaced_actions); + GList *all_actions = + g_list_concat (tmp, scenario->priv->on_addition_actions); for (tmp = all_actions; tmp; tmp = tmp->next) { GstValidateAction *action = ((GstValidateAction *) tmp->data); @@ -1561,8 +1579,20 @@ _load_scenario_file (GstValidateScenario * scenario, } action->action_number = priv->num_actions++; - if (str_playback_time == NULL) - priv->actions = g_list_append (priv->actions, action); + if (str_playback_time == NULL) { + GstValidateActionType *type = _find_action_type (action->type); + + if (type->flags & GST_VALIDATE_ACTION_TYPE_CAN_EXECUTE_ON_ADDITION + && !GST_CLOCK_TIME_IS_VALID (action->playback_time)) { + SCENARIO_LOCK (scenario); + priv->on_addition_actions = g_list_append (priv->on_addition_actions, + action); + SCENARIO_UNLOCK (scenario); + + } else { + priv->actions = g_list_append (priv->actions, action); + } + } } done: @@ -1810,11 +1840,13 @@ static void _element_added_cb (GstBin * bin, GstElement * element, GstValidateScenario * scenario) { - GstValidateScenarioPrivate *priv = scenario->priv; GList *tmp; + GstValidateScenarioPrivate *priv = scenario->priv; + /* Check if it's an element we track for a set-property action */ - tmp = priv->actions; + SCENARIO_LOCK (scenario); + tmp = priv->on_addition_actions; while (tmp) { GstValidateAction *action = (GstValidateAction *) tmp->data; const gchar *name; @@ -1832,18 +1864,19 @@ _element_added_cb (GstBin * bin, GstElement * element, action_type = _find_action_type (action->type); GST_DEBUG_OBJECT (element, "Executing set-property action"); if (action_type->execute (scenario, action)) { - priv->actions = g_list_remove_link (priv->actions, tmp); + priv->on_addition_actions = + g_list_remove_link (priv->on_addition_actions, tmp); gst_mini_object_unref (GST_MINI_OBJECT (action)); g_list_free (tmp); - tmp = priv->actions; + tmp = priv->on_addition_actions; } else tmp = tmp->next; } else tmp = tmp->next; } + SCENARIO_UNLOCK (scenario); - if (priv->actions == NULL) - g_signal_emit (scenario, scenario_signals[DONE], 0); + _check_scenario_is_done (scenario); /* If it's a bin, listen to the child */ if (GST_IS_BIN (element)) { @@ -2532,7 +2565,7 @@ init_scenarios (void) {NULL} }), "Sets a property of any element in the pipeline", - GST_VALIDATE_ACTION_TYPE_NONE); + GST_VALIDATE_ACTION_TYPE_CAN_EXECUTE_ON_ADDITION); REGISTER_ACTION_TYPE ("set-debug-threshold", _execute_set_debug_threshold, diff --git a/validate/gst/validate/gst-validate-scenario.h b/validate/gst/validate/gst-validate-scenario.h index 778aef4cf1..97f5fa45cb 100644 --- a/validate/gst/validate/gst-validate-scenario.h +++ b/validate/gst/validate/gst-validate-scenario.h @@ -113,6 +113,9 @@ typedef struct _GstValidateActionType GstValidateActionType; * @GST_VALIDATE_ACTION_TYPE_INTERLACED: The action will be executed async * but without blocking further actions * to be executed + * @GST_VALIDATE_ACTION_TYPE_CAN_EXECUTE_ON_ADDITION: The action will be executed on 'element-added' + * for a particular element type if no playback-time + * is specified * @GST_VALIDATE_ACTION_TYPE_NEEDS_CLOCK: The pipeline will need to be synchronized with the clock * for that action type to be used. */ @@ -122,6 +125,7 @@ typedef enum GST_VALIDATE_ACTION_TYPE_CONFIG = 1 << 1, GST_VALIDATE_ACTION_TYPE_ASYNC = 1 << 2, GST_VALIDATE_ACTION_TYPE_INTERLACED = 1 << 3, + GST_VALIDATE_ACTION_TYPE_CAN_EXECUTE_ON_ADDITION = 1 << 4, GST_VALIDATE_ACTION_TYPE_NEEDS_CLOCK = 1 << 5, } GstValidateActionTypeFlags;