Blame gst/gstelement.c

Packit Service 963350
/* GStreamer
Packit Service 963350
 * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
Packit Service 963350
 *                    2004 Wim Taymans <wim@fluendo.com>
Packit Service 963350
 *
Packit Service 963350
 * gstelement.c: The base element, all elements derive from this
Packit Service 963350
 *
Packit Service 963350
 * This library is free software; you can redistribute it and/or
Packit Service 963350
 * modify it under the terms of the GNU Library General Public
Packit Service 963350
 * License as published by the Free Software Foundation; either
Packit Service 963350
 * version 2 of the License, or (at your option) any later version.
Packit Service 963350
 *
Packit Service 963350
 * This library is distributed in the hope that it will be useful,
Packit Service 963350
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service 963350
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit Service 963350
 * Library General Public License for more details.
Packit Service 963350
 *
Packit Service 963350
 * You should have received a copy of the GNU Library General Public
Packit Service 963350
 * License along with this library; if not, write to the
Packit Service 963350
 * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
Packit Service 963350
 * Boston, MA 02110-1301, USA.
Packit Service 963350
 */
Packit Service 963350
Packit Service 963350
/**
Packit Service 963350
 * SECTION:gstelement
Packit Service 963350
 * @title: GstElement
Packit Service 963350
 * @short_description: Abstract base class for all pipeline elements
Packit Service 963350
 * @see_also: #GstElementFactory, #GstPad
Packit Service 963350
 *
Packit Service 963350
 * GstElement is the abstract base class needed to construct an element that
Packit Service 963350
 * can be used in a GStreamer pipeline. Please refer to the plugin writers
Packit Service 963350
 * guide for more information on creating #GstElement subclasses.
Packit Service 963350
 *
Packit Service 963350
 * The name of a #GstElement can be get with gst_element_get_name() and set with
Packit Service 963350
 * gst_element_set_name().  For speed, GST_ELEMENT_NAME() can be used in the
Packit Service 963350
 * core when using the appropriate locking. Do not use this in plug-ins or
Packit Service 963350
 * applications in order to retain ABI compatibility.
Packit Service 963350
 *
Packit Service 963350
 * Elements can have pads (of the type #GstPad).  These pads link to pads on
Packit Service 963350
 * other elements.  #GstBuffer flow between these linked pads.
Packit Service 963350
 * A #GstElement has a #GList of #GstPad structures for all their input (or sink)
Packit Service 963350
 * and output (or source) pads.
Packit Service 963350
 * Core and plug-in writers can add and remove pads with gst_element_add_pad()
Packit Service 963350
 * and gst_element_remove_pad().
Packit Service 963350
 *
Packit Service 963350
 * An existing pad of an element can be retrieved by name with
Packit Service 963350
 * gst_element_get_static_pad(). A new dynamic pad can be created using
Packit Service 963350
 * gst_element_request_pad() with a #GstPadTemplate.
Packit Service 963350
 * An iterator of all pads can be retrieved with gst_element_iterate_pads().
Packit Service 963350
 *
Packit Service 963350
 * Elements can be linked through their pads.
Packit Service 963350
 * If the link is straightforward, use the gst_element_link()
Packit Service 963350
 * convenience function to link two elements, or gst_element_link_many()
Packit Service 963350
 * for more elements in a row.
Packit Service 963350
 * Use gst_element_link_filtered() to link two elements constrained by
Packit Service 963350
 * a specified set of #GstCaps.
Packit Service 963350
 * For finer control, use gst_element_link_pads() and
Packit Service 963350
 * gst_element_link_pads_filtered() to specify the pads to link on
Packit Service 963350
 * each element by name.
Packit Service 963350
 *
Packit Service 963350
 * Each element has a state (see #GstState).  You can get and set the state
Packit Service 963350
 * of an element with gst_element_get_state() and gst_element_set_state().
Packit Service 963350
 * Setting a state triggers a #GstStateChange. To get a string representation
Packit Service 963350
 * of a #GstState, use gst_element_state_get_name().
Packit Service 963350
 *
Packit Service 963350
 * You can get and set a #GstClock on an element using gst_element_get_clock()
Packit Service 963350
 * and gst_element_set_clock().
Packit Service 963350
 * Some elements can provide a clock for the pipeline if
Packit Service 963350
 * the #GST_ELEMENT_FLAG_PROVIDE_CLOCK flag is set. With the
Packit Service 963350
 * gst_element_provide_clock() method one can retrieve the clock provided by
Packit Service 963350
 * such an element.
Packit Service 963350
 * Not all elements require a clock to operate correctly. If the
Packit Service 963350
 * #GST_ELEMENT_FLAG_REQUIRE_CLOCK() flag is set, a clock should be set on the
Packit Service 963350
 * element with gst_element_set_clock().
Packit Service 963350
 *
Packit Service 963350
 * Note that clock selection and distribution is normally handled by the
Packit Service 963350
 * toplevel #GstPipeline so the clock functions are only to be used in very
Packit Service 963350
 * specific situations.
Packit Service 963350
 */
Packit Service 963350
Packit Service 963350
#include "gst_private.h"
Packit Service 963350
#include <glib.h>
Packit Service 963350
#include <stdarg.h>
Packit Service 963350
#include <gobject/gvaluecollector.h>
Packit Service 963350
Packit Service 963350
#include "gstelement.h"
Packit Service 963350
#include "gstelementmetadata.h"
Packit Service 963350
#include "gstenumtypes.h"
Packit Service 963350
#include "gstbus.h"
Packit Service 963350
#include "gsterror.h"
Packit Service 963350
#include "gstevent.h"
Packit Service 963350
#include "gstutils.h"
Packit Service 963350
#include "gstinfo.h"
Packit Service 963350
#include "gstquark.h"
Packit Service 963350
#include "gsttracerutils.h"
Packit Service 963350
#include "gstvalue.h"
Packit Service 963350
#include "gst-i18n-lib.h"
Packit Service 963350
#include "glib-compat-private.h"
Packit Service 963350
Packit Service 963350
#ifndef GST_DISABLE_GST_DEBUG
Packit Service 963350
#include "printf/printf.h"
Packit Service 963350
#endif
Packit Service 963350
Packit Service 963350
/* Element signals and args */
Packit Service 963350
enum
Packit Service 963350
{
Packit Service 963350
  PAD_ADDED,
Packit Service 963350
  PAD_REMOVED,
Packit Service 963350
  NO_MORE_PADS,
Packit Service 963350
  /* add more above */
Packit Service 963350
  LAST_SIGNAL
Packit Service 963350
};
Packit Service 963350
Packit Service 963350
enum
Packit Service 963350
{
Packit Service 963350
  ARG_0
Packit Service 963350
      /* FILL ME */
Packit Service 963350
};
Packit Service 963350
Packit Service 963350
static void gst_element_class_init (GstElementClass * klass);
Packit Service 963350
static void gst_element_init (GstElement * element);
Packit Service 963350
static void gst_element_base_class_init (gpointer g_class);
Packit Service 963350
Packit Service 963350
static void gst_element_constructed (GObject * object);
Packit Service 963350
static void gst_element_dispose (GObject * object);
Packit Service 963350
static void gst_element_finalize (GObject * object);
Packit Service 963350
Packit Service 963350
static GstStateChangeReturn gst_element_change_state_func (GstElement * element,
Packit Service 963350
    GstStateChange transition);
Packit Service 963350
static GstStateChangeReturn gst_element_get_state_func (GstElement * element,
Packit Service 963350
    GstState * state, GstState * pending, GstClockTime timeout);
Packit Service 963350
static GstStateChangeReturn gst_element_set_state_func (GstElement * element,
Packit Service 963350
    GstState state);
Packit Service 963350
static gboolean gst_element_set_clock_func (GstElement * element,
Packit Service 963350
    GstClock * clock);
Packit Service 963350
static void gst_element_set_bus_func (GstElement * element, GstBus * bus);
Packit Service 963350
static gboolean gst_element_post_message_default (GstElement * element,
Packit Service 963350
    GstMessage * message);
Packit Service 963350
static void gst_element_set_context_default (GstElement * element,
Packit Service 963350
    GstContext * context);
Packit Service 963350
Packit Service 963350
static gboolean gst_element_default_send_event (GstElement * element,
Packit Service 963350
    GstEvent * event);
Packit Service 963350
static gboolean gst_element_default_query (GstElement * element,
Packit Service 963350
    GstQuery * query);
Packit Service 963350
Packit Service 963350
static GstPadTemplate
Packit Service 963350
    * gst_element_class_get_request_pad_template (GstElementClass *
Packit Service 963350
    element_class, const gchar * name);
