* SECTION:gstutils
* @short_description: Various utility functions
*
- * When defining own plugins, use the GST_BOILERPLATE ease gobject creation.
*/
#include "gst_private.h"
#include "gstparse.h"
#include "gstvalue.h"
#include "gst-i18n-lib.h"
+#include "glib-compat-private.h"
#include <math.h>
/**
/**
* gst_util_set_value_from_string:
- * @value: the value to set
+ * @value: (out caller-allocates): the value to set
* @value_str: the string to get the value from
*
* Converts the string to the type of the value and
gst_util_seqnum_next (void)
{
static gint counter = 0;
- return g_atomic_int_exchange_and_add (&counter, 1);
+ return G_ATOMIC_INT_ADD (&counter, 1);
}
/**
* gst_print_pad_caps:
* @buf: the buffer to print the caps in
* @indent: initial indentation
- * @pad: the pad to print the caps from
+ * @pad: (transfer none): the pad to print the caps from
*
* Write the pad capabilities in a human readable format into
* the given GString.
{
GstCaps *caps;
- caps = pad->caps;
+ caps = gst_pad_get_current_caps (pad);
if (!caps) {
string_append_indent (buf, indent);
s = gst_caps_to_string (caps);
g_string_append (buf, s);
g_free (s);
+
+ gst_caps_unref (caps);
}
}
* gst_print_element_args:
* @buf: the buffer to print the args in
* @indent: initial indentation
- * @element: the element to print the args of
+ * @element: (transfer none): the element to print the args of
*
* Print the element argument in a human readable format in the given
* GString.
/**
* gst_element_create_all_pads:
- * @element: a #GstElement to create pads for
+ * @element: (transfer none): a #GstElement to create pads for
*
* Creates a pad for each pad template that is always available.
* This function is only useful during object intialization of
/**
* gst_element_get_compatible_pad_template:
- * @element: a #GstElement to get a compatible pad template for.
- * @compattempl: the #GstPadTemplate to find a compatible template for.
+ * @element: (transfer none): a #GstElement to get a compatible pad template for
+ * @compattempl: (transfer none): the #GstPadTemplate to find a compatible
+ * template for
*
* Retrieves a pad template from @element that is compatible with @compattempl.
* Pads from compatible templates can be linked together.
*
- * Returns: a compatible #GstPadTemplate, or NULL if none was found. No
- * unreferencing is necessary.
+ * Returns: (transfer none): a compatible #GstPadTemplate, or NULL if none
+ * was found. No unreferencing is necessary.
*/
GstPadTemplate *
gst_element_get_compatible_pad_template (GstElement * element,
return newtempl;
}
-static GstPad *
-gst_element_request_pad (GstElement * element, GstPadTemplate * templ,
- const gchar * name)
-{
- GstPad *newpad = NULL;
- GstElementClass *oclass;
-
- oclass = GST_ELEMENT_GET_CLASS (element);
-
- if (oclass->request_new_pad)
- newpad = (oclass->request_new_pad) (element, templ, name);
-
- if (newpad)
- gst_object_ref (newpad);
-
- return newpad;
-}
-
-
-
/**
* gst_element_get_pad_from_template:
- * @element: a #GstElement.
- * @templ: a #GstPadTemplate belonging to @element.
+ * @element: (transfer none): a #GstElement.
+ * @templ: (transfer none): a #GstPadTemplate belonging to @element.
*
* Gets a pad from @element described by @templ. If the presence of @templ is
* #GST_PAD_REQUEST, requests a new pad. Can return %NULL for #GST_PAD_SOMETIMES
* templates.
*
- * Returns: the #GstPad, or NULL if one could not be found or created.
+ * Returns: (transfer full): the #GstPad, or NULL if one could not be found
+ * or created.
*/
static GstPad *
gst_element_get_pad_from_template (GstElement * element, GstPadTemplate * templ)
break;
case GST_PAD_REQUEST:
- ret = gst_element_request_pad (element, templ, NULL);
+ ret = gst_element_request_pad (element, templ, NULL, NULL);
break;
}
/**
* gst_element_get_compatible_pad:
- * @element: a #GstElement in which the pad should be found.
- * @pad: the #GstPad to find a compatible one for.
+ * @element: (transfer none): a #GstElement in which the pad should be found.
+ * @pad: (transfer none): the #GstPad to find a compatible one for.
* @caps: the #GstCaps to use as a filter.
*
* Looks for an unlinked pad to which the given pad can link. It is not
* guaranteed that linking the pads will work, though it should work in most
* cases.
*
- * Returns: the #GstPad to which a link can be made, or %NULL if one cannot be
- * found. gst_object_unref() after usage.
+ * This function will first attempt to find a compatible unlinked ALWAYS pad,
+ * and if none can be found, it will request a compatible REQUEST pad by looking
+ * at the templates of @element.
+ *
+ * Returns: (transfer full): the #GstPad to which a link can be made, or %NULL
+ * if one cannot be found. gst_object_unref() after usage.
*/
GstPad *
gst_element_get_compatible_pad (GstElement * element, GstPad * pad,
GstCaps *templcaps;
GstPad *foundpad = NULL;
gboolean done;
+ GValue padptr = { 0, };
g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
g_return_val_if_fail (GST_IS_PAD (pad), NULL);
g_return_val_if_fail (GST_PAD_PEER (pad) == NULL, NULL);
done = FALSE;
+
/* try to get an existing unlinked pad */
- pads = gst_element_iterate_pads (element);
- while (!done) {
- gpointer padptr;
+ if (GST_PAD_IS_SRC (pad)) {
+ pads = gst_element_iterate_sink_pads (element);
+ } else if (GST_PAD_IS_SINK (pad)) {
+ pads = gst_element_iterate_src_pads (element);
+ } else {
+ pads = gst_element_iterate_pads (element);
+ }
+ while (!done) {
switch (gst_iterator_next (pads, &padptr)) {
case GST_ITERATOR_OK:
{
GstPad *peer;
GstPad *current;
+ GstPad *srcpad;
+ GstPad *sinkpad;
- current = GST_PAD (padptr);
+ current = g_value_get_object (&padptr);
GST_CAT_LOG (GST_CAT_ELEMENT_PADS, "examining pad %s:%s",
GST_DEBUG_PAD_NAME (current));
+ if (GST_PAD_IS_SRC (current)) {
+ srcpad = current;
+ sinkpad = pad;
+ } else {
+ srcpad = pad;
+ sinkpad = current;
+ }
peer = gst_pad_get_peer (current);
- if (peer == NULL && gst_pad_check_link (pad, current)) {
+ if (peer == NULL && gst_pad_check_link (srcpad, sinkpad)) {
GstCaps *temp, *intersection;
gboolean compatible;
/* Now check if the two pads' caps are compatible */
- temp = gst_pad_get_caps_reffed (pad);
+ temp = gst_pad_get_caps (pad, NULL);
if (caps) {
intersection = gst_caps_intersect (temp, caps);
gst_caps_unref (temp);
intersection = temp;
}
- temp = gst_pad_get_caps_reffed (current);
+ temp = gst_pad_get_caps (current, NULL);
compatible = gst_caps_can_intersect (temp, intersection);
gst_caps_unref (temp);
gst_caps_unref (intersection);
GST_DEBUG_PAD_NAME (current));
gst_iterator_free (pads);
+ current = gst_object_ref (current);
+ g_value_unset (&padptr);
+
return current;
} else {
GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "incompatible pads");
}
GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "unreffing pads");
- gst_object_unref (current);
+ g_value_reset (&padptr);
if (peer)
gst_object_unref (peer);
break;
break;
}
}
+ g_value_unset (&padptr);
gst_iterator_free (pads);
GST_CAT_DEBUG_OBJECT (GST_CAT_ELEMENT_PADS, element,
/* try to create a new one */
/* requesting is a little crazy, we need a template. Let's create one */
/* FIXME: why not gst_pad_get_pad_template (pad); */
- templcaps = gst_pad_get_caps_reffed (pad);
-
+ templcaps = gst_pad_get_caps (pad, NULL);
templ = gst_pad_template_new ((gchar *) GST_PAD_NAME (pad),
GST_PAD_DIRECTION (pad), GST_PAD_ALWAYS, templcaps);
+ gst_caps_unref (templcaps);
foundpad = gst_element_request_compatible_pad (element, templ);
gst_object_unref (templ);
*
* Gets a string representing the given state.
*
- * Returns: a string with the name of the state.
+ * Returns: (transfer none): a string with the name of the state.
*/
G_CONST_RETURN gchar *
gst_element_state_get_name (GstState state)
{
switch (state) {
-#ifdef GST_DEBUG_COLOR
- case GST_STATE_VOID_PENDING:
- return "VOID_PENDING";
- case GST_STATE_NULL:
- return "\033[01;34mNULL\033[00m";
- case GST_STATE_READY:
- return "\033[01;31mREADY\033[00m";
- case GST_STATE_PLAYING:
- return "\033[01;32mPLAYING\033[00m";
- case GST_STATE_PAUSED:
- return "\033[01;33mPAUSED\033[00m";
- default:
- /* This is a memory leak */
- return g_strdup_printf ("\033[01;35;41mUNKNOWN!\033[00m(%d)", state);
-#else
case GST_STATE_VOID_PENDING:
return "VOID_PENDING";
case GST_STATE_NULL:
default:
/* This is a memory leak */
return g_strdup_printf ("UNKNOWN!(%d)", state);
-#endif
}
}
*
* Gets a string representing the given state change result.
*
- * Returns: a string with the name of the state change result.
+ * Returns: (transfer none): a string with the name of the state
+ * result.
*
* Since: 0.10.11
*/
gst_element_state_change_return_get_name (GstStateChangeReturn state_ret)
{
switch (state_ret) {
-#ifdef GST_DEBUG_COLOR
- case GST_STATE_CHANGE_FAILURE:
- return "\033[01;31mFAILURE\033[00m";
- case GST_STATE_CHANGE_SUCCESS:
- return "\033[01;32mSUCCESS\033[00m";
- case GST_STATE_CHANGE_ASYNC:
- return "\033[01;33mASYNC\033[00m";
- case GST_STATE_CHANGE_NO_PREROLL:
- return "\033[01;34mNO_PREROLL\033[00m";
- default:
- /* This is a memory leak */
- return g_strdup_printf ("\033[01;35;41mUNKNOWN!\033[00m(%d)", state_ret);
-#else
case GST_STATE_CHANGE_FAILURE:
return "FAILURE";
case GST_STATE_CHANGE_SUCCESS:
default:
/* This is a memory leak */
return g_strdup_printf ("UNKNOWN!(%d)", state_ret);
-#endif
}
}
-/**
- * gst_element_factory_can_src_caps:
- * @factory: factory to query
- * @caps: the caps to check
- *
- * Checks if the factory can source the given capability.
- *
- * Returns: true if it can src the capabilities
- */
-gboolean
-gst_element_factory_can_src_caps (GstElementFactory * factory,
- const GstCaps * caps)
+static gboolean
+gst_element_factory_can_accept_all_caps_in_direction (GstElementFactory *
+ factory, const GstCaps * caps, GstPadDirection direction)
{
GList *templates;
while (templates) {
GstStaticPadTemplate *template = (GstStaticPadTemplate *) templates->data;
- if (template->direction == GST_PAD_SRC) {
- if (gst_caps_is_always_compatible (gst_static_caps_get
- (&template->static_caps), caps))
+ if (template->direction == direction) {
+ GstCaps *templcaps = gst_static_caps_get (&template->static_caps);
+
+ if (gst_caps_is_always_compatible (caps, templcaps)) {
+ gst_caps_unref (templcaps);
return TRUE;
+ }
+ gst_caps_unref (templcaps);
}
templates = g_list_next (templates);
}
return FALSE;
}
-/**
- * gst_element_factory_can_sink_caps:
- * @factory: factory to query
- * @caps: the caps to check
- *
- * Checks if the factory can sink the given capability.
- *
- * Returns: true if it can sink the capabilities
- */
-gboolean
-gst_element_factory_can_sink_caps (GstElementFactory * factory,
- const GstCaps * caps)
+static gboolean
+gst_element_factory_can_accept_any_caps_in_direction (GstElementFactory *
+ factory, const GstCaps * caps, GstPadDirection direction)
{
GList *templates;
while (templates) {
GstStaticPadTemplate *template = (GstStaticPadTemplate *) templates->data;
- if (template->direction == GST_PAD_SINK) {
- if (gst_caps_is_always_compatible (caps,
- gst_static_caps_get (&template->static_caps)))
+ if (template->direction == direction) {
+ GstCaps *templcaps = gst_static_caps_get (&template->static_caps);
+
+ if (gst_caps_can_intersect (caps, templcaps)) {
+ gst_caps_unref (templcaps);
return TRUE;
+ }
+ gst_caps_unref (templcaps);
}
templates = g_list_next (templates);
}
return FALSE;
}
+/**
+ * gst_element_factory_can_sink_all_caps:
+ * @factory: factory to query
+ * @caps: the caps to check
+ *
+ * Checks if the factory can sink all possible capabilities.
+ *
+ * Returns: %TRUE if the caps are fully compatible.
+ *
+ * Since: 0.10.33
+ */
+gboolean
+gst_element_factory_can_sink_all_caps (GstElementFactory * factory,
+ const GstCaps * caps)
+{
+ return gst_element_factory_can_accept_all_caps_in_direction (factory, caps,
+ GST_PAD_SINK);
+}
+
+/**
+ * gst_element_factory_can_src_all_caps:
+ * @factory: factory to query
+ * @caps: the caps to check
+ *
+ * Checks if the factory can src all possible capabilities.
+ *
+ * Returns: %TRUE if the caps are fully compatible.
+ *
+ * Since: 0.10.33
+ */
+gboolean
+gst_element_factory_can_src_all_caps (GstElementFactory * factory,
+ const GstCaps * caps)
+{
+ return gst_element_factory_can_accept_all_caps_in_direction (factory, caps,
+ GST_PAD_SRC);
+}
+
+/**
+ * gst_element_factory_can_sink_any_caps:
+ * @factory: factory to query
+ * @caps: the caps to check
+ *
+ * Checks if the factory can sink any possible capability.
+ *
+ * Returns: %TRUE if the caps have a common subset.
+ *
+ * Since: 0.10.33
+ */
+gboolean
+gst_element_factory_can_sink_any_caps (GstElementFactory * factory,
+ const GstCaps * caps)
+{
+ return gst_element_factory_can_accept_any_caps_in_direction (factory, caps,
+ GST_PAD_SINK);
+}
+
+/**
+ * gst_element_factory_can_src_any_caps:
+ * @factory: factory to query
+ * @caps: the caps to check
+ *
+ * Checks if the factory can src any possible capability.
+ *
+ * Returns: %TRUE if the caps have a common subset.
+ *
+ * Since: 0.10.33
+ */
+gboolean
+gst_element_factory_can_src_any_caps (GstElementFactory * factory,
+ const GstCaps * caps)
+{
+ return gst_element_factory_can_accept_any_caps_in_direction (factory, caps,
+ GST_PAD_SRC);
+}
/* if return val is true, *direct_child is a caller-owned ref on the direct
* child of ancestor that is part of object's ancestry */
static gint ghost_pad_index = 0;
GstPad *gpad;
gchar *name;
+ GstState current;
+ GstState next;
GstObject *parent = GST_OBJECT_PARENT (e);
name = g_strdup_printf ("ghost%d", ghost_pad_index++);
gpad = gst_ghost_pad_new (name, pad);
g_free (name);
+ GST_STATE_LOCK (e);
+ gst_element_get_state (e, ¤t, &next, 0);
+
+ if (current > GST_STATE_READY || next == GST_STATE_PAUSED)
+ gst_pad_set_active (gpad, TRUE);
+
if (!gst_element_add_pad ((GstElement *) parent, gpad)) {
g_warning ("Pad named %s already exists in element %s\n",
GST_OBJECT_NAME (gpad), GST_OBJECT_NAME (parent));
gst_object_unref ((GstObject *) gpad);
+ GST_STATE_UNLOCK (e);
return NULL;
}
+ GST_STATE_UNLOCK (e);
return gpad;
}
/**
* gst_element_link_pads_full:
* @src: a #GstElement containing the source pad.
- * @srcpadname: the name of the #GstPad in source element or NULL for any pad.
- * @dest: the #GstElement containing the destination pad.
- * @destpadname: the name of the #GstPad in destination element,
+ * @srcpadname: (allow-none): the name of the #GstPad in source element
+ * or NULL for any pad.
+ * @dest: (transfer none): the #GstElement containing the destination pad.
+ * @destpadname: (allow-none): the name of the #GstPad in destination element,
* or NULL for any pad.
* @flags: the #GstPadLinkCheck to be performed when linking pads.
*
* is the same as calling gst_element_link_pads() and the recommended way of
* linking pads with safety checks applied.
*
+ * This is a convenience function for gst_pad_link_full().
+ *
* Returns: TRUE if the pads could be linked, FALSE otherwise.
*
* Since: 0.10.30
return FALSE;
}
if (GST_PAD_PEER (srcpad) != NULL) {
- GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "pad %s:%s is already linked",
- GST_DEBUG_PAD_NAME (srcpad));
+ GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS,
+ "pad %s:%s is already linked to %s:%s", GST_DEBUG_PAD_NAME (srcpad),
+ GST_DEBUG_PAD_NAME (GST_PAD_PEER (srcpad)));
gst_object_unref (srcpad);
return FALSE;
}
return FALSE;
}
if (GST_PAD_PEER (destpad) != NULL) {
- GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "pad %s:%s is already linked",
- GST_DEBUG_PAD_NAME (destpad));
+ GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS,
+ "pad %s:%s is already linked to %s:%s",
+ GST_DEBUG_PAD_NAME (destpad),
+ GST_DEBUG_PAD_NAME (GST_PAD_PEER (destpad)));
gst_object_unref (destpad);
return FALSE;
}
desttempl = (GstPadTemplate *) l->data;
if (desttempl->presence == GST_PAD_REQUEST &&
desttempl->direction != srctempl->direction) {
- if (gst_caps_is_always_compatible (gst_pad_template_get_caps
- (srctempl), gst_pad_template_get_caps (desttempl))) {
+ GstCaps *srccaps, *destcaps;
+
+ srccaps = gst_pad_template_get_caps (srctempl);
+ destcaps = gst_pad_template_get_caps (desttempl);
+ if (gst_caps_is_always_compatible (srccaps, destcaps)) {
srcpad =
- gst_element_get_request_pad (src, srctempl->name_template);
+ gst_element_request_pad (src, srctempl,
+ srctempl->name_template, NULL);
destpad =
- gst_element_get_request_pad (dest, desttempl->name_template);
+ gst_element_request_pad (dest, desttempl,
+ desttempl->name_template, NULL);
if (srcpad && destpad
&& pad_link_maybe_ghosting (srcpad, destpad, flags)) {
GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS,
GST_DEBUG_PAD_NAME (srcpad), GST_DEBUG_PAD_NAME (destpad));
gst_object_unref (srcpad);
gst_object_unref (destpad);
+ gst_caps_unref (srccaps);
+ gst_caps_unref (destcaps);
return TRUE;
}
/* it failed, so we release the request pads */
if (destpad)
gst_element_release_request_pad (dest, destpad);
}
+ gst_caps_unref (srccaps);
+ gst_caps_unref (destcaps);
}
}
}
/**
* gst_element_link_pads:
* @src: a #GstElement containing the source pad.
- * @srcpadname: the name of the #GstPad in source element or NULL for any pad.
- * @dest: the #GstElement containing the destination pad.
- * @destpadname: the name of the #GstPad in destination element,
+ * @srcpadname: (allow-none): the name of the #GstPad in source element
+ * or NULL for any pad.
+ * @dest: (transfer none): the #GstElement containing the destination pad.
+ * @destpadname: (allow-none): the name of the #GstPad in destination element,
* or NULL for any pad.
*
* Links the two named pads of the source and destination elements.
/**
* gst_element_link_pads_filtered:
* @src: a #GstElement containing the source pad.
- * @srcpadname: the name of the #GstPad in source element or NULL for any pad.
- * @dest: the #GstElement containing the destination pad.
- * @destpadname: the name of the #GstPad in destination element or NULL for any pad.
- * @filter: the #GstCaps to filter the link, or #NULL for no filter.
+ * @srcpadname: (allow-none): the name of the #GstPad in source element
+ * or NULL for any pad.
+ * @dest: (transfer none): the #GstElement containing the destination pad.
+ * @destpadname: (allow-none): the name of the #GstPad in destination element
+ * or NULL for any pad.
+ * @filter: (transfer none) (allow-none): the #GstCaps to filter the link,
+ * or #NULL for no filter.
*
* Links the two named pads of the source and destination elements. Side effect
* is that if one of the pads has no parent, it becomes a child of the parent of
GstElement *capsfilter;
GstObject *parent;
GstState state, pending;
+ gboolean lr1, lr2;
capsfilter = gst_element_factory_make ("capsfilter", NULL);
if (!capsfilter) {
g_object_set (capsfilter, "caps", filter, NULL);
- if (gst_element_link_pads (src, srcpadname, capsfilter, "sink")
- && gst_element_link_pads (capsfilter, "src", dest, destpadname)) {
+ lr1 = gst_element_link_pads (src, srcpadname, capsfilter, "sink");
+ lr2 = gst_element_link_pads (capsfilter, "src", dest, destpadname);
+ if (lr1 && lr2) {
return TRUE;
} else {
- GST_INFO ("Could not link elements");
+ if (!lr1) {
+ GST_INFO ("Could not link pads: %s:%s - capsfilter:sink",
+ GST_ELEMENT_NAME (src), srcpadname);
+ } else {
+ GST_INFO ("Could not link pads: capsfilter:src - %s:%s",
+ GST_ELEMENT_NAME (dest), destpadname);
+ }
gst_element_set_state (capsfilter, GST_STATE_NULL);
/* this will unlink and unref as appropriate */
gst_bin_remove (GST_BIN (GST_OBJECT_PARENT (capsfilter)), capsfilter);
return FALSE;
}
} else {
- return gst_element_link_pads (src, srcpadname, dest, destpadname);
+ if (gst_element_link_pads (src, srcpadname, dest, destpadname)) {
+ return TRUE;
+ } else {
+ GST_INFO ("Could not link pads: %s:%s - %s:%s", GST_ELEMENT_NAME (src),
+ srcpadname, GST_ELEMENT_NAME (dest), destpadname);
+ return FALSE;
+ }
}
}
/**
* gst_element_link:
- * @src: a #GstElement containing the source pad.
- * @dest: the #GstElement containing the destination pad.
+ * @src: (transfer none): a #GstElement containing the source pad.
+ * @dest: (transfer none): the #GstElement containing the destination pad.
*
* Links @src to @dest. The link must be from source to
* destination; the other direction will not be tried. The function looks for
/**
* gst_element_link_many:
- * @element_1: the first #GstElement in the link chain.
- * @element_2: the second #GstElement in the link chain.
+ * @element_1: (transfer none): the first #GstElement in the link chain.
+ * @element_2: (transfer none): the second #GstElement in the link chain.
* @...: the NULL-terminated list of elements to link in order.
*
* Chain together a series of elements. Uses gst_element_link().
/**
* gst_element_link_filtered:
* @src: a #GstElement containing the source pad.
- * @dest: the #GstElement containing the destination pad.
- * @filter: the #GstCaps to filter the link, or #NULL for no filter.
+ * @dest: (transfer none): the #GstElement containing the destination pad.
+ * @filter: (transfer none) (allow-none): the #GstCaps to filter the link,
+ * or #NULL for no filter.
*
* Links @src to @dest using the given caps as filtercaps.
* The link must be from source to
/**
* gst_element_unlink_pads:
- * @src: a #GstElement containing the source pad.
+ * @src: a (transfer none): #GstElement containing the source pad.
* @srcpadname: the name of the #GstPad in source element.
- * @dest: a #GstElement containing the destination pad.
+ * @dest: (transfer none): a #GstElement containing the destination pad.
* @destpadname: the name of the #GstPad in destination element.
*
* Unlinks the two named pads of the source and destination elements.
+ *
+ * This is a convenience function for gst_pad_unlink().
*/
void
gst_element_unlink_pads (GstElement * src, const gchar * srcpadname,
/**
* gst_element_unlink_many:
- * @element_1: the first #GstElement in the link chain.
- * @element_2: the second #GstElement in the link chain.
+ * @element_1: (transfer none): the first #GstElement in the link chain.
+ * @element_2: (transfer none): the second #GstElement in the link chain.
* @...: the NULL-terminated list of elements to unlink in order.
*
* Unlinks a series of elements. Uses gst_element_unlink().
/**
* gst_element_unlink:
- * @src: the source #GstElement to unlink.
- * @dest: the sink #GstElement to unlink.
+ * @src: (transfer none): the source #GstElement to unlink.
+ * @dest: (transfer none): the sink #GstElement to unlink.
*
* Unlinks all source pads of the source element with all sink pads
* of the sink element to which they are linked.
{
GstIterator *pads;
gboolean done = FALSE;
+ GValue data = { 0, };
g_return_if_fail (GST_IS_ELEMENT (src));
g_return_if_fail (GST_IS_ELEMENT (dest));
pads = gst_element_iterate_pads (src);
while (!done) {
- gpointer data;
-
switch (gst_iterator_next (pads, &data)) {
case GST_ITERATOR_OK:
{
- GstPad *pad = GST_PAD_CAST (data);
+ GstPad *pad = g_value_get_object (&data);
if (GST_PAD_IS_SRC (pad)) {
GstPad *peerpad = gst_pad_get_peer (pad);
gst_object_unref (peerpad);
}
}
- gst_object_unref (pad);
+ g_value_reset (&data);
break;
}
case GST_ITERATOR_RESYNC:
break;
}
}
+ g_value_unset (&data);
gst_iterator_free (pads);
}
/**
* gst_element_query_position:
* @element: a #GstElement to invoke the position query on.
- * @format: a pointer to the #GstFormat asked for.
+ * @format: (inout): a pointer to the #GstFormat asked for.
* On return contains the #GstFormat used.
- * @cur: A location in which to store the current position, or NULL.
+ * @cur: (out) (allow-none): a location in which to store the current
+ * position, or NULL.
*
- * Queries an element for the stream position.
+ * Queries an element for the stream position. If one repeatedly calls this
+ * function one can also create and reuse it in gst_element_query().
*
* Returns: TRUE if the query could be performed.
*/
/**
* gst_element_query_convert:
* @element: a #GstElement to invoke the convert query on.
- * @src_format: a #GstFormat to convert from.
+ * @src_format: (inout): a #GstFormat to convert from.
* @src_val: a value to convert.
- * @dest_format: a pointer to the #GstFormat to convert to.
- * @dest_val: a pointer to the result.
+ * @dest_format: (inout): a pointer to the #GstFormat to convert to.
+ * @dest_val: (out): a pointer to the result.
*
* Queries an element to convert @src_val in @src_format to @dest_format.
*
g_return_val_if_fail (dest_format != NULL, FALSE);
g_return_val_if_fail (dest_val != NULL, FALSE);
- if (*dest_format == src_format) {
+ if (*dest_format == src_format || src_val == -1) {
*dest_val = src_val;
return TRUE;
}
* gst_pad_use_fixed_caps:
* @pad: the pad to use
*
- * A helper function you can use that sets the
- * @gst_pad_get_fixed_caps_func as the getcaps function for the
- * pad. This way the function will always return the negotiated caps
+ * A helper function you can use that sets the FIXED_CAPS flag
+ * This way the default getcaps function will always return the negotiated caps
* or in case the pad is not negotiated, the padtemplate caps.
*
* Use this function on a pad that, once gst_pad_set_caps() has been called
void
gst_pad_use_fixed_caps (GstPad * pad)
{
- gst_pad_set_getcaps_function (pad, gst_pad_get_fixed_caps_func);
-}
-
-/**
- * gst_pad_get_fixed_caps_func:
- * @pad: the pad to use
- *
- * A helper function you can use as a GetCaps function that
- * will return the currently negotiated caps or the padtemplate
- * when NULL.
- *
- * Returns: The currently negotiated caps or the padtemplate.
- */
-GstCaps *
-gst_pad_get_fixed_caps_func (GstPad * pad)
-{
- GstCaps *result;
-
- g_return_val_if_fail (GST_IS_PAD (pad), NULL);
-
- GST_OBJECT_LOCK (pad);
- if (GST_PAD_CAPS (pad)) {
- result = GST_PAD_CAPS (pad);
-
- GST_CAT_DEBUG (GST_CAT_CAPS,
- "using pad caps %p %" GST_PTR_FORMAT, result, result);
-
- result = gst_caps_ref (result);
- } else if (GST_PAD_PAD_TEMPLATE (pad)) {
- GstPadTemplate *templ = GST_PAD_PAD_TEMPLATE (pad);
-
- result = GST_PAD_TEMPLATE_CAPS (templ);
- GST_CAT_DEBUG (GST_CAT_CAPS,
- "using pad template %p with caps %p %" GST_PTR_FORMAT, templ, result,
- result);
-
- result = gst_caps_ref (result);
- } else {
- GST_CAT_DEBUG (GST_CAT_CAPS, "pad has no caps");
- result = gst_caps_new_empty ();
- }
- GST_OBJECT_UNLOCK (pad);
-
- return result;
+ GST_OBJECT_FLAG_SET (pad, GST_PAD_FIXED_CAPS);
}
/**
* Gets the parent of @pad, cast to a #GstElement. If a @pad has no parent or
* its parent is not an element, return NULL.
*
- * Returns: The parent of the pad. The caller has a reference on the parent, so
- * unref when you're finished with it.
+ * Returns: (transfer full): the parent of the pad. The caller has a
+ * reference on the parent, so unref when you're finished with it.
*
* MT safe.
*/
/**
* gst_object_default_error:
* @source: the #GstObject that initiated the error.
- * @error: the GError.
- * @debug: an additional debug information string, or NULL.
+ * @error: (in): the GError.
+ * @debug: (in) (allow-none): an additional debug information string, or NULL
*
- * A default error function.
+ * A default error function that uses g_printerr() to display the error message
+ * and the optional debug sting..
*
* The default handler will simply print the error string using g_print.
*/
void
-gst_object_default_error (GstObject * source, GError * error, gchar * debug)
+gst_object_default_error (GstObject * source, const GError * error,
+ const gchar * debug)
{
gchar *name = gst_object_get_path_string (source);
- g_print (_("ERROR: from element %s: %s\n"), name, error->message);
+ g_printerr (_("ERROR: from element %s: %s\n"), name, error->message);
if (debug)
- g_print (_("Additional debug info:\n%s\n"), debug);
+ g_printerr (_("Additional debug info:\n%s\n"), debug);
g_free (name);
}
/**
* gst_bin_add_many:
* @bin: a #GstBin
- * @element_1: the #GstElement element to add to the bin
- * @...: additional elements to add to the bin
+ * @element_1: (transfer full): the #GstElement element to add to the bin
+ * @...: (transfer full): additional elements to add to the bin
*
* Adds a NULL-terminated list of elements to a bin. This function is
* equivalent to calling gst_bin_add() for each member of the list. The return
/**
* gst_bin_remove_many:
* @bin: a #GstBin
- * @element_1: the first #GstElement to remove from the bin
- * @...: NULL-terminated list of elements to remove from the bin
+ * @element_1: (transfer none): the first #GstElement to remove from the bin
+ * @...: (transfer none): NULL-terminated list of elements to remove from the bin
*
* Remove a list of elements from a bin. This function is equivalent
* to calling gst_bin_remove() with each member of the list.
/**
* gst_buffer_merge:
- * @buf1: the first source #GstBuffer to merge.
- * @buf2: the second source #GstBuffer to merge.
+ * @buf1: (transfer none): the first source #GstBuffer to merge.
+ * @buf2: (transfer none): the second source #GstBuffer to merge.
*
* Create a new buffer that is the concatenation of the two source
* buffers. The original source buffers will not be modified or
* If the buffers point to contiguous areas of memory, the buffer
* is created without copying the data.
*
- * Returns: the new #GstBuffer which is the concatenation of the source buffers.
+ * Free-function: gst_buffer_unref
+ *
+ * Returns: (transfer full): the new #GstBuffer which is the concatenation
+ * of the source buffers.
*/
GstBuffer *
gst_buffer_merge (GstBuffer * buf1, GstBuffer * buf2)
{
GstBuffer *result;
+ gsize size1, size2;
+
+ size1 = gst_buffer_get_size (buf1);
+ size2 = gst_buffer_get_size (buf2);
/* we're just a specific case of the more general gst_buffer_span() */
- result = gst_buffer_span (buf1, 0, buf2, buf1->size + buf2->size);
+ result = gst_buffer_span (buf1, 0, buf2, size1 + size2);
return result;
}
* unreffing the input parameters. Language bindings without
* explicit reference counting should not wrap this function.
*
- * Returns: the new #GstBuffer which is the concatenation of the source buffers.
+ * Returns: (transfer full): the new #GstBuffer which is the concatenation of
+ * the source buffers.
*/
GstBuffer *
gst_buffer_join (GstBuffer * buf1, GstBuffer * buf2)
{
GstBuffer *result;
+ gsize size1, size2;
- result = gst_buffer_span (buf1, 0, buf2, buf1->size + buf2->size);
+ size1 = gst_buffer_get_size (buf1);
+ size2 = gst_buffer_get_size (buf2);
+
+ result = gst_buffer_span (buf1, 0, buf2, size1 + size2);
gst_buffer_unref (buf1);
gst_buffer_unref (buf2);
return result;
}
-
-/**
- * gst_buffer_stamp:
- * @dest: buffer to stamp
- * @src: buffer to stamp from
- *
- * Copies additional information (the timestamp, duration, and offset start
- * and end) from one buffer to the other.
- *
- * This function does not copy any buffer flags or caps and is equivalent to
- * gst_buffer_copy_metadata(@dest, @src, GST_BUFFER_COPY_TIMESTAMPS).
- *
- * Deprecated: use gst_buffer_copy_metadata() instead, it provides more
- * control.
- */
-#ifndef GST_REMOVE_DEPRECATED
-#ifdef GST_DISABLE_DEPRECATED
-void gst_buffer_stamp (GstBuffer * dest, const GstBuffer * src);
-#endif
-void
-gst_buffer_stamp (GstBuffer * dest, const GstBuffer * src)
-{
- gst_buffer_copy_metadata (dest, src, GST_BUFFER_COPY_TIMESTAMPS);
-}
-#endif /* GST_REMOVE_DEPRECATED */
-
static gboolean
-getcaps_fold_func (GstPad * pad, GValue * ret, GstPad * orig)
+getcaps_fold_func (const GValue * vpad, GValue * ret, GstCaps * filter)
{
+ GstPad *pad = g_value_get_object (vpad);
gboolean empty = FALSE;
GstCaps *peercaps, *existing;
existing = g_value_get_pointer (ret);
- peercaps = gst_pad_peer_get_caps_reffed (pad);
+ peercaps = gst_pad_peer_get_caps (pad, filter);
if (G_LIKELY (peercaps)) {
GstCaps *intersection = gst_caps_intersect (existing, peercaps);
gst_caps_unref (existing);
gst_caps_unref (peercaps);
}
- gst_object_unref (pad);
return !empty;
}
/**
* gst_pad_proxy_getcaps:
* @pad: a #GstPad to proxy.
+ * @filter: a #GstCaps filter.
*
* Calls gst_pad_get_allowed_caps() for every other pad belonging to the
* same element as @pad, and returns the intersection of the results.
* that can handle any stream format, but requires all its pads to have
* the same caps. Two such elements are tee and adder.
*
- * Returns: the intersection of the other pads' allowed caps.
+ * Free-function: gst_caps_unref
+ *
+ * Returns: (transfer full): the intersection of the other pads' allowed caps.
*/
GstCaps *
-gst_pad_proxy_getcaps (GstPad * pad)
+gst_pad_proxy_getcaps (GstPad * pad, GstCaps * filter)
{
GstElement *element;
GstCaps *caps, *intersected;
while (1) {
res =
gst_iterator_fold (iter, (GstIteratorFoldFunction) getcaps_fold_func,
- &ret, pad);
+ &ret, filter);
switch (res) {
case GST_ITERATOR_RESYNC:
/* unref any value stored */
case GST_ITERATOR_DONE:
/* all pads iterated, return collected value */
goto done;
+ case GST_ITERATOR_OK:
+ /* premature exit (happens if caps intersection is empty) */
+ goto done;
default:
- /* iterator returned _ERROR or premature end with _OK,
- * mark an error and exit */
+ /* iterator returned _ERROR, mark an error and exit */
if ((caps = g_value_get_pointer (&ret)))
gst_caps_unref (caps);
g_value_set_pointer (&ret, NULL);
}
}
-typedef struct
-{
- GstPad *orig;
- GstCaps *caps;
-} SetCapsFoldData;
-
-static gboolean
-setcaps_fold_func (GstPad * pad, GValue * ret, SetCapsFoldData * data)
-{
- gboolean success = TRUE;
-
- if (pad != data->orig) {
- success = gst_pad_set_caps (pad, data->caps);
- g_value_set_boolean (ret, success);
- }
- gst_object_unref (pad);
-
- return success;
-}
-
-/**
- * gst_pad_proxy_setcaps
- * @pad: a #GstPad to proxy from
- * @caps: the #GstCaps to link with
- *
- * Calls gst_pad_set_caps() for every other pad belonging to the
- * same element as @pad. If gst_pad_set_caps() fails on any pad,
- * the proxy setcaps fails. May be used only during negotiation.
- *
- * Returns: TRUE if sucessful
- */
-gboolean
-gst_pad_proxy_setcaps (GstPad * pad, GstCaps * caps)
-{
- GstElement *element;
- GstIterator *iter;
- GstIteratorResult res;
- GValue ret = { 0, };
- SetCapsFoldData data;
-
- g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
- g_return_val_if_fail (caps != NULL, FALSE);
-
- GST_CAT_DEBUG (GST_CAT_PADS, "proxying pad link for %s:%s",
- GST_DEBUG_PAD_NAME (pad));
-
- element = gst_pad_get_parent_element (pad);
- if (element == NULL)
- return FALSE;
-
- /* only iterate the pads in the oposite direction */
- if (GST_PAD_IS_SRC (pad))
- iter = gst_element_iterate_sink_pads (element);
- else
- iter = gst_element_iterate_src_pads (element);
-
- g_value_init (&ret, G_TYPE_BOOLEAN);
- g_value_set_boolean (&ret, TRUE);
- data.orig = pad;
- data.caps = caps;
-
- while (1) {
- res = gst_iterator_fold (iter, (GstIteratorFoldFunction) setcaps_fold_func,
- &ret, &data);
-
- switch (res) {
- case GST_ITERATOR_RESYNC:
- /* reset return value */
- g_value_set_boolean (&ret, TRUE);
- gst_iterator_resync (iter);
- break;
- case GST_ITERATOR_DONE:
- /* all pads iterated, return collected value */
- goto done;
- default:
- /* iterator returned _ERROR or premature end with _OK,
- * mark an error and exit */
- goto error;
- }
- }
-done:
- gst_iterator_free (iter);
-
- gst_object_unref (element);
-
- /* ok not to unset the gvalue */
- return g_value_get_boolean (&ret);
-
- /* ERRORS */
-error:
- {
- g_warning ("Pad list return error on element %s",
- GST_ELEMENT_NAME (element));
- gst_iterator_free (iter);
- gst_object_unref (element);
- return FALSE;
- }
-}
-
/**
* gst_pad_query_position:
* @pad: a #GstPad to invoke the position query on.
* gst_pad_query_peer_position:
* @pad: a #GstPad on whose peer to invoke the position query on.
* Must be a sink pad.
- * @format: a pointer to the #GstFormat asked for.
+ * @format: (inout): a pointer to the #GstFormat asked for.
* On return contains the #GstFormat used.
- * @cur: A location in which to store the current position, or NULL.
+ * @cur: (out) (allow-none): a location in which to store the current
+ * position, or NULL.
*
* Queries the peer of a given sink pad for the stream position.
*
/**
* gst_pad_query_duration:
* @pad: a #GstPad to invoke the duration query on.
- * @format: a pointer to the #GstFormat asked for.
+ * @format: (inout): a pointer to the #GstFormat asked for.
* On return contains the #GstFormat used.
- * @duration: A location in which to store the total duration, or NULL.
+ * @duration: (out) (allow-none): a location in which to store the total
+ * duration, or NULL.
*
* Queries a pad for the total stream duration.
*
* gst_pad_query_peer_duration:
* @pad: a #GstPad on whose peer pad to invoke the duration query on.
* Must be a sink pad.
- * @format: a pointer to the #GstFormat asked for.
+ * @format: (inout) :a pointer to the #GstFormat asked for.
* On return contains the #GstFormat used.
- * @duration: A location in which to store the total duration, or NULL.
+ * @duration: (out) (allow-none): a location in which to store the total
+ * duration, or NULL.
*
* Queries the peer pad of a given sink pad for the total stream duration.
*
* @pad: a #GstPad to invoke the convert query on.
* @src_format: a #GstFormat to convert from.
* @src_val: a value to convert.
- * @dest_format: a pointer to the #GstFormat to convert to.
- * @dest_val: a pointer to the result.
+ * @dest_format: (inout): a pointer to the #GstFormat to convert to.
+ * @dest_val: (out): a pointer to the result.
*
* Queries a pad to convert @src_val in @src_format to @dest_format.
*
g_return_val_if_fail (dest_format != NULL, FALSE);
g_return_val_if_fail (dest_val != NULL, FALSE);
- if (*dest_format == src_format) {
+ if (*dest_format == src_format || src_val == -1) {
*dest_val = src_val;
return TRUE;
}
* Must be a sink pad.
* @src_format: a #GstFormat to convert from.
* @src_val: a value to convert.
- * @dest_format: a pointer to the #GstFormat to convert to.
- * @dest_val: a pointer to the result.
+ * @dest_format: (inout): a pointer to the #GstFormat to convert to.
+ * @dest_val: (out): a pointer to the result.
*
* Queries the peer pad of a given sink pad to convert @src_val in @src_format
* to @dest_format.
g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
g_return_val_if_fail (GST_PAD_IS_SINK (pad), FALSE);
- g_return_val_if_fail (src_val >= 0, FALSE);
g_return_val_if_fail (dest_format != NULL, FALSE);
g_return_val_if_fail (dest_val != NULL, FALSE);
}
/**
- * gst_atomic_int_set:
- * @atomic_int: pointer to an atomic integer
- * @value: value to set
- *
- * Unconditionally sets the atomic integer to @value.
- *
- * Deprecated: Use g_atomic_int_set().
- *
- */
-#ifndef GST_REMOVE_DEPRECATED
-#ifdef GST_DISABLE_DEPRECATED
-void gst_atomic_int_set (gint * atomic_int, gint value);
-#endif
-void
-gst_atomic_int_set (gint * atomic_int, gint value)
-{
- g_atomic_int_set (atomic_int, value);
-}
-#endif
-
-/**
- * gst_pad_add_data_probe:
- * @pad: pad to add the data probe handler to
- * @handler: function to call when data is passed over pad
- * @data: data to pass along with the handler
- *
- * Adds a "data probe" to a pad. This function will be called whenever data
- * passes through a pad. In this case data means both events and buffers. The
- * probe will be called with the data as an argument, meaning @handler should
- * have the same callback signature as the #GstPad::have-data signal.
- * Note that the data will have a reference count greater than 1, so it will
- * be immutable -- you must not change it.
- *
- * For source pads, the probe will be called after the blocking function, if any
- * (see gst_pad_set_blocked_async()), but before looking up the peer to chain
- * to. For sink pads, the probe function will be called before configuring the
- * sink with new caps, if any, and before calling the pad's chain function.
- *
- * Your data probe should return TRUE to let the data continue to flow, or FALSE
- * to drop it. Dropping data is rarely useful, but occasionally comes in handy
- * with events.
- *
- * Although probes are implemented internally by connecting @handler to the
- * have-data signal on the pad, if you want to remove a probe it is insufficient
- * to only call g_signal_handler_disconnect on the returned handler id. To
- * remove a probe, use the appropriate function, such as
- * gst_pad_remove_data_probe().
- *
- * Returns: The handler id.
- */
-gulong
-gst_pad_add_data_probe (GstPad * pad, GCallback handler, gpointer data)
-{
- return gst_pad_add_data_probe_full (pad, handler, data, NULL);
-}
-
-/**
- * gst_pad_add_data_probe_full:
- * @pad: pad to add the data probe handler to
- * @handler: function to call when data is passed over pad
- * @data: data to pass along with the handler
- * @notify: function to call when the probe is disconnected, or NULL
- *
- * Adds a "data probe" to a pad. This function will be called whenever data
- * passes through a pad. In this case data means both events and buffers. The
- * probe will be called with the data as an argument, meaning @handler should
- * have the same callback signature as the #GstPad::have-data signal.
- * Note that the data will have a reference count greater than 1, so it will
- * be immutable -- you must not change it.
- *
- * For source pads, the probe will be called after the blocking function, if any
- * (see gst_pad_set_blocked_async()), but before looking up the peer to chain
- * to. For sink pads, the probe function will be called before configuring the
- * sink with new caps, if any, and before calling the pad's chain function.
- *
- * Your data probe should return TRUE to let the data continue to flow, or FALSE
- * to drop it. Dropping data is rarely useful, but occasionally comes in handy
- * with events.
- *
- * Although probes are implemented internally by connecting @handler to the
- * have-data signal on the pad, if you want to remove a probe it is insufficient
- * to only call g_signal_handler_disconnect on the returned handler id. To
- * remove a probe, use the appropriate function, such as
- * gst_pad_remove_data_probe().
- *
- * The @notify function is called when the probe is disconnected and usually
- * used to free @data.
- *
- * Returns: The handler id.
- *
- * Since: 0.10.20
- */
-gulong
-gst_pad_add_data_probe_full (GstPad * pad, GCallback handler,
- gpointer data, GDestroyNotify notify)
-{
- gulong sigid;
-
- g_return_val_if_fail (GST_IS_PAD (pad), 0);
- g_return_val_if_fail (handler != NULL, 0);
-
- GST_OBJECT_LOCK (pad);
-
- /* we only expose a GDestroyNotify in our API because that's less confusing */
- sigid = g_signal_connect_data (pad, "have-data", handler, data,
- (GClosureNotify) notify, 0);
-
- GST_PAD_DO_EVENT_SIGNALS (pad)++;
- GST_PAD_DO_BUFFER_SIGNALS (pad)++;
- GST_CAT_DEBUG_OBJECT (GST_CAT_PADS, pad,
- "adding data probe, now %d data, %d event probes",
- GST_PAD_DO_BUFFER_SIGNALS (pad), GST_PAD_DO_EVENT_SIGNALS (pad));
- GST_OBJECT_UNLOCK (pad);
-
- return sigid;
-}
-
-/**
- * gst_pad_add_event_probe:
- * @pad: pad to add the event probe handler to
- * @handler: function to call when events are passed over pad
- * @data: data to pass along with the handler
- *
- * Adds a probe that will be called for all events passing through a pad. See
- * gst_pad_add_data_probe() for more information.
- *
- * Returns: The handler id
- */
-gulong
-gst_pad_add_event_probe (GstPad * pad, GCallback handler, gpointer data)
-{
- return gst_pad_add_event_probe_full (pad, handler, data, NULL);
-}
-
-/**
- * gst_pad_add_event_probe_full:
- * @pad: pad to add the event probe handler to
- * @handler: function to call when events are passed over pad
- * @data: data to pass along with the handler, or NULL
- * @notify: function to call when probe is disconnected, or NULL
- *
- * Adds a probe that will be called for all events passing through a pad. See
- * gst_pad_add_data_probe() for more information.
- *
- * The @notify function is called when the probe is disconnected and usually
- * used to free @data.
- *
- * Returns: The handler id
- *
- * Since: 0.10.20
- */
-gulong
-gst_pad_add_event_probe_full (GstPad * pad, GCallback handler,
- gpointer data, GDestroyNotify notify)
-{
- gulong sigid;
-
- g_return_val_if_fail (GST_IS_PAD (pad), 0);
- g_return_val_if_fail (handler != NULL, 0);
-
- GST_OBJECT_LOCK (pad);
-
- /* we only expose a GDestroyNotify in our API because that's less confusing */
- sigid = g_signal_connect_data (pad, "have-data::event", handler, data,
- (GClosureNotify) notify, 0);
-
- GST_PAD_DO_EVENT_SIGNALS (pad)++;
- GST_CAT_DEBUG_OBJECT (GST_CAT_PADS, pad, "adding event probe, now %d probes",
- GST_PAD_DO_EVENT_SIGNALS (pad));
- GST_OBJECT_UNLOCK (pad);
-
- return sigid;
-}
-
-/**
- * gst_pad_add_buffer_probe:
- * @pad: pad to add the buffer probe handler to
- * @handler: function to call when buffers are passed over pad
- * @data: data to pass along with the handler
- *
- * Adds a probe that will be called for all buffers passing through a pad. See
- * gst_pad_add_data_probe() for more information.
- *
- * Returns: The handler id
- */
-gulong
-gst_pad_add_buffer_probe (GstPad * pad, GCallback handler, gpointer data)
-{
- return gst_pad_add_buffer_probe_full (pad, handler, data, NULL);
-}
-
-/**
- * gst_pad_add_buffer_probe_full:
- * @pad: pad to add the buffer probe handler to
- * @handler: function to call when buffer are passed over pad
- * @data: data to pass along with the handler
- * @notify: function to call when the probe is disconnected, or NULL
- *
- * Adds a probe that will be called for all buffers passing through a pad. See
- * gst_pad_add_data_probe() for more information.
- *
- * The @notify function is called when the probe is disconnected and usually
- * used to free @data.
- *
- * Returns: The handler id
- *
- * Since: 0.10.20
- */
-gulong
-gst_pad_add_buffer_probe_full (GstPad * pad, GCallback handler,
- gpointer data, GDestroyNotify notify)
-{
- gulong sigid;
-
- g_return_val_if_fail (GST_IS_PAD (pad), 0);
- g_return_val_if_fail (handler != NULL, 0);
-
- GST_OBJECT_LOCK (pad);
-
- /* we only expose a GDestroyNotify in our API because that's less confusing */
- sigid = g_signal_connect_data (pad, "have-data::buffer", handler, data,
- (GClosureNotify) notify, 0);
-
- GST_PAD_DO_BUFFER_SIGNALS (pad)++;
- GST_CAT_DEBUG_OBJECT (GST_CAT_PADS, pad, "adding buffer probe, now %d probes",
- GST_PAD_DO_BUFFER_SIGNALS (pad));
- GST_OBJECT_UNLOCK (pad);
-
- return sigid;
-}
-
-/**
- * gst_pad_remove_data_probe:
- * @pad: pad to remove the data probe handler from
- * @handler_id: handler id returned from gst_pad_add_data_probe
- *
- * Removes a data probe from @pad.
- */
-void
-gst_pad_remove_data_probe (GstPad * pad, guint handler_id)
-{
- g_return_if_fail (GST_IS_PAD (pad));
- g_return_if_fail (handler_id > 0);
-
- GST_OBJECT_LOCK (pad);
- g_signal_handler_disconnect (pad, handler_id);
- GST_PAD_DO_BUFFER_SIGNALS (pad)--;
- GST_PAD_DO_EVENT_SIGNALS (pad)--;
- GST_CAT_DEBUG_OBJECT (GST_CAT_PADS, pad,
- "removed data probe, now %d event, %d buffer probes",
- GST_PAD_DO_EVENT_SIGNALS (pad), GST_PAD_DO_BUFFER_SIGNALS (pad));
- GST_OBJECT_UNLOCK (pad);
-
-}
-
-/**
- * gst_pad_remove_event_probe:
- * @pad: pad to remove the event probe handler from
- * @handler_id: handler id returned from gst_pad_add_event_probe
- *
- * Removes an event probe from @pad.
- */
-void
-gst_pad_remove_event_probe (GstPad * pad, guint handler_id)
-{
- g_return_if_fail (GST_IS_PAD (pad));
- g_return_if_fail (handler_id > 0);
-
- GST_OBJECT_LOCK (pad);
- g_signal_handler_disconnect (pad, handler_id);
- GST_PAD_DO_EVENT_SIGNALS (pad)--;
- GST_CAT_DEBUG_OBJECT (GST_CAT_PADS, pad,
- "removed event probe, now %d event probes",
- GST_PAD_DO_EVENT_SIGNALS (pad));
- GST_OBJECT_UNLOCK (pad);
-}
-
-/**
- * gst_pad_remove_buffer_probe:
- * @pad: pad to remove the buffer probe handler from
- * @handler_id: handler id returned from gst_pad_add_buffer_probe
- *
- * Removes a buffer probe from @pad.
- */
-void
-gst_pad_remove_buffer_probe (GstPad * pad, guint handler_id)
-{
- g_return_if_fail (GST_IS_PAD (pad));
- g_return_if_fail (handler_id > 0);
-
- GST_OBJECT_LOCK (pad);
- g_signal_handler_disconnect (pad, handler_id);
- GST_PAD_DO_BUFFER_SIGNALS (pad)--;
- GST_CAT_DEBUG_OBJECT (GST_CAT_PADS, pad,
- "removed buffer probe, now %d buffer probes",
- GST_PAD_DO_BUFFER_SIGNALS (pad));
- GST_OBJECT_UNLOCK (pad);
-
-}
-
-/**
* gst_element_found_tags_for_pad:
* @element: element for which to post taglist to bus.
- * @pad: pad on which to push tag-event.
- * @list: the taglist to post on the bus and create event from.
+ * @pad: (transfer none): pad on which to push tag-event
+ * @list: (transfer full): the taglist to post on the bus and create event from
*
* Posts a message to the bus that new tags were found and pushes the
* tags as event. Takes ownership of the @list.
}
static void
-push_and_ref (GstPad * pad, GstEvent * event)
+push_and_ref (const GValue * vpad, GstEvent * event)
{
+ GstPad *pad = g_value_get_object (vpad);
+
gst_pad_push_event (pad, gst_event_ref (event));
- /* iterator refs pad, we unref when we are done with it */
- gst_object_unref (pad);
}
/**
* gst_element_found_tags:
* @element: element for which we found the tags.
- * @list: list of tags.
+ * @list: (transfer full): list of tags.
*
* Posts a message to the bus that new tags were found, and pushes an event
* to all sourcepads. Takes ownership of the @list.
iter = gst_element_iterate_src_pads (element);
event = gst_event_new_tag (gst_tag_list_copy (list));
- gst_iterator_foreach (iter, (GFunc) push_and_ref, event);
+ gst_iterator_foreach (iter, (GstIteratorForeachFunction) push_and_ref, event);
gst_iterator_free (iter);
gst_event_unref (event);
GstIterator *iter;
GstPad *unlinked_pad = NULL;
gboolean done;
+ GValue data = { 0, };
switch (direction) {
case GST_PAD_SRC:
done = FALSE;
while (!done) {
- gpointer pad;
-
- switch (gst_iterator_next (iter, &pad)) {
+ switch (gst_iterator_next (iter, &data)) {
case GST_ITERATOR_OK:{
GstPad *peer;
+ GstPad *pad = g_value_get_object (&data);
GST_CAT_LOG (GST_CAT_ELEMENT_PADS, "examining pad %s:%s",
GST_DEBUG_PAD_NAME (pad));
- peer = gst_pad_get_peer (GST_PAD (pad));
+ peer = gst_pad_get_peer (pad);
if (peer == NULL) {
- unlinked_pad = pad;
+ unlinked_pad = gst_object_ref (pad);
done = TRUE;
GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS,
"found existing unlinked pad %s:%s",
GST_DEBUG_PAD_NAME (unlinked_pad));
} else {
- gst_object_unref (pad);
gst_object_unref (peer);
}
+ g_value_reset (&data);
break;
}
case GST_ITERATOR_DONE:
break;
}
}
-
+ g_value_unset (&data);
gst_iterator_free (iter);
return unlinked_pad;
* owns a reference to it and should use gst_object_unref() on the
* pad when it is not needed any longer.
*
- * Returns: unlinked pad of the given direction, or NULL.
+ * Returns: (transfer full): unlinked pad of the given direction, or NULL.
*
* Since: 0.10.20
*/
GstIterator *iter;
gboolean done;
GstPad *pad = NULL;
+ GValue data = { 0, };
g_return_val_if_fail (GST_IS_BIN (bin), NULL);
g_return_val_if_fail (direction != GST_PAD_UNKNOWN, NULL);
done = FALSE;
iter = gst_bin_iterate_recurse (bin);
while (!done) {
- gpointer element;
+ switch (gst_iterator_next (iter, &data)) {
+ case GST_ITERATOR_OK:{
+ GstElement *element = g_value_get_object (&data);
- switch (gst_iterator_next (iter, &element)) {
- case GST_ITERATOR_OK:
- pad = element_find_unlinked_pad (GST_ELEMENT (element), direction);
- gst_object_unref (element);
+ pad = element_find_unlinked_pad (element, direction);
if (pad != NULL)
done = TRUE;
+ g_value_reset (&data);
break;
+ }
case GST_ITERATOR_DONE:
done = TRUE;
break;
break;
}
}
-
+ g_value_unset (&data);
gst_iterator_free (iter);
return pad;
}
/**
- * gst_bin_find_unconnected_pad:
- * @bin: bin in which to look for elements with unlinked pads
- * @direction: whether to look for an unlinked source or sink pad
- *
- * Recursively looks for elements with an unlinked pad of the given
- * direction within the specified bin and returns an unlinked pad
- * if one is found, or NULL otherwise. If a pad is found, the caller
- * owns a reference to it and should use gst_object_unref() on the
- * pad when it is not needed any longer.
- *
- * Returns: unlinked pad of the given direction, or NULL.
- *
- * Since: 0.10.3
- *
- * Deprecated: use gst_bin_find_unlinked_pad() instead.
- */
-#ifndef GST_REMOVE_DEPRECATED
-#ifdef GST_DISABLE_DEPRECATED
-GstPad *gst_bin_find_unconnected_pad (GstBin * bin, GstPadDirection direction);
-#endif
-GstPad *
-gst_bin_find_unconnected_pad (GstBin * bin, GstPadDirection direction)
-{
- return gst_bin_find_unlinked_pad (bin, direction);
-}
-#endif
-
-/**
* gst_parse_bin_from_description:
* @bin_description: command line describing the bin
* @ghost_unlinked_pads: whether to automatically create ghost pads
* and want them all ghosted, you will have to create the ghost pads
* yourself).
*
- * Returns: a newly-created bin, or NULL if an error occurred.
+ * Returns: (transfer full): a newly-created bin, or NULL if an error occurred.
*
* Since: 0.10.3
*/
gboolean ghost_unlinked_pads, GError ** err)
{
return gst_parse_bin_from_description_full (bin_description,
- ghost_unlinked_pads, NULL, 0, err);
+ ghost_unlinked_pads, NULL, GST_PARSE_FLAG_NONE, err);
}
/**
* @bin_description: command line describing the bin
* @ghost_unlinked_pads: whether to automatically create ghost pads
* for unlinked source or sink pads within the bin
- * @context: a parse context allocated with gst_parse_context_new(), or %NULL
+ * @context: (transfer none) (allow-none): a parse context allocated with
+ * gst_parse_context_new(), or %NULL
* @flags: parsing options, or #GST_PARSE_FLAG_NONE
* @err: where to store the error message in case of an error, or NULL
*
* and want them all ghosted, you will have to create the ghost pads
* yourself).
*
- * Returns: a newly-created bin, or NULL if an error occurred.
+ * Returns: (transfer full): a newly-created bin, or NULL if an error occurred.
*
* Since: 0.10.20
*/
* @array: the sorted input array
* @num_elements: number of elements in the array
* @element_size: size of every element in bytes
- * @search_func: function to compare two elements, @search_data will always be passed as second argument
+ * @search_func: (scope call): function to compare two elements, @search_data will always be passed as second argument
* @mode: search mode that should be used
* @search_data: element that should be found
- * @user_data: data to pass to @search_func
+ * @user_data: (closure): data to pass to @search_func
*
* Searches inside @array for @search_data by using the comparison function
* @search_func. @array must be sorted ascending.
*
* The complexity of this search function is O(log (num_elements)).
*
- * Returns: The address of the found element or %NULL if nothing was found
+ * Returns: (transfer none): The address of the found element or %NULL if nothing was found
*
* Since: 0.10.23
*/
* gst_util_fraction_to_double:
* @src_n: Fraction numerator as #gint
* @src_d: Fraction denominator #gint
- * @dest: pointer to a #gdouble for the result
+ * @dest: (out): pointer to a #gdouble for the result
*
- * Transforms a #gdouble to a fraction and simplifies the result.
+ * Transforms a fraction to a #gdouble.
*
* Since: 0.10.26
*/
/**
* gst_util_double_to_fraction:
* @src: #gdouble to transform
- * @dest_n: pointer to a #gint to hold the result numerator
- * @dest_d: pointer to a #gint to hold the result denominator
+ * @dest_n: (out): pointer to a #gint to hold the result numerator
+ * @dest_d: (out): pointer to a #gint to hold the result denominator
*
* Transforms a #gdouble to a fraction and simplifies
* the result.
* @a_d: Denominator of first value
* @b_n: Numerator of second value
* @b_d: Denominator of second value
- * @res_n: Pointer to #gint to hold the result numerator
- * @res_d: Pointer to #gint to hold the result denominator
+ * @res_n: (out): Pointer to #gint to hold the result numerator
+ * @res_d: (out): Pointer to #gint to hold the result denominator
*
* Multiplies the fractions @a_n/@a_d and @b_n/@b_d and stores
* the result in @res_n and @res_d.
* @a_d: Denominator of first value
* @b_n: Numerator of second value
* @b_d: Denominator of second value
- * @res_n: Pointer to #gint to hold the result numerator
- * @res_d: Pointer to #gint to hold the result denominator
+ * @res_n: (out): Pointer to #gint to hold the result numerator
+ * @res_d: (out): Pointer to #gint to hold the result denominator
*
* Adds the fractions @a_n/@a_d and @b_n/@b_d and stores
* the result in @res_n and @res_d.
return TRUE;
}
+
+/**
+ * gst_util_fraction_compare:
+ * @a_n: Numerator of first value
+ * @a_d: Denominator of first value
+ * @b_n: Numerator of second value
+ * @b_d: Denominator of second value
+ *
+ * Compares the fractions @a_n/@a_d and @b_n/@b_d and returns
+ * -1 if a < b, 0 if a = b and 1 if a > b.
+ *
+ * Returns: -1 if a < b; 0 if a = b; 1 if a > b.
+ *
+ * Since: 0.10.31
+ */
+gint
+gst_util_fraction_compare (gint a_n, gint a_d, gint b_n, gint b_d)
+{
+ gint64 new_num_1;
+ gint64 new_num_2;
+ gint gcd;
+
+ g_return_val_if_fail (a_d != 0 && b_d != 0, 0);
+
+ /* Simplify */
+ gcd = gst_util_greatest_common_divisor (a_n, a_d);
+ a_n /= gcd;
+ a_d /= gcd;
+
+ gcd = gst_util_greatest_common_divisor (b_n, b_d);
+ b_n /= gcd;
+ b_d /= gcd;
+
+ /* fractions are reduced when set, so we can quickly see if they're equal */
+ if (a_n == b_n && a_d == b_d)
+ return 0;
+
+ /* extend to 64 bits */
+ new_num_1 = ((gint64) a_n) * b_d;
+ new_num_2 = ((gint64) b_n) * a_d;
+ if (new_num_1 < new_num_2)
+ return -1;
+ if (new_num_1 > new_num_2)
+ return 1;
+
+ /* Should not happen because a_d and b_d are not 0 */
+ g_return_val_if_reached (0);
+}