3 * Copyright (C) 2013 Collabora Ltd.
4 * Author: Thiago Sousa Santos <thiago.sousa.santos@collabora.com>
6 * gst-validate-bin-monitor.c - Validate BinMonitor 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-internal.h"
29 #include "gst-validate-bin-monitor.h"
30 #include "gst-validate-monitor-factory.h"
32 #define PRINT_POSITION_TIMEOUT 250
35 * SECTION:gst-validate-bin-monitor
36 * @short_description: Class that wraps a #GstBin for Validate checks
48 #define gst_validate_bin_monitor_parent_class parent_class
49 G_DEFINE_TYPE (GstValidateBinMonitor, gst_validate_bin_monitor,
50 GST_TYPE_VALIDATE_ELEMENT_MONITOR);
53 gst_validate_bin_monitor_get_property (GObject * object, guint prop_id,
54 GValue * value, GParamSpec * pspec);
56 gst_validate_bin_monitor_set_property (GObject * object, guint prop_id,
57 const GValue * value, GParamSpec * pspec);
59 gst_validate_bin_monitor_wrap_element (GstValidateBinMonitor * monitor,
60 GstElement * element);
61 static gboolean gst_validate_bin_monitor_setup (GstValidateMonitor * monitor);
64 _validate_bin_element_added (GstBin * bin, GstElement * pad,
65 GstValidateBinMonitor * monitor);
68 _validate_bin_element_removed (GstBin * bin, GstElement * element,
69 GstValidateBinMonitor * monitor);
72 gst_validate_bin_set_media_descriptor (GstValidateMonitor * monitor,
73 GstValidateMediaDescriptor * media_descriptor)
77 GST_VALIDATE_MONITOR_LOCK (monitor);
78 for (tmp = GST_VALIDATE_BIN_MONITOR_CAST (monitor)->element_monitors; tmp;
80 GstValidateMonitor *sub_monitor = (GstValidateMonitor *) tmp->data;
81 gst_validate_monitor_set_media_descriptor (sub_monitor, media_descriptor);
83 GST_VALIDATE_MONITOR_UNLOCK (monitor);
85 GST_VALIDATE_MONITOR_CLASS (parent_class)->set_media_descriptor (monitor,
90 gst_validate_bin_monitor_set_property (GObject * object, guint prop_id,
91 const GValue * value, GParamSpec * pspec)
94 case PROP_HANDLES_STATE:
95 g_assert_not_reached ();
98 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
104 gst_validate_bin_monitor_get_property (GObject * object, guint prop_id,
105 GValue * value, GParamSpec * pspec)
107 GstValidateBinMonitor *monitor;
109 monitor = GST_VALIDATE_BIN_MONITOR_CAST (object);
112 case PROP_HANDLES_STATE:
113 if (monitor->scenario == NULL)
114 g_value_set_boolean (value, FALSE);
116 g_object_get_property (G_OBJECT (monitor->scenario), "handles-states",
120 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
126 purge_and_unref_reporter (gpointer data)
128 GstValidateReporter *reporter = data;
130 gst_validate_reporter_purge_reports (reporter);
131 g_object_unref (reporter);
135 gst_validate_bin_monitor_dispose (GObject * object)
137 GstValidateBinMonitor *monitor = GST_VALIDATE_BIN_MONITOR_CAST (object);
139 GST_ELEMENT (gst_validate_monitor_get_target (GST_VALIDATE_MONITOR_CAST
143 if (monitor->element_added_id)
144 g_signal_handler_disconnect (bin, monitor->element_added_id);
145 if (monitor->element_removed_id)
146 g_signal_handler_disconnect (bin, monitor->element_removed_id);
147 gst_object_unref (bin);
150 if (monitor->scenario) {
151 gst_validate_reporter_purge_reports (GST_VALIDATE_REPORTER
152 (monitor->scenario));
153 gst_clear_object (&monitor->scenario);
156 g_list_free_full (monitor->element_monitors, purge_and_unref_reporter);
158 G_OBJECT_CLASS (parent_class)->dispose (object);
163 gst_validate_bin_monitor_class_init (GstValidateBinMonitorClass * klass)
165 GObjectClass *gobject_class;
166 GstValidateMonitorClass *validatemonitor_class;
168 gobject_class = G_OBJECT_CLASS (klass);
169 validatemonitor_class = GST_VALIDATE_MONITOR_CLASS_CAST (klass);
171 gobject_class->get_property = gst_validate_bin_monitor_get_property;
172 gobject_class->set_property = gst_validate_bin_monitor_set_property;
173 gobject_class->dispose = gst_validate_bin_monitor_dispose;
175 g_object_class_install_property (gobject_class, PROP_HANDLES_STATE,
176 g_param_spec_boolean ("handles-states", "Handles state",
177 "True if the application should not set handle the first state change "
178 " False if it is application responsibility",
179 FALSE, G_PARAM_READABLE));
181 validatemonitor_class->setup = gst_validate_bin_monitor_setup;
182 validatemonitor_class->set_media_descriptor =
183 gst_validate_bin_set_media_descriptor;
187 gst_validate_bin_monitor_init (GstValidateBinMonitor * bin_monitor)
192 * gst_validate_bin_monitor_new:
193 * @bin: (transfer none): a #GstBin to run Validate on
195 GstValidateBinMonitor *
196 gst_validate_bin_monitor_new (GstBin * bin, GstValidateRunner * runner,
197 GstValidateMonitor * parent)
199 GstValidateBinMonitor *monitor =
200 g_object_new (GST_TYPE_VALIDATE_BIN_MONITOR, "object",
201 bin, "validate-runner", runner, "validate-parent", parent, NULL);
203 gst_validate_monitor_get_target (GST_VALIDATE_MONITOR (monitor));
205 if (target == NULL) {
206 g_object_unref (monitor);
209 gst_object_unref (target);
215 gst_validate_bin_child_added_overrides (GstValidateMonitor * monitor,
216 GstElement * element)
220 GST_VALIDATE_MONITOR_OVERRIDES_LOCK (monitor);
221 for (iter = GST_VALIDATE_MONITOR_OVERRIDES (monitor).head; iter;
222 iter = g_list_next (iter)) {
223 GstValidateOverride *override = iter->data;
225 gst_validate_override_element_added_handler (override, monitor, element);
227 GST_VALIDATE_MONITOR_OVERRIDES_UNLOCK (monitor);
231 gst_validate_bin_monitor_setup (GstValidateMonitor * monitor)
233 GstIterator *iterator;
236 GstValidateBinMonitor *bin_monitor = GST_VALIDATE_BIN_MONITOR_CAST (monitor);
237 GstBin *bin = GST_BIN_CAST (gst_validate_monitor_get_target (monitor));
239 if (!GST_IS_BIN (bin)) {
240 GST_WARNING_OBJECT (monitor, "Trying to create bin monitor with other "
245 GST_DEBUG_OBJECT (bin_monitor, "Setting up monitor for bin %" GST_PTR_FORMAT,
248 if (g_object_get_data ((GObject *) bin, "validate-monitor")) {
249 GST_DEBUG_OBJECT (bin_monitor,
250 "Bin already has a validate-monitor associated");
254 bin_monitor->element_added_id =
255 g_signal_connect (bin, "element-added",
256 G_CALLBACK (_validate_bin_element_added), monitor);
258 bin_monitor->element_removed_id =
259 g_signal_connect (bin, "element-removed",
260 G_CALLBACK (_validate_bin_element_removed), monitor);
262 iterator = gst_bin_iterate_elements (bin);
265 GValue value = { 0, };
267 switch (gst_iterator_next (iterator, &value)) {
268 case GST_ITERATOR_OK:
269 element = g_value_get_object (&value);
270 gst_validate_bin_monitor_wrap_element (bin_monitor, element);
271 g_value_reset (&value);
273 case GST_ITERATOR_RESYNC:
274 /* TODO how to handle this? */
275 gst_iterator_resync (iterator);
277 case GST_ITERATOR_ERROR:
280 case GST_ITERATOR_DONE:
285 gst_iterator_free (iterator);
286 gst_object_unref (bin);
288 return GST_VALIDATE_MONITOR_CLASS (parent_class)->setup (monitor);
292 gst_object_unref (bin);
297 gst_validate_bin_monitor_wrap_element (GstValidateBinMonitor * monitor,
298 GstElement * element)
300 GstValidateElementMonitor *element_monitor;
301 GstValidateRunner *runner =
302 gst_validate_reporter_get_runner (GST_VALIDATE_REPORTER (monitor));
304 GST_DEBUG_OBJECT (monitor, "Wrapping element %s", GST_ELEMENT_NAME (element));
307 GST_VALIDATE_ELEMENT_MONITOR_CAST (gst_validate_monitor_factory_create
308 (GST_OBJECT_CAST (element), runner, GST_VALIDATE_MONITOR_CAST (monitor)));
309 g_return_if_fail (element_monitor != NULL);
311 GST_VALIDATE_MONITOR_CAST (element_monitor)->verbosity =
312 GST_VALIDATE_MONITOR_CAST (monitor)->verbosity;
313 gst_validate_bin_child_added_overrides (GST_VALIDATE_MONITOR (monitor),
316 if (GST_VALIDATE_MONITOR_CAST (monitor)->verbosity &
317 GST_VALIDATE_VERBOSITY_NEW_ELEMENTS)
318 gst_validate_printf (NULL, "(element-added) %s added to %s\n",
319 GST_ELEMENT_NAME (element),
320 gst_validate_reporter_get_name (GST_VALIDATE_REPORTER (monitor)));
322 GST_VALIDATE_MONITOR_LOCK (monitor);
323 monitor->element_monitors = g_list_prepend (monitor->element_monitors,
325 GST_VALIDATE_MONITOR_UNLOCK (monitor);
327 gst_object_unref (runner);
331 _validate_bin_element_added (GstBin * bin, GstElement * element,
332 GstValidateBinMonitor * monitor)
335 gst_validate_monitor_get_target (GST_VALIDATE_MONITOR (monitor));
337 g_return_if_fail (GST_ELEMENT_CAST (target) == GST_ELEMENT_CAST (bin));
339 gst_object_unref (target);
340 gst_validate_bin_monitor_wrap_element (monitor, element);
344 _validate_bin_element_removed (GstBin * bin, GstElement * element,
345 GstValidateBinMonitor * monitor)
347 if (GST_VALIDATE_MONITOR_CAST (monitor)->verbosity &
348 GST_VALIDATE_VERBOSITY_NEW_ELEMENTS)
349 gst_validate_printf (NULL, "(element-removed) %s removed from %s\n",
350 GST_ELEMENT_NAME (element),
351 gst_validate_reporter_get_name (GST_VALIDATE_REPORTER (monitor)));
355 * gst_validate_bin_monitor_get_scenario:
356 * @monitor: A #GstValidateBinMonitor
358 * Returns: (transfer full) (nullable): The #GstValidateScenario being executed
359 * under @monitor watch
363 GstValidateScenario *
364 gst_validate_bin_monitor_get_scenario (GstValidateBinMonitor * monitor)
366 if (monitor->scenario)
367 return gst_object_ref (monitor->scenario);