mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-30 12:10:37 +00:00
b1b696017c
And add a way to check that a configured number of instances of a particular element is used, this is useful to make sure for example that playing a particular stream doesn't lead to several decoders being instanciated.
168 lines
4.7 KiB
C
168 lines
4.7 KiB
C
#include <gst/gst.h>
|
|
#include "../../gst/validate/validate.h"
|
|
#include "../../gst/validate/gst-validate-utils.h"
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
#include "config.h"
|
|
#endif
|
|
|
|
#define EXTRA_CHECKS_WRONG_NUMBER_OF_INSTANCES g_quark_from_static_string ("extrachecks::wrong-number-of-instances")
|
|
|
|
typedef struct
|
|
{
|
|
gchar *pname;
|
|
gchar *klass;
|
|
gint expected_n_instances;
|
|
gint n_instances;
|
|
} CheckNumInstanceData;
|
|
|
|
static CheckNumInstanceData *
|
|
gst_validate_check_num_instances_data_new (GstStructure * check)
|
|
{
|
|
CheckNumInstanceData *data = g_new0 (CheckNumInstanceData, 1);
|
|
|
|
if (!gst_structure_get_int (check, "num-instances",
|
|
&data->expected_n_instances)) {
|
|
g_error ("[CONFIG ERROR] Mandatory field `num-instances` not found in "
|
|
"extra-check `num-instances`");
|
|
goto failed;
|
|
}
|
|
|
|
data->pname = g_strdup (gst_structure_get_string (check, "pipeline-name"));
|
|
if (!data->pname) {
|
|
g_error ("[CONFIG ERROR] Mandatory field `pipeline` not found in "
|
|
"extra-check `num-instances`");
|
|
goto failed;
|
|
}
|
|
|
|
data->klass = g_strdup (gst_structure_get_string (check, "element-klass"));
|
|
if (!data->klass) {
|
|
g_error ("[CONFIG ERROR] Mandatory field `element-klass` not found in "
|
|
"extra-check `num-instances`");
|
|
goto failed;
|
|
}
|
|
|
|
return data;
|
|
|
|
failed:
|
|
g_free (data);
|
|
g_free (data->klass);
|
|
|
|
return NULL;
|
|
}
|
|
|
|
static void
|
|
gst_validate_check_num_instances_data_free (CheckNumInstanceData * data)
|
|
{
|
|
g_free (data->pname);
|
|
g_free (data);
|
|
}
|
|
|
|
static void
|
|
gst_validate_check_num_instances (GstValidateOverride * o,
|
|
GstValidateMonitor * monitor, GstElement * nelem)
|
|
{
|
|
gchar *pname;
|
|
CheckNumInstanceData *data = g_object_get_data (G_OBJECT (o), "check-data");
|
|
GstPipeline *pipe = gst_validate_monitor_get_pipeline (monitor);
|
|
|
|
if (!pipe)
|
|
return;
|
|
|
|
pname = gst_object_get_name (GST_OBJECT (pipe));
|
|
if (g_strcmp0 (data->pname, pname))
|
|
goto done;
|
|
|
|
if (!gst_validate_element_has_klass (nelem, data->klass))
|
|
return;
|
|
|
|
data->n_instances++;
|
|
|
|
if (data->n_instances > data->expected_n_instances) {
|
|
GST_VALIDATE_REPORT (o, EXTRA_CHECKS_WRONG_NUMBER_OF_INSTANCES,
|
|
"%d instances allows in pipeline %s but already %d where added.",
|
|
data->expected_n_instances, pname, data->n_instances);
|
|
}
|
|
GST_ERROR_OBJECT (nelem, "HERE I AM %d", data->n_instances);
|
|
|
|
done:
|
|
g_free (pname);
|
|
gst_object_unref (pipe);
|
|
}
|
|
|
|
static void
|
|
runner_stopping (GstValidateRunner * runner, GstValidateOverride * o)
|
|
{
|
|
CheckNumInstanceData *data = g_object_get_data (G_OBJECT (o), "check-data");
|
|
|
|
if (data->expected_n_instances != data->n_instances) {
|
|
GST_VALIDATE_REPORT (o, EXTRA_CHECKS_WRONG_NUMBER_OF_INSTANCES,
|
|
"%d instances expected in pipeline %s but %d where added.",
|
|
data->expected_n_instances, data->pname, data->n_instances);
|
|
}
|
|
}
|
|
|
|
static void
|
|
_runner_set (GObject * object, GParamSpec * pspec, gpointer user_data)
|
|
{
|
|
GstValidateRunner *runner =
|
|
gst_validate_reporter_get_runner (GST_VALIDATE_REPORTER (object));
|
|
|
|
g_signal_connect (runner, "stopping", G_CALLBACK (runner_stopping), object);
|
|
gst_object_unref (runner);
|
|
}
|
|
|
|
static void
|
|
gst_validate_add_num_instances_check (GstStructure * structure)
|
|
{
|
|
CheckNumInstanceData *data =
|
|
gst_validate_check_num_instances_data_new (structure);
|
|
GstValidateOverride *o = gst_validate_override_new ();
|
|
|
|
g_object_set_data_full (G_OBJECT (o), "check-data", data,
|
|
(GDestroyNotify) gst_validate_check_num_instances_data_free);
|
|
|
|
gst_validate_override_set_element_added_handler (o,
|
|
gst_validate_check_num_instances);
|
|
|
|
g_signal_connect (o, "notify::validate-runner", G_CALLBACK (_runner_set),
|
|
NULL);
|
|
|
|
gst_validate_override_register_by_type (GST_TYPE_BIN, o);
|
|
gst_object_unref (o);
|
|
}
|
|
|
|
static gboolean
|
|
gst_validate_extra_checks_init (GstPlugin * plugin)
|
|
{
|
|
GList *config, *tmp;
|
|
config = gst_validate_plugin_get_config (plugin);
|
|
|
|
if (!config)
|
|
return TRUE;
|
|
|
|
for (tmp = config; tmp; tmp = tmp->next) {
|
|
GstStructure *check = tmp->data;
|
|
|
|
if (gst_structure_has_field (check, "num-instances"))
|
|
gst_validate_add_num_instances_check (check);
|
|
}
|
|
|
|
gst_validate_issue_register (gst_validate_issue_new
|
|
(EXTRA_CHECKS_WRONG_NUMBER_OF_INSTANCES,
|
|
"The configured number of possible instances of an element type"
|
|
" in a pipeline is not respected.",
|
|
"The `num-instances` extra checks allow user to make sure that"
|
|
" a previously defined number of instances of an element is added"
|
|
" in a given pipeline, that test failed.",
|
|
GST_VALIDATE_REPORT_LEVEL_CRITICAL));
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
GST_PLUGIN_DEFINE (GST_VERSION_MAJOR,
|
|
GST_VERSION_MINOR,
|
|
extrachecks,
|
|
"GstValidate plugin that implements extra, configurable tests.",
|
|
gst_validate_extra_checks_init, VERSION, "LGPL", GST_PACKAGE_NAME,
|
|
GST_PACKAGE_ORIGIN)
|