Merge branch 'master' into 0.11
authorSebastian Dröge <sebastian.droege@collabora.co.uk>
Mon, 16 May 2011 14:53:04 +0000 (16:53 +0200)
committerSebastian Dröge <sebastian.droege@collabora.co.uk>
Mon, 16 May 2011 14:53:04 +0000 (16:53 +0200)
Conflicts:
configure.ac
docs/gst/gstreamer-sections.txt
gst/gstbin.c
gst/gstelement.c
gst/gstelement.h
gst/gstghostpad.c
gst/gstminiobject.c
gst/gstminiobject.h
libs/gst/base/gstbasesrc.c
libs/gst/base/gstbasetransform.c
plugins/elements/gstinputselector.c
tests/check/gst/gstminiobject.c

19 files changed:
1  2 
configure.ac
docs/gst/gstreamer-sections.txt
docs/plugins/gstreamer-plugins.args
gst/gst_private.h
gst/gstbin.c
gst/gstelement.c
gst/gstelement.h
gst/gstghostpad.c
gst/gstghostpad.h
gst/gstminiobject.c
gst/gstminiobject.h
gst/gstsystemclock.c
libs/gst/base/gstbasesrc.c
plugins/elements/gstinputselector.c
plugins/elements/gstmultiqueue.c
plugins/elements/gstqueue2.c
tests/check/gst/gstghostpad.c
tests/check/gst/gstminiobject.c
win32/common/libgstreamer.def

diff --cc configure.ac
Simple merge
@@@ -938,9 -909,37 +940,36 @@@ gst_ghost_pad_ne
  gst_ghost_pad_new_no_target
  gst_ghost_pad_new_from_template
  gst_ghost_pad_new_no_target_from_template
  gst_ghost_pad_set_target
  gst_ghost_pad_get_target
  gst_ghost_pad_construct
 -gst_proxy_pad_bufferalloc_default
+ gst_ghost_pad_setcaps_default
+ gst_ghost_pad_unlink_default
+ gst_ghost_pad_link_default
+ gst_ghost_pad_activate_pull_default
+ gst_ghost_pad_activate_push_default
+ gst_ghost_pad_internal_activate_push_default
+ gst_ghost_pad_internal_activate_pull_default
+ gst_proxy_pad_get_internal
+ gst_proxy_pad_query_type_default
+ gst_proxy_pad_event_default
+ gst_proxy_pad_query_default
+ gst_proxy_pad_iterate_internal_links_default
+ gst_proxy_pad_chain_default
+ gst_proxy_pad_chain_list_default
+ gst_proxy_pad_getrange_default
+ gst_proxy_pad_checkgetrange_default
+ gst_proxy_pad_getcaps_default
+ gst_proxy_pad_acceptcaps_default
+ gst_proxy_pad_fixatecaps_default
+ gst_proxy_pad_setcaps_default
+ gst_proxy_pad_unlink_default
  <SUBSECTION Standard>
  GstGhostPadClass
  GST_GHOST_PAD
@@@ -1391,10 -1342,9 +1420,11 @@@ GST_MESSAGE_WAI
  GstMiniObject
  GstMiniObjectFlags
  GstMiniObjectCopyFunction
 -GstMiniObjectFinalizeFunction
 +GstMiniObjectDisposeFunction
 +GstMiniObjectFreeFunction
+ GstMiniObjectWeakNotify
  
 +GST_MINI_OBJECT_TYPE
  GST_MINI_OBJECT_FLAGS
  GST_MINI_OBJECT_FLAG_IS_SET
  GST_MINI_OBJECT_FLAG_SET
@@@ -1412,12 -1359,27 +1442,15 @@@ gst_mini_object_make_writabl
  
  gst_mini_object_ref
  gst_mini_object_unref
 -gst_mini_object_replace
  
 -GstParamSpecMiniObject
 -gst_param_spec_mini_object
 -
 -gst_value_set_mini_object
 -gst_value_take_mini_object
 -gst_value_get_mini_object
 -gst_value_dup_mini_object
+ gst_mini_object_weak_ref
+ gst_mini_object_weak_unref
 +gst_mini_object_replace
  
  <SUBSECTION Standard>
 -GstMiniObjectClass
  GST_MINI_OBJECT
 -GST_IS_MINI_OBJECT
 -GST_MINI_OBJECT_CLASS
 -GST_IS_MINI_OBJECT_CLASS
 -GST_MINI_OBJECT_GET_CLASS
 -GST_TYPE_MINI_OBJECT
 +GST_IS_MINI_OBJECT_TYPE
  GST_TYPE_MINI_OBJECT_FLAGS
  GST_MINI_OBJECT_CAST
  GST_MINI_OBJECT_CONST_CAST
@@@ -1540,11 -1521,11 +1573,6 @@@ gst_pad_ne
  gst_pad_new_from_template
  gst_pad_new_from_static_template
  
--gst_pad_alloc_buffer
--gst_pad_alloc_buffer_and_set_caps
--gst_pad_set_bufferalloc_function
--GstPadBufferAllocFunction
--
  gst_pad_set_chain_function
  GstPadChainFunction
  
Simple merge
@@@ -115,8 -116,12 +118,12 @@@ gboolean _gst_plugin_loader_client_run 
  
  void _priv_gst_pad_invalidate_cache (GstPad *pad);
  
+ /* Used in GstBin for manual state handling */
+ void _priv_gst_element_state_changed (GstElement *element, GstState oldstate,
+     GstState newstate, GstState pending);
  /* used in both gststructure.c and gstcaps.c; numbers are completely made up */
 -#define STRUCTURE_ESTIMATED_STRING_LEN(s) (16 + (s)->fields->len * 22)
 +#define STRUCTURE_ESTIMATED_STRING_LEN(s) (16 + gst_structure_n_fields(s) * 22)
  
  gboolean  priv_gst_structure_append_to_gstring (const GstStructure * structure,
                                                  GString            * s);
diff --cc gst/gstbin.c
@@@ -2237,8 -2250,11 +2248,7 @@@ activate_pads (const GValue * vpad, GVa
  
    if (!(cont = gst_pad_set_active (pad, *active)))
      g_value_set_boolean (ret, FALSE);
 -  else if (!*active)
 -    gst_pad_set_caps (pad, NULL);
  
--  /* unref the object that was reffed for us by _fold */
 -  gst_object_unref (pad);
    return cont;
  }
  
@@@ -2691,7 -2812,8 +2701,6 @@@ activate_pads (const GValue * vpad, GVa
    if (!(cont = gst_pad_set_active (pad, *active)))
      g_value_set_boolean (ret, FALSE);
  
--  /* unref the object that was reffed for us by _fold */
 -  gst_object_unref (pad);
    return cont;
  }
  
@@@ -636,6 -642,6 +637,8 @@@ struct _GstElementClas
                                                   GstState * pending, GstClockTime timeout);
    GstStateChangeReturn (*set_state)             (GstElement *element, GstState state);
    GstStateChangeReturn (*change_state)          (GstElement *element, GstStateChange transition);
++  void                 (*state_changed)         (GstElement *element, GstState oldstate,
++                                                 GstState newstate, GstState pending);
  
    /* bus */
    void                  (*set_bus)              (GstElement * element, GstBus * bus);
@@@ -110,12 -147,27 +139,27 @@@ gst_proxy_pad_event_default (GstPad * p
    return res;
  }
  
- static gboolean
- gst_proxy_pad_do_query (GstPad * pad, GstQuery ** query)
+ /**
+  * gst_proxy_pad_query_default:
+  * @pad: a #GstPad to invoke the default query on.
+  * @query: (transfer none): the #GstQuery to perform.
+  *
+  * Invoke the default query function of the proxy pad.
+  *
+  * Returns: TRUE if the query could be performed.
+  *
+  * Since: 0.10.35
+  */
+ gboolean
 -gst_proxy_pad_query_default (GstPad * pad, GstQuery * query)
