diff -r 567bb019e3e3 -r 7e817e7e631c gstreamer_core/gst/gstutils.c --- a/gstreamer_core/gst/gstutils.c Tue Aug 31 15:30:33 2010 +0300 +++ b/gstreamer_core/gst/gstutils.c Wed Sep 01 12:16:41 2010 +0100 @@ -3,7 +3,7 @@ * 2000 Wim Taymans * 2002 Thomas Vander Stichele * - * gstutils.c: Utility functions + * gstutils.c: Utility functions: gtk_get_property stuff, etc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -37,16 +37,8 @@ #include "gsterror.h" #include "gstinfo.h" #include "gstparse.h" -#include "gstvalue.h" #include "gst-i18n-lib.h" -/** - * gst_util_dump_mem: - * @mem: a pointer to the memory to dump - * @size: the size of the memory block to dump - * - * Dumps the memory block into a hex representation. Useful for debugging. - */ #ifdef __SYMBIAN32__ #include #include @@ -103,9 +95,6 @@ * * Converts the string to the type of the value and * sets the value with it. - * - * Note that this function is dangerous as it does not return any indication - * if the conversion worked or not. */ #ifdef __SYMBIAN32__ EXPORT_C @@ -114,7 +103,7 @@ void gst_util_set_value_from_string (GValue * value, const gchar * value_str) { - gboolean res; + gint sscanf_ret; g_return_if_fail (value != NULL); g_return_if_fail (value_str != NULL); @@ -122,13 +111,86 @@ GST_CAT_DEBUG (GST_CAT_PARAMS, "parsing '%s' to type %s", value_str, g_type_name (G_VALUE_TYPE (value))); - res = gst_value_deserialize (value, value_str); - if (!res && G_VALUE_TYPE (value) == G_TYPE_BOOLEAN) { - /* backwards compat, all booleans that fail to parse are false */ - g_value_set_boolean (value, FALSE); - res = TRUE; + switch (G_VALUE_TYPE (value)) { + case G_TYPE_STRING: + g_value_set_string (value, value_str); + break; + case G_TYPE_ENUM: + case G_TYPE_INT:{ + gint i; + + sscanf_ret = sscanf (value_str, "%d", &i); + g_return_if_fail (sscanf_ret == 1); + g_value_set_int (value, i); + break; + } + case G_TYPE_UINT:{ + guint i; + + sscanf_ret = sscanf (value_str, "%u", &i); + g_return_if_fail (sscanf_ret == 1); + g_value_set_uint (value, i); + break; + } + case G_TYPE_LONG:{ + glong i; + + sscanf_ret = sscanf (value_str, "%ld", &i); + g_return_if_fail (sscanf_ret == 1); + g_value_set_long (value, i); + break; + } + case G_TYPE_ULONG:{ + gulong i; + + sscanf_ret = sscanf (value_str, "%lu", &i); + g_return_if_fail (sscanf_ret == 1); + g_value_set_ulong (value, i); + break; + } + case G_TYPE_BOOLEAN:{ + gboolean i = FALSE; + + if (!g_ascii_strncasecmp ("true", value_str, 4)) + i = TRUE; + g_value_set_boolean (value, i); + break; + } + case G_TYPE_CHAR:{ + gchar i; + + sscanf_ret = sscanf (value_str, "%c", &i); + g_return_if_fail (sscanf_ret == 1); + g_value_set_char (value, i); + break; + } + case G_TYPE_UCHAR:{ + guchar i; + + sscanf_ret = sscanf (value_str, "%c", &i); + g_return_if_fail (sscanf_ret == 1); + g_value_set_uchar (value, i); + break; + } + case G_TYPE_FLOAT:{ + gfloat i; + + sscanf_ret = sscanf (value_str, "%f", &i); + g_return_if_fail (sscanf_ret == 1); + g_value_set_float (value, i); + break; + } + case G_TYPE_DOUBLE:{ + gfloat i; + + sscanf_ret = sscanf (value_str, "%g", &i); + g_return_if_fail (sscanf_ret == 1); + g_value_set_double (value, (gdouble) i); + break; + } + default: + break; } - g_return_if_fail (res); } /** @@ -139,9 +201,6 @@ * * Convertes the string value to the type of the objects argument and * sets the argument with it. - * - * Note that this function silently returns if @object has no property named - * @name or when @value cannot be converted to the type of the property. */ #ifdef __SYMBIAN32__ EXPORT_C @@ -151,41 +210,111 @@ gst_util_set_object_arg (GObject * object, const gchar * name, const gchar * value) { - GParamSpec *pspec; - GType value_type; - GValue v = { 0, }; - - g_return_if_fail (G_IS_OBJECT (object)); - g_return_if_fail (name != NULL); - g_return_if_fail (value != NULL); - - pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (object), name); - if (!pspec) - return; - - value_type = G_PARAM_SPEC_VALUE_TYPE (pspec); - - GST_DEBUG ("pspec->flags is %d, pspec->value_type is %s", - pspec->flags, g_type_name (value_type)); - - if (!(pspec->flags & G_PARAM_WRITABLE)) - return; - - g_value_init (&v, value_type); - - /* special case for element <-> xml (de)serialisation */ - if (GST_VALUE_HOLDS_STRUCTURE (&v) && strcmp (value, "NULL") == 0) { - g_value_set_boxed (&v, NULL); - goto done; + gboolean sscanf_ret; + + if (name && value) { + GParamSpec *paramspec; + + paramspec = + g_object_class_find_property (G_OBJECT_GET_CLASS (object), name); + + if (!paramspec) { + return; + } + + GST_DEBUG ("paramspec->flags is %d, paramspec->value_type is %d", + paramspec->flags, (gint) paramspec->value_type); + + if (paramspec->flags & G_PARAM_WRITABLE) { + switch (paramspec->value_type) { + case G_TYPE_STRING: + g_object_set (G_OBJECT (object), name, value, NULL); + break; + case G_TYPE_ENUM: + case G_TYPE_INT:{ + gint i; + + sscanf_ret = sscanf (value, "%d", &i); + g_return_if_fail (sscanf_ret == 1); + g_object_set (G_OBJECT (object), name, i, NULL); + break; + } + case G_TYPE_UINT:{ + guint i; + + sscanf_ret = sscanf (value, "%u", &i); + g_return_if_fail (sscanf_ret == 1); + g_object_set (G_OBJECT (object), name, i, NULL); + break; + } + case G_TYPE_LONG:{ + glong i; + + sscanf_ret = sscanf (value, "%ld", &i); + g_return_if_fail (sscanf_ret == 1); + g_object_set (G_OBJECT (object), name, i, NULL); + break; + } + case G_TYPE_ULONG:{ + gulong i; + + sscanf_ret = sscanf (value, "%lu", &i); + g_return_if_fail (sscanf_ret == 1); + g_object_set (G_OBJECT (object), name, i, NULL); + break; + } + case G_TYPE_BOOLEAN:{ + gboolean i = FALSE; + + if (!g_ascii_strncasecmp ("true", value, 4)) + i = TRUE; + g_object_set (G_OBJECT (object), name, i, NULL); + break; + } + case G_TYPE_CHAR:{ + gchar i; + + sscanf_ret = sscanf (value, "%c", &i); + g_return_if_fail (sscanf_ret == 1); + g_object_set (G_OBJECT (object), name, i, NULL); + break; + } + case G_TYPE_UCHAR:{ + guchar i; + + sscanf_ret = sscanf (value, "%c", &i); + g_return_if_fail (sscanf_ret == 1); + g_object_set (G_OBJECT (object), name, i, NULL); + break; + } + case G_TYPE_FLOAT:{ + gfloat i; + + sscanf_ret = sscanf (value, "%f", &i); + g_return_if_fail (sscanf_ret == 1); + g_object_set (G_OBJECT (object), name, i, NULL); + break; + } + case G_TYPE_DOUBLE:{ + gfloat i; + + sscanf_ret = sscanf (value, "%g", &i); + g_return_if_fail (sscanf_ret == 1); + g_object_set (G_OBJECT (object), name, (gdouble) i, NULL); + break; + } + default: + if (G_IS_PARAM_SPEC_ENUM (paramspec)) { + gint i; + + sscanf_ret = sscanf (value, "%d", &i); + g_return_if_fail (sscanf_ret == 1); + g_object_set (G_OBJECT (object), name, i, NULL); + } + break; + } + } } - - if (!gst_value_deserialize (&v, value)) - return; - -done: - - g_object_set_property (object, pspec->name, &v); - g_value_unset (&v); } /* work around error C2520: conversion from unsigned __int64 to double @@ -306,7 +435,7 @@ } static guint64 -gst_util_uint64_scale_int64_unchecked (guint64 val, guint64 num, guint64 denom) +gst_util_uint64_scale_int64 (guint64 val, guint64 num, guint64 denom) { GstUInt64 a0, a1, b0, b1, c0, ct, c1, result; GstUInt64 v, n; @@ -338,7 +467,7 @@ c1.ll = (guint64) a1.l.high + b0.l.high + ct.l.high + b1.ll; /* if high bits bigger than denom, we overflow */ - if (G_UNLIKELY (c1.ll >= denom)) + if (c1.ll >= denom) goto overflow; /* shortcut for division by 1, c1.ll should be 0 because of the @@ -368,36 +497,6 @@ } } -static inline guint64 -gst_util_uint64_scale_int_unchecked (guint64 val, gint num, gint denom) -{ - GstUInt64 result; - GstUInt64 low, high; - - /* do 96 bits mult/div */ - low.ll = val; - result.ll = ((guint64) low.l.low) * num; - high.ll = ((guint64) low.l.high) * num + (result.l.high); - - low.ll = high.ll / denom; - result.l.high = high.ll % denom; - result.ll /= denom; - - /* avoid overflow */ - if (G_UNLIKELY (low.ll + result.l.high > G_MAXUINT32)) - goto overflow; - - result.l.high += low.l.low; - - return result.ll; - -overflow: - { - return G_MAXUINT64; - } -} - - /** * gst_util_uint64_scale: * @val: the number to scale @@ -420,33 +519,33 @@ { g_return_val_if_fail (denom != 0, G_MAXUINT64); - if (G_UNLIKELY (num == 0)) + if (num == 0) return 0; - if (G_UNLIKELY (num == denom)) + if (num == 1 && denom == 1) return val; /* if the denom is high, we need to do a 64 muldiv */ - if (G_UNLIKELY (denom > G_MAXINT32)) + if (denom > G_MAXINT32) goto do_int64; /* if num and denom are low we can do a 32 bit muldiv */ - if (G_LIKELY (num <= G_MAXINT32)) + if (num <= G_MAXINT32) goto do_int32; /* val and num are high, we need 64 muldiv */ - if (G_UNLIKELY (val > G_MAXINT32)) + if (val > G_MAXINT32) goto do_int64; /* val is low and num is high, we can swap them and do 32 muldiv */ - return gst_util_uint64_scale_int_unchecked (num, (gint) val, (gint) denom); + return gst_util_uint64_scale_int (num, (gint) val, (gint) denom); do_int32: - return gst_util_uint64_scale_int_unchecked (val, (gint) num, (gint) denom); + return gst_util_uint64_scale_int (val, (gint) num, (gint) denom); do_int64: /* to the more heavy implementations... */ - return gst_util_uint64_scale_int64_unchecked (val, num, denom); + return gst_util_uint64_scale_int64 (val, num, denom); } /** @@ -470,71 +569,43 @@ guint64 gst_util_uint64_scale_int (guint64 val, gint num, gint denom) { + GstUInt64 result; + GstUInt64 low, high; + g_return_val_if_fail (denom > 0, G_MAXUINT64); g_return_val_if_fail (num >= 0, G_MAXUINT64); - if (G_UNLIKELY (num == 0)) + if (num == 0) return 0; - if (G_UNLIKELY (num == denom)) + if (num == 1 && denom == 1) return val; if (val <= G_MAXUINT32) /* simple case */ return val * num / denom; - return gst_util_uint64_scale_int_unchecked (val, num, denom); -} - -/** - * gst_util_seqnum_next: - * - * Return a constantly incrementing sequence number. - * - * This function is used internally to GStreamer to be able to determine which - * events and messages are "the same". For example, elements may set the seqnum - * on a segment-done message to be the same as that of the last seek event, to - * indicate that event and the message correspond to the same segment. - * - * Returns: A constantly incrementing 32-bit unsigned integer, which might - * overflow back to 0 at some point. Use gst_util_seqnum_compare() to make sure - * you handle wraparound correctly. - * - * Since: 0.10.22 - */ -#ifdef __SYMBIAN32__ -EXPORT_C -#endif - -guint32 -gst_util_seqnum_next (void) -{ - static gint counter = 0; - return g_atomic_int_exchange_and_add (&counter, 1); -} - -/** - * gst_util_seqnum_compare: - * @s1: A sequence number. - * @s2: Another sequence number. - * - * Compare two sequence numbers, handling wraparound. - * - * The current implementation just returns (gint32)(@s1 - @s2). - * - * Returns: A negative number if @s1 is before @s2, 0 if they are equal, or a - * positive number if @s1 is after @s2. - * - * Since: 0.10.22 - */ -#ifdef __SYMBIAN32__ -EXPORT_C -#endif - -gint32 -gst_util_seqnum_compare (guint32 s1, guint32 s2) -{ - return (gint32) (s1 - s2); + /* do 96 bits mult/div */ + low.ll = val; + result.ll = ((guint64) low.l.low) * num; + high.ll = ((guint64) low.l.high) * num + (result.l.high); + + low.ll = high.ll / denom; + result.l.high = high.ll % denom; + result.ll /= denom; + + /* avoid overflow */ + if (low.ll + result.l.high > G_MAXUINT32) + goto overflow; + + result.l.high += low.l.low; + + return result.ll; + +overflow: + { + return G_MAXUINT64; + } } /* ----------------------------------------------------- @@ -857,60 +928,6 @@ return pad; } -/* - * Checks if the source pad and the sink pad can be linked. - * Both @srcpad and @sinkpad must be unlinked and have a parent. - */ -static gboolean -gst_pad_check_link (GstPad * srcpad, GstPad * sinkpad) -{ - /* FIXME This function is gross. It's almost a direct copy of - * gst_pad_link_filtered(). Any decent programmer would attempt - * to merge the two functions, which I will do some day. --ds - */ - - /* generic checks */ - g_return_val_if_fail (GST_IS_PAD (srcpad), FALSE); - g_return_val_if_fail (GST_IS_PAD (sinkpad), FALSE); - - GST_CAT_INFO (GST_CAT_PADS, "trying to link %s:%s and %s:%s", - GST_DEBUG_PAD_NAME (srcpad), GST_DEBUG_PAD_NAME (sinkpad)); - - /* FIXME: shouldn't we convert this to g_return_val_if_fail? */ - if (GST_PAD_PEER (srcpad) != NULL) { - GST_CAT_INFO (GST_CAT_PADS, "Source pad %s:%s has a peer, failed", - GST_DEBUG_PAD_NAME (srcpad)); - return FALSE; - } - if (GST_PAD_PEER (sinkpad) != NULL) { - GST_CAT_INFO (GST_CAT_PADS, "Sink pad %s:%s has a peer, failed", - GST_DEBUG_PAD_NAME (sinkpad)); - return FALSE; - } - if (!GST_PAD_IS_SRC (srcpad)) { - GST_CAT_INFO (GST_CAT_PADS, "Src pad %s:%s is not source pad, failed", - GST_DEBUG_PAD_NAME (srcpad)); - return FALSE; - } - if (!GST_PAD_IS_SINK (sinkpad)) { - GST_CAT_INFO (GST_CAT_PADS, "Sink pad %s:%s is not sink pad, failed", - GST_DEBUG_PAD_NAME (sinkpad)); - return FALSE; - } - if (GST_PAD_PARENT (srcpad) == NULL) { - GST_CAT_INFO (GST_CAT_PADS, "Src pad %s:%s has no parent, failed", - GST_DEBUG_PAD_NAME (srcpad)); - return FALSE; - } - if (GST_PAD_PARENT (sinkpad) == NULL) { - GST_CAT_INFO (GST_CAT_PADS, "Sink pad %s:%s has no parent, failed", - GST_DEBUG_PAD_NAME (srcpad)); - return FALSE; - } - - return TRUE; -} - /** * gst_element_get_compatible_pad: * @element: a #GstElement in which the pad should be found. @@ -938,6 +955,8 @@ GstPad *foundpad = NULL; gboolean done; + /* FIXME check for caps compatibility */ + g_return_val_if_fail (GST_IS_ELEMENT (element), NULL); g_return_val_if_fail (GST_IS_PAD (pad), NULL); @@ -966,47 +985,22 @@ peer = gst_pad_get_peer (current); - if (peer == NULL && gst_pad_check_link (pad, current)) { - GstCaps *temp, *temp2, *intersection; - - /* Now check if the two pads' caps are compatible */ - temp = gst_pad_get_caps (pad); - if (caps) { - intersection = gst_caps_intersect (temp, caps); - gst_caps_unref (temp); - } else { - intersection = temp; - } - - temp = gst_pad_get_caps (current); - temp2 = gst_caps_intersect (temp, intersection); - gst_caps_unref (temp); - gst_caps_unref (intersection); - - intersection = temp2; - - if (!gst_caps_is_empty (intersection)) { - gst_caps_unref (intersection); - - GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, - "found existing unlinked compatible pad %s:%s", - GST_DEBUG_PAD_NAME (current)); - gst_iterator_free (pads); - - return current; - } else { - GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "incompatible pads"); - } - gst_caps_unref (intersection); + if (peer == NULL && gst_pad_can_link (pad, current)) { + + GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, + "found existing unlinked pad %s:%s", + GST_DEBUG_PAD_NAME (current)); + + gst_iterator_free (pads); + + return current; } else { - GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, - "already linked or cannot be linked (peer = %p)", peer); + GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "unreffing pads"); + + gst_object_unref (current); + if (peer) + gst_object_unref (peer); } - GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "unreffing pads"); - - gst_object_unref (current); - if (peer) - gst_object_unref (peer); break; } case GST_ITERATOR_DONE: @@ -1022,18 +1016,12 @@ } gst_iterator_free (pads); - GST_CAT_DEBUG_OBJECT (GST_CAT_ELEMENT_PADS, element, - "Could not find a compatible unlinked always pad to link to %s:%s, now checking request pads", - GST_DEBUG_PAD_NAME (pad)); - /* 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 (pad); templ = gst_pad_template_new ((gchar *) GST_PAD_NAME (pad), GST_PAD_DIRECTION (pad), GST_PAD_ALWAYS, templcaps); - foundpad = gst_element_request_compatible_pad (element, templ); gst_object_unref (templ); @@ -1172,8 +1160,8 @@ 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 (gst_caps_is_always_compatible (gst_static_caps_get (&template-> + static_caps), caps)) return TRUE; } templates = g_list_next (templates); @@ -1449,8 +1437,7 @@ /* get a src pad */ if (srcpadname) { /* name specified, look it up */ - if (!(srcpad = gst_element_get_static_pad (src, srcpadname))) - srcpad = gst_element_get_request_pad (src, srcpadname); + srcpad = gst_element_get_pad (src, srcpadname); if (!srcpad) { GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "no pad %s:%s", GST_ELEMENT_NAME (src), srcpadname); @@ -1483,8 +1470,7 @@ /* get a destination pad */ if (destpadname) { /* name specified, look it up */ - if (!(destpad = gst_element_get_static_pad (dest, destpadname))) - destpad = gst_element_get_request_pad (dest, destpadname); + destpad = gst_element_get_pad (dest, destpadname); if (!destpad) { GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "no pad %s:%s", GST_ELEMENT_NAME (dest), destpadname); @@ -1789,7 +1775,6 @@ gboolean gst_element_link_many (GstElement * element_1, GstElement * element_2, ...) { - gboolean res = TRUE; va_list args; g_return_val_if_fail (GST_IS_ELEMENT (element_1), FALSE); @@ -1798,10 +1783,8 @@ va_start (args, element_2); while (element_2) { - if (!gst_element_link (element_1, element_2)) { - res = FALSE; - break; - } + if (!gst_element_link (element_1, element_2)) + return FALSE; element_1 = element_2; element_2 = va_arg (args, GstElement *); @@ -1809,7 +1792,7 @@ va_end (args); - return res; + return TRUE; } /** @@ -1858,9 +1841,6 @@ GstElement * dest, const gchar * destpadname) { GstPad *srcpad, *destpad; - gboolean srcrequest, destrequest; - - srcrequest = destrequest = FALSE; g_return_if_fail (src != NULL); g_return_if_fail (GST_IS_ELEMENT (src)); @@ -1870,33 +1850,23 @@ g_return_if_fail (destpadname != NULL); /* obtain the pads requested */ - if (!(srcpad = gst_element_get_static_pad (src, srcpadname))) - if ((srcpad = gst_element_get_request_pad (src, srcpadname))) - srcrequest = TRUE; + srcpad = gst_element_get_pad (src, srcpadname); if (srcpad == NULL) { GST_WARNING_OBJECT (src, "source element has no pad \"%s\"", srcpadname); return; } - if (!(destpad = gst_element_get_static_pad (dest, destpadname))) - if ((destpad = gst_element_get_request_pad (dest, destpadname))) - destrequest = TRUE; + destpad = gst_element_get_pad (dest, destpadname); if (destpad == NULL) { GST_WARNING_OBJECT (dest, "destination element has no pad \"%s\"", destpadname); - goto free_src; + gst_object_unref (srcpad); + return; } /* we're satisified they can be unlinked, let's do it */ gst_pad_unlink (srcpad, destpad); - - if (destrequest) - gst_element_release_request_pad (dest, destpad); + gst_object_unref (srcpad); gst_object_unref (destpad); - -free_src: - if (srcrequest) - gst_element_release_request_pad (src, srcpad); - gst_object_unref (srcpad); } /** @@ -1970,7 +1940,8 @@ if (GST_PAD_IS_SRC (pad)) { GstPad *peerpad = gst_pad_get_peer (pad); - /* see if the pad is linked and is really a pad of dest */ + /* see if the pad is connected and is really a pad + * of dest */ if (peerpad) { GstElement *peerelem; @@ -2164,6 +2135,70 @@ } /** + * gst_pad_can_link: + * @srcpad: the source #GstPad to link. + * @sinkpad: the sink #GstPad to link. + * + * Checks if the source pad and the sink pad can be linked. + * Both @srcpad and @sinkpad must be unlinked. + * + * Returns: TRUE if the pads can be linked, FALSE otherwise. + */ +#ifdef __SYMBIAN32__ +EXPORT_C +#endif + +gboolean +gst_pad_can_link (GstPad * srcpad, GstPad * sinkpad) +{ + /* FIXME This function is gross. It's almost a direct copy of + * gst_pad_link_filtered(). Any decent programmer would attempt + * to merge the two functions, which I will do some day. --ds + */ + + /* generic checks */ + g_return_val_if_fail (GST_IS_PAD (srcpad), FALSE); + g_return_val_if_fail (GST_IS_PAD (sinkpad), FALSE); + + GST_CAT_INFO (GST_CAT_PADS, "trying to link %s:%s and %s:%s", + GST_DEBUG_PAD_NAME (srcpad), GST_DEBUG_PAD_NAME (sinkpad)); + + /* FIXME: shouldn't we convert this to g_return_val_if_fail? */ + if (GST_PAD_PEER (srcpad) != NULL) { + GST_CAT_INFO (GST_CAT_PADS, "Source pad %s:%s has a peer, failed", + GST_DEBUG_PAD_NAME (srcpad)); + return FALSE; + } + if (GST_PAD_PEER (sinkpad) != NULL) { + GST_CAT_INFO (GST_CAT_PADS, "Sink pad %s:%s has a peer, failed", + GST_DEBUG_PAD_NAME (sinkpad)); + return FALSE; + } + if (!GST_PAD_IS_SRC (srcpad)) { + GST_CAT_INFO (GST_CAT_PADS, "Src pad %s:%s is not source pad, failed", + GST_DEBUG_PAD_NAME (srcpad)); + return FALSE; + } + if (!GST_PAD_IS_SINK (sinkpad)) { + GST_CAT_INFO (GST_CAT_PADS, "Sink pad %s:%s is not sink pad, failed", + GST_DEBUG_PAD_NAME (sinkpad)); + return FALSE; + } + if (GST_PAD_PARENT (srcpad) == NULL) { + GST_CAT_INFO (GST_CAT_PADS, "Src pad %s:%s has no parent, failed", + GST_DEBUG_PAD_NAME (srcpad)); + return FALSE; + } + if (GST_PAD_PARENT (sinkpad) == NULL) { + GST_CAT_INFO (GST_CAT_PADS, "Sink pad %s:%s has no parent, failed", + GST_DEBUG_PAD_NAME (srcpad)); + return FALSE; + } + + return TRUE; +} + +/** * gst_pad_use_fixed_caps: * @pad: the pad to use * @@ -2214,7 +2249,9 @@ "using pad caps %p %" GST_PTR_FORMAT, result, result); result = gst_caps_ref (result); - } else if (GST_PAD_PAD_TEMPLATE (pad)) { + goto done; + } + if (GST_PAD_PAD_TEMPLATE (pad)) { GstPadTemplate *templ = GST_PAD_PAD_TEMPLATE (pad); result = GST_PAD_TEMPLATE_CAPS (templ); @@ -2223,10 +2260,12 @@ result); result = gst_caps_ref (result); - } else { - GST_CAT_DEBUG (GST_CAT_CAPS, "pad has no caps"); - result = gst_caps_new_empty (); + goto done; } + GST_CAT_DEBUG (GST_CAT_CAPS, "pad has no caps"); + result = gst_caps_new_empty (); + +done: GST_OBJECT_UNLOCK (pad); return result; @@ -2520,11 +2559,6 @@ * If the buffers point to contiguous areas of memory, the buffer * is created without copying the data. * - * This is a convenience function for C programmers. See also - * gst_buffer_merge(), which does the same thing without - * 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. */ #ifdef __SYMBIAN32__ @@ -2572,7 +2606,6 @@ static gboolean intersect_caps_func (GstPad * pad, GValue * ret, GstPad * orig) { - /* skip the pad, the request came from */ if (pad != orig) { GstCaps *peercaps, *existing; @@ -2616,8 +2649,7 @@ g_return_val_if_fail (GST_IS_PAD (pad), NULL); - GST_CAT_DEBUG (GST_CAT_PADS, "proxying getcaps for %s:%s", - GST_DEBUG_PAD_NAME (pad)); + GST_DEBUG ("proxying getcaps for %s:%s", GST_DEBUG_PAD_NAME (pad)); element = gst_pad_get_parent_element (pad); if (element == NULL) @@ -2725,8 +2757,7 @@ 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)); + GST_DEBUG ("proxying pad link for %s:%s", GST_DEBUG_PAD_NAME (pad)); element = gst_pad_get_parent_element (pad); if (element == NULL) @@ -2926,6 +2957,7 @@ gboolean ret; g_return_val_if_fail (GST_IS_PAD (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); @@ -2992,11 +3024,7 @@ * @value: value to set * * Unconditionally sets the atomic integer to @value. - * - * Deprecated: Use g_atomic_int_set(). - * */ -#ifndef GST_REMOVE_DEPRECATED #ifdef __SYMBIAN32__ EXPORT_C #endif @@ -3004,9 +3032,12 @@ void gst_atomic_int_set (gint * atomic_int, gint value) { - g_atomic_int_set (atomic_int, value); + int ignore; + + *atomic_int = value; + /* read acts as a memory barrier */ + ignore = g_atomic_int_get (atomic_int); } -#endif /** * gst_pad_add_data_probe: @@ -3045,68 +3076,17 @@ 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 - */ -#ifdef __SYMBIAN32__ -EXPORT_C -#endif - -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); - + sigid = g_signal_connect (pad, "have-data", handler, data); 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_DEBUG ("adding data probe to pad %s:%s, now %d data, %d event probes", + GST_DEBUG_PAD_NAME (pad), GST_PAD_DO_BUFFER_SIGNALS (pad), GST_PAD_DO_EVENT_SIGNALS (pad)); GST_OBJECT_UNLOCK (pad); @@ -3131,48 +3111,16 @@ 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 - */ -#ifdef __SYMBIAN32__ -EXPORT_C -#endif - -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); - + sigid = g_signal_connect (pad, "have-data::event", handler, data); 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_DEBUG ("adding event probe to pad %s:%s, now %d probes", + GST_DEBUG_PAD_NAME (pad), GST_PAD_DO_EVENT_SIGNALS (pad)); GST_OBJECT_UNLOCK (pad); return sigid; @@ -3196,48 +3144,16 @@ 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 - */ -#ifdef __SYMBIAN32__ -EXPORT_C -#endif - -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); - + sigid = g_signal_connect (pad, "have-data::buffer", handler, data); 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_DEBUG ("adding buffer probe to pad %s:%s, now %d probes", + GST_DEBUG_PAD_NAME (pad), GST_PAD_DO_BUFFER_SIGNALS (pad)); GST_OBJECT_UNLOCK (pad); return sigid; @@ -3264,9 +3180,10 @@ 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_DEBUG + ("removed data probe from pad %s:%s, now %d event, %d buffer probes", + GST_DEBUG_PAD_NAME (pad), GST_PAD_DO_EVENT_SIGNALS (pad), + GST_PAD_DO_BUFFER_SIGNALS (pad)); GST_OBJECT_UNLOCK (pad); } @@ -3291,9 +3208,8 @@ 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_DEBUG ("removed event probe from pad %s:%s, now %d event probes", + GST_DEBUG_PAD_NAME (pad), GST_PAD_DO_EVENT_SIGNALS (pad)); GST_OBJECT_UNLOCK (pad); } @@ -3317,9 +3233,8 @@ 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_DEBUG ("removed buffer probe from pad %s:%s, now %d buffer probes", + GST_DEBUG_PAD_NAME (pad), GST_PAD_DO_BUFFER_SIGNALS (pad)); GST_OBJECT_UNLOCK (pad); } @@ -3349,9 +3264,8 @@ g_return_if_fail (list != NULL); gst_pad_push_event (pad, gst_event_new_tag (gst_tag_list_copy (list))); - /* FIXME 0.11: Set the pad as source. */ gst_element_post_message (element, - gst_message_new_tag_full (GST_OBJECT (element), pad, list)); + gst_message_new_tag (GST_OBJECT (element), list)); } static void @@ -3397,10 +3311,10 @@ } static GstPad * -element_find_unlinked_pad (GstElement * element, GstPadDirection direction) +element_find_unconnected_pad (GstElement * element, GstPadDirection direction) { GstIterator *iter; - GstPad *unlinked_pad = NULL; + GstPad *unconnected_pad = NULL; gboolean done; switch (direction) { @@ -3427,11 +3341,11 @@ peer = gst_pad_get_peer (GST_PAD (pad)); if (peer == NULL) { - unlinked_pad = pad; + unconnected_pad = pad; done = TRUE; GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "found existing unlinked pad %s:%s", - GST_DEBUG_PAD_NAME (unlinked_pad)); + GST_DEBUG_PAD_NAME (unconnected_pad)); } else { gst_object_unref (pad); gst_object_unref (peer); @@ -3452,30 +3366,30 @@ gst_iterator_free (iter); - return unlinked_pad; + return unconnected_pad; } /** - * gst_bin_find_unlinked_pad: - * @bin: bin in which to look for elements with unlinked pads - * @direction: whether to look for an unlinked source or sink pad + * gst_bin_find_unconnected_pad: + * @bin: bin in which to look for elements with unconnected pads + * @direction: whether to look for an unconnected 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 + * Recursively looks for elements with an unconnected pad of the given + * direction within the specified bin and returns an unconnected 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. + * Returns: unconnected pad of the given direction, or NULL. * - * Since: 0.10.20 + * Since: 0.10.3 */ #ifdef __SYMBIAN32__ EXPORT_C #endif GstPad * -gst_bin_find_unlinked_pad (GstBin * bin, GstPadDirection direction) +gst_bin_find_unconnected_pad (GstBin * bin, GstPadDirection direction) { GstIterator *iter; gboolean done; @@ -3491,7 +3405,7 @@ switch (gst_iterator_next (iter, &element)) { case GST_ITERATOR_OK: - pad = element_find_unlinked_pad (GST_ELEMENT (element), direction); + pad = element_find_unconnected_pad (GST_ELEMENT (element), direction); gst_object_unref (element); if (pad != NULL) done = TRUE; @@ -3514,48 +3428,20 @@ } /** - * 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 __SYMBIAN32__ -EXPORT_C -#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 - * for unlinked source or sink pads within the bin + * @ghost_unconnected_pads: whether to automatically create ghost pads + * for unconnected source or sink pads within + * the bin * @err: where to store the error message in case of an error, or NULL * * This is a convenience wrapper around gst_parse_launch() to create a * #GstBin from a gst-launch-style pipeline description. See * gst_parse_launch() and the gst-launch man page for details about the - * syntax. Ghost pads on the bin for unlinked source or sink pads + * syntax. Ghost pads on the bin for unconnected source or sink pads * within the bin can automatically be created (but only a maximum of * one ghost pad for each direction will be created; if you expect - * multiple unlinked source pads or multiple unlinked sink pads + * multiple unconnected source pads or multiple unconnected sink pads * and want them all ghosted, you will have to create the ghost pads * yourself). * @@ -3569,43 +3455,7 @@ GstElement * gst_parse_bin_from_description (const gchar * bin_description, - gboolean ghost_unlinked_pads, GError ** err) -{ - return gst_parse_bin_from_description_full (bin_description, - ghost_unlinked_pads, NULL, 0, err); -} - -/** - * gst_parse_bin_from_description_full: - * @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 - * @flags: parsing options, or #GST_PARSE_FLAG_NONE - * @err: where to store the error message in case of an error, or NULL - * - * This is a convenience wrapper around gst_parse_launch() to create a - * #GstBin from a gst-launch-style pipeline description. See - * gst_parse_launch() and the gst-launch man page for details about the - * syntax. Ghost pads on the bin for unlinked source or sink pads - * within the bin can automatically be created (but only a maximum of - * one ghost pad for each direction will be created; if you expect - * multiple unlinked source pads or multiple unlinked sink 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. - * - * Since: 0.10.20 - */ -#ifdef __SYMBIAN32__ -EXPORT_C -#endif - -GstElement * -gst_parse_bin_from_description_full (const gchar * bin_description, - gboolean ghost_unlinked_pads, GstParseContext * context, - GstParseFlags flags, GError ** err) + gboolean ghost_unconnected_pads, GError ** err) { #ifndef GST_DISABLE_PARSE GstPad *pad = NULL; @@ -3619,7 +3469,7 @@ /* parse the pipeline to a bin */ desc = g_strdup_printf ("bin.( %s )", bin_description); - bin = (GstBin *) gst_parse_launch_full (desc, context, flags, err); + bin = (GstBin *) gst_parse_launch (desc, err); g_free (desc); if (bin == NULL || (err && *err != NULL)) { @@ -3629,12 +3479,12 @@ } /* find pads and ghost them if necessary */ - if (ghost_unlinked_pads) { - if ((pad = gst_bin_find_unlinked_pad (bin, GST_PAD_SRC))) { + if (ghost_unconnected_pads) { + if ((pad = gst_bin_find_unconnected_pad (bin, GST_PAD_SRC))) { gst_element_add_pad (GST_ELEMENT (bin), gst_ghost_pad_new ("src", pad)); gst_object_unref (pad); } - if ((pad = gst_bin_find_unlinked_pad (bin, GST_PAD_SINK))) { + if ((pad = gst_bin_find_unconnected_pad (bin, GST_PAD_SINK))) { gst_element_add_pad (GST_ELEMENT (bin), gst_ghost_pad_new ("sink", pad)); gst_object_unref (pad); } @@ -3644,7 +3494,7 @@ #else gchar *msg; - GST_WARNING ("Disabled API called"); + GST_WARNING ("Disabled API called: gst_parse_bin_from_description()"); msg = gst_error_get_message (GST_CORE_ERROR, GST_CORE_ERROR_DISABLED); g_set_error (err, GST_CORE_ERROR, GST_CORE_ERROR_DISABLED, "%s", msg); @@ -3757,95 +3607,3 @@ return GST_TIMEVAL_TO_TIME (now); #endif } - -/** - * gst_util_array_binary_search: - * @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 - * @mode: search mode that should be used - * @search_data: element that should be found - * @user_data: data to pass to @search_func - * - * Searches inside @array for @search_data by using the comparison function - * @search_func. @array must be sorted ascending. - * - * As @search_data is always passed as second argument to @search_func it's - * not required that @search_data has the same type as the array elements. - * - * The complexity of this search function is O(log (num_elements)). - * - * Returns: The address of the found element or %NULL if nothing was found - * - * Since: 0.10.23 - */ -#ifdef __SYMBIAN32__ -EXPORT_C -#endif - -gpointer -gst_util_array_binary_search (gpointer array, guint num_elements, - gsize element_size, GCompareDataFunc search_func, GstSearchMode mode, - gconstpointer search_data, gpointer user_data) -{ - glong left = 0, right = num_elements - 1, m; - gint ret; - guint8 *data = (guint8 *) array; - - g_return_val_if_fail (array != NULL, NULL); - g_return_val_if_fail (element_size > 0, NULL); - g_return_val_if_fail (search_func != NULL, NULL); - - /* 0. No elements => return NULL */ - if (num_elements == 0) - return NULL; - - /* 1. If search_data is before the 0th element return the 0th element */ - ret = search_func (data, search_data, user_data); - if ((ret >= 0 && mode == GST_SEARCH_MODE_AFTER) || ret == 0) - return data; - else if (ret > 0) - return NULL; - - /* 2. If search_data is after the last element return the last element */ - ret = - search_func (data + (num_elements - 1) * element_size, search_data, - user_data); - if ((ret <= 0 && mode == GST_SEARCH_MODE_BEFORE) || ret == 0) - return data + (num_elements - 1) * element_size; - else if (ret < 0) - return NULL; - - /* 3. else binary search */ - while (TRUE) { - m = left + (right - left) / 2; - - ret = search_func (data + m * element_size, search_data, user_data); - - if (ret == 0) { - return data + m * element_size; - } else if (ret < 0) { - left = m + 1; - } else { - right = m - 1; - } - - /* No exact match found */ - if (right < left) { - if (mode == GST_SEARCH_MODE_EXACT) { - return NULL; - } else if (mode == GST_SEARCH_MODE_AFTER) { - if (ret < 0) - return (m < num_elements) ? data + (m + 1) * element_size : NULL; - else - return data + m * element_size; - } else { - if (ret < 0) - return data + m * element_size; - else - return (m > 0) ? data + (m - 1) * element_size : NULL; - } - } - } -}