validate: Add an option to print all avalaible actions with details

+ Cleanup actions descriptions
+ Make GstValidateActionType internal only and only expose the structure
This commit is contained in:
Thibault Saunier 2014-08-13 23:07:47 +02:00 committed by Thibault Saunier
parent 45e6d86c92
commit d29a8e4a77
7 changed files with 204 additions and 68 deletions

View file

@ -26,6 +26,28 @@
GST_DEBUG_CATEGORY_EXTERN (gstvalidate_debug); GST_DEBUG_CATEGORY_EXTERN (gstvalidate_debug);
#define GST_CAT_DEFAULT gstvalidate_debug #define GST_CAT_DEFAULT gstvalidate_debug
typedef struct _GstValidateScenario GstValidateScenario;
typedef struct _GstValidateAction GstValidateAction;
typedef gboolean (*GstValidateExecuteAction) (GstValidateScenario * scenario, GstValidateAction * action);
struct _GstValidateActionType
{
GstMiniObject mini_object;
gchar *name;
GstValidateExecuteAction execute;
gchar **mandatory_fields;
gchar **option_fields;
gchar *description;
gboolean is_config;
gpointer _gst_reserved[GST_PADDING_LARGE];
};
void init_scenarios (void); void init_scenarios (void);
#endif #endif

View file