++gst_proxy_pad_query_default (GstPad * pad, GstQuery ** query)
  {
    gboolean res = FALSE;
-   GstPad *target = gst_proxy_pad_get_target (pad);
+   GstPad *target;
+   g_return_val_if_fail (GST_IS_PROXY_PAD (pad), FALSE);
+   g_return_val_if_fail (GST_IS_QUERY (query), FALSE);
  
+   target = gst_proxy_pad_get_target (pad);
    if (target) {
      res = gst_pad_query (target, query);
      gst_object_unref (target);
    return res;
  }
  
- static GstIterator *
- gst_proxy_pad_do_iterate_internal_links (GstPad * pad)
+ /**
+  * gst_proyx_pad_iterate_internal_links_default:
+  * @pad: the #GstPad to get the internal links of.
+  *
+  * Invoke the default iterate internal links function of the proxy pad.
+  *
+  * Returns: a #GstIterator of #GstPad, or NULL if @pad has no parent. Unref each
+  * returned pad with gst_object_unref().
+  *
+  * Since: 0.10.35
+  */
+ GstIterator *
+ gst_proxy_pad_iterate_internal_links_default (GstPad * pad)
  {
    GstIterator *res = NULL;
-   GstPad *internal = GST_PROXY_PAD_INTERNAL (pad);
+   GstPad *internal;
+   g_return_val_if_fail (GST_IS_PROXY_PAD (pad), NULL);
+   internal =
+       GST_PAD_CAST (gst_proxy_pad_get_internal (GST_PROXY_PAD_CAST (pad)));
  
    if (internal) {
 -    res =
 -        gst_iterator_new_single (GST_TYPE_PAD, internal,
 -        (GstCopyFunction) gst_object_ref, (GFreeFunc) gst_object_unref);
 -    gst_object_unref (internal);
 -  }
 -
 -  return res;
 -}
 -
 -/**
 - * gst_proxy_pad_bufferalloc_default:
 - * @pad: a source #GstPad
 - * @offset: the offset of the new buffer in the stream
 - * @size: the size of the new buffer
 - * @caps: the caps of the new buffer
 - * @buf: a newly allocated buffer
 - *
 - * Invoke the default bufferalloc function of the proxy pad.
 - *
 - * Returns: a result code indicating success of the operation. Any
 - * result code other than #GST_FLOW_OK is an error and @buf should
 - * not be used.
 - * An error can occur if the pad is not connected or when the downstream
 - * peer elements cannot provide an acceptable buffer.
 - *
 - * Since: 0.10.35
 - */
 -GstFlowReturn
 -gst_proxy_pad_bufferalloc_default (GstPad * pad, guint64 offset, guint size,
 -    GstCaps * caps, GstBuffer ** buf)
 -{
 -  GstFlowReturn result = GST_FLOW_WRONG_STATE;
 -  GstPad *internal;
 -
 -  g_return_val_if_fail (GST_IS_PROXY_PAD (pad), GST_FLOW_ERROR);
 -  g_return_val_if_fail (caps == NULL || GST_IS_CAPS (caps), GST_FLOW_ERROR);
 -  g_return_val_if_fail (buf != NULL, GST_FLOW_ERROR);
 +    GValue v = { 0, };
  
 -  internal =
 -      GST_PAD_CAST (gst_proxy_pad_get_internal (GST_PROXY_PAD_CAST (pad)));
 -  if (internal) {
 -    result = gst_pad_alloc_buffer (internal, offset, size, caps, buf);
 +    g_value_init (&v, GST_TYPE_PAD);
 +    g_value_set_object (&v, internal);
 +    res = gst_iterator_new_single (GST_TYPE_PAD, &v);
 +    g_value_unset (&v);
+     gst_object_unref (internal);
    }
  
 -  return result;
 +  return res;
  }
  
- static GstFlowReturn
- gst_proxy_pad_do_chain (GstPad * pad, GstBuffer * buffer)
+ /**
+  * gst_proxy_pad_chain_default:
+  * @pad: a sink #GstPad, returns GST_FLOW_ERROR if not.
+  * @buffer: (transfer full): the #GstBuffer to send, return GST_FLOW_ERROR
+  *     if not.
+  *
+  * Invoke the default chain function of the proxy pad.
+  *
+  * Returns: a #GstFlowReturn from the pad.
+  *
+  * Since: 0.10.35
+  */
+ GstFlowReturn
+ gst_proxy_pad_chain_default (GstPad * pad, GstBuffer * buffer)
  {
    GstFlowReturn res;
-   GstPad *internal = GST_PROXY_PAD_INTERNAL (pad);
+   GstPad *internal;
+   g_return_val_if_fail (GST_IS_PROXY_PAD (pad), GST_FLOW_ERROR);
+   g_return_val_if_fail (GST_IS_BUFFER (buffer), GST_FLOW_ERROR);
  
+   internal = GST_PROXY_PAD_INTERNAL (pad);
    res = gst_pad_push (internal, buffer);
  
    return res;
@@@ -187,16 -355,30 +311,31 @@@ gst_proxy_pad_checkgetrange_default (Gs
    return result;
  }
  
static GstCaps *
- gst_proxy_pad_do_getcaps (GstPad * pad, GstCaps * filter)
/**
+  * gst_proxy_pad_getcaps_default:
 - * @pad: a  #GstPad to get the capabilities of.
++ * @pad: a #GstPad to get the capabilities of.
++ * @filter: a #GstCaps filter.
+  *
+  * Invoke the default getcaps function of the proxy pad.
+  *
+  * Returns: (transfer full): the caps of the pad with incremented ref-count
+  *
+  * Since: 0.10.35
+  */
+ GstCaps *
 -gst_proxy_pad_getcaps_default (GstPad * pad)
++gst_proxy_pad_getcaps_default (GstPad * pad, GstCaps * filter)
  {
-   GstPad *target = gst_proxy_pad_get_target (pad);
+   GstPad *target;
    GstCaps *res;
-   GstPadTemplate *templ = GST_PAD_PAD_TEMPLATE (pad);
+   GstPadTemplate *templ;
  
+   g_return_val_if_fail (GST_IS_PROXY_PAD (pad), NULL);
+   templ = GST_PAD_PAD_TEMPLATE (pad);
+   target = gst_proxy_pad_get_target (pad);
    if (target) {
      /* if we have a real target, proxy the call */
 -    res = gst_pad_get_caps_reffed (target);
 +    res = gst_pad_get_caps (target, filter);
  
      GST_DEBUG_OBJECT (pad, "get caps of target %s:%s : %" GST_PTR_FORMAT,
          GST_DEBUG_PAD_NAME (target), res);
@@@ -395,20 -636,31 +602,20 @@@ gst_proxy_pad_class_init (GstProxyPadCl
    gobject_class->dispose = gst_proxy_pad_dispose;
    gobject_class->finalize = gst_proxy_pad_finalize;
  
 -#if !defined(GST_DISABLE_LOADSAVE) && !defined(GST_REMOVE_DEPRECATED)
 -  {
 -    GstObjectClass *gstobject_class = (GstObjectClass *) klass;
 -
 -    gstobject_class->save_thyself =
 -        ((gpointer (*)(GstObject * object,
 -                gpointer self)) *
 -        GST_DEBUG_FUNCPTR (gst_proxy_pad_save_thyself));
 -  }
 -#endif
    /* Register common function pointer descriptions */
-   GST_DEBUG_REGISTER_FUNCPTR (gst_proxy_pad_do_query_type);
-   GST_DEBUG_REGISTER_FUNCPTR (gst_proxy_pad_do_event);
-   GST_DEBUG_REGISTER_FUNCPTR (gst_proxy_pad_do_query);
-   GST_DEBUG_REGISTER_FUNCPTR (gst_proxy_pad_do_iterate_internal_links);
-   GST_DEBUG_REGISTER_FUNCPTR (gst_proxy_pad_do_getcaps);
-   GST_DEBUG_REGISTER_FUNCPTR (gst_proxy_pad_do_acceptcaps);
-   GST_DEBUG_REGISTER_FUNCPTR (gst_proxy_pad_do_fixatecaps);
-   GST_DEBUG_REGISTER_FUNCPTR (gst_proxy_pad_do_setcaps);
-   GST_DEBUG_REGISTER_FUNCPTR (gst_proxy_pad_do_unlink);
-   GST_DEBUG_REGISTER_FUNCPTR (gst_proxy_pad_do_chain);
-   GST_DEBUG_REGISTER_FUNCPTR (gst_proxy_pad_do_chain_list);
-   GST_DEBUG_REGISTER_FUNCPTR (gst_proxy_pad_do_getrange);
-   GST_DEBUG_REGISTER_FUNCPTR (gst_proxy_pad_do_checkgetrange);
+   GST_DEBUG_REGISTER_FUNCPTR (gst_proxy_pad_query_type_default);
+   GST_DEBUG_REGISTER_FUNCPTR (gst_proxy_pad_event_default);
+   GST_DEBUG_REGISTER_FUNCPTR (gst_proxy_pad_query_default);
+   GST_DEBUG_REGISTER_FUNCPTR (gst_proxy_pad_iterate_internal_links_default);
+   GST_DEBUG_REGISTER_FUNCPTR (gst_proxy_pad_getcaps_default);
+   GST_DEBUG_REGISTER_FUNCPTR (gst_proxy_pad_acceptcaps_default);
+   GST_DEBUG_REGISTER_FUNCPTR (gst_proxy_pad_fixatecaps_default);
+   GST_DEBUG_REGISTER_FUNCPTR (gst_proxy_pad_setcaps_default);
+   GST_DEBUG_REGISTER_FUNCPTR (gst_proxy_pad_unlink_default);
 -  GST_DEBUG_REGISTER_FUNCPTR (gst_proxy_pad_bufferalloc_default);
+   GST_DEBUG_REGISTER_FUNCPTR (gst_proxy_pad_chain_default);
+   GST_DEBUG_REGISTER_FUNCPTR (gst_proxy_pad_chain_list_default);
+   GST_DEBUG_REGISTER_FUNCPTR (gst_proxy_pad_getrange_default);
+   GST_DEBUG_REGISTER_FUNCPTR (gst_proxy_pad_checkgetrange_default);
  }
  
  static void
@@@ -449,19 -701,73 +656,19 @@@ gst_proxy_pad_init (GstProxyPad * ppad
        GST_TYPE_PROXY_PAD, GstProxyPadPrivate);
    GST_PROXY_GET_LOCK (pad) = g_mutex_new ();
  
-   gst_pad_set_query_type_function (pad, gst_proxy_pad_do_query_type);
-   gst_pad_set_event_function (pad, gst_proxy_pad_do_event);
-   gst_pad_set_query_function (pad, gst_proxy_pad_do_query);
+   gst_pad_set_query_type_function (pad, gst_proxy_pad_query_type_default);
+   gst_pad_set_event_function (pad, gst_proxy_pad_event_default);
+   gst_pad_set_query_function (pad, gst_proxy_pad_query_default);
    gst_pad_set_iterate_internal_links_function (pad,
-       gst_proxy_pad_do_iterate_internal_links);
+       gst_proxy_pad_iterate_internal_links_default);
  
-   gst_pad_set_getcaps_function (pad, gst_proxy_pad_do_getcaps);
-   gst_pad_set_acceptcaps_function (pad, gst_proxy_pad_do_acceptcaps);
-   gst_pad_set_fixatecaps_function (pad, gst_proxy_pad_do_fixatecaps);
-   gst_pad_set_setcaps_function (pad, gst_proxy_pad_do_setcaps);
-   gst_pad_set_unlink_function (pad, gst_proxy_pad_do_unlink);
+   gst_pad_set_getcaps_function (pad, gst_proxy_pad_getcaps_default);
+   gst_pad_set_acceptcaps_function (pad, gst_proxy_pad_acceptcaps_default);
+   gst_pad_set_fixatecaps_function (pad, gst_proxy_pad_fixatecaps_default);
+   gst_pad_set_setcaps_function (pad, gst_proxy_pad_setcaps_default);
+   gst_pad_set_unlink_function (pad, gst_proxy_pad_unlink_default);
  }
  
 -#if !defined(GST_DISABLE_LOADSAVE) && !defined(GST_REMOVE_DEPRECATED)
 -/**
 - * gst_proxy_pad_save_thyself:
 - * @pad: a ghost #GstPad to save.
 - * @parent: the parent #xmlNodePtr to save the description in.
 - *
 - * Saves the ghost pad into an xml representation.
 - *
 - * Returns: the #xmlNodePtr representation of the pad.
 - */
 -static xmlNodePtr
 -gst_proxy_pad_save_thyself (GstObject * object, xmlNodePtr parent)
 -{
 -  xmlNodePtr self;
 -  GstProxyPad *proxypad;
 -  GstPad *pad;
 -  GstPad *peer;
 -
 -  g_return_val_if_fail (GST_IS_PROXY_PAD (object), NULL);
 -
 -  self = xmlNewChild (parent, NULL, (xmlChar *) "ghostpad", NULL);
 -  xmlNewChild (self, NULL, (xmlChar *) "name",
 -      (xmlChar *) GST_OBJECT_NAME (object));
 -  xmlNewChild (self, NULL, (xmlChar *) "parent",
 -      (xmlChar *) GST_OBJECT_NAME (GST_OBJECT_PARENT (object)));
 -
 -  proxypad = GST_PROXY_PAD_CAST (object);
 -  pad = GST_PAD_CAST (proxypad);
 -  peer = GST_PAD_CAST (pad->peer);
 -
 -  if (GST_IS_PAD (pad)) {
 -    if (GST_PAD_IS_SRC (pad))
 -      xmlNewChild (self, NULL, (xmlChar *) "direction", (xmlChar *) "source");
 -    else if (GST_PAD_IS_SINK (pad))
 -      xmlNewChild (self, NULL, (xmlChar *) "direction", (xmlChar *) "sink");
 -    else
 -      xmlNewChild (self, NULL, (xmlChar *) "direction", (xmlChar *) "unknown");
 -  } else {
 -    xmlNewChild (self, NULL, (xmlChar *) "direction", (xmlChar *) "unknown");
 -  }
 -  if (GST_IS_PAD (peer)) {
 -    gchar *content = g_strdup_printf ("%s.%s",
 -        GST_OBJECT_NAME (GST_PAD_PARENT (peer)), GST_PAD_NAME (peer));
 -
 -    xmlNewChild (self, NULL, (xmlChar *) "peer", (xmlChar *) content);
 -    g_free (content);
 -  } else {
 -    xmlNewChild (self, NULL, (xmlChar *) "peer", NULL);
 -  }
 -
 -  return self;
 -}
 -#endif /* GST_DISABLE_LOADSAVE */
 -
  
  /***********************************************************************
   * Ghost pads, implemented as a pair of proxy pads (sort of)
@@@ -859,11 -1231,13 +1138,12 @@@ gst_ghost_pad_construct (GstGhostPad * 
  
    /* Set directional padfunctions for ghostpad */
    if (dir == GST_PAD_SINK) {
-     gst_pad_set_chain_function (pad, gst_proxy_pad_do_chain);
-     gst_pad_set_chain_list_function (pad, gst_proxy_pad_do_chain_list);
 -    gst_pad_set_bufferalloc_function (pad, gst_proxy_pad_bufferalloc_default);
+     gst_pad_set_chain_function (pad, gst_proxy_pad_chain_default);
+     gst_pad_set_chain_list_function (pad, gst_proxy_pad_chain_list_default);
    } else {
-     gst_pad_set_getrange_function (pad, gst_proxy_pad_do_getrange);
-     gst_pad_set_checkgetrange_function (pad, gst_proxy_pad_do_checkgetrange);
+     gst_pad_set_getrange_function (pad, gst_proxy_pad_getrange_default);
+     gst_pad_set_checkgetrange_function (pad,
+         gst_proxy_pad_checkgetrange_default);
    }
  
    /* link/unlink functions */
  
    /* Set directional padfunctions for internal pad */
    if (dir == GST_PAD_SRC) {
-     gst_pad_set_chain_function (internal, gst_proxy_pad_do_chain);
-     gst_pad_set_chain_list_function (internal, gst_proxy_pad_do_chain_list);
 -    gst_pad_set_bufferalloc_function (internal,
 -        gst_proxy_pad_bufferalloc_default);
+     gst_pad_set_chain_function (internal, gst_proxy_pad_chain_default);
+     gst_pad_set_chain_list_function (internal,
+         gst_proxy_pad_chain_list_default);
    } else {
-     gst_pad_set_getrange_function (internal, gst_proxy_pad_do_getrange);
+     gst_pad_set_getrange_function (internal, gst_proxy_pad_getrange_default);
      gst_pad_set_checkgetrange_function (internal,
-         gst_proxy_pad_do_checkgetrange);
+         gst_proxy_pad_checkgetrange_default);
    }
  
    GST_PROXY_LOCK (pad);
@@@ -59,6 -59,23 +59,22 @@@ struct _GstProxyPadClas
  
  GType gst_proxy_pad_get_type (void);
  
 -gboolean            gst_proxy_pad_query_default                  (GstPad *pad, GstQuery *query);
+ GstProxyPad*     gst_proxy_pad_get_internal     (GstProxyPad *pad);
+ const GstQueryType* gst_proxy_pad_query_type_default             (GstPad *pad);
+ gboolean            gst_proxy_pad_event_default                  (GstPad *pad, GstEvent *event);
 -GstFlowReturn       gst_proxy_pad_bufferalloc_default            (GstPad *pad, guint64 offset, guint size, GstCaps *caps, GstBuffer **buf);
++gboolean            gst_proxy_pad_query_default                  (GstPad *pad, GstQuery **query);
+ GstIterator*        gst_proxy_pad_iterate_internal_links_default (GstPad *pad);
 -GstCaps*            gst_proxy_pad_getcaps_default                (GstPad *pad);
+ GstFlowReturn       gst_proxy_pad_chain_default                  (GstPad *pad, GstBuffer *buf);
+ GstFlowReturn       gst_proxy_pad_chain_list_default             (GstPad *pad, GstBufferList *list);
+ GstFlowReturn       gst_proxy_pad_getrange_default               (GstPad *pad, guint64 offset, guint size, GstBuffer **buffer);
+ gboolean            gst_proxy_pad_checkgetrange_default          (GstPad *pad);
++GstCaps*            gst_proxy_pad_getcaps_default                (GstPad *pad, GstCaps * filter);
+ gboolean            gst_proxy_pad_acceptcaps_default             (GstPad *pad, GstCaps *caps);
+ void                gst_proxy_pad_fixatecaps_default             (GstPad *pad, GstCaps *caps);
+ gboolean            gst_proxy_pad_setcaps_default                (GstPad *pad, GstCaps *caps);
+ void                gst_proxy_pad_unlink_default                 (GstPad * pad);
  
  #define GST_TYPE_GHOST_PAD            (gst_ghost_pad_get_type ())
  #define GST_IS_GHOST_PAD(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_GHOST_PAD))
  static GstAllocTrace *_gst_mini_object_trace;
  #endif
  
--#define GST_MINI_OBJECT_GET_CLASS_UNCHECKED(obj) \
--    ((GstMiniObjectClass *) (((GTypeInstance*)(obj))->g_class))
 -
 -/* Structure used for storing weak references */
 -typedef struct
 -{
 -  GstMiniObject *object;
 -  guint n_weak_refs;
 -  struct
 -  {
 -    GstMiniObjectWeakNotify notify;
 -    gpointer data;
 -  } weak_refs[1];               /* flexible array */
 -} WeakRefStack;
 -
 -/* Structure for storing a mini object's private data */
 -struct _GstMiniObjectPrivate
 -{
 -  WeakRefStack *wstack;
 -};
 -
 -#if 0
 -static void gst_mini_object_base_init (gpointer g_class);
 -static void gst_mini_object_base_finalize (gpointer g_class);
 -#endif
 -static void gst_mini_object_class_init (gpointer g_class, gpointer class_data);
 -static void gst_mini_object_init (GTypeInstance * instance, gpointer klass);
 -
 -static void gst_value_mini_object_init (GValue * value);
 -static void gst_value_mini_object_free (GValue * value);
 -static void weak_refs_notify (WeakRefStack * data);
 -static void gst_value_mini_object_copy (const GValue * src_value,
 -    GValue * dest_value);
 -static gpointer gst_value_mini_object_peek_pointer (const GValue * value);
 -static gchar *gst_value_mini_object_collect (GValue * value,
 -    guint n_collect_values, GTypeCValue * collect_values, guint collect_flags);
 -static gchar *gst_value_mini_object_lcopy (const GValue * value,
 -    guint n_collect_values, GTypeCValue * collect_values, guint collect_flags);
 -
 -static GstMiniObject *gst_mini_object_copy_default (const GstMiniObject * obj);
 -static void gst_mini_object_finalize (GstMiniObject * obj);
 -
+ /* Mutex used for weak referencing */
+ G_LOCK_DEFINE_STATIC (weak_refs_mutex);
  
 -GType
 -gst_mini_object_get_type (void)
 -{
 -  static volatile GType _gst_mini_object_type = 0;
 -
 -  if (g_once_init_enter (&_gst_mini_object_type)) {
 -    GType _type;
 -    static const GTypeValueTable value_table = {
 -      gst_value_mini_object_init,
 -      gst_value_mini_object_free,
 -      gst_value_mini_object_copy,
 -      gst_value_mini_object_peek_pointer,
 -      (char *) "p",
 -      gst_value_mini_object_collect,
 -      (char *) "p",
 -      gst_value_mini_object_lcopy
 -    };
 -    static const GTypeInfo mini_object_info = {
 -      sizeof (GstMiniObjectClass),
 -#if 0
 -      gst_mini_object_base_init,
 -      gst_mini_object_base_finalize,
 -#else
 -      NULL, NULL,
 -#endif
 -      gst_mini_object_class_init,
 -      NULL,
 -      NULL,
 -      sizeof (GstMiniObject),
 -      0,
 -      (GInstanceInitFunc) gst_mini_object_init,
 -      &value_table
 -    };
 -    static const GTypeFundamentalInfo mini_object_fundamental_info = {
 -      (G_TYPE_FLAG_CLASSED | G_TYPE_FLAG_INSTANTIATABLE |
 -          G_TYPE_FLAG_DERIVABLE | G_TYPE_FLAG_DEEP_DERIVABLE)
 -    };
 -
 -    _type = g_type_fundamental_next ();
 -    g_type_register_fundamental (_type, "GstMiniObject",
 -        &mini_object_info, &mini_object_fundamental_info, G_TYPE_FLAG_ABSTRACT);
 -
 -#ifndef GST_DISABLE_TRACE
 -    _gst_mini_object_trace = gst_alloc_trace_register (g_type_name (_type));
 -#endif
 -    g_once_init_leave (&_gst_mini_object_type, _type);
 -  }
 -
 -  return _gst_mini_object_type;
 -}
 -
 -#if 0
 -static void
 -gst_mini_object_base_init (gpointer g_class)
 -{
 -  /* do nothing */
 -}
 -
 -static void
 -gst_mini_object_base_finalize (gpointer g_class)
 +/* boxed copy and free functions. Don't real copy or free but simply
 + * change the refcount */
 +static GstMiniObject *
 +_gst_mini_object_boxed_copy (GstMiniObject * mini_object)
  {
 -  /* do nothing */
 +  if (mini_object)
 +    return gst_mini_object_ref (mini_object);
 +  else
 +    return NULL;
  }
 -#endif
  
  static void
 -gst_mini_object_class_init (gpointer g_class, gpointer class_data)
 +_gst_mini_object_boxed_free (GstMiniObject * mini_object)
  {
 -  GstMiniObjectClass *mo_class = GST_MINI_OBJECT_CLASS (g_class);
 -
 -  mo_class->copy = gst_mini_object_copy_default;
 -  mo_class->finalize = gst_mini_object_finalize;
 -
 -  /* Set the instance data type */
 -  g_type_class_add_private (g_class, sizeof (GstMiniObjectPrivate));
 +  if (mini_object)
 +    gst_mini_object_unref (mini_object);
  }
  
 -static void
 -gst_mini_object_init (GTypeInstance * instance, gpointer klass)
 +/**
 + * gst_mini_object_register:
 + * @name: name of the new boxed type
 + *
 + * This function creates a new G_TYPE_BOXED derived type id for a new boxed type
 + * with name @name. The default miniobject refcounting copy and free function
 + * are used for the boxed type.
 + *
 + * Returns: a new G_TYPE_BOXED derived type id for @name.
 + */
 +GType
 +gst_mini_object_register (const gchar * name)
  {
 -  GstMiniObject *mini_object = GST_MINI_OBJECT_CAST (instance);
 +  GType type;
  
 -  mini_object->refcount = 1;
 +  g_return_val_if_fail (name != NULL, 0);
  
 -  /* Initialize the mini object's private data */
 +  type = g_boxed_type_register_static (name,
 +      (GBoxedCopyFunc) _gst_mini_object_boxed_copy,
 +      (GBoxedFreeFunc) _gst_mini_object_boxed_free);
  
 -  mini_object->priv = (GstMiniObjectPrivate *)
 -      G_TYPE_INSTANCE_GET_PRIVATE (instance, GST_TYPE_MINI_OBJECT,
 -      GstMiniObjectPrivate);
 -
 -  mini_object->priv->wstack = NULL;
 -}
 -
 -static GstMiniObject *
 -gst_mini_object_copy_default (const GstMiniObject * obj)
 -{
 -  g_warning ("GstMiniObject classes must implement GstMiniObject::copy");
 -  return NULL;
 -}
 -
 -static void
 -gst_mini_object_finalize (GstMiniObject * obj)
 -{
 -  /* do nothing */
 -
 -  /* WARNING: if anything is ever put in this method, make sure that the
 -   * following sub-classes' finalize method chains up to this one:
 -   * gstbuffer
 -   * gstevent
 -   * gstmessage
 -   * gstquery
 -   */
 +  return type;
  }
  
  /**
   *
   * Returns: (transfer full): the new mini-object.
   */
 -GstMiniObject *
 -gst_mini_object_new (GType type)
 +void
 +gst_mini_object_init (GstMiniObject * mini_object, GType type, gsize size)
  {
 -  GstMiniObject *mini_object;
 -
 -  /* we don't support dynamic types because they really aren't useful,
 -   * and could cause refcount problems */
 -  mini_object = (GstMiniObject *) g_type_create_instance (type);
 -
 -#ifndef GST_DISABLE_TRACE
 -  gst_alloc_trace_new (_gst_mini_object_trace, mini_object);
 -#endif
 -
 -  return mini_object;
 +  mini_object->type = type;
 +  mini_object->refcount = 1;
 +  mini_object->flags = 0;
 +  mini_object->size = size;
++  mini_object->n_weak_refs = 0;
++  mini_object->weak_refs = NULL;
  }
  
 -/* FIXME 0.11: Current way of doing the copy makes it impossible
 - * to currectly chain to the parent classes and do a copy in a
 - * subclass without knowing all internals of the parent classes.
 - *
 - * For 0.11 we should do something like the following:
 - *  - The GstMiniObjectClass::copy() implementation of GstMiniObject
 - *    should call g_type_create_instance() with the type of the source
 - *    object.
 - *  - All GstMiniObjectClass::copy() implementations should as first
 - *    thing chain up to the parent class and then do whatever they need
 - *    to do to copy their type specific data. Note that this way the
 - *    instance_init() functions are called!
 - */
 -
  /**
   * gst_mini_object_copy:
   * @mini_object: the mini-object to copy
@@@ -223,79 -353,446 +225,185 @@@ gst_mini_object_ref (GstMiniObject * mi
    return mini_object;
  }
  
 -weak_refs_notify (WeakRefStack * wstack)
+ static void
 -  for (i = 0; i < wstack->n_weak_refs; i++)
 -    wstack->weak_refs[i].notify (wstack->weak_refs[i].data, wstack->object);
 -  g_free (wstack);
++weak_refs_notify (GstMiniObject * obj)
+ {
+   guint i;
 -static void
 -gst_mini_object_free (GstMiniObject * mini_object)
++  for (i = 0; i < obj->n_weak_refs; i++)
++    obj->weak_refs[i].notify (obj->weak_refs[i].data, obj);
++  g_free (obj->weak_refs);
+ }
 +/**
 + * gst_mini_object_unref:
 + * @mini_object: the mini-object
 + *
 + * Decreases the reference count of the mini-object, possibly freeing
 + * the mini-object.
 + */
 +void
 +gst_mini_object_unref (GstMiniObject * mini_object)
  {
 -  GstMiniObjectClass *mo_class;
 +  g_return_if_fail (mini_object != NULL);
 +  g_return_if_fail (mini_object->refcount > 0);
  
 -  /* At this point, the refcount of the object is 0. We increase the refcount
 -   * here because if a subclass recycles the object and gives out a new
 -   * reference we don't want to free the instance anymore. */
 -  GST_CAT_TRACE (GST_CAT_REFCOUNTING, "%p ref %d->%d", mini_object,
 +  GST_CAT_TRACE (GST_CAT_REFCOUNTING, "%p unref %d->%d",
 +      mini_object,
        GST_MINI_OBJECT_REFCOUNT_VALUE (mini_object),
 -      GST_MINI_OBJECT_REFCOUNT_VALUE (mini_object) + 1);
 +      GST_MINI_OBJECT_REFCOUNT_VALUE (mini_object) - 1);
  
 -  g_atomic_int_inc (&mini_object->refcount);
 +  if (G_UNLIKELY (g_atomic_int_dec_and_test (&mini_object->refcount))) {
 +    /* At this point, the refcount of the object is 0. We increase the refcount
 +     * here because if a subclass recycles the object and gives out a new
 +     * reference we don't want to free the instance anymore. */
 +    gst_mini_object_ref (mini_object);
  
 -  mo_class = GST_MINI_OBJECT_GET_CLASS_UNCHECKED (mini_object);
 -  mo_class->finalize (mini_object);
 +    if (mini_object->dispose)
 +      mini_object->dispose (mini_object);
  
 -  /* decrement the refcount again, if the subclass recycled the object we don't
 -   * want to free the instance anymore */
 -  if (G_LIKELY (g_atomic_int_dec_and_test (&mini_object->refcount))) {
 -    /* The weak reference stack is freed in the notification function */
 -    if (mini_object->priv->wstack)
 -      weak_refs_notify (mini_object->priv->wstack);
 +    /* decrement the refcount again, if the subclass recycled the object we don't
 +     * want to free the instance anymore */
 +    if (G_LIKELY (g_atomic_int_dec_and_test (&mini_object->refcount))) {
++      /* The weak reference stack is freed in the notification function */
++      if (mini_object->n_weak_refs)
++        weak_refs_notify (mini_object);
  #ifndef GST_DISABLE_TRACE
 -    gst_alloc_trace_free (_gst_mini_object_trace, mini_object);
 +      gst_alloc_trace_free (_gst_mini_object_trace, mini_object);
  #endif
 -    g_type_free_instance ((GTypeInstance *) mini_object);
 +      if (mini_object->free)
 +        mini_object->free (mini_object);
 +    }
    }
  }
  
  /**
 - * gst_mini_object_unref:
 - * @mini_object: the mini-object
 + * gst_mini_object_replace:
 + * @olddata: (inout) (transfer full): pointer to a pointer to a mini-object to
 + *     be replaced
 + * @newdata: pointer to new mini-object
   *
 - * Decreases the reference count of the mini-object, possibly freeing
 - * the mini-object.
 + * Modifies a pointer to point to a new mini-object.  The modification
 + * is done atomically, and the reference counts are updated correctly.
 + * Either @newdata and the value pointed to by @olddata may be NULL.
   */
  void
 -gst_mini_object_unref (GstMiniObject * mini_object)
 +gst_mini_object_replace (GstMiniObject ** olddata, GstMiniObject * newdata)
  {
 -  g_return_if_fail (GST_IS_MINI_OBJECT (mini_object));
 -  g_return_if_fail (mini_object->refcount > 0);
 +  GstMiniObject *olddata_val;
  
 -  GST_CAT_TRACE (GST_CAT_REFCOUNTING, "%p unref %d->%d",
 -      mini_object,
 -      GST_MINI_OBJECT_REFCOUNT_VALUE (mini_object),
 -      GST_MINI_OBJECT_REFCOUNT_VALUE (mini_object) - 1);
 +  g_return_if_fail (olddata != NULL);
  
 -  if (G_UNLIKELY (g_atomic_int_dec_and_test (&mini_object->refcount))) {
 -    gst_mini_object_free (mini_object);
 +  GST_CAT_TRACE (GST_CAT_REFCOUNTING, "replace %p (%d) with %p (%d)",
 +      *olddata, *olddata ? (*olddata)->refcount : 0,
 +      newdata, newdata ? newdata->refcount : 0);
 +
 +  olddata_val = g_atomic_pointer_get ((gpointer *) olddata);
 +
 +  if (olddata_val == newdata)
 +    return;
 +
 +  if (newdata)
 +    gst_mini_object_ref (newdata);
 +
 +  while (!g_atomic_pointer_compare_and_exchange ((gpointer *) olddata,
 +          olddata_val, newdata)) {
 +    olddata_val = g_atomic_pointer_get ((gpointer *) olddata);
    }
 +
 +  if (olddata_val)
 +    gst_mini_object_unref (olddata_val);
  }
 -  g_return_if_fail (GST_IS_MINI_OBJECT (object));
+ /**
+  * gst_mini_object_weak_ref: (skip)
+  * @mini_object: #GstMiniObject to reference weakly
+  * @notify: callback to invoke before the mini object is freed
+  * @data: extra data to pass to notify
+  *
+  * Adds a weak reference callback to a mini object. Weak references are
+  * used for notification when a mini object is finalized. They are called
+  * "weak references" because they allow you to safely hold a pointer
+  * to the mini object without calling gst_mini_object_ref()
+  * (gst_mini_object_ref() adds a strong reference, that is, forces the object
+  * to stay alive).
+  *
+  * Since: 0.10.35
+  */
+ void
+ gst_mini_object_weak_ref (GstMiniObject * object,
+     GstMiniObjectWeakNotify notify, gpointer data)
+ {
+   guint i;
 -  if (object->priv->wstack) {
++  g_return_if_fail (object != NULL);
+   g_return_if_fail (notify != NULL);
+   g_return_if_fail (GST_MINI_OBJECT_REFCOUNT_VALUE (object) >= 1);
+   G_LOCK (weak_refs_mutex);
 -    for (i = 0; i < object->priv->wstack->n_weak_refs; i++) {
 -      if (object->priv->wstack->weak_refs[i].notify == notify &&
 -          object->priv->wstack->weak_refs[i].data == data) {
++  if (object->n_weak_refs) {
+     /* Don't add the weak reference if it already exists. */
 -    i = object->priv->wstack->n_weak_refs++;
 -    object->priv->wstack =
 -        g_realloc (object->priv->wstack, sizeof (*(object->priv->wstack)) +
 -        sizeof (object->priv->wstack->weak_refs[0]) * i);
++    for (i = 0; i < object->n_weak_refs; i++) {
++      if (object->weak_refs[i].notify == notify &&
++          object->weak_refs[i].data == data) {
+         g_warning ("%s: Attempt to re-add existing weak ref %p(%p) failed.",
+             G_STRFUNC, notify, data);
+         goto found;
+       }
+     }
 -    object->priv->wstack = g_renew (WeakRefStack, NULL, 1);
 -    object->priv->wstack->object = object;
 -    object->priv->wstack->n_weak_refs = 1;
++    i = object->n_weak_refs++;
++    object->weak_refs =
++        g_realloc (object->weak_refs, sizeof (object->weak_refs[0]) * i);
+   } else {
 -  object->priv->wstack->weak_refs[i].notify = notify;
 -  object->priv->wstack->weak_refs[i].data = data;
++    object->weak_refs = g_malloc0 (sizeof (object->weak_refs[0]));
++    object->n_weak_refs = 1;
+     i = 0;
+   }
 -  g_return_if_fail (GST_IS_MINI_OBJECT (object));
++  object->weak_refs[i].notify = notify;
++  object->weak_refs[i].data = data;
+ found:
+   G_UNLOCK (weak_refs_mutex);
+ }
+ /**
+  * gst_mini_object_weak_unref: (skip)
+  * @mini_object: #GstMiniObject to remove a weak reference from
+  * @notify: callback to search for
+  * @data: data to search for
+  *
+  * Removes a weak reference callback to a mini object.
+  *
+  * Since: 0.10.35
+  */
+ void
+ gst_mini_object_weak_unref (GstMiniObject * object,
+     GstMiniObjectWeakNotify notify, gpointer data)
+ {
+   gboolean found_one = FALSE;
 -  if (object->priv->wstack) {
++  g_return_if_fail (object != NULL);
+   g_return_if_fail (notify != NULL);
+   G_LOCK (weak_refs_mutex);
 -    for (i = 0; i < object->priv->wstack->n_weak_refs; i++)
 -      if (object->priv->wstack->weak_refs[i].notify == notify &&
 -          object->priv->wstack->weak_refs[i].data == data) {
++  if (object->n_weak_refs) {
+     guint i;
 -        object->priv->wstack->n_weak_refs -= 1;
 -        if (i != object->priv->wstack->n_weak_refs)
 -          object->priv->wstack->weak_refs[i] =
 -              object->priv->wstack->weak_refs[object->priv->wstack->
 -              n_weak_refs];
++    for (i = 0; i < object->n_weak_refs; i++)
++      if (object->weak_refs[i].notify == notify &&
++          object->weak_refs[i].data == data) {
+         found_one = TRUE;
 -
 -/**
 - * gst_mini_object_replace:
 - * @olddata: (inout) (transfer full): pointer to a pointer to a mini-object to
 - *     be replaced
 - * @newdata: pointer to new mini-object
 - *
 - * Modifies a pointer to point to a new mini-object.  The modification
 - * is done atomically, and the reference counts are updated correctly.
 - * Either @newdata and the value pointed to by @olddata may be NULL.
 - */
 -void
 -gst_mini_object_replace (GstMiniObject ** olddata, GstMiniObject * newdata)
 -{
 -  GstMiniObject *olddata_val;
 -
 -  g_return_if_fail (olddata != NULL);
 -
 -  GST_CAT_TRACE (GST_CAT_REFCOUNTING, "replace %p (%d) with %p (%d)",
 -      *olddata, *olddata ? (*olddata)->refcount : 0,
 -      newdata, newdata ? newdata->refcount : 0);
 -
 -  olddata_val = g_atomic_pointer_get ((gpointer *) olddata);
 -
 -  if (olddata_val == newdata)
 -    return;
 -
 -  if (newdata)
 -    gst_mini_object_ref (newdata);
 -
 -  while (!g_atomic_pointer_compare_and_exchange ((gpointer *) olddata,
 -          olddata_val, newdata)) {
 -    olddata_val = g_atomic_pointer_get ((gpointer *) olddata);
 -  }
 -
 -  if (olddata_val)
 -    gst_mini_object_unref (olddata_val);
 -}
 -
 -static void
 -gst_value_mini_object_init (GValue * value)
 -{
 -  value->data[0].v_pointer = NULL;
 -}
 -
 -static void
 -gst_value_mini_object_free (GValue * value)
 -{
 -  if (value->data[0].v_pointer) {
 -    gst_mini_object_unref (GST_MINI_OBJECT_CAST (value->data[0].v_pointer));
 -  }
 -}
 -
 -static void
 -gst_value_mini_object_copy (const GValue * src_value, GValue * dest_value)
 -{
 -  if (src_value->data[0].v_pointer) {
 -    dest_value->data[0].v_pointer =
 -        gst_mini_object_ref (GST_MINI_OBJECT_CAST (src_value->data[0].
 -            v_pointer));
 -  } else {
 -    dest_value->data[0].v_pointer = NULL;
 -  }
 -}
 -
 -static gpointer
 -gst_value_mini_object_peek_pointer (const GValue * value)
 -{
 -  return value->data[0].v_pointer;
 -}
 -
 -static gchar *
 -gst_value_mini_object_collect (GValue * value, guint n_collect_values,
 -    GTypeCValue * collect_values, guint collect_flags)
 -{
 -  if (collect_values[0].v_pointer) {
 -    value->data[0].v_pointer =
 -        gst_mini_object_ref (collect_values[0].v_pointer);
 -  } else {
 -    value->data[0].v_pointer = NULL;
 -  }
 -
 -  return NULL;
 -}
 -
 -static gchar *
 -gst_value_mini_object_lcopy (const GValue * value, guint n_collect_values,
 -    GTypeCValue * collect_values, guint collect_flags)
 -{
 -  gpointer *mini_object_p = collect_values[0].v_pointer;
 -
 -  if (!mini_object_p) {
 -    return g_strdup_printf ("value location for '%s' passed as NULL",
 -        G_VALUE_TYPE_NAME (value));
 -  }
 -
 -  if (!value->data[0].v_pointer)
 -    *mini_object_p = NULL;
 -  else if (collect_flags & G_VALUE_NOCOPY_CONTENTS)
 -    *mini_object_p = value->data[0].v_pointer;
 -  else
 -    *mini_object_p = gst_mini_object_ref (value->data[0].v_pointer);
 -
 -  return NULL;
 -}
 -
 -/**
 - * gst_value_set_mini_object:
 - * @value: a valid #GValue of %GST_TYPE_MINI_OBJECT derived type
 - * @mini_object: (transfer none): mini object value to set
 - *
 - * Set the contents of a %GST_TYPE_MINI_OBJECT derived #GValue to
 - * @mini_object.
 - * The caller retains ownership of the reference.
 - */
 -void
 -gst_value_set_mini_object (GValue * value, GstMiniObject * mini_object)
 -{
 -  gpointer *pointer_p;
 -
 -  g_return_if_fail (GST_VALUE_HOLDS_MINI_OBJECT (value));
 -  g_return_if_fail (mini_object == NULL || GST_IS_MINI_OBJECT (mini_object));
 -
 -  pointer_p = &value->data[0].v_pointer;
 -  gst_mini_object_replace ((GstMiniObject **) pointer_p, mini_object);
 -}
 -
 -/**
 - * gst_value_take_mini_object:
 - * @value: a valid #GValue of %GST_TYPE_MINI_OBJECT derived type
 - * @mini_object: (transfer full): mini object value to take
 - *
 - * Set the contents of a %GST_TYPE_MINI_OBJECT derived #GValue to
 - * @mini_object.
 - * Takes over the ownership of the caller's reference to @mini_object;
 - * the caller doesn't have to unref it any more.
 - */
 -void
 -gst_value_take_mini_object (GValue * value, GstMiniObject * mini_object)
 -{
 -  gpointer *pointer_p;
 -
 -  g_return_if_fail (GST_VALUE_HOLDS_MINI_OBJECT (value));
 -  g_return_if_fail (mini_object == NULL || GST_IS_MINI_OBJECT (mini_object));
 -
 -  pointer_p = &value->data[0].v_pointer;
 -  /* takes additional refcount */
 -  gst_mini_object_replace ((GstMiniObject **) pointer_p, mini_object);
 -  /* remove additional refcount */
 -  if (mini_object)
 -    gst_mini_object_unref (mini_object);
 -}
 -
 -/**
 - * gst_value_get_mini_object:
 - * @value:   a valid #GValue of %GST_TYPE_MINI_OBJECT derived type
 - *
 - * Get the contents of a %GST_TYPE_MINI_OBJECT derived #GValue.
 - * Does not increase the refcount of the returned object.
 - *
 - * Returns: (transfer none): mini object contents of @value
 - */
 -GstMiniObject *
 -gst_value_get_mini_object (const GValue * value)
 -{
 -  g_return_val_if_fail (GST_VALUE_HOLDS_MINI_OBJECT (value), NULL);
 -
 -  return value->data[0].v_pointer;
 -}
 -
 -/**
 - * gst_value_dup_mini_object:
 - * @value:   a valid #GValue of %GST_TYPE_MINI_OBJECT derived type
 - *
 - * Get the contents of a %GST_TYPE_MINI_OBJECT derived #GValue,
 - * increasing its reference count. If the contents of the #GValue
 - * are %NULL, %NULL will be returned.
 - *
 - * Returns: (transfer full): mini object contents of @value
 - *
 - * Since: 0.10.20
 - */
 -GstMiniObject *
 -gst_value_dup_mini_object (const GValue * value)
 -{
 -  g_return_val_if_fail (GST_VALUE_HOLDS_MINI_OBJECT (value), NULL);
 -
 -  return value->data[0].v_pointer ? gst_mini_object_ref (value->
 -      data[0].v_pointer) : NULL;
 -}
 -
 -
 -/* param spec */
 -
 -static void
 -param_mini_object_init (GParamSpec * pspec)
 -{
 -  /* GParamSpecMiniObject *ospec = G_PARAM_SPEC_MINI_OBJECT (pspec); */
 -}
 -
 -static void
 -param_mini_object_set_default (GParamSpec * pspec, GValue * value)
 -{
 -  value->data[0].v_pointer = NULL;
 -}
 -
 -static gboolean
 -param_mini_object_validate (GParamSpec * pspec, GValue * value)
 -{
 -  GstMiniObject *mini_object = value->data[0].v_pointer;
 -  gboolean changed = FALSE;
 -
 -  if (mini_object
 -      && !g_value_type_compatible (G_OBJECT_TYPE (mini_object),
 -          pspec->value_type)) {
 -    gst_mini_object_unref (mini_object);
 -    value->data[0].v_pointer = NULL;
 -    changed = TRUE;
 -  }
 -
 -  return changed;
 -}
 -
 -static gint
 -param_mini_object_values_cmp (GParamSpec * pspec,
 -    const GValue * value1, const GValue * value2)
 -{
 -  guint8 *p1 = value1->data[0].v_pointer;
 -  guint8 *p2 = value2->data[0].v_pointer;
 -
 -  /* not much to compare here, try to at least provide stable lesser/greater result */
 -
 -  return p1 < p2 ? -1 : p1 > p2;
 -}
 -
 -GType
 -gst_param_spec_mini_object_get_type (void)
 -{
 -  static GType type;
 -
 -  if (G_UNLIKELY (type) == 0) {
 -    static const GParamSpecTypeInfo pspec_info = {
 -      sizeof (GstParamSpecMiniObject),  /* instance_size */
 -      16,                       /* n_preallocs */
 -      param_mini_object_init,   /* instance_init */
 -      G_TYPE_OBJECT,            /* value_type */
 -      NULL,                     /* finalize */
 -      param_mini_object_set_default,    /* value_set_default */
 -      param_mini_object_validate,       /* value_validate */
 -      param_mini_object_values_cmp,     /* values_cmp */
 -    };
 -    /* FIXME 0.11: Should really be GstParamSpecMiniObject */
 -    type = g_param_type_register_static ("GParamSpecMiniObject", &pspec_info);
 -  }
 -
 -  return type;
 -}
 -
 -/**
 - * gst_param_spec_mini_object:
 - * @name: the canonical name of the property
 - * @nick: the nickname of the property
 - * @blurb: a short description of the property
 - * @object_type: the #GstMiniObject #GType for the property
 - * @flags: a combination of #GParamFlags
 - *
 - * Creates a new #GParamSpec instance that hold #GstMiniObject references.
 - *
 - * Returns: (transfer full): a newly allocated #GParamSpec instance
 - */
 -GParamSpec *
 -gst_param_spec_mini_object (const char *name, const char *nick,
 -    const char *blurb, GType object_type, GParamFlags flags)
 -{
 -  GstParamSpecMiniObject *ospec;
 -
 -  g_return_val_if_fail (g_type_is_a (object_type, GST_TYPE_MINI_OBJECT), NULL);
 -
 -  ospec = g_param_spec_internal (GST_TYPE_PARAM_MINI_OBJECT,
 -      name, nick, blurb, flags);
 -  G_PARAM_SPEC (ospec)->value_type = object_type;
 -
 -  return G_PARAM_SPEC (ospec);
 -}
++        object->n_weak_refs -= 1;
++        if (i != object->n_weak_refs)
++          object->weak_refs[i] = object->weak_refs[object->n_weak_refs];
+         break;
+       }
+   }
+   G_UNLOCK (weak_refs_mutex);
+   if (!found_one)
+     g_warning ("%s: couldn't find weak ref %p(%p)", G_STRFUNC, notify, data);
+ }
@@@ -46,32 -51,17 +46,48 @@@ typedef struct _GstMiniObject GstMiniOb
   */
  typedef GstMiniObject * (*GstMiniObjectCopyFunction) (const GstMiniObject *obj);
  /**
 - * GstMiniObjectFinalizeFunction:
 - * @obj: MiniObject to finalize
 + * GstMiniObjectDisposeFunction:
 + * @obj: MiniObject to dispose
   *
 - * Virtual function prototype for methods to free ressources used by
 - * mini-objects. Subclasses of the mini object are allowed to revive the
 + * Function prototype for when a miniobject has lost its last refcount.
 + * Implementation of the mini object are allowed to revive the
   * passed object by doing a gst_mini_object_ref(). If the object is not
 - * revived after the finalize function, the memory associated with the
 + * revived after the dispose function, the memory associated with the
   * object is freed.
   */
 -typedef void (*GstMiniObjectFinalizeFunction) (GstMiniObject *obj);
 +typedef void (*GstMiniObjectDisposeFunction) (GstMiniObject *obj);
 +/**
 + * GstMiniObjectFreeFunction:
 + * @obj: MiniObject to free
 + *
 + * Virtual function prototype for methods to free ressources used by
 + * mini-objects.
 + */
 +typedef void (*GstMiniObjectFreeFunction) (GstMiniObject *obj);
  
++ /**
++ * GstMiniObjectWeakNotify:
++ * @data: data that was provided when the weak reference was established
++ * @where_the_mini_object_was: the mini object being finalized
++ * 
++ * A #GstMiniObjectWeakNotify function can be added to a mini object as a
++ * callback that gets triggered when the mini object is finalized. Since the
++ * mini object is already being finalized when the #GstMiniObjectWeakNotify is
++ * called, there's not much you could do with the object, apart from e.g. using
++ * its adress as hash-index or the like.
++ *
++ * Since: 0.10.35
++ */
++typedef void (*GstMiniObjectWeakNotify) (gpointer data,
++    GstMiniObject * where_the_mini_object_was);
++
 +/**
 + * GST_MINI_OBJECT_FLAGS:
 + * @obj: MiniObject to return flags for.
 + *
 + * This macro returns the entire set of flags for the mini-object.
 + */
 +#define GST_MINI_OBJECT_TYPE(obj)  (GST_MINI_OBJECT_CAST(obj)->type)
  /**
   * GST_MINI_OBJECT_FLAGS:
   * @obj: MiniObject to return flags for.
@@@ -151,36 -163,83 +167,52 @@@ typedef enu
   * Base class for refcounted lightweight objects.
   * Ref Func: gst_mini_object_ref
   * Unref Func: gst_mini_object_unref
 - * Set Value Func: gst_value_set_mini_object
 - * Get Value Func: gst_value_get_mini_object
 + * Set Value Func: g_value_set_boxed
 + * Get Value Func: g_value_get_boxed
   */
  struct _GstMiniObject {
 -  GTypeInstance instance;
 -  /*< public >*/ /* with COW */
 -  gint refcount;
 -  guint flags;
 -
 -  /*< private >*/
 -  GstMiniObjectPrivate *priv;
 -};
 +  GType   type;
  
 -struct _GstMiniObjectClass {
 -  GTypeClass type_class;
 +  /*< public >*/ /* with COW */
 +  gint    refcount;
 +  guint   flags;
 +  gsize   size;
  
    GstMiniObjectCopyFunction copy;
 -  GstMiniObjectFinalizeFunction finalize;
 -
 -  /*< private >*/
 -  gpointer _gst_reserved;
 +  GstMiniObjectDisposeFunction dispose;
 +  GstMiniObjectFreeFunction free;
++
++  /* < private > */
++  /* Used to keep track of weak ref notifies */
++  guint n_weak_refs;
++  struct
++  {
++    GstMiniObjectWeakNotify notify;
++    gpointer data;
++  } *weak_refs;
  };
  
 -GType                 gst_mini_object_get_type        (void);
 +GType           gst_mini_object_register        (const gchar *name);
 +
 +void            gst_mini_object_init            (GstMiniObject *mini_object,
 +                                                 GType type, gsize size);
  
 -GstMiniObject*        gst_mini_object_new             (GType type);
 -GstMiniObject*        gst_mini_object_copy            (const GstMiniObject *mini_object);
 -gboolean      gst_mini_object_is_writable     (const GstMiniObject *mini_object);
 -GstMiniObject*  gst_mini_object_make_writable         (GstMiniObject *mini_object);
 +GstMiniObject*        gst_mini_object_copy            (const GstMiniObject *mini_object);
 +gboolean      gst_mini_object_is_writable     (const GstMiniObject *mini_object);
 +GstMiniObject*  gst_mini_object_make_writable (GstMiniObject *mini_object);
  
  /* refcounting */
 -GstMiniObject*        gst_mini_object_ref             (GstMiniObject *mini_object);
 -void          gst_mini_object_unref           (GstMiniObject *mini_object);
 +GstMiniObject*        gst_mini_object_ref             (GstMiniObject *mini_object);
 +void          gst_mini_object_unref           (GstMiniObject *mini_object);
 +
+ void          gst_mini_object_weak_ref        (GstMiniObject *object,
+                                                GstMiniObjectWeakNotify notify,
+                                                gpointer data);
+ void          gst_mini_object_weak_unref      (GstMiniObject *object,
+                                                GstMiniObjectWeakNotify notify,
+                                                gpointer data);
 -void          gst_mini_object_replace         (GstMiniObject **olddata, GstMiniObject *newdata);
 -
 -/* GParamSpec */
 -
 -#define       GST_TYPE_PARAM_MINI_OBJECT              (gst_param_spec_mini_object_get_type())
 -#define GST_IS_PARAM_SPEC_MINI_OBJECT(pspec)    (G_TYPE_CHECK_INSTANCE_TYPE ((pspec), \
 -                                                 GST_TYPE_PARAM_MINI_OBJECT))
 -#define GST_PARAM_SPEC_MINI_OBJECT(pspec)       (G_TYPE_CHECK_INSTANCE_CAST ((pspec), \
 -                                                 GST_TYPE_PARAM_MINI_OBJECT, \
 -                                               GstParamSpecMiniObject))
 -
 -typedef struct _GstParamSpecMiniObject GstParamSpecMiniObject;
 -
 -/**
 - * GstParamSpecMiniObject:
 - * @parent_instance: private %GParamSpec portion
 - * 
 - * A %GParamSpec derived structure that contains the meta data
 - * for %GstMiniObject properties.
 - */
 -struct _GstParamSpecMiniObject
 -{
 -  GParamSpec parent_instance;
 -};
 -
 -
 -GType gst_param_spec_mini_object_get_type (void);
 -
 -GParamSpec*   gst_param_spec_mini_object      (const char *name, const char *nick,
 -                                               const char *blurb, GType object_type, 
 -                                               GParamFlags flags);
 -
 -/* GValue stuff */
 -void          gst_value_set_mini_object       (GValue *value, GstMiniObject *mini_object);
 -void          gst_value_take_mini_object      (GValue *value, GstMiniObject *mini_object);
 -GstMiniObject*        gst_value_get_mini_object       (const GValue *value);
 -GstMiniObject*  gst_value_dup_mini_object       (const GValue *value);
 +void          gst_mini_object_replace         (GstMiniObject **olddata, GstMiniObject *newdata);
  
  
  G_END_DECLS
Simple merge
@@@ -2112,8 -2160,8 +2112,8 @@@ again
  
    /* no timestamp set and we are at offset 0, we can timestamp with 0 */
    if (offset == 0 && src->segment.time == 0
-       && GST_BUFFER_TIMESTAMP (*buf) == -1) {
+       && GST_BUFFER_TIMESTAMP (*buf) == -1 && !src->is_live) {
 -    *buf = gst_buffer_make_metadata_writable (*buf);
 +    *buf = gst_buffer_make_writable (*buf);
      GST_BUFFER_TIMESTAMP (*buf) = 0;
    }
  
@@@ -520,6 -627,105 +523,105 @@@ gst_input_selector_wait (GstInputSelect
    return self->flushing;
  }
  
 -        active_seg->last_stop);
+ /* must be called with the SELECTOR_LOCK, will block until the running time
+  * of the active pad is after this pad or return TRUE when flushing */
+ static gboolean
+ gst_input_selector_wait_running_time (GstInputSelector * sel,
+     GstSelectorPad * pad, GstBuffer * buf)
+ {
+   GstPad *active_sinkpad;
+   GstSelectorPad *active_selpad;
+   GstSegment *seg, *active_seg;
+   GstClockTime running_time, active_running_time = -1;
+   seg = &pad->segment;
+   active_sinkpad =
+       gst_input_selector_activate_sinkpad (sel, GST_PAD_CAST (pad));
+   active_selpad = GST_SELECTOR_PAD_CAST (active_sinkpad);
+   active_seg = &active_selpad->segment;
+   /* We can only sync if the segments are in time format or
+    * if the active pad had no newsegment event yet */
+   if (seg->format != GST_FORMAT_TIME ||
+       (active_seg->format != GST_FORMAT_TIME
+           && active_seg->format != GST_FORMAT_UNDEFINED))
+     return FALSE;
+   /* If we have no valid timestamp we can't sync this buffer */
+   if (!GST_BUFFER_TIMESTAMP_IS_VALID (buf))
+     return FALSE;
+   running_time = GST_BUFFER_TIMESTAMP (buf);
+   /* If possible try to get the running time at the end of the buffer */
+   if (GST_BUFFER_DURATION_IS_VALID (buf))
+     running_time += GST_BUFFER_DURATION (buf);
+   if (running_time > seg->stop)
+     running_time = seg->stop;
+   running_time =
+       gst_segment_to_running_time (seg, GST_FORMAT_TIME, running_time);
+   /* If this is outside the segment don't sync */
+   if (running_time == -1)
+     return FALSE;
+   /* Get active pad's running time, if no configured segment yet keep at -1 */
+   if (active_seg->format == GST_FORMAT_TIME)
+     active_running_time =
+         gst_segment_to_running_time (active_seg, GST_FORMAT_TIME,
 -          active_seg->last_stop);
++        active_seg->position);
+   /* Wait until
+    *   a) this is the active pad
+    *   b) the pad or the selector is flushing
+    *   c) the selector is not blocked
+    *   d) the active pad has no running time or the active
+    *      pad's running time is before this running time
+    *   e) the active pad has a non-time segment
+    */
+   while (pad != active_selpad && !sel->flushing && !pad->flushing &&
+       (sel->blocked || active_running_time == -1
+           || running_time >= active_running_time)) {
+     if (!sel->blocked)
+       GST_DEBUG_OBJECT (pad,
+           "Waiting for active streams to advance. %" GST_TIME_FORMAT " >= %"
+           GST_TIME_FORMAT, GST_TIME_ARGS (running_time),
+           GST_TIME_ARGS (active_running_time));
+     GST_INPUT_SELECTOR_WAIT (sel);
+     /* Get new active pad, it might have changed */
+     active_sinkpad =
+         gst_input_selector_activate_sinkpad (sel, GST_PAD_CAST (pad));
+     active_selpad = GST_SELECTOR_PAD_CAST (active_sinkpad);
+     active_seg = &active_selpad->segment;
+     /* If the active segment is configured but not to time format
+      * we can't do any syncing at all */
+     if (active_seg->format != GST_FORMAT_TIME
+         && active_seg->format != GST_FORMAT_UNDEFINED)
+       break;
+     /* Get the new active pad running time */
+     if (active_seg->format == GST_FORMAT_TIME)
+       active_running_time =
+           gst_segment_to_running_time (active_seg, GST_FORMAT_TIME,
++          active_seg->position);
+     else
+       active_running_time = -1;
+     if (!sel->blocked)
+       GST_DEBUG_OBJECT (pad,
+           "Waited for active streams to advance. %" GST_TIME_FORMAT " >= %"
+           GST_TIME_FORMAT, GST_TIME_ARGS (running_time),
+           GST_TIME_ARGS (active_running_time));
+   }
+   /* Return TRUE if the selector or the pad is flushing */
+   return (sel->flushing || pad->flushing);
+ }
  static GstFlowReturn
  gst_selector_pad_chain (GstPad * pad, GstBuffer * buf)
  {
    if (pad != active_sinkpad)
      goto ignore;
  
 -  if (G_UNLIKELY (sel->pending_close)) {
 -    GstSegment *cseg = &sel->segment;
 -
 -    GST_DEBUG_OBJECT (sel,
 -        "pushing close NEWSEGMENT update %d, rate %lf, applied rate %lf, "
 -        "format %d, "
 -        "%" G_GINT64_FORMAT " -- %" G_GINT64_FORMAT ", time %"
 -        G_GINT64_FORMAT, TRUE, cseg->rate, cseg->applied_rate, cseg->format,
 -        cseg->start, cseg->stop, cseg->time);
 -
 -    /* create update segment */
 -    close_event = gst_event_new_new_segment_full (TRUE, cseg->rate,
 -        cseg->applied_rate, cseg->format, cseg->start, cseg->stop, cseg->time);
 -
 -    sel->pending_close = FALSE;
 -  }
+   /* Tell all non-active pads that we advanced the running time */
+   if (sel->sync_streams)
+     GST_INPUT_SELECTOR_BROADCAST (sel);
    /* if we have a pending segment, push it out now */
    if (G_UNLIKELY (selpad->segment_pending)) {
      GST_DEBUG_OBJECT (pad,
@@@ -932,6 -983,71 +969,63 @@@ apply_buffer (GstMultiQueue * mq, GstSi
    GST_MULTI_QUEUE_MUTEX_UNLOCK (mq);
  }
  
 -    GstBufferListIterator *it = gst_buffer_list_iterate (list);
+ static GstClockTime
+ get_running_time (GstSegment * segment, GstMiniObject * object, gboolean end)
+ {
+   GstClockTime time = GST_CLOCK_TIME_NONE;
+   if (GST_IS_BUFFER (object)) {
+     GstBuffer *buf = GST_BUFFER_CAST (object);
+     if (GST_BUFFER_TIMESTAMP_IS_VALID (buf)) {
+       time = GST_BUFFER_TIMESTAMP (buf);
+       if (end && GST_BUFFER_DURATION_IS_VALID (buf))
+         time += GST_BUFFER_DURATION (buf);
+       if (time > segment->stop)
+         time = segment->stop;
+       time = gst_segment_to_running_time (segment, GST_FORMAT_TIME, time);
+     }
+   } else if (GST_IS_BUFFER_LIST (object)) {
+     GstBufferList *list = GST_BUFFER_LIST_CAST (object);
 -    do {
 -      while ((buf = gst_buffer_list_iterator_next (it))) {
 -        if (GST_BUFFER_TIMESTAMP_IS_VALID (buf)) {
 -          time = GST_BUFFER_TIMESTAMP (buf);
 -          if (end && GST_BUFFER_DURATION_IS_VALID (buf))
 -            time += GST_BUFFER_DURATION (buf);
 -          if (time > segment->stop)
 -            time = segment->stop;
 -          time = gst_segment_to_running_time (segment, GST_FORMAT_TIME, time);
 -          if (!end)
 -            goto done;
 -        } else if (!end) {
++    gint i, n;
+     GstBuffer *buf;
 -        }
++    n = gst_buffer_list_len (list);
++    for (i = 0; i < n; i++) {
++      buf = gst_buffer_list_get (list, i);
++      if (GST_BUFFER_TIMESTAMP_IS_VALID (buf)) {
++        time = GST_BUFFER_TIMESTAMP (buf);
++        if (end && GST_BUFFER_DURATION_IS_VALID (buf))
++          time += GST_BUFFER_DURATION (buf);
++        if (time > segment->stop)
++          time = segment->stop;
++        time = gst_segment_to_running_time (segment, GST_FORMAT_TIME, time);
++        if (!end)
+           goto done;
 -    } while (gst_buffer_list_iterator_next_group (it));
++      } else if (!end) {
++        goto done;
+       }
 -    if (GST_EVENT_TYPE (event) == GST_EVENT_NEWSEGMENT) {
++    }
+   } else if (GST_IS_EVENT (object)) {
+     GstEvent *event = GST_EVENT_CAST (object);
+     /* For newsegment events return the running time of the start position */
 -      gboolean update;
 -      gdouble rate, applied_rate;
 -      GstFormat format;
 -      gint64 start, stop, position;
 -
 -      gst_event_parse_new_segment_full (event, &update, &rate, &applied_rate,
 -          &format, &start, &stop, &position);
 -      if (format == GST_FORMAT_TIME) {
 -        gst_segment_set_newsegment_full (&new_segment, update, rate,
 -            applied_rate, format, start, stop, position);
++    if (GST_EVENT_TYPE (event) == GST_EVENT_SEGMENT) {
+       GstSegment new_segment = *segment;
++      gst_event_parse_segment (event, &new_segment);
++      if (new_segment.format == GST_FORMAT_TIME) {
+         time =
+             gst_segment_to_running_time (&new_segment, GST_FORMAT_TIME,
+             new_segment.start);
+       }
+     }
+   }
+ done:
+   return time;
+ }
  static GstFlowReturn
  gst_single_queue_push_one (GstMultiQueue * mq, GstSingleQueue * sq,
      GstMiniObject * object)
Simple merge
Simple merge
@@@ -168,7 -175,33 +168,34 @@@ GST_START_TEST (test_unref_threaded
  
  GST_END_TEST;
  
+ /* ======== weak ref test ======== */
+ static gboolean weak_ref_notify_succeeded = FALSE;
+ static void
+ on_weak_ref_notify (gpointer data, GstMiniObject * where_object_was)
+ {
+   weak_ref_notify_succeeded = TRUE;
+ }
+ GST_START_TEST (test_weak_ref)
+ {
+   GstBuffer *buffer;
+   buffer = gst_buffer_new_and_alloc (4);
+   gst_mini_object_weak_ref (GST_MINI_OBJECT (buffer), on_weak_ref_notify,
+       &buffer);
+   gst_buffer_unref (buffer);
+   fail_unless (weak_ref_notify_succeeded,
+       "No weak reference notification took place.");
+ }
+ GST_END_TEST;
 +#if 0
  /* ======== recycle test ======== */
  
  static gint recycle_buffer_count = 10;
@@@ -434,7 -506,8 +461,8 @@@ gst_mini_object_suite (void
    tcase_add_test (tc_chain, test_make_writable);
    tcase_add_test (tc_chain, test_ref_threaded);
    tcase_add_test (tc_chain, test_unref_threaded);
 -  tcase_add_test (tc_chain, test_recycle_threaded);
+   tcase_add_test (tc_chain, test_weak_ref);
 +  //tcase_add_test (tc_chain, test_recycle_threaded);
    tcase_add_test (tc_chain, test_value_collection);
    tcase_add_test (tc_chain, test_dup_null_mini_object);
    return s;
@@@ -601,18 -599,17 +608,20 @@@ EXPORT
        gst_message_type_get_name
        gst_message_type_get_type
        gst_message_type_to_quark
 +      gst_meta_get_info
 +      gst_meta_register
 +      gst_meta_timing_get_info
        gst_mini_object_copy
        gst_mini_object_flags_get_type
 -      gst_mini_object_get_type
 +      gst_mini_object_init
        gst_mini_object_is_writable
        gst_mini_object_make_writable
 -      gst_mini_object_new
        gst_mini_object_ref
 +      gst_mini_object_register
        gst_mini_object_replace
        gst_mini_object_unref
+       gst_mini_object_weak_ref
+       gst_mini_object_weak_unref
        gst_object_check_uniqueness
        gst_object_default_deep_notify
        gst_object_default_error
        gst_print_element_args
        gst_print_pad_caps
        gst_progress_type_get_type
+       gst_proxy_pad_acceptcaps_default
+       gst_proxy_pad_bufferalloc_default
+       gst_proxy_pad_chain_default
+       gst_proxy_pad_chain_list_default
+       gst_proxy_pad_checkgetrange_default
+       gst_proxy_pad_event_default
+       gst_proxy_pad_fixatecaps_default
+       gst_proxy_pad_get_internal
        gst_proxy_pad_get_type
+       gst_proxy_pad_getcaps_default
+       gst_proxy_pad_getrange_default
+       gst_proxy_pad_iterate_internal_links_default
+       gst_proxy_pad_query_default
+       gst_proxy_pad_query_type_default
+       gst_proxy_pad_setcaps_default
+       gst_proxy_pad_unlink_default
        gst_qos_type_get_type
 +      gst_query_add_allocation_meta
        gst_query_add_buffering_range
 +      gst_query_get_n_allocation_meta
        gst_query_get_n_buffering_ranges
        gst_query_get_structure
        gst_query_get_type