static void
gst_validate_bin_monitor_wrap_element (GstValidateBinMonitor * monitor,
    GstElement * element)
{
  GstValidateElementMonitor *element_monitor;
  GST_DEBUG_OBJECT (monitor, "Wrapping element %s", GST_ELEMENT_NAME (element));

  element_monitor =
      GST_VALIDATE_ELEMENT_MONITOR_CAST (gst_validate_monitor_factory_create
      (GST_OBJECT_CAST (element), GST_VALIDATE_MONITOR_GET_RUNNER (monitor),
          GST_VALIDATE_MONITOR_CAST (monitor)));
  g_return_if_fail (element_monitor != NULL);

  GST_VALIDATE_MONITOR_LOCK (monitor);
  monitor->element_monitors = g_list_prepend (monitor->element_monitors,
      element_monitor);
  GST_VALIDATE_MONITOR_UNLOCK (monitor);
}
static void
gst_validate_element_monitor_dispose (GObject * object)
{
  GstValidateElementMonitor *monitor =
      GST_VALIDATE_ELEMENT_MONITOR_CAST (object);
  GstObject *target =
      gst_validate_monitor_get_target (GST_VALIDATE_MONITOR (monitor));

  if (target) {
    if (monitor->pad_added_id)
      g_signal_handler_disconnect (target, monitor->pad_added_id);
    gst_object_unref (target);
  }

  g_list_free_full (monitor->pad_monitors, purge_and_unref_reporter);

  G_OBJECT_CLASS (parent_class)->dispose (object);
}
/**
 * gst_validate_monitor_factory_create:
 * @target: The #GstObject to create a #GstValidateMonitor for
 * @runner: The #GstValidateRunner to use for the new monitor
 * @parent: (nullable): The parent of the new monitor
 *
 * Create a new monitor for @target and starts monitoring it.
 *
 * Returns: (transfer full): The newly created #GstValidateMonitor
 */
GstValidateMonitor *
gst_validate_monitor_factory_create (GstObject * target,
    GstValidateRunner * runner, GstValidateMonitor * parent)
{
  GstValidateMonitor *monitor = NULL;
  g_return_val_if_fail (target != NULL, NULL);

  monitor = g_object_get_data ((GObject *) target, "validate-monitor");
  if (monitor) {
    GST_INFO_OBJECT (target, "Is already monitored by %" GST_PTR_FORMAT,
        monitor);

    return g_object_ref (monitor);
  }

  if (GST_IS_PAD (target)) {
    monitor =
        GST_VALIDATE_MONITOR_CAST (gst_validate_pad_monitor_new (GST_PAD_CAST
            (target), runner, GST_VALIDATE_ELEMENT_MONITOR_CAST (parent)));
  } else if (GST_IS_PIPELINE (target)) {
    monitor =
        GST_VALIDATE_MONITOR_CAST (gst_validate_pipeline_monitor_new
        (GST_PIPELINE_CAST (target), runner, parent));
  } else if (GST_IS_BIN (target)) {
    monitor =
        GST_VALIDATE_MONITOR_CAST (gst_validate_bin_monitor_new (GST_BIN_CAST
            (target), runner, parent));
  } else if (GST_IS_ELEMENT (target)) {
    monitor =
        GST_VALIDATE_MONITOR_CAST (gst_validate_element_monitor_new
        (GST_ELEMENT_CAST (target), runner, parent));
  } else {
    g_assert_not_reached ();
  }

  return monitor;
}
static gboolean
gst_validate_element_monitor_do_setup (GstValidateMonitor * monitor)
{
  GstIterator *iterator;
  gboolean done;
  GstPad *pad;
  GstValidateElementMonitor *elem_monitor;
  GstElement *element;
  GstObject *target = gst_validate_monitor_get_target (monitor);

  if (!GST_IS_ELEMENT (target)) {
    gst_object_unref (target);
    GST_WARNING_OBJECT (monitor, "Trying to create element monitor with other "
        "type of object");
    return FALSE;
  }

  elem_monitor = GST_VALIDATE_ELEMENT_MONITOR_CAST (monitor);

  GST_DEBUG_OBJECT (monitor, "Setting up monitor for element %" GST_PTR_FORMAT,
      target);
  element = GST_ELEMENT_CAST (target);

  if (g_object_get_data ((GObject *) element, "validate-monitor")) {
    GST_DEBUG_OBJECT (elem_monitor,
        "Pad already has a validate-monitor associated");
    gst_object_unref (target);
    return FALSE;
  }

  gst_validate_element_monitor_inspect (elem_monitor);

  elem_monitor->pad_added_id = g_signal_connect (element, "pad-added",
      G_CALLBACK (_validate_element_pad_added), monitor);

  iterator = gst_element_iterate_pads (element);
  done = FALSE;
  while (!done) {
    GValue value = { 0, };

    switch (gst_iterator_next (iterator, &value)) {
      case GST_ITERATOR_OK:
        pad = g_value_get_object (&value);
        gst_validate_element_monitor_wrap_pad (elem_monitor, pad);
        g_value_reset (&value);
        break;
      case GST_ITERATOR_RESYNC:
        /* TODO how to handle this? */
        gst_iterator_resync (iterator);
        break;
      case GST_ITERATOR_ERROR:
        done = TRUE;
        break;
      case GST_ITERATOR_DONE:
        done = TRUE;
        break;
    }
  }
  gst_iterator_free (iterator);
  gst_object_unref (target);

  set_config_properties (monitor, element);

  return TRUE;
}