mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-11-25 03:01:03 +00:00
validate: Allow overriding features rank early in testfiles meta
Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/7700>
This commit is contained in:
parent
f5b0f91d33
commit
2c88bbf07f
9 changed files with 151 additions and 12 deletions
|
@ -0,0 +1,16 @@
|
|||
The `features-rank` field is an array of structures that defines how to
|
||||
override `GstPluginFeature::rank` to ensure some features will be used,
|
||||
or at contrary won't be used.
|
||||
|
||||
For example:
|
||||
|
||||
``` yaml
|
||||
features-rank = {
|
||||
[mandatory, glvideomixer=9999],
|
||||
[optional, someoptionalfeature=0],
|
||||
},
|
||||
```
|
||||
|
||||
One could also use the `set-feature-rank` scenario action, but that
|
||||
happens after GStreamer or other components are initialized which might
|
||||
be a problem in some cases.
|
|
@ -64,6 +64,7 @@ G_GNUC_INTERNAL void gst_validate_deinit_runner (void);
|
|||
G_GNUC_INTERNAL void gst_validate_report_deinit (void);
|
||||
G_GNUC_INTERNAL gboolean gst_validate_send (JsonNode * root);
|
||||
G_GNUC_INTERNAL void gst_validate_set_test_file_globals (GstStructure* meta, const gchar* testfile, gboolean use_fakesinks);
|
||||
G_GNUC_INTERNAL gboolean gst_validate_structure_file_field_is_metadata (const GstIdStr *field_id);
|
||||
G_GNUC_INTERNAL gboolean gst_validate_get_test_file_scenario (GList** structs, const gchar** scenario_name, gchar** original_name);
|
||||
G_GNUC_INTERNAL GstValidateScenario* gst_validate_scenario_from_structs (GstValidateRunner* runner, GstElement* pipeline, GList* structures,
|
||||
const gchar* origin_file);
|
||||
|
|
|
@ -7698,6 +7698,9 @@ register_action_types (void)
|
|||
GBytes *meta_expected_issues_doc =
|
||||
g_resource_lookup_data (resource, "/validate/doc/meta-expected-issues.md",
|
||||
G_RESOURCE_LOOKUP_FLAGS_NONE, NULL);
|
||||
GBytes *meta_features_rank_doc =
|
||||
g_resource_lookup_data (resource, "/validate/doc/meta-features-rank.md",
|
||||
G_RESOURCE_LOOKUP_FLAGS_NONE, NULL);
|
||||
|
||||
/* *INDENT-OFF* */
|
||||
REGISTER_ACTION_TYPE ("meta", NULL,
|
||||
|
@ -7874,12 +7877,31 @@ register_action_types (void)
|
|||
.possible_variables = NULL,
|
||||
.def = "{}"
|
||||
},
|
||||
{
|
||||
.name="features-rank",
|
||||
.description=g_bytes_get_data (meta_features_rank_doc, NULL),
|
||||
.mandatory = FALSE,
|
||||
.types = "bool",
|
||||
.possible_variables = NULL,
|
||||
.def = "false"
|
||||
},
|
||||
{
|
||||
.name="monitor-all-pipelines",
|
||||
.description="This should only be used in `.validatetest` files, and allows forcing to monitor "
|
||||
"all pipelines instead of only the one the tools wanted to monitor, for example to "
|
||||
"use `validateflow` on auxilary pipelines",
|
||||
.mandatory = FALSE,
|
||||
.types = "bool",
|
||||
.possible_variables = NULL,
|
||||
.def = "false"
|
||||
},
|
||||
{NULL}
|
||||
}),
|
||||
"Scenario metadata.\n\nNOTE: it used to be called \"description\"",
|
||||
GST_VALIDATE_ACTION_TYPE_CONFIG);
|
||||
g_bytes_unref (meta_config_doc);
|
||||
g_bytes_unref (meta_expected_issues_doc);
|
||||
g_bytes_unref (meta_features_rank_doc);
|
||||
|
||||
REGISTER_ACTION_TYPE ("seek", _execute_seek,
|
||||
((GstValidateActionParameter []) {
|
||||
|
|
|
@ -1352,9 +1352,8 @@ done:
|
|||
g_clear_pointer (&match_info, g_match_info_free);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
_structure_set_variables (const GstIdStr * fieldname, GValue * value,
|
||||
ReplaceData * data)
|
||||
gboolean
|
||||
gst_validate_structure_file_field_is_metadata (const GstIdStr * fieldname)
|
||||
{
|
||||
static const gchar *skip_fields[] = {
|
||||
"__filename__",
|
||||
|
@ -1363,7 +1362,15 @@ _structure_set_variables (const GstIdStr * fieldname, GValue * value,
|
|||
NULL,
|
||||
};
|
||||
|
||||
if (fieldname && g_strv_contains (skip_fields, gst_id_str_as_str (fieldname)))
|
||||
return fieldname
|
||||
&& g_strv_contains (skip_fields, gst_id_str_as_str (fieldname));
|
||||
}
|
||||
|
||||
static gboolean
|
||||
_structure_set_variables (const GstIdStr * fieldname, GValue * value,
|
||||
ReplaceData * data)
|
||||
{
|
||||
if (gst_validate_structure_file_field_is_metadata (fieldname))
|
||||
return TRUE;
|
||||
|
||||
if (GST_VALUE_HOLDS_LIST (value)) {
|
||||
|
|
|
@ -93,6 +93,7 @@ GST_VALIDATE_API
|
|||
void gst_validate_structure_resolve_variables (gpointer source, GstStructure *structure, GstStructure *local_variables,
|
||||
GstValidateStructureResolveVariablesFlags flags);
|
||||
void gst_validate_structure_set_variables_from_struct_file(GstStructure* vars, const gchar* struct_file);
|
||||
GST_VALIDATE_API
|
||||
void gst_validate_set_globals(GstStructure* structure);
|
||||
GST_VALIDATE_API
|
||||
gboolean gst_validate_fail_on_missing_plugin(void);
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
* @short_description: Initialize GstValidate
|
||||
*/
|
||||
|
||||
#include "gst/gstidstr.h"
|
||||
#ifdef HAVE_CONFIG_H
|
||||
# include "config.h"
|
||||
#endif /* HAVE_CONFIG_H */
|
||||
|
@ -265,16 +266,23 @@ get_structures_from_array_in_meta (const gchar * fieldname)
|
|||
if (!meta)
|
||||
return NULL;
|
||||
|
||||
res = get_structures_from_array (meta, fieldname);
|
||||
if (res)
|
||||
return res;
|
||||
|
||||
gst_structure_get (meta,
|
||||
"__lineno__", G_TYPE_INT, ¤t_lineno,
|
||||
"__debug__", G_TYPE_STRING, &debug,
|
||||
"__filename__", G_TYPE_STRING, &filename, NULL);
|
||||
strs = gst_validate_utils_get_strv (meta, fieldname);
|
||||
|
||||
res = get_structures_from_array (meta, fieldname);
|
||||
if (res) {
|
||||
for (GList * tmp = res; tmp; tmp = tmp->next) {
|
||||
gst_structure_set (tmp->data,
|
||||
"__lineno__", G_TYPE_INT, current_lineno,
|
||||
"__filename__", G_TYPE_STRING, filename,
|
||||
"__debug__", G_TYPE_STRING, debug, NULL);
|
||||
}
|
||||
goto done;
|
||||
}
|
||||
|
||||
strs = gst_validate_utils_get_strv (meta, fieldname);
|
||||
if (strs) {
|
||||
gint i;
|
||||
|
||||
|
@ -294,6 +302,7 @@ get_structures_from_array_in_meta (const gchar * fieldname)
|
|||
}
|
||||
}
|
||||
|
||||
done:
|
||||
g_free (filename);
|
||||
g_free (debug);
|
||||
g_strfreev (strs);
|
||||
|
@ -612,6 +621,46 @@ validate_test_include_paths (const gchar * includer_file)
|
|||
return env_configdir;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
_set_feature_rank (const GstIdStr * fieldname, GValue * value,
|
||||
GstStructure * structure)
|
||||
{
|
||||
GstRegistry *registry = gst_registry_get ();
|
||||
guint rank = 0;
|
||||
|
||||
if (gst_validate_structure_file_field_is_metadata (fieldname))
|
||||
return TRUE;
|
||||
|
||||
if (G_VALUE_TYPE (value) == G_TYPE_UINT) {
|
||||
rank = (guint) g_value_get_uint (value);
|
||||
} else if (G_VALUE_TYPE (value) == G_TYPE_INT) {
|
||||
rank = g_value_get_int (value);
|
||||
} else {
|
||||
gst_validate_error_structure (structure,
|
||||
"Invalid value %s for field '%s' (expecting int) in the 'features-rank' structure",
|
||||
G_VALUE_TYPE_NAME (value), gst_value_serialize (value));
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
GstPluginFeature *feature =
|
||||
gst_registry_lookup_feature (registry, gst_id_str_as_str (fieldname));
|
||||
if (!feature) {
|
||||
if (gst_structure_has_name (structure, "mandatory")) {
|
||||
gst_validate_error_structure (structure,
|
||||
"Feature `%s` not found while its ranks has been requested to be set to %d",
|
||||
gst_id_str_as_str (fieldname), rank);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gst_plugin_feature_set_rank (feature, rank);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* Only the first monitor pipeline will be used */
|
||||
GstStructure *
|
||||
gst_validate_setup_test_file (const gchar * testfile, gboolean use_fakesinks)
|
||||
|
@ -653,6 +702,21 @@ gst_validate_setup_test_file (const gchar * testfile, gboolean use_fakesinks)
|
|||
register_action_types ();
|
||||
gst_validate_scenario_check_and_set_needs_clock_sync (testfile_structs, &res);
|
||||
|
||||
GList *feature_ranks_def =
|
||||
get_structures_from_array_in_meta ("features-rank");
|
||||
for (GList * tmp = feature_ranks_def; tmp; tmp = tmp->next) {
|
||||
GstStructure *feature_ranks = tmp->data;
|
||||
if (!gst_structure_has_name (feature_ranks, "mandatory")
|
||||
&& !gst_structure_has_name (feature_ranks, "optional")) {
|
||||
gst_validate_error_structure (res,
|
||||
"Feature rank structures should have either `mandatory` or `optional` as a name, got: %s",
|
||||
gst_structure_to_string (feature_ranks));
|
||||
return NULL;
|
||||
}
|
||||
gst_structure_filter_and_map_in_place_id_str (feature_ranks,
|
||||
(GstStructureFilterMapIdStrFunc) _set_feature_rank, feature_ranks);
|
||||
}
|
||||
|
||||
gst_validate_set_test_file_globals (res, global_testfile, use_fakesinks);
|
||||
gst_validate_structure_resolve_variables (NULL, res, NULL, 0);
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
<gresource prefix="/validate/">
|
||||
<file>doc/meta-configs.md</file>
|
||||
<file>doc/meta-expected-issues.md</file>
|
||||
<file>doc/meta-features-rank.md</file>
|
||||
</gresource>
|
||||
</gresources>
|
||||
|
||||
|
|
|
@ -33,6 +33,10 @@
|
|||
#include "utils.h"
|
||||
#include "ges-launcher-kb.h"
|
||||
|
||||
#ifdef HAVE_GST_VALIDATE
|
||||
#include <gst/validate/validate.h>
|
||||
#endif
|
||||
|
||||
typedef enum
|
||||
{
|
||||
GST_PLAY_TRICK_MODE_NONE = 0,
|
||||
|
@ -321,6 +325,19 @@ _parse_track_type (const gchar * option_name, const gchar * value,
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
#ifdef HAVE_GST_VALIDATE
|
||||
static gboolean
|
||||
_parse_test_file (const gchar * option_name, const gchar * value,
|
||||
GESLauncherParsedOptions * opts, GError ** error)
|
||||
{
|
||||
opts->testfile = g_strdup (value);
|
||||
gst_validate_init_debug ();
|
||||
gst_validate_setup_test_file (opts->testfile, FALSE);
|
||||
return TRUE;
|
||||
}
|
||||
#endif
|
||||
|
||||
static gboolean
|
||||
_set_track_restriction_caps (GESTrack * track, const gchar * caps_str)
|
||||
{
|
||||
|
@ -1037,6 +1054,8 @@ bus_message_cb (GstBus * bus, GstMessage * message, GESLauncher * self)
|
|||
break;
|
||||
}
|
||||
case GST_MESSAGE_EOS:
|
||||
GST_DEBUG_BIN_TO_DOT_FILE_WITH_TS (GST_BIN (self->priv->pipeline),
|
||||
GST_DEBUG_GRAPH_SHOW_ALL, "ges-launch.eos");
|
||||
if (!self->priv->parsed_options.ignore_eos) {
|
||||
ges_ok ("\nDone\n");
|
||||
g_application_quit (G_APPLICATION (self));
|
||||
|
@ -1177,7 +1196,8 @@ _run_pipeline (GESLauncher * self)
|
|||
|
||||
bus = gst_pipeline_get_bus (GST_PIPELINE (self->priv->pipeline));
|
||||
gst_bus_add_signal_watch (bus);
|
||||
g_signal_connect (bus, "message", G_CALLBACK (bus_message_cb), self);
|
||||
g_signal_connect_object (bus, "message", G_CALLBACK (bus_message_cb), self,
|
||||
0);
|
||||
|
||||
g_application_hold (G_APPLICATION (self));
|
||||
|
||||
|
@ -1433,7 +1453,7 @@ ges_launcher_parse_options (GESLauncher * self,
|
|||
"Specify the track restriction caps of the audio track.",
|
||||
},
|
||||
#ifdef HAVE_GST_VALIDATE
|
||||
{"set-test-file", 0, 0, G_OPTION_ARG_STRING, &opts->testfile,
|
||||
{"set-test-file", 0, 0, G_OPTION_ARG_CALLBACK, &_parse_test_file,
|
||||
"ges-launch-1.0 exposes gst-validate functionalities, such as test files and scenarios."
|
||||
" Scenarios describe actions to execute, such as seeks or setting of "
|
||||
"properties. "
|
||||
|
|
|
@ -138,7 +138,14 @@ ges_validate_activate (GstPipeline * pipeline, GESLauncher * launcher,
|
|||
if (opts->testfile) {
|
||||
if (opts->scenario)
|
||||
g_error ("Can not specify scenario and testfile at the same time");
|
||||
gst_validate_setup_test_file (opts->testfile, opts->mute);
|
||||
if (!opts->mute) {
|
||||
gst_validate_set_globals (gst_structure_new ("globals",
|
||||
"videosink", G_TYPE_STRING,
|
||||
opts->videosink ? opts->videosink : "autovideosink", "audiosink",
|
||||
G_TYPE_STRING,
|
||||
opts->audiosink ? opts->audiosink : "autoaudiosink", NULL)
|
||||
);
|
||||
}
|
||||
} else if (opts->scenario) {
|
||||
if (g_strcmp0 (opts->scenario, "none")) {
|
||||
gchar *scenario_name =
|
||||
|
|
Loading…
Reference in a new issue