summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThibault Saunier <tsaunier@igalia.com>2020-12-15 18:15:50 -0300
committerThibault Saunier <tsaunier@igalia.com>2020-12-16 22:00:37 -0300
commitf1de7c3a7fb813e7eec3ccee03f881368a662bea (patch)
tree20a24fbdda8c42ebc60baa5a571fc8d651030b58
parent9dfb2016a261de7e8ff307aa54887161eb8c7f91 (diff)
validate: Add an `expected-values` parameter to `wait, message-type=XX`
Allowing more precise filtering of the message we are waiting for. Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-devtools/-/merge_requests/233>
-rw-r--r--validate/gst/validate/gst-validate-scenario.c104
1 files changed, 87 insertions, 17 deletions
diff --git a/validate/gst/validate/gst-validate-scenario.c b/validate/gst/validate/gst-validate-scenario.c
index 154b7a0..950d266 100644
--- a/validate/gst/validate/gst-validate-scenario.c
+++ b/validate/gst/validate/gst-validate-scenario.c
@@ -242,7 +242,7 @@ struct _GstValidateScenarioPrivate
guint action_execution_interval;
/* Name of message the wait action is waiting for */
- const gchar *message_type;
+ GstValidateAction *wait_message_action;
gboolean buffering;
@@ -2152,7 +2152,7 @@ _add_execute_actions_gsource (GstValidateScenario * scenario)
SCENARIO_LOCK (scenario);
if (priv->execute_actions_source_id == 0 && priv->wait_id == 0
- && priv->signal_handler_id == 0 && priv->message_type == NULL) {
+ && priv->signal_handler_id == 0 && priv->wait_message_action == NULL) {
if (!scenario->priv->action_execution_interval)
priv->execute_actions_source_id =
g_idle_add ((GSourceFunc) execute_next_action, scenario);
@@ -2899,7 +2899,8 @@ _execute_wait_for_message (GstValidateScenario * scenario,
priv->execute_actions_source_id = 0;
}
- priv->message_type = g_strdup (message_type);
+ g_assert (!priv->wait_message_action);
+ priv->wait_message_action = gst_validate_action_ref (action);
gst_object_unref (pipeline);
return GST_VALIDATE_EXECUTE_ACTION_ASYNC;
@@ -3820,24 +3821,82 @@ gst_validate_foreach_prepare (GstValidateAction * action)
return GST_VALIDATE_EXECUTE_ACTION_DONE;
}
+static gboolean
+_check_structure_has_expected_value (GQuark field_id, const GValue * value,
+ GstStructure * message_struct)
+{
+ const GValue *v = gst_structure_id_get_value (message_struct, field_id);
+
+ if (!v) {
+ gst_structure_set (message_struct, "__validate_has_expected_values",
+ G_TYPE_BOOLEAN, FALSE, NULL);
+ return FALSE;
+ }
+
+ if (gst_value_compare (value, v) != GST_VALUE_EQUAL) {
+ gst_structure_set (message_struct, "__validate_has_expected_values",
+ G_TYPE_BOOLEAN, FALSE, NULL);
+ return FALSE;
+ }
+
+ gst_structure_set (message_struct, "__validate_has_expected_values",
+ G_TYPE_BOOLEAN, TRUE, NULL);
+
+ return TRUE;
+}
+
static void
_check_waiting_for_message (GstValidateScenario * scenario,
GstMessage * message)
{
+ GstStructure *expected_values = NULL;
GstValidateScenarioPrivate *priv = scenario->priv;
+ const gchar *message_type;
- if (!g_strcmp0 (priv->message_type,
- gst_message_type_get_name (GST_MESSAGE_TYPE (message)))) {
- GstValidateAction *action = scenario->priv->actions->data;
+ if (!priv->wait_message_action) {
+ GST_LOG_OBJECT (scenario, "Not waiting for message");
+ return;
+ }
- g_free ((gpointer) priv->message_type);
- priv->message_type = NULL;
+ message_type = gst_structure_get_string (priv->wait_message_action->structure,
+ "message-type");
- gst_validate_printf (scenario, "Stop waiting for message\n");
+ if (g_strcmp0 (message_type, GST_MESSAGE_TYPE_NAME (message)))
+ return;
- gst_validate_action_set_done (action);
- _add_execute_actions_gsource (scenario);
+ GST_LOG_OBJECT (scenario, " Waiting for %s and got %s", message_type,
+ GST_MESSAGE_TYPE_NAME (message));
+
+ gst_structure_get (priv->wait_message_action->structure, "expected-values",
+ GST_TYPE_STRUCTURE, &expected_values, NULL);
+ if (expected_values) {
+ gboolean res = FALSE;
+ GstStructure *message_struct =
+ (GstStructure *) gst_message_get_structure (message);
+
+ message_struct =
+ message_struct ? gst_structure_copy (message_struct) : NULL;
+ if (!message_struct) {
+ GST_DEBUG_OBJECT (scenario,
+ "Waiting for %" GST_PTR_FORMAT " but message has no structure.",
+ priv->wait_message_action->structure);
+ return;
+ }
+
+ gst_structure_set (message_struct, "__validate_has_expected_values",
+ G_TYPE_BOOLEAN, FALSE, NULL);
+ gst_structure_foreach (expected_values,
+ (GstStructureForeachFunc) _check_structure_has_expected_value,
+ message_struct);
+
+ if (!gst_structure_get_boolean (message_struct,
+ "__validate_has_expected_values", &res) || !res) {
+ return;
+ }
}
+
+ gst_validate_action_set_done (priv->wait_message_action);
+ _add_execute_actions_gsource (scenario);
}
static gboolean
@@ -4035,9 +4094,9 @@ handle_bus_message (MessageData * d)
if (!is_error) {
priv->got_eos = TRUE;
- if (priv->message_type) {
+ if (priv->wait_message_action) {
- if (priv->actions->next) {
+ if (priv->actions && priv->actions->next) {
GST_DEBUG_OBJECT (scenario,
"Waiting for a message and got a next action"
" to execute, letting it a chance!");
@@ -4184,8 +4243,7 @@ handle_bus_message (MessageData * d)
done:
gst_object_unref (pipeline);
/* Check if we got the message expected by a wait action */
- if (priv->message_type)
- _check_waiting_for_message (scenario, message);
+ _check_waiting_for_message (scenario, message);
execute_next_action_full (scenario, message);
@@ -5894,10 +5952,10 @@ void
gst_validate_action_set_done (GstValidateAction * action)
{
GMainContext *context = action->priv->context;
+ GstValidateScenario *scenario = gst_validate_action_get_scenario (action);
action->priv->context = NULL;
if (action->priv->state == GST_VALIDATE_EXECUTE_ACTION_NON_BLOCKING) {
- GstValidateScenario *scenario = gst_validate_action_get_scenario (action);
GList *item = NULL;
if (scenario) {
@@ -5907,7 +5965,6 @@ gst_validate_action_set_done (GstValidateAction * action)
g_list_delete_link (scenario->priv->non_blocking_running_actions,
item);
SCENARIO_UNLOCK (scenario);
- g_object_unref (scenario);
}
if (item)
@@ -5917,6 +5974,10 @@ gst_validate_action_set_done (GstValidateAction * action)
g_assert (!action->priv->pending_set_done);
action->priv->pending_set_done = TRUE;
+ if (scenario && scenario->priv->wait_message_action == action)
+ scenario->priv->wait_message_action = NULL;
+ gst_clear_object (&scenario);
+
g_main_context_invoke_full (action->priv->context,
G_PRIORITY_DEFAULT_IDLE,
(GSourceFunc) _action_set_done,
@@ -6534,6 +6595,15 @@ register_action_types (void)
NULL
},
{
+ .name = "expected-values",
+ .description = "Expected values in the message structure (valid only when "
+ "`message-type`). Example: "
+ "wait, on-client=true, message-type=buffering, expected-values=[values, buffer-percent=100]",
+ .mandatory = FALSE,
+ .types = "GstStructure",
+ NULL
+ },
+ {
.name = "on-clock",
.description = "Wait until the test clock get a new pending entry"
" see #gst_test_clock_wait_for_next_pending_id.",