@ -44,7 +44,7 @@ static GHashTable *_gst_validate_issues = NULL;
static FILE **log_files = NULL; static FILE **log_files = NULL;
#ifndef GST_DISABLE_GST_DEBUG #ifndef GST_DISABLE_GST_DEBUG
static GRegex *regex = NULL; static GRegex *newline_regex = NULL;
#endif #endif
GST_DEBUG_CATEGORY_STATIC (gst_validate_report_debug); GST_DEBUG_CATEGORY_STATIC (gst_validate_report_debug);
@ -309,7 +309,9 @@ gst_validate_report_init (void)
} }
#ifndef GST_DISABLE_GST_DEBUG #ifndef GST_DISABLE_GST_DEBUG
regex = g_regex_new ("\n", G_REGEX_OPTIMIZE | G_REGEX_MULTILINE, 0, NULL); if (!newline_regex)
newline_regex =
g_regex_new ("\n", G_REGEX_OPTIMIZE | G_REGEX_MULTILINE, 0, NULL);
#endif #endif
} }
@ -470,6 +472,42 @@ gst_validate_printf_valist (gpointer source, const gchar * format, va_list args)
" repeat: %i) | ", g_strcmp0 (action->name, " repeat: %i) | ", g_strcmp0 (action->name,
"") == 0 ? "Unnamed" : action->name, action->action_number, "") == 0 ? "Unnamed" : action->name, action->action_number,
GST_TIME_ARGS (action->playback_time), action->repeat); GST_TIME_ARGS (action->playback_time), action->repeat);
} else if (*(GType *) source == GST_TYPE_VALIDATE_ACTION_TYPE) {
gint i;
gchar *desc, *tmp;
GstValidateActionType *type = GST_VALIDATE_ACTION_TYPE (source);
g_string_printf (string, "\n%s Action type:", type->name);
g_string_append_printf (string, "\n%s Name: %s", type->name,
type->name);
if (type->is_config)
g_string_append_printf (string,
"\n%s Is config action (meaning it will be executing right "
"at the begining of the execution of the pipeline)", type->name);
tmp = g_strdup_printf ("\n%s ", type->name);
desc =
g_regex_replace (newline_regex, type->description, -1, 0, tmp, 0,
NULL);
g_string_append_printf (string, "\n%s Description: \n%s %s",
type->name, type->name, desc);
g_free (desc);
g_free (tmp);
if (type->mandatory_fields) {
g_string_append_printf (string, "\n%s Mandatory fileds:",
type->name);
for (i = 0; type->mandatory_fields[i]; i++)
g_string_append_printf (string,
"\n%s %s", type->name, type->mandatory_fields[i]);
} else {
g_string_append_printf (string, "\n%s No mandatory field",
type->name);
}
} else if (GST_IS_OBJECT (source)) { } else if (GST_IS_OBJECT (source)) {
g_string_printf (string, "\n%s --> ", GST_OBJECT_NAME (source)); g_string_printf (string, "\n%s --> ", GST_OBJECT_NAME (source));
} else if (G_IS_OBJECT (source)) { } else if (G_IS_OBJECT (source)) {
@ -482,7 +520,13 @@ gst_validate_printf_valist (gpointer source, const gchar * format, va_list args)
#ifndef GST_DISABLE_GST_DEBUG #ifndef GST_DISABLE_GST_DEBUG
{ {
gchar *str = g_regex_replace (regex, string->str, string->len, 0, gchar *str;
if (!newline_regex)
newline_regex =
g_regex_new ("\n", G_REGEX_OPTIMIZE | G_REGEX_MULTILINE, 0, NULL);
str = g_regex_replace (newline_regex, string->str, string->len, 0,
"", 0, NULL); "", 0, NULL);
if (source) if (source)

View file

@ -187,6 +187,7 @@ _action_type_free (GstValidateActionType * type)
{ {
g_strfreev (type->mandatory_fields); g_strfreev (type->mandatory_fields);
g_free (type->description); g_free (type->description);
g_free (type->name);
} }
static void static void
@ -1856,6 +1857,7 @@ gst_validate_add_action_type (const gchar * type_name,
g_free, (GDestroyNotify) _free_action_type); g_free, (GDestroyNotify) _free_action_type);
type->execute = function; type->execute = function;
type->name = g_strdup (type_name);
type->mandatory_fields = g_strdupv ((gchar **) mandatory_fields); type->mandatory_fields = g_strdupv ((gchar **) mandatory_fields);
type->description = g_strdup (description); type->description = g_strdup (description);
type->is_config = is_config; type->is_config = is_config;
@ -1863,6 +1865,50 @@ gst_validate_add_action_type (const gchar * type_name,
g_hash_table_insert (action_types_table, g_strdup (type_name), type); g_hash_table_insert (action_types_table, g_strdup (type_name), type);
} }
static GList *
gst_validate_list_action_types (void)
{
if (action_types_table)
return g_hash_table_get_values (action_types_table);
return NULL;
}
gboolean
gst_validate_print_action_types (gchar ** wanted_types, gint num_wanted_types)
{
GList *tmp;
gint nfound;
for (tmp = gst_validate_list_action_types (); tmp; tmp = tmp->next) {
gboolean print = FALSE;
if (num_wanted_types) {
gint n;
for (n = 0; n < num_wanted_types; n++) {
if (g_strcmp0 (((GstValidateActionType *) tmp->data)->name,
wanted_types[n]) == 0) {
nfound++;
print = TRUE;
break;
}
}
} else {
print = TRUE;
}
if (print)
gst_validate_printf (tmp->data, "\n");
}
if (num_wanted_types && num_wanted_types != nfound) {
return FALSE;
}
return TRUE;
}
void void
init_scenarios (void) init_scenarios (void)
@ -1885,43 +1931,47 @@ init_scenarios (void)
clean_action_str = g_regex_new ("\\\\\n|#.*\n", G_REGEX_CASELESS, 0, NULL); clean_action_str = g_regex_new ("\\\\\n|#.*\n", G_REGEX_CASELESS, 0, NULL);
gst_validate_add_action_type ("seek", _execute_seek, seek_mandatory_fields, gst_validate_add_action_type ("seek", _execute_seek, seek_mandatory_fields,
"Allows to seek into the files", FALSE); "Seeks into the files", FALSE);
gst_validate_add_action_type ("pause", _execute_pause, NULL, gst_validate_add_action_type ("pause", _execute_pause, NULL,
"Make it possible to set pipeline to PAUSED, you can add a duration" "Sets pipeline to PAUSED. You can add a 'duration'\n"
" parametter so the pipeline goaes back to playing after that duration" "parametter so the pipeline goaes back to playing after that duration\n"
" (in second)", FALSE); "(in second)", FALSE);
gst_validate_add_action_type ("play", _execute_play, NULL, gst_validate_add_action_type ("play", _execute_play, NULL,
"Make it possible to set the pipeline state to PLAYING", FALSE); "Sets the pipeline state to PLAYING", FALSE);
gst_validate_add_action_type ("stop", _execute_stop, NULL, gst_validate_add_action_type ("stop", _execute_stop, NULL,
"Make it possible to set the pipeline state to NULL", FALSE); "Sets the pipeline state to NULL", FALSE);
gst_validate_add_action_type ("eos", _execute_eos, NULL, gst_validate_add_action_type ("eos", _execute_eos, NULL,
"Make it possible to send an EOS to the pipeline", FALSE); "Sends an EOS event to the pipeline", FALSE);
gst_validate_add_action_type ("switch-track", _execute_switch_track, NULL, gst_validate_add_action_type ("switch-track", _execute_switch_track, NULL,
"The 'switch-track' command can be used to switch tracks.\n" "The 'switch-track' command can be used to switch tracks.\n"
"The 'type' argument selects which track type to change (can be 'audio', 'video'," "The 'type' argument selects which track type to change (can be 'audio', 'video',"
" or 'text'). The 'index' argument selects which track of this type" " or 'text').\nThe 'index' argument selects which track of this type\n"
" to use: it can be either a number, which will be the Nth track of" "to use: it can be either a number, which will be the Nth track of\n"
" the given type, or a number with a '+' or '-' prefix, which means" "the given type, or a number with a '+' or '-' prefix, which means\n"
" a relative change (eg, '+1' means 'next track', '-1' means 'previous" "a relative change (eg, '+1' means 'next track', '-1' means 'previous\n"
" track'), note that you need to state that it is a string in the scenario file" "track'), note that you need to state that it is a string in the scenario file\n"
" prefixing it with (string).", FALSE); "prefixing it with (string).", FALSE);
gst_validate_add_action_type ("wait", _execute_wait, wait_mandatory_fields, gst_validate_add_action_type ("wait", _execute_wait, wait_mandatory_fields,
"Action to wait during 'duration' seconds", FALSE); "Waits during 'duration' seconds", FALSE);
gst_validate_add_action_type ("dot-pipeline", _execute_dot_pipeline, NULL, gst_validate_add_action_type ("dot-pipeline", _execute_dot_pipeline, NULL,
"Action to wait dot the pipeline (the 'name' property will be included in the" "Dots the pipeline (the 'name' property will be used in the\n"
" dot filename. Also the GST_DEBUG_DUMP_DOT_DIR env variable needs to be set", "dot filename).\n"
"For more information have a look at the GST_DEBUG_BIN_TO_DOT_FILE documentation."
"Note that the GST_DEBUG_DUMP_DOT_DIR env variable needs to be set\n",
FALSE); FALSE);
gst_validate_add_action_type ("set-feature-rank", _set_rank, NULL, gst_validate_add_action_type ("set-feature-rank", _set_rank, NULL,
"Allows you to change the ranking of a particular plugin feature", TRUE); "Changes the ranking of a particular plugin feature", TRUE);
gst_validate_add_action_type ("set-state", _execute_set_state, gst_validate_add_action_type ("set-state", _execute_set_state,
set_state_mandatory_fields, set_state_mandatory_fields,
"Allows to change the state of the pipeline to any GstState", FALSE); "Change the state of the pipeline to any GstState as a string like:\n"
" * 'null'\n"
" * 'ready'\n" " * 'paused'\n" " * 'play'\n", FALSE);
gst_validate_add_action_type ("set-property", _execute_set_property, gst_validate_add_action_type ("set-property", _execute_set_property,
set_property_mandatory_fields, set_property_mandatory_fields,
"Allows to set a property of any element in the pipeline", FALSE); "Sets a property of any element in the pipeline", FALSE);
gst_validate_add_action_type ("set-debug-threshold", gst_validate_add_action_type ("set-debug-threshold",
_execute_set_debug_threshold, set_debug_threshold_mandatory_fields, _execute_set_debug_threshold, set_debug_threshold_mandatory_fields,
"Sets the debug level to be used, same format as " "Sets the debug level to be used, same format as\n"
"setting the GST_DEBUG env variable", FALSE); "setting the GST_DEBUG env variable", FALSE);
gst_validate_add_action_type ("emit-signal", _execute_emit_signal, gst_validate_add_action_type ("emit-signal", _execute_emit_signal,
emit_signal_mandatory_fields, emit_signal_mandatory_fields,

View file

@ -65,25 +65,12 @@ struct _GstValidateAction
#define GST_IS_VALIDATE_ACTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_VALIDATE_ACTION)) #define GST_IS_VALIDATE_ACTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_VALIDATE_ACTION))
GType gst_validate_action_get_type (void); GType gst_validate_action_get_type (void);
struct _GstValidateActionType
{
GstMiniObject mini_object;
GstValidateExecuteAction execute;
gchar **mandatory_fields;
gchar **option_fields;
gchar *description;
gboolean is_config;
gpointer _gst_reserved[GST_PADDING_LARGE];
};
#define GST_TYPE_VALIDATE_ACTION_TYPE (gst_validate_action_type_get_type ()) #define GST_TYPE_VALIDATE_ACTION_TYPE (gst_validate_action_type_get_type ())
#define GST_IS_VALIDATE_ACTION_TYPE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_VALIDATE_ACTION_TYPE)) #define GST_IS_VALIDATE_ACTION_TYPE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_VALIDATE_ACTION_TYPE))
GType gst_validate_action_type_get_type (void); #define GST_VALIDATE_ACTION_TYPE(obj) ((GstValidateActionType*) obj)
GType gst_validate_action_type_get_type (void);
gboolean gst_validate_print_action_types (gchar ** wanted_types, gint num_wanted_types);
struct _GstValidateScenarioClass struct _GstValidateScenarioClass
{ {

View file

@ -36,12 +36,12 @@ gst_validate_init (void)
GST_DEBUG_CATEGORY_INIT (gstvalidate_debug, "validate", 0, GST_DEBUG_CATEGORY_INIT (gstvalidate_debug, "validate", 0,
"Validation library"); "Validation library");
/* Init the scenario system */
init_scenarios ();
/* init the report system (can be called multiple times) */ /* init the report system (can be called multiple times) */
gst_validate_report_init (); gst_validate_report_init ();
/* Init the scenario system */
init_scenarios ();
/* Ensure we load overrides before any use of a monitor */ /* Ensure we load overrides before any use of a monitor */
gst_validate_override_registry_preload (); gst_validate_override_registry_preload ();
} }

View file

@ -733,7 +733,7 @@ main (int argc, gchar ** argv)
GError *err = NULL; GError *err = NULL;
const gchar *scenario = NULL, *configs = NULL; const gchar *scenario = NULL, *configs = NULL;
gboolean want_help = FALSE; gboolean want_help = FALSE;
gboolean list_scenarios = FALSE; gboolean list_scenarios = FALSE, list_action_types = FALSE;
GOptionEntry options[] = { GOptionEntry options[] = {
{"output-format", 'o', 0, G_OPTION_ARG_CALLBACK, &_parse_encoding_profile, {"output-format", 'o', 0, G_OPTION_ARG_CALLBACK, &_parse_encoding_profile,
@ -760,6 +760,8 @@ main (int argc, gchar ** argv)
"exiting.", NULL}, "exiting.", NULL},
{"list-scenarios", 'l', 0, G_OPTION_ARG_NONE, &list_scenarios, {"list-scenarios", 'l', 0, G_OPTION_ARG_NONE, &list_scenarios,
"List the avalaible scenarios that can be run", NULL}, "List the avalaible scenarios that can be run", NULL},
{"list-action-types", 't', 0, G_OPTION_ARG_NONE, &list_action_types,
"List the avalaible action types with which to write scenarios", NULL},
{"scenarios-defs-output-file", '\0', 0, G_OPTION_ARG_FILENAME, {"scenarios-defs-output-file", '\0', 0, G_OPTION_ARG_FILENAME,
&output_file, "The output file to store scenarios details. " &output_file, "The output file to store scenarios details. "
"Implies --list-scenario", "Implies --list-scenario",
@ -822,6 +824,14 @@ main (int argc, gchar ** argv)
_register_actions (); _register_actions ();
if (list_action_types) {
if (gst_validate_print_action_types (argv + 1, argc - 1))
return 0;
return -1;
}
if (argc != 3) { if (argc != 3) {
g_printerr ("%i arguments recived, 2 expected.\n" g_printerr ("%i arguments recived, 2 expected.\n"
"You should run the test using:\n" "You should run the test using:\n"

View file

@ -300,12 +300,45 @@ _execute_switch_track (GstValidateScenario * scenario,
return TRUE; return TRUE;
} }
static void
_register_playbin_actions (void)
{
/* *INDENT-OFF* */
gst_validate_add_action_type ("set-subtitle", _execute_set_subtitles,
(GstValidateActionParameter [])
{
{"subtitle-file", "", TRUE}
, {NULL}
},
"Action to set a subtitle file to use on a playbin pipeline.\n"
"The subtitles file that will be used should will be specified\n"
"relatively to the playbin URI in use thanks to the subtitle-file\n"
"action property. You can also specify a folder with subtitle-dir\n"
"For example if playbin.uri='file://some/uri.mov\n"
"and action looks like 'set-subtitle, subtitle-file=en.srt'\n"
"the subtitle URI will be set to 'file:///some/uri.mov.en.srt'\n",
FALSE);
/* Overriding default implementation */
gst_validate_add_action_type ("switch-track", _execute_switch_track, NULL,
"The 'switch-track' command can be used to switch tracks.\n"
"The 'type' argument selects which track type to change (can be 'audio', 'video',"
" or 'text').\nThe 'index' argument selects which track of this type\n"
"to use: it can be either a number, which will be the Nth track of\n"
"the given type, or a number with a '+' or '-' prefix, which means\n"
"a relative change (eg, '+1' means 'next track', '-1' means 'previous\n"
"track'), note that you need to state that it is a string in the scenario file\n"
"prefixing it with (string).", FALSE);
/* *INDENT-ON* */
}
int int
main (int argc, gchar ** argv) main (int argc, gchar ** argv)
{ {
GError *err = NULL; GError *err = NULL;
const gchar *scenario = NULL, *configs = NULL; const gchar *scenario = NULL, *configs = NULL;
gboolean list_scenarios = FALSE, monitor_handles_state; gboolean list_scenarios = FALSE, monitor_handles_state,
list_action_types = FALSE;
GstStateChangeReturn sret; GstStateChangeReturn sret;
gchar *output_file = NULL; gchar *output_file = NULL;
gint ret = 0; gint ret = 0;
@ -325,6 +358,8 @@ main (int argc, gchar ** argv)
&output_file, "The output file to store scenarios details. " &output_file, "The output file to store scenarios details. "
"Implies --list-scenario", "Implies --list-scenario",
NULL}, NULL},
{"list-action-types", 't', 0, G_OPTION_ARG_NONE, &list_action_types,
"List the avalaible action types with which to write scenarios", NULL},
{"set-configs", '\0', 0, G_OPTION_ARG_STRING, &configs, {"set-configs", '\0', 0, G_OPTION_ARG_STRING, &configs,
"Let you set a config scenario, the scenario needs to be set as 'config" "Let you set a config scenario, the scenario needs to be set as 'config"
"' you can specify a list of scenario separated by ':'" "' you can specify a list of scenario separated by ':'"
@ -380,6 +415,17 @@ main (int argc, gchar ** argv)
return 0; return 0;
} }
if (list_action_types) {
_register_playbin_actions ();
if (!gst_validate_print_action_types (argv + 1, argc - 1)) {
GST_ERROR ("Could not print all wanted types");
return -1;
}
return 0;
}
if (argc == 1) { if (argc == 1) {
g_print ("%s", g_option_context_get_help (ctx, FALSE, NULL)); g_print ("%s", g_option_context_get_help (ctx, FALSE, NULL));
g_option_context_free (ctx); g_option_context_free (ctx);
@ -413,30 +459,7 @@ main (int argc, gchar ** argv)
#endif #endif
if (_is_playbin_pipeline (argc, argv + 1)) { if (_is_playbin_pipeline (argc, argv + 1)) {
const gchar *sub_mandatory_fields[] = { "subtitle-file", NULL }; _register_playbin_actions ();
gst_validate_add_action_type ("set-subtitle", _execute_set_subtitles,
sub_mandatory_fields,
"Action to wait set the subtitle file to use on a playbin pipeline. "
"The subtitles file that will be use should will be specified "
"relatively to the playbin URI in use thanks to the subtitle-file "
" action property. You can also specify a folder with subtitle-dir\n"
"For example if playbin.uri='file://some/uri.mov"
" and action looks like 'set-subtitle, subtitle-file=en.srt'"
" the subtitle URI will be set to 'file:///some/uri.mov.en.srt'",
FALSE);
/* Overriding default implementation */
gst_validate_add_action_type ("switch-track", _execute_switch_track, NULL,
"The 'switch-track' command can be used to switch tracks.\n"
"The 'type' argument selects which track type to change (can be 'audio', 'video',"
" or 'text'). The 'index' argument selects which track of this type"
" to use: it can be either a number, which will be the Nth track of"
" the given type, or a number with a '+' or '-' prefix, which means"
" a relative change (eg, '+1' means 'next track', '-1' means 'previous"
" track'), note that you need to state that it is a string in the scenario file"
" prefixing it with (string). You can also disable the track type"
" setting the 'disable' field (to anything)", FALSE);
} }
runner = gst_validate_runner_new (); runner = gst_validate_runner_new ();