gstreamer/gst/gstelement.c

3758 lines
111 KiB
C
Raw Normal View History

/* GStreamer
* Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
* 2004 Wim Taymans <wim@fluendo.com>
*
* gstelement.c: The base element, all elements derive from this
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
/**
* SECTION:gstelement
* @title: GstElement
* @short_description: Abstract base class for all pipeline elements
* @see_also: #GstElementFactory, #GstPad
*
* GstElement is the abstract base class needed to construct an element that
* can be used in a GStreamer pipeline. Please refer to the plugin writers
* guide for more information on creating #GstElement subclasses.
*
* The name of a #GstElement can be get with gst_element_get_name() and set with
* gst_element_set_name(). For speed, GST_ELEMENT_NAME() can be used in the
* core when using the appropriate locking. Do not use this in plug-ins or
* applications in order to retain ABI compatibility.
*
2012-03-28 16:12:23 +00:00
* Elements can have pads (of the type #GstPad). These pads link to pads on
* other elements. #GstBuffer flow between these linked pads.
* A #GstElement has a #GList of #GstPad structures for all their input (or sink)
* and output (or source) pads.
* Core and plug-in writers can add and remove pads with gst_element_add_pad()
* and gst_element_remove_pad().
*
* An existing pad of an element can be retrieved by name with
* gst_element_get_static_pad(). A new dynamic pad can be created using
* gst_element_request_pad() with a #GstPadTemplate.
* An iterator of all pads can be retrieved with gst_element_iterate_pads().
*
* Elements can be linked through their pads.
* If the link is straightforward, use the gst_element_link()
* convenience function to link two elements, or gst_element_link_many()
* for more elements in a row.
* Use gst_element_link_filtered() to link two elements constrained by
* a specified set of #GstCaps.
* For finer control, use gst_element_link_pads() and
* gst_element_link_pads_filtered() to specify the pads to link on
* each element by name.
*
* Each element has a state (see #GstState). You can get and set the state
* of an element with gst_element_get_state() and gst_element_set_state().
* Setting a state triggers a #GstStateChange. To get a string representation
* of a #GstState, use gst_element_state_get_name().
*
* You can get and set a #GstClock on an element using gst_element_get_clock()
* and gst_element_set_clock().
* Some elements can provide a clock for the pipeline if
2012-03-28 16:12:23 +00:00
* the #GST_ELEMENT_FLAG_PROVIDE_CLOCK flag is set. With the
* gst_element_provide_clock() method one can retrieve the clock provided by
* such an element.
2012-03-28 16:12:23 +00:00
* Not all elements require a clock to operate correctly. If the
* #GST_ELEMENT_FLAG_REQUIRE_CLOCK() flag is set, a clock should be set on the
* element with gst_element_set_clock().
*
* Note that clock selection and distribution is normally handled by the
* toplevel #GstPipeline so the clock functions are only to be used in very
* specific situations.
*/
2005-10-10 16:38:26 +00:00
#include "gst_private.h"
- some fixes to int2float making automake 1.5 happy (gst now requires automake1.5). It's still not perfect but it bui... Original commit message from CVS: - added playondemand plugin by Leif Morgan Johnson <lmjohns3@eos.ncsu.edu> - some fixes to int2float - aplied a patch from wrobell <wrobell@ite.pl> that is a first attempt at making automake 1.5 happy (gst now requires automake1.5). It's still not perfect but it builds. - Made the schedulers plugable. The default scheduler now lives inside a plugin. - Added a new mpeg1/2 parser/demuxer. - Fixed some compiler warnings in the core libs. - substantial work to GstThread (hopefully less race conditions). simplified the code in GstThread a bit. A state change can now also happen in the thread context. - reworked the state semantics of a bin. it'll now automatically get the highest state of its children. - the autoplugger now nests the threads so that a state change failure of one thread doesn't make its upstream thread lock. - GstQueue refuses to go to PLAYING if the sinkpad is not connected. This way the queue will not wedge in the _get lock. - GstQueue unlocks its mutexes when going to PAUSED. - make sure that when all elements in a bin/thread go to PAUSED, the bin is set to PAUSED too. - make a parent bin wait for its children to PAUSE before ending the iteration with FALSE (EOS) - Some changes to GstPlay to deal with EOS. - aplied the latest patch from Zeenix to gstrtp. end result: GstPlay doesn't crash on EOS and the pipeline is now shut down properly.
2001-12-04 22:12:50 +00:00
#include <glib.h>
#include <stdarg.h>
#include <gobject/gvaluecollector.h>
#include "gstelement.h"
#include "gstelementmetadata.h"
docs/gst/gstreamer-sections.txt: Add new element field and method. Original commit message from CVS: * docs/gst/gstreamer-sections.txt: Add new element field and method. * gst/gstbin.c: (gst_bin_class_init), (gst_bin_init), (bin_remove_messages), (gst_bin_add_func), (gst_bin_remove_func), (gst_bin_recalc_state), (gst_bin_get_state_func), (gst_bin_element_set_state), (gst_bin_change_state_func), (gst_bin_continue_func), (bin_bus_handler), (bin_push_state_continue), (bin_handle_async_start), (bin_handle_async_done), (gst_bin_handle_message_func): Make async state changes a bit smarter by using new ASYNC_START and ASYNC_DONE messages. This reduces the number of times we run the state recalculation thread. Don't change state of element with a pending ASYNC_START message. Deprecate STATE_DIRTY messages. * gst/gstelement.c: (gst_element_init), (gst_element_send_event), (gst_element_get_state_func), (gst_element_continue_state), (gst_element_lost_state), (gst_element_set_state_func), (gst_element_change_state): * gst/gstelement.h: Keep the state that was last set by the app in a new element field. Don't allow state changes when handling an element event. Post ASYNC_START and ASYNC_DONE messages. Change lost_state so that we go to PAUSED and wait for the parent to set us to PLAYING again (so latency calculation can be performed) Export gst_element_change_state() method so that subclasses can use it. API: gst_element_change_state() API: GST_STATE_TARGET * gst/gstpipeline.c: (gst_pipeline_class_init), (reset_stream_time), (gst_pipeline_change_state), (gst_pipeline_handle_message), (gst_pipeline_set_new_stream_time): Using the new ASYNC_START message we can reset the base_time when needed. This can then be used to implement base_time redistribution in flushing seeks so that we can remove the explicit seek handling. Perform latency query and configuration when going to PLAYING. * libs/gst/base/gstbasesink.c: (gst_base_sink_commit_state), (gst_base_sink_query), (gst_base_sink_change_state): Post new ASYNC_START/ASYNC_DONE messages. * tests/check/generic/sinks.c: (GST_START_TEST): Fix test because the bin will not set the async element to PLAYING right away. * tests/check/gst/gstbin.c: (pop_async_done), (GST_START_TEST): Make the message check a little stronger. Handle ASYNC messages. * tests/check/pipelines/cleanup.c: (GST_START_TEST): * tests/check/pipelines/simple-launch-lines.c: (GST_START_TEST): Expect ASYNC_DONE messages.
2007-03-19 10:47:56 +00:00
#include "gstenumtypes.h"
#include "gstbus.h"
#include "gsterror.h"
#include "gstevent.h"
#include "gstutils.h"
#include "gstinfo.h"
#include "gstquark.h"
#include "gsttracerutils.h"
#include "gstvalue.h"
#include "gst-i18n-lib.h"
#include "glib-compat-private.h"
#ifndef GST_DISABLE_GST_DEBUG
#include "printf/printf.h"
#endif
/* Element signals and args */
enum
{
PAD_ADDED,
PAD_REMOVED,
NO_MORE_PADS,
/* add more above */
LAST_SIGNAL
};
enum
{
ARG_0
/* FILL ME */
};
static void gst_element_class_init (GstElementClass * klass);
static void gst_element_init (GstElement * element);
static void gst_element_base_class_init (gpointer g_class);
static void gst_element_constructed (GObject * object);
static void gst_element_dispose (GObject * object);
static void gst_element_finalize (GObject * object);
static GstStateChangeReturn gst_element_change_state_func (GstElement * element,
GstStateChange transition);
static GstStateChangeReturn gst_element_get_state_func (GstElement * element,
GstState * state, GstState * pending, GstClockTime timeout);
static GstStateChangeReturn gst_element_set_state_func (GstElement * element,
GstState state);
static gboolean gst_element_set_clock_func (GstElement * element,
GstClock * clock);
static void gst_element_set_bus_func (GstElement * element, GstBus * bus);
static gboolean gst_element_post_message_default (GstElement * element,
GstMessage * message);
static void gst_element_set_context_default (GstElement * element,
GstContext * context);
static gboolean gst_element_default_send_event (GstElement * element,
GstEvent * event);
static gboolean gst_element_default_query (GstElement * element,
GstQuery * query);
static GstPadTemplate
* gst_element_class_get_request_pad_template (GstElementClass *
element_class, const gchar * name);
static void gst_element_call_async_func (gpointer data, gpointer user_data);
static GstObjectClass *parent_class = NULL;
static guint gst_element_signals[LAST_SIGNAL] = { 0 };
static GThreadPool *gst_element_pool = NULL;
/* this is used in gstelementfactory.c:gst_element_register() */
GQuark __gst_elementclass_factory = 0;
GType
gst_element_get_type (void)
{
static volatile gsize gst_element_type = 0;
if (g_once_init_enter (&gst_element_type)) {
GType _type;
static const GTypeInfo element_info = {
sizeof (GstElementClass),
gst_element_base_class_init,
NULL, /* base_class_finalize */
(GClassInitFunc) gst_element_class_init,
NULL,
NULL,
sizeof (GstElement),
0,
(GInstanceInitFunc) gst_element_init,
NULL
};
_type = g_type_register_static (GST_TYPE_OBJECT, "GstElement",
&element_info, G_TYPE_FLAG_ABSTRACT);
__gst_elementclass_factory =
g_quark_from_static_string ("GST_ELEMENTCLASS_FACTORY");
g_once_init_leave (&gst_element_type, _type);
}
return gst_element_type;
}
static void
gst_element_setup_thread_pool (void)
{
GError *err = NULL;
GST_DEBUG ("creating element thread pool");
gst_element_pool =
g_thread_pool_new ((GFunc) gst_element_call_async_func, NULL, -1, FALSE,
&err);
if (err != NULL) {
g_critical ("could not alloc threadpool %s", err->message);
g_clear_error (&err);
}
}
static void
gst_element_class_init (GstElementClass * klass)
{
GObjectClass *gobject_class;
gobject_class = (GObjectClass *) klass;
parent_class = g_type_class_peek_parent (klass);
/**
* GstElement::pad-added:
* @gstelement: the object which received the signal
* @new_pad: the pad that has been added
*
* a new #GstPad has been added to the element. Note that this signal will
* usually be emitted from the context of the streaming thread. Also keep in
* mind that if you add new elements to the pipeline in the signal handler
* you will need to set them to the desired target state with
2011-05-02 12:48:01 +00:00
* gst_element_set_state() or gst_element_sync_state_with_parent().
*/
gst_element_signals[PAD_ADDED] =
g_signal_new ("pad-added", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GstElementClass, pad_added), NULL, NULL,
g_cclosure_marshal_generic, G_TYPE_NONE, 1, GST_TYPE_PAD);
/**
* GstElement::pad-removed:
* @gstelement: the object which received the signal
* @old_pad: the pad that has been removed
*
* a #GstPad has been removed from the element
*/
gst_element_signals[PAD_REMOVED] =
g_signal_new ("pad-removed", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GstElementClass, pad_removed), NULL, NULL,
g_cclosure_marshal_generic, G_TYPE_NONE, 1, GST_TYPE_PAD);
/**
* GstElement::no-more-pads:
* @gstelement: the object which received the signal
*
* This signals that the element will not generate more dynamic pads.
* Note that this signal will usually be emitted from the context of
* the streaming thread.
*/
gst_element_signals[NO_MORE_PADS] =
g_signal_new ("no-more-pads", G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstElementClass, no_more_pads), NULL,
NULL, g_cclosure_marshal_generic, G_TYPE_NONE, 0);
gobject_class->dispose = gst_element_dispose;
gobject_class->finalize = gst_element_finalize;
gobject_class->constructed = gst_element_constructed;
klass->change_state = GST_DEBUG_FUNCPTR (gst_element_change_state_func);
klass->set_state = GST_DEBUG_FUNCPTR (gst_element_set_state_func);
klass->get_state = GST_DEBUG_FUNCPTR (gst_element_get_state_func);
klass->set_clock = GST_DEBUG_FUNCPTR (gst_element_set_clock_func);
klass->set_bus = GST_DEBUG_FUNCPTR (gst_element_set_bus_func);
klass->query = GST_DEBUG_FUNCPTR (gst_element_default_query);
klass->send_event = GST_DEBUG_FUNCPTR (gst_element_default_send_event);
klass->numpadtemplates = 0;
klass->post_message = GST_DEBUG_FUNCPTR (gst_element_post_message_default);
klass->set_context = GST_DEBUG_FUNCPTR (gst_element_set_context_default);
klass->elementfactory = NULL;
gst_element_setup_thread_pool ();
}
static void
gst_element_base_class_init (gpointer g_class)
{
GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
GList *node, *padtemplates;
/* Copy the element details here so elements can inherit the
* details from their base class and classes only need to set
* the details in class_init instead of base_init */
element_class->metadata =
element_class->metadata ? gst_structure_copy (element_class->metadata) :
gst_structure_new_empty ("metadata");
/* Copy the pad templates so elements inherit them
* from their base class but elements can add pad templates in class_init
* instead of base_init.
*/
padtemplates = g_list_copy (element_class->padtemplates);
for (node = padtemplates; node != NULL; node = node->next) {
GstPadTemplate *tmpl = (GstPadTemplate *) node->data;
gst_object_ref (tmpl);
}
element_class->padtemplates = padtemplates;
/* set the factory, see gst_element_register() */
element_class->elementfactory =
g_type_get_qdata (G_TYPE_FROM_CLASS (element_class),
__gst_elementclass_factory);
2012-12-14 10:08:57 +00:00
GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "type %s : factory %p",
G_OBJECT_CLASS_NAME (element_class), element_class->elementfactory);
}
static void
gst_element_init (GstElement * element)
{
2005-10-10 16:38:26 +00:00
GST_STATE (element) = GST_STATE_NULL;
docs/gst/gstreamer-sections.txt: Add new element field and method. Original commit message from CVS: * docs/gst/gstreamer-sections.txt: Add new element field and method. * gst/gstbin.c: (gst_bin_class_init), (gst_bin_init), (bin_remove_messages), (gst_bin_add_func), (gst_bin_remove_func), (gst_bin_recalc_state), (gst_bin_get_state_func), (gst_bin_element_set_state), (gst_bin_change_state_func), (gst_bin_continue_func), (bin_bus_handler), (bin_push_state_continue), (bin_handle_async_start), (bin_handle_async_done), (gst_bin_handle_message_func): Make async state changes a bit smarter by using new ASYNC_START and ASYNC_DONE messages. This reduces the number of times we run the state recalculation thread. Don't change state of element with a pending ASYNC_START message. Deprecate STATE_DIRTY messages. * gst/gstelement.c: (gst_element_init), (gst_element_send_event), (gst_element_get_state_func), (gst_element_continue_state), (gst_element_lost_state), (gst_element_set_state_func), (gst_element_change_state): * gst/gstelement.h: Keep the state that was last set by the app in a new element field. Don't allow state changes when handling an element event. Post ASYNC_START and ASYNC_DONE messages. Change lost_state so that we go to PAUSED and wait for the parent to set us to PLAYING again (so latency calculation can be performed) Export gst_element_change_state() method so that subclasses can use it. API: gst_element_change_state() API: GST_STATE_TARGET * gst/gstpipeline.c: (gst_pipeline_class_init), (reset_stream_time), (gst_pipeline_change_state), (gst_pipeline_handle_message), (gst_pipeline_set_new_stream_time): Using the new ASYNC_START message we can reset the base_time when needed. This can then be used to implement base_time redistribution in flushing seeks so that we can remove the explicit seek handling. Perform latency query and configuration when going to PLAYING. * libs/gst/base/gstbasesink.c: (gst_base_sink_commit_state), (gst_base_sink_query), (gst_base_sink_change_state): Post new ASYNC_START/ASYNC_DONE messages. * tests/check/generic/sinks.c: (GST_START_TEST): Fix test because the bin will not set the async element to PLAYING right away. * tests/check/gst/gstbin.c: (pop_async_done), (GST_START_TEST): Make the message check a little stronger. Handle ASYNC messages. * tests/check/pipelines/cleanup.c: (GST_START_TEST): * tests/check/pipelines/simple-launch-lines.c: (GST_START_TEST): Expect ASYNC_DONE messages.
2007-03-19 10:47:56 +00:00
GST_STATE_TARGET (element) = GST_STATE_NULL;
2005-10-10 16:38:26 +00:00
GST_STATE_NEXT (element) = GST_STATE_VOID_PENDING;
GST_STATE_PENDING (element) = GST_STATE_VOID_PENDING;
GST_STATE_RETURN (element) = GST_STATE_CHANGE_SUCCESS;
2012-01-19 08:27:04 +00:00
g_rec_mutex_init (&element->state_lock);
g_cond_init (&element->state_cond);
}
static void
gst_element_constructed (GObject * object)
{
GST_TRACER_ELEMENT_NEW (GST_ELEMENT_CAST (object));
G_OBJECT_CLASS (parent_class)->constructed (object);
}
/**
* gst_element_release_request_pad:
* @element: a #GstElement to release the request pad of.
* @pad: the #GstPad to release.
*
* Makes the element free the previously requested pad as obtained
* with gst_element_request_pad().
*
* This does not unref the pad. If the pad was created by using
* gst_element_request_pad(), gst_element_release_request_pad() needs to be
* followed by gst_object_unref() to free the @pad.
*
* MT safe.
*/
void
gst_element_release_request_pad (GstElement * element, GstPad * pad)
{
GstElementClass *oclass;
g_return_if_fail (GST_IS_ELEMENT (element));
g_return_if_fail (GST_IS_PAD (pad));
g_return_if_fail (GST_PAD_PAD_TEMPLATE (pad) == NULL ||
GST_PAD_TEMPLATE_PRESENCE (GST_PAD_PAD_TEMPLATE (pad)) ==
GST_PAD_REQUEST);
g_return_if_fail (GST_PAD_PARENT (pad) == element);
oclass = GST_ELEMENT_GET_CLASS (element);
/* if the element implements a custom release function we call that, else we
* simply remove the pad from the element */
if (oclass->release_pad)
oclass->release_pad (element, pad);
else
gst_element_remove_pad (element, pad);
}
/**
* gst_element_provide_clock:
* @element: a #GstElement to query
*
* Get the clock provided by the given element.
* > An element is only required to provide a clock in the PAUSED
* > state. Some elements can provide a clock in other states.
*
* Returns: (transfer full) (nullable): the GstClock provided by the
* element or %NULL if no clock could be provided. Unref after usage.
*
* MT safe.
*/
GstClock *
gst_element_provide_clock (GstElement * element)
{
GstClock *result = NULL;
GstElementClass *oclass;
g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
oclass = GST_ELEMENT_GET_CLASS (element);
if (oclass->provide_clock)
result = oclass->provide_clock (element);
return result;
}
static gboolean
gst_element_set_clock_func (GstElement * element, GstClock * clock)
{
GstClock **clock_p;
GST_OBJECT_LOCK (element);
clock_p = &element->clock;
gst_object_replace ((GstObject **) clock_p, (GstObject *) clock);
GST_OBJECT_UNLOCK (element);
return TRUE;
}
/**
* gst_element_set_clock:
* @element: a #GstElement to set the clock for.
* @clock: (transfer none) (allow-none): the #GstClock to set for the element.
*
* Sets the clock for the element. This function increases the
* refcount on the clock. Any previously set clock on the object
* is unreffed.
*
* Returns: %TRUE if the element accepted the clock. An element can refuse a
* clock when it, for example, is not able to slave its internal clock to the
* @clock or when it requires a specific clock to operate.
gst/base/gstbasesink.*: No need to store the clock, the parent element class already has it. Original commit message from CVS: * gst/base/gstbasesink.c: (gst_base_sink_class_init), (gst_base_sink_wait), (gst_base_sink_do_sync), (gst_base_sink_handle_event): * gst/base/gstbasesink.h: No need to store the clock, the parent element class already has it. * gst/gstbin.c: (gst_bin_set_clock_func), (gst_bin_add_func): Updates for clock_set returning a gboolean * gst/gstclock.c: (gst_clock_entry_new), (gst_clock_id_wait), (gst_clock_id_wait_async), (gst_clock_class_init), (gst_clock_init), (gst_clock_finalize), (gst_clock_get_internal_time), (gst_clock_get_time), (gst_clock_slave_callback), (gst_clock_set_master), (gst_clock_get_master), (do_linear_regression), (gst_clock_add_observation), (gst_clock_set_property), (gst_clock_get_property): * gst/gstclock.h: Implement master/slave. When setting a clock as a slave, a periodic timeout is scheduled to sample master and slave times. Then the slave clock is recalibrated to match offset and rate of the master clock. Update logging a bit. Add flag so that a clock can state that is cannot be slaved to another clock. * gst/gstelement.c: (gst_element_set_clock): * gst/gstelement.h: The set_clock returns a gboolean for when an element cannot deal with the selected clock in the pipeline. * gst/gstpipeline.c: (gst_pipeline_change_state), (gst_pipeline_set_clock): * gst/gstpipeline.h: Handle the case where the selected clock cannot be set on the pipeline. * gst/net/gstnetclientclock.c: (gst_net_client_clock_class_init), (gst_net_client_clock_init), (gst_net_client_clock_finalize), (gst_net_client_clock_set_property), (gst_net_client_clock_get_property), (gst_net_client_clock_observe_times): * gst/net/gstnetclientclock.h: Use regression code in GstClock parent, remove duplicated functionality.
2005-11-22 18:28:44 +00:00
*
* MT safe.
*/
gst/base/gstbasesink.*: No need to store the clock, the parent element class already has it. Original commit message from CVS: * gst/base/gstbasesink.c: (gst_base_sink_class_init), (gst_base_sink_wait), (gst_base_sink_do_sync), (gst_base_sink_handle_event): * gst/base/gstbasesink.h: No need to store the clock, the parent element class already has it. * gst/gstbin.c: (gst_bin_set_clock_func), (gst_bin_add_func): Updates for clock_set returning a gboolean * gst/gstclock.c: (gst_clock_entry_new), (gst_clock_id_wait), (gst_clock_id_wait_async), (gst_clock_class_init), (gst_clock_init), (gst_clock_finalize), (gst_clock_get_internal_time), (gst_clock_get_time), (gst_clock_slave_callback), (gst_clock_set_master), (gst_clock_get_master), (do_linear_regression), (gst_clock_add_observation), (gst_clock_set_property), (gst_clock_get_property): * gst/gstclock.h: Implement master/slave. When setting a clock as a slave, a periodic timeout is scheduled to sample master and slave times. Then the slave clock is recalibrated to match offset and rate of the master clock. Update logging a bit. Add flag so that a clock can state that is cannot be slaved to another clock. * gst/gstelement.c: (gst_element_set_clock): * gst/gstelement.h: The set_clock returns a gboolean for when an element cannot deal with the selected clock in the pipeline. * gst/gstpipeline.c: (gst_pipeline_change_state), (gst_pipeline_set_clock): * gst/gstpipeline.h: Handle the case where the selected clock cannot be set on the pipeline. * gst/net/gstnetclientclock.c: (gst_net_client_clock_class_init), (gst_net_client_clock_init), (gst_net_client_clock_finalize), (gst_net_client_clock_set_property), (gst_net_client_clock_get_property), (gst_net_client_clock_observe_times): * gst/net/gstnetclientclock.h: Use regression code in GstClock parent, remove duplicated functionality.
2005-11-22 18:28:44 +00:00
gboolean
gst_element_set_clock (GstElement * element, GstClock * clock)
{
GstElementClass *oclass;
gboolean res = FALSE;
gst/base/gstbasesink.*: No need to store the clock, the parent element class already has it. Original commit message from CVS: * gst/base/gstbasesink.c: (gst_base_sink_class_init), (gst_base_sink_wait), (gst_base_sink_do_sync), (gst_base_sink_handle_event): * gst/base/gstbasesink.h: No need to store the clock, the parent element class already has it. * gst/gstbin.c: (gst_bin_set_clock_func), (gst_bin_add_func): Updates for clock_set returning a gboolean * gst/gstclock.c: (gst_clock_entry_new), (gst_clock_id_wait), (gst_clock_id_wait_async), (gst_clock_class_init), (gst_clock_init), (gst_clock_finalize), (gst_clock_get_internal_time), (gst_clock_get_time), (gst_clock_slave_callback), (gst_clock_set_master), (gst_clock_get_master), (do_linear_regression), (gst_clock_add_observation), (gst_clock_set_property), (gst_clock_get_property): * gst/gstclock.h: Implement master/slave. When setting a clock as a slave, a periodic timeout is scheduled to sample master and slave times. Then the slave clock is recalibrated to match offset and rate of the master clock. Update logging a bit. Add flag so that a clock can state that is cannot be slaved to another clock. * gst/gstelement.c: (gst_element_set_clock): * gst/gstelement.h: The set_clock returns a gboolean for when an element cannot deal with the selected clock in the pipeline. * gst/gstpipeline.c: (gst_pipeline_change_state), (gst_pipeline_set_clock): * gst/gstpipeline.h: Handle the case where the selected clock cannot be set on the pipeline. * gst/net/gstnetclientclock.c: (gst_net_client_clock_class_init), (gst_net_client_clock_init), (gst_net_client_clock_finalize), (gst_net_client_clock_set_property), (gst_net_client_clock_get_property), (gst_net_client_clock_observe_times): * gst/net/gstnetclientclock.h: Use regression code in GstClock parent, remove duplicated functionality.
2005-11-22 18:28:44 +00:00
g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
g_return_val_if_fail (clock == NULL || GST_IS_CLOCK (clock), FALSE);
oclass = GST_ELEMENT_GET_CLASS (element);
GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, element, "setting clock %p", clock);
if (oclass->set_clock)
gst/base/gstbasesink.*: No need to store the clock, the parent element class already has it. Original commit message from CVS: * gst/base/gstbasesink.c: (gst_base_sink_class_init), (gst_base_sink_wait), (gst_base_sink_do_sync), (gst_base_sink_handle_event): * gst/base/gstbasesink.h: No need to store the clock, the parent element class already has it. * gst/gstbin.c: (gst_bin_set_clock_func), (gst_bin_add_func): Updates for clock_set returning a gboolean * gst/gstclock.c: (gst_clock_entry_new), (gst_clock_id_wait), (gst_clock_id_wait_async), (gst_clock_class_init), (gst_clock_init), (gst_clock_finalize), (gst_clock_get_internal_time), (gst_clock_get_time), (gst_clock_slave_callback), (gst_clock_set_master), (gst_clock_get_master), (do_linear_regression), (gst_clock_add_observation), (gst_clock_set_property), (gst_clock_get_property): * gst/gstclock.h: Implement master/slave. When setting a clock as a slave, a periodic timeout is scheduled to sample master and slave times. Then the slave clock is recalibrated to match offset and rate of the master clock. Update logging a bit. Add flag so that a clock can state that is cannot be slaved to another clock. * gst/gstelement.c: (gst_element_set_clock): * gst/gstelement.h: The set_clock returns a gboolean for when an element cannot deal with the selected clock in the pipeline. * gst/gstpipeline.c: (gst_pipeline_change_state), (gst_pipeline_set_clock): * gst/gstpipeline.h: Handle the case where the selected clock cannot be set on the pipeline. * gst/net/gstnetclientclock.c: (gst_net_client_clock_class_init), (gst_net_client_clock_init), (gst_net_client_clock_finalize), (gst_net_client_clock_set_property), (gst_net_client_clock_get_property), (gst_net_client_clock_observe_times): * gst/net/gstnetclientclock.h: Use regression code in GstClock parent, remove duplicated functionality.
2005-11-22 18:28:44 +00:00
res = oclass->set_clock (element, clock);
gst/base/gstbasesink.*: No need to store the clock, the parent element class already has it. Original commit message from CVS: * gst/base/gstbasesink.c: (gst_base_sink_class_init), (gst_base_sink_wait), (gst_base_sink_do_sync), (gst_base_sink_handle_event): * gst/base/gstbasesink.h: No need to store the clock, the parent element class already has it. * gst/gstbin.c: (gst_bin_set_clock_func), (gst_bin_add_func): Updates for clock_set returning a gboolean * gst/gstclock.c: (gst_clock_entry_new), (gst_clock_id_wait), (gst_clock_id_wait_async), (gst_clock_class_init), (gst_clock_init), (gst_clock_finalize), (gst_clock_get_internal_time), (gst_clock_get_time), (gst_clock_slave_callback), (gst_clock_set_master), (gst_clock_get_master), (do_linear_regression), (gst_clock_add_observation), (gst_clock_set_property), (gst_clock_get_property): * gst/gstclock.h: Implement master/slave. When setting a clock as a slave, a periodic timeout is scheduled to sample master and slave times. Then the slave clock is recalibrated to match offset and rate of the master clock. Update logging a bit. Add flag so that a clock can state that is cannot be slaved to another clock. * gst/gstelement.c: (gst_element_set_clock): * gst/gstelement.h: The set_clock returns a gboolean for when an element cannot deal with the selected clock in the pipeline. * gst/gstpipeline.c: (gst_pipeline_change_state), (gst_pipeline_set_clock): * gst/gstpipeline.h: Handle the case where the selected clock cannot be set on the pipeline. * gst/net/gstnetclientclock.c: (gst_net_client_clock_class_init), (gst_net_client_clock_init), (gst_net_client_clock_finalize), (gst_net_client_clock_set_property), (gst_net_client_clock_get_property), (gst_net_client_clock_observe_times): * gst/net/gstnetclientclock.h: Use regression code in GstClock parent, remove duplicated functionality.
2005-11-22 18:28:44 +00:00
return res;
}
/**
* gst_element_get_clock:
* @element: a #GstElement to get the clock of.
*
* Gets the currently configured clock of the element. This is the clock as was
* last set with gst_element_set_clock().
*
* Elements in a pipeline will only have their clock set when the
* pipeline is in the PLAYING state.
*
* Returns: (transfer full) (nullable): the #GstClock of the element. unref after usage.
*
* MT safe.
*/
GstClock *
gst_element_get_clock (GstElement * element)
{
GstClock *result;
g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
GST_OBJECT_LOCK (element);
if ((result = element->clock))
gst_object_ref (result);
GST_OBJECT_UNLOCK (element);
return result;
}
/**
* gst_element_set_base_time:
* @element: a #GstElement.
* @time: the base time to set.
*
* Set the base time of an element. See gst_element_get_base_time().
*
* MT safe.
*/
void
gst_element_set_base_time (GstElement * element, GstClockTime time)
{
GstClockTime old;
g_return_if_fail (GST_IS_ELEMENT (element));
GST_OBJECT_LOCK (element);
old = element->base_time;
element->base_time = time;
GST_OBJECT_UNLOCK (element);
GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, element,
"set base_time=%" GST_TIME_FORMAT ", old %" GST_TIME_FORMAT,
GST_TIME_ARGS (time), GST_TIME_ARGS (old));
}
/**
* gst_element_get_base_time:
* @element: a #GstElement.
*
* Returns the base time of the element. The base time is the
* absolute time of the clock when this element was last put to
* PLAYING. Subtracting the base time from the clock time gives
* the running time of the element.
*
* Returns: the base time of the element.
*
* MT safe.
*/
GstClockTime
gst_element_get_base_time (GstElement * element)
{
GstClockTime result;
g_return_val_if_fail (GST_IS_ELEMENT (element), GST_CLOCK_TIME_NONE);
GST_OBJECT_LOCK (element);
result = element->base_time;
GST_OBJECT_UNLOCK (element);
return result;
}
/**
* gst_element_set_start_time:
* @element: a #GstElement.
* @time: the base time to set.
*
2009-05-29 11:03:15 +00:00
* Set the start time of an element. The start time of the element is the
* running time of the element when it last went to the PAUSED state. In READY
* or after a flushing seek, it is set to 0.
*
* Toplevel elements like #GstPipeline will manage the start_time and
* base_time on its children. Setting the start_time to #GST_CLOCK_TIME_NONE
* on such a toplevel element will disable the distribution of the base_time to
* the children and can be useful if the application manages the base_time
* itself, for example if you want to synchronize capture from multiple
* pipelines, and you can also ensure that the pipelines have the same clock.
*
* MT safe.
*/
void
gst_element_set_start_time (GstElement * element, GstClockTime time)
{
GstClockTime old;
g_return_if_fail (GST_IS_ELEMENT (element));
GST_OBJECT_LOCK (element);
old = GST_ELEMENT_START_TIME (element);
GST_ELEMENT_START_TIME (element) = time;
GST_OBJECT_UNLOCK (element);
GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, element,
"set start_time=%" GST_TIME_FORMAT ", old %" GST_TIME_FORMAT,
GST_TIME_ARGS (time), GST_TIME_ARGS (old));
}
/**
* gst_element_get_start_time:
* @element: a #GstElement.
*
* Returns the start time of the element. The start time is the
* running time of the clock when this element was last put to PAUSED.
2009-05-29 11:03:15 +00:00
*
* Usually the start_time is managed by a toplevel element such as
* #GstPipeline.
*
* MT safe.
*
* Returns: the start time of the element.
*/
GstClockTime
gst_element_get_start_time (GstElement * element)
{
GstClockTime result;
g_return_val_if_fail (GST_IS_ELEMENT (element), GST_CLOCK_TIME_NONE);
GST_OBJECT_LOCK (element);
result = GST_ELEMENT_START_TIME (element);
GST_OBJECT_UNLOCK (element);
return result;
}
#if 0
/**
* gst_element_set_index:
* @element: a #GstElement.
* @index: (transfer none): a #GstIndex.
*
* Set @index on the element. The refcount of the index
* will be increased, any previously set index is unreffed.
*
* MT safe.
*/
void
gst_element_set_index (GstElement * element, GstIndex * index)
{
GstElementClass *oclass;
g_return_if_fail (GST_IS_ELEMENT (element));
g_return_if_fail (index == NULL || GST_IS_INDEX (index));
oclass = GST_ELEMENT_GET_CLASS (element);
if (oclass->set_index)
oclass->set_index (element, index);
}
/**
* gst_element_get_index:
* @element: a #GstElement.
*
* Gets the index from the element.
*
* Returns: (transfer full) (nullable): a #GstIndex or %NULL when no
* index was set on the element. unref after usage.
*
* MT safe.
*/
GstIndex *
gst_element_get_index (GstElement * element)
{
GstElementClass *oclass;
GstIndex *result = NULL;
g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
oclass = GST_ELEMENT_GET_CLASS (element);
if (oclass->get_index)
result = oclass->get_index (element);
return result;
}
#endif
/**
* gst_element_add_pad:
* @element: a #GstElement to add the pad to.
* @pad: (transfer floating): the #GstPad to add to the element.
*
gst/gstpad.c (gst_pad_custom_new): Add a FIXME, this is a hacky way to do inheritance. Original commit message from CVS: 2004-02-10 Andy Wingo <wingo@pobox.com> * gst/gstpad.c (gst_pad_custom_new): Add a FIXME, this is a hacky way to do inheritance. (gst_pad_get_event_masks, gst_pad_get_event_masks_default) (gst_pad_get_query_types, gst_pad_get_query_types_default): Routine docs. (gst_pad_set_link_function, gst_pad_set_fixate_function) (gst_pad_set_getcaps_function): Doc from Dave's negotation random doc. (gst_pad_unlink, gst_pad_is_linked): Docs. (gst_pad_renegotiate): A brief description of capsnego. (gst_pad_try_set_caps): Document. (gst_pad_try_set_caps_nonfixed): Document. (gst_pad_can_link_filtered, gst_pad_link_filtered): Doc fixes. (gst_pad_set_parent): Deprecated (although not out of the API). (gst_pad_get_parent): Deprecated, although many plugins use this. (gst_pad_add_ghost_pad, gst_pad_remove_ghost_pad): Doc that these are private and will go away in 0.9. (gst_pad_perform_negotiate): Doc. (gst_pad_link_unnegotiate): I think this is meant to be static. (gst_pad_get_negotiated_caps, gst_pad_get_pad_template_caps) (gst_pad_template_get_caps_by_name, gst_pad_check_compatibility) (gst_pad_get_peer): Doc updates. (gst_pad_caps_change_notify): Doc. (gst_pad_alloc_buffer, gst_pad_push, gst_static_pad_template_get) (gst_ghost_pad_new): Doc fixes. * gst/gstobject.c (gst_object_get_parent, gst_object_unparent) (gst_object_check_uniqueness): * gst/gstelement.c (gst_element_add_pad) (gst_element_add_ghost_pad, gst_element_remove_pad) (gst_element_remove_ghost_pad, gst_element_get_pad) (gst_element_get_static_pad, gst_element_get_pad_list) (gst_element_class_get_pad_template_list) (gst_element_class_get_pad_template): Work on the docs. (gst_element_get_pad_template_list): Uses the class method. (gst_element_get_compatible_pad_template): Docs, and consolidate some test conditions. (gst_element_get_pad_from_template): New static function. (gst_element_request_compatible_pad): Docs, and work with non-request compatible templates. (gst_element_get_compatible_pad_filtered): Docs and remove redundant checks. (gst_element_get_compatible_pad, gst_element_link_pads_filtered) (gst_element_link_filtered, gst_element_link_many) (gst_element_link, gst_element_link_pads) (gst_element_unlink_many): Docs. 2004-02-05 Andy Wingo <wingo@pobox.com> * gst/gstpad.c (_gst_real_pad_fixate_accumulator): s/pointer/boxed/. * gst/gstmarshal.list (VOID:BOXED, BOXED:BOXED): New marshallers. * gst/gstpad.c (gst_real_pad_class_init): Use a BOXED:BOXED marshaller for ::fixate, and VOID:BOXED for ::caps-nego-failed, with the type=GST_TYPE_CAPS. This allows language bindings to know what kind of data they're dealing with. * gst/gstcaps.c (_gst_caps_value_init): GBoxed values initialize to NULL when g_value_init is called. GstCaps, which rolls its own type implementation, now does the same instead of allocating empty caps. (_gst_caps_initialize, _gst_caps_collect_value, _gst_caps_lcopy_value): Provide collect_value and lcopy_value type table methods. This allows G_VALUE_COLLECT to work. 2004-02-05 Andy Wingo <wingo@pobox.com> * configure.ac: * testsuite/Makefile.am (SUBDIRS): * testsuite/ghostpads/Makefile.am: * testsuite/ghostpads/ghostpads.c: A new test for ghost pads. * gst/gstpad.c (gst_pad_add_ghost_pad, gst_pad_remove_ghost_pad): These two routines are the only ones that set GST_GPAD_REALPAD(gpad), the ghost pad list, and the ghost pad's pad template. They should be made static, depending on ABI needs. (gst_real_pad_dispose): Handle the case of ghost pads without a parent. Assert after dealing with ghost pads that the ghost pad list is empty. (gst_ghost_pad_class_init): New property added, ::real-pad. Can be set after creation. (gst_ghost_pad_dispose): Set ::real-pad to NULL. (gst_ghost_pad_set_property, gst_ghost_pad_get_property): New functions. set_property will call add_ghost_pad/remove_ghost_pad as appropriate. (gst_ghost_pad_new): All the work is offloaded to g_object_new. * gst/gstelement.c (gst_element_add_pad): Handle ghost pads as well. (gst_element_add_ghost_pad): Remove code duplicated from _add_pad. (gst_element_remove_pad): Handle ghost pads as well. (gst_element_remove_ghost_pad): Deprecated (could be removed, depending on API-stability needs). 2004-02-05 Andy Wingo <wingo@pobox.com> * gst/gstbin.[ch]: (gst_bin_get_by_interface): GTypes are scalars, of course they're const
2004-02-11 13:26:04 +00:00
* Adds a pad (link point) to @element. @pad's parent will be set to @element;
* see gst_object_set_parent() for refcounting information.
*
* Pads are not automatically activated so elements should perform the needed
* steps to activate the pad in case this pad is added in the PAUSED or PLAYING
* state. See gst_pad_set_active() for more information about activating pads.
*
* The pad and the element should be unlocked when calling this function.
*
* This function will emit the #GstElement::pad-added signal on the element.
*
* Returns: %TRUE if the pad could be added. This function can fail when
* a pad with the same name already existed or the pad already had another
* parent.
*
* MT safe.
*/
gboolean
gst_element_add_pad (GstElement * element, GstPad * pad)
{
gchar *pad_name;
gboolean active;
g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
/* locking pad to look at the name */
GST_OBJECT_LOCK (pad);
pad_name = g_strdup (GST_PAD_NAME (pad));
GST_CAT_INFO_OBJECT (GST_CAT_ELEMENT_PADS, element, "adding pad '%s'",
GST_STR_NULL (pad_name));
active = GST_PAD_IS_ACTIVE (pad);
GST_OBJECT_FLAG_SET (pad, GST_PAD_FLAG_NEED_PARENT);
GST_OBJECT_UNLOCK (pad);
/* then check to see if there's already a pad by that name here */
GST_OBJECT_LOCK (element);
if (G_UNLIKELY (!gst_object_check_uniqueness (element->pads, pad_name)))
goto name_exists;
/* try to set the pad's parent */
if (G_UNLIKELY (!gst_object_set_parent (GST_OBJECT_CAST (pad),
GST_OBJECT_CAST (element))))
goto had_parent;
/* check for active pads */
if (!active && (GST_STATE (element) > GST_STATE_READY ||
GST_STATE_NEXT (element) == GST_STATE_PAUSED)) {
g_warning ("adding inactive pad '%s' to running element '%s', you need to "
"use gst_pad_set_active(pad,TRUE) before adding it.",
GST_STR_NULL (pad_name), GST_ELEMENT_NAME (element));
gst_pad_set_active (pad, TRUE);
}
g_free (pad_name);
/* add it to the list */
gst/gstpad.c (_gst_real_pad_fixate_accumulator): s/pointer/boxed/. Original commit message from CVS: 2004-02-05 Andy Wingo <wingo@pobox.com> * gst/gstpad.c (_gst_real_pad_fixate_accumulator): s/pointer/boxed/. * gst/gstmarshal.list (VOID:BOXED, BOXED:BOXED): New marshallers. * gst/gstpad.c (gst_real_pad_class_init): Use a BOXED:BOXED marshaller for ::fixate, and VOID:BOXED for ::caps-nego-failed, with the type=GST_TYPE_CAPS. This allows language bindings to know what kind of data they're dealing with. * gst/gstcaps.c (_gst_caps_value_init): GBoxed values initialize to NULL when g_value_init is called. GstCaps, which rolls its own type implementation, now does the same instead of allocating empty caps. (_gst_caps_initialize, _gst_caps_collect_value, _gst_caps_lcopy_value): Provide collect_value and lcopy_value type table methods. This allows G_VALUE_COLLECT to work. 2004-02-05 Andy Wingo <wingo@pobox.com> * configure.ac: * testsuite/Makefile.am (SUBDIRS): * testsuite/ghostpads/Makefile.am: * testsuite/ghostpads/ghostpads.c: A new test for ghost pads. * gst/gstpad.c (gst_pad_add_ghost_pad, gst_pad_remove_ghost_pad): These two routines are the only ones that set GST_GPAD_REALPAD(gpad), the ghost pad list, and the ghost pad's pad template. They should be made static, depending on ABI needs. (gst_real_pad_dispose): Handle the case of ghost pads without a parent. Assert after dealing with ghost pads that the ghost pad list is empty. (gst_ghost_pad_class_init): New property added, ::real-pad. Can be set after creation. (gst_ghost_pad_dispose): Set ::real-pad to NULL. (gst_ghost_pad_set_property, gst_ghost_pad_get_property): New functions. set_property will call add_ghost_pad/remove_ghost_pad as appropriate. (gst_ghost_pad_new): All the work is offloaded to g_object_new. * gst/gstelement.c (gst_element_add_pad): Handle ghost pads as well. (gst_element_add_ghost_pad): Remove code duplicated from _add_pad. (gst_element_remove_pad): Handle ghost pads as well. (gst_element_remove_ghost_pad): Deprecated (could be removed, depending on API-stability needs). 2004-02-05 Andy Wingo <wingo@pobox.com> * gst/gstbin.[ch]: (gst_bin_get_by_interface): GTypes are scalars, of course they're const
2004-02-05 13:51:26 +00:00
switch (gst_pad_get_direction (pad)) {
case GST_PAD_SRC:
element->srcpads = g_list_append (element->srcpads, pad);
element->numsrcpads++;
break;
case GST_PAD_SINK:
element->sinkpads = g_list_append (element->sinkpads, pad);
element->numsinkpads++;
break;
default:
gst/gstutils.c: RPAD fixes all around. Original commit message from CVS: 2005-06-08 Andy Wingo <wingo@pobox.com> * gst/gstutils.c: RPAD fixes all around. (gst_element_link_pads): Refcounting fixes. * tools/gst-inspect.c: * tools/gst-xmlinspect.c: * parse/grammar.y: * gst/base/gsttypefindhelper.c: * gst/base/gstbasesink.c: * gst/gstqueue.c: RPAD fixes. * gst/gstghostpad.h: * gst/gstghostpad.c: New ghost pad implementation as full proxy pads. The tricky thing is they provide both source and sink interfaces, since they proxy the internal pad for the external pad, and vice versa. Implement with lower-level ProxyPad objects, with the interior proxy pad as a child of the exterior ghost pad. Should write a doc on this. * gst/gstpad.h: s/RPAD/PAD/, s/RealPad/Pad/. (gst_pad_set_name, gst_pad_set_parent): Macros removed, use gst_object API. * gst/gstpad.c: Big changes. No more stub base GstPad, now all pads are real pads. No ghost pads in this file. Not documenting the myriad s/RPAD/PAD/ and REALIZE fixes. (gst_pad_class_init): Add properties for "direction" and "template". Both are construct-only, so they can't change during the life of the pad. Fixes properly deriving from GstPad. (gst_pad_custom_new, gst_pad_custom_new_from_template): Gone. For derived objects, just set properties when creating the objects via g_object_new. (gst_pad_get_parent): Implement as a function, return NULL if the parent is not an element. (gst_pad_get_real_parent, gst_pad_add_ghost_pad) (gst_pad_remove_ghost_pad, gst_pad_realize): Removed. * gst/gstobject.c (gst_object_class_init): Make name a construct property. Don't set it in the object init. * gst/gstelement.c (gst_element_add_pad): Don't allow adding pads with UNKNOWN direction. (gst_element_add_ghost_pad): Remove non-orthogonal API. Replace with gst_element_add_pad (e, gst_ghost_pad_new (name, pad)). (gst_element_remove_pad): Remove ghost-pad special cases. (gst_element_pads_activate): Remove rpad cruft. * gst/gstbin.c (gst_bin_change_state): Use gst_pad_get_parent to catch the pad's-parent-not-an-element case. * gst/gst.h: Include gstghostpad.h. * gst/gst.c (init_post): No more real, ghost pads. * gst/Makefile.am: Add gstghostpad.[ch]. * check/Makefile.am: * check/gst/gstbin.c: * check/gst/gstghostpad.c (test_ghost_pads): Check that linking into a bin creates ghost pads, and that the refcounts are right. Partly moved from gstbin.c.
2005-06-08 22:16:27 +00:00
goto no_direction;
gst/gstpad.c (_gst_real_pad_fixate_accumulator): s/pointer/boxed/. Original commit message from CVS: 2004-02-05 Andy Wingo <wingo@pobox.com> * gst/gstpad.c (_gst_real_pad_fixate_accumulator): s/pointer/boxed/. * gst/gstmarshal.list (VOID:BOXED, BOXED:BOXED): New marshallers. * gst/gstpad.c (gst_real_pad_class_init): Use a BOXED:BOXED marshaller for ::fixate, and VOID:BOXED for ::caps-nego-failed, with the type=GST_TYPE_CAPS. This allows language bindings to know what kind of data they're dealing with. * gst/gstcaps.c (_gst_caps_value_init): GBoxed values initialize to NULL when g_value_init is called. GstCaps, which rolls its own type implementation, now does the same instead of allocating empty caps. (_gst_caps_initialize, _gst_caps_collect_value, _gst_caps_lcopy_value): Provide collect_value and lcopy_value type table methods. This allows G_VALUE_COLLECT to work. 2004-02-05 Andy Wingo <wingo@pobox.com> * configure.ac: * testsuite/Makefile.am (SUBDIRS): * testsuite/ghostpads/Makefile.am: * testsuite/ghostpads/ghostpads.c: A new test for ghost pads. * gst/gstpad.c (gst_pad_add_ghost_pad, gst_pad_remove_ghost_pad): These two routines are the only ones that set GST_GPAD_REALPAD(gpad), the ghost pad list, and the ghost pad's pad template. They should be made static, depending on ABI needs. (gst_real_pad_dispose): Handle the case of ghost pads without a parent. Assert after dealing with ghost pads that the ghost pad list is empty. (gst_ghost_pad_class_init): New property added, ::real-pad. Can be set after creation. (gst_ghost_pad_dispose): Set ::real-pad to NULL. (gst_ghost_pad_set_property, gst_ghost_pad_get_property): New functions. set_property will call add_ghost_pad/remove_ghost_pad as appropriate. (gst_ghost_pad_new): All the work is offloaded to g_object_new. * gst/gstelement.c (gst_element_add_pad): Handle ghost pads as well. (gst_element_add_ghost_pad): Remove code duplicated from _add_pad. (gst_element_remove_pad): Handle ghost pads as well. (gst_element_remove_ghost_pad): Deprecated (could be removed, depending on API-stability needs). 2004-02-05 Andy Wingo <wingo@pobox.com> * gst/gstbin.[ch]: (gst_bin_get_by_interface): GTypes are scalars, of course they're const
2004-02-05 13:51:26 +00:00
}
element->pads = g_list_append (element->pads, pad);
element->numpads++;
element->pads_cookie++;
GST_OBJECT_UNLOCK (element);
/* emit the PAD_ADDED signal */
g_signal_emit (element, gst_element_signals[PAD_ADDED], 0, pad);
GST_TRACER_ELEMENT_ADD_PAD (element, pad);
return TRUE;
/* ERROR cases */
name_exists:
{
g_critical ("Padname %s is not unique in element %s, not adding",
pad_name, GST_ELEMENT_NAME (element));
GST_OBJECT_UNLOCK (element);
g_free (pad_name);
gst_object_ref_sink (pad);
gst_object_unref (pad);
return FALSE;
}
had_parent:
{
g_critical
("Pad %s already has parent when trying to add to element %s",
pad_name, GST_ELEMENT_NAME (element));
GST_OBJECT_UNLOCK (element);
g_free (pad_name);
return FALSE;
}
gst/gstutils.c: RPAD fixes all around. Original commit message from CVS: 2005-06-08 Andy Wingo <wingo@pobox.com> * gst/gstutils.c: RPAD fixes all around. (gst_element_link_pads): Refcounting fixes. * tools/gst-inspect.c: * tools/gst-xmlinspect.c: * parse/grammar.y: * gst/base/gsttypefindhelper.c: * gst/base/gstbasesink.c: * gst/gstqueue.c: RPAD fixes. * gst/gstghostpad.h: * gst/gstghostpad.c: New ghost pad implementation as full proxy pads. The tricky thing is they provide both source and sink interfaces, since they proxy the internal pad for the external pad, and vice versa. Implement with lower-level ProxyPad objects, with the interior proxy pad as a child of the exterior ghost pad. Should write a doc on this. * gst/gstpad.h: s/RPAD/PAD/, s/RealPad/Pad/. (gst_pad_set_name, gst_pad_set_parent): Macros removed, use gst_object API. * gst/gstpad.c: Big changes. No more stub base GstPad, now all pads are real pads. No ghost pads in this file. Not documenting the myriad s/RPAD/PAD/ and REALIZE fixes. (gst_pad_class_init): Add properties for "direction" and "template". Both are construct-only, so they can't change during the life of the pad. Fixes properly deriving from GstPad. (gst_pad_custom_new, gst_pad_custom_new_from_template): Gone. For derived objects, just set properties when creating the objects via g_object_new. (gst_pad_get_parent): Implement as a function, return NULL if the parent is not an element. (gst_pad_get_real_parent, gst_pad_add_ghost_pad) (gst_pad_remove_ghost_pad, gst_pad_realize): Removed. * gst/gstobject.c (gst_object_class_init): Make name a construct property. Don't set it in the object init. * gst/gstelement.c (gst_element_add_pad): Don't allow adding pads with UNKNOWN direction. (gst_element_add_ghost_pad): Remove non-orthogonal API. Replace with gst_element_add_pad (e, gst_ghost_pad_new (name, pad)). (gst_element_remove_pad): Remove ghost-pad special cases. (gst_element_pads_activate): Remove rpad cruft. * gst/gstbin.c (gst_bin_change_state): Use gst_pad_get_parent to catch the pad's-parent-not-an-element case. * gst/gst.h: Include gstghostpad.h. * gst/gst.c (init_post): No more real, ghost pads. * gst/Makefile.am: Add gstghostpad.[ch]. * check/Makefile.am: * check/gst/gstbin.c: * check/gst/gstghostpad.c (test_ghost_pads): Check that linking into a bin creates ghost pads, and that the refcounts are right. Partly moved from gstbin.c.
2005-06-08 22:16:27 +00:00
no_direction:
{
GST_OBJECT_LOCK (pad);
gst/gstutils.c: RPAD fixes all around. Original commit message from CVS: 2005-06-08 Andy Wingo <wingo@pobox.com> * gst/gstutils.c: RPAD fixes all around. (gst_element_link_pads): Refcounting fixes. * tools/gst-inspect.c: * tools/gst-xmlinspect.c: * parse/grammar.y: * gst/base/gsttypefindhelper.c: * gst/base/gstbasesink.c: * gst/gstqueue.c: RPAD fixes. * gst/gstghostpad.h: * gst/gstghostpad.c: New ghost pad implementation as full proxy pads. The tricky thing is they provide both source and sink interfaces, since they proxy the internal pad for the external pad, and vice versa. Implement with lower-level ProxyPad objects, with the interior proxy pad as a child of the exterior ghost pad. Should write a doc on this. * gst/gstpad.h: s/RPAD/PAD/, s/RealPad/Pad/. (gst_pad_set_name, gst_pad_set_parent): Macros removed, use gst_object API. * gst/gstpad.c: Big changes. No more stub base GstPad, now all pads are real pads. No ghost pads in this file. Not documenting the myriad s/RPAD/PAD/ and REALIZE fixes. (gst_pad_class_init): Add properties for "direction" and "template". Both are construct-only, so they can't change during the life of the pad. Fixes properly deriving from GstPad. (gst_pad_custom_new, gst_pad_custom_new_from_template): Gone. For derived objects, just set properties when creating the objects via g_object_new. (gst_pad_get_parent): Implement as a function, return NULL if the parent is not an element. (gst_pad_get_real_parent, gst_pad_add_ghost_pad) (gst_pad_remove_ghost_pad, gst_pad_realize): Removed. * gst/gstobject.c (gst_object_class_init): Make name a construct property. Don't set it in the object init. * gst/gstelement.c (gst_element_add_pad): Don't allow adding pads with UNKNOWN direction. (gst_element_add_ghost_pad): Remove non-orthogonal API. Replace with gst_element_add_pad (e, gst_ghost_pad_new (name, pad)). (gst_element_remove_pad): Remove ghost-pad special cases. (gst_element_pads_activate): Remove rpad cruft. * gst/gstbin.c (gst_bin_change_state): Use gst_pad_get_parent to catch the pad's-parent-not-an-element case. * gst/gst.h: Include gstghostpad.h. * gst/gst.c (init_post): No more real, ghost pads. * gst/Makefile.am: Add gstghostpad.[ch]. * check/Makefile.am: * check/gst/gstbin.c: * check/gst/gstghostpad.c (test_ghost_pads): Check that linking into a bin creates ghost pads, and that the refcounts are right. Partly moved from gstbin.c.
2005-06-08 22:16:27 +00:00
g_critical
("Trying to add pad %s to element %s, but it has no direction",
GST_OBJECT_NAME (pad), GST_ELEMENT_NAME (element));
GST_OBJECT_UNLOCK (pad);
GST_OBJECT_UNLOCK (element);
gst/gstutils.c: RPAD fixes all around. Original commit message from CVS: 2005-06-08 Andy Wingo <wingo@pobox.com> * gst/gstutils.c: RPAD fixes all around. (gst_element_link_pads): Refcounting fixes. * tools/gst-inspect.c: * tools/gst-xmlinspect.c: * parse/grammar.y: * gst/base/gsttypefindhelper.c: * gst/base/gstbasesink.c: * gst/gstqueue.c: RPAD fixes. * gst/gstghostpad.h: * gst/gstghostpad.c: New ghost pad implementation as full proxy pads. The tricky thing is they provide both source and sink interfaces, since they proxy the internal pad for the external pad, and vice versa. Implement with lower-level ProxyPad objects, with the interior proxy pad as a child of the exterior ghost pad. Should write a doc on this. * gst/gstpad.h: s/RPAD/PAD/, s/RealPad/Pad/. (gst_pad_set_name, gst_pad_set_parent): Macros removed, use gst_object API. * gst/gstpad.c: Big changes. No more stub base GstPad, now all pads are real pads. No ghost pads in this file. Not documenting the myriad s/RPAD/PAD/ and REALIZE fixes. (gst_pad_class_init): Add properties for "direction" and "template". Both are construct-only, so they can't change during the life of the pad. Fixes properly deriving from GstPad. (gst_pad_custom_new, gst_pad_custom_new_from_template): Gone. For derived objects, just set properties when creating the objects via g_object_new. (gst_pad_get_parent): Implement as a function, return NULL if the parent is not an element. (gst_pad_get_real_parent, gst_pad_add_ghost_pad) (gst_pad_remove_ghost_pad, gst_pad_realize): Removed. * gst/gstobject.c (gst_object_class_init): Make name a construct property. Don't set it in the object init. * gst/gstelement.c (gst_element_add_pad): Don't allow adding pads with UNKNOWN direction. (gst_element_add_ghost_pad): Remove non-orthogonal API. Replace with gst_element_add_pad (e, gst_ghost_pad_new (name, pad)). (gst_element_remove_pad): Remove ghost-pad special cases. (gst_element_pads_activate): Remove rpad cruft. * gst/gstbin.c (gst_bin_change_state): Use gst_pad_get_parent to catch the pad's-parent-not-an-element case. * gst/gst.h: Include gstghostpad.h. * gst/gst.c (init_post): No more real, ghost pads. * gst/Makefile.am: Add gstghostpad.[ch]. * check/Makefile.am: * check/gst/gstbin.c: * check/gst/gstghostpad.c (test_ghost_pads): Check that linking into a bin creates ghost pads, and that the refcounts are right. Partly moved from gstbin.c.
2005-06-08 22:16:27 +00:00
return FALSE;
}
gst/gstpad.c (_gst_real_pad_fixate_accumulator): s/pointer/boxed/. Original commit message from CVS: 2004-02-05 Andy Wingo <wingo@pobox.com> * gst/gstpad.c (_gst_real_pad_fixate_accumulator): s/pointer/boxed/. * gst/gstmarshal.list (VOID:BOXED, BOXED:BOXED): New marshallers. * gst/gstpad.c (gst_real_pad_class_init): Use a BOXED:BOXED marshaller for ::fixate, and VOID:BOXED for ::caps-nego-failed, with the type=GST_TYPE_CAPS. This allows language bindings to know what kind of data they're dealing with. * gst/gstcaps.c (_gst_caps_value_init): GBoxed values initialize to NULL when g_value_init is called. GstCaps, which rolls its own type implementation, now does the same instead of allocating empty caps. (_gst_caps_initialize, _gst_caps_collect_value, _gst_caps_lcopy_value): Provide collect_value and lcopy_value type table methods. This allows G_VALUE_COLLECT to work. 2004-02-05 Andy Wingo <wingo@pobox.com> * configure.ac: * testsuite/Makefile.am (SUBDIRS): * testsuite/ghostpads/Makefile.am: * testsuite/ghostpads/ghostpads.c: A new test for ghost pads. * gst/gstpad.c (gst_pad_add_ghost_pad, gst_pad_remove_ghost_pad): These two routines are the only ones that set GST_GPAD_REALPAD(gpad), the ghost pad list, and the ghost pad's pad template. They should be made static, depending on ABI needs. (gst_real_pad_dispose): Handle the case of ghost pads without a parent. Assert after dealing with ghost pads that the ghost pad list is empty. (gst_ghost_pad_class_init): New property added, ::real-pad. Can be set after creation. (gst_ghost_pad_dispose): Set ::real-pad to NULL. (gst_ghost_pad_set_property, gst_ghost_pad_get_property): New functions. set_property will call add_ghost_pad/remove_ghost_pad as appropriate. (gst_ghost_pad_new): All the work is offloaded to g_object_new. * gst/gstelement.c (gst_element_add_pad): Handle ghost pads as well. (gst_element_add_ghost_pad): Remove code duplicated from _add_pad. (gst_element_remove_pad): Handle ghost pads as well. (gst_element_remove_ghost_pad): Deprecated (could be removed, depending on API-stability needs). 2004-02-05 Andy Wingo <wingo@pobox.com> * gst/gstbin.[ch]: (gst_bin_get_by_interface): GTypes are scalars, of course they're const
2004-02-05 13:51:26 +00:00
}
/**
* gst_element_remove_pad:
* @element: a #GstElement to remove pad from.
* @pad: (transfer none): the #GstPad to remove from the element.
*
gst/gstpad.c (gst_pad_custom_new): Add a FIXME, this is a hacky way to do inheritance. Original commit message from CVS: 2004-02-10 Andy Wingo <wingo@pobox.com> * gst/gstpad.c (gst_pad_custom_new): Add a FIXME, this is a hacky way to do inheritance. (gst_pad_get_event_masks, gst_pad_get_event_masks_default) (gst_pad_get_query_types, gst_pad_get_query_types_default): Routine docs. (gst_pad_set_link_function, gst_pad_set_fixate_function) (gst_pad_set_getcaps_function): Doc from Dave's negotation random doc. (gst_pad_unlink, gst_pad_is_linked): Docs. (gst_pad_renegotiate): A brief description of capsnego. (gst_pad_try_set_caps): Document. (gst_pad_try_set_caps_nonfixed): Document. (gst_pad_can_link_filtered, gst_pad_link_filtered): Doc fixes. (gst_pad_set_parent): Deprecated (although not out of the API). (gst_pad_get_parent): Deprecated, although many plugins use this. (gst_pad_add_ghost_pad, gst_pad_remove_ghost_pad): Doc that these are private and will go away in 0.9. (gst_pad_perform_negotiate): Doc. (gst_pad_link_unnegotiate): I think this is meant to be static. (gst_pad_get_negotiated_caps, gst_pad_get_pad_template_caps) (gst_pad_template_get_caps_by_name, gst_pad_check_compatibility) (gst_pad_get_peer): Doc updates. (gst_pad_caps_change_notify): Doc. (gst_pad_alloc_buffer, gst_pad_push, gst_static_pad_template_get) (gst_ghost_pad_new): Doc fixes. * gst/gstobject.c (gst_object_get_parent, gst_object_unparent) (gst_object_check_uniqueness): * gst/gstelement.c (gst_element_add_pad) (gst_element_add_ghost_pad, gst_element_remove_pad) (gst_element_remove_ghost_pad, gst_element_get_pad) (gst_element_get_static_pad, gst_element_get_pad_list) (gst_element_class_get_pad_template_list) (gst_element_class_get_pad_template): Work on the docs. (gst_element_get_pad_template_list): Uses the class method. (gst_element_get_compatible_pad_template): Docs, and consolidate some test conditions. (gst_element_get_pad_from_template): New static function. (gst_element_request_compatible_pad): Docs, and work with non-request compatible templates. (gst_element_get_compatible_pad_filtered): Docs and remove redundant checks. (gst_element_get_compatible_pad, gst_element_link_pads_filtered) (gst_element_link_filtered, gst_element_link_many) (gst_element_link, gst_element_link_pads) (gst_element_unlink_many): Docs. 2004-02-05 Andy Wingo <wingo@pobox.com> * gst/gstpad.c (_gst_real_pad_fixate_accumulator): s/pointer/boxed/. * gst/gstmarshal.list (VOID:BOXED, BOXED:BOXED): New marshallers. * gst/gstpad.c (gst_real_pad_class_init): Use a BOXED:BOXED marshaller for ::fixate, and VOID:BOXED for ::caps-nego-failed, with the type=GST_TYPE_CAPS. This allows language bindings to know what kind of data they're dealing with. * gst/gstcaps.c (_gst_caps_value_init): GBoxed values initialize to NULL when g_value_init is called. GstCaps, which rolls its own type implementation, now does the same instead of allocating empty caps. (_gst_caps_initialize, _gst_caps_collect_value, _gst_caps_lcopy_value): Provide collect_value and lcopy_value type table methods. This allows G_VALUE_COLLECT to work. 2004-02-05 Andy Wingo <wingo@pobox.com> * configure.ac: * testsuite/Makefile.am (SUBDIRS): * testsuite/ghostpads/Makefile.am: * testsuite/ghostpads/ghostpads.c: A new test for ghost pads. * gst/gstpad.c (gst_pad_add_ghost_pad, gst_pad_remove_ghost_pad): These two routines are the only ones that set GST_GPAD_REALPAD(gpad), the ghost pad list, and the ghost pad's pad template. They should be made static, depending on ABI needs. (gst_real_pad_dispose): Handle the case of ghost pads without a parent. Assert after dealing with ghost pads that the ghost pad list is empty. (gst_ghost_pad_class_init): New property added, ::real-pad. Can be set after creation. (gst_ghost_pad_dispose): Set ::real-pad to NULL. (gst_ghost_pad_set_property, gst_ghost_pad_get_property): New functions. set_property will call add_ghost_pad/remove_ghost_pad as appropriate. (gst_ghost_pad_new): All the work is offloaded to g_object_new. * gst/gstelement.c (gst_element_add_pad): Handle ghost pads as well. (gst_element_add_ghost_pad): Remove code duplicated from _add_pad. (gst_element_remove_pad): Handle ghost pads as well. (gst_element_remove_ghost_pad): Deprecated (could be removed, depending on API-stability needs). 2004-02-05 Andy Wingo <wingo@pobox.com> * gst/gstbin.[ch]: (gst_bin_get_by_interface): GTypes are scalars, of course they're const
2004-02-11 13:26:04 +00:00
* Removes @pad from @element. @pad will be destroyed if it has not been
* referenced elsewhere using gst_object_unparent().
*
* This function is used by plugin developers and should not be used
* by applications. Pads that were dynamically requested from elements
* with gst_element_request_pad() should be released with the
* gst_element_release_request_pad() function instead.
*
* Pads are not automatically deactivated so elements should perform the needed
* steps to deactivate the pad in case this pad is removed in the PAUSED or
* PLAYING state. See gst_pad_set_active() for more information about
* deactivating pads.
*
* The pad and the element should be unlocked when calling this function.
*
* This function will emit the #GstElement::pad-removed signal on the element.
*
* Returns: %TRUE if the pad could be removed. Can return %FALSE if the
* pad does not belong to the provided element.
*
* MT safe.
*/
gboolean
gst_element_remove_pad (GstElement * element, GstPad * pad)
{
gst/gstutils.c: RPAD fixes all around. Original commit message from CVS: 2005-06-08 Andy Wingo <wingo@pobox.com> * gst/gstutils.c: RPAD fixes all around. (gst_element_link_pads): Refcounting fixes. * tools/gst-inspect.c: * tools/gst-xmlinspect.c: * parse/grammar.y: * gst/base/gsttypefindhelper.c: * gst/base/gstbasesink.c: * gst/gstqueue.c: RPAD fixes. * gst/gstghostpad.h: * gst/gstghostpad.c: New ghost pad implementation as full proxy pads. The tricky thing is they provide both source and sink interfaces, since they proxy the internal pad for the external pad, and vice versa. Implement with lower-level ProxyPad objects, with the interior proxy pad as a child of the exterior ghost pad. Should write a doc on this. * gst/gstpad.h: s/RPAD/PAD/, s/RealPad/Pad/. (gst_pad_set_name, gst_pad_set_parent): Macros removed, use gst_object API. * gst/gstpad.c: Big changes. No more stub base GstPad, now all pads are real pads. No ghost pads in this file. Not documenting the myriad s/RPAD/PAD/ and REALIZE fixes. (gst_pad_class_init): Add properties for "direction" and "template". Both are construct-only, so they can't change during the life of the pad. Fixes properly deriving from GstPad. (gst_pad_custom_new, gst_pad_custom_new_from_template): Gone. For derived objects, just set properties when creating the objects via g_object_new. (gst_pad_get_parent): Implement as a function, return NULL if the parent is not an element. (gst_pad_get_real_parent, gst_pad_add_ghost_pad) (gst_pad_remove_ghost_pad, gst_pad_realize): Removed. * gst/gstobject.c (gst_object_class_init): Make name a construct property. Don't set it in the object init. * gst/gstelement.c (gst_element_add_pad): Don't allow adding pads with UNKNOWN direction. (gst_element_add_ghost_pad): Remove non-orthogonal API. Replace with gst_element_add_pad (e, gst_ghost_pad_new (name, pad)). (gst_element_remove_pad): Remove ghost-pad special cases. (gst_element_pads_activate): Remove rpad cruft. * gst/gstbin.c (gst_bin_change_state): Use gst_pad_get_parent to catch the pad's-parent-not-an-element case. * gst/gst.h: Include gstghostpad.h. * gst/gst.c (init_post): No more real, ghost pads. * gst/Makefile.am: Add gstghostpad.[ch]. * check/Makefile.am: * check/gst/gstbin.c: * check/gst/gstghostpad.c (test_ghost_pads): Check that linking into a bin creates ghost pads, and that the refcounts are right. Partly moved from gstbin.c.
2005-06-08 22:16:27 +00:00
GstPad *peer;
g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
/* locking pad to look at the name and parent */
GST_OBJECT_LOCK (pad);
GST_CAT_INFO_OBJECT (GST_CAT_ELEMENT_PADS, element, "removing pad '%s'",
GST_STR_NULL (GST_PAD_NAME (pad)));
if (G_UNLIKELY (GST_PAD_PARENT (pad) != element))
goto not_our_pad;
GST_OBJECT_UNLOCK (pad);
gst/gstutils.c: RPAD fixes all around. Original commit message from CVS: 2005-06-08 Andy Wingo <wingo@pobox.com> * gst/gstutils.c: RPAD fixes all around. (gst_element_link_pads): Refcounting fixes. * tools/gst-inspect.c: * tools/gst-xmlinspect.c: * parse/grammar.y: * gst/base/gsttypefindhelper.c: * gst/base/gstbasesink.c: * gst/gstqueue.c: RPAD fixes. * gst/gstghostpad.h: * gst/gstghostpad.c: New ghost pad implementation as full proxy pads. The tricky thing is they provide both source and sink interfaces, since they proxy the internal pad for the external pad, and vice versa. Implement with lower-level ProxyPad objects, with the interior proxy pad as a child of the exterior ghost pad. Should write a doc on this. * gst/gstpad.h: s/RPAD/PAD/, s/RealPad/Pad/. (gst_pad_set_name, gst_pad_set_parent): Macros removed, use gst_object API. * gst/gstpad.c: Big changes. No more stub base GstPad, now all pads are real pads. No ghost pads in this file. Not documenting the myriad s/RPAD/PAD/ and REALIZE fixes. (gst_pad_class_init): Add properties for "direction" and "template". Both are construct-only, so they can't change during the life of the pad. Fixes properly deriving from GstPad. (gst_pad_custom_new, gst_pad_custom_new_from_template): Gone. For derived objects, just set properties when creating the objects via g_object_new. (gst_pad_get_parent): Implement as a function, return NULL if the parent is not an element. (gst_pad_get_real_parent, gst_pad_add_ghost_pad) (gst_pad_remove_ghost_pad, gst_pad_realize): Removed. * gst/gstobject.c (gst_object_class_init): Make name a construct property. Don't set it in the object init. * gst/gstelement.c (gst_element_add_pad): Don't allow adding pads with UNKNOWN direction. (gst_element_add_ghost_pad): Remove non-orthogonal API. Replace with gst_element_add_pad (e, gst_ghost_pad_new (name, pad)). (gst_element_remove_pad): Remove ghost-pad special cases. (gst_element_pads_activate): Remove rpad cruft. * gst/gstbin.c (gst_bin_change_state): Use gst_pad_get_parent to catch the pad's-parent-not-an-element case. * gst/gst.h: Include gstghostpad.h. * gst/gst.c (init_post): No more real, ghost pads. * gst/Makefile.am: Add gstghostpad.[ch]. * check/Makefile.am: * check/gst/gstbin.c: * check/gst/gstghostpad.c (test_ghost_pads): Check that linking into a bin creates ghost pads, and that the refcounts are right. Partly moved from gstbin.c.
2005-06-08 22:16:27 +00:00
/* unlink */
if ((peer = gst_pad_get_peer (pad))) {
gst/gstutils.c: RPAD fixes all around. Original commit message from CVS: 2005-06-08 Andy Wingo <wingo@pobox.com> * gst/gstutils.c: RPAD fixes all around. (gst_element_link_pads): Refcounting fixes. * tools/gst-inspect.c: * tools/gst-xmlinspect.c: * parse/grammar.y: * gst/base/gsttypefindhelper.c: * gst/base/gstbasesink.c: * gst/gstqueue.c: RPAD fixes. * gst/gstghostpad.h: * gst/gstghostpad.c: New ghost pad implementation as full proxy pads. The tricky thing is they provide both source and sink interfaces, since they proxy the internal pad for the external pad, and vice versa. Implement with lower-level ProxyPad objects, with the interior proxy pad as a child of the exterior ghost pad. Should write a doc on this. * gst/gstpad.h: s/RPAD/PAD/, s/RealPad/Pad/. (gst_pad_set_name, gst_pad_set_parent): Macros removed, use gst_object API. * gst/gstpad.c: Big changes. No more stub base GstPad, now all pads are real pads. No ghost pads in this file. Not documenting the myriad s/RPAD/PAD/ and REALIZE fixes. (gst_pad_class_init): Add properties for "direction" and "template". Both are construct-only, so they can't change during the life of the pad. Fixes properly deriving from GstPad. (gst_pad_custom_new, gst_pad_custom_new_from_template): Gone. For derived objects, just set properties when creating the objects via g_object_new. (gst_pad_get_parent): Implement as a function, return NULL if the parent is not an element. (gst_pad_get_real_parent, gst_pad_add_ghost_pad) (gst_pad_remove_ghost_pad, gst_pad_realize): Removed. * gst/gstobject.c (gst_object_class_init): Make name a construct property. Don't set it in the object init. * gst/gstelement.c (gst_element_add_pad): Don't allow adding pads with UNKNOWN direction. (gst_element_add_ghost_pad): Remove non-orthogonal API. Replace with gst_element_add_pad (e, gst_ghost_pad_new (name, pad)). (gst_element_remove_pad): Remove ghost-pad special cases. (gst_element_pads_activate): Remove rpad cruft. * gst/gstbin.c (gst_bin_change_state): Use gst_pad_get_parent to catch the pad's-parent-not-an-element case. * gst/gst.h: Include gstghostpad.h. * gst/gst.c (init_post): No more real, ghost pads. * gst/Makefile.am: Add gstghostpad.[ch]. * check/Makefile.am: * check/gst/gstbin.c: * check/gst/gstghostpad.c (test_ghost_pads): Check that linking into a bin creates ghost pads, and that the refcounts are right. Partly moved from gstbin.c.
2005-06-08 22:16:27 +00:00
/* window for MT unsafeness, someone else could unlink here
* and then we call unlink with wrong pads. The unlink
* function would catch this and safely return failed. */
if (GST_PAD_IS_SRC (pad))
gst_pad_unlink (pad, peer);
gst/gstutils.c: RPAD fixes all around. Original commit message from CVS: 2005-06-08 Andy Wingo <wingo@pobox.com> * gst/gstutils.c: RPAD fixes all around. (gst_element_link_pads): Refcounting fixes. * tools/gst-inspect.c: * tools/gst-xmlinspect.c: * parse/grammar.y: * gst/base/gsttypefindhelper.c: * gst/base/gstbasesink.c: * gst/gstqueue.c: RPAD fixes. * gst/gstghostpad.h: * gst/gstghostpad.c: New ghost pad implementation as full proxy pads. The tricky thing is they provide both source and sink interfaces, since they proxy the internal pad for the external pad, and vice versa. Implement with lower-level ProxyPad objects, with the interior proxy pad as a child of the exterior ghost pad. Should write a doc on this. * gst/gstpad.h: s/RPAD/PAD/, s/RealPad/Pad/. (gst_pad_set_name, gst_pad_set_parent): Macros removed, use gst_object API. * gst/gstpad.c: Big changes. No more stub base GstPad, now all pads are real pads. No ghost pads in this file. Not documenting the myriad s/RPAD/PAD/ and REALIZE fixes. (gst_pad_class_init): Add properties for "direction" and "template". Both are construct-only, so they can't change during the life of the pad. Fixes properly deriving from GstPad. (gst_pad_custom_new, gst_pad_custom_new_from_template): Gone. For derived objects, just set properties when creating the objects via g_object_new. (gst_pad_get_parent): Implement as a function, return NULL if the parent is not an element. (gst_pad_get_real_parent, gst_pad_add_ghost_pad) (gst_pad_remove_ghost_pad, gst_pad_realize): Removed. * gst/gstobject.c (gst_object_class_init): Make name a construct property. Don't set it in the object init. * gst/gstelement.c (gst_element_add_pad): Don't allow adding pads with UNKNOWN direction. (gst_element_add_ghost_pad): Remove non-orthogonal API. Replace with gst_element_add_pad (e, gst_ghost_pad_new (name, pad)). (gst_element_remove_pad): Remove ghost-pad special cases. (gst_element_pads_activate): Remove rpad cruft. * gst/gstbin.c (gst_bin_change_state): Use gst_pad_get_parent to catch the pad's-parent-not-an-element case. * gst/gst.h: Include gstghostpad.h. * gst/gst.c (init_post): No more real, ghost pads. * gst/Makefile.am: Add gstghostpad.[ch]. * check/Makefile.am: * check/gst/gstbin.c: * check/gst/gstghostpad.c (test_ghost_pads): Check that linking into a bin creates ghost pads, and that the refcounts are right. Partly moved from gstbin.c.
2005-06-08 22:16:27 +00:00
else
gst_pad_unlink (peer, pad);
gst/gstutils.c: RPAD fixes all around. Original commit message from CVS: 2005-06-08 Andy Wingo <wingo@pobox.com> * gst/gstutils.c: RPAD fixes all around. (gst_element_link_pads): Refcounting fixes. * tools/gst-inspect.c: * tools/gst-xmlinspect.c: * parse/grammar.y: * gst/base/gsttypefindhelper.c: * gst/base/gstbasesink.c: * gst/gstqueue.c: RPAD fixes. * gst/gstghostpad.h: * gst/gstghostpad.c: New ghost pad implementation as full proxy pads. The tricky thing is they provide both source and sink interfaces, since they proxy the internal pad for the external pad, and vice versa. Implement with lower-level ProxyPad objects, with the interior proxy pad as a child of the exterior ghost pad. Should write a doc on this. * gst/gstpad.h: s/RPAD/PAD/, s/RealPad/Pad/. (gst_pad_set_name, gst_pad_set_parent): Macros removed, use gst_object API. * gst/gstpad.c: Big changes. No more stub base GstPad, now all pads are real pads. No ghost pads in this file. Not documenting the myriad s/RPAD/PAD/ and REALIZE fixes. (gst_pad_class_init): Add properties for "direction" and "template". Both are construct-only, so they can't change during the life of the pad. Fixes properly deriving from GstPad. (gst_pad_custom_new, gst_pad_custom_new_from_template): Gone. For derived objects, just set properties when creating the objects via g_object_new. (gst_pad_get_parent): Implement as a function, return NULL if the parent is not an element. (gst_pad_get_real_parent, gst_pad_add_ghost_pad) (gst_pad_remove_ghost_pad, gst_pad_realize): Removed. * gst/gstobject.c (gst_object_class_init): Make name a construct property. Don't set it in the object init. * gst/gstelement.c (gst_element_add_pad): Don't allow adding pads with UNKNOWN direction. (gst_element_add_ghost_pad): Remove non-orthogonal API. Replace with gst_element_add_pad (e, gst_ghost_pad_new (name, pad)). (gst_element_remove_pad): Remove ghost-pad special cases. (gst_element_pads_activate): Remove rpad cruft. * gst/gstbin.c (gst_bin_change_state): Use gst_pad_get_parent to catch the pad's-parent-not-an-element case. * gst/gst.h: Include gstghostpad.h. * gst/gst.c (init_post): No more real, ghost pads. * gst/Makefile.am: Add gstghostpad.[ch]. * check/Makefile.am: * check/gst/gstbin.c: * check/gst/gstghostpad.c (test_ghost_pads): Check that linking into a bin creates ghost pads, and that the refcounts are right. Partly moved from gstbin.c.
2005-06-08 22:16:27 +00:00
gst_object_unref (peer);
}
GST_OBJECT_LOCK (element);
/* remove it from the list */
gst/gstpad.c (_gst_real_pad_fixate_accumulator): s/pointer/boxed/. Original commit message from CVS: 2004-02-05 Andy Wingo <wingo@pobox.com> * gst/gstpad.c (_gst_real_pad_fixate_accumulator): s/pointer/boxed/. * gst/gstmarshal.list (VOID:BOXED, BOXED:BOXED): New marshallers. * gst/gstpad.c (gst_real_pad_class_init): Use a BOXED:BOXED marshaller for ::fixate, and VOID:BOXED for ::caps-nego-failed, with the type=GST_TYPE_CAPS. This allows language bindings to know what kind of data they're dealing with. * gst/gstcaps.c (_gst_caps_value_init): GBoxed values initialize to NULL when g_value_init is called. GstCaps, which rolls its own type implementation, now does the same instead of allocating empty caps. (_gst_caps_initialize, _gst_caps_collect_value, _gst_caps_lcopy_value): Provide collect_value and lcopy_value type table methods. This allows G_VALUE_COLLECT to work. 2004-02-05 Andy Wingo <wingo@pobox.com> * configure.ac: * testsuite/Makefile.am (SUBDIRS): * testsuite/ghostpads/Makefile.am: * testsuite/ghostpads/ghostpads.c: A new test for ghost pads. * gst/gstpad.c (gst_pad_add_ghost_pad, gst_pad_remove_ghost_pad): These two routines are the only ones that set GST_GPAD_REALPAD(gpad), the ghost pad list, and the ghost pad's pad template. They should be made static, depending on ABI needs. (gst_real_pad_dispose): Handle the case of ghost pads without a parent. Assert after dealing with ghost pads that the ghost pad list is empty. (gst_ghost_pad_class_init): New property added, ::real-pad. Can be set after creation. (gst_ghost_pad_dispose): Set ::real-pad to NULL. (gst_ghost_pad_set_property, gst_ghost_pad_get_property): New functions. set_property will call add_ghost_pad/remove_ghost_pad as appropriate. (gst_ghost_pad_new): All the work is offloaded to g_object_new. * gst/gstelement.c (gst_element_add_pad): Handle ghost pads as well. (gst_element_add_ghost_pad): Remove code duplicated from _add_pad. (gst_element_remove_pad): Handle ghost pads as well. (gst_element_remove_ghost_pad): Deprecated (could be removed, depending on API-stability needs). 2004-02-05 Andy Wingo <wingo@pobox.com> * gst/gstbin.[ch]: (gst_bin_get_by_interface): GTypes are scalars, of course they're const
2004-02-05 13:51:26 +00:00
switch (gst_pad_get_direction (pad)) {
case GST_PAD_SRC:
element->srcpads = g_list_remove (element->srcpads, pad);
element->numsrcpads--;
break;
case GST_PAD_SINK:
element->sinkpads = g_list_remove (element->sinkpads, pad);
element->numsinkpads--;
break;
default:
gst/gstutils.c: RPAD fixes all around. Original commit message from CVS: 2005-06-08 Andy Wingo <wingo@pobox.com> * gst/gstutils.c: RPAD fixes all around. (gst_element_link_pads): Refcounting fixes. * tools/gst-inspect.c: * tools/gst-xmlinspect.c: * parse/grammar.y: * gst/base/gsttypefindhelper.c: * gst/base/gstbasesink.c: * gst/gstqueue.c: RPAD fixes. * gst/gstghostpad.h: * gst/gstghostpad.c: New ghost pad implementation as full proxy pads. The tricky thing is they provide both source and sink interfaces, since they proxy the internal pad for the external pad, and vice versa. Implement with lower-level ProxyPad objects, with the interior proxy pad as a child of the exterior ghost pad. Should write a doc on this. * gst/gstpad.h: s/RPAD/PAD/, s/RealPad/Pad/. (gst_pad_set_name, gst_pad_set_parent): Macros removed, use gst_object API. * gst/gstpad.c: Big changes. No more stub base GstPad, now all pads are real pads. No ghost pads in this file. Not documenting the myriad s/RPAD/PAD/ and REALIZE fixes. (gst_pad_class_init): Add properties for "direction" and "template". Both are construct-only, so they can't change during the life of the pad. Fixes properly deriving from GstPad. (gst_pad_custom_new, gst_pad_custom_new_from_template): Gone. For derived objects, just set properties when creating the objects via g_object_new. (gst_pad_get_parent): Implement as a function, return NULL if the parent is not an element. (gst_pad_get_real_parent, gst_pad_add_ghost_pad) (gst_pad_remove_ghost_pad, gst_pad_realize): Removed. * gst/gstobject.c (gst_object_class_init): Make name a construct property. Don't set it in the object init. * gst/gstelement.c (gst_element_add_pad): Don't allow adding pads with UNKNOWN direction. (gst_element_add_ghost_pad): Remove non-orthogonal API. Replace with gst_element_add_pad (e, gst_ghost_pad_new (name, pad)). (gst_element_remove_pad): Remove ghost-pad special cases. (gst_element_pads_activate): Remove rpad cruft. * gst/gstbin.c (gst_bin_change_state): Use gst_pad_get_parent to catch the pad's-parent-not-an-element case. * gst/gst.h: Include gstghostpad.h. * gst/gst.c (init_post): No more real, ghost pads. * gst/Makefile.am: Add gstghostpad.[ch]. * check/Makefile.am: * check/gst/gstbin.c: * check/gst/gstghostpad.c (test_ghost_pads): Check that linking into a bin creates ghost pads, and that the refcounts are right. Partly moved from gstbin.c.
2005-06-08 22:16:27 +00:00
g_critical ("Removing pad without direction???");
break;
gst/gstpad.c (_gst_real_pad_fixate_accumulator): s/pointer/boxed/. Original commit message from CVS: 2004-02-05 Andy Wingo <wingo@pobox.com> * gst/gstpad.c (_gst_real_pad_fixate_accumulator): s/pointer/boxed/. * gst/gstmarshal.list (VOID:BOXED, BOXED:BOXED): New marshallers. * gst/gstpad.c (gst_real_pad_class_init): Use a BOXED:BOXED marshaller for ::fixate, and VOID:BOXED for ::caps-nego-failed, with the type=GST_TYPE_CAPS. This allows language bindings to know what kind of data they're dealing with. * gst/gstcaps.c (_gst_caps_value_init): GBoxed values initialize to NULL when g_value_init is called. GstCaps, which rolls its own type implementation, now does the same instead of allocating empty caps. (_gst_caps_initialize, _gst_caps_collect_value, _gst_caps_lcopy_value): Provide collect_value and lcopy_value type table methods. This allows G_VALUE_COLLECT to work. 2004-02-05 Andy Wingo <wingo@pobox.com> * configure.ac: * testsuite/Makefile.am (SUBDIRS): * testsuite/ghostpads/Makefile.am: * testsuite/ghostpads/ghostpads.c: A new test for ghost pads. * gst/gstpad.c (gst_pad_add_ghost_pad, gst_pad_remove_ghost_pad): These two routines are the only ones that set GST_GPAD_REALPAD(gpad), the ghost pad list, and the ghost pad's pad template. They should be made static, depending on ABI needs. (gst_real_pad_dispose): Handle the case of ghost pads without a parent. Assert after dealing with ghost pads that the ghost pad list is empty. (gst_ghost_pad_class_init): New property added, ::real-pad. Can be set after creation. (gst_ghost_pad_dispose): Set ::real-pad to NULL. (gst_ghost_pad_set_property, gst_ghost_pad_get_property): New functions. set_property will call add_ghost_pad/remove_ghost_pad as appropriate. (gst_ghost_pad_new): All the work is offloaded to g_object_new. * gst/gstelement.c (gst_element_add_pad): Handle ghost pads as well. (gst_element_add_ghost_pad): Remove code duplicated from _add_pad. (gst_element_remove_pad): Handle ghost pads as well. (gst_element_remove_ghost_pad): Deprecated (could be removed, depending on API-stability needs). 2004-02-05 Andy Wingo <wingo@pobox.com> * gst/gstbin.[ch]: (gst_bin_get_by_interface): GTypes are scalars, of course they're const
2004-02-05 13:51:26 +00:00
}
element->pads = g_list_remove (element->pads, pad);
element->numpads--;
element->pads_cookie++;
GST_OBJECT_UNLOCK (element);
/* emit the PAD_REMOVED signal before unparenting and losing the last ref. */
g_signal_emit (element, gst_element_signals[PAD_REMOVED], 0, pad);
GST_TRACER_ELEMENT_REMOVE_PAD (element, pad);
gst_object_unparent (GST_OBJECT_CAST (pad));
return TRUE;
gst/gstpad.c (_gst_real_pad_fixate_accumulator): s/pointer/boxed/. Original commit message from CVS: 2004-02-05 Andy Wingo <wingo@pobox.com> * gst/gstpad.c (_gst_real_pad_fixate_accumulator): s/pointer/boxed/. * gst/gstmarshal.list (VOID:BOXED, BOXED:BOXED): New marshallers. * gst/gstpad.c (gst_real_pad_class_init): Use a BOXED:BOXED marshaller for ::fixate, and VOID:BOXED for ::caps-nego-failed, with the type=GST_TYPE_CAPS. This allows language bindings to know what kind of data they're dealing with. * gst/gstcaps.c (_gst_caps_value_init): GBoxed values initialize to NULL when g_value_init is called. GstCaps, which rolls its own type implementation, now does the same instead of allocating empty caps. (_gst_caps_initialize, _gst_caps_collect_value, _gst_caps_lcopy_value): Provide collect_value and lcopy_value type table methods. This allows G_VALUE_COLLECT to work. 2004-02-05 Andy Wingo <wingo@pobox.com> * configure.ac: * testsuite/Makefile.am (SUBDIRS): * testsuite/ghostpads/Makefile.am: * testsuite/ghostpads/ghostpads.c: A new test for ghost pads. * gst/gstpad.c (gst_pad_add_ghost_pad, gst_pad_remove_ghost_pad): These two routines are the only ones that set GST_GPAD_REALPAD(gpad), the ghost pad list, and the ghost pad's pad template. They should be made static, depending on ABI needs. (gst_real_pad_dispose): Handle the case of ghost pads without a parent. Assert after dealing with ghost pads that the ghost pad list is empty. (gst_ghost_pad_class_init): New property added, ::real-pad. Can be set after creation. (gst_ghost_pad_dispose): Set ::real-pad to NULL. (gst_ghost_pad_set_property, gst_ghost_pad_get_property): New functions. set_property will call add_ghost_pad/remove_ghost_pad as appropriate. (gst_ghost_pad_new): All the work is offloaded to g_object_new. * gst/gstelement.c (gst_element_add_pad): Handle ghost pads as well. (gst_element_add_ghost_pad): Remove code duplicated from _add_pad. (gst_element_remove_pad): Handle ghost pads as well. (gst_element_remove_ghost_pad): Deprecated (could be removed, depending on API-stability needs). 2004-02-05 Andy Wingo <wingo@pobox.com> * gst/gstbin.[ch]: (gst_bin_get_by_interface): GTypes are scalars, of course they're const
2004-02-05 13:51:26 +00:00
/* ERRORS */
not_our_pad:
{
2011-06-02 13:37:41 +00:00
/* locking order is element > pad */
GST_OBJECT_UNLOCK (pad);
GST_OBJECT_LOCK (element);
2011-06-02 13:37:41 +00:00
GST_OBJECT_LOCK (pad);
g_critical ("Padname %s:%s does not belong to element %s when removing",
GST_DEBUG_PAD_NAME (pad), GST_ELEMENT_NAME (element));
GST_OBJECT_UNLOCK (pad);
2011-06-02 13:37:41 +00:00
GST_OBJECT_UNLOCK (element);
return FALSE;
}
}
/**
* gst_element_no_more_pads:
* @element: a #GstElement
*
* Use this function to signal that the element does not expect any more pads
* to show up in the current pipeline. This function should be called whenever
* pads have been added by the element itself. Elements with #GST_PAD_SOMETIMES
* pad templates use this in combination with autopluggers to figure out that
* the element is done initializing its pads.
*
* This function emits the #GstElement::no-more-pads signal.
*
* MT safe.
*/
void
gst_element_no_more_pads (GstElement * element)
{
g_return_if_fail (GST_IS_ELEMENT (element));
g_signal_emit (element, gst_element_signals[NO_MORE_PADS], 0);
}
static gint
pad_compare_name (GstPad * pad1, const gchar * name)
{
gint result;
GST_OBJECT_LOCK (pad1);
result = strcmp (GST_PAD_NAME (pad1), name);
GST_OBJECT_UNLOCK (pad1);
return result;
}
/**
* gst_element_get_static_pad:
* @element: a #GstElement to find a static pad of.
* @name: the name of the static #GstPad to retrieve.
*
gst/gstpad.c (gst_pad_custom_new): Add a FIXME, this is a hacky way to do inheritance. Original commit message from CVS: 2004-02-10 Andy Wingo <wingo@pobox.com> * gst/gstpad.c (gst_pad_custom_new): Add a FIXME, this is a hacky way to do inheritance. (gst_pad_get_event_masks, gst_pad_get_event_masks_default) (gst_pad_get_query_types, gst_pad_get_query_types_default): Routine docs. (gst_pad_set_link_function, gst_pad_set_fixate_function) (gst_pad_set_getcaps_function): Doc from Dave's negotation random doc. (gst_pad_unlink, gst_pad_is_linked): Docs. (gst_pad_renegotiate): A brief description of capsnego. (gst_pad_try_set_caps): Document. (gst_pad_try_set_caps_nonfixed): Document. (gst_pad_can_link_filtered, gst_pad_link_filtered): Doc fixes. (gst_pad_set_parent): Deprecated (although not out of the API). (gst_pad_get_parent): Deprecated, although many plugins use this. (gst_pad_add_ghost_pad, gst_pad_remove_ghost_pad): Doc that these are private and will go away in 0.9. (gst_pad_perform_negotiate): Doc. (gst_pad_link_unnegotiate): I think this is meant to be static. (gst_pad_get_negotiated_caps, gst_pad_get_pad_template_caps) (gst_pad_template_get_caps_by_name, gst_pad_check_compatibility) (gst_pad_get_peer): Doc updates. (gst_pad_caps_change_notify): Doc. (gst_pad_alloc_buffer, gst_pad_push, gst_static_pad_template_get) (gst_ghost_pad_new): Doc fixes. * gst/gstobject.c (gst_object_get_parent, gst_object_unparent) (gst_object_check_uniqueness): * gst/gstelement.c (gst_element_add_pad) (gst_element_add_ghost_pad, gst_element_remove_pad) (gst_element_remove_ghost_pad, gst_element_get_pad) (gst_element_get_static_pad, gst_element_get_pad_list) (gst_element_class_get_pad_template_list) (gst_element_class_get_pad_template): Work on the docs. (gst_element_get_pad_template_list): Uses the class method. (gst_element_get_compatible_pad_template): Docs, and consolidate some test conditions. (gst_element_get_pad_from_template): New static function. (gst_element_request_compatible_pad): Docs, and work with non-request compatible templates. (gst_element_get_compatible_pad_filtered): Docs and remove redundant checks. (gst_element_get_compatible_pad, gst_element_link_pads_filtered) (gst_element_link_filtered, gst_element_link_many) (gst_element_link, gst_element_link_pads) (gst_element_unlink_many): Docs. 2004-02-05 Andy Wingo <wingo@pobox.com> * gst/gstpad.c (_gst_real_pad_fixate_accumulator): s/pointer/boxed/. * gst/gstmarshal.list (VOID:BOXED, BOXED:BOXED): New marshallers. * gst/gstpad.c (gst_real_pad_class_init): Use a BOXED:BOXED marshaller for ::fixate, and VOID:BOXED for ::caps-nego-failed, with the type=GST_TYPE_CAPS. This allows language bindings to know what kind of data they're dealing with. * gst/gstcaps.c (_gst_caps_value_init): GBoxed values initialize to NULL when g_value_init is called. GstCaps, which rolls its own type implementation, now does the same instead of allocating empty caps. (_gst_caps_initialize, _gst_caps_collect_value, _gst_caps_lcopy_value): Provide collect_value and lcopy_value type table methods. This allows G_VALUE_COLLECT to work. 2004-02-05 Andy Wingo <wingo@pobox.com> * configure.ac: * testsuite/Makefile.am (SUBDIRS): * testsuite/ghostpads/Makefile.am: * testsuite/ghostpads/ghostpads.c: A new test for ghost pads. * gst/gstpad.c (gst_pad_add_ghost_pad, gst_pad_remove_ghost_pad): These two routines are the only ones that set GST_GPAD_REALPAD(gpad), the ghost pad list, and the ghost pad's pad template. They should be made static, depending on ABI needs. (gst_real_pad_dispose): Handle the case of ghost pads without a parent. Assert after dealing with ghost pads that the ghost pad list is empty. (gst_ghost_pad_class_init): New property added, ::real-pad. Can be set after creation. (gst_ghost_pad_dispose): Set ::real-pad to NULL. (gst_ghost_pad_set_property, gst_ghost_pad_get_property): New functions. set_property will call add_ghost_pad/remove_ghost_pad as appropriate. (gst_ghost_pad_new): All the work is offloaded to g_object_new. * gst/gstelement.c (gst_element_add_pad): Handle ghost pads as well. (gst_element_add_ghost_pad): Remove code duplicated from _add_pad. (gst_element_remove_pad): Handle ghost pads as well. (gst_element_remove_ghost_pad): Deprecated (could be removed, depending on API-stability needs). 2004-02-05 Andy Wingo <wingo@pobox.com> * gst/gstbin.[ch]: (gst_bin_get_by_interface): GTypes are scalars, of course they're const
2004-02-11 13:26:04 +00:00
* Retrieves a pad from @element by name. This version only retrieves
* already-existing (i.e. 'static') pads.
*
* Returns: (transfer full) (nullable): the requested #GstPad if
* found, otherwise %NULL. unref after usage.
*
* MT safe.
*/
GstPad *
gst_element_get_static_pad (GstElement * element, const gchar * name)
{
GList *find;
GstPad *result = NULL;
g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
g_return_val_if_fail (name != NULL, NULL);
GST_OBJECT_LOCK (element);
find =
g_list_find_custom (element->pads, name, (GCompareFunc) pad_compare_name);
if (find) {
result = GST_PAD_CAST (find->data);
gst_object_ref (result);
}
if (result == NULL) {
GST_CAT_INFO (GST_CAT_ELEMENT_PADS, "no such pad '%s' in element \"%s\"",
name, GST_ELEMENT_NAME (element));
} else {
GST_CAT_INFO (GST_CAT_ELEMENT_PADS, "found pad %s:%s",
GST_ELEMENT_NAME (element), name);
}
GST_OBJECT_UNLOCK (element);
return result;
}
static gboolean
gst_element_is_valid_request_template_name (const gchar * templ_name,
const gchar * name)
{
gchar *endptr;
const gchar *templ_name_ptr, *name_ptr;
gboolean next_specifier;
guint templ_postfix_len = 0, name_postfix_len = 0;
g_return_val_if_fail (templ_name != NULL, FALSE);
g_return_val_if_fail (name != NULL, FALSE);
/* Is this the template name? */
if (strcmp (templ_name, name) == 0)
return TRUE;
/* otherwise check all the specifiers */
do {
/* Because of sanity checks in gst_pad_template_new(), we know that %s
* and %d and %u, occurring at the template_name */
templ_name_ptr = strchr (templ_name, '%');
/* check characters ahead of the specifier */
if (!templ_name_ptr || strlen (name) <= templ_name_ptr - templ_name
|| strncmp (templ_name, name, templ_name_ptr - templ_name) != 0) {
return FALSE;
}
/* %s is not allowed for multiple specifiers, just a single specifier can be
* accepted in gst_pad_template_new() and can not be mixed with other
* specifier '%u' and '%d' */
if (*(templ_name_ptr + 1) == 's' && g_strcmp0 (templ_name, name) == 0) {
return TRUE;
}
name_ptr = name + (templ_name_ptr - templ_name);
/* search next specifier, each of specifier should be separated by '_' */
templ_name = strchr (templ_name_ptr, '_');
name = strchr (name_ptr, '_');
/* don't match the number of specifiers */
if ((templ_name && !name) || (!templ_name && name))
return FALSE;
if (templ_name && name)
next_specifier = TRUE;
else
next_specifier = FALSE;
/* check characters followed by the specifier */
if (*(templ_name_ptr + 2) != '\0' && *(templ_name_ptr + 2) != '_') {
if (next_specifier) {
templ_postfix_len = templ_name - (templ_name_ptr + 2);
name_postfix_len = name - name_ptr;
} else {
templ_postfix_len = strlen (templ_name_ptr + 2);
name_postfix_len = strlen (name_ptr);
}
if (strncmp (templ_name_ptr + 2,
name_ptr + name_postfix_len - templ_postfix_len,
templ_postfix_len) != 0) {
return FALSE;
}
}
/* verify the specifier */
if (*(name_ptr) == '%') {
guint len;
len = (next_specifier) ? name - name_ptr : strlen (name_ptr);
if (strncmp (name_ptr, templ_name_ptr, len) != 0)
return FALSE;
} else {
const gchar *specifier;
gchar *target = NULL;
/* extract specifier when it has postfix characters */
if (name_postfix_len > templ_postfix_len) {
target = g_strndup (name_ptr, name_postfix_len - templ_postfix_len);
}
specifier = target ? target : name_ptr;
if (*(templ_name_ptr + 1) == 'd') {
gint64 tmp;
/* it's an int */
tmp = g_ascii_strtoll (specifier, &endptr, 10);
if (tmp < G_MININT || tmp > G_MAXINT || (*endptr != '\0'
&& *endptr != '_'))
return FALSE;
} else if (*(templ_name_ptr + 1) == 'u') {
guint64 tmp;
/* it's an int */
tmp = g_ascii_strtoull (specifier, &endptr, 10);
if (tmp > G_MAXUINT || (*endptr != '\0' && *endptr != '_'))
return FALSE;
}
g_free (target);
}
/* otherwise we increment these from NULL to 1 */
if (next_specifier) {
templ_name++;
name++;
}
} while (next_specifier);
return TRUE;
}
static GstPad *
_gst_element_request_pad (GstElement * element, GstPadTemplate * templ,
const gchar * name, const GstCaps * caps)
{
GstPad *newpad = NULL;
GstElementClass *oclass;
oclass = GST_ELEMENT_GET_CLASS (element);
#ifndef G_DISABLE_CHECKS
/* Some sanity checking here */
if (name) {
GstPad *pad;
g_return_val_if_fail (gst_element_is_valid_request_template_name
(templ->name_template, name), NULL);
pad = gst_element_get_static_pad (element, name);
if (pad) {
gst_object_unref (pad);
/* FIXME 2.0: Change this to g_return_val_if_fail() */
g_critical ("Element %s already has a pad named %s, the behaviour of "
" gst_element_get_request_pad() for existing pads is undefined!",
GST_ELEMENT_NAME (element), name);
}
}
#endif
if (oclass->request_new_pad)
newpad = (oclass->request_new_pad) (element, templ, name, caps);
if (newpad)
gst_object_ref (newpad);
return newpad;
}
/**
* gst_element_get_request_pad:
* @element: a #GstElement to find a request pad of.
* @name: the name of the request #GstPad to retrieve.
*
2011-09-07 11:50:08 +00:00
* Retrieves a pad from the element by name (e.g. "src_\%d"). This version only
* retrieves request pads. The pad should be released with
* gst_element_release_request_pad().
*
* This method is slower than manually getting the pad template and calling
* gst_element_request_pad() if the pads should have a specific name (e.g.
* @name is "src_1" instead of "src_\%u").
*
* Returns: (transfer full) (nullable): requested #GstPad if found,
* otherwise %NULL. Release after usage.
*/
GstPad *
gst_element_get_request_pad (GstElement * element, const gchar * name)
{
GstPadTemplate *templ = NULL;
GstPad *pad;
const gchar *req_name = NULL;
gboolean templ_found = FALSE;
GList *list;
GstElementClass *class;
g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
g_return_val_if_fail (name != NULL, NULL);
class = GST_ELEMENT_GET_CLASS (element);
templ = gst_element_class_get_request_pad_template (class, name);
if (templ) {
req_name = strstr (name, "%") ? NULL : name;
templ_found = TRUE;
} else {
/* there is no % in the name, try to find a matching template */
list = class->padtemplates;
while (!templ_found && list) {
templ = (GstPadTemplate *) list->data;
if (templ->presence == GST_PAD_REQUEST) {
GST_CAT_DEBUG (GST_CAT_PADS, "comparing %s to %s", name,
templ->name_template);
if (gst_element_is_valid_request_template_name (templ->name_template,
name)) {
templ_found = TRUE;
req_name = name;
break;
}
}
list = list->next;
}
}
if (!templ_found)
return NULL;
pad = _gst_element_request_pad (element, templ, req_name, NULL);
return pad;
}
/**
* gst_element_request_pad: (virtual request_new_pad)
* @element: a #GstElement to find a request pad of.
* @templ: a #GstPadTemplate of which we want a pad of.
* @name: (transfer none) (allow-none): the name of the request #GstPad
* to retrieve. Can be %NULL.
* @caps: (transfer none) (allow-none): the caps of the pad we want to
* request. Can be %NULL.
*
* Retrieves a request pad from the element according to the provided template.
* Pad templates can be looked up using
* gst_element_factory_get_static_pad_templates().
*
* The pad should be released with gst_element_release_request_pad().
*
* Returns: (transfer full) (nullable): requested #GstPad if found,
* otherwise %NULL. Release after usage.
*/
GstPad *
gst_element_request_pad (GstElement * element,
GstPadTemplate * templ, const gchar * name, const GstCaps * caps)
{
g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
g_return_val_if_fail (templ != NULL, NULL);
g_return_val_if_fail (templ->presence == GST_PAD_REQUEST, NULL);
return _gst_element_request_pad (element, templ, name, caps);
}
static GstIterator *
gst_element_iterate_pad_list (GstElement * element, GList ** padlist)
{
GstIterator *result;
GST_OBJECT_LOCK (element);
result = gst_iterator_new_list (GST_TYPE_PAD,
GST_OBJECT_GET_LOCK (element),
&element->pads_cookie, padlist, (GObject *) element, NULL);
GST_OBJECT_UNLOCK (element);
return result;
}
/**
* gst_element_iterate_pads:
* @element: a #GstElement to iterate pads of.
*
* Retrieves an iterator of @element's pads. The iterator should
* be freed after usage. Also more specialized iterators exists such as
* gst_element_iterate_src_pads() or gst_element_iterate_sink_pads().
*
* The order of pads returned by the iterator will be the order in which
* the pads were added to the element.
*
* Returns: (transfer full): the #GstIterator of #GstPad.
*
* MT safe.
*/
GstIterator *
gst_element_iterate_pads (GstElement * element)
gst/base/gsttypefindhelper.c (gst_type_find_helper): Unref any remaining buffer. Original commit message from CVS: 2005-06-27 Andy Wingo <wingo@pobox.com> * gst/base/gsttypefindhelper.c (gst_type_find_helper): Unref any remaining buffer. * gst/gsttrace.c (gst_alloc_trace_list_sorted): New helper, returns a sorted copy of the trace list. (gst_alloc_trace_print_live): New API, only prints traces with live objects. Sort the list. (gst_alloc_trace_print_all): Sort the list. (gst_alloc_trace_print): Align columns. * gst/elements/gstttypefindelement.c: * gst/elements/gsttee.c: * gst/base/gstbasesrc.c: * gst/base/gstbasesink.c: * gst/base/gstbasetransform.c: * gst/gstqueue.c: Adapt for pad activation changes. * gst/gstpipeline.c (gst_pipeline_init): Unref after parenting sched. (gst_pipeline_dispose): Drop ref on sched. * gst/gstpad.c (gst_pad_init): Set the default activate func. (gst_pad_activate_default): Push mode by default. (pre_activate_switch, post_activate_switch): New stubs, things to do before and after switching activation modes on pads. (gst_pad_set_active): Take a boolean and not a mode, dispatch to the pad's activate function to choose which mode to activate. Shortcut on deactivation and call the right function directly. (gst_pad_activate_pull): New API, (de)activates a pad in pull mode. (gst_pad_activate_push): New API, same for push mode. (gst_pad_set_activate_function) (gst_pad_set_activatepull_function) (gst_pad_set_activatepush_function): Setters for new API. * gst/gstminiobject.c (gst_mini_object_new, gst_mini_object_free): Trace all miniobjects. (gst_mini_object_make_writable): Unref the arg if we copy, like gst_caps_make_writable. * gst/gstmessage.c (_gst_message_initialize): No trace init. * gst/gstghostpad.c (gst_proxy_pad_do_activate) (gst_proxy_pad_do_activatepull, gst_proxy_pad_do_activatepush): Adapt for new pad API. * gst/gstevent.c (_gst_event_initialize): Don't initialize trace. * gst/gstelement.h: * gst/gstelement.c (gst_element_iterate_src_pads) (gst_element_iterate_sink_pads): New API functions. * gst/gstelement.c (iterator_fold_with_resync): New utility, should fold into gstiterator.c in some form. (gst_element_pads_activate): Simplified via use of fold and delegation of decisions to gstpad->activate. * gst/gstbus.c (gst_bus_source_finalize): Set the bus to NULL, help in debugging. * gst/gstbuffer.c (_gst_buffer_initialize): Ref the buffer type class once in init, like gstmessage. Didn't run into this issue but it seems correct. Don't initialize a trace, gstminiobject does that. * check/pipelines/simple_launch_lines.c (test_stop_from_app): New test, runs fakesrc ! fakesink, stopping on ::handoff via a message to the bus. (assert_live_count): New util function, uses alloc traces to check cleanup. * check/gst/gstghostpad.c (test_ghost_pads): More refcount checks. To be modified when unlink drops the internal pad.
2005-06-27 18:35:05 +00:00
{
g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
return gst_element_iterate_pad_list (element, &element->pads);
gst/base/gsttypefindhelper.c (gst_type_find_helper): Unref any remaining buffer. Original commit message from CVS: 2005-06-27 Andy Wingo <wingo@pobox.com> * gst/base/gsttypefindhelper.c (gst_type_find_helper): Unref any remaining buffer. * gst/gsttrace.c (gst_alloc_trace_list_sorted): New helper, returns a sorted copy of the trace list. (gst_alloc_trace_print_live): New API, only prints traces with live objects. Sort the list. (gst_alloc_trace_print_all): Sort the list. (gst_alloc_trace_print): Align columns. * gst/elements/gstttypefindelement.c: * gst/elements/gsttee.c: * gst/base/gstbasesrc.c: * gst/base/gstbasesink.c: * gst/base/gstbasetransform.c: * gst/gstqueue.c: Adapt for pad activation changes. * gst/gstpipeline.c (gst_pipeline_init): Unref after parenting sched. (gst_pipeline_dispose): Drop ref on sched. * gst/gstpad.c (gst_pad_init): Set the default activate func. (gst_pad_activate_default): Push mode by default. (pre_activate_switch, post_activate_switch): New stubs, things to do before and after switching activation modes on pads. (gst_pad_set_active): Take a boolean and not a mode, dispatch to the pad's activate function to choose which mode to activate. Shortcut on deactivation and call the right function directly. (gst_pad_activate_pull): New API, (de)activates a pad in pull mode. (gst_pad_activate_push): New API, same for push mode. (gst_pad_set_activate_function) (gst_pad_set_activatepull_function) (gst_pad_set_activatepush_function): Setters for new API. * gst/gstminiobject.c (gst_mini_object_new, gst_mini_object_free): Trace all miniobjects. (gst_mini_object_make_writable): Unref the arg if we copy, like gst_caps_make_writable. * gst/gstmessage.c (_gst_message_initialize): No trace init. * gst/gstghostpad.c (gst_proxy_pad_do_activate) (gst_proxy_pad_do_activatepull, gst_proxy_pad_do_activatepush): Adapt for new pad API. * gst/gstevent.c (_gst_event_initialize): Don't initialize trace. * gst/gstelement.h: * gst/gstelement.c (gst_element_iterate_src_pads) (gst_element_iterate_sink_pads): New API functions. * gst/gstelement.c (iterator_fold_with_resync): New utility, should fold into gstiterator.c in some form. (gst_element_pads_activate): Simplified via use of fold and delegation of decisions to gstpad->activate. * gst/gstbus.c (gst_bus_source_finalize): Set the bus to NULL, help in debugging. * gst/gstbuffer.c (_gst_buffer_initialize): Ref the buffer type class once in init, like gstmessage. Didn't run into this issue but it seems correct. Don't initialize a trace, gstminiobject does that. * check/pipelines/simple_launch_lines.c (test_stop_from_app): New test, runs fakesrc ! fakesink, stopping on ::handoff via a message to the bus. (assert_live_count): New util function, uses alloc traces to check cleanup. * check/gst/gstghostpad.c (test_ghost_pads): More refcount checks. To be modified when unlink drops the internal pad.
2005-06-27 18:35:05 +00:00
}
/**
* gst_element_iterate_src_pads:
* @element: a #GstElement.
*
* Retrieves an iterator of @element's source pads.
gst/base/gsttypefindhelper.c (gst_type_find_helper): Unref any remaining buffer. Original commit message from CVS: 2005-06-27 Andy Wingo <wingo@pobox.com> * gst/base/gsttypefindhelper.c (gst_type_find_helper): Unref any remaining buffer. * gst/gsttrace.c (gst_alloc_trace_list_sorted): New helper, returns a sorted copy of the trace list. (gst_alloc_trace_print_live): New API, only prints traces with live objects. Sort the list. (gst_alloc_trace_print_all): Sort the list. (gst_alloc_trace_print): Align columns. * gst/elements/gstttypefindelement.c: * gst/elements/gsttee.c: * gst/base/gstbasesrc.c: * gst/base/gstbasesink.c: * gst/base/gstbasetransform.c: * gst/gstqueue.c: Adapt for pad activation changes. * gst/gstpipeline.c (gst_pipeline_init): Unref after parenting sched. (gst_pipeline_dispose): Drop ref on sched. * gst/gstpad.c (gst_pad_init): Set the default activate func. (gst_pad_activate_default): Push mode by default. (pre_activate_switch, post_activate_switch): New stubs, things to do before and after switching activation modes on pads. (gst_pad_set_active): Take a boolean and not a mode, dispatch to the pad's activate function to choose which mode to activate. Shortcut on deactivation and call the right function directly. (gst_pad_activate_pull): New API, (de)activates a pad in pull mode. (gst_pad_activate_push): New API, same for push mode. (gst_pad_set_activate_function) (gst_pad_set_activatepull_function) (gst_pad_set_activatepush_function): Setters for new API. * gst/gstminiobject.c (gst_mini_object_new, gst_mini_object_free): Trace all miniobjects. (gst_mini_object_make_writable): Unref the arg if we copy, like gst_caps_make_writable. * gst/gstmessage.c (_gst_message_initialize): No trace init. * gst/gstghostpad.c (gst_proxy_pad_do_activate) (gst_proxy_pad_do_activatepull, gst_proxy_pad_do_activatepush): Adapt for new pad API. * gst/gstevent.c (_gst_event_initialize): Don't initialize trace. * gst/gstelement.h: * gst/gstelement.c (gst_element_iterate_src_pads) (gst_element_iterate_sink_pads): New API functions. * gst/gstelement.c (iterator_fold_with_resync): New utility, should fold into gstiterator.c in some form. (gst_element_pads_activate): Simplified via use of fold and delegation of decisions to gstpad->activate. * gst/gstbus.c (gst_bus_source_finalize): Set the bus to NULL, help in debugging. * gst/gstbuffer.c (_gst_buffer_initialize): Ref the buffer type class once in init, like gstmessage. Didn't run into this issue but it seems correct. Don't initialize a trace, gstminiobject does that. * check/pipelines/simple_launch_lines.c (test_stop_from_app): New test, runs fakesrc ! fakesink, stopping on ::handoff via a message to the bus. (assert_live_count): New util function, uses alloc traces to check cleanup. * check/gst/gstghostpad.c (test_ghost_pads): More refcount checks. To be modified when unlink drops the internal pad.
2005-06-27 18:35:05 +00:00
*
* The order of pads returned by the iterator will be the order in which
* the pads were added to the element.
*
* Returns: (transfer full): the #GstIterator of #GstPad.
gst/base/gsttypefindhelper.c (gst_type_find_helper): Unref any remaining buffer. Original commit message from CVS: 2005-06-27 Andy Wingo <wingo@pobox.com> * gst/base/gsttypefindhelper.c (gst_type_find_helper): Unref any remaining buffer. * gst/gsttrace.c (gst_alloc_trace_list_sorted): New helper, returns a sorted copy of the trace list. (gst_alloc_trace_print_live): New API, only prints traces with live objects. Sort the list. (gst_alloc_trace_print_all): Sort the list. (gst_alloc_trace_print): Align columns. * gst/elements/gstttypefindelement.c: * gst/elements/gsttee.c: * gst/base/gstbasesrc.c: * gst/base/gstbasesink.c: * gst/base/gstbasetransform.c: * gst/gstqueue.c: Adapt for pad activation changes. * gst/gstpipeline.c (gst_pipeline_init): Unref after parenting sched. (gst_pipeline_dispose): Drop ref on sched. * gst/gstpad.c (gst_pad_init): Set the default activate func. (gst_pad_activate_default): Push mode by default. (pre_activate_switch, post_activate_switch): New stubs, things to do before and after switching activation modes on pads. (gst_pad_set_active): Take a boolean and not a mode, dispatch to the pad's activate function to choose which mode to activate. Shortcut on deactivation and call the right function directly. (gst_pad_activate_pull): New API, (de)activates a pad in pull mode. (gst_pad_activate_push): New API, same for push mode. (gst_pad_set_activate_function) (gst_pad_set_activatepull_function) (gst_pad_set_activatepush_function): Setters for new API. * gst/gstminiobject.c (gst_mini_object_new, gst_mini_object_free): Trace all miniobjects. (gst_mini_object_make_writable): Unref the arg if we copy, like gst_caps_make_writable. * gst/gstmessage.c (_gst_message_initialize): No trace init. * gst/gstghostpad.c (gst_proxy_pad_do_activate) (gst_proxy_pad_do_activatepull, gst_proxy_pad_do_activatepush): Adapt for new pad API. * gst/gstevent.c (_gst_event_initialize): Don't initialize trace. * gst/gstelement.h: * gst/gstelement.c (gst_element_iterate_src_pads) (gst_element_iterate_sink_pads): New API functions. * gst/gstelement.c (iterator_fold_with_resync): New utility, should fold into gstiterator.c in some form. (gst_element_pads_activate): Simplified via use of fold and delegation of decisions to gstpad->activate. * gst/gstbus.c (gst_bus_source_finalize): Set the bus to NULL, help in debugging. * gst/gstbuffer.c (_gst_buffer_initialize): Ref the buffer type class once in init, like gstmessage. Didn't run into this issue but it seems correct. Don't initialize a trace, gstminiobject does that. * check/pipelines/simple_launch_lines.c (test_stop_from_app): New test, runs fakesrc ! fakesink, stopping on ::handoff via a message to the bus. (assert_live_count): New util function, uses alloc traces to check cleanup. * check/gst/gstghostpad.c (test_ghost_pads): More refcount checks. To be modified when unlink drops the internal pad.
2005-06-27 18:35:05 +00:00
*
* MT safe.
*/
GstIterator *
gst_element_iterate_src_pads (GstElement * element)
{
g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
return gst_element_iterate_pad_list (element, &element->srcpads);
gst/base/gsttypefindhelper.c (gst_type_find_helper): Unref any remaining buffer. Original commit message from CVS: 2005-06-27 Andy Wingo <wingo@pobox.com> * gst/base/gsttypefindhelper.c (gst_type_find_helper): Unref any remaining buffer. * gst/gsttrace.c (gst_alloc_trace_list_sorted): New helper, returns a sorted copy of the trace list. (gst_alloc_trace_print_live): New API, only prints traces with live objects. Sort the list. (gst_alloc_trace_print_all): Sort the list. (gst_alloc_trace_print): Align columns. * gst/elements/gstttypefindelement.c: * gst/elements/gsttee.c: * gst/base/gstbasesrc.c: * gst/base/gstbasesink.c: * gst/base/gstbasetransform.c: * gst/gstqueue.c: Adapt for pad activation changes. * gst/gstpipeline.c (gst_pipeline_init): Unref after parenting sched. (gst_pipeline_dispose): Drop ref on sched. * gst/gstpad.c (gst_pad_init): Set the default activate func. (gst_pad_activate_default): Push mode by default. (pre_activate_switch, post_activate_switch): New stubs, things to do before and after switching activation modes on pads. (gst_pad_set_active): Take a boolean and not a mode, dispatch to the pad's activate function to choose which mode to activate. Shortcut on deactivation and call the right function directly. (gst_pad_activate_pull): New API, (de)activates a pad in pull mode. (gst_pad_activate_push): New API, same for push mode. (gst_pad_set_activate_function) (gst_pad_set_activatepull_function) (gst_pad_set_activatepush_function): Setters for new API. * gst/gstminiobject.c (gst_mini_object_new, gst_mini_object_free): Trace all miniobjects. (gst_mini_object_make_writable): Unref the arg if we copy, like gst_caps_make_writable. * gst/gstmessage.c (_gst_message_initialize): No trace init. * gst/gstghostpad.c (gst_proxy_pad_do_activate) (gst_proxy_pad_do_activatepull, gst_proxy_pad_do_activatepush): Adapt for new pad API. * gst/gstevent.c (_gst_event_initialize): Don't initialize trace. * gst/gstelement.h: * gst/gstelement.c (gst_element_iterate_src_pads) (gst_element_iterate_sink_pads): New API functions. * gst/gstelement.c (iterator_fold_with_resync): New utility, should fold into gstiterator.c in some form. (gst_element_pads_activate): Simplified via use of fold and delegation of decisions to gstpad->activate. * gst/gstbus.c (gst_bus_source_finalize): Set the bus to NULL, help in debugging. * gst/gstbuffer.c (_gst_buffer_initialize): Ref the buffer type class once in init, like gstmessage. Didn't run into this issue but it seems correct. Don't initialize a trace, gstminiobject does that. * check/pipelines/simple_launch_lines.c (test_stop_from_app): New test, runs fakesrc ! fakesink, stopping on ::handoff via a message to the bus. (assert_live_count): New util function, uses alloc traces to check cleanup. * check/gst/gstghostpad.c (test_ghost_pads): More refcount checks. To be modified when unlink drops the internal pad.
2005-06-27 18:35:05 +00:00
}
/**
* gst_element_iterate_sink_pads:
* @element: a #GstElement.
*
* Retrieves an iterator of @element's sink pads.
gst/base/gsttypefindhelper.c (gst_type_find_helper): Unref any remaining buffer. Original commit message from CVS: 2005-06-27 Andy Wingo <wingo@pobox.com> * gst/base/gsttypefindhelper.c (gst_type_find_helper): Unref any remaining buffer. * gst/gsttrace.c (gst_alloc_trace_list_sorted): New helper, returns a sorted copy of the trace list. (gst_alloc_trace_print_live): New API, only prints traces with live objects. Sort the list. (gst_alloc_trace_print_all): Sort the list. (gst_alloc_trace_print): Align columns. * gst/elements/gstttypefindelement.c: * gst/elements/gsttee.c: * gst/base/gstbasesrc.c: * gst/base/gstbasesink.c: * gst/base/gstbasetransform.c: * gst/gstqueue.c: Adapt for pad activation changes. * gst/gstpipeline.c (gst_pipeline_init): Unref after parenting sched. (gst_pipeline_dispose): Drop ref on sched. * gst/gstpad.c (gst_pad_init): Set the default activate func. (gst_pad_activate_default): Push mode by default. (pre_activate_switch, post_activate_switch): New stubs, things to do before and after switching activation modes on pads. (gst_pad_set_active): Take a boolean and not a mode, dispatch to the pad's activate function to choose which mode to activate. Shortcut on deactivation and call the right function directly. (gst_pad_activate_pull): New API, (de)activates a pad in pull mode. (gst_pad_activate_push): New API, same for push mode. (gst_pad_set_activate_function) (gst_pad_set_activatepull_function) (gst_pad_set_activatepush_function): Setters for new API. * gst/gstminiobject.c (gst_mini_object_new, gst_mini_object_free): Trace all miniobjects. (gst_mini_object_make_writable): Unref the arg if we copy, like gst_caps_make_writable. * gst/gstmessage.c (_gst_message_initialize): No trace init. * gst/gstghostpad.c (gst_proxy_pad_do_activate) (gst_proxy_pad_do_activatepull, gst_proxy_pad_do_activatepush): Adapt for new pad API. * gst/gstevent.c (_gst_event_initialize): Don't initialize trace. * gst/gstelement.h: * gst/gstelement.c (gst_element_iterate_src_pads) (gst_element_iterate_sink_pads): New API functions. * gst/gstelement.c (iterator_fold_with_resync): New utility, should fold into gstiterator.c in some form. (gst_element_pads_activate): Simplified via use of fold and delegation of decisions to gstpad->activate. * gst/gstbus.c (gst_bus_source_finalize): Set the bus to NULL, help in debugging. * gst/gstbuffer.c (_gst_buffer_initialize): Ref the buffer type class once in init, like gstmessage. Didn't run into this issue but it seems correct. Don't initialize a trace, gstminiobject does that. * check/pipelines/simple_launch_lines.c (test_stop_from_app): New test, runs fakesrc ! fakesink, stopping on ::handoff via a message to the bus. (assert_live_count): New util function, uses alloc traces to check cleanup. * check/gst/gstghostpad.c (test_ghost_pads): More refcount checks. To be modified when unlink drops the internal pad.
2005-06-27 18:35:05 +00:00
*
* The order of pads returned by the iterator will be the order in which
* the pads were added to the element.
*
* Returns: (transfer full): the #GstIterator of #GstPad.
gst/base/gsttypefindhelper.c (gst_type_find_helper): Unref any remaining buffer. Original commit message from CVS: 2005-06-27 Andy Wingo <wingo@pobox.com> * gst/base/gsttypefindhelper.c (gst_type_find_helper): Unref any remaining buffer. * gst/gsttrace.c (gst_alloc_trace_list_sorted): New helper, returns a sorted copy of the trace list. (gst_alloc_trace_print_live): New API, only prints traces with live objects. Sort the list. (gst_alloc_trace_print_all): Sort the list. (gst_alloc_trace_print): Align columns. * gst/elements/gstttypefindelement.c: * gst/elements/gsttee.c: * gst/base/gstbasesrc.c: * gst/base/gstbasesink.c: * gst/base/gstbasetransform.c: * gst/gstqueue.c: Adapt for pad activation changes. * gst/gstpipeline.c (gst_pipeline_init): Unref after parenting sched. (gst_pipeline_dispose): Drop ref on sched. * gst/gstpad.c (gst_pad_init): Set the default activate func. (gst_pad_activate_default): Push mode by default. (pre_activate_switch, post_activate_switch): New stubs, things to do before and after switching activation modes on pads. (gst_pad_set_active): Take a boolean and not a mode, dispatch to the pad's activate function to choose which mode to activate. Shortcut on deactivation and call the right function directly. (gst_pad_activate_pull): New API, (de)activates a pad in pull mode. (gst_pad_activate_push): New API, same for push mode. (gst_pad_set_activate_function) (gst_pad_set_activatepull_function) (gst_pad_set_activatepush_function): Setters for new API. * gst/gstminiobject.c (gst_mini_object_new, gst_mini_object_free): Trace all miniobjects. (gst_mini_object_make_writable): Unref the arg if we copy, like gst_caps_make_writable. * gst/gstmessage.c (_gst_message_initialize): No trace init. * gst/gstghostpad.c (gst_proxy_pad_do_activate) (gst_proxy_pad_do_activatepull, gst_proxy_pad_do_activatepush): Adapt for new pad API. * gst/gstevent.c (_gst_event_initialize): Don't initialize trace. * gst/gstelement.h: * gst/gstelement.c (gst_element_iterate_src_pads) (gst_element_iterate_sink_pads): New API functions. * gst/gstelement.c (iterator_fold_with_resync): New utility, should fold into gstiterator.c in some form. (gst_element_pads_activate): Simplified via use of fold and delegation of decisions to gstpad->activate. * gst/gstbus.c (gst_bus_source_finalize): Set the bus to NULL, help in debugging. * gst/gstbuffer.c (_gst_buffer_initialize): Ref the buffer type class once in init, like gstmessage. Didn't run into this issue but it seems correct. Don't initialize a trace, gstminiobject does that. * check/pipelines/simple_launch_lines.c (test_stop_from_app): New test, runs fakesrc ! fakesink, stopping on ::handoff via a message to the bus. (assert_live_count): New util function, uses alloc traces to check cleanup. * check/gst/gstghostpad.c (test_ghost_pads): More refcount checks. To be modified when unlink drops the internal pad.
2005-06-27 18:35:05 +00:00
*
* MT safe.
*/
GstIterator *
gst_element_iterate_sink_pads (GstElement * element)
{
g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
return gst_element_iterate_pad_list (element, &element->sinkpads);
gst/base/gsttypefindhelper.c (gst_type_find_helper): Unref any remaining buffer. Original commit message from CVS: 2005-06-27 Andy Wingo <wingo@pobox.com> * gst/base/gsttypefindhelper.c (gst_type_find_helper): Unref any remaining buffer. * gst/gsttrace.c (gst_alloc_trace_list_sorted): New helper, returns a sorted copy of the trace list. (gst_alloc_trace_print_live): New API, only prints traces with live objects. Sort the list. (gst_alloc_trace_print_all): Sort the list. (gst_alloc_trace_print): Align columns. * gst/elements/gstttypefindelement.c: * gst/elements/gsttee.c: * gst/base/gstbasesrc.c: * gst/base/gstbasesink.c: * gst/base/gstbasetransform.c: * gst/gstqueue.c: Adapt for pad activation changes. * gst/gstpipeline.c (gst_pipeline_init): Unref after parenting sched. (gst_pipeline_dispose): Drop ref on sched. * gst/gstpad.c (gst_pad_init): Set the default activate func. (gst_pad_activate_default): Push mode by default. (pre_activate_switch, post_activate_switch): New stubs, things to do before and after switching activation modes on pads. (gst_pad_set_active): Take a boolean and not a mode, dispatch to the pad's activate function to choose which mode to activate. Shortcut on deactivation and call the right function directly. (gst_pad_activate_pull): New API, (de)activates a pad in pull mode. (gst_pad_activate_push): New API, same for push mode. (gst_pad_set_activate_function) (gst_pad_set_activatepull_function) (gst_pad_set_activatepush_function): Setters for new API. * gst/gstminiobject.c (gst_mini_object_new, gst_mini_object_free): Trace all miniobjects. (gst_mini_object_make_writable): Unref the arg if we copy, like gst_caps_make_writable. * gst/gstmessage.c (_gst_message_initialize): No trace init. * gst/gstghostpad.c (gst_proxy_pad_do_activate) (gst_proxy_pad_do_activatepull, gst_proxy_pad_do_activatepush): Adapt for new pad API. * gst/gstevent.c (_gst_event_initialize): Don't initialize trace. * gst/gstelement.h: * gst/gstelement.c (gst_element_iterate_src_pads) (gst_element_iterate_sink_pads): New API functions. * gst/gstelement.c (iterator_fold_with_resync): New utility, should fold into gstiterator.c in some form. (gst_element_pads_activate): Simplified via use of fold and delegation of decisions to gstpad->activate. * gst/gstbus.c (gst_bus_source_finalize): Set the bus to NULL, help in debugging. * gst/gstbuffer.c (_gst_buffer_initialize): Ref the buffer type class once in init, like gstmessage. Didn't run into this issue but it seems correct. Don't initialize a trace, gstminiobject does that. * check/pipelines/simple_launch_lines.c (test_stop_from_app): New test, runs fakesrc ! fakesink, stopping on ::handoff via a message to the bus. (assert_live_count): New util function, uses alloc traces to check cleanup. * check/gst/gstghostpad.c (test_ghost_pads): More refcount checks. To be modified when unlink drops the internal pad.
2005-06-27 18:35:05 +00:00
}
static gboolean
gst_element_do_foreach_pad (GstElement * element,
GstElementForeachPadFunc func, gpointer user_data,
GList ** p_pads, guint16 * p_npads)
{
gboolean ret = TRUE;
GstPad **pads;
guint n_pads, i;
GList *l;
g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
g_return_val_if_fail (func != NULL, FALSE);
GST_OBJECT_LOCK (element);
n_pads = *p_npads;
pads = g_newa (GstPad *, n_pads + 1);
for (l = *p_pads, i = 0; l != NULL; l = l->next) {
g_assert (i < n_pads);
pads[i++] = gst_object_ref (l->data);
}
GST_OBJECT_UNLOCK (element);
if (n_pads == 0)
return FALSE;
for (i = 0; i < n_pads; ++i) {
ret = func (element, pads[i], user_data);
if (!ret)
break;
}
for (i = 0; i < n_pads; ++i)
gst_object_unref (pads[i]);
return ret;
}
/**
* gst_element_foreach_sink_pad:
* @element: a #GstElement to iterate sink pads of
* @func: (scope call): function to call for each sink pad
* @user_data: (closure): user data passed to @func
*
* Call @func with @user_data for each of @element's sink pads. @func will be
* called exactly once for each sink pad that exists at the time of this call,
* unless one of the calls to @func returns %FALSE in which case we will stop
* iterating pads and return early. If new sink pads are added or sink pads
* are removed while the sink pads are being iterated, this will not be taken
* into account until next time this function is used.
*
* Returns: %FALSE if @element had no sink pads or if one of the calls to @func
* returned %FALSE.
*
* Since: 1.14
*/
gboolean
gst_element_foreach_sink_pad (GstElement * element,
GstElementForeachPadFunc func, gpointer user_data)
{
return gst_element_do_foreach_pad (element, func, user_data,
&element->sinkpads, &element->numsinkpads);
}
/**
* gst_element_foreach_src_pad:
* @element: a #GstElement to iterate source pads of
* @func: (scope call): function to call for each source pad
* @user_data: (closure): user data passed to @func
*
* Call @func with @user_data for each of @element's source pads. @func will be
* called exactly once for each source pad that exists at the time of this call,
* unless one of the calls to @func returns %FALSE in which case we will stop
* iterating pads and return early. If new source pads are added or source pads
* are removed while the source pads are being iterated, this will not be taken
* into account until next time this function is used.
*
* Returns: %FALSE if @element had no source pads or if one of the calls
* to @func returned %FALSE.
*
* Since: 1.14
*/
gboolean
gst_element_foreach_src_pad (GstElement * element,
GstElementForeachPadFunc func, gpointer user_data)
{
return gst_element_do_foreach_pad (element, func, user_data,
&element->srcpads, &element->numsrcpads);
}
/**
* gst_element_foreach_pad:
* @element: a #GstElement to iterate pads of
* @func: (scope call): function to call for each pad
* @user_data: (closure): user data passed to @func
*
* Call @func with @user_data for each of @element's pads. @func will be called
* exactly once for each pad that exists at the time of this call, unless
* one of the calls to @func returns %FALSE in which case we will stop
* iterating pads and return early. If new pads are added or pads are removed
* while pads are being iterated, this will not be taken into account until
* next time this function is used.
*
* Returns: %FALSE if @element had no pads or if one of the calls to @func
* returned %FALSE.
*
* Since: 1.14
*/
gboolean
gst_element_foreach_pad (GstElement * element, GstElementForeachPadFunc func,
gpointer user_data)
{
return gst_element_do_foreach_pad (element, func, user_data,
&element->pads, &element->numpads);
}
/**
* gst_element_class_add_pad_template:
* @klass: the #GstElementClass to add the pad template to.
* @templ: (transfer floating): a #GstPadTemplate to add to the element class.
*
* Adds a padtemplate to an element class. This is mainly used in the _class_init
* functions of classes. If a pad template with the same name as an already
* existing one is added the old one is replaced by the new one.
*
* @templ's reference count will be incremented, and any floating
* reference will be removed (see gst_object_ref_sink())
*
*/
void
gst_element_class_add_pad_template (GstElementClass * klass,
GstPadTemplate * templ)
{
GList *template_list = klass->padtemplates;
g_return_if_fail (GST_IS_ELEMENT_CLASS (klass));
g_return_if_fail (GST_IS_PAD_TEMPLATE (templ));
/* If we already have a pad template with the same name replace the
* old one. */
while (template_list) {
GstPadTemplate *padtempl = (GstPadTemplate *) template_list->data;
/* Found pad with the same name, replace and return */
if (strcmp (templ->name_template, padtempl->name_template) == 0) {
gst_object_ref_sink (padtempl);
gst_object_unref (padtempl);
template_list->data = templ;
return;
}
template_list = g_list_next (template_list);
}
/* Take ownership of the floating ref */
gst_object_ref_sink (templ);
klass->padtemplates = g_list_append (klass->padtemplates, templ);
klass->numpadtemplates++;
}
/**
* gst_element_class_add_static_pad_template:
* @klass: the #GstElementClass to add the pad template to.
* @static_templ: #GstStaticPadTemplate to add as pad template to the element class.
*
* Adds a pad template to an element class based on the static pad template
* @templ. This is mainly used in the _class_init functions of element
* implementations. If a pad template with the same name already exists,
* the old one is replaced by the new one.
*
* Since: 1.8
*/
void
gst_element_class_add_static_pad_template (GstElementClass * klass,
GstStaticPadTemplate * static_templ)
{
gst_element_class_add_pad_template (klass,
gst_static_pad_template_get (static_templ));
}
/**
* gst_element_class_add_static_pad_template_with_gtype:
* @klass: the #GstElementClass to add the pad template to.
* @static_templ: #GstStaticPadTemplate to add as pad template to the element class.
* @pad_type: The #GType of the pad to create
*
* Adds a pad template to an element class based on the static pad template
* @templ. This is mainly used in the _class_init functions of element
* implementations. If a pad template with the same name already exists,
* the old one is replaced by the new one.
*
* Since: 1.14
*/
void
gst_element_class_add_static_pad_template_with_gtype (GstElementClass * klass,
GstStaticPadTemplate * static_templ, GType pad_type)
{
gst_element_class_add_pad_template (klass,
gst_pad_template_new_from_static_pad_template_with_gtype (static_templ,
pad_type));
}
/**
* gst_element_class_add_metadata:
* @klass: class to set metadata for
* @key: the key to set
* @value: the value to set
*
* Set @key with @value as metadata in @klass.
*/
void
gst_element_class_add_metadata (GstElementClass * klass,
const gchar * key, const gchar * value)
{
g_return_if_fail (GST_IS_ELEMENT_CLASS (klass));
g_return_if_fail (key != NULL);
g_return_if_fail (value != NULL);
gst_structure_set ((GstStructure *) klass->metadata,
key, G_TYPE_STRING, value, NULL);
}
/**
* gst_element_class_add_static_metadata:
* @klass: class to set metadata for
* @key: the key to set
* @value: the value to set
*
* Set @key with @value as metadata in @klass.
*
* Same as gst_element_class_add_metadata(), but @value must be a static string
* or an inlined string, as it will not be copied. (GStreamer plugins will
* be made resident once loaded, so this function can be used even from
* dynamically loaded plugins.)
*/
void
gst_element_class_add_static_metadata (GstElementClass * klass,
const gchar * key, const gchar * value)
{
GValue val = G_VALUE_INIT;
g_return_if_fail (GST_IS_ELEMENT_CLASS (klass));
g_return_if_fail (key != NULL);
g_return_if_fail (value != NULL);
g_value_init (&val, G_TYPE_STRING);
g_value_set_static_string (&val, value);
gst_structure_take_value ((GstStructure *) klass->metadata, key, &val);
}
/**
* gst_element_class_set_metadata:
* @klass: class to set metadata for
* @longname: The long English name of the element. E.g. "File Sink"
* @classification: String describing the type of element, as an unordered list
* separated with slashes ('/'). See draft-klass.txt of the design docs
* for more details and common types. E.g: "Sink/File"
* @description: Sentence describing the purpose of the element.
* E.g: "Write stream to a file"
* @author: Name and contact details of the author(s). Use \n to separate
* multiple author metadata. E.g: "Joe Bloggs &lt;joe.blogs at foo.com&gt;"
*
* Sets the detailed information for a #GstElementClass.
* > This function is for use in _class_init functions only.
*/
void
gst_element_class_set_metadata (GstElementClass * klass,
const gchar * longname, const gchar * classification,
const gchar * description, const gchar * author)
{
g_return_if_fail (GST_IS_ELEMENT_CLASS (klass));
g_return_if_fail (longname != NULL && *longname != '\0');
g_return_if_fail (classification != NULL && *classification != '\0');
g_return_if_fail (description != NULL && *description != '\0');
g_return_if_fail (author != NULL && *author != '\0');
gst_structure_id_set ((GstStructure *) klass->metadata,
GST_QUARK (ELEMENT_METADATA_LONGNAME), G_TYPE_STRING, longname,
GST_QUARK (ELEMENT_METADATA_KLASS), G_TYPE_STRING, classification,
GST_QUARK (ELEMENT_METADATA_DESCRIPTION), G_TYPE_STRING, description,
GST_QUARK (ELEMENT_METADATA_AUTHOR), G_TYPE_STRING, author, NULL);
}
/**
* gst_element_class_set_static_metadata:
* @klass: class to set metadata for
* @longname: The long English name of the element. E.g. "File Sink"
* @classification: String describing the type of element, as an unordered list
* separated with slashes ('/'). See draft-klass.txt of the design docs
* for more details and common types. E.g: "Sink/File"
* @description: Sentence describing the purpose of the element.
* E.g: "Write stream to a file"
* @author: Name and contact details of the author(s). Use \n to separate
* multiple author metadata. E.g: "Joe Bloggs &lt;joe.blogs at foo.com&gt;"
*
* Sets the detailed information for a #GstElementClass.
*
* > This function is for use in _class_init functions only.
*
* Same as gst_element_class_set_metadata(), but @longname, @classification,
* @description, and @author must be static strings or inlined strings, as
* they will not be copied. (GStreamer plugins will be made resident once
* loaded, so this function can be used even from dynamically loaded plugins.)
*/
void
gst_element_class_set_static_metadata (GstElementClass * klass,
const gchar * longname, const gchar * classification,
const gchar * description, const gchar * author)
{
GstStructure *s = (GstStructure *) klass->metadata;
GValue val = G_VALUE_INIT;
g_return_if_fail (GST_IS_ELEMENT_CLASS (klass));
g_return_if_fail (longname != NULL && *longname != '\0');
g_return_if_fail (classification != NULL && *classification != '\0');
g_return_if_fail (description != NULL && *description != '\0');
g_return_if_fail (author != NULL && *author != '\0');
g_value_init (&val, G_TYPE_STRING);
g_value_set_static_string (&val, longname);
gst_structure_id_set_value (s, GST_QUARK (ELEMENT_METADATA_LONGNAME), &val);
g_value_set_static_string (&val, classification);
gst_structure_id_set_value (s, GST_QUARK (ELEMENT_METADATA_KLASS), &val);
g_value_set_static_string (&val, description);
gst_structure_id_set_value (s, GST_QUARK (ELEMENT_METADATA_DESCRIPTION),
&val);
g_value_set_static_string (&val, author);
gst_structure_id_take_value (s, GST_QUARK (ELEMENT_METADATA_AUTHOR), &val);
}
/**
* gst_element_class_get_metadata:
* @klass: class to get metadata for
* @key: the key to get
*
* Get metadata with @key in @klass.
*
* Returns: the metadata for @key.
*/
const gchar *
gst_element_class_get_metadata (GstElementClass * klass, const gchar * key)
{
g_return_val_if_fail (GST_IS_ELEMENT_CLASS (klass), NULL);
g_return_val_if_fail (key != NULL, NULL);
return gst_structure_get_string ((GstStructure *) klass->metadata, key);
}
/**
* gst_element_get_metadata:
* @element: class to get metadata for
* @key: the key to get
*
* Get metadata with @key in @klass.
*
* Returns: the metadata for @key.
*
* Since: 1.14
*/
const gchar *
gst_element_get_metadata (GstElement * element, const gchar * key)
{
g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
g_return_val_if_fail (key != NULL, NULL);
return gst_element_class_get_metadata (GST_ELEMENT_GET_CLASS (element), key);
}
/**
* gst_element_class_get_pad_template_list:
gst/gstpad.c (gst_pad_custom_new): Add a FIXME, this is a hacky way to do inheritance. Original commit message from CVS: 2004-02-10 Andy Wingo <wingo@pobox.com> * gst/gstpad.c (gst_pad_custom_new): Add a FIXME, this is a hacky way to do inheritance. (gst_pad_get_event_masks, gst_pad_get_event_masks_default) (gst_pad_get_query_types, gst_pad_get_query_types_default): Routine docs. (gst_pad_set_link_function, gst_pad_set_fixate_function) (gst_pad_set_getcaps_function): Doc from Dave's negotation random doc. (gst_pad_unlink, gst_pad_is_linked): Docs. (gst_pad_renegotiate): A brief description of capsnego. (gst_pad_try_set_caps): Document. (gst_pad_try_set_caps_nonfixed): Document. (gst_pad_can_link_filtered, gst_pad_link_filtered): Doc fixes. (gst_pad_set_parent): Deprecated (although not out of the API). (gst_pad_get_parent): Deprecated, although many plugins use this. (gst_pad_add_ghost_pad, gst_pad_remove_ghost_pad): Doc that these are private and will go away in 0.9. (gst_pad_perform_negotiate): Doc. (gst_pad_link_unnegotiate): I think this is meant to be static. (gst_pad_get_negotiated_caps, gst_pad_get_pad_template_caps) (gst_pad_template_get_caps_by_name, gst_pad_check_compatibility) (gst_pad_get_peer): Doc updates. (gst_pad_caps_change_notify): Doc. (gst_pad_alloc_buffer, gst_pad_push, gst_static_pad_template_get) (gst_ghost_pad_new): Doc fixes. * gst/gstobject.c (gst_object_get_parent, gst_object_unparent) (gst_object_check_uniqueness): * gst/gstelement.c (gst_element_add_pad) (gst_element_add_ghost_pad, gst_element_remove_pad) (gst_element_remove_ghost_pad, gst_element_get_pad) (gst_element_get_static_pad, gst_element_get_pad_list) (gst_element_class_get_pad_template_list) (gst_element_class_get_pad_template): Work on the docs. (gst_element_get_pad_template_list): Uses the class method. (gst_element_get_compatible_pad_template): Docs, and consolidate some test conditions. (gst_element_get_pad_from_template): New static function. (gst_element_request_compatible_pad): Docs, and work with non-request compatible templates. (gst_element_get_compatible_pad_filtered): Docs and remove redundant checks. (gst_element_get_compatible_pad, gst_element_link_pads_filtered) (gst_element_link_filtered, gst_element_link_many) (gst_element_link, gst_element_link_pads) (gst_element_unlink_many): Docs. 2004-02-05 Andy Wingo <wingo@pobox.com> * gst/gstpad.c (_gst_real_pad_fixate_accumulator): s/pointer/boxed/. * gst/gstmarshal.list (VOID:BOXED, BOXED:BOXED): New marshallers. * gst/gstpad.c (gst_real_pad_class_init): Use a BOXED:BOXED marshaller for ::fixate, and VOID:BOXED for ::caps-nego-failed, with the type=GST_TYPE_CAPS. This allows language bindings to know what kind of data they're dealing with. * gst/gstcaps.c (_gst_caps_value_init): GBoxed values initialize to NULL when g_value_init is called. GstCaps, which rolls its own type implementation, now does the same instead of allocating empty caps. (_gst_caps_initialize, _gst_caps_collect_value, _gst_caps_lcopy_value): Provide collect_value and lcopy_value type table methods. This allows G_VALUE_COLLECT to work. 2004-02-05 Andy Wingo <wingo@pobox.com> * configure.ac: * testsuite/Makefile.am (SUBDIRS): * testsuite/ghostpads/Makefile.am: * testsuite/ghostpads/ghostpads.c: A new test for ghost pads. * gst/gstpad.c (gst_pad_add_ghost_pad, gst_pad_remove_ghost_pad): These two routines are the only ones that set GST_GPAD_REALPAD(gpad), the ghost pad list, and the ghost pad's pad template. They should be made static, depending on ABI needs. (gst_real_pad_dispose): Handle the case of ghost pads without a parent. Assert after dealing with ghost pads that the ghost pad list is empty. (gst_ghost_pad_class_init): New property added, ::real-pad. Can be set after creation. (gst_ghost_pad_dispose): Set ::real-pad to NULL. (gst_ghost_pad_set_property, gst_ghost_pad_get_property): New functions. set_property will call add_ghost_pad/remove_ghost_pad as appropriate. (gst_ghost_pad_new): All the work is offloaded to g_object_new. * gst/gstelement.c (gst_element_add_pad): Handle ghost pads as well. (gst_element_add_ghost_pad): Remove code duplicated from _add_pad. (gst_element_remove_pad): Handle ghost pads as well. (gst_element_remove_ghost_pad): Deprecated (could be removed, depending on API-stability needs). 2004-02-05 Andy Wingo <wingo@pobox.com> * gst/gstbin.[ch]: (gst_bin_get_by_interface): GTypes are scalars, of course they're const
2004-02-11 13:26:04 +00:00
* @element_class: a #GstElementClass to get pad templates of.
*
gst/gstpad.c (gst_pad_custom_new): Add a FIXME, this is a hacky way to do inheritance. Original commit message from CVS: 2004-02-10 Andy Wingo <wingo@pobox.com> * gst/gstpad.c (gst_pad_custom_new): Add a FIXME, this is a hacky way to do inheritance. (gst_pad_get_event_masks, gst_pad_get_event_masks_default) (gst_pad_get_query_types, gst_pad_get_query_types_default): Routine docs. (gst_pad_set_link_function, gst_pad_set_fixate_function) (gst_pad_set_getcaps_function): Doc from Dave's negotation random doc. (gst_pad_unlink, gst_pad_is_linked): Docs. (gst_pad_renegotiate): A brief description of capsnego. (gst_pad_try_set_caps): Document. (gst_pad_try_set_caps_nonfixed): Document. (gst_pad_can_link_filtered, gst_pad_link_filtered): Doc fixes. (gst_pad_set_parent): Deprecated (although not out of the API). (gst_pad_get_parent): Deprecated, although many plugins use this. (gst_pad_add_ghost_pad, gst_pad_remove_ghost_pad): Doc that these are private and will go away in 0.9. (gst_pad_perform_negotiate): Doc. (gst_pad_link_unnegotiate): I think this is meant to be static. (gst_pad_get_negotiated_caps, gst_pad_get_pad_template_caps) (gst_pad_template_get_caps_by_name, gst_pad_check_compatibility) (gst_pad_get_peer): Doc updates. (gst_pad_caps_change_notify): Doc. (gst_pad_alloc_buffer, gst_pad_push, gst_static_pad_template_get) (gst_ghost_pad_new): Doc fixes. * gst/gstobject.c (gst_object_get_parent, gst_object_unparent) (gst_object_check_uniqueness): * gst/gstelement.c (gst_element_add_pad) (gst_element_add_ghost_pad, gst_element_remove_pad) (gst_element_remove_ghost_pad, gst_element_get_pad) (gst_element_get_static_pad, gst_element_get_pad_list) (gst_element_class_get_pad_template_list) (gst_element_class_get_pad_template): Work on the docs. (gst_element_get_pad_template_list): Uses the class method. (gst_element_get_compatible_pad_template): Docs, and consolidate some test conditions. (gst_element_get_pad_from_template): New static function. (gst_element_request_compatible_pad): Docs, and work with non-request compatible templates. (gst_element_get_compatible_pad_filtered): Docs and remove redundant checks. (gst_element_get_compatible_pad, gst_element_link_pads_filtered) (gst_element_link_filtered, gst_element_link_many) (gst_element_link, gst_element_link_pads) (gst_element_unlink_many): Docs. 2004-02-05 Andy Wingo <wingo@pobox.com> * gst/gstpad.c (_gst_real_pad_fixate_accumulator): s/pointer/boxed/. * gst/gstmarshal.list (VOID:BOXED, BOXED:BOXED): New marshallers. * gst/gstpad.c (gst_real_pad_class_init): Use a BOXED:BOXED marshaller for ::fixate, and VOID:BOXED for ::caps-nego-failed, with the type=GST_TYPE_CAPS. This allows language bindings to know what kind of data they're dealing with. * gst/gstcaps.c (_gst_caps_value_init): GBoxed values initialize to NULL when g_value_init is called. GstCaps, which rolls its own type implementation, now does the same instead of allocating empty caps. (_gst_caps_initialize, _gst_caps_collect_value, _gst_caps_lcopy_value): Provide collect_value and lcopy_value type table methods. This allows G_VALUE_COLLECT to work. 2004-02-05 Andy Wingo <wingo@pobox.com> * configure.ac: * testsuite/Makefile.am (SUBDIRS): * testsuite/ghostpads/Makefile.am: * testsuite/ghostpads/ghostpads.c: A new test for ghost pads. * gst/gstpad.c (gst_pad_add_ghost_pad, gst_pad_remove_ghost_pad): These two routines are the only ones that set GST_GPAD_REALPAD(gpad), the ghost pad list, and the ghost pad's pad template. They should be made static, depending on ABI needs. (gst_real_pad_dispose): Handle the case of ghost pads without a parent. Assert after dealing with ghost pads that the ghost pad list is empty. (gst_ghost_pad_class_init): New property added, ::real-pad. Can be set after creation. (gst_ghost_pad_dispose): Set ::real-pad to NULL. (gst_ghost_pad_set_property, gst_ghost_pad_get_property): New functions. set_property will call add_ghost_pad/remove_ghost_pad as appropriate. (gst_ghost_pad_new): All the work is offloaded to g_object_new. * gst/gstelement.c (gst_element_add_pad): Handle ghost pads as well. (gst_element_add_ghost_pad): Remove code duplicated from _add_pad. (gst_element_remove_pad): Handle ghost pads as well. (gst_element_remove_ghost_pad): Deprecated (could be removed, depending on API-stability needs). 2004-02-05 Andy Wingo <wingo@pobox.com> * gst/gstbin.[ch]: (gst_bin_get_by_interface): GTypes are scalars, of course they're const
2004-02-11 13:26:04 +00:00
* Retrieves a list of the pad templates associated with @element_class. The
* list must not be modified by the calling code.
* > If you use this function in the #GInstanceInitFunc of an object class
* > that has subclasses, make sure to pass the g_class parameter of the
* > #GInstanceInitFunc here.
*
* Returns: (transfer none) (element-type Gst.PadTemplate): the #GList of
* pad templates.
*/
GList *
gst_element_class_get_pad_template_list (GstElementClass * element_class)
{
g_return_val_if_fail (GST_IS_ELEMENT_CLASS (element_class), NULL);
return element_class->padtemplates;
}
/**
* gst_element_get_pad_template_list:
* @element: a #GstElement to get pad templates of.
*
* Retrieves a list of the pad templates associated with @element. The
* list must not be modified by the calling code.
*
* Returns: (transfer none) (element-type Gst.PadTemplate): the #GList of
* pad templates.
*
* Since: 1.14
*/
GList *
gst_element_get_pad_template_list (GstElement * element)
{
g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
return
gst_element_class_get_pad_template_list (GST_ELEMENT_GET_CLASS (element));
}
/**
* gst_element_class_get_pad_template:
gst/gstpad.c (gst_pad_custom_new): Add a FIXME, this is a hacky way to do inheritance. Original commit message from CVS: 2004-02-10 Andy Wingo <wingo@pobox.com> * gst/gstpad.c (gst_pad_custom_new): Add a FIXME, this is a hacky way to do inheritance. (gst_pad_get_event_masks, gst_pad_get_event_masks_default) (gst_pad_get_query_types, gst_pad_get_query_types_default): Routine docs. (gst_pad_set_link_function, gst_pad_set_fixate_function) (gst_pad_set_getcaps_function): Doc from Dave's negotation random doc. (gst_pad_unlink, gst_pad_is_linked): Docs. (gst_pad_renegotiate): A brief description of capsnego. (gst_pad_try_set_caps): Document. (gst_pad_try_set_caps_nonfixed): Document. (gst_pad_can_link_filtered, gst_pad_link_filtered): Doc fixes. (gst_pad_set_parent): Deprecated (although not out of the API). (gst_pad_get_parent): Deprecated, although many plugins use this. (gst_pad_add_ghost_pad, gst_pad_remove_ghost_pad): Doc that these are private and will go away in 0.9. (gst_pad_perform_negotiate): Doc. (gst_pad_link_unnegotiate): I think this is meant to be static. (gst_pad_get_negotiated_caps, gst_pad_get_pad_template_caps) (gst_pad_template_get_caps_by_name, gst_pad_check_compatibility) (gst_pad_get_peer): Doc updates. (gst_pad_caps_change_notify): Doc. (gst_pad_alloc_buffer, gst_pad_push, gst_static_pad_template_get) (gst_ghost_pad_new): Doc fixes. * gst/gstobject.c (gst_object_get_parent, gst_object_unparent) (gst_object_check_uniqueness): * gst/gstelement.c (gst_element_add_pad) (gst_element_add_ghost_pad, gst_element_remove_pad) (gst_element_remove_ghost_pad, gst_element_get_pad) (gst_element_get_static_pad, gst_element_get_pad_list) (gst_element_class_get_pad_template_list) (gst_element_class_get_pad_template): Work on the docs. (gst_element_get_pad_template_list): Uses the class method. (gst_element_get_compatible_pad_template): Docs, and consolidate some test conditions. (gst_element_get_pad_from_template): New static function. (gst_element_request_compatible_pad): Docs, and work with non-request compatible templates. (gst_element_get_compatible_pad_filtered): Docs and remove redundant checks. (gst_element_get_compatible_pad, gst_element_link_pads_filtered) (gst_element_link_filtered, gst_element_link_many) (gst_element_link, gst_element_link_pads) (gst_element_unlink_many): Docs. 2004-02-05 Andy Wingo <wingo@pobox.com> * gst/gstpad.c (_gst_real_pad_fixate_accumulator): s/pointer/boxed/. * gst/gstmarshal.list (VOID:BOXED, BOXED:BOXED): New marshallers. * gst/gstpad.c (gst_real_pad_class_init): Use a BOXED:BOXED marshaller for ::fixate, and VOID:BOXED for ::caps-nego-failed, with the type=GST_TYPE_CAPS. This allows language bindings to know what kind of data they're dealing with. * gst/gstcaps.c (_gst_caps_value_init): GBoxed values initialize to NULL when g_value_init is called. GstCaps, which rolls its own type implementation, now does the same instead of allocating empty caps. (_gst_caps_initialize, _gst_caps_collect_value, _gst_caps_lcopy_value): Provide collect_value and lcopy_value type table methods. This allows G_VALUE_COLLECT to work. 2004-02-05 Andy Wingo <wingo@pobox.com> * configure.ac: * testsuite/Makefile.am (SUBDIRS): * testsuite/ghostpads/Makefile.am: * testsuite/ghostpads/ghostpads.c: A new test for ghost pads. * gst/gstpad.c (gst_pad_add_ghost_pad, gst_pad_remove_ghost_pad): These two routines are the only ones that set GST_GPAD_REALPAD(gpad), the ghost pad list, and the ghost pad's pad template. They should be made static, depending on ABI needs. (gst_real_pad_dispose): Handle the case of ghost pads without a parent. Assert after dealing with ghost pads that the ghost pad list is empty. (gst_ghost_pad_class_init): New property added, ::real-pad. Can be set after creation. (gst_ghost_pad_dispose): Set ::real-pad to NULL. (gst_ghost_pad_set_property, gst_ghost_pad_get_property): New functions. set_property will call add_ghost_pad/remove_ghost_pad as appropriate. (gst_ghost_pad_new): All the work is offloaded to g_object_new. * gst/gstelement.c (gst_element_add_pad): Handle ghost pads as well. (gst_element_add_ghost_pad): Remove code duplicated from _add_pad. (gst_element_remove_pad): Handle ghost pads as well. (gst_element_remove_ghost_pad): Deprecated (could be removed, depending on API-stability needs). 2004-02-05 Andy Wingo <wingo@pobox.com> * gst/gstbin.[ch]: (gst_bin_get_by_interface): GTypes are scalars, of course they're const
2004-02-11 13:26:04 +00:00
* @element_class: a #GstElementClass to get the pad template of.
* @name: the name of the #GstPadTemplate to get.
*
gst/gstpad.c (gst_pad_custom_new): Add a FIXME, this is a hacky way to do inheritance. Original commit message from CVS: 2004-02-10 Andy Wingo <wingo@pobox.com> * gst/gstpad.c (gst_pad_custom_new): Add a FIXME, this is a hacky way to do inheritance. (gst_pad_get_event_masks, gst_pad_get_event_masks_default) (gst_pad_get_query_types, gst_pad_get_query_types_default): Routine docs. (gst_pad_set_link_function, gst_pad_set_fixate_function) (gst_pad_set_getcaps_function): Doc from Dave's negotation random doc. (gst_pad_unlink, gst_pad_is_linked): Docs. (gst_pad_renegotiate): A brief description of capsnego. (gst_pad_try_set_caps): Document. (gst_pad_try_set_caps_nonfixed): Document. (gst_pad_can_link_filtered, gst_pad_link_filtered): Doc fixes. (gst_pad_set_parent): Deprecated (although not out of the API). (gst_pad_get_parent): Deprecated, although many plugins use this. (gst_pad_add_ghost_pad, gst_pad_remove_ghost_pad): Doc that these are private and will go away in 0.9. (gst_pad_perform_negotiate): Doc. (gst_pad_link_unnegotiate): I think this is meant to be static. (gst_pad_get_negotiated_caps, gst_pad_get_pad_template_caps) (gst_pad_template_get_caps_by_name, gst_pad_check_compatibility) (gst_pad_get_peer): Doc updates. (gst_pad_caps_change_notify): Doc. (gst_pad_alloc_buffer, gst_pad_push, gst_static_pad_template_get) (gst_ghost_pad_new): Doc fixes. * gst/gstobject.c (gst_object_get_parent, gst_object_unparent) (gst_object_check_uniqueness): * gst/gstelement.c (gst_element_add_pad) (gst_element_add_ghost_pad, gst_element_remove_pad) (gst_element_remove_ghost_pad, gst_element_get_pad) (gst_element_get_static_pad, gst_element_get_pad_list) (gst_element_class_get_pad_template_list) (gst_element_class_get_pad_template): Work on the docs. (gst_element_get_pad_template_list): Uses the class method. (gst_element_get_compatible_pad_template): Docs, and consolidate some test conditions. (gst_element_get_pad_from_template): New static function. (gst_element_request_compatible_pad): Docs, and work with non-request compatible templates. (gst_element_get_compatible_pad_filtered): Docs and remove redundant checks. (gst_element_get_compatible_pad, gst_element_link_pads_filtered) (gst_element_link_filtered, gst_element_link_many) (gst_element_link, gst_element_link_pads) (gst_element_unlink_many): Docs. 2004-02-05 Andy Wingo <wingo@pobox.com> * gst/gstpad.c (_gst_real_pad_fixate_accumulator): s/pointer/boxed/. * gst/gstmarshal.list (VOID:BOXED, BOXED:BOXED): New marshallers. * gst/gstpad.c (gst_real_pad_class_init): Use a BOXED:BOXED marshaller for ::fixate, and VOID:BOXED for ::caps-nego-failed, with the type=GST_TYPE_CAPS. This allows language bindings to know what kind of data they're dealing with. * gst/gstcaps.c (_gst_caps_value_init): GBoxed values initialize to NULL when g_value_init is called. GstCaps, which rolls its own type implementation, now does the same instead of allocating empty caps. (_gst_caps_initialize, _gst_caps_collect_value, _gst_caps_lcopy_value): Provide collect_value and lcopy_value type table methods. This allows G_VALUE_COLLECT to work. 2004-02-05 Andy Wingo <wingo@pobox.com> * configure.ac: * testsuite/Makefile.am (SUBDIRS): * testsuite/ghostpads/Makefile.am: * testsuite/ghostpads/ghostpads.c: A new test for ghost pads. * gst/gstpad.c (gst_pad_add_ghost_pad, gst_pad_remove_ghost_pad): These two routines are the only ones that set GST_GPAD_REALPAD(gpad), the ghost pad list, and the ghost pad's pad template. They should be made static, depending on ABI needs. (gst_real_pad_dispose): Handle the case of ghost pads without a parent. Assert after dealing with ghost pads that the ghost pad list is empty. (gst_ghost_pad_class_init): New property added, ::real-pad. Can be set after creation. (gst_ghost_pad_dispose): Set ::real-pad to NULL. (gst_ghost_pad_set_property, gst_ghost_pad_get_property): New functions. set_property will call add_ghost_pad/remove_ghost_pad as appropriate. (gst_ghost_pad_new): All the work is offloaded to g_object_new. * gst/gstelement.c (gst_element_add_pad): Handle ghost pads as well. (gst_element_add_ghost_pad): Remove code duplicated from _add_pad. (gst_element_remove_pad): Handle ghost pads as well. (gst_element_remove_ghost_pad): Deprecated (could be removed, depending on API-stability needs). 2004-02-05 Andy Wingo <wingo@pobox.com> * gst/gstbin.[ch]: (gst_bin_get_by_interface): GTypes are scalars, of course they're const
2004-02-11 13:26:04 +00:00
* Retrieves a padtemplate from @element_class with the given name.
* > If you use this function in the #GInstanceInitFunc of an object class
* > that has subclasses, make sure to pass the g_class parameter of the
* > #GInstanceInitFunc here.
*
* Returns: (transfer none) (nullable): the #GstPadTemplate with the
* given name, or %NULL if none was found. No unreferencing is
* necessary.
*/
GstPadTemplate *
gst_element_class_get_pad_template (GstElementClass *
element_class, const gchar * name)
{
GList *padlist;
g_return_val_if_fail (GST_IS_ELEMENT_CLASS (element_class), NULL);
g_return_val_if_fail (name != NULL, NULL);
padlist = element_class->padtemplates;
while (padlist) {
GstPadTemplate *padtempl = (GstPadTemplate *) padlist->data;
if (strcmp (padtempl->name_template, name) == 0)
return padtempl;
padlist = g_list_next (padlist);
}
return NULL;
}
/**
* gst_element_get_pad_template:
* @element: a #GstElement to get the pad template of.
* @name: the name of the #GstPadTemplate to get.
*
* Retrieves a padtemplate from @element with the given name.
*
* Returns: (transfer none) (nullable): the #GstPadTemplate with the
* given name, or %NULL if none was found. No unreferencing is
* necessary.
*
* Since: 1.14
*/
GstPadTemplate *
gst_element_get_pad_template (GstElement * element, const gchar * name)
{
g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
g_return_val_if_fail (name != NULL, NULL);
return gst_element_class_get_pad_template (GST_ELEMENT_GET_CLASS (element),
name);
}
static GstPadTemplate *
gst_element_class_get_request_pad_template (GstElementClass *
element_class, const gchar * name)
{
GstPadTemplate *tmpl;
tmpl = gst_element_class_get_pad_template (element_class, name);
if (tmpl != NULL && tmpl->presence == GST_PAD_REQUEST)
return tmpl;
return NULL;
}
/* get a random pad on element of the given direction.
* The pad is random in a sense that it is the first pad that is (optionally) linked.
*/
static GstPad *
gst_element_get_random_pad (GstElement * element,
gboolean need_linked, GstPadDirection dir)
{
GstPad *result = NULL;
GList *pads;
gst/gstpad.c (gst_pad_custom_new): Add a FIXME, this is a hacky way to do inheritance. Original commit message from CVS: 2004-02-10 Andy Wingo <wingo@pobox.com> * gst/gstpad.c (gst_pad_custom_new): Add a FIXME, this is a hacky way to do inheritance. (gst_pad_get_event_masks, gst_pad_get_event_masks_default) (gst_pad_get_query_types, gst_pad_get_query_types_default): Routine docs. (gst_pad_set_link_function, gst_pad_set_fixate_function) (gst_pad_set_getcaps_function): Doc from Dave's negotation random doc. (gst_pad_unlink, gst_pad_is_linked): Docs. (gst_pad_renegotiate): A brief description of capsnego. (gst_pad_try_set_caps): Document. (gst_pad_try_set_caps_nonfixed): Document. (gst_pad_can_link_filtered, gst_pad_link_filtered): Doc fixes. (gst_pad_set_parent): Deprecated (although not out of the API). (gst_pad_get_parent): Deprecated, although many plugins use this. (gst_pad_add_ghost_pad, gst_pad_remove_ghost_pad): Doc that these are private and will go away in 0.9. (gst_pad_perform_negotiate): Doc. (gst_pad_link_unnegotiate): I think this is meant to be static. (gst_pad_get_negotiated_caps, gst_pad_get_pad_template_caps) (gst_pad_template_get_caps_by_name, gst_pad_check_compatibility) (gst_pad_get_peer): Doc updates. (gst_pad_caps_change_notify): Doc. (gst_pad_alloc_buffer, gst_pad_push, gst_static_pad_template_get) (gst_ghost_pad_new): Doc fixes. * gst/gstobject.c (gst_object_get_parent, gst_object_unparent) (gst_object_check_uniqueness): * gst/gstelement.c (gst_element_add_pad) (gst_element_add_ghost_pad, gst_element_remove_pad) (gst_element_remove_ghost_pad, gst_element_get_pad) (gst_element_get_static_pad, gst_element_get_pad_list) (gst_element_class_get_pad_template_list) (gst_element_class_get_pad_template): Work on the docs. (gst_element_get_pad_template_list): Uses the class method. (gst_element_get_compatible_pad_template): Docs, and consolidate some test conditions. (gst_element_get_pad_from_template): New static function. (gst_element_request_compatible_pad): Docs, and work with non-request compatible templates. (gst_element_get_compatible_pad_filtered): Docs and remove redundant checks. (gst_element_get_compatible_pad, gst_element_link_pads_filtered) (gst_element_link_filtered, gst_element_link_many) (gst_element_link, gst_element_link_pads) (gst_element_unlink_many): Docs. 2004-02-05 Andy Wingo <wingo@pobox.com> * gst/gstpad.c (_gst_real_pad_fixate_accumulator): s/pointer/boxed/. * gst/gstmarshal.list (VOID:BOXED, BOXED:BOXED): New marshallers. * gst/gstpad.c (gst_real_pad_class_init): Use a BOXED:BOXED marshaller for ::fixate, and VOID:BOXED for ::caps-nego-failed, with the type=GST_TYPE_CAPS. This allows language bindings to know what kind of data they're dealing with. * gst/gstcaps.c (_gst_caps_value_init): GBoxed values initialize to NULL when g_value_init is called. GstCaps, which rolls its own type implementation, now does the same instead of allocating empty caps. (_gst_caps_initialize, _gst_caps_collect_value, _gst_caps_lcopy_value): Provide collect_value and lcopy_value type table methods. This allows G_VALUE_COLLECT to work. 2004-02-05 Andy Wingo <wingo@pobox.com> * configure.ac: * testsuite/Makefile.am (SUBDIRS): * testsuite/ghostpads/Makefile.am: * testsuite/ghostpads/ghostpads.c: A new test for ghost pads. * gst/gstpad.c (gst_pad_add_ghost_pad, gst_pad_remove_ghost_pad): These two routines are the only ones that set GST_GPAD_REALPAD(gpad), the ghost pad list, and the ghost pad's pad template. They should be made static, depending on ABI needs. (gst_real_pad_dispose): Handle the case of ghost pads without a parent. Assert after dealing with ghost pads that the ghost pad list is empty. (gst_ghost_pad_class_init): New property added, ::real-pad. Can be set after creation. (gst_ghost_pad_dispose): Set ::real-pad to NULL. (gst_ghost_pad_set_property, gst_ghost_pad_get_property): New functions. set_property will call add_ghost_pad/remove_ghost_pad as appropriate. (gst_ghost_pad_new): All the work is offloaded to g_object_new. * gst/gstelement.c (gst_element_add_pad): Handle ghost pads as well. (gst_element_add_ghost_pad): Remove code duplicated from _add_pad. (gst_element_remove_pad): Handle ghost pads as well. (gst_element_remove_ghost_pad): Deprecated (could be removed, depending on API-stability needs). 2004-02-05 Andy Wingo <wingo@pobox.com> * gst/gstbin.[ch]: (gst_bin_get_by_interface): GTypes are scalars, of course they're const
2004-02-11 13:26:04 +00:00
GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "getting a random pad");
gst/gstpad.c (gst_pad_custom_new): Add a FIXME, this is a hacky way to do inheritance. Original commit message from CVS: 2004-02-10 Andy Wingo <wingo@pobox.com> * gst/gstpad.c (gst_pad_custom_new): Add a FIXME, this is a hacky way to do inheritance. (gst_pad_get_event_masks, gst_pad_get_event_masks_default) (gst_pad_get_query_types, gst_pad_get_query_types_default): Routine docs. (gst_pad_set_link_function, gst_pad_set_fixate_function) (gst_pad_set_getcaps_function): Doc from Dave's negotation random doc. (gst_pad_unlink, gst_pad_is_linked): Docs. (gst_pad_renegotiate): A brief description of capsnego. (gst_pad_try_set_caps): Document. (gst_pad_try_set_caps_nonfixed): Document. (gst_pad_can_link_filtered, gst_pad_link_filtered): Doc fixes. (gst_pad_set_parent): Deprecated (although not out of the API). (gst_pad_get_parent): Deprecated, although many plugins use this. (gst_pad_add_ghost_pad, gst_pad_remove_ghost_pad): Doc that these are private and will go away in 0.9. (gst_pad_perform_negotiate): Doc. (gst_pad_link_unnegotiate): I think this is meant to be static. (gst_pad_get_negotiated_caps, gst_pad_get_pad_template_caps) (gst_pad_template_get_caps_by_name, gst_pad_check_compatibility) (gst_pad_get_peer): Doc updates. (gst_pad_caps_change_notify): Doc. (gst_pad_alloc_buffer, gst_pad_push, gst_static_pad_template_get) (gst_ghost_pad_new): Doc fixes. * gst/gstobject.c (gst_object_get_parent, gst_object_unparent) (gst_object_check_uniqueness): * gst/gstelement.c (gst_element_add_pad) (gst_element_add_ghost_pad, gst_element_remove_pad) (gst_element_remove_ghost_pad, gst_element_get_pad) (gst_element_get_static_pad, gst_element_get_pad_list) (gst_element_class_get_pad_template_list) (gst_element_class_get_pad_template): Work on the docs. (gst_element_get_pad_template_list): Uses the class method. (gst_element_get_compatible_pad_template): Docs, and consolidate some test conditions. (gst_element_get_pad_from_template): New static function. (gst_element_request_compatible_pad): Docs, and work with non-request compatible templates. (gst_element_get_compatible_pad_filtered): Docs and remove redundant checks. (gst_element_get_compatible_pad, gst_element_link_pads_filtered) (gst_element_link_filtered, gst_element_link_many) (gst_element_link, gst_element_link_pads) (gst_element_unlink_many): Docs. 2004-02-05 Andy Wingo <wingo@pobox.com> * gst/gstpad.c (_gst_real_pad_fixate_accumulator): s/pointer/boxed/. * gst/gstmarshal.list (VOID:BOXED, BOXED:BOXED): New marshallers. * gst/gstpad.c (gst_real_pad_class_init): Use a BOXED:BOXED marshaller for ::fixate, and VOID:BOXED for ::caps-nego-failed, with the type=GST_TYPE_CAPS. This allows language bindings to know what kind of data they're dealing with. * gst/gstcaps.c (_gst_caps_value_init): GBoxed values initialize to NULL when g_value_init is called. GstCaps, which rolls its own type implementation, now does the same instead of allocating empty caps. (_gst_caps_initialize, _gst_caps_collect_value, _gst_caps_lcopy_value): Provide collect_value and lcopy_value type table methods. This allows G_VALUE_COLLECT to work. 2004-02-05 Andy Wingo <wingo@pobox.com> * configure.ac: * testsuite/Makefile.am (SUBDIRS): * testsuite/ghostpads/Makefile.am: * testsuite/ghostpads/ghostpads.c: A new test for ghost pads. * gst/gstpad.c (gst_pad_add_ghost_pad, gst_pad_remove_ghost_pad): These two routines are the only ones that set GST_GPAD_REALPAD(gpad), the ghost pad list, and the ghost pad's pad template. They should be made static, depending on ABI needs. (gst_real_pad_dispose): Handle the case of ghost pads without a parent. Assert after dealing with ghost pads that the ghost pad list is empty. (gst_ghost_pad_class_init): New property added, ::real-pad. Can be set after creation. (gst_ghost_pad_dispose): Set ::real-pad to NULL. (gst_ghost_pad_set_property, gst_ghost_pad_get_property): New functions. set_property will call add_ghost_pad/remove_ghost_pad as appropriate. (gst_ghost_pad_new): All the work is offloaded to g_object_new. * gst/gstelement.c (gst_element_add_pad): Handle ghost pads as well. (gst_element_add_ghost_pad): Remove code duplicated from _add_pad. (gst_element_remove_pad): Handle ghost pads as well. (gst_element_remove_ghost_pad): Deprecated (could be removed, depending on API-stability needs). 2004-02-05 Andy Wingo <wingo@pobox.com> * gst/gstbin.[ch]: (gst_bin_get_by_interface): GTypes are scalars, of course they're const
2004-02-11 13:26:04 +00:00
switch (dir) {
case GST_PAD_SRC:
GST_OBJECT_LOCK (element);
pads = element->srcpads;
break;
case GST_PAD_SINK:
GST_OBJECT_LOCK (element);
pads = element->sinkpads;
break;
default:
goto wrong_direction;
}
for (; pads; pads = g_list_next (pads)) {
GstPad *pad = GST_PAD_CAST (pads->data);
GST_OBJECT_LOCK (pad);
GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "checking pad %s:%s",
GST_DEBUG_PAD_NAME (pad));
if (need_linked && !GST_PAD_IS_LINKED (pad)) {
/* if we require a linked pad, and it is not linked, continue the
* search */
GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "pad %s:%s is not linked",
GST_DEBUG_PAD_NAME (pad));
GST_OBJECT_UNLOCK (pad);
continue;
} else {
/* found a pad, stop search */
GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "found pad %s:%s",
GST_DEBUG_PAD_NAME (pad));
GST_OBJECT_UNLOCK (pad);
result = pad;
break;
}
}
if (result)
gst_object_ref (result);
GST_OBJECT_UNLOCK (element);
return result;
/* ERROR handling */
wrong_direction:
{
g_warning ("unknown pad direction %d", dir);
return NULL;
}
}
static gboolean
gst_element_default_send_event (GstElement * element, GstEvent * event)
{
gboolean result = FALSE;
GstPad *pad;
pad = GST_EVENT_IS_DOWNSTREAM (event) ?
gst_element_get_random_pad (element, TRUE, GST_PAD_SINK) :
gst_element_get_random_pad (element, TRUE, GST_PAD_SRC);
if (pad) {
GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS,
"pushing %s event to random %s pad %s:%s",
GST_EVENT_TYPE_NAME (event),
(GST_PAD_DIRECTION (pad) == GST_PAD_SRC ? "src" : "sink"),
GST_DEBUG_PAD_NAME (pad));
result = gst_pad_send_event (pad, event);
gst_object_unref (pad);
} else {
GST_CAT_INFO (GST_CAT_ELEMENT_PADS, "can't send %s event on element %s",
GST_EVENT_TYPE_NAME (event), GST_ELEMENT_NAME (element));
gst_event_unref (event);
}
return result;
}
/**
* gst_element_send_event:
* @element: a #GstElement to send the event to.
* @event: (transfer full): the #GstEvent to send to the element.
*
* Sends an event to an element. If the element doesn't implement an
* event handler, the event will be pushed on a random linked sink pad for
* downstream events or a random linked source pad for upstream events.
*
* This function takes ownership of the provided event so you should
* gst_event_ref() it if you want to reuse the event after this call.
*
* MT safe.
*
* Returns: %TRUE if the event was handled. Events that trigger a preroll (such
* as flushing seeks and steps) will emit %GST_MESSAGE_ASYNC_DONE.
*/
gboolean
gst_element_send_event (GstElement * element, GstEvent * event)
{
GstElementClass *oclass;
gboolean result = FALSE;
g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
g_return_val_if_fail (event != NULL, FALSE);
oclass = GST_ELEMENT_GET_CLASS (element);
GST_STATE_LOCK (element);
if (oclass->send_event) {
GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "send %s event on element %s",
GST_EVENT_TYPE_NAME (event), GST_ELEMENT_NAME (element));
result = oclass->send_event (element, event);
} else {
gst_event_unref (event);
}
GST_STATE_UNLOCK (element);
docs/gst/gstreamer-sections.txt: Add new element field and method. Original commit message from CVS: * docs/gst/gstreamer-sections.txt: Add new element field and method. * gst/gstbin.c: (gst_bin_class_init), (gst_bin_init), (bin_remove_messages), (gst_bin_add_func), (gst_bin_remove_func), (gst_bin_recalc_state), (gst_bin_get_state_func), (gst_bin_element_set_state), (gst_bin_change_state_func), (gst_bin_continue_func), (bin_bus_handler), (bin_push_state_continue), (bin_handle_async_start), (bin_handle_async_done), (gst_bin_handle_message_func): Make async state changes a bit smarter by using new ASYNC_START and ASYNC_DONE messages. This reduces the number of times we run the state recalculation thread. Don't change state of element with a pending ASYNC_START message. Deprecate STATE_DIRTY messages. * gst/gstelement.c: (gst_element_init), (gst_element_send_event), (gst_element_get_state_func), (gst_element_continue_state), (gst_element_lost_state), (gst_element_set_state_func), (gst_element_change_state): * gst/gstelement.h: Keep the state that was last set by the app in a new element field. Don't allow state changes when handling an element event. Post ASYNC_START and ASYNC_DONE messages. Change lost_state so that we go to PAUSED and wait for the parent to set us to PLAYING again (so latency calculation can be performed) Export gst_element_change_state() method so that subclasses can use it. API: gst_element_change_state() API: GST_STATE_TARGET * gst/gstpipeline.c: (gst_pipeline_class_init), (reset_stream_time), (gst_pipeline_change_state), (gst_pipeline_handle_message), (gst_pipeline_set_new_stream_time): Using the new ASYNC_START message we can reset the base_time when needed. This can then be used to implement base_time redistribution in flushing seeks so that we can remove the explicit seek handling. Perform latency query and configuration when going to PLAYING. * libs/gst/base/gstbasesink.c: (gst_base_sink_commit_state), (gst_base_sink_query), (gst_base_sink_change_state): Post new ASYNC_START/ASYNC_DONE messages. * tests/check/generic/sinks.c: (GST_START_TEST): Fix test because the bin will not set the async element to PLAYING right away. * tests/check/gst/gstbin.c: (pop_async_done), (GST_START_TEST): Make the message check a little stronger. Handle ASYNC messages. * tests/check/pipelines/cleanup.c: (GST_START_TEST): * tests/check/pipelines/simple-launch-lines.c: (GST_START_TEST): Expect ASYNC_DONE messages.
2007-03-19 10:47:56 +00:00
return result;
}
/**
* gst_element_seek:
* @element: a #GstElement to send the event to.
* @rate: The new playback rate
* @format: The format of the seek values
* @flags: The optional seek flags.
* @start_type: The type and flags for the new start position
* @start: The value of the new start position
* @stop_type: The type and flags for the new stop position
* @stop: The value of the new stop position
*
* Sends a seek event to an element. See gst_event_new_seek() for the details of
* the parameters. The seek event is sent to the element using
* gst_element_send_event().
*
* MT safe.
*
* Returns: %TRUE if the event was handled. Flushing seeks will trigger a
* preroll, which will emit %GST_MESSAGE_ASYNC_DONE.
*/
gboolean
Some docs updates Original commit message from CVS: * CHANGES-0.9: * docs/design/part-TODO.txt: * docs/design/part-events.txt: Some docs updates * gst/base/gstbasesink.c: (gst_base_sink_handle_object), (gst_base_sink_event), (gst_base_sink_do_sync), (gst_base_sink_activate_push), (gst_base_sink_activate_pull): * gst/base/gstbasesrc.c: (gst_base_src_send_discont), (gst_base_src_do_seek), (gst_base_src_event_handler), (gst_base_src_loop): * gst/base/gstbasetransform.c: (gst_base_transform_transform_caps), (gst_base_transform_configure_caps), (gst_base_transform_setcaps), (gst_base_transform_get_size), (gst_base_transform_buffer_alloc), (gst_base_transform_event), (gst_base_transform_handle_buffer), (gst_base_transform_set_passthrough), (gst_base_transform_is_passthrough): * gst/elements/gstfakesink.c: (gst_fake_sink_event): * gst/elements/gstfilesink.c: (gst_file_sink_event): Event updates. * gst/gstbuffer.h: Use faster casts. * gst/gstelement.c: (gst_element_seek): * gst/gstelement.h: Update gst_element_seek. * gst/gstevent.c: (gst_event_finalize), (_gst_event_copy), (gst_event_new), (gst_event_new_custom), (gst_event_get_structure), (gst_event_new_flush_start), (gst_event_new_flush_stop), (gst_event_new_eos), (gst_event_new_newsegment), (gst_event_parse_newsegment), (gst_event_new_tag), (gst_event_parse_tag), (gst_event_new_filler), (gst_event_new_qos), (gst_event_parse_qos), (gst_event_new_seek), (gst_event_parse_seek), (gst_event_new_navigation): * gst/gstevent.h: Make GstEvent use GstStructure. Add parsing code, make sure the API is sufficiently generic. Mark possible directions of events and serialization. * gst/gstmessage.c: (gst_message_init), (gst_message_finalize), (_gst_message_copy), (gst_message_new_segment_start), (gst_message_new_segment_done), (gst_message_new_custom), (gst_message_parse_segment_start), (gst_message_parse_segment_done): Small cleanups. * gst/gstpad.c: (gst_pad_get_caps_unlocked), (gst_pad_accept_caps), (gst_pad_set_caps), (gst_pad_send_event): Update for new events. Catch events sent in wrong directions. * gst/gstqueue.c: (gst_queue_link_src), (gst_queue_handle_sink_event), (gst_queue_chain), (gst_queue_loop), (gst_queue_handle_src_query): Event updates. * gst/gsttag.c: * gst/gsttag.h: Remove event code from this file. * libs/gst/dataprotocol/dataprotocol.c: (gst_dp_packet_from_event), (gst_dp_event_from_packet): Event updates.
2005-07-27 18:33:03 +00:00
gst_element_seek (GstElement * element, gdouble rate, GstFormat format,
GstSeekFlags flags, GstSeekType start_type, gint64 start,
Some docs updates Original commit message from CVS: * CHANGES-0.9: * docs/design/part-TODO.txt: * docs/design/part-events.txt: Some docs updates * gst/base/gstbasesink.c: (gst_base_sink_handle_object), (gst_base_sink_event), (gst_base_sink_do_sync), (gst_base_sink_activate_push), (gst_base_sink_activate_pull): * gst/base/gstbasesrc.c: (gst_base_src_send_discont), (gst_base_src_do_seek), (gst_base_src_event_handler), (gst_base_src_loop): * gst/base/gstbasetransform.c: (gst_base_transform_transform_caps), (gst_base_transform_configure_caps), (gst_base_transform_setcaps), (gst_base_transform_get_size), (gst_base_transform_buffer_alloc), (gst_base_transform_event), (gst_base_transform_handle_buffer), (gst_base_transform_set_passthrough), (gst_base_transform_is_passthrough): * gst/elements/gstfakesink.c: (gst_fake_sink_event): * gst/elements/gstfilesink.c: (gst_file_sink_event): Event updates. * gst/gstbuffer.h: Use faster casts. * gst/gstelement.c: (gst_element_seek): * gst/gstelement.h: Update gst_element_seek. * gst/gstevent.c: (gst_event_finalize), (_gst_event_copy), (gst_event_new), (gst_event_new_custom), (gst_event_get_structure), (gst_event_new_flush_start), (gst_event_new_flush_stop), (gst_event_new_eos), (gst_event_new_newsegment), (gst_event_parse_newsegment), (gst_event_new_tag), (gst_event_parse_tag), (gst_event_new_filler), (gst_event_new_qos), (gst_event_parse_qos), (gst_event_new_seek), (gst_event_parse_seek), (gst_event_new_navigation): * gst/gstevent.h: Make GstEvent use GstStructure. Add parsing code, make sure the API is sufficiently generic. Mark possible directions of events and serialization. * gst/gstmessage.c: (gst_message_init), (gst_message_finalize), (_gst_message_copy), (gst_message_new_segment_start), (gst_message_new_segment_done), (gst_message_new_custom), (gst_message_parse_segment_start), (gst_message_parse_segment_done): Small cleanups. * gst/gstpad.c: (gst_pad_get_caps_unlocked), (gst_pad_accept_caps), (gst_pad_set_caps), (gst_pad_send_event): Update for new events. Catch events sent in wrong directions. * gst/gstqueue.c: (gst_queue_link_src), (gst_queue_handle_sink_event), (gst_queue_chain), (gst_queue_loop), (gst_queue_handle_src_query): Event updates. * gst/gsttag.c: * gst/gsttag.h: Remove event code from this file. * libs/gst/dataprotocol/dataprotocol.c: (gst_dp_packet_from_event), (gst_dp_event_from_packet): Event updates.
2005-07-27 18:33:03 +00:00
GstSeekType stop_type, gint64 stop)
{
GstEvent *event;
gboolean result;
g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
Some docs updates Original commit message from CVS: * CHANGES-0.9: * docs/design/part-TODO.txt: * docs/design/part-events.txt: Some docs updates * gst/base/gstbasesink.c: (gst_base_sink_handle_object), (gst_base_sink_event), (gst_base_sink_do_sync), (gst_base_sink_activate_push), (gst_base_sink_activate_pull): * gst/base/gstbasesrc.c: (gst_base_src_send_discont), (gst_base_src_do_seek), (gst_base_src_event_handler), (gst_base_src_loop): * gst/base/gstbasetransform.c: (gst_base_transform_transform_caps), (gst_base_transform_configure_caps), (gst_base_transform_setcaps), (gst_base_transform_get_size), (gst_base_transform_buffer_alloc), (gst_base_transform_event), (gst_base_transform_handle_buffer), (gst_base_transform_set_passthrough), (gst_base_transform_is_passthrough): * gst/elements/gstfakesink.c: (gst_fake_sink_event): * gst/elements/gstfilesink.c: (gst_file_sink_event): Event updates. * gst/gstbuffer.h: Use faster casts. * gst/gstelement.c: (gst_element_seek): * gst/gstelement.h: Update gst_element_seek. * gst/gstevent.c: (gst_event_finalize), (_gst_event_copy), (gst_event_new), (gst_event_new_custom), (gst_event_get_structure), (gst_event_new_flush_start), (gst_event_new_flush_stop), (gst_event_new_eos), (gst_event_new_newsegment), (gst_event_parse_newsegment), (gst_event_new_tag), (gst_event_parse_tag), (gst_event_new_filler), (gst_event_new_qos), (gst_event_parse_qos), (gst_event_new_seek), (gst_event_parse_seek), (gst_event_new_navigation): * gst/gstevent.h: Make GstEvent use GstStructure. Add parsing code, make sure the API is sufficiently generic. Mark possible directions of events and serialization. * gst/gstmessage.c: (gst_message_init), (gst_message_finalize), (_gst_message_copy), (gst_message_new_segment_start), (gst_message_new_segment_done), (gst_message_new_custom), (gst_message_parse_segment_start), (gst_message_parse_segment_done): Small cleanups. * gst/gstpad.c: (gst_pad_get_caps_unlocked), (gst_pad_accept_caps), (gst_pad_set_caps), (gst_pad_send_event): Update for new events. Catch events sent in wrong directions. * gst/gstqueue.c: (gst_queue_link_src), (gst_queue_handle_sink_event), (gst_queue_chain), (gst_queue_loop), (gst_queue_handle_src_query): Event updates. * gst/gsttag.c: * gst/gsttag.h: Remove event code from this file. * libs/gst/dataprotocol/dataprotocol.c: (gst_dp_packet_from_event), (gst_dp_event_from_packet): Event updates.
2005-07-27 18:33:03 +00:00
event =
gst_event_new_seek (rate, format, flags, start_type, start, stop_type,
stop);
result = gst_element_send_event (element, event);
return result;
}
static gboolean
gst_element_default_query (GstElement * element, GstQuery * query)
{
gboolean result = FALSE;
GstPad *pad;
pad = gst_element_get_random_pad (element, FALSE, GST_PAD_SRC);
if (pad) {
result = gst_pad_query (pad, query);
gst_object_unref (pad);
} else {
pad = gst_element_get_random_pad (element, TRUE, GST_PAD_SINK);
if (pad) {
GstPad *peer = gst_pad_get_peer (pad);
if (peer) {
result = gst_pad_query (peer, query);
gst_object_unref (peer);
}
gst_object_unref (pad);
}
}
return result;
}
/**
* gst_element_query:
* @element: a #GstElement to perform the query on.
* @query: (transfer none): the #GstQuery.
*
* Performs a query on the given element.
*
* For elements that don't implement a query handler, this function
* forwards the query to a random srcpad or to the peer of a
* random linked sinkpad of this element.
*
* Please note that some queries might need a running pipeline to work.
*
* Returns: %TRUE if the query could be performed.
*
* MT safe.
*/
gboolean
gst_element_query (GstElement * element, GstQuery * query)
{
GstElementClass *klass;
gboolean res = FALSE;
g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
g_return_val_if_fail (query != NULL, FALSE);
GST_TRACER_ELEMENT_QUERY_PRE (element, query);
klass = GST_ELEMENT_GET_CLASS (element);
if (klass->query) {
GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "send query on element %s",
GST_ELEMENT_NAME (element));
res = klass->query (element, query);
}
GST_TRACER_ELEMENT_QUERY_POST (element, query, res);
return res;
}
static gboolean
gst_element_post_message_default (GstElement * element, GstMessage * message)
{
GstBus *bus;
gboolean result = FALSE;
g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
g_return_val_if_fail (message != NULL, FALSE);
GST_OBJECT_LOCK (element);
bus = element->bus;
if (G_UNLIKELY (bus == NULL))
goto no_bus;
gst_object_ref (bus);
GST_OBJECT_UNLOCK (element);
/* we release the element lock when posting the message so that any
* (synchronous) message handlers can operate on the element */
result = gst_bus_post (bus, message);
gst_object_unref (bus);
return result;
/* ERRORS */
no_bus:
{
GST_CAT_DEBUG_OBJECT (GST_CAT_MESSAGE, element,
"not posting message %p: no bus", message);
GST_OBJECT_UNLOCK (element);
gst_message_unref (message);
return FALSE;
}
}
/**
* gst_element_post_message:
* @element: a #GstElement posting the message
* @message: (transfer full): a #GstMessage to post
*
* Post a message on the element's #GstBus. This function takes ownership of the
* message; if you want to access the message after this call, you should add an
* additional reference before calling.
*
* Returns: %TRUE if the message was successfully posted. The function returns
* %FALSE if the element did not have a bus.
*
* MT safe.
*/
gboolean
gst_element_post_message (GstElement * element, GstMessage * message)
{
GstElementClass *klass;
gboolean res = FALSE;
g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
g_return_val_if_fail (message != NULL, FALSE);
GST_TRACER_ELEMENT_POST_MESSAGE_PRE (element, message);
klass = GST_ELEMENT_GET_CLASS (element);
if (klass->post_message)
res = klass->post_message (element, message);
else
gst_message_unref (message);
GST_TRACER_ELEMENT_POST_MESSAGE_POST (element, res);
return res;
}
/**
* _gst_element_error_printf:
* @format: (allow-none): the printf-like format to use, or %NULL
*
* This function is only used internally by the gst_element_error() macro.
*
* Returns: (transfer full) (nullable): a newly allocated string, or
* %NULL if the format was %NULL or ""
*
* MT safe.
*/
gchar *
_gst_element_error_printf (const gchar * format, ...)
{
va_list args;
gchar *buffer;
int len;
if (format == NULL)
return NULL;
if (format[0] == 0)
return NULL;
va_start (args, format);
len = __gst_vasprintf (&buffer, format, args);
va_end (args);
if (len < 0)
buffer = NULL;
return buffer;
}
/**
* gst_element_message_full_with_details:
* @element: a #GstElement to send message from
* @type: the #GstMessageType
* @domain: the GStreamer GError domain this message belongs to
* @code: the GError code belonging to the domain
* @text: (allow-none) (transfer full): an allocated text string to be used
* as a replacement for the default message connected to code,
* or %NULL
* @debug: (allow-none) (transfer full): an allocated debug message to be
* used as a replacement for the default debugging information,
* or %NULL
* @file: the source code file where the error was generated
* @function: the source code function where the error was generated
* @line: the source code line where the error was generated
* @structure:(transfer full): optional details structure
*
* Post an error, warning or info message on the bus from inside an element.
*
* @type must be of #GST_MESSAGE_ERROR, #GST_MESSAGE_WARNING or
* #GST_MESSAGE_INFO.
*
* Since: 1.10
*/
void gst_element_message_full_with_details
(GstElement * element, GstMessageType type,
GQuark domain, gint code, gchar * text,
gchar * debug, const gchar * file, const gchar * function, gint line,
GstStructure * structure)
{
GError *gerror = NULL;
gchar *name;
gchar *sent_text;
gchar *sent_debug;
gboolean has_debug = TRUE;
GstMessage *message = NULL;
/* checks */
GST_CAT_DEBUG_OBJECT (GST_CAT_MESSAGE, element, "start");
This is an attempt at not segfaulting on errors but reporting some usefull info instead. Original commit message from CVS: This is an attempt at not segfaulting on errors but reporting some usefull info instead. - bin changes so errors can propagate. - changed the _FAST macros to _CAST because that is what they do. - removed all references to cothreads out of the core, they are really a scheduler issue, handler with a sched_private gpointer. - added a live buffer count, for debugging buffer leaks. - added error checking in gst_scheduler_state_transition this solves the "out of cothreads" problem. - GST_ELEMENT_NO_ENTRY == GST_ELEMENT_INFINITE_LOOP - added 2 private element flasg for use by the scheduler (_COTHREAD_STOPPING) is now - added scheduler entry points: - _yield : to create possible scheduling points. - _interrupt: to stop execution of an element. - _error: to signal en error condition to the scheduler. - improved error messages for pads. - signal gst_element_error where appropriate. - added the a new bin to the parent before entering it so one can reference its children. - queue memleak fixes on dispose. - added possible deadlock detection in queue (turned off be default) - GstBasicScheduler is a real class of its own now, hiding its internal variables. - GST_ELEMENT_IS_COTHREAD_STOPPING is gone. either call explicit _yield operations, or make a sane loop. - Better state change handling in filesrc. Better error reporting/recovery too. - updated core plugins. - detect non decoupled elements on scheduler boundries and error.
2001-12-22 21:18:17 +00:00
g_return_if_fail (GST_IS_ELEMENT (element));
g_return_if_fail ((type == GST_MESSAGE_ERROR) ||
(type == GST_MESSAGE_WARNING) || (type == GST_MESSAGE_INFO));
/* check if we send the given text or the default error text */
if ((text == NULL) || (text[0] == 0)) {
/* text could have come from g_strdup_printf (""); */
g_free (text);
sent_text = gst_error_get_message (domain, code);
} else
sent_text = text;
This is an attempt at not segfaulting on errors but reporting some usefull info instead. Original commit message from CVS: This is an attempt at not segfaulting on errors but reporting some usefull info instead. - bin changes so errors can propagate. - changed the _FAST macros to _CAST because that is what they do. - removed all references to cothreads out of the core, they are really a scheduler issue, handler with a sched_private gpointer. - added a live buffer count, for debugging buffer leaks. - added error checking in gst_scheduler_state_transition this solves the "out of cothreads" problem. - GST_ELEMENT_NO_ENTRY == GST_ELEMENT_INFINITE_LOOP - added 2 private element flasg for use by the scheduler (_COTHREAD_STOPPING) is now - added scheduler entry points: - _yield : to create possible scheduling points. - _interrupt: to stop execution of an element. - _error: to signal en error condition to the scheduler. - improved error messages for pads. - signal gst_element_error where appropriate. - added the a new bin to the parent before entering it so one can reference its children. - queue memleak fixes on dispose. - added possible deadlock detection in queue (turned off be default) - GstBasicScheduler is a real class of its own now, hiding its internal variables. - GST_ELEMENT_IS_COTHREAD_STOPPING is gone. either call explicit _yield operations, or make a sane loop. - Better state change handling in filesrc. Better error reporting/recovery too. - updated core plugins. - detect non decoupled elements on scheduler boundries and error.
2001-12-22 21:18:17 +00:00
/* construct a sent_debug with extra information from source */
if ((debug == NULL) || (debug[0] == 0)) {
/* debug could have come from g_strdup_printf (""); */
has_debug = FALSE;
}
name = gst_object_get_path_string (GST_OBJECT_CAST (element));
if (has_debug)
sent_debug = g_strdup_printf ("%s(%d): %s (): %s:\n%s",
file, line, function, name, debug);
else
sent_debug = g_strdup_printf ("%s(%d): %s (): %s",
file, line, function, name);
g_free (name);
g_free (debug);
This is an attempt at not segfaulting on errors but reporting some usefull info instead. Original commit message from CVS: This is an attempt at not segfaulting on errors but reporting some usefull info instead. - bin changes so errors can propagate. - changed the _FAST macros to _CAST because that is what they do. - removed all references to cothreads out of the core, they are really a scheduler issue, handler with a sched_private gpointer. - added a live buffer count, for debugging buffer leaks. - added error checking in gst_scheduler_state_transition this solves the "out of cothreads" problem. - GST_ELEMENT_NO_ENTRY == GST_ELEMENT_INFINITE_LOOP - added 2 private element flasg for use by the scheduler (_COTHREAD_STOPPING) is now - added scheduler entry points: - _yield : to create possible scheduling points. - _interrupt: to stop execution of an element. - _error: to signal en error condition to the scheduler. - improved error messages for pads. - signal gst_element_error where appropriate. - added the a new bin to the parent before entering it so one can reference its children. - queue memleak fixes on dispose. - added possible deadlock detection in queue (turned off be default) - GstBasicScheduler is a real class of its own now, hiding its internal variables. - GST_ELEMENT_IS_COTHREAD_STOPPING is gone. either call explicit _yield operations, or make a sane loop. - Better state change handling in filesrc. Better error reporting/recovery too. - updated core plugins. - detect non decoupled elements on scheduler boundries and error.
2001-12-22 21:18:17 +00:00
/* create gerror and post message */
GST_CAT_INFO_OBJECT (GST_CAT_ERROR_SYSTEM, element, "posting message: %s",
sent_text);
gerror = g_error_new_literal (domain, code, sent_text);
switch (type) {
case GST_MESSAGE_ERROR:
message =
gst_message_new_error_with_details (GST_OBJECT_CAST (element), gerror,
sent_debug, structure);
break;
case GST_MESSAGE_WARNING:
message =
gst_message_new_warning_with_details (GST_OBJECT_CAST (element),
gerror, sent_debug, structure);
break;
case GST_MESSAGE_INFO:
message =
gst_message_new_info_with_details (GST_OBJECT_CAST (element), gerror,
sent_debug, structure);
break;
default:
g_assert_not_reached ();
break;
}
gst_element_post_message (element, message);
GST_CAT_INFO_OBJECT (GST_CAT_ERROR_SYSTEM, element, "posted %s message: %s",
(type == GST_MESSAGE_ERROR ? "error" : "warning"), sent_text);
/* cleanup */
g_error_free (gerror);
g_free (sent_debug);
g_free (sent_text);
}
/**
* gst_element_message_full:
* @element: a #GstElement to send message from
* @type: the #GstMessageType
* @domain: the GStreamer GError domain this message belongs to
* @code: the GError code belonging to the domain
* @text: (allow-none) (transfer full): an allocated text string to be used
* as a replacement for the default message connected to code,
* or %NULL
* @debug: (allow-none) (transfer full): an allocated debug message to be
* used as a replacement for the default debugging information,
* or %NULL
* @file: the source code file where the error was generated
* @function: the source code function where the error was generated
* @line: the source code line where the error was generated
*
* Post an error, warning or info message on the bus from inside an element.
*
* @type must be of #GST_MESSAGE_ERROR, #GST_MESSAGE_WARNING or
* #GST_MESSAGE_INFO.
*
* MT safe.
*/
void gst_element_message_full
(GstElement * element, GstMessageType type,
GQuark domain, gint code, gchar * text,
gchar * debug, const gchar * file, const gchar * function, gint line)
{
gst_element_message_full_with_details (element, type, domain, code, text,
debug, file, function, line, NULL);
}
/**
* gst_element_is_locked_state:
* @element: a #GstElement.
*
* Checks if the state of an element is locked.
* If the state of an element is locked, state changes of the parent don't
* affect the element.
* This way you can leave currently unused elements inside bins. Just lock their
* state before changing the state from #GST_STATE_NULL.
*
* MT safe.
*
* Returns: %TRUE, if the element's state is locked.
*/
gboolean
gst_element_is_locked_state (GstElement * element)
{
gboolean result;
g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
GST_OBJECT_LOCK (element);
result = GST_ELEMENT_IS_LOCKED_STATE (element);
GST_OBJECT_UNLOCK (element);
return result;
}
/**
* gst_element_set_locked_state:
* @element: a #GstElement
* @locked_state: %TRUE to lock the element's state
*
* Locks the state of an element, so state changes of the parent don't affect
* this element anymore.
*
* MT safe.
*
* Returns: %TRUE if the state was changed, %FALSE if bad parameters were given
* or the elements state-locking needed no change.
*/
gboolean
gst_element_set_locked_state (GstElement * element, gboolean locked_state)
{
gboolean old;
g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
GST_OBJECT_LOCK (element);
old = GST_ELEMENT_IS_LOCKED_STATE (element);
if (G_UNLIKELY (old == locked_state))
goto was_ok;
if (locked_state) {
GST_CAT_DEBUG (GST_CAT_STATES, "locking state of element %s",
GST_ELEMENT_NAME (element));
GST_OBJECT_FLAG_SET (element, GST_ELEMENT_FLAG_LOCKED_STATE);
} else {
GST_CAT_DEBUG (GST_CAT_STATES, "unlocking state of element %s",
GST_ELEMENT_NAME (element));
GST_OBJECT_FLAG_UNSET (element, GST_ELEMENT_FLAG_LOCKED_STATE);
}
GST_OBJECT_UNLOCK (element);
return TRUE;
was_ok:
{
GST_CAT_DEBUG (GST_CAT_STATES,
"elements %s was already in locked state %d",
GST_ELEMENT_NAME (element), old);
GST_OBJECT_UNLOCK (element);
return FALSE;
}
}
/**
* gst_element_sync_state_with_parent:
* @element: a #GstElement.
*
* Tries to change the state of the element to the same as its parent.
* If this function returns %FALSE, the state of element is undefined.
*
* Returns: %TRUE, if the element's state could be synced to the parent's state.
*
* MT safe.
*/
gboolean
gst_element_sync_state_with_parent (GstElement * element)
{
GstElement *parent;
GstState target;
GstStateChangeReturn ret;
g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE);
if ((parent = GST_ELEMENT_CAST (gst_element_get_parent (element)))) {
GstState parent_current, parent_pending;
GST_OBJECT_LOCK (parent);
parent_current = GST_STATE (parent);
parent_pending = GST_STATE_PENDING (parent);
GST_OBJECT_UNLOCK (parent);
/* set to pending if there is one, else we set it to the current state of
* the parent */
if (parent_pending != GST_STATE_VOID_PENDING)
target = parent_pending;
else
target = parent_current;
GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
"syncing state (%s) to parent %s %s (%s, %s)",
gst_element_state_get_name (GST_STATE (element)),
GST_ELEMENT_NAME (parent), gst_element_state_get_name (target),
gst_element_state_get_name (parent_current),
gst_element_state_get_name (parent_pending));
ret = gst_element_set_state (element, target);
if (ret == GST_STATE_CHANGE_FAILURE)
goto failed;
gst_object_unref (parent);
return TRUE;
} else {
GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element, "element has no parent");
}
return FALSE;
/* ERROR */
failed:
{
GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
"syncing state failed (%s)",
gst_element_state_change_return_get_name (ret));
gst_object_unref (parent);
return FALSE;
}
}
/* MT safe */
static GstStateChangeReturn
gst_element_get_state_func (GstElement * element,
GstState * state, GstState * pending, GstClockTime timeout)
{
GstStateChangeReturn ret = GST_STATE_CHANGE_FAILURE;
GstState old_pending;
GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element, "getting state, timeout %"
GST_TIME_FORMAT, GST_TIME_ARGS (timeout));
GST_OBJECT_LOCK (element);
2005-10-10 16:38:26 +00:00
ret = GST_STATE_RETURN (element);
GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element, "RETURN is %s",
gst_element_state_change_return_get_name (ret));
2005-10-10 16:38:26 +00:00
2010-03-04 14:21:37 +00:00
/* we got an error, report immediately */
2005-10-10 16:38:26 +00:00
if (ret == GST_STATE_CHANGE_FAILURE)
goto done;
/* we got no_preroll, report immediately */
2005-10-10 16:38:26 +00:00
if (ret == GST_STATE_CHANGE_NO_PREROLL)
goto done;
/* no need to wait async if we are not async */
if (ret != GST_STATE_CHANGE_ASYNC)
goto done;
old_pending = GST_STATE_PENDING (element);
if (old_pending != GST_STATE_VOID_PENDING) {
2012-01-19 08:27:04 +00:00
gboolean signaled;
guint32 cookie;
2009-05-25 16:44:14 +00:00
/* get cookie to detect state changes during waiting */
cookie = element->state_cookie;
GST_CAT_INFO_OBJECT (GST_CAT_STATES, element,
"waiting for element to commit state");
/* we have a pending state change, wait for it to complete */
2012-01-19 08:27:04 +00:00
if (timeout != GST_CLOCK_TIME_NONE) {
gint64 end_time;
/* make timeout absolute */
end_time = g_get_monotonic_time () + (timeout / 1000);
signaled = GST_STATE_WAIT_UNTIL (element, end_time);
} else {
GST_STATE_WAIT (element);
signaled = TRUE;
}
if (!signaled) {
GST_CAT_INFO_OBJECT (GST_CAT_STATES, element, "timed out");
/* timeout triggered */
ret = GST_STATE_CHANGE_ASYNC;
} else {
if (cookie != element->state_cookie)
goto interrupted;
/* could be success or failure */
if (old_pending == GST_STATE (element)) {
GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element, "got success");
ret = GST_STATE_CHANGE_SUCCESS;
} else {
GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element, "got failure");
ret = GST_STATE_CHANGE_FAILURE;
}
}
2007-06-18 15:12:28 +00:00
/* if nothing is pending anymore we can return SUCCESS */
if (GST_STATE_PENDING (element) == GST_STATE_VOID_PENDING) {
GST_CAT_LOG_OBJECT (GST_CAT_STATES, element, "nothing pending");
ret = GST_STATE_CHANGE_SUCCESS;
}
}
done:
if (state)
*state = GST_STATE (element);
if (pending)
*pending = GST_STATE_PENDING (element);
GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
"state current: %s, pending: %s, result: %s",
gst_element_state_get_name (GST_STATE (element)),
gst_element_state_get_name (GST_STATE_PENDING (element)),
gst_element_state_change_return_get_name (ret));
GST_OBJECT_UNLOCK (element);
return ret;
interrupted:
{
if (state)
*state = GST_STATE_VOID_PENDING;
if (pending)
*pending = GST_STATE_VOID_PENDING;
GST_CAT_INFO_OBJECT (GST_CAT_STATES, element, "interrupted");
GST_OBJECT_UNLOCK (element);
return GST_STATE_CHANGE_FAILURE;
}
}
/**
* gst_element_get_state:
* @element: a #GstElement to get the state of.
* @state: (out) (allow-none): a pointer to #GstState to hold the state.
* Can be %NULL.
* @pending: (out) (allow-none): a pointer to #GstState to hold the pending
* state. Can be %NULL.
* @timeout: a #GstClockTime to specify the timeout for an async
* state change or %GST_CLOCK_TIME_NONE for infinite timeout.
*
* Gets the state of the element.
*
* For elements that performed an ASYNC state change, as reported by
* gst_element_set_state(), this function will block up to the
* specified timeout value for the state change to complete.
* If the element completes the state change or goes into
* an error, this function returns immediately with a return value of
* %GST_STATE_CHANGE_SUCCESS or %GST_STATE_CHANGE_FAILURE respectively.
*
* For elements that did not return %GST_STATE_CHANGE_ASYNC, this function
* returns the current and pending state immediately.
*
* This function returns %GST_STATE_CHANGE_NO_PREROLL if the element
* successfully changed its state but is not able to provide data yet.
2011-05-02 12:48:01 +00:00
* This mostly happens for live sources that only produce data in
* %GST_STATE_PLAYING. While the state change return is equivalent to
* %GST_STATE_CHANGE_SUCCESS, it is returned to the application to signal that
* some sink elements might not be able to complete their state change because
* an element is not producing data to complete the preroll. When setting the
* element to playing, the preroll will complete and playback will start.
*
* Returns: %GST_STATE_CHANGE_SUCCESS if the element has no more pending state
* and the last state change succeeded, %GST_STATE_CHANGE_ASYNC if the
* element is still performing a state change or
* %GST_STATE_CHANGE_FAILURE if the last state change failed.
*
* MT safe.
*/
GstStateChangeReturn
gst_element_get_state (GstElement * element,
GstState * state, GstState * pending, GstClockTime timeout)
{
GstElementClass *oclass;
GstStateChangeReturn result = GST_STATE_CHANGE_FAILURE;
g_return_val_if_fail (GST_IS_ELEMENT (element), GST_STATE_CHANGE_FAILURE);
oclass = GST_ELEMENT_GET_CLASS (element);
if (oclass->get_state)
result = (oclass->get_state) (element, state, pending, timeout);
return result;
}
/**
* gst_element_abort_state:
* @element: a #GstElement to abort the state of.
*
* Abort the state change of the element. This function is used
* by elements that do asynchronous state changes and find out
* something is wrong.
*
* This function should be called with the STATE_LOCK held.
*
* MT safe.
*/
void
gst_element_abort_state (GstElement * element)
{
GstState pending;
#ifndef GST_DISABLE_GST_DEBUG
GstState old_state;
#endif
g_return_if_fail (GST_IS_ELEMENT (element));
GST_OBJECT_LOCK (element);
pending = GST_STATE_PENDING (element);
if (pending == GST_STATE_VOID_PENDING ||
GST_STATE_RETURN (element) == GST_STATE_CHANGE_FAILURE)
goto nothing_aborted;
#ifndef GST_DISABLE_GST_DEBUG
old_state = GST_STATE (element);
GST_CAT_INFO_OBJECT (GST_CAT_STATES, element,
"aborting state from %s to %s", gst_element_state_get_name (old_state),
gst_element_state_get_name (pending));
#endif
/* flag error */
GST_STATE_RETURN (element) = GST_STATE_CHANGE_FAILURE;
GST_STATE_BROADCAST (element);
GST_OBJECT_UNLOCK (element);
return;
nothing_aborted:
{
GST_OBJECT_UNLOCK (element);
return;
}
}
/* Not static because GstBin has manual state handling too */
void
_priv_gst_element_state_changed (GstElement * element, GstState oldstate,
GstState newstate, GstState pending)
{
GstElementClass *klass = GST_ELEMENT_GET_CLASS (element);
GstMessage *message;
GST_CAT_INFO_OBJECT (GST_CAT_STATES, element,
"notifying about state-changed %s to %s (%s pending)",
gst_element_state_get_name (oldstate),
gst_element_state_get_name (newstate),
gst_element_state_get_name (pending));
if (klass->state_changed)
klass->state_changed (element, oldstate, newstate, pending);
message = gst_message_new_state_changed (GST_OBJECT_CAST (element),
oldstate, newstate, pending);
gst_element_post_message (element, message);
}
/**
* gst_element_continue_state:
* @element: a #GstElement to continue the state change of.
* @ret: The previous state return value
*
* Commit the state change of the element and proceed to the next
* pending state if any. This function is used
* by elements that do asynchronous state changes.
* The core will normally call this method automatically when an
* element returned %GST_STATE_CHANGE_SUCCESS from the state change function.
*
* If after calling this method the element still has not reached
* the pending state, the next state change is performed.
*
* This method is used internally and should normally not be called by plugins
* or applications.
*
* This function must be called with STATE_LOCK held.
*
* Returns: The result of the commit state change.
*
* MT safe.
*/
2005-10-10 16:38:26 +00:00
GstStateChangeReturn
gst_element_continue_state (GstElement * element, GstStateChangeReturn ret)
{
docs/gst/gstreamer-sections.txt: Add new element field and method. Original commit message from CVS: * docs/gst/gstreamer-sections.txt: Add new element field and method. * gst/gstbin.c: (gst_bin_class_init), (gst_bin_init), (bin_remove_messages), (gst_bin_add_func), (gst_bin_remove_func), (gst_bin_recalc_state), (gst_bin_get_state_func), (gst_bin_element_set_state), (gst_bin_change_state_func), (gst_bin_continue_func), (bin_bus_handler), (bin_push_state_continue), (bin_handle_async_start), (bin_handle_async_done), (gst_bin_handle_message_func): Make async state changes a bit smarter by using new ASYNC_START and ASYNC_DONE messages. This reduces the number of times we run the state recalculation thread. Don't change state of element with a pending ASYNC_START message. Deprecate STATE_DIRTY messages. * gst/gstelement.c: (gst_element_init), (gst_element_send_event), (gst_element_get_state_func), (gst_element_continue_state), (gst_element_lost_state), (gst_element_set_state_func), (gst_element_change_state): * gst/gstelement.h: Keep the state that was last set by the app in a new element field. Don't allow state changes when handling an element event. Post ASYNC_START and ASYNC_DONE messages. Change lost_state so that we go to PAUSED and wait for the parent to set us to PLAYING again (so latency calculation can be performed) Export gst_element_change_state() method so that subclasses can use it. API: gst_element_change_state() API: GST_STATE_TARGET * gst/gstpipeline.c: (gst_pipeline_class_init), (reset_stream_time), (gst_pipeline_change_state), (gst_pipeline_handle_message), (gst_pipeline_set_new_stream_time): Using the new ASYNC_START message we can reset the base_time when needed. This can then be used to implement base_time redistribution in flushing seeks so that we can remove the explicit seek handling. Perform latency query and configuration when going to PLAYING. * libs/gst/base/gstbasesink.c: (gst_base_sink_commit_state), (gst_base_sink_query), (gst_base_sink_change_state): Post new ASYNC_START/ASYNC_DONE messages. * tests/check/generic/sinks.c: (GST_START_TEST): Fix test because the bin will not set the async element to PLAYING right away. * tests/check/gst/gstbin.c: (pop_async_done), (GST_START_TEST): Make the message check a little stronger. Handle ASYNC messages. * tests/check/pipelines/cleanup.c: (GST_START_TEST): * tests/check/pipelines/simple-launch-lines.c: (GST_START_TEST): Expect ASYNC_DONE messages.
2007-03-19 10:47:56 +00:00
GstStateChangeReturn old_ret;
GstState old_state, old_next;
GstState current, next, pending;
GstStateChange transition;
GST_OBJECT_LOCK (element);
docs/gst/gstreamer-sections.txt: Add new element field and method. Original commit message from CVS: * docs/gst/gstreamer-sections.txt: Add new element field and method. * gst/gstbin.c: (gst_bin_class_init), (gst_bin_init), (bin_remove_messages), (gst_bin_add_func), (gst_bin_remove_func), (gst_bin_recalc_state), (gst_bin_get_state_func), (gst_bin_element_set_state), (gst_bin_change_state_func), (gst_bin_continue_func), (bin_bus_handler), (bin_push_state_continue), (bin_handle_async_start), (bin_handle_async_done), (gst_bin_handle_message_func): Make async state changes a bit smarter by using new ASYNC_START and ASYNC_DONE messages. This reduces the number of times we run the state recalculation thread. Don't change state of element with a pending ASYNC_START message. Deprecate STATE_DIRTY messages. * gst/gstelement.c: (gst_element_init), (gst_element_send_event), (gst_element_get_state_func), (gst_element_continue_state), (gst_element_lost_state), (gst_element_set_state_func), (gst_element_change_state): * gst/gstelement.h: Keep the state that was last set by the app in a new element field. Don't allow state changes when handling an element event. Post ASYNC_START and ASYNC_DONE messages. Change lost_state so that we go to PAUSED and wait for the parent to set us to PLAYING again (so latency calculation can be performed) Export gst_element_change_state() method so that subclasses can use it. API: gst_element_change_state() API: GST_STATE_TARGET * gst/gstpipeline.c: (gst_pipeline_class_init), (reset_stream_time), (gst_pipeline_change_state), (gst_pipeline_handle_message), (gst_pipeline_set_new_stream_time): Using the new ASYNC_START message we can reset the base_time when needed. This can then be used to implement base_time redistribution in flushing seeks so that we can remove the explicit seek handling. Perform latency query and configuration when going to PLAYING. * libs/gst/base/gstbasesink.c: (gst_base_sink_commit_state), (gst_base_sink_query), (gst_base_sink_change_state): Post new ASYNC_START/ASYNC_DONE messages. * tests/check/generic/sinks.c: (GST_START_TEST): Fix test because the bin will not set the async element to PLAYING right away. * tests/check/gst/gstbin.c: (pop_async_done), (GST_START_TEST): Make the message check a little stronger. Handle ASYNC messages. * tests/check/pipelines/cleanup.c: (GST_START_TEST): * tests/check/pipelines/simple-launch-lines.c: (GST_START_TEST): Expect ASYNC_DONE messages.
2007-03-19 10:47:56 +00:00
old_ret = GST_STATE_RETURN (element);
GST_STATE_RETURN (element) = ret;
pending = GST_STATE_PENDING (element);
2005-10-10 16:38:26 +00:00
/* check if there is something to commit */
if (pending == GST_STATE_VOID_PENDING)
goto nothing_pending;
old_state = GST_STATE (element);
/* this is the state we should go to next */
old_next = GST_STATE_NEXT (element);
/* update current state */
current = GST_STATE (element) = old_next;
2005-10-10 16:38:26 +00:00
/* see if we reached the final state */
if (pending == current)
goto complete;
2005-10-10 16:38:26 +00:00
next = GST_STATE_GET_NEXT (current, pending);
transition = (GstStateChange) GST_STATE_TRANSITION (current, next);
GST_STATE_NEXT (element) = next;
/* mark busy */
GST_STATE_RETURN (element) = GST_STATE_CHANGE_ASYNC;
GST_OBJECT_UNLOCK (element);
2005-10-10 16:38:26 +00:00
GST_CAT_INFO_OBJECT (GST_CAT_STATES, element,
"committing state from %s to %s, pending %s, next %s",
gst_element_state_get_name (old_state),
gst_element_state_get_name (old_next),
gst_element_state_get_name (pending), gst_element_state_get_name (next));
2005-10-10 16:38:26 +00:00
_priv_gst_element_state_changed (element, old_state, old_next, pending);
2005-10-10 16:38:26 +00:00
GST_CAT_INFO_OBJECT (GST_CAT_STATES, element,
"continue state change %s to %s, final %s",
gst_element_state_get_name (current),
gst_element_state_get_name (next), gst_element_state_get_name (pending));
2005-10-10 16:38:26 +00:00
ret = gst_element_change_state (element, transition);
2005-10-10 16:38:26 +00:00
return ret;
nothing_pending:
{
GST_CAT_INFO_OBJECT (GST_CAT_STATES, element, "nothing pending");
GST_OBJECT_UNLOCK (element);
return ret;
}
complete:
{
GST_STATE_PENDING (element) = GST_STATE_VOID_PENDING;
GST_STATE_NEXT (element) = GST_STATE_VOID_PENDING;
docs/gst/gstreamer-sections.txt: Add new element field and method. Original commit message from CVS: * docs/gst/gstreamer-sections.txt: Add new element field and method. * gst/gstbin.c: (gst_bin_class_init), (gst_bin_init), (bin_remove_messages), (gst_bin_add_func), (gst_bin_remove_func), (gst_bin_recalc_state), (gst_bin_get_state_func), (gst_bin_element_set_state), (gst_bin_change_state_func), (gst_bin_continue_func), (bin_bus_handler), (bin_push_state_continue), (bin_handle_async_start), (bin_handle_async_done), (gst_bin_handle_message_func): Make async state changes a bit smarter by using new ASYNC_START and ASYNC_DONE messages. This reduces the number of times we run the state recalculation thread. Don't change state of element with a pending ASYNC_START message. Deprecate STATE_DIRTY messages. * gst/gstelement.c: (gst_element_init), (gst_element_send_event), (gst_element_get_state_func), (gst_element_continue_state), (gst_element_lost_state), (gst_element_set_state_func), (gst_element_change_state): * gst/gstelement.h: Keep the state that was last set by the app in a new element field. Don't allow state changes when handling an element event. Post ASYNC_START and ASYNC_DONE messages. Change lost_state so that we go to PAUSED and wait for the parent to set us to PLAYING again (so latency calculation can be performed) Export gst_element_change_state() method so that subclasses can use it. API: gst_element_change_state() API: GST_STATE_TARGET * gst/gstpipeline.c: (gst_pipeline_class_init), (reset_stream_time), (gst_pipeline_change_state), (gst_pipeline_handle_message), (gst_pipeline_set_new_stream_time): Using the new ASYNC_START message we can reset the base_time when needed. This can then be used to implement base_time redistribution in flushing seeks so that we can remove the explicit seek handling. Perform latency query and configuration when going to PLAYING. * libs/gst/base/gstbasesink.c: (gst_base_sink_commit_state), (gst_base_sink_query), (gst_base_sink_change_state): Post new ASYNC_START/ASYNC_DONE messages. * tests/check/generic/sinks.c: (GST_START_TEST): Fix test because the bin will not set the async element to PLAYING right away. * tests/check/gst/gstbin.c: (pop_async_done), (GST_START_TEST): Make the message check a little stronger. Handle ASYNC messages. * tests/check/pipelines/cleanup.c: (GST_START_TEST): * tests/check/pipelines/simple-launch-lines.c: (GST_START_TEST): Expect ASYNC_DONE messages.
2007-03-19 10:47:56 +00:00
GST_CAT_INFO_OBJECT (GST_CAT_STATES, element,
"completed state change to %s", gst_element_state_get_name (pending));
GST_OBJECT_UNLOCK (element);
/* don't post silly messages with the same state. This can happen
* when an element state is changed to what it already was. For bins
* this can be the result of a lost state, which we check with the
* previous return value.
* We do signal the cond though as a _get_state() might be blocking
* on it. */
if (old_state != old_next || old_ret == GST_STATE_CHANGE_ASYNC)
_priv_gst_element_state_changed (element, old_state, old_next,
GST_STATE_VOID_PENDING);
GST_STATE_BROADCAST (element);
return ret;
}
}
/**
* gst_element_lost_state:
* @element: a #GstElement the state is lost of
*
* Brings the element to the lost state. The current state of the
* element is copied to the pending state so that any call to
* gst_element_get_state() will return %GST_STATE_CHANGE_ASYNC.
*
* An ASYNC_START message is posted. If the element was PLAYING, it will
* go to PAUSED. The element will be restored to its PLAYING state by
* the parent pipeline when it prerolls again.
docs/gst/gstreamer-sections.txt: Add new element field and method. Original commit message from CVS: * docs/gst/gstreamer-sections.txt: Add new element field and method. * gst/gstbin.c: (gst_bin_class_init), (gst_bin_init), (bin_remove_messages), (gst_bin_add_func), (gst_bin_remove_func), (gst_bin_recalc_state), (gst_bin_get_state_func), (gst_bin_element_set_state), (gst_bin_change_state_func), (gst_bin_continue_func), (bin_bus_handler), (bin_push_state_continue), (bin_handle_async_start), (bin_handle_async_done), (gst_bin_handle_message_func): Make async state changes a bit smarter by using new ASYNC_START and ASYNC_DONE messages. This reduces the number of times we run the state recalculation thread. Don't change state of element with a pending ASYNC_START message. Deprecate STATE_DIRTY messages. * gst/gstelement.c: (gst_element_init), (gst_element_send_event), (gst_element_get_state_func), (gst_element_continue_state), (gst_element_lost_state), (gst_element_set_state_func), (gst_element_change_state): * gst/gstelement.h: Keep the state that was last set by the app in a new element field. Don't allow state changes when handling an element event. Post ASYNC_START and ASYNC_DONE messages. Change lost_state so that we go to PAUSED and wait for the parent to set us to PLAYING again (so latency calculation can be performed) Export gst_element_change_state() method so that subclasses can use it. API: gst_element_change_state() API: GST_STATE_TARGET * gst/gstpipeline.c: (gst_pipeline_class_init), (reset_stream_time), (gst_pipeline_change_state), (gst_pipeline_handle_message), (gst_pipeline_set_new_stream_time): Using the new ASYNC_START message we can reset the base_time when needed. This can then be used to implement base_time redistribution in flushing seeks so that we can remove the explicit seek handling. Perform latency query and configuration when going to PLAYING. * libs/gst/base/gstbasesink.c: (gst_base_sink_commit_state), (gst_base_sink_query), (gst_base_sink_change_state): Post new ASYNC_START/ASYNC_DONE messages. * tests/check/generic/sinks.c: (GST_START_TEST): Fix test because the bin will not set the async element to PLAYING right away. * tests/check/gst/gstbin.c: (pop_async_done), (GST_START_TEST): Make the message check a little stronger. Handle ASYNC messages. * tests/check/pipelines/cleanup.c: (GST_START_TEST): * tests/check/pipelines/simple-launch-lines.c: (GST_START_TEST): Expect ASYNC_DONE messages.
2007-03-19 10:47:56 +00:00
*
* This is mostly used for elements that lost their preroll buffer
docs/gst/gstreamer-sections.txt: Add new element field and method. Original commit message from CVS: * docs/gst/gstreamer-sections.txt: Add new element field and method. * gst/gstbin.c: (gst_bin_class_init), (gst_bin_init), (bin_remove_messages), (gst_bin_add_func), (gst_bin_remove_func), (gst_bin_recalc_state), (gst_bin_get_state_func), (gst_bin_element_set_state), (gst_bin_change_state_func), (gst_bin_continue_func), (bin_bus_handler), (bin_push_state_continue), (bin_handle_async_start), (bin_handle_async_done), (gst_bin_handle_message_func): Make async state changes a bit smarter by using new ASYNC_START and ASYNC_DONE messages. This reduces the number of times we run the state recalculation thread. Don't change state of element with a pending ASYNC_START message. Deprecate STATE_DIRTY messages. * gst/gstelement.c: (gst_element_init), (gst_element_send_event), (gst_element_get_state_func), (gst_element_continue_state), (gst_element_lost_state), (gst_element_set_state_func), (gst_element_change_state): * gst/gstelement.h: Keep the state that was last set by the app in a new element field. Don't allow state changes when handling an element event. Post ASYNC_START and ASYNC_DONE messages. Change lost_state so that we go to PAUSED and wait for the parent to set us to PLAYING again (so latency calculation can be performed) Export gst_element_change_state() method so that subclasses can use it. API: gst_element_change_state() API: GST_STATE_TARGET * gst/gstpipeline.c: (gst_pipeline_class_init), (reset_stream_time), (gst_pipeline_change_state), (gst_pipeline_handle_message), (gst_pipeline_set_new_stream_time): Using the new ASYNC_START message we can reset the base_time when needed. This can then be used to implement base_time redistribution in flushing seeks so that we can remove the explicit seek handling. Perform latency query and configuration when going to PLAYING. * libs/gst/base/gstbasesink.c: (gst_base_sink_commit_state), (gst_base_sink_query), (gst_base_sink_change_state): Post new ASYNC_START/ASYNC_DONE messages. * tests/check/generic/sinks.c: (GST_START_TEST): Fix test because the bin will not set the async element to PLAYING right away. * tests/check/gst/gstbin.c: (pop_async_done), (GST_START_TEST): Make the message check a little stronger. Handle ASYNC messages. * tests/check/pipelines/cleanup.c: (GST_START_TEST): * tests/check/pipelines/simple-launch-lines.c: (GST_START_TEST): Expect ASYNC_DONE messages.
2007-03-19 10:47:56 +00:00
* in the %GST_STATE_PAUSED or %GST_STATE_PLAYING state after a flush,
* they will go to their pending state again when a new preroll buffer is
* queued. This function can only be called when the element is currently
* not in error or an async state change.
*
* This function is used internally and should normally not be called from
* plugins or applications.
*/
- some fixes to int2float making automake 1.5 happy (gst now requires automake1.5). It's still not perfect but it bui... Original commit message from CVS: - added playondemand plugin by Leif Morgan Johnson <lmjohns3@eos.ncsu.edu> - some fixes to int2float - aplied a patch from wrobell <wrobell@ite.pl> that is a first attempt at making automake 1.5 happy (gst now requires automake1.5). It's still not perfect but it builds. - Made the schedulers plugable. The default scheduler now lives inside a plugin. - Added a new mpeg1/2 parser/demuxer. - Fixed some compiler warnings in the core libs. - substantial work to GstThread (hopefully less race conditions). simplified the code in GstThread a bit. A state change can now also happen in the thread context. - reworked the state semantics of a bin. it'll now automatically get the highest state of its children. - the autoplugger now nests the threads so that a state change failure of one thread doesn't make its upstream thread lock. - GstQueue refuses to go to PLAYING if the sinkpad is not connected. This way the queue will not wedge in the _get lock. - GstQueue unlocks its mutexes when going to PAUSED. - make sure that when all elements in a bin/thread go to PAUSED, the bin is set to PAUSED too. - make a parent bin wait for its children to PAUSE before ending the iteration with FALSE (EOS) - Some changes to GstPlay to deal with EOS. - aplied the latest patch from Zeenix to gstrtp. end result: GstPlay doesn't crash on EOS and the pipeline is now shut down properly.
2001-12-04 22:12:50 +00:00
void
gst_element_lost_state (GstElement * element)
- some fixes to int2float making automake 1.5 happy (gst now requires automake1.5). It's still not perfect but it bui... Original commit message from CVS: - added playondemand plugin by Leif Morgan Johnson <lmjohns3@eos.ncsu.edu> - some fixes to int2float - aplied a patch from wrobell <wrobell@ite.pl> that is a first attempt at making automake 1.5 happy (gst now requires automake1.5). It's still not perfect but it builds. - Made the schedulers plugable. The default scheduler now lives inside a plugin. - Added a new mpeg1/2 parser/demuxer. - Fixed some compiler warnings in the core libs. - substantial work to GstThread (hopefully less race conditions). simplified the code in GstThread a bit. A state change can now also happen in the thread context. - reworked the state semantics of a bin. it'll now automatically get the highest state of its children. - the autoplugger now nests the threads so that a state change failure of one thread doesn't make its upstream thread lock. - GstQueue refuses to go to PLAYING if the sinkpad is not connected. This way the queue will not wedge in the _get lock. - GstQueue unlocks its mutexes when going to PAUSED. - make sure that when all elements in a bin/thread go to PAUSED, the bin is set to PAUSED too. - make a parent bin wait for its children to PAUSE before ending the iteration with FALSE (EOS) - Some changes to GstPlay to deal with EOS. - aplied the latest patch from Zeenix to gstrtp. end result: GstPlay doesn't crash on EOS and the pipeline is now shut down properly.
2001-12-04 22:12:50 +00:00
{
docs/gst/gstreamer-sections.txt: Add new element field and method. Original commit message from CVS: * docs/gst/gstreamer-sections.txt: Add new element field and method. * gst/gstbin.c: (gst_bin_class_init), (gst_bin_init), (bin_remove_messages), (gst_bin_add_func), (gst_bin_remove_func), (gst_bin_recalc_state), (gst_bin_get_state_func), (gst_bin_element_set_state), (gst_bin_change_state_func), (gst_bin_continue_func), (bin_bus_handler), (bin_push_state_continue), (bin_handle_async_start), (bin_handle_async_done), (gst_bin_handle_message_func): Make async state changes a bit smarter by using new ASYNC_START and ASYNC_DONE messages. This reduces the number of times we run the state recalculation thread. Don't change state of element with a pending ASYNC_START message. Deprecate STATE_DIRTY messages. * gst/gstelement.c: (gst_element_init), (gst_element_send_event), (gst_element_get_state_func), (gst_element_continue_state), (gst_element_lost_state), (gst_element_set_state_func), (gst_element_change_state): * gst/gstelement.h: Keep the state that was last set by the app in a new element field. Don't allow state changes when handling an element event. Post ASYNC_START and ASYNC_DONE messages. Change lost_state so that we go to PAUSED and wait for the parent to set us to PLAYING again (so latency calculation can be performed) Export gst_element_change_state() method so that subclasses can use it. API: gst_element_change_state() API: GST_STATE_TARGET * gst/gstpipeline.c: (gst_pipeline_class_init), (reset_stream_time), (gst_pipeline_change_state), (gst_pipeline_handle_message), (gst_pipeline_set_new_stream_time): Using the new ASYNC_START message we can reset the base_time when needed. This can then be used to implement base_time redistribution in flushing seeks so that we can remove the explicit seek handling. Perform latency query and configuration when going to PLAYING. * libs/gst/base/gstbasesink.c: (gst_base_sink_commit_state), (gst_base_sink_query), (gst_base_sink_change_state): Post new ASYNC_START/ASYNC_DONE messages. * tests/check/generic/sinks.c: (GST_START_TEST): Fix test because the bin will not set the async element to PLAYING right away. * tests/check/gst/gstbin.c: (pop_async_done), (GST_START_TEST): Make the message check a little stronger. Handle ASYNC messages. * tests/check/pipelines/cleanup.c: (GST_START_TEST): * tests/check/pipelines/simple-launch-lines.c: (GST_START_TEST): Expect ASYNC_DONE messages.
2007-03-19 10:47:56 +00:00
GstState old_state, new_state;
GstMessage *message;
g_return_if_fail (GST_IS_ELEMENT (element));
GST_OBJECT_LOCK (element);
if (GST_STATE_RETURN (element) == GST_STATE_CHANGE_FAILURE)
goto nothing_lost;
if (GST_STATE_PENDING (element) != GST_STATE_VOID_PENDING)
goto only_async_start;
docs/gst/gstreamer-sections.txt: Add new element field and method. Original commit message from CVS: * docs/gst/gstreamer-sections.txt: Add new element field and method. * gst/gstbin.c: (gst_bin_class_init), (gst_bin_init), (bin_remove_messages), (gst_bin_add_func), (gst_bin_remove_func), (gst_bin_recalc_state), (gst_bin_get_state_func), (gst_bin_element_set_state), (gst_bin_change_state_func), (gst_bin_continue_func), (bin_bus_handler), (bin_push_state_continue), (bin_handle_async_start), (bin_handle_async_done), (gst_bin_handle_message_func): Make async state changes a bit smarter by using new ASYNC_START and ASYNC_DONE messages. This reduces the number of times we run the state recalculation thread. Don't change state of element with a pending ASYNC_START message. Deprecate STATE_DIRTY messages. * gst/gstelement.c: (gst_element_init), (gst_element_send_event), (gst_element_get_state_func), (gst_element_continue_state), (gst_element_lost_state), (gst_element_set_state_func), (gst_element_change_state): * gst/gstelement.h: Keep the state that was last set by the app in a new element field. Don't allow state changes when handling an element event. Post ASYNC_START and ASYNC_DONE messages. Change lost_state so that we go to PAUSED and wait for the parent to set us to PLAYING again (so latency calculation can be performed) Export gst_element_change_state() method so that subclasses can use it. API: gst_element_change_state() API: GST_STATE_TARGET * gst/gstpipeline.c: (gst_pipeline_class_init), (reset_stream_time), (gst_pipeline_change_state), (gst_pipeline_handle_message), (gst_pipeline_set_new_stream_time): Using the new ASYNC_START message we can reset the base_time when needed. This can then be used to implement base_time redistribution in flushing seeks so that we can remove the explicit seek handling. Perform latency query and configuration when going to PLAYING. * libs/gst/base/gstbasesink.c: (gst_base_sink_commit_state), (gst_base_sink_query), (gst_base_sink_change_state): Post new ASYNC_START/ASYNC_DONE messages. * tests/check/generic/sinks.c: (GST_START_TEST): Fix test because the bin will not set the async element to PLAYING right away. * tests/check/gst/gstbin.c: (pop_async_done), (GST_START_TEST): Make the message check a little stronger. Handle ASYNC messages. * tests/check/pipelines/cleanup.c: (GST_START_TEST): * tests/check/pipelines/simple-launch-lines.c: (GST_START_TEST): Expect ASYNC_DONE messages.
2007-03-19 10:47:56 +00:00
old_state = GST_STATE (element);
/* when we were PLAYING, the new state is PAUSED. We will also not
* automatically go to PLAYING but let the parent bin(s) set us to PLAYING
* when we preroll. */
if (old_state > GST_STATE_PAUSED)
new_state = GST_STATE_PAUSED;
else
new_state = old_state;
GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
docs/gst/gstreamer-sections.txt: Add new element field and method. Original commit message from CVS: * docs/gst/gstreamer-sections.txt: Add new element field and method. * gst/gstbin.c: (gst_bin_class_init), (gst_bin_init), (bin_remove_messages), (gst_bin_add_func), (gst_bin_remove_func), (gst_bin_recalc_state), (gst_bin_get_state_func), (gst_bin_element_set_state), (gst_bin_change_state_func), (gst_bin_continue_func), (bin_bus_handler), (bin_push_state_continue), (bin_handle_async_start), (bin_handle_async_done), (gst_bin_handle_message_func): Make async state changes a bit smarter by using new ASYNC_START and ASYNC_DONE messages. This reduces the number of times we run the state recalculation thread. Don't change state of element with a pending ASYNC_START message. Deprecate STATE_DIRTY messages. * gst/gstelement.c: (gst_element_init), (gst_element_send_event), (gst_element_get_state_func), (gst_element_continue_state), (gst_element_lost_state), (gst_element_set_state_func), (gst_element_change_state): * gst/gstelement.h: Keep the state that was last set by the app in a new element field. Don't allow state changes when handling an element event. Post ASYNC_START and ASYNC_DONE messages. Change lost_state so that we go to PAUSED and wait for the parent to set us to PLAYING again (so latency calculation can be performed) Export gst_element_change_state() method so that subclasses can use it. API: gst_element_change_state() API: GST_STATE_TARGET * gst/gstpipeline.c: (gst_pipeline_class_init), (reset_stream_time), (gst_pipeline_change_state), (gst_pipeline_handle_message), (gst_pipeline_set_new_stream_time): Using the new ASYNC_START message we can reset the base_time when needed. This can then be used to implement base_time redistribution in flushing seeks so that we can remove the explicit seek handling. Perform latency query and configuration when going to PLAYING. * libs/gst/base/gstbasesink.c: (gst_base_sink_commit_state), (gst_base_sink_query), (gst_base_sink_change_state): Post new ASYNC_START/ASYNC_DONE messages. * tests/check/generic/sinks.c: (GST_START_TEST): Fix test because the bin will not set the async element to PLAYING right away. * tests/check/gst/gstbin.c: (pop_async_done), (GST_START_TEST): Make the message check a little stronger. Handle ASYNC messages. * tests/check/pipelines/cleanup.c: (GST_START_TEST): * tests/check/pipelines/simple-launch-lines.c: (GST_START_TEST): Expect ASYNC_DONE messages.
2007-03-19 10:47:56 +00:00
"lost state of %s to %s", gst_element_state_get_name (old_state),
gst_element_state_get_name (new_state));
docs/gst/gstreamer-sections.txt: Add new element field and method. Original commit message from CVS: * docs/gst/gstreamer-sections.txt: Add new element field and method. * gst/gstbin.c: (gst_bin_class_init), (gst_bin_init), (bin_remove_messages), (gst_bin_add_func), (gst_bin_remove_func), (gst_bin_recalc_state), (gst_bin_get_state_func), (gst_bin_element_set_state), (gst_bin_change_state_func), (gst_bin_continue_func), (bin_bus_handler), (bin_push_state_continue), (bin_handle_async_start), (bin_handle_async_done), (gst_bin_handle_message_func): Make async state changes a bit smarter by using new ASYNC_START and ASYNC_DONE messages. This reduces the number of times we run the state recalculation thread. Don't change state of element with a pending ASYNC_START message. Deprecate STATE_DIRTY messages. * gst/gstelement.c: (gst_element_init), (gst_element_send_event), (gst_element_get_state_func), (gst_element_continue_state), (gst_element_lost_state), (gst_element_set_state_func), (gst_element_change_state): * gst/gstelement.h: Keep the state that was last set by the app in a new element field. Don't allow state changes when handling an element event. Post ASYNC_START and ASYNC_DONE messages. Change lost_state so that we go to PAUSED and wait for the parent to set us to PLAYING again (so latency calculation can be performed) Export gst_element_change_state() method so that subclasses can use it. API: gst_element_change_state() API: GST_STATE_TARGET * gst/gstpipeline.c: (gst_pipeline_class_init), (reset_stream_time), (gst_pipeline_change_state), (gst_pipeline_handle_message), (gst_pipeline_set_new_stream_time): Using the new ASYNC_START message we can reset the base_time when needed. This can then be used to implement base_time redistribution in flushing seeks so that we can remove the explicit seek handling. Perform latency query and configuration when going to PLAYING. * libs/gst/base/gstbasesink.c: (gst_base_sink_commit_state), (gst_base_sink_query), (gst_base_sink_change_state): Post new ASYNC_START/ASYNC_DONE messages. * tests/check/generic/sinks.c: (GST_START_TEST): Fix test because the bin will not set the async element to PLAYING right away. * tests/check/gst/gstbin.c: (pop_async_done), (GST_START_TEST): Make the message check a little stronger. Handle ASYNC messages. * tests/check/pipelines/cleanup.c: (GST_START_TEST): * tests/check/pipelines/simple-launch-lines.c: (GST_START_TEST): Expect ASYNC_DONE messages.
2007-03-19 10:47:56 +00:00
GST_STATE (element) = new_state;
GST_STATE_NEXT (element) = new_state;
GST_STATE_PENDING (element) = new_state;
GST_STATE_RETURN (element) = GST_STATE_CHANGE_ASYNC;
GST_OBJECT_UNLOCK (element);
_priv_gst_element_state_changed (element, new_state, new_state, new_state);
message = gst_message_new_async_start (GST_OBJECT_CAST (element));
gst_element_post_message (element, message);
return;
nothing_lost:
{
GST_OBJECT_UNLOCK (element);
return;
}
only_async_start:
{
GST_OBJECT_UNLOCK (element);
message = gst_message_new_async_start (GST_OBJECT_CAST (element));
gst_element_post_message (element, message);
return;
}
- some fixes to int2float making automake 1.5 happy (gst now requires automake1.5). It's still not perfect but it bui... Original commit message from CVS: - added playondemand plugin by Leif Morgan Johnson <lmjohns3@eos.ncsu.edu> - some fixes to int2float - aplied a patch from wrobell <wrobell@ite.pl> that is a first attempt at making automake 1.5 happy (gst now requires automake1.5). It's still not perfect but it builds. - Made the schedulers plugable. The default scheduler now lives inside a plugin. - Added a new mpeg1/2 parser/demuxer. - Fixed some compiler warnings in the core libs. - substantial work to GstThread (hopefully less race conditions). simplified the code in GstThread a bit. A state change can now also happen in the thread context. - reworked the state semantics of a bin. it'll now automatically get the highest state of its children. - the autoplugger now nests the threads so that a state change failure of one thread doesn't make its upstream thread lock. - GstQueue refuses to go to PLAYING if the sinkpad is not connected. This way the queue will not wedge in the _get lock. - GstQueue unlocks its mutexes when going to PAUSED. - make sure that when all elements in a bin/thread go to PAUSED, the bin is set to PAUSED too. - make a parent bin wait for its children to PAUSE before ending the iteration with FALSE (EOS) - Some changes to GstPlay to deal with EOS. - aplied the latest patch from Zeenix to gstrtp. end result: GstPlay doesn't crash on EOS and the pipeline is now shut down properly.
2001-12-04 22:12:50 +00:00
}
/**
* gst_element_set_state:
* @element: a #GstElement to change state of.
* @state: the element's new #GstState.
*
* Sets the state of the element. This function will try to set the
* requested state by going through all the intermediary states and calling
* the class's state change function for each.
*
* This function can return #GST_STATE_CHANGE_ASYNC, in which case the
* element will perform the remainder of the state change asynchronously in
* another thread.
2005-10-10 16:38:26 +00:00
* An application can use gst_element_get_state() to wait for the completion
* of the state change or it can wait for a %GST_MESSAGE_ASYNC_DONE or
* %GST_MESSAGE_STATE_CHANGED on the bus.
2005-10-10 16:38:26 +00:00
*
* State changes to %GST_STATE_READY or %GST_STATE_NULL never return
* #GST_STATE_CHANGE_ASYNC.
*
* Returns: Result of the state change using #GstStateChangeReturn.
*
* MT safe.
*/
GstStateChangeReturn
gst_element_set_state (GstElement * element, GstState state)
{
GstElementClass *oclass;
GstStateChangeReturn result = GST_STATE_CHANGE_FAILURE;
g_return_val_if_fail (GST_IS_ELEMENT (element), GST_STATE_CHANGE_FAILURE);
oclass = GST_ELEMENT_GET_CLASS (element);
if (oclass->set_state)
result = (oclass->set_state) (element, state);
return result;
}
/*
* default set state function, calculates the next state based
* on current state and calls the change_state function
*/
static GstStateChangeReturn
gst_element_set_state_func (GstElement * element, GstState state)
{
2005-10-10 16:38:26 +00:00
GstState current, next, old_pending;
GstStateChangeReturn ret;
GstStateChange transition;
2005-10-10 16:38:26 +00:00
GstStateChangeReturn old_ret;
g_return_val_if_fail (GST_IS_ELEMENT (element), GST_STATE_CHANGE_FAILURE);
GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element, "set_state to %s",
gst_element_state_get_name (state));
/* state lock is taken to protect the set_state() and get_state()
* procedures, it does not lock any variables. */
GST_STATE_LOCK (element);
/* now calculate how to get to the new state */
GST_OBJECT_LOCK (element);
2005-10-10 16:38:26 +00:00
old_ret = GST_STATE_RETURN (element);
/* previous state change returned an error, remove all pending
* and next states */
if (old_ret == GST_STATE_CHANGE_FAILURE) {
GST_STATE_NEXT (element) = GST_STATE_VOID_PENDING;
GST_STATE_PENDING (element) = GST_STATE_VOID_PENDING;
GST_STATE_RETURN (element) = GST_STATE_CHANGE_SUCCESS;
}
current = GST_STATE (element);
next = GST_STATE_NEXT (element);
old_pending = GST_STATE_PENDING (element);
docs/gst/gstreamer-sections.txt: Add new element field and method. Original commit message from CVS: * docs/gst/gstreamer-sections.txt: Add new element field and method. * gst/gstbin.c: (gst_bin_class_init), (gst_bin_init), (bin_remove_messages), (gst_bin_add_func), (gst_bin_remove_func), (gst_bin_recalc_state), (gst_bin_get_state_func), (gst_bin_element_set_state), (gst_bin_change_state_func), (gst_bin_continue_func), (bin_bus_handler), (bin_push_state_continue), (bin_handle_async_start), (bin_handle_async_done), (gst_bin_handle_message_func): Make async state changes a bit smarter by using new ASYNC_START and ASYNC_DONE messages. This reduces the number of times we run the state recalculation thread. Don't change state of element with a pending ASYNC_START message. Deprecate STATE_DIRTY messages. * gst/gstelement.c: (gst_element_init), (gst_element_send_event), (gst_element_get_state_func), (gst_element_continue_state), (gst_element_lost_state), (gst_element_set_state_func), (gst_element_change_state): * gst/gstelement.h: Keep the state that was last set by the app in a new element field. Don't allow state changes when handling an element event. Post ASYNC_START and ASYNC_DONE messages. Change lost_state so that we go to PAUSED and wait for the parent to set us to PLAYING again (so latency calculation can be performed) Export gst_element_change_state() method so that subclasses can use it. API: gst_element_change_state() API: GST_STATE_TARGET * gst/gstpipeline.c: (gst_pipeline_class_init), (reset_stream_time), (gst_pipeline_change_state), (gst_pipeline_handle_message), (gst_pipeline_set_new_stream_time): Using the new ASYNC_START message we can reset the base_time when needed. This can then be used to implement base_time redistribution in flushing seeks so that we can remove the explicit seek handling. Perform latency query and configuration when going to PLAYING. * libs/gst/base/gstbasesink.c: (gst_base_sink_commit_state), (gst_base_sink_query), (gst_base_sink_change_state): Post new ASYNC_START/ASYNC_DONE messages. * tests/check/generic/sinks.c: (GST_START_TEST): Fix test because the bin will not set the async element to PLAYING right away. * tests/check/gst/gstbin.c: (pop_async_done), (GST_START_TEST): Make the message check a little stronger. Handle ASYNC messages. * tests/check/pipelines/cleanup.c: (GST_START_TEST): * tests/check/pipelines/simple-launch-lines.c: (GST_START_TEST): Expect ASYNC_DONE messages.
2007-03-19 10:47:56 +00:00
/* this is the (new) state we should go to. TARGET is the last state we set on
* the element. */
if (state != GST_STATE_TARGET (element)) {
GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
"setting target state to %s", gst_element_state_get_name (state));
GST_STATE_TARGET (element) = state;
/* increment state cookie so that we can track each state change. We only do
* this if this is actually a new state change. */
element->state_cookie++;
}
2005-10-10 16:38:26 +00:00
GST_STATE_PENDING (element) = state;
GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
"current %s, old_pending %s, next %s, old return %s",
2005-10-10 16:38:26 +00:00
gst_element_state_get_name (current),
gst_element_state_get_name (old_pending),
gst_element_state_get_name (next),
gst_element_state_change_return_get_name (old_ret));
2005-10-10 16:38:26 +00:00
/* if the element was busy doing a state change, we just update the
* target state, it'll get to it async then. */
if (old_pending != GST_STATE_VOID_PENDING) {
/* upwards state change will happen ASYNC */
if (old_pending <= state)
goto was_busy;
/* element is going to this state already */
else if (next == state)
goto was_busy;
2005-10-10 16:38:26 +00:00
/* element was performing an ASYNC upward state change and
* we request to go downward again. Start from the next pending
* state then. */
else if (next > state
&& GST_STATE_RETURN (element) == GST_STATE_CHANGE_ASYNC) {
current = next;
}
}
2005-10-10 16:38:26 +00:00
next = GST_STATE_GET_NEXT (current, state);
/* now we store the next state */
GST_STATE_NEXT (element) = next;
/* mark busy, we need to check that there is actually a state change
* to be done else we could accidentally override SUCCESS/NO_PREROLL and
* the default element change_state function has no way to know what the
* old value was... could consider this a FIXME...*/
if (current != next)
GST_STATE_RETURN (element) = GST_STATE_CHANGE_ASYNC;
transition = (GstStateChange) GST_STATE_TRANSITION (current, next);
2005-10-10 16:38:26 +00:00
GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
"%s: setting state from %s to %s",
(next != state ? "intermediate" : "final"),
gst_element_state_get_name (current), gst_element_state_get_name (next));
/* now signal any waiters, they will error since the cookie was incremented */
GST_STATE_BROADCAST (element);
GST_OBJECT_UNLOCK (element);
ret = gst_element_change_state (element, transition);
GST_STATE_UNLOCK (element);
GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element, "returned %s",
gst_element_state_change_return_get_name (ret));
return ret;
was_busy:
{
2005-10-10 16:38:26 +00:00
GST_STATE_RETURN (element) = GST_STATE_CHANGE_ASYNC;
GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
"element was busy with async state change");
GST_OBJECT_UNLOCK (element);
GST_STATE_UNLOCK (element);
return GST_STATE_CHANGE_ASYNC;
}
}
docs/gst/gstreamer-sections.txt: Add new element field and method. Original commit message from CVS: * docs/gst/gstreamer-sections.txt: Add new element field and method. * gst/gstbin.c: (gst_bin_class_init), (gst_bin_init), (bin_remove_messages), (gst_bin_add_func), (gst_bin_remove_func), (gst_bin_recalc_state), (gst_bin_get_state_func), (gst_bin_element_set_state), (gst_bin_change_state_func), (gst_bin_continue_func), (bin_bus_handler), (bin_push_state_continue), (bin_handle_async_start), (bin_handle_async_done), (gst_bin_handle_message_func): Make async state changes a bit smarter by using new ASYNC_START and ASYNC_DONE messages. This reduces the number of times we run the state recalculation thread. Don't change state of element with a pending ASYNC_START message. Deprecate STATE_DIRTY messages. * gst/gstelement.c: (gst_element_init), (gst_element_send_event), (gst_element_get_state_func), (gst_element_continue_state), (gst_element_lost_state), (gst_element_set_state_func), (gst_element_change_state): * gst/gstelement.h: Keep the state that was last set by the app in a new element field. Don't allow state changes when handling an element event. Post ASYNC_START and ASYNC_DONE messages. Change lost_state so that we go to PAUSED and wait for the parent to set us to PLAYING again (so latency calculation can be performed) Export gst_element_change_state() method so that subclasses can use it. API: gst_element_change_state() API: GST_STATE_TARGET * gst/gstpipeline.c: (gst_pipeline_class_init), (reset_stream_time), (gst_pipeline_change_state), (gst_pipeline_handle_message), (gst_pipeline_set_new_stream_time): Using the new ASYNC_START message we can reset the base_time when needed. This can then be used to implement base_time redistribution in flushing seeks so that we can remove the explicit seek handling. Perform latency query and configuration when going to PLAYING. * libs/gst/base/gstbasesink.c: (gst_base_sink_commit_state), (gst_base_sink_query), (gst_base_sink_change_state): Post new ASYNC_START/ASYNC_DONE messages. * tests/check/generic/sinks.c: (GST_START_TEST): Fix test because the bin will not set the async element to PLAYING right away. * tests/check/gst/gstbin.c: (pop_async_done), (GST_START_TEST): Make the message check a little stronger. Handle ASYNC messages. * tests/check/pipelines/cleanup.c: (GST_START_TEST): * tests/check/pipelines/simple-launch-lines.c: (GST_START_TEST): Expect ASYNC_DONE messages.
2007-03-19 10:47:56 +00:00
/**
* gst_element_change_state:
* @element: a #GstElement
* @transition: the requested transition
*
* Perform @transition on @element.
*
* This function must be called with STATE_LOCK held and is mainly used
* internally.
*
* Returns: the #GstStateChangeReturn of the state transition.
*/
GstStateChangeReturn
gst_element_change_state (GstElement * element, GstStateChange transition)
{
GstElementClass *oclass;
GstStateChangeReturn ret = GST_STATE_CHANGE_SUCCESS;
oclass = GST_ELEMENT_GET_CLASS (element);
GST_TRACER_ELEMENT_CHANGE_STATE_PRE (element, transition);
2005-10-10 16:38:26 +00:00
/* call the state change function so it can set the state */
if (oclass->change_state)
ret = (oclass->change_state) (element, transition);
else
ret = GST_STATE_CHANGE_FAILURE;
GST_TRACER_ELEMENT_CHANGE_STATE_POST (element, transition, ret);
2005-10-10 16:38:26 +00:00
switch (ret) {
case GST_STATE_CHANGE_FAILURE:
GST_CAT_INFO_OBJECT (GST_CAT_STATES, element,
"have FAILURE change_state return");
/* state change failure */
gst_element_abort_state (element);
break;
case GST_STATE_CHANGE_ASYNC:
docs/gst/gstreamer-sections.txt: Add new element field and method. Original commit message from CVS: * docs/gst/gstreamer-sections.txt: Add new element field and method. * gst/gstbin.c: (gst_bin_class_init), (gst_bin_init), (bin_remove_messages), (gst_bin_add_func), (gst_bin_remove_func), (gst_bin_recalc_state), (gst_bin_get_state_func), (gst_bin_element_set_state), (gst_bin_change_state_func), (gst_bin_continue_func), (bin_bus_handler), (bin_push_state_continue), (bin_handle_async_start), (bin_handle_async_done), (gst_bin_handle_message_func): Make async state changes a bit smarter by using new ASYNC_START and ASYNC_DONE messages. This reduces the number of times we run the state recalculation thread. Don't change state of element with a pending ASYNC_START message. Deprecate STATE_DIRTY messages. * gst/gstelement.c: (gst_element_init), (gst_element_send_event), (gst_element_get_state_func), (gst_element_continue_state), (gst_element_lost_state), (gst_element_set_state_func), (gst_element_change_state): * gst/gstelement.h: Keep the state that was last set by the app in a new element field. Don't allow state changes when handling an element event. Post ASYNC_START and ASYNC_DONE messages. Change lost_state so that we go to PAUSED and wait for the parent to set us to PLAYING again (so latency calculation can be performed) Export gst_element_change_state() method so that subclasses can use it. API: gst_element_change_state() API: GST_STATE_TARGET * gst/gstpipeline.c: (gst_pipeline_class_init), (reset_stream_time), (gst_pipeline_change_state), (gst_pipeline_handle_message), (gst_pipeline_set_new_stream_time): Using the new ASYNC_START message we can reset the base_time when needed. This can then be used to implement base_time redistribution in flushing seeks so that we can remove the explicit seek handling. Perform latency query and configuration when going to PLAYING. * libs/gst/base/gstbasesink.c: (gst_base_sink_commit_state), (gst_base_sink_query), (gst_base_sink_change_state): Post new ASYNC_START/ASYNC_DONE messages. * tests/check/generic/sinks.c: (GST_START_TEST): Fix test because the bin will not set the async element to PLAYING right away. * tests/check/gst/gstbin.c: (pop_async_done), (GST_START_TEST): Make the message check a little stronger. Handle ASYNC messages. * tests/check/pipelines/cleanup.c: (GST_START_TEST): * tests/check/pipelines/simple-launch-lines.c: (GST_START_TEST): Expect ASYNC_DONE messages.
2007-03-19 10:47:56 +00:00
{
GstState target;
GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
2005-10-10 16:38:26 +00:00
"element will change state ASYNC");
docs/gst/gstreamer-sections.txt: Add new element field and method. Original commit message from CVS: * docs/gst/gstreamer-sections.txt: Add new element field and method. * gst/gstbin.c: (gst_bin_class_init), (gst_bin_init), (bin_remove_messages), (gst_bin_add_func), (gst_bin_remove_func), (gst_bin_recalc_state), (gst_bin_get_state_func), (gst_bin_element_set_state), (gst_bin_change_state_func), (gst_bin_continue_func), (bin_bus_handler), (bin_push_state_continue), (bin_handle_async_start), (bin_handle_async_done), (gst_bin_handle_message_func): Make async state changes a bit smarter by using new ASYNC_START and ASYNC_DONE messages. This reduces the number of times we run the state recalculation thread. Don't change state of element with a pending ASYNC_START message. Deprecate STATE_DIRTY messages. * gst/gstelement.c: (gst_element_init), (gst_element_send_event), (gst_element_get_state_func), (gst_element_continue_state), (gst_element_lost_state), (gst_element_set_state_func), (gst_element_change_state): * gst/gstelement.h: Keep the state that was last set by the app in a new element field. Don't allow state changes when handling an element event. Post ASYNC_START and ASYNC_DONE messages. Change lost_state so that we go to PAUSED and wait for the parent to set us to PLAYING again (so latency calculation can be performed) Export gst_element_change_state() method so that subclasses can use it. API: gst_element_change_state() API: GST_STATE_TARGET * gst/gstpipeline.c: (gst_pipeline_class_init), (reset_stream_time), (gst_pipeline_change_state), (gst_pipeline_handle_message), (gst_pipeline_set_new_stream_time): Using the new ASYNC_START message we can reset the base_time when needed. This can then be used to implement base_time redistribution in flushing seeks so that we can remove the explicit seek handling. Perform latency query and configuration when going to PLAYING. * libs/gst/base/gstbasesink.c: (gst_base_sink_commit_state), (gst_base_sink_query), (gst_base_sink_change_state): Post new ASYNC_START/ASYNC_DONE messages. * tests/check/generic/sinks.c: (GST_START_TEST): Fix test because the bin will not set the async element to PLAYING right away. * tests/check/gst/gstbin.c: (pop_async_done), (GST_START_TEST): Make the message check a little stronger. Handle ASYNC messages. * tests/check/pipelines/cleanup.c: (GST_START_TEST): * tests/check/pipelines/simple-launch-lines.c: (GST_START_TEST): Expect ASYNC_DONE messages.
2007-03-19 10:47:56 +00:00
target = GST_STATE_TARGET (element);
if (target > GST_STATE_READY)
goto async;
2005-10-10 16:38:26 +00:00
/* else we just continue the state change downwards */
GST_CAT_INFO_OBJECT (GST_CAT_STATES, element,
docs/gst/gstreamer-sections.txt: Add new element field and method. Original commit message from CVS: * docs/gst/gstreamer-sections.txt: Add new element field and method. * gst/gstbin.c: (gst_bin_class_init), (gst_bin_init), (bin_remove_messages), (gst_bin_add_func), (gst_bin_remove_func), (gst_bin_recalc_state), (gst_bin_get_state_func), (gst_bin_element_set_state), (gst_bin_change_state_func), (gst_bin_continue_func), (bin_bus_handler), (bin_push_state_continue), (bin_handle_async_start), (bin_handle_async_done), (gst_bin_handle_message_func): Make async state changes a bit smarter by using new ASYNC_START and ASYNC_DONE messages. This reduces the number of times we run the state recalculation thread. Don't change state of element with a pending ASYNC_START message. Deprecate STATE_DIRTY messages. * gst/gstelement.c: (gst_element_init), (gst_element_send_event), (gst_element_get_state_func), (gst_element_continue_state), (gst_element_lost_state), (gst_element_set_state_func), (gst_element_change_state): * gst/gstelement.h: Keep the state that was last set by the app in a new element field. Don't allow state changes when handling an element event. Post ASYNC_START and ASYNC_DONE messages. Change lost_state so that we go to PAUSED and wait for the parent to set us to PLAYING again (so latency calculation can be performed) Export gst_element_change_state() method so that subclasses can use it. API: gst_element_change_state() API: GST_STATE_TARGET * gst/gstpipeline.c: (gst_pipeline_class_init), (reset_stream_time), (gst_pipeline_change_state), (gst_pipeline_handle_message), (gst_pipeline_set_new_stream_time): Using the new ASYNC_START message we can reset the base_time when needed. This can then be used to implement base_time redistribution in flushing seeks so that we can remove the explicit seek handling. Perform latency query and configuration when going to PLAYING. * libs/gst/base/gstbasesink.c: (gst_base_sink_commit_state), (gst_base_sink_query), (gst_base_sink_change_state): Post new ASYNC_START/ASYNC_DONE messages. * tests/check/generic/sinks.c: (GST_START_TEST): Fix test because the bin will not set the async element to PLAYING right away. * tests/check/gst/gstbin.c: (pop_async_done), (GST_START_TEST): Make the message check a little stronger. Handle ASYNC messages. * tests/check/pipelines/cleanup.c: (GST_START_TEST): * tests/check/pipelines/simple-launch-lines.c: (GST_START_TEST): Expect ASYNC_DONE messages.
2007-03-19 10:47:56 +00:00
"forcing commit state %s <= %s",
gst_element_state_get_name (target),
gst_element_state_get_name (GST_STATE_READY));
2005-10-10 16:38:26 +00:00
ret = gst_element_continue_state (element, GST_STATE_CHANGE_SUCCESS);
2005-10-10 16:38:26 +00:00
break;
docs/gst/gstreamer-sections.txt: Add new element field and method. Original commit message from CVS: * docs/gst/gstreamer-sections.txt: Add new element field and method. * gst/gstbin.c: (gst_bin_class_init), (gst_bin_init), (bin_remove_messages), (gst_bin_add_func), (gst_bin_remove_func), (gst_bin_recalc_state), (gst_bin_get_state_func), (gst_bin_element_set_state), (gst_bin_change_state_func), (gst_bin_continue_func), (bin_bus_handler), (bin_push_state_continue), (bin_handle_async_start), (bin_handle_async_done), (gst_bin_handle_message_func): Make async state changes a bit smarter by using new ASYNC_START and ASYNC_DONE messages. This reduces the number of times we run the state recalculation thread. Don't change state of element with a pending ASYNC_START message. Deprecate STATE_DIRTY messages. * gst/gstelement.c: (gst_element_init), (gst_element_send_event), (gst_element_get_state_func), (gst_element_continue_state), (gst_element_lost_state), (gst_element_set_state_func), (gst_element_change_state): * gst/gstelement.h: Keep the state that was last set by the app in a new element field. Don't allow state changes when handling an element event. Post ASYNC_START and ASYNC_DONE messages. Change lost_state so that we go to PAUSED and wait for the parent to set us to PLAYING again (so latency calculation can be performed) Export gst_element_change_state() method so that subclasses can use it. API: gst_element_change_state() API: GST_STATE_TARGET * gst/gstpipeline.c: (gst_pipeline_class_init), (reset_stream_time), (gst_pipeline_change_state), (gst_pipeline_handle_message), (gst_pipeline_set_new_stream_time): Using the new ASYNC_START message we can reset the base_time when needed. This can then be used to implement base_time redistribution in flushing seeks so that we can remove the explicit seek handling. Perform latency query and configuration when going to PLAYING. * libs/gst/base/gstbasesink.c: (gst_base_sink_commit_state), (gst_base_sink_query), (gst_base_sink_change_state): Post new ASYNC_START/ASYNC_DONE messages. * tests/check/generic/sinks.c: (GST_START_TEST): Fix test because the bin will not set the async element to PLAYING right away. * tests/check/gst/gstbin.c: (pop_async_done), (GST_START_TEST): Make the message check a little stronger. Handle ASYNC messages. * tests/check/pipelines/cleanup.c: (GST_START_TEST): * tests/check/pipelines/simple-launch-lines.c: (GST_START_TEST): Expect ASYNC_DONE messages.
2007-03-19 10:47:56 +00:00
}
2005-10-10 16:38:26 +00:00
case GST_STATE_CHANGE_SUCCESS:
GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
2005-10-10 16:38:26 +00:00
"element changed state SUCCESS");
/* we can commit the state now which will proceed to
2005-10-10 16:38:26 +00:00
* the next state */
ret = gst_element_continue_state (element, ret);
2005-10-10 16:38:26 +00:00
break;
case GST_STATE_CHANGE_NO_PREROLL:
GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
2005-10-10 16:38:26 +00:00
"element changed state NO_PREROLL");
/* we can commit the state now which will proceed to
2005-10-10 16:38:26 +00:00
* the next state */
ret = gst_element_continue_state (element, ret);
2005-10-10 16:38:26 +00:00
break;
default:
goto invalid_return;
}
GST_CAT_LOG_OBJECT (GST_CAT_STATES, element, "exit state change %d", ret);
return ret;
async:
GST_CAT_LOG_OBJECT (GST_CAT_STATES, element, "exit async state change %d",
ret);
return ret;
/* ERROR */
invalid_return:
{
GST_OBJECT_LOCK (element);
/* somebody added a GST_STATE_ and forgot to do stuff here ! */
g_critical ("%s: unknown return value %d from a state change function",
GST_ELEMENT_NAME (element), ret);
/* we are in error now */
ret = GST_STATE_CHANGE_FAILURE;
2005-10-10 16:38:26 +00:00
GST_STATE_RETURN (element) = ret;
GST_OBJECT_UNLOCK (element);
return ret;
}
- some fixes to int2float making automake 1.5 happy (gst now requires automake1.5). It's still not perfect but it bui... Original commit message from CVS: - added playondemand plugin by Leif Morgan Johnson <lmjohns3@eos.ncsu.edu> - some fixes to int2float - aplied a patch from wrobell <wrobell@ite.pl> that is a first attempt at making automake 1.5 happy (gst now requires automake1.5). It's still not perfect but it builds. - Made the schedulers plugable. The default scheduler now lives inside a plugin. - Added a new mpeg1/2 parser/demuxer. - Fixed some compiler warnings in the core libs. - substantial work to GstThread (hopefully less race conditions). simplified the code in GstThread a bit. A state change can now also happen in the thread context. - reworked the state semantics of a bin. it'll now automatically get the highest state of its children. - the autoplugger now nests the threads so that a state change failure of one thread doesn't make its upstream thread lock. - GstQueue refuses to go to PLAYING if the sinkpad is not connected. This way the queue will not wedge in the _get lock. - GstQueue unlocks its mutexes when going to PAUSED. - make sure that when all elements in a bin/thread go to PAUSED, the bin is set to PAUSED too. - make a parent bin wait for its children to PAUSE before ending the iteration with FALSE (EOS) - Some changes to GstPlay to deal with EOS. - aplied the latest patch from Zeenix to gstrtp. end result: GstPlay doesn't crash on EOS and the pipeline is now shut down properly.
2001-12-04 22:12:50 +00:00
}
/* gst_iterator_fold functions for pads_activate
* Stop the iterator if activating one pad failed, but only if that pad
* has not been removed from the element. */
static gboolean
activate_pads (const GValue * vpad, GValue * ret, gboolean * active)
{
GstPad *pad = g_value_get_object (vpad);
gboolean cont = TRUE;
if (!gst_pad_set_active (pad, *active)) {
if (GST_PAD_PARENT (pad) != NULL) {
cont = FALSE;
g_value_set_boolean (ret, FALSE);
}
}
return cont;
gst/base/gsttypefindhelper.c (gst_type_find_helper): Unref any remaining buffer. Original commit message from CVS: 2005-06-27 Andy Wingo <wingo@pobox.com> * gst/base/gsttypefindhelper.c (gst_type_find_helper): Unref any remaining buffer. * gst/gsttrace.c (gst_alloc_trace_list_sorted): New helper, returns a sorted copy of the trace list. (gst_alloc_trace_print_live): New API, only prints traces with live objects. Sort the list. (gst_alloc_trace_print_all): Sort the list. (gst_alloc_trace_print): Align columns. * gst/elements/gstttypefindelement.c: * gst/elements/gsttee.c: * gst/base/gstbasesrc.c: * gst/base/gstbasesink.c: * gst/base/gstbasetransform.c: * gst/gstqueue.c: Adapt for pad activation changes. * gst/gstpipeline.c (gst_pipeline_init): Unref after parenting sched. (gst_pipeline_dispose): Drop ref on sched. * gst/gstpad.c (gst_pad_init): Set the default activate func. (gst_pad_activate_default): Push mode by default. (pre_activate_switch, post_activate_switch): New stubs, things to do before and after switching activation modes on pads. (gst_pad_set_active): Take a boolean and not a mode, dispatch to the pad's activate function to choose which mode to activate. Shortcut on deactivation and call the right function directly. (gst_pad_activate_pull): New API, (de)activates a pad in pull mode. (gst_pad_activate_push): New API, same for push mode. (gst_pad_set_activate_function) (gst_pad_set_activatepull_function) (gst_pad_set_activatepush_function): Setters for new API. * gst/gstminiobject.c (gst_mini_object_new, gst_mini_object_free): Trace all miniobjects. (gst_mini_object_make_writable): Unref the arg if we copy, like gst_caps_make_writable. * gst/gstmessage.c (_gst_message_initialize): No trace init. * gst/gstghostpad.c (gst_proxy_pad_do_activate) (gst_proxy_pad_do_activatepull, gst_proxy_pad_do_activatepush): Adapt for new pad API. * gst/gstevent.c (_gst_event_initialize): Don't initialize trace. * gst/gstelement.h: * gst/gstelement.c (gst_element_iterate_src_pads) (gst_element_iterate_sink_pads): New API functions. * gst/gstelement.c (iterator_fold_with_resync): New utility, should fold into gstiterator.c in some form. (gst_element_pads_activate): Simplified via use of fold and delegation of decisions to gstpad->activate. * gst/gstbus.c (gst_bus_source_finalize): Set the bus to NULL, help in debugging. * gst/gstbuffer.c (_gst_buffer_initialize): Ref the buffer type class once in init, like gstmessage. Didn't run into this issue but it seems correct. Don't initialize a trace, gstminiobject does that. * check/pipelines/simple_launch_lines.c (test_stop_from_app): New test, runs fakesrc ! fakesink, stopping on ::handoff via a message to the bus. (assert_live_count): New util function, uses alloc traces to check cleanup. * check/gst/gstghostpad.c (test_ghost_pads): More refcount checks. To be modified when unlink drops the internal pad.
2005-06-27 18:35:05 +00:00
}
/* returns false on error or early cutout of the fold, true if all
* pads in @iter were (de)activated successfully. */
gst/base/gsttypefindhelper.c (gst_type_find_helper): Unref any remaining buffer. Original commit message from CVS: 2005-06-27 Andy Wingo <wingo@pobox.com> * gst/base/gsttypefindhelper.c (gst_type_find_helper): Unref any remaining buffer. * gst/gsttrace.c (gst_alloc_trace_list_sorted): New helper, returns a sorted copy of the trace list. (gst_alloc_trace_print_live): New API, only prints traces with live objects. Sort the list. (gst_alloc_trace_print_all): Sort the list. (gst_alloc_trace_print): Align columns. * gst/elements/gstttypefindelement.c: * gst/elements/gsttee.c: * gst/base/gstbasesrc.c: * gst/base/gstbasesink.c: * gst/base/gstbasetransform.c: * gst/gstqueue.c: Adapt for pad activation changes. * gst/gstpipeline.c (gst_pipeline_init): Unref after parenting sched. (gst_pipeline_dispose): Drop ref on sched. * gst/gstpad.c (gst_pad_init): Set the default activate func. (gst_pad_activate_default): Push mode by default. (pre_activate_switch, post_activate_switch): New stubs, things to do before and after switching activation modes on pads. (gst_pad_set_active): Take a boolean and not a mode, dispatch to the pad's activate function to choose which mode to activate. Shortcut on deactivation and call the right function directly. (gst_pad_activate_pull): New API, (de)activates a pad in pull mode. (gst_pad_activate_push): New API, same for push mode. (gst_pad_set_activate_function) (gst_pad_set_activatepull_function) (gst_pad_set_activatepush_function): Setters for new API. * gst/gstminiobject.c (gst_mini_object_new, gst_mini_object_free): Trace all miniobjects. (gst_mini_object_make_writable): Unref the arg if we copy, like gst_caps_make_writable. * gst/gstmessage.c (_gst_message_initialize): No trace init. * gst/gstghostpad.c (gst_proxy_pad_do_activate) (gst_proxy_pad_do_activatepull, gst_proxy_pad_do_activatepush): Adapt for new pad API. * gst/gstevent.c (_gst_event_initialize): Don't initialize trace. * gst/gstelement.h: * gst/gstelement.c (gst_element_iterate_src_pads) (gst_element_iterate_sink_pads): New API functions. * gst/gstelement.c (iterator_fold_with_resync): New utility, should fold into gstiterator.c in some form. (gst_element_pads_activate): Simplified via use of fold and delegation of decisions to gstpad->activate. * gst/gstbus.c (gst_bus_source_finalize): Set the bus to NULL, help in debugging. * gst/gstbuffer.c (_gst_buffer_initialize): Ref the buffer type class once in init, like gstmessage. Didn't run into this issue but it seems correct. Don't initialize a trace, gstminiobject does that. * check/pipelines/simple_launch_lines.c (test_stop_from_app): New test, runs fakesrc ! fakesink, stopping on ::handoff via a message to the bus. (assert_live_count): New util function, uses alloc traces to check cleanup. * check/gst/gstghostpad.c (test_ghost_pads): More refcount checks. To be modified when unlink drops the internal pad.
2005-06-27 18:35:05 +00:00
static gboolean
iterator_activate_fold_with_resync (GstIterator * iter,
GstIteratorFoldFunction func, gpointer user_data)
gst/base/gsttypefindhelper.c (gst_type_find_helper): Unref any remaining buffer. Original commit message from CVS: 2005-06-27 Andy Wingo <wingo@pobox.com> * gst/base/gsttypefindhelper.c (gst_type_find_helper): Unref any remaining buffer. * gst/gsttrace.c (gst_alloc_trace_list_sorted): New helper, returns a sorted copy of the trace list. (gst_alloc_trace_print_live): New API, only prints traces with live objects. Sort the list. (gst_alloc_trace_print_all): Sort the list. (gst_alloc_trace_print): Align columns. * gst/elements/gstttypefindelement.c: * gst/elements/gsttee.c: * gst/base/gstbasesrc.c: * gst/base/gstbasesink.c: * gst/base/gstbasetransform.c: * gst/gstqueue.c: Adapt for pad activation changes. * gst/gstpipeline.c (gst_pipeline_init): Unref after parenting sched. (gst_pipeline_dispose): Drop ref on sched. * gst/gstpad.c (gst_pad_init): Set the default activate func. (gst_pad_activate_default): Push mode by default. (pre_activate_switch, post_activate_switch): New stubs, things to do before and after switching activation modes on pads. (gst_pad_set_active): Take a boolean and not a mode, dispatch to the pad's activate function to choose which mode to activate. Shortcut on deactivation and call the right function directly. (gst_pad_activate_pull): New API, (de)activates a pad in pull mode. (gst_pad_activate_push): New API, same for push mode. (gst_pad_set_activate_function) (gst_pad_set_activatepull_function) (gst_pad_set_activatepush_function): Setters for new API. * gst/gstminiobject.c (gst_mini_object_new, gst_mini_object_free): Trace all miniobjects. (gst_mini_object_make_writable): Unref the arg if we copy, like gst_caps_make_writable. * gst/gstmessage.c (_gst_message_initialize): No trace init. * gst/gstghostpad.c (gst_proxy_pad_do_activate) (gst_proxy_pad_do_activatepull, gst_proxy_pad_do_activatepush): Adapt for new pad API. * gst/gstevent.c (_gst_event_initialize): Don't initialize trace. * gst/gstelement.h: * gst/gstelement.c (gst_element_iterate_src_pads) (gst_element_iterate_sink_pads): New API functions. * gst/gstelement.c (iterator_fold_with_resync): New utility, should fold into gstiterator.c in some form. (gst_element_pads_activate): Simplified via use of fold and delegation of decisions to gstpad->activate. * gst/gstbus.c (gst_bus_source_finalize): Set the bus to NULL, help in debugging. * gst/gstbuffer.c (_gst_buffer_initialize): Ref the buffer type class once in init, like gstmessage. Didn't run into this issue but it seems correct. Don't initialize a trace, gstminiobject does that. * check/pipelines/simple_launch_lines.c (test_stop_from_app): New test, runs fakesrc ! fakesink, stopping on ::handoff via a message to the bus. (assert_live_count): New util function, uses alloc traces to check cleanup. * check/gst/gstghostpad.c (test_ghost_pads): More refcount checks. To be modified when unlink drops the internal pad.
2005-06-27 18:35:05 +00:00
{
GstIteratorResult ires;
GValue ret = { 0 };
/* no need to unset this later, it's just a boolean */
g_value_init (&ret, G_TYPE_BOOLEAN);
g_value_set_boolean (&ret, TRUE);
gst/gstutils.c: RPAD fixes all around. Original commit message from CVS: 2005-06-08 Andy Wingo <wingo@pobox.com> * gst/gstutils.c: RPAD fixes all around. (gst_element_link_pads): Refcounting fixes. * tools/gst-inspect.c: * tools/gst-xmlinspect.c: * parse/grammar.y: * gst/base/gsttypefindhelper.c: * gst/base/gstbasesink.c: * gst/gstqueue.c: RPAD fixes. * gst/gstghostpad.h: * gst/gstghostpad.c: New ghost pad implementation as full proxy pads. The tricky thing is they provide both source and sink interfaces, since they proxy the internal pad for the external pad, and vice versa. Implement with lower-level ProxyPad objects, with the interior proxy pad as a child of the exterior ghost pad. Should write a doc on this. * gst/gstpad.h: s/RPAD/PAD/, s/RealPad/Pad/. (gst_pad_set_name, gst_pad_set_parent): Macros removed, use gst_object API. * gst/gstpad.c: Big changes. No more stub base GstPad, now all pads are real pads. No ghost pads in this file. Not documenting the myriad s/RPAD/PAD/ and REALIZE fixes. (gst_pad_class_init): Add properties for "direction" and "template". Both are construct-only, so they can't change during the life of the pad. Fixes properly deriving from GstPad. (gst_pad_custom_new, gst_pad_custom_new_from_template): Gone. For derived objects, just set properties when creating the objects via g_object_new. (gst_pad_get_parent): Implement as a function, return NULL if the parent is not an element. (gst_pad_get_real_parent, gst_pad_add_ghost_pad) (gst_pad_remove_ghost_pad, gst_pad_realize): Removed. * gst/gstobject.c (gst_object_class_init): Make name a construct property. Don't set it in the object init. * gst/gstelement.c (gst_element_add_pad): Don't allow adding pads with UNKNOWN direction. (gst_element_add_ghost_pad): Remove non-orthogonal API. Replace with gst_element_add_pad (e, gst_ghost_pad_new (name, pad)). (gst_element_remove_pad): Remove ghost-pad special cases. (gst_element_pads_activate): Remove rpad cruft. * gst/gstbin.c (gst_bin_change_state): Use gst_pad_get_parent to catch the pad's-parent-not-an-element case. * gst/gst.h: Include gstghostpad.h. * gst/gst.c (init_post): No more real, ghost pads. * gst/Makefile.am: Add gstghostpad.[ch]. * check/Makefile.am: * check/gst/gstbin.c: * check/gst/gstghostpad.c (test_ghost_pads): Check that linking into a bin creates ghost pads, and that the refcounts are right. Partly moved from gstbin.c.
2005-06-08 22:16:27 +00:00
while (1) {
ires = gst_iterator_fold (iter, func, &ret, user_data);
gst/base/gsttypefindhelper.c (gst_type_find_helper): Unref any remaining buffer. Original commit message from CVS: 2005-06-27 Andy Wingo <wingo@pobox.com> * gst/base/gsttypefindhelper.c (gst_type_find_helper): Unref any remaining buffer. * gst/gsttrace.c (gst_alloc_trace_list_sorted): New helper, returns a sorted copy of the trace list. (gst_alloc_trace_print_live): New API, only prints traces with live objects. Sort the list. (gst_alloc_trace_print_all): Sort the list. (gst_alloc_trace_print): Align columns. * gst/elements/gstttypefindelement.c: * gst/elements/gsttee.c: * gst/base/gstbasesrc.c: * gst/base/gstbasesink.c: * gst/base/gstbasetransform.c: * gst/gstqueue.c: Adapt for pad activation changes. * gst/gstpipeline.c (gst_pipeline_init): Unref after parenting sched. (gst_pipeline_dispose): Drop ref on sched. * gst/gstpad.c (gst_pad_init): Set the default activate func. (gst_pad_activate_default): Push mode by default. (pre_activate_switch, post_activate_switch): New stubs, things to do before and after switching activation modes on pads. (gst_pad_set_active): Take a boolean and not a mode, dispatch to the pad's activate function to choose which mode to activate. Shortcut on deactivation and call the right function directly. (gst_pad_activate_pull): New API, (de)activates a pad in pull mode. (gst_pad_activate_push): New API, same for push mode. (gst_pad_set_activate_function) (gst_pad_set_activatepull_function) (gst_pad_set_activatepush_function): Setters for new API. * gst/gstminiobject.c (gst_mini_object_new, gst_mini_object_free): Trace all miniobjects. (gst_mini_object_make_writable): Unref the arg if we copy, like gst_caps_make_writable. * gst/gstmessage.c (_gst_message_initialize): No trace init. * gst/gstghostpad.c (gst_proxy_pad_do_activate) (gst_proxy_pad_do_activatepull, gst_proxy_pad_do_activatepush): Adapt for new pad API. * gst/gstevent.c (_gst_event_initialize): Don't initialize trace. * gst/gstelement.h: * gst/gstelement.c (gst_element_iterate_src_pads) (gst_element_iterate_sink_pads): New API functions. * gst/gstelement.c (iterator_fold_with_resync): New utility, should fold into gstiterator.c in some form. (gst_element_pads_activate): Simplified via use of fold and delegation of decisions to gstpad->activate. * gst/gstbus.c (gst_bus_source_finalize): Set the bus to NULL, help in debugging. * gst/gstbuffer.c (_gst_buffer_initialize): Ref the buffer type class once in init, like gstmessage. Didn't run into this issue but it seems correct. Don't initialize a trace, gstminiobject does that. * check/pipelines/simple_launch_lines.c (test_stop_from_app): New test, runs fakesrc ! fakesink, stopping on ::handoff via a message to the bus. (assert_live_count): New util function, uses alloc traces to check cleanup. * check/gst/gstghostpad.c (test_ghost_pads): More refcount checks. To be modified when unlink drops the internal pad.
2005-06-27 18:35:05 +00:00
switch (ires) {
case GST_ITERATOR_RESYNC:
/* need to reset the result again */
g_value_set_boolean (&ret, TRUE);
gst_iterator_resync (iter);
gst/base/gsttypefindhelper.c (gst_type_find_helper): Unref any remaining buffer. Original commit message from CVS: 2005-06-27 Andy Wingo <wingo@pobox.com> * gst/base/gsttypefindhelper.c (gst_type_find_helper): Unref any remaining buffer. * gst/gsttrace.c (gst_alloc_trace_list_sorted): New helper, returns a sorted copy of the trace list. (gst_alloc_trace_print_live): New API, only prints traces with live objects. Sort the list. (gst_alloc_trace_print_all): Sort the list. (gst_alloc_trace_print): Align columns. * gst/elements/gstttypefindelement.c: * gst/elements/gsttee.c: * gst/base/gstbasesrc.c: * gst/base/gstbasesink.c: * gst/base/gstbasetransform.c: * gst/gstqueue.c: Adapt for pad activation changes. * gst/gstpipeline.c (gst_pipeline_init): Unref after parenting sched. (gst_pipeline_dispose): Drop ref on sched. * gst/gstpad.c (gst_pad_init): Set the default activate func. (gst_pad_activate_default): Push mode by default. (pre_activate_switch, post_activate_switch): New stubs, things to do before and after switching activation modes on pads. (gst_pad_set_active): Take a boolean and not a mode, dispatch to the pad's activate function to choose which mode to activate. Shortcut on deactivation and call the right function directly. (gst_pad_activate_pull): New API, (de)activates a pad in pull mode. (gst_pad_activate_push): New API, same for push mode. (gst_pad_set_activate_function) (gst_pad_set_activatepull_function) (gst_pad_set_activatepush_function): Setters for new API. * gst/gstminiobject.c (gst_mini_object_new, gst_mini_object_free): Trace all miniobjects. (gst_mini_object_make_writable): Unref the arg if we copy, like gst_caps_make_writable. * gst/gstmessage.c (_gst_message_initialize): No trace init. * gst/gstghostpad.c (gst_proxy_pad_do_activate) (gst_proxy_pad_do_activatepull, gst_proxy_pad_do_activatepush): Adapt for new pad API. * gst/gstevent.c (_gst_event_initialize): Don't initialize trace. * gst/gstelement.h: * gst/gstelement.c (gst_element_iterate_src_pads) (gst_element_iterate_sink_pads): New API functions. * gst/gstelement.c (iterator_fold_with_resync): New utility, should fold into gstiterator.c in some form. (gst_element_pads_activate): Simplified via use of fold and delegation of decisions to gstpad->activate. * gst/gstbus.c (gst_bus_source_finalize): Set the bus to NULL, help in debugging. * gst/gstbuffer.c (_gst_buffer_initialize): Ref the buffer type class once in init, like gstmessage. Didn't run into this issue but it seems correct. Don't initialize a trace, gstminiobject does that. * check/pipelines/simple_launch_lines.c (test_stop_from_app): New test, runs fakesrc ! fakesink, stopping on ::handoff via a message to the bus. (assert_live_count): New util function, uses alloc traces to check cleanup. * check/gst/gstghostpad.c (test_ghost_pads): More refcount checks. To be modified when unlink drops the internal pad.
2005-06-27 18:35:05 +00:00
break;
case GST_ITERATOR_DONE:
/* all pads iterated, return collected value */
gst/base/gsttypefindhelper.c (gst_type_find_helper): Unref any remaining buffer. Original commit message from CVS: 2005-06-27 Andy Wingo <wingo@pobox.com> * gst/base/gsttypefindhelper.c (gst_type_find_helper): Unref any remaining buffer. * gst/gsttrace.c (gst_alloc_trace_list_sorted): New helper, returns a sorted copy of the trace list. (gst_alloc_trace_print_live): New API, only prints traces with live objects. Sort the list. (gst_alloc_trace_print_all): Sort the list. (gst_alloc_trace_print): Align columns. * gst/elements/gstttypefindelement.c: * gst/elements/gsttee.c: * gst/base/gstbasesrc.c: * gst/base/gstbasesink.c: * gst/base/gstbasetransform.c: * gst/gstqueue.c: Adapt for pad activation changes. * gst/gstpipeline.c (gst_pipeline_init): Unref after parenting sched. (gst_pipeline_dispose): Drop ref on sched. * gst/gstpad.c (gst_pad_init): Set the default activate func. (gst_pad_activate_default): Push mode by default. (pre_activate_switch, post_activate_switch): New stubs, things to do before and after switching activation modes on pads. (gst_pad_set_active): Take a boolean and not a mode, dispatch to the pad's activate function to choose which mode to activate. Shortcut on deactivation and call the right function directly. (gst_pad_activate_pull): New API, (de)activates a pad in pull mode. (gst_pad_activate_push): New API, same for push mode. (gst_pad_set_activate_function) (gst_pad_set_activatepull_function) (gst_pad_set_activatepush_function): Setters for new API. * gst/gstminiobject.c (gst_mini_object_new, gst_mini_object_free): Trace all miniobjects. (gst_mini_object_make_writable): Unref the arg if we copy, like gst_caps_make_writable. * gst/gstmessage.c (_gst_message_initialize): No trace init. * gst/gstghostpad.c (gst_proxy_pad_do_activate) (gst_proxy_pad_do_activatepull, gst_proxy_pad_do_activatepush): Adapt for new pad API. * gst/gstevent.c (_gst_event_initialize): Don't initialize trace. * gst/gstelement.h: * gst/gstelement.c (gst_element_iterate_src_pads) (gst_element_iterate_sink_pads): New API functions. * gst/gstelement.c (iterator_fold_with_resync): New utility, should fold into gstiterator.c in some form. (gst_element_pads_activate): Simplified via use of fold and delegation of decisions to gstpad->activate. * gst/gstbus.c (gst_bus_source_finalize): Set the bus to NULL, help in debugging. * gst/gstbuffer.c (_gst_buffer_initialize): Ref the buffer type class once in init, like gstmessage. Didn't run into this issue but it seems correct. Don't initialize a trace, gstminiobject does that. * check/pipelines/simple_launch_lines.c (test_stop_from_app): New test, runs fakesrc ! fakesink, stopping on ::handoff via a message to the bus. (assert_live_count): New util function, uses alloc traces to check cleanup. * check/gst/gstghostpad.c (test_ghost_pads): More refcount checks. To be modified when unlink drops the internal pad.
2005-06-27 18:35:05 +00:00
goto done;
default:
/* iterator returned _ERROR or premature end with _OK,
* mark an error and exit */
g_value_set_boolean (&ret, FALSE);
gst/base/gsttypefindhelper.c (gst_type_find_helper): Unref any remaining buffer. Original commit message from CVS: 2005-06-27 Andy Wingo <wingo@pobox.com> * gst/base/gsttypefindhelper.c (gst_type_find_helper): Unref any remaining buffer. * gst/gsttrace.c (gst_alloc_trace_list_sorted): New helper, returns a sorted copy of the trace list. (gst_alloc_trace_print_live): New API, only prints traces with live objects. Sort the list. (gst_alloc_trace_print_all): Sort the list. (gst_alloc_trace_print): Align columns. * gst/elements/gstttypefindelement.c: * gst/elements/gsttee.c: * gst/base/gstbasesrc.c: * gst/base/gstbasesink.c: * gst/base/gstbasetransform.c: * gst/gstqueue.c: Adapt for pad activation changes. * gst/gstpipeline.c (gst_pipeline_init): Unref after parenting sched. (gst_pipeline_dispose): Drop ref on sched. * gst/gstpad.c (gst_pad_init): Set the default activate func. (gst_pad_activate_default): Push mode by default. (pre_activate_switch, post_activate_switch): New stubs, things to do before and after switching activation modes on pads. (gst_pad_set_active): Take a boolean and not a mode, dispatch to the pad's activate function to choose which mode to activate. Shortcut on deactivation and call the right function directly. (gst_pad_activate_pull): New API, (de)activates a pad in pull mode. (gst_pad_activate_push): New API, same for push mode. (gst_pad_set_activate_function) (gst_pad_set_activatepull_function) (gst_pad_set_activatepush_function): Setters for new API. * gst/gstminiobject.c (gst_mini_object_new, gst_mini_object_free): Trace all miniobjects. (gst_mini_object_make_writable): Unref the arg if we copy, like gst_caps_make_writable. * gst/gstmessage.c (_gst_message_initialize): No trace init. * gst/gstghostpad.c (gst_proxy_pad_do_activate) (gst_proxy_pad_do_activatepull, gst_proxy_pad_do_activatepush): Adapt for new pad API. * gst/gstevent.c (_gst_event_initialize): Don't initialize trace. * gst/gstelement.h: * gst/gstelement.c (gst_element_iterate_src_pads) (gst_element_iterate_sink_pads): New API functions. * gst/gstelement.c (iterator_fold_with_resync): New utility, should fold into gstiterator.c in some form. (gst_element_pads_activate): Simplified via use of fold and delegation of decisions to gstpad->activate. * gst/gstbus.c (gst_bus_source_finalize): Set the bus to NULL, help in debugging. * gst/gstbuffer.c (_gst_buffer_initialize): Ref the buffer type class once in init, like gstmessage. Didn't run into this issue but it seems correct. Don't initialize a trace, gstminiobject does that. * check/pipelines/simple_launch_lines.c (test_stop_from_app): New test, runs fakesrc ! fakesink, stopping on ::handoff via a message to the bus. (assert_live_count): New util function, uses alloc traces to check cleanup. * check/gst/gstghostpad.c (test_ghost_pads): More refcount checks. To be modified when unlink drops the internal pad.
2005-06-27 18:35:05 +00:00
goto done;
}
}
done:
/* return collected value */
return g_value_get_boolean (&ret);
gst/base/gsttypefindhelper.c (gst_type_find_helper): Unref any remaining buffer. Original commit message from CVS: 2005-06-27 Andy Wingo <wingo@pobox.com> * gst/base/gsttypefindhelper.c (gst_type_find_helper): Unref any remaining buffer. * gst/gsttrace.c (gst_alloc_trace_list_sorted): New helper, returns a sorted copy of the trace list. (gst_alloc_trace_print_live): New API, only prints traces with live objects. Sort the list. (gst_alloc_trace_print_all): Sort the list. (gst_alloc_trace_print): Align columns. * gst/elements/gstttypefindelement.c: * gst/elements/gsttee.c: * gst/base/gstbasesrc.c: * gst/base/gstbasesink.c: * gst/base/gstbasetransform.c: * gst/gstqueue.c: Adapt for pad activation changes. * gst/gstpipeline.c (gst_pipeline_init): Unref after parenting sched. (gst_pipeline_dispose): Drop ref on sched. * gst/gstpad.c (gst_pad_init): Set the default activate func. (gst_pad_activate_default): Push mode by default. (pre_activate_switch, post_activate_switch): New stubs, things to do before and after switching activation modes on pads. (gst_pad_set_active): Take a boolean and not a mode, dispatch to the pad's activate function to choose which mode to activate. Shortcut on deactivation and call the right function directly. (gst_pad_activate_pull): New API, (de)activates a pad in pull mode. (gst_pad_activate_push): New API, same for push mode. (gst_pad_set_activate_function) (gst_pad_set_activatepull_function) (gst_pad_set_activatepush_function): Setters for new API. * gst/gstminiobject.c (gst_mini_object_new, gst_mini_object_free): Trace all miniobjects. (gst_mini_object_make_writable): Unref the arg if we copy, like gst_caps_make_writable. * gst/gstmessage.c (_gst_message_initialize): No trace init. * gst/gstghostpad.c (gst_proxy_pad_do_activate) (gst_proxy_pad_do_activatepull, gst_proxy_pad_do_activatepush): Adapt for new pad API. * gst/gstevent.c (_gst_event_initialize): Don't initialize trace. * gst/gstelement.h: * gst/gstelement.c (gst_element_iterate_src_pads) (gst_element_iterate_sink_pads): New API functions. * gst/gstelement.c (iterator_fold_with_resync): New utility, should fold into gstiterator.c in some form. (gst_element_pads_activate): Simplified via use of fold and delegation of decisions to gstpad->activate. * gst/gstbus.c (gst_bus_source_finalize): Set the bus to NULL, help in debugging. * gst/gstbuffer.c (_gst_buffer_initialize): Ref the buffer type class once in init, like gstmessage. Didn't run into this issue but it seems correct. Don't initialize a trace, gstminiobject does that. * check/pipelines/simple_launch_lines.c (test_stop_from_app): New test, runs fakesrc ! fakesink, stopping on ::handoff via a message to the bus. (assert_live_count): New util function, uses alloc traces to check cleanup. * check/gst/gstghostpad.c (test_ghost_pads): More refcount checks. To be modified when unlink drops the internal pad.
2005-06-27 18:35:05 +00:00
}
gst/gstutils.c: RPAD fixes all around. Original commit message from CVS: 2005-06-08 Andy Wingo <wingo@pobox.com> * gst/gstutils.c: RPAD fixes all around. (gst_element_link_pads): Refcounting fixes. * tools/gst-inspect.c: * tools/gst-xmlinspect.c: * parse/grammar.y: * gst/base/gsttypefindhelper.c: * gst/base/gstbasesink.c: * gst/gstqueue.c: RPAD fixes. * gst/gstghostpad.h: * gst/gstghostpad.c: New ghost pad implementation as full proxy pads. The tricky thing is they provide both source and sink interfaces, since they proxy the internal pad for the external pad, and vice versa. Implement with lower-level ProxyPad objects, with the interior proxy pad as a child of the exterior ghost pad. Should write a doc on this. * gst/gstpad.h: s/RPAD/PAD/, s/RealPad/Pad/. (gst_pad_set_name, gst_pad_set_parent): Macros removed, use gst_object API. * gst/gstpad.c: Big changes. No more stub base GstPad, now all pads are real pads. No ghost pads in this file. Not documenting the myriad s/RPAD/PAD/ and REALIZE fixes. (gst_pad_class_init): Add properties for "direction" and "template". Both are construct-only, so they can't change during the life of the pad. Fixes properly deriving from GstPad. (gst_pad_custom_new, gst_pad_custom_new_from_template): Gone. For derived objects, just set properties when creating the objects via g_object_new. (gst_pad_get_parent): Implement as a function, return NULL if the parent is not an element. (gst_pad_get_real_parent, gst_pad_add_ghost_pad) (gst_pad_remove_ghost_pad, gst_pad_realize): Removed. * gst/gstobject.c (gst_object_class_init): Make name a construct property. Don't set it in the object init. * gst/gstelement.c (gst_element_add_pad): Don't allow adding pads with UNKNOWN direction. (gst_element_add_ghost_pad): Remove non-orthogonal API. Replace with gst_element_add_pad (e, gst_ghost_pad_new (name, pad)). (gst_element_remove_pad): Remove ghost-pad special cases. (gst_element_pads_activate): Remove rpad cruft. * gst/gstbin.c (gst_bin_change_state): Use gst_pad_get_parent to catch the pad's-parent-not-an-element case. * gst/gst.h: Include gstghostpad.h. * gst/gst.c (init_post): No more real, ghost pads. * gst/Makefile.am: Add gstghostpad.[ch]. * check/Makefile.am: * check/gst/gstbin.c: * check/gst/gstghostpad.c (test_ghost_pads): Check that linking into a bin creates ghost pads, and that the refcounts are right. Partly moved from gstbin.c.
2005-06-08 22:16:27 +00:00
gst/base/gsttypefindhelper.c (gst_type_find_helper): Unref any remaining buffer. Original commit message from CVS: 2005-06-27 Andy Wingo <wingo@pobox.com> * gst/base/gsttypefindhelper.c (gst_type_find_helper): Unref any remaining buffer. * gst/gsttrace.c (gst_alloc_trace_list_sorted): New helper, returns a sorted copy of the trace list. (gst_alloc_trace_print_live): New API, only prints traces with live objects. Sort the list. (gst_alloc_trace_print_all): Sort the list. (gst_alloc_trace_print): Align columns. * gst/elements/gstttypefindelement.c: * gst/elements/gsttee.c: * gst/base/gstbasesrc.c: * gst/base/gstbasesink.c: * gst/base/gstbasetransform.c: * gst/gstqueue.c: Adapt for pad activation changes. * gst/gstpipeline.c (gst_pipeline_init): Unref after parenting sched. (gst_pipeline_dispose): Drop ref on sched. * gst/gstpad.c (gst_pad_init): Set the default activate func. (gst_pad_activate_default): Push mode by default. (pre_activate_switch, post_activate_switch): New stubs, things to do before and after switching activation modes on pads. (gst_pad_set_active): Take a boolean and not a mode, dispatch to the pad's activate function to choose which mode to activate. Shortcut on deactivation and call the right function directly. (gst_pad_activate_pull): New API, (de)activates a pad in pull mode. (gst_pad_activate_push): New API, same for push mode. (gst_pad_set_activate_function) (gst_pad_set_activatepull_function) (gst_pad_set_activatepush_function): Setters for new API. * gst/gstminiobject.c (gst_mini_object_new, gst_mini_object_free): Trace all miniobjects. (gst_mini_object_make_writable): Unref the arg if we copy, like gst_caps_make_writable. * gst/gstmessage.c (_gst_message_initialize): No trace init. * gst/gstghostpad.c (gst_proxy_pad_do_activate) (gst_proxy_pad_do_activatepull, gst_proxy_pad_do_activatepush): Adapt for new pad API. * gst/gstevent.c (_gst_event_initialize): Don't initialize trace. * gst/gstelement.h: * gst/gstelement.c (gst_element_iterate_src_pads) (gst_element_iterate_sink_pads): New API functions. * gst/gstelement.c (iterator_fold_with_resync): New utility, should fold into gstiterator.c in some form. (gst_element_pads_activate): Simplified via use of fold and delegation of decisions to gstpad->activate. * gst/gstbus.c (gst_bus_source_finalize): Set the bus to NULL, help in debugging. * gst/gstbuffer.c (_gst_buffer_initialize): Ref the buffer type class once in init, like gstmessage. Didn't run into this issue but it seems correct. Don't initialize a trace, gstminiobject does that. * check/pipelines/simple_launch_lines.c (test_stop_from_app): New test, runs fakesrc ! fakesink, stopping on ::handoff via a message to the bus. (assert_live_count): New util function, uses alloc traces to check cleanup. * check/gst/gstghostpad.c (test_ghost_pads): More refcount checks. To be modified when unlink drops the internal pad.
2005-06-27 18:35:05 +00:00
/* is called with STATE_LOCK
*
* Pads are activated from source pads to sinkpads.
gst/base/gsttypefindhelper.c (gst_type_find_helper): Unref any remaining buffer. Original commit message from CVS: 2005-06-27 Andy Wingo <wingo@pobox.com> * gst/base/gsttypefindhelper.c (gst_type_find_helper): Unref any remaining buffer. * gst/gsttrace.c (gst_alloc_trace_list_sorted): New helper, returns a sorted copy of the trace list. (gst_alloc_trace_print_live): New API, only prints traces with live objects. Sort the list. (gst_alloc_trace_print_all): Sort the list. (gst_alloc_trace_print): Align columns. * gst/elements/gstttypefindelement.c: * gst/elements/gsttee.c: * gst/base/gstbasesrc.c: * gst/base/gstbasesink.c: * gst/base/gstbasetransform.c: * gst/gstqueue.c: Adapt for pad activation changes. * gst/gstpipeline.c (gst_pipeline_init): Unref after parenting sched. (gst_pipeline_dispose): Drop ref on sched. * gst/gstpad.c (gst_pad_init): Set the default activate func. (gst_pad_activate_default): Push mode by default. (pre_activate_switch, post_activate_switch): New stubs, things to do before and after switching activation modes on pads. (gst_pad_set_active): Take a boolean and not a mode, dispatch to the pad's activate function to choose which mode to activate. Shortcut on deactivation and call the right function directly. (gst_pad_activate_pull): New API, (de)activates a pad in pull mode. (gst_pad_activate_push): New API, same for push mode. (gst_pad_set_activate_function) (gst_pad_set_activatepull_function) (gst_pad_set_activatepush_function): Setters for new API. * gst/gstminiobject.c (gst_mini_object_new, gst_mini_object_free): Trace all miniobjects. (gst_mini_object_make_writable): Unref the arg if we copy, like gst_caps_make_writable. * gst/gstmessage.c (_gst_message_initialize): No trace init. * gst/gstghostpad.c (gst_proxy_pad_do_activate) (gst_proxy_pad_do_activatepull, gst_proxy_pad_do_activatepush): Adapt for new pad API. * gst/gstevent.c (_gst_event_initialize): Don't initialize trace. * gst/gstelement.h: * gst/gstelement.c (gst_element_iterate_src_pads) (gst_element_iterate_sink_pads): New API functions. * gst/gstelement.c (iterator_fold_with_resync): New utility, should fold into gstiterator.c in some form. (gst_element_pads_activate): Simplified via use of fold and delegation of decisions to gstpad->activate. * gst/gstbus.c (gst_bus_source_finalize): Set the bus to NULL, help in debugging. * gst/gstbuffer.c (_gst_buffer_initialize): Ref the buffer type class once in init, like gstmessage. Didn't run into this issue but it seems correct. Don't initialize a trace, gstminiobject does that. * check/pipelines/simple_launch_lines.c (test_stop_from_app): New test, runs fakesrc ! fakesink, stopping on ::handoff via a message to the bus. (assert_live_count): New util function, uses alloc traces to check cleanup. * check/gst/gstghostpad.c (test_ghost_pads): More refcount checks. To be modified when unlink drops the internal pad.
2005-06-27 18:35:05 +00:00
*/
static gboolean
gst_element_pads_activate (GstElement * element, gboolean active)
{
GstIterator *iter;
gboolean res;
gst/base/gsttypefindhelper.c (gst_type_find_helper): Unref any remaining buffer. Original commit message from CVS: 2005-06-27 Andy Wingo <wingo@pobox.com> * gst/base/gsttypefindhelper.c (gst_type_find_helper): Unref any remaining buffer. * gst/gsttrace.c (gst_alloc_trace_list_sorted): New helper, returns a sorted copy of the trace list. (gst_alloc_trace_print_live): New API, only prints traces with live objects. Sort the list. (gst_alloc_trace_print_all): Sort the list. (gst_alloc_trace_print): Align columns. * gst/elements/gstttypefindelement.c: * gst/elements/gsttee.c: * gst/base/gstbasesrc.c: * gst/base/gstbasesink.c: * gst/base/gstbasetransform.c: * gst/gstqueue.c: Adapt for pad activation changes. * gst/gstpipeline.c (gst_pipeline_init): Unref after parenting sched. (gst_pipeline_dispose): Drop ref on sched. * gst/gstpad.c (gst_pad_init): Set the default activate func. (gst_pad_activate_default): Push mode by default. (pre_activate_switch, post_activate_switch): New stubs, things to do before and after switching activation modes on pads. (gst_pad_set_active): Take a boolean and not a mode, dispatch to the pad's activate function to choose which mode to activate. Shortcut on deactivation and call the right function directly. (gst_pad_activate_pull): New API, (de)activates a pad in pull mode. (gst_pad_activate_push): New API, same for push mode. (gst_pad_set_activate_function) (gst_pad_set_activatepull_function) (gst_pad_set_activatepush_function): Setters for new API. * gst/gstminiobject.c (gst_mini_object_new, gst_mini_object_free): Trace all miniobjects. (gst_mini_object_make_writable): Unref the arg if we copy, like gst_caps_make_writable. * gst/gstmessage.c (_gst_message_initialize): No trace init. * gst/gstghostpad.c (gst_proxy_pad_do_activate) (gst_proxy_pad_do_activatepull, gst_proxy_pad_do_activatepush): Adapt for new pad API. * gst/gstevent.c (_gst_event_initialize): Don't initialize trace. * gst/gstelement.h: * gst/gstelement.c (gst_element_iterate_src_pads) (gst_element_iterate_sink_pads): New API functions. * gst/gstelement.c (iterator_fold_with_resync): New utility, should fold into gstiterator.c in some form. (gst_element_pads_activate): Simplified via use of fold and delegation of decisions to gstpad->activate. * gst/gstbus.c (gst_bus_source_finalize): Set the bus to NULL, help in debugging. * gst/gstbuffer.c (_gst_buffer_initialize): Ref the buffer type class once in init, like gstmessage. Didn't run into this issue but it seems correct. Don't initialize a trace, gstminiobject does that. * check/pipelines/simple_launch_lines.c (test_stop_from_app): New test, runs fakesrc ! fakesink, stopping on ::handoff via a message to the bus. (assert_live_count): New util function, uses alloc traces to check cleanup. * check/gst/gstghostpad.c (test_ghost_pads): More refcount checks. To be modified when unlink drops the internal pad.
2005-06-27 18:35:05 +00:00
GST_CAT_DEBUG_OBJECT (GST_CAT_ELEMENT_PADS, element,
"%s pads", active ? "activate" : "deactivate");
iter = gst_element_iterate_src_pads (element);
res =
iterator_activate_fold_with_resync (iter,
(GstIteratorFoldFunction) activate_pads, &active);
gst/base/gsttypefindhelper.c (gst_type_find_helper): Unref any remaining buffer. Original commit message from CVS: 2005-06-27 Andy Wingo <wingo@pobox.com> * gst/base/gsttypefindhelper.c (gst_type_find_helper): Unref any remaining buffer. * gst/gsttrace.c (gst_alloc_trace_list_sorted): New helper, returns a sorted copy of the trace list. (gst_alloc_trace_print_live): New API, only prints traces with live objects. Sort the list. (gst_alloc_trace_print_all): Sort the list. (gst_alloc_trace_print): Align columns. * gst/elements/gstttypefindelement.c: * gst/elements/gsttee.c: * gst/base/gstbasesrc.c: * gst/base/gstbasesink.c: * gst/base/gstbasetransform.c: * gst/gstqueue.c: Adapt for pad activation changes. * gst/gstpipeline.c (gst_pipeline_init): Unref after parenting sched. (gst_pipeline_dispose): Drop ref on sched. * gst/gstpad.c (gst_pad_init): Set the default activate func. (gst_pad_activate_default): Push mode by default. (pre_activate_switch, post_activate_switch): New stubs, things to do before and after switching activation modes on pads. (gst_pad_set_active): Take a boolean and not a mode, dispatch to the pad's activate function to choose which mode to activate. Shortcut on deactivation and call the right function directly. (gst_pad_activate_pull): New API, (de)activates a pad in pull mode. (gst_pad_activate_push): New API, same for push mode. (gst_pad_set_activate_function) (gst_pad_set_activatepull_function) (gst_pad_set_activatepush_function): Setters for new API. * gst/gstminiobject.c (gst_mini_object_new, gst_mini_object_free): Trace all miniobjects. (gst_mini_object_make_writable): Unref the arg if we copy, like gst_caps_make_writable. * gst/gstmessage.c (_gst_message_initialize): No trace init. * gst/gstghostpad.c (gst_proxy_pad_do_activate) (gst_proxy_pad_do_activatepull, gst_proxy_pad_do_activatepush): Adapt for new pad API. * gst/gstevent.c (_gst_event_initialize): Don't initialize trace. * gst/gstelement.h: * gst/gstelement.c (gst_element_iterate_src_pads) (gst_element_iterate_sink_pads): New API functions. * gst/gstelement.c (iterator_fold_with_resync): New utility, should fold into gstiterator.c in some form. (gst_element_pads_activate): Simplified via use of fold and delegation of decisions to gstpad->activate. * gst/gstbus.c (gst_bus_source_finalize): Set the bus to NULL, help in debugging. * gst/gstbuffer.c (_gst_buffer_initialize): Ref the buffer type class once in init, like gstmessage. Didn't run into this issue but it seems correct. Don't initialize a trace, gstminiobject does that. * check/pipelines/simple_launch_lines.c (test_stop_from_app): New test, runs fakesrc ! fakesink, stopping on ::handoff via a message to the bus. (assert_live_count): New util function, uses alloc traces to check cleanup. * check/gst/gstghostpad.c (test_ghost_pads): More refcount checks. To be modified when unlink drops the internal pad.
2005-06-27 18:35:05 +00:00
gst_iterator_free (iter);
if (G_UNLIKELY (!res))
goto src_failed;
iter = gst_element_iterate_sink_pads (element);
res =
iterator_activate_fold_with_resync (iter,
(GstIteratorFoldFunction) activate_pads, &active);
gst/base/gsttypefindhelper.c (gst_type_find_helper): Unref any remaining buffer. Original commit message from CVS: 2005-06-27 Andy Wingo <wingo@pobox.com> * gst/base/gsttypefindhelper.c (gst_type_find_helper): Unref any remaining buffer. * gst/gsttrace.c (gst_alloc_trace_list_sorted): New helper, returns a sorted copy of the trace list. (gst_alloc_trace_print_live): New API, only prints traces with live objects. Sort the list. (gst_alloc_trace_print_all): Sort the list. (gst_alloc_trace_print): Align columns. * gst/elements/gstttypefindelement.c: * gst/elements/gsttee.c: * gst/base/gstbasesrc.c: * gst/base/gstbasesink.c: * gst/base/gstbasetransform.c: * gst/gstqueue.c: Adapt for pad activation changes. * gst/gstpipeline.c (gst_pipeline_init): Unref after parenting sched. (gst_pipeline_dispose): Drop ref on sched. * gst/gstpad.c (gst_pad_init): Set the default activate func. (gst_pad_activate_default): Push mode by default. (pre_activate_switch, post_activate_switch): New stubs, things to do before and after switching activation modes on pads. (gst_pad_set_active): Take a boolean and not a mode, dispatch to the pad's activate function to choose which mode to activate. Shortcut on deactivation and call the right function directly. (gst_pad_activate_pull): New API, (de)activates a pad in pull mode. (gst_pad_activate_push): New API, same for push mode. (gst_pad_set_activate_function) (gst_pad_set_activatepull_function) (gst_pad_set_activatepush_function): Setters for new API. * gst/gstminiobject.c (gst_mini_object_new, gst_mini_object_free): Trace all miniobjects. (gst_mini_object_make_writable): Unref the arg if we copy, like gst_caps_make_writable. * gst/gstmessage.c (_gst_message_initialize): No trace init. * gst/gstghostpad.c (gst_proxy_pad_do_activate) (gst_proxy_pad_do_activatepull, gst_proxy_pad_do_activatepush): Adapt for new pad API. * gst/gstevent.c (_gst_event_initialize): Don't initialize trace. * gst/gstelement.h: * gst/gstelement.c (gst_element_iterate_src_pads) (gst_element_iterate_sink_pads): New API functions. * gst/gstelement.c (iterator_fold_with_resync): New utility, should fold into gstiterator.c in some form. (gst_element_pads_activate): Simplified via use of fold and delegation of decisions to gstpad->activate. * gst/gstbus.c (gst_bus_source_finalize): Set the bus to NULL, help in debugging. * gst/gstbuffer.c (_gst_buffer_initialize): Ref the buffer type class once in init, like gstmessage. Didn't run into this issue but it seems correct. Don't initialize a trace, gstminiobject does that. * check/pipelines/simple_launch_lines.c (test_stop_from_app): New test, runs fakesrc ! fakesink, stopping on ::handoff via a message to the bus. (assert_live_count): New util function, uses alloc traces to check cleanup. * check/gst/gstghostpad.c (test_ghost_pads): More refcount checks. To be modified when unlink drops the internal pad.
2005-06-27 18:35:05 +00:00
gst_iterator_free (iter);
if (G_UNLIKELY (!res))
goto sink_failed;
GST_CAT_DEBUG_OBJECT (GST_CAT_ELEMENT_PADS, element,
"pad %sactivation successful", active ? "" : "de");
gst/base/gsttypefindhelper.c (gst_type_find_helper): Unref any remaining buffer. Original commit message from CVS: 2005-06-27 Andy Wingo <wingo@pobox.com> * gst/base/gsttypefindhelper.c (gst_type_find_helper): Unref any remaining buffer. * gst/gsttrace.c (gst_alloc_trace_list_sorted): New helper, returns a sorted copy of the trace list. (gst_alloc_trace_print_live): New API, only prints traces with live objects. Sort the list. (gst_alloc_trace_print_all): Sort the list. (gst_alloc_trace_print): Align columns. * gst/elements/gstttypefindelement.c: * gst/elements/gsttee.c: * gst/base/gstbasesrc.c: * gst/base/gstbasesink.c: * gst/base/gstbasetransform.c: * gst/gstqueue.c: Adapt for pad activation changes. * gst/gstpipeline.c (gst_pipeline_init): Unref after parenting sched. (gst_pipeline_dispose): Drop ref on sched. * gst/gstpad.c (gst_pad_init): Set the default activate func. (gst_pad_activate_default): Push mode by default. (pre_activate_switch, post_activate_switch): New stubs, things to do before and after switching activation modes on pads. (gst_pad_set_active): Take a boolean and not a mode, dispatch to the pad's activate function to choose which mode to activate. Shortcut on deactivation and call the right function directly. (gst_pad_activate_pull): New API, (de)activates a pad in pull mode. (gst_pad_activate_push): New API, same for push mode. (gst_pad_set_activate_function) (gst_pad_set_activatepull_function) (gst_pad_set_activatepush_function): Setters for new API. * gst/gstminiobject.c (gst_mini_object_new, gst_mini_object_free): Trace all miniobjects. (gst_mini_object_make_writable): Unref the arg if we copy, like gst_caps_make_writable. * gst/gstmessage.c (_gst_message_initialize): No trace init. * gst/gstghostpad.c (gst_proxy_pad_do_activate) (gst_proxy_pad_do_activatepull, gst_proxy_pad_do_activatepush): Adapt for new pad API. * gst/gstevent.c (_gst_event_initialize): Don't initialize trace. * gst/gstelement.h: * gst/gstelement.c (gst_element_iterate_src_pads) (gst_element_iterate_sink_pads): New API functions. * gst/gstelement.c (iterator_fold_with_resync): New utility, should fold into gstiterator.c in some form. (gst_element_pads_activate): Simplified via use of fold and delegation of decisions to gstpad->activate. * gst/gstbus.c (gst_bus_source_finalize): Set the bus to NULL, help in debugging. * gst/gstbuffer.c (_gst_buffer_initialize): Ref the buffer type class once in init, like gstmessage. Didn't run into this issue but it seems correct. Don't initialize a trace, gstminiobject does that. * check/pipelines/simple_launch_lines.c (test_stop_from_app): New test, runs fakesrc ! fakesink, stopping on ::handoff via a message to the bus. (assert_live_count): New util function, uses alloc traces to check cleanup. * check/gst/gstghostpad.c (test_ghost_pads): More refcount checks. To be modified when unlink drops the internal pad.
2005-06-27 18:35:05 +00:00
return TRUE;
/* ERRORS */
src_failed:
{
GST_CAT_DEBUG_OBJECT (GST_CAT_ELEMENT_PADS, element,
"pad %sactivation failed", active ? "" : "de");
return FALSE;
}
sink_failed:
{
GST_CAT_DEBUG_OBJECT (GST_CAT_ELEMENT_PADS, element,
"sink pads_activate failed");
return FALSE;
}
}
/* is called with STATE_LOCK */
static GstStateChangeReturn
gst_element_change_state_func (GstElement * element, GstStateChange transition)
- some fixes to int2float making automake 1.5 happy (gst now requires automake1.5). It's still not perfect but it bui... Original commit message from CVS: - added playondemand plugin by Leif Morgan Johnson <lmjohns3@eos.ncsu.edu> - some fixes to int2float - aplied a patch from wrobell <wrobell@ite.pl> that is a first attempt at making automake 1.5 happy (gst now requires automake1.5). It's still not perfect but it builds. - Made the schedulers plugable. The default scheduler now lives inside a plugin. - Added a new mpeg1/2 parser/demuxer. - Fixed some compiler warnings in the core libs. - substantial work to GstThread (hopefully less race conditions). simplified the code in GstThread a bit. A state change can now also happen in the thread context. - reworked the state semantics of a bin. it'll now automatically get the highest state of its children. - the autoplugger now nests the threads so that a state change failure of one thread doesn't make its upstream thread lock. - GstQueue refuses to go to PLAYING if the sinkpad is not connected. This way the queue will not wedge in the _get lock. - GstQueue unlocks its mutexes when going to PAUSED. - make sure that when all elements in a bin/thread go to PAUSED, the bin is set to PAUSED too. - make a parent bin wait for its children to PAUSE before ending the iteration with FALSE (EOS) - Some changes to GstPlay to deal with EOS. - aplied the latest patch from Zeenix to gstrtp. end result: GstPlay doesn't crash on EOS and the pipeline is now shut down properly.
2001-12-04 22:12:50 +00:00
{
GstState state, next;
GstStateChangeReturn result = GST_STATE_CHANGE_SUCCESS;
- some fixes to int2float making automake 1.5 happy (gst now requires automake1.5). It's still not perfect but it bui... Original commit message from CVS: - added playondemand plugin by Leif Morgan Johnson <lmjohns3@eos.ncsu.edu> - some fixes to int2float - aplied a patch from wrobell <wrobell@ite.pl> that is a first attempt at making automake 1.5 happy (gst now requires automake1.5). It's still not perfect but it builds. - Made the schedulers plugable. The default scheduler now lives inside a plugin. - Added a new mpeg1/2 parser/demuxer. - Fixed some compiler warnings in the core libs. - substantial work to GstThread (hopefully less race conditions). simplified the code in GstThread a bit. A state change can now also happen in the thread context. - reworked the state semantics of a bin. it'll now automatically get the highest state of its children. - the autoplugger now nests the threads so that a state change failure of one thread doesn't make its upstream thread lock. - GstQueue refuses to go to PLAYING if the sinkpad is not connected. This way the queue will not wedge in the _get lock. - GstQueue unlocks its mutexes when going to PAUSED. - make sure that when all elements in a bin/thread go to PAUSED, the bin is set to PAUSED too. - make a parent bin wait for its children to PAUSE before ending the iteration with FALSE (EOS) - Some changes to GstPlay to deal with EOS. - aplied the latest patch from Zeenix to gstrtp. end result: GstPlay doesn't crash on EOS and the pipeline is now shut down properly.
2001-12-04 22:12:50 +00:00
g_return_val_if_fail (GST_IS_ELEMENT (element), GST_STATE_CHANGE_FAILURE);
- some fixes to int2float making automake 1.5 happy (gst now requires automake1.5). It's still not perfect but it bui... Original commit message from CVS: - added playondemand plugin by Leif Morgan Johnson <lmjohns3@eos.ncsu.edu> - some fixes to int2float - aplied a patch from wrobell <wrobell@ite.pl> that is a first attempt at making automake 1.5 happy (gst now requires automake1.5). It's still not perfect but it builds. - Made the schedulers plugable. The default scheduler now lives inside a plugin. - Added a new mpeg1/2 parser/demuxer. - Fixed some compiler warnings in the core libs. - substantial work to GstThread (hopefully less race conditions). simplified the code in GstThread a bit. A state change can now also happen in the thread context. - reworked the state semantics of a bin. it'll now automatically get the highest state of its children. - the autoplugger now nests the threads so that a state change failure of one thread doesn't make its upstream thread lock. - GstQueue refuses to go to PLAYING if the sinkpad is not connected. This way the queue will not wedge in the _get lock. - GstQueue unlocks its mutexes when going to PAUSED. - make sure that when all elements in a bin/thread go to PAUSED, the bin is set to PAUSED too. - make a parent bin wait for its children to PAUSE before ending the iteration with FALSE (EOS) - Some changes to GstPlay to deal with EOS. - aplied the latest patch from Zeenix to gstrtp. end result: GstPlay doesn't crash on EOS and the pipeline is now shut down properly.
2001-12-04 22:12:50 +00:00
state = (GstState) GST_STATE_TRANSITION_CURRENT (transition);
2005-10-10 16:38:26 +00:00
next = GST_STATE_TRANSITION_NEXT (transition);
- some fixes to int2float making automake 1.5 happy (gst now requires automake1.5). It's still not perfect but it bui... Original commit message from CVS: - added playondemand plugin by Leif Morgan Johnson <lmjohns3@eos.ncsu.edu> - some fixes to int2float - aplied a patch from wrobell <wrobell@ite.pl> that is a first attempt at making automake 1.5 happy (gst now requires automake1.5). It's still not perfect but it builds. - Made the schedulers plugable. The default scheduler now lives inside a plugin. - Added a new mpeg1/2 parser/demuxer. - Fixed some compiler warnings in the core libs. - substantial work to GstThread (hopefully less race conditions). simplified the code in GstThread a bit. A state change can now also happen in the thread context. - reworked the state semantics of a bin. it'll now automatically get the highest state of its children. - the autoplugger now nests the threads so that a state change failure of one thread doesn't make its upstream thread lock. - GstQueue refuses to go to PLAYING if the sinkpad is not connected. This way the queue will not wedge in the _get lock. - GstQueue unlocks its mutexes when going to PAUSED. - make sure that when all elements in a bin/thread go to PAUSED, the bin is set to PAUSED too. - make a parent bin wait for its children to PAUSE before ending the iteration with FALSE (EOS) - Some changes to GstPlay to deal with EOS. - aplied the latest patch from Zeenix to gstrtp. end result: GstPlay doesn't crash on EOS and the pipeline is now shut down properly.
2001-12-04 22:12:50 +00:00
/* if the element already is in the given state, we just return success */
if (next == GST_STATE_VOID_PENDING || state == next)
goto was_ok;
GST_CAT_LOG_OBJECT (GST_CAT_STATES, element,
"default handler tries setting state from %s to %s (%04x)",
gst_element_state_get_name (state),
gst_element_state_get_name (next), transition);
- some fixes to int2float making automake 1.5 happy (gst now requires automake1.5). It's still not perfect but it bui... Original commit message from CVS: - added playondemand plugin by Leif Morgan Johnson <lmjohns3@eos.ncsu.edu> - some fixes to int2float - aplied a patch from wrobell <wrobell@ite.pl> that is a first attempt at making automake 1.5 happy (gst now requires automake1.5). It's still not perfect but it builds. - Made the schedulers plugable. The default scheduler now lives inside a plugin. - Added a new mpeg1/2 parser/demuxer. - Fixed some compiler warnings in the core libs. - substantial work to GstThread (hopefully less race conditions). simplified the code in GstThread a bit. A state change can now also happen in the thread context. - reworked the state semantics of a bin. it'll now automatically get the highest state of its children. - the autoplugger now nests the threads so that a state change failure of one thread doesn't make its upstream thread lock. - GstQueue refuses to go to PLAYING if the sinkpad is not connected. This way the queue will not wedge in the _get lock. - GstQueue unlocks its mutexes when going to PAUSED. - make sure that when all elements in a bin/thread go to PAUSED, the bin is set to PAUSED too. - make a parent bin wait for its children to PAUSE before ending the iteration with FALSE (EOS) - Some changes to GstPlay to deal with EOS. - aplied the latest patch from Zeenix to gstrtp. end result: GstPlay doesn't crash on EOS and the pipeline is now shut down properly.
2001-12-04 22:12:50 +00:00
switch (transition) {
case GST_STATE_CHANGE_NULL_TO_READY:
break;
case GST_STATE_CHANGE_READY_TO_PAUSED:
if (!gst_element_pads_activate (element, TRUE)) {
result = GST_STATE_CHANGE_FAILURE;
gst/gstclock.*: deprecate old interface and disable functions that aren't in use anymore. Original commit message from CVS: 2004-01-13 Benjamin Otte <in7y118@public.uni-hamburg.de> * gst/gstclock.c: (gst_clock_class_init), (gst_clock_init), (gst_clock_set_speed), (gst_clock_set_active), (gst_clock_is_active), (gst_clock_reset), (gst_clock_handle_discont): * gst/gstclock.h: deprecate old interface and disable functions that aren't in use anymore. * gst/gstelement.h: * gst/gstelement.c: (gst_element_get_time), (gst_element_wait), (gst_element_set_time), (gst_element_adjust_time): add concept of "element time" and functions to get/set this time. * gst/gstelement.c: (gst_element_change_state): update element time correctly. * gst/gstelement.c: (gst_element_get_compatible_pad_filtered): This is a debug message, not a g_critical. * gst/gstpad.c: (gst_pad_event_default): handle discontinuous events right with element time. * gst/gstscheduler.c: (gst_scheduler_state_transition): update to clocking fixes. set clocks on elements in READY=>PAUSED. The old behaviour caused a wrong element time on the first element that started playing. * gst/schedulers/gstbasicscheduler.c: (gst_basic_scheduler_class_init): * gst/schedulers/gstoptimalscheduler.c: (gst_opt_scheduler_class_init): remove code that just implements the default behaviour. * gst/elements/gstfakesink.c: (gst_fakesink_chain): update to use new clocking functions * testsuite/clock/clock1.c: (gst_clock_debug), (main): * testsuite/clock/clock2.c: (gst_clock_debug), (main): update to test new element time. * gst/autoplug/gstspideridentity.c: (gst_spider_identity_getcaps): use _get_allowed_caps instead of _get_caps. This catches filtered caps correctly. * testsuite/debug/commandline.c: update for new GST_DEBUG syntax. * testsuite/threads/Makefile.am: disable a test that only works sometimes.
2004-01-14 00:46:48 +00:00
}
break;
case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
break;
case GST_STATE_CHANGE_PLAYING_TO_PAUSED:
break;
case GST_STATE_CHANGE_PAUSED_TO_READY:
case GST_STATE_CHANGE_READY_TO_NULL:{
GList *l;
/* deactivate pads in both cases, since they are activated on
ready->paused but the element might not have made it to paused */
if (!gst_element_pads_activate (element, FALSE)) {
result = GST_STATE_CHANGE_FAILURE;
}
/* Remove all non-persistent contexts */
GST_OBJECT_LOCK (element);
for (l = element->contexts; l;) {
GstContext *context = l->data;
if (!gst_context_is_persistent (context)) {
GList *next;
gst_context_unref (context);
next = l->next;
element->contexts = g_list_delete_link (element->contexts, l);
l = next;
} else {
l = l->next;
}
}
GST_OBJECT_UNLOCK (element);
break;
}
default:
/* this will catch real but unhandled state changes;
* can only be caused by:
* - a new state was added
* - somehow the element was asked to jump across an intermediate state
*/
g_warning ("Unhandled state change from %s to %s",
gst_element_state_get_name (state),
gst_element_state_get_name (next));
break;
}
return result;
was_ok:
{
GST_OBJECT_LOCK (element);
result = GST_STATE_RETURN (element);
GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, element,
"element is already in the %s state",
gst_element_state_get_name (state));
GST_OBJECT_UNLOCK (element);
return result;
}
}
/**
* gst_element_get_factory:
* @element: a #GstElement to request the element factory of.
*
* Retrieves the factory that was used to create this element.
*
* Returns: (transfer none): the #GstElementFactory used for creating this
* element. no refcounting is needed.
*/
GstElementFactory *
gst_element_get_factory (GstElement * element)
{
g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
return GST_ELEMENT_GET_CLASS (element)->elementfactory;
}
static void
gst_element_dispose (GObject * object)
{
2009-12-24 13:40:54 +00:00
GstElement *element = GST_ELEMENT_CAST (object);
GstClock **clock_p;
GstBus **bus_p;
GstElementClass *oclass;
GList *walk;
oclass = GST_ELEMENT_GET_CLASS (element);
GST_CAT_INFO_OBJECT (GST_CAT_REFCOUNTING, element, "%p dispose", element);
if (GST_STATE (element) != GST_STATE_NULL)
goto not_null;
/* start by releasing all request pads, this might also remove some dynamic
* pads */
walk = element->pads;
while (walk) {
GstPad *pad = GST_PAD_CAST (walk->data);
walk = walk->next;
if (oclass->release_pad && GST_PAD_PAD_TEMPLATE (pad) &&
GST_PAD_TEMPLATE_PRESENCE (GST_PAD_PAD_TEMPLATE (pad))
== GST_PAD_REQUEST) {
GST_CAT_DEBUG_OBJECT (GST_CAT_ELEMENT_PADS, element,
"removing request pad %s:%s", GST_DEBUG_PAD_NAME (pad));
oclass->release_pad (element, pad);
/* in case the release_pad function removed the next pad too */
if (walk && g_list_position (element->pads, walk) == -1)
walk = element->pads;
}
}
/* remove the remaining pads */
while (element->pads) {
GstPad *pad = GST_PAD_CAST (element->pads->data);
GST_CAT_DEBUG_OBJECT (GST_CAT_ELEMENT_PADS, element,
"removing pad %s:%s", GST_DEBUG_PAD_NAME (pad));
if (!gst_element_remove_pad (element, pad)) {
/* only happens when someone unparented our pad.. */
g_critical ("failed to remove pad %s:%s", GST_DEBUG_PAD_NAME (pad));
break;
}
}
GST_OBJECT_LOCK (element);
clock_p = &element->clock;
bus_p = &element->bus;
gst_object_replace ((GstObject **) clock_p, NULL);
gst_object_replace ((GstObject **) bus_p, NULL);
g_list_free_full (element->contexts, (GDestroyNotify) gst_context_unref);
GST_OBJECT_UNLOCK (element);
GST_CAT_INFO_OBJECT (GST_CAT_REFCOUNTING, element, "%p parent class dispose",
element);
G_OBJECT_CLASS (parent_class)->dispose (object);
return;
/* ERRORS */
not_null:
{
gboolean is_locked;
is_locked = GST_ELEMENT_IS_LOCKED_STATE (element);
g_critical
("\nTrying to dispose element %s, but it is in %s%s instead of the NULL"
" state.\n"
"You need to explicitly set elements to the NULL state before\n"
"dropping the final reference, to allow them to clean up.\n"
"This problem may also be caused by a refcounting bug in the\n"
"application or some element.\n",
GST_OBJECT_NAME (element),
gst_element_state_get_name (GST_STATE (element)),
is_locked ? " (locked)" : "");
return;
}
}
static void
gst_element_finalize (GObject * object)
{
2009-12-24 13:40:54 +00:00
GstElement *element = GST_ELEMENT_CAST (object);
GST_CAT_INFO_OBJECT (GST_CAT_REFCOUNTING, element, "%p finalize", element);
2012-01-19 08:27:04 +00:00
g_cond_clear (&element->state_cond);
g_rec_mutex_clear (&element->state_lock);
GST_CAT_INFO_OBJECT (GST_CAT_REFCOUNTING, element, "%p finalize parent",
element);
G_OBJECT_CLASS (parent_class)->finalize (object);
}
static void
gst_element_set_bus_func (GstElement * element, GstBus * bus)
{
GstBus **bus_p;
g_return_if_fail (GST_IS_ELEMENT (element));
GST_CAT_DEBUG_OBJECT (GST_CAT_PARENTAGE, element, "setting bus to %p", bus);
GST_OBJECT_LOCK (element);
bus_p = &GST_ELEMENT_BUS (element);
gst_object_replace ((GstObject **) bus_p, GST_OBJECT_CAST (bus));
GST_OBJECT_UNLOCK (element);
}
/**
* gst_element_set_bus:
* @element: a #GstElement to set the bus of.
* @bus: (transfer none) (allow-none): the #GstBus to set.
*
* Sets the bus of the element. Increases the refcount on the bus.
* For internal use only, unless you're testing elements.
*
* MT safe.
*/
void
gst_element_set_bus (GstElement * element, GstBus * bus)
{
GstElementClass *oclass;
g_return_if_fail (GST_IS_ELEMENT (element));
oclass = GST_ELEMENT_GET_CLASS (element);
if (oclass->set_bus)
oclass->set_bus (element, bus);
}
/**
* gst_element_get_bus:
* @element: a #GstElement to get the bus of.
*
2007-06-18 15:12:28 +00:00
* Returns the bus of the element. Note that only a #GstPipeline will provide a
* bus for the application.
*
* Returns: (transfer full) (nullable): the element's #GstBus. unref after
* usage.
*
* MT safe.
*/
GstBus *
gst_element_get_bus (GstElement * element)
{
GstBus *result = NULL;
g_return_val_if_fail (GST_IS_ELEMENT (element), result);
GST_OBJECT_LOCK (element);
if ((result = GST_ELEMENT_BUS (element)))
gst_object_ref (result);
GST_OBJECT_UNLOCK (element);
GST_CAT_DEBUG_OBJECT (GST_CAT_BUS, element, "got bus %" GST_PTR_FORMAT,
result);
return result;
}
static void
gst_element_set_context_default (GstElement * element, GstContext * context)
{
const gchar *context_type;
GList *l;
g_return_if_fail (GST_IS_CONTEXT (context));
context_type = gst_context_get_context_type (context);
g_return_if_fail (context_type != NULL);
GST_OBJECT_LOCK (element);
for (l = element->contexts; l; l = l->next) {
GstContext *tmp = l->data;
const gchar *tmp_type = gst_context_get_context_type (tmp);
/* Always store newest context but never replace
* a persistent one by a non-persistent one */
if (g_strcmp0 (context_type, tmp_type) == 0 &&
(gst_context_is_persistent (context) ||
!gst_context_is_persistent (tmp))) {
gst_context_replace ((GstContext **) & l->data, context);
break;
}
}
/* Not found? Add */
if (l == NULL) {
element->contexts =
g_list_prepend (element->contexts, gst_context_ref (context));
}
GST_OBJECT_UNLOCK (element);
}
/**
* gst_element_set_context:
* @element: a #GstElement to set the context of.
* @context: (transfer none): the #GstContext to set.
*
* Sets the context of the element. Increases the refcount of the context.
*
* MT safe.
*/
void
gst_element_set_context (GstElement * element, GstContext * context)
{
GstElementClass *oclass;
g_return_if_fail (GST_IS_ELEMENT (element));
g_return_if_fail (GST_IS_CONTEXT (context));
oclass = GST_ELEMENT_GET_CLASS (element);
GST_CAT_DEBUG_OBJECT (GST_CAT_CONTEXT, element,
"set context %p %" GST_PTR_FORMAT, context,
gst_context_get_structure (context));
if (oclass->set_context)
oclass->set_context (element, context);
}
/**
* gst_element_get_contexts:
* @element: a #GstElement to set the context of.
*
* Gets the contexts set on the element.
*
* MT safe.
*
* Returns: (element-type Gst.Context) (transfer full): List of #GstContext
*
* Since: 1.8
*/
GList *
gst_element_get_contexts (GstElement * element)
{
GList *ret;
g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
GST_OBJECT_LOCK (element);
ret = g_list_copy_deep (element->contexts, (GCopyFunc) gst_context_ref, NULL);
GST_OBJECT_UNLOCK (element);
return ret;
}
static gint
_match_context_type (GstContext * c1, const gchar * context_type)
{
const gchar *c1_type;
c1_type = gst_context_get_context_type (c1);
return g_strcmp0 (c1_type, context_type);
}
/**
* gst_element_get_context_unlocked:
* @element: a #GstElement to get the context of.
* @context_type: a name of a context to retrieve
*
* Gets the context with @context_type set on the element or NULL.
*
* Returns: (transfer full) (nullable): A #GstContext or NULL
*
* Since: 1.8
*/
GstContext *
gst_element_get_context_unlocked (GstElement * element,
const gchar * context_type)
{
GstContext *ret = NULL;
GList *node;
g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
node =
g_list_find_custom (element->contexts, context_type,
(GCompareFunc) _match_context_type);
if (node && node->data)
ret = gst_context_ref (node->data);
return ret;
}
/**
* gst_element_get_context:
* @element: a #GstElement to get the context of.
* @context_type: a name of a context to retrieve
*
* Gets the context with @context_type set on the element or NULL.
*
* MT safe.
*
* Returns: (transfer full): A #GstContext or NULL
*
* Since: 1.8
*/
GstContext *
gst_element_get_context (GstElement * element, const gchar * context_type)
{
GstContext *ret = NULL;
g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
GST_OBJECT_LOCK (element);
ret = gst_element_get_context_unlocked (element, context_type);
GST_OBJECT_UNLOCK (element);
return ret;
}
static void
gst_element_property_post_notify_msg (GstElement * element, GObject * obj,
GParamSpec * pspec, gboolean include_value)
{
GValue val = G_VALUE_INIT;
GValue *v;
GST_LOG_OBJECT (element, "property '%s' of object %" GST_PTR_FORMAT " has "
"changed, posting message with%s value", pspec->name, obj,
include_value ? "" : "out");
if (include_value && (pspec->flags & G_PARAM_READABLE) != 0) {
g_value_init (&val, pspec->value_type);
g_object_get_property (obj, pspec->name, &val);
v = &val;
} else {
v = NULL;
}
gst_element_post_message (element,
gst_message_new_property_notify (GST_OBJECT_CAST (obj), pspec->name, v));
}
static void
gst_element_property_deep_notify_cb (GstElement * element, GObject * prop_obj,
GParamSpec * pspec, gpointer user_data)
{
gboolean include_value = GPOINTER_TO_INT (user_data);
gst_element_property_post_notify_msg (element, prop_obj, pspec,
include_value);
}
static void
gst_element_property_notify_cb (GObject * obj, GParamSpec * pspec,
gpointer user_data)
{
gboolean include_value = GPOINTER_TO_INT (user_data);
gst_element_property_post_notify_msg (GST_ELEMENT_CAST (obj), obj, pspec,
include_value);
}
/**
* gst_element_add_property_notify_watch:
* @element: a #GstElement to watch for property changes
* @property_name: (allow-none): name of property to watch for changes, or
* NULL to watch all properties
* @include_value: whether to include the new property value in the message
*
* Returns: a watch id, which can be used in connection with
* gst_element_remove_property_notify_watch() to remove the watch again.
*
* Since: 1.10
*/
gulong
gst_element_add_property_notify_watch (GstElement * element,
const gchar * property_name, gboolean include_value)
{
const gchar *sep;
gchar *signal_name;
gulong id;
g_return_val_if_fail (GST_IS_ELEMENT (element), 0);
sep = (property_name != NULL) ? "::" : NULL;
signal_name = g_strconcat ("notify", sep, property_name, NULL);
id = g_signal_connect (element, signal_name,
G_CALLBACK (gst_element_property_notify_cb),
GINT_TO_POINTER (include_value));
g_free (signal_name);
return id;
}
/**
* gst_element_add_property_deep_notify_watch:
* @element: a #GstElement to watch (recursively) for property changes
* @property_name: (allow-none): name of property to watch for changes, or
* NULL to watch all properties
* @include_value: whether to include the new property value in the message
*
* Returns: a watch id, which can be used in connection with
* gst_element_remove_property_notify_watch() to remove the watch again.
*
* Since: 1.10
*/
gulong
gst_element_add_property_deep_notify_watch (GstElement * element,
const gchar * property_name, gboolean include_value)
{
const gchar *sep;
gchar *signal_name;
gulong id;
g_return_val_if_fail (GST_IS_ELEMENT (element), 0);
sep = (property_name != NULL) ? "::" : NULL;
signal_name = g_strconcat ("deep-notify", sep, property_name, NULL);
id = g_signal_connect (element, signal_name,
G_CALLBACK (gst_element_property_deep_notify_cb),
GINT_TO_POINTER (include_value));
g_free (signal_name);
return id;
}
/**
* gst_element_remove_property_notify_watch:
* @element: a #GstElement being watched for property changes
* @watch_id: watch id to remove
*
* Since: 1.10
*/
void
gst_element_remove_property_notify_watch (GstElement * element, gulong watch_id)
{
g_signal_handler_disconnect (element, watch_id);
}
typedef struct
{
GstElement *element;
GstElementCallAsyncFunc func;
gpointer user_data;
GDestroyNotify destroy_notify;
} GstElementCallAsyncData;
static void
gst_element_call_async_func (gpointer data, gpointer user_data)
{
GstElementCallAsyncData *async_data = data;
async_data->func (async_data->element, async_data->user_data);
if (async_data->destroy_notify)
async_data->destroy_notify (async_data->user_data);
gst_object_unref (async_data->element);
g_free (async_data);
}
/**
* gst_element_call_async:
* @element: a #GstElement
* @func: Function to call asynchronously from another thread
* @user_data: Data to pass to @func
* @destroy_notify: GDestroyNotify for @user_data
*
* Calls @func from another thread and passes @user_data to it. This is to be
* used for cases when a state change has to be performed from a streaming
* thread, directly via gst_element_set_state() or indirectly e.g. via SEEK
* events.
*
* Calling those functions directly from the streaming thread will cause
* deadlocks in many situations, as they might involve waiting for the
* streaming thread to shut down from this very streaming thread.
*
* MT safe.
*
* Since: 1.10
*/
void
gst_element_call_async (GstElement * element, GstElementCallAsyncFunc func,
gpointer user_data, GDestroyNotify destroy_notify)
{
GstElementCallAsyncData *async_data;
g_return_if_fail (GST_IS_ELEMENT (element));
async_data = g_new0 (GstElementCallAsyncData, 1);
async_data->element = gst_object_ref (element);
async_data->func = func;
async_data->user_data = user_data;
async_data->destroy_notify = destroy_notify;
g_thread_pool_push (gst_element_pool, async_data, NULL);
}
void
_priv_gst_element_cleanup (void)
{
if (gst_element_pool) {
g_thread_pool_free (gst_element_pool, FALSE, TRUE);
gst_element_setup_thread_pool ();
}
}
GstStructure *
gst_make_element_message_details (const char *name, ...)
{
GstStructure *structure;
va_list varargs;
if (name == NULL)
return NULL;
va_start (varargs, name);
structure = gst_structure_new_valist ("details", name, varargs);
va_end (varargs);
return structure;
}