validate: cleanup the use of GST_VALIDATE_API on Windows
[platform/upstream/gstreamer.git] / subprojects / gst-devtools / validate / gst / validate / gst-validate-extra-checks.c
1 #ifdef HAVE_CONFIG_H
2 #include "config.h"
3 #endif
4
5 #include <gst/gst.h>
6 #include "validate.h"
7 #include "gst-validate-utils.h"
8 #include "gst-validate-internal.h"
9
10
11
12 #define EXTRA_CHECKS_WRONG_NUMBER_OF_INSTANCES g_quark_from_static_string ("extrachecks::wrong-number-of-instances")
13
14 typedef struct
15 {
16   gchar *pname;
17   gchar *klass;
18   gint expected_n_instances;
19   gint n_instances;
20 } CheckNumInstanceData;
21
22 static CheckNumInstanceData *
23 gst_validate_check_num_instances_data_new (GstStructure * check)
24 {
25   CheckNumInstanceData *data = g_new0 (CheckNumInstanceData, 1);
26
27   if (!gst_structure_get_int (check, "num-instances",
28           &data->expected_n_instances)) {
29     gst_validate_abort
30         ("[CONFIG ERROR] Mandatory field `num-instances` not found in "
31         "extra-check `num-instances`");
32     goto failed;
33   }
34
35   data->pname = g_strdup (gst_structure_get_string (check, "pipeline-name"));
36   if (!data->pname) {
37     gst_validate_abort
38         ("[CONFIG ERROR] Mandatory field `pipeline` not found in "
39         "extra-check `num-instances`");
40     goto failed;
41   }
42
43   data->klass = g_strdup (gst_structure_get_string (check, "element-klass"));
44   if (!data->klass) {
45     gst_validate_abort
46         ("[CONFIG ERROR] Mandatory field `element-klass` not found in "
47         "extra-check `num-instances`");
48     goto failed;
49   }
50
51   return data;
52
53 failed:
54   g_free (data);
55   g_free (data->klass);
56
57   return NULL;
58 }
59
60 static void
61 gst_validate_check_num_instances_data_free (CheckNumInstanceData * data)
62 {
63   g_free (data->pname);
64   g_free (data);
65 }
66
67 static void
68 gst_validate_check_num_instances (GstValidateOverride * o,
69     GstValidateMonitor * monitor, GstElement * nelem)
70 {
71   gchar *pname;
72   CheckNumInstanceData *data = g_object_get_data (G_OBJECT (o), "check-data");
73   GstPipeline *pipe = gst_validate_monitor_get_pipeline (monitor);
74
75   if (!pipe)
76     return;
77
78   pname = gst_object_get_name (GST_OBJECT (pipe));
79   if (g_strcmp0 (data->pname, pname))
80     goto done;
81
82   if (!gst_validate_element_has_klass (nelem, data->klass))
83     return;
84
85   data->n_instances++;
86
87   if (data->n_instances > data->expected_n_instances) {
88     GST_VALIDATE_REPORT (o, EXTRA_CHECKS_WRONG_NUMBER_OF_INSTANCES,
89         "%d instances allows in pipeline %s but already %d where added.",
90         data->expected_n_instances, pname, data->n_instances);
91   }
92   GST_ERROR_OBJECT (nelem, "HERE I AM %d", data->n_instances);
93
94 done:
95   g_free (pname);
96   gst_object_unref (pipe);
97 }
98
99 static void
100 runner_stopping (GstValidateRunner * runner, GstValidateOverride * o)
101 {
102   CheckNumInstanceData *data = g_object_get_data (G_OBJECT (o), "check-data");
103
104   if (data->expected_n_instances != data->n_instances) {
105     GST_VALIDATE_REPORT (o, EXTRA_CHECKS_WRONG_NUMBER_OF_INSTANCES,
106         "%d instances expected in pipeline %s but %d where added.",
107         data->expected_n_instances, data->pname, data->n_instances);
108   }
109 }
110
111 static void
112 _runner_set (GObject * object, GParamSpec * pspec, gpointer user_data)
113 {
114   GstValidateRunner *runner =
115       gst_validate_reporter_get_runner (GST_VALIDATE_REPORTER (object));
116
117   g_signal_connect (runner, "stopping", G_CALLBACK (runner_stopping), object);
118   gst_object_unref (runner);
119 }
120
121 static void
122 gst_validate_add_num_instances_check (GstStructure * structure)
123 {
124   CheckNumInstanceData *data =
125       gst_validate_check_num_instances_data_new (structure);
126   GstValidateOverride *o = gst_validate_override_new ();
127
128   g_object_set_data_full (G_OBJECT (o), "check-data", data,
129       (GDestroyNotify) gst_validate_check_num_instances_data_free);
130
131   gst_validate_override_set_element_added_handler (o,
132       gst_validate_check_num_instances);
133
134   g_signal_connect (o, "notify::validate-runner", G_CALLBACK (_runner_set),
135       NULL);
136
137   gst_validate_override_register_by_type (GST_TYPE_BIN, o);
138   gst_object_unref (o);
139 }
140
141 gboolean
142 gst_validate_extra_checks_init ()
143 {
144   GList *config, *tmp;
145   config = gst_validate_get_config ("extrachecks");
146
147   if (!config)
148     return TRUE;
149
150   for (tmp = config; tmp; tmp = tmp->next) {
151     GstStructure *check = tmp->data;
152
153     if (gst_structure_has_field (check, "num-instances"))
154       gst_validate_add_num_instances_check (check);
155   }
156   g_list_free (config);
157
158   gst_validate_issue_register (gst_validate_issue_new
159       (EXTRA_CHECKS_WRONG_NUMBER_OF_INSTANCES,
160           "The configured number of possible instances of an element type"
161           " in a pipeline is not respected.",
162           "The `num-instances` extra checks allow user to make sure that"
163           " a previously defined number of instances of an element is added"
164           " in a given pipeline, that test failed.",
165           GST_VALIDATE_REPORT_LEVEL_CRITICAL));
166
167   return TRUE;
168 }