Packit Service 963350
Packit Service 963350
static void gst_element_call_async_func (gpointer data, gpointer user_data);
Packit Service 963350
Packit Service 963350
static GstObjectClass *parent_class = NULL;
Packit Service 963350
static guint gst_element_signals[LAST_SIGNAL] = { 0 };
Packit Service 963350
Packit Service 963350
static GThreadPool *gst_element_pool = NULL;
Packit Service 963350
Packit Service 963350
/* this is used in gstelementfactory.c:gst_element_register() */
Packit Service 963350
GQuark __gst_elementclass_factory = 0;
Packit Service 963350
Packit Service 963350
GType
Packit Service 963350
gst_element_get_type (void)
Packit Service 963350
{
Packit Service 963350
  static volatile gsize gst_element_type = 0;
Packit Service 963350
Packit Service 963350
  if (g_once_init_enter (&gst_element_type)) {
Packit Service 963350
    GType _type;
Packit Service 963350
    static const GTypeInfo element_info = {
Packit Service 963350
      sizeof (GstElementClass),
Packit Service 963350
      gst_element_base_class_init,
Packit Service 963350
      NULL,                     /* base_class_finalize */
Packit Service 963350
      (GClassInitFunc) gst_element_class_init,
Packit Service 963350
      NULL,
Packit Service 963350
      NULL,
Packit Service 963350
      sizeof (GstElement),
Packit Service 963350
      0,
Packit Service 963350
      (GInstanceInitFunc) gst_element_init,
Packit Service 963350
      NULL
Packit Service 963350
    };
Packit Service 963350
Packit Service 963350
    _type = g_type_register_static (GST_TYPE_OBJECT, "GstElement",
Packit Service 963350
        &element_info, G_TYPE_FLAG_ABSTRACT);
Packit Service 963350
Packit Service 963350
    __gst_elementclass_factory =
Packit Service 963350
        g_quark_from_static_string ("GST_ELEMENTCLASS_FACTORY");
Packit Service 963350
    g_once_init_leave (&gst_element_type, _type);
Packit Service 963350
  }
Packit Service 963350
  return gst_element_type;
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
static void
Packit Service 963350
gst_element_setup_thread_pool (void)
Packit Service 963350
{
Packit Service 963350
  GError *err = NULL;
Packit Service 963350
Packit Service 963350
  GST_DEBUG ("creating element thread pool");
Packit Service 963350
  gst_element_pool =
Packit Service 963350
      g_thread_pool_new ((GFunc) gst_element_call_async_func, NULL, -1, FALSE,
Packit Service 963350
      &err;;
Packit Service 963350
  if (err != NULL) {
Packit Service 963350
    g_critical ("could not alloc threadpool %s", err->message);
Packit Service 963350
    g_clear_error (&err;;
Packit Service 963350
  }
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
static void
Packit Service 963350
gst_element_class_init (GstElementClass * klass)
Packit Service 963350
{
Packit Service 963350
  GObjectClass *gobject_class;
Packit Service 963350
Packit Service 963350
  gobject_class = (GObjectClass *) klass;
Packit Service 963350
Packit Service 963350
  parent_class = g_type_class_peek_parent (klass);
Packit Service 963350
Packit Service 963350
  /**
Packit Service 963350
   * GstElement::pad-added:
Packit Service 963350
   * @gstelement: the object which received the signal
Packit Service 963350
   * @new_pad: the pad that has been added
Packit Service 963350
   *
Packit Service 963350
   * a new #GstPad has been added to the element. Note that this signal will
Packit Service 963350
   * usually be emitted from the context of the streaming thread. Also keep in
Packit Service 963350
   * mind that if you add new elements to the pipeline in the signal handler
Packit Service 963350
   * you will need to set them to the desired target state with
Packit Service 963350
   * gst_element_set_state() or gst_element_sync_state_with_parent().
Packit Service 963350
   */
Packit Service 963350
  gst_element_signals[PAD_ADDED] =
Packit Service 963350
      g_signal_new ("pad-added", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
Packit Service 963350
      G_STRUCT_OFFSET (GstElementClass, pad_added), NULL, NULL,
Packit Service 963350
      g_cclosure_marshal_generic, G_TYPE_NONE, 1, GST_TYPE_PAD);
Packit Service 963350
  /**
Packit Service 963350
   * GstElement::pad-removed:
Packit Service 963350
   * @gstelement: the object which received the signal
Packit Service 963350
   * @old_pad: the pad that has been removed
Packit Service 963350
   *
Packit Service 963350
   * a #GstPad has been removed from the element
Packit Service 963350
   */
Packit Service 963350
  gst_element_signals[PAD_REMOVED] =
Packit Service 963350
      g_signal_new ("pad-removed", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
Packit Service 963350
      G_STRUCT_OFFSET (GstElementClass, pad_removed), NULL, NULL,
Packit Service 963350
      g_cclosure_marshal_generic, G_TYPE_NONE, 1, GST_TYPE_PAD);
Packit Service 963350
  /**
Packit Service 963350
   * GstElement::no-more-pads:
Packit Service 963350
   * @gstelement: the object which received the signal
Packit Service 963350
   *
Packit Service 963350
   * This signals that the element will not generate more dynamic pads.
Packit Service 963350
   * Note that this signal will usually be emitted from the context of
Packit Service 963350
   * the streaming thread.
Packit Service 963350
   */
Packit Service 963350
  gst_element_signals[NO_MORE_PADS] =
Packit Service 963350
      g_signal_new ("no-more-pads", G_TYPE_FROM_CLASS (klass),
Packit Service 963350
      G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstElementClass, no_more_pads), NULL,
Packit Service 963350
      NULL, g_cclosure_marshal_generic, G_TYPE_NONE, 0);
Packit Service 963350
Packit Service 963350
  gobject_class->dispose = gst_element_dispose;
Packit Service 963350
  gobject_class->finalize = gst_element_finalize;
Packit Service 963350
  gobject_class->constructed = gst_element_constructed;
Packit Service 963350
Packit Service 963350
  klass->change_state = GST_DEBUG_FUNCPTR (gst_element_change_state_func);
Packit Service 963350
  klass->set_state = GST_DEBUG_FUNCPTR (gst_element_set_state_func);
Packit Service 963350
  klass->get_state = GST_DEBUG_FUNCPTR (gst_element_get_state_func);
Packit Service 963350
  klass->set_clock = GST_DEBUG_FUNCPTR (gst_element_set_clock_func);
Packit Service 963350
  klass->set_bus = GST_DEBUG_FUNCPTR (gst_element_set_bus_func);
Packit Service 963350
  klass->query = GST_DEBUG_FUNCPTR (gst_element_default_query);
Packit Service 963350
  klass->send_event = GST_DEBUG_FUNCPTR (gst_element_default_send_event);
Packit Service 963350
  klass->numpadtemplates = 0;
Packit Service 963350
  klass->post_message = GST_DEBUG_FUNCPTR (gst_element_post_message_default);
Packit Service 963350
  klass->set_context = GST_DEBUG_FUNCPTR (gst_element_set_context_default);
Packit Service 963350
Packit Service 963350
  klass->elementfactory = NULL;
Packit Service 963350
Packit Service 963350
  gst_element_setup_thread_pool ();
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
static void
Packit Service 963350
gst_element_base_class_init (gpointer g_class)
Packit Service 963350
{
Packit Service 963350
  GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
Packit Service 963350
  GList *node, *padtemplates;
Packit Service 963350
Packit Service 963350
  /* Copy the element details here so elements can inherit the
Packit Service 963350
   * details from their base class and classes only need to set
Packit Service 963350
   * the details in class_init instead of base_init */
Packit Service 963350
  element_class->metadata =
Packit Service 963350
      element_class->metadata ? gst_structure_copy (element_class->metadata) :
Packit Service 963350
      gst_structure_new_empty ("metadata");
Packit Service 963350
Packit Service 963350
  /* Copy the pad templates so elements inherit them
Packit Service 963350
   * from their base class but elements can add pad templates in class_init
Packit Service 963350
   * instead of base_init.
Packit Service 963350
   */
Packit Service 963350
  padtemplates = g_list_copy (element_class->padtemplates);
Packit Service 963350
  for (node = padtemplates; node != NULL; node = node->next) {
Packit Service 963350
    GstPadTemplate *tmpl = (GstPadTemplate *) node->data;
Packit Service 963350
    gst_object_ref (tmpl);
Packit Service 963350
  }
Packit Service 963350
  element_class->padtemplates = padtemplates;
Packit Service 963350
Packit Service 963350
  /* set the factory, see gst_element_register() */
Packit Service 963350
  element_class->elementfactory =
Packit Service 963350
      g_type_get_qdata (G_TYPE_FROM_CLASS (element_class),
Packit Service 963350
      __gst_elementclass_factory);
Packit Service 963350
  GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "type %s : factory %p",
Packit Service 963350
      G_OBJECT_CLASS_NAME (element_class), element_class->elementfactory);
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
static void
Packit Service 963350
gst_element_init (GstElement * element)
Packit Service 963350
{
Packit Service 963350
  GST_STATE (element) = GST_STATE_NULL;
Packit Service 963350
  GST_STATE_TARGET (element) = GST_STATE_NULL;
Packit Service 963350
  GST_STATE_NEXT (element) = GST_STATE_VOID_PENDING;
Packit Service 963350
  GST_STATE_PENDING (element) = GST_STATE_VOID_PENDING;
Packit Service 963350
  GST_STATE_RETURN (element) = GST_STATE_CHANGE_SUCCESS;
Packit Service 963350
Packit Service 963350
  g_rec_mutex_init (&element->state_lock);
Packit Service 963350
  g_cond_init (&element->state_cond);
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
static void
Packit Service 963350
gst_element_constructed (GObject * object)
Packit Service 963350
{
Packit Service 963350
  GST_TRACER_ELEMENT_NEW (GST_ELEMENT_CAST (object));
Packit Service 963350
  G_OBJECT_CLASS (parent_class)->constructed (object);
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
/**
Packit Service 963350
 * gst_element_release_request_pad:
Packit Service 963350
 * @element: a #GstElement to release the request pad of.
Packit Service 963350
 * @pad: the #GstPad to release.
Packit Service 963350
 *
Packit Service 963350
 * Makes the element free the previously requested pad as obtained
Packit Service 963350
 * with gst_element_request_pad().
Packit Service 963350
 *
Packit Service 963350
 * This does not unref the pad. If the pad was created by using
Packit Service 963350
 * gst_element_request_pad(), gst_element_release_request_pad() needs to be
Packit Service 963350
 * followed by gst_object_unref() to free the @pad.
Packit Service 963350
 *
Packit Service 963350
 * MT safe.
Packit Service 963350
 */
Packit Service 963350
void
Packit Service 963350
gst_element_release_request_pad (GstElement * element, GstPad * pad)
Packit Service 963350
{
Packit Service 963350
  GstElementClass *oclass;
Packit Service 963350
Packit Service 963350
  g_return_if_fail (GST_IS_ELEMENT (element));
Packit Service 963350
  g_return_if_fail (GST_IS_PAD (pad));
Packit Service 963350
  g_return_if_fail (GST_PAD_PAD_TEMPLATE (pad) == NULL ||
Packit Service 963350
      GST_PAD_TEMPLATE_PRESENCE (GST_PAD_PAD_TEMPLATE (pad)) ==
Packit Service 963350
      GST_PAD_REQUEST);
Packit Service 963350
  g_return_if_fail (GST_PAD_PARENT (pad) == element);
Packit Service 963350
Packit Service 963350
  oclass = GST_ELEMENT_GET_CLASS (element);
Packit Service 963350
Packit Service 963350
  /* if the element implements a custom release function we call that, else we
Packit Service 963350
   * simply remove the pad from the element */
Packit Service 963350
  if (oclass->release_pad)
Packit Service 963350
    oclass->release_pad (element, pad);
Packit Service 963350
  else
Packit Service 963350
    gst_element_remove_pad (element, pad);
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
/**
Packit Service 963350
 * gst_element_provide_clock:
Packit Service 963350
 * @element: a #GstElement to query
Packit Service 963350
 *
Packit Service 963350
 * Get the clock provided by the given element.
Packit Service 963350
 * > An element is only required to provide a clock in the PAUSED
Packit Service 963350
 * > state. Some elements can provide a clock in other states.
Packit Service 963350
 *
Packit Service 963350
 * Returns: (transfer full) (nullable): the GstClock provided by the
Packit Service 963350
 * element or %NULL if no clock could be provided.  Unref after usage.
Packit Service 963350
 *
Packit Service 963350
 * MT safe.
Packit Service 963350
 */
Packit Service 963350
GstClock *
Packit Service 963350
gst_element_provide_clock (GstElement * element)
Packit Service 963350
{
Packit Service 963350
  GstClock *result = NULL;
Packit Service 963350
  GstElementClass *oclass;
Packit Service 963350
Packit Service 963350
  g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
Packit Service 963350
Packit Service 963350
  oclass = GST_ELEMENT_GET_CLASS (element);
Packit Service 963350
Packit Service 963350
  if (oclass->provide_clock)
Packit Service 963350
    result = oclass->provide_clock (element);
Packit Service 963350
Packit Service 963350
  return result;
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
static gboolean
Packit Service 963350
gst_element_set_clock_func (GstElement * element, GstClock * clock)
Packit Service 963350
{
Packit Service 963350
  GstClock **clock_p;
Packit Service 963350
Packit Service 963350
  GST_OBJECT_LOCK (element);
Packit Service 963350
  clock_p = &element->clock;
Packit Service 963350
  gst_object_replace ((GstObject **) clock_p, (GstObject *) clock);
Packit Service 963350
  GST_OBJECT_UNLOCK (element);
Packit Service 963350
Packit Service 963350
  return TRUE;
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
/**
Packit Service 963350
 * gst_element_set_clock:
Packit Service 963350
 * @element: a #GstElement to set the clock for.
Packit Service 963350
 * @clock: (transfer none) (allow-none): the #GstClock to set for the element.
Packit Service 963350
 *
Packit Service 963350
 * Sets the clock for the element. This function increases the
Packit Service 963350
 * refcount on the clock. Any previously set clock on the object
Packit Service 963350
 * is unreffed.
Packit Service 963350
 *
Packit Service 963350
 * Returns: %TRUE if the element accepted the clock. An element can refuse a
Packit Service 963350
 * clock when it, for example, is not able to slave its internal clock to the
Packit Service 963350
 * @clock or when it requires a specific clock to operate.
Packit Service 963350
 *
Packit Service 963350
 * MT safe.
Packit Service 963350
 */
Packit Service 963350
gboolean
Packit Service 963350
gst_element_set_clock (GstElement * element, GstClock * clock)
Packit Service 963350
{
Packit Service 963350
  GstElementClass *oclass;
Packit Service 963350
  gboolean res = FALSE;
Packit Service 963350
Packit Service 963350
  g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
Packit Service 963350
  g_return_val_if_fail (clock == NULL || GST_IS_CLOCK (clock), FALSE);
Packit Service 963350
Packit Service 963350
  oclass = GST_ELEMENT_GET_CLASS (element);
Packit Service 963350
Packit Service 963350
  GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, element, "setting clock %p", clock);
Packit Service 963350
Packit Service 963350
  if (oclass->set_clock)
Packit Service 963350
    res = oclass->set_clock (element, clock);
Packit Service 963350
Packit Service 963350
  return res;
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
/**
Packit Service 963350
 * gst_element_get_clock:
Packit Service 963350
 * @element: a #GstElement to get the clock of.
Packit Service 963350
 *
Packit Service 963350
 * Gets the currently configured clock of the element. This is the clock as was
Packit Service 963350
 * last set with gst_element_set_clock().
Packit Service 963350
 *
Packit Service 963350
 * Elements in a pipeline will only have their clock set when the
Packit Service 963350
 * pipeline is in the PLAYING state.
Packit Service 963350
 *
Packit Service 963350
 * Returns: (transfer full) (nullable): the #GstClock of the element. unref after usage.
Packit Service 963350
 *
Packit Service 963350
 * MT safe.
Packit Service 963350
 */
Packit Service 963350
GstClock *
Packit Service 963350
gst_element_get_clock (GstElement * element)
Packit Service 963350
{
Packit Service 963350
  GstClock *result;
Packit Service 963350
Packit Service 963350
  g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
Packit Service 963350
Packit Service 963350
  GST_OBJECT_LOCK (element);
Packit Service 963350
  if ((result = element->clock))
Packit Service 963350
    gst_object_ref (result);
Packit Service 963350
  GST_OBJECT_UNLOCK (element);
Packit Service 963350
Packit Service 963350
  return result;
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
/**
Packit Service 963350
 * gst_element_set_base_time:
Packit Service 963350
 * @element: a #GstElement.
Packit Service 963350
 * @time: the base time to set.
Packit Service 963350
 *
Packit Service 963350
 * Set the base time of an element. See gst_element_get_base_time().
Packit Service 963350
 *
Packit Service 963350
 * MT safe.
Packit Service 963350
 */
Packit Service 963350
void
Packit Service 963350
gst_element_set_base_time (GstElement * element, GstClockTime time)
Packit Service 963350
{
Packit Service 963350
  GstClockTime old;
Packit Service 963350
Packit Service 963350
  g_return_if_fail (GST_IS_ELEMENT (element));
Packit Service 963350
Packit Service 963350
  GST_OBJECT_LOCK (element);
Packit Service 963350
  old = element->base_time;
Packit Service 963350
  element->base_time = time;
Packit Service 963350
  GST_OBJECT_UNLOCK (element);
Packit Service 963350
Packit Service 963350
  GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, element,
Packit Service 963350
      "set base_time=%" GST_TIME_FORMAT ", old %" GST_TIME_FORMAT,
Packit Service 963350
      GST_TIME_ARGS (time), GST_TIME_ARGS (old));
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
/**
Packit Service 963350
 * gst_element_get_base_time:
Packit Service 963350
 * @element: a #GstElement.
Packit Service 963350
 *
Packit Service 963350
 * Returns the base time of the element. The base time is the
Packit Service 963350
 * absolute time of the clock when this element was last put to
Packit Service 963350
 * PLAYING. Subtracting the base time from the clock time gives
Packit Service 963350
 * the running time of the element.
Packit Service 963350
 *
Packit Service 963350
 * Returns: the base time of the element.
Packit Service 963350
 *
Packit Service 963350
 * MT safe.
Packit Service 963350
 */
Packit Service 963350
GstClockTime
Packit Service 963350
gst_element_get_base_time (GstElement * element)
Packit Service 963350
{
Packit Service 963350
  GstClockTime result;
Packit Service 963350
Packit Service 963350
  g_return_val_if_fail (GST_IS_ELEMENT (element), GST_CLOCK_TIME_NONE);
Packit Service 963350
Packit Service 963350
  GST_OBJECT_LOCK (element);
Packit Service 963350
  result = element->base_time;
Packit Service 963350
  GST_OBJECT_UNLOCK (element);
Packit Service 963350
Packit Service 963350
  return result;
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
/**
Packit Service 963350
 * gst_element_set_start_time:
Packit Service 963350
 * @element: a #GstElement.
Packit Service 963350
 * @time: the base time to set.
Packit Service 963350
 *
Packit Service 963350
 * Set the start time of an element. The start time of the element is the
Packit Service 963350
 * running time of the element when it last went to the PAUSED state. In READY
Packit Service 963350
 * or after a flushing seek, it is set to 0.
Packit Service 963350
 *
Packit Service 963350
 * Toplevel elements like #GstPipeline will manage the start_time and
Packit Service 963350
 * base_time on its children. Setting the start_time to #GST_CLOCK_TIME_NONE
Packit Service 963350
 * on such a toplevel element will disable the distribution of the base_time to
Packit Service 963350
 * the children and can be useful if the application manages the base_time
Packit Service 963350
 * itself, for example if you want to synchronize capture from multiple
Packit Service 963350
 * pipelines, and you can also ensure that the pipelines have the same clock.
Packit Service 963350
 *
Packit Service 963350
 * MT safe.
Packit Service 963350
 */
Packit Service 963350
void
Packit Service 963350
gst_element_set_start_time (GstElement * element, GstClockTime time)
Packit Service 963350
{
Packit Service 963350
  GstClockTime old;
Packit Service 963350
Packit Service 963350
  g_return_if_fail (GST_IS_ELEMENT (element));
Packit Service 963350
Packit Service 963350
  GST_OBJECT_LOCK (element);
Packit Service 963350
  old = GST_ELEMENT_START_TIME (element);
Packit Service 963350
  GST_ELEMENT_START_TIME (element) = time;
Packit Service 963350
  GST_OBJECT_UNLOCK (element);
Packit Service 963350
Packit Service 963350
  GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, element,
Packit Service 963350
      "set start_time=%" GST_TIME_FORMAT ", old %" GST_TIME_FORMAT,
Packit Service 963350
      GST_TIME_ARGS (time), GST_TIME_ARGS (old));
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
/**
Packit Service 963350
 * gst_element_get_start_time:
Packit Service 963350
 * @element: a #GstElement.
Packit Service 963350
 *
Packit Service 963350
 * Returns the start time of the element. The start time is the
Packit Service 963350
 * running time of the clock when this element was last put to PAUSED.
Packit Service 963350
 *
Packit Service 963350
 * Usually the start_time is managed by a toplevel element such as
Packit Service 963350
 * #GstPipeline.
Packit Service 963350
 *
Packit Service 963350
 * MT safe.
Packit Service 963350
 *
Packit Service 963350
 * Returns: the start time of the element.
Packit Service 963350
 */
Packit Service 963350
GstClockTime
Packit Service 963350
gst_element_get_start_time (GstElement * element)
Packit Service 963350
{
Packit Service 963350
  GstClockTime result;
Packit Service 963350
Packit Service 963350
  g_return_val_if_fail (GST_IS_ELEMENT (element), GST_CLOCK_TIME_NONE);
Packit Service 963350
Packit Service 963350
  GST_OBJECT_LOCK (element);
Packit Service 963350
  result = GST_ELEMENT_START_TIME (element);
Packit Service 963350
  GST_OBJECT_UNLOCK (element);
Packit Service 963350
Packit Service 963350
  return result;
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
#if 0
Packit Service 963350
/**
Packit Service 963350
 * gst_element_set_index:
Packit Service 963350
 * @element: a #GstElement.
Packit Service 963350
 * @index: (transfer none): a #GstIndex.
Packit Service 963350
 *
Packit Service 963350
 * Set @index on the element. The refcount of the index
Packit Service 963350
 * will be increased, any previously set index is unreffed.
Packit Service 963350
 *
Packit Service 963350
 * MT safe.
Packit Service 963350
 */
Packit Service 963350
void
Packit Service 963350
gst_element_set_index (GstElement * element, GstIndex * index)
Packit Service 963350
{
Packit Service 963350
  GstElementClass *oclass;
Packit Service 963350
Packit Service 963350
  g_return_if_fail (GST_IS_ELEMENT (element));
Packit Service 963350
  g_return_if_fail (index == NULL || GST_IS_INDEX (index));
Packit Service 963350
Packit Service 963350
  oclass = GST_ELEMENT_GET_CLASS (element);
Packit Service 963350
Packit Service 963350
  if (oclass->set_index)
Packit Service 963350
    oclass->set_index (element, index);
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
/**
Packit Service 963350
 * gst_element_get_index:
Packit Service 963350
 * @element: a #GstElement.
Packit Service 963350
 *
Packit Service 963350
 * Gets the index from the element.
Packit Service 963350
 *
Packit Service 963350
 * Returns: (transfer full) (nullable): a #GstIndex or %NULL when no
Packit Service 963350
 * index was set on the element. unref after usage.
Packit Service 963350
 *
Packit Service 963350
 * MT safe.
Packit Service 963350
 */
Packit Service 963350
GstIndex *
Packit Service 963350
gst_element_get_index (GstElement * element)
Packit Service 963350
{
Packit Service 963350
  GstElementClass *oclass;
Packit Service 963350
  GstIndex *result = NULL;
Packit Service 963350
Packit Service 963350
  g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
Packit Service 963350
Packit Service 963350
  oclass = GST_ELEMENT_GET_CLASS (element);
Packit Service 963350
Packit Service 963350
  if (oclass->get_index)
Packit Service 963350
    result = oclass->get_index (element);
Packit Service 963350
Packit Service 963350
  return result;
Packit Service 963350
}
Packit Service 963350
#endif
Packit Service 963350
Packit Service 963350
/**
Packit Service 963350
 * gst_element_add_pad:
Packit Service 963350
 * @element: a #GstElement to add the pad to.
Packit Service 963350
 * @pad: (transfer floating): the #GstPad to add to the element.
Packit Service 963350
 *
Packit Service 963350
 * Adds a pad (link point) to @element. @pad's parent will be set to @element;
Packit Service 963350
 * see gst_object_set_parent() for refcounting information.
Packit Service 963350
 *
Packit Service 963350
 * Pads are not automatically activated so elements should perform the needed
Packit Service 963350
 * steps to activate the pad in case this pad is added in the PAUSED or PLAYING
Packit Service 963350
 * state. See gst_pad_set_active() for more information about activating pads.
Packit Service 963350
 *
Packit Service 963350
 * The pad and the element should be unlocked when calling this function.
Packit Service 963350
 *
Packit Service 963350
 * This function will emit the #GstElement::pad-added signal on the element.
Packit Service 963350
 *
Packit Service 963350
 * Returns: %TRUE if the pad could be added. This function can fail when
Packit Service 963350
 * a pad with the same name already existed or the pad already had another
Packit Service 963350
 * parent.
Packit Service 963350
 *
Packit Service 963350
 * MT safe.
Packit Service 963350
 */
Packit Service 963350
gboolean
Packit Service 963350
gst_element_add_pad (GstElement * element, GstPad * pad)
Packit Service 963350
{
Packit Service 963350
  gchar *pad_name;
Packit Service 963350
  gboolean active;
Packit Service 963350
Packit Service 963350
  g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
Packit Service 963350
  g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
Packit Service 963350
Packit Service 963350
  /* locking pad to look at the name */
Packit Service 963350
  GST_OBJECT_LOCK (pad);
Packit Service 963350
  pad_name = g_strdup (GST_PAD_NAME (pad));
Packit Service 963350
  GST_CAT_INFO_OBJECT (GST_CAT_ELEMENT_PADS, element, "adding pad '%s'",
Packit Service 963350
      GST_STR_NULL (pad_name));
Packit Service 963350
  active = GST_PAD_IS_ACTIVE (pad);
Packit Service 963350
  GST_OBJECT_FLAG_SET (pad, GST_PAD_FLAG_NEED_PARENT);
Packit Service 963350
  GST_OBJECT_UNLOCK (pad);
Packit Service 963350
Packit Service 963350
  /* then check to see if there's already a pad by that name here */
Packit Service 963350
  GST_OBJECT_LOCK (element);
Packit Service 963350
  if (G_UNLIKELY (!gst_object_check_uniqueness (element->pads, pad_name)))
Packit Service 963350
    goto name_exists;
Packit Service 963350
Packit Service 963350
  /* try to set the pad's parent */
Packit Service 963350
  if (G_UNLIKELY (!gst_object_set_parent (GST_OBJECT_CAST (pad),
Packit Service 963350
              GST_OBJECT_CAST (element))))
Packit Service 963350
    goto had_parent;
Packit Service 963350
Packit Service 963350
  /* check for active pads */
Packit Service 963350
  if (!active && (GST_STATE (element) > GST_STATE_READY ||
Packit Service 963350
          GST_STATE_NEXT (element) == GST_STATE_PAUSED)) {
Packit Service 963350
    g_warning ("adding inactive pad '%s' to running element '%s', you need to "
Packit Service 963350
        "use gst_pad_set_active(pad,TRUE) before adding it.",
Packit Service 963350
        GST_STR_NULL (pad_name), GST_ELEMENT_NAME (element));
Packit Service 963350
    gst_pad_set_active (pad, TRUE);
Packit Service 963350
  }
Packit Service 963350
Packit Service 963350
  g_free (pad_name);
Packit Service 963350
Packit Service 963350
  /* add it to the list */
Packit Service 963350
  switch (gst_pad_get_direction (pad)) {
Packit Service 963350
    case GST_PAD_SRC:
Packit Service 963350
      element->srcpads = g_list_append (element->srcpads, pad);
Packit Service 963350
      element->numsrcpads++;
Packit Service 963350
      break;
Packit Service 963350
    case GST_PAD_SINK:
Packit Service 963350
      element->sinkpads = g_list_append (element->sinkpads, pad);
Packit Service 963350
      element->numsinkpads++;
Packit Service 963350
      break;
Packit Service 963350
    default:
Packit Service 963350
      goto no_direction;
Packit Service 963350
  }
Packit Service 963350
  element->pads = g_list_append (element->pads, pad);
Packit Service 963350
  element->numpads++;
Packit Service 963350
  element->pads_cookie++;
Packit Service 963350
  GST_OBJECT_UNLOCK (element);
Packit Service 963350
Packit Service 963350
  /* emit the PAD_ADDED signal */
Packit Service 963350
  g_signal_emit (element, gst_element_signals[PAD_ADDED], 0, pad);
Packit Service 963350
  GST_TRACER_ELEMENT_ADD_PAD (element, pad);
Packit Service 963350
  return TRUE;
Packit Service 963350
Packit Service 963350
  /* ERROR cases */
Packit Service 963350
name_exists:
Packit Service 963350
  {
Packit Service 963350
    g_critical ("Padname %s is not unique in element %s, not adding",
Packit Service 963350
        pad_name, GST_ELEMENT_NAME (element));
Packit Service 963350
    GST_OBJECT_UNLOCK (element);
Packit Service 963350
    g_free (pad_name);
Packit Service 963350
    gst_object_ref_sink (pad);
Packit Service 963350
    gst_object_unref (pad);
Packit Service 963350
    return FALSE;
Packit Service 963350
  }
Packit Service 963350
had_parent:
Packit Service 963350
  {
Packit Service 963350
    g_critical
Packit Service 963350
        ("Pad %s already has parent when trying to add to element %s",
Packit Service 963350
        pad_name, GST_ELEMENT_NAME (element));
Packit Service 963350
    GST_OBJECT_UNLOCK (element);
Packit Service 963350
    g_free (pad_name);
Packit Service 963350
    return FALSE;
Packit Service 963350
  }
Packit Service 963350
no_direction:
Packit Service 963350
  {
Packit Service 963350
    GST_OBJECT_LOCK (pad);
Packit Service 963350
    g_critical
Packit Service 963350
        ("Trying to add pad %s to element %s, but it has no direction",
Packit Service 963350
        GST_OBJECT_NAME (pad), GST_ELEMENT_NAME (element));
Packit Service 963350
    GST_OBJECT_UNLOCK (pad);
Packit Service 963350
    GST_OBJECT_UNLOCK (element);
Packit Service 963350
    return FALSE;
Packit Service 963350
  }
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
/**
Packit Service 963350
 * gst_element_remove_pad:
Packit Service 963350
 * @element: a #GstElement to remove pad from.
Packit Service 963350
 * @pad: (transfer none): the #GstPad to remove from the element.
Packit Service 963350
 *
Packit Service 963350
 * Removes @pad from @element. @pad will be destroyed if it has not been
Packit Service 963350
 * referenced elsewhere using gst_object_unparent().
Packit Service 963350
 *
Packit Service 963350
 * This function is used by plugin developers and should not be used
Packit Service 963350
 * by applications. Pads that were dynamically requested from elements
Packit Service 963350
 * with gst_element_request_pad() should be released with the
Packit Service 963350
 * gst_element_release_request_pad() function instead.
Packit Service 963350
 *
Packit Service 963350
 * Pads are not automatically deactivated so elements should perform the needed
Packit Service 963350
 * steps to deactivate the pad in case this pad is removed in the PAUSED or
Packit Service 963350
 * PLAYING state. See gst_pad_set_active() for more information about
Packit Service 963350
 * deactivating pads.
Packit Service 963350
 *
Packit Service 963350
 * The pad and the element should be unlocked when calling this function.
Packit Service 963350
 *
Packit Service 963350
 * This function will emit the #GstElement::pad-removed signal on the element.
Packit Service 963350
 *
Packit Service 963350
 * Returns: %TRUE if the pad could be removed. Can return %FALSE if the
Packit Service 963350
 * pad does not belong to the provided element.
Packit Service 963350
 *
Packit Service 963350
 * MT safe.
Packit Service 963350
 */
Packit Service 963350
gboolean
Packit Service 963350
gst_element_remove_pad (GstElement * element, GstPad * pad)
Packit Service 963350
{
Packit Service 963350
  GstPad *peer;
Packit Service 963350
Packit Service 963350
  g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
Packit Service 963350
  g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
Packit Service 963350
Packit Service 963350
  /* locking pad to look at the name and parent */
Packit Service 963350
  GST_OBJECT_LOCK (pad);
Packit Service 963350
  GST_CAT_INFO_OBJECT (GST_CAT_ELEMENT_PADS, element, "removing pad '%s'",
Packit Service 963350
      GST_STR_NULL (GST_PAD_NAME (pad)));
Packit Service 963350
Packit Service 963350
  if (G_UNLIKELY (GST_PAD_PARENT (pad) != element))
Packit Service 963350
    goto not_our_pad;
Packit Service 963350
  GST_OBJECT_UNLOCK (pad);
Packit Service 963350
Packit Service 963350
  /* unlink */
Packit Service 963350
  if ((peer = gst_pad_get_peer (pad))) {
Packit Service 963350
    /* window for MT unsafeness, someone else could unlink here
Packit Service 963350
     * and then we call unlink with wrong pads. The unlink
Packit Service 963350
     * function would catch this and safely return failed. */
Packit Service 963350
    if (GST_PAD_IS_SRC (pad))
Packit Service 963350
      gst_pad_unlink (pad, peer);
Packit Service 963350
    else
Packit Service 963350
      gst_pad_unlink (peer, pad);
Packit Service 963350
Packit Service 963350
    gst_object_unref (peer);
Packit Service 963350
  }
Packit Service 963350
Packit Service 963350
  GST_OBJECT_LOCK (element);
Packit Service 963350
  /* remove it from the list */
Packit Service 963350
  switch (gst_pad_get_direction (pad)) {
Packit Service 963350
    case GST_PAD_SRC:
Packit Service 963350
      element->srcpads = g_list_remove (element->srcpads, pad);
Packit Service 963350
      element->numsrcpads--;
Packit Service 963350
      break;
Packit Service 963350
    case GST_PAD_SINK:
Packit Service 963350
      element->sinkpads = g_list_remove (element->sinkpads, pad);
Packit Service 963350
      element->numsinkpads--;
Packit Service 963350
      break;
Packit Service 963350
    default:
Packit Service 963350
      g_critical ("Removing pad without direction???");
Packit Service 963350
      break;
Packit Service 963350
  }
Packit Service 963350
  element->pads = g_list_remove (element->pads, pad);
Packit Service 963350
  element->numpads--;
Packit Service 963350
  element->pads_cookie++;
Packit Service 963350
  GST_OBJECT_UNLOCK (element);
Packit Service 963350
Packit Service 963350
  /* emit the PAD_REMOVED signal before unparenting and losing the last ref. */
Packit Service 963350
  g_signal_emit (element, gst_element_signals[PAD_REMOVED], 0, pad);
Packit Service 963350
  GST_TRACER_ELEMENT_REMOVE_PAD (element, pad);
Packit Service 963350
  gst_object_unparent (GST_OBJECT_CAST (pad));
Packit Service 963350
Packit Service 963350
  return TRUE;
Packit Service 963350
Packit Service 963350
  /* ERRORS */
Packit Service 963350
not_our_pad:
Packit Service 963350
  {
Packit Service 963350
    /* locking order is element > pad */
Packit Service 963350
    GST_OBJECT_UNLOCK (pad);
Packit Service 963350
Packit Service 963350
    GST_OBJECT_LOCK (element);
Packit Service 963350
    GST_OBJECT_LOCK (pad);
Packit Service 963350
    g_critical ("Padname %s:%s does not belong to element %s when removing",
Packit Service 963350
        GST_DEBUG_PAD_NAME (pad), GST_ELEMENT_NAME (element));
Packit Service 963350
    GST_OBJECT_UNLOCK (pad);
Packit Service 963350
    GST_OBJECT_UNLOCK (element);
Packit Service 963350
    return FALSE;
Packit Service 963350
  }
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
/**
Packit Service 963350
 * gst_element_no_more_pads:
Packit Service 963350
 * @element: a #GstElement
Packit Service 963350
 *
Packit Service 963350
 * Use this function to signal that the element does not expect any more pads
Packit Service 963350
 * to show up in the current pipeline. This function should be called whenever
Packit Service 963350
 * pads have been added by the element itself. Elements with #GST_PAD_SOMETIMES
Packit Service 963350
 * pad templates use this in combination with autopluggers to figure out that
Packit Service 963350
 * the element is done initializing its pads.
Packit Service 963350
 *
Packit Service 963350
 * This function emits the #GstElement::no-more-pads signal.
Packit Service 963350
 *
Packit Service 963350
 * MT safe.
Packit Service 963350
 */
Packit Service 963350
void
Packit Service 963350
gst_element_no_more_pads (GstElement * element)
Packit Service 963350
{
Packit Service 963350
  g_return_if_fail (GST_IS_ELEMENT (element));
Packit Service 963350
Packit Service 963350
  g_signal_emit (element, gst_element_signals[NO_MORE_PADS], 0);
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
static gint
Packit Service 963350
pad_compare_name (GstPad * pad1, const gchar * name)
Packit Service 963350
{
Packit Service 963350
  gint result;
Packit Service 963350
Packit Service 963350
  GST_OBJECT_LOCK (pad1);
Packit Service 963350
  result = strcmp (GST_PAD_NAME (pad1), name);
Packit Service 963350
  GST_OBJECT_UNLOCK (pad1);
Packit Service 963350
Packit Service 963350
  return result;
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
/**
Packit Service 963350
 * gst_element_get_static_pad:
Packit Service 963350
 * @element: a #GstElement to find a static pad of.
Packit Service 963350
 * @name: the name of the static #GstPad to retrieve.
Packit Service 963350
 *
Packit Service 963350
 * Retrieves a pad from @element by name. This version only retrieves
Packit Service 963350
 * already-existing (i.e. 'static') pads.
Packit Service 963350
 *
Packit Service 963350
 * Returns: (transfer full) (nullable): the requested #GstPad if
Packit Service 963350
 *     found, otherwise %NULL.  unref after usage.
Packit Service 963350
 *
Packit Service 963350
 * MT safe.
Packit Service 963350
 */
Packit Service 963350
GstPad *
Packit Service 963350
gst_element_get_static_pad (GstElement * element, const gchar * name)
Packit Service 963350
{
Packit Service 963350
  GList *find;
Packit Service 963350
  GstPad *result = NULL;
Packit Service 963350
Packit Service 963350
  g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
Packit Service 963350
  g_return_val_if_fail (name != NULL, NULL);
Packit Service 963350
Packit Service 963350
  GST_OBJECT_LOCK (element);
Packit Service 963350
  find =
Packit Service 963350
      g_list_find_custom (element->pads, name, (GCompareFunc) pad_compare_name);
Packit Service 963350
  if (find) {
Packit Service 963350
    result = GST_PAD_CAST (find->data);
Packit Service 963350
    gst_object_ref (result);
Packit Service 963350
  }
Packit Service 963350
Packit Service 963350
  if (result == NULL) {
Packit Service 963350
    GST_CAT_INFO (GST_CAT_ELEMENT_PADS, "no such pad '%s' in element \"%s\"",
Packit Service 963350
        name, GST_ELEMENT_NAME (element));
Packit Service 963350
  } else {
Packit Service 963350
    GST_CAT_INFO (GST_CAT_ELEMENT_PADS, "found pad %s:%s",
Packit Service 963350
        GST_ELEMENT_NAME (element), name);
Packit Service 963350
  }
Packit Service 963350
  GST_OBJECT_UNLOCK (element);
Packit Service 963350
Packit Service 963350
  return result;
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
static gboolean
Packit Service 963350
gst_element_is_valid_request_template_name (const gchar * templ_name,
Packit Service 963350
    const gchar * name)
Packit Service 963350
{
Packit Service 963350
  gchar *endptr;
Packit Service 963350
  const gchar *templ_name_ptr, *name_ptr;
Packit Service 963350
  gboolean next_specifier;
Packit Service 963350
  guint templ_postfix_len = 0, name_postfix_len = 0;
Packit Service 963350
Packit Service 963350
  g_return_val_if_fail (templ_name != NULL, FALSE);
Packit Service 963350
  g_return_val_if_fail (name != NULL, FALSE);
Packit Service 963350
Packit Service 963350
  /* Is this the template name? */
Packit Service 963350
  if (strcmp (templ_name, name) == 0)
Packit Service 963350
    return TRUE;
Packit Service 963350
Packit Service 963350
  /* otherwise check all the specifiers */
Packit Service 963350
  do {
Packit Service 963350
    /* Because of sanity checks in gst_pad_template_new(), we know that %s
Packit Service 963350
     * and %d and %u, occurring at the template_name */
Packit Service 963350
    templ_name_ptr = strchr (templ_name, '%');
Packit Service 963350
Packit Service 963350
    /* check characters ahead of the specifier */
Packit Service 963350
    if (!templ_name_ptr || strlen (name) <= templ_name_ptr - templ_name
Packit Service 963350
        || strncmp (templ_name, name, templ_name_ptr - templ_name) != 0) {
Packit Service 963350
      return FALSE;
Packit Service 963350
    }
Packit Service 963350
Packit Service 963350
    /* %s is not allowed for multiple specifiers, just a single specifier can be
Packit Service 963350
     * accepted in gst_pad_template_new() and can not be mixed with other
Packit Service 963350
     * specifier '%u' and '%d' */
Packit Service 963350
    if (*(templ_name_ptr + 1) == 's' && g_strcmp0 (templ_name, name) == 0) {
Packit Service 963350
      return TRUE;
Packit Service 963350
    }
Packit Service 963350
Packit Service 963350
    name_ptr = name + (templ_name_ptr - templ_name);
Packit Service 963350
Packit Service 963350
    /* search next specifier, each of specifier should be separated by '_' */
Packit Service 963350
    templ_name = strchr (templ_name_ptr, '_');
Packit Service 963350
    name = strchr (name_ptr, '_');
Packit Service 963350
Packit Service 963350
    /* don't match the number of specifiers */
Packit Service 963350
    if ((templ_name && !name) || (!templ_name && name))
Packit Service 963350
      return FALSE;
Packit Service 963350
Packit Service 963350
    if (templ_name && name)
Packit Service 963350
      next_specifier = TRUE;
Packit Service 963350
    else
Packit Service 963350
      next_specifier = FALSE;
Packit Service 963350
Packit Service 963350
    /* check characters followed by the specifier */
Packit Service 963350
    if (*(templ_name_ptr + 2) != '\0' && *(templ_name_ptr + 2) != '_') {
Packit Service 963350
      if (next_specifier) {
Packit Service 963350
        templ_postfix_len = templ_name - (templ_name_ptr + 2);
Packit Service 963350
        name_postfix_len = name - name_ptr;
Packit Service 963350
      } else {
Packit Service 963350
        templ_postfix_len = strlen (templ_name_ptr + 2);
Packit Service 963350
        name_postfix_len = strlen (name_ptr);
Packit Service 963350
      }
Packit Service 963350
Packit Service 963350
      if (strncmp (templ_name_ptr + 2,
Packit Service 963350
              name_ptr + name_postfix_len - templ_postfix_len,
Packit Service 963350
              templ_postfix_len) != 0) {
Packit Service 963350
        return FALSE;
Packit Service 963350
      }
Packit Service 963350
    }
Packit Service 963350
Packit Service 963350
    /* verify the specifier */
Packit Service 963350
    if (*(name_ptr) == '%') {
Packit Service 963350
      guint len;
Packit Service 963350
Packit Service 963350
      len = (next_specifier) ? name - name_ptr : strlen (name_ptr);
Packit Service 963350
Packit Service 963350
      if (strncmp (name_ptr, templ_name_ptr, len) != 0)
Packit Service 963350
        return FALSE;
Packit Service 963350
Packit Service 963350
    } else {
Packit Service 963350
      const gchar *specifier;
Packit Service 963350
      gchar *target = NULL;
Packit Service 963350
Packit Service 963350
      /* extract specifier when it has postfix characters */
Packit Service 963350
      if (name_postfix_len > templ_postfix_len) {
Packit Service 963350
        target = g_strndup (name_ptr, name_postfix_len - templ_postfix_len);
Packit Service 963350
      }
Packit Service 963350
      specifier = target ? target : name_ptr;
Packit Service 963350
Packit Service 963350
      if (*(templ_name_ptr + 1) == 'd') {
Packit Service 963350
        gint64 tmp;
Packit Service 963350
Packit Service 963350
        /* it's an int */
Packit Service 963350
        tmp = g_ascii_strtoll (specifier, &endptr, 10);
Packit Service 963350
        if (tmp < G_MININT || tmp > G_MAXINT || (*endptr != '\0'
Packit Service 963350
                && *endptr != '_'))
Packit Service 963350
          return FALSE;
Packit Service 963350
      } else if (*(templ_name_ptr + 1) == 'u') {
Packit Service 963350
        guint64 tmp;
Packit Service 963350
Packit Service 963350
        /* it's an int */
Packit Service 963350
        tmp = g_ascii_strtoull (specifier, &endptr, 10);
Packit Service 963350
        if (tmp > G_MAXUINT || (*endptr != '\0' && *endptr != '_'))
Packit Service 963350
          return FALSE;
Packit Service 963350
      }
Packit Service 963350
Packit Service 963350
      g_free (target);
Packit Service 963350
    }
Packit Service 963350
Packit Service 963350
    /* otherwise we increment these from NULL to 1 */
Packit Service 963350
    if (next_specifier) {
Packit Service 963350
      templ_name++;
Packit Service 963350
      name++;
Packit Service 963350
    }
Packit Service 963350
  } while (next_specifier);
Packit Service 963350
Packit Service 963350
  return TRUE;
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
static GstPad *
Packit Service 963350
_gst_element_request_pad (GstElement * element, GstPadTemplate * templ,
Packit Service 963350
    const gchar * name, const GstCaps * caps)
Packit Service 963350
{
Packit Service 963350
  GstPad *newpad = NULL;
Packit Service 963350
  GstElementClass *oclass;
Packit Service 963350
Packit Service 963350
  oclass = GST_ELEMENT_GET_CLASS (element);
Packit Service 963350
Packit Service 963350
#ifndef G_DISABLE_CHECKS
Packit Service 963350
  /* Some sanity checking here */
Packit Service 963350
  if (name) {
Packit Service 963350
    GstPad *pad;
Packit Service 963350
Packit Service 963350
    g_return_val_if_fail (gst_element_is_valid_request_template_name
Packit Service 963350
        (templ->name_template, name), NULL);
Packit Service 963350
Packit Service 963350
    pad = gst_element_get_static_pad (element, name);
Packit Service 963350
    if (pad) {
Packit Service 963350
      gst_object_unref (pad);
Packit Service 963350
      /* FIXME 2.0: Change this to g_return_val_if_fail() */
Packit Service 963350
      g_critical ("Element %s already has a pad named %s, the behaviour of "
Packit Service 963350
          " gst_element_get_request_pad() for existing pads is undefined!",
Packit Service 963350
          GST_ELEMENT_NAME (element), name);
Packit Service 963350
    }
Packit Service 963350
  }
Packit Service 963350
#endif
Packit Service 963350
Packit Service 963350
  if (oclass->request_new_pad)
Packit Service 963350
    newpad = (oclass->request_new_pad) (element, templ, name, caps);
Packit Service 963350
Packit Service 963350
  if (newpad)
Packit Service 963350
    gst_object_ref (newpad);
Packit Service 963350
Packit Service 963350
  return newpad;
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
/**
Packit Service 963350
 * gst_element_get_request_pad:
Packit Service 963350
 * @element: a #GstElement to find a request pad of.
Packit Service 963350
 * @name: the name of the request #GstPad to retrieve.
Packit Service 963350
 *
Packit Service 963350
 * Retrieves a pad from the element by name (e.g. "src_\%d"). This version only
Packit Service 963350
 * retrieves request pads. The pad should be released with
Packit Service 963350
 * gst_element_release_request_pad().
Packit Service 963350
 *
Packit Service 963350
 * This method is slower than manually getting the pad template and calling
Packit Service 963350
 * gst_element_request_pad() if the pads should have a specific name (e.g.
Packit Service 963350
 * @name is "src_1" instead of "src_\%u").
Packit Service 963350
 *
Packit Service 963350
 * Returns: (transfer full) (nullable): requested #GstPad if found,
Packit Service 963350
 *     otherwise %NULL.  Release after usage.
Packit Service 963350
 */
Packit Service 963350
GstPad *
Packit Service 963350
gst_element_get_request_pad (GstElement * element, const gchar * name)
Packit Service 963350
{
Packit Service 963350
  GstPadTemplate *templ = NULL;
Packit Service 963350
  GstPad *pad;
Packit Service 963350
  const gchar *req_name = NULL;
Packit Service 963350
  gboolean templ_found = FALSE;
Packit Service 963350
  GList *list;
Packit Service 963350
  GstElementClass *class;
Packit Service 963350
Packit Service 963350
  g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
Packit Service 963350
  g_return_val_if_fail (name != NULL, NULL);
Packit Service 963350
Packit Service 963350
  class = GST_ELEMENT_GET_CLASS (element);
Packit Service 963350
Packit Service 963350
  templ = gst_element_class_get_request_pad_template (class, name);
Packit Service 963350
  if (templ) {
Packit Service 963350
    req_name = strstr (name, "%") ? NULL : name;
Packit Service 963350
    templ_found = TRUE;
Packit Service 963350
  } else {
Packit Service 963350
    /* there is no % in the name, try to find a matching template */
Packit Service 963350
    list = class->padtemplates;
Packit Service 963350
    while (!templ_found && list) {
Packit Service 963350
      templ = (GstPadTemplate *) list->data;
Packit Service 963350
      if (templ->presence == GST_PAD_REQUEST) {
Packit Service 963350
        GST_CAT_DEBUG (GST_CAT_PADS, "comparing %s to %s", name,
Packit Service 963350
            templ->name_template);
Packit Service 963350
        if (gst_element_is_valid_request_template_name (templ->name_template,
Packit Service 963350
                name)) {
Packit Service 963350
          templ_found = TRUE;
Packit Service 963350
          req_name = name;
Packit Service 963350
          break;
Packit Service 963350
        }
Packit Service 963350
      }
Packit Service 963350
      list = list->next;
Packit Service 963350
    }
Packit Service 963350
  }
Packit Service 963350
Packit Service 963350
  if (!templ_found)
Packit Service 963350
    return NULL;
Packit Service 963350
Packit Service 963350
  pad = _gst_element_request_pad (element, templ, req_name, NULL);
Packit Service 963350
Packit Service 963350
  return pad;
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
/**
Packit Service 963350
 * gst_element_request_pad: (virtual request_new_pad)
Packit Service 963350
 * @element: a #GstElement to find a request pad of.
Packit Service 963350
 * @templ: a #GstPadTemplate of which we want a pad of.
Packit Service 963350
 * @name: (transfer none) (allow-none): the name of the request #GstPad
Packit Service 963350
 * to retrieve. Can be %NULL.
Packit Service 963350
 * @caps: (transfer none) (allow-none): the caps of the pad we want to
Packit Service 963350
 * request. Can be %NULL.
Packit Service 963350
 *
Packit Service 963350
 * Retrieves a request pad from the element according to the provided template.
Packit Service 963350
 * Pad templates can be looked up using
Packit Service 963350
 * gst_element_factory_get_static_pad_templates().
Packit Service 963350
 *
Packit Service 963350
 * The pad should be released with gst_element_release_request_pad().
Packit Service 963350
 *
Packit Service 963350
 * Returns: (transfer full) (nullable): requested #GstPad if found,
Packit Service 963350
 *     otherwise %NULL.  Release after usage.
Packit Service 963350
 */
Packit Service 963350
GstPad *
Packit Service 963350
gst_element_request_pad (GstElement * element,
Packit Service 963350
    GstPadTemplate * templ, const gchar * name, const GstCaps * caps)
Packit Service 963350
{
Packit Service 963350
  g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
Packit Service 963350
  g_return_val_if_fail (templ != NULL, NULL);
Packit Service 963350
  g_return_val_if_fail (templ->presence == GST_PAD_REQUEST, NULL);
Packit Service 963350
Packit Service 963350
  return _gst_element_request_pad (element, templ, name, caps);
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
static GstIterator *
Packit Service 963350
gst_element_iterate_pad_list (GstElement * element, GList ** padlist)
Packit Service 963350
{
Packit Service 963350
  GstIterator *result;
Packit Service 963350
Packit Service 963350
  GST_OBJECT_LOCK (element);
Packit Service 963350
  result = gst_iterator_new_list (GST_TYPE_PAD,
Packit Service 963350
      GST_OBJECT_GET_LOCK (element),
Packit Service 963350
      &element->pads_cookie, padlist, (GObject *) element, NULL);
Packit Service 963350
  GST_OBJECT_UNLOCK (element);
Packit Service 963350
Packit Service 963350
  return result;
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
/**
Packit Service 963350
 * gst_element_iterate_pads:
Packit Service 963350
 * @element: a #GstElement to iterate pads of.
Packit Service 963350
 *
Packit Service 963350
 * Retrieves an iterator of @element's pads. The iterator should
Packit Service 963350
 * be freed after usage. Also more specialized iterators exists such as
Packit Service 963350
 * gst_element_iterate_src_pads() or gst_element_iterate_sink_pads().
Packit Service 963350
 *
Packit Service 963350
 * The order of pads returned by the iterator will be the order in which
Packit Service 963350
 * the pads were added to the element.
Packit Service 963350
 *
Packit Service 963350
 * Returns: (transfer full): the #GstIterator of #GstPad.
Packit Service 963350
 *
Packit Service 963350
 * MT safe.
Packit Service 963350
 */
Packit Service 963350
GstIterator *
Packit Service 963350
gst_element_iterate_pads (GstElement * element)
Packit Service 963350
{
Packit Service 963350
  g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
Packit Service 963350
Packit Service 963350
  return gst_element_iterate_pad_list (element, &element->pads);
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
/**
Packit Service 963350
 * gst_element_iterate_src_pads:
Packit Service 963350
 * @element: a #GstElement.
Packit Service 963350
 *
Packit Service 963350
 * Retrieves an iterator of @element's source pads.
Packit Service 963350
 *
Packit Service 963350
 * The order of pads returned by the iterator will be the order in which
Packit Service 963350
 * the pads were added to the element.
Packit Service 963350
 *
Packit Service 963350
 * Returns: (transfer full): the #GstIterator of #GstPad.
Packit Service 963350
 *
Packit Service 963350
 * MT safe.
Packit Service 963350
 */
Packit Service 963350
GstIterator *
Packit Service 963350
gst_element_iterate_src_pads (GstElement * element)
Packit Service 963350
{
Packit Service 963350
  g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
Packit Service 963350
Packit Service 963350
  return gst_element_iterate_pad_list (element, &element->srcpads);
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
/**
Packit Service 963350
 * gst_element_iterate_sink_pads:
Packit Service 963350
 * @element: a #GstElement.
Packit Service 963350
 *
Packit Service 963350
 * Retrieves an iterator of @element's sink pads.
Packit Service 963350
 *
Packit Service 963350
 * The order of pads returned by the iterator will be the order in which
Packit Service 963350
 * the pads were added to the element.
Packit Service 963350
 *
Packit Service 963350
 * Returns: (transfer full): the #GstIterator of #GstPad.
Packit Service 963350
 *
Packit Service 963350
 * MT safe.
Packit Service 963350
 */
Packit Service 963350
GstIterator *
Packit Service 963350
gst_element_iterate_sink_pads (GstElement * element)
Packit Service 963350
{
Packit Service 963350
  g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
Packit Service 963350
Packit Service 963350
  return gst_element_iterate_pad_list (element, &element->sinkpads);
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
static gboolean
Packit Service 963350
gst_element_do_foreach_pad (GstElement * element,
Packit Service 963350
    GstElementForeachPadFunc func, gpointer user_data,
Packit Service 963350
    GList ** p_pads, guint16 * p_npads)
Packit Service 963350
{
Packit Service 963350
  gboolean ret = TRUE;
Packit Service 963350
  GstPad **pads;
Packit Service 963350
  guint n_pads, i;
Packit Service 963350
  GList *l;
Packit Service 963350
Packit Service 963350
  g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
Packit Service 963350
  g_return_val_if_fail (func != NULL, FALSE);
Packit Service 963350
Packit Service 963350
  GST_OBJECT_LOCK (element);
Packit Service 963350
  n_pads = *p_npads;
Packit Service 963350
  pads = g_newa (GstPad *, n_pads + 1);
Packit Service 963350
  for (l = *p_pads, i = 0; l != NULL; l = l->next) {
Packit Service 963350
    g_assert (i < n_pads);
Packit Service 963350
    pads[i++] = gst_object_ref (l->data);
Packit Service 963350
  }
Packit Service 963350
  GST_OBJECT_UNLOCK (element);
Packit Service 963350
Packit Service 963350
  if (n_pads == 0)
Packit Service 963350
    return FALSE;
Packit Service 963350
Packit Service 963350
  for (i = 0; i < n_pads; ++i) {
Packit Service 963350
    ret = func (element, pads[i], user_data);
Packit Service 963350
    if (!ret)
Packit Service 963350
      break;
Packit Service 963350
  }
Packit Service 963350
Packit Service 963350
  for (i = 0; i < n_pads; ++i)
Packit Service 963350
    gst_object_unref (pads[i]);
Packit Service 963350
Packit Service 963350
  return ret;
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
/**
Packit Service 963350
 * gst_element_foreach_sink_pad:
Packit Service 963350
 * @element: a #GstElement to iterate sink pads of
Packit Service 963350
 * @func: (scope call): function to call for each sink pad
Packit Service 963350
 * @user_data: (closure): user data passed to @func
Packit Service 963350
 *
Packit Service 963350
 * Call @func with @user_data for each of @element's sink pads. @func will be
Packit Service 963350
 * called exactly once for each sink pad that exists at the time of this call,
Packit Service 963350
 * unless one of the calls to @func returns %FALSE in which case we will stop
Packit Service 963350
 * iterating pads and return early. If new sink pads are added or sink pads
Packit Service 963350
 * are removed while the sink pads are being iterated, this will not be taken
Packit Service 963350
 * into account until next time this function is used.
Packit Service 963350
 *
Packit Service 963350
 * Returns: %FALSE if @element had no sink pads or if one of the calls to @func
Packit Service 963350
 *   returned %FALSE.
Packit Service 963350
 *
Packit Service 963350
 * Since: 1.14
Packit Service 963350
 */
Packit Service 963350
gboolean
Packit Service 963350
gst_element_foreach_sink_pad (GstElement * element,
Packit Service 963350
    GstElementForeachPadFunc func, gpointer user_data)
Packit Service 963350
{
Packit Service 963350
  return gst_element_do_foreach_pad (element, func, user_data,
Packit Service 963350
      &element->sinkpads, &element->numsinkpads);
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
/**
Packit Service 963350
 * gst_element_foreach_src_pad:
Packit Service 963350
 * @element: a #GstElement to iterate source pads of
Packit Service 963350
 * @func: (scope call): function to call for each source pad
Packit Service 963350
 * @user_data: (closure): user data passed to @func
Packit Service 963350
 *
Packit Service 963350
 * Call @func with @user_data for each of @element's source pads. @func will be
Packit Service 963350
 * called exactly once for each source pad that exists at the time of this call,
Packit Service 963350
 * unless one of the calls to @func returns %FALSE in which case we will stop
Packit Service 963350
 * iterating pads and return early. If new source pads are added or source pads
Packit Service 963350
 * are removed while the source pads are being iterated, this will not be taken
Packit Service 963350
 * into account until next time this function is used.
Packit Service 963350
 *
Packit Service 963350
 * Returns: %FALSE if @element had no source pads or if one of the calls
Packit Service 963350
 *   to @func returned %FALSE.
Packit Service 963350
 *
Packit Service 963350
 * Since: 1.14
Packit Service 963350
 */
Packit Service 963350
gboolean
Packit Service 963350
gst_element_foreach_src_pad (GstElement * element,
Packit Service 963350
    GstElementForeachPadFunc func, gpointer user_data)
Packit Service 963350
{
Packit Service 963350
  return gst_element_do_foreach_pad (element, func, user_data,
Packit Service 963350
      &element->srcpads, &element->numsrcpads);
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
/**
Packit Service 963350
 * gst_element_foreach_pad:
Packit Service 963350
 * @element: a #GstElement to iterate pads of
Packit Service 963350
 * @func: (scope call): function to call for each pad
Packit Service 963350
 * @user_data: (closure): user data passed to @func
Packit Service 963350
 *
Packit Service 963350
 * Call @func with @user_data for each of @element's pads. @func will be called
Packit Service 963350
 * exactly once for each pad that exists at the time of this call, unless
Packit Service 963350
 * one of the calls to @func returns %FALSE in which case we will stop
Packit Service 963350
 * iterating pads and return early. If new pads are added or pads are removed
Packit Service 963350
 * while pads are being iterated, this will not be taken into account until
Packit Service 963350
 * next time this function is used.
Packit Service 963350
 *
Packit Service 963350
 * Returns: %FALSE if @element had no pads or if one of the calls to @func
Packit Service 963350
 *   returned %FALSE.
Packit Service 963350
 *
Packit Service 963350
 * Since: 1.14
Packit Service 963350
 */
Packit Service 963350
gboolean
Packit Service 963350
gst_element_foreach_pad (GstElement * element, GstElementForeachPadFunc func,
Packit Service 963350
    gpointer user_data)
Packit Service 963350
{
Packit Service 963350
  return gst_element_do_foreach_pad (element, func, user_data,
Packit Service 963350
      &element->pads, &element->numpads);
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
/**
Packit Service 963350
 * gst_element_class_add_pad_template:
Packit Service 963350
 * @klass: the #GstElementClass to add the pad template to.
Packit Service 963350
 * @templ: (transfer floating): a #GstPadTemplate to add to the element class.
Packit Service 963350
 *
Packit Service 963350
 * Adds a padtemplate to an element class. This is mainly used in the _class_init
Packit Service 963350
 * functions of classes. If a pad template with the same name as an already
Packit Service 963350
 * existing one is added the old one is replaced by the new one.
Packit Service 963350
 *
Packit Service 963350
 * @templ's reference count will be incremented, and any floating
Packit Service 963350
 * reference will be removed (see gst_object_ref_sink())
Packit Service 963350
 *
Packit Service 963350
 */
Packit Service 963350
void
Packit Service 963350
gst_element_class_add_pad_template (GstElementClass * klass,
Packit Service 963350
    GstPadTemplate * templ)
Packit Service 963350
{
Packit Service 963350
  GList *template_list = klass->padtemplates;
Packit Service 963350
Packit Service 963350
  g_return_if_fail (GST_IS_ELEMENT_CLASS (klass));
Packit Service 963350
  g_return_if_fail (GST_IS_PAD_TEMPLATE (templ));
Packit Service 963350
Packit Service 963350
  /* If we already have a pad template with the same name replace the
Packit Service 963350
   * old one. */
Packit Service 963350
  while (template_list) {
Packit Service 963350
    GstPadTemplate *padtempl = (GstPadTemplate *) template_list->data;
Packit Service 963350
Packit Service 963350
    /* Found pad with the same name, replace and return */
Packit Service 963350
    if (strcmp (templ->name_template, padtempl->name_template) == 0) {
Packit Service 963350
      gst_object_ref_sink (padtempl);
Packit Service 963350
      gst_object_unref (padtempl);
Packit Service 963350
      template_list->data = templ;
Packit Service 963350
      return;
Packit Service 963350
    }
Packit Service 963350
    template_list = g_list_next (template_list);
Packit Service 963350
  }
Packit Service 963350
Packit Service 963350
  /* Take ownership of the floating ref */
Packit Service 963350
  gst_object_ref_sink (templ);
Packit Service 963350
Packit Service 963350
  klass->padtemplates = g_list_append (klass->padtemplates, templ);
Packit Service 963350
  klass->numpadtemplates++;
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
/**
Packit Service 963350
 * gst_element_class_add_static_pad_template:
Packit Service 963350
 * @klass: the #GstElementClass to add the pad template to.
Packit Service 963350
 * @static_templ: #GstStaticPadTemplate to add as pad template to the element class.
Packit Service 963350
 *
Packit Service 963350
 * Adds a pad template to an element class based on the static pad template
Packit Service 963350
 * @templ. This is mainly used in the _class_init functions of element
Packit Service 963350
 * implementations. If a pad template with the same name already exists,
Packit Service 963350
 * the old one is replaced by the new one.
Packit Service 963350
 *
Packit Service 963350
 * Since: 1.8
Packit Service 963350
 */
Packit Service 963350
void
Packit Service 963350
gst_element_class_add_static_pad_template (GstElementClass * klass,
Packit Service 963350
    GstStaticPadTemplate * static_templ)
Packit Service 963350
{
Packit Service 963350
  gst_element_class_add_pad_template (klass,
Packit Service 963350
      gst_static_pad_template_get (static_templ));
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
/**
Packit Service 963350
 * gst_element_class_add_static_pad_template_with_gtype:
Packit Service 963350
 * @klass: the #GstElementClass to add the pad template to.
Packit Service 963350
 * @static_templ: #GstStaticPadTemplate to add as pad template to the element class.
Packit Service 963350
 * @pad_type: The #GType of the pad to create
Packit Service 963350
 *
Packit Service 963350
 * Adds a pad template to an element class based on the static pad template
Packit Service 963350
 * @templ. This is mainly used in the _class_init functions of element
Packit Service 963350
 * implementations. If a pad template with the same name already exists,
Packit Service 963350
 * the old one is replaced by the new one.
Packit Service 963350
 *
Packit Service 963350
 * Since: 1.14
Packit Service 963350
 */
Packit Service 963350
void
Packit Service 963350
gst_element_class_add_static_pad_template_with_gtype (GstElementClass * klass,
Packit Service 963350
    GstStaticPadTemplate * static_templ, GType pad_type)
Packit Service 963350
{
Packit Service 963350
  gst_element_class_add_pad_template (klass,
Packit Service 963350
      gst_pad_template_new_from_static_pad_template_with_gtype (static_templ,
Packit Service 963350
          pad_type));
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
/**
Packit Service 963350
 * gst_element_class_add_metadata:
Packit Service 963350
 * @klass: class to set metadata for
Packit Service 963350
 * @key: the key to set
Packit Service 963350
 * @value: the value to set
Packit Service 963350
 *
Packit Service 963350
 * Set @key with @value as metadata in @klass.
Packit Service 963350
 */
Packit Service 963350
void
Packit Service 963350
gst_element_class_add_metadata (GstElementClass * klass,
Packit Service 963350
    const gchar * key, const gchar * value)
Packit Service 963350
{
Packit Service 963350
  g_return_if_fail (GST_IS_ELEMENT_CLASS (klass));
Packit Service 963350
  g_return_if_fail (key != NULL);
Packit Service 963350
  g_return_if_fail (value != NULL);
Packit Service 963350
Packit Service 963350
  gst_structure_set ((GstStructure *) klass->metadata,
Packit Service 963350
      key, G_TYPE_STRING, value, NULL);
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
/**
Packit Service 963350
 * gst_element_class_add_static_metadata:
Packit Service 963350
 * @klass: class to set metadata for
Packit Service 963350
 * @key: the key to set
Packit Service 963350
 * @value: the value to set
Packit Service 963350
 *
Packit Service 963350
 * Set @key with @value as metadata in @klass.
Packit Service 963350
 *
Packit Service 963350
 * Same as gst_element_class_add_metadata(), but @value must be a static string
Packit Service 963350
 * or an inlined string, as it will not be copied. (GStreamer plugins will
Packit Service 963350
 * be made resident once loaded, so this function can be used even from
Packit Service 963350
 * dynamically loaded plugins.)
Packit Service 963350
 */
Packit Service 963350
void
Packit Service 963350
gst_element_class_add_static_metadata (GstElementClass * klass,
Packit Service 963350
    const gchar * key, const gchar * value)
Packit Service 963350
{
Packit Service 963350
  GValue val = G_VALUE_INIT;
Packit Service 963350
Packit Service 963350
  g_return_if_fail (GST_IS_ELEMENT_CLASS (klass));
Packit Service 963350
  g_return_if_fail (key != NULL);
Packit Service 963350
  g_return_if_fail (value != NULL);
Packit Service 963350
Packit Service 963350
  g_value_init (&val, G_TYPE_STRING);
Packit Service 963350
  g_value_set_static_string (&val, value);
Packit Service 963350
  gst_structure_take_value ((GstStructure *) klass->metadata, key, &val;;
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
/**
Packit Service 963350
 * gst_element_class_set_metadata:
Packit Service 963350
 * @klass: class to set metadata for
Packit Service 963350
 * @longname: The long English name of the element. E.g. "File Sink"
Packit Service 963350
 * @classification: String describing the type of element, as an unordered list
Packit Service 963350
 * separated with slashes ('/'). See draft-klass.txt of the design docs
Packit Service 963350
 * for more details and common types. E.g: "Sink/File"
Packit Service 963350
 * @description: Sentence describing the purpose of the element.
Packit Service 963350
 * E.g: "Write stream to a file"
Packit Service 963350
 * @author: Name and contact details of the author(s). Use \n to separate
Packit Service 963350
 * multiple author metadata. E.g: "Joe Bloggs <joe.blogs at foo.com>"
Packit Service 963350
 *
Packit Service 963350
 * Sets the detailed information for a #GstElementClass.
Packit Service 963350
 * > This function is for use in _class_init functions only.
Packit Service 963350
 */
Packit Service 963350
void
Packit Service 963350
gst_element_class_set_metadata (GstElementClass * klass,
Packit Service 963350
    const gchar * longname, const gchar * classification,
Packit Service 963350
    const gchar * description, const gchar * author)
Packit Service 963350
{
Packit Service 963350
  g_return_if_fail (GST_IS_ELEMENT_CLASS (klass));
Packit Service 963350
  g_return_if_fail (longname != NULL && *longname != '\0');
Packit Service 963350
  g_return_if_fail (classification != NULL && *classification != '\0');
Packit Service 963350
  g_return_if_fail (description != NULL && *description != '\0');
Packit Service 963350
  g_return_if_fail (author != NULL && *author != '\0');
Packit Service 963350
Packit Service 963350
  gst_structure_id_set ((GstStructure *) klass->metadata,
Packit Service 963350
      GST_QUARK (ELEMENT_METADATA_LONGNAME), G_TYPE_STRING, longname,
Packit Service 963350
      GST_QUARK (ELEMENT_METADATA_KLASS), G_TYPE_STRING, classification,
Packit Service 963350
      GST_QUARK (ELEMENT_METADATA_DESCRIPTION), G_TYPE_STRING, description,
Packit Service 963350
      GST_QUARK (ELEMENT_METADATA_AUTHOR), G_TYPE_STRING, author, NULL);
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
/**
Packit Service 963350
 * gst_element_class_set_static_metadata:
Packit Service 963350
 * @klass: class to set metadata for
Packit Service 963350
 * @longname: The long English name of the element. E.g. "File Sink"
Packit Service 963350
 * @classification: String describing the type of element, as an unordered list
Packit Service 963350
 * separated with slashes ('/'). See draft-klass.txt of the design docs
Packit Service 963350
 * for more details and common types. E.g: "Sink/File"
Packit Service 963350
 * @description: Sentence describing the purpose of the element.
Packit Service 963350
 * E.g: "Write stream to a file"
Packit Service 963350
 * @author: Name and contact details of the author(s). Use \n to separate
Packit Service 963350
 * multiple author metadata. E.g: "Joe Bloggs <joe.blogs at foo.com>"
Packit Service 963350
 *
Packit Service 963350
 * Sets the detailed information for a #GstElementClass.
Packit Service 963350
 *
Packit Service 963350
 * > This function is for use in _class_init functions only.
Packit Service 963350
 *
Packit Service 963350
 * Same as gst_element_class_set_metadata(), but @longname, @classification,
Packit Service 963350
 * @description, and @author must be static strings or inlined strings, as
Packit Service 963350
 * they will not be copied. (GStreamer plugins will be made resident once
Packit Service 963350
 * loaded, so this function can be used even from dynamically loaded plugins.)
Packit Service 963350
 */
Packit Service 963350
void
Packit Service 963350
gst_element_class_set_static_metadata (GstElementClass * klass,
Packit Service 963350
    const gchar * longname, const gchar * classification,
Packit Service 963350
    const gchar * description, const gchar * author)
Packit Service 963350
{
Packit Service 963350
  GstStructure *s = (GstStructure *) klass->metadata;
Packit Service 963350
  GValue val = G_VALUE_INIT;
Packit Service 963350
Packit Service 963350
  g_return_if_fail (GST_IS_ELEMENT_CLASS (klass));
Packit Service 963350
  g_return_if_fail (longname != NULL && *longname != '\0');
Packit Service 963350
  g_return_if_fail (classification != NULL && *classification != '\0');
Packit Service 963350
  g_return_if_fail (description != NULL && *description != '\0');
Packit Service 963350
  g_return_if_fail (author != NULL && *author != '\0');
Packit Service 963350
Packit Service 963350
  g_value_init (&val, G_TYPE_STRING);
Packit Service 963350
Packit Service 963350
  g_value_set_static_string (&val, longname);
Packit Service 963350
  gst_structure_id_set_value (s, GST_QUARK (ELEMENT_METADATA_LONGNAME), &val;;
Packit Service 963350
Packit Service 963350
  g_value_set_static_string (&val, classification);
Packit Service 963350
  gst_structure_id_set_value (s, GST_QUARK (ELEMENT_METADATA_KLASS), &val;;
Packit Service 963350
Packit Service 963350
  g_value_set_static_string (&val, description);
Packit Service 963350
  gst_structure_id_set_value (s, GST_QUARK (ELEMENT_METADATA_DESCRIPTION),
Packit Service 963350
      &val;;
Packit Service 963350
Packit Service 963350
  g_value_set_static_string (&val, author);
Packit Service 963350
  gst_structure_id_take_value (s, GST_QUARK (ELEMENT_METADATA_AUTHOR), &val;;
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
/**
Packit Service 963350
 * gst_element_class_get_metadata:
Packit Service 963350
 * @klass: class to get metadata for
Packit Service 963350
 * @key: the key to get
Packit Service 963350
 *
Packit Service 963350
 * Get metadata with @key in @klass.
Packit Service 963350
 *
Packit Service 963350
 * Returns: the metadata for @key.
Packit Service 963350
 */
Packit Service 963350
const gchar *
Packit Service 963350
gst_element_class_get_metadata (GstElementClass * klass, const gchar * key)
Packit Service 963350
{
Packit Service 963350
  g_return_val_if_fail (GST_IS_ELEMENT_CLASS (klass), NULL);
Packit Service 963350
  g_return_val_if_fail (key != NULL, NULL);
Packit Service 963350
Packit Service 963350
  return gst_structure_get_string ((GstStructure *) klass->metadata, key);
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
/**
Packit Service 963350
 * gst_element_get_metadata:
Packit Service 963350
 * @element: class to get metadata for
Packit Service 963350
 * @key: the key to get
Packit Service 963350
 *
Packit Service 963350
 * Get metadata with @key in @klass.
Packit Service 963350
 *
Packit Service 963350
 * Returns: the metadata for @key.
Packit Service 963350
 *
Packit Service 963350
 * Since: 1.14
Packit Service 963350
 */
Packit Service 963350
const gchar *
Packit Service 963350
gst_element_get_metadata (GstElement * element, const gchar * key)
Packit Service 963350
{
Packit Service 963350
  g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
Packit Service 963350
  g_return_val_if_fail (key != NULL, NULL);
Packit Service 963350
Packit Service 963350
  return gst_element_class_get_metadata (GST_ELEMENT_GET_CLASS (element), key);
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
/**
Packit Service 963350
 * gst_element_class_get_pad_template_list:
Packit Service 963350
 * @element_class: a #GstElementClass to get pad templates of.
Packit Service 963350
 *
Packit Service 963350
 * Retrieves a list of the pad templates associated with @element_class. The
Packit Service 963350
 * list must not be modified by the calling code.
Packit Service 963350
 * > If you use this function in the #GInstanceInitFunc of an object class
Packit Service 963350
 * > that has subclasses, make sure to pass the g_class parameter of the
Packit Service 963350
 * > #GInstanceInitFunc here.
Packit Service 963350
 *
Packit Service 963350
 * Returns: (transfer none) (element-type Gst.PadTemplate): the #GList of
Packit Service 963350
 *     pad templates.
Packit Service 963350
 */
Packit Service 963350
GList *
Packit Service 963350
gst_element_class_get_pad_template_list (GstElementClass * element_class)
Packit Service 963350
{
Packit Service 963350
  g_return_val_if_fail (GST_IS_ELEMENT_CLASS (element_class), NULL);
Packit Service 963350
Packit Service 963350
  return element_class->padtemplates;
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
/**
Packit Service 963350
 * gst_element_get_pad_template_list:
Packit Service 963350
 * @element: a #GstElement to get pad templates of.
Packit Service 963350
 *
Packit Service 963350
 * Retrieves a list of the pad templates associated with @element. The
Packit Service 963350
 * list must not be modified by the calling code.
Packit Service 963350
 *
Packit Service 963350
 * Returns: (transfer none) (element-type Gst.PadTemplate): the #GList of
Packit Service 963350
 *     pad templates.
Packit Service 963350
 *
Packit Service 963350
 * Since: 1.14
Packit Service 963350
 */
Packit Service 963350
GList *
Packit Service 963350
gst_element_get_pad_template_list (GstElement * element)
Packit Service 963350
{
Packit Service 963350
  g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
Packit Service 963350
Packit Service 963350
  return
Packit Service 963350
      gst_element_class_get_pad_template_list (GST_ELEMENT_GET_CLASS (element));
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
/**
Packit Service 963350
 * gst_element_class_get_pad_template:
Packit Service 963350
 * @element_class: a #GstElementClass to get the pad template of.
Packit Service 963350
 * @name: the name of the #GstPadTemplate to get.
Packit Service 963350
 *
Packit Service 963350
 * Retrieves a padtemplate from @element_class with the given name.
Packit Service 963350
 * > If you use this function in the #GInstanceInitFunc of an object class
Packit Service 963350
 * > that has subclasses, make sure to pass the g_class parameter of the
Packit Service 963350
 * > #GInstanceInitFunc here.
Packit Service 963350
 *
Packit Service 963350
 * Returns: (transfer none) (nullable): the #GstPadTemplate with the
Packit Service 963350
 *     given name, or %NULL if none was found. No unreferencing is
Packit Service 963350
 *     necessary.
Packit Service 963350
 */
Packit Service 963350
GstPadTemplate *
Packit Service 963350
gst_element_class_get_pad_template (GstElementClass *
Packit Service 963350
    element_class, const gchar * name)
Packit Service 963350
{
Packit Service 963350
  GList *padlist;
Packit Service 963350
Packit Service 963350
  g_return_val_if_fail (GST_IS_ELEMENT_CLASS (element_class), NULL);
Packit Service 963350
  g_return_val_if_fail (name != NULL, NULL);
Packit Service 963350
Packit Service 963350
  padlist = element_class->padtemplates;
Packit Service 963350
Packit Service 963350
  while (padlist) {
Packit Service 963350
    GstPadTemplate *padtempl = (GstPadTemplate *) padlist->data;
Packit Service 963350
Packit Service 963350
    if (strcmp (padtempl->name_template, name) == 0)
Packit Service 963350
      return padtempl;
Packit Service 963350
Packit Service 963350
    padlist = g_list_next (padlist);
Packit Service 963350
  }
Packit Service 963350
Packit Service 963350
  return NULL;
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
/**
Packit Service 963350
 * gst_element_get_pad_template:
Packit Service 963350
 * @element: a #GstElement to get the pad template of.
Packit Service 963350
 * @name: the name of the #GstPadTemplate to get.
Packit Service 963350
 *
Packit Service 963350
 * Retrieves a padtemplate from @element with the given name.
Packit Service 963350
 *
Packit Service 963350
 * Returns: (transfer none) (nullable): the #GstPadTemplate with the
Packit Service 963350
 *     given name, or %NULL if none was found. No unreferencing is
Packit Service 963350
 *     necessary.
Packit Service 963350
 *
Packit Service 963350
 * Since: 1.14
Packit Service 963350
 */
Packit Service 963350
GstPadTemplate *
Packit Service 963350
gst_element_get_pad_template (GstElement * element, const gchar * name)
Packit Service 963350
{
Packit Service 963350
  g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
Packit Service 963350
  g_return_val_if_fail (name != NULL, NULL);
Packit Service 963350
Packit Service 963350
  return gst_element_class_get_pad_template (GST_ELEMENT_GET_CLASS (element),
Packit Service 963350
      name);
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
static GstPadTemplate *
Packit Service 963350
gst_element_class_get_request_pad_template (GstElementClass *
Packit Service 963350
    element_class, const gchar * name)
Packit Service 963350
{
Packit Service 963350
  GstPadTemplate *tmpl;
Packit Service 963350
Packit Service 963350
  tmpl = gst_element_class_get_pad_template (element_class, name);
Packit Service 963350
  if (tmpl != NULL && tmpl->presence == GST_PAD_REQUEST)
Packit Service 963350
    return tmpl;
Packit Service 963350
Packit Service 963350
  return NULL;
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
/* get a random pad on element of the given direction.
Packit Service 963350
 * The pad is random in a sense that it is the first pad that is (optionaly) linked.
Packit Service 963350
 */
Packit Service 963350
static GstPad *
Packit Service 963350
gst_element_get_random_pad (GstElement * element,
Packit Service 963350
    gboolean need_linked, GstPadDirection dir)
Packit Service 963350
{
Packit Service 963350
  GstPad *result = NULL;
Packit Service 963350
  GList *pads;
Packit Service 963350
Packit Service 963350
  GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "getting a random pad");
Packit Service 963350
Packit Service 963350
  switch (dir) {
Packit Service 963350
    case GST_PAD_SRC:
Packit Service 963350
      GST_OBJECT_LOCK (element);
Packit Service 963350
      pads = element->srcpads;
Packit Service 963350
      break;
Packit Service 963350
    case GST_PAD_SINK:
Packit Service 963350
      GST_OBJECT_LOCK (element);
Packit Service 963350
      pads = element->sinkpads;
Packit Service 963350
      break;
Packit Service 963350
    default:
Packit Service 963350
      goto wrong_direction;
Packit Service 963350
  }
Packit Service 963350
  for (; pads; pads = g_list_next (pads)) {
Packit Service 963350
    GstPad *pad = GST_PAD_CAST (pads->data);
Packit Service 963350
Packit Service 963350
    GST_OBJECT_LOCK (pad);
Packit Service 963350
    GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "checking pad %s:%s",
Packit Service 963350
        GST_DEBUG_PAD_NAME (pad));
Packit Service 963350
Packit Service 963350
    if (need_linked && !GST_PAD_IS_LINKED (pad)) {
Packit Service 963350
      /* if we require a linked pad, and it is not linked, continue the
Packit Service 963350
       * search */
Packit Service 963350
      GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "pad %s:%s is not linked",
Packit Service 963350
          GST_DEBUG_PAD_NAME (pad));
Packit Service 963350
      GST_OBJECT_UNLOCK (pad);
Packit Service 963350
      continue;
Packit Service 963350
    } else {
Packit Service 963350
      /* found a pad, stop search */
Packit Service 963350
      GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "found pad %s:%s",
Packit Service 963350
          GST_DEBUG_PAD_NAME (pad));
Packit Service 963350
      GST_OBJECT_UNLOCK (pad);
Packit Service 963350
      result = pad;
Packit Service 963350
      break;
Packit Service 963350
    }
Packit Service 963350
  }
Packit Service 963350
  if (result)
Packit Service 963350
    gst_object_ref (result);
Packit Service 963350
Packit Service 963350
  GST_OBJECT_UNLOCK (element);
Packit Service 963350
Packit Service 963350
  return result;
Packit Service 963350
Packit Service 963350
  /* ERROR handling */
Packit Service 963350
wrong_direction:
Packit Service 963350
  {
Packit Service 963350
    g_warning ("unknown pad direction %d", dir);
Packit Service 963350
    return NULL;
Packit Service 963350
  }
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
static gboolean
Packit Service 963350
gst_element_default_send_event (GstElement * element, GstEvent * event)
Packit Service 963350
{
Packit Service 963350
  gboolean result = FALSE;
Packit Service 963350
  GstPad *pad;
Packit Service 963350
Packit Service 963350
  pad = GST_EVENT_IS_DOWNSTREAM (event) ?
Packit Service 963350
      gst_element_get_random_pad (element, TRUE, GST_PAD_SINK) :
Packit Service 963350
      gst_element_get_random_pad (element, TRUE, GST_PAD_SRC);
Packit Service 963350
Packit Service 963350
  if (pad) {
Packit Service 963350
    GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS,
Packit Service 963350
        "pushing %s event to random %s pad %s:%s",
Packit Service 963350
        GST_EVENT_TYPE_NAME (event),
Packit Service 963350
        (GST_PAD_DIRECTION (pad) == GST_PAD_SRC ? "src" : "sink"),
Packit Service 963350
        GST_DEBUG_PAD_NAME (pad));
Packit Service 963350
Packit Service 963350
    result = gst_pad_send_event (pad, event);
Packit Service 963350
    gst_object_unref (pad);
Packit Service 963350
  } else {
Packit Service 963350
    GST_CAT_INFO (GST_CAT_ELEMENT_PADS, "can't send %s event on element %s",
Packit Service 963350
        GST_EVENT_TYPE_NAME (event), GST_ELEMENT_NAME (element));
Packit Service 963350
    gst_event_unref (event);
Packit Service 963350
  }
Packit Service 963350
  return result;
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
/**
Packit Service 963350
 * gst_element_send_event:
Packit Service 963350
 * @element: a #GstElement to send the event to.
Packit Service 963350
 * @event: (transfer full): the #GstEvent to send to the element.
Packit Service 963350
 *
Packit Service 963350
 * Sends an event to an element. If the element doesn't implement an
Packit Service 963350
 * event handler, the event will be pushed on a random linked sink pad for
Packit Service 963350
 * downstream events or a random linked source pad for upstream events.
Packit Service 963350
 *
Packit Service 963350
 * This function takes ownership of the provided event so you should
Packit Service 963350
 * gst_event_ref() it if you want to reuse the event after this call.
Packit Service 963350
 *
Packit Service 963350
 * MT safe.
Packit Service 963350
 *
Packit Service 963350
 * Returns: %TRUE if the event was handled. Events that trigger a preroll (such
Packit Service 963350
 * as flushing seeks and steps) will emit %GST_MESSAGE_ASYNC_DONE.
Packit Service 963350
 */
Packit Service 963350
gboolean
Packit Service 963350
gst_element_send_event (GstElement * element, GstEvent * event)
Packit Service 963350
{
Packit Service 963350
  GstElementClass *oclass;
Packit Service 963350
  gboolean result = FALSE;
Packit Service 963350
Packit Service 963350
  g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
Packit Service 963350
  g_return_val_if_fail (event != NULL, FALSE);
Packit Service 963350
Packit Service 963350
  oclass = GST_ELEMENT_GET_CLASS (element);
Packit Service 963350
Packit Service 963350
  GST_STATE_LOCK (element);
Packit Service 963350
  if (oclass->send_event) {
Packit Service 963350
    GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "send %s event on element %s",
Packit Service 963350
        GST_EVENT_TYPE_NAME (event), GST_ELEMENT_NAME (element));
Packit Service 963350
    result = oclass->send_event (element, event);
Packit Service 963350
  } else {
Packit Service 963350
    gst_event_unref (event);
Packit Service 963350
  }
Packit Service 963350
  GST_STATE_UNLOCK (element);
Packit Service 963350
Packit Service 963350
  return result;
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
/**
Packit Service 963350
 * gst_element_seek:
Packit Service 963350
 * @element: a #GstElement to send the event to.
Packit Service 963350
 * @rate: The new playback rate
Packit Service 963350
 * @format: The format of the seek values
Packit Service 963350
 * @flags: The optional seek flags.
Packit Service 963350
 * @start_type: The type and flags for the new start position
Packit Service 963350
 * @start: The value of the new start position
Packit Service 963350
 * @stop_type: The type and flags for the new stop position
Packit Service 963350
 * @stop: The value of the new stop position
Packit Service 963350
 *
Packit Service 963350
 * Sends a seek event to an element. See gst_event_new_seek() for the details of
Packit Service 963350
 * the parameters. The seek event is sent to the element using
Packit Service 963350
 * gst_element_send_event().
Packit Service 963350
 *
Packit Service 963350
 * MT safe.
Packit Service 963350
 *
Packit Service 963350
 * Returns: %TRUE if the event was handled. Flushing seeks will trigger a
Packit Service 963350
 * preroll, which will emit %GST_MESSAGE_ASYNC_DONE.
Packit Service 963350
 */
Packit Service 963350
gboolean
Packit Service 963350
gst_element_seek (GstElement * element, gdouble rate, GstFormat format,
Packit Service 963350
    GstSeekFlags flags, GstSeekType start_type, gint64 start,
Packit Service 963350
    GstSeekType stop_type, gint64 stop)
Packit Service 963350
{
Packit Service 963350
  GstEvent *event;
Packit Service 963350
  gboolean result;
Packit Service 963350
Packit Service 963350
  g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
Packit Service 963350
Packit Service 963350
  event =
Packit Service 963350
      gst_event_new_seek (rate, format, flags, start_type, start, stop_type,
Packit Service 963350
      stop);
Packit Service 963350
  result = gst_element_send_event (element, event);
Packit Service 963350
Packit Service 963350
  return result;
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
static gboolean
Packit Service 963350
gst_element_default_query (GstElement * element, GstQuery * query)
Packit Service 963350
{
Packit Service 963350
  gboolean result = FALSE;
Packit Service 963350
  GstPad *pad;
Packit Service 963350
Packit Service 963350
  pad = gst_element_get_random_pad (element, FALSE, GST_PAD_SRC);
Packit Service 963350
  if (pad) {
Packit Service 963350
    result = gst_pad_query (pad, query);
Packit Service 963350
Packit Service 963350
    gst_object_unref (pad);
Packit Service 963350
  } else {
Packit Service 963350
    pad = gst_element_get_random_pad (element, TRUE, GST_PAD_SINK);
Packit Service 963350
    if (pad) {
Packit Service 963350
      GstPad *peer = gst_pad_get_peer (pad);
Packit Service 963350
Packit Service 963350
      if (peer) {
Packit Service 963350
        result = gst_pad_query (peer, query);
Packit Service 963350
Packit Service 963350
        gst_object_unref (peer);
Packit Service 963350
      }
Packit Service 963350
      gst_object_unref (pad);
Packit Service 963350
    }
Packit Service 963350
  }
Packit Service 963350
  return result;
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
/**
Packit Service 963350
 * gst_element_query:
Packit Service 963350
 * @element: a #GstElement to perform the query on.
Packit Service 963350
 * @query: (transfer none): the #GstQuery.
Packit Service 963350
 *
Packit Service 963350
 * Performs a query on the given element.
Packit Service 963350
 *
Packit Service 963350
 * For elements that don't implement a query handler, this function
Packit Service 963350
 * forwards the query to a random srcpad or to the peer of a
Packit Service 963350
 * random linked sinkpad of this element.
Packit Service 963350
 *
Packit Service 963350
 * Please note that some queries might need a running pipeline to work.
Packit Service 963350
 *
Packit Service 963350
 * Returns: %TRUE if the query could be performed.
Packit Service 963350
 *
Packit Service 963350
 * MT safe.
Packit Service 963350
 */
Packit Service 963350
gboolean
Packit Service 963350
gst_element_query (GstElement * element, GstQuery * query)
Packit Service 963350
{
Packit Service 963350
  GstElementClass *klass;
Packit Service 963350
  gboolean res = FALSE;
Packit Service 963350
Packit Service 963350
  g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
Packit Service 963350
  g_return_val_if_fail (query != NULL, FALSE);
Packit Service 963350
Packit Service 963350
  GST_TRACER_ELEMENT_QUERY_PRE (element, query);
Packit Service 963350
Packit Service 963350
  klass = GST_ELEMENT_GET_CLASS (element);
Packit Service 963350
  if (klass->query) {
Packit Service 963350
    GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "send query on element %s",
Packit Service 963350
        GST_ELEMENT_NAME (element));
Packit Service 963350
    res = klass->query (element, query);
Packit Service 963350
  }
Packit Service 963350
Packit Service 963350
  GST_TRACER_ELEMENT_QUERY_POST (element, query, res);
Packit Service 963350
  return res;
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
static gboolean
Packit Service 963350
gst_element_post_message_default (GstElement * element, GstMessage * message)
Packit Service 963350
{
Packit Service 963350
  GstBus *bus;
Packit Service 963350
  gboolean result = FALSE;
Packit Service 963350
Packit Service 963350
  g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
Packit Service 963350
  g_return_val_if_fail (message != NULL, FALSE);
Packit Service 963350
Packit Service 963350
  GST_OBJECT_LOCK (element);
Packit Service 963350
  bus = element->bus;
Packit Service 963350
Packit Service 963350
  if (G_UNLIKELY (bus == NULL))
Packit Service 963350
    goto no_bus;
Packit Service 963350
Packit Service 963350
  gst_object_ref (bus);
Packit Service 963350
  GST_OBJECT_UNLOCK (element);
Packit Service 963350
Packit Service 963350
  /* we release the element lock when posting the message so that any
Packit Service 963350
   * (synchronous) message handlers can operate on the element */
Packit Service 963350
  result = gst_bus_post (bus, message);
Packit Service 963350
  gst_object_unref (bus);
Packit Service 963350
Packit Service 963350
  return result;
Packit Service 963350
Packit Service 963350
  /* ERRORS */
Packit Service 963350
no_bus:
Packit Service 963350
  {
Packit Service 963350
    GST_CAT_DEBUG_OBJECT (GST_CAT_MESSAGE, element,
Packit Service 963350
        "not posting message %p: no bus", message);
Packit Service 963350
    GST_OBJECT_UNLOCK (element);
Packit Service 963350
    gst_message_unref (message);
Packit Service 963350
    return FALSE;
Packit Service 963350
  }
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
/**
Packit Service 963350
 * gst_element_post_message:
Packit Service 963350
 * @element: a #GstElement posting the message
Packit Service 963350
 * @message: (transfer full): a #GstMessage to post
Packit Service 963350
 *
Packit Service 963350
 * Post a message on the element's #GstBus. This function takes ownership of the
Packit Service 963350
 * message; if you want to access the message after this call, you should add an
Packit Service 963350
 * additional reference before calling.
Packit Service 963350
 *
Packit Service 963350
 * Returns: %TRUE if the message was successfully posted. The function returns
Packit Service 963350
 * %FALSE if the element did not have a bus.
Packit Service 963350
 *
Packit Service 963350
 * MT safe.
Packit Service 963350
 */
Packit Service 963350
gboolean
Packit Service 963350
gst_element_post_message (GstElement * element, GstMessage * message)
Packit Service 963350
{
Packit Service 963350
  GstElementClass *klass;
Packit Service 963350
  gboolean res = FALSE;
Packit Service 963350
Packit Service 963350
  g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
Packit Service 963350
  g_return_val_if_fail (message != NULL, FALSE);
Packit Service 963350
Packit Service 963350
  GST_TRACER_ELEMENT_POST_MESSAGE_PRE (element, message);
Packit Service 963350
Packit Service 963350
  klass = GST_ELEMENT_GET_CLASS (element);
Packit Service 963350
  if (klass->post_message)
Packit Service 963350
    res = klass->post_message (element, message);
Packit Service 963350
  else
Packit Service 963350
    gst_message_unref (message);
Packit Service 963350
Packit Service 963350
  GST_TRACER_ELEMENT_POST_MESSAGE_POST (element, res);
Packit Service 963350
  return res;
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
/**
Packit Service 963350
 * _gst_element_error_printf:
Packit Service 963350
 * @format: (allow-none): the printf-like format to use, or %NULL
Packit Service 963350
 *
Packit Service 963350
 * This function is only used internally by the gst_element_error() macro.
Packit Service 963350
 *
Packit Service 963350
 * Returns: (transfer full) (nullable): a newly allocated string, or
Packit Service 963350
 *     %NULL if the format was %NULL or ""
Packit Service 963350
 *
Packit Service 963350
 * MT safe.
Packit Service 963350
 */
Packit Service 963350
gchar *
Packit Service 963350
_gst_element_error_printf (const gchar * format, ...)
Packit Service 963350
{
Packit Service 963350
  va_list args;
Packit Service 963350
  gchar *buffer;
Packit Service 963350
  int len;
Packit Service 963350
Packit Service 963350
  if (format == NULL)
Packit Service 963350
    return NULL;
Packit Service 963350
  if (format[0] == 0)
Packit Service 963350
    return NULL;
Packit Service 963350
Packit Service 963350
  va_start (args, format);
Packit Service 963350
Packit Service 963350
  len = __gst_vasprintf (&buffer, format, args);
Packit Service 963350
Packit Service 963350
  va_end (args);
Packit Service 963350
Packit Service 963350
  if (len < 0)
Packit Service 963350
    buffer = NULL;
Packit Service 963350
Packit Service 963350
  return buffer;
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
/**
Packit Service 963350
 * gst_element_message_full_with_details:
Packit Service 963350
 * @element:  a #GstElement to send message from
Packit Service 963350
 * @type:     the #GstMessageType
Packit Service 963350
 * @domain:   the GStreamer GError domain this message belongs to
Packit Service 963350
 * @code:     the GError code belonging to the domain
Packit Service 963350
 * @text:     (allow-none) (transfer full): an allocated text string to be used
Packit Service 963350
 *            as a replacement for the default message connected to code,
Packit Service 963350
 *            or %NULL
Packit Service 963350
 * @debug:    (allow-none) (transfer full): an allocated debug message to be
Packit Service 963350
 *            used as a replacement for the default debugging information,
Packit Service 963350
 *            or %NULL
Packit Service 963350
 * @file:     the source code file where the error was generated
Packit Service 963350
 * @function: the source code function where the error was generated
Packit Service 963350
 * @line:     the source code line where the error was generated
Packit Service 963350
 * @structure:(transfer full): optional details structure
Packit Service 963350
 *
Packit Service 963350
 * Post an error, warning or info message on the bus from inside an element.
Packit Service 963350
 *
Packit Service 963350
 * @type must be of #GST_MESSAGE_ERROR, #GST_MESSAGE_WARNING or
Packit Service 963350
 * #GST_MESSAGE_INFO.
Packit Service 963350
 *
Packit Service 963350
 * Since: 1.10
Packit Service 963350
 */
Packit Service 963350
void gst_element_message_full_with_details
Packit Service 963350
    (GstElement * element, GstMessageType type,
Packit Service 963350
    GQuark domain, gint code, gchar * text,
Packit Service 963350
    gchar * debug, const gchar * file, const gchar * function, gint line,
Packit Service 963350
    GstStructure * structure)
Packit Service 963350
{
Packit Service 963350
  GError *gerror = NULL;
Packit Service 963350
  gchar *name;
Packit Service 963350
  gchar *sent_text;
Packit Service 963350
  gchar *sent_debug;
Packit Service 963350
  gboolean has_debug = TRUE;
Packit Service 963350
  GstMessage *message = NULL;
Packit Service 963350
Packit Service 963350
  /* checks */
Packit Service 963350
  GST_CAT_DEBUG_OBJECT (GST_CAT_MESSAGE, element, "start");
Packit Service 963350
  g_return_if_fail (GST_IS_ELEMENT (element));
Packit Service 963350
  g_return_if_fail ((type == GST_MESSAGE_ERROR) ||
Packit Service 963350
      (type == GST_MESSAGE_WARNING) || (type == GST_MESSAGE_INFO));
Packit Service 963350
Packit Service 963350
  /* check if we send the given text or the default error text */
Packit Service 963350
  if ((text == NULL) || (text[0] == 0)) {
Packit Service 963350
    /* text could have come from g_strdup_printf (""); */
Packit Service 963350
    g_free (text);
Packit Service 963350
    sent_text = gst_error_get_message (domain, code);
Packit Service 963350
  } else
Packit Service 963350
    sent_text = text;
Packit Service 963350
Packit Service 963350
  /* construct a sent_debug with extra information from source */
Packit Service 963350
  if ((debug == NULL) || (debug[0] == 0)) {
Packit Service 963350
    /* debug could have come from g_strdup_printf (""); */
Packit Service 963350
    has_debug = FALSE;
Packit Service 963350
  }
Packit Service 963350
Packit Service 963350
  name = gst_object_get_path_string (GST_OBJECT_CAST (element));
Packit Service 963350
  if (has_debug)
Packit Service 963350
    sent_debug = g_strdup_printf ("%s(%d): %s (): %s:\n%s",
Packit Service 963350
        file, line, function, name, debug);
Packit Service 963350
  else
Packit Service 963350
    sent_debug = g_strdup_printf ("%s(%d): %s (): %s",
Packit Service 963350
        file, line, function, name);
Packit Service 963350
  g_free (name);
Packit Service 963350
  g_free (debug);
Packit Service 963350
Packit Service 963350
  /* create gerror and post message */
Packit Service 963350
  GST_CAT_INFO_OBJECT (GST_CAT_ERROR_SYSTEM, element, "posting message: %s",
Packit Service 963350
      sent_text);
Packit Service 963350
  gerror = g_error_new_literal (domain, code, sent_text);
Packit Service 963350
Packit Service 963350
  switch (type) {
Packit Service 963350
    case GST_MESSAGE_ERROR:
Packit Service 963350
      message =
Packit Service 963350
          gst_message_new_error_with_details (GST_OBJECT_CAST (element), gerror,
Packit Service 963350
          sent_debug, structure);
Packit Service 963350
      break;
Packit Service 963350
    case GST_MESSAGE_WARNING:
Packit Service 963350
      message =
Packit Service 963350
          gst_message_new_warning_with_details (GST_OBJECT_CAST (element),
Packit Service 963350
          gerror, sent_debug, structure);
Packit Service 963350
      break;
Packit Service 963350
    case GST_MESSAGE_INFO:
Packit Service 963350
      message =
Packit Service 963350
          gst_message_new_info_with_details (GST_OBJECT_CAST (element), gerror,
Packit Service 963350
          sent_debug, structure);
Packit Service 963350
      break;
Packit Service 963350
    default:
Packit Service 963350
      g_assert_not_reached ();
Packit Service 963350
      break;
Packit Service 963350
  }
Packit Service 963350
Packit Service 963350
  gst_element_post_message (element, message);
Packit Service 963350
Packit Service 963350
  GST_CAT_INFO_OBJECT (GST_CAT_ERROR_SYSTEM, element, "posted %s message: %s",
Packit Service 963350
      (type == GST_MESSAGE_ERROR ? "error" : "warning"), sent_text);
Packit Service 963350
Packit Service 963350
  /* cleanup */
Packit Service 963350
  g_error_free (gerror);
Packit Service 963350
  g_free (sent_debug);
Packit Service 963350
  g_free (sent_text);
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
/**
Packit Service 963350
 * gst_element_message_full:
Packit Service 963350
 * @element:  a #GstElement to send message from
Packit Service 963350
 * @type:     the #GstMessageType
Packit Service 963350
 * @domain:   the GStreamer GError domain this message belongs to
Packit Service 963350
 * @code:     the GError code belonging to the domain
Packit Service 963350
 * @text:     (allow-none) (transfer full): an allocated text string to be used
Packit Service 963350
 *            as a replacement for the default message connected to code,
Packit Service 963350
 *            or %NULL
Packit Service 963350
 * @debug:    (allow-none) (transfer full): an allocated debug message to be
Packit Service 963350
 *            used as a replacement for the default debugging information,
Packit Service 963350
 *            or %NULL
Packit Service 963350
 * @file:     the source code file where the error was generated
Packit Service 963350
 * @function: the source code function where the error was generated
Packit Service 963350
 * @line:     the source code line where the error was generated
Packit Service 963350
 *
Packit Service 963350
 * Post an error, warning or info message on the bus from inside an element.
Packit Service 963350
 *
Packit Service 963350
 * @type must be of #GST_MESSAGE_ERROR, #GST_MESSAGE_WARNING or
Packit Service 963350
 * #GST_MESSAGE_INFO.
Packit Service 963350
 *
Packit Service 963350
 * MT safe.
Packit Service 963350
 */
Packit Service 963350
void gst_element_message_full
Packit Service 963350
    (GstElement * element, GstMessageType type,
Packit Service 963350
    GQuark domain, gint code, gchar * text,
Packit Service 963350
    gchar * debug, const gchar * file, const gchar * function, gint line)
Packit Service 963350
{
Packit Service 963350
  gst_element_message_full_with_details (element, type, domain, code, text,
Packit Service 963350
      debug, file, function, line, NULL);
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
/**
Packit Service 963350
 * gst_element_is_locked_state:
Packit Service 963350
 * @element: a #GstElement.
Packit Service 963350
 *
Packit Service 963350
 * Checks if the state of an element is locked.
Packit Service 963350
 * If the state of an element is locked, state changes of the parent don't
Packit Service 963350
 * affect the element.
Packit Service 963350
 * This way you can leave currently unused elements inside bins. Just lock their
Packit Service 963350
 * state before changing the state from #GST_STATE_NULL.
Packit Service 963350
 *
Packit Service 963350
 * MT safe.
Packit Service 963350
 *
Packit Service 963350
 * Returns: %TRUE, if the element's state is locked.
Packit Service 963350
 */
Packit Service 963350
gboolean
Packit Service 963350
gst_element_is_locked_state (GstElement * element)
Packit Service 963350
{
Packit Service 963350
  gboolean result;
Packit Service 963350
Packit Service 963350
  g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
Packit Service 963350
Packit Service 963350
  GST_OBJECT_LOCK (element);
Packit Service 963350
  result = GST_ELEMENT_IS_LOCKED_STATE (element);
Packit Service 963350
  GST_OBJECT_UNLOCK (element);
Packit Service 963350
Packit Service 963350
  return result;
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
/**
Packit Service 963350
 * gst_element_set_locked_state:
Packit Service 963350
 * @element: a #GstElement
Packit Service 963350
 * @locked_state: %TRUE to lock the element's state
Packit Service 963350
 *
Packit Service 963350
 * Locks the state of an element, so state changes of the parent don't affect
Packit Service 963350
 * this element anymore.
Packit Service 963350
 *
Packit Service 963350
 * MT safe.
Packit Service 963350
 *
Packit Service 963350
 * Returns: %TRUE if the state was changed, %FALSE if bad parameters were given
Packit Service 963350
 * or the elements state-locking needed no change.
Packit Service 963350
 */
Packit Service 963350
gboolean
Packit Service 963350
gst_element_set_locked_state (GstElement * element, gboolean locked_state)
Packit Service 963350
{
Packit Service 963350
  gboolean old;
Packit Service 963350
Packit Service 963350
  g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
Packit Service 963350
Packit Service 963350
  GST_OBJECT_LOCK (element);
Packit Service 963350
  old = GST_ELEMENT_IS_LOCKED_STATE (element);
Packit Service 963350
Packit Service 963350
  if (G_UNLIKELY (old == locked_state))
Packit Service 963350
    goto was_ok;
Packit Service 963350
Packit Service 963350
  if (locked_state) {
Packit Service 963350
    GST_CAT_DEBUG (GST_CAT_STATES, "locking state of element %s",
Packit Service 963350
        GST_ELEMENT_NAME (element));
Packit Service 963350
    GST_OBJECT_FLAG_SET (element, GST_ELEMENT_FLAG_LOCKED_STATE);
Packit Service 963350
  } else {
Packit Service 963350
    GST_CAT_DEBUG (GST_CAT_STATES, "unlocking state of element %s",
Packit Service 963350
        GST_ELEMENT_NAME (element));
Packit Service 963350
    GST_OBJECT_FLAG_UNSET (element, GST_ELEMENT_FLAG_LOCKED_STATE);
Packit Service 963350
  }
Packit Service 963350
  GST_OBJECT_UNLOCK (element);
Packit Service 963350
Packit Service 963350
  return TRUE;
Packit Service 963350
Packit Service 963350
was_ok:
Packit Service 963350
  {
Packit Service 963350
    GST_CAT_DEBUG (GST_CAT_STATES,
Packit Service 963350
        "elements %s was already in locked state %d",
Packit Service 963350
        GST_ELEMENT_NAME (element), old);
Packit Service 963350
    GST_OBJECT_UNLOCK (element);
Packit Service 963350
Packit Service 963350
    return FALSE;
Packit Service 963350
  }
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
/**
Packit Service 963350
 * gst_element_sync_state_with_parent:
Packit Service 963350
 * @element: a #GstElement.
Packit Service 963350
 *
Packit Service 963350
 * Tries to change the state of the element to the same as its parent.
Packit Service 963350
 * If this function returns %FALSE, the state of element is undefined.
Packit Service 963350
 *
Packit Service 963350
 * Returns: %TRUE, if the element's state could be synced to the parent's state.
Packit Service 963350
 *
Packit Service 963350
 * MT safe.
Packit Service 963350
 */
Packit Service 963350
gboolean
Packit Service 963350
gst_element_sync_state_with_parent (GstElement * element)
Packit Service 963350
{
Packit Service 963350
  GstElement *parent;
Packit Service 963350
  GstState target;
Packit Service 963350
  GstStateChangeReturn ret;
Packit Service 963350
Packit Service 963350
  g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
Packit Service 963350
Packit Service 963350
  if ((parent = GST_ELEMENT_CAST (gst_element_get_parent (element)))) {
Packit Service 963350
    GstState parent_current, parent_pending;
Packit Service 963350
Packit Service 963350
    GST_OBJECT_LOCK (parent);
Packit Service 963350
    parent_current = GST_STATE (parent);
Packit Service 963350
    parent_pending = GST_STATE_PENDING (parent);
Packit Service 963350
    GST_OBJECT_UNLOCK (parent);
Packit Service 963350
Packit Service 963350
    /* set to pending if there is one, else we set it to the current state of
Packit Service 963350
     * the parent */
Packit Service 963350
    if (parent_pending != GST_STATE_VOID_PENDING)
Packit Service 963350
      target = parent_pending;
Packit Service 963350
    else
Packit Service 963350
      target = parent_current;
Packit Service 963350
Packit Service 963350
    GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
Packit Service 963350
        "syncing state (%s) to parent %s %s (%s, %s)",
Packit Service 963350
        gst_element_state_get_name (GST_STATE (element)),
Packit Service 963350
        GST_ELEMENT_NAME (parent), gst_element_state_get_name (target),
Packit Service 963350
        gst_element_state_get_name (parent_current),
Packit Service 963350
        gst_element_state_get_name (parent_pending));
Packit Service 963350
Packit Service 963350
    ret = gst_element_set_state (element, target);
Packit Service 963350
    if (ret == GST_STATE_CHANGE_FAILURE)
Packit Service 963350
      goto failed;
Packit Service 963350
Packit Service 963350
    gst_object_unref (parent);
Packit Service 963350
Packit Service 963350
    return TRUE;
Packit Service 963350
  } else {
Packit Service 963350
    GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element, "element has no parent");
Packit Service 963350
  }
Packit Service 963350
  return FALSE;
Packit Service 963350
Packit Service 963350
  /* ERROR */
Packit Service 963350
failed:
Packit Service 963350
  {
Packit Service 963350
    GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
Packit Service 963350
        "syncing state failed (%s)",
Packit Service 963350
        gst_element_state_change_return_get_name (ret));
Packit Service 963350
    gst_object_unref (parent);
Packit Service 963350
    return FALSE;
Packit Service 963350
  }
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
/* MT safe */
Packit Service 963350
static GstStateChangeReturn
Packit Service 963350
gst_element_get_state_func (GstElement * element,
Packit Service 963350
    GstState * state, GstState * pending, GstClockTime timeout)
Packit Service 963350
{
Packit Service 963350
  GstStateChangeReturn ret = GST_STATE_CHANGE_FAILURE;
Packit Service 963350
  GstState old_pending;
Packit Service 963350
Packit Service 963350
  GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element, "getting state, timeout %"
Packit Service 963350
      GST_TIME_FORMAT, GST_TIME_ARGS (timeout));
Packit Service 963350
Packit Service 963350
  GST_OBJECT_LOCK (element);
Packit Service 963350
  ret = GST_STATE_RETURN (element);
Packit Service 963350
  GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element, "RETURN is %s",
Packit Service 963350
      gst_element_state_change_return_get_name (ret));
Packit Service 963350
Packit Service 963350
  /* we got an error, report immediately */
Packit Service 963350
  if (ret == GST_STATE_CHANGE_FAILURE)
Packit Service 963350
    goto done;
Packit Service 963350
Packit Service 963350
  /* we got no_preroll, report immediately */
Packit Service 963350
  if (ret == GST_STATE_CHANGE_NO_PREROLL)
Packit Service 963350
    goto done;
Packit Service 963350
Packit Service 963350
  /* no need to wait async if we are not async */
Packit Service 963350
  if (ret != GST_STATE_CHANGE_ASYNC)
Packit Service 963350
    goto done;
Packit Service 963350
Packit Service 963350
  old_pending = GST_STATE_PENDING (element);
Packit Service 963350
  if (old_pending != GST_STATE_VOID_PENDING) {
Packit Service 963350
    gboolean signaled;
Packit Service 963350
    guint32 cookie;
Packit Service 963350
Packit Service 963350
    /* get cookie to detect state changes during waiting */
Packit Service 963350
    cookie = element->state_cookie;
Packit Service 963350
Packit Service 963350
    GST_CAT_INFO_OBJECT (GST_CAT_STATES, element,
Packit Service 963350
        "waiting for element to commit state");
Packit Service 963350
Packit Service 963350
    /* we have a pending state change, wait for it to complete */
Packit Service 963350
    if (timeout != GST_CLOCK_TIME_NONE) {
Packit Service 963350
      gint64 end_time;
Packit Service 963350
      /* make timeout absolute */
Packit Service 963350
      end_time = g_get_monotonic_time () + (timeout / 1000);
Packit Service 963350
      signaled = GST_STATE_WAIT_UNTIL (element, end_time);
Packit Service 963350
    } else {
Packit Service 963350
      GST_STATE_WAIT (element);
Packit Service 963350
      signaled = TRUE;
Packit Service 963350
    }
Packit Service 963350
Packit Service 963350
    if (!signaled) {
Packit Service 963350
      GST_CAT_INFO_OBJECT (GST_CAT_STATES, element, "timed out");
Packit Service 963350
      /* timeout triggered */
Packit Service 963350
      ret = GST_STATE_CHANGE_ASYNC;
Packit Service 963350
    } else {
Packit Service 963350
      if (cookie != element->state_cookie)
Packit Service 963350
        goto interrupted;
Packit Service 963350
Packit Service 963350
      /* could be success or failure */
Packit Service 963350
      if (old_pending == GST_STATE (element)) {
Packit Service 963350
        GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element, "got success");
Packit Service 963350
        ret = GST_STATE_CHANGE_SUCCESS;
Packit Service 963350
      } else {
Packit Service 963350
        GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element, "got failure");
Packit Service 963350
        ret = GST_STATE_CHANGE_FAILURE;
Packit Service 963350
      }
Packit Service 963350
    }
Packit Service 963350
    /* if nothing is pending anymore we can return SUCCESS */
Packit Service 963350
    if (GST_STATE_PENDING (element) == GST_STATE_VOID_PENDING) {
Packit Service 963350
      GST_CAT_LOG_OBJECT (GST_CAT_STATES, element, "nothing pending");
Packit Service 963350
      ret = GST_STATE_CHANGE_SUCCESS;
Packit Service 963350
    }
Packit Service 963350
  }
Packit Service 963350
Packit Service 963350
done:
Packit Service 963350
  if (state)
Packit Service 963350
    *state = GST_STATE (element);
Packit Service 963350
  if (pending)
Packit Service 963350
    *pending = GST_STATE_PENDING (element);
Packit Service 963350
Packit Service 963350
  GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
Packit Service 963350
      "state current: %s, pending: %s, result: %s",
Packit Service 963350
      gst_element_state_get_name (GST_STATE (element)),
Packit Service 963350
      gst_element_state_get_name (GST_STATE_PENDING (element)),
Packit Service 963350
      gst_element_state_change_return_get_name (ret));
Packit Service 963350
  GST_OBJECT_UNLOCK (element);
Packit Service 963350
Packit Service 963350
  return ret;
Packit Service 963350
Packit Service 963350
interrupted:
Packit Service 963350
  {
Packit Service 963350
    if (state)
Packit Service 963350
      *state = GST_STATE_VOID_PENDING;
Packit Service 963350
    if (pending)
Packit Service 963350
      *pending = GST_STATE_VOID_PENDING;
Packit Service 963350
Packit Service 963350
    GST_CAT_INFO_OBJECT (GST_CAT_STATES, element, "interruped");
Packit Service 963350
Packit Service 963350
    GST_OBJECT_UNLOCK (element);
Packit Service 963350
Packit Service 963350
    return GST_STATE_CHANGE_FAILURE;
Packit Service 963350
  }
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
/**
Packit Service 963350
 * gst_element_get_state:
Packit Service 963350
 * @element: a #GstElement to get the state of.
Packit Service 963350
 * @state: (out) (allow-none): a pointer to #GstState to hold the state.
Packit Service 963350
 *     Can be %NULL.
Packit Service 963350
 * @pending: (out) (allow-none): a pointer to #GstState to hold the pending
Packit Service 963350
 *     state. Can be %NULL.
Packit Service 963350
 * @timeout: a #GstClockTime to specify the timeout for an async
Packit Service 963350
 *           state change or %GST_CLOCK_TIME_NONE for infinite timeout.
Packit Service 963350
 *
Packit Service 963350
 * Gets the state of the element.
Packit Service 963350
 *
Packit Service 963350
 * For elements that performed an ASYNC state change, as reported by
Packit Service 963350
 * gst_element_set_state(), this function will block up to the
Packit Service 963350
 * specified timeout value for the state change to complete.
Packit Service 963350
 * If the element completes the state change or goes into
Packit Service 963350
 * an error, this function returns immediately with a return value of
Packit Service 963350
 * %GST_STATE_CHANGE_SUCCESS or %GST_STATE_CHANGE_FAILURE respectively.
Packit Service 963350
 *
Packit Service 963350
 * For elements that did not return %GST_STATE_CHANGE_ASYNC, this function
Packit Service 963350
 * returns the current and pending state immediately.
Packit Service 963350
 *
Packit Service 963350
 * This function returns %GST_STATE_CHANGE_NO_PREROLL if the element
Packit Service 963350
 * successfully changed its state but is not able to provide data yet.
Packit Service 963350
 * This mostly happens for live sources that only produce data in
Packit Service 963350
 * %GST_STATE_PLAYING. While the state change return is equivalent to
Packit Service 963350
 * %GST_STATE_CHANGE_SUCCESS, it is returned to the application to signal that
Packit Service 963350
 * some sink elements might not be able to complete their state change because
Packit Service 963350
 * an element is not producing data to complete the preroll. When setting the
Packit Service 963350
 * element to playing, the preroll will complete and playback will start.
Packit Service 963350
 *
Packit Service 963350
 * Returns: %GST_STATE_CHANGE_SUCCESS if the element has no more pending state
Packit Service 963350
 *          and the last state change succeeded, %GST_STATE_CHANGE_ASYNC if the
Packit Service 963350
 *          element is still performing a state change or
Packit Service 963350
 *          %GST_STATE_CHANGE_FAILURE if the last state change failed.
Packit Service 963350
 *
Packit Service 963350
 * MT safe.
Packit Service 963350
 */
Packit Service 963350
GstStateChangeReturn
Packit Service 963350
gst_element_get_state (GstElement * element,
Packit Service 963350
    GstState * state, GstState * pending, GstClockTime timeout)
Packit Service 963350
{
Packit Service 963350
  GstElementClass *oclass;
Packit Service 963350
  GstStateChangeReturn result = GST_STATE_CHANGE_FAILURE;
Packit Service 963350
Packit Service 963350
  g_return_val_if_fail (GST_IS_ELEMENT (element), GST_STATE_CHANGE_FAILURE);
Packit Service 963350
Packit Service 963350
  oclass = GST_ELEMENT_GET_CLASS (element);
Packit Service 963350
Packit Service 963350
  if (oclass->get_state)
Packit Service 963350
    result = (oclass->get_state) (element, state, pending, timeout);
Packit Service 963350
Packit Service 963350
  return result;
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
/**
Packit Service 963350
 * gst_element_abort_state:
Packit Service 963350
 * @element: a #GstElement to abort the state of.
Packit Service 963350
 *
Packit Service 963350
 * Abort the state change of the element. This function is used
Packit Service 963350
 * by elements that do asynchronous state changes and find out
Packit Service 963350
 * something is wrong.
Packit Service 963350
 *
Packit Service 963350
 * This function should be called with the STATE_LOCK held.
Packit Service 963350
 *
Packit Service 963350
 * MT safe.
Packit Service 963350
 */
Packit Service 963350
void
Packit Service 963350
gst_element_abort_state (GstElement * element)
Packit Service 963350
{
Packit Service 963350
  GstState pending;
Packit Service 963350
Packit Service 963350
#ifndef GST_DISABLE_GST_DEBUG
Packit Service 963350
  GstState old_state;
Packit Service 963350
#endif
Packit Service 963350
Packit Service 963350
  g_return_if_fail (GST_IS_ELEMENT (element));
Packit Service 963350
Packit Service 963350
  GST_OBJECT_LOCK (element);
Packit Service 963350
  pending = GST_STATE_PENDING (element);
Packit Service 963350
Packit Service 963350
  if (pending == GST_STATE_VOID_PENDING ||
Packit Service 963350
      GST_STATE_RETURN (element) == GST_STATE_CHANGE_FAILURE)
Packit Service 963350
    goto nothing_aborted;
Packit Service 963350
Packit Service 963350
#ifndef GST_DISABLE_GST_DEBUG
Packit Service 963350
  old_state = GST_STATE (element);
Packit Service 963350
Packit Service 963350
  GST_CAT_INFO_OBJECT (GST_CAT_STATES, element,
Packit Service 963350
      "aborting state from %s to %s", gst_element_state_get_name (old_state),
Packit Service 963350
      gst_element_state_get_name (pending));
Packit Service 963350
#endif
Packit Service 963350
Packit Service 963350
  /* flag error */
Packit Service 963350
  GST_STATE_RETURN (element) = GST_STATE_CHANGE_FAILURE;
Packit Service 963350
Packit Service 963350
  GST_STATE_BROADCAST (element);
Packit Service 963350
  GST_OBJECT_UNLOCK (element);
Packit Service 963350
Packit Service 963350
  return;
Packit Service 963350
Packit Service 963350
nothing_aborted:
Packit Service 963350
  {
Packit Service 963350
    GST_OBJECT_UNLOCK (element);
Packit Service 963350
    return;
Packit Service 963350
  }
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
/* Not static because GstBin has manual state handling too */
Packit Service 963350
void
Packit Service 963350
_priv_gst_element_state_changed (GstElement * element, GstState oldstate,
Packit Service 963350
    GstState newstate, GstState pending)
Packit Service 963350
{
Packit Service 963350
  GstElementClass *klass = GST_ELEMENT_GET_CLASS (element);
Packit Service 963350
  GstMessage *message;
Packit Service 963350
Packit Service 963350
  GST_CAT_INFO_OBJECT (GST_CAT_STATES, element,
Packit Service 963350
      "notifying about state-changed %s to %s (%s pending)",
Packit Service 963350
      gst_element_state_get_name (oldstate),
Packit Service 963350
      gst_element_state_get_name (newstate),
Packit Service 963350
      gst_element_state_get_name (pending));
Packit Service 963350
Packit Service 963350
  if (klass->state_changed)
Packit Service 963350
    klass->state_changed (element, oldstate, newstate, pending);
Packit Service 963350
Packit Service 963350
  message = gst_message_new_state_changed (GST_OBJECT_CAST (element),
Packit Service 963350
      oldstate, newstate, pending);
Packit Service 963350
  gst_element_post_message (element, message);
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
/**
Packit Service 963350
 * gst_element_continue_state:
Packit Service 963350
 * @element: a #GstElement to continue the state change of.
Packit Service 963350
 * @ret: The previous state return value
Packit Service 963350
 *
Packit Service 963350
 * Commit the state change of the element and proceed to the next
Packit Service 963350
 * pending state if any. This function is used
Packit Service 963350
 * by elements that do asynchronous state changes.
Packit Service 963350
 * The core will normally call this method automatically when an
Packit Service 963350
 * element returned %GST_STATE_CHANGE_SUCCESS from the state change function.
Packit Service 963350
 *
Packit Service 963350
 * If after calling this method the element still has not reached
Packit Service 963350
 * the pending state, the next state change is performed.
Packit Service 963350
 *
Packit Service 963350
 * This method is used internally and should normally not be called by plugins
Packit Service 963350
 * or applications.
Packit Service 963350
 *
Packit Service 963350
 * This function must be called with STATE_LOCK held.
Packit Service 963350
 *
Packit Service 963350
 * Returns: The result of the commit state change.
Packit Service 963350
 *
Packit Service 963350
 * MT safe.
Packit Service 963350
 */
Packit Service 963350
GstStateChangeReturn
Packit Service 963350
gst_element_continue_state (GstElement * element, GstStateChangeReturn ret)
Packit Service 963350
{
Packit Service 963350
  GstStateChangeReturn old_ret;
Packit Service 963350
  GstState old_state, old_next;
Packit Service 963350
  GstState current, next, pending;
Packit Service 963350
  GstStateChange transition;
Packit Service 963350
Packit Service 963350
  GST_OBJECT_LOCK (element);
Packit Service 963350
  old_ret = GST_STATE_RETURN (element);
Packit Service 963350
  GST_STATE_RETURN (element) = ret;
Packit Service 963350
  pending = GST_STATE_PENDING (element);
Packit Service 963350
Packit Service 963350
  /* check if there is something to commit */
Packit Service 963350
  if (pending == GST_STATE_VOID_PENDING)
Packit Service 963350
    goto nothing_pending;
Packit Service 963350
Packit Service 963350
  old_state = GST_STATE (element);
Packit Service 963350
  /* this is the state we should go to next */
Packit Service 963350
  old_next = GST_STATE_NEXT (element);
Packit Service 963350
  /* update current state */
Packit Service 963350
  current = GST_STATE (element) = old_next;
Packit Service 963350
Packit Service 963350
  /* see if we reached the final state */
Packit Service 963350
  if (pending == current)
Packit Service 963350
    goto complete;
Packit Service 963350
Packit Service 963350
  next = GST_STATE_GET_NEXT (current, pending);
Packit Service 963350
  transition = (GstStateChange) GST_STATE_TRANSITION (current, next);
Packit Service 963350
Packit Service 963350
  GST_STATE_NEXT (element) = next;
Packit Service 963350
  /* mark busy */
Packit Service 963350
  GST_STATE_RETURN (element) = GST_STATE_CHANGE_ASYNC;
Packit Service 963350
  GST_OBJECT_UNLOCK (element);
Packit Service 963350
Packit Service 963350
  GST_CAT_INFO_OBJECT (GST_CAT_STATES, element,
Packit Service 963350
      "committing state from %s to %s, pending %s, next %s",
Packit Service 963350
      gst_element_state_get_name (old_state),
Packit Service 963350
      gst_element_state_get_name (old_next),
Packit Service 963350
      gst_element_state_get_name (pending), gst_element_state_get_name (next));
Packit Service 963350
Packit Service 963350
  _priv_gst_element_state_changed (element, old_state, old_next, pending);
Packit Service 963350
Packit Service 963350
  GST_CAT_INFO_OBJECT (GST_CAT_STATES, element,
Packit Service 963350
      "continue state change %s to %s, final %s",
Packit Service 963350
      gst_element_state_get_name (current),
Packit Service 963350
      gst_element_state_get_name (next), gst_element_state_get_name (pending));
Packit Service 963350
Packit Service 963350
  ret = gst_element_change_state (element, transition);
Packit Service 963350
Packit Service 963350
  return ret;
Packit Service 963350
Packit Service 963350
nothing_pending:
Packit Service 963350
  {
Packit Service 963350
    GST_CAT_INFO_OBJECT (GST_CAT_STATES, element, "nothing pending");
Packit Service 963350
    GST_OBJECT_UNLOCK (element);
Packit Service 963350
    return ret;
Packit Service 963350
  }
Packit Service 963350
complete:
Packit Service 963350
  {
Packit Service 963350
    GST_STATE_PENDING (element) = GST_STATE_VOID_PENDING;
Packit Service 963350
    GST_STATE_NEXT (element) = GST_STATE_VOID_PENDING;
Packit Service 963350
Packit Service 963350
    GST_CAT_INFO_OBJECT (GST_CAT_STATES, element,
Packit Service 963350
        "completed state change to %s", gst_element_state_get_name (pending));
Packit Service 963350
    GST_OBJECT_UNLOCK (element);
Packit Service 963350
Packit Service 963350
    /* don't post silly messages with the same state. This can happen
Packit Service 963350
     * when an element state is changed to what it already was. For bins
Packit Service 963350
     * this can be the result of a lost state, which we check with the
Packit Service 963350
     * previous return value.
Packit Service 963350
     * We do signal the cond though as a _get_state() might be blocking
Packit Service 963350
     * on it. */
Packit Service 963350
    if (old_state != old_next || old_ret == GST_STATE_CHANGE_ASYNC)
Packit Service 963350
      _priv_gst_element_state_changed (element, old_state, old_next,
Packit Service 963350
          GST_STATE_VOID_PENDING);
Packit Service 963350
Packit Service 963350
    GST_STATE_BROADCAST (element);
Packit Service 963350
Packit Service 963350
    return ret;
Packit Service 963350
  }
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
/**
Packit Service 963350
 * gst_element_lost_state:
Packit Service 963350
 * @element: a #GstElement the state is lost of
Packit Service 963350
 *
Packit Service 963350
 * Brings the element to the lost state. The current state of the
Packit Service 963350
 * element is copied to the pending state so that any call to
Packit Service 963350
 * gst_element_get_state() will return %GST_STATE_CHANGE_ASYNC.
Packit Service 963350
 *
Packit Service 963350
 * An ASYNC_START message is posted. If the element was PLAYING, it will
Packit Service 963350
 * go to PAUSED. The element will be restored to its PLAYING state by
Packit Service 963350
 * the parent pipeline when it prerolls again.
Packit Service 963350
 *
Packit Service 963350
 * This is mostly used for elements that lost their preroll buffer
Packit Service 963350
 * in the %GST_STATE_PAUSED or %GST_STATE_PLAYING state after a flush,
Packit Service 963350
 * they will go to their pending state again when a new preroll buffer is
Packit Service 963350
 * queued. This function can only be called when the element is currently
Packit Service 963350
 * not in error or an async state change.
Packit Service 963350
 *
Packit Service 963350
 * This function is used internally and should normally not be called from
Packit Service 963350
 * plugins or applications.
Packit Service 963350
 */
Packit Service 963350
void
Packit Service 963350
gst_element_lost_state (GstElement * element)
Packit Service 963350
{
Packit Service 963350
  GstState old_state, new_state;
Packit Service 963350
  GstMessage *message;
Packit Service 963350
Packit Service 963350
  g_return_if_fail (GST_IS_ELEMENT (element));
Packit Service 963350
Packit Service 963350
  GST_OBJECT_LOCK (element);
Packit Service 963350
  if (GST_STATE_RETURN (element) == GST_STATE_CHANGE_FAILURE)
Packit Service 963350
    goto nothing_lost;
Packit Service 963350
Packit Service 963350
  if (GST_STATE_PENDING (element) != GST_STATE_VOID_PENDING)
Packit Service 963350
    goto only_async_start;
Packit Service 963350
Packit Service 963350
  old_state = GST_STATE (element);
Packit Service 963350
Packit Service 963350
  /* when we were PLAYING, the new state is PAUSED. We will also not
Packit Service 963350
   * automatically go to PLAYING but let the parent bin(s) set us to PLAYING
Packit Service 963350
   * when we preroll. */
Packit Service 963350
  if (old_state > GST_STATE_PAUSED)
Packit Service 963350
    new_state = GST_STATE_PAUSED;
Packit Service 963350
  else
Packit Service 963350
    new_state = old_state;
Packit Service 963350
Packit Service 963350
  GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
Packit Service 963350
      "lost state of %s to %s", gst_element_state_get_name (old_state),
Packit Service 963350
      gst_element_state_get_name (new_state));
Packit Service 963350
Packit Service 963350
  GST_STATE (element) = new_state;
Packit Service 963350
  GST_STATE_NEXT (element) = new_state;
Packit Service 963350
  GST_STATE_PENDING (element) = new_state;
Packit Service 963350
  GST_STATE_RETURN (element) = GST_STATE_CHANGE_ASYNC;
Packit Service 963350
  GST_OBJECT_UNLOCK (element);
Packit Service 963350
Packit Service 963350
  _priv_gst_element_state_changed (element, new_state, new_state, new_state);
Packit Service 963350
Packit Service 963350
  message = gst_message_new_async_start (GST_OBJECT_CAST (element));
Packit Service 963350
  gst_element_post_message (element, message);
Packit Service 963350
Packit Service 963350
  return;
Packit Service 963350
Packit Service 963350
nothing_lost:
Packit Service 963350
  {
Packit Service 963350
    GST_OBJECT_UNLOCK (element);
Packit Service 963350
    return;
Packit Service 963350
  }
Packit Service 963350
only_async_start:
Packit Service 963350
  {
Packit Service 963350
    GST_OBJECT_UNLOCK (element);
Packit Service 963350
Packit Service 963350
    message = gst_message_new_async_start (GST_OBJECT_CAST (element));
Packit Service 963350
    gst_element_post_message (element, message);
Packit Service 963350
    return;
Packit Service 963350
  }
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
/**
Packit Service 963350
 * gst_element_set_state:
Packit Service 963350
 * @element: a #GstElement to change state of.
Packit Service 963350
 * @state: the element's new #GstState.
Packit Service 963350
 *
Packit Service 963350
 * Sets the state of the element. This function will try to set the
Packit Service 963350
 * requested state by going through all the intermediary states and calling
Packit Service 963350
 * the class's state change function for each.
Packit Service 963350
 *
Packit Service 963350
 * This function can return #GST_STATE_CHANGE_ASYNC, in which case the
Packit Service 963350
 * element will perform the remainder of the state change asynchronously in
Packit Service 963350
 * another thread.
Packit Service 963350
 * An application can use gst_element_get_state() to wait for the completion
Packit Service 963350
 * of the state change or it can wait for a %GST_MESSAGE_ASYNC_DONE or
Packit Service 963350
 * %GST_MESSAGE_STATE_CHANGED on the bus.
Packit Service 963350
 *
Packit Service 963350
 * State changes to %GST_STATE_READY or %GST_STATE_NULL never return
Packit Service 963350
 * #GST_STATE_CHANGE_ASYNC.
Packit Service 963350
 *
Packit Service 963350
 * Returns: Result of the state change using #GstStateChangeReturn.
Packit Service 963350
 *
Packit Service 963350
 * MT safe.
Packit Service 963350
 */
Packit Service 963350
GstStateChangeReturn
Packit Service 963350
gst_element_set_state (GstElement * element, GstState state)
Packit Service 963350
{
Packit Service 963350
  GstElementClass *oclass;
Packit Service 963350
  GstStateChangeReturn result = GST_STATE_CHANGE_FAILURE;
Packit Service 963350
Packit Service 963350
  g_return_val_if_fail (GST_IS_ELEMENT (element), GST_STATE_CHANGE_FAILURE);
Packit Service 963350
Packit Service 963350
  oclass = GST_ELEMENT_GET_CLASS (element);
Packit Service 963350
Packit Service 963350
  if (oclass->set_state)
Packit Service 963350
    result = (oclass->set_state) (element, state);
Packit Service 963350
Packit Service 963350
  return result;
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
/*
Packit Service 963350
 * default set state function, calculates the next state based
Packit Service 963350
 * on current state and calls the change_state function
Packit Service 963350
 */
Packit Service 963350
static GstStateChangeReturn
Packit Service 963350
gst_element_set_state_func (GstElement * element, GstState state)
Packit Service 963350
{
Packit Service 963350
  GstState current, next, old_pending;
Packit Service 963350
  GstStateChangeReturn ret;
Packit Service 963350
  GstStateChange transition;
Packit Service 963350
  GstStateChangeReturn old_ret;
Packit Service 963350
Packit Service 963350
  g_return_val_if_fail (GST_IS_ELEMENT (element), GST_STATE_CHANGE_FAILURE);
Packit Service 963350
Packit Service 963350
  GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element, "set_state to %s",
Packit Service 963350
      gst_element_state_get_name (state));
Packit Service 963350
Packit Service 963350
  /* state lock is taken to protect the set_state() and get_state()
Packit Service 963350
   * procedures, it does not lock any variables. */
Packit Service 963350
  GST_STATE_LOCK (element);
Packit Service 963350
Packit Service 963350
  /* now calculate how to get to the new state */
Packit Service 963350
  GST_OBJECT_LOCK (element);
Packit Service 963350
  old_ret = GST_STATE_RETURN (element);
Packit Service 963350
  /* previous state change returned an error, remove all pending
Packit Service 963350
   * and next states */
Packit Service 963350
  if (old_ret == GST_STATE_CHANGE_FAILURE) {
Packit Service 963350
    GST_STATE_NEXT (element) = GST_STATE_VOID_PENDING;
Packit Service 963350
    GST_STATE_PENDING (element) = GST_STATE_VOID_PENDING;
Packit Service 963350
    GST_STATE_RETURN (element) = GST_STATE_CHANGE_SUCCESS;
Packit Service 963350
  }
Packit Service 963350
Packit Service 963350
  current = GST_STATE (element);
Packit Service 963350
  next = GST_STATE_NEXT (element);
Packit Service 963350
  old_pending = GST_STATE_PENDING (element);
Packit Service 963350
Packit Service 963350
  /* this is the (new) state we should go to. TARGET is the last state we set on
Packit Service 963350
   * the element. */
Packit Service 963350
  if (state != GST_STATE_TARGET (element)) {
Packit Service 963350
    GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
Packit Service 963350
        "setting target state to %s", gst_element_state_get_name (state));
Packit Service 963350
    GST_STATE_TARGET (element) = state;
Packit Service 963350
    /* increment state cookie so that we can track each state change. We only do
Packit Service 963350
     * this if this is actually a new state change. */
Packit Service 963350
    element->state_cookie++;
Packit Service 963350
  }
Packit Service 963350
  GST_STATE_PENDING (element) = state;
Packit Service 963350
Packit Service 963350
  GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
Packit Service 963350
      "current %s, old_pending %s, next %s, old return %s",
Packit Service 963350
      gst_element_state_get_name (current),
Packit Service 963350
      gst_element_state_get_name (old_pending),
Packit Service 963350
      gst_element_state_get_name (next),
Packit Service 963350
      gst_element_state_change_return_get_name (old_ret));
Packit Service 963350
Packit Service 963350
  /* if the element was busy doing a state change, we just update the
Packit Service 963350
   * target state, it'll get to it async then. */
Packit Service 963350
  if (old_pending != GST_STATE_VOID_PENDING) {
Packit Service 963350
    /* upwards state change will happen ASYNC */
Packit Service 963350
    if (old_pending <= state)
Packit Service 963350
      goto was_busy;
Packit Service 963350
    /* element is going to this state already */
Packit Service 963350
    else if (next == state)
Packit Service 963350
      goto was_busy;
Packit Service 963350
    /* element was performing an ASYNC upward state change and
Packit Service 963350
     * we request to go downward again. Start from the next pending
Packit Service 963350
     * state then. */
Packit Service 963350
    else if (next > state
Packit Service 963350
        && GST_STATE_RETURN (element) == GST_STATE_CHANGE_ASYNC) {
Packit Service 963350
      current = next;
Packit Service 963350
    }
Packit Service 963350
  }
Packit Service 963350
  next = GST_STATE_GET_NEXT (current, state);
Packit Service 963350
  /* now we store the next state */
Packit Service 963350
  GST_STATE_NEXT (element) = next;
Packit Service 963350
  /* mark busy, we need to check that there is actually a state change
Packit Service 963350
   * to be done else we could accidentally override SUCCESS/NO_PREROLL and
Packit Service 963350
   * the default element change_state function has no way to know what the
Packit Service 963350
   * old value was... could consider this a FIXME...*/
Packit Service 963350
  if (current != next)
Packit Service 963350
    GST_STATE_RETURN (element) = GST_STATE_CHANGE_ASYNC;
Packit Service 963350
Packit Service 963350
  transition = (GstStateChange) GST_STATE_TRANSITION (current, next);
Packit Service 963350
Packit Service 963350
  GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
Packit Service 963350
      "%s: setting state from %s to %s",
Packit Service 963350
      (next != state ? "intermediate" : "final"),
Packit Service 963350
      gst_element_state_get_name (current), gst_element_state_get_name (next));
Packit Service 963350
Packit Service 963350
  /* now signal any waiters, they will error since the cookie was incremented */
Packit Service 963350
  GST_STATE_BROADCAST (element);
Packit Service 963350
Packit Service 963350
  GST_OBJECT_UNLOCK (element);
Packit Service 963350
Packit Service 963350
  ret = gst_element_change_state (element, transition);
Packit Service 963350
Packit Service 963350
  GST_STATE_UNLOCK (element);
Packit Service 963350
Packit Service 963350
  GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element, "returned %s",
Packit Service 963350
      gst_element_state_change_return_get_name (ret));
Packit Service 963350
Packit Service 963350
  return ret;
Packit Service 963350
Packit Service 963350
was_busy:
Packit Service 963350
  {
Packit Service 963350
    GST_STATE_RETURN (element) = GST_STATE_CHANGE_ASYNC;
Packit Service 963350
    GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
Packit Service 963350
        "element was busy with async state change");
Packit Service 963350
    GST_OBJECT_UNLOCK (element);
Packit Service 963350
Packit Service 963350
    GST_STATE_UNLOCK (element);
Packit Service 963350
Packit Service 963350
    return GST_STATE_CHANGE_ASYNC;
Packit Service 963350
  }
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
/**
Packit Service 963350
 * gst_element_change_state:
Packit Service 963350
 * @element: a #GstElement
Packit Service 963350
 * @transition: the requested transition
Packit Service 963350
 *
Packit Service 963350
 * Perform @transition on @element.
Packit Service 963350
 *
Packit Service 963350
 * This function must be called with STATE_LOCK held and is mainly used
Packit Service 963350
 * internally.
Packit Service 963350
 *
Packit Service 963350
 * Returns: the #GstStateChangeReturn of the state transition.
Packit Service 963350
 */
Packit Service 963350
GstStateChangeReturn
Packit Service 963350
gst_element_change_state (GstElement * element, GstStateChange transition)
Packit Service 963350
{
Packit Service 963350
  GstElementClass *oclass;
Packit Service 963350
  GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
Packit Service 963350
Packit Service 963350
  oclass = GST_ELEMENT_GET_CLASS (element);
Packit Service 963350
Packit Service 963350
  GST_TRACER_ELEMENT_CHANGE_STATE_PRE (element, transition);
Packit Service 963350
Packit Service 963350
  /* call the state change function so it can set the state */
Packit Service 963350
  if (oclass->change_state)
Packit Service 963350
    ret = (oclass->change_state) (element, transition);
Packit Service 963350
  else
Packit Service 963350
    ret = GST_STATE_CHANGE_FAILURE;
Packit Service 963350
Packit Service 963350
  GST_TRACER_ELEMENT_CHANGE_STATE_POST (element, transition, ret);
Packit Service 963350
Packit Service 963350
  switch (ret) {
Packit Service 963350
    case GST_STATE_CHANGE_FAILURE:
Packit Service 963350
      GST_CAT_INFO_OBJECT (GST_CAT_STATES, element,
Packit Service 963350
          "have FAILURE change_state return");
Packit Service 963350
      /* state change failure */
Packit Service 963350
      gst_element_abort_state (element);
Packit Service 963350
      break;
Packit Service 963350
    case GST_STATE_CHANGE_ASYNC:
Packit Service 963350
    {
Packit Service 963350
      GstState target;
Packit Service 963350
Packit Service 963350
      GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
Packit Service 963350
          "element will change state ASYNC");
Packit Service 963350
Packit Service 963350
      target = GST_STATE_TARGET (element);
Packit Service 963350
Packit Service 963350
      if (target > GST_STATE_READY)
Packit Service 963350
        goto async;
Packit Service 963350
Packit Service 963350
      /* else we just continue the state change downwards */
Packit Service 963350
      GST_CAT_INFO_OBJECT (GST_CAT_STATES, element,
Packit Service 963350
          "forcing commit state %s <= %s",
Packit Service 963350
          gst_element_state_get_name (target),
Packit Service 963350
          gst_element_state_get_name (GST_STATE_READY));
Packit Service 963350
Packit Service 963350
      ret = gst_element_continue_state (element, GST_STATE_CHANGE_SUCCESS);
Packit Service 963350
      break;
Packit Service 963350
    }
Packit Service 963350
    case GST_STATE_CHANGE_SUCCESS:
Packit Service 963350
      GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
Packit Service 963350
          "element changed state SUCCESS");
Packit Service 963350
      /* we can commit the state now which will proceeed to
Packit Service 963350
       * the next state */
Packit Service 963350
      ret = gst_element_continue_state (element, ret);
Packit Service 963350
      break;
Packit Service 963350
    case GST_STATE_CHANGE_NO_PREROLL:
Packit Service 963350
      GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
Packit Service 963350
          "element changed state NO_PREROLL");
Packit Service 963350
      /* we can commit the state now which will proceeed to
Packit Service 963350
       * the next state */
Packit Service 963350
      ret = gst_element_continue_state (element, ret);
Packit Service 963350
      break;
Packit Service 963350
    default:
Packit Service 963350
      goto invalid_return;
Packit Service 963350
  }
Packit Service 963350
Packit Service 963350
  GST_CAT_LOG_OBJECT (GST_CAT_STATES, element, "exit state change %d", ret);
Packit Service 963350
Packit Service 963350
  return ret;
Packit Service 963350
Packit Service 963350
async:
Packit Service 963350
  GST_CAT_LOG_OBJECT (GST_CAT_STATES, element, "exit async state change %d",
Packit Service 963350
      ret);
Packit Service 963350
Packit Service 963350
  return ret;
Packit Service 963350
Packit Service 963350
  /* ERROR */
Packit Service 963350
invalid_return:
Packit Service 963350
  {
Packit Service 963350
    GST_OBJECT_LOCK (element);
Packit Service 963350
    /* somebody added a GST_STATE_ and forgot to do stuff here ! */
Packit Service 963350
    g_critical ("%s: unknown return value %d from a state change function",
Packit Service 963350
        GST_ELEMENT_NAME (element), ret);
Packit Service 963350
Packit Service 963350
    /* we are in error now */
Packit Service 963350
    ret = GST_STATE_CHANGE_FAILURE;
Packit Service 963350
    GST_STATE_RETURN (element) = ret;
Packit Service 963350
    GST_OBJECT_UNLOCK (element);
Packit Service 963350
Packit Service 963350
    return ret;
Packit Service 963350
  }
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
/* gst_iterator_fold functions for pads_activate
Packit Service 963350
 * Stop the iterator if activating one pad failed, but only if that pad
Packit Service 963350
 * has not been removed from the element. */
Packit Service 963350
static gboolean
Packit Service 963350
activate_pads (const GValue * vpad, GValue * ret, gboolean * active)
Packit Service 963350
{
Packit Service 963350
  GstPad *pad = g_value_get_object (vpad);
Packit Service 963350
  gboolean cont = TRUE;
Packit Service 963350
Packit Service 963350
  if (!gst_pad_set_active (pad, *active)) {
Packit Service 963350
    if (GST_PAD_PARENT (pad) != NULL) {
Packit Service 963350
      cont = FALSE;
Packit Service 963350
      g_value_set_boolean (ret, FALSE);
Packit Service 963350
    }
Packit Service 963350
  }
Packit Service 963350
Packit Service 963350
  return cont;
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
/* returns false on error or early cutout of the fold, true if all
Packit Service 963350
 * pads in @iter were (de)activated successfully. */
Packit Service 963350
static gboolean
Packit Service 963350
iterator_activate_fold_with_resync (GstIterator * iter,
Packit Service 963350
    GstIteratorFoldFunction func, gpointer user_data)
Packit Service 963350
{
Packit Service 963350
  GstIteratorResult ires;
Packit Service 963350
  GValue ret = { 0 };
Packit Service 963350
Packit Service 963350
  /* no need to unset this later, it's just a boolean */
Packit Service 963350
  g_value_init (&ret, G_TYPE_BOOLEAN);
Packit Service 963350
  g_value_set_boolean (&ret, TRUE);
Packit Service 963350
Packit Service 963350
  while (1) {
Packit Service 963350
    ires = gst_iterator_fold (iter, func, &ret, user_data);
Packit Service 963350
    switch (ires) {
Packit Service 963350
      case GST_ITERATOR_RESYNC:
Packit Service 963350
        /* need to reset the result again */
Packit Service 963350
        g_value_set_boolean (&ret, TRUE);
Packit Service 963350
        gst_iterator_resync (iter);
Packit Service 963350
        break;
Packit Service 963350
      case GST_ITERATOR_DONE:
Packit Service 963350
        /* all pads iterated, return collected value */
Packit Service 963350
        goto done;
Packit Service 963350
      default:
Packit Service 963350
        /* iterator returned _ERROR or premature end with _OK,
Packit Service 963350
         * mark an error and exit */
Packit Service 963350
        g_value_set_boolean (&ret, FALSE);
Packit Service 963350
        goto done;
Packit Service 963350
    }
Packit Service 963350
  }
Packit Service 963350
done:
Packit Service 963350
  /* return collected value */
Packit Service 963350
  return g_value_get_boolean (&ret;;
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
/* is called with STATE_LOCK
Packit Service 963350
 *
Packit Service 963350
 * Pads are activated from source pads to sinkpads.
Packit Service 963350
 */
Packit Service 963350
static gboolean
Packit Service 963350
gst_element_pads_activate (GstElement * element, gboolean active)
Packit Service 963350
{
Packit Service 963350
  GstIterator *iter;
Packit Service 963350
  gboolean res;
Packit Service 963350
Packit Service 963350
  GST_CAT_DEBUG_OBJECT (GST_CAT_ELEMENT_PADS, element,
Packit Service 963350
      "%s pads", active ? "activate" : "deactivate");
Packit Service 963350
Packit Service 963350
  iter = gst_element_iterate_src_pads (element);
Packit Service 963350
  res =
Packit Service 963350
      iterator_activate_fold_with_resync (iter,
Packit Service 963350
      (GstIteratorFoldFunction) activate_pads, &active);
Packit Service 963350
  gst_iterator_free (iter);
Packit Service 963350
  if (G_UNLIKELY (!res))
Packit Service 963350
    goto src_failed;
Packit Service 963350
Packit Service 963350
  iter = gst_element_iterate_sink_pads (element);
Packit Service 963350
  res =
Packit Service 963350
      iterator_activate_fold_with_resync (iter,
Packit Service 963350
      (GstIteratorFoldFunction) activate_pads, &active);
Packit Service 963350
  gst_iterator_free (iter);
Packit Service 963350
  if (G_UNLIKELY (!res))
Packit Service 963350
    goto sink_failed;
Packit Service 963350
Packit Service 963350
  GST_CAT_DEBUG_OBJECT (GST_CAT_ELEMENT_PADS, element,
Packit Service 963350
      "pad %sactivation successful", active ? "" : "de");
Packit Service 963350
Packit Service 963350
  return TRUE;
Packit Service 963350
Packit Service 963350
  /* ERRORS */
Packit Service 963350
src_failed:
Packit Service 963350
  {
Packit Service 963350
    GST_CAT_DEBUG_OBJECT (GST_CAT_ELEMENT_PADS, element,
Packit Service 963350
        "pad %sactivation failed", active ? "" : "de");
Packit Service 963350
    return FALSE;
Packit Service 963350
  }
Packit Service 963350
sink_failed:
Packit Service 963350
  {
Packit Service 963350
    GST_CAT_DEBUG_OBJECT (GST_CAT_ELEMENT_PADS, element,
Packit Service 963350
        "sink pads_activate failed");
Packit Service 963350
    return FALSE;
Packit Service 963350
  }
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
/* is called with STATE_LOCK */
Packit Service 963350
static GstStateChangeReturn
Packit Service 963350
gst_element_change_state_func (GstElement * element, GstStateChange transition)
Packit Service 963350
{
Packit Service 963350
  GstState state, next;
Packit Service 963350
  GstStateChangeReturn result = GST_STATE_CHANGE_SUCCESS;
Packit Service 963350
Packit Service 963350
  g_return_val_if_fail (GST_IS_ELEMENT (element), GST_STATE_CHANGE_FAILURE);
Packit Service 963350
Packit Service 963350
  state = (GstState) GST_STATE_TRANSITION_CURRENT (transition);
Packit Service 963350
  next = GST_STATE_TRANSITION_NEXT (transition);
Packit Service 963350
Packit Service 963350
  /* if the element already is in the given state, we just return success */
Packit Service 963350
  if (next == GST_STATE_VOID_PENDING || state == next)
Packit Service 963350
    goto was_ok;
Packit Service 963350
Packit Service 963350
  GST_CAT_LOG_OBJECT (GST_CAT_STATES, element,
Packit Service 963350
      "default handler tries setting state from %s to %s (%04x)",
Packit Service 963350
      gst_element_state_get_name (state),
Packit Service 963350
      gst_element_state_get_name (next), transition);
Packit Service 963350
Packit Service 963350
  switch (transition) {
Packit Service 963350
    case GST_STATE_CHANGE_NULL_TO_READY:
Packit Service 963350
      break;
Packit Service 963350
    case GST_STATE_CHANGE_READY_TO_PAUSED:
Packit Service 963350
      if (!gst_element_pads_activate (element, TRUE)) {
Packit Service 963350
        result = GST_STATE_CHANGE_FAILURE;
Packit Service 963350
      }
Packit Service 963350
      break;
Packit Service 963350
    case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
Packit Service 963350
      break;
Packit Service 963350
    case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
Packit Service 963350
      break;
Packit Service 963350
    case GST_STATE_CHANGE_PAUSED_TO_READY:
Packit Service 963350
    case GST_STATE_CHANGE_READY_TO_NULL:{
Packit Service 963350
      GList *l;
Packit Service 963350
Packit Service 963350
      /* deactivate pads in both cases, since they are activated on
Packit Service 963350
         ready->paused but the element might not have made it to paused */
Packit Service 963350
      if (!gst_element_pads_activate (element, FALSE)) {
Packit Service 963350
        result = GST_STATE_CHANGE_FAILURE;
Packit Service 963350
      }
Packit Service 963350
Packit Service 963350
      /* Remove all non-persistent contexts */
Packit Service 963350
      GST_OBJECT_LOCK (element);
Packit Service 963350
      for (l = element->contexts; l;) {
Packit Service 963350
        GstContext *context = l->data;
Packit Service 963350
Packit Service 963350
        if (!gst_context_is_persistent (context)) {
Packit Service 963350
          GList *next;
Packit Service 963350
Packit Service 963350
          gst_context_unref (context);
Packit Service 963350
          next = l->next;
Packit Service 963350
          element->contexts = g_list_delete_link (element->contexts, l);
Packit Service 963350
          l = next;
Packit Service 963350
        } else {
Packit Service 963350
          l = l->next;
Packit Service 963350
        }
Packit Service 963350
      }
Packit Service 963350
      GST_OBJECT_UNLOCK (element);
Packit Service 963350
      break;
Packit Service 963350
    }
Packit Service 963350
    default:
Packit Service 963350
      /* this will catch real but unhandled state changes;
Packit Service 963350
       * can only be caused by:
Packit Service 963350
       * - a new state was added
Packit Service 963350
       * - somehow the element was asked to jump across an intermediate state
Packit Service 963350
       */
Packit Service 963350
      g_warning ("Unhandled state change from %s to %s",
Packit Service 963350
          gst_element_state_get_name (state),
Packit Service 963350
          gst_element_state_get_name (next));
Packit Service 963350
      break;
Packit Service 963350
  }
Packit Service 963350
  return result;
Packit Service 963350
Packit Service 963350
was_ok:
Packit Service 963350
  {
Packit Service 963350
    GST_OBJECT_LOCK (element);
Packit Service 963350
    result = GST_STATE_RETURN (element);
Packit Service 963350
    GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
Packit Service 963350
        "element is already in the %s state",
Packit Service 963350
        gst_element_state_get_name (state));
Packit Service 963350
    GST_OBJECT_UNLOCK (element);
Packit Service 963350
Packit Service 963350
    return result;
Packit Service 963350
  }
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
/**
Packit Service 963350
 * gst_element_get_factory:
Packit Service 963350
 * @element: a #GstElement to request the element factory of.
Packit Service 963350
 *
Packit Service 963350
 * Retrieves the factory that was used to create this element.
Packit Service 963350
 *
Packit Service 963350
 * Returns: (transfer none): the #GstElementFactory used for creating this
Packit Service 963350
 *     element. no refcounting is needed.
Packit Service 963350
 */
Packit Service 963350
GstElementFactory *
Packit Service 963350
gst_element_get_factory (GstElement * element)
Packit Service 963350
{
Packit Service 963350
  g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
Packit Service 963350
Packit Service 963350
  return GST_ELEMENT_GET_CLASS (element)->elementfactory;
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
static void
Packit Service 963350
gst_element_dispose (GObject * object)
Packit Service 963350
{
Packit Service 963350
  GstElement *element = GST_ELEMENT_CAST (object);
Packit Service 963350
  GstClock **clock_p;
Packit Service 963350
  GstBus **bus_p;
Packit Service 963350
  GstElementClass *oclass;
Packit Service 963350
  GList *walk;
Packit Service 963350
Packit Service 963350
  oclass = GST_ELEMENT_GET_CLASS (element);
Packit Service 963350
Packit Service 963350
  GST_CAT_INFO_OBJECT (GST_CAT_REFCOUNTING, element, "%p dispose", element);
Packit Service 963350
Packit Service 963350
  if (GST_STATE (element) != GST_STATE_NULL)
Packit Service 963350
    goto not_null;
Packit Service 963350
Packit Service 963350
  /* start by releasing all request pads, this might also remove some dynamic
Packit Service 963350
   * pads */
Packit Service 963350
  walk = element->pads;
Packit Service 963350
  while (walk) {
Packit Service 963350
    GstPad *pad = GST_PAD_CAST (walk->data);
Packit Service 963350
Packit Service 963350
    walk = walk->next;
Packit Service 963350
Packit Service 963350
    if (oclass->release_pad && GST_PAD_PAD_TEMPLATE (pad) &&
Packit Service 963350
        GST_PAD_TEMPLATE_PRESENCE (GST_PAD_PAD_TEMPLATE (pad))
Packit Service 963350
        == GST_PAD_REQUEST) {
Packit Service 963350
      GST_CAT_DEBUG_OBJECT (GST_CAT_ELEMENT_PADS, element,
Packit Service 963350
          "removing request pad %s:%s", GST_DEBUG_PAD_NAME (pad));
Packit Service 963350
      oclass->release_pad (element, pad);
Packit Service 963350
Packit Service 963350
      /* in case the release_pad function removed the next pad too */
Packit Service 963350
      if (walk && g_list_position (element->pads, walk) == -1)
Packit Service 963350
        walk = element->pads;
Packit Service 963350
    }
Packit Service 963350
  }
Packit Service 963350
  /* remove the remaining pads */
Packit Service 963350
  while (element->pads) {
Packit Service 963350
    GstPad *pad = GST_PAD_CAST (element->pads->data);
Packit Service 963350
    GST_CAT_DEBUG_OBJECT (GST_CAT_ELEMENT_PADS, element,
Packit Service 963350
        "removing pad %s:%s", GST_DEBUG_PAD_NAME (pad));
Packit Service 963350
    if (!gst_element_remove_pad (element, pad)) {
Packit Service 963350
      /* only happens when someone unparented our pad.. */
Packit Service 963350
      g_critical ("failed to remove pad %s:%s", GST_DEBUG_PAD_NAME (pad));
Packit Service 963350
      break;
Packit Service 963350
    }
Packit Service 963350
  }
Packit Service 963350
Packit Service 963350
  GST_OBJECT_LOCK (element);
Packit Service 963350
  clock_p = &element->clock;
Packit Service 963350
  bus_p = &element->bus;
Packit Service 963350
  gst_object_replace ((GstObject **) clock_p, NULL);
Packit Service 963350
  gst_object_replace ((GstObject **) bus_p, NULL);
Packit Service 963350
  g_list_free_full (element->contexts, (GDestroyNotify) gst_context_unref);
Packit Service 963350
  GST_OBJECT_UNLOCK (element);
Packit Service 963350
Packit Service 963350
  GST_CAT_INFO_OBJECT (GST_CAT_REFCOUNTING, element, "%p parent class dispose",
Packit Service 963350
      element);
Packit Service 963350
Packit Service 963350
  G_OBJECT_CLASS (parent_class)->dispose (object);
Packit Service 963350
Packit Service 963350
  return;
Packit Service 963350
Packit Service 963350
  /* ERRORS */
Packit Service 963350
not_null:
Packit Service 963350
  {
Packit Service 963350
    gboolean is_locked;
Packit Service 963350
Packit Service 963350
    is_locked = GST_ELEMENT_IS_LOCKED_STATE (element);
Packit Service 963350
    g_critical
Packit Service 963350
        ("\nTrying to dispose element %s, but it is in %s%s instead of the NULL"
Packit Service 963350
        " state.\n"
Packit Service 963350
        "You need to explicitly set elements to the NULL state before\n"
Packit Service 963350
        "dropping the final reference, to allow them to clean up.\n"
Packit Service 963350
        "This problem may also be caused by a refcounting bug in the\n"
Packit Service 963350
        "application or some element.\n",
Packit Service 963350
        GST_OBJECT_NAME (element),
Packit Service 963350
        gst_element_state_get_name (GST_STATE (element)),
Packit Service 963350
        is_locked ? " (locked)" : "");
Packit Service 963350
    return;
Packit Service 963350
  }
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
static void
Packit Service 963350
gst_element_finalize (GObject * object)
Packit Service 963350
{
Packit Service 963350
  GstElement *element = GST_ELEMENT_CAST (object);
Packit Service 963350
Packit Service 963350
  GST_CAT_INFO_OBJECT (GST_CAT_REFCOUNTING, element, "%p finalize", element);
Packit Service 963350
Packit Service 963350
  g_cond_clear (&element->state_cond);
Packit Service 963350
  g_rec_mutex_clear (&element->state_lock);
Packit Service 963350
Packit Service 963350
  GST_CAT_INFO_OBJECT (GST_CAT_REFCOUNTING, element, "%p finalize parent",
Packit Service 963350
      element);
Packit Service 963350
Packit Service 963350
  G_OBJECT_CLASS (parent_class)->finalize (object);
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
static void
Packit Service 963350
gst_element_set_bus_func (GstElement * element, GstBus * bus)
Packit Service 963350
{
Packit Service 963350
  GstBus **bus_p;
Packit Service 963350
Packit Service 963350
  g_return_if_fail (GST_IS_ELEMENT (element));
Packit Service 963350
Packit Service 963350
  GST_CAT_DEBUG_OBJECT (GST_CAT_PARENTAGE, element, "setting bus to %p", bus);
Packit Service 963350
Packit Service 963350
  GST_OBJECT_LOCK (element);
Packit Service 963350
  bus_p = &GST_ELEMENT_BUS (element);
Packit Service 963350
  gst_object_replace ((GstObject **) bus_p, GST_OBJECT_CAST (bus));
Packit Service 963350
  GST_OBJECT_UNLOCK (element);
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
/**
Packit Service 963350
 * gst_element_set_bus:
Packit Service 963350
 * @element: a #GstElement to set the bus of.
Packit Service 963350
 * @bus: (transfer none) (allow-none): the #GstBus to set.
Packit Service 963350
 *
Packit Service 963350
 * Sets the bus of the element. Increases the refcount on the bus.
Packit Service 963350
 * For internal use only, unless you're testing elements.
Packit Service 963350
 *
Packit Service 963350
 * MT safe.
Packit Service 963350
 */
Packit Service 963350
void
Packit Service 963350
gst_element_set_bus (GstElement * element, GstBus * bus)
Packit Service 963350
{
Packit Service 963350
  GstElementClass *oclass;
Packit Service 963350
Packit Service 963350
  g_return_if_fail (GST_IS_ELEMENT (element));
Packit Service 963350
Packit Service 963350
  oclass = GST_ELEMENT_GET_CLASS (element);
Packit Service 963350
Packit Service 963350
  if (oclass->set_bus)
Packit Service 963350
    oclass->set_bus (element, bus);
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
/**
Packit Service 963350
 * gst_element_get_bus:
Packit Service 963350
 * @element: a #GstElement to get the bus of.
Packit Service 963350
 *
Packit Service 963350
 * Returns the bus of the element. Note that only a #GstPipeline will provide a
Packit Service 963350
 * bus for the application.
Packit Service 963350
 *
Packit Service 963350
 * Returns: (transfer full) (nullable): the element's #GstBus. unref after
Packit Service 963350
 * usage.
Packit Service 963350
 *
Packit Service 963350
 * MT safe.
Packit Service 963350
 */
Packit Service 963350
GstBus *
Packit Service 963350
gst_element_get_bus (GstElement * element)
Packit Service 963350
{
Packit Service 963350
  GstBus *result = NULL;
Packit Service 963350
Packit Service 963350
  g_return_val_if_fail (GST_IS_ELEMENT (element), result);
Packit Service 963350
Packit Service 963350
  GST_OBJECT_LOCK (element);
Packit Service 963350
  if ((result = GST_ELEMENT_BUS (element)))
Packit Service 963350
    gst_object_ref (result);
Packit Service 963350
  GST_OBJECT_UNLOCK (element);
Packit Service 963350
Packit Service 963350
  GST_CAT_DEBUG_OBJECT (GST_CAT_BUS, element, "got bus %" GST_PTR_FORMAT,
Packit Service 963350
      result);
Packit Service 963350
Packit Service 963350
  return result;
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
static void
Packit Service 963350
gst_element_set_context_default (GstElement * element, GstContext * context)
Packit Service 963350
{
Packit Service 963350
  const gchar *context_type;
Packit Service 963350
  GList *l;
Packit Service 963350
Packit Service 963350
  g_return_if_fail (GST_IS_CONTEXT (context));
Packit Service 963350
  context_type = gst_context_get_context_type (context);
Packit Service 963350
  g_return_if_fail (context_type != NULL);
Packit Service 963350
Packit Service 963350
  GST_OBJECT_LOCK (element);
Packit Service 963350
  for (l = element->contexts; l; l = l->next) {
Packit Service 963350
    GstContext *tmp = l->data;
Packit Service 963350
    const gchar *tmp_type = gst_context_get_context_type (tmp);
Packit Service 963350
Packit Service 963350
    /* Always store newest context but never replace
Packit Service 963350
     * a persistent one by a non-persistent one */
Packit Service 963350
    if (g_strcmp0 (context_type, tmp_type) == 0 &&
Packit Service 963350
        (gst_context_is_persistent (context) ||
Packit Service 963350
            !gst_context_is_persistent (tmp))) {
Packit Service 963350
      gst_context_replace ((GstContext **) & l->data, context);
Packit Service 963350
      break;
Packit Service 963350
    }
Packit Service 963350
  }
Packit Service 963350
  /* Not found? Add */
Packit Service 963350
  if (l == NULL) {
Packit Service 963350
    element->contexts =
Packit Service 963350
        g_list_prepend (element->contexts, gst_context_ref (context));
Packit Service 963350
  }
Packit Service 963350
  GST_OBJECT_UNLOCK (element);
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
/**
Packit Service 963350
 * gst_element_set_context:
Packit Service 963350
 * @element: a #GstElement to set the context of.
Packit Service 963350
 * @context: (transfer none): the #GstContext to set.
Packit Service 963350
 *
Packit Service 963350
 * Sets the context of the element. Increases the refcount of the context.
Packit Service 963350
 *
Packit Service 963350
 * MT safe.
Packit Service 963350
 */
Packit Service 963350
void
Packit Service 963350
gst_element_set_context (GstElement * element, GstContext * context)
Packit Service 963350
{
Packit Service 963350
  GstElementClass *oclass;
Packit Service 963350
Packit Service 963350
  g_return_if_fail (GST_IS_ELEMENT (element));
Packit Service 963350
  g_return_if_fail (GST_IS_CONTEXT (context));
Packit Service 963350
Packit Service 963350
  oclass = GST_ELEMENT_GET_CLASS (element);
Packit Service 963350
Packit Service 963350
  GST_CAT_DEBUG_OBJECT (GST_CAT_CONTEXT, element,
Packit Service 963350
      "set context %p %" GST_PTR_FORMAT, context,
Packit Service 963350
      gst_context_get_structure (context));
Packit Service 963350
Packit Service 963350
  if (oclass->set_context)
Packit Service 963350
    oclass->set_context (element, context);
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
/**
Packit Service 963350
 * gst_element_get_contexts:
Packit Service 963350
 * @element: a #GstElement to set the context of.
Packit Service 963350
 *
Packit Service 963350
 * Gets the contexts set on the element.
Packit Service 963350
 *
Packit Service 963350
 * MT safe.
Packit Service 963350
 *
Packit Service 963350
 * Returns: (element-type Gst.Context) (transfer full): List of #GstContext
Packit Service 963350
 *
Packit Service 963350
 * Since: 1.8
Packit Service 963350
 */
Packit Service 963350
GList *
Packit Service 963350
gst_element_get_contexts (GstElement * element)
Packit Service 963350
{
Packit Service 963350
  GList *ret;
Packit Service 963350
Packit Service 963350
  g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
Packit Service 963350
Packit Service 963350
  GST_OBJECT_LOCK (element);
Packit Service 963350
  ret = g_list_copy_deep (element->contexts, (GCopyFunc) gst_context_ref, NULL);
Packit Service 963350
  GST_OBJECT_UNLOCK (element);
Packit Service 963350
Packit Service 963350
  return ret;
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
static gint
Packit Service 963350
_match_context_type (GstContext * c1, const gchar * context_type)
Packit Service 963350
{
Packit Service 963350
  const gchar *c1_type;
Packit Service 963350
Packit Service 963350
  c1_type = gst_context_get_context_type (c1);
Packit Service 963350
Packit Service 963350
  return g_strcmp0 (c1_type, context_type);
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
/**
Packit Service 963350
 * gst_element_get_context_unlocked:
Packit Service 963350
 * @element: a #GstElement to get the context of.
Packit Service 963350
 * @context_type: a name of a context to retrieve
Packit Service 963350
 *
Packit Service 963350
 * Gets the context with @context_type set on the element or NULL.
Packit Service 963350
 *
Packit Service 963350
 * Returns: (transfer full) (nullable): A #GstContext or NULL
Packit Service 963350
 *
Packit Service 963350
 * Since: 1.8
Packit Service 963350
 */
Packit Service 963350
GstContext *
Packit Service 963350
gst_element_get_context_unlocked (GstElement * element,
Packit Service 963350
    const gchar * context_type)
Packit Service 963350
{
Packit Service 963350
  GstContext *ret = NULL;
Packit Service 963350
  GList *node;
Packit Service 963350
Packit Service 963350
  g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
Packit Service 963350
Packit Service 963350
  node =
Packit Service 963350
      g_list_find_custom (element->contexts, context_type,
Packit Service 963350
      (GCompareFunc) _match_context_type);
Packit Service 963350
  if (node && node->data)
Packit Service 963350
    ret = gst_context_ref (node->data);
Packit Service 963350
Packit Service 963350
  return ret;
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
/**
Packit Service 963350
 * gst_element_get_context:
Packit Service 963350
 * @element: a #GstElement to get the context of.
Packit Service 963350
 * @context_type: a name of a context to retrieve
Packit Service 963350
 *
Packit Service 963350
 * Gets the context with @context_type set on the element or NULL.
Packit Service 963350
 *
Packit Service 963350
 * MT safe.
Packit Service 963350
 *
Packit Service 963350
 * Returns: (transfer full): A #GstContext or NULL
Packit Service 963350
 *
Packit Service 963350
 * Since: 1.8
Packit Service 963350
 */
Packit Service 963350
GstContext *
Packit Service 963350
gst_element_get_context (GstElement * element, const gchar * context_type)
Packit Service 963350
{
Packit Service 963350
  GstContext *ret = NULL;
Packit Service 963350
Packit Service 963350
  g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
Packit Service 963350
Packit Service 963350
  GST_OBJECT_LOCK (element);
Packit Service 963350
  ret = gst_element_get_context_unlocked (element, context_type);
Packit Service 963350
  GST_OBJECT_UNLOCK (element);
Packit Service 963350
Packit Service 963350
  return ret;
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
static void
Packit Service 963350
gst_element_property_post_notify_msg (GstElement * element, GObject * obj,
Packit Service 963350
    GParamSpec * pspec, gboolean include_value)
Packit Service 963350
{
Packit Service 963350
  GValue val = G_VALUE_INIT;
Packit Service 963350
  GValue *v;
Packit Service 963350
Packit Service 963350
  GST_LOG_OBJECT (element, "property '%s' of object %" GST_PTR_FORMAT " has "
Packit Service 963350
      "changed, posting message with%s value", pspec->name, obj,
Packit Service 963350
      include_value ? "" : "out");
Packit Service 963350
Packit Service 963350
  if (include_value && (pspec->flags & G_PARAM_READABLE) != 0) {
Packit Service 963350
    g_value_init (&val, pspec->value_type);
Packit Service 963350
    g_object_get_property (obj, pspec->name, &val;;
Packit Service 963350
    v = &val;
Packit Service 963350
  } else {
Packit Service 963350
    v = NULL;
Packit Service 963350
  }
Packit Service 963350
  gst_element_post_message (element,
Packit Service 963350
      gst_message_new_property_notify (GST_OBJECT_CAST (obj), pspec->name, v));
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
static void
Packit Service 963350
gst_element_property_deep_notify_cb (GstElement * element, GObject * prop_obj,
Packit Service 963350
    GParamSpec * pspec, gpointer user_data)
Packit Service 963350
{
Packit Service 963350
  gboolean include_value = GPOINTER_TO_INT (user_data);
Packit Service 963350
Packit Service 963350
  gst_element_property_post_notify_msg (element, prop_obj, pspec,
Packit Service 963350
      include_value);
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
static void
Packit Service 963350
gst_element_property_notify_cb (GObject * obj, GParamSpec * pspec,
Packit Service 963350
    gpointer user_data)
Packit Service 963350
{
Packit Service 963350
  gboolean include_value = GPOINTER_TO_INT (user_data);
Packit Service 963350
Packit Service 963350
  gst_element_property_post_notify_msg (GST_ELEMENT_CAST (obj), obj, pspec,
Packit Service 963350
      include_value);
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
/**
Packit Service 963350
 * gst_element_add_property_notify_watch:
Packit Service 963350
 * @element: a #GstElement to watch for property changes
Packit Service 963350
 * @property_name: (allow-none): name of property to watch for changes, or
Packit Service 963350
 *     NULL to watch all properties
Packit Service 963350
 * @include_value: whether to include the new property value in the message
Packit Service 963350
 *
Packit Service 963350
 * Returns: a watch id, which can be used in connection with
Packit Service 963350
 *     gst_element_remove_property_notify_watch() to remove the watch again.
Packit Service 963350
 *
Packit Service 963350
 * Since: 1.10
Packit Service 963350
 */
Packit Service 963350
gulong
Packit Service 963350
gst_element_add_property_notify_watch (GstElement * element,
Packit Service 963350
    const gchar * property_name, gboolean include_value)
Packit Service 963350
{
Packit Service 963350
  const gchar *sep;
Packit Service 963350
  gchar *signal_name;
Packit Service 963350
  gulong id;
Packit Service 963350
Packit Service 963350
  g_return_val_if_fail (GST_IS_ELEMENT (element), 0);
Packit Service 963350
Packit Service 963350
  sep = (property_name != NULL) ? "::" : NULL;
Packit Service 963350
  signal_name = g_strconcat ("notify", sep, property_name, NULL);
Packit Service 963350
  id = g_signal_connect (element, signal_name,
Packit Service 963350
      G_CALLBACK (gst_element_property_notify_cb),
Packit Service 963350
      GINT_TO_POINTER (include_value));
Packit Service 963350
  g_free (signal_name);
Packit Service 963350
Packit Service 963350
  return id;
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
/**
Packit Service 963350
 * gst_element_add_property_deep_notify_watch:
Packit Service 963350
 * @element: a #GstElement to watch (recursively) for property changes
Packit Service 963350
 * @property_name: (allow-none): name of property to watch for changes, or
Packit Service 963350
 *     NULL to watch all properties
Packit Service 963350
 * @include_value: whether to include the new property value in the message
Packit Service 963350
 *
Packit Service 963350
 * Returns: a watch id, which can be used in connection with
Packit Service 963350
 *     gst_element_remove_property_notify_watch() to remove the watch again.
Packit Service 963350
 *
Packit Service 963350
 * Since: 1.10
Packit Service 963350
 */
Packit Service 963350
gulong
Packit Service 963350
gst_element_add_property_deep_notify_watch (GstElement * element,
Packit Service 963350
    const gchar * property_name, gboolean include_value)
Packit Service 963350
{
Packit Service 963350
  const gchar *sep;
Packit Service 963350
  gchar *signal_name;
Packit Service 963350
  gulong id;
Packit Service 963350
Packit Service 963350
  g_return_val_if_fail (GST_IS_ELEMENT (element), 0);
Packit Service 963350
Packit Service 963350
  sep = (property_name != NULL) ? "::" : NULL;
Packit Service 963350
  signal_name = g_strconcat ("deep-notify", sep, property_name, NULL);
Packit Service 963350
  id = g_signal_connect (element, signal_name,
Packit Service 963350
      G_CALLBACK (gst_element_property_deep_notify_cb),
Packit Service 963350
      GINT_TO_POINTER (include_value));
Packit Service 963350
  g_free (signal_name);
Packit Service 963350
Packit Service 963350
  return id;
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
/**
Packit Service 963350
 * gst_element_remove_property_notify_watch:
Packit Service 963350
 * @element: a #GstElement being watched for property changes
Packit Service 963350
 * @watch_id: watch id to remove
Packit Service 963350
 *
Packit Service 963350
 * Since: 1.10
Packit Service 963350
 */
Packit Service 963350
void
Packit Service 963350
gst_element_remove_property_notify_watch (GstElement * element, gulong watch_id)
Packit Service 963350
{
Packit Service 963350
  g_signal_handler_disconnect (element, watch_id);
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
typedef struct
Packit Service 963350
{
Packit Service 963350
  GstElement *element;
Packit Service 963350
  GstElementCallAsyncFunc func;
Packit Service 963350
  gpointer user_data;
Packit Service 963350
  GDestroyNotify destroy_notify;
Packit Service 963350
} GstElementCallAsyncData;
Packit Service 963350
Packit Service 963350
static void
Packit Service 963350
gst_element_call_async_func (gpointer data, gpointer user_data)
Packit Service 963350
{
Packit Service 963350
  GstElementCallAsyncData *async_data = data;
Packit Service 963350
Packit Service 963350
  async_data->func (async_data->element, async_data->user_data);
Packit Service 963350
  if (async_data->destroy_notify)
Packit Service 963350
    async_data->destroy_notify (async_data->user_data);
Packit Service 963350
  gst_object_unref (async_data->element);
Packit Service 963350
  g_free (async_data);
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
/**
Packit Service 963350
 * gst_element_call_async:
Packit Service 963350
 * @element: a #GstElement
Packit Service 963350
 * @func: Function to call asynchronously from another thread
Packit Service 963350
 * @user_data: Data to pass to @func
Packit Service 963350
 * @destroy_notify: GDestroyNotify for @user_data
Packit Service 963350
 *
Packit Service 963350
 * Calls @func from another thread and passes @user_data to it. This is to be
Packit Service 963350
 * used for cases when a state change has to be performed from a streaming
Packit Service 963350
 * thread, directly via gst_element_set_state() or indirectly e.g. via SEEK
Packit Service 963350
 * events.
Packit Service 963350
 *
Packit Service 963350
 * Calling those functions directly from the streaming thread will cause
Packit Service 963350
 * deadlocks in many situations, as they might involve waiting for the
Packit Service 963350
 * streaming thread to shut down from this very streaming thread.
Packit Service 963350
 *
Packit Service 963350
 * MT safe.
Packit Service 963350
 *
Packit Service 963350
 * Since: 1.10
Packit Service 963350
 */
Packit Service 963350
void
Packit Service 963350
gst_element_call_async (GstElement * element, GstElementCallAsyncFunc func,
Packit Service 963350
    gpointer user_data, GDestroyNotify destroy_notify)
Packit Service 963350
{
Packit Service 963350
  GstElementCallAsyncData *async_data;
Packit Service 963350
Packit Service 963350
  g_return_if_fail (GST_IS_ELEMENT (element));
Packit Service 963350
Packit Service 963350
  async_data = g_new0 (GstElementCallAsyncData, 1);
Packit Service 963350
  async_data->element = gst_object_ref (element);
Packit Service 963350
  async_data->func = func;
Packit Service 963350
  async_data->user_data = user_data;
Packit Service 963350
  async_data->destroy_notify = destroy_notify;
Packit Service 963350
Packit Service 963350
  g_thread_pool_push (gst_element_pool, async_data, NULL);
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
void
Packit Service 963350
_priv_gst_element_cleanup (void)
Packit Service 963350
{
Packit Service 963350
  if (gst_element_pool) {
Packit Service 963350
    g_thread_pool_free (gst_element_pool, FALSE, TRUE);
Packit Service 963350
    gst_element_setup_thread_pool ();
Packit Service 963350
  }
Packit Service 963350
}
Packit Service 963350
Packit Service 963350
GstStructure *
Packit Service 963350
gst_make_element_message_details (const char *name, ...)
Packit Service 963350
{
Packit Service 963350
  GstStructure *structure;
Packit Service 963350
  va_list varargs;
Packit Service 963350
Packit Service 963350
  if (name == NULL)
Packit Service 963350
    return NULL;
Packit Service 963350
Packit Service 963350
  va_start (varargs, name);
Packit Service 963350
  structure = gst_structure_new_valist ("details", name, varargs);
Packit Service 963350
  va_end (varargs);
Packit Service 963350
Packit Service 963350
  return structure;
Packit Service 963350
}