mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-10 03:19:40 +00:00
validate: Print actions directly from the scenario
Avoiding user to have to print them in each and every action type implementation. This requires adding some API to prepare actions before printing them. Preparing action in that case mean parsing the values contained in the GstStructure parsing equations and setting back the actual value afterward API: * GstValidatePrepateAction * gst_validate_action_type_set_prepare_function
This commit is contained in:
parent
8b6c521bb1
commit
08afce235c
3 changed files with 115 additions and 36 deletions
|
@ -506,6 +506,27 @@ gst_validate_printf (gpointer source, const gchar * format, ...)
|
|||
va_end (var_args);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
_append_value (GQuark field_id, const GValue * value, GString * string)
|
||||
{
|
||||
gchar *val_str = NULL;
|
||||
|
||||
if (G_VALUE_TYPE (value) == GST_TYPE_CLOCK_TIME)
|
||||
val_str = g_strdup_printf ("%" GST_TIME_FORMAT,
|
||||
GST_TIME_ARGS (g_value_get_uint64 (value)));
|
||||
else
|
||||
val_str = gst_value_serialize (value);
|
||||
|
||||
g_string_append (string, g_quark_to_string (field_id));
|
||||
g_string_append_len (string, "=", 1);
|
||||
g_string_append (string, val_str);
|
||||
g_string_append_len (string, " ", 1);
|
||||
|
||||
g_free (val_str);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* gst_validate_print_action:
|
||||
* @action: (allow-none): The source object to log
|
||||
|
@ -516,7 +537,22 @@ gst_validate_printf (gpointer source, const gchar * format, ...)
|
|||
void
|
||||
gst_validate_print_action (GstValidateAction * action, const gchar * message)
|
||||
{
|
||||
GString *string = NULL;
|
||||
|
||||
if (message == NULL) {
|
||||
GString *string = g_string_new (gst_structure_get_name (action->structure));
|
||||
|
||||
g_string_append_len (string, ": ", 2);
|
||||
gst_structure_foreach (action->structure,
|
||||
(GstStructureForeachFunc) _append_value, string);
|
||||
g_string_append_len (string, "\n", 1);
|
||||
message = string->str;
|
||||
}
|
||||
|
||||
gst_validate_printf (action, "%s", message);
|
||||
|
||||
if (string)
|
||||
g_string_free (string, TRUE);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -589,11 +625,11 @@ gst_validate_printf_valist (gpointer source, const gchar * format, va_list args)
|
|||
if (*(GType *) source == GST_TYPE_VALIDATE_ACTION) {
|
||||
GstValidateAction *action = (GstValidateAction *) source;
|
||||
|
||||
g_string_printf (string,
|
||||
"\n(Executing action: %s, number: %u at position: %" GST_TIME_FORMAT
|
||||
" repeat: %i) | ", g_strcmp0 (action->name,
|
||||
"") == 0 ? "Unnamed" : action->name, action->action_number,
|
||||
GST_TIME_ARGS (action->playback_time), action->repeat);
|
||||
if (action->printed)
|
||||
return;
|
||||
|
||||
action->printed = TRUE;
|
||||
g_string_printf (string, "Executing ");
|
||||
|
||||
} else if (*(GType *) source == GST_TYPE_VALIDATE_ACTION_TYPE) {
|
||||
gint i;
|
||||
|
|
|
@ -368,13 +368,24 @@ gst_validate_action_get_clocktime (GstValidateScenario * scenario,
|
|||
{
|
||||
gdouble val;
|
||||
const gchar *strval;
|
||||
const GValue *gvalue = gst_structure_get_value (action->structure, name);
|
||||
|
||||
if (gvalue == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (G_VALUE_TYPE (gvalue) == GST_TYPE_CLOCK_TIME) {
|
||||
*retval = g_value_get_uint64 (gvalue);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (!gst_structure_get_double (action->structure, name, &val)) {
|
||||
gchar *error = NULL;
|
||||
|
||||
if (!(strval = gst_structure_get_string (action->structure, name))) {
|
||||
GST_INFO_OBJECT (scenario, "Could not find %s", name);
|
||||
return FALSE;
|
||||
return -1;
|
||||
}
|
||||
val =
|
||||
gst_validate_utils_parse_expression (strval, _set_variable_func,
|
||||
|
@ -482,10 +493,6 @@ _execute_seek (GstValidateScenario * scenario, GstValidateAction * action)
|
|||
|
||||
gst_validate_action_get_clocktime (scenario, action, "stop", &stop);
|
||||
|
||||
gst_validate_printf (action, "seeking to: %" GST_TIME_FORMAT
|
||||
" stop: %" GST_TIME_FORMAT " Rate %lf\n",
|
||||
GST_TIME_ARGS (start), GST_TIME_ARGS (stop), rate);
|
||||
|
||||
return gst_validate_scenario_execute_seek (scenario, action, rate, format,
|
||||
flags, start_type, start, stop_type, stop);
|
||||
}
|
||||
|
@ -525,8 +532,6 @@ _execute_set_state (GstValidateScenario * scenario, GstValidateAction * action)
|
|||
scenario->priv->changing_state = TRUE;
|
||||
scenario->priv->seeked_in_pause = FALSE;
|
||||
|
||||
gst_validate_printf (action, "Setting state to %s\n", str_state);
|
||||
|
||||
ret = gst_element_set_state (scenario->pipeline, state);
|
||||
|
||||
if (ret == GST_STATE_CHANGE_FAILURE) {
|
||||
|
@ -553,9 +558,6 @@ _execute_pause (GstValidateScenario * scenario, GstValidateAction * action)
|
|||
GstStateChangeReturn ret;
|
||||
|
||||
gst_structure_get_double (action->structure, "duration", &duration);
|
||||
gst_validate_printf (action, "pausing for %" GST_TIME_FORMAT "\n",
|
||||
GST_TIME_ARGS (duration * GST_SECOND));
|
||||
|
||||
gst_structure_set (action->structure, "state", G_TYPE_STRING, "paused", NULL);
|
||||
|
||||
GST_DEBUG ("Pausing for %" GST_TIME_FORMAT,
|
||||
|
@ -606,8 +608,6 @@ _execute_stop (GstValidateScenario * scenario, GstValidateAction * action)
|
|||
{
|
||||
GstBus *bus = gst_element_get_bus (scenario->pipeline);
|
||||
|
||||
gst_validate_printf (action, "Stoping pipeline\n");
|
||||
|
||||
gst_bus_post (bus,
|
||||
gst_message_new_request_state (GST_OBJECT_CAST (scenario),
|
||||
GST_STATE_NULL));
|
||||
|
@ -618,9 +618,6 @@ _execute_stop (GstValidateScenario * scenario, GstValidateAction * action)
|
|||
static gboolean
|
||||
_execute_eos (GstValidateScenario * scenario, GstValidateAction * action)
|
||||
{
|
||||
gst_validate_printf (action, "sending EOS at %" GST_TIME_FORMAT "\n",
|
||||
GST_TIME_ARGS (action->playback_time));
|
||||
|
||||
GST_DEBUG ("Sending eos to pipeline at %" GST_TIME_FORMAT,
|
||||
GST_TIME_ARGS (action->playback_time));
|
||||
|
||||
|
@ -808,10 +805,6 @@ _execute_switch_track (GstValidateScenario * scenario,
|
|||
|
||||
pad = find_nth_sink_pad (input_selector, index);
|
||||
g_object_get (input_selector, "active-pad", &cpad, NULL);
|
||||
gst_validate_printf (action, "Switching to track number: %i,"
|
||||
" (from %s:%s to %s:%s)\n",
|
||||
index, GST_DEBUG_PAD_NAME (cpad), GST_DEBUG_PAD_NAME (pad));
|
||||
|
||||
if (gst_element_get_state (scenario->pipeline, &state, &next, 0) &&
|
||||
state == GST_STATE_PLAYING && next == GST_STATE_VOID_PENDING) {
|
||||
srcpad = gst_element_get_static_pad (input_selector, "src");
|
||||
|
@ -972,6 +965,17 @@ gst_validate_execute_action (GstValidateActionType * action_type,
|
|||
g_return_val_if_fail (g_strcmp0 (action_type->name, action->type) == 0,
|
||||
GST_VALIDATE_EXECUTE_ACTION_ERROR);
|
||||
|
||||
if (action_type->prepare) {
|
||||
if (action_type->prepare (action) == FALSE) {
|
||||
GST_ERROR_OBJECT (action->scenario, "Action %" GST_PTR_FORMAT
|
||||
" could not be prepared", action->structure);
|
||||
|
||||
return GST_VALIDATE_EXECUTE_ACTION_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
gst_validate_print_action (action, NULL);
|
||||
|
||||
res = action_type->execute (action->scenario, action);
|
||||
|
||||
if (!gst_structure_has_field (action->structure, "sub-action")) {
|
||||
|
@ -1212,9 +1216,6 @@ _execute_wait (GstValidateScenario * scenario, GstValidateAction * action)
|
|||
}
|
||||
|
||||
duration *= wait_multiplier;
|
||||
gst_validate_printf (action,
|
||||
"Waiting for %" GST_TIME_FORMAT " (wait_multiplier: %f)\n",
|
||||
GST_TIME_ARGS (duration), wait_multiplier);
|
||||
|
||||
SCENARIO_LOCK (scenario);
|
||||
if (priv->get_pos_id) {
|
||||
|
@ -1246,7 +1247,6 @@ _execute_dot_pipeline (GstValidateScenario * scenario,
|
|||
else
|
||||
dotname = g_strdup ("validate.action.unnamed");
|
||||
|
||||
gst_validate_printf (action, "Doting pipeline (name %s)\n", dotname);
|
||||
GST_DEBUG_BIN_TO_DOT_FILE_WITH_TS (GST_BIN (scenario->pipeline),
|
||||
details, dotname);
|
||||
|
||||
|
@ -1310,8 +1310,6 @@ _execute_set_property (GstValidateScenario * scenario,
|
|||
property_value = gst_structure_get_value (action->structure,
|
||||
"property-value");
|
||||
|
||||
gst_validate_printf (action, "Setting property %s to %s\n",
|
||||
property, gst_value_serialize (property_value));
|
||||
ret = _object_set_property (G_OBJECT (target), property, property_value);
|
||||
|
||||
gst_object_unref (target);
|
||||
|
@ -1340,11 +1338,6 @@ _execute_set_debug_threshold (GstValidateScenario * scenario,
|
|||
|
||||
gst_structure_get_boolean (action->structure, "reset", &reset);
|
||||
|
||||
gst_validate_printf (action,
|
||||
"%s -- Set debug threshold to '%s', %sreseting all\n",
|
||||
gst_structure_to_string (action->structure), threshold_str,
|
||||
reset ? "" : "NOT ");
|
||||
|
||||
gst_debug_set_threshold_from_string (threshold_str, reset);
|
||||
|
||||
if (str)
|
||||
|
@ -1443,6 +1436,36 @@ _set_action_playback_time (GstValidateScenario * scenario,
|
|||
return FALSE;
|
||||
}
|
||||
|
||||
gst_structure_set (action->structure, "playback-time", GST_TYPE_CLOCK_TIME,
|
||||
action->playback_time, NULL);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
gst_validate_action_default_prepare_func (GstValidateAction * action)
|
||||
{
|
||||
gulong i;
|
||||
GstClockTime time;
|
||||
const gchar *vars[] = { "duration", "start", "stop" };
|
||||
|
||||
for (i = 0; i < G_N_ELEMENTS (vars); i++) {
|
||||
gint res =
|
||||
gst_validate_action_get_clocktime (action->scenario, action, vars[i],
|
||||
&time);
|
||||
if (res == FALSE) {
|
||||
GST_ERROR_OBJECT (action->scenario, "Could not get clocktime for"
|
||||
" variable %s", vars[i]);
|
||||
|
||||
return FALSE;
|
||||
} else if (res == -1) {
|
||||
continue;
|
||||
}
|
||||
|
||||
gst_structure_set (action->structure, vars[i], GST_TYPE_CLOCK_TIME,
|
||||
time, NULL);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
@ -2446,6 +2469,7 @@ gst_validate_register_action_type_dynamic (GstPlugin * plugin,
|
|||
sizeof (GstValidateActionParameter) * (n_params));
|
||||
}
|
||||
|
||||
type->prepare = gst_validate_action_default_prepare_func;
|
||||
type->execute = function;
|
||||
type->name = g_strdup (type_name);
|
||||
if (plugin)
|
||||
|
|
|
@ -65,6 +65,19 @@ enum
|
|||
*/
|
||||
typedef GstValidateExecuteActionReturn (*GstValidateExecuteAction) (GstValidateScenario * scenario, GstValidateAction * action);
|
||||
|
||||
/**
|
||||
* GstValidatePrepareAction:
|
||||
* @action: The #GstValidateAction to prepare before execution
|
||||
*
|
||||
* A function that prepares @action so it can be executed right after.
|
||||
* Most of the time that function is used to parse and set field with
|
||||
* equations in the action structure.
|
||||
*
|
||||
* Returns: a %TRUE if the action could be prepared and is ready to be run
|
||||
* %FALSE otherwise
|
||||
*/
|
||||
typedef gboolean (*GstValidatePrepareAction) (GstValidateAction * action);
|
||||
|
||||
|
||||
/**
|
||||
* GstValidateAction:
|
||||
|
@ -92,8 +105,9 @@ struct _GstValidateAction
|
|||
gint repeat;
|
||||
GstClockTime playback_time;
|
||||
GstValidateExecuteActionReturn state; /* Actually ActionState */
|
||||
gboolean printed;
|
||||
|
||||
gpointer _gst_reserved[GST_PADDING_LARGE - sizeof (gint) - 2];
|
||||
gpointer _gst_reserved[GST_PADDING_LARGE - sizeof (gint) - 2 - sizeof(gboolean)];
|
||||
};
|
||||
|
||||
void gst_validate_action_set_done (GstValidateAction *action);
|
||||
|
@ -144,6 +158,7 @@ struct _GstValidateActionType
|
|||
gchar *name;
|
||||
gchar *implementer_namespace;
|
||||
|
||||
GstValidatePrepareAction prepare;
|
||||
GstValidateExecuteAction execute;
|
||||
|
||||
GstValidateActionParameter *parameters;
|
||||
|
@ -244,6 +259,10 @@ gst_validate_register_action_type (const gchar *type_name,
|
|||
const gchar *description,
|
||||
GstValidateActionTypeFlags flags);
|
||||
|
||||
void
|
||||
gst_validate_action_type_set_prepare_function (GstValidateActionType *type,
|
||||
GstValidatePrepareAction prepare_action);
|
||||
|
||||
GstValidateActionType *
|
||||
gst_validate_register_action_type_dynamic (GstPlugin *plugin,
|
||||
const gchar * type_name,
|
||||
|
|
Loading…
Reference in a new issue