3 * Copyright (C) 2013 Collabora Ltd.
4 * Author: Thiago Sousa Santos <thiago.sousa.santos@collabora.com>
6 * gst-validate-monitor.c - Validate Monitor class
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Library General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Library General Public License for more details.
18 * You should have received a copy of the GNU Library General Public
19 * License along with this library; if not, write to the
20 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
21 * Boston, MA 02111-1307, USA.
28 #include "gst-validate-enum-types.h"
29 #include "gst-validate-internal.h"
30 #include "gst-validate-monitor.h"
31 #include "gst-validate-override-registry.h"
34 * SECTION:gst-validate-monitor
35 * @short_description: Base class that wraps a #GObject for Validate checks
51 static gboolean gst_validate_monitor_do_setup (GstValidateMonitor * monitor);
53 gst_validate_monitor_get_property (GObject * object, guint prop_id,
54 GValue * value, GParamSpec * pspec);
56 gst_validate_monitor_set_property (GObject * object, guint prop_id,
57 const GValue * value, GParamSpec * pspec);
58 static GObject *gst_validate_monitor_constructor (GType type,
59 guint n_construct_params, GObjectConstructParam * construct_params);
61 static gboolean gst_validate_monitor_setup (GstValidateMonitor * monitor);
63 static GstValidateInterceptionReturn
64 gst_validate_monitor_intercept_report (GstValidateReporter * reporter,
65 GstValidateReport * report);
68 G_IMPLEMENT_INTERFACE (GST_TYPE_VALIDATE_REPORTER, _reporter_iface_init)
70 static GstValidateReportingDetails
71 _get_reporting_level (GstValidateReporter * monitor)
73 return GST_VALIDATE_MONITOR (monitor)->level;
77 * gst_validate_monitor_get_pipeline:
78 * @monitor: The monitor to get the pipeline from
80 * Returns: (transfer full) (nullable): The pipeline in which @monitor
84 gst_validate_monitor_get_pipeline (GstValidateMonitor * monitor)
86 return g_weak_ref_get (&monitor->pipeline);
90 * gst_validate_monitor_get_target:
91 * @monitor: The monitor to get the target from
93 * Returns: (transfer full) (nullable): The target object
96 gst_validate_monitor_get_target (GstValidateMonitor * monitor)
98 return g_weak_ref_get (&monitor->target);
102 _get_pipeline (GstValidateReporter * monitor)
104 return g_weak_ref_get (&(GST_VALIDATE_MONITOR (monitor)->pipeline));
108 _reporter_iface_init (GstValidateReporterInterface * iface)
110 iface->intercept_report = gst_validate_monitor_intercept_report;
111 iface->get_reporting_level = _get_reporting_level;
112 iface->get_pipeline = _get_pipeline;
115 #define gst_validate_monitor_parent_class parent_class
116 G_DEFINE_ABSTRACT_TYPE_WITH_CODE (GstValidateMonitor, gst_validate_monitor,
117 GST_TYPE_OBJECT, _do_init);
120 gst_validate_monitor_dispose (GObject * object)
122 GstValidateMonitor *monitor = GST_VALIDATE_MONITOR_CAST (object);
124 g_mutex_clear (&monitor->mutex);
125 g_mutex_clear (&monitor->overrides_mutex);
126 g_queue_clear (&monitor->overrides);
128 g_weak_ref_clear (&monitor->pipeline);
129 g_weak_ref_clear (&monitor->target);
131 if (monitor->media_descriptor)
132 gst_object_unref (monitor->media_descriptor);
134 G_OBJECT_CLASS (parent_class)->dispose (object);
138 gst_validate_monitor_finalize (GObject * object)
140 gst_validate_reporter_set_name (GST_VALIDATE_REPORTER (object), NULL);
142 G_OBJECT_CLASS (parent_class)->finalize (object);
146 gst_validate_monitor_class_init (GstValidateMonitorClass * klass)
148 GObjectClass *gobject_class;
150 gobject_class = G_OBJECT_CLASS (klass);
152 gobject_class->get_property = gst_validate_monitor_get_property;
153 gobject_class->set_property = gst_validate_monitor_set_property;
154 gobject_class->dispose = gst_validate_monitor_dispose;
155 gobject_class->finalize = gst_validate_monitor_finalize;
156 gobject_class->constructor = gst_validate_monitor_constructor;
158 klass->setup = gst_validate_monitor_do_setup;
160 g_object_class_install_property (gobject_class, PROP_OBJECT,
161 g_param_spec_object ("object", "Object", "The object to be monitored",
162 G_TYPE_OBJECT, G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE));
164 g_object_class_install_property (gobject_class, PROP_PIPELINE,
165 g_param_spec_object ("pipeline", "Pipeline", "The pipeline in which the"
166 "monitored object is", GST_TYPE_PIPELINE,
167 G_PARAM_CONSTRUCT | G_PARAM_READWRITE));
169 g_object_class_install_property (gobject_class, PROP_RUNNER,
170 g_param_spec_object ("validate-runner", "VALIDATE Runner",
171 "The Validate runner to report errors to",
172 GST_TYPE_VALIDATE_RUNNER,
173 G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE));
175 g_object_class_install_property (gobject_class, PROP_VALIDATE_PARENT,
176 g_param_spec_object ("validate-parent", "VALIDATE parent monitor",
177 "The Validate monitor that is the parent of this one",
178 GST_TYPE_VALIDATE_MONITOR,
179 G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE));
181 g_object_class_install_property (gobject_class, PROP_VERBOSITY,
182 g_param_spec_flags ("verbosity", "Verbosity",
183 "The verbosity of GstValidate on the monitor",
184 GST_TYPE_VALIDATE_VERBOSITY_FLAGS,
185 GST_VALIDATE_VERBOSITY_POSITION, G_PARAM_READWRITE));
189 gst_validate_monitor_constructor (GType type, guint n_construct_params,
190 GObjectConstructParam * construct_params)
193 GstValidateMonitor *monitor =
194 GST_VALIDATE_MONITOR_CAST (G_OBJECT_CLASS (parent_class)->constructor
199 if (monitor->parent) {
200 GstPipeline *parent_pipeline =
201 gst_validate_monitor_get_pipeline (monitor->parent);
203 gst_validate_monitor_set_media_descriptor (monitor,
204 monitor->parent->media_descriptor);
206 if (parent_pipeline) {
207 g_weak_ref_init (&monitor->pipeline, parent_pipeline);
209 gst_object_unref (parent_pipeline);
213 gst_validate_monitor_setup (monitor);
214 gst_validate_override_registry_attach_overrides (monitor);
216 target = gst_validate_monitor_get_target (monitor);
217 g_object_set_data ((GObject *) target, "validate-monitor", monitor);
218 gst_object_unref (target);
220 return (GObject *) monitor;
224 gst_validate_monitor_init (GstValidateMonitor * monitor)
226 g_mutex_init (&monitor->mutex);
228 g_mutex_init (&monitor->overrides_mutex);
229 g_queue_init (&monitor->overrides);
231 monitor->verbosity = GST_VALIDATE_VERBOSITY_POSITION;
235 gst_validate_monitor_do_setup (GstValidateMonitor * monitor)
241 static GstValidateReportingDetails
242 _get_report_level_for_pad (GstValidateRunner * runner, GstObject * pad)
245 GstValidateReportingDetails level = GST_VALIDATE_SHOW_UNKNOWN;
247 name = g_strdup_printf ("%s__%s", GST_DEBUG_PAD_NAME (pad));
248 level = gst_validate_runner_get_reporting_level_for_name (runner, name);
255 _determine_reporting_level (GstValidateMonitor * monitor)
257 GstValidateRunner *runner;
258 GstObject *object, *parent;
260 GstValidateReportingDetails level = GST_VALIDATE_SHOW_UNKNOWN;
262 object = gst_validate_monitor_get_target (monitor);
263 runner = gst_validate_reporter_get_runner (GST_VALIDATE_REPORTER (monitor));
266 if (!GST_IS_OBJECT (object))
269 /* Let's allow for singling out pads */
270 if (GST_IS_PAD (object)) {
271 level = _get_report_level_for_pad (runner, object);
272 if (level != GST_VALIDATE_SHOW_UNKNOWN)
276 object_name = gst_object_get_name (object);
277 level = gst_validate_runner_get_reporting_level_for_name (runner,
279 parent = gst_object_get_parent (object);
280 gst_object_unref (object);
282 g_free (object_name);
283 } while (object && level == GST_VALIDATE_SHOW_UNKNOWN);
286 gst_object_unref (object);
289 gst_object_unref (runner);
291 monitor->level = level;
295 gst_validate_monitor_setup (GstValidateMonitor * monitor)
299 GST_DEBUG_OBJECT (monitor, "Starting monitor setup");
301 for (config = gst_validate_plugin_get_config (NULL); config;
302 config = config->next) {
303 const gchar *verbosity =
304 gst_structure_get_string (GST_STRUCTURE (config->data),
308 gst_util_set_object_arg (G_OBJECT (monitor), "verbosity", verbosity);
311 /* For now we just need to do this at setup time */
312 _determine_reporting_level (monitor);
313 return GST_VALIDATE_MONITOR_GET_CLASS (monitor)->setup (monitor);
317 * gst_validate_monitor_get_element
318 * @monitor: The monitor
320 * Returns: (transfer none) (nullable): The GstElement associated with @monitor
323 gst_validate_monitor_get_element (GstValidateMonitor * monitor)
325 GstValidateMonitorClass *klass = GST_VALIDATE_MONITOR_GET_CLASS (monitor);
326 GstElement *element = NULL;
328 if (klass->get_element)
329 element = klass->get_element (monitor);
335 * gst_validate_monitor_get_element_name
336 * @monitor: The monitor
338 * Returns: (transfer full) (nullable): The name of the element associated with @monitor
341 gst_validate_monitor_get_element_name (GstValidateMonitor * monitor)
346 element = gst_validate_monitor_get_element (monitor);
348 res = g_strdup (GST_ELEMENT_NAME (element));
349 gst_object_unref (element);
355 /* Check if any of our overrides wants to change the report severity */
356 static GstValidateInterceptionReturn
357 gst_validate_monitor_intercept_report (GstValidateReporter * reporter,
358 GstValidateReport * report)
361 GstValidateMonitor *monitor = GST_VALIDATE_MONITOR_CAST (reporter);
363 GST_VALIDATE_MONITOR_OVERRIDES_LOCK (monitor);
364 for (iter = monitor->overrides.head; iter; iter = g_list_next (iter)) {
366 gst_validate_override_get_severity (iter->data,
367 gst_validate_issue_get_id (report->issue), report->level);
369 GST_VALIDATE_MONITOR_OVERRIDES_UNLOCK (monitor);
371 return GST_VALIDATE_REPORTER_REPORT;
375 gst_validate_monitor_attach_override (GstValidateMonitor * monitor,
376 GstValidateOverride * override)
378 GstValidateRunner *runner;
379 GstValidateRunner *mrunner;
381 if (!gst_validate_override_can_attach (override, monitor)) {
382 GST_INFO_OBJECT (monitor, "Can not attach override %s",
383 gst_validate_reporter_get_name (GST_VALIDATE_REPORTER (override)));
388 runner = gst_validate_reporter_get_runner (GST_VALIDATE_REPORTER (override));
389 mrunner = gst_validate_reporter_get_runner (GST_VALIDATE_REPORTER (monitor));
390 GST_VALIDATE_MONITOR_OVERRIDES_LOCK (monitor);
392 g_assert (runner == mrunner);
394 gst_validate_reporter_set_runner (GST_VALIDATE_REPORTER (override),
396 g_queue_push_tail (&monitor->overrides, override);
397 GST_VALIDATE_MONITOR_OVERRIDES_UNLOCK (monitor);
400 gst_object_unref (runner);
402 gst_object_unref (mrunner);
403 gst_validate_override_attached (override);
407 gst_validate_monitor_set_property (GObject * object, guint prop_id,
408 const GValue * value, GParamSpec * pspec)
410 GstValidateMonitor *monitor;
412 monitor = GST_VALIDATE_MONITOR_CAST (object);
419 target = g_value_get_object (value);
421 g_assert (gst_validate_monitor_get_target (monitor) == NULL);
422 g_weak_ref_init (&monitor->target, target);
424 if (GST_IS_OBJECT (target))
425 gst_validate_reporter_set_name (GST_VALIDATE_REPORTER (monitor),
426 gst_object_get_name (target));
431 g_weak_ref_init (&monitor->pipeline, g_value_get_object (value));
434 gst_validate_reporter_set_runner (GST_VALIDATE_REPORTER (monitor),
435 g_value_get_object (value));
437 case PROP_VALIDATE_PARENT:
438 monitor->parent = g_value_get_object (value);
441 monitor->verbosity = g_value_get_flags (value);
444 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
450 gst_validate_monitor_get_property (GObject * object, guint prop_id,
451 GValue * value, GParamSpec * pspec)
453 GstValidateMonitor *monitor;
455 monitor = GST_VALIDATE_MONITOR_CAST (object);
459 g_value_take_object (value, gst_validate_monitor_get_target (monitor));
462 g_value_take_object (value, gst_validate_monitor_get_pipeline (monitor));
465 g_value_take_object (value,
466 gst_validate_reporter_get_runner (GST_VALIDATE_REPORTER (monitor)));
468 case PROP_VALIDATE_PARENT:
469 g_value_set_object (value, GST_VALIDATE_MONITOR_GET_PARENT (monitor));
472 g_value_set_flags (value, monitor->verbosity);
475 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
481 gst_validate_monitor_set_media_descriptor (GstValidateMonitor * monitor,
482 GstValidateMediaDescriptor * media_descriptor)
484 GstValidateMonitorClass *klass = GST_VALIDATE_MONITOR_GET_CLASS (monitor);
486 GST_DEBUG_OBJECT (monitor, "Set media desc: %" GST_PTR_FORMAT,
488 if (monitor->media_descriptor)
489 gst_object_unref (monitor->media_descriptor);
491 if (media_descriptor)
492 gst_object_ref (media_descriptor);
494 monitor->media_descriptor = media_descriptor;
495 if (klass->set_media_descriptor)
496 klass->set_media_descriptor (monitor, media_descriptor);
500 gst_validate_get_monitor (GObject * object)
502 return GST_VALIDATE_MONITOR (g_object_get_data (object, "validate-monitor"));