Merge branch 'master' into 0.11
authorWim Taymans <wim.taymans@collabora.co.uk>
Mon, 13 Jun 2011 17:10:00 +0000 (19:10 +0200)
committerWim Taymans <wim.taymans@collabora.co.uk>
Mon, 13 Jun 2011 17:10:00 +0000 (19:10 +0200)
315 files changed:
Android.mk
Makefile.am
configure.ac
docs/design/Makefile.am
docs/design/draft-buffer2.txt [deleted file]
docs/design/draft-bufferpool.txt [deleted file]
docs/design/part-TODO.txt
docs/design/part-block.txt
docs/design/part-buffer.txt [new file with mode: 0644]
docs/design/part-bufferlist.txt [deleted file]
docs/design/part-bufferpool.txt [new file with mode: 0644]
docs/design/part-caps.txt
docs/design/part-element-transform.txt
docs/design/part-events.txt
docs/design/part-gstelement.txt
docs/design/part-gstobject.txt
docs/design/part-latency.txt
docs/design/part-memory.txt [new file with mode: 0644]
docs/design/part-messages.txt
docs/design/part-meta.txt [new file with mode: 0644]
docs/design/part-negotiation.txt
docs/design/part-overview.txt
docs/design/part-probes.txt [new file with mode: 0644]
docs/design/part-scheduling.txt
docs/design/part-seeking.txt
docs/design/part-segments.txt
docs/design/part-sparsestreams.txt
docs/design/part-streams.txt
docs/design/part-synchronisation.txt
docs/design/part-trickmodes.txt
docs/faq/using.xml
docs/gst/gstreamer-docs.sgml
docs/gst/gstreamer-sections.txt
docs/gst/gstreamer.types.in
docs/libs/gstreamer-libs-sections.txt
docs/manual/advanced-autoplugging.xml
docs/manual/advanced-dataaccess.xml
docs/manual/highlevel-components.xml
docs/plugins/gstreamer-plugins.args
docs/plugins/gstreamer-plugins.hierarchy
docs/random/plan-0.11.txt [new file with mode: 0644]
docs/random/porting-to-0.11.txt [new file with mode: 0644]
docs/random/use-cases-0.11.txt [new file with mode: 0644]
gst/Makefile.am
gst/gst.c
gst/gst.h
gst/gst_private.h
gst/gstbin.c
gst/gstbin.h
gst/gstbuffer.c
gst/gstbuffer.h
gst/gstbufferlist.c
gst/gstbufferlist.h
gst/gstbufferpool.c [new file with mode: 0644]
gst/gstbufferpool.h [new file with mode: 0644]
gst/gstbus.c
gst/gstbus.h
gst/gstcaps.c
gst/gstcaps.h
gst/gstclock.c
gst/gstclock.h
gst/gstcompat.h
gst/gstconfig.h.in
gst/gstdebugutils.c
gst/gstelement.c
gst/gstelement.h
gst/gstelementdetails.h [deleted file]
gst/gstelementfactory.c
gst/gstelementfactory.h
gst/gstelementmetadata.h [new file with mode: 0644]
gst/gstevent.c
gst/gstevent.h
gst/gstformat.c
gst/gstghostpad.c
gst/gstghostpad.h
gst/gstindex.h
gst/gstindexfactory.c
gst/gstinfo.c
gst/gstiterator.c
gst/gstiterator.h
gst/gstmarshal.list
gst/gstmemory.c [new file with mode: 0644]
gst/gstmemory.h [new file with mode: 0644]
gst/gstmessage.c
gst/gstmessage.h
gst/gstmeta.c [new file with mode: 0644]
gst/gstmeta.h [new file with mode: 0644]
gst/gstminiobject.c
gst/gstminiobject.h
gst/gstobject.c
gst/gstobject.h
gst/gstpad.c
gst/gstpad.h
gst/gstpadtemplate.c
gst/gstpadtemplate.h
gst/gstparse.c
gst/gstpipeline.c
gst/gstpipeline.h
gst/gstplugin.c
gst/gstplugin.h
gst/gstpluginfeature.c
gst/gstpluginfeature.h
gst/gstpreset.c
gst/gstquark.c
gst/gstquark.h
gst/gstquery.c
gst/gstquery.h
gst/gstregistry.c
gst/gstregistry.h
gst/gstregistrybinary.c
gst/gstregistrychunks.c
gst/gstsegment.c
gst/gstsegment.h
gst/gststructure.c
gst/gststructure.h
gst/gstsystemclock.c
gst/gstsystemclock.h
gst/gsttaglist.c
gst/gsttagsetter.c
gst/gsttask.c
gst/gsttask.h
gst/gsttypefind.c
gst/gsttypefind.h
gst/gstutils.c
gst/gstutils.h
gst/gstvalue.c
gst/gstvalue.h
gst/gstxml.c [deleted file]
gst/gstxml.h [deleted file]
gst/parse/Makefile.am
gstreamer.spec.in
libs/gst/base/Makefile.am
libs/gst/base/gstadapter.c
libs/gst/base/gstadapter.h
libs/gst/base/gstbaseparse.c
libs/gst/base/gstbasesink.c
libs/gst/base/gstbasesink.h
libs/gst/base/gstbasesrc.c
libs/gst/base/gstbasesrc.h
libs/gst/base/gstbasetransform.c
libs/gst/base/gstbasetransform.h
libs/gst/base/gstbitreader.c
libs/gst/base/gstbitreader.h
libs/gst/base/gstbytereader.c
libs/gst/base/gstbytereader.h
libs/gst/base/gstbytewriter.c
libs/gst/base/gstbytewriter.h
libs/gst/base/gstcollectpads.c
libs/gst/base/gstcollectpads.h
libs/gst/base/gstdataqueue.c
libs/gst/base/gstdataqueue.h
libs/gst/base/gstpushsrc.c
libs/gst/base/gstpushsrc.h
libs/gst/base/gsttypefindhelper.c
libs/gst/base/gsttypefindhelper.h
libs/gst/check/Makefile.am
libs/gst/check/gstbufferstraw.c
libs/gst/check/gstcheck.c
libs/gst/check/gstcheck.h
libs/gst/check/gstconsistencychecker.c
libs/gst/controller/Makefile.am
libs/gst/controller/gstcontroller.c
libs/gst/controller/gstcontroller.h
libs/gst/dataprotocol/Makefile.am
libs/gst/dataprotocol/dataprotocol.c
libs/gst/dataprotocol/dataprotocol.h
libs/gst/net/Makefile.am
libs/gst/net/gstnetclientclock.c
libs/gst/net/gstnettimeprovider.c
pkgconfig/gstreamer-uninstalled.pc.in
pkgconfig/gstreamer.pc.in
plugins/elements/gstcapsfilter.c
plugins/elements/gstfakesink.c
plugins/elements/gstfakesrc.c
plugins/elements/gstfdsink.c
plugins/elements/gstfdsrc.c
plugins/elements/gstfilesink.c
plugins/elements/gstfilesrc.c
plugins/elements/gstfilesrc.h
plugins/elements/gstfunnel.c
plugins/elements/gstidentity.c
plugins/elements/gstinputselector.c
plugins/elements/gstinputselector.h
plugins/elements/gstmultiqueue.c
plugins/elements/gstoutputselector.c
plugins/elements/gstqueue.c
plugins/elements/gstqueue2.c
plugins/elements/gsttee.c
plugins/elements/gsttypefindelement.c
plugins/elements/gsttypefindelement.h
plugins/elements/gstvalve.c
plugins/indexers/Makefile.am
plugins/indexers/gstindexers.c
plugins/indexers/gstindexers.h
po/af.po
po/az.po
po/be.po
po/bg.po
po/ca.po
po/cs.po
po/da.po
po/de.po
po/el.po
po/en_GB.po
po/es.po
po/eu.po
po/fi.po
po/fr.po
po/gl.po
po/hu.po
po/id.po
po/it.po
po/ja.po
po/lt.po
po/nb.po
po/nl.po
po/pl.po
po/pt_BR.po
po/ro.po
po/ru.po
po/rw.po
po/sk.po
po/sl.po
po/sq.po
po/sr.po
po/sv.po
po/tr.po
po/uk.po
po/vi.po
po/zh_CN.po
po/zh_TW.po
tests/check/Makefile.am
tests/check/elements/fakesink.c
tests/check/elements/fakesrc.c
tests/check/elements/filesink.c
tests/check/elements/filesrc.c
tests/check/elements/funnel.c
tests/check/elements/identity.c
tests/check/elements/multiqueue.c
tests/check/elements/queue.c
tests/check/elements/selector.c
tests/check/elements/tee.c
tests/check/elements/valve.c
tests/check/generic/sinks.c
tests/check/gst/.gitignore
tests/check/gst/gstbin.c
tests/check/gst/gstbuffer.c
tests/check/gst/gstbufferlist.c
tests/check/gst/gstcaps.c
tests/check/gst/gstelement.c
tests/check/gst/gstelementfactory.c
tests/check/gst/gstevent.c
tests/check/gst/gstghostpad.c
tests/check/gst/gstinfo.c
tests/check/gst/gstiterator.c
tests/check/gst/gstmeta.c [new file with mode: 0644]
tests/check/gst/gstminiobject.c
tests/check/gst/gstobject.c
tests/check/gst/gstpad.c
tests/check/gst/gstparamspecs.c
tests/check/gst/gstpipeline.c
tests/check/gst/gstplugin.c
tests/check/gst/gstpreset.c
tests/check/gst/gstquery.c
tests/check/gst/gstsegment.c
tests/check/gst/gststructure.c
tests/check/gst/gsttag.c
tests/check/gst/gsttagsetter.c
tests/check/gst/gstutils.c
tests/check/gst/gstvalue.c
tests/check/gst/gstxml.c [deleted file]
tests/check/gst/struct_arm.h
tests/check/gst/struct_hppa.h
tests/check/gst/struct_i386.h
tests/check/gst/struct_ppc32.h
tests/check/gst/struct_ppc64.h
tests/check/gst/struct_sparc.h
tests/check/gst/struct_x86_64.h
tests/check/libs/adapter.c
tests/check/libs/basesrc.c
tests/check/libs/bitreader.c
tests/check/libs/bytereader.c
tests/check/libs/gdp.c
tests/check/libs/test_transform.c
tests/check/libs/transform1.c
tests/check/libs/typefindhelper.c
tests/check/pipelines/parse-launch.c
tests/check/pipelines/queue-error.c
tests/examples/adapter/adapter_test.c
tests/examples/manual/Makefile.am
tools/.gitignore
tools/BUGS [deleted file]
tools/Makefile.am
tools/README [deleted file]
tools/gst-feedback-m.m [deleted file]
tools/gst-feedback.1.in [deleted file]
tools/gst-inspect.c
tools/gst-launch.1.in
tools/gst-launch.c
tools/gst-run.c [deleted file]
tools/gst-xmlinspect.1.in [deleted file]
tools/gst-xmlinspect.c [deleted file]
tools/gst-xmllaunch.1.in [deleted file]
tools/gstreamer-completion
tools/xml2text.xsl [deleted file]
win32/common/config.h
win32/common/gstenumtypes.c
win32/common/gstenumtypes.h
win32/common/gstmarshal.c
win32/common/gstmarshal.h
win32/common/gstversion.h
win32/common/libgstbase.def
win32/common/libgstcontroller.def
win32/common/libgstdataprotocol.def
win32/common/libgstreamer.def

index 853b4b0..d9868ca 100644 (file)
@@ -53,7 +53,7 @@ gst-configure-real:
        PKG_CONFIG_LIBDIR=$(CONFIGURE_PKG_CONFIG_LIBDIR) \
        PKG_CONFIG_TOP_BUILD_DIR=/ \
        $(abspath $(gstreamer_TOP))/$(CONFIGURE) --host=arm-linux-androideabi \
-       --prefix=/system --disable-nls --disable-loadsave \
+       --prefix=/system --disable-nls \
        --disable-valgrind --disable-gtk-doc && \
        for file in $(GST_BUILT_SOURCES); do \
                rm -f $$file && \
index 383dfc7..f6ddc4a 100644 (file)
@@ -142,13 +142,11 @@ include $(top_srcdir)/common/coverage/lcov.mak
 
 # Do not run the check-exports test in case any option which causes the API to
 # change has been used
-if !GST_DISABLE_LOADSAVE
 if !GST_DISABLE_REGISTRY
 if !GST_DISABLE_TRACE
 CHECK_EXPORTS = check-exports
 endif
 endif
-endif
 
 check: $(CHECK_EXPORTS) check-enum-gettypes
 
index d216f2e..cf94327 100644 (file)
@@ -3,7 +3,7 @@ AC_PREREQ(2.60)
 dnl initialize autoconf
 dnl when going to/from release please set the nano (fourth number) right !
 dnl releases only do Wall, git and prerelease does Werror too
-AC_INIT(GStreamer, 0.10.34.1,
+AC_INIT(GStreamer, 0.11.0.1,
     http://bugzilla.gnome.org/enter_bug.cgi?product=GStreamer,
     gstreamer)
 AG_GST_INIT
@@ -37,7 +37,7 @@ m4_ifdef([AM_SILENT_RULES],[AM_SILENT_RULES([yes])],
 dnl our libraries and install dirs use major.minor as a version
 GST_MAJORMINOR=$PACKAGE_VERSION_MAJOR.$PACKAGE_VERSION_MINOR
 dnl we override it here for release candidates for a new series
-GST_MAJORMINOR=0.10
+GST_MAJORMINOR=0.11
 AC_SUBST(GST_MAJORMINOR)
 AC_DEFINE_UNQUOTED(GST_MAJORMINOR, "$GST_MAJORMINOR",
   [library major.minor version])
@@ -78,16 +78,6 @@ dnl subsystems - can influence other decisions so needs to be high up
 dnl we need to AM_CONDITIONAL them here for automake 1.6.x compatibility
 AG_GST_CHECK_SUBSYSTEM_DISABLE(GST_DEBUG,[debugging subsystem])
 AM_CONDITIONAL(GST_DISABLE_GST_DEBUG, test "x$GST_DISABLE_GST_DEBUG" = "xyes")
-AG_GST_CHECK_SUBSYSTEM_DISABLE(LOADSAVE,[pipeline XML load/save])
-AM_CONDITIONAL(GST_DISABLE_LOADSAVE, test "x$GST_DISABLE_LOADSAVE" = "xyes")
-dnl define a substitution to use in docs/gst/gstreamer.types
-if test "x$GST_DISABLE_LOADSAVE" = "xyes"
-then
-  GST_LOADSAVE_DOC_TYPES="%"
-else
-  GST_LOADSAVE_DOC_TYPES=
-fi
-AC_SUBST(GST_LOADSAVE_DOC_TYPES)
 AG_GST_CHECK_SUBSYSTEM_DISABLE(PARSE,[command-line parser])
 AM_CONDITIONAL(GST_DISABLE_PARSE, test "x$GST_DISABLE_PARSE" = "xyes")
 if test "x$GST_DISABLE_PARSE" = xyes; then
@@ -539,10 +529,6 @@ GLIB_REQ=2.24
 
 AG_GST_GLIB_CHECK([$GLIB_REQ])
 
-dnl FIXME: 0.11: Guess we need to keep this around until 0.11
-GST_HAVE_GLIB_2_8_DEFINE="#define GST_HAVE_GLIB_2_8 1"
-AC_SUBST(GST_HAVE_GLIB_2_8_DEFINE)
-
 dnl Check for glib2 without extra fat, useful for the unversioned tool frontends
 PKG_CHECK_MODULES(GLIB_ONLY, glib-2.0 >= $GLIB_REQ)
 
@@ -550,18 +536,6 @@ dnl Check for documentation xrefs
 GLIB_PREFIX="`$PKG_CONFIG --variable=prefix glib-2.0`"
 AC_SUBST(GLIB_PREFIX)
 
-dnl libxml2 is only needed for xml loading/saving of pipelines these days
-if test "x$GST_DISABLE_LOADSAVE" = "xyes"
-then
-  AC_MSG_NOTICE([XML registry and load/save are disabled, not checking for libxml2])
-  GST_DISABLE_XML_DEFINE="#define GST_DISABLE_XML 1"
-else
-  dnl check for libxml2 with minimum req version
-  AG_GST_LIBXML2_CHECK(2.4.9)
-  GST_DISABLE_XML_DEFINE="/* #undef GST_DISABLE_XML */"
-fi
-AC_SUBST(GST_DISABLE_XML_DEFINE)
-
 dnl building of unit test libraries
 AC_ARG_ENABLE(check,
   AC_HELP_STRING([--disable-check], [disable building unit test libraries]),
@@ -582,22 +556,22 @@ dnl bit of a misnomer, but keep the conditional named like this so we don't
 dnl have to change too much elsewhere
 AM_CONDITIONAL(HAVE_CHECK, test "x$BUILD_CHECK" = "xyes")
 
-dnl configure the desired buffer alignment
-AC_ARG_WITH([buffer-alignment],
-  AS_HELP_STRING([--with-buffer-alignment],[8,N,malloc,pagesize (default is 32)]),
+dnl configure the desired memory alignment
+AC_ARG_WITH([memory-alignment],
+  AS_HELP_STRING([--with-memory-alignment],[8,N,malloc,pagesize (default is 32)]),
   [
     if test "x$withval" = "xyes"
     then
-      AC_DEFINE(BUFFER_ALIGNMENT, 32, [Buffer alignment to use])
+      AC_DEFINE(MEMORY_ALIGNMENT, 32, [Memory alignment to use])
     else
       case "${withval}" in
-        malloc) AC_DEFINE(BUFFER_ALIGNMENT_MALLOC, 1, [Buffer alignment by malloc default]) ;;
-        pagesize)  AC_DEFINE(BUFFER_ALIGNMENT_PAGESIZE, 1, [Buffer alignment by pagesize]) ;;
-        *)   AC_DEFINE_UNQUOTED(BUFFER_ALIGNMENT, ${withval}, [Buffer alignment to use]) ;;
+        malloc) AC_DEFINE(MEMORY_ALIGNMENT_MALLOC, 1, [Memory alignment by malloc default]) ;;
+        pagesize)  AC_DEFINE(MEMORY_ALIGNMENT_PAGESIZE, 1, [Memory alignment by pagesize]) ;;
+        *)   AC_DEFINE_UNQUOTED(MEMORY_ALIGNMENT, ${withval}, [Memory alignment to use]) ;;
       esac
     fi
   ], [
-    AC_DEFINE(BUFFER_ALIGNMENT_MALLOC, 1, [Buffer alignment by malloc default]) 
+    AC_DEFINE(MEMORY_ALIGNMENT_MALLOC, 1, [Memory alignment by malloc default]) 
   ]
 )
 
@@ -633,7 +607,6 @@ AC_DEFINE_UNQUOTED(GST_DATADIR, "$DATADIR", [data dir])
 dnl set location of plugin directory
 AG_GST_SET_PLUGINDIR
 
-dnl FIXME: add LIBXML_PKG here if we use it
 GST_PKG_DEPS="glib-2.0, gobject-2.0, gmodule-no-export-2.0, gthread-2.0"
 AC_SUBST(GST_PKG_DEPS)
 
@@ -681,13 +654,10 @@ AC_SUBST(GST_OPTION_CXXFLAGS)
 dnl GST_ALL_*
 dnl vars common to for all internal objects (core libs, elements, applications)
 dnl CFLAGS:
-dnl - XML needs to be added because xmlPtr is used in core
 dnl - src and build dirs need to be added because every piece that gets built
 dnl   will need the GStreamer source and generated headers
-dnl LIBS: XML doesn't need to be added because we don't explicitly use symbols
-dnl       from LibXML except for in the core library
-GST_ALL_CXXFLAGS="-I\$(top_srcdir)/libs -I\$(top_srcdir) -I\$(top_builddir)/libs -I\$(top_builddir) $GLIB_CFLAGS $GLIB_EXTRA_CFLAGS $XML_CFLAGS \$(GST_OPTION_CXXFLAGS) \$(ERROR_CXXFLAGS)"
-GST_ALL_CFLAGS="-I\$(top_srcdir)/libs -I\$(top_srcdir) -I\$(top_builddir)/libs -I\$(top_builddir) $GLIB_CFLAGS $GLIB_EXTRA_CFLAGS $XML_CFLAGS \$(GST_OPTION_CFLAGS) \$(ERROR_CFLAGS)"
+GST_ALL_CXXFLAGS="-I\$(top_srcdir)/libs -I\$(top_srcdir) -I\$(top_builddir)/libs -I\$(top_builddir) $GLIB_CFLAGS $GLIB_EXTRA_CFLAGS \$(GST_OPTION_CXXFLAGS) \$(ERROR_CXXFLAGS)"
+GST_ALL_CFLAGS="-I\$(top_srcdir)/libs -I\$(top_srcdir) -I\$(top_builddir)/libs -I\$(top_builddir) $GLIB_CFLAGS $GLIB_EXTRA_CFLAGS \$(GST_OPTION_CFLAGS) \$(ERROR_CFLAGS)"
 
 dnl FIXME: check if LTLIBINTL is needed everywhere
 dnl I presume it is given that it contains the symbols that _() stuff maps to
@@ -820,7 +790,6 @@ sed \
     -e 's/.* HAVE_CPU_I386$/#define HAVE_CPU_I386 1/' \
     -e 's/.* HAVE_FGETPOS$/#define HAVE_FGETPOS 1/' \
     -e 's/.* HAVE_FSETPOS$/#define HAVE_FSETPOS 1/' \
-    -e 's/.* HAVE_LIBXML2$/#define HAVE_LIBXML2 1/' \
     -e 's/.* HAVE_PROCESS_H$/#define HAVE_PROCESS_H 1/' \
     -e 's/.* HAVE_STDLIB_H$/#define HAVE_STDLIB_H 1/' \
     -e 's/.* HAVE_STRING_H$/#define HAVE_STRING_H 1/' \
@@ -829,7 +798,7 @@ sed \
     -e 's/.* HAVE_WIN32$/#define HAVE_WIN32 1/' \
     -e 's/.* HAVE_WINSOCK2_H$/#define HAVE_WINSOCK2_H 1/' \
     -e 's/.* HOST_CPU$/#define HOST_CPU "i686"/' \
-    -e 's/.* BUFFER_ALIGNMENT_MALLOC/#define BUFFER_ALIGNMENT_MALLOC 1/' \
+    -e 's/.* MEMORY_ALIGNMENT_MALLOC/#define MEMORY_ALIGNMENT_MALLOC 1/' \
     -e 's/.* LIBDIR$/#ifdef _DEBUG\n#  define LIBDIR PREFIX "\\\\debug\\\\lib"\n#else\n#  define LIBDIR PREFIX "\\\\lib"\n#endif/' \
     -e 's/.* LOCALEDIR$/#define LOCALEDIR PREFIX "\\\\share\\\\locale"/' \
     -e 's/.* PACKAGE$/#define PACKAGE "gstreamer"/' \
@@ -838,7 +807,7 @@ sed \
     -e "s/.* PACKAGE_STRING$/#define PACKAGE_STRING \"$PACKAGE_STRING\"/" \
     -e 's/.* PACKAGE_TARNAME$/#define PACKAGE_TARNAME "'$PACKAGE_TARNAME'"/' \
     -e 's/.* PACKAGE_VERSION$/#define PACKAGE_VERSION "'$PACKAGE_VERSION'"/' \
-    -e 's/.* PLUGINDIR$/#ifdef _DEBUG\n#  define PLUGINDIR PREFIX "\\\\debug\\\\lib\\\\gstreamer-0.10"\n#else\n#  define PLUGINDIR PREFIX "\\\\lib\\\\gstreamer-0.10"\n#endif/' \
+    -e 's/.* PLUGINDIR$/#ifdef _DEBUG\n#  define PLUGINDIR PREFIX "\\\\debug\\\\lib\\\\gstreamer-0.11"\n#else\n#  define PLUGINDIR PREFIX "\\\\lib\\\\gstreamer-0.11"\n#endif/' \
     -e 's/.* GST_PLUGIN_SCANNER_INSTALLED$/#define GST_PLUGIN_SCANNER_INSTALLED LIBDIR "\\\\gst-plugin-scanner"/' \
     -e 's/.* VERSION$/#define VERSION "'$VERSION'"/' \
     config.h.in >win32/common/config.h-new
@@ -847,7 +816,6 @@ AC_OUTPUT
 
 dnl negate for output
 if test "x${GST_DISABLE_GST_DEBUG}" = "xno"; then enable_gst_debug="yes"; fi
-if test "x${GST_DISABLE_LOADSAVE}" = "xno"; then enable_loadsave="yes"; fi
 if test "x${GST_DISABLE_PARSE}" = "xno"; then enable_parse="yes"; fi
 if test "x${GST_DISABLE_OPTION_PARSING}" = "xno"; then enable_option_parsing="yes"; fi
 if test "x${GST_DISABLE_TRACE}" = "xno"; then enable_trace="yes"; fi
@@ -870,7 +838,6 @@ Configuration
        Documentation (API)        : ${enable_gtk_doc}
 
        Debug Logging              : ${enable_gst_debug}
-       Pipeline XML load/save     : ${enable_loadsave}
        Command-line parser        : ${enable_parse}
        Option parsing in gst_init : ${enable_option_parsing}
        Tracing subsystem          : ${enable_trace}
index b313c9d..64875c9 100644 (file)
@@ -1,13 +1,11 @@
 
 EXTRA_DIST = \
-       draft-buffer2.txt \
        draft-klass.txt \
        draft-push-pull.txt \
        draft-tagreading.txt \
        part-activation.txt \
        part-block.txt \
        part-buffering.txt \
-       part-bufferlist.txt \
        part-caps.txt \
        part-clocks.txt \
        part-conventions.txt \
diff --git a/docs/design/draft-buffer2.txt b/docs/design/draft-buffer2.txt
deleted file mode 100644 (file)
index 20a03ae..0000000
+++ /dev/null
@@ -1,455 +0,0 @@
-GstBuffer^2
------------
-
-This draft document describes a possible design for arbitrary per-buffer
-metadata.
-
-The proposed changes in this document are not ABI/API compatible with the 0.10
-version of GStreamer and should thus only be considered for upcomming unstable
-versions.
-
-Buffer metadata typically includes properties that give more information about
-the buffer contents. These properties are usually not negotiated and are thus
-not inside the caps.
-
-Some examples of metadata:
-
- - timestamp, duration
- - offset, offset_end
- - interlacing information
- - video alignment, cropping, panning information
- - extra container information such as granulepos, ...
- - extra global buffer properties
-
-
-Requirements
-~~~~~~~~~~~~
-
- - It must be fast
-    * allocation, free, low fragmentation
-    * access to the metadata fields, preferably not much slower than directly
-      accessing a C structure field
- - It must be extensible. Elements should be able to add new arbitrary metadata
-   without requiring much effort. Also new metadata fields should not break API
-   or ABI.
- - It plays nice with subbuffers. When a subbuffer is created, the various
-   buffer metadata should be copied/updated correctly.
- - We should be able to pass metadata in pad_alloc() and get_range() functions
-   to specify extra allocation parameters.
- - We should be able to attach statically allocated metadata to a buffer. This
-   is for metadata that does not change much.
-
-
-GstMiniObject
-~~~~~~~~~~~~~
-
-We make GstMiniObject a simple refcounted C structure and also a GLib boxed
-type. The following fields will be in the structure:
-
-struct _GstMiniObject {
-  GType type;
-
-  /*< public >*/ /* with COW */
-  /* refcounting */
-  gint       refcount;
-  guint      flags;
-
-  GstMiniObjectCopyFunction copy;
-  GstMiniObjectFreeFunction free;
-}
-
-We will use the regular GSlice allocator or custom object pooling for allocating
-instances of the mini object.
-
-We use the well known refcounting mechanisms to manage the lifetime of the
-objects.
-
-
-GstEvent, GstCaps, GstQuery, GstMessage
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Have the new GstMiniObject be the first field in these objects. They will probably
-also replace the copy and free functions with their own implementations.
-
-Allocation of the objects will use the regular gst_*_new() functions that will
-allocate and initialize a parent GstMiniObject of the required size and setting up
-the custom functions.
-
-
-GstBuffer
-~~~~~~~~~
-
-A GstMiniObject will be the parent instance of the GstBuffer object, which is a
-regular C structure.
-
-struct _GstBuffer {
-  GstMiniObject          mini_object;
-
-  gsize                  free_size;
-
-  GstCaps               *caps;
-  GstBuffer             *parent;
-
-  gpointer _gst_padding[10];
-};
-
-The Buffer object will contain a pointer to the parent buffer to allow for subbuffers
-as a first class feature of a GstBuffer.
-
-Allocation of the GstBuffer structure will result in the allocation of a memory region
-of a customizable size (512 bytes). Only the first sizeof (GstBuffer) bytes of this
-region will initially be used. The remaining bytes will be part of the free metadata
-region of the buffer. The size of the free region is kept in the free_size field.
-
-Buffers point to a GstCaps structure that contains the caps of the buffer data.
-
-
-GstBufferMeta
-~~~~~~~~~~~~~
-
-A GstBufferMeta is a structure as follows:
-
-  struct _GstBufferMeta {
-    GstBufferMetaInfo *info;  /* tag and info for the meta item */
-    GstBufferMeta     *next;  /* pointer to the next item */
-  }
-
-The purpose of the this structure is to serve as a common header for all metadata
-information that we can attach to a buffer. Specific metadata, such as timing metadata,
-will have this structure as the first field. For example:
-
-  struct _GstBufferMetaTiming {
-    GstBufferMeta  meta;        /* common meta header */
-    GstClockTime   dts;         /* decoding timestamp */
-    GstClockTime   pts;         /* presentation timestamp */
-    GstClockTime   duration;    /* duration of the data */
-    GstClockTime   clock_rate;  /* clock rate for the above values */
-  };
-
-Or another example for the buffer memory region
-
-  struct _GstBufferMetaMemory {
-    GstBufferMeta      meta;
-   
-    /* pointer to data and its size */
-    guint8            *data;
-    guint              size;
-    guint8            *malloc_data;
-    GFreeFunc          data_free;
-    gpointer           data_user;
-  };
-
-GstBufferMetaInfo will point to more information about the metadata and looks like this:
-
-  struct _GstBufferMetaInfo {
-    GQuark                     tag;       /* tag name */
-    gsize                      size;      /* size of the structure */
-
-    GstMetaInitFunction        init_func;
-    GstMetaFreeFunction        free_func;
-    GstMetaCopyFunction        copy_func;
-    GstMetaSubFunction         sub_func;
-    GstMetaSerializeFunction   serialize_func
-    GstMetaDeserializeFunction deserialize_func
-    GstMetaConvFunction        conv_func;
-  }
-
-Tag will contain a GQuark of the metadata name. We will be able to refer to specific
-metadata by name or by its (cached) GQuark.  A repository of registered MetaInfo
-will be maintained by the core. We will register some common metadata structures
-in core and some media specific info for audio/video/text in -base. Plugins can
-register additional custom metadata.
-
-Along with the metadata description we will have functions to initialize/free (and/or refcount)
-a specific GstBufferMeta instance. We also have the possibility to add a custom subbuffer
-function that can be used to modify the metadata when a subbuffer is taken.
-
-We also add serialize and deserialize function for the metadata in case we need special
-logic for reading and writing the metadata. This is needed for GDP payloading of the
-metadata.
-
-We add a conv function to the Info structure that will be called when a buffer
-should be converted to an old-style buffer for backward compatibility.
-
-The purpose of the separate MetaInfo is to not have to carry the free/init functions in
-each buffer instance but to define them globally. We still want quick access to the info
-so we need to make the buffer metadata point to the info.
-
-Technically we could also specify the field and types in the MetaInfo and
-provide a generic API to retrieve the metadata fields without the need for a
-header file. We will not do this yet.
-The complete buffer with metadata would then look as follows:
-
-                         +-------------------------------------+
-GstMiniObject            |     GType (GstBuffer)               |
-                         |     refcount, flags, copy/free      |
-                         +-------------------------------------+
-GstBuffer                |     caps, parent, subfunc           |
-                         +.....................................+
-                      +- |     info                           ------> GstBufferMetaInfo
-GstBufferMetaTiming   |  |     next                           ---+
-                      |  |                                     | |
-                      |  |     dts                             | |
-                      |  |     pts                             | |
-                      |  |     duration                        | |
-                      +- |     clock_rate                      | |
-                         + . . . . . . . . . . . . . . . . . . + |
-                      +- |     info                           <--+ -> GstBufferMetaInfo
-GstBufferMetaMemory   |  |     next                           ---+
-                      |  |                                     | |
-                      |  |     data                            | |
-                      |  |     size                            | |
-                      |  |     mallocdata                      | |
-                      |  |     data_free                       | |
-                      +- |     data_user                       | |
-                         + . . . . . . . . . . . . . . . . . . + .
-                         .                                       .
-
-API examples
-~~~~~~~~~~~~
-
-Buffers are created using the normal gst_buffer_new functions. The standard fields
-are initialized as usual. A memory area that is bigger than the structure size
-is allocated for the buffer metadata. The remaining free area is stored in the
-free_size field.
-
-  gst_buffer_new ();
-
-After creating a buffer, the application can set caps. and add other metadata
-information. 
-
-In order to modify metadata, a reference to the MetaInfo should be obtained.
-This can be done like this:
-
-  GstBufferMetaInfo *info;
-
-  info = gst_buffer_meta_get_info (GQuark tag);
-
-Usually the info will be obtained only once in order to avoid lock contention on
-the global pool of meta info. The core will also provide convenience functions
-for the core metainfo.
-
-Once a reference to the info has been obtained, the associated metadata can be
-added or modified on a buffer.
-
-For example, to modify the timing info on a buffer, one could use the following
-sequence:
-
-  GstBufferMetaInfo *info;
-  GstBufferMetaTiming *timing;
-
-  info = gst_buffer_meta_get_info (GST_META_TIMING_QUARK);
-  
-  timing = gst_buffer_get_meta (buffer, info, TRUE); /* TRUE = create if absent */
-  timing->timestamp = 0;
-  timing->duration = 20 * GST_MSECOND;
-
-The _get_meta() function returns a pointer to the metadata structure associated
-with the GST_META_TIMING_QUARK info.
-
-For the core meta info, we will provide convenience code that uses the cached
-GstBufferMetaInfo, making the above code a little more simple.
-
-  GstBufferMetaTiming *timing;
-
-  timing = gst_buffer_get_meta_timing (buffer, TRUE); /* TRUE = create if absent */
-  timing->timestamp = 0;
-  timing->duration = 20 * GST_MSECOND;
-Note that for each of the metadata that we will add to buffers, we need a struct
-definition and a registered MetaInfo. 
-
-
-We will also provide an API to iterate the different metainfo structures. A
-possible simple API would look like this:
-
- GstBufferMeta *current = NULL;
-
- /* passing NULL gives the first entry */ 
- current = gst_buffer_meta_get_next (buffer, current);
-
- /* passing a GstBufferMeta returns the next */
- current = gst_buffer_meta_get_next (buffer, current);
-
-
-
-Memory management
-~~~~~~~~~~~~~~~~~
-
-* allocation
-
-  We will initially allocate a reasonable sized GstBuffer structure (say 512
-  bytes) and we will set the free_size to the maximum amount of metadata we can
-  store.
-
-  Since the complete buffer structure, including a large area for metadata, is
-  allocated in one go, we can reduce the number of memory allocations while still
-  providing dynamic metadata.
-
-  When adding metadata, we need to call the init function of the associated
-  metadata info structure. Since adding the metadata requires the caller to pass
-  a handle to the info, this operation does not require table lookups.
-
-  Per-metadata memory initialisation is needed because not all metadata is
-  initialized in the same way. We need to, for example, set the timestamps to
-  NONE in the MetaTiming structures.
-
-  The init/free functions can also be used to implement refcounting for a metadata
-  structure. This can be useful when a structure is shared between buffers.
-
-  When the free_size of the GstBuffer is exhausted, we will allocate new memory
-  for each newly added BufferMeta and use the next pointers to point to this. It
-  is expected that this does not occur often and we might be able to optimize
-  this transparently in the future.
-
-* free
-
-  When a GstBuffer is freed, we potentially might have to call a custom free
-  function on the metadata info. In the case of the Memory metadata, we need to
-  call the associated free function to free the memory.
-  
-  When freeing a GstBuffer, the custom buffer free function will iterate all of
-  the metadata in the buffer and call the associated free functions in the
-  MetaInfo associated with the entries. Usually, this function will be NULL.
-
-
-Subbuffers
-~~~~~~~~~~
-
-Subbuffers are a first class feature of the GstBuffer. 
-
-Creating a subbuffer from a GstBuffer will allocate a new GstBuffer and ref the
-parent buffer. It will then iterate all of the metadata entries for the parent
-buffer and call the associated sub_func in the MetaInfo.
-
-This allows each metadata structure to implement the actions needed to update
-the metadata of the subbuffer. 
-
-A pointer to the old and new memory location of the metadata is passed to the
-sub_func. The default implementation will simply copy the metadata. Custom
-implementations can adjust the values. For example, when making a subbuffer, the
-timing metadata needs to be reset to NONE when the start offset is different.
-
-
-Serialization
-~~~~~~~~~~~~~
-
-When buffer should be sent over the wire or be serialized in GDP, we need a way
-to perform custom serialization and deserialization on the metadata.
-
-For this we add the serialize and deserialize functions to the metadata info.
-Possible use cases are to make sure we write out the fields with a specific size
-and endianness.
-
-
-Transformations
-~~~~~~~~~~~~~~~
-
-After certain transformations, the metadata on a buffer might not be relevant
-anymore.
-
-Consider, for example, metadata that lists certain regions of interest
-on the video data. If the video is scaled or rotated, the coordinates might not
-make sense anymore. A transform element should be able to adjust or remove the
-associated metadata when it becomes invalid. 
-
-We can make the transform element aware of the metadata so that it can adjust or
-remove in an intelligent way. Since we allow arbitrary metadata, we can't do
-this for all metadata and thus we need some other way.
-
-One proposition is to tag the metadata type with keywords that specify what it
-functionally refers too. We could, for example, tag the metadata for the regions
-of interest with a tag that notes that the metadata refers to absolute pixel
-positions. A transform could then know that the metadata is not valid anymore
-when the position of the pixels changed (due to rotation, flipping, scaling and
-so on).
-
-
-Other use cases
-~~~~~~~~~~~~~~~
-
-Making the GstBufferMetaMemory (for making the buffer point to the associated
-memory region) as metadata on a GstBuffer, as opposed to making it an integral
-part of GstBuffer, allows for some more interesting ways to transfer data.
-
-We could for example make a new GstBufferMetaIOVec metadata structure like this:
-
-  struct _GstBufferMetaIOVec {
-    GstBufferMeta  meta;
-   
-    /* pointer to data and its size */
-    GFreeFunc       data_free;
-    gpointer        data_user;
-    guint           len;
-    struct iovec   *iov;
-  };
-
-This would allow us to transfer data in a scatter/gather array. Since the fields
-in the buffer metadata are now explicit, elements that don't support this kind
-of metadata can gracefully degrade.
-
-Another use case for not having the Memory metadata in the buffers would be for
-_pad_alloc() and get_range(). We can pass a GstBuffer with the requested
-metadata fields to those functions and have the _get_range() or pad_alloc()
-implementations add (or use, in the case of a file reader) the memory metadata. 
-
-
-Relationship with GstCaps
-~~~~~~~~~~~~~~~~~~~~~~~~~
-
-The difference between GstCaps, used in negotiation, and the metadata is not
-clearly defined. 
-
-We would like to think of the GstCaps containing the information needed to
-functionally negotiate the format between two elements. The Metadata should then
-only contain variables that can change between each buffer.
-
-For example, for video we would have width/height/framerate in the caps but then
-have the more technical details, such as stride, data pointers, pan/crop/zoom
-etc in the metadata.
-
-A scheme like this would still allow us to functionally specify the desired
-video resolution while the implementation details would be inside the metadata.
-
-
-Compatibility
-~~~~~~~~~~~~~
-
-We need to make sure that elements exchange metadata that they both understand,
-This is particulary important when the metadata describes the data layout in
-memory (such as strides).
-
-Currently the only way to communicate buffer formats between elements is by
-using caps. We would like to use the caps system to negotiate the metadata that
-will be put on buffers.
-
-We would like to add to the caps on the buffer (and pad) an array of metadata
-structures (as strings) that is on the buffer. This way, an element can
-quickly know what metadata to look for.
-
-In order to remain compatibility with older plugins we need to convert buffers
-that use metadata to specify a non-standard data layout to the old format. We
-need to do this before handing buffers to old elements. We will require elements
-that are metadata aware to set a flag on their pads; any buffer passed on that
-pad will be converted to the old layout when the flag is not set.
-
-
-Notes
-~~~~~
-
-Some structures that we need to be able to add to buffers.
-
-* Clean Aperture
-* Arbitrary Matrix Transform
-* Aspect ratio
-* Pan/crop/zoom
-* Video strides
-
-Some of these overlap, we need to find a minimal set of metadata structures that
-allows us to define all use cases.
-
-
-
-
diff --git a/docs/design/draft-bufferpool.txt b/docs/design/draft-bufferpool.txt
deleted file mode 100644 (file)
index 72d3a61..0000000
+++ /dev/null
@@ -1,415 +0,0 @@
-Bufferpool
-----------
-
-This document details a possible design for how buffers can be allocated
-and managed in pools.
-
-Bufferpools should increase performance by reducing allocation overhead and
-improving possibilities to implement zero-copy memory transfer.
-
-
-Current Situation
------------------
-
- - elements can choose to implement a pool of buffers. These pools
-   can contain buffers for both source and sink pad buffers.
-
- - elements can provide buffers to upstream elements when the upstream element
-   requests a buffer with gst_pad_alloc_buffer().
-
- - The buffer pool can preallocate a certain amount of buffers to avoid
-   runtime allocation. pad_alloc_buffer() is allowed to block the upstream
-   element until buffers are recycled in the pool.
-
- - the pad_alloc_buffer function call can be passed downstream to the sink
-   that actually will perform the allocation. A fallback option exists to use
-   a default memory bufferpool whe there is no alloc_buffer function installed
-   on a pad.
-
- - Upstream renegotiation is performed by making the pad_alloc_buffer function
-   return a buffer with new caps.
-
-
-Problems
---------
-
- - There is currently no helper base class to implement efficient buffer pools
-   meaning that each element has to implement its own version.
-
- - There is no negotiation between elements about their buffer requirements.
-   Upstream elements that decide to use pad_alloc_buffer() can find that the
-   buffer they received is not appropriate at all. The most common problem
-   is that the buffers don't have the right alignment or insufficient padding.
-
- - There is no negotiation of minimum and maximum amounts of preallocated
-   buffers. In order to not avoid deadlocks, this means that buffer pool
-   implementations should be able to allocate unlimited amounts of buffers and
-   are never allowed to block in pad_alloc_buffer()
-
-
-Requirements
-------------
-
- - maintain and reuse a list of buffers in a reusable base GstBufferPool
-   object
-
- - negotiate allocation configuration between source and sink pad.
-   - have minimum and maximum amount of buffers with the option of 
-     preallocating buffers.
-   - alignment and padding support
-   - arbitrary extra options
-
- - integrate with dynamic caps renegotiation
-
- - dynamically change bufferpool configuration based on pipeline changes.
-
- - allow the application to control buffer allocation
-
-
-GstBufferPool
--------------
-
- The bufferpool object manages a list of buffers with the same properties such
- as size, padding and alignment.
-
- The bufferpool has two states: flushing and non-flushing. In the flushing
- state, the bufferpool can be configured with the required allocation
- preferences. In the non-flushing state, buffers can be retrieved from and
- returned to the pool.
-
- The default implementation of the bufferpool is able to allocate buffers
- from main memory with arbitrary alignment and padding/prefix.
-
- Custom implementations of the bufferpool can override the allocation and
- free algorithms of the buffers from the pool. This should allow for
- different allocation strategies such as using shared memory or hardware
- mapped memory.
-
- The bufferpool object is also used to perform the negotiation of configuration
- between elements.
-
-
-GstPad
-------
-
- The GstPad has a method to query a GstBufferPool and its configuration.
-
-   GstBufferPool * gst_pad_query_bufferpool (GstPad * pad);
-
- This function can return a handle to a bufferpool object or NULL when no
- bufferpool object can be provided by the pad.
-
- This function should return a bufferpool object with the
- GstBufferPoolConfig set to the desired parameters of the buffers that will be
- handled by the given pad. This function can only be called on a sinkpad and
- will usually be called by the peer srcpad with the convenience method:
-
-   GstBufferPool * gst_pad_peer_query_bufferpool (GstPad * pad);
- There is also a new function to configure a bufferpool on a pad and its peer
- pad:
-
-   gboolean gst_pad_set_bufferpool (GstPad * pad, GstBufferPool *pool);
- This function is to inform a pad and its peer pad that a bufferpool should
- be used for allocation (on source pads) and that bufferpool is used by the
- upstream element (on sinkpads).
-
- The currently configured bufferpool can be retrieved with:
-
-   GstBufferPool * gst_pad_get_bufferpool (GstPad * pad);
-
- New functions exist to configure these bufferpool functions on pads:
- gst_pad_set_querybufferpool_function and gst_pad_set_setbufferpool_function.
-
-negotiating pool and config
----------------------------
-
-Since upstream needs to allocate buffers from a buffer pool, it should first
-negotiate a buffer pool with the downstream element. We propose a simple
-scheme where a sink can propose a bufferpool and some configuration and where
-the source can choose to use this allocator or use its own.
-
-The algorithm for doing this is rougly like this:
-
-
-   /* srcpad knows media type and size of buffers and is ready to
-    * prepare an output buffer but has no pool yet */
-
-   /* first get the pool from the downstream peer */
-   pool = gst_pad_peer_query_bufferpool (srcpad);
-
-   if (pool != NULL) {
-     GstBufferPoolConfig config;
-
-     /* clear the pool so that we can reconfigure it */
-     gst_buffer_pool_set_flushing (pool, TRUE);
-
-     do {
-       /* get the config */
-       gst_buffer_pool_get_config (pool, &config);
-
-       /* check and modify the config to match our requirements */
-       if (!tweak_config (&config)) {
-         /* we can't tweak the config any more, exit and fail */
-         gst_object_unref (pool);
-         pool = NULL;
-         break;
-       } 
-     }
-     /* update the config */
-     while (!gst_buffer_pool_set_config (pool, &config));
-
-     /* we managed to update the config, all is fine now */
-     /* set the pool to non-flushing to make it allocate things */
-     gst_buffer_pool_set_flushing (pool, FALSE);
-   }
-
-   if (pool == NULL) {
-     /* still no pool, we create one ourself with our ideal config */
-     pool = gst_buffer_pool_new (...);
-   }
-
-   /* now set the pool on this pad and the peer pad */
-   gst_pad_set_bufferpool (pad, pool);
-
-
-Negotiation is the same for both push and pull mode. In the case of pull
-mode scheduling, the srcpad will perform the negotiation of the pool
-when it receives the first pull request.
-
-
-Allocating from pool
---------------------
-
- Buffers are allocated from the pool of a pad:
-
-  res = gst_buffer_pool_acquire_buffer (pool, &buffer, &params);
-
- convenience functions to automatically get the pool from a pad can be made:
-  
-  res = gst_pad_acquire_buffer (pad, &buffer, &params);
-
- Buffers are refcounted in te usual way. When the refcount of the buffer
- reaches 0, the buffer is automatically returned to the pool. This is achieved
- by setting and reffing the pool as a new buffer member.
-
- Since all the buffers allocated from the pool keep a reference to the pool,
- when nothing else is holding a refcount to the pool, it will be finalized
- when all the buffers from the pool are unreffed. By setting the pool to
- the flushing state we can drain all buffers from the pool. 
-
-
-Renegotiation
--------------
-
-Renegotiation of the bufferpool might need to be performed when the
-configuration of the pool changes. Changes can be in the buffer size (because
-of a caps change), alignment or number of buffers. 
-
-* downstream
-
-  When the upstream element wants to negotiate a new format, it might need
-  to renegotiate a new bufferpool configuration with the downstream element.
-  This can, for example, happen when the buffer size changes.
-
-  We can not just reconfigure the existing bufferpool because there might
-  still be outstanding buffers from the pool in the pipeline. Therefore we
-  need to create a new bufferpool for the new configuration while we let the
-  old pool drain.
-
-  Implementations can choose to reuse the same bufferpool object and wait for
-  the drain to finish before reconfiguring the pool.
-
-  The element that wants to renegotiate a new bufferpool uses exactly the same
-  algorithm as when it first started.
-  
-* upstream 
-
-  When a downstream element wants to negotiate a new format, it will send a 
-  RECONFIGURE event upstream. This instructs upstream to renegotiate both
-  the format and the bufferpool when needed.
-
-  A pipeline reconfiguration is when new elements are added or removed from
-  the pipeline or when the topology of the pipeline changes. Pipeline
-  reconfiguration also triggers possible renegotiation of the bufferpool and
-  caps.
-
-  A RECONFIGURE event tags each pad it travels on as needing reconfiguration.
-  The next buffer allocation will then require the renegotiation or
-  reconfiguration of a pool.
-
-  If downstream has specified a RENEGOTIATE flag, it must be prepared to
-  received NOT_NEGOTIATED results when allocating buffers, which instructs
-  it to start caps and bufferpool renegotiation. When using this flag, 
-  upstream can more quickly react to downstream format or size changes.
-
-
-Shutting down
--------------
-
- In push mode, a source pad is responsible for setting the pool to the
- flushing state when streaming stops. The flush will unblock any pending
- allocations so that the element can shut down.
-
- In pull mode, the sink element should set the pool to the flushing state when
- shutting down so that the peer _get_range() function can unblock.
-
- In the flushing state, all the buffers that are returned to the pool will
- be automatically freed by the pool and new allocations will fail.
-
-
-
-Use cases
----------
-
-1)  videotestsrc ! xvimagesink
-
- Before videotestsrc can output a buffer, it needs to negotiate caps and
- a bufferpool with the downstream peer pad.
-
- First it will negotiate a suitable format with downstream according to the
- normal rules.
-
- Then it does gst_pad_peer_query_bufferpool() which triggers the querybufferpool
- function installed on the xvimagesink pad. This bufferpool is currently in
- the flushing state and thus has no buffers allocated.
-
- videotestsrc gets the configuration of the bufferpool object. This
- configuration lists the desired configuration of the xvimagesink, which can
- have specific alignment and/or min/max amount of buffers.
-
- videotestsrc updates the configuration of the bufferpool, it will likely
- set the min buffers to 1 and the size of the desired buffers. It then
- updates the bufferpool configuration with the new properties.
-
- When the configuration is successfully updated, videotestsrc sets the 
- bufferpool on its source pad, this will also set the pool on the peer 
- sinkpad.
-
- It then sets the bufferpool to the non-flushing state. This preallocates
- the buffers in the pool (if needed). This operation can fail when there
- is not enough memory available. Since the bufferpool is provided by
- xvimagesink, it will allocate buffers backed by an XvImage and pointing
- to shared memory with the X server.
-
- If the bufferpool is successfully activated, videotestsrc can acquire a
- buffer from the pool, set the caps on it, fill in the data and push it
- out to xvimagesink.
-
- xvimagesink can know that the buffer originated from its pool by following
- the pool member or checking the specific GType of it GstBuffer subclass.
- It might need to get the parent buffer first in case of subbuffers.
-
- when shutting down, videotestsrc will set the pool to the flushing state,
- this will cause further allocations to fail and currently allocated buffers
- to be freed. videotestsrc will then free the pool and stop streaming.
-
-
-2) videotestsrc ! queue ! myvideosink
-
- In this second use case we have a videosink that can at most allocate
- 3 video buffers.
-
- Again videotestsrc will have to negotiate a bufferpool with the peer 
- element. For this it will perform gst_pad_peer_query_bufferpool() which
- queue will proxy to its downstream peer element.
-
- The bufferpool returned from myvideosink will have a max_buffers set to 3.
- queue and videotestsrc can operate with this upper limit because none of
- those elements require more than that amount of buffers for temporary
- storage.
-
- The bufferpool of myvideosink will then be configured with the size of the
- buffers for the negotiated format and according to the padding and alignment
- rules. When videotestsrc sets the pool to non-flushing, the 3 video
- buffers will be preallocated in the pool.
-
- The pool will then be configured on the src of videotestsrc and the
- sinkpad of the queue. The queue will proxy the setbufferpool method to
- its srcpad, which finally configures the pool all the way to the sink.
-
- videotestsrc acquires a buffer from the configured pool on its srcpad and
- pushes this into the queue. When the videotestsrc has acquired and pushed
- 3 frames, the next call to gst_buffer_pool_acquire_buffer() will block
- (assuming the GST_BUFFER_POOL_FLAG_WAIT is specified).
-
- When the queue has pushed out a buffer and the sink has rendered it, the
- refcount of the buffer reaches 0 and the buffer is recycled in the pool.
- This will wake up the videotestsrc that was blocked, waiting for more
- buffers and will make it produce the next buffer. 
-
- In this setup, there are at most 3 buffers active in the pipeline and
- the videotestsrc is rate limited by the rate at which buffers are recycled
- in the bufferpool.
-
- When shutting down, videotestsrc will first set the bufferpool on the srcpad
- to flushing. This causes any pending (blocked) acquire to return with a 
- WRONG_STATE result and causes the streaming thread to pause.
-
-3) .. ! myvideodecoder ! queue ! fakesink 
-
- In this case, the myvideodecoder requires buffers to be aligned to 128
- bytes and padded with 4096 bytes. The pipeline starts out with the
- decoder linked to a fakesink but we will then dynamically change the
- sink to one that can provide a bufferpool.
-
- When it negotiates the size with the downstream element fakesink, it will
- receive a NULL bufferpool because fakesink does not provide a bufferpool.
- It will then select it own custom bufferpool to start the datatransfer.
-
- At some point we block the queue srcpad, unlink the queue from the 
- fakesink, link a new sink, set the new sink to the PLAYING state and send
- the right newsegment event to the sink. Linking the new sink would 
- automatically send a RENEGOTIATE event upstream and, through queue, inform
- myvideodecoder that it should renegotiate its bufferpool because downstream
- has been reconfigured.
-
- Before pushing the next buffer, myvideodecoder would renegotiate a new
- bufferpool. To do this, it performs the usual bufferpool negotiation
- algorithm. If it can obtain and configure a new bufferpool from downstream,
- it sets its own (old) pool to flushing and unrefs it. This will eventually
- drain and unref the old bufferpool.
-
- The new bufferpool is set as the new bufferpool for the srcpad and sinkpad
- of the queue and set to the non-flushing state.
-
-
-4) .. ! myvideodecoder ! queue ! myvideosink 
-
- myvideodecoder has negotiated a bufferpool with the downstream myvideosink
- to handle buffers of size 320x240. It has now detected a change in the 
- video format and need to renegotiate to a resolution of 640x480. This
- requires it to negotiate a new bufferpool with a larger buffersize.
-
- When myvideodecoder needs to get the bigger buffer, it starts the 
- negotiation of a new bufferpool. It queries a bufferpool from downstream,
- reconfigures it with the new configuration (which includes the bigger buffer
- size), it sets the bufferpool to non-flushing and sets the bufferpool as
- the new pool for the srcpad and its peer. This automatically flushes the
- old pool and unrefs it, which causes the old format to drain.
-
- It then uses the new bufferpool for allocating new buffers of the new 
- dimension.
-
- If at some point, the decoder wants to switch to a lower resolution again,
- it can choose to use the current pool (which has buffers that are larger
- than the required size) or it can choose to renegotiate a new bufferpool.
-
-
-5) .. ! myvideodecoder ! videoscale ! myvideosink 
-
- myvideosink is providing a bufferpool for upstream elements and wants to
- change the resolution.
-
- myvideosink sends a RENEGOTIATE event upstream to notify upstream that a
- new format is desirable. upstream elements try to negotiate a new format
- and bufferpool before pushing out a new buffer. The old bufferpools are
- drained in the regular way.
-
-
-
index 32ea190..6e5bab8 100644 (file)
@@ -22,13 +22,14 @@ API/ABI
 
 - rethink how we handle dynamic replugging wrt segments and other events that
   already got pushed and need to be pushed again. Might need GstFlowReturn from
-  gst_pad_push_event().
+  gst_pad_push_event(). FIXED in 0.11 with sticky events.
 
 - Optimize negotiation. We currently do a get_caps() call when we link pads,
   which could potentially generate a huge list of caps and all their
   combinations, we need to avoid generating these huge lists by generating them
   incrementaly when needed. We can do this with a gst_pad_iterate_caps() call.
-  We also need to incrementally return intersections etc, for this.
+  We also need to incrementally return intersections etc, for this. somewhat
+  FIXED in 0.11 with a filter on getcaps functions.
 
 - Elements in a bin have no clue about the final state of the parent element
   since the bin sets the target state on its children in small steps. This
@@ -50,6 +51,7 @@ API/ABI
     and another a push, the push might be busy while the block callback is done.
   * maybe this name is overloaded. We need to look at some more use cases before
     trying to fix this.
+  FIXED in 0.11 with BLOCKING probes. Not everything is implemented yet, though.
 
 - rethink the way we do upstream renegotiation. Currently it's done with
   pad_alloc but this has many issues such as only being able to suggest 1 format
@@ -57,8 +59,7 @@ API/ABI
   as capsfilter only know about the format, not the size). We would ideally like
   to let upstream renegotiate a new format just like it did when it started.
   This could, for example, easily be triggered with a RENEGOTIATE event.
-
-- Remove the XML serialisation stuff.
+  FIXED in 0.11 with RECONFIGURE events.
 
 - Remove the result format value in queries.
 
@@ -75,8 +76,6 @@ IMPLEMENTATION
 
 - implement BUFFERSIZE.
 
-- implement pad_block with probes? see above.
-
 
 DESIGN
 ~~~~~~
index 6a028b1..8d2508d 100644 (file)
@@ -156,20 +156,3 @@ as well, so that there is a generic method for both PAUSED and PLAYING.
 
 The same flow works as well for any chain of multiple elements and might 
 be implemented with a helper function in the future.
-
-
-Issues
-~~~~~~
-
-When an EOS event has passed a pad and the pad is set to blocked, the block will
-never happen because no data is going to flow anymore. One possibility is to
-keep track of the pad's EOS state and make the block succeed immediatly. This is
-not yet implemenented.
-
-When dynamically reconnecting pads, some events (like NEWSEGMENT, EOS,
-TAGS, ...) are not yet retransmitted to the newly connected element. It's
-unclear if this can be done by core automatically by caching those events and
-resending them on a relink. It might also be possible that this needs a
-GstFlowReturn value from the event function, in which case the implementation
-must be delayed for after 0.11, when we can break API/ABI.
-
diff --git a/docs/design/part-buffer.txt b/docs/design/part-buffer.txt
new file mode 100644 (file)
index 0000000..b6568ed
--- /dev/null
@@ -0,0 +1,154 @@
+GstBuffer
+---------
+
+This document describes the design for buffers.
+
+A GstBuffer is the object that is passed from an upstream element to a
+downstream element and contains memory and metadata information.
+
+Requirements
+~~~~~~~~~~~~
+
+ - It must be fast
+    * allocation, free, low fragmentation
+ - Must be able to attach multiple memory blocks to the buffer
+ - Must be able to attach artibtrary metadata to buffers
+ - efficient handling of subbuffer, copy, span, trim
+
+Writability
+-----------
+
+The Buffers is writable when the refcount is 1. This means that:
+
+ - metadata can be added/removed and the metadata can be changed
+ - GstMemory blocks can be added/removed
+
+The individual memory blocks have their own refcounting and READONLY flags
+that might influence their writability.
+
+Buffers can be made writable with gst_buffer_make_writable(). This will copy the
+buffer with the metadata and will ref the memory in the buffer. This means that
+the memory is not automatically copied when copying buffers.
+
+
+Managing GstMemory
+------------------
+
+A GstBuffer contains an array of pointers to GstMemory objects. 
+
+When the buffer is writable, gst_buffer_take_memory() can be used to add a
+new GstMemory object to the buffer. When the array of memory is full, memory
+will be merged to make room for the new memory object.
+
+gst_buffer_n_memory() is used to get the amount of memory blocks on the
+GstBuffer.
+
+With gst_buffer_peek_memory(), memory can be retrieved from the memory array.
+The desired access pattern for the memory block should be specified so that
+appropriate checks can be made and, in case of GST_MAP_WRITE, a writable copy
+can be constructed when needed.
+
+gst_buffer_remove_memory_range() and gst_buffer_remove_memory() can be used to
+remove memory from the GstBuffer.
+
+
+Subbuffers
+----------
+
+Subbuffers are made by copying only a region of the memory blocks and copying
+all of the metadata.
+
+
+Span
+----
+
+Spanning will merge together the data of 2 buffers into a new buffer
+
+
+Data access
+-----------
+
+ Accessing the data of the buffer can happen by retrieving the individual
+ GstMemory objects in the GstBuffer or my using the gst_buffer_map() and
+ gst_buffer_unmap() function.
+
+ The _map and _unmap function will always return the memory of all blocks as one
+ large contiguous region of memory. Using the _map and _unmap function might be
+ more convenient that accessing the individual memory blocks at the expense of
+ being more expensive because it might perform memcpy operations.
+
+ For buffers with only one GstMemory object (the most common case), _map and
+ _unmap have no performance penalty at all.
+
+
+* Read access with 1 memory block
+
+  The memory block is accessed and mapped for read access.
+  The memory block is unmapped after usage
+
+* write access with 1 memory block
+
+  The buffer should be writable or this operation will fail..
+  The memory block is accessed. If the memory block is readonly, a copy is made
+  and the original memory block is replaced with this copy. then the memory
+  block is mapped in write mode.
+  The memory block is unmapped after usage.
+
+* Read access with multiple memory blocks
+
+  The memory blocks are combined into one large memory block. If the buffer is
+  writable, The memory blocks are replace with this new memory block. If the
+  buffer is not writable, the memory is returned as is.
+  The memory block is then mapped in read mode.
+
+  When the memory is unmapped after usage and the buffer has multiple memory
+  blocks, this means that the map operation was not able to store the combined
+  buffer and it thus returned memory that should be freed. Otherwise, the memory
+  is unmapped.
+
+* Write access with multiple memory blocks
+
+  The buffer should be writable or the operation fails. The memory blocks are
+  combined into one large memory block and the existing blocks are replaced with
+  this new block. The memory is then mapped in write mode.
+  The memory is unmapped after usage.
+
+
+Use cases
+---------
+
+Generating RTP packets from h264 video
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+We receive as input a GstBuffer with an encoded h264 image and we need to
+create RTP packets containing this h264 data as the payload. We typically need
+to fragment the h264 data into multiple packets, each with their own RTP and
+payload specific header.
+
+                       +-------+-------+---------------------------+--------+
+  input H264 buffer:   | NALU1 | NALU2 |  .....                    | NALUx  |
+                       +-------+-------+---------------------------+--------+
+                             |
+                             V
+  array of             +-+ +-------+  +-+ +-------+            +-+ +-------+
+  output buffers:      | | | NALU1 |  | | | NALU2 |   ....     | | | NALUx |
+                       +-+ +-------+  +-+ +-------+            +-+ +-------+
+                       :           :  :           :
+                       \-----------/  \-----------/
+                         buffer 1        buffer 2
+
+The output buffer array consists of x buffers consisting of an RTP payload header
+and a subbuffer of the original input H264 buffer. Since the rtp headers and
+the h264 data don't need to be contiguous in memory, they are added to the buffer
+as separate GstMemory blocks and we can avoid to memcpy the h264 data into
+contiguous memory.
+
+A typical udpsink will then use something like sendmsg to send the memory regions
+on the network inside one UDP packet. This will further avoid having to memcpy
+data into contiguous memory.
+
+Using bufferlists, the complete array of output buffers can be pushed in one
+operation to the peer element.
+
+
+
diff --git a/docs/design/part-bufferlist.txt b/docs/design/part-bufferlist.txt
deleted file mode 100644 (file)
index d885781..0000000
+++ /dev/null
@@ -1,96 +0,0 @@
-Buffer Lists
-------------
-
-GstBuffer provides a datastructure to manage:
-
- - a continuous region of memory
- - functions to copy/free the memory
- - metadata associated with that memory such as timestamps and caps.
-
-It is the primary means of transfering data between pads and elements.
-
-GstBufferList expands on GstBuffer to allow multiple GstBuffers (conceptually 
-organized in a list) to be treated as a multiple groups of GstBuffers. This allows
-for the following extra functionality:
-
- - A logical GstBuffer (called a group) can consist of disjoint memory each with
-   their own copy/free and metadata. Logically the group should be treated as
-   one single GstBuffer.
- - Multiple groups can be put into one bufferlist. This allows for a single
-   method call to pass multiple (logical) buffers downstream.
-
-
-Use cases
-~~~~~~~~~
-
-A typical use case for multimedia pipelines is to append or remove 'headers'
-from packets of data.
-
-Generating RTP packets from h264 video
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-We receive as input a GstBuffer with an encoded h264 image and we need to
-create RTP packets containing this h264 data as the payload. We typically need
-to fragment the h264 data into multiple packets, each with their own RTP and
-payload specific header.
-
-                       +-------+-------+---------------------------+--------+
-  input H264 buffer:   | NALU1 | NALU2 |  .....                    | NALUx  |
-                       +-------+-------+---------------------------+--------+
-                             |
-                             V
-                       +-+ +-------+  +-+ +-------+            +-+ +-------+
-  output bufferlist:   | | | NALU1 |  | | | NALU2 |   ....     | | | NALUx |
-                       +-+ +-------+  +-+ +-------+            +-+ +-------+
-                       :           :  :           :
-                       \-----------/  \-----------/
-                         group 1        group 2 
-
-The output bufferlist consists of x groups consisting of an RTP payload header
-and a subbuffer of the original input H264 buffer. Since the rtp headers and
-the h264 data don't need to be contiguous in memory, we can avoid to memcpy the
-h264 data into the rtp packets.
-
-Since we can generate a bufferlist with multiple groups, we can push all the
-RTP packets for the input data to the next element in one operation.
-
-A typical udpsink will then use something like sendmsg to send the groups on
-the network inside one UDP packet. This will further avoid having to memcpy
-data into contiguous memory.
-
-
-API
-~~~
-
-The GstBufferList is an opaque data structure and is operated on using an
-iterator. It derives from GstMiniObject so that it has basic refcounting and
-copy/free functions.
-
-The bufferlist is writable when its refcount is 1 and it's not marked as
-readonly. A writable bufferlist means that elements can be added and removed
-form the list but it does not mean that the actual buffers in the list are
-writable.
-
-To modify the data in the buffers of the bufferlist, both the list and the
-buffer must be writable.
-
-Methods exist for navigating the groups in the list and the buffers inside a
-group. 
-
-
-Metadata
-~~~~~~~~
-
-Each of the buffers inside the bufferlist can have metadata assiociated with it.
-
-The metadata of the bufferlist is always the metadata of the first buffer of the
-first group in the bufferlist. This means that:
-
-  - Before pushing the list to a pad, negotiation happens with (only) the caps of
-    the first buffer in the list. Caps of other buffers is ignore.
-
-  - synchronisation happens on the timestamp of the first buffer in the list.
-
-This allows for efficient (re)timestamping and re-typing (caps) of a group of
-buffers without having to modify each of the buffer's metadata.
-
diff --git a/docs/design/part-bufferpool.txt b/docs/design/part-bufferpool.txt
new file mode 100644 (file)
index 0000000..04f5d62
--- /dev/null
@@ -0,0 +1,329 @@
+Bufferpool
+----------
+
+This document details the design of how buffers are be allocated and
+managed in pools.
+
+Bufferpools increases performance by reducing allocation overhead and
+improving possibilities to implement zero-copy memory transfer.
+
+Together with the ALLOCATION query, elements can negotiate allocation properties
+and bufferpools between themselves. This also allows elements to negotiate
+buffer metadata between themselves.
+
+Requirements
+------------
+
+ - Provide a GstBufferPool base class to help the efficient implementation of a
+   list of reusable GstBuffer objects.
+
+ - Let upstream elements initiate the negotiation of a bufferpool and it
+   configuration. Allow downstream elements provide bufferpool properties and/or
+   a bufferpool. This includes the following properties:
+
+    * have minimum and maximum amount of buffers with the option of 
+      preallocating buffers.
+    * alignment and padding support
+    * buffer metadata
+    * arbitrary extra options
+
+ - Integrate with dynamic caps renegotiation.
+
+ - Notify upstream element of new bufferpool availability. This is important
+   when a new element, that can provide a bufferpool, is dynamically linked
+   downstream.
+
+
+GstBufferPool
+-------------
+
+ The bufferpool object manages a list of buffers with the same properties such
+ as size, padding and alignment.
+
+ The bufferpool has two states: active and inactive. In the in-active
+ state, the bufferpool can be configured with the required allocation
+ preferences. In the active state, buffers can be retrieved from and
+ returned to the pool.
+
+ The default implementation of the bufferpool is able to allocate buffers
+ from main memory with arbitrary alignment and padding/prefix.
+
+ Custom implementations of the bufferpool can override the allocation and
+ free algorithms of the buffers from the pool. This should allow for
+ different allocation strategies such as using shared memory or hardware
+ mapped memory.
+
+
+Negotiation
+-----------
+
+ After a particular media format has been negotiated between two pads (using the
+ CAPS event), they must agree on how to allocate buffers.
+
+ The srcpad will always take the initiative to negotiate the allocation
+ properties. It starts with creating a GST_QUERY_ALLOCATION with the negotiated
+ caps.
+
+ The srcpad can set the need-pool flag to TRUE in the query to optionally make the
+ peer pad allocate a bufferpool.
+
+ It will then inspect the returned results and configure the returned pool or
+ create a new pool with the returned properties when needed.
+
+ Buffers are then allocated by the srcpad from the negotiated pool and pushed to
+ the peer pad as usual.
+
+
+Allocation query
+----------------
+
+ The allocation query has the following fields:
+
+  (in) "caps", GST_TYPE_CAPS
+        - the caps that was negotiated
+
+  (in) "need-pool", G_TYPE_BOOLEAN
+        - if a GstBufferPool is requested
+
+  (out) "prefix", G_TYPE_UINT
+        - the prefix of the buffer memory
+
+  (out) "align", G_TYPE_UINT
+        - the aligment of the memory in the buffers, the alignment will be applied
+          to the prefix.
+
+  (out) "size", G_TYPE_UINT
+        - the total size of the buffer memory
+
+  (out) "pool", GST_TYPE_BUFFER_POOL
+        - a buffer pool when need-pool was TRUE and the peer can provide a pool
+
+  (out) "metadata", G_TYPE_VALUE_ARRAY of G_TYPE_STRING
+        - an array of metadata API strings that can be accepted.
+
+
+Allocating from pool
+--------------------
+
+ Buffers are allocated from the pool of a pad:
+
+  res = gst_buffer_pool_acquire_buffer (pool, &buffer, &params);
+
+ A GstBuffer that is allocated from the pool will always be writable (have a
+ refcount of 1) and it will also have its pool member point to the GstBufferPool
+ that created the buffer.
+
+ Buffers are refcounted in the usual way. When the refcount of the buffer
+ reaches 0, the buffer is automatically returned to the pool.
+
+ Since all the buffers allocated from the pool keep a reference to the pool,
+ when nothing else is holding a refcount to the pool, it will be finalized
+ when all the buffers from the pool are unreffed. By setting the pool to
+ the inactive state we can drain all buffers from the pool. 
+
+ When the pool is in the inactive state, gst_buffer_pool_acquire_buffer() will
+ return GST_FLOW_WRONG_STATE immediately.
+
+ Extra parameters can be given to the gst_buffer_pool_acquire_buffer() method to
+ influence the allocation decision. GST_BUFFER_POOL_FLAG_KEY_UNIT and
+ GST_BUFFER_POOL_FLAG_DISCONT serve as hints.
+
+ When the bufferpool is configured with a maximum number of buffers, allocation
+ will block when all buffers are outstanding until a buffer is returned to the
+ pool. This behaviour can be changed by specifying the
+ GST_BUFFER_POOL_FLAG_DONTWAIT flag in the parameters. With this flag set,
+ allocation will return GST_FLOW_UNEXPECTED when the pool is empty.
+
+
+Renegotiation
+-------------
+
+Renegotiation of the bufferpool might need to be performed when the
+configuration of the pool changes. Changes can be in the buffer size (because
+of a caps change), alignment or number of buffers. 
+
+* downstream
+
+  When the upstream element wants to negotiate a new format, it might need
+  to renegotiate a new bufferpool configuration with the downstream element.
+  This can, for example, happen when the buffer size changes.
+
+  We can not just reconfigure the existing bufferpool because there might
+  still be outstanding buffers from the pool in the pipeline. Therefore we
+  need to create a new bufferpool for the new configuration while we let the
+  old pool drain.
+
+  Implementations can choose to reuse the same bufferpool object and wait for
+  the drain to finish before reconfiguring the pool.
+
+  The element that wants to renegotiate a new bufferpool uses exactly the same
+  algorithm as when it first started. It will negotiate caps first then use the
+  ALLOCATION query to get and configure the new pool.
+  
+* upstream 
+
+  When a downstream element wants to negotiate a new format, it will send a 
+  RECONFIGURE event upstream. This instructs upstream to renegotiate both
+  the format and the bufferpool when needed.
+
+  A pipeline reconfiguration is when new elements are added or removed from
+  the pipeline or when the topology of the pipeline changes. Pipeline
+  reconfiguration also triggers possible renegotiation of the bufferpool and
+  caps.
+
+  A RECONFIGURE event tags each pad it travels on as needing reconfiguration.
+  The next buffer allocation will then require the renegotiation or
+  reconfiguration of a pool.
+
+
+Shutting down
+-------------
+
+ In push mode, a source pad is responsible for setting the pool to the
+ inactive state when streaming stops. The inactive state will unblock any pending
+ allocations so that the element can shut down.
+
+ In pull mode, the sink element should set the pool to the inactive state when
+ shutting down so that the peer _get_range() function can unblock.
+
+ In the inactive state, all the buffers that are returned to the pool will
+ automatically be freed by the pool and new allocations will fail.
+
+Use cases
+---------
+
+1)  videotestsrc ! xvimagesink
+
+ Before videotestsrc can output a buffer, it needs to negotiate caps and
+ a bufferpool with the downstream peer pad.
+
+ First it will negotiate a suitable format with downstream according to the
+ normal rules. It will send a CAPS event downstream with the negotiated
+ configuration.
+
+ Then it does an ALLOCATION query. It will use the returned bufferpool or
+ configures its own bufferpool with the returned parameters. The bufferpool is
+ initially in the inactive state.
+
+ The ALLOCATION query lists the desired configuration of the downstream 
+ xvimagesink, which can have specific alignment and/or min/max amount of
+ buffers.
+
+ videotestsrc updates the configuration of the bufferpool, it will likely
+ set the min buffers to 1 and the size of the desired buffers. It then
+ updates the bufferpool configuration with the new properties.
+
+ When the configuration is successfully updated, videotestsrc sets the
+ bufferpool to the active state. This preallocates the buffers in the pool
+ (if needed). This operation can fail when there is not enough memory
+ available. Since the bufferpool is provided by xvimagesink, it will allocate
+ buffers backed by an XvImage and pointing to shared memory with the X server.
+
+ If the bufferpool is successfully activated, videotestsrc can acquire a
+ buffer from the pool, fill in the data and push it out to xvimagesink.
+
+ xvimagesink can know that the buffer originated from its pool by following
+ the pool member.
+
+ when shutting down, videotestsrc will set the pool to the inactive state,
+ this will cause further allocations to fail and currently allocated buffers
+ to be freed. videotestsrc will then free the pool and stop streaming.
+
+
+2) videotestsrc ! queue ! myvideosink
+
+ In this second use case we have a videosink that can at most allocate
+ 3 video buffers.
+
+ Again videotestsrc will have to negotiate a bufferpool with the peer 
+ element. For this it will perform the ALLOCATION query which
+ queue will proxy to its downstream peer element.
+
+ The bufferpool returned from myvideosink will have a max_buffers set to 3.
+ queue and videotestsrc can operate with this upper limit because none of
+ those elements require more than that amount of buffers for temporary
+ storage.
+
+ The bufferpool of myvideosink will then be configured with the size of the
+ buffers for the negotiated format and according to the padding and alignment
+ rules. When videotestsrc sets the pool to active, the 3 video
+ buffers will be preallocated in the pool.
+
+ videotestsrc acquires a buffer from the configured pool on its srcpad and
+ pushes this into the queue. When the videotestsrc has acquired and pushed
+ 3 frames, the next call to gst_buffer_pool_acquire_buffer() will block
+ (assuming the GST_BUFFER_POOL_FLAG_DONTWAIT is not specified).
+
+ When the queue has pushed out a buffer and the sink has rendered it, the
+ refcount of the buffer reaches 0 and the buffer is recycled in the pool.
+ This will wake up the videotestsrc that was blocked, waiting for more
+ buffers and will make it produce the next buffer. 
+
+ In this setup, there are at most 3 buffers active in the pipeline and
+ the videotestsrc is rate limited by the rate at which buffers are recycled
+ in the bufferpool.
+
+ When shutting down, videotestsrc will first set the bufferpool on the srcpad
+ to inactive. This causes any pending (blocked) acquire to return with a 
+ WRONG_STATE result and causes the streaming thread to pause.
+
+3) .. ! myvideodecoder ! queue ! fakesink 
+
+ In this case, the myvideodecoder requires buffers to be aligned to 128
+ bytes and padded with 4096 bytes. The pipeline starts out with the
+ decoder linked to a fakesink but we will then dynamically change the
+ sink to one that can provide a bufferpool.
+
+ When it negotiates the size with the downstream element fakesink, it will
+ receive a NULL bufferpool because fakesink does not provide a bufferpool.
+ It will then select its own custom bufferpool to start the datatransfer.
+
+ At some point we block the queue srcpad, unlink the queue from the 
+ fakesink, link a new sink and set the new sink to the PLAYING state.
+ Linking the new sink would automatically send a RECONFIGURE event upstream
+ and, through queue, inform myvideodecoder that it should renegotiate its
+ bufferpool because downstream has been reconfigured.
+
+ Before pushing the next buffer, myvideodecoder would renegotiate a new
+ bufferpool. To do this, it performs the usual bufferpool negotiation
+ algorithm. If it can obtain and configure a new bufferpool from downstream,
+ it sets its own (old) pool to inactive and unrefs it. This will eventually
+ drain and unref the old bufferpool.
+
+ The new bufferpool is set as the new bufferpool for the srcpad and sinkpad
+ of the queue and set to the active state.
+
+
+4) .. ! myvideodecoder ! queue ! myvideosink 
+
+ myvideodecoder has negotiated a bufferpool with the downstream myvideosink
+ to handle buffers of size 320x240. It has now detected a change in the 
+ video format and need to renegotiate to a resolution of 640x480. This
+ requires it to negotiate a new bufferpool with a larger buffersize.
+
+ When myvideodecoder needs to get the bigger buffer, it starts the 
+ negotiation of a new bufferpool. It queries a bufferpool from downstream,
+ reconfigures it with the new configuration (which includes the bigger buffer
+ size) and it then sets the bufferpool to active. The old pool is inactivated
+ and unreffed, which causes the old format to drain.
+
+ It then uses the new bufferpool for allocating new buffers of the new 
+ dimension.
+
+ If at some point, the decoder wants to switch to a lower resolution again,
+ it can choose to use the current pool (which has buffers that are larger
+ than the required size) or it can choose to renegotiate a new bufferpool.
+
+
+5) .. ! myvideodecoder ! videoscale ! myvideosink 
+
+ myvideosink is providing a bufferpool for upstream elements and wants to
+ change the resolution.
+
+ myvideosink sends a RECONFIGURE event upstream to notify upstream that a
+ new format is desirable. upstream elements try to negotiate a new format
+ and bufferpool before pushing out a new buffer. The old bufferpools are
+ drained in the regular way.
+
index bdbdbe7..ee4b5aa 100644 (file)
@@ -12,9 +12,6 @@ Caps are exposed on the element pads using the _get_caps() pad function.
 This function describes the possible types that the pad can handle or
 produce (see part-pads.txt and part-negotiation.txt).
 
-Caps are also attached to buffers to describe to content of the data
-pointed to be the buffer.
-
 Various methods exist to work with the media types such as substracting
 or intersecting.
 
index 783b688..73f18bf 100644 (file)
@@ -99,8 +99,7 @@ Negotiation
 Typical (re)negotiation of the transform element in push mode always goes from
 sink to src, this means triggers the following sequence:
  
-  - the sinkpad receives a buffer with new caps, this triggers the setcaps
-    function on the sinkpad before handing the buffer to transform.
+  - the sinkpad receives a new caps event.
   - the transform function figures out what it can convert these caps to.
   - try to see if we can configure the caps unmodified on the peer. We need to
     do this because we prefer to not do anything.
@@ -111,10 +110,10 @@ sink to src, this means triggers the following sequence:
 We call this downstream negotiation (DN) and it goes roughly like this:
 
                sinkpad              transform               srcpad
-     setcaps()    |                    |                      |
+     CAPS event   |                    |                      |
      ------------>|  find_transform()  |                      |
                   |------------------->|                      |
-                  |                    |       setcaps()      |
+                  |                    |       CAPS event     |
                   |                    |--------------------->|
                   | <configure caps> <-|                      |
 
@@ -148,8 +147,7 @@ assume nothing is going to write to the buffer and we don't enforce a writable
 buffer for the transform_ip function, when present.
 
 One common function that we need for the transform element is to find the best
-transform from one format (src) to another (dest). Since the function is
-bidirectional, we will use the src->dest negotiation. Some requirements of this
+transform from one format (src) to another (dest). Some requirements of this
 function are:
 
    - has a fixed src caps
@@ -198,18 +196,14 @@ state. We can identify these steady states:
       - in-place: buffers are modified in-place, this means that the input
        buffer is modified to produce a new output buffer. This requires the
        input buffer to be writable. If the input buffer is not writable, a new
-       buffer has to be allocated with pad-alloc. (SCI)
+       buffer has to be allocated from the bufferpool. (SCI)
 
                sinkpad              transform               srcpad
        chain()    |                    |                      |
      ------------>|   handle_buffer()  |                      |
                   |------------------->|                      |
                   |                    |   [!writable]        |
-                  |                    |     pad-alloc()      |
-                  |                    |--------------------->|
-                  |  [caps-changed]  .-|  [caps-changed]      |
-                  |   <reconfigure>  | |     setcaps()        |
-                  |                  '>|--------------------->|
+                  |                    |   alloc buffer       |
                   |                  .-|                      |
                   |  <transform_ip>  | |                      |
                   |                  '>|                      |
@@ -217,18 +211,15 @@ state. We can identify these steady states:
                   |                    |--------------------->|
                   |                    |                      |
 
-      - copy transform: a new output buffer is allocated with pad-alloc and data
-        from the input buffer is transformed into the output buffer. (SCC)
+      - copy transform: a new output buffer is allocate from the bufferpool
+        and data from the input buffer is transformed into the output buffer.
+        (SCC)
 
                sinkpad              transform               srcpad
        chain()    |                    |                      |
      ------------>|   handle_buffer()  |                      |
                   |------------------->|                      |
-                  |                    |     pad_alloc()      |
-                  |                    |--------------------->|
-                  |  [caps-changed]  .-|   [caps-changed]     |
-                  |   <reconfigure>  | |      setcaps()       |
-                  |                  '>|--------------------->|
+                  |                    |     alloc buffer     |
                   |                  .-|                      |
                   |     <transform>  | |                      |
                   |                  '>|                      |
@@ -250,11 +241,7 @@ state. We can identify these steady states:
      ------------>|   handle_buffer()  |                      |
                   |------------------->|                      |
                   |                    | [!writable || !size] |
-                  |                    |     pad-alloc        |
-                  |                    |--------------------->|
-                  |  [caps-changed]  .-|  [caps-changed]      |
-                  |   <reconfigure>  | |     setcaps()        |
-                  |                  '>|--------------------->|
+                  |                    |     alloc buffer     |
                   |                  .-|                      |
                   |  <transform_ip>  | |                      |
                   |                  '>|                      |
@@ -267,146 +254,41 @@ state. We can identify these steady states:
        the same as the case with the same-caps negotiation. (DCC)
  
 We can immeditatly observe that the copy transform states will need to
-allocate a buffer from a downstream element using pad-alloc. When the transform
-element is receiving a non-writable buffer in the in-place state, it will also
-need to perform a pad-alloc. There is no reason why the passthrough state would
-perform a pad-alloc. This is important because upstream re-negotiation can only
-happen when the transform uses pad-alloc for all outgoing buffers.
+allocate a new buffer from the bufferpool. When the transform element is
+receiving a non-writable buffer in the in-place state, it will also
+need to perform an allocation. There is no reason why the passthrough state would
+perform an allocation.
 
 This steady state changes when one of the following actions occur:
 
   - the sink pad receives new caps, this triggers the above downstream
     renegotation process, see above for the flow.
-  - the src pad is instructed to produce new caps because of new caps from
-    pad-alloc, this only happens when the transform calls pad-alloc on the
-    srcpad in order to produce a new output buffer.
   - the transform element wants to renegotiate (because of changed properties,
     for example). This essentially clears the current steady state and
-    triggers the downstream and upstream renegotiation process.
-
-Parallel to the downstream negotiation process there is an upstream negotiation
-process. The handling and proxy of buffer-alloc is the most comple part of the
-transform element. This upstream negotiation process has 3 cases: (UN)
-
-  - upstream calls the buffer-alloc function of the transform sinkpad and this
-    call is proxied downstream (UNP)
-  - upstream calls the buffer-alloc function of the transform sinkpad, the
-    transform does not proxy the call but returns a buffer itself (UNU)
-  - the transform calls the pad-alloc function downstream to allocate a new
-    output buffer (but not because of a proxied buffer-alloc) (UNA)
-
-The case where the pad-alloc is called because an output buffer must be
-generated in the chain function is handled above in the copy-transform and the
-in-place transform when the input buffer is not writable or the input buffer
-size is smaller than the output size.
-
-We are left with the last case (proxy an incomming pad-alloc or not). We have 2
-possibilities here:
-
-   - pad-alloc is called with the same caps as are currently being handled by
-     the transform on the sinkcaps. Note that this will only be true when the
-     transform element is completely negotiated because of data processing, see
-     above. Then the element is not yet negotiated, we proceed with the case
-     where sinkcaps are different from thos in the buffer-alloc.
-     
-     * If the transform is using copy-transform, we don't need to proxy because
-       we will call pad-alloc when generating an output buffer. 
-
-               sinkpad              transform               srcpad
-   buffer_alloc() |                    |                      |
-  --------------->|                    |                      |
-                  |                    |                      |
-                  |-. [same caps &&    |                      |
-   return default | |  copy-trans]     |                      |
-     <------------|<'                  |                      |
-                  |                    |                      |
-
-     * If the transform is using in-place and insize < outsize, we proxy
-       the pad-alloc with the srccaps. If the caps are unmodified, we proxy
-       the buffer after changing the caps and size. 
-
-               sinkpad              transform               srcpad
-   buffer_alloc() |                    |                      |
-  --------------->|                    |                      |
-                  |   [same caps &&    |                      |
-                  |    in-place]       |                      |
-                  |------------------->|    pad_alloc()       |
-                  |                    |--------------------->|
-                  | [caps unchanged]   |                      |
-      return      |  adjust_buffer     |                      |
-    <----------------------------------|                      |
-                  |                    |                      |
-                  |                    |                      |
-
-     * If the transform is using in-place and insize < outsize, we proxy
-       the pad-alloc with the srccaps. If the caps are modified find the best
-       transform from these new caps and return a buffer of this size/caps
-       instead. 
-
-               sinkpad              transform               srcpad
-   buffer_alloc() |                    |                      |
-  --------------->|                    |                      |
-                  |   [same caps &&    |                      |
-                  |    in-place]       |    pad-alloc()       |
-                  |------------------------------------------>|
-                  | [caps changed]   .-|                      |
-                  | find_transform() | |                      |
-      return      |                  '>|                      |
-    <----------------------------------|                      |
-                  |                    |                      |
+    triggers the downstream and upstream renegotiation process. This situation
+    also happens when a RECONFIGURE event was received on the transform srcpad.
 
-     * If the transform is using in-place and insize >= outsize, we cannot proxy
-       the pad-alloc because the resulting buffer would be too small to return
-       anyway. 
 
-     * If the transform is using passthrough, we can proxy the pad-alloc to the
-       source pad. If the caps change, find the best transform and return a
-       buffer of those caps and size instead.
+Allocation
+~~~~~~~~~~
 
-               sinkpad              transform               srcpad
-   buffer_alloc() |                    |                      |
-  --------------->| [same caps &&      |                      |
-                  |  passtrough]       |     pad-alloc()      |
-                  |------------------------------------------>|
-                  | [caps changed]   .-|                      |
-                  | find_transform() | |                      |
-      return      |                  '>|                      |
-    <----------------------------------|                      |
-                  |                    |                      |
+After the transform element is configured with caps, a bufferpool needs to be
+negotiated to perform the allocation of buffers. We habe 2 cases:
 
-   - pad-alloc is called with different caps than are currently being handled by
-     the transform on the sinkcaps we have to try to negotiate a new
-     configuration for the transform element.
+  - The element is operating in passthrough we don't need to allocate a buffer
+    in the transform element.
+  - The element is not operating in passthrough and needs to allocation an
+    output buffer.
 
-      * we perform the standard way to finding a best transform using
-        find_transform() and we call the pad-alloc function with these caps.
-       If we get different caps from pad-alloc, we find the best format to
-       transform these to and return those caps instead.
+In case 1, we don't query and configure a pool. We let upstream decide if it
+wants to use a bufferpool and then we will proxy the bufferpool from downstream
+to upstream.
 
+In case 2, we query and set a bufferpool on the srcpad that will be used for
+doing the allocations.
 
-               sinkpad              transform               srcpad
-   buffer_alloc() |                    |                      |
-  --------------->|                    |                      |
-                  |  find_transform()  |                      |
-                  |------------------->|                      |
-                  |                    |  pad-alloc()         |
-                  |                    |--------------------->|
-      return      | [caps unchanged]   |                      |
-    <----------------------------------|                      |
-                  |                    |                      |
-                  | [caps changed]   .-|                      |
-                  | find_transform() | |                      |
-      return      |                  '>|                      |
-    <----------------------------------|                      |
-                  |                    |                      |
-
-In order to perform passthrough buffer-alloc or pad-alloc, we need to be able
-to get the size of the output buffer after the transform.
-
-For passthrough buffer-alloc, this is trivial: the input size equals the output
-size.
-
-For the copy transform or the in-place transform we need additional function to
+In order to perform allocation, we need to be able to get the size of the
+output buffer after the transform.  We need additional function to
 retrieve the size. There are two functions:
 
   - transform_size()
@@ -424,62 +306,3 @@ retrieve the size. There are two functions:
 
  For performance reasons, the mapping between caps and size is kept in a cache.
 
-
-Issues
-~~~~~~
-
-passthrough and in-place transforms (with writable buffers) never need to
-perform a pad-alloc on the srcpad. This means that if upstream negotiation
-happens, the transform element will never know about it.
-
-The transform element will keep therefore track of the allocation pattern of
-the peer elements. We can see the following cases:
-
-- upstream peer calls buffer-alloc on the sinkpad of the transform. In some
-  cases (see above) this call gets proxied or not.
-
-- upstream peer does never call buffer-alloc.
-
-We will keeps state about this allocation pattern and perform the following in
-each case respectively:
-
-- Upstream calls buffer-alloc: In passthrough and (some) in-place we proxy
-  this call onto the downstream element. If the caps are changed, we mark
-  a flag that we will require a new pad-alloc for the output of the next
-  output buffer.
-
-- upstream peer does not call buffer-alloc: We always perform a pad-alloc
-  when processing buffers. We can further optimize by only looking at the
-  returned caps instead of doing a full, needless buffer copy.
-
-
-Use cases
-~~~~~~~~~
-
- videotestsrc ! ximagesink
-  
-   - resizing happens because videotestsrc performs pad-alloc.
-
- videotestsrc peer-alloc=0 ! ximagesink
-
-   - resizing cannot happen because videotestsrc never performs pad-alloc.
-
- videotestsrc ! videoscale ! ximagesink
-  
-   - videoscale is initially configured in passthrough mode, pad-alloc from
-     videotestsrc is proxied through videoscale.
-   - pad-alloc will renegotiate a new size in videotestsrc.
-
- videotestsrc peer-alloc=0 ! videoscale ! ximagesink
-  
-   - videoscale is initially configured in passthrough mode.
-   - videoscale performs pad-alloc because no buffer-alloc is called on the
-     sinkpad
-   - resizing the videosink makes videoscale perform the scaling.
-   
-Problematic
-~~~~~~~~~~~
-
-    filesrc location=~/media/moveyourfeet.mov ! decodebin !
-    ffmpegcolorspace ! videoscale ! ffmpegcolorspace ! ximagesink -v
-
index c2fd650..78f15c1 100644 (file)
@@ -12,20 +12,63 @@ Different types of events exist to implement various functionalities.
 
   GST_EVENT_FLUSH_START:   data is to be discarded
   GST_EVENT_FLUSH_STOP:    data is allowed again
-  GST_EVENT_EOS:          no more data is to be expected on a pad.
-  GST_EVENT_NEWSEGMENT:    A new group of buffers with common start time  
+  GST_EVENT_CAPS:          Format information about the following buffers
+  GST_EVENT_SEGMENT:       Timing information for the following buffers
   GST_EVENT_TAG:           Stream metadata.
   GST_EVENT_BUFFERSIZE:    Buffer size requirements
+  GST_EVENT_SINK_MESSAGE:  An event turned into a message by sinks
+  GST_EVENT_EOS:          no more data is to be expected on a pad.
   GST_EVENT_QOS:           A notification of the quality of service of the stream
   GST_EVENT_SEEK:          A seek should be performed to a new position in the stream
   GST_EVENT_NAVIGATION:    A navigation event.
   GST_EVENT_LATENCY:       Configure the latency in a pipeline
+  GST_EVENT_STEP:          Stepping event
+  GST_EVENT_RECONFIGURE:   stream reconfigure event
 
   * GST_EVENT_DRAIN:       Play all data downstream before returning.
 
 * not yet implemented, under investigation, might be needed to do still frames
   in DVD.
 
+
+src pads
+--------
+
+A gst_pad_push_event() on a srcpad will first store the event in the sticky
+array before sending the event to the peer pad. If there is no peer pad, the
+gst_pad_push_event() function returns NOT_LINKED.
+
+Note that the behaviour is not influenced by a flushing pad.
+
+FLUSH_START and FLUSH_STOP events are dropped on blocked pads.
+
+sink pads
+---------
+
+A gst_pad_send_event() on a sinkpad will check the new event against the
+existing event. If they are different, the new event is stored as a pending
+event. If the events are the same, nothing changes.
+
+When the pad is flushing, the _send_event() function returns WRONG_STATE
+immediately.
+
+The event function is then called for all pending events. If the function
+returns success, the pending event is copied to the active events, else the
+pending event is removed and the current active event is unchanged.
+
+This ensures that the event function is never called for flushing pads and that
+the sticky array only contains events for which the event function returned
+success.
+
+
+pad link
+--------
+
+When linking pads, all the sticky events from the srcpad are copied to the
+pending array on the sinkpad. The pending events will be sent to the event
+function of the sinkpad on the next event or buffer.
+
+
 FLUSH_START/STOP
 ~~~~~~~~~~~~~~~~
 
@@ -57,11 +100,9 @@ For elements that use the pullrange function, they send both flush events to
 the upstream pads in the same way to make sure that the pullrange function
 unlocks and any pending buffers are cleared in the upstream elements.
 
-A FLUSH_STOP event will also clear any configured synchronisation information
-like NEWSEGMENT events. After a FLUSH_STOP, any element that performs
-synchronisation to the clock will therefore need a NEWSEGMENT event (which makes
-the running_time start from 0 again) and will therefore also need a new
-base_time (see part-clocks.txt and part-synchronisation.txt).
+A FLUSH_START may instruct the pipeline to distribute a new base_time to
+elements so that the running_time is reset to 0. 
+(see part-clocks.txt and part-synchronisation.txt).
 
 
 EOS
@@ -106,43 +147,38 @@ goes to PLAYING.
 A FLUSH_STOP event on an element flushes the EOS state and all pending EOS messages.
 
 
-NEWSEGMENT
-~~~~~~~~~~
+SEGMENT
+~~~~~~~
 
-A newsegment event is sent downstream by an element to indicate that the following
+A segment event is sent downstream by an element to indicate that the following
 group of buffers start and end at the specified positions. The newsegment event
 also contains the playback speed and the applied rate of the stream.
 
 Since the stream time is always set to 0 at start and after a seek, a 0
 point for all next buffer's timestamps has to be propagated through the
-pipeline using the NEWSEGMENT event.
+pipeline using the SEGMENT event.
 
-Before sending buffers, an element must send a NEWSEGMENT event. An element is
-free to refuse buffers if they were not preceeded by a NEWSEGMENT event.
+Before sending buffers, an element must send a SEGMENT event. An element is
+free to refuse buffers if they were not preceeded by a SEGMENT event.
 
-Elements that sync to the clock should store the NEWSEGMENT start and end values
+Elements that sync to the clock should store the SEGMENT start and end values
 and substract the start value from the buffer timestamp before comparing
 it against the stream time (see part-clocks.txt).
 
-An element is allowed to send out buffers with the NEWSEGMENT start time already
+An element is allowed to send out buffers with the SEGMENT start time already
 substracted from the timestamp. If it does so, it needs to send a corrected
-NEWSEGMENT downstream, ie, one with start time 0.
+SEGMENT downstream, ie, one with start time 0.
 
-A NEWSEGMENT event should be generated as soon as possible in the pipeline and
+A SEGMENT event should be generated as soon as possible in the pipeline and
 is usually generated by a demuxer or source. The event is generated before 
 pushing the first buffer and after a seek, right before pushing the new buffer.
 
-The NEWSEGMENT event should be sent from the streaming thread and should be
+The SEGMENT event should be sent from the streaming thread and should be
 serialized with the buffers.
 
 Buffers should be clipped within the range indicated by the newsegment event
 start and stop values. Sinks must drop buffers with timestamps out of the
-indicated newsegment range.
-
-If a newsegment arrives at an element not preceeded by a flush event, the 
-streamtime of the pipeline will not be reset to 0 so any element that syncs
-to the clock must use the stop times of the previous newsegment events to
-make the buffer timestamps increasing (part-segments.txt).
+indicated segment range.
 
 
 TAG
index ad3951a..e1514d4 100644 (file)
@@ -39,7 +39,7 @@ These pads are stored in a single GList within the Element.  Several counters
 are kept in order to allow quicker determination of the type and properties of
 a given Element.
 
-Pads may be added to an element with _add_pad.  Retrieval is via _get_pad(),
+Pads may be added to an element with _add_pad.  Retrieval is via _get_static_pad(),
 which operates on the name of the Pad (the unique key).  This means that all
 Pads owned by a given Element must have unique names.
 A pointer to the GList of pads may be obtained with _iterate_pads. 
index b846072..473dc7f 100644 (file)
@@ -89,12 +89,3 @@ Flags
 
 Each object in the GStreamer object hierarchy can have flags associated with it,
 which are used to describe a state or a feature of the object.
-GstObject has flags to mark its lifecycle: FLOATING and DISPOSING.
-
-
-Class signals
-~~~~~~~~~~~~~
-
-It is possible to know when a new object is loaded by connecting to the
-GstObjectClass signal. This feature is not very much used and might be removed
-at some point.
index 637d584..464e3a0 100644 (file)
@@ -195,13 +195,11 @@ capture pipelines.
   prerolled.
 
 
-State Changes revised
-~~~~~~~~~~~~~~~~~~~~~
+State Changes
+~~~~~~~~~~~~~
 
-As a first step in a generic solution we propose to modify the state changes so
-that no sink is set to PLAYING before it is prerolled.
-
-In order to do this, the pipeline (at the GstBin level) keeps track of all
+A Sink is never set to PLAYING before it is prerolled. In order to do this, the
+pipeline (at the GstBin level) keeps track of all
 elements that require preroll (the ones that return ASYNC from the state
 change). These elements posted a ASYNC_START message without a matching
 ASYNC_DONE message.
@@ -221,18 +219,12 @@ NO_PREROLL element to PLAYING. This operation has to be performed in the
 separate async state change thread (like the one currently used for going from
 PAUSED->PLAYING in a non-live pipeline).
 
-implications:
-
- - the current async_play vmethod in basesink can be deprecated since we now
-   always call the state change function when going from PAUSED->PLAYING. We
-   keep this method however to remain backward compatible.
-
 
 Latency compensation
 ~~~~~~~~~~~~~~~~~~~~
 
-As an extension to the revised state changes we can perform latency calculation
-and compensation before we proceed to the PLAYING state. 
+Latency calculation and compensation is performed before the pipeline proceeds to
+the PLAYING state. 
 
 When the pipeline collected all ASYNC_DONE messages it can calculate the global
 latency as follows:
@@ -279,8 +271,8 @@ the same for all sinks, all sinks will render data relatively synchronised.
 Flushing a playing pipeline
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-Using the new state change mechanism we can implement resynchronisation after an
-uncontrolled FLUSH in (part of) a pipeline. Indeed, when a flush is performed on
+We can implement resynchronisation after an uncontrolled FLUSH in (part of) a
+pipeline in the same way. Indeed, when a flush is performed on
 a PLAYING live element, a new base time must be distributed to this element.
 
 A flush in a pipeline can happen in the following cases:
diff --git a/docs/design/part-memory.txt b/docs/design/part-memory.txt
new file mode 100644 (file)
index 0000000..bcb6156
--- /dev/null
@@ -0,0 +1,140 @@
+GstMemory
+---------
+
+This document describes the design of the memory objects.
+
+GstMemory objects are usually added to GstBuffer objects and contain the
+multimedia data passed around in the pipeline.
+
+Requirements
+~~~~~~~~~~~~
+
+ - It must be possible to have different memory allocators
+ - It must be possible to efficiently share memory objects, copy, span
+   and trim.
+
+
+Allocators
+~~~~~~~~~~
+
+ GstMemory objects are created by allocators. Allocators are registered to the
+ memory system with a set of methods contained in a GstMemoryInfo structure.
+
+  struct _GstMemoryInfo {
+    GstMemoryAllocFunction    alloc;
+    GstMemoryGetSizesFunction get_sizes;
+    GstMemoryResizeFunction   resize;
+    GstMemoryMapFunction      map;
+    GstMemoryUnmapFunction    unmap;
+    GstMemoryFreeFunction     free;
+
+    GstMemoryCopyFunction     copy;
+    GstMemoryShareFunction    share;
+    GstMemoryIsSpanFunction   is_span;
+
+    gpointer user_data;
+  };
+
+ After an allocator is registerd, new GstMemory can be created with 
+
+   GstMemory * gst_memory_allocator_alloc (const GstMemoryAllocator * allocator,
+                                           gsize maxsize, gsize align);
+
+ The GstMemory object is a refcounted object that must be freed with
+ gst_memory_unref ().
+
+ It is also possible to create a new GstMemory object that wraps existing
+ memory with:
+  
+   GstMemory * gst_memory_new_wrapped  (GstMemoryFlags flags, gpointer data,
+                                        GFreeFunc free_func, gsize maxsize,
+                                        gsize offset, gsize size);
+
+Lifecycle
+~~~~~~~~~
+
+GstMemory objects are refcounted. When the GstMemory object is first created, it
+has a refcount of 1. 
+
+Each variable holding a reference to the GstMemory object is responsible for
+updating the refcount.
+
+The refcount determines the writability of the object. If the refcount > 1, it is
+by definition used by multipled objects and thus cannot be safely written to.
+
+When the refcount reaches 0, and thus no objects hold a reference anymore, we
+can free the memory. The GstMemoryFreeFunction of the allocator will be called
+to cleanup the memory.
+
+
+Memory layout
+~~~~~~~~~~~~~
+
+ GstMemory manages a memory region. The accesible part of the managed region is
+ defined by an offset relative to the start of the region and a size. This
+ means that the managed region can be larger than what is visible to the user of
+ GstMemory API.
+
+ Schematically, GstMemory has a pointer to a memory region of _maxsize_. The area
+ starting from _offset_ and _size_ is accessible.
+
+               memory
+    GstMemory  ->*----------------------------------------------------*
+                 ^----------------------------------------------------^ 
+                                   maxsize
+                      ^--------------------------------------^         
+                     offset            size
+
+ The current properties of the accessible memory can be retrieved with:
+
+   gsize       gst_memory_get_sizes  (GstMemory *mem, gsize *maxsize);
+
+ The offset and size can be changed with:
+
+   void        gst_memory_resize     (GstMemory *mem, gsize offset, gsize size);
+
+ The visible memory region can currently only be made smaller.
+
+ The memory object is always readable. The memory block is writable when:
+
+  - the refcount is exactly 1
+  - the memory object has no parent, or if it has a parent, the parent is
+    writable.
+  - the memory object is not marked as READONLY.
+
+
+Data Access
+~~~~~~~~~~~
+
+ Access to the memory region is always controlled with a map and unmap method
+ call. This allows the implementation to monitor the access patterns or set up
+ the required memory mappings when needed.
+
+ Mapping a memory region requires the caller to specify the access method: READ
+ and/or WRITE. For write access, the GstMemory object must be writable.
+
+ After the data has been accessed in the object, the unmap call must be
+ performed. The call will update the new memory size with the specified size.
+
+
+Copy
+~~~~
+
+ A GstMemory copy can be made with the gst_memory_copy() call. Normally,
+ allocators will implement a custom version of this function to make a copy of
+ the same kind of memory as the original one.
+
+ This is what the fallback version of the copy function will do, albeit slower
+ than what as custom implementation could do.
+
+ The copy operation is only required to copy the visible range of the memory
+ block.
+
+
+Share
+~~~~~
+
+ A memory region can be shared between GstMemory object with the
+ gst_memory_share() operation. 
+
+
index a0eef63..8e79be9 100644 (file)
@@ -134,3 +134,16 @@ GST_MESSAGE_REQUEST_STATE:
   are in. A typical use case would be an audio sink that requests the pipeline
   to pause in order to play a higher priority stream.
 
+GST_MESSAGE_STEP_START:
+
+  A Stepping operation has started.
+
+GST_MESSAGE_QOS:
+
+  A buffer was dropped or an element changed its processing strategy for
+  Quality of Service reasons.
+
+GST_MESSAGE_PROGRESS:
+
+  A progress message was posted. Progress messages inform the application about
+  the state of asynchronous operations.
diff --git a/docs/design/part-meta.txt b/docs/design/part-meta.txt
new file mode 100644 (file)
index 0000000..071ddc5
--- /dev/null
@@ -0,0 +1,388 @@
+GstMeta
+-------
+
+This document describes the design for arbitrary per-buffer metadata.
+
+Buffer metadata typically describes the lowlevel properties of the buffer
+content. These properties are typically not negotiated with caps but they are
+negotiated in the bufferpools.
+
+Some examples of metadata:
+
+ - timestamp, duration
+ - offset, offset_end
+ - interlacing information
+ - video alignment, cropping, panning information
+ - extra container information such as granulepos, ...
+ - extra global buffer properties
+
+
+Requirements
+~~~~~~~~~~~~
+
+ - It must be fast
+    * allocation, free, low fragmentation
+    * access to the metadata fields, preferably not much slower than directly
+      accessing a C structure field
+ - It must be extensible. Elements should be able to add new arbitrary metadata
+   without requiring much effort. Also new metadata fields should not break API
+   or ABI.
+ - It plays nice with subbuffers. When a subbuffer is created, the various
+   buffer metadata should be copied/updated correctly.
+ - We should be able to negotiate metadata between elements
+
+Use cases
+---------
+
+ * Video planes
+
+ Video data is sometimes allocated in non-contiguous planes for the Y and the UV
+ data. We need to be able to specify the data on a buffer using multiple
+ pointers in memory. We also need to be able to specify the stride for these
+ planes.
+
+ * Extra buffer data
+
+ Some elements might need to store extra data for a buffer. This is typically
+ done when the resources are allocated from another subsystem such as OMX or
+ X11. 
+
+ * Processing information
+
+ Pan and crop information can be added to the buffer data when the downstream
+ element can understand and use this metadata. An imagesink can, for example,
+ use the pan and cropping formation when it blits the image on the screen
+ with little overhead.
+
+
+GstMeta
+~~~~~~~
+
+A GstMeta is a structure as follows:
+
+  struct _GstMeta {
+    const GstMetaInfo *info;    /* tag and info for the meta item */
+  };
+
+The purpose of the this structure is to serve as a common header for all metadata
+information that we can attach to a buffer. Specific metadata, such as timing metadata,
+will have this structure as the first field. For example:
+
+  struct _GstMetaTiming {
+    GstMeta        meta;        /* common meta header */
+    GstClockTime   dts;         /* decoding timestamp */
+    GstClockTime   pts;         /* presentation timestamp */
+    GstClockTime   duration;    /* duration of the data */
+    GstClockTime   clock_rate;  /* clock rate for the above values */
+  };
+
+Or another example for the video memory regions that consists of both fields and
+methods.
+
+
+ #define GST_VIDEO_MAX_PLANES 4
+
+ struct GstMetaVideoPlane {
+   gsize           offset;   /* offset in the buffer memory region of the
+                              * first pixel. */
+   gint            stride;   /* stride of the image lines. Can be negative when
+                              * the image is upside-down */
+ };
+
+ struct GstMetaVideo {
+   GstMeta       meta
+
+   GstMetaVideoFlags flags
+
+   guint               n_planes;
+   GstVideoPlane       plane[GST_VIDEO_MAX_PLANES];
+
+   gpointer (*map)     (GstMetaVideo *meta, guint plane, gint *stride,
+                        GstMapflags flags);
+   gboolean (*unmap)   (GstMetaVideo *meta, guint plane, gpointer data);
+ };
+
+ gpointer gst_meta_video_map   (GstMetaVideo *meta, guint plane, gint *stride,
+                                GstMapflags flags);
+ gboolean gst_meta_video_unmap (GstMetaVideo *meta, guint plane, gpointer data);
+
+GstMeta derived structures define the API of the metadata. The API can consist of
+fields and/or methods. It is possible to have different implementations for the
+same GstMeta structure.
+
+The implementation of the GstMeta api would typically add more fields to the
+public structure that allow it to implement the API.
+
+GstMetaInfo will point to more information about the metadata and looks like this:
+
+  struct _GstMetaInfo {
+    GQuark                     api;       /* api name */
+    GType                      type;      /* implementation type */
+    gsize                      size;      /* size of the structure */
+
+    GstMetaInitFunction        init_func;
+    GstMetaFreeFunction        free_func;
+    GstMetaCopyFunction        copy_func;
+    GstMetaTransformFunction   transform_func;
+  };
+
+api will contain a GQuark of the metadata api. A repository of registered MetaInfo
+will be maintained by the core. We will register some common metadata structures
+in core and some media specific info for audio/video/text in -base. Plugins can
+register additional custom metadata.
+
+For each implementation of api, there will thus be a unique GstMetaInfo. In the
+case of metadata with a well defined API, the implementation specific init
+function will setup the methods in the metadata structure. A unique GType will
+be made for each implementation and stored in the type field.
+
+Along with the metadata description we will have functions to initialize/free (and/or refcount)
+a specific GstMeta instance. We also have the possibility to add a custom
+transform function that can be used to modify the metadata when a transformation
+happens.
+
+There are no explicit methods to serialize and deserialize the metadata. Since
+each type has a GType, we can reuse the GValue transform functions for this.
+
+The purpose of the separate MetaInfo is to not have to carry the free/init functions in
+each buffer instance but to define them globally. We still want quick access to the info
+so we need to make the buffer metadata point to the info.
+
+Technically we could also specify the field and types in the MetaInfo and
+provide a generic API to retrieve the metadata fields without the need for a
+header file. We will not do this yet.
+
+Allocation of the GstBuffer structure will result in the allocation of a memory region
+of a customizable size (512 bytes). Only the first sizeof (GstBuffer) bytes of this
+region will initially be used. The remaining bytes will be part of the free metadata
+region of the buffer. Different implementations are possible and are invisible
+in the API or ABI.
+
+The complete buffer with metadata could, for example, look as follows:
+
+                         +-------------------------------------+
+GstMiniObject            |     GType (GstBuffer)               |
+                         |     refcount, flags, copy/disp/free |
+                         +-------------------------------------+
+GstBuffer                |     caps, parent, pool              |
+                         +.....................................+
+                         |     next                           ---+
+                      +- |     info                           ------> GstMetaInfo
+GstMetaTiming         |  |                                     | |
+                      |  |     dts                             | |
+                      |  |     pts                             | |
+                      |  |     duration                        | |
+                      +- |     clock_rate                      | |
+                         + . . . . . . . . . . . . . . . . . . + |
+                         |     next                           <--+
+GstMetaVideo       +- +- |     info                           ------> GstMetaInfo
+                   |  |  |                                     | |
+                   |  |  |     flags                           | |
+                   |  |  |     n_planes                        | |
+                   |  |  |     planes[]                        | |
+                   |  |  |     map                             | |
+                   |  |  |     unmap                           | |
+                   +- |  |                                     | |
+                      |  |     private fields                  | |
+GstMetaVideoImpl      |  |     ...                             | |
+                      |  |     ...                             | |
+                      +- |                                     | |
+                         + . . . . . . . . . . . . . . . . . . + .
+                         .                                       .
+
+
+API examples
+~~~~~~~~~~~~
+
+Buffers are created using the normal gst_buffer_new functions. The standard fields
+are initialized as usual. A memory area that is bigger than the structure size
+is allocated for the buffer metadata.
+
+  gst_buffer_new ();
+
+After creating a buffer, the application can set caps and add metadata
+information. 
+
+To add or retrieve metadata, a handle to a GstMetaInfo structure needs to be
+obtained. This defines the implementation and API of the metadata. Usually, a
+handle to this info structure can be obtained by calling a public _get_info()
+method from a shared library (for shared metadata).
+
+The following defines can usually be found in the shared .h file.
+
+  GstMetaInfo * gst_meta_timing_get_info();
+  #define GST_META_TIMING_INFO  (gst_meta_timing_get_info())
+
+Adding metadata to a buffer can be done with the gst_buffer_add_meta() call.
+This function will create new metadata based on the implementation specified by
+the GstMetaInfo. It is also possible to pass a generic pointer to the add_meta()
+function that can contain parameters to initialize the new metadata fields.
+
+Retrieving the metadata on a buffer can be done with the
+gst_buffer_meta_get() method. This function retrieves an existing metadata
+conforming to the API specified in the given info. When no such metadata exists,
+the function will return NULL.
+
+  GstMetaTiming *timing;
+
+  timing = gst_buffer_get_meta (buffer, GST_META_TIMING_INFO);
+
+Once a reference to the info has been obtained, the associated metadata can be
+added or modified on a buffer.
+
+  timing->timestamp = 0;
+  timing->duration = 20 * GST_MSECOND;
+
+Other convenience macros can be made to simplify the above code:
+
+ #define gst_buffer_get_meta_timing(b) \
+    ((GstMetaTiming *) gst_buffer_get_meta ((b), GST_META_TIMING_INFO)
+
+This makes the code look like this:
+
+  GstMetaTiming *timing;
+
+  timing = gst_buffer_get_meta_timing (buffer);
+  timing->timestamp = 0;
+  timing->duration = 20 * GST_MSECOND;
+To iterate the different metainfo structures, one can use the
+gst_buffer_meta_get_next() methods.
+
+ GstMeta *current = NULL;
+
+ /* passing NULL gives the first entry */ 
+ current = gst_buffer_meta_get_next (buffer, current);
+
+ /* passing a GstMeta returns the next */
+ current = gst_buffer_meta_get_next (buffer, current);
+
+
+Memory management
+~~~~~~~~~~~~~~~~~
+
+* allocation
+
+  We initially allocate a reasonable sized GstBuffer structure (say 512 bytes).
+
+  Since the complete buffer structure, including a large area for metadata, is
+  allocated in one go, we can reduce the number of memory allocations while still
+  providing dynamic metadata.
+
+  When adding metadata, we need to call the init function of the associated
+  metadata info structure. Since adding the metadata requires the caller to pass
+  a handle to the info, this operation does not require table lookups.
+
+  Per-metadata memory initialisation is needed because not all metadata is
+  initialized in the same way. We need to, for example, set the timestamps to
+  NONE in the MetaTiming structures.
+
+  The init/free functions can also be used to implement refcounting for a metadata
+  structure. This can be useful when a structure is shared between buffers.
+
+  When the free_size of the GstBuffer is exhausted, we will allocate new memory
+  for each newly added Meta and use the next pointers to point to this. It
+  is expected that this does not occur often and we might be able to optimize
+  this transparently in the future.
+
+* free
+
+  When a GstBuffer is freed, we potentially might have to call a custom free
+  function on the metadata info. In the case of the Memory metadata, we need to
+  call the associated free function to free the memory.
+  
+  When freeing a GstBuffer, the custom buffer free function will iterate all of
+  the metadata in the buffer and call the associated free functions in the
+  MetaInfo associated with the entries. Usually, this function will be NULL.
+
+
+Serialization
+~~~~~~~~~~~~~
+
+When buffer should be sent over the wire or be serialized in GDP, we need a way
+to perform custom serialization and deserialization on the metadata.
+
+for this we can use the GValue transform functions.
+
+
+Transformations
+~~~~~~~~~~~~~~~
+
+After certain transformations, the metadata on a buffer might not be relevant
+anymore.
+
+Consider, for example, metadata that lists certain regions of interest
+on the video data. If the video is scaled or rotated, the coordinates might not
+make sense anymore. A transform element should be able to adjust or remove the
+associated metadata when it becomes invalid. 
+
+We can make the transform element aware of the metadata so that it can adjust or
+remove in an intelligent way. Since we allow arbitrary metadata, we can't do
+this for all metadata and thus we need some other way.
+
+One proposition is to tag the metadata type with keywords that specify what it
+functionally refers too. We could, for example, tag the metadata for the regions
+of interest with a tag that notes that the metadata refers to absolute pixel
+positions. A transform could then know that the metadata is not valid anymore
+when the position of the pixels changed (due to rotation, flipping, scaling and
+so on).
+
+
+Subbuffers
+~~~~~~~~~~
+
+Subbuffers are implemented with a generic copy. Parameters to the copy
+are the offset and size. This allows each metadata structure to implement the
+actions needed to update the metadata of the subbuffer. 
+
+It might not make sense for some metadata to work with subbuffers. For example
+when  we take a subbuffer of a buffer with a video frame, the GstMetaVideo
+simply becomes invalid and is removed from the new subbuffer.
+
+
+Relationship with GstCaps
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The difference between GstCaps, used in negotiation, and the metadata is not
+clearly defined. 
+
+We would like to think of the GstCaps containing the information needed to
+functionally negotiate the format between two elements. The Metadata should then
+only contain variables that can change between each buffer.
+
+For example, for video we would have width/height/framerate in the caps but then
+have the more technical details, such as stride, data pointers, pan/crop/zoom
+etc in the metadata.
+
+A scheme like this would still allow us to functionally specify the desired
+video resolution while the implementation details would be inside the metadata.
+
+
+Compatibility
+~~~~~~~~~~~~~
+
+We need to make sure that elements exchange metadata that they both understand,
+This is particulary important when the metadata describes the data layout in
+memory (such as strides).
+
+We would like to use the bufferpool negotiation system to negotiate the possible
+metadata that can be exchanged between elements.
+
+When deciding the allocation properties, we will also negotiate the buffer
+metadata structures that we can exchange.
+
+
+Notes
+~~~~~
+
+Some structures that we need to be able to add to buffers.
+
+* Clean Aperture
+* Arbitrary Matrix Transform
+* Aspect ratio
+* Pan/crop/zoom
+* Video strides
+
+Some of these overlap, we need to find a minimal set of metadata structures that
+allows us to define all use cases.
index 2d8d837..77e3a79 100644 (file)
@@ -26,32 +26,18 @@ negotiation.
 
 The basics of negotiation are as follows:
 
- - GstCaps (see part-caps.txt) are refcounted before they
-   are attached to a buffer to describe the contents of the buffer.
-   It is possible to add a NULL caps to a buffer, this means that the
-   buffer type did not change relative to the previous buffer. If no
-   previous buffer was received by a downstream element, it is free to
-   discard the buffer.
-
- - Before receiving a buffer, an element must check if the datatype of
-   the buffer has changed. The element should reconfigure itself to the
-   new format before processing the buffer data. If the data type on
-   the buffer is not acceptable, the element should refuse the buffer by 
+ - GstCaps (see part-caps.txt) are refcounted before they are pushed as
+   an event to describe the contents of the following buffer.
+
+ - An element should reconfigure itself to the new format received as a CAPS
+   event before processing the following buffers. If the data type in the
+   caps event is not acceptable, the element should refuse the buffer by 
    returning an appropriate GST_FLOW_NOT_NEGOTIATED return value from the
    chain function.
-   The core will automatically call the set_caps function for this purpose
-   when it is installed on the sink or source pad.
-
- - When requesting a buffer from a bufferpool, the prefered type should
-   be passed to the buffer allocation function. After receiving a buffer
-   from a bufferpool, the datatype should be checked again.
-
- - A bufferpool allocation function should try to allocate a buffer of the
-   prefered type. If there is a good reason to choose another type, the
-   alloc function should see if that other type is accepted by the other
-   element, then allocate a buffer of that type and attach the type to the
-   buffer before returning it.
 
+ - Downstream elements can request a format change of the stream by sending a
+   RECONFIGURE event upstream. Upstream elements will renegotiate a new format
+   when they receive a RECONFIGURE event.
 
 The general flow for a source pad starting the negotiation.
 
@@ -60,17 +46,14 @@ The general flow for a source pad starting the negotiation.
               |  accepts?       |
   type A      |---------------->|
               |      yes        |
-              |<----------------|
+              |< - - - - - - - -|
               |                 |
get buffer   |  alloc_buf      |
- from pool    |---------------->| 
with type A  |                 | Create buffer of type A.
             |  send_event()   |
+ send CAPS    |---------------->| Receive type A, reconfigure to
event A      |                 | process type A.
               |                 |
- check type   |<----------------|
- and use A    |                 |
               |  push           |
- push buffer  |---------------->| Receive type A, reconfigure to
- with new type|                 | process type A.
+ push buffer  |---------------->| Process buffer of type A
               |                 |
 
  One possible implementation in pseudo code:
@@ -93,20 +76,14 @@ The general flow for a source pad starting the negotiation.
      if gst_pad_peer_accept_caps (srcpad, fixedcaps)
        # store the caps as the negotiated caps, this will
        # call the setcaps function on the pad
-       gst_pad_set_caps (srcpad, fixedcaps)
+       gst_pad_push_event (srcpad, gst_event_new_caps (fixedcaps))
        break
      endif
    done
  endif
 
- # if the type is different, the buffer will have different caps from
- # the src pad -- setcaps will get called on the pad_push
- buffer = gst_pad_alloc_buffer (srcpad, 0, size, GST_PAD_CAPS (fixedcaps));
- if buffer
-   [fill buffer and push]
- elseif
-   [no buffer, either no peer or no acceptable format found]
- endif
+ buffer = gst_buffer_new_and_alloc (size);
+ [fill buffer and push]
 
 
 The general flow for a sink pad starting a renegotiation.
@@ -116,21 +93,27 @@ The general flow for a sink pad starting a renegotiation.
               |  accepts?       |
               |<----------------| type B
               |      yes        |
-              |---------------->|
+              |- - - - - - - - >|-.
+              |                 | | suggest B caps next
+              |                 |<'
               |                 |
- get buffer   |  alloc_buf      |
- from pool    |---------------->| 
- with type A  |                 | Create buffer of new type B.
+              |   push_event()  |
+  mark      .-|<----------------| send RECONFIGURE event
+ renegotiate| |                 |
+            '>|                 |
+              |   get_caps()    |
+ renegotiate  |---------------->| 
+              |  suggest B      |
+              |< - - - - - - - -|
+              |                 |
+              |  send_event()   |
+ send CAPS    |---------------->| Receive type B, reconfigure to
+ event B      |                 | process type B.
               |                 |
- check type   |<----------------|
- and          |                 |
- reconfigure  |                 |
               |  push           |
- push buffer  |---------------->| Receive type B, reconfigure to
- with new type|                 | process type B.
+ push buffer  |---------------->| Process buffer of type B
               |                 |
 
-             
 
 Use case:
 
@@ -146,25 +129,30 @@ videotestsrc ! xvimagesink
 
   2) When does negotiation happen?
    - before srcpad does a push, it figures out a type as stated in 1), then 
-     it calls the pad alloc function with the type. The sinkpad has to 
-     create a buffer of that type, src fills the buffer and sends it to sink.
+     it pushes a caps event with the type. The sink checks the media type and
+     configures itself for this type.
+   - the source then usually does an ALLOCATION query to negotiate a bufferpool
+     with the sink. It then allocates a buffer from the pool and pushes it to
+     the sink. since the sink accepted the caps, it can create a pool for the
+     format.
    - since the sink stated in 1) it could accept the type, it will be able to
-     create a buffer of the type and handle it.
-   - sink checks media type of buffer and configures itself for this type.
+     handle it.
      
   3) How can sink request another format?
    - sink asks if new format is possible for the source.
-   - sink returns buffer with new type in allocfunction.
-   - src receives buffer with new type, reconfigures and pushes.
-   - sink can always select something it can create and handle since it takes
-     the initiative. src should be able to handle the new type since it said
-     it could accept it.
+   - sink pushes RECONFIGURE event upstream
+   - src receives the RECONFIGURE event and marks renegotiation
+   - On the next buffer push, the source renegotiates the caps and the
+     bufferpool. The sink will put the new new prefered format high in the list
+     of caps it returns from its getcaps function.
 
 videotestsrc ! queue ! xvimagesink
 
-  - queue implements an allocfunction, proxying all calls to its srcpad peer.
   - queue proxies all accept and getcaps to the other peer pad.
-  - queue contains buffers with different types.
+  - queue proxies the bufferpool
+  - queue proxies the RECONFIGURE event
+  - queue stores CAPS event in the queue. This means that the queue can contain
+    buffers with different types.
 
    
 Pull-mode negotiation
@@ -232,7 +220,7 @@ deadlines.
 The pull thread is usually started in the PAUSED->PLAYING state change. We must
 be able to complete the negotiation before this state change happens.
 
-The time to do capsnego, then, is after _check_pull_range() has succeeded,
+The time to do capsnego, then, is after the SCHEDULING query has succeeded,
 but before the sink has spawned the pulling thread.
 
 
@@ -240,7 +228,7 @@ Mechanism
 ^^^^^^^^^
 
 The sink determines that the upstream elements support pull based scheduling by
-calling gst_pad_check_pull_range().
+doing a SCHEDULING query.
 
 The sink initiates the negotiation process by intersecting the results
 of gst_pad_get_caps() on its sink pad and its peer src pad. This is the
@@ -250,8 +238,7 @@ intersection of calling get_allowed_caps() on all of its sink pads. In
 this way the sink element knows the capabilities of the entire pipeline.
 
 The sink element then fixates the resulting caps, if necessary,
-resulting in the flow caps. It notifies the pipeline of the caps by
-calling gst_pad_set_caps() on its sink pad. From now on, the getcaps function
+resulting in the flow caps.  From now on, the getcaps function
 of the sinkpad will only return these fixed caps meaning that upstream elements
 will only be able to produce this format.
 
@@ -269,11 +256,3 @@ function. The state will commit to PAUSED when the first buffer is received in
 the sink. This is needed to provide a consistent API to the applications that
 expect ASYNC return values from sinks but it also allows us to perform the
 remainder of the negotiation outside of the context of the pulling thread.
-
-During dataflow, gst_pad_pull_range() checks the caps on the pulled
-buffer. If they are different from the sink pad's caps, it will return
-GST_FLOW_NOT_NEGOTIATED. Because of the low-latency requirements,
-changing caps in an activate pull-mode pipeline is not supported, as it
-might require e.g. the sound card to reconfigure its hardware buffers,
-and start capsnego again.
-
index e292150..a51471a 100644 (file)
@@ -195,10 +195,9 @@ includes:
   - offset of the data: a media specific offset, this could be samples for audio or
       frames for video.
   - the duration of the data in time.
-  - the media type of the data described with caps, these are key/value pairs that
-      describe the media type in a unique way.
   - additional flags describing special properties of the data such as 
     discontinuities or delta units.
+  - additional arbitrary metadata
 
 When an element whishes to send a buffer to another element is does this using one
 of the pads that is linked to a pad of the other element. In the push model, a 
@@ -208,13 +207,13 @@ is pulled from the peer with the gst_pad_pull_range() function.
 Before an element pushes out a buffer, it should make sure that the peer element
 can understand the buffer contents.  It does this by querying the peer element
 for the supported formats and by selecting a suitable common format. The selected
-format is then attached to the buffer with gst_buffer_set_caps() before pushing
-out the buffer.
+format is then first sent to the peer element with a CAPS event before pushing
+the buffer.
 
-When an element pad receives a buffer, if has to check if it understands the media
-type of the buffer before starting processing it. The GStreamer core does this
-automatically and will call the gst_pad_set_caps() function of the element before
-sending the buffer to the element.
+
+When an element pad receives a CAPS event, it has to check if it understand the
+media type. The element must refuse following buffers if the media type
+preceeding it was not accepted.
 
 Both gst_pad_push() and gst_pad_pull_range() have a return value indicating whether
 the operation succeeded. An error code means that no more data should be sent
@@ -222,12 +221,11 @@ to that pad. A source element that initiates the data flow in a thread typically
 pauses the producing thread when this happens.
 
 A buffer can be created with gst_buffer_new() or by requesting a usable buffer
-from the peer pad using gst_pad_alloc_buffer(). Using the second method, it is
-possible for the peer element to suggest the element to produce data in another 
-format by attaching another media type caps to the buffer.
+from a buffer pool using gst_buffer_pool_acquire_buffer(). Using the second
+method, it is possible for the peer element to implement a custom buffer
+allocation algorithm.
 
-The process of selecting a media type and attaching it to the buffers is called
-caps negotiation.
+The process of selecting a media type is called caps negotiation.
 
 
 Caps
@@ -349,14 +347,18 @@ it accepts the data from filesrc on the sinkpad and starts decoding the compress
 data to raw audio samples.
 
 The mp3 decoder figures out the samplerate, the number of channels and other audio
-properties of the raw audio samples, puts the decoded samples into a Buffer,  
-attaches the media type caps to the buffer and pushes this buffer to the next
+properties of the raw audio samples and sends out a caps event with the media type.
+
+Alsasink then receives the caps event, inspects the caps and reconfigures
+itself to process the media type.
+
+mp3dec then puts the decoded samples into a Buffer and pushes this buffer to the next
 element.
 
-Alsasink then receives the buffer, inspects the caps and reconfigures itself to process
-the buffer. Since it received the first buffer of samples, it completes the state change
-to the PAUSED state. At this point the pipeline is prerolled and all elements have
-samples. Alsasink is now also capable of providing a clock to the pipeline.
+Alsasink receives the buffer with samples. Since it received the first buffer of
+samples, it completes the state change to the PAUSED state. At this point the
+pipeline is prerolled and all elements have samples. Alsasink is now also
+capable of providing a clock to the pipeline.
 
 Since alsasink is now in the PAUSED state it blocks while receiving the first buffer. This
 effectively blocks both mp3dec and filesrc in their gst_pad_push().
@@ -488,7 +490,7 @@ element performs the following steps.
      always stop because of step 1).
   3) perform the seek operation
   4) send a FLUSH done event to all downstream and upstream peer elements.
-  5) send NEWSEGMENT event to inform all elements of the new position and to complete
+  5) send SEGMENT event to inform all elements of the new position and to complete
      the seek.
 
 In step 1) all downstream elements have to return from any blocking operations
@@ -512,8 +514,8 @@ Since the pipeline is still PAUSED, this will preroll the next media sample in t
 sinks. The application can wait for this preroll to complete by performing a 
 _get_state() on the pipeline.
 
-The last step in the seek operation is then to adjust the stream time of the pipeline
-to 0 and to set the pipeline back to PLAYING.
+The last step in the seek operation is then to adjust the stream running_time of
+the pipeline to 0 and to set the pipeline back to PLAYING.
 
 The sequence of events in our mp3 playback example.
 
@@ -533,8 +535,8 @@ The sequence of events in our mp3 playback example.
              | 2) stop streaming
              | 3) perform seek
               --------------------------> 4) FLUSH done event
-              --------------------------> 5) NEWSEGMENT event
+              --------------------------> 5) SEGMENT event
   
-                                      | e) update stream time to 0
+                                      | e) update running_time to 0
                                      | f) PLAY pipeline
 
diff --git a/docs/design/part-probes.txt b/docs/design/part-probes.txt
new file mode 100644 (file)
index 0000000..dff13b1
--- /dev/null
@@ -0,0 +1,239 @@
+Probes
+------
+
+ Probes are callbacks that can be installed by the application and will notify
+ the application about the states of the dataflow.
+
+
+Requirements
+------------
+
+Applications should be able to monitor and control the dataflow on pads. We
+identify the following types:
+
+ - be notified when the pad is/becomes idle and make sure the pad stays idle.
+   This is essential to be able to implement dynamic relinking of elements
+   without breaking the dataflow.
+
+ - be notified when data or events are pushed or sent on a pad. It should also
+   be possible to inspect and modify the data.
+ - be able to drop, pass and block on data based on the result of the callback.
+
+ - be able to drop, pass data on blocking pads based on methods performed by
+   the application thread.
+
+
+Overview
+--------
+
+ The function gst_pad_add_probe() is used to add a probe to a pad. It accepts a
+ probe type mask and a callback.
+
+   gulong  gst_pad_add_probe    (GstPad *pad,
+                                 GstProbeType mask,
+                                 GstPadProbeCallback callback,
+                                 gpointer user_data,
+                                 GDestroyNotify destroy_data);
+
+ The function returns a gulong that uniquely identifies the probe and that can
+ be used to remove the probe with gst_pad_remove_probe():
+
+   void    gst_pad_remove_probe (GstPad *pad, gulong id);
+
+ The mask parameter is a bitwise or of the following flags:
+  
+    typedef enum
+    {
+      GST_PROBE_TYPE_INVALID      = 0,
+
+      /* flags to control blocking */
+      GST_PROBE_TYPE_IDLE         = (1 << 0),
+      GST_PROBE_TYPE_BLOCK        = (1 << 1),
+
+      /* flags to select datatypes */
+      GST_PROBE_TYPE_BUFFER       = (1 << 2),
+      GST_PROBE_TYPE_BUFFER_LIST  = (1 << 3),
+      GST_PROBE_TYPE_EVENT        = (1 << 4),
+
+      /* flags to select scheduling mode */
+      GST_PROBE_TYPE_PUSH         = (1 << 5),
+      GST_PROBE_TYPE_PULL         = (1 << 6),
+    } GstProbeType;
+
+ When adding a probe with the IDLE or BLOCK flag, the probe will become a
+ blocking probe (see below). Otherwise the probe will be a DATA probe.
+
+ The datatype and scheduling selector flags are used to select what kind of
+ datatypes and scheduling modes should be allowed in the callback.
+ The blocking flags must match the triggered probe exactly.
+
+ The probe callback is defined as:
+
+   GstProbeReturn (*GstPadProbeCallback) (GstPad *pad, GstProbeType type,
+                                          gpointer type_data,
+                                          gpointer user_data);
+
+ The executing probe type is passed as an argument and is guaranteed to match
+ the mask that was used to register the callback. type_data contains type
+ specific data, which is usually the data item that is blocked or NULL when
+ no data item is present.  
+ The probe can return any of the following return values:
+
+   typedef enum
+   {
+     GST_PROBE_DROP,
+     GST_PROBE_OK,
+     GST_PROBE_REMOVE,
+     GST_PROBE_PASS,
+   } GstProbeReturn;
+
+ GST_PROBE_OK is the normal return value.  DROP will drop the item that is
+ currently being probed. GST_PROBE_REMOVE the currently executing probe from the
+ list of probes. 
+ GST_PROBE_PASS is relevant for blocking probes and will temporarily unblock the
+ pad and let the item trough, it will then block again on the next item.
+
+
+Blocking probes
+---------------
+
+  Blocking probes are probes with BLOCK or IDLE flags set. They will always
+  block the dataflow and trigger the callback according to the following rules:
+
+  When the IDLE flag is set, the probe callback is called as soon as no data is
+  flowing over the pad. If at the time of probe registration, the pad is idle,
+  the callback will be called immediately from the current thread. Otherwise,
+  the callback will be called as soon as the pad becomes idle in the streaming
+  thread.
+
+  The IDLE probe in useful to perform dynamic linking, it allows to wait for for
+  a safe moment when an unlink/link operation can be done. Since the event is a
+  blocking event, it will also make sure that the pad stays idle until the probe
+  is removed.
+
+  When the BLOCK flag is set, the probe callback will be called when new data
+  arrives on the pad and right before the pad goes into the blocking state. This
+  callback is thus only called when there is new data on the pad.
+
+  The blocking probe is removed with gst_pad_remove_probe() or when the probe
+  callback return GST_PROBE_REMOVE. In both cases, and if this was the last
+  blocking probe on the pad, the pad is unblocked and dataflow can continue.
+
+
+Non-Blocking probes
+--------------------
+
+  Non-blocking probes or DATA probes are probes triggered when data is flowing
+  over the pad. The are called after the blocking probes are run and always with
+  data.
+
+
+Push dataflow
+-------------
+
+All probes have the GST_PROBE_TYPE_PUSH flag set in the callbacks.
+
+In push based scheduling, the blocking probe is called first with the data item.
+Then the data probes are called before the peer pad chain or event function is
+called.
+
+The data probes are called before the peer pad is checked. This allows for
+linking the pad in either the BLOCK or DATA probes on the pad.
+
+Before the peerpad chain or event function is called, the peer pad data probes
+are called.
+
+Finally, the IDLE probe is called on the pad after the data was sent to the
+peer pad.
+
+The push dataflow probe behavior is the same for buffers and biderectional events.
+
+
+                     pad                           peerpad
+                      |                               |
+ gst_pad_push() /     |                               |
+ gst_pad_push_event() |                               |
+ -------------------->O                               |
+                      O                               | 
+        flushing?     O                               | 
+        WRONG_STATE   O                               |
+        < - - - - - - O                               | 
+                      O-> do BLOCK probes             | 
+                      O                               | 
+                      O-> do DATA probes              | 
+         no peer?     O                               |
+        NOT_LINKED    O                               | 
+        < - - - - - - O                               |
+                      O   gst_pad_chain() /           | 
+                      O   gst_pad_send_event()        | 
+                      O------------------------------>O
+                      O                   flushing?   O 
+                      O                 WRONG_STATE   O 
+                      O< - - - - - - - - - - - - - - -O 
+                      O                               O-> do DATA probes
+                      O                               O 
+                      O                               O---> chainfunc /
+                      O                               O     eventfunc
+                      O< - - - - - - - - - - - - - - -O 
+                      O                               |
+                      O-> do IDLE probes              | 
+                      O                               | 
+        < - - - - - - O                               | 
+                      |                               | 
+
+
+Pull dataflow
+-------------
+
+All probes have the GST_PROBE_TYPE_PULL flag set in the callbacks.
+
+The gst_pad_pull_range() call will first trigger the BLOCK probes without a DATA
+item. This allows the pad to be linked before the peer pad is resolved.
+
+After the getrange function is called on the peer pad and there is a data item,
+the DATA probes are called.
+
+When control returns to the sinkpad, the IDLE callbacks are called. The IDLE
+callback is called without a data item so that it will also be called when there
+was an error.
+
+It there is a valid DATA item, the DATA probes are called for the item.
+
+
+                srcpad                          sinkpad
+                  |                               |
+                  |                               | gst_pad_pull_range()
+                  |                               O<---------------------
+                  |                               O
+                  |                               O  flushing?
+                  |                               O  WRONG_STATE
+                  |                               O - - - - - - - - - - >
+                  |             do BLOCK probes <-O
+                  |                               O   no peer?
+                  |                               O  NOT_LINKED
+                  |                               O - - - - - - - - - - >
+                  |          gst_pad_get_range()  O
+                  O<------------------------------O
+                  O                               O
+                  O flushing?                     O
+                  O WRONG_STATE                   O
+                  O- - - - - - - - - - - - - - - >O
+ getrangefunc <---O                               O
+                  O  flow error?                  O
+                  O- - - - - - - - - - - - - - - >O
+                  O                               O
+ do DATA probes <-O                               O
+                  O- - - - - - - - - - - - - - - >O
+                  |                               O 
+                  |              do IDLE probes <-O               
+                  |                               O   flow error?
+                  |                               O - - - - - - - - - - >
+                  |                               O
+                  |              do DATA probes <-O  
+                  |                               O - - - - - - - - - - >
+                  |                               |
+
index 3e17340..e546130 100644 (file)
@@ -52,6 +52,38 @@ The getrange function
 The getrange function is called when a peer pad performs a _pull_range() on the pad. This
 downstream pad can be a pulling element or another _pull_range() based element.
 
+
+Scheduling Query
+~~~~~~~~~~~~~~~~
+
+A sinkpad can ask the upstream srcpad for its scheduling attributes. It does
+this with the SCHEDULING query.
+
+
+ (out) "pull-mode", G_TYPE_BOOLEAN (default FALSE)
+       - if the pad can operate in pull mode, if this flag is not set the pad
+         will operate in push mode.
+
+ (out) "random-access", G_TYPE_BOOLEAN (default FALSE)
+       - the offset of a pull operation can be specified, if this flag is false,
+         the offset should be -1,
+
+ (out) "sequential", G_TYPE_BOOLEAN (default TRUE)
+       - suggest sequential access to the data. If random-access is specified,
+         seeks are allowed but should be avoided. This is common for network
+         streams. (
+
+ (out) "minsize", G_TYPE_INT (default 1)
+       - the suggested minimum size of pull requests
+
+ (out) "maxsize", G_TYPE_INT (default -1, unlimited)
+       - the suggested maximum size of pull requests
+
+ (out) "align", G_TYPE_INT (default 1)
+       - the suggested alignment for the pull requests.
+
+
+
 Plug-in techniques
 ~~~~~~~~~~~~~~~~~~
 
index 01788dd..2e9d454 100644 (file)
@@ -127,7 +127,7 @@ When a seek to a certain position is requested, the demuxer/parser will
 do two things (ignoring flushing and segment seeks, and simplified for
 illustration purposes):
 
- - send a newsegment event with a new start position
+ - send a segment event with a new start position
 
  - start pushing data/buffers again
 
@@ -136,15 +136,15 @@ can actually be decoded, a demuxer or parser needs to start pushing data
 from a keyframe/keyunit at or before the requested seek position.
 
 Unless requested differently (via the KEY_UNIT flag), the start of the
-newsegment event should be the requested seek position.
+segment event should be the requested seek position.
 
 So by default a demuxer/parser will then start pushing data from
-position DATA and send a newsegment event with start position SEG_START,
+position DATA and send a segment event with start position SEG_START,
 and DATA <= SEG_START.
 
 If DATA < SEG_START, a well-behaved video decoder will start decoding frames
 from DATA, but take into account the segment configured by the demuxer via
-the newsegment event, and only actually output decoded video frames from
+the segment event, and only actually output decoded video frames from
 SEG_START onwards, dropping all decoded frames that are before the
 segment start and adjusting the timestamp/duration of the buffer that
 overlaps the segment start ("clipping"). A not-so-well-behaved video decoder
index d5b7e76..e05ec5b 100644 (file)
@@ -22,8 +22,8 @@ on the stream. The seek has a start time, a stop time and a processing rate.
 
 
 The playback of a segment starts with a source or demuxer element pushing a
-newsegment event containing the start time, stop time and rate of the segment.
-The purpose of this newsegment is to inform downstream elements of the 
+segment event containing the start time, stop time and rate of the segment.
+The purpose of this segment is to inform downstream elements of the 
 requested segment positions. Some elements might produce buffers that fall
 outside of the segment and that might therefore be discarded or clipped.
 
@@ -46,8 +46,8 @@ Use case: FLUSHING seek
     upstream and downstream.
 
     When avidemux starts playback of the segment from second 1 to 5, it pushes
-    out a newsegment with 1 and 5 as start and stop times. The stream_time in
-    the newsegment is also 1 as this is the position we seek to.
+    out a segment with 1 and 5 as start and stop times. The stream_time in
+    the segment is also 1 as this is the position we seek to.
 
     The video decoder stores these values internally and forwards them to the
     next downstream element (videosink, which also stores the values)
@@ -64,7 +64,7 @@ Use case: FLUSHING seek
     When it reaches timestamp 5, it does not decode and push frames anymore.
 
     The video sink receives a frame of timestamp 1. It takes the start value of 
-    the previous newsegment and aplies the folowing (simplified) formula:
+    the previous segment and aplies the folowing (simplified) formula:
 
         render_time = BUFFER_TIMESTAMP - segment_start + element->base_time
 
index 4770e90..269faa5 100644 (file)
@@ -8,7 +8,7 @@ In 0.8, there was some support for Sparse Streams through the use of
 FILLER events. These were used to mark gaps between buffers so that downstream
 elements could know not to expect any more data for that gap. 
 
-In 0.10, segment information conveyed through NEWSEGMENT events can be used
+In 0.10, segment information conveyed through SEGMENT events can be used
 for the same purpose.
 
 Use cases
@@ -45,9 +45,9 @@ Details
   The main requirement here is to avoid stalling the pipeline between sub-title
   packets, and is effectively updating the minimum-timestamp for that stream.
   
-  A demuxer can do this by sending an 'update' NEWSEGMENT with a new start time
+  A demuxer can do this by sending an 'update' SEGMENT with a new start time
   to the subtitle pad. For example, every time the SCR in MPEG data 
-  advances more than 0.5 seconds, the MPEG demuxer can issue a NEWSEGMENT with
+  advances more than 0.5 seconds, the MPEG demuxer can issue a SEGMENT with
    (update=TRUE, start=SCR ). Downstream elements can then be aware not to 
    expect any data older than the new start time.
 
@@ -57,7 +57,7 @@ Details
    
   This technique can also be used, for example, to represent a stream of 
   MIDI events spaced to a clock period. When there is no event present for 
-  a clock time, a NEWSEGMENT update can be sent in its place.
+  a clock time, a SEGMENT update can be sent in its place.
   
 2) Still frame/menu support
   Still frames in DVD menus are not the same, in that they do not introduce
@@ -74,7 +74,7 @@ Details
       if necessary due to an intervening activity (such as a user navigation)
     * FLUSH the pipeline using a normal flush sequence (FLUSH_START, 
       chain-lock, FLUSH_STOP)
-    * Send a NEWSEGMENT to restart playback with the next timestamp in the 
+    * Send a SEGMENT to restart playback with the next timestamp in the 
       stream.
   
   The upstream element performing the wait must only do so when in the PLAYING 
@@ -90,7 +90,7 @@ Details
   arriving late at the sink, and they will be discarded instead of played.
 
 3) For audio, 3) is the same case as 1) - there is a 'gap' in the audio data 
-   that needs to be presented, and this can be done by sending a NEWSEGMENT 
+   that needs to be presented, and this can be done by sending a SEGMENT 
    update that moves the start time of the segment to the next timestamp when 
    data will be sent.
    
index 1274ae0..119921d 100644 (file)
@@ -11,7 +11,7 @@ Stream objects
 The following objects are to be expected in the streaming thread:
 
  - events
-    - NEW_SEGMENT      (NS)
+    - SEGMENT           (S)
     - EOS              (EOS)  *
     - TAG               (T)
  - buffers              (B)    *
@@ -23,25 +23,27 @@ and live sources.
 Typical stream
 ~~~~~~~~~~~~~~
 
- A typical stream starts with a newsegment event that marks the
+ A typical stream starts with a segment event that marks the
  buffer timestamp range. After that buffers are sent one after the
  other. After the last buffer an EOS marks the end of the stream. No
  more buffers are to be processed after the EOS event.
 
-  +--+ +-++-+     +-+ +---+
-  |NS| |B||B| ... |B| |EOS|
-  +--+ +-++-+     +-+ +---+
+  +-+ +-++-+     +-+ +---+
+  |S| |B||B| ... |B| |EOS|
+  +-+ +-++-+     +-+ +---+
 
-  1) NEW_SEGMENT, rate, start/stop, time
+  1) SEGMENT, rate, start/stop, time
      - marks valid buffer timestamp range (start, stop)
      - marks stream_time of buffers (time). This is the stream time of buffers
        with a timestamp of NS.start.
      - marks playback rate (rate). This is the required playback rate.
      - marks applied rate (applied_rate). This is the already applied playback
        rate. (See also part-trickmodes.txt)
+     - marks running_time of buffers. This is the time used to synchronize
+       against the clock.
 
   2) N buffers
-     - displayable buffers are between start/stop of the NEW_SEGMENT. Buffers
+     - displayable buffers are between start/stop of the SEGMENT. Buffers
        outside the segment range should be dropped or clipped.
 
      - running_time: 
index 07d87c8..68ac0f0 100644 (file)
@@ -8,7 +8,7 @@ Synchronisation in a GstPipeline is achieved using the following 3 components:
 
  - a GstClock, which is global for all elements in a GstPipeline.
  - Timestamps on a GstBuffer.
- - the NEW_SEGMENT event preceding the buffers.
+ - the SEGMENT event preceding the buffers.
 
 
 A GstClock
@@ -68,7 +68,7 @@ This value is monotonically increasing at the rate of the clock.
 Timestamps
 ~~~~~~~~~~
  
-The GstBuffer timestamps and the preceeding NEW_SEGMENT event (See
+The GstBuffer timestamps and the preceeding SEGMENT event (See
 part-streams.txt) define a transformation of the buffer timestamps to
 running_time as follows:
 
@@ -77,13 +77,13 @@ The following notation is used:
  B: GstBuffer 
   - B.timestamp = buffer timestamp (GST_BUFFER_TIMESTAMP)
 
- NS:  NEWSEGMENT event preceeding the buffers.
-  - NS.start: start field in the NEWSEGMENT event
-  - NS.stop: stop field in the NEWSEGMENT event
-  - NS.rate: rate field of NEWSEGMENT event
-  - NS.abs_rate: absolute value of rate field of NEWSEGMENT event
-  - NS.time: time field in the NEWSEGMENT event
-  - NS.accum: total accumulated time of all previous NEWSEGMENT events. This
+ NS:  SEGMENT event preceeding the buffers.
+  - NS.start: start field in the SEGMENT event
+  - NS.stop: stop field in the SEGMENT event
+  - NS.rate: rate field of SEGMENT event
+  - NS.abs_rate: absolute value of rate field of SEGMENT event
+  - NS.time: time field in the SEGMENT event
+  - NS.accum: total accumulated time of all previous SEGMENT events. This
               field is kept in the GstSegment structure.
 
 Valid buffers for synchronisation are those with B.timestamp between NS.start
@@ -97,7 +97,7 @@ The following transformation to running_time exist:
     else
       B.running_time = (NS.stop - B.timestamp) / NS.abs_rate + NS.accum
 
-We write B.running_time as the running_time obtained from the NEWSEGMENT event
+We write B.running_time as the running_time obtained from the SEGMENT event
 and the buffers of that segment.
 
 The first displayable buffer will yield a value of 0 (since B.timestamp ==
@@ -120,7 +120,7 @@ As we have seen, we can get a running_time:
 
     C.running_time = absolute_time - base_time
 
- - using the buffer timestamp and the preceeding NEWSEGMENT event as (assuming
+ - using the buffer timestamp and the preceeding SEGMENT event as (assuming
    positive playback rate):
 
     B.running_time = (B.timestamp - NS.start) / NS.abs_rate + NS.accum
@@ -154,9 +154,9 @@ the sink (See also part-clocks.txt).
 For multiple streams this means that buffers with the same running_time are to
 be displayed at the same time. 
 
-A demuxer must make sure that the NEWSEGMENT it emits on its output pads yield
+A demuxer must make sure that the SEGMENT it emits on its output pads yield
 the same running_time for buffers that should be played synchronized. This
-usually means sending the same NEWSEGMENT on all pads and making sure that the
+usually means sending the same SEGMENT on all pads and making sure that the
 synchronized buffers have the same timestamps.
 
 
@@ -172,7 +172,7 @@ It is the stream time that is used for:
   - the position used in seek events/queries
   - the position used to synchronize controller values
 
-Stream time is calculated using the buffer times and the preceeding NEWSEGMENT
+Stream time is calculated using the buffer times and the preceeding SEGMENT
 event as follows:
 
     stream_time = (B.timestamp - NS.start) * NS.abs_applied_rate + NS.time
index e188ee2..f1bc40e 100644 (file)
@@ -72,12 +72,12 @@ One element will actually perform the seek, this is usually the demuxer or
 source element. For more information on how to perform the different seek
 types see part-seeking.txt.
 
-For client side trickmode a NEW_SEGMENT event will be sent downstream with
+For client side trickmode a SEGMENT event will be sent downstream with
 the new rate and start/stop positions. All elements prepare themselves to
-handle the rate (see below). The applied rate of the NEW_SEGMENT event will
+handle the rate (see below). The applied rate of the SEGMENT event will
 be set to 1.0 to indicate that no rate adjustment has been done.
 
-for server side trick mode a NEW_SEGMENT event is sent downstream with a
+for server side trick mode a SEGMENT event is sent downstream with a
 rate of 1.0 and the start/stop positions. The elements will configure themselves
 for normal playback speed since the server will perform the rate conversions.
 The applied rate will be set to the rate that will be applied by the server. This
@@ -137,16 +137,16 @@ playback speed or direction.
 client side forward trickmodes 
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-The seek happens as stated above. a NEW_SEGMENT event is sent downstream with a rate
-different from 1.0. Plugins receiving the NEW_SEGMENT can decide to perform the 
+The seek happens as stated above. a SEGMENT event is sent downstream with a rate
+different from 1.0. Plugins receiving the SEGMENT can decide to perform the 
 rate conversion of the media data (retimestamp video frames, resample audio, ...).
 
-If a plugin decides to resample or retimestamp, it should modify the NEW_SEGMENT with
+If a plugin decides to resample or retimestamp, it should modify the SEGMENT with
 a rate of 1.0 and update the applied rate so that downstream elements don't resample
 again but are aware that the media has been modified.
 
 The GStreamer base audio and video sinks will resample automatically if they receive
-a NEW_SEGMENT event with a rate different from 1.0. The position reporting in the
+a SEGMENT event with a rate different from 1.0. The position reporting in the
 base audio and video sinks will also depend on the applied rate of the segment
 information.
 
@@ -162,10 +162,10 @@ client side backwards trickmode
 
 For backwards playback the following rules apply:
 
- - the rate in the NEW_SEGMENT is less than 0.0.
- - the NEW_SEGMENT start position is less than the stop position, playback will
+ - the rate in the SEGMENT is less than 0.0.
+ - the SEGMENT start position is less than the stop position, playback will
    however happen from stop to start in reverse.
- - the time member in the NEW_SEGMENT is set to the stream time of the start
+ - the time member in the SEGMENT is set to the stream time of the start
    position.
 
 For plugins the following rules apply:
@@ -181,12 +181,12 @@ For plugins the following rules apply:
    forward continuous with the previous buffer.
 
  - A video decoder decodes and accumulates all decoded frames. If a buffer with
-   a DISCONT, accumulate NEWSEGMENT or EOS is received, all accumulated frames
-   are sent downsteam in reverse.
+   a DISCONT, SEGMENT or EOS is received, all accumulated frames are sent
+   downsteam in reverse.
 
  - An audio decoder decodes and accumulates all decoded audio. If a buffer with
-   a DISCONT, accumulate NEWSEGMENT or EOS is received, all accumulated audio
-   is sent downstream in reverse order. Some audio codecs need the previous
+   a DISCONT, SEGMENT or EOS is received, all accumulated audio is sent
+   downstream in reverse order. Some audio codecs need the previous
    data buffer to decode the current one, in that case, the previous DISCONT
    buffer needs to be combined with the last non-DISCONT buffer to generate the
    last bit of output.
@@ -201,7 +201,7 @@ For plugins the following rules apply:
  - for transcoding, audio and video resamplers can be used to reverse, resample
    and retimestamp the buffers. Any rate adjustments performed on the media must
    be added to the applied_rate and subtracted from the rate members in the
-   NEWSEGMENT event.
+   SEGMENT event.
 
  In SKIP mode, the same algorithm as for forward SKIP mode can be used.
 
index 395f6b8..4ee7eed 100644 (file)
@@ -154,19 +154,6 @@ how you installed GStreamer (from git, source, packages, which ?)</para></listit
 </itemizedlist>
         </para>
         <para>
-It also is useful for us if you attach output of
-the gst-feedback command to your bug report.
-If you're having problem with a specific application (either one of ours,
-somebody else's, or your own), please also provide a log of gst-mask by
-running
-<programlisting>
-myapp --gst-mask=-1 > mask.log 2>&amp;1
-gzip mask.log
-</programlisting>
-(interrupting the program if it doesn't stop by itself)
-and attach mask.log.gz to your bug report.
-        </para>
-        <para>
 If the application you are having problems with is segfaulting, then
 provide us with the necessary gdb output.  See
 <xref linkend="troubleshooting-segfault" endterm="troubleshooting-segfault"/>
index ca969a1..dc4bef3 100644 (file)
@@ -61,6 +61,7 @@ Windows.  It is released under the GNU Library General Public License
     <xi:include href="xml/gstbin.xml" />
     <xi:include href="xml/gstbuffer.xml" />
     <xi:include href="xml/gstbufferlist.xml" />
+    <xi:include href="xml/gstbufferpool.xml" />
     <xi:include href="xml/gstbus.xml" />
     <xi:include href="xml/gstcaps.xml" />
     <xi:include href="xml/gstchildproxy.xml" />
@@ -78,7 +79,9 @@ Windows.  It is released under the GNU Library General Public License
     <xi:include href="xml/gstindex.xml" />
     <xi:include href="xml/gstindexfactory.xml" />
     <xi:include href="xml/gstiterator.xml" />
+    <xi:include href="xml/gstmemory.xml" />
     <xi:include href="xml/gstmessage.xml" />
+    <xi:include href="xml/gstmeta.xml" />
     <xi:include href="xml/gstminiobject.xml" />
     <xi:include href="xml/gstobject.xml" />
     <xi:include href="xml/gstpad.xml" />
@@ -105,7 +108,6 @@ Windows.  It is released under the GNU Library General Public License
     <xi:include href="xml/gstutils.xml" />
     <xi:include href="xml/gstvalue.xml" />
     <xi:include href="xml/gstversion.xml" />
-    <xi:include href="xml/gstxml.xml" />
 
   </chapter>
 
index c29ac05..f02d03e 100644 (file)
@@ -81,7 +81,6 @@ gst_bin_recalculate_latency
 gst_bin_add_many
 gst_bin_remove_many
 gst_bin_find_unlinked_pad
-gst_bin_find_unconnected_pad
 
 <SUBSECTION>
 GstBinFlags
@@ -164,14 +163,11 @@ GST_BUFFER_FLAGS
 GST_BUFFER_FLAG_IS_SET
 GST_BUFFER_FLAG_SET
 GST_BUFFER_FLAG_UNSET
+GST_META_TIMING_INFO
+GstMetaTiming
 
-GST_BUFFER_DATA
-GST_BUFFER_MALLOCDATA
-GST_BUFFER_FREE_FUNC
-GST_BUFFER_SIZE
 GST_BUFFER_TIMESTAMP
 GST_BUFFER_DURATION
-GST_BUFFER_CAPS
 GST_BUFFER_OFFSET
 GST_BUFFER_OFFSET_END
 GST_BUFFER_OFFSET_NONE
@@ -184,98 +180,141 @@ GST_BUFFER_TRACE_NAME
 
 gst_buffer_new
 gst_buffer_new_and_alloc
-gst_buffer_try_new_and_alloc
 
 gst_buffer_ref
 gst_buffer_unref
 
-gst_buffer_set_data
-gst_buffer_copy
+gst_buffer_get_size
+gst_buffer_resize
+gst_buffer_set_size
+
+gst_buffer_n_memory
+gst_buffer_take_memory
+gst_buffer_peek_memory
+gst_buffer_remove_memory
+gst_buffer_remove_memory_range
+
+gst_buffer_join
+gst_buffer_memcmp
+gst_buffer_merge
 
+gst_buffer_map
+gst_buffer_unmap
+
+gst_buffer_extract
+gst_buffer_fill
+
+GST_BUFFER_COPY_METADATA
 GST_BUFFER_COPY_ALL
-gst_buffer_copy_metadata
+gst_buffer_copy
+gst_buffer_copy_into
+gst_buffer_copy_region
+
 gst_buffer_is_writable
 gst_buffer_make_writable
-gst_buffer_is_metadata_writable
-gst_buffer_make_metadata_writable
 gst_buffer_replace
 
-gst_buffer_get_caps
-gst_buffer_set_caps
-
-gst_buffer_create_sub
 gst_buffer_is_span_fast
 gst_buffer_span
 
-gst_buffer_stamp
-gst_buffer_join
-gst_buffer_merge
+gst_buffer_get_meta
+gst_buffer_add_meta
+gst_buffer_remove_meta
+gst_buffer_iterate_meta
 
+gst_buffer_add_meta_timing
+gst_buffer_get_meta_timing
+gst_meta_timing_get_info
 <SUBSECTION Standard>
 GstBufferClass
 GST_BUFFER
-GST_BUFFER_CLASS
-GST_BUFFER_GET_CLASS
 GST_IS_BUFFER
-GST_IS_BUFFER_CLASS
 GST_TYPE_BUFFER
 GST_TYPE_BUFFER_FLAG
 GST_TYPE_BUFFER_COPY_FLAGS
 GST_BUFFER_CAST
 <SUBSECTION Private>
-gst_buffer_get_type
 gst_buffer_flag_get_type
 gst_buffer_copy_flags_get_type
 </SECTION>
 
 <SECTION>
+<FILE>gstmeta</FILE>
+<TITLE>GstMeta</TITLE>
+GstMeta
+GstMetaInfo
+GST_META_TRACE_NAME
+GstMetaInitFunction
+GstMetaFreeFunction
+GstMetaCopyFunction
+GstMetaTransformFunction
+gst_meta_register
+gst_meta_get_info
+</SECTION>
+
+
+<SECTION>
+<FILE>gstbufferpool</FILE>
+<TITLE>GstBufferPool</TITLE>
+GstBufferPool
+GstBufferPoolClass
+GstBufferPoolFlags
+GstBufferPoolParams
+gst_buffer_pool_new
+
+gst_buffer_pool_config_get
+gst_buffer_pool_config_set
+
+gst_buffer_pool_get_config
+gst_buffer_pool_set_config
+
+gst_buffer_pool_set_active
+
+gst_buffer_pool_acquire_buffer
+gst_buffer_pool_release_buffer
+<SUBSECTION Standard>
+GST_BUFFER_POOL_CLASS
+GST_BUFFER_POOL_CAST
+GST_BUFFER_POOL_TRACE_NAME
+GstBufferPoolPrivate
+GST_BUFFER_POOL
+GST_IS_BUFFER_POOL
+GST_TYPE_BUFFER_POOL
+gst_buffer_pool_get_type
+GST_TYPE_BUFFER_POOL_FLAGS
+gst_buffer_pool_flags_get_type
+GST_IS_BUFFER_POOL_CLASS
+GST_BUFFER_POOL_GET_CLASS
+</SECTION>
+
+<SECTION>
 <FILE>gstbufferlist</FILE>
 <TITLE>GstBufferList</TITLE>
 GstBufferList
-GstBufferListIterator
-GstBufferListDoFunction
 
 gst_buffer_list_new
+gst_buffer_list_sized_new
+gst_buffer_list_len
+gst_buffer_list_add
+gst_buffer_list_insert
+gst_buffer_list_remove
+
 gst_buffer_list_ref
 gst_buffer_list_unref
 gst_buffer_list_copy
 gst_buffer_list_is_writable
 gst_buffer_list_make_writable
 
-gst_buffer_list_n_groups
-
-GstBufferListItem
 GstBufferListFunc
 gst_buffer_list_foreach
 gst_buffer_list_get
 
-gst_buffer_list_iterate
-gst_buffer_list_iterator_free
-gst_buffer_list_iterator_n_buffers
-gst_buffer_list_iterator_add
-gst_buffer_list_iterator_add_group
-gst_buffer_list_iterator_add_list
-gst_buffer_list_iterator_next
-gst_buffer_list_iterator_next_group
-gst_buffer_list_iterator_remove
-gst_buffer_list_iterator_steal
-gst_buffer_list_iterator_take
-gst_buffer_list_iterator_do
-gst_buffer_list_iterator_merge_group
 <SUBSECTION Standard>
-GstBufferListClass
 GST_BUFFER_LIST
-GST_BUFFER_LIST_CLASS
-GST_BUFFER_LIST_GET_CLASS
 GST_IS_BUFFER_LIST
-GST_IS_BUFFER_LIST_CLASS
 GST_TYPE_BUFFER_LIST
 GST_BUFFER_LIST_CAST
-GST_TYPE_BUFFER_LIST_ITEM
-GST_TYPE_BUFFER_LIST_ITERATOR
 <SUBSECTION Private>
-gst_buffer_list_item_get_type
-gst_buffer_list_iterator_get_type
 gst_buffer_list_get_type
 </SECTION>
 
@@ -294,14 +333,18 @@ GST_CAPS_REFCOUNT_VALUE
 GST_STATIC_CAPS_ANY
 GST_STATIC_CAPS_NONE
 GST_CAPS_IS_SIMPLE
-GST_DEBUG_CAPS
 GST_STATIC_CAPS
+GST_CAPS_FLAGS
+GST_CAPS_FLAG_IS_SET
+GST_CAPS_FLAG_SET
+GST_CAPS_FLAG_UNSET
 
 gst_caps_new_empty
 gst_caps_new_any
 gst_caps_new_simple
 gst_caps_new_full
 gst_caps_new_full_valist
+gst_caps_is_writable
 gst_caps_copy
 gst_caps_copy_nth
 gst_static_caps_get
@@ -330,8 +373,6 @@ gst_caps_intersect_full
 gst_caps_union
 gst_caps_normalize
 gst_caps_do_simplify
-gst_caps_save_thyself
-gst_caps_load_thyself
 gst_caps_replace
 gst_caps_to_string
 gst_caps_from_string
@@ -469,21 +510,25 @@ gst_clock_return_get_type
 <FILE>gstcompat</FILE>
 <TITLE>GstCompat</TITLE>
 <SUBSECTION Standard>
+gst_element_class_set_details_simple
+gst_element_factory_get_author
+gst_element_factory_get_description
+gst_element_factory_get_documentation_uri
+gst_element_factory_get_icon_name
+gst_element_factory_get_klass
+gst_element_factory_get_longname
 <SUBSECTION Private>
 </SECTION>
 
 <SECTION>
 <FILE>gstconfig</FILE>
 GST_DISABLE_GST_DEBUG
-GST_DISABLE_LOADSAVE
 GST_DISABLE_PARSE
 GST_DISABLE_TRACE
 GST_DISABLE_ALLOC_TRACE
 GST_DISABLE_REGISTRY
 GST_DISABLE_PLUGIN
-GST_DISABLE_XML
 <SUBSECTION Private>
-GST_DISABLE_LOADSAVE_REGISTRY
 GST_HAVE_GLIB_2_8
 GST_PTR_FORMAT
 GST_SEGMENT_FORMAT
@@ -529,19 +574,23 @@ GST_ELEMENT_WARNING
 GST_ELEMENT_INFO
 GST_ELEMENT_IS_LOCKED_STATE
 
+GST_ELEMENT_METADATA_AUTHOR
+GST_ELEMENT_METADATA_DESCRIPTION
+GST_ELEMENT_METADATA_DOC_URI
+GST_ELEMENT_METADATA_ICON_NAME
+GST_ELEMENT_METADATA_KLASS
+GST_ELEMENT_METADATA_LONGNAME
+
 <SUBSECTION element-construction>
 gst_element_class_add_pad_template
 gst_element_class_get_pad_template
 gst_element_class_get_pad_template_list
 gst_element_class_install_std_props
-gst_element_class_set_details
-gst_element_class_set_details_simple
-gst_element_class_set_documentation_uri
-gst_element_class_set_icon_name
+gst_element_class_set_metadata
+gst_element_class_add_metadata
 
 <SUBSECTION element-pads>
 gst_element_add_pad
-gst_element_get_pad
 gst_element_create_all_pads
 gst_element_get_compatible_pad
 gst_element_get_compatible_pad_template
@@ -567,6 +616,7 @@ gst_element_link_pads_filtered
 gst_element_link_filtered
 
 <SUBSECTION element-properties>
+gst_element_class_get_metadata
 gst_element_set_base_time
 gst_element_get_base_time
 gst_element_set_start_time
@@ -597,7 +647,6 @@ gst_element_is_locked_state
 gst_element_abort_state
 gst_element_continue_state
 gst_element_lost_state
-gst_element_lost_state_full
 gst_element_state_get_name
 gst_element_state_change_return_get_name
 gst_element_sync_state_with_parent
@@ -658,26 +707,16 @@ gst_state_change_return_get_type
 <FILE>gstelementfactory</FILE>
 <TITLE>GstElementFactory</TITLE>
 GstElementFactory
-GstElementDetails
-GST_ELEMENT_DETAILS
-GST_IS_ELEMENT_DETAILS
 gst_element_register
 gst_element_factory_find
 gst_element_factory_get_element_type
-gst_element_factory_get_longname
-gst_element_factory_get_klass
-gst_element_factory_get_description
-gst_element_factory_get_author
-gst_element_factory_get_documentation_uri
-gst_element_factory_get_icon_name
+gst_element_factory_get_metadata
 gst_element_factory_get_num_pad_templates
 gst_element_factory_get_uri_type
 gst_element_factory_get_uri_protocols
 gst_element_factory_has_interface
 gst_element_factory_create
 gst_element_factory_make
-gst_element_factory_can_sink_caps
-gst_element_factory_can_src_caps
 gst_element_factory_can_sink_all_caps
 gst_element_factory_can_src_all_caps
 gst_element_factory_can_sink_any_caps
@@ -785,10 +824,11 @@ GST_EVENT_TRACE_NAME
 GST_EVENT_TYPE
 GST_EVENT_TYPE_NAME
 GST_EVENT_TIMESTAMP
-GST_EVENT_SRC
+
 GST_EVENT_IS_UPSTREAM
 GST_EVENT_IS_DOWNSTREAM
 GST_EVENT_IS_SERIALIZED
+GST_EVENT_IS_STICKY
 
 gst_event_type_get_flags
 gst_event_type_get_name
@@ -798,7 +838,12 @@ gst_event_ref
 gst_event_unref
 gst_event_replace
 gst_event_copy
+gst_event_steal
+gst_event_take
 
+gst_event_is_writable
+gst_event_make_writable
+gst_event_writable_structure
 
 gst_event_new_custom
 gst_event_get_structure
@@ -809,13 +854,13 @@ gst_event_set_seqnum
 
 gst_event_new_flush_start
 gst_event_new_flush_stop
+gst_event_parse_flush_stop
 
 gst_event_new_eos
 
-gst_event_new_new_segment
-gst_event_new_new_segment_full
-gst_event_parse_new_segment
-gst_event_parse_new_segment_full
+gst_event_new_segment
+gst_event_parse_segment
+gst_event_copy_segment
 
 gst_event_new_tag
 gst_event_parse_tag
@@ -825,9 +870,7 @@ gst_event_parse_buffer_size
 
 GstQOSType
 gst_event_new_qos
-gst_event_new_qos_full
 gst_event_parse_qos
-gst_event_parse_qos_full
 
 GstSeekType
 GstSeekFlags
@@ -844,6 +887,11 @@ gst_event_parse_step
 
 gst_event_new_sink_message
 gst_event_parse_sink_message
+
+gst_event_new_reconfigure
+
+gst_event_new_caps
+gst_event_parse_caps
 <SUBSECTION Standard>
 GstEventClass
 GST_EVENT
@@ -916,7 +964,6 @@ gst_ghost_pad_get_target
 
 gst_ghost_pad_construct
 
-gst_ghost_pad_setcaps_default
 gst_ghost_pad_unlink_default
 gst_ghost_pad_link_default
 gst_ghost_pad_activate_pull_default
@@ -931,15 +978,12 @@ 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_bufferalloc_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
@@ -1188,13 +1232,13 @@ GstIterator
 GstIteratorItem
 GstIteratorResult
 
-GstIteratorDisposeFunction
+GstIteratorCopyFunction
 GstIteratorNextFunction
 GstIteratorItemFunction
 GstIteratorResyncFunction
 GstIteratorFreeFunction
+GstIteratorForeachFunction
 GstIteratorFoldFunction
-GstCopyFunction
 
 GST_ITERATOR
 GST_ITERATOR_LOCK
@@ -1205,9 +1249,11 @@ gst_iterator_new
 gst_iterator_new_list
 gst_iterator_new_single
 
+gst_iterator_copy
+gst_iterator_free
+
 gst_iterator_next
 gst_iterator_resync
-gst_iterator_free
 gst_iterator_push
 gst_iterator_filter
 gst_iterator_fold
@@ -1215,15 +1261,64 @@ gst_iterator_foreach
 gst_iterator_find_custom
 
 <SUBSECTION Standard>
+GST_TYPE_ITERATOR
 GST_TYPE_ITERATOR_ITEM
 GST_TYPE_ITERATOR_RESULT
 <SUBSECTION Private>
+gst_iterator_get_type
 gst_iterator_item_get_type
 gst_iterator_result_get_type
 </SECTION>
 
 
 <SECTION>
+<FILE>gstmemory</FILE>
+<TITLE>GstMemory</TITLE>
+GstMemory
+GstMemoryInfo
+GstMemoryAllocator
+GST_MEMORY_IS_WRITABLE
+GstMemoryFlags
+GstMapFlags
+GST_MAP_READWRITE
+GstMemoryAllocFunction
+GstMemoryGetSizesFunction
+GstMemoryResizeFunction
+GstMemoryMapFunction
+GstMemoryUnmapFunction
+GstMemoryFreeFunction
+GstMemoryCopyFunction
+GstMemoryShareFunction
+GstMemoryIsSpanFunction
+gst_memory_allocator_alloc
+gst_memory_new_wrapped
+
+gst_memory_ref
+gst_memory_unref
+
+gst_memory_get_sizes
+gst_memory_resize
+
+gst_memory_map
+gst_memory_unmap
+
+gst_memory_copy
+gst_memory_share
+
+gst_memory_is_span
+
+gst_memory_allocator_find
+gst_memory_allocator_register
+gst_memory_allocator_set_default
+<SUBSECTION Standard>
+GST_MEMORY_TRACE_NAME
+GST_TYPE_MAP_FLAGS
+GST_TYPE_MEMORY_FLAGS
+gst_map_flags_get_type
+gst_memory_flags_get_type
+</SECTION>
+
+<SECTION>
 <FILE>gstmessage</FILE>
 <TITLE>GstMessage</TITLE>
 GstMessage
@@ -1231,6 +1326,7 @@ GstMessageType
 GST_MESSAGE_SRC
 GST_MESSAGE_SRC_NAME
 GST_MESSAGE_TIMESTAMP
+GST_MESSAGE_SEQNUM
 GST_MESSAGE_TYPE
 GST_MESSAGE_TYPE_NAME
 GST_MESSAGE_TRACE_NAME
@@ -1243,6 +1339,9 @@ gst_message_get_structure
 gst_message_make_writable
 gst_message_get_seqnum
 gst_message_set_seqnum
+gst_message_has_name
+gst_message_is_writable
+gst_message_replace
 
 gst_message_new_eos
 gst_message_new_error
@@ -1281,8 +1380,8 @@ gst_message_new_duration
 gst_message_parse_duration
 gst_message_new_latency
 gst_message_new_async_start
-gst_message_parse_async_start
 gst_message_new_async_done
+gst_message_parse_async_done
 gst_message_new_step_start
 gst_message_parse_step_start
 gst_message_new_qos
@@ -1342,55 +1441,45 @@ GST_MESSAGE_WAIT
 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
 GST_MINI_OBJECT_FLAG_UNSET
 GST_MINI_OBJECT_REFCOUNT
 GST_MINI_OBJECT_REFCOUNT_VALUE
+GST_MINI_OBJECT_SIZE
+
+gst_mini_object_register
+gst_mini_object_init
 
-gst_mini_object_new
 gst_mini_object_copy
 gst_mini_object_is_writable
 gst_mini_object_make_writable
 
 gst_mini_object_ref
 gst_mini_object_unref
-gst_mini_object_replace
 
 gst_mini_object_weak_ref
 gst_mini_object_weak_unref
 
-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_replace
+gst_mini_object_steal
+gst_mini_object_take
 
 <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
 
-GST_IS_PARAM_SPEC_MINI_OBJECT
-GST_PARAM_SPEC_MINI_OBJECT
-GST_TYPE_PARAM_MINI_OBJECT
 <SUBSECTION Private>
-gst_mini_object_get_type
 gst_mini_object_flags_get_type
-gst_param_spec_mini_object_get_type
 </SECTION>
 
 
@@ -1406,14 +1495,8 @@ GST_OBJECT_FLAG_SET
 GST_OBJECT_FLAG_UNSET
 GST_OBJECT_NAME
 GST_OBJECT_PARENT
-GST_OBJECT_IS_DISPOSING
-GST_OBJECT_IS_FLOATING
 GST_OBJECT_REFCOUNT
 GST_OBJECT_REFCOUNT_VALUE
-GST_CLASS_GET_LOCK
-GST_CLASS_LOCK
-GST_CLASS_TRYLOCK
-GST_CLASS_UNLOCK
 GST_OBJECT_LOCK
 GST_OBJECT_TRYLOCK
 GST_OBJECT_UNLOCK
@@ -1424,22 +1507,15 @@ gst_object_get_name
 gst_object_set_parent
 gst_object_get_parent
 gst_object_unparent
-gst_object_get_name_prefix
-gst_object_set_name_prefix
 gst_object_default_deep_notify
 gst_object_default_error
 gst_object_check_uniqueness
 gst_object_has_ancestor
-gst_object_save_thyself
-gst_object_restore_thyself
 gst_object_ref
 gst_object_unref
 gst_object_ref_sink
-gst_object_sink
 gst_object_replace
 gst_object_get_path_string
-gst_class_signal_connect
-gst_class_signal_emit_by_name
 <SUBSECTION Standard>
 GST_OBJECT
 GST_IS_OBJECT
@@ -1453,7 +1529,6 @@ GST_OBJECT_CLASS_CAST
 <SUBSECTION Private>
 gst_object_get_type
 gst_object_flags_get_type
-GstXmlNodePtr
 </SECTION>
 
 
@@ -1471,6 +1546,11 @@ GstPadLinkCheck
 GST_PAD_LINK_CHECK_DEFAULT
 GstFlowReturn
 GstActivateMode
+GstProbeReturn
+GstProbeType
+GST_PROBE_TYPE_BLOCKING
+GST_PROBE_TYPE_DATA
+GST_PROBE_TYPE_SCHEDULING
 
 <SUBSECTION Application>
 gst_pad_get_name
@@ -1489,6 +1569,7 @@ gst_pad_get_caps
 gst_pad_get_caps_reffed
 gst_pad_get_allowed_caps
 gst_pad_get_negotiated_caps
+gst_pad_get_current_caps
 gst_pad_get_pad_template_caps
 gst_pad_set_caps
 
@@ -1496,45 +1577,34 @@ gst_pad_get_peer
 gst_pad_peer_get_caps
 gst_pad_peer_get_caps_reffed
 gst_pad_use_fixed_caps
+gst_pad_has_current_caps
+
+gst_pad_get_sticky_event
+GstPadStickyEventsForeachFunction
+gst_pad_sticky_events_foreach
 
 gst_pad_is_active
 
-gst_pad_set_blocked
-gst_pad_set_blocked_async
-gst_pad_set_blocked_async_full
-GstPadBlockCallback
 gst_pad_is_blocked
 gst_pad_is_blocking
 
-gst_pad_add_data_probe
-gst_pad_add_data_probe_full
-gst_pad_add_buffer_probe
-gst_pad_add_buffer_probe_full
-gst_pad_add_event_probe
-gst_pad_add_event_probe_full
-gst_pad_remove_data_probe
-gst_pad_remove_buffer_probe
-gst_pad_remove_event_probe
+GstPadProbeCallback
+gst_pad_add_probe
+gst_pad_remove_probe
 
+gst_pad_get_offset
+gst_pad_set_offset
 <SUBSECTION Element>
 gst_pad_new
 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
 
 gst_pad_set_chain_list_function
 GstPadChainListFunction
 
-gst_pad_set_checkgetrange_function
-GstPadCheckGetRangeFunction
-
 gst_pad_get_range
 gst_pad_set_getrange_function
 GstPadGetRangeFunction
@@ -1555,16 +1625,10 @@ gst_pad_set_getcaps_function
 GstPadGetCapsFunction
 gst_pad_proxy_getcaps
 
-gst_pad_set_setcaps_function
-GstPadSetCapsFunction
-gst_pad_proxy_setcaps
-
 gst_pad_fixate_caps
 gst_pad_set_fixatecaps_function
 GstPadFixateCapsFunction
 
-gst_pad_get_fixed_caps_func
-
 gst_pad_peer_accept_caps
 
 gst_pad_set_activate_function
@@ -1577,7 +1641,6 @@ GstPadActivateModeFunction
 gst_pad_push
 gst_pad_push_event
 gst_pad_push_list
-gst_pad_check_pull_range
 gst_pad_pull_range
 gst_pad_activate_pull
 gst_pad_activate_push
@@ -1605,19 +1668,11 @@ GstPadIterIntLinkFunction
 gst_pad_iterate_internal_links
 gst_pad_iterate_internal_links_default
 
-gst_pad_set_internal_link_function
-GstPadIntLinkFunction
-gst_pad_get_internal_links
-gst_pad_get_internal_links_default
-
-gst_pad_load_and_link
-
-gst_pad_dispatcher
-GstPadDispatcherFunction
-
 gst_pad_set_element_private
 gst_pad_get_element_private
 
+GstPadForwardFunction
+gst_pad_forward
 <SUBSECTION Core>
 gst_pad_chain
 gst_pad_chain_list
@@ -1628,8 +1683,6 @@ gst_pad_stop_task
 
 gst_pad_set_active
 
-GST_PAD_CAPS
-
 GST_PAD_GET_STREAM_LOCK
 GST_PAD_STREAM_LOCK
 GST_PAD_STREAM_LOCK_FULL
@@ -1637,9 +1690,6 @@ GST_PAD_STREAM_TRYLOCK
 GST_PAD_STREAM_UNLOCK
 GST_PAD_STREAM_UNLOCK_FULL
 
-GST_FLOW_IS_FATAL
-GST_FLOW_IS_SUCCESS
-
 <SUBSECTION Standard>
 GstPadClass
 GstPadPrivate
@@ -1655,6 +1705,8 @@ GST_TYPE_PAD_LINK_CHECK
 GST_TYPE_PAD_PRESENCE
 GST_TYPE_FLOW_RETURN
 GST_TYPE_ACTIVATE_MODE
+GST_TYPE_PROBE_RETURN
+GST_TYPE_PROBE_TYPE
 
 <SUBSECTION Private>
 gst_pad_get_type
@@ -1665,6 +1717,8 @@ gst_pad_link_check_get_type
 gst_pad_presence_get_type
 gst_flow_return_get_type
 gst_activate_mode_get_type
+gst_probe_return_get_type
+gst_probe_type_get_type
 
 GST_PAD_NAME
 GST_PAD_PARENT
@@ -1675,6 +1729,9 @@ GST_PAD_PEER
 GST_PAD_IS_LINKED
 GST_PAD_IS_SRC
 GST_PAD_IS_SINK
+GST_PAD_IS_FIXED_CAPS
+GST_PAD_NEEDS_EVENTS
+GST_PAD_NEEDS_RECONFIGURE
 
 GST_PAD_IS_IN_GETCAPS
 GST_PAD_MODE_ACTIVATE
@@ -1699,18 +1756,16 @@ GST_PAD_ACTIVATEPULLFUNC
 GST_PAD_ACTIVATEPUSHFUNC
 GST_PAD_BUFFERALLOCFUNC
 GST_PAD_CHAINFUNC
-GST_PAD_CHECKGETRANGEFUNC
+GST_PAD_CHAINLISTFUNC
 GST_PAD_EVENTFUNC
 GST_PAD_FIXATECAPSFUNC
 GST_PAD_GETCAPSFUNC
 GST_PAD_GETRANGEFUNC
-GST_PAD_INTLINKFUNC
 GST_PAD_ITERINTLINKFUNC
 GST_PAD_IS_FLUSHING
 GST_PAD_LINKFUNC
 GST_PAD_QUERYFUNC
 GST_PAD_QUERYTYPEFUNC
-GST_PAD_SETCAPSFUNC
 GST_PAD_UNLINKFUNC
 
 GST_PAD_PREROLL_BROADCAST
@@ -1832,9 +1887,6 @@ gst_pipeline_get_clock
 gst_pipeline_use_clock
 gst_pipeline_auto_clock
 
-gst_pipeline_set_new_stream_time
-gst_pipeline_get_last_stream_time
-
 gst_pipeline_set_auto_flush_bus
 gst_pipeline_get_auto_flush_bus
 
@@ -1869,7 +1921,6 @@ GstPluginDesc
 GstPluginInitFunc
 GstPluginInitFullFunc
 GST_PLUGIN_DEFINE
-GST_PLUGIN_DEFINE_STATIC
 GST_LICENSE_UNKNOWN
 GstPluginFilter
 gst_plugin_get_name
@@ -1922,7 +1973,6 @@ gst_plugin_flags_get_type
 <FILE>gstpluginfeature</FILE>
 <TITLE>GstPluginFeature</TITLE>
 GstPluginFeature
-GST_PLUGIN_FEATURE_NAME
 GstTypeNameData
 GstPluginFeatureFilter
 GstRank
@@ -2024,8 +2074,11 @@ gst_query_ref
 gst_query_unref
 gst_query_copy
 gst_query_make_writable
+gst_query_is_writable
+gst_query_replace
+gst_query_writable_structure
 
-gst_query_new_application
+gst_query_new_custom
 gst_query_get_structure
 
 gst_query_new_convert
@@ -2051,8 +2104,8 @@ gst_query_parse_seeking
 gst_query_new_formats
 gst_query_set_formats
 gst_query_set_formatsv
-gst_query_parse_formats_length
-gst_query_parse_formats_nth
+gst_query_parse_n_formats
+gst_query_parse_nth_format
 
 gst_query_new_segment
 gst_query_set_segment
@@ -2073,6 +2126,21 @@ gst_query_parse_nth_buffering_range
 gst_query_new_uri
 gst_query_parse_uri
 gst_query_set_uri
+
+gst_query_new_allocation
+gst_query_parse_allocation
+gst_query_parse_allocation_params
+gst_query_parse_nth_allocation_memory
+gst_query_parse_nth_allocation_meta
+gst_query_set_allocation_params
+gst_query_add_allocation_memory
+gst_query_add_allocation_meta
+gst_query_get_n_allocation_memories
+gst_query_get_n_allocation_metas
+
+gst_query_new_scheduling
+gst_query_parse_scheduling
+gst_query_set_scheduling
 <SUBSECTION Standard>
 GstQueryClass
 GST_QUERY
@@ -2139,8 +2207,6 @@ GST_MAGIC_BINARY_VERSION_STR
 GST_MAGIC_BINARY_VERSION_LEN
 gst_registry_get_type
 GstRegistryPrivate
-gst_registry_xml_read_cache
-gst_registry_xml_write_cache
 </SECTION>
 
 
@@ -2148,23 +2214,23 @@ gst_registry_xml_write_cache
 <FILE>gstsegment</FILE>
 <TITLE>GstSegment</TITLE>
 GstSegment
+GstSegmentFlags
 gst_segment_clip
 gst_segment_init
 gst_segment_new
 gst_segment_copy
 gst_segment_free
-gst_segment_set_duration
-gst_segment_set_last_stop
-gst_segment_set_newsegment
-gst_segment_set_newsegment_full
-gst_segment_set_seek
+gst_segment_do_seek
 gst_segment_to_running_time
 gst_segment_to_stream_time
 gst_segment_to_position
 gst_segment_set_running_time
+gst_segment_copy_into
 <SUBSECTION Standard>
 GST_TYPE_SEGMENT
+GST_TYPE_SEGMENT_FLAGS
 gst_segment_get_type
+gst_segment_flags_get_type
 <SUBSECTION Private>
 </SECTION>
 
@@ -2238,6 +2304,7 @@ gst_structure_fixate_field_boolean
 gst_structure_fixate_field_string
 <SUBSECTION Standard>
 GST_STRUCTURE
+GST_STRUCTURE_CAST
 GST_IS_STRUCTURE
 GST_TYPE_STRUCTURE
 <SUBSECTION Private>
@@ -2641,21 +2708,8 @@ gst_uri_type_get_type
 <SECTION>
 <FILE>gstutils</FILE>
 <TITLE>GstUtils</TITLE>
-GST_BOILERPLATE_WITH_INTERFACE
-GST_BOILERPLATE_FULL
-GST_BOILERPLATE
 GST_CALL_PARENT
 GST_CALL_PARENT_WITH_DEFAULT
-GDOUBLE_FROM_BE
-GDOUBLE_FROM_LE
-GDOUBLE_TO_BE
-GDOUBLE_TO_LE
-GDOUBLE_SWAP_LE_BE
-GFLOAT_FROM_BE
-GFLOAT_FROM_LE
-GFLOAT_TO_BE
-GFLOAT_TO_LE
-GFLOAT_SWAP_LE_BE
 GST_READ_UINT8
 GST_READ_UINT16_LE
 GST_READ_UINT16_BE
@@ -2695,7 +2749,6 @@ GST_ROUND_DOWN_16
 GST_ROUND_DOWN_32
 GST_ROUND_DOWN_64
 
-gst_atomic_int_set
 gst_flow_get_name
 gst_flow_to_quark
 gst_print_element_args
@@ -2837,9 +2890,7 @@ GST_VALUE_HOLDS_STRUCTURE
 gst_value_set_structure
 gst_value_get_structure
 
-<SUBSECTION miniobject>
-GST_VALUE_HOLDS_MINI_OBJECT
-
+<SUBSECTION buffer>
 GST_VALUE_HOLDS_BUFFER
 gst_value_get_buffer
 gst_value_set_buffer
@@ -2879,6 +2930,7 @@ gst_value_array_append_value
 gst_value_array_get_size
 gst_value_array_get_value
 gst_value_array_prepend_value
+gst_value_fixate
 
 
 <SUBSECTION Private>
@@ -2904,29 +2956,3 @@ GST_VERSION_NANO
 GST_CHECK_VERSION
 </SECTION>
 
-
-<SECTION>
-<FILE>gstxml</FILE>
-<TITLE>GstXML</TITLE>
-GstXML
-
-gst_xml_write
-gst_xml_write_file
-gst_xml_new
-gst_xml_parse_doc
-gst_xml_parse_file
-gst_xml_parse_memory
-gst_xml_get_element
-gst_xml_get_topelements
-gst_xml_make_element
-<SUBSECTION Standard>
-GstXMLClass
-GST_XML
-GST_IS_XML
-GST_XML_CLASS
-GST_IS_XML_CLASS
-GST_XML_GET_CLASS
-GST_TYPE_XML
-<SUBSECTION Private>
-gst_xml_get_type
-</SECTION>
index 2bcd498..3ac4043 100644 (file)
@@ -30,7 +30,6 @@ gst_tag_setter_get_type
 gst_task_get_type
 gst_type_find_factory_get_type
 gst_uri_handler_get_type
-@GST_LOADSAVE_DOC_TYPES@gst_xml_get_type
 
 % these are not GObject derived types
 % this works with gtk-doc 1.10 at least
index 621cbbd..29f4fcd 100644 (file)
@@ -38,10 +38,6 @@ gst_dp_crc
 gst_dp_header_payload_length
 gst_dp_header_payload_type
 
-gst_dp_header_from_buffer
-gst_dp_packet_from_caps
-gst_dp_packet_from_event
-
 gst_dp_buffer_from_header
 gst_dp_caps_from_packet
 gst_dp_event_from_packet
@@ -75,12 +71,6 @@ gst_controller_set_control_source
 gst_controller_get
 gst_controller_get_value_arrays
 gst_controller_get_value_array
-gst_controller_set
-gst_controller_set_from_list
-gst_controller_unset
-gst_controller_unset_all
-gst_controller_get_all
-gst_controller_set_interpolation_mode
 <SUBSECTION Standard>
 GstControllerClass
 GstControllerPrivate
@@ -198,7 +188,8 @@ GstAdapter
 gst_adapter_new
 gst_adapter_clear
 gst_adapter_push
-gst_adapter_peek
+gst_adapter_map
+gst_adapter_unmap
 gst_adapter_copy
 gst_adapter_flush
 gst_adapter_available
@@ -236,6 +227,7 @@ gst_base_parse_set_passthrough
 gst_base_parse_set_syncable
 gst_base_parse_set_has_timing_info
 gst_base_parse_set_frame_rate
+gst_base_parse_set_latency
 gst_base_parse_convert_default
 gst_base_parse_add_index_entry
 
@@ -288,6 +280,7 @@ gst_base_src_get_do_timestamp
 gst_base_src_set_do_timestamp
 gst_base_src_set_dynamic_size
 gst_base_src_new_seamless_segment
+gst_base_src_set_dynamic_size
 
 GST_BASE_SRC_PAD
 <SUBSECTION Standard>
@@ -337,6 +330,15 @@ gst_base_sink_get_throttle_time
 gst_base_sink_set_throttle_time
 
 GST_BASE_SINK_PAD
+GST_BASE_SINK_GET_PREROLL_COND
+GST_BASE_SINK_GET_PREROLL_LOCK
+GST_BASE_SINK_PREROLL_BROADCAST
+GST_BASE_SINK_PREROLL_LOCK
+GST_BASE_SINK_PREROLL_SIGNAL
+GST_BASE_SINK_PREROLL_TIMED_WAIT
+GST_BASE_SINK_PREROLL_TRYLOCK
+GST_BASE_SINK_PREROLL_UNLOCK
+GST_BASE_SINK_PREROLL_WAIT
 
 <SUBSECTION Standard>
 GST_BASE_SINK
@@ -401,14 +403,11 @@ gst_base_transform_get_type
 GstBitReader
 
 GST_BIT_READER_INIT
-GST_BIT_READER_INIT_FROM_BUFFER
 
 gst_bit_reader_new
-gst_bit_reader_new_from_buffer
 gst_bit_reader_free
 
 gst_bit_reader_init
-gst_bit_reader_init_from_buffer
 
 gst_bit_reader_get_pos
 gst_bit_reader_get_remaining
@@ -451,14 +450,11 @@ GST_BIT_READER
 GstByteReader
 
 GST_BYTE_READER_INIT
-GST_BYTE_READER_INIT_FROM_BUFFER
 
 gst_byte_reader_new
-gst_byte_reader_new_from_buffer
 gst_byte_reader_free
 
 gst_byte_reader_init
-gst_byte_reader_init_from_buffer
 
 gst_byte_reader_get_pos
 gst_byte_reader_get_remaining
@@ -608,12 +604,10 @@ g_memdup
 GstByteWriter
 
 gst_byte_writer_new
-gst_byte_writer_new_with_buffer
 gst_byte_writer_new_with_data
 gst_byte_writer_new_with_size
 
 gst_byte_writer_init
-gst_byte_writer_init_with_buffer
 gst_byte_writer_init_with_data
 gst_byte_writer_init_with_size
 
@@ -719,7 +713,6 @@ gst_collect_pads_set_flushing
 gst_collect_pads_peek
 gst_collect_pads_pop
 gst_collect_pads_available
-gst_collect_pads_read
 gst_collect_pads_read_buffer
 gst_collect_pads_take_buffer
 gst_collect_pads_flush
@@ -768,6 +761,7 @@ gst_push_src_get_type
 gst_type_find_helper
 gst_type_find_helper_for_buffer
 gst_type_find_helper_for_extension
+gst_type_find_helper_for_data
 GstTypeFindHelperGetRangeFunction
 gst_type_find_helper_get_range
 gst_type_find_helper_get_range_ext
@@ -881,12 +875,14 @@ fail_unless_equals_int
 fail_unless_equals_float
 fail_unless_equals_string
 fail_unless_equals_uint64
+fail_unless_equals_int64
 fail_unless_message_error
 
 assert_equals_int
 assert_equals_float
 assert_equals_string
 assert_equals_uint64
+assert_equals_int64
 assert_message_error
 
 gst_check_init
@@ -901,6 +897,7 @@ gst_check_teardown_element
 gst_check_teardown_sink_pad
 gst_check_teardown_src_pad
 gst_check_drop_buffers
+gst_check_buffer_data
 gst_check_caps_equal
 gst_check_element_push_buffer_list
 gst_check_element_push_buffer
index 58889da..3e24f71 100644 (file)
@@ -344,7 +344,7 @@ cb_newpad (GstElement *element,
 {
   GstCaps *caps;
 
-  caps = gst_pad_get_caps (pad);
+  caps = gst_pad_get_caps (pad, NULL);
   try_to_plug (pad, caps);
   gst_caps_unref (caps);
 }
@@ -389,7 +389,7 @@ close_link (GstPad      *srcpad,
     switch (templ->presence) {
       case GST_PAD_ALWAYS: {
         GstPad *pad = gst_element_get_static_pad (sinkelement, templ->name_template);
-        GstCaps *caps = gst_pad_get_caps (pad);
+        GstCaps *caps = gst_pad_get_caps (pad, NULL);
 
         /* link */
         try_to_plug (pad, caps);
@@ -436,7 +436,8 @@ try_to_plug (GstPad        *pad,
   }
 
   /* can it link to the audiopad? */
-  audiocaps = gst_pad_get_caps (gst_element_get_static_pad (audiosink, "sink"));
+  audiocaps = gst_pad_get_caps (gst_element_get_static_pad (audiosink, "sink"),
+  NULL);
   res = gst_caps_intersect (caps, audiocaps);
   if (res &amp;&amp; !gst_caps_is_empty (res)) {
     g_print ("Found pad to link to audiosink - plugging is now done\n");
index 0db6e3c..60d1f72 100644 (file)
@@ -56,17 +56,23 @@ cb_have_data (GstPad    *pad,
              gpointer   u_data)
 {
   gint x, y;
-  guint16 *data = (guint16 *) GST_BUFFER_DATA (buffer), t;
+  guint16 *data, *ptr, t;
+  gsize size;
+  
+  data = gst_buffer_map (buffer, &amp;size, NULL, GST_MAP_WRITE);
 
+  ptr = data;
   /* invert data */
   for (y = 0; y &lt; 288; y++) {
     for (x = 0; x &lt; 384 / 2; x++) {
-      t = data[384 - 1 - x];
-      data[384 - 1 - x] = data[x];
-      data[x] = t;
+      t = ptr[384 - 1 - x];
+      ptr[384 - 1 - x] = ptr[x];
+      ptr[x] = t;
     }
-    data += 384;
+    ptr += 384;
   }
+  gst_buffer_unmap (buffer, data, size);
+
 
   return TRUE;
 }
@@ -282,11 +288,16 @@ cb_handoff (GstElement *fakesrc,
            gpointer    user_data)
 {
   static gboolean white = FALSE;
+  gpointer data;
+  gsize size;
+  
+  data = gst_buffer_map (buffer, &amp;size, NULL, GST_MAP_WRITE);
 
   /* this makes the image black/white */
-  memset (GST_BUFFER_DATA (buffer), white ? 0xff : 0x0,
-         GST_BUFFER_SIZE (buffer));
+  memset (data, white ? 0xff : 0x0, size);
   white = !white;
+
+  gst_buffer_unmap (buffer, data, size);
 }
 
 gint
index 87d1d5f..b65df9a 100644 (file)
@@ -253,7 +253,7 @@ cb_newpad (GstElement *decodebin,
   }
 
   /* check media type */
-  caps = gst_pad_get_caps (pad);
+  caps = gst_pad_get_caps (pad, NULL);
   str = gst_caps_get_structure (caps, 0);
   if (!g_strrstr (gst_structure_get_name (str), "audio")) {
     gst_caps_unref (caps);
index fd88bb8..1198280 100644 (file)
 <RANGE></RANGE>
 <FLAGS>rw</FLAGS>
 <NICK>Single Segment</NICK>
-<BLURB>Timestamp buffers and eat newsegments so as to appear as one segment.</BLURB>
+<BLURB>Timestamp buffers and eat segments so as to appear as one segment.</BLURB>
 <DEFAULT>FALSE</DEFAULT>
 </ARG>
 
index ea81e4a..1c36392 100644 (file)
@@ -1,44 +1,45 @@
 GObject
-  GstObject
-    GstBus
-    GstClock
-    GstElement
-      GstBaseSink
-        GstFakeSink
-        GstFdSink
-        GstFileSink
-      GstBaseSrc
-        GstFakeSrc
-        GstFileSrc
-        GstPushSrc
-          GstFdSrc
-      GstBaseTransform
-        GstCapsFilter
-        GstIdentity
-      GstBin
-        GstPipeline
-      GstFunnel
-      GstInputSelector
-      GstMultiQueue
-      GstOutputSelector
-      GstQueue
-      GstQueue2
-      GstTee
-      GstTypeFindElement
-      GstValve
-    GstIndex
-      GstMemIndex
-    GstPad
-    GstPadTemplate
-    GstPlugin
-    GstPluginFeature
-      GstElementFactory
-      GstIndexFactory
-      GstTypeFindFactory
-    GstRegistry
-    GstTask
-    GstTaskPool
-  GstSignalObject
+  GInitiallyUnowned
+    GstObject
+      GstPad
+      GstPadTemplate
+      GstPluginFeature
+        GstElementFactory
+        GstTypeFindFactory
+        GstIndexFactory
+      GstElement
+        GstBin
+          GstPipeline
+        GstBaseTransform
+          GstCapsFilter
+          GstIdentity
+        GstBaseSrc
+          GstFakeSrc
+          GstPushSrc
+            GstFdSrc
+          GstFileSrc
+        GstBaseSink
+          GstFakeSink
+          GstFdSink
+          GstFileSink
+        GstFunnel
+        GstInputSelector
+        GstOutputSelector
+        GstQueue
+        GstQueue2
+        GstTee
+        GstTypeFindElement
+        GstMultiQueue
+        GstValve
+      GstBus
+      GstTask
+      GstTaskPool
+      GstClock
+      GstPlugin
+      GstRegistry
+      GstIndex
+        GstMemIndex
+        GstFileIndex
 GInterface
   GTypePlugin
   GstChildProxy
diff --git a/docs/random/plan-0.11.txt b/docs/random/plan-0.11.txt
new file mode 100644 (file)
index 0000000..3569927
--- /dev/null
@@ -0,0 +1,141 @@
+Plan for 0.11
+=============
+
+First attempt at making a list of tasks in roughly chronological order.
+
+* General cleanup
+
+  - Remove deprecated methods
+  - Cleanup structs + PADDING
+  - ..
+  
+  This should allow us to continue expanding later in the same way that 0.10 was
+  expanded.
+
+
+* Review GstCaps fields
+
+  - go over caps fields for audio, video, compressed media-type etc
+
+  We need to express things with less fields. This would speed up caps, make
+  them less verbose and speed up some elements.
+
+
+* Add GstFlowReturn for events (and query)
+
+  This would allow us to know more precisely what went wrong.
+
+  http://cgit.freedesktop.org/~wtay/gstreamer/log/?h=events2
+
+
+* add return structure for events and query
+
+  Make events return more information. (a seek event might want to return the
+  final position of the keyframe seek and the accuracy of the seek)
+
+  Make bindings easiers. Currently the writability of a query depends on the
+  refcount being exactly 1. If the query is not writable, it simply cannot be
+  answered.
+
+
+* Make GstMiniObject a simple boxed type
+
+  - Move copy and free function to structure
+  - convert GstBuffer, GstEvent, GstMessage, GstQuery,
+
+  We don't need to subclass miniobjects when we have arbitrary metadata. 
+
+  Allocation should be more efficient and buffer/metadata/data can be allocated
+  and pooled in one contiguous memory area.
+
+  Typechecking of various types is much more efficient when there is only
+  one class.
+
+  http://cgit.freedesktop.org/~wtay/gstreamer/log/?h=miniobject2
+
+
+* Convert GstCaps to GstMiniObject
+
+  Currently it has its own refcounting and flags.
+
+  http://cgit.freedesktop.org/~wtay/gstreamer/log/?h=miniobject2
+
+
+* GVariant registry
+
+  - allow for mmaped registy (tpm)
+
+* Incremental caps
+
+  - Remove array from caps ?
+  - make caps iterator or is the array the cache for iterator ?
+
+  We need to perform less caps operations when negotiating formats. One way is
+  to only handle small caps objects incrementally.
+
+  http://cgit.freedesktop.org/~ensonic/gstreamer/log/?h=lazycaps
+
+
+* Make GstBufferMetadata
+
+  - Make functions to register metadata
+  - Make common metadata: timeinfo, memory data, video data
+  - Remove GstBuffer Fields
+  - Make methods to add metadata to buffers.
+  
+  More flexible metadata for buffers.
+
+  http://cgit.freedesktop.org/~wtay/gstreamer/log/?h=buffermeta
+
+
+* Negotiation of metadata
+
+  - figure out if we need to negotiate the metadata on the caps or if we can
+    gracefully degrade when an element doesn't understand the metadata.
+
+  We need to avoid that elements put metadata on buffers that is essential in
+  handling the buffer contents but that is then not understood by other
+  elements.
+
+
+* Rework reverse negotiation
+
+  - upstream event to notify of a downstream caps change
+  - _alloc_buffer() takes input GstBuffer prototype (or NULL)
+  - _alloc_buffer() never returns changed caps.
+
+  One of the performance problems in 0.10 is that transform elements need to
+  call gst_pad_alloc_buffer() downstream to check if the caps changed. This
+  usually also results in a useless memory allocation. 
+  
+  We would make a new upstream event to notify downstream elements that new caps
+  are possible somewhere downstream.
+
+  gst_pad_alloc_buffer() would take a GstBuffer as an input argument to make the
+  API easier, we can then use metadata to specify additional contraints for the
+  new buffer (such as strides, etc)
+  
+
+* Incremental event progation
+
+  - certain events would be sticky on a pad like for caps
+  - rules for pushing an event downstream
+     - right before pushing a buffer
+     - after link operation
+  - activate for most serialized downstream events
+
+  This would allow an application to have more control over the state of the
+  dataflow in a pipeline. 
+
+
+* GstSegment changes
+
+  - remove segment accumulation
+  - add accumulated time to the event
+  - apply segment info to pads
+  - add method on pads to get/adjust sync offset
+  - add method on pads to query current running_time 
+
+  The goal is to make the timing model more comprehensible and thus make dynamic
+  pipeline plugging easier.
+
diff --git a/docs/random/porting-to-0.11.txt b/docs/random/porting-to-0.11.txt
new file mode 100644 (file)
index 0000000..828aaf5
--- /dev/null
@@ -0,0 +1,321 @@
+The 0.11 porting guide
+----------------------
+
+* All deprecated methods were removed. Recompile against 0.10 with
+  DISABLE_DEPRECATED and fix issues before attempting to port to 0.11.
+
+* GST_BOILERPLATE is gone, use G_DEFINE_TYPE instead.
+
+* various methods take a gsize instead of a guint when talking about memory
+  sizes.
+
+* multifdsink, tcpclientsink, tcpclientsrc, tcpserversrc the protocol property
+  is removed, use gdppay and gdpdepay.
+
+* Presets and plugins moved to $XDG_DATA_HOME/gstreamer-0.11/ root
+  directory. Registry moved to $XDG_CACHE_HOME/gstreamer-0.11/.
+  XDG_CACHE_HOME usually points to $HOME/.cache and XDG_DATA_HOME
+  usually is $HOME/.local/share/.
+
+* GstObject:
+    GST_OBJECT_DISPOSING flag removed
+    GST_OBJECT_IS_DISPOSING removed
+    GST_OBJECT_FLOATING flag remove, GstObject is now GInitiallyUnowned
+    GST_OBJECT_IS_FLOATING removed, use g_object_is_floating()
+
+    GST_CLASS_GET_LOCK, GST_CLASS_LOCK, GST_CLASS_TRYLOCK, GST_CLASS_UNLOCK,
+    used to be a workaround for thread-unsafe glib < 2.8
+
+    gst_object_ref_sink() has gpointer as result to make it more like the
+    GObject version.
+
+    gst_object_sink() removed, use gst_object_ref_sink() instead.
+
+    gst_class_signal_connect() removed, was only used for XML
+
+    parent-set and parent-unset signals removed. Use notify:parent. Currently
+    still disabled because of deep notify locking issues.
+
+* GstElement:
+    GstElementDetails is removed and replaced with more generic metadata.
+
+    gst_element_class_set_details_simple() -> gst_element_class_set_metadata()
+    gst_element_class_set_documentation_uri -> gst_element_class_add_metadata
+    gst_element_class_set_icon_name -> gst_element_class_add_metadata
+    also gst_element_class_get_metadata()
+
+    gst_element_factory_get_longname -> gst_element_factory_get_metadata
+    gst_element_factory_get_klass -> gst_element_factory_get_metadata
+    gst_element_factory_get_description -> gst_element_factory_get_metadata
+    gst_element_factory_get_author -> gst_element_factory_get_metadata
+    gst_element_factory_get_documentation_uri -> gst_element_factory_get_metadata
+    gst_element_factory_get_icon_name -> gst_element_factory_get_metadata
+
+    gstelementmetadata.h contains the keys for all standard metadata.
+
+    gst_element_factory_can_{src,sink}_caps() => gst_element_factory_can_{src,sink}_{any,all}_caps()
+
+    Element metadata and pad templates are inherited from parent classes and
+    should be added in class_init instead of base_init.
+
+    gst_element_class_add_pad_template() takes ownership of the template
+
+    Elements that change the duration must post DURATION messages on the
+    bus when the duration changes in PAUSED or PLAYING.
+
+    gst_element_lost_state_full() -> gst_element_lost_state()
+    gst_element_lost_state() -> gst_element_lost_state(, TRUE)
+
+    request_new_pad_full() -> request_new_pad()
+
+* GstPad:
+    gst_pad_get_caps() does not return writable caps anymore and an explicit
+    gst_caps_make_writable() needs to be performed. This was the functionality
+    of gst_pad_get_caps_reffed(), which is removed now.
+
+    A similar change was done for gst_pad_peer_get_caps() and
+    gst_pad_peer_get_caps_reffed()
+
+    gst_pad_set_bufferalloc_function(), gst_pad_alloc_buffer() and
+    gst_pad_alloc_buffer_and_set_caps() are removed. Use the ALLOCATION query
+    now to obtain a reference to a bufferpool object that can be used to
+    allocate buffers.
+
+    removed sched_private, it should not be used, use g_object_set_qdata() or
+    use element_private.
+
+    Removed GST_PAD_CAPS() use gst_pad_get_current_caps() to get a handle to the
+    currently configured caps.
+
+    GstPadGetCapsFunction, gst_pad_get_caps(), gst_pad_peer_get_caps(),
+    gst_pad_proxy_getcaps() now takes a GstCaps* parameter to inform
+    the other side about the possible caps and preferences.
+
+    gst_pad_get_pad_template_caps() and gst_pad_get_pad_template()
+    return a new reference of the caps or template now and the return
+    value needs to be unreffed after usage.
+
+    gst_pad_set_caps() now pushes a CAPS event for backward compatibility.
+    Consider sending the CAPS event yourself. It is not possible anymore to set
+    NULL caps.
+
+    gst_pad_set_checkgetrange_function() and gst_pad_check_pull_range() are
+    gone, use the SCHEDULING query now.
+
+    gst_pad_set_blocked(), gst_pad_set_blocked_async(),
+    gst_pad_set_blocked_async_full() are removed, use the gst_pad_add_probe()
+    method with the GST_PROBE_TYPE_BLOCK to get the same result as the async
+    blocking version. There is no more sync version of blocking, this is in
+    general dangerous and can be implemented using the callbacks if needed.
+
+    gst_pad_add_data_probe(), gst_pad_add_data_probe_full(),
+    gst_pad_remove_data_probe(), gst_pad_add_event_probe(),
+    gst_pad_add_event_probe_full(), gst_pad_remove_event_probe(),
+    gst_pad_add_buffer_probe(), gst_pad_add_buffer_probe_full(),
+    gst_pad_remove_buffer_probe() are removed. Use gst_pad_add_probe() and
+    gst_pad_remove_probe() for equivalent functionality.
+
+    The have-data signal was removed from pads, it was never supposed to be used
+    without calling the _add_.*_probe() methods.
+
+    The request-link signal was removed. It was never used.
+
+* GstPadTemplate
+    gst_pad_template_get_caps() returns a new reference of the caps
+    and the return value needs to be unreffed after usage.
+
+    gst_pad_template_new() does not take ownership of the caps anymore.
+
+    GstPadTemplate is now created with a floating ref and
+    gst_element_class_add_pad_template() takes ownership of this floating ref.
+
+    GstPadTemplate instances are considered immutable and must not be
+    changed.
+
+* GstMiniObject
+    A miniobject is now a simple refcounted structure holding the information
+    common to buffers, events, messages, queries and caps.
+
+    There is no more GST_TYPE_MINIOBJECT as the type for subclasses.
+    G_TYPE_BOXED can be used as the type of all GstMiniObject based types such
+    as buffers, events, messages, caps, etc. Signals, for example, would use the
+    boxed type if the argument include GstMiniObject derived types.
+
+    gst_mini_object_new() is removed. You would allocate memory with the the
+    methods specific for the derived type.
+
+    GstParamSpecMiniObject is removed, use boxed param spec now with the GType
+    of the specific GstMiniObject derived type. Also
+    gst_param_spec_mini_object().
+
+    gst_param_spec_mini_object() -> g_param_spec_boxed()
+
+    The specific gst_value_*_mini_object() methods are removed, used the generic
+    boxed methods instead.
+
+    gst_value_set_mini_object() -> g_value_set_boxed()
+    gst_value_take_mini_object() -> g_value_take_boxed()
+    gst_value_take_get_object() -> g_value_get_boxed()
+    gst_value_take_dup_object() -> g_value_dup_boxed()
+
+    GST_VALUE_HOLDS_MINI_OBJECT() was removed, use G_VALUE_HOLDS_BOXED() or
+    type-specific GST_VALUE_HOLDS_{BUFFER,CAPS,etc.}() instead.
+
+    The GST_MINI_OBJECT_READONLY flag was removed as it used to mark the
+    memory in buffers as READONLY. Marking memory READONLY can now be done
+    with the GstMemory API. Writability of miniobjects is now only done by using
+    the refcount.
+
+* GstBuffer
+    A GstBuffer is now a simple boxed type this means that subclassing is not
+    possible anymore. 
+
+    To add data to the buffer you would now use gst_buffer_take_memory() with
+    a GstMemory object containing the data. Multiple memory blocks can added to
+    a GstBuffer that can then be retrieved with gst_buffer_peek_memory().
+
+    GST_BUFFER_DATA(), GST_BUFFER_MALLOCDATA(), GST_BUFFER_FREE_FUNC() and
+    GST_BUFFER_SIZE() are gone, along with the fields in GstBuffer. Use the
+    memory API to get access to the buffer data. GST_BUFFER_SIZE() can be
+    replaced with gst_buffer_get_size() but if also access to the data is
+    required, gst_buffer_map() can return both the size and data in one go.
+
+    The most common way to access all the data in a buffer is by using
+    gst_buffer_map() and gst_buffer_unmap(). These calls require you to specify
+    the access mode required to the data and will automatically merge and return
+    a writable copy of the data.
+
+    The buffer must be writable (gst_buffer_is_writable()) in order to modify
+    the fields, metadata or buffer memory. gst_buffer_make_writable() will not
+    automatically make a writable copy of the memory but will instead increase
+    the refcount of the memory. The _map() and _peek_memory() methods will
+    automatically create writable copies when needed.
+    
+    gst_buffer_make_metadata_writable() is gone, you can replace this safely
+    with gst_buffer_make_writable().
+
+    gst_buffer_create_sub() is gone and can be safely replaced with
+    gst_buffer_copy_region(). 
+
+    Changing the size of the buffer data can be done with gst_buffer_resize(),
+    which will also update the metadata fields correctly. gst_buffer_set_size()
+    is #defined to a special case of gst_buffer_resize() with a 0 offset.
+
+    gst_buffer_try_new_and_alloc() is replaced with gst_buffer_new_and_alloc(),
+    which now returns NULL when memory allocation fails.
+
+    GST_BUFFER_CAPS() is gone, caps are not set on buffers anymore but are set
+    on the pads where the buffer is pushed on. Likewise GST_BUFFER_COPY_CAPS is
+    not needed anymore. gst_buffer_get/set_caps() are gone too.
+
+* GstBufferList
+    The GstBufferList object is much simplified because most of the
+    functionality in the groups is now part of the GstMemory in buffers.
+    
+    The object is reduced to encapsulating an array of buffers that you can send
+    with the regular gst_pad_push_list. The iterator is not needed anymore
+    because you can simply use gst_buffer_list_len() and gst_buffer_list_get()
+    to iterate the array.
+
+    For dealing with the groups, it's now needed to add the memory blocks to
+    GstBuffer and use the normal buffer API to get and merge the groups.
+
+* GstStructure
+
+    The GArray of the structure fields are moved to private part and are not
+    accessible from the application anymore. Use the methods to retrieve and
+    modify fields from the array.
+
+* GstEvent
+    GST_EVENT_SRC is removed. Don't use this anymore.
+
+    gst_event_new_qos_full() -> gst_event_new_qos()
+    gst_event_parse_qos_full() -> gst_event_parse_qos()
+
+    The GstStructure is removed from the public API, use the getters to get
+    a handle to a GstStructure.
+
+    GST_EVENT_NEWSEGMENT -> GST_EVENT_SEGMENT
+
+    gst_event_new_new_segment () -> gst_event_new_segment() and it takes a
+    GstSegment structure as an argument.
+    gst_event_parse_new_segment() -> gst_event_parse_segment() to retrieve the
+    GstSegment structure from the event.
+    gst_event_copy_segment() to fill a GstSegment structure.
+
+* GstQuery
+    Boxed types derived from GstMiniObject.
+
+    The GstStructure is removed from the public API, use the getters to get
+    a handle to a GstStructure.
+
+    gst_query_new_application() -> gst_query_new_custom()
+
+    gst_query_parse_formats_length() -> gst_query_parse_n_formats()
+    gst_query_parse_formats_nth() -> gst_query_parse_nth_format()
+
+* GstBufferList
+    Is now a boxed type derived from GstMiniObject.
+
+* GstMessage
+    Is now a boxed type derived from GstMiniObject
+
+    The GstStructure is removed from the public API, use the getters to get
+    a handle to a GstStructure.
+
+* GstCaps
+    Is now a boxed type derived from GstMiniObject. 
+
+* GstSegment
+    abs_rate was removed from the public fields, it can be trivially calculated
+    from the rate field.
+
+    accum was renamed to base. last_stop was renamed to position.
+
+    The segment info now contains all the information needed to convert buffer
+    timestamps to running_time and stream_time. There is no more segment
+    accumulation, the GstSegment is completely self contained.
+
+    gst_segment_set_duration() and gst_segment_set_last_stop() are removed,
+    simply modify the structure members duration and position respectively.
+
+    gst_segment_set_newsegment() is removed, it was used to accumulate segments
+    and is not needed anymore, use gst_segment_copy_into() or modify the segment
+    values directly.
+
+    gst_segment_set_seek() -> gst_segment_do_seek(). Updates the segment values
+    with seek parameters.
+
+* GstPluginFeature
+    GST_PLUGIN_FEATURE_NAME() was removed, use GST_OBJECT_NAME() instead.
+
+* GstTypeFind
+    gst_type_find_peek() returns a const guint8 * now.
+
+* GstAdapter
+    gst_adapter_peek() is removed, use gst_adapter_map() and gst_adapter_unmap()
+    to get access to raw data from the adapter.
+
+    Arguments renamed from guint to gsize.
+
+* GstBitReader, GstByteReader, GstByteWriter
+    gst_*_reader_new_from_buffer(), gst_*_reader_init_from_buffer() removed, get
+    access to the buffer data with _map() and then use the _new() functions.
+
+    gst_byte_reader_new_from_buffer() and gst_byte_reader_init_from_buffer()
+    removed, get access to the buffer data and then use the _new() functions.
+
+* GstCollectPads
+    gst_collect_pads_read() removed, use _read_buffer() or _take_buffer() and
+    then use the memory API to get to the memory.
+
+* GstBaseSrc, GstBaseTransform, GstBaseSink
+    GstBaseSrc::get_caps(), GstBaseTransform::transform_caps() and
+    GstBaseSink::get_caps() now take a filter GstCaps* parameter to
+    filter the caps and allow better negotiation decisions.
+* GstBaseTransform
+    GstBaseTransform::transform_caps() now gets the complete caps passed
+    instead of getting it passed structure by structure.
+
+
diff --git a/docs/random/use-cases-0.11.txt b/docs/random/use-cases-0.11.txt
new file mode 100644 (file)
index 0000000..6ba1d4d
--- /dev/null
@@ -0,0 +1,21 @@
+Use cases for 0.11
+------------------
+
+- improve performance 
+
+  * incremental caps
+  * cleanup caps fields
+  * Make miniobject a simple boxed type
+  * reverse negotiation with an event
+
+- buffer metadata
+
+  * Handle strides for video
+  * express crop, scaling, region of interest, ...
+  * Better support for foreign objects such as Cairo, OpenGL, OMX, ...
+
+- make dynamic pipelines easier
+
+  * sticky event propagation
+  * newsegment simplifications
+  * per-pad time offsets
index 60d4b11..8988efe 100644 (file)
@@ -1,11 +1,5 @@
 lib_LTLIBRARIES = libgstreamer-@GST_MAJORMINOR@.la
 
-if GST_DISABLE_LOADSAVE
-GST_LOADSAVE_SRC =
-else
-GST_LOADSAVE_SRC = gstxml.c
-endif
-
 if GST_DISABLE_REGISTRY
 GST_REGISTRY_SRC =
 else
@@ -44,7 +38,7 @@ built_header_make = gstenumtypes.h gstmarshal.h
 built_source_make = gstenumtypes.c gstmarshal.c
 
 EXTRA_libgstreamer_@GST_MAJORMINOR@_la_SOURCES = \
-       gstmarshal.list gsttrace.c gstxml.c \
+       gstmarshal.list gsttrace.c \
        gstregistrybinary.c
 
 
@@ -57,6 +51,7 @@ libgstreamer_@GST_MAJORMINOR@_la_SOURCES = \
        gstbin.c                \
        gstbuffer.c             \
        gstbufferlist.c         \
+       gstbufferpool.c         \
        gstbus.c                \
        gstcaps.c               \
        gstchildproxy.c         \
@@ -77,6 +72,8 @@ libgstreamer_@GST_MAJORMINOR@_la_SOURCES = \
        gstiterator.c           \
        gstatomicqueue.c        \
        gstmessage.c            \
+       gstmeta.c               \
+       gstmemory.c             \
        gstminiobject.c         \
        gstpad.c                \
        gstpadtemplate.c        \
@@ -105,8 +102,7 @@ libgstreamer_@GST_MAJORMINOR@_la_SOURCES = \
        gstutils.c              \
        gstvalue.c              \
        gstparse.c              \
-       $(GST_REGISTRY_SRC)     \
-       $(GST_LOADSAVE_SRC)
+       $(GST_REGISTRY_SRC)
 
 # do not put files in the distribution that are generated
 nodist_libgstreamer_@GST_MAJORMINOR@_la_SOURCES = $(built_source_make)
@@ -134,7 +130,6 @@ libgstreamer_@GST_MAJORMINOR@_la_LIBADD =           \
        $(GST_PARSE_LA)                                 \
        $(GST_ALL_LIBS)                                 \
        $(WIN32_LIBS)                                   \
-       $(XML_LIBS)                                     \
        $(LIBM)
 
 libgstreamer_@GST_MAJORMINOR@_la_LDFLAGS =             \
@@ -149,6 +144,7 @@ gst_headers =                       \
        gstbin.h                \
        gstbuffer.h             \
        gstbufferlist.h         \
+       gstbufferpool.h         \
        gstbus.h                \
        gstcaps.h               \
        gstchildproxy.h         \
@@ -157,6 +153,7 @@ gst_headers =                       \
        gstdatetime.h           \
        gstdebugutils.h         \
        gstelement.h            \
+       gstelementmetadata.h    \
        gstelementfactory.h     \
        gsterror.h              \
        gstevent.h              \
@@ -171,6 +168,8 @@ gst_headers =                       \
        gstatomicqueue.h        \
        gstmacros.h             \
        gstmessage.h            \
+       gstmeta.h               \
+       gstmemory.h             \
        gstminiobject.h         \
        gstpad.h                \
        gstpadtemplate.h        \
@@ -195,8 +194,7 @@ gst_headers =                       \
        gstutils.h              \
        gstvalue.h              \
        gstregistry.h           \
-       gstparse.h              \
-       gstxml.h
+       gstparse.h
 
 libgstreamer_@GST_MAJORMINOR@include_HEADERS = $(gst_headers) math-compat.h
 
@@ -208,7 +206,7 @@ noinst_HEADERS =            \
        glib-compat-private.h   \
        gst-i18n-lib.h          \
        gst-i18n-app.h          \
-       gstelementdetails.h     \
+       gstelementmetadata.h    \
        gstpluginloader.h       \
        gstquark.h              \
        gstregistrybinary.h     \
@@ -279,18 +277,16 @@ Gst-@GST_MAJORMINOR@.gir: $(INTROSPECTION_SCANNER) libgstreamer-@GST_MAJORMINOR@
                -I$(top_builddir) \
                -DIN_GOBJECT_INTROSPECTION=1 \
                --c-include='gst/gst.h' \
-               --library=libgstreamer-0.10.la \
+               --library=libgstreamer-0.11.la \
                --include=GLib-2.0 \
                --include=GObject-2.0 \
                --include=GModule-2.0 \
-               --include=libxml2-2.0 \
                --libtool="$(top_builddir)/libtool" \
                --pkg glib-2.0 \
                --pkg gobject-2.0 \
                --pkg gmodule-no-export-2.0 \
                --pkg gthread-2.0 \
-               --pkg libxml-2.0 \
-               --pkg-export gstreamer-0.10 \
+               --pkg-export gstreamer-@GST_MAJORMINOR@ \
                --add-init-section="gst_init(NULL, NULL);" \
                --output $@ \
                $(gir_headers) \
index e109eff..93f756e 100644 (file)
--- a/gst/gst.c
+++ b/gst/gst.c
@@ -665,8 +665,13 @@ init_post (GOptionContext * context, GOptionGroup * group, gpointer data,
   g_log_set_handler (g_log_domain_gstreamer, llf, debug_log_handler, NULL);
 
   _priv_gst_quarks_initialize ();
+  _gst_memory_init ();
   _gst_format_initialize ();
   _gst_query_initialize ();
+  _gst_structure_initialize ();
+  _gst_caps_initialize ();
+  _gst_meta_init ();
+
   g_type_class_ref (gst_object_get_type ());
   g_type_class_ref (gst_pad_get_type ());
   g_type_class_ref (gst_element_factory_get_type ());
@@ -684,7 +689,6 @@ init_post (GOptionContext * context, GOptionGroup * group, gpointer data,
   g_type_class_ref (gst_bin_flags_get_type ());
   g_type_class_ref (gst_buffer_flag_get_type ());
   g_type_class_ref (gst_buffer_copy_flags_get_type ());
-  g_type_class_ref (gst_buffer_list_item_get_type ());
   g_type_class_ref (gst_bus_flags_get_type ());
   g_type_class_ref (gst_bus_sync_reply_get_type ());
   g_type_class_ref (gst_caps_flags_get_type ());
@@ -747,17 +751,19 @@ init_post (GOptionContext * context, GOptionGroup * group, gpointer data,
   g_type_class_ref (gst_parse_flags_get_type ());
   g_type_class_ref (gst_search_mode_get_type ());
   g_type_class_ref (gst_progress_type_get_type ());
+  g_type_class_ref (gst_buffer_pool_flags_get_type ());
+  g_type_class_ref (gst_memory_flags_get_type ());
+  g_type_class_ref (gst_map_flags_get_type ());
   g_type_class_ref (gst_caps_intersect_mode_get_type ());
+  g_type_class_ref (gst_probe_type_get_type ());
+  g_type_class_ref (gst_probe_return_get_type ());
 
-  gst_structure_get_type ();
-  _gst_value_initialize ();
-  g_type_class_ref (gst_param_spec_fraction_get_type ());
-  gst_caps_get_type ();
   _gst_event_initialize ();
   _gst_buffer_initialize ();
-  _gst_buffer_list_initialize ();
-  gst_buffer_list_iterator_get_type ();
   _gst_message_initialize ();
+  _gst_buffer_list_initialize ();
+  _gst_value_initialize ();
+  g_type_class_ref (gst_param_spec_fraction_get_type ());
   _gst_tag_initialize ();
   gst_parse_context_get_type ();
 
@@ -1048,7 +1054,6 @@ gst_deinit (void)
   g_type_class_unref (g_type_class_peek (gst_bin_flags_get_type ()));
   g_type_class_unref (g_type_class_peek (gst_buffer_flag_get_type ()));
   g_type_class_unref (g_type_class_peek (gst_buffer_copy_flags_get_type ()));
-  g_type_class_unref (g_type_class_peek (gst_buffer_list_item_get_type ()));
   g_type_class_unref (g_type_class_peek (gst_bus_flags_get_type ()));
   g_type_class_unref (g_type_class_peek (gst_bus_sync_reply_get_type ()));
   g_type_class_unref (g_type_class_peek (gst_caps_flags_get_type ()));
@@ -1115,7 +1120,12 @@ gst_deinit (void)
   g_type_class_unref (g_type_class_peek (gst_parse_error_get_type ()));
   g_type_class_unref (g_type_class_peek (gst_param_spec_fraction_get_type ()));
   g_type_class_unref (g_type_class_peek (gst_progress_type_get_type ()));
+  g_type_class_unref (g_type_class_peek (gst_buffer_pool_flags_get_type ()));
+  g_type_class_unref (g_type_class_peek (gst_memory_flags_get_type ()));
+  g_type_class_unref (g_type_class_peek (gst_map_flags_get_type ()));
   g_type_class_unref (g_type_class_peek (gst_caps_intersect_mode_get_type ()));
+  g_type_class_unref (g_type_class_peek (gst_probe_type_get_type ()));
+  g_type_class_unref (g_type_class_peek (gst_probe_return_get_type ()));
 
   gst_deinitialized = TRUE;
   GST_INFO ("deinitialized GStreamer");
index 6238dcf..954fd6c 100644 (file)
--- a/gst/gst.h
+++ b/gst/gst.h
 #include <gst/gstbin.h>
 #include <gst/gstbuffer.h>
 #include <gst/gstbufferlist.h>
+#include <gst/gstbufferpool.h>
 #include <gst/gstcaps.h>
 #include <gst/gstchildproxy.h>
 #include <gst/gstclock.h>
 #include <gst/gstdatetime.h>
 #include <gst/gstdebugutils.h>
 #include <gst/gstelement.h>
+#include <gst/gstelementmetadata.h>
 #include <gst/gsterror.h>
 #include <gst/gstevent.h>
 #include <gst/gstghostpad.h>
@@ -50,6 +52,7 @@
 #include <gst/gstiterator.h>
 #include <gst/gstmarshal.h>
 #include <gst/gstmessage.h>
+#include <gst/gstmemory.h>
 #include <gst/gstminiobject.h>
 #include <gst/gstobject.h>
 #include <gst/gstpad.h>
@@ -73,7 +76,6 @@
 #include <gst/gsturi.h>
 #include <gst/gstutils.h>
 #include <gst/gstvalue.h>
-#include <gst/gstxml.h>
 
 #include <gst/gstparse.h>
 
index 6bd6725..b318abb 100644 (file)
@@ -101,6 +101,8 @@ void _priv_gst_quarks_initialize (void);
  * we want enterprise edition packagers dancing on our heads) */
 void  _gst_buffer_initialize (void);
 void  _gst_buffer_list_initialize (void);
+void  _gst_structure_initialize (void);
+void  _gst_caps_initialize (void);
 void  _gst_event_initialize (void);
 void  _gst_format_initialize (void);
 void  _gst_message_initialize (void);
@@ -114,14 +116,12 @@ gboolean _priv_gst_registry_remove_cache_plugins (GstRegistry *registry);
 void _priv_gst_registry_cleanup (void);
 gboolean _gst_plugin_loader_client_run (void);
 
-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);
@@ -130,7 +130,6 @@ gboolean  priv_gst_structure_append_to_gstring (const GstStructure * structure,
 gboolean               gst_registry_binary_read_cache  (GstRegistry * registry, const char *location);
 gboolean               gst_registry_binary_write_cache (GstRegistry * registry, const char *location);
 
-
 /* used in gstvalue.c and gststructure.c */
 #define GST_ASCII_IS_STRING(c) (g_ascii_isalnum((c)) || ((c) == '_') || \
     ((c) == '-') || ((c) == '+') || ((c) == '/') || ((c) == ':') || \
@@ -184,7 +183,6 @@ GST_EXPORT GstDebugCategory *GST_CAT_PIPELINE;
 GST_EXPORT GstDebugCategory *GST_CAT_PLUGIN_LOADING;
 GST_EXPORT GstDebugCategory *GST_CAT_PLUGIN_INFO;
 GST_EXPORT GstDebugCategory *GST_CAT_PROPERTIES;
-GST_EXPORT GstDebugCategory *GST_CAT_XML;
 GST_EXPORT GstDebugCategory *GST_CAT_NEGOTIATION;
 GST_EXPORT GstDebugCategory *GST_CAT_REFCOUNTING;
 GST_EXPORT GstDebugCategory *GST_CAT_ERROR_SYSTEM;
@@ -224,7 +222,6 @@ extern GstDebugCategory *_priv_GST_CAT_POLL;
 #define GST_CAT_PLUGIN_LOADING   NULL
 #define GST_CAT_PLUGIN_INFO      NULL
 #define GST_CAT_PROPERTIES       NULL
-#define GST_CAT_XML              NULL
 #define GST_CAT_NEGOTIATION      NULL
 #define GST_CAT_REFCOUNTING      NULL
 #define GST_CAT_ERROR_SYSTEM     NULL
@@ -241,10 +238,6 @@ extern GstDebugCategory *_priv_GST_CAT_POLL;
 
 #endif
 
-#ifdef GST_DISABLE_DEPRECATED
-typedef GList*                 (*GstPadIntLinkFunction)        (GstPad *pad);
-#endif
-
 
 G_END_DECLS
 #endif /* __GST_PRIVATE_H__ */
index 89ad34e..9eec87f 100644 (file)
 #include "gstevent.h"
 #include "gstbin.h"
 #include "gstmarshal.h"
-#include "gstxml.h"
 #include "gstinfo.h"
 #include "gsterror.h"
 
 #include "gstutils.h"
 #include "gstchildproxy.h"
 
-#ifdef GST_DISABLE_DEPRECATED
-#if !defined(GST_DISABLE_LOADSAVE) && !defined(GST_REMOVE_DEPRECATED)
-#undef GstXmlNodePtr
-#define GstXmlNodePtr xmlNodePtr
-#include <libxml/parser.h>
-GstXmlNodePtr gst_object_save_thyself (GstObject * object,
-    GstXmlNodePtr parent);
-void gst_object_restore_thyself (GstObject * object, GstXmlNodePtr parent);
-GstElement *gst_xml_make_element (xmlNodePtr cur, GstObject * parent);
-#endif
-#endif
-
-/* enable for DURATION caching.
- * FIXME currently too many elements don't update
- * their duration when it changes so we return inaccurate values. */
-#undef DURATION_CACHING
-
 /* latency is by default enabled now.
  * live-preroll and no-live-preroll in the environment var GST_COMPAT
  * to enables or disable it respectively.
@@ -245,8 +227,8 @@ static void gst_bin_state_changed (GstElement * element, GstState oldstate,
 static GstStateChangeReturn gst_bin_get_state_func (GstElement * element,
     GstState * state, GstState * pending, GstClockTime timeout);
 static void bin_handle_async_done (GstBin * bin, GstStateChangeReturn ret,
-    gboolean flag_pending);
-static void bin_handle_async_start (GstBin * bin, gboolean new_base_time);
+    gboolean flag_pending, gboolean reset_time);
+static void bin_handle_async_start (GstBin * bin);
 static void bin_push_state_continue (BinContinueData * data);
 static void bin_do_eos (GstBin * bin);
 
@@ -267,11 +249,6 @@ static gboolean gst_bin_query (GstElement * element, GstQuery * query);
 
 static gboolean gst_bin_do_latency_func (GstBin * bin);
 
-#if !defined(GST_DISABLE_LOADSAVE) && !defined(GST_REMOVE_DEPRECATED)
-static xmlNodePtr gst_bin_save_thyself (GstObject * object, xmlNodePtr parent);
-static void gst_bin_restore_thyself (GstObject * object, xmlNodePtr self);
-#endif
-
 static void bin_remove_messages (GstBin * bin, GstObject * src,
     GstMessageType types);
 static void gst_bin_continue_func (BinContinueData * data);
@@ -304,7 +281,7 @@ static void gst_bin_child_proxy_init (gpointer g_iface, gpointer iface_data);
 
 static guint gst_bin_signals[LAST_SIGNAL] = { 0 };
 
-#define _do_init(type) \
+#define _do_init \
 { \
   const gchar *compat; \
   static const GInterfaceInfo iface_info = { \
@@ -312,7 +289,7 @@ static guint gst_bin_signals[LAST_SIGNAL] = { 0 };
     NULL, \
     NULL}; \
   \
-  g_type_add_interface_static (type, GST_TYPE_CHILD_PROXY, &iface_info); \
+  g_type_add_interface_static (g_define_type_id, GST_TYPE_CHILD_PROXY, &iface_info); \
   \
   GST_DEBUG_CATEGORY_INIT (bin_debug, "bin", GST_DEBUG_BOLD, \
       "debugging info for the 'bin' container element"); \
@@ -327,19 +304,8 @@ static guint gst_bin_signals[LAST_SIGNAL] = { 0 };
   } \
 }
 
-GST_BOILERPLATE_FULL (GstBin, gst_bin, GstElement, GST_TYPE_ELEMENT, _do_init);
-
-static void
-gst_bin_base_init (gpointer g_class)
-{
-  GstElementClass *gstelement_class = GST_ELEMENT_CLASS (g_class);
-
-  gst_element_class_set_details_simple (gstelement_class, "Generic bin",
-      "Generic/Bin",
-      "Simple container object",
-      "Erik Walthinsen <omega@cse.ogi.edu>,"
-      "Wim Taymans <wim.taymans@gmail.com>");
-}
+#define gst_bin_parent_class parent_class
+G_DEFINE_TYPE_WITH_CODE (GstBin, gst_bin, GST_TYPE_ELEMENT, _do_init);
 
 static GstObject *
 gst_bin_child_proxy_get_child_by_index (GstChildProxy * child_proxy,
@@ -402,12 +368,10 @@ static void
 gst_bin_class_init (GstBinClass * klass)
 {
   GObjectClass *gobject_class;
-  GstObjectClass *gstobject_class;
   GstElementClass *gstelement_class;
   GError *err;
 
   gobject_class = (GObjectClass *) klass;
-  gstobject_class = (GstObjectClass *) klass;
   gstelement_class = (GstElementClass *) klass;
 
   g_type_class_add_private (klass, sizeof (GstBinPrivate));
@@ -496,14 +460,11 @@ gst_bin_class_init (GstBinClass * klass)
 
   gobject_class->dispose = gst_bin_dispose;
 
-#if !defined(GST_DISABLE_LOADSAVE) && !defined(GST_REMOVE_DEPRECATED)
-  gstobject_class->save_thyself =
-      ((gpointer (*)(GstObject * object,
-              gpointer self)) * GST_DEBUG_FUNCPTR (gst_bin_save_thyself));
-  gstobject_class->restore_thyself =
-      ((void (*)(GstObject * object,
-              gpointer self)) *GST_DEBUG_FUNCPTR (gst_bin_restore_thyself));
-#endif
+  gst_element_class_set_metadata (gstelement_class, "Generic bin",
+      "Generic/Bin",
+      "Simple container object",
+      "Erik Walthinsen <omega@cse.ogi.edu>,"
+      "Wim Taymans <wim.taymans@gmail.com>");
 
   gstelement_class->change_state =
       GST_DEBUG_FUNCPTR (gst_bin_change_state_func);
@@ -534,7 +495,7 @@ gst_bin_class_init (GstBinClass * klass)
 }
 
 static void
-gst_bin_init (GstBin * bin, GstBinClass * klass)
+gst_bin_init (GstBin * bin)
 {
   GstBus *bus;
 
@@ -546,7 +507,7 @@ gst_bin_init (GstBin * bin, GstBinClass * klass)
   bin->clock_dirty = FALSE;
 
   /* Set up a bus for listening to child elements */
-  bus = gst_bus_new ();
+  bus = g_object_new (GST_TYPE_BUS, "enable-async", FALSE, NULL);
   bin->child_bus = bus;
   GST_DEBUG_OBJECT (bin, "using bus %" GST_PTR_FORMAT " to listen to children",
       bus);
@@ -680,6 +641,7 @@ gst_bin_set_index_func (GstElement * element, GstIndex * index)
   gboolean done;
   GstIterator *it;
   GstIndex *old;
+  GValue data = { 0, };
 
   bin = GST_BIN_CAST (element);
 
@@ -700,18 +662,16 @@ gst_bin_set_index_func (GstElement * element, GstIndex * index)
   /* set the index on all elements in the bin */
   done = FALSE;
   while (!done) {
-    gpointer data;
-
     switch (gst_iterator_next (it, &data)) {
       case GST_ITERATOR_OK:
       {
-        GstElement *child = GST_ELEMENT_CAST (data);
+        GstElement *child = g_value_get_object (&data);
 
         GST_DEBUG_OBJECT (bin, "setting index on '%s'",
             GST_ELEMENT_NAME (child));
         gst_element_set_index (child, index);
 
-        gst_object_unref (child);
+        g_value_reset (&data);
         break;
       }
       case GST_ITERATOR_RESYNC:
@@ -725,6 +685,7 @@ gst_bin_set_index_func (GstElement * element, GstIndex * index)
         break;
     }
   }
+  g_value_unset (&data);
   gst_iterator_free (it);
   return;
 
@@ -747,6 +708,7 @@ gst_bin_set_clock_func (GstElement * element, GstClock * clock)
   gboolean done;
   GstIterator *it;
   gboolean res = TRUE;
+  GValue data = { 0, };
 
   bin = GST_BIN_CAST (element);
 
@@ -754,16 +716,14 @@ gst_bin_set_clock_func (GstElement * element, GstClock * clock)
 
   done = FALSE;
   while (!done) {
-    gpointer data;
-
     switch (gst_iterator_next (it, &data)) {
       case GST_ITERATOR_OK:
       {
-        GstElement *child = GST_ELEMENT_CAST (data);
+        GstElement *child = g_value_get_object (&data);
 
         res &= gst_element_set_clock (child, clock);
 
-        gst_object_unref (child);
+        g_value_reset (&data);
         break;
       }
       case GST_ITERATOR_RESYNC:
@@ -778,6 +738,7 @@ gst_bin_set_clock_func (GstElement * element, GstClock * clock)
         break;
     }
   }
+  g_value_unset (&data);
   gst_iterator_free (it);
 
   return res;
@@ -799,7 +760,8 @@ gst_bin_provide_clock_func (GstElement * element)
   GstElement *provider = NULL;
   GstBin *bin;
   GstIterator *it;
-  gpointer val;
+  gboolean done;
+  GValue val = { 0, };
   GstClock **provided_clock_p;
   GstElement **clock_provider_p;
 
@@ -812,25 +774,53 @@ gst_bin_provide_clock_func (GstElement * element)
   GST_DEBUG_OBJECT (bin, "finding new clock");
 
   it = gst_bin_sort_iterator_new (bin);
+  GST_OBJECT_UNLOCK (bin);
+
+  done = FALSE;
+  while (!done) {
+    switch (gst_iterator_next (it, &val)) {
+      case GST_ITERATOR_OK:
+      {
+        GstElement *child = g_value_get_object (&val);
+        GstClock *clock;
+
+        clock = gst_element_provide_clock (child);
+        if (clock) {
+          GST_DEBUG_OBJECT (bin, "found candidate clock %p by element %s",
+              clock, GST_ELEMENT_NAME (child));
+          if (result) {
+            gst_object_unref (result);
+            gst_object_unref (provider);
+          }
+          result = clock;
+          provider = gst_object_ref (child);
+        }
 
-  while (it->next (it, &val) == GST_ITERATOR_OK) {
-    GstElement *child = GST_ELEMENT_CAST (val);
-    GstClock *clock;
-
-    clock = gst_element_provide_clock (child);
-    if (clock) {
-      GST_DEBUG_OBJECT (bin, "found candidate clock %p by element %s",
-          clock, GST_ELEMENT_NAME (child));
-      if (result) {
-        gst_object_unref (result);
-        gst_object_unref (provider);
+        g_value_reset (&val);
+        break;
       }
-      result = clock;
-      provider = child;
-    } else {
-      gst_object_unref (child);
+      case GST_ITERATOR_RESYNC:
+        gst_iterator_resync (it);
+        break;
+      default:
+      case GST_ITERATOR_DONE:
+        done = TRUE;
+        break;
     }
   }
+  g_value_unset (&val);
+  gst_iterator_free (it);
+
+  GST_OBJECT_LOCK (bin);
+  if (!bin->clock_dirty) {
+    if (provider)
+      gst_object_unref (provider);
+    if (result)
+      gst_object_unref (result);
+    result = NULL;
+
+    goto not_dirty;
+  }
 
   provided_clock_p = &bin->provided_clock;
   clock_provider_p = &bin->clock_provider;
@@ -845,8 +835,6 @@ gst_bin_provide_clock_func (GstElement * element)
     gst_object_unref (provider);
   GST_OBJECT_UNLOCK (bin);
 
-  gst_iterator_free (it);
-
   return result;
 
 not_dirty:
@@ -1029,10 +1017,13 @@ is_eos (GstBin * bin, guint32 * seqnum)
 }
 
 static void
-unlink_pads (GstPad * pad)
+unlink_pads (const GValue * item, gpointer user_data)
 {
+  GstPad *pad;
   GstPad *peer;
 
+  pad = g_value_get_object (item);
+
   if ((peer = gst_pad_get_peer (pad))) {
     if (gst_pad_get_direction (pad) == GST_PAD_SRC)
       gst_pad_unlink (pad, peer);
@@ -1040,7 +1031,6 @@ unlink_pads (GstPad * pad)
       gst_pad_unlink (peer, pad);
     gst_object_unref (peer);
   }
-  gst_object_unref (pad);
 }
 
 /* vmethod that adds an element to a bin
@@ -1135,13 +1125,12 @@ gst_bin_add_func (GstBin * bin, GstElement * element)
     {
       /* create message to track this aync element when it posts an async-done
        * message */
-      async_message =
-          gst_message_new_async_start (GST_OBJECT_CAST (element), FALSE);
+      async_message = gst_message_new_async_start (GST_OBJECT_CAST (element));
       break;
     }
     case GST_STATE_CHANGE_NO_PREROLL:
       /* ignore all async elements we might have and commit our state */
-      bin_handle_async_done (bin, ret, FALSE);
+      bin_handle_async_done (bin, ret, FALSE, FALSE);
       break;
     case GST_STATE_CHANGE_FAILURE:
       break;
@@ -1162,7 +1151,7 @@ no_state_recalc:
 
   /* unlink all linked pads */
   it = gst_element_iterate_pads (element);
-  gst_iterator_foreach (it, (GFunc) unlink_pads, element);
+  gst_iterator_foreach (it, (GstIteratorForeachFunction) unlink_pads, NULL);
   gst_iterator_free (it);
 
   GST_CAT_DEBUG_OBJECT (GST_CAT_PARENTAGE, bin, "added element \"%s\"",
@@ -1288,7 +1277,7 @@ gst_bin_remove_func (GstBin * bin, GstElement * element)
 
   /* unlink all linked pads */
   it = gst_element_iterate_pads (element);
-  gst_iterator_foreach (it, (GFunc) unlink_pads, element);
+  gst_iterator_foreach (it, (GstIteratorForeachFunction) unlink_pads, NULL);
   gst_iterator_free (it);
 
   GST_OBJECT_LOCK (bin);
@@ -1435,7 +1424,7 @@ gst_bin_remove_func (GstBin * bin, GstElement * element)
     else
       ret = GST_STATE_CHANGE_SUCCESS;
 
-    bin_handle_async_done (bin, ret, FALSE);
+    bin_handle_async_done (bin, ret, FALSE, FALSE);
   } else {
     GST_DEBUG_OBJECT (bin,
         "recalc state preroll: %d, other async: %d, this async %d",
@@ -1553,13 +1542,6 @@ no_function:
   }
 }
 
-static GstIteratorItem
-iterate_child (GstIterator * it, GstElement * child)
-{
-  gst_object_ref (child);
-  return GST_ITERATOR_ITEM_PASS;
-}
-
 /**
  * gst_bin_iterate_elements:
  * @bin: a #GstBin
@@ -1581,26 +1563,19 @@ gst_bin_iterate_elements (GstBin * bin)
   g_return_val_if_fail (GST_IS_BIN (bin), NULL);
 
   GST_OBJECT_LOCK (bin);
-  /* add ref because the iterator refs the bin. When the iterator
-   * is freed it will unref the bin again using the provided dispose
-   * function. */
-  gst_object_ref (bin);
   result = gst_iterator_new_list (GST_TYPE_ELEMENT,
       GST_OBJECT_GET_LOCK (bin),
-      &bin->children_cookie,
-      &bin->children,
-      bin,
-      (GstIteratorItemFunction) iterate_child,
-      (GstIteratorDisposeFunction) gst_object_unref);
+      &bin->children_cookie, &bin->children, (GObject *) bin, NULL);
   GST_OBJECT_UNLOCK (bin);
 
   return result;
 }
 
 static GstIteratorItem
-iterate_child_recurse (GstIterator * it, GstElement * child)
+iterate_child_recurse (GstIterator * it, const GValue * item)
 {
-  gst_object_ref (child);
+  GstElement *child = g_value_get_object (item);
+
   if (GST_IS_BIN (child)) {
     GstIterator *other = gst_bin_iterate_recurse (GST_BIN_CAST (child));
 
@@ -1631,17 +1606,11 @@ gst_bin_iterate_recurse (GstBin * bin)
   g_return_val_if_fail (GST_IS_BIN (bin), NULL);
 
   GST_OBJECT_LOCK (bin);
-  /* add ref because the iterator refs the bin. When the iterator
-   * is freed it will unref the bin again using the provided dispose
-   * function. */
-  gst_object_ref (bin);
   result = gst_iterator_new_list (GST_TYPE_ELEMENT,
       GST_OBJECT_GET_LOCK (bin),
       &bin->children_cookie,
       &bin->children,
-      bin,
-      (GstIteratorItemFunction) iterate_child_recurse,
-      (GstIteratorDisposeFunction) gst_object_unref);
+      (GObject *) bin, (GstIteratorItemFunction) iterate_child_recurse);
   GST_OBJECT_UNLOCK (bin);
 
   return result;
@@ -1667,17 +1636,12 @@ bin_element_is_sink (GstElement * child, GstBin * bin)
 }
 
 static gint
-sink_iterator_filter (GstElement * child, GstBin * bin)
+sink_iterator_filter (const GValue * vchild, GValue * vbin)
 {
-  if (bin_element_is_sink (child, bin) == 0) {
-    /* returns 0 because this is a GCompareFunc */
-    return 0;
-  } else {
-    /* child carries a ref from gst_bin_iterate_elements -- drop if not passing
-       through */
-    gst_object_unref (child);
-    return 1;
-  }
+  GstBin *bin = g_value_get_object (vbin);
+  GstElement *child = g_value_get_object (vchild);
+
+  return (bin_element_is_sink (child, bin));
 }
 
 /**
@@ -1699,12 +1663,18 @@ gst_bin_iterate_sinks (GstBin * bin)
 {
   GstIterator *children;
   GstIterator *result;
+  GValue vbin = { 0, };
 
   g_return_val_if_fail (GST_IS_BIN (bin), NULL);
 
+  g_value_init (&vbin, GST_TYPE_BIN);
+  g_value_set_object (&vbin, bin);
+
   children = gst_bin_iterate_elements (bin);
   result = gst_iterator_filter (children,
-      (GCompareFunc) sink_iterator_filter, bin);
+      (GCompareFunc) sink_iterator_filter, &vbin);
+
+  g_value_unset (&vbin);
 
   return result;
 }
@@ -1729,17 +1699,12 @@ bin_element_is_src (GstElement * child, GstBin * bin)
 }
 
 static gint
-src_iterator_filter (GstElement * child, GstBin * bin)
+src_iterator_filter (const GValue * vchild, GValue * vbin)
 {
-  if (bin_element_is_src (child, bin) == 0) {
-    /* returns 0 because this is a GCompareFunc */
-    return 0;
-  } else {
-    /* child carries a ref from gst_bin_iterate_elements -- drop if not passing
-       through */
-    gst_object_unref (child);
-    return 1;
-  }
+  GstBin *bin = g_value_get_object (vbin);
+  GstElement *child = g_value_get_object (vchild);
+
+  return (bin_element_is_src (child, bin));
 }
 
 /**
@@ -1761,12 +1726,18 @@ gst_bin_iterate_sources (GstBin * bin)
 {
   GstIterator *children;
   GstIterator *result;
+  GValue vbin = { 0, };
 
   g_return_val_if_fail (GST_IS_BIN (bin), NULL);
 
+  g_value_init (&vbin, GST_TYPE_BIN);
+  g_value_set_object (&vbin, bin);
+
   children = gst_bin_iterate_elements (bin);
   result = gst_iterator_filter (children,
-      (GCompareFunc) src_iterator_filter, bin);
+      (GCompareFunc) src_iterator_filter, &vbin);
+
+  g_value_unset (&vbin);
 
   return result;
 }
@@ -1782,7 +1753,9 @@ gst_bin_get_state_func (GstElement * element, GstState * state,
 
   GST_CAT_INFO_OBJECT (GST_CAT_STATES, element, "getting state");
 
-  ret = parent_class->get_state (element, state, pending, timeout);
+  ret =
+      GST_ELEMENT_CLASS (parent_class)->get_state (element, state, pending,
+      timeout);
 
   return ret;
 }
@@ -1811,6 +1784,26 @@ typedef struct _GstBinSortIterator
   gboolean dirty;               /* we detected structure change */
 } GstBinSortIterator;
 
+static void
+gst_bin_sort_iterator_copy (const GstBinSortIterator * it,
+    GstBinSortIterator * copy)
+{
+  GHashTableIter iter;
+  gpointer key, value;
+
+  copy->queue = g_queue_copy (it->queue);
+  g_queue_foreach (copy->queue, (GFunc) gst_object_ref, NULL);
+
+  copy->bin = gst_object_ref (it->bin);
+  if (it->best)
+    copy->best = gst_object_ref (it->best);
+
+  copy->hash = g_hash_table_new (NULL, NULL);
+  g_hash_table_iter_init (&iter, it->hash);
+  while (g_hash_table_iter_next (&iter, &key, &value))
+    g_hash_table_insert (copy->hash, key, value);
+}
+
 /* we add and subtract 1 to make sure we don't confuse NULL and 0 */
 #define HASH_SET_DEGREE(bit, elem, deg) \
     g_hash_table_replace (bit->hash, elem, GINT_TO_POINTER(deg+1))
@@ -1990,13 +1983,13 @@ find_element (GstElement * element, GstBinSortIterator * bit)
 /* get next element in iterator. the returned element has the
  * refcount increased */
 static GstIteratorResult
-gst_bin_sort_iterator_next (GstBinSortIterator * bit, gpointer * result)
+gst_bin_sort_iterator_next (GstBinSortIterator * bit, GValue * result)
 {
+  GstElement *best;
   GstBin *bin = bit->bin;
 
   /* empty queue, we have to find a next best element */
   if (g_queue_is_empty (bit->queue)) {
-    GstElement *best;
 
     bit->best = NULL;
     bit->best_deg = G_MAXINT;
@@ -2013,9 +2006,8 @@ gst_bin_sort_iterator_next (GstBinSortIterator * bit, gpointer * result)
       /* best unhandled element, schedule as next element */
       GST_DEBUG_OBJECT (bin, "queue empty, next best: %s",
           GST_ELEMENT_NAME (best));
-      gst_object_ref (best);
       HASH_SET_DEGREE (bit, best, -1);
-      *result = best;
+      g_value_set_object (result, best);
     } else {
       GST_DEBUG_OBJECT (bin, "queue empty, elements exhausted");
       /* no more unhandled elements, we are done */
@@ -2023,12 +2015,14 @@ gst_bin_sort_iterator_next (GstBinSortIterator * bit, gpointer * result)
     }
   } else {
     /* everything added to the queue got reffed */
-    *result = g_queue_pop_head (bit->queue);
+    best = g_queue_pop_head (bit->queue);
+    g_value_set_object (result, best);
+    gst_object_unref (best);
   }
 
-  GST_DEBUG_OBJECT (bin, "queue head gives %s", GST_ELEMENT_NAME (*result));
+  GST_DEBUG_OBJECT (bin, "queue head gives %s", GST_ELEMENT_NAME (best));
   /* update degrees of linked elements */
-  update_degree (GST_ELEMENT_CAST (*result), bit);
+  update_degree (best, bit);
 
   return GST_ITERATOR_OK;
 }
@@ -2062,7 +2056,6 @@ gst_bin_sort_iterator_free (GstBinSortIterator * bit)
   g_queue_free (bit->queue);
   g_hash_table_destroy (bit->hash);
   gst_object_unref (bin);
-  g_free (bit);
 }
 
 /* should be called with the bin LOCK held */
@@ -2078,6 +2071,7 @@ gst_bin_sort_iterator_new (GstBin * bin)
       GST_TYPE_ELEMENT,
       GST_OBJECT_GET_LOCK (bin),
       &bin->priv->structure_cookie,
+      (GstIteratorCopyFunction) gst_bin_sort_iterator_copy,
       (GstIteratorNextFunction) gst_bin_sort_iterator_next,
       (GstIteratorItemFunction) NULL,
       (GstIteratorResyncFunction) gst_bin_sort_iterator_resync,
@@ -2244,17 +2238,14 @@ unneeded:
 /* gst_iterator_fold functions for pads_activate
  * Stop the iterator if activating one pad failed. */
 static gboolean
-activate_pads (GstPad * pad, GValue * ret, gboolean * active)
+activate_pads (const GValue * vpad, GValue * ret, gboolean * active)
 {
+  GstPad *pad = g_value_get_object (vpad);
   gboolean cont = TRUE;
 
   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;
 }
 
@@ -2427,6 +2418,7 @@ gst_bin_change_state_func (GstElement * element, GstStateChange transition)
   GstClockTime base_time, start_time;
   GstIterator *it;
   gboolean done;
+  GValue data = { 0, };
 
   /* we don't need to take the STATE_LOCK, it is already taken */
   current = (GstState) GST_STATE_TRANSITION_CURRENT (transition);
@@ -2505,14 +2497,12 @@ restart:
 
   done = FALSE;
   while (!done) {
-    gpointer data;
-
     switch (gst_iterator_next (it, &data)) {
       case GST_ITERATOR_OK:
       {
         GstElement *child;
 
-        child = GST_ELEMENT_CAST (data);
+        child = g_value_get_object (&data);
 
         /* set state and base_time now */
         ret = gst_bin_element_set_state (bin, child, base_time, start_time,
@@ -2548,7 +2538,6 @@ restart:
             parent = gst_object_get_parent (GST_OBJECT_CAST (child));
             if (parent == GST_OBJECT_CAST (element)) {
               /* element is still in bin, really error now */
-              gst_object_unref (child);
               gst_object_unref (parent);
               goto done;
             }
@@ -2574,7 +2563,7 @@ restart:
             g_assert_not_reached ();
             break;
         }
-        gst_object_unref (child);
+        g_value_reset (&data);
         break;
       }
       case GST_ITERATOR_RESYNC:
@@ -2589,7 +2578,7 @@ restart:
     }
   }
 
-  ret = parent_class->change_state (element, transition);
+  ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
   if (G_UNLIKELY (ret == GST_STATE_CHANGE_FAILURE))
     goto done;
 
@@ -2605,6 +2594,7 @@ restart:
   }
 
 done:
+  g_value_unset (&data);
   gst_iterator_free (it);
 
   GST_OBJECT_LOCK (bin);
@@ -2637,7 +2627,7 @@ done:
     bin_remove_messages (bin, NULL, GST_MESSAGE_ASYNC_DONE);
 
     GST_DEBUG_OBJECT (bin, "async elements commited");
-    bin_handle_async_done (bin, GST_STATE_CHANGE_SUCCESS, FALSE);
+    bin_handle_async_done (bin, GST_STATE_CHANGE_SUCCESS, FALSE, FALSE);
   }
 
 state_end:
@@ -2678,6 +2668,7 @@ gst_bin_send_event (GstElement * element, GstEvent * event)
   GstIterator *iter;
   gboolean res = TRUE;
   gboolean done = FALSE;
+  GValue data = { 0, };
 
   if (GST_EVENT_IS_DOWNSTREAM (event)) {
     iter = gst_bin_iterate_sources (bin);
@@ -2690,17 +2681,14 @@ gst_bin_send_event (GstElement * element, GstEvent * event)
   }
 
   while (!done) {
-    gpointer data;
-
     switch (gst_iterator_next (iter, &data)) {
       case GST_ITERATOR_OK:
       {
-        GstElement *child;
+        GstElement *child = g_value_get_object (&data);;
 
         gst_event_ref (event);
-        child = GST_ELEMENT_CAST (data);
         res &= gst_element_send_event (child, event);
-        gst_object_unref (child);
+        g_value_reset (&data);
         break;
       }
       case GST_ITERATOR_RESYNC:
@@ -2715,6 +2703,7 @@ gst_bin_send_event (GstElement * element, GstEvent * event)
         break;
     }
   }
+  g_value_unset (&data);
   gst_iterator_free (iter);
   gst_event_unref (event);
 
@@ -2813,7 +2802,7 @@ bin_push_state_continue (BinContinueData * data)
  * This function is called with the OBJECT lock.
  */
 static void
-bin_handle_async_start (GstBin * bin, gboolean new_base_time)
+bin_handle_async_start (GstBin * bin)
 {
   GstState old_state, new_state;
   gboolean toplevel;
@@ -2829,8 +2818,7 @@ bin_handle_async_start (GstBin * bin, gboolean new_base_time)
    * are busy with a state change or when we are NO_PREROLL. */
   if (!toplevel)
     /* non toplevel bin, prepare async-start for the parent */
-    amessage =
-        gst_message_new_async_start (GST_OBJECT_CAST (bin), new_base_time);
+    amessage = gst_message_new_async_start (GST_OBJECT_CAST (bin));
 
   if (bin->polling || GST_STATE_PENDING (bin) != GST_STATE_VOID_PENDING)
     goto was_busy;
@@ -2897,7 +2885,7 @@ was_no_preroll:
  */
 static void
 bin_handle_async_done (GstBin * bin, GstStateChangeReturn ret,
-    gboolean flag_pending)
+    gboolean flag_pending, gboolean reset_time)
 {
   GstState current, pending, target;
   GstStateChangeReturn old_ret;
@@ -2925,7 +2913,7 @@ bin_handle_async_done (GstBin * bin, GstStateChangeReturn ret,
   target = GST_STATE_TARGET (bin);
   pending = GST_STATE_PENDING (bin) = target;
 
-  amessage = gst_message_new_async_done (GST_OBJECT_CAST (bin));
+  amessage = gst_message_new_async_done (GST_OBJECT_CAST (bin), reset_time);
 
   old_state = GST_STATE (bin);
   /* this is the state we should go to next */
@@ -3315,14 +3303,11 @@ gst_bin_handle_message_func (GstBin * bin, GstMessage * message)
     }
     case GST_MESSAGE_ASYNC_START:
     {
-      gboolean new_base_time;
       GstState target;
 
       GST_DEBUG_OBJECT (bin, "ASYNC_START message %p, %s", message,
           src ? GST_OBJECT_NAME (src) : "(NULL)");
 
-      gst_message_parse_async_start (message, &new_base_time);
-
       GST_OBJECT_LOCK (bin);
       bin_do_message_forward (bin, message);
 
@@ -3333,7 +3318,7 @@ gst_bin_handle_message_func (GstBin * bin, GstMessage * message)
       /* takes ownership of the message */
       bin_replace_message (bin, message, GST_MESSAGE_ASYNC_START);
 
-      bin_handle_async_start (bin, new_base_time);
+      bin_handle_async_start (bin);
       GST_OBJECT_UNLOCK (bin);
       break;
 
@@ -3348,11 +3333,14 @@ gst_bin_handle_message_func (GstBin * bin, GstMessage * message)
     }
     case GST_MESSAGE_ASYNC_DONE:
     {
+      gboolean reset_time;
       GstState target;
 
       GST_DEBUG_OBJECT (bin, "ASYNC_DONE message %p, %s", message,
           src ? GST_OBJECT_NAME (src) : "(NULL)");
 
+      gst_message_parse_async_done (message, &reset_time);
+
       GST_OBJECT_LOCK (bin);
       bin_do_message_forward (bin, message);
 
@@ -3373,7 +3361,7 @@ gst_bin_handle_message_func (GstBin * bin, GstMessage * message)
          * need to set the pending_done flag so that at the end of the state
          * change we can see if we need to verify pending async elements, hence
          * the TRUE argument here. */
-        bin_handle_async_done (bin, GST_STATE_CHANGE_SUCCESS, TRUE);
+        bin_handle_async_done (bin, GST_STATE_CHANGE_SUCCESS, TRUE, reset_time);
       } else {
         GST_DEBUG_OBJECT (bin, "there are more async elements pending");
       }
@@ -3454,8 +3442,10 @@ bin_query_min_max_init (GstBin * bin, QueryFold * fold)
 }
 
 static gboolean
-bin_query_duration_fold (GstElement * item, GValue * ret, QueryFold * fold)
+bin_query_duration_fold (const GValue * vitem, GValue * ret, QueryFold * fold)
 {
+  GstElement *item = g_value_get_object (vitem);
+
   if (gst_element_query (item, fold->query)) {
     gint64 duration;
 
@@ -3469,7 +3459,6 @@ bin_query_duration_fold (GstElement * item, GValue * ret, QueryFold * fold)
       fold->max = duration;
   }
 
-  gst_object_unref (item);
   return TRUE;
 }
 
@@ -3484,18 +3473,18 @@ bin_query_duration_done (GstBin * bin, QueryFold * fold)
 
   GST_DEBUG_OBJECT (bin, "max duration %" G_GINT64_FORMAT, fold->max);
 
-#ifdef DURATION_CACHING
   /* and cache now */
   GST_OBJECT_LOCK (bin);
   bin->messages = g_list_prepend (bin->messages,
       gst_message_new_duration (GST_OBJECT_CAST (bin), format, fold->max));
   GST_OBJECT_UNLOCK (bin);
-#endif
 }
 
 static gboolean
-bin_query_position_fold (GstElement * item, GValue * ret, QueryFold * fold)
+bin_query_position_fold (const GValue * vitem, GValue * ret, QueryFold * fold)
 {
+  GstElement *item = g_value_get_object (vitem);
+
   if (gst_element_query (item, fold->query)) {
     gint64 position;
 
@@ -3509,7 +3498,6 @@ bin_query_position_fold (GstElement * item, GValue * ret, QueryFold * fold)
       fold->max = position;
   }
 
-  gst_object_unref (item);
   return TRUE;
 }
 
@@ -3526,8 +3514,10 @@ bin_query_position_done (GstBin * bin, QueryFold * fold)
 }
 
 static gboolean
-bin_query_latency_fold (GstElement * item, GValue * ret, QueryFold * fold)
+bin_query_latency_fold (const GValue * vitem, GValue * ret, QueryFold * fold)
 {
+  GstElement *item = g_value_get_object (vitem);
+
   if (gst_element_query (item, fold->query)) {
     GstClockTime min, max;
     gboolean live;
@@ -3555,7 +3545,6 @@ bin_query_latency_fold (GstElement * item, GValue * ret, QueryFold * fold)
     GST_DEBUG_OBJECT (item, "failed query");
   }
 
-  gst_object_unref (item);
   return TRUE;
 }
 
@@ -3573,8 +3562,9 @@ bin_query_latency_done (GstBin * bin, QueryFold * fold)
 
 /* generic fold, return first valid result */
 static gboolean
-bin_query_generic_fold (GstElement * item, GValue * ret, QueryFold * fold)
+bin_query_generic_fold (const GValue * vitem, GValue * ret, QueryFold * fold)
 {
+  GstElement *item = g_value_get_object (vitem);
   gboolean res;
 
   if ((res = gst_element_query (item, fold->query))) {
@@ -3582,8 +3572,6 @@ bin_query_generic_fold (GstElement * item, GValue * ret, QueryFold * fold)
     GST_DEBUG_OBJECT (item, "answered query %p", fold->query);
   }
 
-  gst_object_unref (item);
-
   /* and stop as soon as we have a valid result */
   return !res;
 }
@@ -3603,7 +3591,6 @@ gst_bin_query (GstElement * element, GstQuery * query)
   switch (GST_QUERY_TYPE (query)) {
     case GST_QUERY_DURATION:
     {
-#ifdef DURATION_CACHING
       GList *cached;
       GstFormat qformat;
 
@@ -3634,7 +3621,6 @@ gst_bin_query (GstElement * element, GstQuery * query)
         }
       }
       GST_OBJECT_UNLOCK (bin);
-#endif
       /* no cached value found, iterate and collect durations */
       fold_func = (GstIteratorFoldFunction) bin_query_duration_fold;
       fold_init = bin_query_min_max_init;
@@ -3700,26 +3686,22 @@ gst_bin_query (GstElement * element, GstQuery * query)
 done:
   gst_iterator_free (iter);
 
-#ifdef DURATION_CACHING
 exit:
-#endif
   GST_DEBUG_OBJECT (bin, "query %p result %d", query, res);
 
   return res;
 }
 
 static gint
-compare_name (GstElement * element, const gchar * name)
+compare_name (const GValue * velement, const gchar * name)
 {
   gint eq;
+  GstElement *element = g_value_get_object (velement);
 
   GST_OBJECT_LOCK (element);
   eq = strcmp (GST_ELEMENT_NAME (element), name);
   GST_OBJECT_UNLOCK (element);
 
-  if (eq != 0) {
-    gst_object_unref (element);
-  }
   return eq;
 }
 
@@ -3741,7 +3723,9 @@ GstElement *
 gst_bin_get_by_name (GstBin * bin, const gchar * name)
 {
   GstIterator *children;
-  gpointer result;
+  GValue result = { 0, };
+  GstElement *element;
+  gboolean found;
 
   g_return_val_if_fail (GST_IS_BIN (bin), NULL);
 
@@ -3749,11 +3733,18 @@ gst_bin_get_by_name (GstBin * bin, const gchar * name)
       GST_ELEMENT_NAME (bin), name);
 
   children = gst_bin_iterate_recurse (bin);
-  result = gst_iterator_find_custom (children,
-      (GCompareFunc) compare_name, (gpointer) name);
+  found = gst_iterator_find_custom (children,
+      (GCompareFunc) compare_name, &result, (gpointer) name);
   gst_iterator_free (children);
 
-  return GST_ELEMENT_CAST (result);
+  if (found) {
+    element = g_value_dup_object (&result);
+    g_value_unset (&result);
+  } else {
+    element = NULL;
+  }
+
+  return element;
 }
 
 /**
@@ -3797,17 +3788,15 @@ gst_bin_get_by_name_recurse_up (GstBin * bin, const gchar * name)
 }
 
 static gint
-compare_interface (GstElement * element, gpointer interface)
+compare_interface (const GValue * velement, GValue * interface)
 {
-  GType interface_type = (GType) interface;
+  GstElement *element = g_value_get_object (velement);
+  GType interface_type = (GType) g_value_get_pointer (interface);
   gint ret;
 
   if (G_TYPE_CHECK_INSTANCE_TYPE (element, interface_type)) {
     ret = 0;
   } else {
-    /* we did not find the element, need to release the ref
-     * added by the iterator */
-    gst_object_unref (element);
     ret = 1;
   }
   return ret;
@@ -3832,17 +3821,31 @@ GstElement *
 gst_bin_get_by_interface (GstBin * bin, GType iface)
 {
   GstIterator *children;
-  gpointer result;
+  GValue result = { 0, };
+  GstElement *element;
+  gboolean found;
+  GValue viface = { 0, };
 
   g_return_val_if_fail (GST_IS_BIN (bin), NULL);
   g_return_val_if_fail (G_TYPE_IS_INTERFACE (iface), NULL);
 
+  g_value_init (&viface, G_TYPE_POINTER);
+  g_value_set_pointer (&viface, (gpointer) iface);
+
   children = gst_bin_iterate_recurse (bin);
-  result = gst_iterator_find_custom (children, (GCompareFunc) compare_interface,
-      (gpointer) iface);
+  found = gst_iterator_find_custom (children, (GCompareFunc) compare_interface,
+      &result, &viface);
   gst_iterator_free (children);
 
-  return GST_ELEMENT_CAST (result);
+  if (found) {
+    element = g_value_dup_object (&result);
+    g_value_unset (&result);
+  } else {
+    element = NULL;
+  }
+  g_value_unset (&viface);
+
+  return element;
 }
 
 /**
@@ -3868,68 +3871,19 @@ gst_bin_iterate_all_by_interface (GstBin * bin, GType iface)
 {
   GstIterator *children;
   GstIterator *result;
+  GValue viface = { 0, };
 
   g_return_val_if_fail (GST_IS_BIN (bin), NULL);
   g_return_val_if_fail (G_TYPE_IS_INTERFACE (iface), NULL);
 
+  g_value_init (&viface, G_TYPE_POINTER);
+  g_value_set_pointer (&viface, (gpointer) iface);
+
   children = gst_bin_iterate_recurse (bin);
   result = gst_iterator_filter (children, (GCompareFunc) compare_interface,
-      (gpointer) iface);
-
-  return result;
-}
-
-#if !defined(GST_DISABLE_LOADSAVE) && !defined(GST_REMOVE_DEPRECATED)
-static xmlNodePtr
-gst_bin_save_thyself (GstObject * object, xmlNodePtr parent)
-{
-  GstBin *bin = GST_BIN_CAST (object);
-  xmlNodePtr childlist, elementnode;
-  GList *children;
-  GstElement *child;
-
-  if (GST_OBJECT_CLASS (parent_class)->save_thyself)
-    GST_OBJECT_CLASS (parent_class)->save_thyself (GST_OBJECT (bin), parent);
-
-  childlist = xmlNewChild (parent, NULL, (xmlChar *) "children", NULL);
-
-  GST_CAT_INFO (GST_CAT_XML, "[%s]: saving %d children",
-      GST_ELEMENT_NAME (bin), bin->numchildren);
+      &viface);
 
-  children = g_list_last (bin->children);
-  while (children) {
-    child = GST_ELEMENT_CAST (children->data);
-    elementnode = xmlNewChild (childlist, NULL, (xmlChar *) "element", NULL);
-    gst_object_save_thyself (GST_OBJECT (child), elementnode);
-    children = g_list_previous (children);
-  }
-  return childlist;
-}
+  g_value_unset (&viface);
 
-static void
-gst_bin_restore_thyself (GstObject * object, xmlNodePtr self)
-{
-  GstBin *bin = GST_BIN_CAST (object);
-  xmlNodePtr field = self->xmlChildrenNode;
-  xmlNodePtr childlist;
-
-  while (field) {
-    if (!strcmp ((char *) field->name, "children")) {
-      GST_CAT_INFO (GST_CAT_XML, "[%s]: loading children",
-          GST_ELEMENT_NAME (object));
-      childlist = field->xmlChildrenNode;
-      while (childlist) {
-        if (!strcmp ((char *) childlist->name, "element")) {
-          /* gst_xml_make_element will gst_bin_add() the element to ourself */
-          gst_xml_make_element (childlist, GST_OBJECT (bin));
-        }
-        childlist = childlist->next;
-      }
-    }
-
-    field = field->next;
-  }
-  if (GST_OBJECT_CLASS (parent_class)->restore_thyself)
-    (GST_OBJECT_CLASS (parent_class)->restore_thyself) (object, self);
+  return result;
 }
-#endif /* GST_DISABLE_LOADSAVE */
index 2473ef6..19c7634 100644 (file)
@@ -117,7 +117,7 @@ struct _GstBin {
   /*< private >*/
   GstBinPrivate *priv;
 
-  gpointer _gst_reserved[GST_PADDING - 1];
+  gpointer _gst_reserved[GST_PADDING];
 };
 
 /**
@@ -156,7 +156,7 @@ struct _GstBinClass {
   gboolean     (*do_latency)           (GstBin *bin);
 
   /*< private >*/
-  gpointer _gst_reserved[GST_PADDING-1];
+  gpointer _gst_reserved[GST_PADDING];
 };
 
 GType          gst_bin_get_type                (void);
index 5a12663..a78a9c6 100644 (file)
  * @see_also: #GstPad, #GstMiniObject
  *
  * Buffers are the basic unit of data transfer in GStreamer.  The #GstBuffer
- * type provides all the state necessary to define a region of memory as part
- * of a stream.  Sub-buffers are also supported, allowing a smaller region of a
- * buffer to become its own buffer, with mechanisms in place to ensure that
- * neither memory space goes away prematurely.
+ * type provides all the state necessary to define the regions of memory as
+ * part of a stream. Region copies are also supported, allowing a smaller
+ * region of a buffer to become its own buffer, with mechanisms in place to
+ * ensure that neither memory space goes away prematurely.
  *
  * Buffers are usually created with gst_buffer_new(). After a buffer has been
  * created one will typically allocate memory for it and set the size of the
  * next element.
  *
  * To efficiently create a smaller buffer out of an existing one, you can
- * use gst_buffer_create_sub().
+ * use gst_buffer_copy_region().
  *
- * If a plug-in wants to modify the buffer data in-place, it should first obtain
- * a buffer that is safe to modify by using gst_buffer_make_writable().  This
- * function is optimized so that a copy will only be made when it is necessary.
- *
- * A plugin that only wishes to modify the metadata of a buffer, such as the
- * offset, timestamp or caps, should use gst_buffer_make_metadata_writable(),
- * which will create a subbuffer of the original buffer to ensure the caller
- * has sole ownership, and not copy the buffer data.
+ * If a plug-in wants to modify the buffer data or metadata in-place, it should
+ * first obtain a buffer that is safe to modify by using
+ * gst_buffer_make_writable().  This function is optimized so that a copy will
+ * only be made when it is necessary.
  *
  * Several flags of the buffer can be set and unset with the
  * GST_BUFFER_FLAG_SET() and GST_BUFFER_FLAG_UNSET() macros. Use
  * GST_BUFFER_FLAG_IS_SET() to test if a certain #GstBufferFlag is set.
  *
  * Buffers can be efficiently merged into a larger buffer with
- * gst_buffer_merge() and gst_buffer_span() if the gst_buffer_is_span_fast()
+ * gst_buffer_span(), which avoids memory copies when the gst_buffer_is_span_fast()
  * function returns TRUE.
  *
  * An element should either unref the buffer or push it out on a src pad
  * using gst_pad_push() (see #GstPad).
  *
  * Buffers are usually freed by unreffing them with gst_buffer_unref(). When
- * the refcount drops to 0, any data pointed to by GST_BUFFER_MALLOCDATA() will
- * also be freed.
+ * the refcount drops to 0, any data pointed to by the buffer is unreffed as
+ * well.
  *
- * Last reviewed on August 11th, 2006 (0.10.10)
+ * Last reviewed on March 30, 2011 (0.11.0)
  */
 #include "gst_private.h"
 
 #endif
 
 #include "gstbuffer.h"
+#include "gstbufferpool.h"
 #include "gstinfo.h"
 #include "gstutils.h"
 #include "gstminiobject.h"
 #include "gstversion.h"
 
-static void gst_buffer_finalize (GstBuffer * buffer);
-static GstBuffer *_gst_buffer_copy (GstBuffer * buffer);
+GType _gst_buffer_type = 0;
 
-static GType _gst_buffer_type = 0;
+static GstMemory *_gst_buffer_arr_span (GstMemory ** mem[], gsize len[],
+    guint n, gsize offset, gsize size, gboolean writable);
 
-/* buffer alignment in bytes
- * an alignment of 8 would be the same as malloc() guarantees
- */
-#ifdef HAVE_POSIX_MEMALIGN
-#if defined(BUFFER_ALIGNMENT_MALLOC)
-static size_t _gst_buffer_data_alignment = 8;
-#elif defined(BUFFER_ALIGNMENT_PAGESIZE)
-static size_t _gst_buffer_data_alignment = 0;
-#elif defined(BUFFER_ALIGNMENT)
-static size_t _gst_buffer_data_alignment = BUFFER_ALIGNMENT;
-#else
-#error "No buffer alignment configured"
-#endif
+typedef struct _GstMetaItem GstMetaItem;
 
-static inline gboolean
-aligned_malloc (gpointer * memptr, guint size)
+struct _GstMetaItem
 {
-  gint res;
+  GstMetaItem *next;
+  GstMeta meta;
+};
+#define ITEM_SIZE(info) ((info)->size + sizeof (GstMetaItem))
 
-  res = posix_memalign (memptr, _gst_buffer_data_alignment, size);
-  return (res == 0);
-}
+#define GST_BUFFER_MEM_MAX         16
 
-#endif /* HAVE_POSIX_MEMALIGN */
+#define GST_BUFFER_MEM_LEN(b)      (((GstBufferImpl *)(b))->len)
+#define GST_BUFFER_MEM_ARRAY(b)    (((GstBufferImpl *)(b))->mem)
+#define GST_BUFFER_MEM_PTR(b,i)    (((GstBufferImpl *)(b))->mem[i])
+#define GST_BUFFER_BUFMEM(b)       (((GstBufferImpl *)(b))->bufmem)
+#define GST_BUFFER_META(b)         (((GstBufferImpl *)(b))->item)
 
-void
-_gst_buffer_initialize (void)
+typedef struct
 {
-  /* the GstMiniObject types need to be class_ref'd once before it can be
-   * done from multiple threads;
-   * see http://bugzilla.gnome.org/show_bug.cgi?id=304551 */
-  g_type_class_ref (gst_buffer_get_type ());
-#ifdef HAVE_GETPAGESIZE
-#ifdef BUFFER_ALIGNMENT_PAGESIZE
-  _gst_buffer_data_alignment = getpagesize ();
-#endif
-#endif
-}
+  GstBuffer buffer;
 
-#define _do_init \
-{ \
-  _gst_buffer_type = g_define_type_id; \
-}
+  /* the memory blocks */
+  guint len;
+  GstMemory *mem[GST_BUFFER_MEM_MAX];
 
-G_DEFINE_TYPE_WITH_CODE (GstBuffer, gst_buffer, GST_TYPE_MINI_OBJECT, _do_init);
+  /* memory of the buffer when allocated from 1 chunk */
+  GstMemory *bufmem;
 
-static void
-gst_buffer_class_init (GstBufferClass * klass)
+  /* FIXME, make metadata allocation more efficient by using part of the
+   * GstBufferImpl */
+  GstMetaItem *item;
+} GstBufferImpl;
+
+static GstMemory *
+_span_memory (GstBuffer * buffer, gsize offset, gsize size, gboolean writable)
 {
-  klass->mini_object_class.copy = (GstMiniObjectCopyFunction) _gst_buffer_copy;
-  klass->mini_object_class.finalize =
-      (GstMiniObjectFinalizeFunction) gst_buffer_finalize;
+  GstMemory *span, **mem[1];
+  gsize len[1];
+
+  /* not enough room, span buffers */
+  mem[0] = GST_BUFFER_MEM_ARRAY (buffer);
+  len[0] = GST_BUFFER_MEM_LEN (buffer);
+
+  if (size == -1)
+    size = gst_buffer_get_size (buffer);
+
+  span = _gst_buffer_arr_span (mem, len, 1, offset, size, writable);
+
+  return span;
 }
 
 static void
-gst_buffer_finalize (GstBuffer * buffer)
+_replace_memory (GstBuffer * buffer, GstMemory * mem)
 {
-  g_return_if_fail (buffer != NULL);
+  gsize len, i;
 
-  GST_CAT_LOG (GST_CAT_BUFFER, "finalize %p", buffer);
+  /* unref old buffers */
+  len = GST_BUFFER_MEM_LEN (buffer);
+  for (i = 0; i < len; i++)
+    gst_memory_unref (GST_BUFFER_MEM_PTR (buffer, i));
 
-  /* free our data */
-  if (G_LIKELY (buffer->malloc_data))
-    buffer->free_func (buffer->malloc_data);
+  /* replace with single spanned buffer */
+  GST_BUFFER_MEM_PTR (buffer, 0) = mem;
+  GST_BUFFER_MEM_LEN (buffer) = 1;
+}
 
-  gst_caps_replace (&GST_BUFFER_CAPS (buffer), NULL);
+static inline void
+_memory_add (GstBuffer * buffer, guint idx, GstMemory * mem)
+{
+  guint i, len = GST_BUFFER_MEM_LEN (buffer);
+
+  if (G_UNLIKELY (len >= GST_BUFFER_MEM_MAX)) {
+    /* too many buffer, span them. */
+    /* FIXME, there is room for improvement here: We could only try to merge
+     * 2 buffers to make some room. If we can't efficiently merge 2 buffers we
+     * could try to only merge the two smallest buffers to avoid memcpy, etc. */
+    _replace_memory (buffer, _span_memory (buffer, 0, -1, FALSE));
+    /* we now have 1 single spanned buffer */
+    len = 1;
+  }
+
+  if (idx == -1)
+    idx = len;
 
-  if (buffer->parent)
-    gst_buffer_unref (buffer->parent);
+  for (i = len; i > idx; i--) {
+    /* move buffers to insert, FIXME, we need to insert first and then merge */
+    GST_BUFFER_MEM_PTR (buffer, i) = GST_BUFFER_MEM_PTR (buffer, i - 1);
+  }
+  /* and insert the new buffer */
+  GST_BUFFER_MEM_PTR (buffer, idx) = mem;
+  GST_BUFFER_MEM_LEN (buffer) = len + 1;
+}
 
-/*   ((GstMiniObjectClass *) */
-/*       gst_buffer_parent_class)->finalize (GST_MINI_OBJECT_CAST (buffer)); */
+void
+_gst_buffer_initialize (void)
+{
+  if (G_LIKELY (_gst_buffer_type == 0)) {
+    _gst_buffer_type = gst_mini_object_register ("GstBuffer");
+  }
 }
 
 /**
- * gst_buffer_copy_metadata:
+ * gst_buffer_copy_into:
  * @dest: a destination #GstBuffer
  * @src: a source #GstBuffer
  * @flags: flags indicating what metadata fields should be copied.
+ * @offset: offset to copy from
+ * @size: total size to copy
  *
- * Copies the metadata from @src into @dest. The data, size and mallocdata
- * fields are not copied.
+ * Copies the information from @src into @dest.
  *
- * @flags indicate which fields will be copied. Use #GST_BUFFER_COPY_ALL to copy
- * all the metadata fields.
- *
- * This function is typically called from a custom buffer copy function after
- * creating @dest and setting the data, size, mallocdata.
- *
- * Since: 0.10.13
+ * @flags indicate which fields will be copied.
  */
 void
-gst_buffer_copy_metadata (GstBuffer * dest, const GstBuffer * src,
-    GstBufferCopyFlags flags)
+gst_buffer_copy_into (GstBuffer * dest, GstBuffer * src,
+    GstBufferCopyFlags flags, gsize offset, gsize size)
 {
+  GstMetaItem *walk;
+  gsize bufsize;
+
   g_return_if_fail (dest != NULL);
   g_return_if_fail (src != NULL);
 
@@ -235,12 +257,17 @@ gst_buffer_copy_metadata (GstBuffer * dest, const GstBuffer * src,
   if (G_UNLIKELY (dest == src))
     return;
 
-#if GST_VERSION_NANO == 1
-  /* we enable this extra debugging in git versions only for now */
-  g_warn_if_fail (gst_buffer_is_metadata_writable (dest));
-#endif
+  g_return_if_fail (gst_buffer_is_writable (dest));
+
+  bufsize = gst_buffer_get_size (src);
+  g_return_if_fail (bufsize >= offset);
+  if (size == -1)
+    size = bufsize - offset;
+  g_return_if_fail (bufsize >= offset + size);
 
-  GST_CAT_LOG (GST_CAT_BUFFER, "copy %p to %p", src, dest);
+  GST_CAT_LOG (GST_CAT_BUFFER, "copy %p to %p, offset %" G_GSIZE_FORMAT
+      "-%" G_GSIZE_FORMAT "/%" G_GSIZE_FORMAT, src, dest, offset, size,
+      bufsize);
 
   if (flags & GST_BUFFER_COPY_FLAGS) {
     guint mask;
@@ -254,14 +281,67 @@ gst_buffer_copy_metadata (GstBuffer * dest, const GstBuffer * src,
   }
 
   if (flags & GST_BUFFER_COPY_TIMESTAMPS) {
-    GST_BUFFER_TIMESTAMP (dest) = GST_BUFFER_TIMESTAMP (src);
-    GST_BUFFER_DURATION (dest) = GST_BUFFER_DURATION (src);
-    GST_BUFFER_OFFSET (dest) = GST_BUFFER_OFFSET (src);
-    GST_BUFFER_OFFSET_END (dest) = GST_BUFFER_OFFSET_END (src);
+    if (offset == 0) {
+      GST_BUFFER_TIMESTAMP (dest) = GST_BUFFER_TIMESTAMP (src);
+      GST_BUFFER_OFFSET (dest) = GST_BUFFER_OFFSET (src);
+      if (size == bufsize) {
+        GST_BUFFER_DURATION (dest) = GST_BUFFER_DURATION (src);
+        GST_BUFFER_OFFSET_END (dest) = GST_BUFFER_OFFSET_END (src);
+      }
+    } else {
+      GST_BUFFER_TIMESTAMP (dest) = GST_CLOCK_TIME_NONE;
+      GST_BUFFER_DURATION (dest) = GST_CLOCK_TIME_NONE;
+      GST_BUFFER_OFFSET (dest) = GST_BUFFER_OFFSET_NONE;
+      GST_BUFFER_OFFSET_END (dest) = GST_BUFFER_OFFSET_NONE;
+    }
+  }
+
+  if (flags & GST_BUFFER_COPY_MEMORY) {
+    GstMemory *mem;
+    gsize skip, left, len, i, bsize;
+
+    len = GST_BUFFER_MEM_LEN (src);
+    left = size;
+    skip = offset;
+
+    /* copy and make regions of the memory */
+    for (i = 0; i < len && left > 0; i++) {
+      mem = GST_BUFFER_MEM_PTR (src, i);
+      bsize = gst_memory_get_sizes (mem, NULL);
+
+      if (bsize <= skip) {
+        /* don't copy buffer */
+        skip -= bsize;
+      } else {
+        gsize tocopy;
+
+        tocopy = MIN (bsize - skip, left);
+        if (mem->flags & GST_MEMORY_FLAG_NO_SHARE) {
+          /* no share, always copy then */
+          mem = gst_memory_copy (mem, skip, tocopy);
+          skip = 0;
+        } else if (tocopy < bsize) {
+          /* we need to clip something */
+          mem = gst_memory_share (mem, skip, tocopy);
+          skip = 0;
+        } else {
+          mem = gst_memory_ref (mem);
+        }
+        _memory_add (dest, -1, mem);
+        left -= tocopy;
+      }
+    }
+    if (flags & GST_BUFFER_COPY_MERGE) {
+      _replace_memory (dest, _span_memory (dest, 0, size, FALSE));
+    }
   }
 
-  if (flags & GST_BUFFER_COPY_CAPS) {
-    gst_caps_replace (&GST_BUFFER_CAPS (dest), GST_BUFFER_CAPS (src));
+  for (walk = GST_BUFFER_META (src); walk; walk = walk->next) {
+    GstMeta *meta = &walk->meta;
+    const GstMetaInfo *info = meta->info;
+
+    if (info->copy_func)
+      info->copy_func (dest, meta, src, offset, size);
   }
 }
 
@@ -276,45 +356,88 @@ _gst_buffer_copy (GstBuffer * buffer)
   copy = gst_buffer_new ();
 
   /* we simply copy everything from our parent */
-#ifdef HAVE_POSIX_MEMALIGN
-  {
-    gpointer memptr = NULL;
+  gst_buffer_copy_into (copy, buffer, GST_BUFFER_COPY_ALL, 0, -1);
 
-    if (G_LIKELY (buffer->size)) {
-      if (G_UNLIKELY (!aligned_malloc (&memptr, buffer->size))) {
-        /* terminate on error like g_memdup() would */
-        g_error ("%s: failed to allocate %u bytes", G_STRLOC, buffer->size);
-      } else {
-        memcpy (memptr, buffer->data, buffer->size);
-      }
-    }
-    copy->data = (guint8 *) memptr;
-    GST_BUFFER_FREE_FUNC (copy) = free;
+  return copy;
+}
+
+/* the default dispose function revives the buffer and returns it to the
+ * pool when there is a pool */
+static void
+_gst_buffer_dispose (GstBuffer * buffer)
+{
+  GstBufferPool *pool;
+
+  if ((pool = buffer->pool) != NULL) {
+    /* keep the buffer alive */
+    gst_buffer_ref (buffer);
+    /* return the buffer to the pool */
+    GST_CAT_LOG (GST_CAT_BUFFER, "release %p to pool %p", buffer, pool);
+    gst_buffer_pool_release_buffer (pool, buffer);
   }
-#else
-  copy->data = g_memdup (buffer->data, buffer->size);
-#endif
+}
 
-  /* make sure it gets freed (even if the parent is subclassed, we return a
-     normal buffer) */
-  copy->malloc_data = copy->data;
-  copy->size = buffer->size;
+static void
+_gst_buffer_free (GstBuffer * buffer)
+{
+  GstMetaItem *walk, *next;
+  guint i, len;
+  gsize msize;
 
-  gst_buffer_copy_metadata (copy, buffer, GST_BUFFER_COPY_ALL);
+  g_return_if_fail (buffer != NULL);
 
-  return copy;
+  GST_CAT_LOG (GST_CAT_BUFFER, "finalize %p", buffer);
+
+  /* free metadata */
+  for (walk = GST_BUFFER_META (buffer); walk; walk = next) {
+    GstMeta *meta = &walk->meta;
+    const GstMetaInfo *info = meta->info;
+
+    /* call free_func if any */
+    if (info->free_func)
+      info->free_func (meta, buffer);
+
+    next = walk->next;
+    /* and free the slice */
+    g_slice_free1 (ITEM_SIZE (info), walk);
+  }
+
+  /* get the size, when unreffing the memory, we could also unref the buffer
+   * itself */
+  msize = GST_MINI_OBJECT_SIZE (buffer);
+
+  /* free our memory */
+  len = GST_BUFFER_MEM_LEN (buffer);
+  for (i = 0; i < len; i++)
+    gst_memory_unref (GST_BUFFER_MEM_PTR (buffer, i));
+
+  /* we set msize to 0 when the buffer is part of the memory block */
+  if (msize)
+    g_slice_free1 (msize, buffer);
+  else
+    gst_memory_unref (GST_BUFFER_BUFMEM (buffer));
 }
 
 static void
-gst_buffer_init (GstBuffer * buffer)
+gst_buffer_init (GstBufferImpl * buffer, gsize size)
 {
-  GST_CAT_LOG (GST_CAT_BUFFER, "init %p", buffer);
+  gst_mini_object_init (GST_MINI_OBJECT_CAST (buffer), _gst_buffer_type, size);
 
+  buffer->buffer.mini_object.copy =
+      (GstMiniObjectCopyFunction) _gst_buffer_copy;
+  buffer->buffer.mini_object.dispose =
+      (GstMiniObjectDisposeFunction) _gst_buffer_dispose;
+  buffer->buffer.mini_object.free =
+      (GstMiniObjectFreeFunction) _gst_buffer_free;
+
+  GST_BUFFER (buffer)->pool = NULL;
   GST_BUFFER_TIMESTAMP (buffer) = GST_CLOCK_TIME_NONE;
   GST_BUFFER_DURATION (buffer) = GST_CLOCK_TIME_NONE;
   GST_BUFFER_OFFSET (buffer) = GST_BUFFER_OFFSET_NONE;
   GST_BUFFER_OFFSET_END (buffer) = GST_BUFFER_OFFSET_NONE;
-  GST_BUFFER_FREE_FUNC (buffer) = g_free;
+
+  GST_BUFFER_MEM_LEN (buffer) = 0;
+  GST_BUFFER_META (buffer) = NULL;
 }
 
 /**
@@ -329,227 +452,610 @@ gst_buffer_init (GstBuffer * buffer)
 GstBuffer *
 gst_buffer_new (void)
 {
-  GstBuffer *newbuf;
-
-  newbuf = (GstBuffer *) gst_mini_object_new (_gst_buffer_type);
+  GstBufferImpl *newbuf;
 
+  newbuf = g_slice_new (GstBufferImpl);
   GST_CAT_LOG (GST_CAT_BUFFER, "new %p", newbuf);
 
-  return newbuf;
+  gst_buffer_init (newbuf, sizeof (GstBufferImpl));
+
+  return GST_BUFFER_CAST (newbuf);
 }
 
 /**
- * gst_buffer_new_and_alloc:
+ * gst_buffer_new_allocate:
+ * @allocator: the #GstMemoryAllocator to use
  * @size: the size in bytes of the new buffer's data.
+ * @align: the alignment of the buffer memory
  *
- * Creates a newly allocated buffer with data of the given size.
- * The buffer memory is not cleared. If the requested amount of
- * memory can't be allocated, the program will abort. Use
- * gst_buffer_try_new_and_alloc() if you want to handle this case
- * gracefully or have gotten the size to allocate from an untrusted
- * source such as a media stream.
- * 
+ * Tries to create a newly allocated buffer with data of the given size and
+ * alignment from @allocator. If the requested amount of memory can't be
+ * allocated, NULL will be returned. The allocated buffer memory is not cleared.
  *
- * Note that when @size == 0, the buffer data pointer will be NULL.
+ * When @allocator is NULL, the default memory allocator will be used.
+ *
+ * Allocator buffer memory will be aligned to multiples of (@align + 1) bytes.
+ *
+ * Note that when @size == 0, the buffer will not have memory associated with it.
  *
  * MT safe.
  *
- * Returns: (transfer full): the new #GstBuffer.
+ * Returns: (transfer full): a new #GstBuffer, or NULL if the memory couldn't
+ *     be allocated.
  */
 GstBuffer *
-gst_buffer_new_and_alloc (guint size)
+gst_buffer_new_allocate (const GstMemoryAllocator * allocator, gsize size,
+    gsize align)
 {
   GstBuffer *newbuf;
+  GstMemory *mem;
+#if 0
+  guint8 *data;
+  gsize asize;
+#endif
+
+#if 1
+  if (size > 0) {
+    mem = gst_memory_allocator_alloc (allocator, size, align);
+    if (G_UNLIKELY (mem == NULL))
+      goto no_memory;
+  } else {
+    mem = NULL;
+  }
 
   newbuf = gst_buffer_new ();
 
-#ifdef HAVE_POSIX_MEMALIGN
-  {
-    gpointer memptr = NULL;
+  if (mem != NULL)
+    _memory_add (newbuf, -1, mem);
 
-    if (G_LIKELY (size)) {
-      if (G_UNLIKELY (!aligned_malloc (&memptr, size))) {
-        /* terminate on error like g_memdup() would */
-        g_error ("%s: failed to allocate %u bytes", G_STRLOC, size);
-      }
-    }
-    newbuf->malloc_data = (guint8 *) memptr;
-    GST_BUFFER_FREE_FUNC (newbuf) = free;
+  GST_CAT_LOG (GST_CAT_BUFFER, "new %p of size %d from allocator %p", newbuf,
+      size, allocator);
+#endif
+
+#if 0
+  asize = sizeof (GstBufferImpl) + size;
+  data = g_slice_alloc (asize);
+  if (G_UNLIKELY (data == NULL))
+    goto no_memory;
+
+  newbuf = GST_BUFFER_CAST (data);
+
+  gst_buffer_init ((GstBufferImpl *) data, asize);
+  if (size > 0) {
+    mem = gst_memory_new_wrapped (0, data + sizeof (GstBufferImpl), NULL,
+        size, 0, size);
+    _memory_add (newbuf, -1, mem);
   }
-#else
-  newbuf->malloc_data = g_malloc (size);
 #endif
-  GST_BUFFER_DATA (newbuf) = newbuf->malloc_data;
-  GST_BUFFER_SIZE (newbuf) = size;
 
-  GST_CAT_LOG (GST_CAT_BUFFER, "new %p of size %d", newbuf, size);
+#if 0
+  /* allocate memory and buffer, it might be interesting to do this but there
+   * are many complications. We need to keep the memory mapped to access the
+   * buffer fields and the memory for the buffer might be just very slow. We
+   * also need to do some more magic to get the alignment right. */
+  asize = sizeof (GstBufferImpl) + size;
+  mem = gst_memory_allocator_alloc (allocator, asize, align);
+  if (G_UNLIKELY (mem == NULL))
+    goto no_memory;
+
+  /* map the data part and init the buffer in it, set the buffer size to 0 so
+   * that a finalize won't free the buffer */
+  data = gst_memory_map (mem, &asize, NULL, GST_MAP_WRITE);
+  gst_buffer_init ((GstBufferImpl *) data, 0);
+  gst_memory_unmap (mem, data, asize);
+
+  /* strip off the buffer */
+  gst_memory_resize (mem, sizeof (GstBufferImpl), size);
+
+  newbuf = GST_BUFFER_CAST (data);
+  GST_BUFFER_BUFMEM (newbuf) = mem;
+
+  if (size > 0)
+    _memory_add (newbuf, -1, gst_memory_ref (mem));
+#endif
 
   return newbuf;
+
+  /* ERRORS */
+no_memory:
+  {
+    GST_CAT_WARNING (GST_CAT_BUFFER, "failed to allocate %d bytes", size);
+    return NULL;
+  }
 }
 
 /**
- * gst_buffer_try_new_and_alloc:
- * @size: the size in bytes of the new buffer's data.
+ * gst_buffer_n_memory:
+ * @buffer: a #GstBuffer.
  *
- * Tries to create a newly allocated buffer with data of the given size. If
- * the requested amount of memory can't be allocated, NULL will be returned.
- * The buffer memory is not cleared.
+ * Get the amount of memory blocks that this buffer has.
  *
- * Note that when @size == 0, the buffer data pointer will be NULL.
+ * Returns: (transfer full): the amount of memory block in this buffer.
+ */
+guint
+gst_buffer_n_memory (GstBuffer * buffer)
+{
+  g_return_val_if_fail (GST_IS_BUFFER (buffer), 0);
+
+  return GST_BUFFER_MEM_LEN (buffer);
+}
+
+/**
+ * gst_buffer_take_memory:
+ * @buffer: a #GstBuffer.
+ * @idx: the index to add the memory
+ * @mem: a #GstMemory.
  *
- * MT safe.
+ * Add the memory block @mem to @buffer at @idx. This function takes ownership of @mem
+ * and thus doesn't increase its refcount.
+ */
+void
+gst_buffer_take_memory (GstBuffer * buffer, guint idx, GstMemory * mem)
+{
+  g_return_if_fail (GST_IS_BUFFER (buffer));
+  g_return_if_fail (gst_buffer_is_writable (buffer));
+  g_return_if_fail (mem != NULL);
+  g_return_if_fail (idx == -1 || idx < GST_BUFFER_MEM_LEN (buffer));
+
+  _memory_add (buffer, idx, mem);
+}
+
+static GstMemory *
+_get_memory (GstBuffer * buffer, guint idx, gboolean write)
+{
+  GstMemory *mem;
+
+  mem = GST_BUFFER_MEM_PTR (buffer, idx);
+
+  if (G_UNLIKELY (write && !GST_MEMORY_IS_WRITABLE (mem))) {
+    GstMemory *copy;
+    GST_CAT_LOG (GST_CAT_BUFFER,
+        "making writable copy of memory %p in buffer %p", mem, buffer);
+    /* replace with a writable copy */
+    copy = gst_memory_copy (mem, 0, -1);
+    GST_BUFFER_MEM_PTR (buffer, idx) = copy;
+    gst_memory_unref (mem);
+    mem = copy;
+  }
+  return mem;
+}
+
+/**
+ * gst_buffer_peek_memory:
+ * @buffer: a #GstBuffer.
+ * @idx: an index
  *
- * Returns: (transfer full): a new #GstBuffer, or NULL if the memory couldn't
- *     be allocated.
+ * Get the memory block in @buffer at @idx. This function does not return a
+ * refcount to the memory block. The memory block stays valid for as long as the
+ * caller has a valid reference to @buffer.
  *
- * Since: 0.10.13
+ * Returns: a #GstMemory at @idx.
  */
-GstBuffer *
-gst_buffer_try_new_and_alloc (guint size)
+GstMemory *
+gst_buffer_peek_memory (GstBuffer * buffer, guint idx, GstMapFlags flags)
 {
-  GstBuffer *newbuf;
-  guint8 *malloc_data;
-#ifdef HAVE_POSIX_MEMALIGN
-  gpointer memptr = NULL;
-
-  if (G_LIKELY (size)) {
-    if (G_UNLIKELY (!aligned_malloc (&memptr, size))) {
-      GST_CAT_WARNING (GST_CAT_BUFFER, "failed to allocate %d bytes", size);
-      return NULL;
-    }
-  }
-  malloc_data = (guint8 *) memptr;
-#else
-  malloc_data = g_try_malloc (size);
+  GstMemory *mem;
+  gboolean write;
 
-  if (G_UNLIKELY (malloc_data == NULL && size != 0)) {
-    GST_CAT_WARNING (GST_CAT_BUFFER, "failed to allocate %d bytes", size);
-    return NULL;
-  }
-#endif
+  write = (flags & GST_MAP_WRITE) != 0;
 
-  /* FIXME: there's no g_type_try_create_instance() in GObject yet, so this
-   * will still abort if a new GstBuffer structure can't be allocated */
-  newbuf = gst_buffer_new ();
+  g_return_val_if_fail (GST_IS_BUFFER (buffer), NULL);
+  g_return_val_if_fail (idx < GST_BUFFER_MEM_LEN (buffer), NULL);
 
-  GST_BUFFER_MALLOCDATA (newbuf) = malloc_data;
-  GST_BUFFER_DATA (newbuf) = malloc_data;
-  GST_BUFFER_SIZE (newbuf) = size;
-#ifdef HAVE_POSIX_MEMALIGN
-  GST_BUFFER_FREE_FUNC (newbuf) = free;
-#endif
+  /* check if we can write when asked for write access */
+  if (G_UNLIKELY (write && !gst_buffer_is_writable (buffer)))
+    goto not_writable;
 
-  GST_CAT_LOG (GST_CAT_BUFFER, "new %p of size %d", newbuf, size);
+  mem = _get_memory (buffer, idx, write);
 
-  return newbuf;
+  return mem;
+
+  /* ERRORS */
+not_writable:
+  {
+    g_return_val_if_fail (gst_buffer_is_writable (buffer), NULL);
+    return NULL;
+  }
 }
 
 /**
- * gst_buffer_get_caps:
+ * gst_buffer_remove_memory_range:
  * @buffer: a #GstBuffer.
+ * @idx: an index
+ * @length: a length
  *
- * Gets the media type of the buffer. This can be NULL if there
- * is no media type attached to this buffer.
+ * Remove @len memory blocks in @buffer starting from @idx.
  *
- * Returns: (transfer full): a reference to the #GstCaps. unref after usage.
- * Returns NULL if there were no caps on this buffer.
+ * @length can be -1, in which case all memory starting from @idx is removed.
  */
-/* this is not made atomic because if the buffer were reffed from multiple
- * threads, it would have a refcount > 2 and thus be immutable.
- */
-GstCaps *
-gst_buffer_get_caps (GstBuffer * buffer)
+void
+gst_buffer_remove_memory_range (GstBuffer * buffer, guint idx, guint length)
 {
-  GstCaps *ret;
+  guint len, i, end;
 
-  g_return_val_if_fail (buffer != NULL, NULL);
+  g_return_if_fail (GST_IS_BUFFER (buffer));
+  g_return_if_fail (gst_buffer_is_writable (buffer));
 
-  ret = GST_BUFFER_CAPS (buffer);
+  len = GST_BUFFER_MEM_LEN (buffer);
+  if (length == -1) {
+    g_return_if_fail (idx < len);
+    length = len - idx;
+  }
 
-  if (ret)
-    gst_caps_ref (ret);
+  end = idx + length;
+  for (i = idx; i < end; i++)
+    gst_memory_unref (GST_BUFFER_MEM_PTR (buffer, i));
 
-  return ret;
+  if (end != len) {
+    g_memmove (&GST_BUFFER_MEM_PTR (buffer, idx),
+        &GST_BUFFER_MEM_PTR (buffer, end), (len - end) * sizeof (gpointer));
+  }
+  GST_BUFFER_MEM_LEN (buffer) = len - length;
 }
 
 /**
- * gst_buffer_set_caps:
+ * gst_buffer_get_size:
  * @buffer: a #GstBuffer.
- * @caps: (transfer none): a #GstCaps.
  *
- * Sets the media type on the buffer. The refcount of the caps will
- * be increased and any previous caps on the buffer will be
- * unreffed.
+ * Get the total size of all memory blocks in @buffer.
+ *
+ * Returns: the total size of the memory in @buffer.
  */
-/* this is not made atomic because if the buffer were reffed from multiple
- * threads, it would have a refcount > 2 and thus be immutable.
+gsize
+gst_buffer_get_size (GstBuffer * buffer)
+{
+  guint i, size, len;
+
+  g_return_val_if_fail (GST_IS_BUFFER (buffer), 0);
+
+  len = GST_BUFFER_MEM_LEN (buffer);
+
+  size = 0;
+  for (i = 0; i < len; i++) {
+    size += gst_memory_get_sizes (GST_BUFFER_MEM_PTR (buffer, i), NULL);
+  }
+  return size;
+}
+
+/**
+ * gst_buffer_resize:
+ * @buffer: a #GstBuffer.
+ * @offset: the new offset
+ * @size: the new size
+ *
+ * Set the total size of the buffer
  */
 void
-gst_buffer_set_caps (GstBuffer * buffer, GstCaps * caps)
+gst_buffer_resize (GstBuffer * buffer, gsize offset, gsize size)
 {
-  g_return_if_fail (buffer != NULL);
-  g_return_if_fail (caps == NULL || GST_CAPS_IS_SIMPLE (caps));
+  guint len;
+  guint si, di;
+  gsize bsize, bufsize;
+  GstMemory *mem;
+
+  GST_CAT_LOG (GST_CAT_BUFFER, "trim %p %" G_GSIZE_FORMAT "-%" G_GSIZE_FORMAT,
+      buffer, offset, size);
+
+  g_return_if_fail (gst_buffer_is_writable (buffer));
+
+  bufsize = gst_buffer_get_size (buffer);
+  g_return_if_fail (bufsize >= offset);
+  if (size == -1)
+    size = bufsize - offset;
+  g_return_if_fail (bufsize >= offset + size);
+
+  len = GST_BUFFER_MEM_LEN (buffer);
+
+  /* copy and trim */
+  for (di = si = 0; si < len && size > 0; si++) {
+    mem = GST_BUFFER_MEM_PTR (buffer, si);
+    bsize = gst_memory_get_sizes (mem, NULL);
+
+    if (bsize <= offset) {
+      /* remove buffer */
+      gst_memory_unref (mem);
+      offset -= bsize;
+    } else {
+      gsize tocopy;
+
+      tocopy = MIN (bsize - offset, size);
+      if (tocopy < bsize) {
+        /* we need to clip something */
+        if (GST_MEMORY_IS_WRITABLE (mem)) {
+          gst_memory_resize (mem, offset, tocopy);
+        } else {
+          GstMemory *tmp;
+
+          if (mem->flags & GST_MEMORY_FLAG_NO_SHARE)
+            tmp = gst_memory_copy (mem, offset, tocopy);
+          else
+            tmp = gst_memory_share (mem, offset, tocopy);
+
+          gst_memory_unref (mem);
+          mem = tmp;
+        }
+        offset = 0;
+      }
+      GST_BUFFER_MEM_PTR (buffer, di++) = mem;
+      size -= tocopy;
+    }
+  }
+  GST_BUFFER_MEM_LEN (buffer) = di;
+}
 
-#if GST_VERSION_NANO == 1
-  /* we enable this extra debugging in git versions only for now */
-  g_warn_if_fail (gst_buffer_is_metadata_writable (buffer));
-  /* FIXME: would be nice to also check if caps are fixed here, but expensive */
-#endif
+/**
+ * gst_buffer_map:
+ * @buffer: a #GstBuffer.
+ * @size: a location for the size
+ * @maxsize: a location for the max size
+ * @flags: flags for the mapping
+ *
+ * This function return a pointer to the memory in @buffer. @flags describe the
+ * desired access of the memory. When @flags is #GST_MAP_WRITE, @buffer should
+ * be writable (as returned from gst_buffer_is_writable()).
+ *
+ * @size and @maxsize will contain the current valid number of bytes in the
+ * returned memory area and the total maximum mount of bytes available in the
+ * returned memory area respectively.
+ *
+ * When @buffer is writable but the memory isn't, a writable copy will
+ * automatically be created and returned. The readonly copy of the buffer memory
+ * will then also be replaced with this writable copy.
+ *
+ * When the buffer contains multiple memory blocks, the returned pointer will be
+ * a concatenation of the memory blocks.
+ *
+ * Returns: a pointer to the memory for the buffer.
+ */
+gpointer
+gst_buffer_map (GstBuffer * buffer, gsize * size, gsize * maxsize,
+    GstMapFlags flags)
+{
+  guint len;
+  gpointer data;
+  GstMemory *mem;
+  gboolean write, writable;
+
+  g_return_val_if_fail (GST_IS_BUFFER (buffer), NULL);
 
-  gst_caps_replace (&GST_BUFFER_CAPS (buffer), caps);
+  write = (flags & GST_MAP_WRITE) != 0;
+  writable = gst_buffer_is_writable (buffer);
+
+  /* check if we can write when asked for write access */
+  if (G_UNLIKELY (write && !writable))
+    goto not_writable;
+
+  len = GST_BUFFER_MEM_LEN (buffer);
+
+  if (G_UNLIKELY (len == 0)) {
+    /* no memory, return immediately */
+    if (size)
+      *size = 0;
+    if (maxsize)
+      *maxsize = 0;
+    return NULL;
+  }
+
+  if (G_LIKELY (len == 1)) {
+    /* we can take the first one */
+    mem = GST_BUFFER_MEM_PTR (buffer, 0);
+  } else {
+    /* we need to span memory */
+    if (writable) {
+      /* if we can write, we can change the memory with the spanned
+       * memory */
+      mem = _span_memory (buffer, 0, -1, write);
+      _replace_memory (buffer, mem);
+    } else {
+      gsize bsize;
+
+      /* extract all data in new memory, FIXME slow!! */
+      bsize = gst_buffer_get_size (buffer);
+
+      data = g_malloc (bsize);
+      gst_buffer_extract (buffer, 0, data, bsize);
+      if (size)
+        *size = bsize;
+      if (maxsize)
+        *maxsize = bsize;
+      return data;
+    }
+  }
+
+  if (G_UNLIKELY (write && !GST_MEMORY_IS_WRITABLE (mem))) {
+    GstMemory *copy;
+    /* replace with a writable copy */
+    copy = gst_memory_copy (mem, 0, -1);
+    GST_BUFFER_MEM_PTR (buffer, 0) = copy;
+    gst_memory_unref (mem);
+    mem = copy;
+  }
+
+  data = gst_memory_map (mem, size, maxsize, flags);
+
+  return data;
+
+  /* ERROR */
+not_writable:
+  {
+    g_return_val_if_fail (gst_buffer_is_writable (buffer), NULL);
+    return NULL;
+  }
 }
 
 /**
- * gst_buffer_is_metadata_writable:
- * @buf: a #GstBuffer
+ * gst_buffer_unmap:
+ * @buffer: a #GstBuffer.
+ * @data: the previously mapped data
+ * @size: the size of @data
  *
- * Similar to gst_buffer_is_writable, but this only ensures that the
- * refcount of the buffer is 1, indicating that the caller is the sole
- * owner and can change the buffer metadata, such as caps and timestamps.
+ * Release the memory previously mapped with gst_buffer_map().
  *
- * Returns: TRUE if the metadata is writable.
+ * Returns: #TRUE on success. #FALSE can be returned when the new size is larger
+ * than the maxsize of the memory.
  */
 gboolean
-gst_buffer_is_metadata_writable (GstBuffer * buf)
+gst_buffer_unmap (GstBuffer * buffer, gpointer data, gsize size)
 {
-  return (GST_MINI_OBJECT_REFCOUNT_VALUE (GST_MINI_OBJECT_CAST (buf)) == 1);
+  gboolean result;
+  guint len;
+
+  g_return_val_if_fail (GST_IS_BUFFER (buffer), FALSE);
+
+  len = GST_BUFFER_MEM_LEN (buffer);
+
+  if (G_LIKELY (len == 1)) {
+    GstMemory *mem = GST_BUFFER_MEM_PTR (buffer, 0);
+
+    result = gst_memory_unmap (mem, data, size);
+  } else {
+    /* this must have been from read-only access. After _map, the buffer either
+     * only contains 1 memory block or it allocated memory to join memory
+     * blocks. It's not allowed to add buffers between _map and _unmap. */
+    g_free (data);
+    result = TRUE;
+  }
+  return result;
 }
 
 /**
- * gst_buffer_make_metadata_writable:
- * @buf: (transfer full): a #GstBuffer
- *
- * Similar to gst_buffer_make_writable, but does not ensure that the buffer
- * data array is writable. Instead, this just ensures that the returned buffer
- * is solely owned by the caller, by creating a subbuffer of the original
- * buffer if necessary.
- * 
- * After calling this function, @buf should not be referenced anymore. The
- * result of this function has guaranteed writable metadata.
- *
- * Returns: (transfer full): a new #GstBuffer with writable metadata, which
- *     may or may not be the same as @buf.
+ * gst_buffer_fill:
+ * @buffer: a #GstBuffer.
+ * @offset: the offset to fill
+ * @src: the source address
+ * @size: the size to fill
+ *
+ * Copy @size bytes from @src to @buffer at @offset.
  */
-GstBuffer *
-gst_buffer_make_metadata_writable (GstBuffer * buf)
+void
+gst_buffer_fill (GstBuffer * buffer, gsize offset, gconstpointer src,
+    gsize size)
 {
-  GstBuffer *ret;
+  gsize i, len;
+  const guint8 *ptr = src;
 
-  if (gst_buffer_is_metadata_writable (buf)) {
-    ret = buf;
-  } else {
-    ret = gst_buffer_create_sub (buf, 0, GST_BUFFER_SIZE (buf));
+  g_return_if_fail (GST_IS_BUFFER (buffer));
+  g_return_if_fail (gst_buffer_is_writable (buffer));
+  g_return_if_fail (src != NULL);
 
-    gst_buffer_unref (buf);
+  len = GST_BUFFER_MEM_LEN (buffer);
+
+  for (i = 0; i < len && size > 0; i++) {
+    guint8 *data;
+    gsize ssize, tocopy;
+    GstMemory *mem;
+
+    mem = _get_memory (buffer, i, TRUE);
+
+    data = gst_memory_map (mem, &ssize, NULL, GST_MAP_WRITE);
+    if (ssize > offset) {
+      /* we have enough */
+      tocopy = MIN (ssize - offset, size);
+      memcpy (data + offset, ptr, tocopy);
+      size -= tocopy;
+      ptr += tocopy;
+      offset = 0;
+    } else {
+      /* offset past buffer, skip */
+      offset -= ssize;
+    }
+    gst_memory_unmap (mem, data, ssize);
   }
+}
 
-  return ret;
+/**
+ * gst_buffer_extract:
+ * @buffer: a #GstBuffer.
+ * @offset: the offset to extract
+ * @dest: the destination address
+ * @size: the size to extract
+ *
+ * Copy @size bytes starting from @offset in @buffer to @dest.
+ */
+void
+gst_buffer_extract (GstBuffer * buffer, gsize offset, gpointer dest, gsize size)
+{
+  gsize i, len;
+  guint8 *ptr = dest;
+
+  g_return_if_fail (GST_IS_BUFFER (buffer));
+  g_return_if_fail (dest != NULL);
+
+  len = GST_BUFFER_MEM_LEN (buffer);
+
+  for (i = 0; i < len && size > 0; i++) {
+    guint8 *data;
+    gsize ssize, tocopy;
+    GstMemory *mem;
+
+    mem = GST_BUFFER_MEM_PTR (buffer, i);
+
+    data = gst_memory_map (mem, &ssize, NULL, GST_MAP_READ);
+    if (ssize > offset) {
+      /* we have enough */
+      tocopy = MIN (ssize - offset, size);
+      memcpy (ptr, data + offset, tocopy);
+      size -= tocopy;
+      ptr += tocopy;
+      offset = 0;
+    } else {
+      /* offset past buffer, skip */
+      offset -= ssize;
+    }
+    gst_memory_unmap (mem, data, ssize);
+  }
 }
 
-#define GST_IS_SUBBUFFER(obj)   (GST_BUFFER_CAST(obj)->parent != NULL)
+/**
+ * gst_buffer_memcmp:
+ * @buffer: a #GstBuffer.
+ * @offset: the offset in @buffer
+ * @mem: the memory to compare
+ * @size: the size to compare
+ *
+ * Compare @size bytes starting from @offset in @buffer with the memory in @mem.
+ *
+ * Returns: 0 if the memory is equal.
+ */
+gint
+gst_buffer_memcmp (GstBuffer * buffer, gsize offset, gconstpointer mem,
+    gsize size)
+{
+  gsize i, len;
+  const guint8 *ptr = mem;
+  gint res = 0;
+
+  g_return_val_if_fail (GST_IS_BUFFER (buffer), 0);
+  g_return_val_if_fail (mem != NULL, 0);
+
+  len = GST_BUFFER_MEM_LEN (buffer);
+
+  for (i = 0; i < len && size > 0 && res == 0; i++) {
+    guint8 *data;
+    gsize ssize, tocmp;
+    GstMemory *mem;
+
+    mem = GST_BUFFER_MEM_PTR (buffer, i);
+
+    data = gst_memory_map (mem, &ssize, NULL, GST_MAP_READ);
+    if (ssize > offset) {
+      /* we have enough */
+      tocmp = MIN (ssize - offset, size);
+      res = memcmp (ptr, data + offset, tocmp);
+      size -= tocmp;
+      ptr += tocmp;
+      offset = 0;
+    } else {
+      /* offset past buffer, skip */
+      offset -= ssize;
+    }
+    gst_memory_unmap (mem, data, ssize);
+  }
+  return res;
+}
 
 /**
- * gst_buffer_create_sub:
+ * gst_buffer_copy_region:
  * @parent: a #GstBuffer.
  * @offset: the offset into parent #GstBuffer at which the new sub-buffer 
  *          begins.
@@ -570,74 +1076,112 @@ gst_buffer_make_metadata_writable (GstBuffer * buf)
  *     invalid.
  */
 GstBuffer *
-gst_buffer_create_sub (GstBuffer * buffer, guint offset, guint size)
+gst_buffer_copy_region (GstBuffer * buffer, GstBufferCopyFlags flags,
+    gsize offset, gsize size)
 {
-  GstBuffer *subbuffer;
-  GstBuffer *parent;
-  gboolean complete;
+  GstBuffer *copy;
 
   g_return_val_if_fail (buffer != NULL, NULL);
-  g_return_val_if_fail (buffer->mini_object.refcount > 0, NULL);
-  g_return_val_if_fail (buffer->size >= offset + size, NULL);
-
-  /* find real parent */
-  if (GST_IS_SUBBUFFER (buffer)) {
-    parent = buffer->parent;
-  } else {
-    parent = buffer;
-  }
-  gst_buffer_ref (parent);
 
   /* create the new buffer */
-  subbuffer = gst_buffer_new ();
-  subbuffer->parent = parent;
-  GST_BUFFER_FLAG_SET (subbuffer, GST_BUFFER_FLAG_READONLY);
+  copy = gst_buffer_new ();
 
-  GST_CAT_LOG (GST_CAT_BUFFER, "new subbuffer %p (parent %p)", subbuffer,
-      parent);
+  GST_CAT_LOG (GST_CAT_BUFFER, "new region copy %p of %p %" G_GSIZE_FORMAT
+      "-%" G_GSIZE_FORMAT, copy, buffer, offset, size);
 
-  /* set the right values in the child */
-  GST_BUFFER_DATA (subbuffer) = buffer->data + offset;
-  GST_BUFFER_SIZE (subbuffer) = size;
+  gst_buffer_copy_into (copy, buffer, flags, offset, size);
 
-  if ((offset == 0) && (size == GST_BUFFER_SIZE (buffer))) {
-    /* copy all the flags except IN_CAPS */
-    GST_BUFFER_FLAG_SET (subbuffer, GST_BUFFER_FLAGS (buffer));
-    GST_BUFFER_FLAG_UNSET (subbuffer, GST_BUFFER_FLAG_IN_CAPS);
-  } else {
-    /* copy only PREROLL & GAP flags */
-    GST_BUFFER_FLAG_SET (subbuffer, (GST_BUFFER_FLAGS (buffer) &
-            (GST_BUFFER_FLAG_PREROLL | GST_BUFFER_FLAG_GAP)));
-  }
+  return copy;
+}
 
-  /* we can copy the timestamp and offset if the new buffer starts at
-   * offset 0 */
-  if (offset == 0) {
-    GST_BUFFER_TIMESTAMP (subbuffer) = GST_BUFFER_TIMESTAMP (buffer);
-    GST_BUFFER_OFFSET (subbuffer) = GST_BUFFER_OFFSET (buffer);
-    complete = (buffer->size == size);
-  } else {
-    GST_BUFFER_TIMESTAMP (subbuffer) = GST_CLOCK_TIME_NONE;
-    GST_BUFFER_OFFSET (subbuffer) = GST_BUFFER_OFFSET_NONE;
-    complete = FALSE;
+static gboolean
+_gst_buffer_arr_is_span_fast (GstMemory ** mem[], gsize len[], guint n,
+    gsize * offset, GstMemory ** parent)
+{
+  GstMemory *mcur, *mprv;
+  gboolean have_offset = FALSE;
+  guint count, i;
+
+  mcur = mprv = NULL;
+  for (count = 0; count < n; count++) {
+    gsize offs, clen;
+    GstMemory **cmem;
+
+    cmem = mem[count];
+    clen = len[count];
+
+    for (i = 0; i < clen; i++) {
+      if (mcur)
+        mprv = mcur;
+      mcur = cmem[i];
+
+      if (mprv && mcur) {
+        /* check is memory is contiguous */
+        if (!gst_memory_is_span (mprv, mcur, &offs))
+          return FALSE;
+
+        if (!have_offset) {
+          if (offset)
+            *offset = offs;
+          if (parent)
+            *parent = mprv->parent;
+
+          have_offset = TRUE;
+        }
+      }
+    }
   }
+  return have_offset;
+}
 
-  if (complete) {
-    GstCaps *caps;
-
-    /* if we copied the complete buffer we can copy the duration,
-     * offset_end and caps as well */
-    GST_BUFFER_DURATION (subbuffer) = GST_BUFFER_DURATION (buffer);
-    GST_BUFFER_OFFSET_END (subbuffer) = GST_BUFFER_OFFSET_END (buffer);
-    if ((caps = GST_BUFFER_CAPS (buffer)))
-      gst_caps_ref (caps);
-    GST_BUFFER_CAPS (subbuffer) = caps;
+static GstMemory *
+_gst_buffer_arr_span (GstMemory ** mem[], gsize len[], guint n, gsize offset,
+    gsize size, gboolean writable)
+{
+  GstMemory *span, *parent = NULL;
+  gsize poffset = 0;
+
+  if (!writable
+      && _gst_buffer_arr_is_span_fast (mem, len, n, &poffset, &parent)) {
+    if (parent->flags & GST_MEMORY_FLAG_NO_SHARE)
+      span = gst_memory_copy (parent, offset + poffset, size);
+    else
+      span = gst_memory_share (parent, offset + poffset, size);
   } else {
-    GST_BUFFER_DURATION (subbuffer) = GST_CLOCK_TIME_NONE;
-    GST_BUFFER_OFFSET_END (subbuffer) = GST_BUFFER_OFFSET_NONE;
-    GST_BUFFER_CAPS (subbuffer) = NULL;
+    gsize count, left;
+    guint8 *dest, *ptr;
+
+    span = gst_memory_allocator_alloc (NULL, size, 0);
+    dest = gst_memory_map (span, NULL, NULL, GST_MAP_WRITE);
+
+    ptr = dest;
+    left = size;
+
+    for (count = 0; count < n; count++) {
+      gsize i, tocopy, clen, ssize;
+      guint8 *src;
+      GstMemory **cmem;
+
+      cmem = mem[count];
+      clen = len[count];
+
+      for (i = 0; i < clen && left > 0; i++) {
+        src = gst_memory_map (cmem[i], &ssize, NULL, GST_MAP_READ);
+        tocopy = MIN (ssize, left);
+        if (tocopy > offset) {
+          memcpy (ptr, src + offset, tocopy - offset);
+          left -= tocopy;
+          ptr += tocopy;
+          offset = 0;
+        } else {
+          offset -= tocopy;
+        }
+        gst_memory_unmap (cmem[i], src, ssize);
+      }
+    }
+    gst_memory_unmap (span, dest, size);
   }
-  return subbuffer;
+  return span;
 }
 
 /**
@@ -646,7 +1190,7 @@ gst_buffer_create_sub (GstBuffer * buffer, guint offset, guint size)
  * @buf2: the second #GstBuffer.
  *
  * Determines whether a gst_buffer_span() can be done without copying
- * the contents, that is, whether the data areas are contiguous sub-buffers of 
+ * the contents, that is, whether the data areas are contiguous sub-buffers of
  * the same buffer.
  *
  * MT safe.
@@ -656,14 +1200,20 @@ gst_buffer_create_sub (GstBuffer * buffer, guint offset, guint size)
 gboolean
 gst_buffer_is_span_fast (GstBuffer * buf1, GstBuffer * buf2)
 {
-  g_return_val_if_fail (buf1 != NULL && buf2 != NULL, FALSE);
+  GstMemory **mem[2];
+  gsize len[2];
+
+  g_return_val_if_fail (GST_IS_BUFFER (buf1), FALSE);
+  g_return_val_if_fail (GST_IS_BUFFER (buf2), FALSE);
   g_return_val_if_fail (buf1->mini_object.refcount > 0, FALSE);
   g_return_val_if_fail (buf2->mini_object.refcount > 0, FALSE);
 
-  /* it's only fast if we have subbuffers of the same parent */
-  return (GST_IS_SUBBUFFER (buf1) &&
-      GST_IS_SUBBUFFER (buf2) && (buf1->parent == buf2->parent)
-      && ((buf1->data + buf1->size) == buf2->data));
+  mem[0] = GST_BUFFER_MEM_ARRAY (buf1);
+  len[0] = GST_BUFFER_MEM_LEN (buf1);
+  mem[1] = GST_BUFFER_MEM_ARRAY (buf2);
+  len[1] = GST_BUFFER_MEM_LEN (buf2);
+
+  return _gst_buffer_arr_is_span_fast (mem, len, 2, NULL, NULL);
 }
 
 /**
@@ -672,7 +1222,7 @@ gst_buffer_is_span_fast (GstBuffer * buf1, GstBuffer * buf2)
  * @offset: the offset in the first buffer from where the new
  * buffer should start.
  * @buf2: the second source #GstBuffer to merge.
- * @len: the total length of the new buffer.
+ * @size: the total size of the new buffer.
  *
  * Creates a new buffer that consists of part of buf1 and buf2.
  * Logically, buf1 and buf2 are concatenated into a single larger
@@ -690,36 +1240,36 @@ gst_buffer_is_span_fast (GstBuffer * buf1, GstBuffer * buf2)
  *     buffers, or NULL if the arguments are invalid.
  */
 GstBuffer *
-gst_buffer_span (GstBuffer * buf1, guint32 offset, GstBuffer * buf2,
-    guint32 len)
+gst_buffer_span (GstBuffer * buf1, gsize offset, GstBuffer * buf2, gsize size)
 {
   GstBuffer *newbuf;
+  GstMemory *span;
+  GstMemory **mem[2];
+  gsize len[2], len1, len2;
 
-  g_return_val_if_fail (buf1 != NULL && buf2 != NULL, NULL);
+  g_return_val_if_fail (GST_IS_BUFFER (buf1), NULL);
+  g_return_val_if_fail (GST_IS_BUFFER (buf2), NULL);
   g_return_val_if_fail (buf1->mini_object.refcount > 0, NULL);
   g_return_val_if_fail (buf2->mini_object.refcount > 0, NULL);
-  g_return_val_if_fail (len > 0, NULL);
-  g_return_val_if_fail (len <= buf1->size + buf2->size - offset, NULL);
+  len1 = gst_buffer_get_size (buf1);
+  len2 = gst_buffer_get_size (buf2);
+  g_return_val_if_fail (len1 + len2 > offset, NULL);
+  if (size == -1)
+    size = len1 + len2 - offset;
+  else
+    g_return_val_if_fail (size <= len1 + len2 - offset, NULL);
 
-  /* if the two buffers have the same parent and are adjacent */
-  if (gst_buffer_is_span_fast (buf1, buf2)) {
-    GstBuffer *parent = buf1->parent;
+  mem[0] = GST_BUFFER_MEM_ARRAY (buf1);
+  len[0] = GST_BUFFER_MEM_LEN (buf1);
+  mem[1] = GST_BUFFER_MEM_ARRAY (buf2);
+  len[1] = GST_BUFFER_MEM_LEN (buf2);
 
-    /* we simply create a subbuffer of the common parent */
-    newbuf = gst_buffer_create_sub (parent,
-        buf1->data - parent->data + offset, len);
-  } else {
-    GST_CAT_DEBUG (GST_CAT_BUFFER,
-        "slow path taken while spanning buffers %p and %p", buf1, buf2);
-    /* otherwise we simply have to brute-force copy the buffers */
-    newbuf = gst_buffer_new_and_alloc (len);
+  span = _gst_buffer_arr_span (mem, len, 2, offset, size, FALSE);
 
-    /* copy the first buffer's data across */
-    memcpy (newbuf->data, buf1->data + offset, buf1->size - offset);
-    /* copy the second buffer's data across */
-    memcpy (newbuf->data + (buf1->size - offset), buf2->data,
-        len - (buf1->size - offset));
-  }
+  newbuf = gst_buffer_new ();
+  _memory_add (newbuf, -1, span);
+
+#if 0
   /* if the offset is 0, the new buffer has the same timestamp as buf1 */
   if (offset == 0) {
     GST_BUFFER_OFFSET (newbuf) = GST_BUFFER_OFFSET (buf1);
@@ -741,6 +1291,164 @@ gst_buffer_span (GstBuffer * buf1, guint32 offset, GstBuffer * buf2,
       }
     }
   }
+#endif
 
   return newbuf;
 }
+
+/**
+ * gst_buffer_get_meta:
+ * @buffer: a #GstBuffer
+ * @info: a #GstMetaInfo
+ *
+ * Get the metadata for the api in @info on buffer. When there is no such
+ * metadata, NULL is returned.
+ *
+ * Note that the result metadata might not be of the implementation @info.
+ *
+ * Returns: the metadata for the api in @info on @buffer.
+ */
+GstMeta *
+gst_buffer_get_meta (GstBuffer * buffer, const GstMetaInfo * info)
+{
+  GstMetaItem *item;
+  GstMeta *result = NULL;
+
+  g_return_val_if_fail (buffer != NULL, NULL);
+  g_return_val_if_fail (info != NULL, NULL);
+
+  /* find GstMeta of the requested API */
+  for (item = GST_BUFFER_META (buffer); item; item = item->next) {
+    GstMeta *meta = &item->meta;
+    if (meta->info->api == info->api) {
+      result = meta;
+      break;
+    }
+  }
+  return result;
+}
+
+/**
+ * gst_buffer_add_meta:
+ * @buffer: a #GstBuffer
+ * @info: a #GstMetaInfo
+ * @params: params for @info
+ *
+ * Add metadata for @info to @buffer using the parameters in @params.
+ *
+ * Returns: the metadata for the api in @info on @buffer.
+ */
+GstMeta *
+gst_buffer_add_meta (GstBuffer * buffer, const GstMetaInfo * info,
+    gpointer params)
+{
+  GstMetaItem *item;
+  GstMeta *result = NULL;
+  gsize size;
+
+  g_return_val_if_fail (buffer != NULL, NULL);
+  g_return_val_if_fail (info != NULL, NULL);
+
+  /* create a new slice */
+  GST_CAT_DEBUG (GST_CAT_BUFFER, "alloc metadata of size %" G_GSIZE_FORMAT,
+      info->size);
+
+  size = ITEM_SIZE (info);
+  item = g_slice_alloc (size);
+  result = &item->meta;
+  result->info = info;
+
+  /* call the init_func when needed */
+  if (info->init_func)
+    if (!info->init_func (result, params, buffer))
+      goto init_failed;
+
+  /* and add to the list of metadata */
+  item->next = GST_BUFFER_META (buffer);
+  GST_BUFFER_META (buffer) = item;
+
+  return result;
+
+init_failed:
+  {
+    g_slice_free1 (size, item);
+    return NULL;
+  }
+}
+
+/**
+ * gst_buffer_remove_meta:
+ * @buffer: a #GstBuffer
+ * @meta: a #GstMeta
+ *
+ * Remove the metadata for @meta on @buffer.
+ *
+ * Returns: %TRUE if the metadata existed and was removed, %FALSE if no such
+ * metadata was on @buffer.
+ */
+gboolean
+gst_buffer_remove_meta (GstBuffer * buffer, GstMeta * meta)
+{
+  GstMetaItem *walk, *prev;
+
+  g_return_val_if_fail (buffer != NULL, FALSE);
+  g_return_val_if_fail (meta != NULL, FALSE);
+
+  /* find the metadata and delete */
+  prev = GST_BUFFER_META (buffer);
+  for (walk = prev; walk; walk = walk->next) {
+    GstMeta *m = &walk->meta;
+    if (m == meta) {
+      const GstMetaInfo *info = meta->info;
+
+      /* remove from list */
+      if (GST_BUFFER_META (buffer) == walk)
+        GST_BUFFER_META (buffer) = walk->next;
+      else
+        prev->next = walk->next;
+      /* call free_func if any */
+      if (info->free_func)
+        info->free_func (m, buffer);
+
+      /* and free the slice */
+      g_slice_free1 (ITEM_SIZE (info), walk);
+      break;
+    }
+    prev = walk;
+  }
+  return walk != NULL;
+}
+
+/**
+ * gst_buffer_iterate_meta:
+ * @buffer: a #GstBuffer
+ * @state: an opaque state pointer
+ *
+ * Retrieve the next #GstMeta after @current. If @state points
+ * to %NULL, the first metadata is returned.
+ *
+ * @state will be updated with an opage state pointer 
+ *
+ * Returns: The next #GstMeta or %NULL when there are no more items.
+ */
+GstMeta *
+gst_buffer_iterate_meta (GstBuffer * buffer, gpointer * state)
+{
+  GstMetaItem **meta;
+
+  g_return_val_if_fail (buffer != NULL, NULL);
+  g_return_val_if_fail (state != NULL, NULL);
+
+  meta = (GstMetaItem **) state;
+  if (*meta == NULL)
+    /* state NULL, move to first item */
+    *meta = GST_BUFFER_META (buffer);
+  else
+    /* state !NULL, move to next item in list */
+    *meta = (*meta)->next;
+
+  if (*meta)
+    return &(*meta)->meta;
+  else
+    return NULL;
+}
index ad48315..48774e6 100644 (file)
 #include <gst/gstminiobject.h>
 #include <gst/gstclock.h>
 #include <gst/gstcaps.h>
+#include <gst/gstmemory.h>
 
 G_BEGIN_DECLS
 
+extern GType _gst_buffer_type;
+
 typedef struct _GstBuffer GstBuffer;
-typedef struct _GstBufferClass GstBufferClass;
+typedef struct _GstBufferPool GstBufferPool;
 
 /**
  * GST_BUFFER_TRACE_NAME:
@@ -40,13 +43,10 @@ typedef struct _GstBufferClass GstBufferClass;
  */
 #define GST_BUFFER_TRACE_NAME           "GstBuffer"
 
-#define GST_TYPE_BUFFER                         (gst_buffer_get_type())
-#define GST_IS_BUFFER(obj)                      (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_BUFFER))
-#define GST_IS_BUFFER_CLASS(klass)              (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_BUFFER))
-#define GST_BUFFER_GET_CLASS(obj)               (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_BUFFER, GstBufferClass))
-#define GST_BUFFER(obj)                         (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_BUFFER, GstBuffer))
-#define GST_BUFFER_CLASS(klass)                 (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_BUFFER, GstBufferClass))
+#define GST_TYPE_BUFFER                         (_gst_buffer_type)
+#define GST_IS_BUFFER(obj)                      (GST_IS_MINI_OBJECT_TYPE(obj, GST_TYPE_BUFFER))
 #define GST_BUFFER_CAST(obj)                    ((GstBuffer *)(obj))
+#define GST_BUFFER(obj)                         (GST_BUFFER_CAST(obj))
 
 /**
  * GST_BUFFER_FLAGS:
@@ -81,20 +81,6 @@ typedef struct _GstBufferClass GstBufferClass;
 #define GST_BUFFER_FLAG_UNSET(buf,flag)         GST_MINI_OBJECT_FLAG_UNSET (buf, flag)
 
 /**
- * GST_BUFFER_DATA:
- * @buf: a #GstBuffer.
- *
- * A pointer to the data element of this buffer.
- */
-#define GST_BUFFER_DATA(buf)                    (GST_BUFFER_CAST(buf)->data)
-/**
- * GST_BUFFER_SIZE:
- * @buf: a #GstBuffer.
- *
- * The size in bytes of the data in this buffer.
- */
-#define GST_BUFFER_SIZE(buf)                    (GST_BUFFER_CAST(buf)->size)
-/**
  * GST_BUFFER_TIMESTAMP:
  * @buf: a #GstBuffer.:
  *
@@ -112,13 +98,6 @@ typedef struct _GstBufferClass GstBufferClass;
  */
 #define GST_BUFFER_DURATION(buf)                (GST_BUFFER_CAST(buf)->duration)
 /**
- * GST_BUFFER_CAPS:
- * @buf: a #GstBuffer.
- *
- * The caps for this buffer.
- */
-#define GST_BUFFER_CAPS(buf)                    (GST_BUFFER_CAST(buf)->caps)
-/**
  * GST_BUFFER_OFFSET:
  * @buf: a #GstBuffer.
  *
@@ -132,28 +111,6 @@ typedef struct _GstBufferClass GstBufferClass;
  * The offset in the source file of the end of this buffer.
  */
 #define GST_BUFFER_OFFSET_END(buf)              (GST_BUFFER_CAST(buf)->offset_end)
-/**
- * GST_BUFFER_MALLOCDATA:
- * @buf: a #GstBuffer.
- *
- * A pointer to any data allocated for this buffer using g_malloc(). If this is
- * non-NULL, this memory will be freed at the end of the buffer's lifecycle
- * (i.e. when its refcount becomes zero).
- */
-#define GST_BUFFER_MALLOCDATA(buf)              (GST_BUFFER_CAST(buf)->malloc_data)
-/**
- * GST_BUFFER_FREE_FUNC:
- * @buf: a #GstBuffer.
- *
- * A pointer to a function that will be called on the buffer's malloc_data when
- * this buffer is finalized. Defaults to g_free().
- *
- * Note that the free function only affects the buffer's malloc_data; if the
- * buffer's malloc_data is %NULL, the function will not be called.
- *
- * Since: 0.10.22
- */
-#define GST_BUFFER_FREE_FUNC(buf)               (GST_BUFFER_CAST(buf)->free_func)
 
 /**
  * GST_BUFFER_OFFSET_NONE:
@@ -202,8 +159,6 @@ typedef struct _GstBufferClass GstBufferClass;
 
 /**
  * GstBufferFlag:
- * @GST_BUFFER_FLAG_READONLY: the buffer is read-only. This means the data of
- * the buffer should not be modified. The metadata might still be modified.
  * @GST_BUFFER_FLAG_PREROLL: the buffer is part of a preroll and should not be
  * displayed.
  * @GST_BUFFER_FLAG_DISCONT: the buffer marks a discontinuity in the stream.
@@ -223,8 +178,6 @@ typedef struct _GstBufferClass GstBufferClass;
  * A set of buffer flags used to describe properties of a #GstBuffer.
  */
 typedef enum {
-  GST_BUFFER_FLAG_READONLY   = GST_MINI_OBJECT_FLAG_READONLY,
-  GST_BUFFER_FLAG_MEDIA4     = GST_MINI_OBJECT_FLAG_RESERVED1,
   GST_BUFFER_FLAG_PREROLL    = (GST_MINI_OBJECT_FLAG_LAST << 0),
   GST_BUFFER_FLAG_DISCONT    = (GST_MINI_OBJECT_FLAG_LAST << 1),
   GST_BUFFER_FLAG_IN_CAPS    = (GST_MINI_OBJECT_FLAG_LAST << 2),
@@ -233,19 +186,18 @@ typedef enum {
   GST_BUFFER_FLAG_MEDIA1     = (GST_MINI_OBJECT_FLAG_LAST << 5),
   GST_BUFFER_FLAG_MEDIA2     = (GST_MINI_OBJECT_FLAG_LAST << 6),
   GST_BUFFER_FLAG_MEDIA3     = (GST_MINI_OBJECT_FLAG_LAST << 7),
-  GST_BUFFER_FLAG_LAST       = (GST_MINI_OBJECT_FLAG_LAST << 8)
+  GST_BUFFER_FLAG_MEDIA4     = (GST_MINI_OBJECT_FLAG_LAST << 8),
+  GST_BUFFER_FLAG_LAST       = (GST_MINI_OBJECT_FLAG_LAST << 16)
 } GstBufferFlag;
 
 /**
  * GstBuffer:
  * @mini_object: the parent structure
- * @data: pointer to the buffer data
- * @size: size of buffer data
+ * @pool: pointer to the pool owner of the buffer
  * @timestamp: timestamp of the buffer, can be #GST_CLOCK_TIME_NONE when the
  *     timestamp is not known or relevant.
  * @duration: duration in time of the buffer data, can be #GST_CLOCK_TIME_NONE
  *     when the duration is not known or relevant.
- * @caps: the #GstCaps describing the data format in this buffer
  * @offset: a media specific offset for the buffer data.
  *     For video frames, this is the frame number of this buffer.
  *     For audio samples, this is the offset of the first sample in this buffer.
@@ -253,11 +205,6 @@ typedef enum {
  *       byte in this buffer.
  * @offset_end: the last offset contained in this buffer. It has the same
  *     format as @offset.
- * @malloc_data: a pointer to the allocated memory associated with this buffer.
- *     When the buffer is freed, this data will freed with @free_func.
- * @free_func: a custom function that will be called with @malloc_data, defaults
- *     to g_free(). Since 0.10.22.
- * @parent: the parent buffer if this is a subbuffer. Since 0.10.26.
  *
  * The structure of a #GstBuffer. Use the associated macros to access the public
  * variables.
@@ -266,60 +213,60 @@ struct _GstBuffer {
   GstMiniObject          mini_object;
 
   /*< public >*/ /* with COW */
-  /* pointer to data and its size */
-  guint8                *data;
-  guint                  size;
+  GstBufferPool         *pool;
 
   /* timestamp */
   GstClockTime           timestamp;
   GstClockTime           duration;
 
-  /* the media type of this buffer */
-  GstCaps               *caps;
-
   /* media specific offset */
   guint64                offset;
   guint64                offset_end;
+};
 
-  guint8                *malloc_data;
-
-  /* ABI Added */
-  GFreeFunc              free_func;
-  GstBuffer             *parent;
+/* allocation */
+GstBuffer * gst_buffer_new                 (void);
+GstBuffer * gst_buffer_new_allocate        (const GstMemoryAllocator * allocator, gsize maxsize, gsize align);
 
-  /*< private >*/
-  gpointer _gst_reserved[GST_PADDING - 2];
-};
+/* memory blocks */
+guint       gst_buffer_n_memory            (GstBuffer *buffer);
+void        gst_buffer_take_memory         (GstBuffer *buffer, guint idx, GstMemory *mem);
+GstMemory * gst_buffer_peek_memory         (GstBuffer *buffer, guint idx, GstMapFlags flags);
+void        gst_buffer_remove_memory_range (GstBuffer *buffer, guint idx, guint length);
 
-struct _GstBufferClass {
-  GstMiniObjectClass    mini_object_class;
-};
+/**
+ * gst_buffer_remove_memory:
+ * @b: a #GstBuffer.
+ * @i: an index
+ *
+ * Remove the memory block in @b at @i.
+ */
+#define     gst_buffer_remove_memory(b,i)  gst_buffer_remove_memory_range ((b), (i), 1)
 
-GType       gst_buffer_get_type (void);
+void        gst_buffer_fill                (GstBuffer *buffer, gsize offset,
+                                            gconstpointer src, gsize size);
+void        gst_buffer_extract             (GstBuffer *buffer, gsize offset,
+                                            gpointer dest, gsize size);
+gint        gst_buffer_memcmp              (GstBuffer *buffer, gsize offset,
+                                            gconstpointer mem, gsize size);
 
-/* allocation */
-GstBuffer * gst_buffer_new               (void);
-GstBuffer * gst_buffer_new_and_alloc     (guint size);
-GstBuffer * gst_buffer_try_new_and_alloc (guint size);
+gsize       gst_buffer_get_size            (GstBuffer *buffer);
+void        gst_buffer_resize              (GstBuffer *buffer, gsize offset, gsize size);
 
 /**
- * gst_buffer_set_data:
- * @buf: a #GstBuffer
- * @data: The data (a #guint8 *) to set on the buffer.
- * @size: The size (in bytes, as a #guint) of the data being set.
- *
- * A convenience function to set the data and size on a buffer.
- * This will replace any existing data pointer set on this buffer, but will
- * not change GST_BUFFER_MALLOCDATA(), if any. Callers should ensure that
- * GST_BUFFER_MALLOCDATA() is non-NULL, or should free that and set it to NULL.
+ * gst_buffer_set_size:
+ * @b: a #GstBuffer.
+ * @s: a new size
  *
- * No checks are done on the data or size arguments passed.
+ * Set the size of @b to @s. This will remove or trim the memory blocks
+ * in the buffer.
  */
-#define         gst_buffer_set_data(buf, data, size)    \
-G_STMT_START {                                          \
-  GST_BUFFER_DATA (buf) = data;                         \
-  GST_BUFFER_SIZE (buf) = size;                         \
-} G_STMT_END
+#define     gst_buffer_set_size(b,s)       gst_buffer_resize ((b), 0, (s))
+
+/* getting memory */
+gpointer    gst_buffer_map                 (GstBuffer *buffer, gsize *size, gsize *maxsize,
+                                            GstMapFlags flags);
+gboolean    gst_buffer_unmap               (GstBuffer *buffer, gpointer data, gsize size);
 
 /* refcounting */
 /**
@@ -388,35 +335,46 @@ gst_buffer_copy (const GstBuffer * buf)
 
 /**
  * GstBufferCopyFlags:
+ * @GST_BUFFER_COPY_NONE: copy nothing
  * @GST_BUFFER_COPY_FLAGS: flag indicating that buffer flags should be copied
  * @GST_BUFFER_COPY_TIMESTAMPS: flag indicating that buffer timestamp, duration,
  * offset and offset_end should be copied
- * @GST_BUFFER_COPY_CAPS: flag indicating that buffer caps should be copied
- *
- * A set of flags that can be provided to the gst_buffer_copy_metadata()
- * function to specify which metadata fields should be copied.
+ * @GST_BUFFER_COPY_MEMORY: flag indicating that buffer memory should be copied
+ * and appended to already existing memory
+ * @GST_BUFFER_COPY_MERGE: flag indicating that buffer memory should be
+ * merged
  *
- * Since: 0.10.13
+ * A set of flags that can be provided to the gst_buffer_copy_into()
+ * function to specify which items should be copied.
  */
 typedef enum {
-  GST_BUFFER_COPY_FLAGS      = (1 << 0),
-  GST_BUFFER_COPY_TIMESTAMPS = (1 << 1),
-  GST_BUFFER_COPY_CAPS       = (1 << 2)
+  GST_BUFFER_COPY_NONE           = 0,
+  GST_BUFFER_COPY_FLAGS          = (1 << 0),
+  GST_BUFFER_COPY_TIMESTAMPS     = (1 << 1),
+  GST_BUFFER_COPY_MEMORY         = (1 << 2),
+  GST_BUFFER_COPY_MERGE          = (1 << 3)
 } GstBufferCopyFlags;
 
 /**
+ * GST_BUFFER_COPY_METADATA:
+ *
+ * Combination of all possible metadata fields that can be copied with
+ * gst_buffer_copy_into().
+ */
+#define GST_BUFFER_COPY_METADATA       (GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_TIMESTAMPS)
+
+/**
  * GST_BUFFER_COPY_ALL:
  *
  * Combination of all possible fields that can be copied with
- * gst_buffer_copy_metadata().
- *
- * Since: 0.10.13
+ * gst_buffer_copy_into().
  */
-#define GST_BUFFER_COPY_ALL (GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_TIMESTAMPS | GST_BUFFER_COPY_CAPS)
+#define GST_BUFFER_COPY_ALL  (GST_BUFFER_COPY_METADATA | GST_BUFFER_COPY_MEMORY)
 
-/* copies metadata into newly allocated buffer */
-void            gst_buffer_copy_metadata        (GstBuffer *dest, const GstBuffer *src,
-                                                 GstBufferCopyFlags flags);
+/* copies memory or metadata into newly allocated buffer */
+void            gst_buffer_copy_into            (GstBuffer *dest, GstBuffer *src,
+                                                 GstBufferCopyFlags flags,
+                                                 gsize offset, gsize size);
 
 /**
  * gst_buffer_is_writable:
@@ -441,11 +399,6 @@ void            gst_buffer_copy_metadata        (GstBuffer *dest, const GstBuffe
  */
 #define         gst_buffer_make_writable(buf)   GST_BUFFER_CAST (gst_mini_object_make_writable (GST_MINI_OBJECT_CAST (buf)))
 
-/* Ensure that the metadata of the buffer is writable, even if the buffer data
- * isn't */
-gboolean        gst_buffer_is_metadata_writable (GstBuffer *buf);
-GstBuffer*      gst_buffer_make_metadata_writable (GstBuffer *buf);
-
 /**
  * gst_buffer_replace:
  * @obuf: (inout) (transfer full): pointer to a pointer to a #GstBuffer to be
@@ -467,15 +420,23 @@ G_STMT_START {                                                                \
       GST_MINI_OBJECT_CAST (nbuf));                       \
 } G_STMT_END
 
-GstCaps*        gst_buffer_get_caps             (GstBuffer *buffer);
-void            gst_buffer_set_caps             (GstBuffer *buffer, GstCaps *caps);
-
-/* creating a subbuffer */
-GstBuffer*      gst_buffer_create_sub           (GstBuffer *parent, guint offset, guint size);
+/* creating a region */
+GstBuffer*      gst_buffer_copy_region          (GstBuffer *parent, GstBufferCopyFlags flags,
+                                                 gsize offset, gsize size);
 
 /* span, two buffers, intelligently */
 gboolean        gst_buffer_is_span_fast         (GstBuffer *buf1, GstBuffer *buf2);
-GstBuffer*      gst_buffer_span                 (GstBuffer *buf1, guint32 offset, GstBuffer *buf2, guint32 len);
+GstBuffer*      gst_buffer_span                 (GstBuffer *buf1, gsize offset, GstBuffer *buf2, gsize size);
+
+/* metadata */
+#include <gst/gstmeta.h>
+
+GstMeta *       gst_buffer_get_meta             (GstBuffer *buffer, const GstMetaInfo *info);
+GstMeta *       gst_buffer_add_meta             (GstBuffer *buffer, const GstMetaInfo *info,
+                                                 gpointer params);
+gboolean        gst_buffer_remove_meta          (GstBuffer *buffer, GstMeta *meta);
+
+GstMeta *       gst_buffer_iterate_meta         (GstBuffer *buffer, gpointer *state);
 
 /**
  * gst_value_set_buffer:
@@ -484,7 +445,7 @@ GstBuffer*      gst_buffer_span                 (GstBuffer *buf1, guint32 offset
  *
  * Sets @b as the value of @v.  Caller retains reference to buffer.
  */
-#define         gst_value_set_buffer(v,b)       gst_value_set_mini_object(v, GST_MINI_OBJECT_CAST(b))
+#define         gst_value_set_buffer(v,b)       g_value_set_boxed((v),(b))
 /**
  * gst_value_take_buffer:
  * @v: a #GValue to receive the data
@@ -492,7 +453,7 @@ GstBuffer*      gst_buffer_span                 (GstBuffer *buf1, guint32 offset
  *
  * Sets @b as the value of @v.  Caller gives away reference to buffer.
  */
-#define         gst_value_take_buffer(v,b)      gst_value_take_mini_object(v, GST_MINI_OBJECT_CAST(b))
+#define         gst_value_take_buffer(v,b)      g_value_take_boxed(v,(b))
 /**
  * gst_value_get_buffer:
  * @v: a #GValue to query
@@ -503,7 +464,7 @@ GstBuffer*      gst_buffer_span                 (GstBuffer *buf1, guint32 offset
  *
  * Returns: (transfer none): buffer
  */
-#define         gst_value_get_buffer(v)         GST_BUFFER_CAST (gst_value_get_mini_object(v))
+#define         gst_value_get_buffer(v)         GST_BUFFER_CAST (g_value_get_boxed(v))
 
 G_END_DECLS
 
index 721c4c3..42690f9 100644 (file)
 
 /**
  * SECTION:gstbufferlist
- * @short_description: Grouped scatter data buffer type for data-passing
+ * @short_description: Lists of buffers for data-passing
  * @see_also: #GstPad, #GstMiniObject
  *
- * Buffer lists are units of grouped scatter/gather data transfer in
- * GStreamer.
+ * Buffer lists are an object containing a list of buffers.
  *
  * Buffer lists are created with gst_buffer_list_new() and filled with data
- * using a #GstBufferListIterator. The iterator has no current buffer; its
- * cursor position lies between buffers, immediately before the buffer that
- * would be returned by gst_buffer_list_iterator_next(). After iterating to the
- * end of a group the iterator must be advanced to the next group by a call to
- * gst_buffer_list_iterator_next_group() before any further calls to
- * gst_buffer_list_iterator_next() can return buffers again. The cursor position
- * of a newly created iterator lies before the first group; a call to
- * gst_buffer_list_iterator_next_group() is necessary before calls to
- * gst_buffer_list_iterator_next() can return buffers.
+ * using a gst_buffer_list_take().
  *
- * <informalfigure>
- *   <programlisting>
- *      +--- group0 ----------------------+--- group1 ------------+
- *      |   buffer0   buffer1   buffer2   |   buffer3   buffer4   |
- *    ^   ^         ^         ^         ^   ^         ^         ^
- *    Iterator positions between buffers
- *   </programlisting>
- * </informalfigure>
- *
- * The gst_buffer_list_iterator_remove(), gst_buffer_list_iterator_steal(),
- * gst_buffer_list_iterator_take() and gst_buffer_list_iterator_do() functions
- * are not defined in terms of the cursor position; they operate on the last
- * element returned from gst_buffer_list_iterator_next().
- *
- * The basic use pattern of creating a buffer list with an iterator is as
- * follows:
- *
- * <example>
- * <title>Creating a buffer list</title>
- *   <programlisting>
- *    GstBufferList *list;
- *    GstBufferListIterator *it;
- *
- *    list = gst_buffer_list_new ();
- *    it = gst_buffer_list_iterate (list);
- *    gst_buffer_list_iterator_add_group (it);
- *    gst_buffer_list_iterator_add (it, header1);
- *    gst_buffer_list_iterator_add (it, data1);
- *    gst_buffer_list_iterator_add_group (it);
- *    gst_buffer_list_iterator_add (it, header2);
- *    gst_buffer_list_iterator_add (it, data2);
- *    gst_buffer_list_iterator_add_group (it);
- *    gst_buffer_list_iterator_add (it, header3);
- *    gst_buffer_list_iterator_add (it, data3);
- *    ...
- *    gst_buffer_list_iterator_free (it);
- *   </programlisting>
- * </example>
- *
- * The basic use pattern of iterating over a buffer list is as follows:
- *
- * <example>
- * <title>Iterating a buffer list</title>
- *   <programlisting>
- *    GstBufferListIterator *it;
- *
- *    it = gst_buffer_list_iterate (list);
- *    while (gst_buffer_list_iterator_next_group (it)) {
- *      while ((buffer = gst_buffer_list_iterator_next (it)) != NULL) {
- *        do_something_with_buffer (buffer);
- *      }
- *    }
- *    gst_buffer_list_iterator_free (it);
- *   </programlisting>
- * </example>
- *
- * The basic use pattern of modifying a buffer in a list is as follows:
- *
- * <example>
- * <title>Modifying the data of the first buffer in a list</title>
- *   <programlisting>
- *    GstBufferListIterator *it;
- *
- *    list = gst_buffer_list_make_writable (list);
- *    it = gst_buffer_list_iterate (list);
- *    if (gst_buffer_list_iterator_next_group (it)) {
- *      GstBuffer *buf
- *
- *      buf = gst_buffer_list_iterator_next (it);
- *      if (buf != NULL) {
- *        buf = gst_buffer_list_iterator_do (it,
- *            (GstBufferListDoFunction) gst_mini_object_make_writable, NULL);
- *        modify_data (GST_BUFFER_DATA (buf));
- *      }
- *    }
- *    gst_buffer_list_iterator_free (it);
- *   </programlisting>
- * </example>
- *
- * Since: 0.10.24
  */
 #include "gst_private.h"
 
 
 #define GST_CAT_DEFAULT GST_CAT_BUFFER_LIST
 
-#define GROUP_START NULL
-static gconstpointer STOLEN = "";
-
 /**
  * GstBufferList:
  *
@@ -141,107 +49,93 @@ struct _GstBufferList
 {
   GstMiniObject mini_object;
 
-  GQueue *buffers;
-};
-
-struct _GstBufferListClass
-{
-  GstMiniObjectClass mini_object_class;
-};
-
-/**
- * GstBufferListIterator:
- *
- * Opaque iterator for a #GstBufferList.
- *
- * Since: 0.10.24
- */
-struct _GstBufferListIterator
-{
-  GstBufferList *list;
-  GList *next;
-  GList *last_returned;
+  GArray *array;
 };
 
-static GType _gst_buffer_list_type = 0;
-
-G_DEFINE_TYPE (GstBufferList, gst_buffer_list, GST_TYPE_MINI_OBJECT);
+GType _gst_buffer_list_type = 0;
 
 void
 _gst_buffer_list_initialize (void)
 {
-  GType type = gst_buffer_list_get_type ();
+  if (G_LIKELY (_gst_buffer_list_type == 0)) {
+    _gst_buffer_list_type = gst_mini_object_register ("GstBufferList");
+  }
+}
+
+static GstBufferList *
+_gst_buffer_list_copy (GstBufferList * list)
+{
+  GstBufferList *copy;
+  guint i, len;
+
+  len = list->array->len;
+  copy = gst_buffer_list_sized_new (len);
 
-  g_type_class_ref (type);
-  _gst_buffer_list_type = type;
+  /* add and ref all buffers in the array */
+  for (i = 0; i < len; i++) {
+    GstBuffer *buf = g_array_index (list->array, GstBuffer *, i);
+    buf = gst_buffer_ref (buf);
+    g_array_append_val (copy->array, buf);
+  }
+  return copy;
 }
 
 static void
-gst_buffer_list_init (GstBufferList * list)
+_gst_buffer_list_free (GstBufferList * list)
 {
-  list->buffers = g_queue_new ();
+  guint i, len;
+  GST_LOG ("free %p", list);
 
-  GST_LOG ("init %p", list);
+  /* unrefs all buffers too */
+  len = list->array->len;
+  for (i = 0; i < len; i++)
+    gst_buffer_unref (g_array_index (list->array, GstBuffer *, i));
+  g_array_free (list->array, TRUE);
+
+  g_slice_free1 (GST_MINI_OBJECT_SIZE (list), list);
 }
 
 static void
-gst_buffer_list_finalize (GstBufferList * list)
+gst_buffer_list_init (GstBufferList * list, gsize size, guint asize)
 {
-  GList *tmp;
+  gst_mini_object_init (GST_MINI_OBJECT_CAST (list), _gst_buffer_list_type,
+      size);
 
-  g_return_if_fail (list != NULL);
+  list->mini_object.copy = (GstMiniObjectCopyFunction) _gst_buffer_list_copy;
+  list->mini_object.free = (GstMiniObjectFreeFunction) _gst_buffer_list_free;
 
-  GST_LOG ("finalize %p", list);
+  list->array = g_array_sized_new (FALSE, FALSE, sizeof (GstBuffer *), asize);
 
-  tmp = list->buffers->head;
-  while (tmp) {
-    if (tmp->data != GROUP_START && tmp->data != STOLEN) {
-      gst_buffer_unref (GST_BUFFER_CAST (tmp->data));
-    }
-    tmp = tmp->next;
-  }
-  g_queue_free (list->buffers);
-
-/* Not chaining up because GstMiniObject::finalize() does nothing
-  GST_MINI_OBJECT_CLASS (gst_buffer_list_parent_class)->finalize
-      (GST_MINI_OBJECT_CAST (list));*/
+  GST_LOG ("init %p", list);
 }
 
-static GstBufferList *
-_gst_buffer_list_copy (GstBufferList * list)
+/**
+ * gst_buffer_list_sized_new:
+ * @size: an initial reserved size
+ *
+ * Creates a new, empty #GstBufferList. The caller is responsible for unreffing
+ * the returned #GstBufferList. The list will have @size space preallocated so
+ * that memory reallocations can be avoided.
+ *
+ * Free-function: gst_buffer_list_unref
+ *
+ * Returns: (transfer full): the new #GstBufferList. gst_buffer_list_unref()
+ *     after usage.
+ *
+ * Since: 0.10.24
+ */
+GstBufferList *
+gst_buffer_list_sized_new (guint size)
 {
-  GstBufferList *list_copy;
-  GQueue *buffers_copy;
-  GList *tmp;
-
-  g_return_val_if_fail (list != NULL, NULL);
-
-  /* shallow copy of list and pointers */
-  buffers_copy = g_queue_copy (list->buffers);
+  GstBufferList *list;
 
-  /* ref all buffers in the list */
-  tmp = list->buffers->head;
-  while (tmp) {
-    if (tmp->data != GROUP_START && tmp->data != STOLEN) {
-      tmp->data = gst_buffer_ref (GST_BUFFER_CAST (tmp->data));
-    }
-    tmp = g_list_next (tmp);
-  }
+  list = g_slice_new0 (GstBufferList);
 
-  list_copy = gst_buffer_list_new ();
-  g_queue_free (list_copy->buffers);
-  list_copy->buffers = buffers_copy;
+  GST_LOG ("new %p", list);
 
-  return list_copy;
-}
+  gst_buffer_list_init (list, sizeof (GstBufferList), size);
 
-static void
-gst_buffer_list_class_init (GstBufferListClass * list_class)
-{
-  list_class->mini_object_class.copy =
-      (GstMiniObjectCopyFunction) _gst_buffer_list_copy;
-  list_class->mini_object_class.finalize =
-      (GstMiniObjectFinalizeFunction) gst_buffer_list_finalize;
+  return list;
 }
 
 /**
@@ -260,43 +154,25 @@ gst_buffer_list_class_init (GstBufferListClass * list_class)
 GstBufferList *
 gst_buffer_list_new (void)
 {
-  GstBufferList *list;
-
-  list = (GstBufferList *) gst_mini_object_new (_gst_buffer_list_type);
-
-  GST_LOG ("new %p", list);
-
-  return list;
+  return gst_buffer_list_sized_new (8);
 }
 
 /**
- * gst_buffer_list_n_groups:
+ * gst_buffer_list_len:
  * @list: a #GstBufferList
  *
- * Returns the number of groups in @list.
+ * Returns the number of buffers in @list.
  *
- * Returns: the number of groups in the buffer list
+ * Returns: the number of buffers in the buffer list
  *
  * Since: 0.10.24
  */
 guint
-gst_buffer_list_n_groups (GstBufferList * list)
+gst_buffer_list_len (GstBufferList * list)
 {
-  GList *tmp;
-  guint n;
+  g_return_val_if_fail (GST_IS_BUFFER_LIST (list), 0);
 
-  g_return_val_if_fail (list != NULL, 0);
-
-  tmp = list->buffers->head;
-  n = 0;
-  while (tmp) {
-    if (tmp->data == GROUP_START) {
-      n++;
-    }
-    tmp = g_list_next (tmp);
-  }
-
-  return n;
+  return list->array->len;
 }
 
 /**
@@ -317,70 +193,43 @@ void
 gst_buffer_list_foreach (GstBufferList * list, GstBufferListFunc func,
     gpointer user_data)
 {
-  GList *tmp, *next;
-  guint group, idx;
-  GstBufferListItem res;
+  guint i, len;
 
-  g_return_if_fail (list != NULL);
+  g_return_if_fail (GST_IS_BUFFER_LIST (list));
   g_return_if_fail (func != NULL);
 
-  next = list->buffers->head;
-  group = idx = 0;
-  while (next) {
-    GstBuffer *buffer;
-
-    tmp = next;
-    next = g_list_next (tmp);
-
-    buffer = tmp->data;
-
-    if (buffer == GROUP_START) {
-      group++;
-      idx = 0;
-      continue;
-    } else if (buffer == STOLEN)
-      continue;
-    else
-      idx++;
-
-    /* need to decrement the indices */
-    res = func (&buffer, group - 1, idx - 1, user_data);
-
-    if (G_UNLIKELY (buffer != tmp->data)) {
-      /* the function changed the buffer */
-      if (buffer == NULL) {
-        /* we were asked to remove the item */
-        g_queue_delete_link (list->buffers, tmp);
-        idx--;
+  len = list->array->len;
+  for (i = 0; i < len;) {
+    GstBuffer *buf, *buf_ret;
+    gboolean ret;
+
+    buf = buf_ret = g_array_index (list->array, GstBuffer *, i);
+    ret = func (&buf_ret, i, user_data);
+
+    /* Check if the function changed the buffer */
+    if (buf != buf_ret) {
+      if (buf_ret == NULL) {
+        g_array_remove_index (list->array, i);
       } else {
-        /* change the buffer */
-        tmp->data = buffer;
+        g_array_index (list->array, GstBuffer *, i) = buf_ret;
       }
     }
 
-    switch (res) {
-      case GST_BUFFER_LIST_CONTINUE:
-        break;
-      case GST_BUFFER_LIST_SKIP_GROUP:
-        while (next && next->data != GROUP_START)
-          next = g_list_next (next);
-        break;
-      case GST_BUFFER_LIST_END:
-        return;
-    }
+    if (!ret)
+      break;
+
+    /* If the buffer was not removed by func go to the next buffer */
+    if (buf_ret != NULL)
+      i++;
   }
 }
 
 /**
  * gst_buffer_list_get:
  * @list: a #GstBufferList
- * @group: the group
- * @idx: the index in @group
+ * @idx: the index
  *
- * Get the buffer at @idx in @group.
- *
- * Note that this function is not efficient for iterating over the entire list.
- * Use an iterator or gst_buffer_list_foreach() instead.
+ * Get the buffer at @idx.
  *
  * Returns: (transfer none): the buffer at @idx in @group or NULL when there
  *     is no buffer. The buffer remains valid as long as @list is valid.
@@ -388,528 +237,48 @@ gst_buffer_list_foreach (GstBufferList * list, GstBufferListFunc func,
  * Since: 0.10.24
  */
 GstBuffer *
-gst_buffer_list_get (GstBufferList * list, guint group, guint idx)
-{
-  GList *tmp;
-  guint cgroup, cidx;
-
-  g_return_val_if_fail (list != NULL, NULL);
-
-  tmp = list->buffers->head;
-  cgroup = 0;
-  while (tmp) {
-    if (tmp->data == GROUP_START) {
-      if (cgroup == group) {
-        /* we found the group */
-        tmp = g_list_next (tmp);
-        cidx = 0;
-        while (tmp && tmp->data != GROUP_START) {
-          if (tmp->data != STOLEN) {
-            if (cidx == idx)
-              return GST_BUFFER_CAST (tmp->data);
-            else
-              cidx++;
-          }
-          tmp = g_list_next (tmp);
-        }
-        break;
-      } else {
-        cgroup++;
-        if (cgroup > group)
-          break;
-      }
-    }
-    tmp = g_list_next (tmp);
-  }
-  return NULL;
-}
-
-static GstBufferListIterator *
-gst_buffer_list_iterator_copy (const GstBufferListIterator * it)
+gst_buffer_list_get (GstBufferList * list, guint idx)
 {
-  GstBufferListIterator *ret;
-
-  ret = g_slice_new (GstBufferListIterator);
-  ret->list = it->list;
-  ret->next = it->next;
-  ret->last_returned = it->last_returned;
-
-  return ret;
-}
+  GstBuffer *buf;
 
-GType
-gst_buffer_list_iterator_get_type (void)
-{
-  static GType type = 0;
+  g_return_val_if_fail (GST_IS_BUFFER_LIST (list), NULL);
+  g_return_val_if_fail (idx < list->array->len, NULL);
 
-  if (G_UNLIKELY (type == 0)) {
-    type = g_boxed_type_register_static ("GstBufferListIterator",
-        (GBoxedCopyFunc) gst_buffer_list_iterator_copy,
-        (GBoxedFreeFunc) gst_buffer_list_iterator_free);
-  }
+  buf = g_array_index (list->array, GstBuffer *, idx);
 
-  return type;
+  return buf;
 }
 
 /**
- * gst_buffer_list_iterate:
+ * gst_buffer_list_insert:
  * @list: a #GstBufferList
+ * @idx: the index
+ * @buffer: a #GstBuffer
  *
- * Iterate the buffers in @list. The owner of the iterator must also be the
- * owner of a reference to @list while the returned iterator is in use.
- *
- * Free-function: gst_buffer_list_iterator_free
- *
- * Returns: (transfer full): a new #GstBufferListIterator of the buffers in
- *     @list. gst_buffer_list_iterator_free() after usage
- *
- * Since: 0.10.24
- */
-GstBufferListIterator *
-gst_buffer_list_iterate (GstBufferList * list)
-{
-  GstBufferListIterator *it;
-
-  g_return_val_if_fail (list != NULL, NULL);
-
-  it = g_slice_new (GstBufferListIterator);
-  it->list = list;
-  it->next = list->buffers->head;
-  it->last_returned = NULL;
-
-  return it;
-}
-
-/**
- * gst_buffer_list_iterator_free:
- * @it: (transfer full): the #GstBufferListIterator to free
- *
- * Free the iterator.
- *
- * Since: 0.10.24
- */
-void
-gst_buffer_list_iterator_free (GstBufferListIterator * it)
-{
-  g_return_if_fail (it != NULL);
-
-  g_slice_free (GstBufferListIterator, it);
-}
-
-/**
- * gst_buffer_list_iterator_n_buffers:
- * @it: a #GstBufferListIterator
- *
- * Returns the number of buffers left to iterate in the current group. I.e. the
- * number of calls that can be made to gst_buffer_list_iterator_next() before
- * it returns NULL.
- *
- * This function will not move the implicit cursor or in any other way affect
- * the state of the iterator @it.
- *
- * Returns: the number of buffers left to iterate in the current group
+ * Insert @buffer at @idx in @list. Other buffers are moved to make room for
+ * this new buffer.
  *
- * Since: 0.10.24
- */
-guint
-gst_buffer_list_iterator_n_buffers (const GstBufferListIterator * it)
-{
-  GList *tmp;
-  guint n;
-
-  g_return_val_if_fail (it != NULL, 0);
-
-  tmp = it->next;
-  n = 0;
-  while (tmp && tmp->data != GROUP_START) {
-    if (tmp->data != STOLEN) {
-      n++;
-    }
-    tmp = g_list_next (tmp);
-  }
-
-  return n;
-}
-
-/**
- * gst_buffer_list_iterator_add:
- * @it: a #GstBufferListIterator
- * @buffer: (transfer full): a #GstBuffer
- *
- * Inserts @buffer into the #GstBufferList iterated with @it. The buffer is
- * inserted into the current group, immediately before the buffer that would be
- * returned by gst_buffer_list_iterator_next(). The buffer is inserted before
- * the implicit cursor, a subsequent call to gst_buffer_list_iterator_next()
- * will return the buffer after the inserted buffer, if any.
- *
- * This function takes ownership of @buffer.
- *
- * Since: 0.10.24
+ * A -1 value for @idx will append the buffer at the end.
  */
 void
-gst_buffer_list_iterator_add (GstBufferListIterator * it, GstBuffer * buffer)
+gst_buffer_list_insert (GstBufferList * list, guint idx, GstBuffer * buffer)
 {
-  g_return_if_fail (it != NULL);
+  g_return_if_fail (GST_IS_BUFFER_LIST (list));
   g_return_if_fail (buffer != NULL);
 
-  /* adding before the first group start is not allowed */
-  g_return_if_fail (it->next != it->list->buffers->head);
-
-  /* cheap insert into the GQueue */
-  if (it->next != NULL) {
-    g_queue_insert_before (it->list->buffers, it->next, buffer);
-  } else {
-    g_queue_push_tail (it->list->buffers, buffer);
+  if (idx == -1)
+    g_array_append_val (list->array, buffer);
+  else {
+    g_return_if_fail (idx < list->array->len);
+    g_array_insert_val (list->array, idx, buffer);
   }
 }
 
-/**
- * gst_buffer_list_iterator_add_list:
- * @it: a #GstBufferListIterator
- * @list: (transfer full) (element-type Gst.Buffer): a #GList of buffers
- *
- * Inserts @list of buffers into the #GstBufferList iterated with @it. The list is
- * inserted into the current group, immediately before the buffer that would be
- * returned by gst_buffer_list_iterator_next(). The list is inserted before
- * the implicit cursor, a subsequent call to gst_buffer_list_iterator_next()
- * will return the buffer after the last buffer of the inserted list, if any.
- *
- * This function takes ownership of @list and all its buffers.
- *
- * Since: 0.10.31
- */
-void
-gst_buffer_list_iterator_add_list (GstBufferListIterator * it, GList * list)
-{
-  GList *last;
-  guint len;
-
-  g_return_if_fail (it != NULL);
-  g_return_if_fail (it->next != it->list->buffers->head);
-
-  if (list == NULL)
-    return;
-
-  last = list;
-  len = 1;
-  while (last->next) {
-    last = last->next;
-    len++;
-  }
-
-  if (it->next) {
-    last->next = it->next;
-    list->prev = it->next->prev;
-    it->next->prev = last;
-    if (list->prev)
-      list->prev->next = list;
-  } else {
-    it->list->buffers->tail->next = list;
-    list->prev = it->list->buffers->tail;
-    it->list->buffers->tail = last;
-  }
-  it->list->buffers->length += len;
-}
-
-/**
- * gst_buffer_list_iterator_add_group:
- * @it: a #GstBufferListIterator
- *
- * Inserts a new, empty group into the #GstBufferList iterated with @it. The
- * group is inserted immediately before the group that would be returned by
- * gst_buffer_list_iterator_next_group(). A subsequent call to
- * gst_buffer_list_iterator_next_group() will advance the iterator to the group
- * after the inserted group, if any.
- *
- * Since: 0.10.24
- */
 void
-gst_buffer_list_iterator_add_group (GstBufferListIterator * it)
-{
-  g_return_if_fail (it != NULL);
-
-  /* advance iterator to next group start */
-  while (it->next != NULL && it->next->data != GROUP_START) {
-    it->next = g_list_next (it->next);
-  }
-
-  /* cheap insert of a group start into the GQueue */
-  if (it->next != NULL) {
-    g_queue_insert_before (it->list->buffers, it->next, GROUP_START);
-  } else {
-    g_queue_push_tail (it->list->buffers, GROUP_START);
-  }
-}
-
-/**
- * gst_buffer_list_iterator_next:
- * @it: a #GstBufferListIterator
- *
- * Returns the next buffer in the list iterated with @it. If the iterator is at
- * the end of a group, NULL will be returned. This function may be called
- * repeatedly to iterate through the current group.
- *
- * The caller will not get a new ref to the returned #GstBuffer and must not
- * unref it.
- *
- * Returns: (transfer none): the next buffer in the current group of the
- *     buffer list, or NULL
- *
- * Since: 0.10.24
- */
-GstBuffer *
-gst_buffer_list_iterator_next (GstBufferListIterator * it)
-{
-  GstBuffer *buffer;
-
-  g_return_val_if_fail (it != NULL, NULL);
-
-  while (it->next != NULL && it->next->data != GROUP_START &&
-      it->next->data == STOLEN) {
-    it->next = g_list_next (it->next);
-  }
-
-  if (it->next == NULL || it->next->data == GROUP_START) {
-    goto no_buffer;
-  }
-
-  buffer = GST_BUFFER_CAST (it->next->data);
-
-  it->last_returned = it->next;
-  it->next = g_list_next (it->next);
-
-  return buffer;
-
-no_buffer:
-  {
-    it->last_returned = NULL;
-    return NULL;
-  }
-}
-
-/**
- * gst_buffer_list_iterator_next_group:
- * @it: a #GstBufferListIterator
- *
- * Advance the iterator @it to the first buffer in the next group. If the
- * iterator is at the last group, FALSE will be returned. This function may be
- * called repeatedly to iterate through the groups in a buffer list.
- *
- * Returns: TRUE if the iterator could be advanced to the next group, FALSE if
- * the iterator was already at the last group
- *
- * Since: 0.10.24
- */
-gboolean
-gst_buffer_list_iterator_next_group (GstBufferListIterator * it)
+gst_buffer_list_remove (GstBufferList * list, guint idx, guint length)
 {
-  g_return_val_if_fail (it != NULL, FALSE);
-
-  /* advance iterator to next group start */
-  while (it->next != NULL && it->next->data != GROUP_START) {
-    it->next = g_list_next (it->next);
-  }
+  g_return_if_fail (GST_IS_BUFFER_LIST (list));
+  g_return_if_fail (idx < list->array->len);
 
-  if (it->next) {
-    /* move one step beyond the group start */
-    it->next = g_list_next (it->next);
-  }
-
-  it->last_returned = NULL;
-
-  return (it->next != NULL);
-}
-
-/**
- * gst_buffer_list_iterator_remove:
- * @it: a #GstBufferListIterator
- *
- * Removes the last buffer returned by gst_buffer_list_iterator_next() from
- * the #GstBufferList iterated with @it. gst_buffer_list_iterator_next() must
- * have been called on @it before this function is called. This function can
- * only be called once per call to gst_buffer_list_iterator_next().
- *
- * The removed buffer is unreffed.
- *
- * Since: 0.10.24
- */
-void
-gst_buffer_list_iterator_remove (GstBufferListIterator * it)
-{
-  g_return_if_fail (it != NULL);
-  g_return_if_fail (it->last_returned != NULL);
-  g_assert (it->last_returned->data != GROUP_START);
-
-  if (it->last_returned->data != STOLEN) {
-    gst_buffer_unref (it->last_returned->data);
-  }
-  g_queue_delete_link (it->list->buffers, it->last_returned);
-  it->last_returned = NULL;
-}
-
-/**
- * gst_buffer_list_iterator_take:
- * @it: a #GstBufferListIterator
- * @buffer: (transfer full): a #GstBuffer
- *
- * Replaces the last buffer returned by gst_buffer_list_iterator_next() with
- * @buffer in the #GstBufferList iterated with @it and takes ownership of
- * @buffer. gst_buffer_list_iterator_next() must have been called on @it before
- * this function is called. gst_buffer_list_iterator_remove() must not have been
- * called since the last call to gst_buffer_list_iterator_next().
- *
- * This function unrefs the replaced buffer if it has not been stolen with
- * gst_buffer_list_iterator_steal() and takes ownership of @buffer (i.e. the
- * refcount of @buffer is not increased).
- *
- * FIXME 0.11: this conditional taking-ownership is not good for bindings
- *
- * Since: 0.10.24
- */
-void
-gst_buffer_list_iterator_take (GstBufferListIterator * it, GstBuffer * buffer)
-{
-  g_return_if_fail (it != NULL);
-  g_return_if_fail (it->last_returned != NULL);
-  g_return_if_fail (buffer != NULL);
-  g_assert (it->last_returned->data != GROUP_START);
-
-  if (it->last_returned->data != STOLEN) {
-    gst_buffer_unref (it->last_returned->data);
-  }
-  it->last_returned->data = buffer;
-}
-
-/**
- * gst_buffer_list_iterator_steal:
- * @it: a #GstBufferListIterator
- *
- * Returns the last buffer returned by gst_buffer_list_iterator_next() without
- * modifying the refcount of the buffer.
- *
- * Returns: (transfer none): the last buffer returned by
- *     gst_buffer_list_iterator_next()
- *
- * Since: 0.10.24
- */
-GstBuffer *
-gst_buffer_list_iterator_steal (GstBufferListIterator * it)
-{
-  GstBuffer *buffer;
-
-  g_return_val_if_fail (it != NULL, NULL);
-  g_return_val_if_fail (it->last_returned != NULL, NULL);
-  g_return_val_if_fail (it->last_returned->data != STOLEN, NULL);
-  g_assert (it->last_returned->data != GROUP_START);
-
-  buffer = it->last_returned->data;
-  it->last_returned->data = (gpointer) STOLEN;
-
-  return buffer;
-}
-
-/**
- * gst_buffer_list_iterator_do:
- * @it: a #GstBufferListIterator
- * @do_func: (scope call): the function to be called
- * @user_data: (closure): the gpointer to optional user data.
- *
- * Calls the given function for the last buffer returned by
- * gst_buffer_list_iterator_next(). gst_buffer_list_iterator_next() must have
- * been called on @it before this function is called.
- * gst_buffer_list_iterator_remove() and gst_buffer_list_iterator_steal() must
- * not have been called since the last call to gst_buffer_list_iterator_next().
- *
- * See #GstBufferListDoFunction for more details.
- *
- * Returns: (transfer none): the return value from @do_func
- *
- * Since: 0.10.24
- */
-GstBuffer *
-gst_buffer_list_iterator_do (GstBufferListIterator * it,
-    GstBufferListDoFunction do_func, gpointer user_data)
-{
-  GstBuffer *buffer;
-
-  g_return_val_if_fail (it != NULL, NULL);
-  g_return_val_if_fail (it->last_returned != NULL, NULL);
-  g_return_val_if_fail (it->last_returned->data != STOLEN, NULL);
-  g_return_val_if_fail (do_func != NULL, NULL);
-  g_return_val_if_fail (gst_buffer_list_is_writable (it->list), NULL);
-  g_assert (it->last_returned->data != GROUP_START);
-
-  buffer = gst_buffer_list_iterator_steal (it);
-  buffer = do_func (buffer, user_data);
-  if (buffer == NULL) {
-    gst_buffer_list_iterator_remove (it);
-  } else {
-    gst_buffer_list_iterator_take (it, buffer);
-  }
-
-  return buffer;
-}
-
-/**
- * gst_buffer_list_iterator_merge_group:
- * @it: a #GstBufferListIterator
- *
- * Merge a buffer list group into a normal #GstBuffer by copying its metadata
- * and memcpying its data into consecutive memory. All buffers in the current
- * group after the implicit cursor will be merged into one new buffer. The
- * metadata of the new buffer will be a copy of the metadata of the buffer that
- * would be returned by gst_buffer_list_iterator_next(). If there is no buffer
- * in the current group after the implicit cursor, NULL will be returned.
- *
- * This function will not move the implicit cursor or in any other way affect
- * the state of the iterator @it or the list.
- *
- * Returns: (transfer full): a new #GstBuffer, gst_buffer_unref() after usage,
- *     or NULL
- *
- * Since: 0.10.24
- */
-GstBuffer *
-gst_buffer_list_iterator_merge_group (const GstBufferListIterator * it)
-{
-  GList *tmp;
-  guint size;
-  GstBuffer *buf;
-  guint8 *ptr;
-
-  g_return_val_if_fail (it != NULL, NULL);
-
-  /* calculate size of merged buffer */
-  size = 0;
-  tmp = it->next;
-  while (tmp && tmp->data != GROUP_START) {
-    if (tmp->data != STOLEN) {
-      size += GST_BUFFER_SIZE (tmp->data);
-    }
-    tmp = g_list_next (tmp);
-  }
-
-  if (size == 0) {
-    return NULL;
-  }
-
-  /* allocate a new buffer */
-  buf = gst_buffer_new_and_alloc (size);
-
-  /* copy metadata from the next buffer after the implicit cursor */
-  gst_buffer_copy_metadata (buf, GST_BUFFER_CAST (it->next->data),
-      GST_BUFFER_COPY_ALL);
-
-  /* copy data of all buffers before the next group start into the new buffer */
-  ptr = GST_BUFFER_DATA (buf);
-  tmp = it->next;
-  do {
-    if (tmp->data != STOLEN) {
-      memcpy (ptr, GST_BUFFER_DATA (tmp->data), GST_BUFFER_SIZE (tmp->data));
-      ptr += GST_BUFFER_SIZE (tmp->data);
-    }
-    tmp = g_list_next (tmp);
-  } while (tmp && tmp->data != GROUP_START);
-
-  return buf;
+  g_array_remove_range (list->array, idx, length);
 }
index ff5022b..6ac0a67 100644 (file)
 
 G_BEGIN_DECLS
 
-#define GST_TYPE_BUFFER_LIST (gst_buffer_list_get_type ())
-#define GST_IS_BUFFER_LIST(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_BUFFER_LIST))
-#define GST_IS_BUFFER_LIST_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_BUFFER_LIST))
-#define GST_BUFFER_LIST_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_BUFFER_LIST, GstBufferListClass))
-#define GST_BUFFER_LIST(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_BUFFER_LIST, GstBufferList))
-#define GST_BUFFER_LIST_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_BUFFER_LIST, GstBufferListClass))
-#define GST_BUFFER_LIST_CAST(obj) ((GstBufferList *)obj)
+extern GType _gst_buffer_list_type;
 
-#define GST_TYPE_BUFFER_LIST_ITERATOR (gst_buffer_list_iterator_get_type ())
+#define GST_TYPE_BUFFER_LIST      (_gst_buffer_list_type)
+#define GST_IS_BUFFER_LIST(obj)   (GST_IS_MINI_OBJECT_TYPE(obj, GST_TYPE_BUFFER_LIST))
+#define GST_BUFFER_LIST_CAST(obj) ((GstBufferList *)obj)
+#define GST_BUFFER_LIST(obj)      (GST_BUFFER_LIST_CAST(obj))
 
 typedef struct _GstBufferList GstBufferList;
-typedef struct _GstBufferListClass GstBufferListClass;
-typedef struct _GstBufferListIterator GstBufferListIterator;
-
-/**
- * GstBufferListDoFunction:
- * @buffer: (transfer full): the #GstBuffer
- * @user_data: user data
- *
- * A function for accessing the last buffer returned by
- * gst_buffer_list_iterator_next(). The function can leave @buffer in the list,
- * replace @buffer in the list or remove @buffer from the list, depending on
- * the return value. If the function returns NULL, @buffer will be removed from
- * the list, otherwise @buffer will be replaced with the returned buffer.
- *
- * The last buffer returned by gst_buffer_list_iterator_next() will be replaced
- * with the buffer returned from the function. The function takes ownership of
- * @buffer and if a different value than @buffer is returned, @buffer must be
- * unreffed. If NULL is returned, the buffer will be removed from the list. The
- * list must be writable.
- *
- * Returns: (transfer full): the buffer to replace @buffer in the list, or NULL
- *     to remove @buffer from the list
- *
- * Since: 0.10.24
- */
-typedef GstBuffer* (*GstBufferListDoFunction) (GstBuffer * buffer, gpointer user_data);
-
-/**
- * GstBufferListItem:
- * @GST_BUFFER_LIST_CONTINUE:   Retrieve next buffer
- * @GST_BUFFER_LIST_SKIP_GROUP: Skip to next group
- * @GST_BUFFER_LIST_END:        End iteration
- *
- * The result of the #GstBufferListFunc.
- *
- * Since: 0.10.24
- */
-typedef enum {
-  GST_BUFFER_LIST_CONTINUE,
-  GST_BUFFER_LIST_SKIP_GROUP,
-  GST_BUFFER_LIST_END
-} GstBufferListItem;
 
 /**
  * GstBufferListFunc:
  * @buffer: pointer the buffer
- * @group: the group index of @buffer
- * @idx: the index in @group of @buffer
+ * @idx: the index of @buffer
  * @user_data: user data passed to gst_buffer_list_foreach()
  *
  * A function that will be called from gst_buffer_list_foreach(). The @buffer
- * field will point to a the reference of the buffer at @idx in @group.
+ * field will point to a the reference of the buffer at @idx.
  *
- * When this function returns #GST_BUFFER_LIST_CONTINUE, the next buffer will be
- * returned. When #GST_BUFFER_LIST_SKIP_GROUP is returned, all remaining buffers
- * in the current group will be skipped and the first buffer of the next group
- * is returned (if any). When GST_BUFFER_LIST_END is returned,
- * gst_buffer_list_foreach() will return.
+ * When this function returns %TRUE, the next buffer will be
+ * returned. When %FALSE is returned, gst_buffer_list_foreach() will return.
  *
  * When @buffer is set to NULL, the item will be removed from the bufferlist.
  * When @buffer has been made writable, the new buffer reference can be assigned
  * to @buffer. This function is responsible for unreffing the old buffer when
  * removing or modifying.
  *
- * Returns: a #GstBufferListItem
- *
- * Since: 0.10.24
+ * Returns: %FALSE when gst_buffer_list_foreach() should stop
  */
-typedef GstBufferListItem (*GstBufferListFunc)   (GstBuffer **buffer, guint group, guint idx,
-                                                  gpointer user_data);
+typedef gboolean   (*GstBufferListFunc)   (GstBuffer **buffer, guint idx,
+                                           gpointer user_data);
 
 
-GType gst_buffer_list_get_type (void);
-
-/* allocation */
-GstBufferList *gst_buffer_list_new (void);
-
 /* refcounting */
 /**
  * gst_buffer_list_ref:
@@ -209,34 +153,21 @@ gst_buffer_list_copy (const GstBufferList * list)
  */
 #define gst_buffer_list_make_writable(list) GST_BUFFER_LIST_CAST (gst_mini_object_make_writable (GST_MINI_OBJECT_CAST (list)))
 
-guint                    gst_buffer_list_n_groups              (GstBufferList *list);
+/* allocation */
+GstBufferList *          gst_buffer_list_new                   (void);
+GstBufferList *          gst_buffer_list_sized_new             (guint size);
+
+guint                    gst_buffer_list_len                   (GstBufferList *list);
+
+GstBuffer *              gst_buffer_list_get                   (GstBufferList *list, guint idx);
+void                     gst_buffer_list_insert                (GstBufferList *list, guint idx, GstBuffer *buffer);
+void                     gst_buffer_list_remove                (GstBufferList *list, guint idx, guint length);
 
 void                     gst_buffer_list_foreach               (GstBufferList *list,
                                                                 GstBufferListFunc func,
                                                                gpointer user_data);
-GstBuffer *              gst_buffer_list_get                   (GstBufferList *list, guint group, guint idx);
-
-/* iterator */
-GType                    gst_buffer_list_iterator_get_type     (void);
-GstBufferListIterator *  gst_buffer_list_iterate               (GstBufferList *list);
-void                     gst_buffer_list_iterator_free         (GstBufferListIterator *it);
-
-guint                    gst_buffer_list_iterator_n_buffers    (const GstBufferListIterator *it);
-GstBuffer *              gst_buffer_list_iterator_next         (GstBufferListIterator *it);
-gboolean                 gst_buffer_list_iterator_next_group   (GstBufferListIterator *it);
-
-void                     gst_buffer_list_iterator_add          (GstBufferListIterator *it, GstBuffer *buffer);
-void                     gst_buffer_list_iterator_add_list     (GstBufferListIterator *it, GList *list);
-void                     gst_buffer_list_iterator_add_group    (GstBufferListIterator *it);
-void                     gst_buffer_list_iterator_remove       (GstBufferListIterator *it);
-GstBuffer *              gst_buffer_list_iterator_steal        (GstBufferListIterator *it);
-void                     gst_buffer_list_iterator_take         (GstBufferListIterator *it, GstBuffer *buffer);
-
-GstBuffer *              gst_buffer_list_iterator_do           (GstBufferListIterator *it, GstBufferListDoFunction do_func,
-                                                                gpointer user_data);
 
-/* conversion */
-GstBuffer *              gst_buffer_list_iterator_merge_group  (const GstBufferListIterator *it);
+#define gst_buffer_list_add(l,b) gst_buffer_list_insert((l),-1,(b));
 
 G_END_DECLS
 
diff --git a/gst/gstbufferpool.c b/gst/gstbufferpool.c
new file mode 100644 (file)
index 0000000..90f697e
--- /dev/null
@@ -0,0 +1,703 @@
+/* GStreamer
+ * Copyright (C) 2010 Wim Taymans <wim.taymans@gmail.com>
+ *
+ * gstbufferpool.c: GstBufferPool baseclass
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/**
+ * SECTION:gstbufferpool
+ * @short_description: Pool for buffers
+ * @see_also: #GstBuffer
+ *
+ */
+
+#include "gst_private.h"
+
+#include <errno.h>
+#ifdef HAVE_UNISTD_H
+#  include <unistd.h>
+#endif
+#include <sys/types.h>
+
+#include "gstinfo.h"
+#include "gstquark.h"
+
+#include "gstbufferpool.h"
+
+GST_DEBUG_CATEGORY_STATIC (gst_buffer_pool_debug);
+#define GST_CAT_DEFAULT gst_buffer_pool_debug
+
+#define GST_BUFFER_POOL_GET_PRIVATE(obj)  \
+   (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GST_TYPE_BUFFER_POOL, GstBufferPoolPrivate))
+
+#define GST_BUFFER_POOL_LOCK(pool)   (g_static_rec_mutex_lock(&pool->priv->rec_lock))
+#define GST_BUFFER_POOL_UNLOCK(pool) (g_static_rec_mutex_unlock(&pool->priv->rec_lock))
+
+struct _GstBufferPoolPrivate
+{
+  GStaticRecMutex rec_lock;
+  guint size;
+  guint min_buffers;
+  guint max_buffers;
+  guint prefix;
+  guint align;
+};
+
+enum
+{
+  /* add more above */
+  LAST_SIGNAL
+};
+
+static void gst_buffer_pool_finalize (GObject * object);
+
+G_DEFINE_TYPE (GstBufferPool, gst_buffer_pool, GST_TYPE_OBJECT);
+
+static gboolean default_start (GstBufferPool * pool);
+static gboolean default_stop (GstBufferPool * pool);
+static gboolean default_set_config (GstBufferPool * pool,
+    GstStructure * config);
+static GstFlowReturn default_alloc_buffer (GstBufferPool * pool,
+    GstBuffer ** buffer, GstBufferPoolParams * params);
+static GstFlowReturn default_acquire_buffer (GstBufferPool * pool,
+    GstBuffer ** buffer, GstBufferPoolParams * params);
+static void default_free_buffer (GstBufferPool * pool, GstBuffer * buffer);
+static void default_release_buffer (GstBufferPool * pool, GstBuffer * buffer);
+
+static void
+gst_buffer_pool_class_init (GstBufferPoolClass * klass)
+{
+  GObjectClass *gobject_class = (GObjectClass *) klass;
+
+  g_type_class_add_private (klass, sizeof (GstBufferPoolPrivate));
+
+  gobject_class->finalize = gst_buffer_pool_finalize;
+
+  klass->start = default_start;
+  klass->stop = default_stop;
+  klass->set_config = default_set_config;
+  klass->acquire_buffer = default_acquire_buffer;
+  klass->alloc_buffer = default_alloc_buffer;
+  klass->release_buffer = default_release_buffer;
+  klass->free_buffer = default_free_buffer;
+
+  GST_DEBUG_CATEGORY_INIT (gst_buffer_pool_debug, "bufferpool", 0,
+      "bufferpool debug");
+}
+
+static void
+gst_buffer_pool_init (GstBufferPool * pool)
+{
+  pool->priv = GST_BUFFER_POOL_GET_PRIVATE (pool);
+
+  g_static_rec_mutex_init (&pool->priv->rec_lock);
+
+  pool->poll = gst_poll_new_timer ();
+  pool->queue = gst_atomic_queue_new (10);
+  pool->flushing = TRUE;
+  pool->active = FALSE;
+  pool->configured = FALSE;
+  pool->started = FALSE;
+  pool->config = gst_structure_id_empty_new (GST_QUARK (BUFFER_POOL_CONFIG));
+  gst_buffer_pool_config_set (pool->config, NULL, 0, 0, 0, 0, 1);
+
+  GST_DEBUG_OBJECT (pool, "created");
+}
+
+static void
+gst_buffer_pool_finalize (GObject * object)
+{
+  GstBufferPool *pool;
+
+  pool = GST_BUFFER_POOL_CAST (object);
+
+  GST_DEBUG_OBJECT (pool, "finalize");
+
+  gst_buffer_pool_set_active (pool, FALSE);
+  gst_atomic_queue_unref (pool->queue);
+  gst_poll_free (pool->poll);
+  gst_structure_free (pool->config);
+  g_static_rec_mutex_free (&pool->priv->rec_lock);
+
+  G_OBJECT_CLASS (gst_buffer_pool_parent_class)->finalize (object);
+}
+
+/**
+ * gst_buffer_pool_new:
+ *
+ * Creates a new #GstBufferPool instance.
+ *
+ * Returns: a new #GstBufferPool instance
+ */
+GstBufferPool *
+gst_buffer_pool_new (void)
+{
+  GstBufferPool *result;
+
+  result = g_object_newv (GST_TYPE_BUFFER_POOL, 0, NULL);
+  GST_DEBUG_OBJECT (result, "created new buffer pool");
+
+  return result;
+}
+
+static GstFlowReturn
+default_alloc_buffer (GstBufferPool * pool, GstBuffer ** buffer,
+    GstBufferPoolParams * params)
+{
+  GstBufferPoolPrivate *priv = pool->priv;
+  GstMemory *mem;
+
+  *buffer = gst_buffer_new ();
+
+  mem =
+      gst_memory_allocator_alloc (NULL, priv->size + priv->prefix, priv->align);
+  gst_memory_resize (mem, priv->prefix, priv->size);
+  gst_buffer_take_memory (*buffer, -1, mem);
+
+  return GST_FLOW_OK;
+}
+
+/* the default implementation for preallocating the buffers
+ * in the pool */
+static gboolean
+default_start (GstBufferPool * pool)
+{
+  guint i;
+  GstBufferPoolPrivate *priv = pool->priv;
+  GstBufferPoolClass *pclass;
+
+  pclass = GST_BUFFER_POOL_GET_CLASS (pool);
+
+  /* no alloc function, error */
+  if (G_UNLIKELY (pclass->alloc_buffer == NULL))
+    goto no_alloc;
+
+  /* we need to prealloc buffers */
+  for (i = 0; i < priv->min_buffers; i++) {
+    GstBuffer *buffer;
+
+    if (pclass->alloc_buffer (pool, &buffer, NULL) != GST_FLOW_OK)
+      goto alloc_failed;
+
+    GST_LOG_OBJECT (pool, "prealloced buffer %d: %p", i, buffer);
+    /* store in the queue */
+    gst_atomic_queue_push (pool->queue, buffer);
+    gst_poll_write_control (pool->poll);
+  }
+  return TRUE;
+
+  /* ERRORS */
+no_alloc:
+  {
+    GST_WARNING_OBJECT (pool, "no alloc function");
+    return FALSE;
+  }
+alloc_failed:
+  {
+    GST_WARNING_OBJECT (pool, "alloc function failed");
+    return FALSE;
+  }
+}
+
+/* must be called with the lock */
+static gboolean
+do_start (GstBufferPool * pool)
+{
+  if (!pool->started) {
+    GstBufferPoolClass *pclass;
+
+    pclass = GST_BUFFER_POOL_GET_CLASS (pool);
+
+    GST_LOG_OBJECT (pool, "starting");
+    /* start the pool, subclasses should allocate buffers and put them
+     * in the queue */
+    if (G_LIKELY (pclass->start)) {
+      if (!pclass->start (pool))
+        return FALSE;
+    }
+    pool->started = TRUE;
+  }
+  return TRUE;
+}
+
+
+static void
+default_free_buffer (GstBufferPool * pool, GstBuffer * buffer)
+{
+  gst_buffer_unref (buffer);
+}
+
+/* must be called with the lock */
+static gboolean
+default_stop (GstBufferPool * pool)
+{
+  GstBuffer *buffer;
+  GstBufferPoolClass *pclass;
+
+  pclass = GST_BUFFER_POOL_GET_CLASS (pool);
+
+  /* clear the pool */
+  while ((buffer = gst_atomic_queue_pop (pool->queue))) {
+    gst_poll_read_control (pool->poll);
+
+    if (G_LIKELY (pclass->free_buffer))
+      pclass->free_buffer (pool, buffer);
+  }
+  return TRUE;
+}
+
+/* must be called with the lock */
+static gboolean
+do_stop (GstBufferPool * pool)
+{
+  if (pool->started) {
+    GstBufferPoolClass *pclass;
+
+    pclass = GST_BUFFER_POOL_GET_CLASS (pool);
+
+    GST_LOG_OBJECT (pool, "stopping");
+    if (G_LIKELY (pclass->stop)) {
+      if (!pclass->stop (pool))
+        return FALSE;
+    }
+    pool->started = FALSE;
+  }
+  return TRUE;
+}
+
+/**
+ * gst_buffer_pool_set_active:
+ * @pool: a #GstBufferPool
+ * @active: the new active state
+ *
+ * Control the active state of @pool. When the pool is active, new calls to
+ * gst_buffer_pool_acquire_buffer() will return with GST_FLOW_WRONG_STATE.
+ *
+ * Returns: %FALSE when the pool was not configured or when preallocation of the
+ * buffers failed.
+ */
+gboolean
+gst_buffer_pool_set_active (GstBufferPool * pool, gboolean active)
+{
+  gboolean res = TRUE;
+
+  g_return_val_if_fail (GST_IS_BUFFER_POOL (pool), FALSE);
+
+  GST_LOG_OBJECT (pool, "active %d", active);
+
+  GST_BUFFER_POOL_LOCK (pool);
+  /* just return if we are already in the right state */
+  if (pool->active == active)
+    goto was_ok;
+
+  /* we need to be configured */
+  if (!pool->configured)
+    goto not_configured;
+
+  if (active) {
+    if (!do_start (pool))
+      goto start_failed;
+
+    /* unset the flushing state now */
+    gst_poll_read_control (pool->poll);
+    g_atomic_int_set (&pool->flushing, FALSE);
+  } else {
+    /* set to flushing first */
+    g_atomic_int_set (&pool->flushing, TRUE);
+    gst_poll_write_control (pool->poll);
+
+    /* when all buffers are in the pool, free them. Else they will be
+     * freed when they are released */
+    if (g_atomic_int_get (&pool->outstanding) == 0) {
+      if (!do_stop (pool))
+        goto stop_failed;
+    }
+  }
+  pool->active = active;
+  GST_BUFFER_POOL_UNLOCK (pool);
+
+  return res;
+
+was_ok:
+  {
+    GST_DEBUG_OBJECT (pool, "pool was in the right state");
+    GST_BUFFER_POOL_UNLOCK (pool);
+    return TRUE;
+  }
+not_configured:
+  {
+    GST_ERROR_OBJECT (pool, "pool was not configured");
+    GST_BUFFER_POOL_UNLOCK (pool);
+    return FALSE;
+  }
+start_failed:
+  {
+    GST_ERROR_OBJECT (pool, "start failed");
+    GST_BUFFER_POOL_UNLOCK (pool);
+    return FALSE;
+  }
+stop_failed:
+  {
+    GST_WARNING_OBJECT (pool, "stop failed");
+    GST_BUFFER_POOL_UNLOCK (pool);
+    return FALSE;
+  }
+}
+
+static gboolean
+default_set_config (GstBufferPool * pool, GstStructure * config)
+{
+  GstBufferPoolPrivate *priv = pool->priv;
+  const GstCaps *caps;
+  guint size, min_buffers, max_buffers;
+  guint prefix, align;
+
+  /* parse the config and keep around */
+  if (!gst_buffer_pool_config_get (config, &caps, &size, &min_buffers,
+          &max_buffers, &prefix, &align))
+    goto wrong_config;
+
+  GST_DEBUG_OBJECT (pool, "config %" GST_PTR_FORMAT, config);
+
+  priv->size = size;
+  priv->min_buffers = min_buffers;
+  priv->max_buffers = max_buffers;
+  priv->prefix = prefix;
+  priv->align = align;
+
+  return TRUE;
+
+wrong_config:
+  {
+    GST_WARNING_OBJECT (pool, "invalid config %" GST_PTR_FORMAT, config);
+    return FALSE;
+  }
+}
+
+/**
+ * gst_buffer_pool_set_config:
+ * @pool: a #GstBufferPool
+ * @config: a #GstStructure
+ *
+ * Set the configuration of the pool. The pool must be inactive and all buffers
+ * allocated form this pool must be returned or else this function will do
+ * nothing and return FALSE.
+ *
+ * @condfig is a #GstStructure that contains the configuration parameters for
+ * the pool. A default and mandatory set of parameters can be configured with
+ * gst_buffer_pool_config_set(). This function takes ownership of @config.
+ *
+ * Returns: TRUE when the configuration could be set.
+ */
+gboolean
+gst_buffer_pool_set_config (GstBufferPool * pool, GstStructure * config)
+{
+  gboolean result;
+  GstBufferPoolClass *pclass;
+
+  g_return_val_if_fail (GST_IS_BUFFER_POOL (pool), FALSE);
+  g_return_val_if_fail (config != NULL, FALSE);
+
+  GST_BUFFER_POOL_LOCK (pool);
+  /* can't change the settings when active */
+  if (pool->active)
+    goto was_active;
+
+  /* we can't change when outstanding buffers */
+  if (g_atomic_int_get (&pool->outstanding) != 0)
+    goto have_outstanding;
+
+  pclass = GST_BUFFER_POOL_GET_CLASS (pool);
+
+  /* set the new config */
+  if (G_LIKELY (pclass->set_config))
+    result = pclass->set_config (pool, config);
+  else
+    result = FALSE;
+
+  if (result) {
+    if (pool->config)
+      gst_structure_free (pool->config);
+    pool->config = config;
+
+    /* now we are configured */
+    pool->configured = TRUE;
+  }
+  GST_BUFFER_POOL_UNLOCK (pool);
+
+  return result;
+
+  /* ERRORS */
+was_active:
+  {
+    GST_WARNING_OBJECT (pool, "can't change config, we are active");
+    GST_BUFFER_POOL_UNLOCK (pool);
+    return FALSE;
+  }
+have_outstanding:
+  {
+    GST_WARNING_OBJECT (pool, "can't change config, have outstanding buffers");
+    GST_BUFFER_POOL_UNLOCK (pool);
+    return FALSE;
+  }
+}
+
+/**
+ * gst_buffer_pool_get_config:
+ * @pool: a #GstBufferPool
+ *
+ * Get a copy of the current configuration of the pool. This configuration
+ * can either be modified and used for the gst_buffer_pool_set_config() call
+ * or it must be freed after usage.
+ *
+ * Returns: a copy of the current configuration of @pool. use
+ * gst_structure_free() after usage or gst_buffer_pool_set_config().
+ */
+GstStructure *
+gst_buffer_pool_get_config (GstBufferPool * pool)
+{
+  GstStructure *result;
+
+  g_return_val_if_fail (GST_IS_BUFFER_POOL (pool), NULL);
+
+  GST_BUFFER_POOL_UNLOCK (pool);
+  result = gst_structure_copy (pool->config);
+  GST_BUFFER_POOL_UNLOCK (pool);
+
+  return result;
+}
+
+/**
+ * gst_buffer_pool_config_set:
+ * @config: a #GstBufferPool
+ * @caps: caps for the buffers
+ * @size: the size of each buffer, not including prefix
+ * @min_buffers: the minimum amount of buffers to allocate.
+ * @max_buffers: the maximum amount of buffers to allocate or 0 for unlimited.
+ * @prefix: prefix each buffer with this many bytes
+ * @align: alignment of the buffer data.
+ *
+ * Configure @config with the given parameters.
+ */
+void
+gst_buffer_pool_config_set (GstStructure * config, const GstCaps * caps,
+    guint size, guint min_buffers, guint max_buffers, guint prefix, guint align)
+{
+  g_return_if_fail (config != NULL);
+
+  gst_structure_id_set (config,
+      GST_QUARK (CAPS), GST_TYPE_CAPS, caps,
+      GST_QUARK (SIZE), G_TYPE_UINT, size,
+      GST_QUARK (MIN_BUFFERS), G_TYPE_UINT, min_buffers,
+      GST_QUARK (MAX_BUFFERS), G_TYPE_UINT, max_buffers,
+      GST_QUARK (PREFIX), G_TYPE_UINT, prefix,
+      GST_QUARK (ALIGN), G_TYPE_UINT, align, NULL);
+}
+
+/**
+ * gst_buffer_pool_config_get:
+ * @config: a #GstBufferPool
+ * @caps: the caps of buffers
+ * @size: the size of each buffer, not including prefix
+ * @min_buffers: the minimum amount of buffers to allocate.
+ * @max_buffers: the maximum amount of buffers to allocate or 0 for unlimited.
+ * @prefix: prefix each buffer with this many bytes
+ * @align: alignment of the buffer data.
+ *
+ * Get the configuration values from @config.
+ */
+gboolean
+gst_buffer_pool_config_get (GstStructure * config, const GstCaps ** caps,
+    guint * size, guint * min_buffers, guint * max_buffers, guint * prefix,
+    guint * align)
+{
+  g_return_val_if_fail (config != NULL, FALSE);
+
+  return gst_structure_id_get (config,
+      GST_QUARK (CAPS), GST_TYPE_CAPS, caps,
+      GST_QUARK (SIZE), G_TYPE_UINT, size,
+      GST_QUARK (MIN_BUFFERS), G_TYPE_UINT, min_buffers,
+      GST_QUARK (MAX_BUFFERS), G_TYPE_UINT, max_buffers,
+      GST_QUARK (PREFIX), G_TYPE_UINT, prefix,
+      GST_QUARK (ALIGN), G_TYPE_UINT, align, NULL);
+}
+
+static GstFlowReturn
+default_acquire_buffer (GstBufferPool * pool, GstBuffer ** buffer,
+    GstBufferPoolParams * params)
+{
+  GstFlowReturn result;
+  GstBufferPoolClass *pclass;
+  GstBufferPoolPrivate *priv = pool->priv;
+
+  pclass = GST_BUFFER_POOL_GET_CLASS (pool);
+
+  while (TRUE) {
+    if (G_UNLIKELY (g_atomic_int_get (&pool->flushing)))
+      goto flushing;
+
+    /* try to get a buffer from the queue */
+    *buffer = gst_atomic_queue_pop (pool->queue);
+    if (G_LIKELY (*buffer)) {
+      gst_poll_read_control (pool->poll);
+      result = GST_FLOW_OK;
+      GST_LOG_OBJECT (pool, "acquired buffer %p", *buffer);
+      break;
+    }
+
+    /* no buffer */
+    if (priv->max_buffers == 0) {
+      /* no max_buffers, we allocate some more */
+      if (G_LIKELY (pclass->alloc_buffer)) {
+        result = pclass->alloc_buffer (pool, buffer, params);
+      } else
+        result = GST_FLOW_NOT_SUPPORTED;
+      GST_LOG_OBJECT (pool, "alloc buffer %p", *buffer);
+      break;
+    }
+
+    /* check if we need to wait */
+    if (params && (params->flags & GST_BUFFER_POOL_FLAG_DONTWAIT)) {
+      GST_LOG_OBJECT (pool, "no more buffers");
+      result = GST_FLOW_UNEXPECTED;
+      break;
+    }
+
+    /* now wait */
+    GST_LOG_OBJECT (pool, "waiting for free buffers");
+    gst_poll_wait (pool->poll, GST_CLOCK_TIME_NONE);
+  }
+
+  return result;
+
+  /* ERRORS */
+flushing:
+  {
+    GST_DEBUG_OBJECT (pool, "we are flushing");
+    return GST_FLOW_WRONG_STATE;
+  }
+}
+
+static inline void
+dec_outstanding (GstBufferPool * pool)
+{
+  if (g_atomic_int_dec_and_test (&pool->outstanding)) {
+    /* all buffers are returned to the pool, see if we need to free them */
+    if (g_atomic_int_get (&pool->flushing)) {
+      /* take the lock so that set_active is not run concurrently */
+      GST_BUFFER_POOL_LOCK (pool);
+      /* recheck the flushing state in the lock, the pool could have been
+       * set to active again */
+      if (g_atomic_int_get (&pool->flushing))
+        do_stop (pool);
+
+      GST_BUFFER_POOL_UNLOCK (pool);
+    }
+  }
+}
+
+/**
+ * gst_buffer_pool_acquire_buffer:
+ * @pool: a #GstBufferPool
+ * @buffer: a location for a #GstBuffer
+ * @params: parameters.
+ *
+ * Acquire a buffer from @pool. @buffer should point to a memory location that
+ * can hold a pointer to the new buffer.
+ *
+ * @params can be NULL or contain optional parameters to influence the allocation.
+ *
+ * Returns: a #GstFlowReturn such as GST_FLOW_WRONG_STATE when the pool is
+ * inactive.
+ */
+GstFlowReturn
+gst_buffer_pool_acquire_buffer (GstBufferPool * pool, GstBuffer ** buffer,
+    GstBufferPoolParams * params)
+{
+  GstBufferPoolClass *pclass;
+  GstFlowReturn result;
+
+  g_return_val_if_fail (GST_IS_BUFFER_POOL (pool), GST_FLOW_ERROR);
+  g_return_val_if_fail (buffer != NULL, GST_FLOW_ERROR);
+
+  pclass = GST_BUFFER_POOL_GET_CLASS (pool);
+
+  /* assume we'll have one more outstanding buffer we need to do that so
+   * that concurrent set_active doesn't clear the buffers */
+  g_atomic_int_inc (&pool->outstanding);
+
+  if (G_LIKELY (pclass->acquire_buffer))
+    result = pclass->acquire_buffer (pool, buffer, params);
+  else
+    result = GST_FLOW_NOT_SUPPORTED;
+
+  if (G_LIKELY (result == GST_FLOW_OK)) {
+    /* all buffers from the pool point to the pool and have the refcount of the
+     * pool incremented */
+    (*buffer)->pool = gst_object_ref (pool);
+  } else {
+    dec_outstanding (pool);
+  }
+
+  return result;
+}
+
+static void
+default_release_buffer (GstBufferPool * pool, GstBuffer * buffer)
+{
+  /* keep it around in our queue */
+  GST_LOG_OBJECT (pool, "released buffer %p", buffer);
+  gst_atomic_queue_push (pool->queue, buffer);
+  gst_poll_write_control (pool->poll);
+}
+
+/**
+ * gst_buffer_pool_release_buffer:
+ * @pool: a #GstBufferPool
+ * @buffer: a #GstBuffer
+ *
+ * Release @buffer to @pool. @buffer should have previously been allocated from
+ * @pool with gst_buffer_pool_acquire_buffer().
+ *
+ * This function is usually called automatically when the last ref on @buffer
+ * disappears.
+ */
+void
+gst_buffer_pool_release_buffer (GstBufferPool * pool, GstBuffer * buffer)
+{
+  GstBufferPoolClass *pclass;
+
+  g_return_if_fail (GST_IS_BUFFER_POOL (pool));
+  g_return_if_fail (buffer != NULL);
+
+  /* check that the buffer is ours, all buffers returned to the pool have the
+   * pool member set to NULL and the pool refcount decreased */
+  if (!g_atomic_pointer_compare_and_exchange ((gpointer *) & buffer->pool,
+          pool, NULL))
+    return;
+
+  pclass = GST_BUFFER_POOL_GET_CLASS (pool);
+
+  if (G_LIKELY (pclass->release_buffer))
+    pclass->release_buffer (pool, buffer);
+
+  dec_outstanding (pool);
+
+  /* decrease the refcount that the buffer had to us */
+  gst_object_unref (pool);
+}
diff --git a/gst/gstbufferpool.h b/gst/gstbufferpool.h
new file mode 100644 (file)
index 0000000..34a8c89
--- /dev/null
@@ -0,0 +1,158 @@
+/* GStreamer
+ * Copyright (C) 2010 Wim Taymans <wim.taymans@gmail.com>
+ *
+ * gstbufferpool.h: Header for GstBufferPool object
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+
+#ifndef __GST_BUFFER_POOL_H__
+#define __GST_BUFFER_POOL_H__
+
+#include <gst/gstminiobject.h>
+#include <gst/gstatomicqueue.h>
+#include <gst/gstpoll.h>
+#include <gst/gstclock.h>
+#include <gst/gstpad.h>
+#include <gst/gstbuffer.h>
+
+G_BEGIN_DECLS
+
+typedef struct _GstBufferPoolPrivate GstBufferPoolPrivate;
+typedef struct _GstBufferPoolClass GstBufferPoolClass;
+
+/**
+ * GST_BUFFER_POOL_TRACE_NAME:
+ *
+ * The name used for tracing memory allocations.
+ */
+#define GST_BUFFER_POOL_TRACE_NAME           "GstBufferPool"
+
+#define GST_TYPE_BUFFER_POOL                 (gst_buffer_pool_get_type())
+#define GST_IS_BUFFER_POOL(obj)              (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_BUFFER_POOL))
+#define GST_IS_BUFFER_POOL_CLASS(klass)      (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_BUFFER_POOL))
+#define GST_BUFFER_POOL_GET_CLASS(obj)       (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_BUFFER_POOL, GstBufferPoolClass))
+#define GST_BUFFER_POOL(obj)                 (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_BUFFER_POOL, GstBufferPool))
+#define GST_BUFFER_POOL_CLASS(klass)         (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_BUFFER_POOL, GstBufferPoolClass))
+#define GST_BUFFER_POOL_CAST(obj)            ((GstBufferPool *)(obj))
+
+/**
+ * GstBufferPoolFlags:
+ * @GST_BUFFER_POOL_FLAG_NONE: no flags
+ * @GST_BUFFER_POOL_FLAG_KEY_UNIT: buffer is keyframe
+ * @GST_BUFFER_POOL_FLAG_DONTWAIT: don't wait for buffer
+ * @GST_BUFFER_POOL_FLAG_DISCONT: buffer is discont
+ *
+ * Additional flags to control the allocation of a buffer
+ */
+typedef enum {
+  GST_BUFFER_POOL_FLAG_NONE     = 0,
+  GST_BUFFER_POOL_FLAG_KEY_UNIT = (1 << 0),
+  GST_BUFFER_POOL_FLAG_DONTWAIT = (1 << 1),
+  GST_BUFFER_POOL_FLAG_DISCONT  = (1 << 2),
+  GST_BUFFER_POOL_FLAG_LAST     = (1 << 16),
+} GstBufferPoolFlags;
+
+/**
+ * GstBufferPoolParams:
+ * @format: the format of @start and @stop
+ * @start: the start position
+ * @stop: the stop position
+ * @flags: additional flags
+ *
+ * Parameters passed to the gst_buffer_pool_acquire_buffer() function to control the
+ * allocation of the buffer.
+ */
+typedef struct _GstBufferPoolParams {
+  GstFormat          format;
+  gint64             start;
+  gint64             stop;
+  GstBufferPoolFlags flags;
+} GstBufferPoolParams;
+
+/**
+ * GstBufferPool:
+ * @object: the parent structure
+ *
+ * The structure of a #GstBufferPool. Use the associated macros to access the public
+ * variables.
+ */
+struct _GstBufferPool {
+  GstObject            object;
+
+  /*< private >*/
+  gboolean             active;
+  gboolean             flushing;
+  gboolean             started;
+  gint                 outstanding;
+  GstAtomicQueue      *queue;
+  GstPoll             *poll;
+
+  gboolean             configured;
+  GstStructure        *config;
+
+  GstBufferPoolPrivate *priv;
+
+  gpointer _gst_reserved[GST_PADDING];
+};
+
+struct _GstBufferPoolClass {
+  GstObjectClass    object_class;
+
+  /* vmethods */
+  gboolean       (*set_config)     (GstBufferPool *pool, GstStructure *config);
+
+  gboolean       (*start)          (GstBufferPool *pool);
+  gboolean       (*stop)           (GstBufferPool *pool);
+
+  GstFlowReturn  (*acquire_buffer) (GstBufferPool *pool, GstBuffer **buffer,
+                                    GstBufferPoolParams *params);
+  GstFlowReturn  (*alloc_buffer)   (GstBufferPool *pool, GstBuffer **buffer,
+                                    GstBufferPoolParams *params);
+  void           (*release_buffer) (GstBufferPool *pool, GstBuffer *buffer);
+  void           (*free_buffer)    (GstBufferPool *pool, GstBuffer *buffer);
+
+  gpointer _gst_reserved[GST_PADDING];
+};
+
+GType       gst_buffer_pool_get_type (void);
+
+/* allocation */
+GstBufferPool *       gst_buffer_pool_new  (void);
+
+/* state management */
+gboolean              gst_buffer_pool_set_active      (GstBufferPool *pool, gboolean active);
+
+gboolean              gst_buffer_pool_set_config      (GstBufferPool *pool, GstStructure *config);
+GstStructure *        gst_buffer_pool_get_config      (GstBufferPool *pool);
+
+/* helpers for configuring the config structure */
+void                  gst_buffer_pool_config_set      (GstStructure *config, const GstCaps *caps,
+                                                       guint size, guint min_buffers, guint max_buffers,
+                                                       guint prefix, guint align);
+gboolean              gst_buffer_pool_config_get      (GstStructure *config, const GstCaps **caps,
+                                                       guint *size, guint *min_buffers, guint *max_buffers,
+                                                       guint *prefix, guint *align);
+
+/* buffer management */
+GstFlowReturn         gst_buffer_pool_acquire_buffer  (GstBufferPool *pool, GstBuffer **buffer,
+                                                       GstBufferPoolParams *params);
+void                  gst_buffer_pool_release_buffer  (GstBufferPool *pool, GstBuffer *buffer);
+
+G_END_DECLS
+
+#endif /* __GST_BUFFER_POOL_H__ */
index bca4558..e3a15f7 100644 (file)
@@ -75,6 +75,7 @@
 #include <sys/types.h>
 
 #include "gstinfo.h"
+#include "gstpoll.h"
 
 #include "gstbus.h"
 
@@ -88,9 +89,15 @@ enum
   LAST_SIGNAL
 };
 
-static void gst_bus_dispose (GObject * object);
+#define DEFAULT_ENABLE_ASYNC (TRUE)
+
+enum
+{
+  PROP_0,
+  PROP_ENABLE_ASYNC
+};
 
-static void gst_bus_set_main_context (GstBus * bus, GMainContext * ctx);
+static void gst_bus_dispose (GObject * object);
 
 static GstObjectClass *parent_class = NULL;
 static guint gst_bus_signals[LAST_SIGNAL] = { 0 };
@@ -98,39 +105,40 @@ static guint gst_bus_signals[LAST_SIGNAL] = { 0 };
 struct _GstBusPrivate
 {
   guint num_sync_message_emitters;
-  GCond *queue_cond;
   GSource *watch_id;
-  GMainContext *main_context;
+
+  gboolean enable_async;
+  GstPoll *poll;
+  GPollFD pollfd;
 };
 
 G_DEFINE_TYPE (GstBus, gst_bus, GST_TYPE_OBJECT);
 
-/* fixme: do something about this */
 static void
-marshal_VOID__MINIOBJECT (GClosure * closure, GValue * return_value,
-    guint n_param_values, const GValue * param_values, gpointer invocation_hint,
-    gpointer marshal_data)
+gst_bus_set_property (GObject * object,
+    guint prop_id, const GValue * value, GParamSpec * pspec)
 {
-  typedef void (*marshalfunc_VOID__MINIOBJECT) (gpointer obj, gpointer arg1,
-      gpointer data2);
-  register marshalfunc_VOID__MINIOBJECT callback;
-  register GCClosure *cc = (GCClosure *) closure;
-  register gpointer data1, data2;
-
-  g_return_if_fail (n_param_values == 2);
+  GstBus *bus = GST_BUS_CAST (object);
 
-  if (G_CCLOSURE_SWAP_DATA (closure)) {
-    data1 = closure->data;
-    data2 = g_value_peek_pointer (param_values + 0);
-  } else {
-    data1 = g_value_peek_pointer (param_values + 0);
-    data2 = closure->data;
+  switch (prop_id) {
+    case PROP_ENABLE_ASYNC:
+      bus->priv->enable_async = g_value_get_boolean (value);
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
   }
-  callback =
-      (marshalfunc_VOID__MINIOBJECT) (marshal_data ? marshal_data :
-      cc->callback);
+}
+
+static void
+gst_bus_constructed (GObject * object)
+{
+  GstBus *bus = GST_BUS_CAST (object);
 
-  callback (data1, gst_value_get_mini_object (param_values + 1), data2);
+  if (bus->priv->enable_async) {
+    bus->priv->poll = gst_poll_new_timer ();
+    gst_poll_get_read_gpollfd (bus->priv->poll, &bus->priv->pollfd);
+  }
 }
 
 static void
@@ -141,6 +149,25 @@ gst_bus_class_init (GstBusClass * klass)
   parent_class = g_type_class_peek_parent (klass);
 
   gobject_class->dispose = gst_bus_dispose;
+  gobject_class->set_property = gst_bus_set_property;
+  gobject_class->constructed = gst_bus_constructed;
+
+  /* GstBus:enable-async:
+   *
+   * Enable async message delivery support for bus watches,
+   * gst_bus_pop() and similar API. Without this only the
+   * synchronous message handlers are called.
+   *
+   * This property is used to create the child element buses
+   * in #GstBin.
+   *
+   * Since: 0.10.33
+   */
+  g_object_class_install_property (gobject_class, PROP_ENABLE_ASYNC,
+      g_param_spec_boolean ("enable-async", "Enable Async",
+          "Enable async message delivery for bus watches and gst_bus_pop()",
+          DEFAULT_ENABLE_ASYNC,
+          G_PARAM_CONSTRUCT_ONLY | G_PARAM_WRITABLE | G_PARAM_STATIC_STRINGS));
 
   /**
    * GstBus::sync-message:
@@ -161,7 +188,7 @@ gst_bus_class_init (GstBusClass * klass)
       g_signal_new ("sync-message", G_TYPE_FROM_CLASS (klass),
       G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
       G_STRUCT_OFFSET (GstBusClass, sync_message), NULL, NULL,
-      marshal_VOID__MINIOBJECT, G_TYPE_NONE, 1, GST_TYPE_MESSAGE);
+      g_cclosure_marshal_VOID__BOXED, G_TYPE_NONE, 1, GST_TYPE_MESSAGE);
 
   /**
    * GstBus::message:
@@ -176,7 +203,7 @@ gst_bus_class_init (GstBusClass * klass)
       g_signal_new ("message", G_TYPE_FROM_CLASS (klass),
       G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
       G_STRUCT_OFFSET (GstBusClass, message), NULL, NULL,
-      marshal_VOID__MINIOBJECT, G_TYPE_NONE, 1, GST_TYPE_MESSAGE);
+      g_cclosure_marshal_VOID__BOXED, G_TYPE_NONE, 1, GST_TYPE_MESSAGE);
 
   g_type_class_add_private (klass, sizeof (GstBusPrivate));
 }
@@ -184,11 +211,11 @@ gst_bus_class_init (GstBusClass * klass)
 static void
 gst_bus_init (GstBus * bus)
 {
-  bus->queue = g_queue_new ();
+  bus->queue = gst_atomic_queue_new (32);
   bus->queue_lock = g_mutex_new ();
 
   bus->priv = G_TYPE_INSTANCE_GET_PRIVATE (bus, GST_TYPE_BUS, GstBusPrivate);
-  bus->priv->queue_cond = g_cond_new ();
+  bus->priv->enable_async = DEFAULT_ENABLE_ASYNC;
 
   GST_DEBUG_OBJECT (bus, "created");
 }
@@ -203,63 +230,24 @@ gst_bus_dispose (GObject * object)
 
     g_mutex_lock (bus->queue_lock);
     do {
-      message = g_queue_pop_head (bus->queue);
+      message = gst_atomic_queue_pop (bus->queue);
       if (message)
         gst_message_unref (message);
     } while (message != NULL);
-    g_queue_free (bus->queue);
+    gst_atomic_queue_unref (bus->queue);
     bus->queue = NULL;
     g_mutex_unlock (bus->queue_lock);
     g_mutex_free (bus->queue_lock);
     bus->queue_lock = NULL;
-    g_cond_free (bus->priv->queue_cond);
-    bus->priv->queue_cond = NULL;
-  }
 
-  if (bus->priv->main_context) {
-    g_main_context_unref (bus->priv->main_context);
-    bus->priv->main_context = NULL;
+    if (bus->priv->poll)
+      gst_poll_free (bus->priv->poll);
+    bus->priv->poll = NULL;
   }
 
   G_OBJECT_CLASS (parent_class)->dispose (object);
 }
 
-static void
-gst_bus_wakeup_main_context (GstBus * bus)
-{
-  GMainContext *ctx;
-
-  GST_OBJECT_LOCK (bus);
-  if ((ctx = bus->priv->main_context))
-    g_main_context_ref (ctx);
-  GST_OBJECT_UNLOCK (bus);
-
-  g_main_context_wakeup (ctx);
-
-  if (ctx)
-    g_main_context_unref (ctx);
-}
-
-static void
-gst_bus_set_main_context (GstBus * bus, GMainContext * ctx)
-{
-  GST_OBJECT_LOCK (bus);
-
-  if (bus->priv->main_context != NULL) {
-    g_main_context_unref (bus->priv->main_context);
-    bus->priv->main_context = NULL;
-  }
-
-  if (ctx != NULL) {
-    bus->priv->main_context = g_main_context_ref (ctx);
-  }
-
-  GST_DEBUG_OBJECT (bus, "setting main context to %p, GLib default context: %p",
-      ctx, g_main_context_default ());
-
-  GST_OBJECT_UNLOCK (bus);
-}
-
 /**
  * gst_bus_new:
  *
@@ -301,10 +289,8 @@ gst_bus_post (GstBus * bus, GstMessage * message)
   g_return_val_if_fail (GST_IS_BUS (bus), FALSE);
   g_return_val_if_fail (GST_IS_MESSAGE (message), FALSE);
 
-  GST_DEBUG_OBJECT (bus, "[msg %p] posting on bus, type %s, %" GST_PTR_FORMAT
-      " from source %" GST_PTR_FORMAT,
-      message, GST_MESSAGE_TYPE_NAME (message), message->structure,
-      message->src);
+  GST_DEBUG_OBJECT (bus, "[msg %p] posting on bus %" GST_PTR_FORMAT, message,
+      message);
 
   GST_OBJECT_LOCK (bus);
   /* check if the bus is flushing */
@@ -326,6 +312,11 @@ gst_bus_post (GstBus * bus, GstMessage * message)
       && handler != gst_bus_sync_signal_handler)
     gst_bus_sync_signal_handler (bus, message, NULL);
 
+  /* If this is a bus without async message delivery
+   * always drop the message */
+  if (!bus->priv->poll)
+    reply = GST_BUS_DROP;
+
   /* now see what we should do with the message */
   switch (reply) {
     case GST_BUS_DROP:
@@ -335,14 +326,10 @@ gst_bus_post (GstBus * bus, GstMessage * message)
     case GST_BUS_PASS:
       /* pass the message to the async queue, refcount passed in the queue */
       GST_DEBUG_OBJECT (bus, "[msg %p] pushing on async queue", message);
-      g_mutex_lock (bus->queue_lock);
-      g_queue_push_tail (bus->queue, message);
-      g_cond_broadcast (bus->priv->queue_cond);
-      g_mutex_unlock (bus->queue_lock);
+      gst_atomic_queue_push (bus->queue, message);
+      gst_poll_write_control (bus->priv->poll);
       GST_DEBUG_OBJECT (bus, "[msg %p] pushed on async queue", message);
 
-      gst_bus_wakeup_main_context (bus);
-
       break;
     case GST_BUS_ASYNC:
     {
@@ -360,12 +347,9 @@ gst_bus_post (GstBus * bus, GstMessage * message)
        * queue. When the message is handled by the app and destroyed,
        * the cond will be signalled and we can continue */
       g_mutex_lock (lock);
-      g_mutex_lock (bus->queue_lock);
-      g_queue_push_tail (bus->queue, message);
-      g_cond_broadcast (bus->priv->queue_cond);
-      g_mutex_unlock (bus->queue_lock);
 
-      gst_bus_wakeup_main_context (bus);
+      gst_atomic_queue_push (bus->queue, message);
+      gst_poll_write_control (bus->priv->poll);
 
       /* now block till the message is freed */
       g_cond_wait (cond, lock);
@@ -413,10 +397,8 @@ gst_bus_have_pending (GstBus * bus)
 
   g_return_val_if_fail (GST_IS_BUS (bus), FALSE);
 
-  g_mutex_lock (bus->queue_lock);
   /* see if there is a message on the bus */
-  result = !g_queue_is_empty (bus->queue);
-  g_mutex_unlock (bus->queue_lock);
+  result = gst_atomic_queue_length (bus->queue) != 0;
 
   return result;
 }
@@ -482,18 +464,25 @@ gst_bus_timed_pop_filtered (GstBus * bus, GstClockTime timeout,
     GstMessageType types)
 {
   GstMessage *message;
-  GTimeVal *timeval, abstimeout;
+  GTimeVal now, then;
   gboolean first_round = TRUE;
+  GstClockTime elapsed = 0;
 
   g_return_val_if_fail (GST_IS_BUS (bus), NULL);
   g_return_val_if_fail (types != 0, NULL);
+  g_return_val_if_fail (timeout == 0 || bus->priv->poll != NULL, NULL);
 
   g_mutex_lock (bus->queue_lock);
 
   while (TRUE) {
-    GST_LOG_OBJECT (bus, "have %d messages", g_queue_get_length (bus->queue));
+    gint ret;
+
+    GST_LOG_OBJECT (bus, "have %d messages",
+        gst_atomic_queue_length (bus->queue));
 
-    while ((message = g_queue_pop_head (bus->queue))) {
+    while ((message = gst_atomic_queue_pop (bus->queue))) {
+      if (bus->priv->poll)
+        gst_poll_read_control (bus->priv->poll);
       GST_DEBUG_OBJECT (bus, "got message %p, %s, type mask is %u",
           message, GST_MESSAGE_TYPE_NAME (message), (guint) types);
       if ((GST_MESSAGE_TYPE (message) & types) != 0) {
@@ -510,28 +499,27 @@ gst_bus_timed_pop_filtered (GstBus * bus, GstClockTime timeout,
     if (timeout == 0)
       break;
 
-    if (timeout == GST_CLOCK_TIME_NONE) {
-      /* wait forever */
-      timeval = NULL;
-    } else if (first_round) {
-      glong add = timeout / 1000;
-
-      if (add == 0)
-        /* no need to wait */
-        break;
-
-      /* make timeout absolute */
-      g_get_current_time (&abstimeout);
-      g_time_val_add (&abstimeout, add);
-      timeval = &abstimeout;
-      first_round = FALSE;
-      GST_DEBUG_OBJECT (bus, "blocking for message, timeout %ld", add);
-    } else {
-      /* calculated the absolute end time already, no need to do it again */
-      GST_DEBUG_OBJECT (bus, "blocking for message, again");
-      timeval = &abstimeout;    /* fool compiler */
+    else if (timeout != GST_CLOCK_TIME_NONE) {
+      if (first_round) {
+        g_get_current_time (&then);
+        first_round = FALSE;
+      } else {
+        g_get_current_time (&now);
+
+        elapsed = GST_TIMEVAL_TO_TIME (now) - GST_TIMEVAL_TO_TIME (then);
+
+        if (elapsed > timeout)
+          break;
+      }
     }
-    if (!g_cond_timed_wait (bus->priv->queue_cond, bus->queue_lock, timeval)) {
+
+    /* only here in timeout case */
+    g_assert (bus->priv->poll);
+    g_mutex_unlock (bus->queue_lock);
+    ret = gst_poll_wait (bus->priv->poll, timeout - elapsed);
+    g_mutex_lock (bus->queue_lock);
+
+    if (ret == 0) {
       GST_INFO_OBJECT (bus, "timed out, breaking loop");
       break;
     } else {
@@ -644,7 +632,7 @@ gst_bus_peek (GstBus * bus)
   g_return_val_if_fail (GST_IS_BUS (bus), NULL);
 
   g_mutex_lock (bus->queue_lock);
-  message = g_queue_peek_head (bus->queue);
+  message = gst_atomic_queue_peek (bus->queue);
   if (message)
     gst_message_ref (message);
   g_mutex_unlock (bus->queue_lock);
@@ -702,24 +690,13 @@ typedef struct
 {
   GSource source;
   GstBus *bus;
-  gboolean inited;
 } GstBusSource;
 
 static gboolean
 gst_bus_source_prepare (GSource * source, gint * timeout)
 {
-  GstBusSource *bsrc = (GstBusSource *) source;
-
-  /* we do this here now that we know that we're attached to a main context
-   * (we don't support detaching a source from a main context and then
-   * re-attaching it to a different main context) */
-  if (G_UNLIKELY (!bsrc->inited)) {
-    gst_bus_set_main_context (bsrc->bus, g_source_get_context (source));
-    bsrc->inited = TRUE;
-  }
-
   *timeout = -1;
-  return gst_bus_have_pending (bsrc->bus);
+  return FALSE;
 }
 
 static gboolean
@@ -727,7 +704,7 @@ gst_bus_source_check (GSource * source)
 {
   GstBusSource *bsrc = (GstBusSource *) source;
 
-  return gst_bus_have_pending (bsrc->bus);
+  return bsrc->bus->priv->pollfd.revents & (G_IO_IN | G_IO_HUP | G_IO_ERR);
 }
 
 static gboolean
@@ -789,7 +766,6 @@ gst_bus_source_finalize (GSource * source)
     bus->priv->watch_id = NULL;
   GST_OBJECT_UNLOCK (bus);
 
-  gst_bus_set_main_context (bsource->bus, NULL);
   gst_object_unref (bsource->bus);
   bsource->bus = NULL;
 }
@@ -817,11 +793,12 @@ gst_bus_create_watch (GstBus * bus)
   GstBusSource *source;
 
   g_return_val_if_fail (GST_IS_BUS (bus), NULL);
+  g_return_val_if_fail (bus->priv->poll != NULL, NULL);
 
   source = (GstBusSource *) g_source_new (&gst_bus_source_funcs,
       sizeof (GstBusSource));
   source->bus = gst_object_ref (bus);
-  source->inited = FALSE;
+  g_source_add_poll ((GSource *) source, &bus->priv->pollfd);
 
   return (GSource *) source;
 }
index 30afe60..732591f 100644 (file)
@@ -28,6 +28,7 @@ typedef struct _GstBusClass GstBusClass;
 
 #include <gst/gstmessage.h>
 #include <gst/gstclock.h>
+#include <gst/gstatomicqueue.h>
 
 G_BEGIN_DECLS
 
@@ -115,7 +116,7 @@ struct _GstBus
   GstObject         object;
 
   /*< private >*/
-  GQueue           *queue;
+  GstAtomicQueue   *queue;
   GMutex           *queue_lock;
 
   GstBusSyncHandler sync_handler;
index 6cc6731..419aa7b 100644 (file)
 #include <gst/gst.h>
 #include <gobject/gvaluecollector.h>
 
-#ifdef GST_DISABLE_DEPRECATED
-#if !defined(GST_DISABLE_LOADSAVE) && !defined(GST_REMOVE_DEPRECATED)
-#include <libxml/parser.h>
-xmlNodePtr gst_caps_save_thyself (const GstCaps * caps, xmlNodePtr parent);
-GstCaps *gst_caps_load_thyself (xmlNodePtr parent);
-#endif
-#endif
-
 #define DEBUG_REFCOUNT
 
-#define CAPS_POISON(caps) G_STMT_START{ \
-  if (caps) { \
-    GstCaps *_newcaps = gst_caps_copy (caps); \
-    gst_caps_unref(caps); \
-    caps = _newcaps; \
-  } \
-} G_STMT_END
-#define STRUCTURE_POISON(structure) G_STMT_START{ \
-  if (structure) { \
-    GstStructure *_newstruct = gst_structure_copy (structure); \
-    gst_structure_free(structure); \
-    structure = _newstruct; \
-  } \
-} G_STMT_END
 #define IS_WRITABLE(caps) \
-  (g_atomic_int_get (&(caps)->refcount) == 1)
+  (GST_CAPS_REFCOUNT_VALUE (caps) == 1)
 
 /* same as gst_caps_is_any () */
 #define CAPS_IS_ANY(caps)                              \
-  ((caps)->flags & GST_CAPS_FLAGS_ANY)
+  (GST_CAPS_FLAGS(caps) & GST_CAPS_FLAGS_ANY)
 
 /* same as gst_caps_is_empty () */
 #define CAPS_IS_EMPTY(caps)                            \
@@ -118,8 +96,8 @@ GstCaps *gst_caps_load_thyself (xmlNodePtr parent);
 /* quick way to append a structure without checking the args */
 #define gst_caps_append_structure_unchecked(caps, structure) G_STMT_START{\
   GstStructure *__s=structure;                                      \
-  gst_structure_set_parent_refcount (__s, &caps->refcount);         \
-  g_ptr_array_add (caps->structs, __s);                             \
+  if (gst_structure_set_parent_refcount (__s, &GST_MINI_OBJECT_REFCOUNT(caps)))         \
+    g_ptr_array_add (caps->structs, __s);                             \
 }G_STMT_END
 
 /* lock to protect multiple invocations of static caps to caps conversion */
@@ -129,26 +107,80 @@ static void gst_caps_transform_to_string (const GValue * src_value,
     GValue * dest_value);
 static gboolean gst_caps_from_string_inplace (GstCaps * caps,
     const gchar * string);
-static GstCaps *gst_caps_copy_conditional (GstCaps * src);
 
-GType
-gst_caps_get_type (void)
+GType _gst_caps_type = 0;
+
+void
+_gst_caps_initialize (void)
+{
+  _gst_caps_type = gst_mini_object_register ("GstCaps");
+
+  g_value_register_transform_func (_gst_caps_type,
+      G_TYPE_STRING, gst_caps_transform_to_string);
+}
+
+static GstCaps *
+_gst_caps_copy (const GstCaps * caps)
 {
-  static GType gst_caps_type = 0;
+  GstCaps *newcaps;
+  GstStructure *structure;
+  guint i, n;
 
-  if (G_UNLIKELY (gst_caps_type == 0)) {
-    gst_caps_type = g_boxed_type_register_static ("GstCaps",
-        (GBoxedCopyFunc) gst_caps_copy_conditional,
-        (GBoxedFreeFunc) gst_caps_unref);
+  g_return_val_if_fail (GST_IS_CAPS (caps), NULL);
+
+  newcaps = gst_caps_new_empty ();
+  GST_CAPS_FLAGS (newcaps) = GST_CAPS_FLAGS (caps);
+  n = caps->structs->len;
 
-    g_value_register_transform_func (gst_caps_type,
-        G_TYPE_STRING, gst_caps_transform_to_string);
+  for (i = 0; i < n; i++) {
+    structure = gst_caps_get_structure_unchecked (caps, i);
+    gst_caps_append_structure (newcaps, gst_structure_copy (structure));
   }
 
-  return gst_caps_type;
+  return newcaps;
 }
 
 /* creation/deletion */
+static void
+_gst_caps_free (GstCaps * caps)
+{
+  GstStructure *structure;
+  guint i, len;
+
+  /* The refcount must be 0, but since we're only called by gst_caps_unref,
+   * don't bother testing. */
+  len = caps->structs->len;
+  /* This can be used to get statistics about caps sizes */
+  /*GST_CAT_INFO (GST_CAT_CAPS, "caps size: %d", len); */
+  for (i = 0; i < len; i++) {
+    structure = (GstStructure *) gst_caps_get_structure_unchecked (caps, i);
+    gst_structure_set_parent_refcount (structure, NULL);
+    gst_structure_free (structure);
+  }
+  g_ptr_array_free (caps->structs, TRUE);
+
+#ifdef DEBUG_REFCOUNT
+  GST_CAT_LOG (GST_CAT_CAPS, "freeing caps %p", caps);
+#endif
+  g_slice_free1 (GST_MINI_OBJECT_SIZE (caps), caps);
+}
+
+static void
+gst_caps_init (GstCaps * caps, gsize size)
+{
+  gst_mini_object_init (GST_MINI_OBJECT_CAST (caps), _gst_caps_type, size);
+
+  caps->mini_object.copy = (GstMiniObjectCopyFunction) _gst_caps_copy;
+  caps->mini_object.dispose = NULL;
+  caps->mini_object.free = (GstMiniObjectFreeFunction) _gst_caps_free;
+
+  /* the 32 has been determined by logging caps sizes in _gst_caps_free
+   * but g_ptr_array uses 16 anyway if it expands once, so this does not help
+   * in practise
+   * caps->structs = g_ptr_array_sized_new (32);
+   */
+  caps->structs = g_ptr_array_new ();
+}
 
 /**
  * gst_caps_new_empty:
@@ -162,17 +194,11 @@ gst_caps_get_type (void)
 GstCaps *
 gst_caps_new_empty (void)
 {
-  GstCaps *caps = g_slice_new (GstCaps);
+  GstCaps *caps;
 
-  caps->type = GST_TYPE_CAPS;
-  caps->refcount = 1;
-  caps->flags = 0;
-  caps->structs = g_ptr_array_new ();
-  /* the 32 has been determined by logging caps sizes in _gst_caps_free
-   * but g_ptr_array uses 16 anyway if it expands once, so this does not help
-   * in practise
-   * caps->structs = g_ptr_array_sized_new (32);
-   */
+  caps = g_slice_new (GstCaps);
+
+  gst_caps_init (caps, sizeof (GstCaps));
 
 #ifdef DEBUG_REFCOUNT
   GST_CAT_LOG (GST_CAT_CAPS, "created caps %p", caps);
@@ -194,7 +220,7 @@ gst_caps_new_any (void)
 {
   GstCaps *caps = gst_caps_new_empty ();
 
-  caps->flags = GST_CAPS_FLAGS_ANY;
+  GST_CAPS_FLAG_SET (caps, GST_CAPS_FLAGS_ANY);
 
   return caps;
 }
@@ -283,162 +309,6 @@ gst_caps_new_full_valist (GstStructure * structure, va_list var_args)
   return caps;
 }
 
-/**
- * gst_caps_copy:
- * @caps: the #GstCaps to copy
- *
- * Creates a new #GstCaps as a copy of the old @caps. The new caps will have a
- * refcount of 1, owned by the caller. The structures are copied as well.
- *
- * Note that this function is the semantic equivalent of a gst_caps_ref()
- * followed by a gst_caps_make_writable(). If you only want to hold on to a
- * reference to the data, you should use gst_caps_ref().
- *
- * When you are finished with the caps, call gst_caps_unref() on it.
- *
- * Returns: (transfer full): the new #GstCaps
- */
-GstCaps *
-gst_caps_copy (const GstCaps * caps)
-{
-  GstCaps *newcaps;
-  GstStructure *structure;
-  guint i, n;
-
-  g_return_val_if_fail (GST_IS_CAPS (caps), NULL);
-
-  newcaps = gst_caps_new_empty ();
-  newcaps->flags = caps->flags;
-  n = caps->structs->len;
-
-  for (i = 0; i < n; i++) {
-    structure = gst_caps_get_structure_unchecked (caps, i);
-    gst_caps_append_structure_unchecked (newcaps,
-        gst_structure_copy (structure));
-  }
-
-  return newcaps;
-}
-
-static void
-_gst_caps_free (GstCaps * caps)
-{
-  GstStructure *structure;
-  guint i, len;
-
-  /* The refcount must be 0, but since we're only called by gst_caps_unref,
-   * don't bother testing. */
-  len = caps->structs->len;
-  /* This can be used to get statistics about caps sizes */
-  /*GST_CAT_INFO (GST_CAT_CAPS, "caps size: %d", len); */
-  for (i = 0; i < len; i++) {
-    structure = (GstStructure *) gst_caps_get_structure_unchecked (caps, i);
-    gst_structure_set_parent_refcount (structure, NULL);
-    gst_structure_free (structure);
-  }
-  g_ptr_array_free (caps->structs, TRUE);
-#ifdef USE_POISONING
-  memset (caps, 0xff, sizeof (GstCaps));
-#endif
-
-#ifdef DEBUG_REFCOUNT
-  GST_CAT_LOG (GST_CAT_CAPS, "freeing caps %p", caps);
-#endif
-  g_slice_free (GstCaps, caps);
-}
-
-/**
- * gst_caps_make_writable:
- * @caps: (transfer full): the #GstCaps to make writable
- *
- * Returns a writable copy of @caps.
- *
- * If there is only one reference count on @caps, the caller must be the owner,
- * and so this function will return the caps object unchanged. If on the other
- * hand there is more than one reference on the object, a new caps object will
- * be returned. The caller's reference on @caps will be removed, and instead the
- * caller will own a reference to the returned object.
- *
- * In short, this function unrefs the caps in the argument and refs the caps
- * that it returns. Don't access the argument after calling this function. See
- * also: gst_caps_ref().
- *
- * Returns: (transfer full): the same #GstCaps object.
- */
-GstCaps *
-gst_caps_make_writable (GstCaps * caps)
-{
-  GstCaps *copy;
-
-  g_return_val_if_fail (caps != NULL, NULL);
-
-  /* we are the only instance reffing this caps */
-  if (IS_WRITABLE (caps))
-    return caps;
-
-  /* else copy */
-  GST_CAT_DEBUG (GST_CAT_PERFORMANCE, "copy caps");
-  copy = gst_caps_copy (caps);
-  gst_caps_unref (caps);
-
-  return copy;
-}
-
-/**
- * gst_caps_ref:
- * @caps: the #GstCaps to reference
- *
- * Add a reference to a #GstCaps object.
- *
- * From this point on, until the caller calls gst_caps_unref() or
- * gst_caps_make_writable(), it is guaranteed that the caps object will not
- * change. This means its structures won't change, etc. To use a #GstCaps
- * object, you must always have a refcount on it -- either the one made
- * implicitly by e.g. gst_caps_new_simple(), or via taking one explicitly with
- * this function.
- *
- * Returns: (transfer full): the same #GstCaps object.
- */
-GstCaps *
-gst_caps_ref (GstCaps * caps)
-{
-  g_return_val_if_fail (caps != NULL, NULL);
-
-#ifdef DEBUG_REFCOUNT
-  GST_CAT_TRACE (GST_CAT_REFCOUNTING, "%p %d->%d", caps,
-      GST_CAPS_REFCOUNT_VALUE (caps), GST_CAPS_REFCOUNT_VALUE (caps) + 1);
-#endif
-  g_return_val_if_fail (GST_CAPS_REFCOUNT_VALUE (caps) > 0, NULL);
-
-  g_atomic_int_inc (&caps->refcount);
-
-  return caps;
-}
-
-/**
- * gst_caps_unref:
- * @caps: (transfer full): the #GstCaps to unref
- *
- * Unref a #GstCaps and and free all its structures and the
- * structures' values when the refcount reaches 0.
- */
-void
-gst_caps_unref (GstCaps * caps)
-{
-  g_return_if_fail (caps != NULL);
-
-#ifdef DEBUG_REFCOUNT
-  GST_CAT_TRACE (GST_CAT_REFCOUNTING, "%p %d->%d", caps,
-      GST_CAPS_REFCOUNT_VALUE (caps), GST_CAPS_REFCOUNT_VALUE (caps) - 1);
-#endif
-
-  g_return_if_fail (GST_CAPS_REFCOUNT_VALUE (caps) > 0);
-
-  /* if we ended up with the refcount at zero, free the caps */
-  if (G_UNLIKELY (g_atomic_int_dec_and_test (&caps->refcount)))
-    _gst_caps_free (caps);
-}
-
 GType
 gst_static_caps_get_type (void)
 {
@@ -471,13 +341,13 @@ gst_static_caps_get (GstStaticCaps * static_caps)
   caps = (GstCaps *) static_caps;
 
   /* refcount is 0 when we need to convert */
-  if (G_UNLIKELY (g_atomic_int_get (&caps->refcount) == 0)) {
+  if (G_UNLIKELY (GST_CAPS_REFCOUNT_VALUE (caps) == 0)) {
     const char *string;
     GstCaps temp;
 
     G_LOCK (static_caps_lock);
     /* check if other thread already updated */
-    if (G_UNLIKELY (g_atomic_int_get (&caps->refcount) > 0))
+    if (G_UNLIKELY (GST_CAPS_REFCOUNT_VALUE (caps) > 0))
       goto done;
 
     string = static_caps->string;
@@ -491,24 +361,16 @@ gst_static_caps_get (GstStaticCaps * static_caps)
      * real caps, refcount last. We do this because we must leave the refcount
      * of the result caps to 0 so that other threads don't run away with the
      * caps while we are constructing it. */
-    temp.type = GST_TYPE_CAPS;
-    temp.flags = 0;
-    temp.structs = g_ptr_array_new ();
-
-    /* initialize the caps to a refcount of 1 so the caps can be writable for
-     * the next statement */
-    temp.refcount = 1;
+    gst_caps_init (&temp, sizeof (GstCaps));
 
     /* convert to string */
     if (G_UNLIKELY (!gst_caps_from_string_inplace (&temp, string)))
       g_critical ("Could not convert static caps \"%s\"", string);
 
+    gst_caps_init (caps, sizeof (GstCaps));
     /* now copy stuff over to the real caps. */
-    caps->type = temp.type;
-    caps->flags = temp.flags;
+    GST_CAPS_FLAGS (caps) = GST_CAPS_FLAGS (&temp);
     caps->structs = temp.structs;
-    /* and bump the refcount so other threads can now read */
-    g_atomic_int_set (&caps->refcount, 1);
 
     GST_CAT_LOG (GST_CAT_CAPS, "created %p", static_caps);
   done:
@@ -585,12 +447,9 @@ gst_caps_append (GstCaps * caps1, GstCaps * caps2)
   g_return_if_fail (IS_WRITABLE (caps1));
   g_return_if_fail (IS_WRITABLE (caps2));
 
-#ifdef USE_POISONING
-  CAPS_POISON (caps2);
-#endif
   if (G_UNLIKELY (CAPS_IS_ANY (caps1) || CAPS_IS_ANY (caps2))) {
     /* FIXME: this leaks */
-    caps1->flags |= GST_CAPS_FLAGS_ANY;
+    GST_CAPS_FLAGS (caps1) |= GST_CAPS_FLAGS_ANY;
     for (i = caps2->structs->len - 1; i >= 0; i--) {
       structure = gst_caps_remove_and_get_structure (caps2, i);
       gst_structure_free (structure);
@@ -627,16 +486,13 @@ gst_caps_merge (GstCaps * caps1, GstCaps * caps2)
   g_return_if_fail (IS_WRITABLE (caps1));
   g_return_if_fail (IS_WRITABLE (caps2));
 
-#ifdef USE_POISONING
-  CAPS_POISON (caps2);
-#endif
   if (G_UNLIKELY (CAPS_IS_ANY (caps1))) {
     for (i = caps2->structs->len - 1; i >= 0; i--) {
       structure = gst_caps_remove_and_get_structure (caps2, i);
       gst_structure_free (structure);
     }
   } else if (G_UNLIKELY (CAPS_IS_ANY (caps2))) {
-    caps1->flags |= GST_CAPS_FLAGS_ANY;
+    GST_CAPS_FLAGS (caps1) |= GST_CAPS_FLAGS_ANY;
     for (i = caps1->structs->len - 1; i >= 0; i--) {
       structure = gst_caps_remove_and_get_structure (caps1, i);
       gst_structure_free (structure);
@@ -674,12 +530,6 @@ gst_caps_append_structure (GstCaps * caps, GstStructure * structure)
   g_return_if_fail (IS_WRITABLE (caps));
 
   if (G_LIKELY (structure)) {
-    g_return_if_fail (structure->parent_refcount == NULL);
-#if 0
-#ifdef USE_POISONING
-    STRUCTURE_POISON (structure);
-#endif
-#endif
     gst_caps_append_structure_unchecked (caps, structure);
   }
 }
@@ -724,12 +574,6 @@ gst_caps_merge_structure (GstCaps * caps, GstStructure * structure)
     int i;
     gboolean unique = TRUE;
 
-    g_return_if_fail (structure->parent_refcount == NULL);
-#if 0
-#ifdef USE_POISONING
-    STRUCTURE_POISON (structure);
-#endif
-#endif
     /* check each structure */
     for (i = caps->structs->len - 1; i >= 0; i--) {
       structure1 = gst_caps_get_structure_unchecked (caps, i);
@@ -814,7 +658,7 @@ gst_caps_copy_nth (const GstCaps * caps, guint nth)
   g_return_val_if_fail (GST_IS_CAPS (caps), NULL);
 
   newcaps = gst_caps_new_empty ();
-  newcaps->flags = caps->flags;
+  GST_CAPS_FLAGS (newcaps) = GST_CAPS_FLAGS (caps);
 
   if (G_LIKELY (caps->structs->len > nth)) {
     structure = gst_caps_get_structure_unchecked (caps, nth);
@@ -1273,7 +1117,7 @@ gst_caps_intersect_zig_zag (const GstCaps * caps1, const GstCaps * caps2)
 
   /* caps are exactly the same pointers, just copy one caps */
   if (G_UNLIKELY (caps1 == caps2))
-    return gst_caps_copy (caps1);
+    return _gst_caps_copy (caps1);
 
   /* empty caps on either side, return empty */
   if (G_UNLIKELY (CAPS_IS_EMPTY (caps1) || CAPS_IS_EMPTY (caps2)))
@@ -1281,9 +1125,9 @@ gst_caps_intersect_zig_zag (const GstCaps * caps1, const GstCaps * caps2)
 
   /* one of the caps is any, just copy the other caps */
   if (G_UNLIKELY (CAPS_IS_ANY (caps1)))
-    return gst_caps_copy (caps2);
+    return _gst_caps_copy (caps2);
   if (G_UNLIKELY (CAPS_IS_ANY (caps2)))
-    return gst_caps_copy (caps1);
+    return _gst_caps_copy (caps1);
 
   dest = gst_caps_new_empty ();
 
@@ -1521,7 +1365,7 @@ gst_caps_subtract (const GstCaps * minuend, const GstCaps * subtrahend)
     return gst_caps_new_empty ();
   }
   if (CAPS_IS_EMPTY_SIMPLE (subtrahend))
-    return gst_caps_copy (minuend);
+    return _gst_caps_copy (minuend);
 
   /* FIXME: Do we want this here or above?
      The reason we need this is that there is no definition about what
@@ -1532,7 +1376,7 @@ gst_caps_subtract (const GstCaps * minuend, const GstCaps * subtrahend)
   sublen = subtrahend->structs->len;
   g_assert (sublen > 0);
 
-  src = gst_caps_copy (minuend);
+  src = _gst_caps_copy (minuend);
   for (i = 0; i < sublen; i++) {
     guint srclen;
 
@@ -1637,16 +1481,16 @@ gst_caps_union (const GstCaps * caps1, const GstCaps * caps2)
   g_return_val_if_fail (caps2 != NULL, NULL);
 
   if (CAPS_IS_EMPTY (caps1))
-    return gst_caps_copy (caps2);
+    return _gst_caps_copy (caps2);
 
   if (CAPS_IS_EMPTY (caps2))
-    return gst_caps_copy (caps1);
+    return _gst_caps_copy (caps1);
 
   if (CAPS_IS_ANY (caps1) || CAPS_IS_ANY (caps2))
     return gst_caps_new_any ();
 
-  dest1 = gst_caps_copy (caps1);
-  dest2 = gst_caps_copy (caps2);
+  dest1 = _gst_caps_copy (caps1);
+  dest2 = _gst_caps_copy (caps2);
   gst_caps_append (dest1, dest2);
 
   gst_caps_do_simplify (dest1);
@@ -1707,7 +1551,7 @@ gst_caps_normalize (const GstCaps * caps)
 
   g_return_val_if_fail (GST_IS_CAPS (caps), NULL);
 
-  newcaps = gst_caps_copy (caps);
+  newcaps = _gst_caps_copy (caps);
   nf.caps = newcaps;
 
   for (i = 0; i < gst_caps_get_size (newcaps); i++) {
@@ -1833,7 +1677,7 @@ gst_caps_switch_structures (GstCaps * caps, GstStructure * old,
 {
   gst_structure_set_parent_refcount (old, NULL);
   gst_structure_free (old);
-  gst_structure_set_parent_refcount (new, &caps->refcount);
+  gst_structure_set_parent_refcount (new, &GST_CAPS_REFCOUNT (caps));
   g_ptr_array_index (caps->structs, i) = new;
 }
 
@@ -1899,84 +1743,9 @@ gst_caps_do_simplify (GstCaps * caps)
   return TRUE;
 }
 
-/* persistence */
-
-#if !defined(GST_DISABLE_LOADSAVE) && !defined(GST_REMOVE_DEPRECATED)
-/**
- * gst_caps_save_thyself:
- * @caps: a #GstCaps structure
- * @parent: a XML parent node
- *
- * Serializes a #GstCaps to XML and adds it as a child node of @parent.
- *
- * Returns: a XML node pointer
- */
-xmlNodePtr
-gst_caps_save_thyself (const GstCaps * caps, xmlNodePtr parent)
-{
-  char *s = gst_caps_to_string (caps);
-
-  xmlNewChild (parent, NULL, (xmlChar *) "caps", (xmlChar *) s);
-  g_free (s);
-  return parent;
-}
-
-/**
- * gst_caps_load_thyself:
- * @parent: a XML node
- *
- * Creates a #GstCaps from its XML serialization.
- *
- * Returns: a new #GstCaps structure
- */
-GstCaps *
-gst_caps_load_thyself (xmlNodePtr parent)
-{
-  if (strcmp ("caps", (char *) parent->name) == 0) {
-    return gst_caps_from_string ((gchar *) xmlNodeGetContent (parent));
-  }
-
-  return NULL;
-}
-#endif
-
 /* utility */
 
 /**
- * gst_caps_replace:
- * @caps: (inout) (transfer full): a pointer to #GstCaps
- * @newcaps: a #GstCaps to replace *caps
- *
- * Replaces *caps with @newcaps.  Unrefs the #GstCaps in the location
- * pointed to by @caps, if applicable, then modifies @caps to point to
- * @newcaps. An additional ref on @newcaps is taken.
- *
- * This function does not take any locks so you might want to lock
- * the object owning @caps pointer.
- */
-void
-gst_caps_replace (GstCaps ** caps, GstCaps * newcaps)
-{
-  GstCaps *oldcaps;
-
-  g_return_if_fail (caps != NULL);
-
-  oldcaps = *caps;
-
-  GST_CAT_TRACE (GST_CAT_REFCOUNTING, "%p, %p -> %p", caps, oldcaps, newcaps);
-
-  if (newcaps != oldcaps) {
-    if (newcaps)
-      gst_caps_ref (newcaps);
-
-    *caps = newcaps;
-
-    if (oldcaps)
-      gst_caps_unref (oldcaps);
-  }
-}
-
-/**
  * gst_caps_to_string:
  * @caps: a #GstCaps
  *
@@ -2048,7 +1817,7 @@ gst_caps_from_string_inplace (GstCaps * caps, const gchar * string)
   gchar *s;
 
   if (strcmp ("ANY", string) == 0) {
-    caps->flags = GST_CAPS_FLAGS_ANY;
+    GST_CAPS_FLAGS (caps) = GST_CAPS_FLAGS_ANY;
     return TRUE;
   }
   if (strcmp ("EMPTY", string) == 0) {
@@ -2115,13 +1884,3 @@ gst_caps_transform_to_string (const GValue * src_value, GValue * dest_value)
   dest_value->data[0].v_pointer =
       gst_caps_to_string (src_value->data[0].v_pointer);
 }
-
-static GstCaps *
-gst_caps_copy_conditional (GstCaps * src)
-{
-  if (src) {
-    return gst_caps_ref (src);
-  } else {
-    return NULL;
-  }
-}
index b7c5c0f..78aa277 100644 (file)
 #define __GST_CAPS_H__
 
 #include <gst/gstconfig.h>
+#include <gst/gstminiobject.h>
 #include <gst/gststructure.h>
 #include <gst/glib-compat.h>
 
 G_BEGIN_DECLS
 
-#define GST_TYPE_CAPS             (gst_caps_get_type())
-#define GST_CAPS(object)          ((GstCaps*)object)
-#define GST_IS_CAPS(object)       ((object) && (GST_CAPS(object)->type == GST_TYPE_CAPS))
+extern GType _gst_caps_type;
+
+#define GST_TYPE_CAPS             (_gst_caps_type)
+#define GST_IS_CAPS(obj)          (GST_IS_MINI_OBJECT_TYPE((obj), GST_TYPE_CAPS))
+#define GST_CAPS_CAST(obj)        ((GstCaps*)(obj))
+#define GST_CAPS(obj)             (GST_CAPS_CAST(obj))
 
 #define GST_TYPE_STATIC_CAPS      (gst_static_caps_get_type())
 
@@ -40,7 +44,7 @@ G_BEGIN_DECLS
  * Extra flags for a caps.
  */
 typedef enum {
-  GST_CAPS_FLAGS_ANY   = (1 << 0)
+  GST_CAPS_FLAGS_ANY   = (GST_MINI_OBJECT_FLAG_LAST << 0)
 } GstCapsFlags;
 
 /**
@@ -114,21 +118,6 @@ typedef enum {
  */
 #define GST_CAPS_IS_SIMPLE(caps) (gst_caps_get_size(caps) == 1)
 
-#ifndef GST_DISABLE_DEPRECATED
-/**
- * GST_DEBUG_CAPS:
- * @string: a string that should be prepended to the caps data.
- * @caps: the #GstCaps instance to print
- *
- * Convenience macro for printing out the contents of caps with GST_DEBUG().
- *
- * Deprecated: do not use anymore
- */
-#define GST_DEBUG_CAPS(string, caps) \
-  GST_DEBUG ( string "%s: " GST_PTR_FORMAT, caps)
-
-#endif /* GST_DISABLE_DEPRECATED */
-
 /**
  * GST_STATIC_CAPS:
  * @string: the string describing the caps
@@ -138,7 +127,8 @@ typedef enum {
  */
 #define GST_STATIC_CAPS(string) \
 { \
-  /* caps */ { 0, 0, (GstCapsFlags) 0, NULL, GST_PADDING_INIT }, \
+  /* miniobject */ { { 0, 0, 0, 0, NULL, NULL, NULL }, \
+  /* caps */ NULL,  GST_PADDING_INIT }, \
   /* string */ string, \
   GST_PADDING_INIT \
 }
@@ -146,6 +136,14 @@ typedef enum {
 typedef struct _GstCaps GstCaps;
 typedef struct _GstStaticCaps GstStaticCaps;
 
+/**
+ * GST_CAPS_FLAGS:
+ * @caps: a #GstCaps.
+ *
+ * A flags word containing #GstCapsFlags flags set on this caps.
+ */
+#define GST_CAPS_FLAGS(caps)                    GST_MINI_OBJECT_FLAGS(caps)
+
 /* refcount */
 /**
  * GST_CAPS_REFCOUNT:
@@ -153,32 +151,168 @@ typedef struct _GstStaticCaps GstStaticCaps;
  *
  * Get access to the reference count field of the caps
  */
-#define GST_CAPS_REFCOUNT(caps)                 ((GST_CAPS(caps))->refcount)
+#define GST_CAPS_REFCOUNT(caps)                 GST_MINI_OBJECT_REFCOUNT(caps)
 /**
  * GST_CAPS_REFCOUNT_VALUE:
  * @caps: a #GstCaps
  *
  * Get the reference count value of the caps.
  */
-#define GST_CAPS_REFCOUNT_VALUE(caps)           (g_atomic_int_get (&(GST_CAPS(caps))->refcount))
+#define GST_CAPS_REFCOUNT_VALUE(caps)           GST_MINI_OBJECT_REFCOUNT_VALUE(caps)
+
+/**
+ * GST_CAPS_FLAG_IS_SET:
+ * @caps: a #GstCaps.
+ * @flag: the #GstCapsFlag to check.
+ *
+ * Gives the status of a specific flag on a caps.
+ */
+#define GST_CAPS_FLAG_IS_SET(caps,flag)        GST_MINI_OBJECT_FLAG_IS_SET (caps, flag)
+/**
+ * GST_CAPS_FLAG_SET:
+ * @caps: a #GstCaps.
+ * @flag: the #GstCapsFlag to set.
+ *
+ * Sets a caps flag on a caps.
+ */
+#define GST_CAPS_FLAG_SET(caps,flag)           GST_MINI_OBJECT_FLAG_SET (caps, flag)
+/**
+ * GST_CAPS_FLAG_UNSET:
+ * @caps: a #GstCaps.
+ * @flag: the #GstCapsFlag to clear.
+ *
+ * Clears a caps flag.
+ */
+#define GST_CAPS_FLAG_UNSET(caps,flag)         GST_MINI_OBJECT_FLAG_UNSET (caps, flag)
+
+/* refcounting */
+/**
+ * gst_caps_ref:
+ * @caps: the #GstCaps to reference
+ *
+ * Add a reference to a #GstCaps object.
+ *
+ * From this point on, until the caller calls gst_caps_unref() or
+ * gst_caps_make_writable(), it is guaranteed that the caps object will not
+ * change. This means its structures won't change, etc. To use a #GstCaps
+ * object, you must always have a refcount on it -- either the one made
+ * implicitly by e.g. gst_caps_new_simple(), or via taking one explicitly with
+ * this function.
+ *
+ * Returns: the same #GstCaps object.
+ */
+#ifdef _FOOL_GTK_DOC_
+G_INLINE_FUNC GstCaps * gst_caps_ref (GstCaps * caps);
+#endif
+
+static inline GstCaps *
+gst_caps_ref (GstCaps * caps)
+{
+  return (GstCaps *) gst_mini_object_ref (GST_MINI_OBJECT_CAST (caps));
+}
+
+/**
+ * gst_caps_unref:
+ * @caps: a #GstCaps.
+ *
+ * Unref a #GstCaps and and free all its structures and the
+ * structures' values when the refcount reaches 0.
+ */
+#ifdef _FOOL_GTK_DOC_
+G_INLINE_FUNC void gst_caps_unref (GstCaps * caps);
+#endif
+
+static inline void
+gst_caps_unref (GstCaps * caps)
+{
+  gst_mini_object_unref (GST_MINI_OBJECT_CAST (caps));
+}
+
+/* copy caps */
+/**
+ * gst_caps_copy:
+ * @caps: a #GstCaps.
+ *
+ * Creates a new #GstCaps as a copy of the old @caps. The new caps will have a
+ * refcount of 1, owned by the caller. The structures are copied as well.
+ *
+ * Note that this function is the semantic equivalent of a gst_caps_ref()
+ * followed by a gst_caps_make_writable(). If you only want to hold on to a
+ * reference to the data, you should use gst_caps_ref().
+ *
+ * When you are finished with the caps, call gst_caps_unref() on it.
+ *
+ * Returns: the new #GstCaps
+ */
+#ifdef _FOOL_GTK_DOC_
+G_INLINE_FUNC GstCaps * gst_caps_copy (const GstCaps * caps);
+#endif
+
+static inline GstCaps *
+gst_caps_copy (const GstCaps * caps)
+{
+  return GST_CAPS (gst_mini_object_copy (GST_MINI_OBJECT_CAST (caps)));
+}
+
+/**
+ * gst_caps_is_writable:
+ * @caps: a #GstCaps
+ *
+ * Tests if you can safely modify @caps. It is only safe to modify caps when
+ * there is only one owner of the caps - ie, the refcount is 1.
+ */
+#define         gst_caps_is_writable(caps)     gst_mini_object_is_writable (GST_MINI_OBJECT_CAST (caps))
+
+/**
+ * gst_caps_make_writable:
+ * @caps: (transfer full): a #GstCaps
+ *
+ * Returns a writable copy of @caps.
+ *
+ * If there is only one reference count on @caps, the caller must be the owner,
+ * and so this function will return the caps object unchanged. If on the other
+ * hand there is more than one reference on the object, a new caps object will
+ * be returned. The caller's reference on @caps will be removed, and instead the
+ * caller will own a reference to the returned object.
+ *
+ * In short, this function unrefs the caps in the argument and refs the caps
+ * that it returns. Don't access the argument after calling this function. See
+ * also: gst_caps_ref().
+ *
+ * Returns: (transfer full): a writable caps which may or may not be the
+ *     same as @caps
+ */
+#define         gst_caps_make_writable(caps)   GST_CAPS_CAST (gst_mini_object_make_writable (GST_MINI_OBJECT_CAST (caps)))
+
+/**
+ * gst_caps_replace:
+ * @ocaps: (inout) (transfer full): pointer to a pointer to a #GstCaps to be
+ *     replaced.
+ * @ncaps: (transfer none) (allow-none): pointer to a #GstCaps that will
+ *     replace the caps pointed to by @ocaps.
+ *
+ * Modifies a pointer to a #GstCaps to point to a different #GstCaps. The
+ * modification is done atomically (so this is useful for ensuring thread safety
+ * in some cases), and the reference counts are updated appropriately (the old
+ * caps is unreffed, the new is reffed).
+ *
+ * Either @ncaps or the #GstCaps pointed to by @ocaps may be NULL.
+ */
+#define         gst_caps_replace(ocaps,ncaps) \
+G_STMT_START {                                                                \
+  GstCaps **___ocapsaddr = (GstCaps **)(ocaps);         \
+  gst_mini_object_replace ((GstMiniObject **)___ocapsaddr, \
+      GST_MINI_OBJECT_CAST (ncaps));                       \
+} G_STMT_END
 
 /**
  * GstCaps:
- * @type: GType of the caps
- * @refcount: the atomic refcount value
- * @flags: extra flags for the caps, read only.
+ * @mini_object: the parent type
  *
  * Object describing media types.
  */
 struct _GstCaps {
-  GType type;
-
-  /*< public >*/ /* with COW */
-  /* refcounting */
-  gint           refcount;
-
-  /*< public >*/ /* read only */
-  GstCapsFlags flags;
+  GstMiniObject mini_object;
 
   /*< private >*/
   GPtrArray *structs;
@@ -205,7 +339,6 @@ struct _GstStaticCaps {
   gpointer _gst_reserved[GST_PADDING];
 };
 
-GType             gst_caps_get_type                (void);
 GstCaps *         gst_caps_new_empty               (void);
 GstCaps *         gst_caps_new_any                 (void);
 GstCaps *         gst_caps_new_simple              (const char    *media_type,
@@ -215,12 +348,6 @@ GstCaps *         gst_caps_new_full                (GstStructure  *struct1, ...)
 GstCaps *         gst_caps_new_full_valist         (GstStructure  *structure,
                                                     va_list        var_args);
 
-/* reference counting */
-GstCaps *         gst_caps_ref                     (GstCaps       *caps);
-GstCaps *         gst_caps_copy                    (const GstCaps *caps);
-GstCaps *         gst_caps_make_writable           (GstCaps       *caps) G_GNUC_WARN_UNUSED_RESULT;
-void              gst_caps_unref                   (GstCaps       *caps);
-
 GType             gst_static_caps_get_type         (void);
 GstCaps *         gst_static_caps_get              (GstStaticCaps *static_caps);
 
@@ -281,15 +408,7 @@ GstCaps *         gst_caps_union                   (const GstCaps *caps1,
 GstCaps *         gst_caps_normalize               (const GstCaps *caps);
 gboolean          gst_caps_do_simplify             (GstCaps       *caps);
 
-#if !defined(GST_DISABLE_LOADSAVE) && !defined(GST_DISABLE_DEPRECATED)
-xmlNodePtr        gst_caps_save_thyself            (const GstCaps *caps,
-                                                    xmlNodePtr     parent);
-GstCaps *         gst_caps_load_thyself            (xmlNodePtr     parent);
-#endif
-
 /* utility */
-void              gst_caps_replace                 (GstCaps      **caps,
-                                                    GstCaps       *newcaps);
 gchar *           gst_caps_to_string               (const GstCaps *caps);
 GstCaps *         gst_caps_from_string             (const gchar   *string);
 
index 45f503e..b167238 100644 (file)
@@ -489,26 +489,10 @@ gst_clock_id_wait (GstClockID id, GstClockTimeDiff * jitter)
   GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock, "waiting on clock entry %p", id);
 
   /* if we have a wait_jitter function, use that */
-  if (G_LIKELY (cclass->wait_jitter)) {
-    res = cclass->wait_jitter (clock, entry, jitter);
-  } else {
-    /* check if we have a simple _wait function otherwise. The function without
-     * the jitter arg is less optimal as we need to do an additional _get_time()
-     * which is not atomic with the _wait() and a typical _wait() function does
-     * yet another _get_time() anyway. */
-    if (G_UNLIKELY (cclass->wait == NULL))
-      goto not_supported;
-
-    if (jitter) {
-      GstClockTime now = gst_clock_get_time (clock);
-
-      /* jitter is the diff against the clock when this entry is scheduled. Negative
-       * values mean that the entry was in time, a positive value means that the
-       * entry was too late. */
-      *jitter = GST_CLOCK_DIFF (requested, now);
-    }
-    res = cclass->wait (clock, entry);
-  }
+  if (G_UNLIKELY (cclass->wait == NULL))
+    goto not_supported;
+
+  res = cclass->wait (clock, entry, jitter);
 
   GST_CAT_DEBUG_OBJECT (GST_CAT_CLOCK, clock,
       "done waiting entry %p, res: %d", id, res);
index 230e190..2bc9d80 100644 (file)
@@ -475,12 +475,11 @@ struct _GstClock {
  *                     be acceptable. The new resolution should be returned.
  * @get_resolution: get the resolution of the clock.
  * @get_internal_time: get the internal unadjusted time of the clock.
- * @wait: perform a blocking wait for the given #GstClockEntry. Deprecated,
  *        implement @wait_jitter instead.
+ * @wait: perform a blocking wait on the given #GstClockEntry and return
+ *               the jitter.
  * @wait_async: perform an asynchronous wait for the given #GstClockEntry.
  * @unschedule: unblock a blocking or async wait operation.
- * @wait_jitter: perform a blocking wait on the given #GstClockEntry and return
- *               the jitter. (Since: 0.10.10)
  *
  * GStreamer clock class. Override the vmethods to implement the clock
  * functionality.
@@ -498,15 +497,13 @@ struct _GstClockClass {
   GstClockTime         (*get_internal_time)    (GstClock *clock);
 
   /* waiting on an ID */
-  GstClockReturn        (*wait)                        (GstClock *clock, GstClockEntry *entry);
+  GstClockReturn        (*wait)                 (GstClock *clock, GstClockEntry *entry,
+                                                GstClockTimeDiff *jitter);
   GstClockReturn        (*wait_async)           (GstClock *clock, GstClockEntry *entry);
   void                  (*unschedule)          (GstClock *clock, GstClockEntry *entry);
 
-  /* ABI added to replace the deprecated wait */
-  GstClockReturn        (*wait_jitter)         (GstClock *clock, GstClockEntry *entry,
-                                                GstClockTimeDiff *jitter);
   /*< private >*/
-  gpointer _gst_reserved[GST_PADDING - 1];
+  gpointer _gst_reserved[GST_PADDING];
 };
 
 GType                  gst_clock_get_type              (void);
index cf2d898..cba5fc2 100644 (file)
 
 G_BEGIN_DECLS
 
+/* added to ease the transition to 0.11 */
+#define gst_element_class_set_details_simple  gst_element_class_set_metadata
+
+#define gst_element_factory_get_longname(f)    gst_element_factory_get_metadata(f, GST_ELEMENT_METADATA_LONGNAME)
+#define gst_element_factory_get_klass(f)       gst_element_factory_get_metadata(f, GST_ELEMENT_METADATA_KLASS)
+#define gst_element_factory_get_description(f) gst_element_factory_get_metadata(f, GST_ELEMENT_METADATA_DESCRIPTION)
+#define gst_element_factory_get_author(f)      gst_element_factory_get_metadata(f, GST_ELEMENT_METADATA_AUTHOR)
+#define gst_element_factory_get_documentation_uri(f)  gst_element_factory_get_metadata(f, GST_ELEMENT_METADATA_DOC_URI)
+#define gst_element_factory_get_icon_name(f)   gst_element_factory_get_metadata(f, GST_ELEMENT_METADATA_ICON_NAME)
+
+#define gst_pad_get_caps_reffed(p)             gst_pad_get_caps(p)
+#define gst_pad_peer_get_caps_reffed(p)        gst_pad_peer_get_caps(p)
+
+//#define gst_buffer_create_sub(b,o,s)           gst_buffer_copy_region(b,GST_BUFFER_COPY_ALL,o,s)
+
+#define gst_buffer_new_and_alloc(s)            gst_buffer_new_allocate(NULL, s, 0)
+
+
 #ifndef GST_DISABLE_DEPRECATED
 
 #endif /* not GST_DISABLE_DEPRECATED */
index 4138b18..7af2496 100644 (file)
 
 #if 0
 #define GST_DISABLE_GST_DEBUG 1
-#define GST_DISABLE_LOADSAVE 1
 #define GST_DISABLE_PARSE 1
 #define GST_DISABLE_TRACE 1
 #define GST_DISABLE_ALLOC_TRACE 1
 #define GST_DISABLE_REGISTRY 1
 #define GST_DISABLE_PLUGIN 1
-#define GST_DISABLE_XML 1
-#define GST_DISABLE_LOADSAVE_REGISTRY 1
 #define GST_HAVE_GLIB_2_8 1
 #endif
 
 @GST_DISABLE_GST_DEBUG_DEFINE@
 
 /**
- * GST_DISABLE_LOADSAVE:
- *
- * Configures the inclusion of the plugin graph xml-serialisation
- * (was used in 0.8 by gst-editor)
- */
-@GST_DISABLE_LOADSAVE_DEFINE@
-
-/**
  * GST_DISABLE_PARSE:
  *
  * Configures the inclusion of the gst-lauch parser
  */
 @GST_DISABLE_REGISTRY_DEFINE@
 
-/**
- * GST_DISABLE_XML:
- *
- * Configures the use libxml2. This setting is derived from the settings of
- * %GST_DISABLE_LOADSAVE and %GST_DISABLE_REGISTRY (in the xml registry case).
- */
-@GST_DISABLE_XML_DEFINE@
-
 /* FIXME: test and document these! */
 /* Configures the use of external plugins */
 @GST_DISABLE_PLUGIN_DEFINE@
 /* whether or not the CPU supports unaligned access */
 @GST_HAVE_UNALIGNED_ACCESS_DEFINE@
 
-/* FIXME: 0.11 (remove)
- * whether or not we are using glib 2.8 api, e.g. atomic gobject
- * refcounting */
-@GST_HAVE_GLIB_2_8_DEFINE@
-
-/***** Deal with XML stuff, we have to handle both loadsave and registry *****/
-/* FIXME: move include to where we need it */
-/*#if (! (defined(GST_DISABLE_LOADSAVE) && defined(GST_DISABLE_REGISTRY)) )*/
-#ifndef GST_DISABLE_XML
-#ifndef GST_DISABLE_DEPRECATED
-# include <libxml/parser.h>
-#endif
-#else
-  /* FIXME: 0.11 (replace by GST_DISABLE_XML) */
-# define GST_DISABLE_LOADSAVE_REGISTRY
-#endif
-
 /**
  * GST_EXPORT:
  *
index 3bca9f7..c28a6ab 100644 (file)
@@ -159,16 +159,15 @@ debug_dump_pad (GstPad * pad, const gchar * color_name,
     }
   }
   if (details & GST_DEBUG_GRAPH_SHOW_STATES) {
-    gchar pad_flags[6];
+    gchar pad_flags[5];
     const gchar *activation_mode = "-><";
 
     /* check if pad flags */
     pad_flags[0] = GST_OBJECT_FLAG_IS_SET (pad, GST_PAD_BLOCKED) ? 'B' : 'b';
     pad_flags[1] = GST_OBJECT_FLAG_IS_SET (pad, GST_PAD_FLUSHING) ? 'F' : 'f';
     pad_flags[2] = GST_OBJECT_FLAG_IS_SET (pad, GST_PAD_IN_GETCAPS) ? 'G' : 'g';
-    pad_flags[3] = GST_OBJECT_FLAG_IS_SET (pad, GST_PAD_IN_SETCAPS) ? 'S' : 's';
-    pad_flags[4] = GST_OBJECT_FLAG_IS_SET (pad, GST_PAD_BLOCKING) ? 'B' : 'b';
-    pad_flags[5] = '\0';
+    pad_flags[3] = GST_OBJECT_FLAG_IS_SET (pad, GST_PAD_BLOCKING) ? 'B' : 'b';
+    pad_flags[4] = '\0';
 
     fprintf (out,
         "%s  %s_%s [color=black, fillcolor=\"%s\", label=\"%s\\n[%c][%s]\", height=\"0.2\", style=\"%s\"];\n",
@@ -473,6 +472,8 @@ debug_dump_element (GstBin * bin, GstDebugGraphDetails details, FILE * out,
 {
   GstIterator *element_iter, *pad_iter;
   gboolean elements_done, pads_done;
+  GValue item = { 0, };
+  GValue item2 = { 0, };
   GstElement *element;
   GstPad *pad;
   GstPadDirection dir;
@@ -485,8 +486,9 @@ debug_dump_element (GstBin * bin, GstDebugGraphDetails details, FILE * out,
   element_iter = gst_bin_iterate_elements (bin);
   elements_done = FALSE;
   while (!elements_done) {
-    switch (gst_iterator_next (element_iter, (gpointer) & element)) {
+    switch (gst_iterator_next (element_iter, &item)) {
       case GST_ITERATOR_OK:
+        element = g_value_get_object (&item);
         element_name = debug_dump_make_object_name (GST_OBJECT (element));
 
         if (details & GST_DEBUG_GRAPH_SHOW_STATES) {
@@ -519,15 +521,16 @@ debug_dump_element (GstBin * bin, GstDebugGraphDetails details, FILE * out,
         if ((pad_iter = gst_element_iterate_pads (element))) {
           pads_done = FALSE;
           while (!pads_done) {
-            switch (gst_iterator_next (pad_iter, (gpointer) & pad)) {
+            switch (gst_iterator_next (pad_iter, &item2)) {
               case GST_ITERATOR_OK:
+                pad = g_value_get_object (&item2);
                 debug_dump_element_pad (pad, element, details, out, indent);
                 dir = gst_pad_get_direction (pad);
                 if (dir == GST_PAD_SRC)
                   src_pads++;
                 else if (dir == GST_PAD_SINK)
                   sink_pads++;
-                gst_object_unref (pad);
+                g_value_reset (&item2);
                 break;
               case GST_ITERATOR_RESYNC:
                 gst_iterator_resync (pad_iter);
@@ -538,6 +541,7 @@ debug_dump_element (GstBin * bin, GstDebugGraphDetails details, FILE * out,
                 break;
             }
           }
+          g_value_unset (&item2);
           gst_iterator_free (pad_iter);
         }
         if (GST_IS_BIN (element)) {
@@ -558,14 +562,15 @@ debug_dump_element (GstBin * bin, GstDebugGraphDetails details, FILE * out,
         if ((pad_iter = gst_element_iterate_pads (element))) {
           pads_done = FALSE;
           while (!pads_done) {
-            switch (gst_iterator_next (pad_iter, (gpointer) & pad)) {
+            switch (gst_iterator_next (pad_iter, &item2)) {
               case GST_ITERATOR_OK:
+                pad = g_value_get_object (&item2);
                 if (gst_pad_is_linked (pad)
                     && gst_pad_get_direction (pad) == GST_PAD_SRC) {
                   debug_dump_element_pad_link (pad, element, details, out,
                       indent);
                 }
-                gst_object_unref (pad);
+                g_value_reset (&item2);
                 break;
               case GST_ITERATOR_RESYNC:
                 gst_iterator_resync (pad_iter);
@@ -576,9 +581,10 @@ debug_dump_element (GstBin * bin, GstDebugGraphDetails details, FILE * out,
                 break;
             }
           }
+          g_value_unset (&item2);
           gst_iterator_free (pad_iter);
         }
-        gst_object_unref (element);
+        g_value_reset (&item);
         break;
       case GST_ITERATOR_RESYNC:
         gst_iterator_resync (element_iter);
@@ -589,6 +595,7 @@ debug_dump_element (GstBin * bin, GstDebugGraphDetails details, FILE * out,
         break;
     }
   }
+  g_value_unset (&item);
   gst_iterator_free (element_iter);
 }
 
index ddbba3e..602601c 100644 (file)
@@ -82,7 +82,7 @@
 #include <gobject/gvaluecollector.h>
 
 #include "gstelement.h"
-#include "gstelementdetails.h"
+#include "gstelementmetadata.h"
 #include "gstenumtypes.h"
 #include "gstbus.h"
 #include "gstmarshal.h"
@@ -109,16 +109,6 @@ enum
       /* FILL ME */
 };
 
-#ifdef GST_DISABLE_DEPRECATED
-#if !defined(GST_DISABLE_LOADSAVE) && !defined(GST_REMOVE_DEPRECATED)
-#include <libxml/parser.h>
-xmlNodePtr gst_object_save_thyself (const GstObject * object,
-    xmlNodePtr parent);
-GstObject *gst_object_load_thyself (xmlNodePtr parent);
-void gst_pad_load_and_link (xmlNodePtr self, GstObject * parent);
-#endif
-#endif
-
 static void gst_element_class_init (GstElementClass * klass);
 static void gst_element_init (GstElement * element);
 static void gst_element_base_class_init (gpointer g_class);
@@ -144,12 +134,6 @@ static GstPadTemplate
     * gst_element_class_get_request_pad_template (GstElementClass *
     element_class, const gchar * name);
 
-#if !defined(GST_DISABLE_LOADSAVE) && !defined(GST_REMOVE_DEPRECATED)
-static xmlNodePtr gst_element_save_thyself (GstObject * object,
-    xmlNodePtr parent);
-static void gst_element_restore_thyself (GstObject * parent, xmlNodePtr self);
-#endif
-
 static GstObjectClass *parent_class = NULL;
 static guint gst_element_signals[LAST_SIGNAL] = { 0 };
 
@@ -190,10 +174,8 @@ static void
 gst_element_class_init (GstElementClass * klass)
 {
   GObjectClass *gobject_class;
-  GstObjectClass *gstobject_class;
 
   gobject_class = (GObjectClass *) klass;
-  gstobject_class = (GstObjectClass *) klass;
 
   parent_class = g_type_class_peek_parent (klass);
 
@@ -239,15 +221,6 @@ gst_element_class_init (GstElementClass * klass)
   gobject_class->dispose = gst_element_dispose;
   gobject_class->finalize = gst_element_finalize;
 
-#if !defined(GST_DISABLE_LOADSAVE) && !defined(GST_REMOVE_DEPRECATED)
-  gstobject_class->save_thyself =
-      ((gpointer (*)(GstObject * object,
-              gpointer self)) * GST_DEBUG_FUNCPTR (gst_element_save_thyself));
-  gstobject_class->restore_thyself =
-      ((void (*)(GstObject * object,
-              gpointer self)) *GST_DEBUG_FUNCPTR (gst_element_restore_thyself));
-#endif
-
   klass->change_state = GST_DEBUG_FUNCPTR (gst_element_change_state_func);
   klass->set_state = GST_DEBUG_FUNCPTR (gst_element_set_state_func);
   klass->get_state = GST_DEBUG_FUNCPTR (gst_element_get_state_func);
@@ -263,19 +236,25 @@ static void
 gst_element_base_class_init (gpointer g_class)
 {
   GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
-
-  /* FIXME 0.11: Copy the element details and instead of clearing the
-   * pad template list copy the list and increase the refcount of
-   * the pad templates by one.
-   *
-   * This will make it possible to add pad templates and set element
-   * details in the class_init functions and is the real GObject way
-   * of doing things.
-   * See http://bugzilla.gnome.org/show_bug.cgi?id=491501
+  GList *node, *padtemplates;
+
+  /* Copy the element details here so elements can inherit the
+   * details from their base class and classes only need to set
+   * the details in class_init instead of base_init */
+  element_class->metadata =
+      element_class->metadata ? gst_structure_copy (element_class->metadata) :
+      gst_structure_empty_new ("metadata");
+
+  /* Copy the pad templates so elements inherit them
+   * from their base class but elements can add pad templates in class_init
+   * instead of base_init.
    */
-  memset (&element_class->details, 0, sizeof (GstElementDetails));
-  element_class->meta_data = NULL;
-  element_class->padtemplates = NULL;
+  padtemplates = g_list_copy (element_class->padtemplates);
+  for (node = padtemplates; node != NULL; node = node->next) {
+    GstPadTemplate *tmpl = (GstPadTemplate *) node->data;
+    gst_object_ref (tmpl);
+  }
+  element_class->padtemplates = padtemplates;
 
   /* set the factory, see gst_element_register() */
   element_class->elementfactory =
@@ -292,11 +271,8 @@ gst_element_base_class_finalize (gpointer g_class)
 
   g_list_foreach (klass->padtemplates, (GFunc) gst_object_unref, NULL);
   g_list_free (klass->padtemplates);
-  __gst_element_details_clear (&klass->details);
-  if (klass->meta_data) {
-    gst_structure_free (klass->meta_data);
-    klass->meta_data = NULL;
-  }
+
+  gst_structure_free (klass->metadata);
 }
 
 static void
@@ -308,9 +284,7 @@ gst_element_init (GstElement * element)
   GST_STATE_PENDING (element) = GST_STATE_VOID_PENDING;
   GST_STATE_RETURN (element) = GST_STATE_CHANGE_SUCCESS;
 
-  /* FIXME 0.11: Store this directly in the instance struct */
-  element->state_lock = g_slice_new (GStaticRecMutex);
-  g_static_rec_mutex_init (element->state_lock);
+  g_static_rec_mutex_init (&element->state_lock);
   element->state_cond = g_cond_new ();
 }
 
@@ -887,12 +861,15 @@ gst_element_remove_pad (GstElement * element, GstPad * pad)
   /* ERRORS */
 not_our_pad:
   {
-    /* FIXME, locking order? */
+    /* locking order is element > pad */
+    GST_OBJECT_UNLOCK (pad);
+
     GST_OBJECT_LOCK (element);
+    GST_OBJECT_LOCK (pad);
     g_critical ("Padname %s:%s does not belong to element %s when removing",
         GST_DEBUG_PAD_NAME (pad), GST_ELEMENT_NAME (element));
-    GST_OBJECT_UNLOCK (element);
     GST_OBJECT_UNLOCK (pad);
+    GST_OBJECT_UNLOCK (element);
     return FALSE;
   }
 }
@@ -1031,10 +1008,8 @@ _gst_element_request_pad (GstElement * element, GstPadTemplate * templ,
   }
 #endif
 
-  if (oclass->request_new_pad_full)
-    newpad = (oclass->request_new_pad_full) (element, templ, name, caps);
-  else if (oclass->request_new_pad)
-    newpad = (oclass->request_new_pad) (element, templ, name);
+  if (oclass->request_new_pad)
+    newpad = (oclass->request_new_pad) (element, templ, name, caps);
 
   if (newpad)
     gst_object_ref (newpad);
@@ -1176,63 +1151,15 @@ gst_element_request_pad (GstElement * element,
   return _gst_element_request_pad (element, templ, name, caps);
 }
 
-/**
- * gst_element_get_pad:
- * @element: a #GstElement.
- * @name: the name of the pad to retrieve.
- *
- * Retrieves a pad from @element by name. Tries gst_element_get_static_pad()
- * first, then gst_element_get_request_pad().
- *
- * Deprecated: This function is deprecated as it's unclear if the reference
- * to the result pad should be released with gst_object_unref() in case of a static pad
- * or gst_element_release_request_pad() in case of a request pad.
- * Use gst_element_get_static_pad() or gst_element_get_request_pad() instead.
- *
- * Returns: (transfer full): the #GstPad if found, otherwise %NULL. Unref or Release after usage,
- * depending on the type of the pad.
- */
-#ifndef GST_REMOVE_DEPRECATED
-#ifdef GST_DISABLE_DEPRECATED
-GstPad *gst_element_get_pad (GstElement * element, const gchar * name);
-#endif
-GstPad *
-gst_element_get_pad (GstElement * element, const gchar * name)
-{
-  GstPad *pad;
-
-  g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
-  g_return_val_if_fail (name != NULL, NULL);
-
-  pad = gst_element_get_static_pad (element, name);
-  if (!pad)
-    pad = gst_element_get_request_pad (element, name);
-
-  return pad;
-}
-#endif /* GST_REMOVE_DEPRECATED */
-
-static GstIteratorItem
-iterate_pad (GstIterator * it, GstPad * pad)
-{
-  gst_object_ref (pad);
-  return GST_ITERATOR_ITEM_PASS;
-}
-
 static GstIterator *
 gst_element_iterate_pad_list (GstElement * element, GList ** padlist)
 {
   GstIterator *result;
 
   GST_OBJECT_LOCK (element);
-  gst_object_ref (element);
   result = gst_iterator_new_list (GST_TYPE_PAD,
       GST_OBJECT_GET_LOCK (element),
-      &element->pads_cookie,
-      padlist,
-      element,
-      (GstIteratorItemFunction) iterate_pad,
-      (GstIteratorDisposeFunction) gst_object_unref);
+      &element->pads_cookie, padlist, (GObject *) element, NULL);
   GST_OBJECT_UNLOCK (element);
 
   return result;
@@ -1299,116 +1226,66 @@ gst_element_iterate_sink_pads (GstElement * element)
 /**
  * gst_element_class_add_pad_template:
  * @klass: the #GstElementClass to add the pad template to.
- * @templ: (transfer none): a #GstPadTemplate to add to the element class.
+ * @templ: (transfer full): a #GstPadTemplate to add to the element class.
+ *
+ * Adds a padtemplate to an element class. This is mainly used in the _class_init
+ * functions of classes. If a pad template with the same name as an already
+ * existing one is added the old one is replaced by the new one.
  *
- * Adds a padtemplate to an element class. This is mainly used in the _base_init
- * functions of classes.
  */
 void
 gst_element_class_add_pad_template (GstElementClass * klass,
     GstPadTemplate * templ)
 {
+  GList *template_list = klass->padtemplates;
+
   g_return_if_fail (GST_IS_ELEMENT_CLASS (klass));
   g_return_if_fail (GST_IS_PAD_TEMPLATE (templ));
 
-  /* FIXME 0.11: allow replacing the pad templates by
-   * calling this with the same name as an already existing pad
-   * template. For this we _must_ _not_ ref the added pad template
-   * a second time and _must_ document that this function takes
-   * ownership of the pad template. Otherwise we will leak pad templates
-   * or the caller unref's the pad template and it disappears */
-  /* avoid registering pad templates with the same name */
-  g_return_if_fail (gst_element_class_get_pad_template (klass,
-          templ->name_template) == NULL);
-
-  klass->padtemplates = g_list_append (klass->padtemplates,
-      gst_object_ref (templ));
-  klass->numpadtemplates++;
-}
+  /* If we already have a pad template with the same name replace the
+   * old one. */
+  while (template_list) {
+    GstPadTemplate *padtempl = (GstPadTemplate *) template_list->data;
 
-static void
-gst_element_class_add_meta_data (GstElementClass * klass,
-    const gchar * key, const gchar * value)
-{
-  if (!klass->meta_data) {
-    /* FIXME: use a quark for "metadata" */
-    klass->meta_data = gst_structure_empty_new ("metadata");
+    /* Found pad with the same name, replace and return */
+    if (strcmp (templ->name_template, padtempl->name_template) == 0) {
+      gst_object_unref (padtempl);
+      template_list->data = templ;
+      return;
+    }
+    template_list = g_list_next (template_list);
   }
 
-  gst_structure_set ((GstStructure *) klass->meta_data,
-      key, G_TYPE_STRING, value, NULL);
-}
-
-/**
- * gst_element_class_set_documentation_uri:
- * @klass: class to set details for
- * @uri: uri of element documentation
- *
- * Set uri pointing to user documentation. Applications can use this to show
- * help for e.g. effects to users.
- *
- * Since: 0.10.31
- */
-void
-gst_element_class_set_documentation_uri (GstElementClass * klass,
-    const gchar * uri)
-{
-  g_return_if_fail (GST_IS_ELEMENT_CLASS (klass));
-
-  gst_element_class_add_meta_data (klass, "doc-uri", uri);
-}
-
-/**
- * gst_element_class_set_icon_name:
- * @klass: class to set details for
- * @name: name of an icon
- *
- * Elements that bridge to certain other products can include an icon of that
- * used product. Application can show the icon in menus/selectors to help
- * identifying specific elements.
- *
- * Since: 0.10.31
- */
-void
-gst_element_class_set_icon_name (GstElementClass * klass, const gchar * name)
-{
-  g_return_if_fail (GST_IS_ELEMENT_CLASS (klass));
+  /* Take ownership of the floating ref */
+  g_object_ref_sink (templ);
 
-  gst_element_class_add_meta_data (klass, "icon-name", name);
+  klass->padtemplates = g_list_append (klass->padtemplates, templ);
+  klass->numpadtemplates++;
 }
 
-/* FIXME-0.11: deprecate and remove gst_element_class_set_details*() */
 /**
- * gst_element_class_set_details:
- * @klass: class to set details for
- * @details: details to set
- *
- * Sets the detailed information for a #GstElementClass.
- * <note>This function is for use in _base_init functions only.</note>
+ * gst_element_class_add_metadata:
+ * @klass: class to set metadata for
+ * @key: the key to set
+ * @value: the value to set
  *
- * The @details are copied.
- *
- * Deprecated: Use gst_element_class_set_details_simple() instead.
+ * Set @key with @value as metadata in @klass.
  */
-#ifndef GST_REMOVE_DEPRECATED
-#ifdef GST_DISABLE_DEPRECATED
-void gst_element_class_set_details (GstElementClass * klass,
-    const GstElementDetails * details);
-#endif
 void
-gst_element_class_set_details (GstElementClass * klass,
-    const GstElementDetails * details)
+gst_element_class_add_metadata (GstElementClass * klass,
+    const gchar * key, const gchar * value)
 {
   g_return_if_fail (GST_IS_ELEMENT_CLASS (klass));
-  g_return_if_fail (GST_IS_ELEMENT_DETAILS (details));
+  g_return_if_fail (key != NULL);
+  g_return_if_fail (value != NULL);
 
-  __gst_element_details_copy (&klass->details, details);
+  gst_structure_set ((GstStructure *) klass->metadata,
+      key, G_TYPE_STRING, value, NULL);
 }
-#endif
 
 /**
- * gst_element_class_set_details_simple:
- * @klass: class to set details for
+ * gst_element_class_set_metadata:
+ * @klass: class to set metadata for
  * @longname: The long English name of the element. E.g. "File Sink"
  * @classification: String describing the type of element, as an unordered list
  * separated with slashes ('/'). See draft-klass.txt of the design docs
@@ -1416,29 +1293,41 @@ gst_element_class_set_details (GstElementClass * klass,
  * @description: Sentence describing the purpose of the element.
  * E.g: "Write stream to a file"
  * @author: Name and contact details of the author(s). Use \n to separate
- * multiple author details. E.g: "Joe Bloggs &lt;joe.blogs at foo.com&gt;"
+ * multiple author metadata. E.g: "Joe Bloggs &lt;joe.blogs at foo.com&gt;"
  *
- * Sets the detailed information for a #GstElementClass. Simpler version of
- * gst_element_class_set_details() that generates less linker overhead.
- * <note>This function is for use in _base_init functions only.</note>
- *
- * The detail parameter strings are copied into the #GstElementDetails for
- * the element class.
- *
- * Since: 0.10.14
+ * Sets the detailed information for a #GstElementClass.
+ * <note>This function is for use in _class_init functions only.</note>
  */
 void
-gst_element_class_set_details_simple (GstElementClass * klass,
+gst_element_class_set_metadata (GstElementClass * klass,
     const gchar * longname, const gchar * classification,
     const gchar * description, const gchar * author)
 {
-  const GstElementDetails details =
-      GST_ELEMENT_DETAILS ((gchar *) longname, (gchar *) classification,
-      (gchar *) description, (gchar *) author);
-
   g_return_if_fail (GST_IS_ELEMENT_CLASS (klass));
 
-  __gst_element_details_copy (&klass->details, &details);
+  gst_structure_set ((GstStructure *) klass->metadata,
+      GST_ELEMENT_METADATA_LONGNAME, G_TYPE_STRING, longname,
+      GST_ELEMENT_METADATA_KLASS, G_TYPE_STRING, classification,
+      GST_ELEMENT_METADATA_DESCRIPTION, G_TYPE_STRING, description,
+      GST_ELEMENT_METADATA_AUTHOR, G_TYPE_STRING, author, NULL);
+}
+
+/**
+ * gst_element_class_get_metadata:
+ * @klass: class to get metadata for
+ * @key: the key to get
+ *
+ * Get metadata with @key in @klass.
+ *
+ * Returns: the metadata for @key.
+ */
+G_CONST_RETURN gchar *
+gst_element_class_get_metadata (GstElementClass * klass, const gchar * key)
+{
+  g_return_val_if_fail (GST_IS_ELEMENT_CLASS (klass), NULL);
+  g_return_val_if_fail (key != NULL, NULL);
+
+  return gst_structure_get_string ((GstStructure *) klass->metadata, key);
 }
 
 /**
@@ -2444,19 +2333,16 @@ complete:
 }
 
 /**
- * gst_element_lost_state_full:
+ * gst_element_lost_state:
  * @element: a #GstElement the state is lost of
- * @new_base_time: if a new base time should be distributed
  *
  * Brings the element to the lost state. The current state of the
  * element is copied to the pending state so that any call to
  * gst_element_get_state() will return %GST_STATE_CHANGE_ASYNC.
  *
- * An ASYNC_START message is posted with indication to distribute a new
- * base_time to the element when @new_base_time is %TRUE.
- * If the element was PLAYING, it will go to PAUSED. The element
- * will be restored to its PLAYING state by the parent pipeline when it
- * prerolls again.
+ * An ASYNC_START message is posted. If the element was PLAYING, it will
+ * go to PAUSED. The element will be restored to its PLAYING state by
+ * the parent pipeline when it prerolls again.
  *
  * This is mostly used for elements that lost their preroll buffer
  * in the %GST_STATE_PAUSED or %GST_STATE_PLAYING state after a flush,
@@ -2466,13 +2352,9 @@ complete:
  *
  * This function is used internally and should normally not be called from
  * plugins or applications.
- *
- * MT safe.
- *
- * Since: 0.10.24
  */
 void
-gst_element_lost_state_full (GstElement * element, gboolean new_base_time)
+gst_element_lost_state (GstElement * element)
 {
   GstState old_state, new_state;
   GstMessage *message;
@@ -2504,14 +2386,11 @@ gst_element_lost_state_full (GstElement * element, gboolean new_base_time)
   GST_STATE_NEXT (element) = new_state;
   GST_STATE_PENDING (element) = new_state;
   GST_STATE_RETURN (element) = GST_STATE_CHANGE_ASYNC;
-  if (new_base_time)
-    GST_ELEMENT_START_TIME (element) = 0;
   GST_OBJECT_UNLOCK (element);
 
   _priv_gst_element_state_changed (element, new_state, new_state, new_state);
 
-  message =
-      gst_message_new_async_start (GST_OBJECT_CAST (element), new_base_time);
+  message = gst_message_new_async_start (GST_OBJECT_CAST (element));
   gst_element_post_message (element, message);
 
   return;
@@ -2525,31 +2404,13 @@ only_async_start:
   {
     GST_OBJECT_UNLOCK (element);
 
-    message = gst_message_new_async_start (GST_OBJECT_CAST (element), TRUE);
+    message = gst_message_new_async_start (GST_OBJECT_CAST (element));
     gst_element_post_message (element, message);
     return;
   }
 }
 
 /**
- * gst_element_lost_state:
- * @element: a #GstElement the state is lost of
- *
- * Brings the element to the lost state. This function calls
- * gst_element_lost_state_full() with the new_base_time set to %TRUE.
- *
- * This function is used internally and should normally not be called from
- * plugins or applications.
- *
- * MT safe.
- */
-void
-gst_element_lost_state (GstElement * element)
-{
-  gst_element_lost_state_full (element, TRUE);
-}
-
-/**
  * gst_element_set_state:
  * @element: a #GstElement to change state of.
  * @state: the element's new #GstState.
@@ -2805,27 +2666,17 @@ invalid_return:
 /* gst_iterator_fold functions for pads_activate
  * Stop the iterator if activating one pad failed. */
 static gboolean
-activate_pads (GstPad * pad, GValue * ret, gboolean * active)
+activate_pads (const GValue * vpad, GValue * ret, gboolean * active)
 {
+  GstPad *pad = g_value_get_object (vpad);
   gboolean cont = TRUE;
 
   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;
 }
 
-/* set the caps on the pad to NULL */
-static gboolean
-clear_caps (GstPad * pad, GValue * ret, gboolean * active)
-{
-  gst_pad_set_caps (pad, NULL);
-  gst_object_unref (pad);
-  return TRUE;
-}
-
 /* returns false on error or early cutout of the fold, true if all
  * pads in @iter were (de)activated successfully. */
 static gboolean
@@ -2891,17 +2742,6 @@ gst_element_pads_activate (GstElement * element, gboolean active)
   if (G_UNLIKELY (!res))
     goto sink_failed;
 
-  if (!active) {
-    /* clear the caps on all pads, this should never fail */
-    iter = gst_element_iterate_pads (element);
-    res =
-        iterator_activate_fold_with_resync (iter,
-        (GstIteratorFoldFunction) clear_caps, &active);
-    gst_iterator_free (iter);
-    if (G_UNLIKELY (!res))
-      goto caps_failed;
-  }
-
   GST_CAT_DEBUG_OBJECT (GST_CAT_ELEMENT_PADS, element,
       "pads_activate successful");
 
@@ -2920,12 +2760,6 @@ sink_failed:
         "sink pads_activate failed");
     return FALSE;
   }
-caps_failed:
-  {
-    GST_CAT_DEBUG_OBJECT (GST_CAT_ELEMENT_PADS, element,
-        "failed to clear caps on pads");
-    return FALSE;
-  }
 }
 
 /* is called with STATE_LOCK */
@@ -2934,7 +2768,6 @@ gst_element_change_state_func (GstElement * element, GstStateChange transition)
 {
   GstState state, next;
   GstStateChangeReturn result = GST_STATE_CHANGE_SUCCESS;
-  GstClock **clock_p;
 
   g_return_val_if_fail (GST_IS_ELEMENT (element), GST_STATE_CHANGE_FAILURE);
 
@@ -2968,15 +2801,7 @@ gst_element_change_state_func (GstElement * element, GstStateChange transition)
          ready->paused but the element might not have made it to paused */
       if (!gst_element_pads_activate (element, FALSE)) {
         result = GST_STATE_CHANGE_FAILURE;
-      } else {
-        gst_element_set_base_time (element, 0);
       }
-
-      /* In null state release the reference to the clock */
-      GST_OBJECT_LOCK (element);
-      clock_p = &element->clock;
-      gst_object_replace ((GstObject **) clock_p, NULL);
-      GST_OBJECT_UNLOCK (element);
       break;
     default:
       /* this will catch real but unhandled state changes;
@@ -3085,162 +2910,14 @@ gst_element_finalize (GObject * object)
 
   GST_CAT_INFO_OBJECT (GST_CAT_REFCOUNTING, element, "finalize");
 
-  GST_STATE_LOCK (element);
-  if (element->state_cond)
-    g_cond_free (element->state_cond);
-  element->state_cond = NULL;
-  GST_STATE_UNLOCK (element);
-  g_static_rec_mutex_free (element->state_lock);
-  g_slice_free (GStaticRecMutex, element->state_lock);
-  element->state_lock = NULL;
+  g_cond_free (element->state_cond);
+  g_static_rec_mutex_free (&element->state_lock);
 
   GST_CAT_INFO_OBJECT (GST_CAT_REFCOUNTING, element, "finalize parent");
 
   G_OBJECT_CLASS (parent_class)->finalize (object);
 }
 
-#if !defined(GST_DISABLE_LOADSAVE) && !defined(GST_REMOVE_DEPRECATED)
-/**
- * gst_element_save_thyself:
- * @element: a #GstElement to save.
- * @parent: the xml parent node.
- *
- * Saves the element as part of the given XML structure.
- *
- * Returns: the new #xmlNodePtr.
- */
-static xmlNodePtr
-gst_element_save_thyself (GstObject * object, xmlNodePtr parent)
-{
-  GList *pads;
-  GstElementClass *oclass;
-  GParamSpec **specs, *spec;
-  guint nspecs;
-  guint i;
-  GValue value = { 0, };
-  GstElement *element;
-
-  g_return_val_if_fail (GST_IS_ELEMENT (object), parent);
-
-  element = GST_ELEMENT_CAST (object);
-
-  oclass = GST_ELEMENT_GET_CLASS (element);
-
-  xmlNewChild (parent, NULL, (xmlChar *) "name",
-      (xmlChar *) GST_ELEMENT_NAME (element));
-
-  if (oclass->elementfactory != NULL) {
-    GstElementFactory *factory = (GstElementFactory *) oclass->elementfactory;
-
-    xmlNewChild (parent, NULL, (xmlChar *) "type",
-        (xmlChar *) GST_PLUGIN_FEATURE (factory)->name);
-  }
-
-  /* params */
-  specs = g_object_class_list_properties (G_OBJECT_GET_CLASS (object), &nspecs);
-
-  for (i = 0; i < nspecs; i++) {
-    spec = specs[i];
-    if (spec->flags & G_PARAM_READABLE) {
-      xmlNodePtr param;
-      char *contents;
-
-      g_value_init (&value, spec->value_type);
-
-      g_object_get_property (G_OBJECT (element), spec->name, &value);
-      param = xmlNewChild (parent, NULL, (xmlChar *) "param", NULL);
-      xmlNewChild (param, NULL, (xmlChar *) "name", (xmlChar *) spec->name);
-
-      if (G_IS_PARAM_SPEC_STRING (spec))
-        contents = g_value_dup_string (&value);
-      else if (G_IS_PARAM_SPEC_ENUM (spec))
-        contents = g_strdup_printf ("%d", g_value_get_enum (&value));
-      else if (G_IS_PARAM_SPEC_INT64 (spec))
-        contents = g_strdup_printf ("%" G_GINT64_FORMAT,
-            g_value_get_int64 (&value));
-      else if (GST_VALUE_HOLDS_STRUCTURE (&value)) {
-        if (g_value_get_boxed (&value) != NULL) {
-          contents = g_strdup_value_contents (&value);
-        } else {
-          contents = g_strdup ("NULL");
-        }
-      } else
-        contents = g_strdup_value_contents (&value);
-
-      xmlNewChild (param, NULL, (xmlChar *) "value", (xmlChar *) contents);
-      g_free (contents);
-
-      g_value_unset (&value);
-    }
-  }
-
-  g_free (specs);
-
-  pads = g_list_last (GST_ELEMENT_PADS (element));
-
-  while (pads) {
-    GstPad *pad = GST_PAD_CAST (pads->data);
-
-    /* figure out if it's a direct pad or a ghostpad */
-    if (GST_ELEMENT_CAST (GST_OBJECT_PARENT (pad)) == element) {
-      xmlNodePtr padtag = xmlNewChild (parent, NULL, (xmlChar *) "pad", NULL);
-
-      gst_object_save_thyself (GST_OBJECT_CAST (pad), padtag);
-    }
-    pads = g_list_previous (pads);
-  }
-
-  return parent;
-}
-
-static void
-gst_element_restore_thyself (GstObject * object, xmlNodePtr self)
-{
-  xmlNodePtr children;
-  GstElement *element;
-  gchar *name = NULL;
-  gchar *value = NULL;
-
-  element = GST_ELEMENT_CAST (object);
-  g_return_if_fail (element != NULL);
-
-  /* parameters */
-  children = self->xmlChildrenNode;
-  while (children) {
-    if (!strcmp ((char *) children->name, "param")) {
-      xmlNodePtr child = children->xmlChildrenNode;
-
-      while (child) {
-        if (!strcmp ((char *) child->name, "name")) {
-          name = (gchar *) xmlNodeGetContent (child);
-        } else if (!strcmp ((char *) child->name, "value")) {
-          value = (gchar *) xmlNodeGetContent (child);
-        }
-        child = child->next;
-      }
-      /* FIXME: can this just be g_object_set ? */
-      gst_util_set_object_arg (G_OBJECT (element), name, value);
-      /* g_object_set (G_OBJECT (element), name, value, NULL); */
-      g_free (name);
-      g_free (value);
-    }
-    children = children->next;
-  }
-
-  /* pads */
-  children = self->xmlChildrenNode;
-  while (children) {
-    if (!strcmp ((char *) children->name, "pad")) {
-      gst_pad_load_and_link (children, GST_OBJECT_CAST (element));
-    }
-    children = children->next;
-  }
-
-  if (GST_OBJECT_CLASS (parent_class)->restore_thyself)
-    (GST_OBJECT_CLASS (parent_class)->restore_thyself) (object, self);
-}
-#endif /* GST_DISABLE_LOADSAVE */
-
 static void
 gst_element_set_bus_func (GstElement * element, GstBus * bus)
 {
index 74a0e2c..2e45ff8 100644 (file)
@@ -64,6 +64,7 @@ typedef enum {
 #include <gst/gstindexfactory.h>
 #include <gst/gstiterator.h>
 #include <gst/gstmessage.h>
+#include <gst/gstquery.h>
 #include <gst/gsttaglist.h>
 
 G_BEGIN_DECLS
@@ -131,7 +132,7 @@ typedef enum {
  *
  * Since: 0.10.13
  */
-#define GST_STATE_TARGET(elem)          (GST_ELEMENT_CAST(elem)->abidata.ABI.target_state)
+#define GST_STATE_TARGET(elem)          (GST_ELEMENT_CAST(elem)->target_state)
 
 /**
  * GST_STATE_RETURN:
@@ -392,7 +393,7 @@ typedef enum
  *
  * Since: 0.10.24
  */
-#define GST_ELEMENT_START_TIME(elem)            (GST_ELEMENT_CAST(elem)->abidata.ABI.start_time)
+#define GST_ELEMENT_START_TIME(elem)            (GST_ELEMENT_CAST(elem)->start_time)
 
 /**
  * GST_ELEMENT_ERROR:
@@ -487,7 +488,7 @@ G_STMT_START {                                                          \
  * This lock is used by the core.  It is taken while getting or setting
  * the state, during state changes, and while finalizing.
  */
-#define GST_STATE_GET_LOCK(elem)               (GST_ELEMENT_CAST(elem)->state_lock)
+#define GST_STATE_GET_LOCK(elem)               (&(GST_ELEMENT_CAST(elem)->state_lock))
 /**
  * GST_STATE_GET_COND:
  * @elem: a #GstElement
@@ -514,6 +515,7 @@ G_STMT_START {                                                          \
  * @state_cond: Used to signal completion of a state change
  * @state_cookie: Used to detect concurrent execution of
  * gst_element_set_state() and gst_element_get_state()
+ * @target_state: the target state of an element as set by the application
  * @current_state: the current state of an element
  * @next_state: the next state of an element, can be #GST_STATE_VOID_PENDING if
  * the element is in the correct state.
@@ -527,6 +529,7 @@ G_STMT_START {                                                          \
  * @base_time: the time of the clock right before the element is set to
  * PLAYING. Subtracting @base_time from the current clock time in the PLAYING
  * state will yield the running_time against the clock.
+ * @start_time: the running_time of the last PAUSED state
  * @numpads: number of pads of the element, includes both source and sink pads.
  * @pads: list of pads
  * @numsrcpads: number of source pads of the element.
@@ -542,11 +545,12 @@ struct _GstElement
   GstObject             object;
 
   /*< public >*/ /* with LOCK */
-  GStaticRecMutex      *state_lock;
+  GStaticRecMutex       state_lock;
 
   /* element state */
   GCond                *state_cond;
   guint32               state_cookie;
+  GstState              target_state;
   GstState              current_state;
   GstState              next_state;
   GstState              pending_state;
@@ -557,6 +561,7 @@ struct _GstElement
   /* allocated clock */
   GstClock             *clock;
   GstClockTimeDiff      base_time; /* NULL/READY: 0 - PAUSED: current time - PLAYING: difference to clock */
+  GstClockTime          start_time;
 
   /* element pads, these lists can only be iterated while holding
    * the LOCK or checking the cookie after each LOCK. */
@@ -569,22 +574,13 @@ struct _GstElement
   guint32               pads_cookie;
 
   /*< private >*/
-  union {
-    struct {
-      /* state set by application */
-      GstState              target_state;
-      /* running time of the last PAUSED state */
-      GstClockTime          start_time;
-    } ABI;
-    /* adding + 0 to mark ABI change to be undone later */
-    gpointer _gst_reserved[GST_PADDING + 0];
-  } abidata;
+  gpointer _gst_reserved[GST_PADDING];
 };
 
 /**
  * GstElementClass:
  * @parent_class: the parent class structure
- * @details: #GstElementDetails for elements of this class
+ * @metadata: metadata for elements of this class
  * @elementfactory: the #GstElementFactory that creates these elements
  * @padtemplates: a #GList of #GstPadTemplate
  * @numpadtemplates: the number of padtemplates
@@ -602,7 +598,6 @@ struct _GstElement
  * @send_event: send a #GstEvent to the element
  * @get_query_types: get the supported #GstQueryType of this element
  * @query: perform a #GstQuery on the element
- * @request_new_pad_full: called when a new pad is requested. Since: 0.10.32.
  * @state_changed: called immediately after a new state was set. Since: 0.10.35.
  *
  * GStreamer element class. Override the vmethods to implement the element
@@ -613,9 +608,8 @@ struct _GstElementClass
   GstObjectClass         parent_class;
 
   /*< public >*/
-  /* the element details */
-  /* FIXME-0.11: deprecate this in favour of meta_data */
-  GstElementDetails      details;
+  /* the element metadata */
+  gpointer              metadata;
 
   /* factory that the element was created from */
   GstElementFactory     *elementfactory;
@@ -635,7 +629,8 @@ struct _GstElementClass
   /* virtual methods for subclasses */
 
   /* request/release pads */
-  GstPad*               (*request_new_pad)      (GstElement *element, GstPadTemplate *templ, const gchar* name);
+  GstPad*               (*request_new_pad)      (GstElement *element, GstPadTemplate *templ,
+                                                 const gchar* name, const GstCaps *caps);
   void                  (*release_pad)          (GstElement *element, GstPad *pad);
 
   /* state changes */
@@ -643,6 +638,8 @@ struct _GstElementClass
                                                  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);
@@ -662,20 +659,7 @@ struct _GstElementClass
   gboolean              (*query)                (GstElement *element, GstQuery *query);
 
   /*< private >*/
-  /* FIXME-0.11: move up and replace details */
-  gpointer             meta_data;
-
-  /*< public >*/
-  /* Virtual method for subclasses (additions) */
-  /* FIXME-0.11 Make this the default behaviour */
-  GstPad*              (*request_new_pad_full) (GstElement *element, GstPadTemplate *templ,
-                                                const gchar* name, const GstCaps *caps);
-
-  void                  (*state_changed)        (GstElement *element, GstState oldstate,
-                                                 GstState newstate, GstState pending);
-
-  /*< private >*/
-  gpointer _gst_reserved[GST_PADDING-3];
+  gpointer _gst_reserved[GST_PADDING];
 };
 
 /* element class pad templates */
@@ -684,16 +668,16 @@ GstPadTemplate*         gst_element_class_get_pad_template      (GstElementClass
 GList*                  gst_element_class_get_pad_template_list (GstElementClass *element_class);
 
 /* element class meta data */
-void                    gst_element_class_set_documentation_uri (GstElementClass * klass, const gchar *uri);
-void                    gst_element_class_set_icon_name         (GstElementClass * klass, const gchar *name);
-#ifndef GST_DISABLE_DEPRECATED
-void                    gst_element_class_set_details           (GstElementClass *klass, const GstElementDetails *details);
-#endif
-void                    gst_element_class_set_details_simple    (GstElementClass *klass,
+void                    gst_element_class_set_metadata          (GstElementClass *klass,
                                                                  const gchar     *longname,
                                                                  const gchar     *classification,
                                                                  const gchar     *description,
                                                                  const gchar     *author);
+void                    gst_element_class_add_metadata          (GstElementClass * klass,
+                                                                 const gchar * key, const gchar * value);
+G_CONST_RETURN gchar *  gst_element_class_get_metadata          (GstElementClass * klass,
+                                                                 const gchar * key);
+
 
 /* element instance */
 GType                   gst_element_get_type            (void);
@@ -767,13 +751,9 @@ gboolean                gst_element_add_pad             (GstElement *element, Gs
 gboolean                gst_element_remove_pad          (GstElement *element, GstPad *pad);
 void                    gst_element_no_more_pads        (GstElement *element);
 
-#ifndef GST_DISABLE_DEPRECATED
-GstPad*                 gst_element_get_pad             (GstElement *element, const gchar *name);
-#endif /* GST_DISABLE_DEPRECATED */
 GstPad*                 gst_element_get_static_pad      (GstElement *element, const gchar *name);
 GstPad*                 gst_element_get_request_pad     (GstElement *element, const gchar *name);
-GstPad*                 gst_element_request_pad         (GstElement *element,
-                                                        GstPadTemplate *templ,
+GstPad*                 gst_element_request_pad         (GstElement *element, GstPadTemplate *templ,
                                                         const gchar * name, const GstCaps *caps);
 void                    gst_element_release_request_pad (GstElement *element, GstPad *pad);
 
@@ -822,7 +802,6 @@ GstStateChangeReturn    gst_element_change_state        (GstElement * element,
 GstStateChangeReturn    gst_element_continue_state      (GstElement * element,
                                                          GstStateChangeReturn ret);
 void                    gst_element_lost_state          (GstElement * element);
-void                    gst_element_lost_state_full     (GstElement * element, gboolean new_base_time);
 
 /* factory management */
 GstElementFactory*      gst_element_get_factory         (GstElement *element);
diff --git a/gst/gstelementdetails.h b/gst/gstelementdetails.h
deleted file mode 100644 (file)
index b59878a..0000000
+++ /dev/null
@@ -1,69 +0,0 @@
-/* GStreamer
- * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
- *               2000,2004 Wim Taymans <wim@fluendo.com>
- *
- * gstelement.h: Header for GstElement
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#ifndef __GST_ELEMENT_DETAILS_H__
-#define __GST_ELEMENT_DETAILS_H__
-
-G_BEGIN_DECLS
-
-static inline void
-__gst_element_details_clear (GstElementDetails * dp)
-{
-  g_free (dp->longname);
-  g_free (dp->klass);
-  g_free (dp->description);
-  g_free (dp->author);
-  memset (dp, 0, sizeof (GstElementDetails));
-}
-
-#define VALIDATE_SET(__dest, __src, __entry)                            \
-G_STMT_START {                                                          \
-  if (g_utf8_validate (__src->__entry, -1, NULL)) {                     \
-    __dest->__entry = g_strdup (__src->__entry);                        \
-  } else {                                                              \
-    g_warning ("Invalid UTF-8 in " G_STRINGIFY (__entry) ": %s",        \
-        __src->__entry);                                                \
-    __dest->__entry = g_strdup ("[ERROR: invalid UTF-8]");              \
-  }                                                                     \
-} G_STMT_END
-
-static inline void
-__gst_element_details_set (GstElementDetails * dest,
-    const GstElementDetails * src)
-{
-  VALIDATE_SET (dest, src, longname);
-  VALIDATE_SET (dest, src, klass);
-  VALIDATE_SET (dest, src, description);
-  VALIDATE_SET (dest, src, author);
-}
-
-static inline void
-__gst_element_details_copy (GstElementDetails * dest,
-    const GstElementDetails * src)
-{
-  __gst_element_details_clear (dest);
-  __gst_element_details_set (dest, src);
-}
-
-G_END_DECLS
-
-#endif /* __GST_ELEMENT_DETAILS_H__ */
index 4c28e82..9ac76eb 100644 (file)
@@ -60,7 +60,7 @@
 #include "gst_private.h"
 
 #include "gstelement.h"
-#include "gstelementdetails.h"
+#include "gstelementmetadata.h"
 #include "gstinfo.h"
 #include "gsturi.h"
 #include "gstregistry.h"
@@ -150,10 +150,9 @@ gst_element_factory_cleanup (GstElementFactory * factory)
 {
   GList *item;
 
-  __gst_element_details_clear (&factory->details);
-  if (factory->meta_data) {
-    gst_structure_free ((GstStructure *) factory->meta_data);
-    factory->meta_data = NULL;
+  if (factory->metadata) {
+    gst_structure_free ((GstStructure *) factory->metadata);
+    factory->metadata = NULL;
   }
   if (factory->type) {
     factory->type = G_TYPE_INVALID;
@@ -164,7 +163,7 @@ gst_element_factory_cleanup (GstElementFactory * factory)
     GstCaps *caps = (GstCaps *) & (templ->static_caps);
 
     /* FIXME: this is not threadsafe */
-    if (caps->refcount == 1) {
+    if (GST_CAPS_REFCOUNT_VALUE (caps) == 1) {
       GstStructure *structure;
       guint i;
 
@@ -174,7 +173,7 @@ gst_element_factory_cleanup (GstElementFactory * factory)
         gst_structure_free (structure);
       }
       g_ptr_array_free (caps->structs, TRUE);
-      caps->refcount = 0;
+      GST_CAPS_REFCOUNT (caps) = 0;
     }
     g_slice_free (GstStaticPadTemplate, templ);
   }
@@ -248,17 +247,16 @@ gst_element_register (GstPlugin * plugin, const gchar * name, guint rank,
   /* provide info needed during class structure setup */
   g_type_set_qdata (type, _gst_elementclass_factory, factory);
   klass = GST_ELEMENT_CLASS (g_type_class_ref (type));
+#if 0
+  /* FIXME */
   if ((klass->details.longname == NULL) ||
       (klass->details.klass == NULL) || (klass->details.author == NULL))
     goto detailserror;
+#endif
 
   factory->type = type;
-  __gst_element_details_copy (&factory->details, &klass->details);
-  if (klass->meta_data) {
-    factory->meta_data = gst_structure_copy ((GstStructure *) klass->meta_data);
-  } else {
-    factory->meta_data = NULL;
-  }
+  factory->metadata = gst_structure_copy ((GstStructure *) klass->metadata);
+
   for (item = klass->padtemplates; item; item = item->next) {
     GstPadTemplate *templ = item->data;
     GstStaticPadTemplate *newt;
@@ -268,7 +266,7 @@ gst_element_register (GstPlugin * plugin, const gchar * name, guint rank,
     newt->name_template = g_intern_string (templ->name_template);
     newt->direction = templ->direction;
     newt->presence = templ->presence;
-    newt->static_caps.caps.refcount = 0;
+    newt->static_caps.caps.mini_object.refcount = 0;
     newt->static_caps.string = g_intern_string (caps_string);
     factory->staticpadtemplates =
         g_list_append (factory->staticpadtemplates, newt);
@@ -329,6 +327,7 @@ urierror:
     return FALSE;
   }
 
+#if 0
 detailserror:
   {
     GST_WARNING_OBJECT (factory,
@@ -336,6 +335,7 @@ detailserror:
     gst_element_factory_cleanup (factory);
     return FALSE;
   }
+#endif
 }
 
 /**
@@ -370,9 +370,9 @@ gst_element_factory_create (GstElementFactory * factory, const gchar * name)
 
   if (name)
     GST_INFO ("creating element \"%s\" named \"%s\"",
-        GST_PLUGIN_FEATURE_NAME (factory), GST_STR_NULL (name));
+        GST_OBJECT_NAME (factory), GST_STR_NULL (name));
   else
-    GST_INFO ("creating element \"%s\"", GST_PLUGIN_FEATURE_NAME (factory));
+    GST_INFO ("creating element \"%s\"", GST_OBJECT_NAME (factory));
 
   if (factory->type == 0)
     goto no_type;
@@ -398,7 +398,7 @@ gst_element_factory_create (GstElementFactory * factory, const gchar * name)
           factory))
     gst_object_unref (factory);
 
-  GST_DEBUG ("created element \"%s\"", GST_PLUGIN_FEATURE_NAME (factory));
+  GST_DEBUG ("created element \"%s\"", GST_OBJECT_NAME (factory));
 
   return element;
 
@@ -504,113 +504,11 @@ gst_element_factory_get_element_type (GstElementFactory * factory)
   return factory->type;
 }
 
-/**
- * gst_element_factory_get_longname:
- * @factory: a #GstElementFactory
- *
- * Gets the longname for this factory
- *
- * Returns: the longname
- */
-const gchar *
-gst_element_factory_get_longname (GstElementFactory * factory)
-{
-  g_return_val_if_fail (GST_IS_ELEMENT_FACTORY (factory), NULL);
-
-  return factory->details.longname;
-}
-
-/**
- * gst_element_factory_get_klass:
- * @factory: a #GstElementFactory
- *
- * Gets the class for this factory.
- *
- * Returns: the class
- */
-const gchar *
-gst_element_factory_get_klass (GstElementFactory * factory)
-{
-  g_return_val_if_fail (GST_IS_ELEMENT_FACTORY (factory), NULL);
-
-  return factory->details.klass;
-}
-
-/**
- * gst_element_factory_get_description:
- * @factory: a #GstElementFactory
- *
- * Gets the description for this factory.
- *
- * Returns: the description
- */
-const gchar *
-gst_element_factory_get_description (GstElementFactory * factory)
-{
-  g_return_val_if_fail (GST_IS_ELEMENT_FACTORY (factory), NULL);
-
-  return factory->details.description;
-}
-
-/**
- * gst_element_factory_get_author:
- * @factory: a #GstElementFactory
- *
- * Gets the author for this factory.
- *
- * Returns: the author
- */
 const gchar *
-gst_element_factory_get_author (GstElementFactory * factory)
-{
-  g_return_val_if_fail (GST_IS_ELEMENT_FACTORY (factory), NULL);
-
-  return factory->details.author;
-}
-
-static const gchar *
-gst_element_factory_get_meta_data (GstElementFactory * factory,
+gst_element_factory_get_metadata (GstElementFactory * factory,
     const gchar * key)
 {
-  if (!factory->meta_data)
-    return NULL;
-
-  /* FIXME: do we want to support other types? */
-  return gst_structure_get_string ((GstStructure *) factory->meta_data, key);
-}
-
-/**
- * gst_element_factory_get_documentation_uri:
- * @factory: a #GstElementFactory
- *
- * Gets documentation uri for this factory if set.
- *
- * Since: 0.10.31
- *
- * Returns: the documentation uri
- */
-const gchar *
-gst_element_factory_get_documentation_uri (GstElementFactory * factory)
-{
-  g_return_val_if_fail (GST_IS_ELEMENT_FACTORY (factory), NULL);
-  return gst_element_factory_get_meta_data (factory, "doc-uri");
-}
-
-/**
- * gst_element_factory_get_icon_name:
- * @factory: a #GstElementFactory
- *
- * Gets icon name for this factory if set.
- *
- * Since: 0.10.31
- *
- * Returns: the icon name
- */
-const gchar *
-gst_element_factory_get_icon_name (GstElementFactory * factory)
-{
-  g_return_val_if_fail (GST_IS_ELEMENT_FACTORY (factory), NULL);
-  return gst_element_factory_get_meta_data (factory, "icon-name");
+  return gst_structure_get_string ((GstStructure *) factory->metadata, key);
 }
 
 /**
@@ -757,7 +655,8 @@ gst_element_factory_list_is_type (GstElementFactory * factory,
   gboolean res = FALSE;
   const gchar *klass;
 
-  klass = gst_element_factory_get_klass (factory);
+  klass =
+      gst_element_factory_get_metadata (factory, GST_ELEMENT_METADATA_KLASS);
 
   /* Filter by element type first, as soon as it matches
    * one type, we skip all other tests */
index fc33982..ee99594 100644 (file)
@@ -32,72 +32,11 @@ typedef struct _GstElementFactoryClass GstElementFactoryClass;
 #include <gst/gstobject.h>
 #include <gst/gstplugin.h>
 #include <gst/gstpluginfeature.h>
+#include <gst/gstpadtemplate.h>
 #include <gst/gstiterator.h>
 
 G_BEGIN_DECLS
 
-/* FIXME 0.11: Move GstElementDetails into a private header and use it internally
- * in GstElementFactory, GstElementClass and the registry
- */
-
-typedef struct _GstElementDetails GstElementDetails;
-
-/**
- * GstElementDetails:
- * @longname: long, english name
- * @klass: string describing the type of element, as an unordered list
- * separated with slashes ('/'). See draft-klass.txt of the design docs
- * for more details and common types
- * @description: what the element is about
- * @author: who wrote this thing?
- *
- * This struct defines the public information about a #GstElement. It contains
- * meta-data about the element that is mostly for the benefit of editors.
- *
- * The @klass member can be used by applications to filter elements based
- * on functionality.
- */
-/* FIXME: need translatable stuff in here (how handle in registry)?
- * can't we use _N("long name") in element implementations and use _(longname)
- * in gst_element_factory_get_longname()
- */
-struct _GstElementDetails
-{
-  /*< public > */
-  gchar *longname;
-  gchar *klass;
-  gchar *description;
-  gchar *author;
-
-  /*< private >*/
-  gpointer _gst_reserved[GST_PADDING];
-};
-
-/**
- * GST_ELEMENT_DETAILS:
- * @longname: long, english name
- * @klass: string describing the type of element, as an unordered list
- * separated with slashes ('/'). See draft-klass.txt of the design docs
- * for more details and common types
- * @description: what the element is about
- * @author: who wrote this element
- *
- * Macro to initialize #GstElementDetails.
- */
-#define GST_ELEMENT_DETAILS(longname,klass,description,author)          \
-  { longname, klass, description, author, {NULL} }
-
-/**
- * GST_IS_ELEMENT_DETAILS:
- * @details: the #GstElementDetails to check
- *
- * Tests if element details are initialized.
- */
-/* FIXME: what about adding '&& (*__gst_reserved==NULL)' */
-#define GST_IS_ELEMENT_DETAILS(details) (                                       \
-  (details) && ((details)->longname != NULL) && ((details)->klass != NULL)      \
-  && ((details)->description != NULL) && ((details)->author != NULL))
-
 #define GST_TYPE_ELEMENT_FACTORY                (gst_element_factory_get_type())
 #define GST_ELEMENT_FACTORY(obj)                (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_ELEMENT_FACTORY,\
                                                  GstElementFactory))
@@ -117,8 +56,7 @@ struct _GstElementFactory {
 
   GType                 type;                   /* unique GType of element or 0 if not loaded */
 
-  /* FIXME-0.11: deprecate this in favour of meta_data */
-  GstElementDetails     details;
+  gpointer             metadata;
 
   GList *               staticpadtemplates;     /* GstStaticPadTemplate list */
   guint                 numpadtemplates;
@@ -130,9 +68,7 @@ struct _GstElementFactory {
   GList *               interfaces;             /* interface type names this element implements */
 
   /*< private >*/
-  /* FIXME-0.11: move up and replace details */
-  gpointer             meta_data;
-  gpointer _gst_reserved[GST_PADDING - 1];
+  gpointer _gst_reserved[GST_PADDING];
 };
 
 struct _GstElementFactoryClass {
@@ -146,16 +82,15 @@ GType                   gst_element_factory_get_type            (void);
 GstElementFactory *     gst_element_factory_find                (const gchar *name);
 
 GType                   gst_element_factory_get_element_type    (GstElementFactory *factory);
-const gchar *           gst_element_factory_get_longname        (GstElementFactory *factory);
-const gchar *           gst_element_factory_get_klass           (GstElementFactory *factory);
-const gchar *           gst_element_factory_get_description     (GstElementFactory *factory);
-const gchar *           gst_element_factory_get_author          (GstElementFactory *factory);
-const gchar *           gst_element_factory_get_documentation_uri (GstElementFactory *factory);
-const gchar *           gst_element_factory_get_icon_name       (GstElementFactory *factory);
+
+const gchar *           gst_element_factory_get_metadata        (GstElementFactory *factory, const gchar *key);
+
 guint                   gst_element_factory_get_num_pad_templates (GstElementFactory *factory);
 const GList *           gst_element_factory_get_static_pad_templates (GstElementFactory *factory);
+
 gint                    gst_element_factory_get_uri_type        (GstElementFactory *factory);
 gchar **                gst_element_factory_get_uri_protocols   (GstElementFactory *factory);
+
 gboolean                gst_element_factory_has_interface       (GstElementFactory *factory,
                                                                  const gchar *interfacename);
 
diff --git a/gst/gstelementmetadata.h b/gst/gstelementmetadata.h
new file mode 100644 (file)
index 0000000..6c331d9
--- /dev/null
@@ -0,0 +1,77 @@
+/* GStreamer
+ * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
+ *               2000,2004 Wim Taymans <wim@fluendo.com>
+ *
+ * gstelementmetadata.h: Metadata for GstElement classes
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __GST_ELEMENT_METADATA_H__
+#define __GST_ELEMENT_METADATA_H__
+
+G_BEGIN_DECLS
+
+/**
+ * GST_ELEMENT_METADATA_LONGNAME:
+ *
+ * The long English name of the element. E.g. "File Sink"
+ */
+#define GST_ELEMENT_METADATA_LONGNAME      "long-name"
+/**
+ * GST_ELEMENT_METADATA_KLASS:
+ *
+ * String describing the type of element, as an unordered list
+ * separated with slashes ('/'). See draft-klass.txt of the design docs
+ * for more details and common types. E.g: "Sink/File"
+ */
+#define GST_ELEMENT_METADATA_KLASS         "klass"
+
+/**
+ * GST_ELEMENT_METADATA_DESCRIPTION:
+ *
+ * Sentence describing the purpose of the element.
+ * E.g: "Write stream to a file"
+ */
+#define GST_ELEMENT_METADATA_DESCRIPTION   "description"
+/**
+ * GST_ELEMENT_METADATA_AUTHOR:
+ *
+ * Name and contact details of the author(s). Use \n to separate
+ * multiple author details.
+ * E.g: "Joe Bloggs &lt;joe.blogs at foo.com&gt;"
+ */
+#define GST_ELEMENT_METADATA_AUTHOR        "author"
+
+/**
+ * GST_ELEMENT_METADATA_DOC_URI:
+ *
+ * Set uri pointing to user documentation. Applications can use this to show
+ * help for e.g. effects to users.
+ */
+#define GST_ELEMENT_METADATA_DOC_URI       "doc-uri"
+/**
+ * GST_ELEMENT_METADATA_ICON_NAME:
+ *
+ * Elements that bridge to certain other products can include an icon of that
+ * used product. Application can show the icon in menus/selectors to help
+ * identifying specific elements.
+ */
+#define GST_ELEMENT_METADATA_ICON_NAME     "icon-name"
+
+G_END_DECLS
+
+#endif /* __GST_ELEMENT_METADATA_H__ */
index 07414c7..821ea7b 100644 (file)
 #include "gstutils.h"
 #include "gstquark.h"
 
-#define GST_EVENT_SEQNUM(e) ((GstEvent*)e)->abidata.seqnum
+GType _gst_event_type = 0;
 
-static void gst_event_finalize (GstEvent * event);
-static GstEvent *_gst_event_copy (GstEvent * event);
+typedef struct
+{
+  GstEvent event;
 
-static GstMiniObjectClass *parent_class = NULL;
+  GstStructure *structure;
+} GstEventImpl;
 
-void
-_gst_event_initialize (void)
-{
-  g_type_class_ref (gst_event_get_type ());
-  g_type_class_ref (gst_seek_flags_get_type ());
-  g_type_class_ref (gst_seek_type_get_type ());
-}
+#define GST_EVENT_STRUCTURE(e)  (((GstEventImpl *)(e))->structure)
 
 typedef struct
 {
@@ -112,7 +108,8 @@ static GstEventQuarks event_quarks[] = {
   {GST_EVENT_FLUSH_START, "flush-start", 0},
   {GST_EVENT_FLUSH_STOP, "flush-stop", 0},
   {GST_EVENT_EOS, "eos", 0},
-  {GST_EVENT_NEWSEGMENT, "newsegment", 0},
+  {GST_EVENT_CAPS, "caps", 0},
+  {GST_EVENT_SEGMENT, "segment", 0},
   {GST_EVENT_TAG, "tag", 0},
   {GST_EVENT_BUFFERSIZE, "buffersize", 0},
   {GST_EVENT_SINK_MESSAGE, "sink-message", 0},
@@ -121,6 +118,7 @@ static GstEventQuarks event_quarks[] = {
   {GST_EVENT_NAVIGATION, "navigation", 0},
   {GST_EVENT_LATENCY, "latency", 0},
   {GST_EVENT_STEP, "step", 0},
+  {GST_EVENT_RECONFIGURE, "reconfigure", 0},
   {GST_EVENT_CUSTOM_UPSTREAM, "custom-upstream", 0},
   {GST_EVENT_CUSTOM_DOWNSTREAM, "custom-downstream", 0},
   {GST_EVENT_CUSTOM_DOWNSTREAM_OOB, "custom-downstream-oob", 0},
@@ -130,6 +128,21 @@ static GstEventQuarks event_quarks[] = {
   {0, NULL, 0}
 };
 
+void
+_gst_event_initialize (void)
+{
+  gint i;
+
+  _gst_event_type = gst_mini_object_register ("GstEvent");
+
+  g_type_class_ref (gst_seek_flags_get_type ());
+  g_type_class_ref (gst_seek_type_get_type ());
+
+  for (i = 0; event_quarks[i].name; i++) {
+    event_quarks[i].quark = g_quark_from_static_string (event_quarks[i].name);
+  }
+}
+
 /**
  * gst_event_type_get_name:
  * @type: the event type
@@ -183,97 +196,83 @@ gst_event_type_get_flags (GstEventType type)
 {
   GstEventTypeFlags ret;
 
-  ret = type & ((1 << GST_EVENT_TYPE_SHIFT) - 1);
+  ret = type & ((1 << GST_EVENT_STICKY_SHIFT) - 1);
 
   return ret;
 }
 
-#define _do_init \
-{ \
-  gint i; \
-  \
-  for (i = 0; event_quarks[i].name; i++) { \
-    event_quarks[i].quark = g_quark_from_static_string (event_quarks[i].name); \
-  } \
-}
-
-G_DEFINE_TYPE_WITH_CODE (GstEvent, gst_event, GST_TYPE_MINI_OBJECT, _do_init);
-
-static void
-gst_event_class_init (GstEventClass * klass)
-{
-  parent_class = g_type_class_peek_parent (klass);
-
-  klass->mini_object_class.copy = (GstMiniObjectCopyFunction) _gst_event_copy;
-  klass->mini_object_class.finalize =
-      (GstMiniObjectFinalizeFunction) gst_event_finalize;
-}
-
 static void
-gst_event_init (GstEvent * event)
+_gst_event_free (GstEvent * event)
 {
-  GST_EVENT_TIMESTAMP (event) = GST_CLOCK_TIME_NONE;
-}
+  GstStructure *s;
 
-static void
-gst_event_finalize (GstEvent * event)
-{
   g_return_if_fail (event != NULL);
   g_return_if_fail (GST_IS_EVENT (event));
 
   GST_CAT_LOG (GST_CAT_EVENT, "freeing event %p type %s", event,
       GST_EVENT_TYPE_NAME (event));
 
-  if (GST_EVENT_SRC (event)) {
-    gst_object_unref (GST_EVENT_SRC (event));
-    GST_EVENT_SRC (event) = NULL;
-  }
-  if (event->structure) {
-    gst_structure_set_parent_refcount (event->structure, NULL);
-    gst_structure_free (event->structure);
+  s = GST_EVENT_STRUCTURE (event);
+
+  if (s) {
+    gst_structure_set_parent_refcount (s, NULL);
+    gst_structure_free (s);
   }
 
-/*   GST_MINI_OBJECT_CLASS (parent_class)->finalize (GST_MINI_OBJECT (event)); */
+  g_slice_free1 (GST_MINI_OBJECT_SIZE (event), event);
 }
 
+static void gst_event_init (GstEventImpl * event, gsize size,
+    GstEventType type);
+
 static GstEvent *
 _gst_event_copy (GstEvent * event)
 {
-  GstEvent *copy;
+  GstEventImpl *copy;
+  GstStructure *s;
+
+  copy = g_slice_new0 (GstEventImpl);
 
-  copy = (GstEvent *) gst_mini_object_new (GST_TYPE_EVENT);
+  gst_event_init (copy, sizeof (GstEventImpl), GST_EVENT_TYPE (event));
 
-  GST_EVENT_TYPE (copy) = GST_EVENT_TYPE (event);
   GST_EVENT_TIMESTAMP (copy) = GST_EVENT_TIMESTAMP (event);
   GST_EVENT_SEQNUM (copy) = GST_EVENT_SEQNUM (event);
 
-  if (GST_EVENT_SRC (event)) {
-    GST_EVENT_SRC (copy) = gst_object_ref (GST_EVENT_SRC (event));
-  }
-  if (event->structure) {
-    copy->structure = gst_structure_copy (event->structure);
-    gst_structure_set_parent_refcount (copy->structure,
-        &copy->mini_object.refcount);
+  s = GST_EVENT_STRUCTURE (event);
+  if (s) {
+    GST_EVENT_STRUCTURE (copy) = gst_structure_copy (s);
+    gst_structure_set_parent_refcount (GST_EVENT_STRUCTURE (copy),
+        &copy->event.mini_object.refcount);
   }
-  return copy;
+  return GST_EVENT_CAST (copy);
+}
+
+static void
+gst_event_init (GstEventImpl * event, gsize size, GstEventType type)
+{
+  gst_mini_object_init (GST_MINI_OBJECT_CAST (event), _gst_event_type, size);
+
+  event->event.mini_object.copy = (GstMiniObjectCopyFunction) _gst_event_copy;
+  event->event.mini_object.free = (GstMiniObjectFreeFunction) _gst_event_free;
+
+  GST_EVENT_TYPE (event) = type;
+  GST_EVENT_TIMESTAMP (event) = GST_CLOCK_TIME_NONE;
+  GST_EVENT_SEQNUM (event) = gst_util_seqnum_next ();
 }
 
 static GstEvent *
 gst_event_new (GstEventType type)
 {
-  GstEvent *event;
+  GstEventImpl *event;
 
-  event = (GstEvent *) gst_mini_object_new (GST_TYPE_EVENT);
+  event = g_slice_new0 (GstEventImpl);
 
   GST_CAT_DEBUG (GST_CAT_EVENT, "creating new event %p %s %d", event,
       gst_event_type_get_name (type), type);
 
-  event->type = type;
-  event->src = NULL;
-  event->structure = NULL;
-  GST_EVENT_SEQNUM (event) = gst_util_seqnum_next ();
+  gst_event_init (event, sizeof (GstEventImpl), type);
 
-  return event;
+  return GST_EVENT_CAST (event);
 }
 
 /**
@@ -301,15 +300,23 @@ gst_event_new_custom (GstEventType type, GstStructure * structure)
   GstEvent *event;
 
   /* structure must not have a parent */
-  if (structure)
-    g_return_val_if_fail (structure->parent_refcount == NULL, NULL);
-
   event = gst_event_new (type);
   if (structure) {
-    gst_structure_set_parent_refcount (structure, &event->mini_object.refcount);
-    event->structure = structure;
+    if (!gst_structure_set_parent_refcount (structure,
+            &event->mini_object.refcount))
+      goto had_parent;
+
+    GST_EVENT_STRUCTURE (event) = structure;
   }
   return event;
+
+  /* ERRORS */
+had_parent:
+  {
+    gst_event_unref (event);
+    g_warning ("structure is already owned by another object");
+    return NULL;
+  }
 }
 
 /**
@@ -329,7 +336,40 @@ gst_event_get_structure (GstEvent * event)
 {
   g_return_val_if_fail (GST_IS_EVENT (event), NULL);
 
-  return event->structure;
+  return GST_EVENT_STRUCTURE (event);
+}
+
+/**
+ * gst_event_writable_structure:
+ * @event: The #GstEvent.
+ *
+ * Get a writable version of the structure.
+ *
+ * Returns: The structure of the event. The structure is still
+ * owned by the event, which means that you should not free it and
+ * that the pointer becomes invalid when you free the event.
+ * This function checks if @event is writable and will never return NULL.
+ *
+ * MT safe.
+ */
+GstStructure *
+gst_event_writable_structure (GstEvent * event)
+{
+  GstStructure *structure;
+
+  g_return_val_if_fail (GST_IS_EVENT (event), NULL);
+  g_return_val_if_fail (gst_event_is_writable (event), NULL);
+
+  structure = GST_EVENT_STRUCTURE (event);
+
+  if (structure == NULL) {
+    structure =
+        gst_structure_id_empty_new (gst_event_type_to_quark (GST_EVENT_TYPE
+            (event)));
+    gst_structure_set_parent_refcount (structure, &event->mini_object.refcount);
+    GST_EVENT_STRUCTURE (event) = structure;
+  }
+  return structure;
 }
 
 /**
@@ -349,10 +389,10 @@ gst_event_has_name (GstEvent * event, const gchar * name)
 {
   g_return_val_if_fail (GST_IS_EVENT (event), FALSE);
 
-  if (event->structure == NULL)
+  if (GST_EVENT_STRUCTURE (event) == NULL)
     return FALSE;
 
-  return gst_structure_has_name (event->structure, name);
+  return gst_structure_has_name (GST_EVENT_STRUCTURE (event), name);
 }
 
 /**
@@ -441,6 +481,7 @@ gst_event_new_flush_start (void)
 
 /**
  * gst_event_new_flush_stop:
+ * @reset_time: if time should be reset
  *
  * Allocate a new flush stop event. The flush stop event can be sent
  * upstream and downstream and travels serialized with the dataflow.
@@ -456,9 +497,39 @@ gst_event_new_flush_start (void)
  * Returns: (transfer full): a new flush stop event.
  */
 GstEvent *
-gst_event_new_flush_stop (void)
+gst_event_new_flush_stop (gboolean reset_time)
+{
+  GstEvent *event;
+
+  GST_CAT_INFO (GST_CAT_EVENT, "creating flush stop %d", reset_time);
+
+  event = gst_event_new_custom (GST_EVENT_FLUSH_STOP,
+      gst_structure_id_new (GST_QUARK (EVENT_FLUSH_STOP),
+          GST_QUARK (RESET_TIME), G_TYPE_BOOLEAN, reset_time, NULL));
+
+  return event;
+}
+
+/**
+ * gst_event_parse_flush_stop:
+ * @event: The event to parse
+ * @reset_time: (out): if time should be reset
+ *
+ * Parse the FLUSH_STOP event and retrieve the @reset_time member.
+ */
+void
+gst_event_parse_flush_stop (GstEvent * event, gboolean * reset_time)
 {
-  return gst_event_new (GST_EVENT_FLUSH_STOP);
+  GstStructure *structure;
+
+  g_return_if_fail (GST_IS_EVENT (event));
+  g_return_if_fail (GST_EVENT_TYPE (event) == GST_EVENT_FLUSH_STOP);
+
+  structure = GST_EVENT_STRUCTURE (event);
+  if (G_LIKELY (reset_time))
+    *reset_time =
+        g_value_get_boolean (gst_structure_id_get_value (structure,
+            GST_QUARK (RESET_TIME)));
 }
 
 /**
@@ -487,65 +558,62 @@ gst_event_new_eos (void)
 }
 
 /**
- * gst_event_new_new_segment:
- * @update: is this segment an update to a previous one
- * @rate: a new rate for playback
- * @format: The format of the segment values
- * @start: the start value of the segment
- * @stop: the stop value of the segment
- * @position: stream position
- *
- * Allocate a new newsegment event with the given format/values tripplets
+ * gst_event_new_caps:
+ * @caps: a #GstCaps
  *
- * This method calls gst_event_new_new_segment_full() passing a default
- * value of 1.0 for applied_rate
+ * Create a new CAPS event for @caps. The caps event can only travel downstream
+ * synchronized with the buffer flow and contains the format of the buffers
+ * that will follow after the event.
  *
- * Returns: (transfer full): a new newsegment event.
+ * Returns: (transfer full): the new CAPS event.
  */
 GstEvent *
-gst_event_new_new_segment (gboolean update, gdouble rate, GstFormat format,
-    gint64 start, gint64 stop, gint64 position)
+gst_event_new_caps (GstCaps * caps)
 {
-  return gst_event_new_new_segment_full (update, rate, 1.0, format, start,
-      stop, position);
+  GstEvent *event;
+
+  g_return_val_if_fail (caps != NULL, NULL);
+  g_return_val_if_fail (gst_caps_is_fixed (caps), NULL);
+
+  GST_CAT_INFO (GST_CAT_EVENT, "creating caps event %" GST_PTR_FORMAT, caps);
+
+  event = gst_event_new_custom (GST_EVENT_CAPS,
+      gst_structure_id_new (GST_QUARK (EVENT_CAPS),
+          GST_QUARK (CAPS), GST_TYPE_CAPS, caps, NULL));
+
+  return event;
 }
 
 /**
- * gst_event_parse_new_segment:
- * @event: The event to query
- * @update: (out): A pointer to the update flag of the segment
- * @rate: (out): A pointer to the rate of the segment
- * @format: (out): A pointer to the format of the newsegment values
- * @start: (out): A pointer to store the start value in
- * @stop: (out): A pointer to store the stop value in
- * @position: (out): A pointer to store the stream time in
- *
- * Get the update flag, rate, format, start, stop and position in the 
- * newsegment event. In general, gst_event_parse_new_segment_full() should
- * be used instead of this, to also retrieve the applied_rate value of the
- * segment. See gst_event_new_new_segment_full() for a full description 
- * of the newsegment event.
+ * gst_event_parse_caps:
+ * @event: The event to parse
+ * @caps: (out): A pointer to the caps
+ *
+ * Get the caps from @event. The caps remains valid as long as @event remains
+ * valid.
  */
 void
-gst_event_parse_new_segment (GstEvent * event, gboolean * update,
-    gdouble * rate, GstFormat * format, gint64 * start,
-    gint64 * stop, gint64 * position)
+gst_event_parse_caps (GstEvent * event, GstCaps ** caps)
 {
-  gst_event_parse_new_segment_full (event, update, rate, NULL, format, start,
-      stop, position);
+  GstStructure *structure;
+
+  g_return_if_fail (GST_IS_EVENT (event));
+  g_return_if_fail (GST_EVENT_TYPE (event) == GST_EVENT_CAPS);
+
+  structure = GST_EVENT_STRUCTURE (event);
+  if (G_LIKELY (caps))
+    *caps =
+        g_value_get_boxed (gst_structure_id_get_value (structure,
+            GST_QUARK (CAPS)));
 }
 
 /**
- * gst_event_new_new_segment_full:
- * @update: Whether this segment is an update to a previous one
- * @rate: A new rate for playback
- * @applied_rate: The rate factor which has already been applied
- * @format: The format of the segment values
- * @start: The start value of the segment
- * @stop: The stop value of the segment
- * @position: stream position
+ * gst_event_new_segment:
+ * @segment: a #GstSegment
  *
- * Allocate a new newsegment event with the given format/values triplets.
+ * Create a new SEGMENT event for @segment. The segment event can only travel
+ * downstream synchronized with the buffer flow and contains timing information
+ * and playback properties for the buffers that will follow.
  *
  * The newsegment event marks the range of buffers to be processed. All
  * data not within the segment range is not to be processed. This can be
@@ -553,132 +621,91 @@ gst_event_parse_new_segment (GstEvent * event, gboolean * update,
  * unneeded data. The valid range is expressed with the @start and @stop
  * values.
  *
- * The position value of the segment is used in conjunction with the start
- * value to convert the buffer timestamps into the stream time. This is 
- * usually done in sinks to report the current stream_time. 
- * @position represents the stream_time of a buffer carrying a timestamp of 
- * @start. @position cannot be -1.
+ * The time value of the segment is used in conjunction with the start
+ * value to convert the buffer timestamps into the stream time. This is
+ * usually done in sinks to report the current stream_time.
+ * @time represents the stream_time of a buffer carrying a timestamp of
+ * @start. @time cannot be -1.
  *
  * @start cannot be -1, @stop can be -1. If there
- * is a valid @stop given, it must be greater or equal the @start, including 
+ * is a valid @stop given, it must be greater or equal the @start, including
  * when the indicated playback @rate is < 0.
  *
  * The @applied_rate value provides information about any rate adjustment that
- * has already been made to the timestamps and content on the buffers of the 
- * stream. (@rate * @applied_rate) should always equal the rate that has been 
- * requested for playback. For example, if an element has an input segment 
- * with intended playback @rate of 2.0 and applied_rate of 1.0, it can adjust 
- * incoming timestamps and buffer content by half and output a newsegment event 
+ * has already been made to the timestamps and content on the buffers of the
+ * stream. (@rate * @applied_rate) should always equal the rate that has been
+ * requested for playback. For example, if an element has an input segment
+ * with intended playback @rate of 2.0 and applied_rate of 1.0, it can adjust
+ * incoming timestamps and buffer content by half and output a newsegment event
  * with @rate of 1.0 and @applied_rate of 2.0
  *
  * After a newsegment event, the buffer stream time is calculated with:
  *
- *   position + (TIMESTAMP(buf) - start) * ABS (rate * applied_rate)
+ *   time + (TIMESTAMP(buf) - start) * ABS (rate * applied_rate)
  *
- * Returns: (transfer full): a new newsegment event.
- *
- * Since: 0.10.6
+ * Returns: (transfer full): the new SEGMENT event.
  */
 GstEvent *
-gst_event_new_new_segment_full (gboolean update, gdouble rate,
-    gdouble applied_rate, GstFormat format, gint64 start, gint64 stop,
-    gint64 position)
+gst_event_new_segment (GstSegment * segment)
 {
   GstEvent *event;
-  GstStructure *structure;
-
-  g_return_val_if_fail (rate != 0.0, NULL);
-  g_return_val_if_fail (applied_rate != 0.0, NULL);
 
-  if (format == GST_FORMAT_TIME) {
-    GST_CAT_INFO (GST_CAT_EVENT,
-        "creating newsegment update %d, rate %lf, format GST_FORMAT_TIME, "
-        "start %" GST_TIME_FORMAT ", stop %" GST_TIME_FORMAT
-        ", position %" GST_TIME_FORMAT,
-        update, rate, GST_TIME_ARGS (start),
-        GST_TIME_ARGS (stop), GST_TIME_ARGS (position));
-  } else {
-    GST_CAT_INFO (GST_CAT_EVENT,
-        "creating newsegment update %d, rate %lf, format %s, "
-        "start %" G_GINT64_FORMAT ", stop %" G_GINT64_FORMAT ", position %"
-        G_GINT64_FORMAT, update, rate, gst_format_get_name (format), start,
-        stop, position);
-  }
+  g_return_val_if_fail (segment != NULL, NULL);
 
-  g_return_val_if_fail (position != -1, NULL);
-  g_return_val_if_fail (start != -1, NULL);
-  if (stop != -1)
-    g_return_val_if_fail (start <= stop, NULL);
+  GST_CAT_INFO (GST_CAT_EVENT, "creating segment event %" GST_SEGMENT_FORMAT,
+      segment);
 
-  structure = gst_structure_id_new (GST_QUARK (EVENT_NEWSEGMENT),
-      GST_QUARK (UPDATE), G_TYPE_BOOLEAN, update,
-      GST_QUARK (RATE), G_TYPE_DOUBLE, rate,
-      GST_QUARK (APPLIED_RATE), G_TYPE_DOUBLE, applied_rate,
-      GST_QUARK (FORMAT), GST_TYPE_FORMAT, format,
-      GST_QUARK (START), G_TYPE_INT64, start,
-      GST_QUARK (STOP), G_TYPE_INT64, stop,
-      GST_QUARK (POSITION), G_TYPE_INT64, position, NULL);
-  event = gst_event_new_custom (GST_EVENT_NEWSEGMENT, structure);
+  event = gst_event_new_custom (GST_EVENT_SEGMENT,
+      gst_structure_id_new (GST_QUARK (EVENT_SEGMENT),
+          GST_QUARK (SEGMENT), GST_TYPE_SEGMENT, segment, NULL));
 
   return event;
 }
 
 /**
- * gst_event_parse_new_segment_full:
- * @event: The event to query
- * @update: (out): A pointer to the update flag of the segment
- * @rate: (out): A pointer to the rate of the segment
- * @applied_rate: (out): A pointer to the applied_rate of the segment
- * @format: (out): A pointer to the format of the newsegment values
- * @start: (out): A pointer to store the start value in
- * @stop: (out): A pointer to store the stop value in
- * @position: (out): A pointer to store the stream time in
- *
- * Get the update, rate, applied_rate, format, start, stop and 
- * position in the newsegment event. See gst_event_new_new_segment_full() 
- * for a full description of the newsegment event.
- *
- * Since: 0.10.6
+ * gst_event_parse_segment:
+ * @event: The event to parse
+ * @segment: (out) (transfer none): a pointer to a #GstSegment
+ *
+ * Parses a segment @event and stores the result in the given @segment location.
+ * @segment remains valid only until the @event is freed. Don't modify the segment
+ * and make a copy if you want to modify it or store it for later use.
  */
 void
-gst_event_parse_new_segment_full (GstEvent * event, gboolean * update,
-    gdouble * rate, gdouble * applied_rate, GstFormat * format,
-    gint64 * start, gint64 * stop, gint64 * position)
+gst_event_parse_segment (GstEvent * event, const GstSegment ** segment)
 {
-  const GstStructure *structure;
+  GstStructure *structure;
 
   g_return_if_fail (GST_IS_EVENT (event));
-  g_return_if_fail (GST_EVENT_TYPE (event) == GST_EVENT_NEWSEGMENT);
+  g_return_if_fail (GST_EVENT_TYPE (event) == GST_EVENT_SEGMENT);
 
-  structure = event->structure;
-  if (G_LIKELY (update))
-    *update =
-        g_value_get_boolean (gst_structure_id_get_value (structure,
-            GST_QUARK (UPDATE)));
-  if (G_LIKELY (rate))
-    *rate =
-        g_value_get_double (gst_structure_id_get_value (structure,
-            GST_QUARK (RATE)));
-  if (G_LIKELY (applied_rate))
-    *applied_rate =
-        g_value_get_double (gst_structure_id_get_value (structure,
-            GST_QUARK (APPLIED_RATE)));
-  if (G_LIKELY (format))
-    *format =
-        g_value_get_enum (gst_structure_id_get_value (structure,
-            GST_QUARK (FORMAT)));
-  if (G_LIKELY (start))
-    *start =
-        g_value_get_int64 (gst_structure_id_get_value (structure,
-            GST_QUARK (START)));
-  if (G_LIKELY (stop))
-    *stop =
-        g_value_get_int64 (gst_structure_id_get_value (structure,
-            GST_QUARK (STOP)));
-  if (G_LIKELY (position))
-    *position =
-        g_value_get_int64 (gst_structure_id_get_value (structure,
-            GST_QUARK (POSITION)));
+  if (segment) {
+    structure = GST_EVENT_STRUCTURE (event);
+    *segment = g_value_get_boxed (gst_structure_id_get_value (structure,
+            GST_QUARK (SEGMENT)));
+  }
+}
+
+/**
+ * gst_event_copy_segment:
+ * @event: The event to parse
+ * @segment: a pointer to a #GstSegment
+ *
+ * Parses a segment @event and copies the #GstSegment into the location
+ * given by @segment.
+ */
+void
+gst_event_copy_segment (GstEvent * event, GstSegment * segment)
+{
+  const GstSegment *src;
+
+  g_return_if_fail (GST_IS_EVENT (event));
+  g_return_if_fail (GST_EVENT_TYPE (event) == GST_EVENT_SEGMENT);
+
+  if (segment) {
+    gst_event_parse_segment (event, &src);
+    gst_segment_copy_into (src, segment);
+  }
 }
 
 /**
@@ -715,7 +742,7 @@ gst_event_parse_tag (GstEvent * event, GstTagList ** taglist)
   g_return_if_fail (GST_EVENT_TYPE (event) == GST_EVENT_TAG);
 
   if (taglist)
-    *taglist = (GstTagList *) event->structure;
+    *taglist = (GstTagList *) GST_EVENT_STRUCTURE (event);
 }
 
 /* buffersize event */
@@ -774,7 +801,7 @@ gst_event_parse_buffer_size (GstEvent * event, GstFormat * format,
   g_return_if_fail (GST_IS_EVENT (event));
   g_return_if_fail (GST_EVENT_TYPE (event) == GST_EVENT_BUFFERSIZE);
 
-  structure = event->structure;
+  structure = GST_EVENT_STRUCTURE (event);
   if (format)
     *format =
         g_value_get_enum (gst_structure_id_get_value (structure,
@@ -795,33 +822,6 @@ gst_event_parse_buffer_size (GstEvent * event, GstFormat * format,
 
 /**
  * gst_event_new_qos:
- * @proportion: the proportion of the qos message
- * @diff: The time difference of the last Clock sync
- * @timestamp: The timestamp of the buffer
- *
- * Allocate a new qos event with the given values. This function calls
- * gst_event_new_qos_full() with the type set to #GST_QOS_TYPE_OVERFLOW
- * when diff is negative (buffers are in time) and #GST_QOS_TYPE_UNDERFLOW
- * when @diff is positive (buffers are late).
- *
- * Returns: (transfer full): a new QOS event.
- */
-GstEvent *
-gst_event_new_qos (gdouble proportion, GstClockTimeDiff diff,
-    GstClockTime timestamp)
-{
-  GstQOSType type;
-
-  if (diff <= 0)
-    type = GST_QOS_TYPE_OVERFLOW;
-  else
-    type = GST_QOS_TYPE_UNDERFLOW;
-
-  return gst_event_new_qos_full (type, proportion, diff, timestamp);
-}
-
-/**
- * gst_event_new_qos_full:
  * @type: the QoS type
  * @proportion: the proportion of the qos message
  * @diff: The time difference of the last Clock sync
@@ -871,11 +871,9 @@ gst_event_new_qos (gdouble proportion, GstClockTimeDiff diff,
  * event and implement custom application specific QoS handling.
  *
  * Returns: (transfer full): a new QOS event.
- *
- * Since: 0.10.33
  */
 GstEvent *
-gst_event_new_qos_full (GstQOSType type, gdouble proportion,
+gst_event_new_qos (GstQOSType type, gdouble proportion,
     GstClockTimeDiff diff, GstClockTime timestamp)
 {
   GstEvent *event;
@@ -902,35 +900,16 @@ gst_event_new_qos_full (GstQOSType type, gdouble proportion,
 /**
  * gst_event_parse_qos:
  * @event: The event to query
- * @proportion: (out): A pointer to store the proportion in
- * @diff: (out): A pointer to store the diff in
- * @timestamp: (out): A pointer to store the timestamp in
- *
- * Get the proportion, diff and timestamp in the qos event. See
- * gst_event_new_qos() for more information about the different QoS values.
- */
-void
-gst_event_parse_qos (GstEvent * event, gdouble * proportion,
-    GstClockTimeDiff * diff, GstClockTime * timestamp)
-{
-  gst_event_parse_qos_full (event, NULL, proportion, diff, timestamp);
-}
-
-/**
- * gst_event_parse_qos_full:
- * @event: The event to query
  * @type: (out): A pointer to store the QoS type in
  * @proportion: (out): A pointer to store the proportion in
  * @diff: (out): A pointer to store the diff in
  * @timestamp: (out): A pointer to store the timestamp in
  *
  * Get the type, proportion, diff and timestamp in the qos event. See
- * gst_event_new_qos_full() for more information about the different QoS values.
- *
- * Since: 0.10.33
+ * gst_event_new_qos() for more information about the different QoS values.
  */
 void
-gst_event_parse_qos_full (GstEvent * event, GstQOSType * type,
+gst_event_parse_qos (GstEvent * event, GstQOSType * type,
     gdouble * proportion, GstClockTimeDiff * diff, GstClockTime * timestamp)
 {
   const GstStructure *structure;
@@ -938,7 +917,7 @@ gst_event_parse_qos_full (GstEvent * event, GstQOSType * type,
   g_return_if_fail (GST_IS_EVENT (event));
   g_return_if_fail (GST_EVENT_TYPE (event) == GST_EVENT_QOS);
 
-  structure = event->structure;
+  structure = GST_EVENT_STRUCTURE (event);
   if (type)
     *type =
         g_value_get_enum (gst_structure_id_get_value (structure,
@@ -1062,7 +1041,7 @@ gst_event_parse_seek (GstEvent * event, gdouble * rate,
   g_return_if_fail (GST_IS_EVENT (event));
   g_return_if_fail (GST_EVENT_TYPE (event) == GST_EVENT_SEEK);
 
-  structure = event->structure;
+  structure = GST_EVENT_STRUCTURE (event);
   if (rate)
     *rate =
         g_value_get_double (gst_structure_id_get_value (structure,
@@ -1158,8 +1137,8 @@ gst_event_parse_latency (GstEvent * event, GstClockTime * latency)
 
   if (latency)
     *latency =
-        g_value_get_uint64 (gst_structure_id_get_value (event->structure,
-            GST_QUARK (LATENCY)));
+        g_value_get_uint64 (gst_structure_id_get_value (GST_EVENT_STRUCTURE
+            (event), GST_QUARK (LATENCY)));
 }
 
 /**
@@ -1232,7 +1211,7 @@ gst_event_parse_step (GstEvent * event, GstFormat * format, guint64 * amount,
   g_return_if_fail (GST_IS_EVENT (event));
   g_return_if_fail (GST_EVENT_TYPE (event) == GST_EVENT_STEP);
 
-  structure = event->structure;
+  structure = GST_EVENT_STRUCTURE (event);
   if (format)
     *format = g_value_get_enum (gst_structure_id_get_value (structure,
             GST_QUARK (FORMAT)));
@@ -1251,6 +1230,30 @@ gst_event_parse_step (GstEvent * event, GstFormat * format, guint64 * amount,
 }
 
 /**
+ * gst_event_new_reconfigure:
+
+ * Create a new reconfigure event. The purpose of the reconfingure event is
+ * to travel upstream and make elements renegotiate their caps or reconfigure
+ * their buffer pools. This is useful when changing properties on elements
+ * or changing the topology of the pipeline.
+ *
+ * Returns: (transfer full): a new #GstEvent
+ *
+ * Since: 0.11.0
+ */
+GstEvent *
+gst_event_new_reconfigure (void)
+{
+  GstEvent *event;
+
+  GST_CAT_INFO (GST_CAT_EVENT, "creating reconfigure event");
+
+  event = gst_event_new_custom (GST_EVENT_RECONFIGURE, NULL);
+
+  return event;
+}
+
+/**
  * gst_event_new_sink_message:
  * @msg: (transfer none): the #GstMessage to be posted
  *
@@ -1292,11 +1295,14 @@ gst_event_new_sink_message (GstMessage * msg)
 void
 gst_event_parse_sink_message (GstEvent * event, GstMessage ** msg)
 {
+  const GstStructure *structure;
+
   g_return_if_fail (GST_IS_EVENT (event));
   g_return_if_fail (GST_EVENT_TYPE (event) == GST_EVENT_SINK_MESSAGE);
 
+  structure = GST_EVENT_STRUCTURE (event);
   if (msg)
     *msg =
-        GST_MESSAGE (gst_value_dup_mini_object (gst_structure_id_get_value
-            (event->structure, GST_QUARK (MESSAGE))));
+        GST_MESSAGE (g_value_dup_boxed (gst_structure_id_get_value
+            (structure, GST_QUARK (MESSAGE))));
 }
index e7ce453..1402967 100644 (file)
 #ifndef __GST_EVENT_H__
 #define __GST_EVENT_H__
 
-#include <gst/gstminiobject.h>
-#include <gst/gstformat.h>
-#include <gst/gstobject.h>
-#include <gst/gstclock.h>
-#include <gst/gststructure.h>
-#include <gst/gsttaglist.h>
-
-G_BEGIN_DECLS
+typedef struct _GstEvent GstEvent;
 
 /**
  * GstEventTypeFlags:
@@ -40,6 +33,7 @@ G_BEGIN_DECLS
  * @GST_EVENT_TYPE_DOWNSTREAM: Set if the event can travel downstream.
  * @GST_EVENT_TYPE_SERIALIZED: Set if the event should be serialized with data
  *                             flow.
+ * @GST_EVENT_TYPE_STICKY:     Set if the event is sticky on the pads.
  *
  * #GstEventTypeFlags indicate the aspects of the different #GstEventType
  * values. You can get the type flags of a #GstEventType with the
@@ -48,7 +42,8 @@ G_BEGIN_DECLS
 typedef enum {
   GST_EVENT_TYPE_UPSTREAM       = 1 << 0,
   GST_EVENT_TYPE_DOWNSTREAM     = 1 << 1,
-  GST_EVENT_TYPE_SERIALIZED     = 1 << 2
+  GST_EVENT_TYPE_SERIALIZED     = 1 << 2,
+  GST_EVENT_TYPE_STICKY         = 1 << 3
 } GstEventTypeFlags;
 
 /**
@@ -59,21 +54,27 @@ typedef enum {
 #define GST_EVENT_TYPE_BOTH \
     (GST_EVENT_TYPE_UPSTREAM | GST_EVENT_TYPE_DOWNSTREAM)
 
-#define GST_EVENT_TYPE_SHIFT    4
+#define GST_EVENT_MAX_STICKY    16
+#define GST_EVENT_STICKY_SHIFT  8
+#define GST_EVENT_NUM_SHIFT     (GST_EVENT_STICKY_SHIFT + 4)
 
 /**
  * GST_EVENT_MAKE_TYPE:
  * @num: the event number to create
+ * @idx: the index in the sticky array
  * @flags: the event flags
  *
  * when making custom event types, use this macro with the num and
  * the given flags
  */
-#define GST_EVENT_MAKE_TYPE(num,flags) \
-    (((num) << GST_EVENT_TYPE_SHIFT) | (flags))
+#define GST_EVENT_MAKE_TYPE(num,idx,flags) \
+    (((num) << GST_EVENT_NUM_SHIFT) | ((idx) << GST_EVENT_STICKY_SHIFT) | (flags))
 
 #define FLAG(name) GST_EVENT_TYPE_##name
 
+#define GST_EVENT_STICKY_IDX_TYPE(type)  (((type) >> GST_EVENT_STICKY_SHIFT) & 0xf)
+#define GST_EVENT_STICKY_IDX(ev)         GST_EVENT_STICKY_IDX_TYPE(GST_EVENT_TYPE(ev))
+
 /**
  * GstEventType:
  * @GST_EVENT_UNKNOWN: unknown event.
@@ -82,8 +83,8 @@ typedef enum {
  * @GST_EVENT_FLUSH_STOP: Stop a flush operation. This event resets the
  *                 running-time of the pipeline.
  * @GST_EVENT_EOS: End-Of-Stream. No more data is to be expected to follow
- *                 without a NEWSEGMENT event.
- * @GST_EVENT_NEWSEGMENT: A new media segment follows in the dataflow. The
+ *                 without a SEGMENT event.
+ * @GST_EVENT_SEGMENT: A new media segment follows in the dataflow. The
  *                 segment events contains information for clipping buffers and
  *                 converting buffer timestamps to running-time and
  *                 stream-time.
@@ -106,6 +107,8 @@ typedef enum {
  *                     Since: 0.10.12
  * @GST_EVENT_STEP: A request for stepping through the media. Sinks will usually
  *                  execute the step operation. Since: 0.10.24
+ * @GST_EVENT_RECONFIGURE: A request for upstream renegotiating caps and reconfiguring.
+ *                         Since: 0.11.0
  * @GST_EVENT_CUSTOM_UPSTREAM: Upstream custom event
  * @GST_EVENT_CUSTOM_DOWNSTREAM: Downstream custom event that travels in the
  *                        data flow.
@@ -124,32 +127,54 @@ typedef enum {
  */
 /* NOTE: keep in sync with quark registration in gstevent.c */
 typedef enum {
-  GST_EVENT_UNKNOWN               = GST_EVENT_MAKE_TYPE (0, 0),
+  GST_EVENT_UNKNOWN               = GST_EVENT_MAKE_TYPE (0, 0, 0),
   /* bidirectional events */
-  GST_EVENT_FLUSH_START           = GST_EVENT_MAKE_TYPE (1, FLAG(BOTH)),
-  GST_EVENT_FLUSH_STOP            = GST_EVENT_MAKE_TYPE (2, FLAG(BOTH) | FLAG(SERIALIZED)),
+  GST_EVENT_FLUSH_START           = GST_EVENT_MAKE_TYPE (1, 0, FLAG(BOTH)),
+  GST_EVENT_FLUSH_STOP            = GST_EVENT_MAKE_TYPE (2, 0, FLAG(BOTH) | FLAG(SERIALIZED)),
   /* downstream serialized events */
-  GST_EVENT_EOS                   = GST_EVENT_MAKE_TYPE (5, FLAG(DOWNSTREAM) | FLAG(SERIALIZED)),
-  GST_EVENT_NEWSEGMENT            = GST_EVENT_MAKE_TYPE (6, FLAG(DOWNSTREAM) | FLAG(SERIALIZED)),
-  GST_EVENT_TAG                   = GST_EVENT_MAKE_TYPE (7, FLAG(DOWNSTREAM) | FLAG(SERIALIZED)),
-  GST_EVENT_BUFFERSIZE            = GST_EVENT_MAKE_TYPE (8, FLAG(DOWNSTREAM) | FLAG(SERIALIZED)),
-  GST_EVENT_SINK_MESSAGE          = GST_EVENT_MAKE_TYPE (9, FLAG(DOWNSTREAM) | FLAG(SERIALIZED)),
+  GST_EVENT_CAPS                  = GST_EVENT_MAKE_TYPE (5, 1, FLAG(DOWNSTREAM) | FLAG(SERIALIZED) | FLAG(STICKY)),
+  GST_EVENT_SEGMENT               = GST_EVENT_MAKE_TYPE (6, 2, FLAG(DOWNSTREAM) | FLAG(SERIALIZED) | FLAG(STICKY)),
+  GST_EVENT_TAG                   = GST_EVENT_MAKE_TYPE (7, 3, FLAG(DOWNSTREAM) | FLAG(SERIALIZED) | FLAG(STICKY)),
+  GST_EVENT_BUFFERSIZE            = GST_EVENT_MAKE_TYPE (8, 4, FLAG(DOWNSTREAM) | FLAG(SERIALIZED) | FLAG(STICKY)),
+  GST_EVENT_SINK_MESSAGE          = GST_EVENT_MAKE_TYPE (9, 5, FLAG(DOWNSTREAM) | FLAG(SERIALIZED) | FLAG(STICKY)),
+  GST_EVENT_EOS                   = GST_EVENT_MAKE_TYPE (10, 6, FLAG(DOWNSTREAM) | FLAG(SERIALIZED) | FLAG(STICKY)),
+
   /* upstream events */
-  GST_EVENT_QOS                   = GST_EVENT_MAKE_TYPE (15, FLAG(UPSTREAM)),
-  GST_EVENT_SEEK                  = GST_EVENT_MAKE_TYPE (16, FLAG(UPSTREAM)),
-  GST_EVENT_NAVIGATION            = GST_EVENT_MAKE_TYPE (17, FLAG(UPSTREAM)),
-  GST_EVENT_LATENCY               = GST_EVENT_MAKE_TYPE (18, FLAG(UPSTREAM)),
-  GST_EVENT_STEP                  = GST_EVENT_MAKE_TYPE (19, FLAG(UPSTREAM)),
+  GST_EVENT_QOS                   = GST_EVENT_MAKE_TYPE (15, 0, FLAG(UPSTREAM)),
+  GST_EVENT_SEEK                  = GST_EVENT_MAKE_TYPE (16, 0, FLAG(UPSTREAM)),
+  GST_EVENT_NAVIGATION            = GST_EVENT_MAKE_TYPE (17, 0, FLAG(UPSTREAM)),
+  GST_EVENT_LATENCY               = GST_EVENT_MAKE_TYPE (18, 0, FLAG(UPSTREAM)),
+  GST_EVENT_STEP                  = GST_EVENT_MAKE_TYPE (19, 0, FLAG(UPSTREAM)),
+  GST_EVENT_RECONFIGURE           = GST_EVENT_MAKE_TYPE (20, 0, FLAG(UPSTREAM)),
 
   /* custom events start here */
-  GST_EVENT_CUSTOM_UPSTREAM       = GST_EVENT_MAKE_TYPE (32, FLAG(UPSTREAM)),
-  GST_EVENT_CUSTOM_DOWNSTREAM     = GST_EVENT_MAKE_TYPE (32, FLAG(DOWNSTREAM) | FLAG(SERIALIZED)),
-  GST_EVENT_CUSTOM_DOWNSTREAM_OOB = GST_EVENT_MAKE_TYPE (32, FLAG(DOWNSTREAM)),
-  GST_EVENT_CUSTOM_BOTH           = GST_EVENT_MAKE_TYPE (32, FLAG(BOTH) | FLAG(SERIALIZED)),
-  GST_EVENT_CUSTOM_BOTH_OOB       = GST_EVENT_MAKE_TYPE (32, FLAG(BOTH))
+  GST_EVENT_CUSTOM_UPSTREAM       = GST_EVENT_MAKE_TYPE (32, 0, FLAG(UPSTREAM)),
+  GST_EVENT_CUSTOM_DOWNSTREAM     = GST_EVENT_MAKE_TYPE (32, 0, FLAG(DOWNSTREAM) | FLAG(SERIALIZED)),
+  GST_EVENT_CUSTOM_DOWNSTREAM_OOB = GST_EVENT_MAKE_TYPE (32, 0, FLAG(DOWNSTREAM)),
+  GST_EVENT_CUSTOM_BOTH           = GST_EVENT_MAKE_TYPE (32, 0, FLAG(BOTH) | FLAG(SERIALIZED)),
+  GST_EVENT_CUSTOM_BOTH_OOB       = GST_EVENT_MAKE_TYPE (32, 0, FLAG(BOTH))
 } GstEventType;
 #undef FLAG
 
+#include <gst/gstminiobject.h>
+#include <gst/gstformat.h>
+#include <gst/gstobject.h>
+#include <gst/gstclock.h>
+#include <gst/gststructure.h>
+#include <gst/gsttaglist.h>
+#include <gst/gstsegment.h>
+#include <gst/gstsegment.h>
+#include <gst/gstmessage.h>
+
+G_BEGIN_DECLS
+
+extern GType _gst_event_type;
+
+#define GST_TYPE_EVENT                  (_gst_event_type)
+#define GST_IS_EVENT(obj)               (GST_IS_MINI_OBJECT_TYPE (obj, GST_TYPE_EVENT))
+#define GST_EVENT_CAST(obj)             ((GstEvent *)(obj))
+#define GST_EVENT(obj)                  (GST_EVENT_CAST(obj))
+
 /**
  * GST_EVENT_TRACE_NAME:
  *
@@ -157,17 +182,6 @@ typedef enum {
  */
 #define GST_EVENT_TRACE_NAME    "GstEvent"
 
-typedef struct _GstEvent GstEvent;
-typedef struct _GstEventClass GstEventClass;
-
-#define GST_TYPE_EVENT                  (gst_event_get_type())
-#define GST_IS_EVENT(obj)               (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_EVENT))
-#define GST_IS_EVENT_CLASS(klass)       (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_EVENT))
-#define GST_EVENT_GET_CLASS(obj)        (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_EVENT, GstEventClass))
-#define GST_EVENT(obj)                  (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_EVENT, GstEvent))
-#define GST_EVENT_CLASS(klass)          (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_EVENT, GstEventClass))
-#define GST_EVENT_CAST(obj)             ((GstEvent *)(obj))
-
 /**
  * GST_EVENT_TYPE:
  * @event: the event to query
@@ -194,12 +208,12 @@ typedef struct _GstEventClass GstEventClass;
 #define GST_EVENT_TIMESTAMP(event)      (GST_EVENT_CAST(event)->timestamp)
 
 /**
- * GST_EVENT_SRC:
+ * GST_EVENT_SEQNUM:
  * @event: the event to query
  *
- * The source #GstObject that generated this event.
+ * The sequence number of @event.
  */
-#define GST_EVENT_SRC(event)            (GST_EVENT_CAST(event)->src)
+#define GST_EVENT_SEQNUM(event)         (GST_EVENT_CAST(event)->seqnum)
 
 /**
  * GST_EVENT_IS_UPSTREAM:
@@ -222,8 +236,35 @@ typedef struct _GstEventClass GstEventClass;
  * Check if an event is serialized with the data stream.
  */
 #define GST_EVENT_IS_SERIALIZED(ev)     !!(GST_EVENT_TYPE (ev) & GST_EVENT_TYPE_SERIALIZED)
+/**
+ * GST_EVENT_IS_STICKY:
+ * @ev: the event to query
+ *
+ * Check if an event is sticky on the pads.
+ */
+#define GST_EVENT_IS_STICKY(ev)     !!(GST_EVENT_TYPE (ev) & GST_EVENT_TYPE_STICKY)
 
 /**
+ * gst_event_is_writable:
+ * @ev: a #GstEvent
+ *
+ * Tests if you can safely write data into a event's structure or validly
+ * modify the seqnum and timestamp field.
+ */
+#define         gst_event_is_writable(ev)     gst_mini_object_is_writable (GST_MINI_OBJECT_CAST (ev))
+/**
+ * gst_event_make_writable:
+ * @ev: (transfer full): a #GstEvent
+ *
+ * Makes a writable event from the given event. If the source event is
+ * already writable, this will simply return the same event. A copy will
+ * otherwise be made using gst_event_copy().
+ *
+ * Returns: (transfer full): a writable event which may or may not be the
+ *     same as @ev
+ */
+#define         gst_event_make_writable(ev)   GST_EVENT_CAST (gst_mini_object_make_writable (GST_MINI_OBJECT_CAST (ev)))
+/**
  * gst_event_replace:
  * @old_event: (inout) (transfer full): pointer to a pointer to a #GstEvent
  *     to be replaced.
@@ -237,81 +278,39 @@ typedef struct _GstEventClass GstEventClass;
  *
  * Either @new_event or the #GstEvent pointed to by @old_event may be NULL.
  *
- * Since: 0.10.3
+ * Returns: TRUE if @new_event was different from @old_event
  */
 #define         gst_event_replace(old_event,new_event) \
     gst_mini_object_replace ((GstMiniObject **)(old_event), GST_MINI_OBJECT_CAST (new_event))
-
 /**
- * GstSeekType:
- * @GST_SEEK_TYPE_NONE: no change in position is required
- * @GST_SEEK_TYPE_CUR: change relative to currently configured segment. This
- *    can't be used to seek relative to the current playback position - do a
- *    position query, calculate the desired position and then do an absolute
- *    position seek instead if that's what you want to do.
- * @GST_SEEK_TYPE_SET: absolute position is requested
- * @GST_SEEK_TYPE_END: relative position to duration is requested
- *
- * The different types of seek events. When constructing a seek event with
- * gst_event_new_seek(), a format, a seek method and optional flags are to
- * be provided. The seek event is then inserted into the graph with
- * gst_pad_send_event() or gst_element_send_event().
+ * gst_event_steal:
+ * @old_event: (inout) (transfer full): pointer to a pointer to a #GstEvent
+ *     to be stolen.
+ *
+ * Atomically replace the #GstEvent pointed to by @old_event with NULL and
+ * return the original event.
+ *
+ * Returns: the #GstEvent that was in @old_event
  */
-typedef enum {
-  /* one of these */
-  GST_SEEK_TYPE_NONE            = 0,
-  GST_SEEK_TYPE_CUR             = 1,
-  GST_SEEK_TYPE_SET             = 2,
-  GST_SEEK_TYPE_END             = 3
-} GstSeekType;
-
+#define         gst_event_steal(old_event) \
+    GST_EVENT_CAST (gst_mini_object_steal ((GstMiniObject **)(old_event)))
 /**
- * GstSeekFlags:
- * @GST_SEEK_FLAG_NONE: no flag
- * @GST_SEEK_FLAG_FLUSH: flush pipeline
- * @GST_SEEK_FLAG_ACCURATE: accurate position is requested, this might
- *                     be considerably slower for some formats.
- * @GST_SEEK_FLAG_KEY_UNIT: seek to the nearest keyframe. This might be
- *                     faster but less accurate.
- * @GST_SEEK_FLAG_SEGMENT: perform a segment seek.
- * @GST_SEEK_FLAG_SKIP: when doing fast foward or fast reverse playback, allow
- *                     elements to skip frames instead of generating all
- *                     frames. Since 0.10.22.
- *
- * Flags to be used with gst_element_seek() or gst_event_new_seek(). All flags
- * can be used together.
- *
- * A non flushing seek might take some time to perform as the currently
- * playing data in the pipeline will not be cleared.
- *
- * An accurate seek might be slower for formats that don't have any indexes
- * or timestamp markers in the stream. Specifying this flag might require a
- * complete scan of the file in those cases.
- *
- * When performing a segment seek: after the playback of the segment completes,
- * no EOS will be emmited by the element that performed the seek, but a
- * #GST_MESSAGE_SEGMENT_DONE message will be posted on the bus by the element.
- * When this message is posted, it is possible to send a new seek event to
- * continue playback. With this seek method it is possible to perform seemless
- * looping or simple linear editing.
- *
- * When doing fast forward (rate > 1.0) or fast reverse (rate < -1.0) trickmode
- * playback, the @GST_SEEK_FLAG_SKIP flag can be used to instruct decoders
- * and demuxers to adjust the playback rate by skipping frames. This can improve
- * performance and decrease CPU usage because not all frames need to be decoded.
- *
- * Also see part-seeking.txt in the GStreamer design documentation for more
- * details on the meaning of these flags and the behaviour expected of
- * elements that handle them.
+ * gst_event_take:
+ * @old_event: (inout) (transfer full): pointer to a pointer to a #GstEvent
+ *     to be stolen.
+ * @new_event: (allow-none) (transfer full): pointer to a #GstEvent that will
+ *     replace the event pointed to by @old_event.
+ *
+ * Modifies a pointer to a #GstEvent to point to a different #GstEvent. This
+ * function is similar to gst_event_replace() except that it takes ownership of
+ * @new_event.
+ *
+ * Either @new_event or the #GstEvent pointed to by @old_event may be NULL.
+ *
+ * Returns: TRUE if @new_event was different from @old_event
  */
-typedef enum {
-  GST_SEEK_FLAG_NONE            = 0,
-  GST_SEEK_FLAG_FLUSH           = (1 << 0),
-  GST_SEEK_FLAG_ACCURATE        = (1 << 1),
-  GST_SEEK_FLAG_KEY_UNIT        = (1 << 2),
-  GST_SEEK_FLAG_SEGMENT         = (1 << 3),
-  GST_SEEK_FLAG_SKIP            = (1 << 4)
-} GstSeekFlags;
+#define         gst_event_take(old_event,new_event) \
+    gst_mini_object_take ((GstMiniObject **)(old_event), GST_MINI_OBJECT_CAST (new_event))
 
 /**
  * GstQOSType:
@@ -321,12 +320,12 @@ typedef enum {
  *    type is also used when buffers arrive early or in time.
  * @GST_QOS_TYPE_UNDERFLOW: The QoS event type that is produced when downstream
  *    elements are producing data too slowly and need to speed up their processing
- *    rate. 
+ *    rate.
  * @GST_QOS_TYPE_THROTTLE: The QoS event type that is produced when the
  *    application enabled throttling to limit the datarate.
  *
- * The different types of QoS events that can be given to the 
- * gst_event_new_qos_full() method. 
+ * The different types of QoS events that can be given to the
+ * gst_event_new_qos() method.
  *
  * Since: 0.10.33
  */
@@ -341,8 +340,6 @@ typedef enum {
  * @mini_object: the parent structure
  * @type: the #GstEventType of the event
  * @timestamp: the timestamp of the event
- * @src: the src of the event
- * @structure: the #GstStructure containing the event info.
  *
  * A #GstEvent.
  */
@@ -352,22 +349,7 @@ struct _GstEvent {
   /*< public >*/ /* with COW */
   GstEventType  type;
   guint64       timestamp;
-  GstObject     *src;
-
-  GstStructure  *structure;
-
-  /*< private >*/
-  union {
-    guint32 seqnum;
-    gpointer _gst_reserved;
-  } abidata;
-};
-
-struct _GstEventClass {
-  GstMiniObjectClass mini_object_class;
-
-  /*< private >*/
-  gpointer _gst_reserved[GST_PADDING];
+  guint32       seqnum;
 };
 
 const gchar*    gst_event_type_get_name         (GstEventType type);
@@ -376,8 +358,6 @@ GstEventTypeFlags
                 gst_event_type_get_flags        (GstEventType type);
 
 
-GType           gst_event_get_type              (void);
-
 /* refcounting */
 /**
  * gst_event_ref:
@@ -438,6 +418,7 @@ GstEvent*       gst_event_new_custom            (GstEventType type, GstStructure
 
 const GstStructure *
                 gst_event_get_structure         (GstEvent *event);
+GstStructure *  gst_event_writable_structure    (GstEvent *event);
 
 gboolean        gst_event_has_name              (GstEvent *event, const gchar *name);
 
@@ -447,34 +428,21 @@ void            gst_event_set_seqnum            (GstEvent *event, guint32 seqnum
 
 /* flush events */
 GstEvent *      gst_event_new_flush_start       (void);
-GstEvent *      gst_event_new_flush_stop        (void);
+
+GstEvent *      gst_event_new_flush_stop        (gboolean reset_time);
+void            gst_event_parse_flush_stop      (GstEvent *event, gboolean *reset_time);
 
 /* EOS event */
 GstEvent *      gst_event_new_eos               (void);
 
-/* newsegment events */
-GstEvent*       gst_event_new_new_segment       (gboolean update, gdouble rate,
-                                                 GstFormat format,
-                                                 gint64 start, gint64 stop,
-                                                 gint64 position);
-GstEvent*       gst_event_new_new_segment_full  (gboolean update, gdouble rate,
-                                                 gdouble applied_rate,
-                                                 GstFormat format,
-                                                 gint64 start, gint64 stop,
-                                                 gint64 position);
-void            gst_event_parse_new_segment     (GstEvent *event,
-                                                 gboolean *update,
-                                                 gdouble *rate,
-                                                 GstFormat *format,
-                                                 gint64 *start, gint64 *stop,
-                                                 gint64 *position);
-void            gst_event_parse_new_segment_full (GstEvent *event,
-                                                 gboolean *update,
-                                                 gdouble *rate,
-                                                 gdouble *applied_rate,
-                                                 GstFormat *format,
-                                                 gint64 *start, gint64 *stop,
-                                                 gint64 *position);
+/* Caps events */
+GstEvent *      gst_event_new_caps              (GstCaps *caps);
+void            gst_event_parse_caps            (GstEvent *event, GstCaps **caps);
+
+/* segment event */
+GstEvent*       gst_event_new_segment           (GstSegment *segment);
+void            gst_event_parse_segment         (GstEvent *event, const GstSegment **segment);
+void            gst_event_copy_segment          (GstEvent *event, GstSegment *segment);
 
 /* tag event */
 GstEvent*       gst_event_new_tag               (GstTagList *taglist);
@@ -486,14 +454,14 @@ GstEvent *      gst_event_new_buffer_size       (GstFormat format, gint64 minsiz
 void            gst_event_parse_buffer_size     (GstEvent *event, GstFormat *format, gint64 *minsize,
                                                  gint64 *maxsize, gboolean *async);
 
+/* sink message */
+GstEvent*       gst_event_new_sink_message      (GstMessage *msg);
+void            gst_event_parse_sink_message    (GstEvent *event, GstMessage **msg);
+
 /* QOS events */
-GstEvent*       gst_event_new_qos               (gdouble proportion, GstClockTimeDiff diff,
-                                                 GstClockTime timestamp);
-GstEvent*       gst_event_new_qos_full          (GstQOSType type, gdouble proportion,
+GstEvent*       gst_event_new_qos               (GstQOSType type, gdouble proportion,
                                                  GstClockTimeDiff diff, GstClockTime timestamp);
-void            gst_event_parse_qos             (GstEvent *event, gdouble *proportion, GstClockTimeDiff *diff,
-                                                 GstClockTime *timestamp);
-void            gst_event_parse_qos_full        (GstEvent *event, GstQOSType *type,
+void            gst_event_parse_qos             (GstEvent *event, GstQOSType *type,
                                                  gdouble *proportion, GstClockTimeDiff *diff,
                                                  GstClockTime *timestamp);
 /* seek event */
@@ -504,6 +472,7 @@ void            gst_event_parse_seek            (GstEvent *event, gdouble *rate,
                                                  GstSeekFlags *flags,
                                                  GstSeekType *start_type, gint64 *start,
                                                  GstSeekType *stop_type, gint64 *stop);
+
 /* navigation event */
 GstEvent*       gst_event_new_navigation        (GstStructure *structure);
 
@@ -517,6 +486,9 @@ GstEvent*       gst_event_new_step              (GstFormat format, guint64 amoun
 void            gst_event_parse_step            (GstEvent *event, GstFormat *format, guint64 *amount,
                                                  gdouble *rate, gboolean *flush, gboolean *intermediate);
 
+/* renegotiate event */
+GstEvent*       gst_event_new_reconfigure       (void);
+
 G_END_DECLS
 
 #endif /* __GST_EVENT_H__ */
index 263fa1d..0006e2c 100644 (file)
@@ -144,8 +144,8 @@ gst_format_register (const gchar * nick, const gchar * description)
   GstFormatDefinition *format;
   GstFormat query;
 
-  g_return_val_if_fail (nick != NULL, 0);
-  g_return_val_if_fail (description != NULL, 0);
+  g_return_val_if_fail (nick != NULL, GST_FORMAT_UNDEFINED);
+  g_return_val_if_fail (description != NULL, GST_FORMAT_UNDEFINED);
 
   query = gst_format_get_by_nick (nick);
   if (query != GST_FORMAT_UNDEFINED)
@@ -182,7 +182,7 @@ gst_format_get_by_nick (const gchar * nick)
 {
   GstFormatDefinition *format;
 
-  g_return_val_if_fail (nick != NULL, 0);
+  g_return_val_if_fail (nick != NULL, GST_FORMAT_UNDEFINED);
 
   g_static_mutex_lock (&mutex);
   format = g_hash_table_lookup (_nick_to_format, nick);
@@ -257,8 +257,7 @@ gst_format_iterate_definitions (void)
   g_static_mutex_lock (&mutex);
   /* FIXME: register a boxed type for GstFormatDefinition */
   result = gst_iterator_new_list (G_TYPE_POINTER,
-      g_static_mutex_get_mutex (&mutex), &_n_values, &_gst_formats,
-      NULL, NULL, NULL);
+      g_static_mutex_get_mutex (&mutex), &_n_values, &_gst_formats, NULL, NULL);
   g_static_mutex_unlock (&mutex);
 
   return result;
index 4a024a2..f2f3e7e 100644 (file)
@@ -77,19 +77,6 @@ static GstPad *gst_proxy_pad_get_target (GstPad * pad);
 static void gst_proxy_pad_dispose (GObject * object);
 static void gst_proxy_pad_finalize (GObject * object);
 
-#if !defined(GST_DISABLE_LOADSAVE) && !defined(GST_REMOVE_DEPRECATED)
-#ifdef GST_DISABLE_DEPRECATED
-#include <libxml/parser.h>
-#endif
-static xmlNodePtr gst_proxy_pad_save_thyself (GstObject * object,
-    xmlNodePtr parent);
-#endif
-
-static void on_src_target_notify (GstPad * target,
-    GParamSpec * unused, gpointer user_data);
-
-static GParamSpec *pspec_caps = NULL;
-
 /**
  * gst_proxy_pad_query_type_default:
  * @pad: a #GstPad.
@@ -199,52 +186,16 @@ gst_proxy_pad_iterate_internal_links_default (GstPad * pad)
       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;
+    GValue v = { 0, };
 
-  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);
-
-  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;
 }
 
 /**
@@ -332,32 +283,9 @@ gst_proxy_pad_getrange_default (GstPad * pad, guint64 offset, guint size,
 }
 
 /**
- * gst_proxy_pad_checkgetrange_default:
- * @pad: a src #GstPad, returns #GST_FLOW_ERROR if not.
- *
- * Invoke the default checkgetrange function of the proxy pad.
- *
- * Returns: a #gboolean from the pad.
- *
- * Since: 0.10.35
- */
-gboolean
-gst_proxy_pad_checkgetrange_default (GstPad * pad)
-{
-  gboolean result;
-  GstPad *internal;
-
-  g_return_val_if_fail (GST_IS_PROXY_PAD (pad), FALSE);
-
-  internal = GST_PROXY_PAD_INTERNAL (pad);
-  result = gst_pad_check_pull_range (internal);
-
-  return result;
-}
-
-/**
  * 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.
  *
@@ -366,7 +294,7 @@ gst_proxy_pad_checkgetrange_default (GstPad * pad)
  * Since: 0.10.35
  */
 GstCaps *
-gst_proxy_pad_getcaps_default (GstPad * pad)
+gst_proxy_pad_getcaps_default (GstPad * pad, GstCaps * filter)
 {
   GstPad *target;
   GstCaps *res;
@@ -378,7 +306,7 @@ gst_proxy_pad_getcaps_default (GstPad * 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);
@@ -391,7 +319,7 @@ gst_proxy_pad_getcaps_default (GstPad * pad)
 
       filt = GST_PAD_TEMPLATE_CAPS (templ);
       if (filt) {
-        tmp = gst_caps_intersect (filt, res);
+        tmp = gst_caps_intersect_full (res, filt, GST_CAPS_INTERSECT_FIRST);
         gst_caps_unref (res);
         res = tmp;
         GST_DEBUG_OBJECT (pad,
@@ -406,6 +334,15 @@ gst_proxy_pad_getcaps_default (GstPad * pad)
           "using pad template %p with caps %p %" GST_PTR_FORMAT, templ, res,
           res);
       res = gst_caps_ref (res);
+
+      if (filter) {
+        GstCaps *intersection =
+            gst_caps_intersect_full (filter, res, GST_CAPS_INTERSECT_FIRST);
+
+        gst_caps_unref (res);
+        res = intersection;
+      }
+
       goto done;
     }
 
@@ -475,41 +412,6 @@ gst_proxy_pad_fixatecaps_default (GstPad * pad, GstCaps * caps)
   }
 }
 
-/**
- * gst_proxy_pad_setcaps_default:
- * @pad: a  #GstPad to set the capabilities of.
- * @caps: (transfer none): a #GstCaps to set.
- *
- * Invoke the default setcaps function of the proxy pad.
- *
- * Returns: TRUE if the caps could be set. FALSE if the caps were not fixed
- * or bad parameters were provided to this function.
- *
- * Since: 0.10.35
- */
-gboolean
-gst_proxy_pad_setcaps_default (GstPad * pad, GstCaps * caps)
-{
-  GstPad *target;
-  gboolean res;
-
-  g_return_val_if_fail (GST_IS_PROXY_PAD (pad), FALSE);
-  g_return_val_if_fail (caps == NULL || GST_IS_CAPS (caps), FALSE);
-
-  target = gst_proxy_pad_get_target (pad);
-  if (target) {
-    res = gst_pad_set_caps (target, caps);
-    gst_object_unref (target);
-  } else {
-    /* We don't have any target, but we shouldn't return FALSE since this
-     * would stop the actual push of a buffer (which might trigger a pad block
-     * or probe, or properly return GST_FLOW_NOT_LINKED.
-     */
-    res = TRUE;
-  }
-  return res;
-}
-
 static gboolean
 gst_proxy_pad_set_target_unlocked (GstPad * pad, GstPad * target)
 {
@@ -636,16 +538,6 @@ gst_proxy_pad_class_init (GstProxyPadClass * klass)
   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_query_type_default);
   GST_DEBUG_REGISTER_FUNCPTR (gst_proxy_pad_event_default);
@@ -654,13 +546,10 @@ gst_proxy_pad_class_init (GstProxyPadClass * klass)
   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
@@ -710,64 +599,9 @@ gst_proxy_pad_init (GstProxyPad * ppad)
   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)
@@ -779,8 +613,6 @@ gst_proxy_pad_save_thyself (GstObject * object, xmlNodePtr parent)
 struct _GstGhostPadPrivate
 {
   /* with PROXY_LOCK */
-  gulong notify_id;
-
   gboolean constructed;
 };
 
@@ -1016,124 +848,14 @@ gst_ghost_pad_unlink_default (GstPad * pad)
 }
 
 static void
-on_int_notify (GstPad * internal, GParamSpec * unused, GstGhostPad * pad)
-{
-  GstCaps *caps;
-  gboolean changed;
-
-  g_object_get (internal, "caps", &caps, NULL);
-
-  GST_DEBUG_OBJECT (pad, "notified %p %" GST_PTR_FORMAT, caps, caps);
-
-  GST_OBJECT_LOCK (pad);
-  changed = (GST_PAD_CAPS (pad) != caps);
-  if (changed)
-    gst_caps_replace (&(GST_PAD_CAPS (pad)), caps);
-  GST_OBJECT_UNLOCK (pad);
-
-  if (changed) {
-#if GLIB_CHECK_VERSION(2,26,0)
-    g_object_notify_by_pspec ((GObject *) pad, pspec_caps);
-#else
-    g_object_notify ((GObject *) pad, "caps");
-#endif
-  }
-
-  if (caps)
-    gst_caps_unref (caps);
-}
-
-static void
-on_src_target_notify (GstPad * target, GParamSpec * unused, gpointer user_data)
-{
-  GstProxyPad *proxypad;
-  GstGhostPad *gpad;
-  GstCaps *caps;
-  gboolean changed;
-
-  g_object_get (target, "caps", &caps, NULL);
-
-  GST_OBJECT_LOCK (target);
-  /* First check if the peer is still available and our proxy pad */
-  if (!GST_PAD_PEER (target) || !GST_IS_PROXY_PAD (GST_PAD_PEER (target))) {
-    GST_OBJECT_UNLOCK (target);
-    goto done;
-  }
-
-  proxypad = GST_PROXY_PAD (GST_PAD_PEER (target));
-  GST_PROXY_LOCK (proxypad);
-  /* Now check if the proxypad's internal pad is still there and
-   * a ghostpad */
-  if (!GST_PROXY_PAD_INTERNAL (proxypad) ||
-      !GST_IS_GHOST_PAD (GST_PROXY_PAD_INTERNAL (proxypad))) {
-    GST_OBJECT_UNLOCK (target);
-    GST_PROXY_UNLOCK (proxypad);
-    goto done;
-  }
-  gpad = GST_GHOST_PAD (GST_PROXY_PAD_INTERNAL (proxypad));
-  g_object_ref (gpad);
-  GST_PROXY_UNLOCK (proxypad);
-  GST_OBJECT_UNLOCK (target);
-
-  GST_OBJECT_LOCK (gpad);
-
-  GST_DEBUG_OBJECT (gpad, "notified %p %" GST_PTR_FORMAT, caps, caps);
-
-  changed = (GST_PAD_CAPS (gpad) != caps);
-  if (changed)
-    gst_caps_replace (&(GST_PAD_CAPS (gpad)), caps);
-  GST_OBJECT_UNLOCK (gpad);
-
-  if (changed) {
-#if GLIB_CHECK_VERSION(2,26,0)
-    g_object_notify_by_pspec ((GObject *) gpad, pspec_caps);
-#else
-    g_object_notify ((GObject *) gpad, "caps");
-#endif
-  }
-
-  g_object_unref (gpad);
-
-done:
-  if (caps)
-    gst_caps_unref (caps);
-}
-
-/**
- * gst_ghost_pad_setcaps_default:
- * @pad: the #GstPad to link.
- * @caps: (transfer none): the #GstCaps to set
- *
- * Invoke the default setcaps function of a ghost pad.
- *
- * Returns: %TRUE if the operation was successful
- *
- * Since: 0.10.35
- */
-gboolean
-gst_ghost_pad_setcaps_default (GstPad * pad, GstCaps * caps)
-{
-  g_return_val_if_fail (GST_IS_GHOST_PAD (pad), FALSE);
-  g_return_val_if_fail (caps == NULL || GST_IS_CAPS (caps), FALSE);
-
-  if (GST_PAD_DIRECTION (pad) == GST_PAD_SRC)
-    return TRUE;
-
-  return gst_proxy_pad_setcaps_default (pad, caps);
-}
-
-static void
 gst_ghost_pad_class_init (GstGhostPadClass * klass)
 {
   GObjectClass *gobject_class = (GObjectClass *) klass;
 
   g_type_class_add_private (klass, sizeof (GstGhostPadPrivate));
 
-  pspec_caps = g_object_class_find_property (gobject_class, "caps");
-
   gobject_class->dispose = gst_ghost_pad_dispose;
 
-  GST_DEBUG_REGISTER_FUNCPTR (gst_ghost_pad_setcaps_default);
   GST_DEBUG_REGISTER_FUNCPTR (gst_ghost_pad_activate_pull_default);
   GST_DEBUG_REGISTER_FUNCPTR (gst_ghost_pad_activate_push_default);
   GST_DEBUG_REGISTER_FUNCPTR (gst_ghost_pad_link_default);
@@ -1145,8 +867,6 @@ gst_ghost_pad_init (GstGhostPad * pad)
   GST_GHOST_PAD_PRIVATE (pad) = G_TYPE_INSTANCE_GET_PRIVATE (pad,
       GST_TYPE_GHOST_PAD, GstGhostPadPrivate);
 
-  gst_pad_set_setcaps_function (GST_PAD_CAST (pad),
-      gst_ghost_pad_setcaps_default);
   gst_pad_set_activatepull_function (GST_PAD_CAST (pad),
       gst_ghost_pad_activate_pull_default);
   gst_pad_set_activatepush_function (GST_PAD_CAST (pad),
@@ -1184,9 +904,6 @@ gst_ghost_pad_dispose (GObject * object)
   gst_pad_set_activatepull_function (internal, NULL);
   gst_pad_set_activatepush_function (internal, NULL);
 
-  g_signal_handler_disconnect (internal,
-      GST_GHOST_PAD_PRIVATE (pad)->notify_id);
-
   /* disposes of the internal pad, since the ghostpad is the only possible object
    * that has a refcount on the internal pad. */
   gst_object_unparent (GST_OBJECT_CAST (internal));
@@ -1231,13 +948,10 @@ gst_ghost_pad_construct (GstGhostPad * gpad)
 
   /* Set directional padfunctions for ghostpad */
   if (dir == GST_PAD_SINK) {
-    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_getrange_default);
-    gst_pad_set_checkgetrange_function (pad,
-        gst_proxy_pad_checkgetrange_default);
   }
 
   /* link/unlink functions */
@@ -1261,15 +975,11 @@ gst_ghost_pad_construct (GstGhostPad * gpad)
 
   /* Set directional padfunctions for internal pad */
   if (dir == GST_PAD_SRC) {
-    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_getrange_default);
-    gst_pad_set_checkgetrange_function (internal,
-        gst_proxy_pad_checkgetrange_default);
   }
 
   GST_PROXY_LOCK (pad);
@@ -1290,15 +1000,6 @@ gst_ghost_pad_construct (GstGhostPad * gpad)
   GST_PROXY_PAD_INTERNAL (pad) = internal;
   GST_PROXY_PAD_INTERNAL (internal) = pad;
 
-  /* could be more general here, iterating over all writable properties...
-   * taking the short road for now tho */
-  GST_GHOST_PAD_PRIVATE (pad)->notify_id =
-      g_signal_connect (internal, "notify::caps", G_CALLBACK (on_int_notify),
-      pad);
-
-  /* call function to init values of the pad caps */
-  on_int_notify (internal, NULL, GST_GHOST_PAD_CAST (pad));
-
   /* special activation functions for the internal pad */
   gst_pad_set_activatepull_function (internal,
       gst_ghost_pad_internal_activate_pull_default);
@@ -1549,10 +1250,6 @@ gst_ghost_pad_set_target (GstGhostPad * gpad, GstPad * newtarget)
   /* clear old target */
   GST_PROXY_LOCK (gpad);
   if ((oldtarget = GST_PROXY_PAD_TARGET (gpad))) {
-    if (GST_PAD_IS_SRC (oldtarget)) {
-      g_signal_handlers_disconnect_by_func (oldtarget,
-          (gpointer) on_src_target_notify, NULL);
-    }
 
     GST_PROXY_PAD_RETARGET (internal) = TRUE;
 
@@ -1569,11 +1266,6 @@ gst_ghost_pad_set_target (GstGhostPad * gpad, GstPad * newtarget)
   GST_PROXY_UNLOCK (gpad);
 
   if (result && newtarget) {
-    if (GST_PAD_IS_SRC (newtarget)) {
-      g_signal_connect (newtarget, "notify::caps",
-          G_CALLBACK (on_src_target_notify), NULL);
-    }
-
     /* and link to internal pad without any checks */
     GST_DEBUG_OBJECT (gpad, "connecting internal pad to target");
 
index 308ab70..8eb010a 100644 (file)
@@ -66,15 +66,12 @@ const GstQueryType* gst_proxy_pad_query_type_default             (GstPad *pad);
 gboolean            gst_proxy_pad_event_default                  (GstPad *pad, GstEvent *event);
 gboolean            gst_proxy_pad_query_default                  (GstPad *pad, GstQuery *query);
 GstIterator*        gst_proxy_pad_iterate_internal_links_default (GstPad *pad);
-GstFlowReturn       gst_proxy_pad_bufferalloc_default            (GstPad *pad, guint64 offset, guint size, GstCaps *caps, GstBuffer **buf);
 GstFlowReturn       gst_proxy_pad_chain_default                  (GstPad *pad, GstBuffer *buffer);
 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*            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 ())
@@ -123,7 +120,6 @@ gboolean     gst_ghost_pad_set_target       (GstGhostPad *gpad, GstPad *newtarget);
 
 gboolean        gst_ghost_pad_construct        (GstGhostPad *gpad);
 
-gboolean         gst_ghost_pad_setcaps_default        (GstPad * pad, GstCaps * caps);
 void             gst_ghost_pad_unlink_default         (GstPad * pad);
 GstPadLinkReturn gst_ghost_pad_link_default           (GstPad * pad, GstPad * peer);
 gboolean         gst_ghost_pad_activate_pull_default  (GstPad * pad, gboolean active);
index e5fc625..9447a38 100644 (file)
@@ -332,6 +332,7 @@ struct _GstIndex {
   GstIndexResolverMethod method;
   GstIndexResolver       resolver;
   gpointer               resolver_user_data;
+  GDestroyNotify         resolver_user_data_destroy;
 
   GstIndexFilter         filter;
   gpointer               filter_user_data;
@@ -340,11 +341,8 @@ struct _GstIndex {
   GHashTable            *writers;
   gint                   last_id;
 
-  /* ABI added since 0.10.18 */
-  GDestroyNotify         resolver_user_data_destroy;
-
   /*< private >*/
-  gpointer _gst_reserved[GST_PADDING - 1];
+  gpointer _gst_reserved[GST_PADDING];
 };
 
 struct _GstIndexClass {
index 62c79fd..111a0ce 100644 (file)
@@ -86,9 +86,11 @@ gst_index_factory_new (const gchar * name, const gchar * longdesc, GType type)
   GstIndexFactory *factory;
 
   g_return_val_if_fail (name != NULL, NULL);
-  factory = GST_INDEX_FACTORY (g_object_newv (GST_TYPE_INDEX_FACTORY, 0, NULL));
 
-  GST_PLUGIN_FEATURE_NAME (factory) = g_strdup (name);
+  factory =
+      GST_INDEX_FACTORY (g_object_new (GST_TYPE_INDEX_FACTORY, "name", name,
+          NULL));
+
   if (factory->longdesc)
     g_free (factory->longdesc);
   factory->longdesc = g_strdup (longdesc);
index 5062239..ca4c003 100644 (file)
@@ -158,7 +158,6 @@ GstDebugCategory *GST_CAT_PLUGIN_LOADING = NULL;
 GstDebugCategory *GST_CAT_PLUGIN_INFO = NULL;
 GstDebugCategory *GST_CAT_PROPERTIES = NULL;
 GstDebugCategory *GST_CAT_TYPES = NULL;
-GstDebugCategory *GST_CAT_XML = NULL;
 GstDebugCategory *GST_CAT_NEGOTIATION = NULL;
 GstDebugCategory *GST_CAT_REFCOUNTING = NULL;
 GstDebugCategory *GST_CAT_ERROR_SYSTEM = NULL;
@@ -394,8 +393,6 @@ _gst_debug_init (void)
       GST_DEBUG_BOLD | GST_DEBUG_FG_WHITE | GST_DEBUG_BG_BLUE, NULL);
   GST_CAT_TYPES = _gst_debug_category_new ("GST_TYPES",
       GST_DEBUG_BOLD | GST_DEBUG_FG_WHITE | GST_DEBUG_BG_RED, NULL);
-  GST_CAT_XML = _gst_debug_category_new ("GST_XML",
-      GST_DEBUG_BOLD | GST_DEBUG_FG_WHITE | GST_DEBUG_BG_RED, NULL);
   GST_CAT_NEGOTIATION = _gst_debug_category_new ("GST_NEGOTIATION",
       GST_DEBUG_BOLD | GST_DEBUG_FG_BLUE, NULL);
   GST_CAT_REFCOUNTING = _gst_debug_category_new ("GST_REFCOUNTING",
@@ -596,7 +593,7 @@ structure_to_pretty_string (const GstStructure * s)
 }
 
 static inline gchar *
-gst_info_structure_to_string (GstStructure * s)
+gst_info_structure_to_string (const GstStructure * s)
 {
   if (G_UNLIKELY (pretty_tags && s->name == GST_QUARK (TAGLIST)))
     return structure_to_pretty_string (s);
@@ -627,10 +624,10 @@ gst_debug_print_object (gpointer ptr)
     return g_strdup ("(NULL)");
   }
   if (*(GType *) ptr == GST_TYPE_CAPS) {
-    return gst_caps_to_string ((GstCaps *) ptr);
+    return gst_caps_to_string ((const GstCaps *) ptr);
   }
   if (*(GType *) ptr == GST_TYPE_STRUCTURE) {
-    return gst_info_structure_to_string ((GstStructure *) ptr);
+    return gst_info_structure_to_string ((const GstStructure *) ptr);
   }
 #ifdef USE_POISONING
   if (*(guint32 *) ptr == 0xffffffff) {
@@ -649,9 +646,12 @@ gst_debug_print_object (gpointer ptr)
   if (GST_IS_MESSAGE (object)) {
     GstMessage *msg = GST_MESSAGE_CAST (object);
     gchar *s, *ret;
+    const GstStructure *structure;
+
+    structure = gst_message_get_structure (msg);
 
-    if (msg->structure) {
-      s = gst_info_structure_to_string (msg->structure);
+    if (structure) {
+      s = gst_info_structure_to_string (structure);
     } else {
       s = g_strdup ("(NULL)");
     }
@@ -664,9 +664,12 @@ gst_debug_print_object (gpointer ptr)
   }
   if (GST_IS_QUERY (object)) {
     GstQuery *query = GST_QUERY_CAST (object);
+    const GstStructure *structure;
+
+    structure = gst_query_get_structure (query);
 
-    if (query->structure) {
-      return gst_info_structure_to_string (query->structure);
+    if (structure) {
+      return gst_info_structure_to_string (structure);
     } else {
       const gchar *query_type_name;
 
@@ -681,18 +684,18 @@ gst_debug_print_object (gpointer ptr)
   if (GST_IS_EVENT (object)) {
     GstEvent *event = GST_EVENT_CAST (object);
     gchar *s, *ret;
+    GstStructure *structure;
 
-    if (event->structure) {
-      s = gst_info_structure_to_string (event->structure);
+    structure = (GstStructure *) gst_event_get_structure (event);
+    if (structure) {
+      s = gst_info_structure_to_string (structure);
     } else {
       s = g_strdup ("(NULL)");
     }
 
-    ret = g_strdup_printf ("%s event from '%s' at time %"
+    ret = g_strdup_printf ("%s event at time %"
         GST_TIME_FORMAT ": %s",
-        GST_EVENT_TYPE_NAME (event), (event->src != NULL) ?
-        GST_OBJECT_NAME (event->src) : "(NULL)",
-        GST_TIME_ARGS (event->timestamp), s);
+        GST_EVENT_TYPE_NAME (event), GST_TIME_ARGS (event->timestamp), s);
     g_free (s);
     return ret;
   }
@@ -718,13 +721,11 @@ gst_debug_print_segment (gpointer ptr)
     }
     case GST_FORMAT_TIME:{
       return g_strdup_printf ("time segment start=%" GST_TIME_FORMAT
-          ", stop=%" GST_TIME_FORMAT ", last_stop=%" GST_TIME_FORMAT
-          ", duration=%" GST_TIME_FORMAT ", rate=%f, applied_rate=%f"
-          ", flags=0x%02x, time=%" GST_TIME_FORMAT ", accum=%" GST_TIME_FORMAT,
+          ", stop=%" GST_TIME_FORMAT ", rate=%f, applied_rate=%f"
+          ", flags=0x%02x, time=%" GST_TIME_FORMAT ", base=%" GST_TIME_FORMAT,
           GST_TIME_ARGS (segment->start), GST_TIME_ARGS (segment->stop),
-          GST_TIME_ARGS (segment->last_stop), GST_TIME_ARGS (segment->duration),
           segment->rate, segment->applied_rate, (guint) segment->flags,
-          GST_TIME_ARGS (segment->time), GST_TIME_ARGS (segment->accum));
+          GST_TIME_ARGS (segment->time), GST_TIME_ARGS (segment->base));
     }
     default:{
       const gchar *format_name;
@@ -733,13 +734,11 @@ gst_debug_print_segment (gpointer ptr)
       if (G_UNLIKELY (format_name == NULL))
         format_name = "(UNKNOWN FORMAT)";
       return g_strdup_printf ("%s segment start=%" G_GINT64_FORMAT
-          ", stop=%" G_GINT64_FORMAT ", last_stop=%" G_GINT64_FORMAT
-          ", duration=%" G_GINT64_FORMAT ", rate=%f, applied_rate=%f"
-          ", flags=0x%02x, time=%" GST_TIME_FORMAT ", accum=%" GST_TIME_FORMAT,
-          format_name, segment->start, segment->stop, segment->last_stop,
-          segment->duration, segment->rate, segment->applied_rate,
-          (guint) segment->flags, GST_TIME_ARGS (segment->time),
-          GST_TIME_ARGS (segment->accum));
+          ", stop=%" G_GINT64_FORMAT ", rate=%f, applied_rate=%f"
+          ", flags=0x%02x, time=%" GST_TIME_FORMAT ", base=%" GST_TIME_FORMAT,
+          format_name, segment->start, segment->stop, segment->rate,
+          segment->applied_rate, (guint) segment->flags,
+          GST_TIME_ARGS (segment->time), GST_TIME_ARGS (segment->base));
     }
   }
 }
index f616282..009a73e 100644 (file)
@@ -1,5 +1,6 @@
 /* GStreamer
  * Copyright (C) 2004 Wim Taymans <wim@fluendo.com>
+ * Copyright (C) 2011 Sebastian Dröge <sebastian.droege@collabora.co.uk>
  *
  * gstiterator.h: Base class for iterating datastructures.
  *
@@ -46,7 +47,7 @@
  *      switch (gst_iterator_next (it, &amp;item)) {
  *        case GST_ITERATOR_OK:
  *          ... use/change item here...
- *          gst_object_unref (item);
+ *          g_value_reset (&amp;item);
  *          break;
  *        case GST_ITERATOR_RESYNC:
  *          ...rollback changes to items...
@@ -61,6 +62,7 @@
  *          break;
  *      }
  *    }
+ *    g_value_unset (&amp;item);
  *    gst_iterator_free (it);
  *   </programlisting>
  * </example>
 #include "gst_private.h"
 #include <gst/gstiterator.h>
 
-/* FIXME 0.11: Store the size inside the iterator, use GSlice for allocation
- * and let gst_iterator_free() free the memory while the free-func only frees
- * additional resources (maybe call it finalize?).
- */
+GstIterator *
+gst_iterator_copy (const GstIterator * it)
+{
+  GstIterator *copy;
+
+  copy = g_slice_copy (it->size, it);
+  if (it->copy)
+    it->copy (it, copy);
+
+  return copy;
+}
+
+GType
+gst_iterator_get_type (void)
+{
+  static GType type = 0;
+
+  if (G_UNLIKELY (type == 0))
+    type = g_boxed_type_register_static ("GstIterator",
+        (GBoxedCopyFunc) gst_iterator_copy, (GBoxedFreeFunc) gst_iterator_free);
+  return type;
+}
 
 static void
 gst_iterator_init (GstIterator * it,
+    guint size,
     GType type,
     GMutex * lock,
     guint32 * master_cookie,
+    GstIteratorCopyFunction copy,
     GstIteratorNextFunction next,
     GstIteratorItemFunction item,
     GstIteratorResyncFunction resync, GstIteratorFreeFunction free)
 {
+  it->size = size;
   it->type = type;
   it->lock = lock;
   it->master_cookie = master_cookie;
   it->cookie = *master_cookie;
+  it->copy = copy;
   it->next = next;
   it->item = item;
   it->resync = resync;
@@ -103,6 +127,7 @@ gst_iterator_init (GstIterator * it,
  * @lock: pointer to a #GMutex.
  * @master_cookie: pointer to a guint32 that is changed when the items in the
  *    iterator changed.
+ * @copy: copy function
  * @next: function to get next item
  * @item: function to call on each item retrieved
  * @resync: function to resync the iterator
@@ -123,6 +148,7 @@ gst_iterator_new (guint size,
     GType type,
     GMutex * lock,
     guint32 * master_cookie,
+    GstIteratorCopyFunction copy,
     GstIteratorNextFunction next,
     GstIteratorItemFunction item,
     GstIteratorResyncFunction resync, GstIteratorFreeFunction free)
@@ -136,9 +162,9 @@ gst_iterator_new (guint size,
   g_return_val_if_fail (resync != NULL, NULL);
   g_return_val_if_fail (free != NULL, NULL);
 
-  result = g_malloc (size);
-  gst_iterator_init (result, type, lock, master_cookie, next, item, resync,
-      free);
+  result = g_slice_alloc0 (size);
+  gst_iterator_init (result, size, type, lock, master_cookie, copy, next, item,
+      resync, free);
 
   return result;
 }
@@ -149,21 +175,33 @@ gst_iterator_new (guint size,
 typedef struct _GstListIterator
 {
   GstIterator iterator;
-  gpointer owner;
+  GObject *owner;
   GList **orig;
   GList *list;                  /* pointer in list */
-  GstIteratorDisposeFunction freefunc;
+
+  void (*set_value) (GValue * value, gpointer item);
 } GstListIterator;
 
+static void
+gst_list_iterator_copy (const GstListIterator * it, GstListIterator * copy)
+{
+  if (copy->owner)
+    g_object_ref (copy->owner);
+}
+
 static GstIteratorResult
-gst_list_iterator_next (GstListIterator * it, gpointer * elem)
+gst_list_iterator_next (GstListIterator * it, GValue * elem)
 {
+  gpointer data;
+
   if (it->list == NULL)
     return GST_ITERATOR_DONE;
 
-  *elem = it->list->data;
+  data = it->list->data;
   it->list = g_list_next (it->list);
 
+  it->set_value (elem, data);
+
   return GST_ITERATOR_OK;
 }
 
@@ -176,10 +214,8 @@ gst_list_iterator_resync (GstListIterator * it)
 static void
 gst_list_iterator_free (GstListIterator * it)
 {
-  if (it->freefunc) {
-    it->freefunc (it->owner);
-  }
-  g_free (it);
+  if (it->owner)
+    g_object_unref (it->owner);
 }
 
 /**
@@ -190,8 +226,7 @@ gst_list_iterator_free (GstListIterator * it)
  *     is changed.
  * @list: pointer to the list
  * @owner: object owning the list
- * @item: function to call for each item
- * @free: function to call when the iterator is freed
+ * @item: function to call on each item retrieved
  *
  * Create a new iterator designed for iterating @list.
  *
@@ -201,46 +236,52 @@ gst_list_iterator_free (GstListIterator * it)
  * The iterator will use @lock to retrieve the next item of the list and it
  * will then call the @item function before releasing @lock again.
  *
- * The @item function usualy makes sure that the item remains alive while
- * @lock is released and the application is using the item. The application is
- * responsible for freeing/unreffing the item after usage as explained in
- * gst_iterator_next().
- *
  * When a concurrent update to the list is performed, usually by @owner while
  * holding @lock, @master_cookie will be updated. The iterator implementation
  * will notice the update of the cookie and will return %GST_ITERATOR_RESYNC to
  * the user of the iterator in the next call to gst_iterator_next().
  *
- * @owner will be passed to the @free function when the iterator is freed.
- *
  * Returns: the new #GstIterator for @list.
  *
  * MT safe.
  */
 GstIterator *
 gst_iterator_new_list (GType type,
-    GMutex * lock,
-    guint32 * master_cookie,
-    GList ** list,
-    gpointer owner,
-    GstIteratorItemFunction item, GstIteratorDisposeFunction free)
+    GMutex * lock, guint32 * master_cookie, GList ** list, GObject * owner,
+    GstIteratorItemFunction item)
 {
   GstListIterator *result;
+  gpointer set_value;
+
+  if (g_type_is_a (type, G_TYPE_OBJECT)) {
+    set_value = g_value_set_object;
+  } else if (g_type_is_a (type, G_TYPE_BOXED)) {
+    set_value = g_value_set_boxed;
+  } else if (g_type_is_a (type, G_TYPE_POINTER)) {
+    set_value = g_value_set_pointer;
+  } else if (g_type_is_a (type, G_TYPE_STRING)) {
+    set_value = g_value_set_string;
+  } else {
+    g_critical ("List iterators can only be created for lists containing "
+        "instances of GObject, boxed types, pointer types and strings");
+    return NULL;
+  }
 
   /* no need to lock, nothing can change here */
   result = (GstListIterator *) gst_iterator_new (sizeof (GstListIterator),
       type,
       lock,
       master_cookie,
+      (GstIteratorCopyFunction) gst_list_iterator_copy,
       (GstIteratorNextFunction) gst_list_iterator_next,
       (GstIteratorItemFunction) item,
       (GstIteratorResyncFunction) gst_list_iterator_resync,
       (GstIteratorFreeFunction) gst_list_iterator_free);
 
-  result->owner = owner;
+  result->owner = owner ? g_object_ref (owner) : NULL;
   result->orig = list;
   result->list = *list;
-  result->freefunc = free;
+  result->set_value = set_value;
 
   return GST_ITERATOR (result);
 }
@@ -262,9 +303,10 @@ gst_iterator_pop (GstIterator * it)
  * Get the next item from the iterator in @elem. 
  *
  * Only when this function returns %GST_ITERATOR_OK, @elem will contain a valid
- * value. For iterators that return refcounted objects, the returned object
- * will have its refcount increased and should therefore be unreffed after
- * usage.
+ * value. @elem must have been initialized to the type of the iterator or
+ * initialized to zeroes with g_value_unset(). The caller is responsible for
+ * unsetting or resetting @elem with g_value_unset() or g_value_reset()
+ * after usage.
  *
  * When this function returns %GST_ITERATOR_DONE, no more elements can be
  * retrieved from @it.
@@ -275,18 +317,22 @@ gst_iterator_pop (GstIterator * it)
  *
  * A return value of %GST_ITERATOR_ERROR indicates an unrecoverable fatal error.
  *
- * Returns: The result of the iteration. Unref @elem after usage if this
- * is a refcounted object.
+ * Returns: The result of the iteration. Unset @elem after usage.
  *
  * MT safe.
  */
 GstIteratorResult
-gst_iterator_next (GstIterator * it, gpointer * elem)
+gst_iterator_next (GstIterator * it, GValue * elem)
 {
   GstIteratorResult result;
 
   g_return_val_if_fail (it != NULL, GST_ITERATOR_ERROR);
   g_return_val_if_fail (elem != NULL, GST_ITERATOR_ERROR);
+  g_return_val_if_fail (G_VALUE_TYPE (elem) == G_TYPE_INVALID
+      || G_VALUE_HOLDS (elem, it->type), GST_ITERATOR_ERROR);
+
+  if (G_VALUE_TYPE (elem) == G_TYPE_INVALID)
+    g_value_init (elem, it->type);
 
 restart:
   if (it->pushed) {
@@ -312,14 +358,16 @@ restart:
   if (result == GST_ITERATOR_OK && it->item) {
     GstIteratorItem itemres;
 
-    itemres = it->item (it, *elem);
+    itemres = it->item (it, elem);
     switch (itemres) {
       case GST_ITERATOR_ITEM_SKIP:
         if (G_LIKELY (it->lock))
           g_mutex_unlock (it->lock);
+        g_value_reset (elem);
         goto restart;
       case GST_ITERATOR_ITEM_END:
         result = GST_ITERATOR_DONE;
+        g_value_reset (elem);
         break;
       case GST_ITERATOR_ITEM_PASS:
         break;
@@ -376,6 +424,8 @@ gst_iterator_free (GstIterator * it)
   gst_iterator_pop (it);
 
   it->free (it);
+
+  g_slice_free1 (it->size, it);
 }
 
 /**
@@ -410,29 +460,28 @@ typedef struct _GstIteratorFilter
   GstIterator *slave;
 
   GCompareFunc func;
-  gpointer user_data;
+  GValue user_data;
+  gboolean have_user_data;
 } GstIteratorFilter;
 
 static GstIteratorResult
-filter_next (GstIteratorFilter * it, gpointer * elem)
+filter_next (GstIteratorFilter * it, GValue * elem)
 {
   GstIteratorResult result = GST_ITERATOR_ERROR;
   gboolean done = FALSE;
-
-  *elem = NULL;
+  GValue item = { 0, };
 
   while (G_LIKELY (!done)) {
-    gpointer item;
-
     result = gst_iterator_next (it->slave, &item);
     switch (result) {
       case GST_ITERATOR_OK:
         if (G_LIKELY (GST_ITERATOR (it)->lock))
           g_mutex_unlock (GST_ITERATOR (it)->lock);
-        if (it->func (item, it->user_data) == 0) {
-          *elem = item;
+        if (it->func (&item, &it->user_data) == 0) {
+          g_value_copy (&item, elem);
           done = TRUE;
         }
+        g_value_reset (&item);
         if (G_LIKELY (GST_ITERATOR (it)->lock))
           g_mutex_lock (GST_ITERATOR (it)->lock);
         break;
@@ -445,27 +494,34 @@ filter_next (GstIteratorFilter * it, gpointer * elem)
         break;
     }
   }
+  g_value_unset (&item);
   return result;
 }
 
 static void
-filter_resync (GstIteratorFilter * it)
+filter_copy (const GstIteratorFilter * it, GstIteratorFilter * copy)
 {
-  gst_iterator_resync (it->slave);
+  copy->slave = gst_iterator_copy (it->slave);
+
+  if (it->have_user_data) {
+    memset (&copy->user_data, 0, sizeof (copy->user_data));
+    g_value_init (&copy->user_data, G_VALUE_TYPE (&it->user_data));
+    g_value_copy (&it->user_data, &copy->user_data);
+  }
 }
 
 static void
-filter_uninit (GstIteratorFilter * it)
+filter_resync (GstIteratorFilter * it)
 {
-  it->slave->lock = GST_ITERATOR (it)->lock;
+  gst_iterator_resync (it->slave);
 }
 
 static void
 filter_free (GstIteratorFilter * it)
 {
-  filter_uninit (it);
+  if (it->have_user_data)
+    g_value_unset (&it->user_data);
   gst_iterator_free (it->slave);
-  g_free (it);
 }
 
 /**
@@ -476,8 +532,9 @@ filter_free (GstIteratorFilter * it)
  *
  * Create a new iterator from an existing iterator. The new iterator
  * will only return those elements that match the given compare function @func.
- * @func should return 0 for elements that should be included
- * in the iterator.
+ * The first parameter that is passed to @func is the #GValue of the current
+ * iterator element and the second parameter is @user_data. @func should
+ * return 0 for elements that should be included in the filtered iterator.
  *
  * When this iterator is freed, @it will also be freed.
  *
@@ -486,7 +543,8 @@ filter_free (GstIteratorFilter * it)
  * MT safe.
  */
 GstIterator *
-gst_iterator_filter (GstIterator * it, GCompareFunc func, gpointer user_data)
+gst_iterator_filter (GstIterator * it, GCompareFunc func,
+    const GValue * user_data)
 {
   GstIteratorFilter *result;
 
@@ -495,13 +553,21 @@ gst_iterator_filter (GstIterator * it, GCompareFunc func, gpointer user_data)
 
   result = (GstIteratorFilter *) gst_iterator_new (sizeof (GstIteratorFilter),
       it->type, it->lock, it->master_cookie,
+      (GstIteratorCopyFunction) filter_copy,
       (GstIteratorNextFunction) filter_next,
       (GstIteratorItemFunction) NULL,
       (GstIteratorResyncFunction) filter_resync,
       (GstIteratorFreeFunction) filter_free);
+
   it->lock = NULL;
   result->func = func;
-  result->user_data = user_data;
+  if (user_data) {
+    g_value_init (&result->user_data, G_VALUE_TYPE (user_data));
+    g_value_copy (user_data, &result->user_data);
+    result->have_user_data = TRUE;
+  } else {
+    result->have_user_data = FALSE;
+  }
   result->slave = it;
 
   return GST_ITERATOR (result);
@@ -517,8 +583,7 @@ gst_iterator_filter (GstIterator * it, GCompareFunc func, gpointer user_data)
  * Folds @func over the elements of @iter. That is to say, @func will be called
  * as @func (object, @ret, @user_data) for each object in @it. The normal use
  * of this procedure is to accumulate the results of operating on the objects in
- * @ret.  If object is a refcounted object its refcount will be increased 
- * before @func is called, and it should be unrefed after use in @func.
+ * @ret.
  *
  * This procedure can be used (and is used internally) to implement the
  * gst_iterator_foreach() and gst_iterator_find_custom() operations.
@@ -539,17 +604,18 @@ GstIteratorResult
 gst_iterator_fold (GstIterator * it, GstIteratorFoldFunction func,
     GValue * ret, gpointer user_data)
 {
-  gpointer item;
+  GValue item = { 0, };
   GstIteratorResult result;
 
   while (1) {
     result = gst_iterator_next (it, &item);
     switch (result) {
       case GST_ITERATOR_OK:
-        if (!func (item, ret, user_data))
+        if (!func (&item, ret, user_data))
           goto fold_done;
-        else
-          break;
+
+        g_value_reset (&item);
+        break;
       case GST_ITERATOR_RESYNC:
       case GST_ITERATOR_ERROR:
         goto fold_done;
@@ -559,17 +625,19 @@ gst_iterator_fold (GstIterator * it, GstIteratorFoldFunction func,
   }
 
 fold_done:
+  g_value_unset (&item);
+
   return result;
 }
 
 typedef struct
 {
-  GFunc func;
+  GstIteratorForeachFunction func;
   gpointer user_data;
 } ForeachFoldData;
 
 static gboolean
-foreach_fold_func (gpointer item, GValue * unused, ForeachFoldData * data)
+foreach_fold_func (const GValue * item, GValue * unused, ForeachFoldData * data)
 {
   data->func (item, data->user_data);
   return TRUE;
@@ -582,9 +650,7 @@ foreach_fold_func (gpointer item, GValue * unused, ForeachFoldData * data)
  * @user_data: (closure): user data passed to the function
  *
  * Iterate over all element of @it and call the given function @func for
- * each element.  As in gst_iterator_fold(), the refcount of a refcounted 
- * object will be increased before @func is called, and should be unrefed
- * after use.
+ * each element.
  *
  * Returns: the result call to gst_iterator_fold(). The iterator will not be
  * freed.
@@ -592,7 +658,8 @@ foreach_fold_func (gpointer item, GValue * unused, ForeachFoldData * data)
  * MT safe.
  */
 GstIteratorResult
-gst_iterator_foreach (GstIterator * it, GFunc func, gpointer user_data)
+gst_iterator_foreach (GstIterator * it, GstIteratorForeachFunction func,
+    gpointer user_data)
 {
   ForeachFoldData data;
 
@@ -607,93 +674,105 @@ typedef struct
 {
   GCompareFunc func;
   gpointer user_data;
+  gboolean found;
 } FindCustomFoldData;
 
 static gboolean
-find_custom_fold_func (gpointer item, GValue * ret, FindCustomFoldData * data)
+find_custom_fold_func (const GValue * item, GValue * ret,
+    FindCustomFoldData * data)
 {
   if (data->func (item, data->user_data) == 0) {
-    g_value_set_pointer (ret, item);
+    data->found = TRUE;
+    g_value_copy (item, ret);
     return FALSE;
   } else {
     return TRUE;
   }
 }
 
-/* FIXME 0.11:
- * We should store ref/unref (or copy/free) functions for the type
- * in GstIterator. The unref but only if it's not a match behaviour
- * of find_custom() is very bad for bindings. The ref/unref functions
- * are also useful for the fold and filter cases.
- */
-
 /**
  * gst_iterator_find_custom:
  * @it: The #GstIterator to iterate
  * @func: (scope call): the compare function to use
+ * @elem: (out): pointer to a #GValue where to store the result
  * @user_data: (closure): user data passed to the compare function
  *
  * Find the first element in @it that matches the compare function @func.
- * @func should return 0 when the element is found.  As in gst_iterator_fold(),
- * the refcount of a refcounted object will be increased before @func is 
- * called, and should be unrefed after use in @func unless it is the matching
- * element.
+ * @func should return 0 when the element is found. The first parameter
+ * to @func will be the current element of the iterator and the
+ * second parameter will be @user_data.
+ * The result will be stored in @elem if a result is found.
  *
  * The iterator will not be freed.
  *
- * This function will return NULL if an error happened to the iterator.
+ * This function will return FALSE if an error happened to the iterator
+ * or if the element wasn't found.
  *
- * Returns: (transfer full): The element in the iterator that matches the compare
- * function or NULL when no element matched.
+ * Returns: Returns TRUE if the element was found, else FALSE.
  *
  * MT safe.
  */
-gpointer
+gboolean
 gst_iterator_find_custom (GstIterator * it, GCompareFunc func,
-    gpointer user_data)
+    GValue * elem, gpointer user_data)
 {
-  GValue ret = { 0, };
   GstIteratorResult res;
   FindCustomFoldData data;
 
-  g_value_init (&ret, G_TYPE_POINTER);
+  g_return_val_if_fail (G_VALUE_TYPE (elem) == G_TYPE_INVALID
+      || G_VALUE_HOLDS (elem, it->type), GST_ITERATOR_ERROR);
+
+  if (G_VALUE_TYPE (elem) == G_TYPE_INVALID)
+    g_value_init (elem, it->type);
+
   data.func = func;
   data.user_data = user_data;
+  data.found = FALSE;
 
   do {
     res =
         gst_iterator_fold (it, (GstIteratorFoldFunction) find_custom_fold_func,
-        &ret, &data);
+        elem, &data);
     if (res == GST_ITERATOR_RESYNC)
       gst_iterator_resync (it);
   } while (res == GST_ITERATOR_RESYNC);
 
-  /* no need to unset, it's just a pointer */
-  return g_value_get_pointer (&ret);
+  if (!data.found)
+    g_value_unset (elem);
+
+  return data.found;
 }
 
 typedef struct
 {
   GstIterator parent;
-  gpointer object;
-  GstCopyFunction copy;
-  GFreeFunc free;
+  GValue object;
   gboolean visited;
+  gboolean empty;
 } GstSingleObjectIterator;
 
 static guint32 _single_object_dummy_cookie = 0;
 
+static void
+gst_single_object_iterator_copy (const GstSingleObjectIterator * it,
+    GstSingleObjectIterator * copy)
+{
+  if (!it->empty) {
+    memset (&copy->object, 0, sizeof (copy->object));
+    g_value_init (&copy->object, it->parent.type);
+    g_value_copy (&it->object, &copy->object);
+  }
+}
+
 static GstIteratorResult
-gst_single_object_iterator_iterator_next (GstSingleObjectIterator * it,
-    gpointer * result)
+gst_single_object_iterator_next (GstSingleObjectIterator * it, GValue * result)
 {
-  if (it->visited || !it->object) {
-    *result = NULL;
+  if (it->visited || it->empty)
     return GST_ITERATOR_DONE;
-  }
 
-  *result = it->copy (it->object);
+  g_value_copy (&it->object, result);
   it->visited = TRUE;
+
   return GST_ITERATOR_OK;
 }
 
@@ -706,17 +785,14 @@ gst_single_object_iterator_resync (GstSingleObjectIterator * it)
 static void
 gst_single_object_iterator_free (GstSingleObjectIterator * it)
 {
-  if (it->object)
-    it->free (it->object);
-  g_free (it);
+  if (!it->empty)
+    g_value_unset (&it->object);
 }
 
 /**
  * gst_iterator_new_single:
  * @type: #GType of the passed object
  * @object: object that this iterator should return
- * @copy: Function that returns a copy of @object or increases its refcount
- * @free: Function to be called for freeing @object
  *
  * This #GstIterator is a convenient iterator for the common
  * case where a #GstIterator needs to be returned but only
@@ -728,25 +804,27 @@ gst_single_object_iterator_free (GstSingleObjectIterator * it)
  * Since: 0.10.25
  */
 GstIterator *
-gst_iterator_new_single (GType type, gpointer object, GstCopyFunction copy,
-    GFreeFunc free)
+gst_iterator_new_single (GType type, const GValue * object)
 {
   GstSingleObjectIterator *result;
 
-  g_return_val_if_fail (copy != NULL, NULL);
-  g_return_val_if_fail (free != NULL, NULL);
-
   result = (GstSingleObjectIterator *)
       gst_iterator_new (sizeof (GstSingleObjectIterator),
       type, NULL, &_single_object_dummy_cookie,
-      (GstIteratorNextFunction) gst_single_object_iterator_iterator_next, NULL,
+      (GstIteratorCopyFunction) gst_single_object_iterator_copy,
+      (GstIteratorNextFunction) gst_single_object_iterator_next,
+      (GstIteratorItemFunction) NULL,
       (GstIteratorResyncFunction) gst_single_object_iterator_resync,
       (GstIteratorFreeFunction) gst_single_object_iterator_free);
 
-  result->object = (object) ? copy (object) : NULL;
-  result->copy = copy;
-  result->free = free;
+  if (object) {
+    g_value_init (&result->object, type);
+    g_value_copy (object, &result->object);
+    result->empty = FALSE;
+  } else {
+    result->empty = TRUE;
+  }
   result->visited = FALSE;
 
-  return (GstIterator *) result;
+  return GST_ITERATOR (result);
 }
index b8af00a..4a8a5a0 100644 (file)
@@ -1,5 +1,6 @@
 /* GStreamer
  * Copyright (C) 2004 Wim Taymans <wim@fluendo.com>
+ * Copyright (C) 2011 Sebastian Dröge <sebastian.droege@collabora.co.uk>
  *
  * gstiterator.h: Header for GstIterator
  *
@@ -27,6 +28,8 @@
 
 G_BEGIN_DECLS
 
+#define GST_TYPE_ITERATOR (gst_iterator_get_type ())
+
 /**
  * GstIteratorResult:
  * @GST_ITERATOR_DONE:   No more items in the iterator
@@ -60,37 +63,38 @@ typedef enum {
 } GstIteratorItem;
 
 /**
- * GstIteratorDisposeFunction:
- * @owner: the owner of the iterator
+ * GstIteratorCopyFunction:
+ * @it: The original iterator
+ * @copy: The copied iterator
  *
- * The function that will be called when a #GList iterator is freed. The
- * owner of the #GList iterator can then clean up its resources.
+ * This function will be called when creating a copy of @it and should
+ * create a copy of all custom iterator fields or increase their
+ * reference counts.
  */
-typedef void             (*GstIteratorDisposeFunction) (gpointer owner);
+typedef void              (*GstIteratorCopyFunction) (const GstIterator *it, GstIterator *copy);
 
 /**
- * GstIteratorNextFunction:
+ * GstIteratorItemFunction:
  * @it: the iterator
- * @result: a pointer to hold the next item
+ * @item: the item being retrieved.
  *
- * The function that will be called when the next element of the iterator
- * should be retrieved. 
+ * The function that will be called after the next item of the iterator
+ * has been retrieved. This function can be used to skip items or stop
+ * the iterator.
  *
- * Implementors of a #GstIterator should implement this
- * function and pass it to the constructor of the custom iterator.
  * The function will be called with the iterator lock held.
  *
  * Returns: the result of the operation.
  */
-typedef GstIteratorResult (*GstIteratorNextFunction)   (GstIterator *it, gpointer *result);
+typedef GstIteratorItem   (*GstIteratorItemFunction)    (GstIterator *it, const GValue * item);
+
 /**
- * GstIteratorItemFunction:
+ * GstIteratorNextFunction:
  * @it: the iterator
- * @item: the item being retrieved.
+ * @result: a pointer to hold the next item
  *
- * The function that will be called after the next item of the iterator
- * has been retrieved. This function will typically increase the refcount
- * of the item or make a copy.
+ * The function that will be called when the next element of the iterator
+ * should be retrieved. 
  *
  * Implementors of a #GstIterator should implement this
  * function and pass it to the constructor of the custom iterator.
@@ -98,7 +102,7 @@ typedef GstIteratorResult (*GstIteratorNextFunction) (GstIterator *it, gpointer
  *
  * Returns: the result of the operation.
  */
-typedef GstIteratorItem          (*GstIteratorItemFunction)    (GstIterator *it, gpointer item);
+typedef GstIteratorResult (*GstIteratorNextFunction)   (GstIterator *it, GValue *result);
 /**
  * GstIteratorResyncFunction:
  * @it: the iterator
@@ -126,6 +130,15 @@ typedef void                 (*GstIteratorResyncFunction)  (GstIterator *it);
 typedef void             (*GstIteratorFreeFunction)    (GstIterator *it);
 
 /**
+ * GstIteratorForeachFunction:
+ * @item: The item
+ * @user_data: User data
+ *
+ * A function that is called by gst_iterator_foreach() for every element.
+ */
+typedef void         (*GstIteratorForeachFunction)     (const GValue * item, gpointer user_data);
+
+/**
  * GstIteratorFoldFunction:
  * @item: the item to fold
  * @ret: a #GValue collecting the result
@@ -135,20 +148,7 @@ typedef void                 (*GstIteratorFreeFunction)    (GstIterator *it);
  *
  * Returns: TRUE if the fold should continue, FALSE if it should stop.
  */
-typedef gboolean         (*GstIteratorFoldFunction)    (gpointer item, GValue *ret, gpointer user_data);
-
-/**
- * GstCopyFunction:
- * @object: The object to copy
- *
- * A function to create a copy of some object or
- * increase its reference count.
- *
- * Returns: a copy of the object or the same object with increased reference count
- *
- * Since: 0.10.25
- */
-typedef gpointer          (*GstCopyFunction)             (gpointer object);
+typedef gboolean         (*GstIteratorFoldFunction)    (const GValue * item, GValue * ret, gpointer user_data);
 
 /**
  * GST_ITERATOR:
@@ -204,6 +204,7 @@ typedef gpointer          (*GstCopyFunction)             (gpointer object);
  */
 struct _GstIterator {
   /*< protected >*/
+  GstIteratorCopyFunction copy;
   GstIteratorNextFunction next;
   GstIteratorItemFunction item;
   GstIteratorResyncFunction resync;
@@ -216,36 +217,39 @@ struct _GstIterator {
   guint32   cookie;            /* cookie of the iterator */
   guint32  *master_cookie;     /* pointer to guint32 holding the cookie when this
                                   iterator was created */
+  guint     size;
 
   /*< private >*/
   gpointer _gst_reserved[GST_PADDING];
 };
 
+GType                   gst_iterator_get_type           (void);
+
 /* creating iterators */
 GstIterator*           gst_iterator_new                (guint size,
                                                         GType type,
                                                         GMutex *lock,
                                                         guint32 *master_cookie,
+                                                         GstIteratorCopyFunction copy,
                                                         GstIteratorNextFunction next,
-                                                        GstIteratorItemFunction item,
+                                                         GstIteratorItemFunction item,
                                                         GstIteratorResyncFunction resync,
                                                         GstIteratorFreeFunction free);
 
-GstIterator*           gst_iterator_new_list           (GType type,
+GstIterator*           gst_iterator_new_list           (GType type,
                                                         GMutex *lock,
                                                         guint32 *master_cookie,
                                                         GList **list,
-                                                        gpointer owner,
-                                                        GstIteratorItemFunction item,
-                                                        GstIteratorDisposeFunction free);
+                                                        GObject * owner,
+                                                         GstIteratorItemFunction item);
 
 GstIterator*            gst_iterator_new_single         (GType type,
-                                                         gpointer object,
-                                                         GstCopyFunction copy,
-                                                         GFreeFunc free);
+                                                         const GValue * object);
+
+GstIterator*            gst_iterator_copy               (const GstIterator *it);
 
 /* using iterators */
-GstIteratorResult      gst_iterator_next               (GstIterator *it, gpointer *elem);
+GstIteratorResult      gst_iterator_next               (GstIterator *it, GValue * elem);
 void                   gst_iterator_resync             (GstIterator *it);
 void                   gst_iterator_free               (GstIterator *it);
 
@@ -253,14 +257,14 @@ void                      gst_iterator_push               (GstIterator *it, GstIterator *other);
 
 /* higher-order functions that operate on iterators */
 GstIterator*           gst_iterator_filter             (GstIterator *it, GCompareFunc func,
-                                                         gpointer user_data);
+                                                         const GValue * user_data);
 GstIteratorResult      gst_iterator_fold               (GstIterator *it,
                                                          GstIteratorFoldFunction func,
                                                          GValue *ret, gpointer user_data);
 GstIteratorResult      gst_iterator_foreach            (GstIterator *it,
-                                                         GFunc func, gpointer user_data);
-gpointer               gst_iterator_find_custom        (GstIterator *it, GCompareFunc func,
-                                                         gpointer user_data);
+                                                         GstIteratorForeachFunction func, gpointer user_data);
+gboolean               gst_iterator_find_custom        (GstIterator *it, GCompareFunc func,
+                                                         GValue *elem, gpointer user_data);
 
 G_END_DECLS
 
index 7d34089..b9fc164 100644 (file)
@@ -20,5 +20,6 @@ VOID:UINT,BOXED
 VOID:UINT,POINTER
 BOOLEAN:VOID
 BOOLEAN:POINTER
+BOOLEAN:BOXED
 POINTER:POINTER
 BOXED:BOXED
diff --git a/gst/gstmemory.c b/gst/gstmemory.c
new file mode 100644 (file)
index 0000000..7985ec9
--- /dev/null
@@ -0,0 +1,677 @@
+/* GStreamer
+ * Copyright (C) 2011 Wim Taymans <wim.taymans@gmail.be>
+ *
+ * gstmemory.c: memory block handling
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/**
+ * SECTION:gstmemory
+ * @short_description: refcounted wrapper for memory blocks
+ * @see_also: #GstBuffer
+ *
+ * GstMemory is a lightweight refcounted object that wraps a region of memory.
+ * They are typically used to manage the data of a #GstBuffer.
+ *
+ * Memory is usually created by allocators with a gst_memory_allocator_alloc()
+ * method call. When NULL is used as the allocator, the default allocator will
+ * be used.
+ *
+ * New allocators can be registered with gst_memory_allocator_register().
+ * Allocators are identified by name and can be retrieved with
+ * gst_memory_allocator_find().
+ *
+ * New memory can be created with gst_memory_new_wrapped() that wraps the memory
+ * allocated elsewhere.
+ *
+ * Refcounting of the memory block is performed with gst_memory_ref() and
+ * gst_memory_unref().
+ *
+ * The size of the memory can be retrieved and changed with
+ * gst_memory_get_sizes() and gst_memory_resize() respectively.
+ *
+ * Getting access to the data of the memory is performed with gst_memory_map().
+ * After the memory access is completed, gst_memory_unmap() should be called.
+ *
+ * Memory can be copied with gst_memory_copy(), which will returnn a writable
+ * copy. gst_memory_share() will create a new memory block that shares the
+ * memory with an existing memory block at a custom offset and with a custom
+ * size.
+ *
+ * Memory can be efficiently merged when gst_memory_is_span() returns TRUE and
+ * with the function gst_memory_span().
+ *
+ * Last reviewed on 2011-06-08 (0.11.0)
+ */
+
+#include "config.h"
+#include "gst_private.h"
+#include "gstmemory.h"
+
+
+/* buffer alignment in bytes - 1
+ * an alignment of 7 would be the same as malloc() guarantees
+ */
+#ifdef HAVE_POSIX_MEMALIGN
+#if defined(MEMORY_ALIGNMENT_MALLOC)
+size_t gst_memory_alignment = 7;
+#elif defined(MEMORY_ALIGNMENT_PAGESIZE)
+size_t gst_memory_alignment = 0;
+#elif defined(MEMORY_ALIGNMENT)
+size_t gst_memory_alignment = MEMORY_ALIGNMENT - 1;
+#else
+#error "No memory alignment configured"
+size_t gst_memory_alignment = 0;
+#endif
+#endif /* HAVE_POSIX_MEMALIGN */
+
+struct _GstMemoryAllocator
+{
+  GQuark name;
+
+  GstMemoryInfo info;
+};
+
+/* default memory implementation */
+typedef struct
+{
+  GstMemory mem;
+  gsize slice_size;
+  guint8 *data;
+  GFreeFunc free_func;
+  gsize maxsize;
+  gsize offset;
+  gsize size;
+} GstMemoryDefault;
+
+/* the default allocator */
+static const GstMemoryAllocator *_default_allocator;
+
+/* our predefined allocators */
+static const GstMemoryAllocator *_default_mem_impl;
+
+/* initialize the fields */
+static void
+_default_mem_init (GstMemoryDefault * mem, GstMemoryFlags flags,
+    GstMemory * parent, gsize slice_size, gpointer data,
+    GFreeFunc free_func, gsize maxsize, gsize offset, gsize size)
+{
+  mem->mem.allocator = _default_mem_impl;
+  mem->mem.flags = flags;
+  mem->mem.refcount = 1;
+  mem->mem.parent = parent ? gst_memory_ref (parent) : NULL;
+  mem->slice_size = slice_size;
+  mem->data = data;
+  mem->free_func = free_func;
+  mem->maxsize = maxsize;
+  mem->offset = offset;
+  mem->size = size;
+}
+
+/* create a new memory block that manages the given memory */
+static GstMemoryDefault *
+_default_mem_new (GstMemoryFlags flags, GstMemory * parent, gpointer data,
+    GFreeFunc free_func, gsize maxsize, gsize offset, gsize size)
+{
+  GstMemoryDefault *mem;
+  gsize slice_size;
+
+  slice_size = sizeof (GstMemoryDefault);
+
+  mem = g_slice_alloc (slice_size);
+  _default_mem_init (mem, flags, parent, slice_size,
+      data, free_func, maxsize, offset, size);
+
+  return mem;
+}
+
+/* allocate the memory and structure in one block */
+static GstMemoryDefault *
+_default_mem_new_block (gsize maxsize, gsize align, gsize offset, gsize size)
+{
+  GstMemoryDefault *mem;
+  gsize aoffset, slice_size;
+  guint8 *data;
+
+  /* ensure configured alignment */
+  align |= gst_memory_alignment;
+  /* allocate more to compensate for alignment */
+  maxsize += align;
+  /* alloc header and data in one block */
+  slice_size = sizeof (GstMemoryDefault) + maxsize;
+
+  mem = g_slice_alloc (slice_size);
+  if (mem == NULL)
+    return NULL;
+
+  data = (guint8 *) mem + sizeof (GstMemoryDefault);
+
+  if ((aoffset = ((guintptr) data & align)))
+    aoffset = (align + 1) - aoffset;
+
+  _default_mem_init (mem, 0, NULL, slice_size, data, NULL, maxsize,
+      aoffset + offset, size);
+
+  return mem;
+}
+
+static GstMemory *
+_default_mem_alloc (const GstMemoryAllocator * allocator, gsize maxsize,
+    gsize align)
+{
+  return (GstMemory *) _default_mem_new_block (maxsize, align, 0, maxsize);
+}
+
+static gsize
+_default_mem_get_sizes (GstMemoryDefault * mem, gsize * maxsize)
+{
+  if (maxsize)
+    *maxsize = mem->maxsize;
+
+  return mem->size;
+}
+
+static void
+_default_mem_resize (GstMemoryDefault * mem, gsize offset, gsize size)
+{
+  g_return_if_fail (size + mem->offset + offset <= mem->maxsize);
+
+  mem->offset += offset;
+  mem->size = size;
+}
+
+static gpointer
+_default_mem_map (GstMemoryDefault * mem, gsize * size, gsize * maxsize,
+    GstMapFlags flags)
+{
+  if (size)
+    *size = mem->size;
+  if (maxsize)
+    *maxsize = mem->maxsize;
+
+  return mem->data + mem->offset;
+}
+
+static gboolean
+_default_mem_unmap (GstMemoryDefault * mem, gpointer data, gsize size)
+{
+  if (size != -1)
+    mem->size = size;
+  return TRUE;
+}
+
+static void
+_default_mem_free (GstMemoryDefault * mem)
+{
+  if (mem->mem.parent)
+    gst_memory_unref (mem->mem.parent);
+
+  if (mem->free_func)
+    mem->free_func (mem->data);
+
+  g_slice_free1 (mem->slice_size, mem);
+}
+
+static GstMemoryDefault *
+_default_mem_copy (GstMemoryDefault * mem, gsize offset, gsize size)
+{
+  GstMemoryDefault *copy;
+
+  if (size == -1)
+    size = mem->size > offset ? mem->size - offset : 0;
+
+  copy = _default_mem_new_block (mem->maxsize, 0, mem->offset + offset, size);
+  memcpy (copy->data, mem->data, mem->maxsize);
+
+  return copy;
+}
+
+static GstMemoryDefault *
+_default_mem_share (GstMemoryDefault * mem, gsize offset, gsize size)
+{
+  GstMemoryDefault *sub;
+  GstMemory *parent;
+
+  /* find the real parent */
+  if ((parent = mem->mem.parent) == NULL)
+    parent = (GstMemory *) mem;
+
+  if (size == -1)
+    size = mem->size - offset;
+
+  sub = _default_mem_new (parent->flags, parent, mem->data, NULL, mem->maxsize,
+      mem->offset + offset, size);
+
+  return sub;
+}
+
+static gboolean
+_default_mem_is_span (GstMemoryDefault * mem1, GstMemoryDefault * mem2,
+    gsize * offset)
+{
+
+  if (offset) {
+    GstMemoryDefault *parent;
+
+    parent = (GstMemoryDefault *) mem1->mem.parent;
+
+    *offset = mem1->offset - parent->offset;
+  }
+
+  /* and memory is contiguous */
+  return mem1->data + mem1->offset + mem1->size == mem2->data + mem2->offset;
+}
+
+static GstMemory *
+_fallback_copy (GstMemory * mem, gsize offset, gsize size)
+{
+  GstMemory *copy;
+  guint8 *data, *dest;
+  gsize msize;
+
+  data = gst_memory_map (mem, &msize, NULL, GST_MAP_READ);
+  if (size == -1)
+    size = msize > offset ? msize - offset : 0;
+  /* use the same allocator as the memory we copy, FIXME, alignment?  */
+  copy = gst_memory_allocator_alloc (mem->allocator, size, 1);
+  dest = gst_memory_map (copy, NULL, NULL, GST_MAP_WRITE);
+  memcpy (dest, data + offset, size);
+  gst_memory_unmap (copy, dest, size);
+
+  gst_memory_unmap (mem, data, msize);
+
+  return (GstMemory *) copy;
+}
+
+static gboolean
+_fallback_is_span (GstMemory * mem1, GstMemory * mem2, gsize * offset)
+{
+  return FALSE;
+}
+
+static GStaticRWLock lock = G_STATIC_RW_LOCK_INIT;
+static GHashTable *allocators;
+
+void
+_gst_memory_init (void)
+{
+  static const GstMemoryInfo _mem_info = {
+    (GstMemoryAllocFunction) _default_mem_alloc,
+    (GstMemoryGetSizesFunction) _default_mem_get_sizes,
+    (GstMemoryResizeFunction) _default_mem_resize,
+    (GstMemoryMapFunction) _default_mem_map,
+    (GstMemoryUnmapFunction) _default_mem_unmap,
+    (GstMemoryFreeFunction) _default_mem_free,
+    (GstMemoryCopyFunction) _default_mem_copy,
+    (GstMemoryShareFunction) _default_mem_share,
+    (GstMemoryIsSpanFunction) _default_mem_is_span,
+    NULL
+  };
+
+  allocators = g_hash_table_new (g_str_hash, g_str_equal);
+
+#ifdef HAVE_GETPAGESIZE
+#ifdef MEMORY_ALIGNMENT_PAGESIZE
+  gst_memory_alignment = getpagesize () - 1;
+#endif
+#endif
+
+  _default_mem_impl =
+      gst_memory_allocator_register ("GstMemoryDefault", &_mem_info);
+
+  _default_allocator = _default_mem_impl;
+}
+
+/**
+ * gst_memory_new_wrapped:
+ * @flags: #GstMemoryFlags
+ * @data: data to wrap
+ * @free_func: function to free @data
+ * @maxsize: allocated size of @data
+ * @offset: offset in @data
+ * @size: size of valid data
+ *
+ * Allocate a new memory block that wraps the given @data.
+ *
+ * Returns: a new #GstMemory.
+ */
+GstMemory *
+gst_memory_new_wrapped (GstMemoryFlags flags, gpointer data,
+    GFreeFunc free_func, gsize maxsize, gsize offset, gsize size)
+{
+  GstMemoryDefault *mem;
+
+  g_return_val_if_fail (data != NULL, NULL);
+  g_return_val_if_fail (offset + size <= maxsize, NULL);
+
+  mem = _default_mem_new (flags, NULL, data, free_func, maxsize, offset, size);
+
+  return (GstMemory *) mem;
+}
+
+/**
+ * gst_memory_ref:
+ * @mem: a #GstMemory
+ *
+ * Increases the refcount of @mem.
+ *
+ * Returns: @mem with increased refcount
+ */
+GstMemory *
+gst_memory_ref (GstMemory * mem)
+{
+  g_return_val_if_fail (mem != NULL, NULL);
+
+  g_atomic_int_inc (&mem->refcount);
+
+  return mem;
+}
+
+/**
+ * gst_memory_unref:
+ * @mem: a #GstMemory
+ *
+ * Decreases the refcount of @mem. When the refcount reaches 0, the free
+ * function of @mem will be called.
+ */
+void
+gst_memory_unref (GstMemory * mem)
+{
+  g_return_if_fail (mem != NULL);
+  g_return_if_fail (mem->allocator != NULL);
+
+  if (g_atomic_int_dec_and_test (&mem->refcount))
+    mem->allocator->info.free (mem);
+}
+
+/**
+ * gst_memory_get_sizes:
+ * @mem: a #GstMemory
+ * @maxsize: pointer to maxsize
+ *
+ * Get the current @size and @maxsize of @mem.
+ *
+ * Returns: the current sizes of @mem
+ */
+gsize
+gst_memory_get_sizes (GstMemory * mem, gsize * maxsize)
+{
+  g_return_val_if_fail (mem != NULL, 0);
+
+  return mem->allocator->info.get_sizes (mem, maxsize);
+}
+
+/**
+ * gst_memory_resize:
+ * @mem: a #GstMemory
+ * @offset: a new offset
+ * @size: a new size
+ *
+ * Resize the memory region. @mem should be writable and offset + size should be
+ * less than the maxsize of @mem.
+ */
+void
+gst_memory_resize (GstMemory * mem, gsize offset, gsize size)
+{
+  g_return_if_fail (mem != NULL);
+  g_return_if_fail (GST_MEMORY_IS_WRITABLE (mem));
+
+  mem->allocator->info.resize (mem, offset, size);
+}
+
+/**
+ * gst_memory_map:
+ * @mem: a #GstMemory
+ * @size: pointer for size
+ * @maxsize: pointer for maxsize
+ * @flags: mapping flags
+ *
+ * Get a pointer to the memory of @mem that can be accessed according to @flags.
+ *
+ * @size and @maxsize will contain the size of the memory and the maximum
+ * allocated memory of @mem respectively. They can be set to NULL.
+ *
+ * Returns: a pointer to the memory of @mem.
+ */
+gpointer
+gst_memory_map (GstMemory * mem, gsize * size, gsize * maxsize,
+    GstMapFlags flags)
+{
+  g_return_val_if_fail (mem != NULL, NULL);
+  g_return_val_if_fail (!(flags & GST_MAP_WRITE) ||
+      GST_MEMORY_IS_WRITABLE (mem), NULL);
+
+  return mem->allocator->info.map (mem, size, maxsize, flags);
+}
+
+/**
+ * gst_memory_unmap:
+ * @mem: a #GstMemory
+ * @data: data to unmap
+ * @size: new size of @mem
+ *
+ * Release the memory pointer obtained with gst_memory_map() and set the size of
+ * the memory to @size. @size can be set to -1 when the size should not be
+ * updated.
+ *
+ * Returns: TRUE when the memory was release successfully.
+ */
+gboolean
+gst_memory_unmap (GstMemory * mem, gpointer data, gsize size)
+{
+  g_return_val_if_fail (mem != NULL, FALSE);
+
+  return mem->allocator->info.unmap (mem, data, size);
+}
+
+/**
+ * gst_memory_copy:
+ * @mem: a #GstMemory
+ * @offset: an offset to copy
+ * @size: size to copy
+ *
+ * Return a copy of @size bytes from @mem starting from @offset. This copy is
+ * guaranteed to be writable. @size can be set to -1 to return a copy all bytes
+ * from @offset.
+ *
+ * Returns: a new #GstMemory.
+ */
+GstMemory *
+gst_memory_copy (GstMemory * mem, gsize offset, gsize size)
+{
+  g_return_val_if_fail (mem != NULL, NULL);
+
+  return mem->allocator->info.copy (mem, offset, size);
+}
+
+/**
+ * gst_memory_share:
+ * @mem: a #GstMemory
+ * @offset: an offset to share
+ * @size: size to share
+ *
+ * Return a shared copy of @size bytes from @mem starting from @offset. No memory
+ * copy is performed and the memory region is simply shared. The result is
+ * guaranteed to be not-writable. @size can be set to -1 to return a share all bytes
+ * from @offset.
+ *
+ * Returns: a new #GstMemory.
+ */
+GstMemory *
+gst_memory_share (GstMemory * mem, gsize offset, gsize size)
+{
+  g_return_val_if_fail (mem != NULL, NULL);
+
+  return mem->allocator->info.share (mem, offset, size);
+}
+
+/**
+ * gst_memory_is_span:
+ * @mem1: a #GstMemory
+ * @mem2: a #GstMemory
+ * @offset: a pointer to a result offset
+ *
+ * Check if @mem1 and mem2 share the memory with a common parent memory object
+ * and that the memory is contiguous.
+ *
+ * If this is the case, the memory of @mem1 and @mem2 can be merged
+ * efficiently by performing gst_memory_share() on the parent object from
+ * the returned @offset.
+ *
+ * Returns: %TRUE if the memory is contiguous and of a common parent.
+ */
+gboolean
+gst_memory_is_span (GstMemory * mem1, GstMemory * mem2, gsize * offset)
+{
+  g_return_val_if_fail (mem1 != NULL, FALSE);
+  g_return_val_if_fail (mem2 != NULL, FALSE);
+
+  /* need to have the same allocators */
+  if (mem1->allocator != mem2->allocator)
+    return FALSE;
+
+  /* need to have the same parent */
+  if (mem1->parent == NULL || mem1->parent != mem2->parent)
+    return FALSE;
+
+  /* and memory is contiguous */
+  if (!mem1->allocator->info.is_span (mem1, mem2, offset))
+    return FALSE;
+
+  return TRUE;
+}
+
+/**
+ * gst_memory_allocator_register:
+ * @name: the name of the allocator
+ * @info: #GstMemoryInfo
+ *
+ * Registers the memory allocator with @name and implementation functions
+ * @info.
+ *
+ * All functions in @info are mandatory exept the copy and is_span
+ * functions, which will have a default implementation when left NULL.
+ *
+ * The user_data field in @info will be passed to all calls of the alloc
+ * function.
+ *
+ * Returns: a new #GstMemoryAllocator.
+ */
+const GstMemoryAllocator *
+gst_memory_allocator_register (const gchar * name, const GstMemoryInfo * info)
+{
+  GstMemoryAllocator *allocator;
+
+#define INSTALL_FALLBACK(_t) \
+  if (allocator->info._t == NULL) allocator->info._t = _fallback_ ##_t;
+
+  g_return_val_if_fail (name != NULL, NULL);
+  g_return_val_if_fail (info != NULL, NULL);
+  g_return_val_if_fail (info->alloc != NULL, NULL);
+  g_return_val_if_fail (info->get_sizes != NULL, NULL);
+  g_return_val_if_fail (info->resize != NULL, NULL);
+  g_return_val_if_fail (info->map != NULL, NULL);
+  g_return_val_if_fail (info->unmap != NULL, NULL);
+  g_return_val_if_fail (info->free != NULL, NULL);
+  g_return_val_if_fail (info->share != NULL, NULL);
+
+  allocator = g_slice_new (GstMemoryAllocator);
+  allocator->name = g_quark_from_string (name);
+  allocator->info = *info;
+  INSTALL_FALLBACK (copy);
+  INSTALL_FALLBACK (is_span);
+#undef INSTALL_FALLBACK
+
+  GST_DEBUG ("register \"%s\" of size %" G_GSIZE_FORMAT, name);
+
+  g_static_rw_lock_writer_lock (&lock);
+  g_hash_table_insert (allocators, (gpointer) name, (gpointer) allocator);
+  g_static_rw_lock_writer_unlock (&lock);
+
+  return allocator;
+}
+
+/**
+ * gst_memory_allocator_find:
+ * @name: the name of the allocator
+ *
+ * Find a previously registered allocator with @name. When @name is NULL, the
+ * default allocator will be returned.
+ *
+ * Returns: a #GstMemoryAllocator or NULL when the allocator with @name was not
+ * registered.
+ */
+const GstMemoryAllocator *
+gst_memory_allocator_find (const gchar * name)
+{
+  const GstMemoryAllocator *allocator;
+
+  g_static_rw_lock_reader_lock (&lock);
+  if (name) {
+    allocator = g_hash_table_lookup (allocators, (gconstpointer) name);
+  } else {
+    allocator = _default_allocator;
+  }
+  g_static_rw_lock_reader_unlock (&lock);
+
+  return allocator;
+}
+
+/**
+ * gst_memory_allocator_set_default:
+ * @allocator: a ##GstMemoryAllocator
+ *
+ * Set the default allocator.
+ */
+void
+gst_memory_allocator_set_default (const GstMemoryAllocator * allocator)
+{
+  g_return_if_fail (allocator != NULL);
+
+  g_static_rw_lock_writer_lock (&lock);
+  _default_allocator = allocator;
+  g_static_rw_lock_writer_unlock (&lock);
+}
+
+/**
+ * gst_memory_allocator_alloc:
+ * @allocator: a #GstMemoryAllocator to use
+ * @maxsize: allocated size of @data
+ * @align: alignment for the data
+ *
+ * Use @allocator to allocate a new memory block with memory that is at least
+ * @maxsize big and has the given alignment.
+ *
+ * When @allocator is NULL, the default allocator will be used.
+ *
+ * @align is given as a bitmask so that @align + 1 equals the amount of bytes to
+ * align to. For example, to align to 8 bytes, use an alignment of 7.
+ *
+ * Returns: a new #GstMemory.
+ */
+GstMemory *
+gst_memory_allocator_alloc (const GstMemoryAllocator * allocator,
+    gsize maxsize, gsize align)
+{
+  g_return_val_if_fail (((align + 1) & align) == 0, NULL);
+
+  if (allocator == NULL)
+    allocator = _default_allocator;
+
+  return allocator->info.alloc (allocator, maxsize, align,
+      allocator->info.user_data);
+}
diff --git a/gst/gstmemory.h b/gst/gstmemory.h
new file mode 100644 (file)
index 0000000..452d1a4
--- /dev/null
@@ -0,0 +1,302 @@
+/* GStreamer
+ * Copyright (C) 2009 Wim Taymans <wim.taymans@gmail.be>
+ *
+ * gstmemory.h: Header for memory blocks
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+
+#ifndef __GST_MEMORY_H__
+#define __GST_MEMORY_H__
+
+#include <gst/gstconfig.h>
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+typedef struct _GstMemory GstMemory;
+typedef struct _GstMemoryInfo GstMemoryInfo;
+typedef struct _GstMemoryAllocator GstMemoryAllocator;
+
+extern gsize gst_memory_alignment;
+
+/**
+ * GstMemoryFlags:
+ * @GST_MEMORY_FLAG_READONLY: memory is readonly. It is not allowed to map the
+ * memory with #GST_MAP_WRITE.
+ * @GST_MEMORY_FLAG_NO_SHARE: memory must not be shared. Copies will have to be
+ * made when this memory needs to be shared between buffers.
+ * @GST_MEMORY_FLAG_LAST: first flag that can be used for custom purposes
+ *
+ * Flags for wrapped memory.
+ */
+typedef enum {
+  GST_MEMORY_FLAG_READONLY = (1 << 0),
+  GST_MEMORY_FLAG_NO_SHARE = (1 << 1),
+
+  GST_MEMORY_FLAG_LAST = (1 << 24)
+} GstMemoryFlags;
+
+/**
+ * GST_MEMORY_IS_WRITABLE:
+ * @mem: a #GstMemory
+ *
+ * Check if @mem is writable.
+ */
+#define GST_MEMORY_IS_WRITABLE(mem) (((mem)->refcount == 1) && \
+    (((mem)->parent == NULL) || ((mem)->parent->refcount == 1)) && \
+    (((mem)->flags & GST_MEMORY_FLAG_READONLY) == 0))
+
+/**
+ * GstMemory:
+ * @allocator: pointer to the #GstMemoryAllocator
+ * @flags: memory flags
+ * @refcount: refcount
+ * @parent: parent memory block
+ *
+ * Base structure for memory implementations. Custom memory will put this structure
+ * as the first member of their structure.
+ */
+struct _GstMemory {
+  const GstMemoryAllocator *allocator;
+
+  GstMemoryFlags  flags;
+  gint            refcount;
+  GstMemory      *parent;
+};
+
+/**
+ * GstMapFlags:
+ * @GST_MAP_READ: map for read access
+ * @GST_MAP_WRITE: map for write access
+ *
+ * Flags used when mapping memory
+ */
+typedef enum {
+  GST_MAP_READ =  (1 << 0),
+  GST_MAP_WRITE = (1 << 1),
+} GstMapFlags;
+
+/**
+ * GST_MAP_READWRITE:
+ *
+ * Map for readwrite access
+ */
+#define GST_MAP_READWRITE      (GST_MAP_READ | GST_MAP_WRITE)
+
+/**
+ * GST_MEMORY_TRACE_NAME:
+ *
+ * The name used for tracing memory allocations.
+ */
+#define GST_MEMORY_TRACE_NAME           "GstMemory"
+
+/**
+ * GstMemoryAllocFunction:
+ * @allocator: a #GstMemoryAllocator
+ * @maxsize: the maxsize
+ * @align: the alignment
+ * @user_data: user data
+ *
+ * Allocate a new #GstMemory from @allocator that can hold at least @maxsize bytes
+ * and is aligned to (@align + 1) bytes.
+ *
+ * @user_data is the data that was used when registering @allocator.
+ *
+ * Returns: a newly allocated #GstMemory. Free with gst_memory_unref()
+ */
+typedef GstMemory *  (*GstMemoryAllocFunction)  (const GstMemoryAllocator *allocator,
+                                                 gsize maxsize, gsize align,
+                                                 gpointer user_data);
+
+/**
+ * GstMemoryGetSizesFunction:
+ * @mem: a #GstMemory
+ * @maxsize: result pointer for maxsize
+ *
+ * Retrieve the size and maxsize of @mem.
+ *
+ * Returns: the size of @mem and the maximum allocated size in @maxsize.
+ */
+typedef gsize       (*GstMemoryGetSizesFunction)  (GstMemory *mem, gsize *maxsize);
+
+/**
+ * GstMemoryResizeFunction:
+ * @mem: a #GstMemory
+ * @offset: the new offset
+ * @size: the new size
+ *
+ * Adjust the size and offset of @mem. @offset bytes will be skipped from the
+ * current first byte in @mem as retrieved with gst_memory_map() and the new
+ * size will be set to @size.
+ *
+ * @size can be set to -1, which will only adjust the offset.
+ */
+typedef void        (*GstMemoryResizeFunction)    (GstMemory *mem, gsize offset, gsize size);
+
+/**
+ * GstMemoryMapFunction:
+ * @mem: a #GstMemory
+ * @size: pointer for the size
+ * @maxsize: pointer for the maxsize
+ * @flags: access mode for the memory
+ *
+ * Get the memory of @mem that can be accessed according to the mode specified
+ * in @flags. @size and @maxsize will respectively contain the current amount of
+ * valid bytes in the returned memory and the maximum allocated memory.
+ * @size and @maxsize can optionally be set to NULL.
+ *
+ * Returns: a pointer to memory. @size bytes are currently used from the
+ * returned pointer and @maxsize bytes can potentially be used.
+ */
+typedef gpointer    (*GstMemoryMapFunction)       (GstMemory *mem, gsize *size, gsize *maxsize,
+                                                   GstMapFlags flags);
+
+/**
+ * GstMemoryUnmapFunction:
+ * @mem: a #GstMemory
+ * @data: the data pointer
+ * @size: the new size
+ *
+ * Return the pointer previously retrieved with gst_memory_map() and adjust the
+ * size of the memory with @size. @size can optionally be set to -1 to not
+ * modify the size.
+ *
+ * Returns: %TRUE on success.
+ */
+typedef gboolean    (*GstMemoryUnmapFunction)     (GstMemory *mem, gpointer data, gsize size);
+
+/**
+ * GstMemoryFreeFunction:
+ * @mem: a #GstMemory
+ *
+ * Free the memory used by @mem. This function is usually called when the
+ * refcount of the @mem has reached 0.
+ */
+typedef void        (*GstMemoryFreeFunction)      (GstMemory *mem);
+
+/**
+ * GstMemoryCopyFunction:
+ * @mem: a #GstMemory
+ * @offset: an offset
+ * @size: a size
+ *
+ * Copy @size bytes from @mem starting at @offset and return them wrapped in a
+ * new GstMemory object.
+ * If @size is set to -1, all bytes starting at @offset are copied.
+ *
+ * Returns: a new #GstMemory object wrapping a copy of the requested region in
+ * @mem.
+ */
+typedef GstMemory * (*GstMemoryCopyFunction)      (GstMemory *mem, gsize offset, gsize size);
+
+/**
+ * GstMemoryShareFunction:
+ * @mem: a #GstMemory
+ * @offset: an offset
+ * @size: a size
+ *
+ * Share @size bytes from @mem starting at @offset and return them wrapped in a
+ * new GstMemory object. If @size is set to -1, all bytes starting at @offset are
+ * shared. This function does not make a copy of the bytes in @mem.
+ *
+ * Returns: a new #GstMemory object sharing the requested region in @mem.
+ */
+typedef GstMemory * (*GstMemoryShareFunction)     (GstMemory *mem, gsize offset, gsize size);
+
+/**
+ * GstMemoryIsSpanFunction:
+ * @mem1: a #GstMemory
+ * @mem2: a #GstMemory
+ * @offset: a result offset
+ *
+ * Check if @mem1 and @mem2 occupy contiguous memory and return the offset of
+ * @mem1 in the parent buffer in @offset.
+ *
+ * Returns: %TRUE if @mem1 and @mem2 are in contiguous memory.
+ */
+typedef gboolean    (*GstMemoryIsSpanFunction)    (GstMemory *mem1, GstMemory *mem2, gsize *offset);
+
+/**
+ * GstMemoryInfo:
+ * @alloc: the implementation of the GstMemoryAllocFunction
+ * @get_sizes: the implementation of the GstMemoryGetSizesFunction
+ * @resize: the implementation of the GstMemoryResizeFunction
+ * @map: the implementation of the GstMemoryMapFunction
+ * @unmap: the implementation of the GstMemoryUnmapFunction
+ * @free: the implementation of the GstMemoryFreeFunction
+ * @copy: the implementation of the GstMemoryCopyFunction
+ * @share: the implementation of the GstMemoryShareFunction
+ * @is_span: the implementation of the GstMemoryIsSpanFunction
+ * @user_data: generic user data for the allocator
+ *
+ * The #GstMemoryInfo is used to register new memory allocators and contain
+ * the implementations for various memory operations.
+ */
+struct _GstMemoryInfo {
+  GstMemoryAllocFunction    alloc;
+  GstMemoryGetSizesFunction get_sizes;
+  GstMemoryResizeFunction   resize;
+  GstMemoryMapFunction      map;
+  GstMemoryUnmapFunction    unmap;
+  GstMemoryFreeFunction     free;
+
+  GstMemoryCopyFunction     copy;
+  GstMemoryShareFunction    share;
+  GstMemoryIsSpanFunction   is_span;
+
+  gpointer user_data;
+};
+
+void _gst_memory_init (void);
+
+/* allocators */
+const GstMemoryAllocator *  gst_memory_allocator_register    (const gchar *name, const GstMemoryInfo *info);
+const GstMemoryAllocator *  gst_memory_allocator_find        (const gchar *name);
+
+void                        gst_memory_allocator_set_default (const GstMemoryAllocator * allocator);
+
+/* allocating memory blocks */
+GstMemory * gst_memory_allocator_alloc (const GstMemoryAllocator * allocator,
+                                        gsize maxsize, gsize align);
+GstMemory * gst_memory_new_wrapped     (GstMemoryFlags flags, gpointer data, GFreeFunc free_func,
+                                        gsize maxsize, gsize offset, gsize size);
+
+/* refcounting */
+GstMemory * gst_memory_ref        (GstMemory *mem);
+void        gst_memory_unref      (GstMemory *mem);
+
+/* getting/setting memory properties */
+gsize       gst_memory_get_sizes  (GstMemory *mem, gsize *maxsize);
+void        gst_memory_resize     (GstMemory *mem, gsize offset, gsize size);
+
+/* retrieving data */
+gpointer    gst_memory_map        (GstMemory *mem, gsize *size, gsize *maxsize,
+                                   GstMapFlags flags);
+gboolean    gst_memory_unmap      (GstMemory *mem, gpointer data, gsize size);
+
+/* copy and subregions */
+GstMemory * gst_memory_copy       (GstMemory *mem, gsize offset, gsize size);
+GstMemory * gst_memory_share      (GstMemory *mem, gsize offset, gsize size);
+
+/* span memory */
+gboolean    gst_memory_is_span    (GstMemory *mem1, GstMemory *mem2, gsize *offset);
+
+G_END_DECLS
+
+#endif /* __GST_MEMORY_H__ */
index e151042..79cfb53 100644 (file)
 #include "gstquark.h"
 
 
-#define GST_MESSAGE_SEQNUM(e) ((GstMessage*)e)->abidata.ABI.seqnum
+static GType _gst_message_type = 0;
 
-static void gst_message_finalize (GstMessage * message);
-static GstMessage *_gst_message_copy (GstMessage * message);
-
-static GstMiniObjectClass *parent_class = NULL;
-
-void
-_gst_message_initialize (void)
+typedef struct
 {
-  GST_CAT_INFO (GST_CAT_GST_INIT, "init messages");
+  GstMessage message;
 
-  /* the GstMiniObject types need to be class_ref'd once before it can be
-   * done from multiple threads;
-   * see http://bugzilla.gnome.org/show_bug.cgi?id=304551 */
-  g_type_class_ref (gst_message_get_type ());
-}
+  GstStructure *structure;
+} GstMessageImpl;
+
+#define GST_MESSAGE_STRUCTURE(m) (((GstMessageImpl *)(m))->structure)
 
 typedef struct
 {
@@ -116,6 +109,24 @@ static GstMessageQuarks message_quarks[] = {
   {0, NULL, 0}
 };
 
+void
+_gst_message_initialize (void)
+{
+  gint i;
+
+  GST_CAT_INFO (GST_CAT_GST_INIT, "init messages");
+
+  /* the GstMiniObject types need to be class_ref'd once before it can be
+   * done from multiple threads;
+   * see http://bugzilla.gnome.org/show_bug.cgi?id=304551 */
+  gst_message_get_type ();
+
+  for (i = 0; message_quarks[i].name; i++) {
+    message_quarks[i].quark =
+        g_quark_from_static_string (message_quarks[i].name);
+  }
+}
+
 /**
  * gst_message_type_get_name:
  * @type: the message type
@@ -156,39 +167,21 @@ gst_message_type_to_quark (GstMessageType type)
   return 0;
 }
 
-#define _do_init \
-{ \
-  gint i; \
-  \
-  for (i = 0; message_quarks[i].name; i++) { \
-    message_quarks[i].quark = \
-        g_quark_from_static_string (message_quarks[i].name); \
-  } \
-}
-
-G_DEFINE_TYPE_WITH_CODE (GstMessage, gst_message, GST_TYPE_MINI_OBJECT,
-    _do_init);
-
-static void
-gst_message_class_init (GstMessageClass * klass)
+GType
+gst_message_get_type (void)
 {
-  parent_class = g_type_class_peek_parent (klass);
-
-  klass->mini_object_class.copy = (GstMiniObjectCopyFunction) _gst_message_copy;
-  klass->mini_object_class.finalize =
-      (GstMiniObjectFinalizeFunction) gst_message_finalize;
+  if (G_UNLIKELY (_gst_message_type == 0)) {
+    _gst_message_type = gst_mini_object_register ("GstMessage");
+  }
+  return _gst_message_type;
 }
 
-static void
-gst_message_init (GstMessage * message)
-{
-  GST_CAT_LOG (GST_CAT_MESSAGE, "new message %p", message);
-  GST_MESSAGE_TIMESTAMP (message) = GST_CLOCK_TIME_NONE;
-}
 
 static void
-gst_message_finalize (GstMessage * message)
+_gst_message_free (GstMessage * message)
 {
+  GstStructure *structure;
+
   g_return_if_fail (message != NULL);
 
   GST_CAT_LOG (GST_CAT_MESSAGE, "finalize message %p", message);
@@ -204,43 +197,51 @@ gst_message_finalize (GstMessage * message)
     GST_MESSAGE_UNLOCK (message);
   }
 
-  if (message->structure) {
-    gst_structure_set_parent_refcount (message->structure, NULL);
-    gst_structure_free (message->structure);
+  structure = GST_MESSAGE_STRUCTURE (message);
+  if (structure) {
+    gst_structure_set_parent_refcount (structure, NULL);
+    gst_structure_free (structure);
   }
 
-/*   GST_MINI_OBJECT_CLASS (parent_class)->finalize (GST_MINI_OBJECT (message)); */
+  g_slice_free1 (GST_MINI_OBJECT_SIZE (message), message);
 }
 
 static GstMessage *
 _gst_message_copy (GstMessage * message)
 {
-  GstMessage *copy;
+  GstMessageImpl *copy;
+  GstStructure *structure;
 
   GST_CAT_LOG (GST_CAT_MESSAGE, "copy message %p", message);
 
-  copy = (GstMessage *) gst_mini_object_new (GST_TYPE_MESSAGE);
+  copy = g_slice_new0 (GstMessageImpl);
 
-  /* FIXME, need to copy relevant data from the miniobject. */
-  //memcpy (copy, message, sizeof (GstMessage));
+  gst_mini_object_init (GST_MINI_OBJECT_CAST (copy),
+      _gst_message_type, sizeof (GstMessageImpl));
+
+  copy->message.mini_object.copy =
+      (GstMiniObjectCopyFunction) _gst_message_copy;
+  copy->message.mini_object.free =
+      (GstMiniObjectFreeFunction) _gst_message_free;
 
-  GST_MESSAGE_GET_LOCK (copy) = GST_MESSAGE_GET_LOCK (message);
-  GST_MESSAGE_COND (copy) = GST_MESSAGE_COND (message);
   GST_MESSAGE_TYPE (copy) = GST_MESSAGE_TYPE (message);
   GST_MESSAGE_TIMESTAMP (copy) = GST_MESSAGE_TIMESTAMP (message);
   GST_MESSAGE_SEQNUM (copy) = GST_MESSAGE_SEQNUM (message);
-
   if (GST_MESSAGE_SRC (message)) {
     GST_MESSAGE_SRC (copy) = gst_object_ref (GST_MESSAGE_SRC (message));
   }
 
-  if (message->structure) {
-    copy->structure = gst_structure_copy (message->structure);
+  GST_MESSAGE_GET_LOCK (copy) = GST_MESSAGE_GET_LOCK (message);
+  GST_MESSAGE_COND (copy) = GST_MESSAGE_COND (message);
+
+  structure = GST_MESSAGE_STRUCTURE (message);
+  if (structure) {
+    copy->structure = gst_structure_copy (structure);
     gst_structure_set_parent_refcount (copy->structure,
-        &copy->mini_object.refcount);
+        &copy->message.mini_object.refcount);
   }
 
-  return copy;
+  return GST_MESSAGE_CAST (copy);
 }
 
 /**
@@ -262,29 +263,36 @@ GstMessage *
 gst_message_new_custom (GstMessageType type, GstObject * src,
     GstStructure * structure)
 {
-  GstMessage *message;
+  GstMessageImpl *message;
+
+  message = g_slice_new0 (GstMessageImpl);
+
+  gst_mini_object_init (GST_MINI_OBJECT_CAST (message),
+      _gst_message_type, sizeof (GstMessageImpl));
 
-  message = (GstMessage *) gst_mini_object_new (GST_TYPE_MESSAGE);
+  message->message.mini_object.copy =
+      (GstMiniObjectCopyFunction) _gst_message_copy;
+  message->message.mini_object.free =
+      (GstMiniObjectFreeFunction) _gst_message_free;
 
   GST_CAT_LOG (GST_CAT_MESSAGE, "source %s: creating new message %p %s",
       (src ? GST_OBJECT_NAME (src) : "NULL"), message,
       gst_message_type_get_name (type));
 
-  message->type = type;
-
+  GST_MESSAGE_TYPE (message) = type;
   if (src)
     gst_object_ref (src);
-  message->src = src;
+  GST_MESSAGE_SRC (message) = src;
+  GST_MESSAGE_TIMESTAMP (message) = GST_CLOCK_TIME_NONE;
+  GST_MESSAGE_SEQNUM (message) = gst_util_seqnum_next ();
 
   if (structure) {
     gst_structure_set_parent_refcount (structure,
-        &message->mini_object.refcount);
+        &message->message.mini_object.refcount);
   }
   message->structure = structure;
 
-  GST_MESSAGE_SEQNUM (message) = gst_util_seqnum_next ();
-
-  return message;
+  return GST_MESSAGE_CAST (message);
 }
 
 /**
@@ -862,27 +870,19 @@ gst_message_new_duration (GstObject * src, GstFormat format, gint64 duration)
 /**
  * gst_message_new_async_start:
  * @src: (transfer none): The object originating the message.
- * @new_base_time: if a new base_time should be set on the element
  *
- * This message is posted by elements when they start an ASYNC state change. 
- * @new_base_time is set to TRUE when the element lost its state when it was
- * PLAYING.
+ * This message is posted by elements when they start an ASYNC state change.
  *
  * Returns: (transfer full): The new async_start message.
  *
  * MT safe.
- *
- * Since: 0.10.13
  */
 GstMessage *
-gst_message_new_async_start (GstObject * src, gboolean new_base_time)
+gst_message_new_async_start (GstObject * src)
 {
   GstMessage *message;
-  GstStructure *structure;
 
-  structure = gst_structure_id_new (GST_QUARK (MESSAGE_ASYNC_START),
-      GST_QUARK (NEW_BASE_TIME), G_TYPE_BOOLEAN, new_base_time, NULL);
-  message = gst_message_new_custom (GST_MESSAGE_ASYNC_START, src, structure);
+  message = gst_message_new_custom (GST_MESSAGE_ASYNC_START, src, NULL);
 
   return message;
 }
@@ -890,21 +890,25 @@ gst_message_new_async_start (GstObject * src, gboolean new_base_time)
 /**
  * gst_message_new_async_done:
  * @src: (transfer none): The object originating the message.
+ * @reset_time: if the running_time should be reset
  *
  * The message is posted when elements completed an ASYNC state change.
+ * @reset_time is set to TRUE when the element requests a new running_time
+ * before going to PLAYING.
  *
  * Returns: (transfer full): The new async_done message.
  *
  * MT safe.
- *
- * Since: 0.10.13
  */
 GstMessage *
-gst_message_new_async_done (GstObject * src)
+gst_message_new_async_done (GstObject * src, gboolean reset_time)
 {
   GstMessage *message;
+  GstStructure *structure;
 
-  message = gst_message_new_custom (GST_MESSAGE_ASYNC_DONE, src, NULL);
+  structure = gst_structure_id_new (GST_QUARK (MESSAGE_ASYNC_DONE),
+      GST_QUARK (RESET_TIME), G_TYPE_BOOLEAN, reset_time, NULL);
+  message = gst_message_new_custom (GST_MESSAGE_ASYNC_DONE, src, structure);
 
   return message;
 }
@@ -977,7 +981,33 @@ gst_message_get_structure (GstMessage * message)
 {
   g_return_val_if_fail (GST_IS_MESSAGE (message), NULL);
 
-  return message->structure;
+  return GST_MESSAGE_STRUCTURE (message);
+}
+
+/**
+ * gst_message_has_name:
+ * @message: The #GstMessage.
+ * @name: name to check
+ *
+ * Checks if @message has the given @name. This function is usually used to
+ * check the name of a custom message.
+ *
+ * Returns: %TRUE if @name matches the name of the message structure.
+ *
+ * Since: 0.10.20
+ */
+gboolean
+gst_message_has_name (GstMessage * message, const gchar * name)
+{
+  GstStructure *structure;
+
+  g_return_val_if_fail (GST_IS_MESSAGE (message), FALSE);
+
+  structure = GST_MESSAGE_STRUCTURE (message);
+  if (structure == NULL)
+    return FALSE;
+
+  return gst_structure_has_name (structure, name);
 }
 
 /**
@@ -1017,7 +1047,7 @@ gst_message_parse_tag (GstMessage * message, GstTagList ** tag_list)
   g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_TAG);
   g_return_if_fail (tag_list != NULL);
 
-  ret = gst_structure_copy (message->structure);
+  ret = gst_structure_copy (GST_MESSAGE_STRUCTURE (message));
   gst_structure_remove_field (ret, "source-pad");
 
   *tag_list = (GstTagList *) ret;
@@ -1047,7 +1077,7 @@ gst_message_parse_tag_full (GstMessage * message, GstPad ** pad,
   g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_TAG);
   g_return_if_fail (tag_list != NULL);
 
-  ret = gst_structure_copy (message->structure);
+  ret = gst_structure_copy (GST_MESSAGE_STRUCTURE (message));
 
   if (gst_structure_has_field (ret, "source-pad") && pad) {
     const GValue *v;
@@ -1084,8 +1114,9 @@ gst_message_parse_buffering (GstMessage * message, gint * percent)
   g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_BUFFERING);
 
   if (percent)
-    *percent = g_value_get_int (gst_structure_id_get_value (message->structure,
-            GST_QUARK (BUFFER_PERCENT)));
+    *percent =
+        g_value_get_int (gst_structure_id_get_value (GST_MESSAGE_STRUCTURE
+            (message), GST_QUARK (BUFFER_PERCENT)));
 }
 
 /**
@@ -1106,7 +1137,7 @@ gst_message_set_buffering_stats (GstMessage * message, GstBufferingMode mode,
 {
   g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_BUFFERING);
 
-  gst_structure_id_set (message->structure,
+  gst_structure_id_set (GST_MESSAGE_STRUCTURE (message),
       GST_QUARK (BUFFERING_MODE), GST_TYPE_BUFFERING_MODE, mode,
       GST_QUARK (AVG_IN_RATE), G_TYPE_INT, avg_in,
       GST_QUARK (AVG_OUT_RATE), G_TYPE_INT, avg_out,
@@ -1131,20 +1162,23 @@ gst_message_parse_buffering_stats (GstMessage * message,
     GstBufferingMode * mode, gint * avg_in, gint * avg_out,
     gint64 * buffering_left)
 {
+  GstStructure *structure;
+
   g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_BUFFERING);
 
+  structure = GST_MESSAGE_STRUCTURE (message);
   if (mode)
-    *mode = g_value_get_enum (gst_structure_id_get_value (message->structure,
+    *mode = g_value_get_enum (gst_structure_id_get_value (structure,
             GST_QUARK (BUFFERING_MODE)));
   if (avg_in)
-    *avg_in = g_value_get_int (gst_structure_id_get_value (message->structure,
+    *avg_in = g_value_get_int (gst_structure_id_get_value (structure,
             GST_QUARK (AVG_IN_RATE)));
   if (avg_out)
-    *avg_out = g_value_get_int (gst_structure_id_get_value (message->structure,
+    *avg_out = g_value_get_int (gst_structure_id_get_value (structure,
             GST_QUARK (AVG_OUT_RATE)));
   if (buffering_left)
     *buffering_left =
-        g_value_get_int64 (gst_structure_id_get_value (message->structure,
+        g_value_get_int64 (gst_structure_id_get_value (structure,
             GST_QUARK (BUFFERING_LEFT)));
 }
 
@@ -1182,19 +1216,22 @@ void
 gst_message_parse_state_changed (GstMessage * message,
     GstState * oldstate, GstState * newstate, GstState * pending)
 {
+  GstStructure *structure;
+
   g_return_if_fail (GST_IS_MESSAGE (message));
   g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_STATE_CHANGED);
 
+  structure = GST_MESSAGE_STRUCTURE (message);
   if (oldstate)
     *oldstate =
-        g_value_get_enum (gst_structure_id_get_value (message->structure,
+        g_value_get_enum (gst_structure_id_get_value (structure,
             GST_QUARK (OLD_STATE)));
   if (newstate)
     *newstate =
-        g_value_get_enum (gst_structure_id_get_value (message->structure,
+        g_value_get_enum (gst_structure_id_get_value (structure,
             GST_QUARK (NEW_STATE)));
   if (pending)
-    *pending = g_value_get_enum (gst_structure_id_get_value (message->structure,
+    *pending = g_value_get_enum (gst_structure_id_get_value (structure,
             GST_QUARK (PENDING_STATE)));
 }
 
@@ -1215,18 +1252,19 @@ gst_message_parse_clock_provide (GstMessage * message, GstClock ** clock,
     gboolean * ready)
 {
   const GValue *clock_gvalue;
+  GstStructure *structure;
 
   g_return_if_fail (GST_IS_MESSAGE (message));
   g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_CLOCK_PROVIDE);
 
-  clock_gvalue =
-      gst_structure_id_get_value (message->structure, GST_QUARK (CLOCK));
+  structure = GST_MESSAGE_STRUCTURE (message);
+  clock_gvalue = gst_structure_id_get_value (structure, GST_QUARK (CLOCK));
   g_return_if_fail (clock_gvalue != NULL);
   g_return_if_fail (G_VALUE_TYPE (clock_gvalue) == GST_TYPE_CLOCK);
 
   if (ready)
     *ready =
-        g_value_get_boolean (gst_structure_id_get_value (message->structure,
+        g_value_get_boolean (gst_structure_id_get_value (structure,
             GST_QUARK (READY)));
   if (clock)
     *clock = (GstClock *) g_value_get_object (clock_gvalue);
@@ -1246,12 +1284,13 @@ void
 gst_message_parse_clock_lost (GstMessage * message, GstClock ** clock)
 {
   const GValue *clock_gvalue;
+  GstStructure *structure;
 
   g_return_if_fail (GST_IS_MESSAGE (message));
   g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_CLOCK_LOST);
 
-  clock_gvalue =
-      gst_structure_id_get_value (message->structure, GST_QUARK (CLOCK));
+  structure = GST_MESSAGE_STRUCTURE (message);
+  clock_gvalue = gst_structure_id_get_value (structure, GST_QUARK (CLOCK));
   g_return_if_fail (clock_gvalue != NULL);
   g_return_if_fail (G_VALUE_TYPE (clock_gvalue) == GST_TYPE_CLOCK);
 
@@ -1274,12 +1313,13 @@ void
 gst_message_parse_new_clock (GstMessage * message, GstClock ** clock)
 {
   const GValue *clock_gvalue;
+  GstStructure *structure;
 
   g_return_if_fail (GST_IS_MESSAGE (message));
   g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_NEW_CLOCK);
 
-  clock_gvalue =
-      gst_structure_id_get_value (message->structure, GST_QUARK (CLOCK));
+  structure = GST_MESSAGE_STRUCTURE (message);
+  clock_gvalue = gst_structure_id_get_value (structure, GST_QUARK (CLOCK));
   g_return_if_fail (clock_gvalue != NULL);
   g_return_if_fail (G_VALUE_TYPE (clock_gvalue) == GST_TYPE_CLOCK);
 
@@ -1307,23 +1347,24 @@ gst_message_parse_structure_change (GstMessage * message,
     GstStructureChangeType * type, GstElement ** owner, gboolean * busy)
 {
   const GValue *owner_gvalue;
+  GstStructure *structure;
 
   g_return_if_fail (GST_IS_MESSAGE (message));
   g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_STRUCTURE_CHANGE);
 
-  owner_gvalue =
-      gst_structure_id_get_value (message->structure, GST_QUARK (OWNER));
+  structure = GST_MESSAGE_STRUCTURE (message);
+  owner_gvalue = gst_structure_id_get_value (structure, GST_QUARK (OWNER));
   g_return_if_fail (owner_gvalue != NULL);
   g_return_if_fail (G_VALUE_TYPE (owner_gvalue) == GST_TYPE_ELEMENT);
 
   if (type)
-    *type = g_value_get_enum (gst_structure_id_get_value (message->structure,
+    *type = g_value_get_enum (gst_structure_id_get_value (structure,
             GST_QUARK (TYPE)));
   if (owner)
     *owner = (GstElement *) g_value_get_object (owner_gvalue);
   if (busy)
     *busy =
-        g_value_get_boolean (gst_structure_id_get_value (message->structure,
+        g_value_get_boolean (gst_structure_id_get_value (structure,
             GST_QUARK (BUSY)));
 }
 
@@ -1365,12 +1406,13 @@ gst_message_parse_error (GstMessage * message, GError ** gerror, gchar ** debug)
 {
   const GValue *error_gvalue;
   GError *error_val;
+  GstStructure *structure;
 
   g_return_if_fail (GST_IS_MESSAGE (message));
   g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_ERROR);
 
-  error_gvalue =
-      gst_structure_id_get_value (message->structure, GST_QUARK (GERROR));
+  structure = GST_MESSAGE_STRUCTURE (message);
+  error_gvalue = gst_structure_id_get_value (structure, GST_QUARK (GERROR));
   g_return_if_fail (error_gvalue != NULL);
   g_return_if_fail (G_VALUE_TYPE (error_gvalue) == GST_TYPE_G_ERROR);
 
@@ -1382,7 +1424,7 @@ gst_message_parse_error (GstMessage * message, GError ** gerror, gchar ** debug)
 
   if (debug)
     *debug =
-        g_value_dup_string (gst_structure_id_get_value (message->structure,
+        g_value_dup_string (gst_structure_id_get_value (structure,
             GST_QUARK (DEBUG)));
 }
 
@@ -1404,12 +1446,13 @@ gst_message_parse_warning (GstMessage * message, GError ** gerror,
 {
   const GValue *error_gvalue;
   GError *error_val;
+  GstStructure *structure;
 
   g_return_if_fail (GST_IS_MESSAGE (message));
   g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_WARNING);
 
-  error_gvalue =
-      gst_structure_id_get_value (message->structure, GST_QUARK (GERROR));
+  structure = GST_MESSAGE_STRUCTURE (message);
+  error_gvalue = gst_structure_id_get_value (structure, GST_QUARK (GERROR));
   g_return_if_fail (error_gvalue != NULL);
   g_return_if_fail (G_VALUE_TYPE (error_gvalue) == GST_TYPE_G_ERROR);
 
@@ -1421,7 +1464,7 @@ gst_message_parse_warning (GstMessage * message, GError ** gerror,
 
   if (debug)
     *debug =
-        g_value_dup_string (gst_structure_id_get_value (message->structure,
+        g_value_dup_string (gst_structure_id_get_value (structure,
             GST_QUARK (DEBUG)));
 }
 
@@ -1444,12 +1487,13 @@ gst_message_parse_info (GstMessage * message, GError ** gerror, gchar ** debug)
 {
   const GValue *error_gvalue;
   GError *error_val;
+  GstStructure *structure;
 
   g_return_if_fail (GST_IS_MESSAGE (message));
   g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_INFO);
 
-  error_gvalue =
-      gst_structure_id_get_value (message->structure, GST_QUARK (GERROR));
+  structure = GST_MESSAGE_STRUCTURE (message);
+  error_gvalue = gst_structure_id_get_value (structure, GST_QUARK (GERROR));
   g_return_if_fail (error_gvalue != NULL);
   g_return_if_fail (G_VALUE_TYPE (error_gvalue) == GST_TYPE_G_ERROR);
 
@@ -1461,7 +1505,7 @@ gst_message_parse_info (GstMessage * message, GError ** gerror, gchar ** debug)
 
   if (debug)
     *debug =
-        g_value_dup_string (gst_structure_id_get_value (message->structure,
+        g_value_dup_string (gst_structure_id_get_value (structure,
             GST_QUARK (DEBUG)));
 }
 
@@ -1479,16 +1523,19 @@ void
 gst_message_parse_segment_start (GstMessage * message, GstFormat * format,
     gint64 * position)
 {
+  GstStructure *structure;
+
   g_return_if_fail (GST_IS_MESSAGE (message));
   g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_SEGMENT_START);
 
+  structure = GST_MESSAGE_STRUCTURE (message);
   if (format)
     *format =
-        g_value_get_enum (gst_structure_id_get_value (message->structure,
+        g_value_get_enum (gst_structure_id_get_value (structure,
             GST_QUARK (FORMAT)));
   if (position)
     *position =
-        g_value_get_int64 (gst_structure_id_get_value (message->structure,
+        g_value_get_int64 (gst_structure_id_get_value (structure,
             GST_QUARK (POSITION)));
 }
 
@@ -1506,16 +1553,19 @@ void
 gst_message_parse_segment_done (GstMessage * message, GstFormat * format,
     gint64 * position)
 {
+  GstStructure *structure;
+
   g_return_if_fail (GST_IS_MESSAGE (message));
   g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_SEGMENT_DONE);
 
+  structure = GST_MESSAGE_STRUCTURE (message);
   if (format)
     *format =
-        g_value_get_enum (gst_structure_id_get_value (message->structure,
+        g_value_get_enum (gst_structure_id_get_value (structure,
             GST_QUARK (FORMAT)));
   if (position)
     *position =
-        g_value_get_int64 (gst_structure_id_get_value (message->structure,
+        g_value_get_int64 (gst_structure_id_get_value (structure,
             GST_QUARK (POSITION)));
 }
 
@@ -1536,40 +1586,44 @@ void
 gst_message_parse_duration (GstMessage * message, GstFormat * format,
     gint64 * duration)
 {
+  GstStructure *structure;
+
   g_return_if_fail (GST_IS_MESSAGE (message));
   g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_DURATION);
 
+  structure = GST_MESSAGE_STRUCTURE (message);
   if (format)
     *format =
-        g_value_get_enum (gst_structure_id_get_value (message->structure,
+        g_value_get_enum (gst_structure_id_get_value (structure,
             GST_QUARK (FORMAT)));
   if (duration)
     *duration =
-        g_value_get_int64 (gst_structure_id_get_value (message->structure,
+        g_value_get_int64 (gst_structure_id_get_value (structure,
             GST_QUARK (DURATION)));
 }
 
 /**
- * gst_message_parse_async_start:
+ * gst_message_parse_async_done:
  * @message: A valid #GstMessage of type GST_MESSAGE_ASYNC_DONE.
- * @new_base_time: (out): Result location for the new_base_time or NULL
+ * @reset_time: (out): Result location for the reset_time or NULL
  *
- * Extract the new_base_time from the async_start message. 
+ * Extract the reset_time from the async_done message.
  *
  * MT safe.
- *
- * Since: 0.10.13
  */
 void
-gst_message_parse_async_start (GstMessage * message, gboolean * new_base_time)
+gst_message_parse_async_done (GstMessage * message, gboolean * reset_time)
 {
+  GstStructure *structure;
+
   g_return_if_fail (GST_IS_MESSAGE (message));
-  g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_ASYNC_START);
+  g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_ASYNC_DONE);
 
-  if (new_base_time)
-    *new_base_time =
-        g_value_get_boolean (gst_structure_id_get_value (message->structure,
-            GST_QUARK (NEW_BASE_TIME)));
+  structure = GST_MESSAGE_STRUCTURE (message);
+  if (reset_time)
+    *reset_time =
+        g_value_get_boolean (gst_structure_id_get_value (structure,
+            GST_QUARK (RESET_TIME)));
 }
 
 /**
@@ -1586,11 +1640,14 @@ gst_message_parse_async_start (GstMessage * message, gboolean * new_base_time)
 void
 gst_message_parse_request_state (GstMessage * message, GstState * state)
 {
+  GstStructure *structure;
+
   g_return_if_fail (GST_IS_MESSAGE (message));
   g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_REQUEST_STATE);
 
+  structure = GST_MESSAGE_STRUCTURE (message);
   if (state)
-    *state = g_value_get_enum (gst_structure_id_get_value (message->structure,
+    *state = g_value_get_enum (gst_structure_id_get_value (structure,
             GST_QUARK (NEW_STATE)));
 }
 
@@ -1643,16 +1700,17 @@ gst_message_parse_stream_status (GstMessage * message,
     GstStreamStatusType * type, GstElement ** owner)
 {
   const GValue *owner_gvalue;
+  GstStructure *structure;
 
   g_return_if_fail (GST_IS_MESSAGE (message));
   g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_STREAM_STATUS);
 
-  owner_gvalue =
-      gst_structure_id_get_value (message->structure, GST_QUARK (OWNER));
+  structure = GST_MESSAGE_STRUCTURE (message);
+  owner_gvalue = gst_structure_id_get_value (structure, GST_QUARK (OWNER));
   g_return_if_fail (owner_gvalue != NULL);
 
   if (type)
-    *type = g_value_get_enum (gst_structure_id_get_value (message->structure,
+    *type = g_value_get_enum (gst_structure_id_get_value (structure,
             GST_QUARK (TYPE)));
   if (owner)
     *owner = (GstElement *) g_value_get_object (owner_gvalue);
@@ -1672,10 +1730,13 @@ void
 gst_message_set_stream_status_object (GstMessage * message,
     const GValue * object)
 {
+  GstStructure *structure;
+
   g_return_if_fail (GST_IS_MESSAGE (message));
   g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_STREAM_STATUS);
 
-  gst_structure_id_set_value (message->structure, GST_QUARK (OBJECT), object);
+  structure = GST_MESSAGE_STRUCTURE (message);
+  gst_structure_id_set_value (structure, GST_QUARK (OBJECT), object);
 }
 
 /**
@@ -1694,12 +1755,14 @@ const GValue *
 gst_message_get_stream_status_object (GstMessage * message)
 {
   const GValue *result;
+  GstStructure *structure;
 
   g_return_val_if_fail (GST_IS_MESSAGE (message), NULL);
   g_return_val_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_STREAM_STATUS,
       NULL);
 
-  result = gst_structure_id_get_value (message->structure, GST_QUARK (OBJECT));
+  structure = GST_MESSAGE_STRUCTURE (message);
+  result = gst_structure_id_get_value (structure, GST_QUARK (OBJECT));
 
   return result;
 }
@@ -1770,10 +1833,13 @@ gst_message_parse_step_done (GstMessage * message, GstFormat * format,
     guint64 * amount, gdouble * rate, gboolean * flush, gboolean * intermediate,
     guint64 * duration, gboolean * eos)
 {
+  GstStructure *structure;
+
   g_return_if_fail (GST_IS_MESSAGE (message));
   g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_STEP_DONE);
 
-  gst_structure_id_get (message->structure,
+  structure = GST_MESSAGE_STRUCTURE (message);
+  gst_structure_id_get (structure,
       GST_QUARK (FORMAT), GST_TYPE_FORMAT, format,
       GST_QUARK (AMOUNT), G_TYPE_UINT64, amount,
       GST_QUARK (RATE), G_TYPE_DOUBLE, rate,
@@ -1850,10 +1916,13 @@ gst_message_parse_step_start (GstMessage * message, gboolean * active,
     GstFormat * format, guint64 * amount, gdouble * rate, gboolean * flush,
     gboolean * intermediate)
 {
+  GstStructure *structure;
+
   g_return_if_fail (GST_IS_MESSAGE (message));
   g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_STEP_START);
 
-  gst_structure_id_get (message->structure,
+  structure = GST_MESSAGE_STRUCTURE (message);
+  gst_structure_id_get (structure,
       GST_QUARK (ACTIVE), G_TYPE_BOOLEAN, active,
       GST_QUARK (FORMAT), GST_TYPE_FORMAT, format,
       GST_QUARK (AMOUNT), G_TYPE_UINT64, amount,
@@ -1934,10 +2003,13 @@ void
 gst_message_set_qos_values (GstMessage * message, gint64 jitter,
     gdouble proportion, gint quality)
 {
+  GstStructure *structure;
+
   g_return_if_fail (GST_IS_MESSAGE (message));
   g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_QOS);
 
-  gst_structure_id_set (message->structure,
+  structure = GST_MESSAGE_STRUCTURE (message);
+  gst_structure_id_set (structure,
       GST_QUARK (JITTER), G_TYPE_INT64, jitter,
       GST_QUARK (PROPORTION), G_TYPE_DOUBLE, proportion,
       GST_QUARK (QUALITY), G_TYPE_INT, quality, NULL);
@@ -1968,10 +2040,13 @@ void
 gst_message_set_qos_stats (GstMessage * message, GstFormat format,
     guint64 processed, guint64 dropped)
 {
+  GstStructure *structure;
+
   g_return_if_fail (GST_IS_MESSAGE (message));
   g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_QOS);
 
-  gst_structure_id_set (message->structure,
+  structure = GST_MESSAGE_STRUCTURE (message);
+  gst_structure_id_set (structure,
       GST_QUARK (FORMAT), GST_TYPE_FORMAT, format,
       GST_QUARK (PROCESSED), G_TYPE_UINT64, processed,
       GST_QUARK (DROPPED), G_TYPE_UINT64, dropped, NULL);
@@ -2005,10 +2080,13 @@ gst_message_parse_qos (GstMessage * message, gboolean * live,
     guint64 * running_time, guint64 * stream_time, guint64 * timestamp,
     guint64 * duration)
 {
+  GstStructure *structure;
+
   g_return_if_fail (GST_IS_MESSAGE (message));
   g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_QOS);
 
-  gst_structure_id_get (message->structure,
+  structure = GST_MESSAGE_STRUCTURE (message);
+  gst_structure_id_get (structure,
       GST_QUARK (LIVE), G_TYPE_BOOLEAN, live,
       GST_QUARK (RUNNING_TIME), G_TYPE_UINT64, running_time,
       GST_QUARK (STREAM_TIME), G_TYPE_UINT64, stream_time,
@@ -2037,10 +2115,13 @@ void
 gst_message_parse_qos_values (GstMessage * message, gint64 * jitter,
     gdouble * proportion, gint * quality)
 {
+  GstStructure *structure;
+
   g_return_if_fail (GST_IS_MESSAGE (message));
   g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_QOS);
 
-  gst_structure_id_get (message->structure,
+  structure = GST_MESSAGE_STRUCTURE (message);
+  gst_structure_id_get (structure,
       GST_QUARK (JITTER), G_TYPE_INT64, jitter,
       GST_QUARK (PROPORTION), G_TYPE_DOUBLE, proportion,
       GST_QUARK (QUALITY), G_TYPE_INT, quality, NULL);
@@ -2072,10 +2153,13 @@ void
 gst_message_parse_qos_stats (GstMessage * message, GstFormat * format,
     guint64 * processed, guint64 * dropped)
 {
+  GstStructure *structure;
+
   g_return_if_fail (GST_IS_MESSAGE (message));
   g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_QOS);
 
-  gst_structure_id_get (message->structure,
+  structure = GST_MESSAGE_STRUCTURE (message);
+  gst_structure_id_get (structure,
       GST_QUARK (FORMAT), GST_TYPE_FORMAT, format,
       GST_QUARK (PROCESSED), G_TYPE_UINT64, processed,
       GST_QUARK (DROPPED), G_TYPE_UINT64, dropped, NULL);
@@ -2138,10 +2222,13 @@ void
 gst_message_parse_progress (GstMessage * message, GstProgressType * type,
     gchar ** code, gchar ** text)
 {
+  GstStructure *structure;
+
   g_return_if_fail (GST_IS_MESSAGE (message));
   g_return_if_fail (GST_MESSAGE_TYPE (message) == GST_MESSAGE_PROGRESS);
 
-  gst_structure_id_get (message->structure,
+  structure = GST_MESSAGE_STRUCTURE (message);
+  gst_structure_id_get (structure,
       GST_QUARK (TYPE), GST_TYPE_PROGRESS_TYPE, type,
       GST_QUARK (CODE), G_TYPE_STRING, code,
       GST_QUARK (TEXT), G_TYPE_STRING, text, NULL);
index 757b1d5..4045e4f 100644 (file)
@@ -25,7 +25,6 @@
 G_BEGIN_DECLS
 
 typedef struct _GstMessage GstMessage;
-typedef struct _GstMessageClass GstMessageClass;
 
 /**
  * GstMessageType:
@@ -133,6 +132,7 @@ typedef enum
 #include <gst/gstelement.h>
 #include <gst/gsttaglist.h>
 #include <gst/gststructure.h>
+#include <gst/gstquery.h>
 
 /**
  * GST_MESSAGE_TRACE_NAME:
@@ -142,12 +142,9 @@ typedef enum
 #define GST_MESSAGE_TRACE_NAME  "GstMessage"
 
 #define GST_TYPE_MESSAGE                         (gst_message_get_type())
-#define GST_IS_MESSAGE(obj)                      (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_MESSAGE))
-#define GST_IS_MESSAGE_CLASS(klass)              (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_MESSAGE))
-#define GST_MESSAGE_GET_CLASS(obj)               (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_MESSAGE, GstMessageClass))
-#define GST_MESSAGE(obj)                         (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_MESSAGE, GstMessage))
-#define GST_MESSAGE_CLASS(klass)                 (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_MESSAGE, GstMessageClass))
+#define GST_IS_MESSAGE(obj)                      (GST_IS_MINI_OBJECT_TYPE (obj, GST_TYPE_MESSAGE))
 #define GST_MESSAGE_CAST(obj)                    ((GstMessage*)(obj))
+#define GST_MESSAGE(obj)                         (GST_MESSAGE_CAST(obj))
 
 /* the lock is used to handle the synchronous handling of messages,
  * the emiting thread is block until the handling thread processed
@@ -190,6 +187,15 @@ typedef enum
  * Get the object that posted @message.
  */
 #define GST_MESSAGE_SRC(message)        (GST_MESSAGE_CAST(message)->src)
+
+/**
+ * GST_MESSAGE_SEQNUM:
+ * @message: a #GstMessage
+ *
+ * Get the sequence number of @message.
+ */
+#define GST_MESSAGE_SEQNUM(message)     (GST_MESSAGE_CAST(message)->seqnum)
+
 /**
  * GST_MESSAGE_SRC_NAME:
  * @message: a #GstMessage
@@ -270,7 +276,6 @@ typedef enum {
  * @type: the #GstMessageType of the message
  * @timestamp: the timestamp of the message
  * @src: the src of the message
- * @structure: the #GstStructure containing the message info.
  *
  * A #GstMessage.
  */
@@ -278,32 +283,15 @@ struct _GstMessage
 {
   GstMiniObject mini_object;
 
-  /*< private >*//* with MESSAGE_LOCK */
-  GMutex *lock;                 /* lock and cond for async delivery */
-  GCond *cond;
-
   /*< public > *//* with COW */
   GstMessageType type;
   guint64 timestamp;
   GstObject *src;
+  guint32 seqnum;
 
-  GstStructure *structure;
-
-  /*< private >*/
-  union {
-    struct {
-      guint32 seqnum;
-    } ABI;
-    /* + 0 to mark ABI change for future greppage */
-    gpointer _gst_reserved[GST_PADDING + 0];
-  } abidata;
-};
-
-struct _GstMessageClass {
-  GstMiniObjectClass mini_object_class;
-
-  /*< private >*/
-  gpointer _gst_reserved[GST_PADDING];
+  /*< private >*//* with MESSAGE_LOCK */
+  GMutex *lock;                 /* lock and cond for async delivery */
+  GCond *cond;
 };
 
 GType           gst_message_get_type            (void);
@@ -369,6 +357,14 @@ gst_message_copy (const GstMessage * msg)
 }
 
 /**
+ * gst_message_is_writable:
+ * @msg: a #GstMessage
+ *
+ * Tests if you can safely write into a message's structure or validly
+ * modify the seqnum and timestamp fields.
+ */
+#define         gst_message_is_writable(msg)     gst_mini_object_is_writable (GST_MINI_OBJECT_CAST (msg))
+/**
  * gst_message_make_writable:
  * @msg: (transfer full): the message to make writable
  *
@@ -380,6 +376,32 @@ gst_message_copy (const GstMessage * msg)
  * MT safe
  */
 #define         gst_message_make_writable(msg)  GST_MESSAGE_CAST (gst_mini_object_make_writable (GST_MINI_OBJECT_CAST (msg)))
+/**
+ * gst_message_replace:
+ * @old_message: (inout) (transfer full): pointer to a pointer to a #GstMessage
+ *     to be replaced.
+ * @new_message: (allow-none) (transfer none): pointer to a #GstMessage that will
+ *     replace the message pointed to by @old_message.
+ *
+ * Modifies a pointer to a #GstMessage to point to a different #GstMessage. The
+ * modification is done atomically (so this is useful for ensuring thread safety
+ * in some cases), and the reference counts are updated appropriately (the old
+ * message is unreffed, the new one is reffed).
+ *
+ * Either @new_message or the #GstMessage pointed to by @old_message may be NULL.
+ */
+#define         gst_message_replace(old_message,new_message) \
+    gst_mini_object_replace ((GstMiniObject **)(old_message), GST_MINI_OBJECT_CAST (new_message))
+
+
+/* custom messages */
+GstMessage *    gst_message_new_custom          (GstMessageType type,
+                                                 GstObject    * src,
+                                                 GstStructure * structure);
+const GstStructure *
+                gst_message_get_structure       (GstMessage *message);
+
+gboolean        gst_message_has_name            (GstMessage *message, const gchar *name);
 
 /* identifiers for events and messages */
 guint32         gst_message_get_seqnum          (GstMessage *message);
@@ -471,11 +493,11 @@ void            gst_message_parse_duration      (GstMessage *message, GstFormat
 GstMessage *    gst_message_new_latency         (GstObject * src);
 
 /* ASYNC_START */
-GstMessage *    gst_message_new_async_start     (GstObject * src, gboolean new_base_time);
-void            gst_message_parse_async_start   (GstMessage *message, gboolean *new_base_time);
+GstMessage *    gst_message_new_async_start     (GstObject * src);
 
 /* ASYNC_DONE */
-GstMessage *    gst_message_new_async_done      (GstObject * src);
+GstMessage *    gst_message_new_async_done      (GstObject * src, gboolean reset_time);
+void            gst_message_parse_async_done    (GstMessage *message, gboolean *reset_time);
 
 /* STRUCTURE CHANGE */
 GstMessage *    gst_message_new_structure_change   (GstObject * src, GstStructureChangeType type,
@@ -523,12 +545,6 @@ void            gst_message_parse_progress         (GstMessage * message, GstPro
                                                     gchar ** text);
 
 
-/* custom messages */
-GstMessage *    gst_message_new_custom          (GstMessageType type,
-                                                 GstObject    * src,
-                                                 GstStructure * structure);
-const GstStructure *  gst_message_get_structure (GstMessage *message);
-
 G_END_DECLS
 
 #endif /* __GST_MESSAGE_H__ */
diff --git a/gst/gstmeta.c b/gst/gstmeta.c
new file mode 100644 (file)
index 0000000..ae0f77e
--- /dev/null
@@ -0,0 +1,152 @@
+/* GStreamer
+ * Copyright (C) 2011 Wim Taymans <wim.taymans@gmail.com>
+ *
+ * gstmeta.c: metadata operations
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/**
+ * SECTION:gstmeta
+ * @short_description: Buffer metadata
+ *
+ * Last reviewed on December 17th, 2009 (0.10.26)
+ */
+#include "gst_private.h"
+
+#include "gstbuffer.h"
+#include "gstmeta.h"
+#include "gstinfo.h"
+#include "gstutils.h"
+
+static GHashTable *metainfo = NULL;
+static GStaticRWLock lock = G_STATIC_RW_LOCK_INIT;
+
+void
+_gst_meta_init (void)
+{
+  metainfo = g_hash_table_new (g_str_hash, g_str_equal);
+}
+
+/**
+ * gst_meta_register_info:
+ * @info: a #GstMetaInfo
+ *
+ * Register a #GstMetaInfo. The same @info can be retrieved later with
+ * gst_meta_get_info() by using @impl as the key.
+ *
+ * Returns: a #GstMetaInfo that can be used to access metadata.
+ */
+
+const GstMetaInfo *
+gst_meta_register (const gchar * api, const gchar * impl, gsize size,
+    GstMetaInitFunction init_func, GstMetaFreeFunction free_func,
+    GstMetaCopyFunction copy_func, GstMetaTransformFunction transform_func)
+{
+  GstMetaInfo *info;
+
+  g_return_val_if_fail (api != NULL, NULL);
+  g_return_val_if_fail (impl != NULL, NULL);
+  g_return_val_if_fail (size != 0, NULL);
+
+  info = g_slice_new (GstMetaInfo);
+  info->api = g_quark_from_string (api);
+  info->type = g_pointer_type_register_static (impl);
+  info->size = size;
+  info->init_func = init_func;
+  info->free_func = free_func;
+  info->copy_func = copy_func;
+  info->transform_func = transform_func;
+
+  GST_DEBUG ("register \"%s\" implementing \"%s\" of size %" G_GSIZE_FORMAT,
+      api, impl, size);
+
+  g_static_rw_lock_writer_lock (&lock);
+  g_hash_table_insert (metainfo, (gpointer) impl, (gpointer) info);
+  g_static_rw_lock_writer_unlock (&lock);
+
+  return info;
+}
+
+/**
+ * gst_meta_get_info:
+ * @impl: the name
+ *
+ * Lookup a previously registered meta info structure by its implementor name
+ * @impl.
+ *
+ * Returns: a #GstMetaInfo with @impl or #NULL when no such metainfo
+ * exists.
+ */
+const GstMetaInfo *
+gst_meta_get_info (const gchar * impl)
+{
+  GstMetaInfo *info;
+
+  g_return_val_if_fail (impl != NULL, NULL);
+
+  g_static_rw_lock_reader_lock (&lock);
+  info = g_hash_table_lookup (metainfo, impl);
+  g_static_rw_lock_reader_unlock (&lock);
+
+  return info;
+}
+
+/* Timing metadata */
+static void
+meta_timing_copy (GstBuffer * copybuf, GstMetaTiming * meta,
+    GstBuffer * buffer, gsize offset, gsize size)
+{
+  GstMetaTiming *timing;
+
+  GST_DEBUG ("trans called from buffer %p to %p, meta %p, %u-%u", buffer,
+      copybuf, meta, offset, size);
+
+  timing = gst_buffer_add_meta_timing (copybuf);
+  if (offset == 0) {
+    /* same offset, copy timestamps */
+    timing->pts = meta->pts;
+    timing->dts = meta->dts;
+    if (size == gst_buffer_get_size (buffer)) {
+      /* same size, copy duration */
+      timing->duration = meta->duration;
+    } else {
+      /* else clear */
+      timing->duration = GST_CLOCK_TIME_NONE;
+    }
+  } else {
+    timing->pts = -1;
+    timing->dts = -1;
+    timing->duration = -1;
+  }
+  timing->clock_rate = meta->clock_rate;
+}
+
+const GstMetaInfo *
+gst_meta_timing_get_info (void)
+{
+  static const GstMetaInfo *meta_info = NULL;
+
+  if (meta_info == NULL) {
+    meta_info = gst_meta_register ("GstMetaTiming", "GstMetaTiming",
+        sizeof (GstMetaTiming),
+        (GstMetaInitFunction) NULL,
+        (GstMetaFreeFunction) NULL,
+        (GstMetaCopyFunction) meta_timing_copy,
+        (GstMetaTransformFunction) NULL);
+  }
+  return meta_info;
+}
diff --git a/gst/gstmeta.h b/gst/gstmeta.h
new file mode 100644 (file)
index 0000000..fe5a4aa
--- /dev/null
@@ -0,0 +1,142 @@
+/* GStreamer
+ * Copyright (C) 2009 Wim Taymans <wim.taymans@gmail.be>
+ *
+ * gstmeta.h: Header for Metadata structures
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+
+#ifndef __GST_META_H__
+#define __GST_META_H__
+
+G_BEGIN_DECLS
+
+typedef struct _GstMeta GstMeta;
+typedef struct _GstMetaInfo GstMetaInfo;
+
+/**
+ * GstMeta:
+ * @info: pointer to the #GstMetaInfo
+ *
+ * Base structure for metadata. Custom metadata will put this structure
+ * as the first member of their structure.
+ */
+struct _GstMeta {
+  const GstMetaInfo *info;
+};
+
+/**
+ * GST_META_TRACE_NAME:
+ *
+ * The name used for tracing memory allocations.
+ */
+#define GST_META_TRACE_NAME           "GstMeta"
+
+/**
+ * GstMetaInitFunction:
+ * @meta: a #GstMeta
+ * @buffer: a #GstBuffer
+ *
+ * Function called when @meta is initialized in @buffer.
+ */
+typedef gboolean (*GstMetaInitFunction) (GstMeta *meta, gpointer params, GstBuffer *buffer);
+
+/**
+ * GstMetaFreeFunction:
+ * @meta: a #GstMeta
+ * @buffer: a #GstBuffer
+ *
+ * Function called when @meta is freed in @buffer.
+ */
+typedef void (*GstMetaFreeFunction)     (GstMeta *meta, GstBuffer *buffer);
+
+typedef void (*GstMetaCopyFunction)     (GstBuffer *dest, GstMeta *meta,
+                                         GstBuffer *buffer, gsize offset, gsize size);
+/**
+ * GstMetaTransformFunction:
+ * @transbuf: a #GstBuffer
+ * @meta: a #GstMeta
+ * @buffer: a #GstBuffer
+ * @data: transform specific data.
+ *
+ * Function called for each @meta in @buffer as a result of performing a
+ * transformation on @transbuf. Additional type specific transform data
+ * is passed to the function.
+ *
+ * Implementations should check the type of the transform @data and parse
+ * additional type specific field that should be used to perform the transform.
+ */
+typedef void (*GstMetaTransformFunction) (GstBuffer *transbuf, GstMeta *meta,
+                                          GstBuffer *buffer, gpointer data);
+
+/**
+ * GstMetaInfo:
+ * @api: tag indentifying the metadata structure and api
+ * @type: type indentifying the implementor of the api
+ * @size: size of the metadata
+ * @init_func: function for initializing the metadata
+ * @free_func: function for freeing the metadata
+ * @copy_func: function for copying the metadata
+ * @transform_func: function for transforming the metadata
+ *
+ * The #GstMetaInfo provides information about a specific metadata
+ * structure.
+ */
+struct _GstMetaInfo {
+  GQuark                     api;
+  GType                      type;
+  gsize                      size;
+
+  GstMetaInitFunction        init_func;
+  GstMetaFreeFunction        free_func;
+  GstMetaCopyFunction        copy_func;
+  GstMetaTransformFunction   transform_func;
+};
+
+void _gst_meta_init (void);
+
+const GstMetaInfo *  gst_meta_register        (const gchar *api, const gchar *impl,
+                                               gsize size,
+                                               GstMetaInitFunction        init_func,
+                                               GstMetaFreeFunction        free_func,
+                                               GstMetaCopyFunction        copy_func,
+                                               GstMetaTransformFunction   transform_func);
+const GstMetaInfo *  gst_meta_get_info        (const gchar * impl);
+
+/* default metadata */
+
+/* timing metadata */
+typedef struct _GstMetaTiming GstMetaTiming;
+
+const GstMetaInfo *gst_meta_timing_get_info(void);
+#define GST_META_TIMING_INFO (gst_meta_timing_get_info())
+
+struct _GstMetaTiming {
+  GstMeta        meta;        /* common meta header */
+
+  GstClockTime   dts;         /* decoding timestamp */
+  GstClockTime   pts;         /* presentation timestamp */
+  GstClockTime   duration;    /* duration of the data */
+  GstClockTime   clock_rate;  /* clock rate for the above values */
+};
+
+#define gst_buffer_get_meta_timing(b)  ((GstMetaTiming*)gst_buffer_get_meta((b),GST_META_TIMING_INFO))
+#define gst_buffer_add_meta_timing(b)  ((GstMetaTiming*)gst_buffer_add_meta((b),GST_META_TIMING_INFO,NULL))
+
+G_END_DECLS
+
+#endif /* __GST_META_H__ */
index 3993e02..9e6fd9b 100644 (file)
 #include "gst/gstinfo.h"
 #include <gobject/gvaluecollector.h>
 
+#define GST_DISABLE_TRACE
+
 #ifndef GST_DISABLE_TRACE
 #include "gsttrace.h"
 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);
 
-  /* we delay initialising the mini object's private data until it's actually
-   * needed for now (mini_object->priv automatically inited to NULL) */
-}
+  type = g_boxed_type_register_static (name,
+      (GBoxedCopyFunc) _gst_mini_object_boxed_copy,
+      (GBoxedFreeFunc) _gst_mini_object_boxed_free);
 
-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;
 }
 
 /**
- * gst_mini_object_new:
+ * gst_mini_object_init:
+ * @mini_object: a #GstMiniObject 
  * @type: the #GType of the mini-object to create
+ * @size: the size of the data
  *
- * Creates a new mini-object of the desired type.
+ * Initializes a mini-object with the desired type and size.
  *
  * MT safe
  *
  * 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
@@ -250,13 +126,16 @@ gst_mini_object_new (GType type)
 GstMiniObject *
 gst_mini_object_copy (const GstMiniObject * mini_object)
 {
-  GstMiniObjectClass *mo_class;
+  GstMiniObject *copy;
 
   g_return_val_if_fail (mini_object != NULL, NULL);
 
-  mo_class = GST_MINI_OBJECT_GET_CLASS (mini_object);
+  if (mini_object->copy)
+    copy = mini_object->copy (mini_object);
+  else
+    copy = NULL;
 
-  return mo_class->copy (mini_object);
+  return copy;
 }
 
 /**
@@ -277,8 +156,7 @@ gst_mini_object_is_writable (const GstMiniObject * mini_object)
 {
   g_return_val_if_fail (mini_object != NULL, FALSE);
 
-  return (GST_MINI_OBJECT_REFCOUNT_VALUE (mini_object) == 1) &&
-      ((mini_object->flags & GST_MINI_OBJECT_FLAG_READONLY) == 0);
+  return (GST_MINI_OBJECT_REFCOUNT_VALUE (mini_object) == 1);
 }
 
 /**
@@ -304,9 +182,9 @@ gst_mini_object_make_writable (GstMiniObject * mini_object)
   if (gst_mini_object_is_writable (mini_object)) {
     ret = mini_object;
   } else {
-    GST_CAT_DEBUG (GST_CAT_PERFORMANCE, "copy %s miniobject",
-        g_type_name (G_TYPE_FROM_INSTANCE (mini_object)));
     ret = gst_mini_object_copy (mini_object);
+    GST_CAT_DEBUG (GST_CAT_PERFORMANCE, "copy %s miniobject %p -> %p",
+        g_type_name (GST_MINI_OBJECT_TYPE (mini_object)), mini_object, ret);
     gst_mini_object_unref (mini_object);
   }
 
@@ -337,7 +215,6 @@ gst_mini_object_ref (GstMiniObject * mini_object)
    * the object
    g_return_val_if_fail (mini_object->refcount > 0, NULL);
    */
-  g_return_val_if_fail (GST_IS_MINI_OBJECT (mini_object), NULL);
 
   GST_CAT_TRACE (GST_CAT_REFCOUNTING, "%p ref %d->%d", mini_object,
       GST_MINI_OBJECT_REFCOUNT_VALUE (mini_object),
@@ -349,44 +226,13 @@ gst_mini_object_ref (GstMiniObject * mini_object)
 }
 
 static void
-weak_refs_notify (WeakRefStack * wstack)
+weak_refs_notify (GstMiniObject * obj)
 {
   guint i;
 
-  for (i = 0; i < wstack->n_weak_refs; i++)
-    wstack->weak_refs[i].notify (wstack->weak_refs[i].data, wstack->object);
-  g_free (wstack);
-}
-
-static void
-gst_mini_object_free (GstMiniObject * mini_object)
-{
-  GstMiniObjectClass *mo_class;
-
-  /* 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_MINI_OBJECT_REFCOUNT_VALUE (mini_object),
-      GST_MINI_OBJECT_REFCOUNT_VALUE (mini_object) + 1);
-
-  g_atomic_int_inc (&mini_object->refcount);
-
-  mo_class = GST_MINI_OBJECT_GET_CLASS_UNCHECKED (mini_object);
-  mo_class->finalize (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 != NULL && mini_object->priv->wstack != NULL)
-      weak_refs_notify (mini_object->priv->wstack);
-
-#ifndef GST_DISABLE_TRACE
-    gst_alloc_trace_free (_gst_mini_object_trace, mini_object);
-#endif
-    g_type_free_instance ((GTypeInstance *) 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);
 }
 
 /**
@@ -399,7 +245,7 @@ gst_mini_object_free (GstMiniObject * mini_object)
 void
 gst_mini_object_unref (GstMiniObject * mini_object)
 {
-  g_return_if_fail (GST_IS_MINI_OBJECT (mini_object));
+  g_return_if_fail (mini_object != NULL);
   g_return_if_fail (mini_object->refcount > 0);
 
   GST_CAT_TRACE (GST_CAT_REFCOUNTING, "%p unref %d->%d",
@@ -408,111 +254,28 @@ gst_mini_object_unref (GstMiniObject * mini_object)
       GST_MINI_OBJECT_REFCOUNT_VALUE (mini_object) - 1);
 
   if (G_UNLIKELY (g_atomic_int_dec_and_test (&mini_object->refcount))) {
-    gst_mini_object_free (mini_object);
-  }
-}
-
-/**
- * gst_mini_object_weak_ref: (skip)
- * @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;
-
-  g_return_if_fail (GST_IS_MINI_OBJECT (object));
-  g_return_if_fail (notify != NULL);
-  g_return_if_fail (GST_MINI_OBJECT_REFCOUNT_VALUE (object) >= 1);
+    /* 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);
 
-  G_LOCK (weak_refs_mutex);
+    if (mini_object->dispose)
+      mini_object->dispose (mini_object);
 
-  if (object->priv == NULL) {
-    object->priv = G_TYPE_INSTANCE_GET_PRIVATE (object, GST_TYPE_MINI_OBJECT,
-        GstMiniObjectPrivate);
+    /* 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);
 
-    /* object->priv->wstack will have been inited to NULL automatically */
-  }
-
-  if (object->priv->wstack) {
-    /* Don't add the weak reference if it already exists. */
-    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) {
-        g_warning ("%s: Attempt to re-add existing weak ref %p(%p) failed.",
-            G_STRFUNC, notify, data);
-        goto found;
-      }
+#ifndef GST_DISABLE_TRACE
+      gst_alloc_trace_free (_gst_mini_object_trace, mini_object);
+#endif
+      if (mini_object->free)
+        mini_object->free (mini_object);
     }
-
-    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);
-  } else {
-    object->priv->wstack = g_renew (WeakRefStack, NULL, 1);
-    object->priv->wstack->object = object;
-    object->priv->wstack->n_weak_refs = 1;
-    i = 0;
   }
-  object->priv->wstack->weak_refs[i].notify = notify;
-  object->priv->wstack->weak_refs[i].data = data;
-found:
-  G_UNLOCK (weak_refs_mutex);
-}
-
-/**
- * gst_mini_object_weak_unref: (skip)
- * @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;
-
-  g_return_if_fail (GST_IS_MINI_OBJECT (object));
-  g_return_if_fail (notify != NULL);
-
-  G_LOCK (weak_refs_mutex);
-
-  if (object->priv != NULL && object->priv->wstack != NULL) {
-    guint i;
-
-    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) {
-        found_one = TRUE;
-        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];
-
-        break;
-      }
-  }
-  G_UNLOCK (weak_refs_mutex);
-  if (!found_one)
-    g_warning ("%s: couldn't find weak ref %p(%p)", G_STRFUNC, notify, data);
 }
 
 /**
@@ -521,16 +284,20 @@ gst_mini_object_weak_unref (GstMiniObject * object,
  *     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.
+ * Atomically modifies a pointer to point to a new mini-object.
+ * The reference count of @olddata is decreased and the reference count of
+ * @newdata is increased.
+ *
  * Either @newdata and the value pointed to by @olddata may be NULL.
+ *
+ * Returns: TRUE if @newdata was different from @olddata
  */
-void
+gboolean
 gst_mini_object_replace (GstMiniObject ** olddata, GstMiniObject * newdata)
 {
   GstMiniObject *olddata_val;
 
-  g_return_if_fail (olddata != NULL);
+  g_return_val_if_fail (olddata != NULL, FALSE);
 
   GST_CAT_TRACE (GST_CAT_REFCOUNTING, "replace %p (%d) with %p (%d)",
       *olddata, *olddata ? (*olddata)->refcount : 0,
@@ -538,263 +305,181 @@ gst_mini_object_replace (GstMiniObject ** olddata, GstMiniObject * newdata)
 
   olddata_val = g_atomic_pointer_get ((gpointer *) olddata);
 
-  if (olddata_val == newdata)
-    return;
+  if (G_UNLIKELY (olddata_val == newdata))
+    return FALSE;
 
   if (newdata)
     gst_mini_object_ref (newdata);
 
-  while (!g_atomic_pointer_compare_and_exchange ((gpointer *) olddata,
-          olddata_val, newdata)) {
+  while (G_UNLIKELY (!g_atomic_pointer_compare_and_exchange ((gpointer *)
+              olddata, olddata_val, newdata))) {
     olddata_val = g_atomic_pointer_get ((gpointer *) olddata);
+    if (G_UNLIKELY (olddata_val == newdata))
+      break;
   }
 
   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;
+  return olddata_val != newdata;
 }
 
 /**
- * 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
+ * gst_mini_object_steal:
+ * @olddata: (inout) (transfer full): pointer to a pointer to a mini-object to
+ *     be stolen
  *
- * 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.
+ * Replace the current #GstMiniObject pointer to by @olddata with NULL and
+ * return the old value.
+ *
+ * Returns: the #GstMiniObject at @oldata
  */
-void
-gst_value_take_mini_object (GValue * value, GstMiniObject * mini_object)
+GstMiniObject *
+gst_mini_object_steal (GstMiniObject ** olddata)
 {
-  gpointer *pointer_p;
+  GstMiniObject *olddata_val;
 
-  g_return_if_fail (GST_VALUE_HOLDS_MINI_OBJECT (value));
-  g_return_if_fail (mini_object == NULL || GST_IS_MINI_OBJECT (mini_object));
+  g_return_val_if_fail (olddata != NULL, NULL);
 
-  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_CAT_TRACE (GST_CAT_REFCOUNTING, "steal %p (%d)",
+      *olddata, *olddata ? (*olddata)->refcount : 0);
 
-/**
- * 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);
+  do {
+    olddata_val = g_atomic_pointer_get ((gpointer *) olddata);
+    if (olddata_val == NULL)
+      break;
+  } while (G_UNLIKELY (!g_atomic_pointer_compare_and_exchange ((gpointer *)
+              olddata, olddata_val, NULL)));
 
-  return value->data[0].v_pointer;
+  return olddata_val;
 }
 
 /**
- * gst_value_dup_mini_object:
- * @value:   a valid #GValue of %GST_TYPE_MINI_OBJECT derived type
+ * gst_mini_object_take:
+ * @olddata: (inout) (transfer full): pointer to a pointer to a mini-object to
+ *     be replaced
  *
- * 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.
+ * Modifies a pointer to point to a new mini-object. The modification
+ * is done atomically. This version is similar to gst_mini_object_replace()
+ * except that it does not increase the refcount of @newdata and thus
+ * takes ownership of @newdata.
  *
- * Returns: (transfer full): mini object contents of @value
+ * Either @newdata and the value pointed to by @olddata may be NULL.
  *
- * Since: 0.10.20
+ * Returns: TRUE if @newdata was different from @olddata
  */
-GstMiniObject *
-gst_value_dup_mini_object (const GValue * value)
+gboolean
+gst_mini_object_take (GstMiniObject ** olddata, GstMiniObject * newdata)
 {
-  g_return_val_if_fail (GST_VALUE_HOLDS_MINI_OBJECT (value), NULL);
+  GstMiniObject *olddata_val;
 
-  return value->data[0].v_pointer ? gst_mini_object_ref (value->
-      data[0].v_pointer) : NULL;
-}
+  g_return_val_if_fail (olddata != NULL, FALSE);
 
+  GST_CAT_TRACE (GST_CAT_REFCOUNTING, "take %p (%d) with %p (%d)",
+      *olddata, *olddata ? (*olddata)->refcount : 0,
+      newdata, newdata ? newdata->refcount : 0);
 
-/* param spec */
+  do {
+    olddata_val = g_atomic_pointer_get ((gpointer *) olddata);
+    if (G_UNLIKELY (olddata_val == newdata))
+      break;
+  } while (G_UNLIKELY (!g_atomic_pointer_compare_and_exchange ((gpointer *)
+              olddata, olddata_val, newdata)));
 
-static void
-param_mini_object_init (GParamSpec * pspec)
-{
-  /* GParamSpecMiniObject *ospec = G_PARAM_SPEC_MINI_OBJECT (pspec); */
-}
+  if (olddata_val)
+    gst_mini_object_unref (olddata_val);
 
-static void
-param_mini_object_set_default (GParamSpec * pspec, GValue * value)
-{
-  value->data[0].v_pointer = NULL;
+  return olddata_val != newdata;
 }
 
-static gboolean
-param_mini_object_validate (GParamSpec * pspec, GValue * value)
+/**
+ * gst_mini_object_weak_ref: (skip)
+ * @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)
 {
-  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;
-}
+  guint i;
 
-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;
+  g_return_if_fail (object != NULL);
+  g_return_if_fail (notify != NULL);
+  g_return_if_fail (GST_MINI_OBJECT_REFCOUNT_VALUE (object) >= 1);
 
-  /* not much to compare here, try to at least provide stable lesser/greater result */
+  G_LOCK (weak_refs_mutex);
 
-  return p1 < p2 ? -1 : p1 > p2;
-}
+  if (object->n_weak_refs) {
+    /* Don't add the weak reference if it already exists. */
+    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;
+      }
+    }
 
-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);
+    i = object->n_weak_refs++;
+    object->weak_refs =
+        g_realloc (object->weak_refs, sizeof (object->weak_refs[0]) * i);
+  } else {
+    object->weak_refs = g_malloc0 (sizeof (object->weak_refs[0]));
+    object->n_weak_refs = 1;
+    i = 0;
   }
-
-  return type;
+  object->weak_refs[i].notify = notify;
+  object->weak_refs[i].data = data;
+found:
+  G_UNLOCK (weak_refs_mutex);
 }
 
 /**
- * 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
+ * gst_mini_object_weak_unref: (skip)
+ * @object: #GstMiniObject to remove a weak reference from
+ * @notify: callback to search for
+ * @data: data to search for
  *
- * Creates a new #GParamSpec instance that hold #GstMiniObject references.
+ * Removes a weak reference callback to a mini object.
  *
- * Returns: (transfer full): a newly allocated #GParamSpec instance
+ * Since: 0.10.35
  */
-GParamSpec *
-gst_param_spec_mini_object (const char *name, const char *nick,
-    const char *blurb, GType object_type, GParamFlags flags)
+void
+gst_mini_object_weak_unref (GstMiniObject * object,
+    GstMiniObjectWeakNotify notify, gpointer data)
 {
-  GstParamSpecMiniObject *ospec;
+  gboolean found_one = FALSE;
 
-  g_return_val_if_fail (g_type_is_a (object_type, GST_TYPE_MINI_OBJECT), NULL);
+  g_return_if_fail (object != NULL);
+  g_return_if_fail (notify != NULL);
+
+  G_LOCK (weak_refs_mutex);
 
-  ospec = g_param_spec_internal (GST_TYPE_PARAM_MINI_OBJECT,
-      name, nick, blurb, flags);
-  G_PARAM_SPEC (ospec)->value_type = object_type;
+  if (object->n_weak_refs) {
+    guint i;
 
-  return G_PARAM_SPEC (ospec);
+    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;
+        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);
 }
index 024d1e2..22c307f 100644 (file)
 
 G_BEGIN_DECLS
 
-#define GST_TYPE_MINI_OBJECT          (gst_mini_object_get_type())
-#define GST_IS_MINI_OBJECT(obj)       (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_MINI_OBJECT))
-#define GST_IS_MINI_OBJECT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_MINI_OBJECT))
-#define GST_MINI_OBJECT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_MINI_OBJECT, GstMiniObjectClass))
-#define GST_MINI_OBJECT(obj)          (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_MINI_OBJECT, GstMiniObject))
-#define GST_MINI_OBJECT_CLASS(klass)  (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_MINI_OBJECT, GstMiniObjectClass))
-#define GST_MINI_OBJECT_CAST(obj)     ((GstMiniObject*)(obj))
-#define GST_MINI_OBJECT_CONST_CAST(obj) ((const GstMiniObject*)(obj))
+#define GST_IS_MINI_OBJECT_TYPE(obj,type)  ((obj) && GST_MINI_OBJECT_TYPE(obj) == (type))
+#define GST_MINI_OBJECT_CAST(obj)          ((GstMiniObject*)(obj))
+#define GST_MINI_OBJECT_CONST_CAST(obj)    ((const GstMiniObject*)(obj))
+#define GST_MINI_OBJECT(obj)               (GST_MINI_OBJECT_CAST(obj))
 
 typedef struct _GstMiniObject GstMiniObject;
-typedef struct _GstMiniObjectClass GstMiniObjectClass;
 
 /**
  * GstMiniObjectCopyFunction:
  * @obj: MiniObject to copy
  *
- * Virtual function prototype for methods to create copies of instances.
+ * Function prototype for methods to create copies of instances.
  *
  * Returns: reference to cloned instance.
  */
 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.
@@ -95,27 +121,13 @@ typedef void (*GstMiniObjectFinalizeFunction) (GstMiniObject *obj);
 #define GST_MINI_OBJECT_FLAG_UNSET(obj,flag)         (GST_MINI_OBJECT_FLAGS (obj) &= ~(flag))
 
 /**
- * GST_VALUE_HOLDS_MINI_OBJECT:
- * @value: the #GValue to check
- *
- * Checks if the given #GValue contains a #GST_TYPE_MINI_OBJECT value.
- */
-#define GST_VALUE_HOLDS_MINI_OBJECT(value)  (G_VALUE_HOLDS(value, GST_TYPE_MINI_OBJECT))
-
-/**
  * GstMiniObjectFlags:
- * @GST_MINI_OBJECT_FLAG_READONLY: is the miniobject readonly or writable
- * @GST_MINI_OBJECT_FLAG_RESERVED1: a flag reserved for internal use e.g. as
- *     GST_BUFFER_FLAG_MEDIA4. Since: 0.10.33.
  * @GST_MINI_OBJECT_FLAG_LAST: first flag that can be used by subclasses.
  *
  * Flags for the mini object
  */
-
 typedef enum
 {
-  GST_MINI_OBJECT_FLAG_READONLY = (1<<0),
-  GST_MINI_OBJECT_FLAG_RESERVED1 = (1<<1),
   /* padding */
   GST_MINI_OBJECT_FLAG_LAST = (1<<4)
 } GstMiniObjectFlags;
@@ -136,110 +148,72 @@ typedef enum
 #define GST_MINI_OBJECT_REFCOUNT_VALUE(obj)     (g_atomic_int_get (&(GST_MINI_OBJECT_CAST(obj))->refcount))
 
 /**
- * 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
+ * GST_MINI_OBJECT_SIZE:
+ * @obj: a #GstMiniObject
  *
+ * Get the allocated size of @obj.
  */
-typedef void (*GstMiniObjectWeakNotify) (gpointer data,
-    GstMiniObject * where_the_mini_object_was);
-
-typedef struct _GstMiniObjectPrivate GstMiniObjectPrivate;
+#define GST_MINI_OBJECT_SIZE(obj)              ((GST_MINI_OBJECT_CAST(obj))->size)
 
 /**
  * GstMiniObject:
- * @instance: type instance
  * @refcount: atomic refcount
  * @flags: extra flags.
- * 
+ * @copy: a copy function
+ * @dispose: a dispose function
+ * @free: the free function
+ *
  * 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);
+gboolean        gst_mini_object_replace         (GstMiniObject **olddata, GstMiniObject *newdata);
+gboolean        gst_mini_object_take            (GstMiniObject **olddata, GstMiniObject *newdata);
+GstMiniObject * gst_mini_object_steal           (GstMiniObject **olddata);
 
 
 G_END_DECLS
index f06d798..9b3c29e 100644 (file)
@@ -98,24 +98,18 @@ static GstAllocTrace *_gst_object_trace;
 #define DEBUG_REFCOUNT
 
 /* Object signals and args */
-/* FIXME-0.11: have a read-only parent property instead of the two signals
- * then we get notify::parent for free */
 enum
 {
-  PARENT_SET,
-  PARENT_UNSET,
-#if !defined(GST_DISABLE_LOADSAVE) && !defined(GST_REMOVE_DEPRECATED)
-  OBJECT_SAVED,
-#endif
   DEEP_NOTIFY,
   LAST_SIGNAL
 };
 
 enum
 {
-  ARG_0,
-  ARG_NAME
-      /* FILL ME */
+  PROP_0,
+  PROP_NAME,
+  PROP_PARENT,
+  PROP_LAST
 };
 
 enum
@@ -129,19 +123,11 @@ static GData *object_name_counts = NULL;
 
 G_LOCK_DEFINE_STATIC (object_name_mutex);
 
-typedef struct _GstSignalObject GstSignalObject;
-typedef struct _GstSignalObjectClass GstSignalObjectClass;
-
-static GType gst_signal_object_get_type (void);
-
-#if !defined(GST_DISABLE_LOADSAVE) && !defined(GST_REMOVE_DEPRECATED)
-static guint gst_signal_object_signals[SO_LAST_SIGNAL] = { 0 };
-#endif
-
 static void gst_object_set_property (GObject * object, guint prop_id,
     const GValue * value, GParamSpec * pspec);
 static void gst_object_get_property (GObject * object, guint prop_id,
     GValue * value, GParamSpec * pspec);
+
 static void gst_object_dispatch_properties_changed (GObject * object,
     guint n_pspecs, GParamSpec ** pspecs);
 
@@ -150,36 +136,17 @@ static void gst_object_finalize (GObject * object);
 
 static gboolean gst_object_set_name_default (GstObject * object);
 
-#ifdef GST_DISABLE_DEPRECATED
-#if !defined(GST_DISABLE_LOADSAVE) && !defined(GST_REMOVE_DEPRECATED)
-#undef GstXmlNodePtr
-#define GstXmlNodePtr xmlNodePtr
-#include <libxml/parser.h>
-GstXmlNodePtr gst_object_save_thyself (GstObject * object,
-    GstXmlNodePtr parent);
-void gst_object_restore_thyself (GstObject * object, GstXmlNodePtr parent);
-void gst_class_signal_emit_by_name (GstObject * object, const gchar * name,
-    GstXmlNodePtr self);
-#endif
-#endif
-
-#if !defined(GST_DISABLE_LOADSAVE) && !defined(GST_REMOVE_DEPRECATED)
-static void gst_object_real_restore_thyself (GstObject * object,
-    GstXmlNodePtr self);
-#endif
-
-static GObjectClass *parent_class = NULL;
 static guint gst_object_signals[LAST_SIGNAL] = { 0 };
 
-G_DEFINE_ABSTRACT_TYPE (GstObject, gst_object, G_TYPE_OBJECT);
+static GParamSpec *properties[PROP_LAST];
+
+G_DEFINE_ABSTRACT_TYPE (GstObject, gst_object, G_TYPE_INITIALLY_UNOWNED);
 
 static void
 gst_object_class_init (GstObjectClass * klass)
 {
   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
 
-  parent_class = g_type_class_peek_parent (klass);
-
 #ifndef GST_DISABLE_TRACE
   _gst_object_trace = gst_alloc_trace_register (g_type_name (GST_TYPE_OBJECT));
 #endif
@@ -187,56 +154,17 @@ gst_object_class_init (GstObjectClass * klass)
   gobject_class->set_property = gst_object_set_property;
   gobject_class->get_property = gst_object_get_property;
 
-  g_object_class_install_property (gobject_class, ARG_NAME,
-      g_param_spec_string ("name", "Name", "The name of the object",
-          NULL,
-          G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS));
-
-  /**
-   * GstObject::parent-set:
-   * @gstobject: a #GstObject
-   * @parent: the new parent
-   *
-   * Emitted when the parent of an object is set.
-   */
-  gst_object_signals[PARENT_SET] =
-      g_signal_new ("parent-set", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
-      G_STRUCT_OFFSET (GstObjectClass, parent_set), NULL, NULL,
-      g_cclosure_marshal_VOID__OBJECT, G_TYPE_NONE, 1, GST_TYPE_OBJECT);
-
-  /**
-   * GstObject::parent-unset:
-   * @gstobject: a #GstObject
-   * @parent: the old parent
-   *
-   * Emitted when the parent of an object is unset.
-   */
-  gst_object_signals[PARENT_UNSET] =
-      g_signal_new ("parent-unset", G_TYPE_FROM_CLASS (klass),
-      G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstObjectClass, parent_unset), NULL,
-      NULL, g_cclosure_marshal_VOID__OBJECT, G_TYPE_NONE, 1, GST_TYPE_OBJECT);
+  properties[PROP_NAME] =
+      g_param_spec_string ("name", "Name", "The name of the object", NULL,
+      G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS);
+  g_object_class_install_property (gobject_class, PROP_NAME,
+      properties[PROP_NAME]);
 
-#if !defined(GST_DISABLE_LOADSAVE) && !defined(GST_REMOVE_DEPRECATED)
-  /**
-   * GstObject::object-saved:
-   * @gstobject: a #GstObject
-   * @xml_node: the xmlNodePtr of the parent node
-   *
-   * Trigered whenever a new object is saved to XML. You can connect to this
-   * signal to insert custom XML tags into the core XML.
-   */
-  /* FIXME This should be the GType of xmlNodePtr instead of G_TYPE_POINTER
-   *       (if libxml would use GObject)
-   */
-  gst_object_signals[OBJECT_SAVED] =
-      g_signal_new ("object-saved", G_TYPE_FROM_CLASS (klass),
-      G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstObjectClass, object_saved), NULL,
-      NULL, g_cclosure_marshal_VOID__POINTER, G_TYPE_NONE, 1, G_TYPE_POINTER);
-
-  klass->restore_thyself =
-      ((void (*)(GstObject * object,
-              gpointer self)) *gst_object_real_restore_thyself);
-#endif
+  properties[PROP_PARENT] =
+      g_param_spec_object ("parent", "Parent", "The parent of the object",
+      GST_TYPE_OBJECT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
+  g_object_class_install_property (gobject_class, PROP_PARENT,
+      properties[PROP_PARENT]);
 
   /**
    * GstObject::deep-notify:
@@ -256,11 +184,6 @@ gst_object_class_init (GstObjectClass * klass)
       G_TYPE_PARAM);
 
   klass->path_string_separator = "/";
-  /* FIXME 0.11: Store this directly in the class struct */
-  klass->lock = g_slice_new (GStaticRecMutex);
-  g_static_rec_mutex_init (klass->lock);
-
-  klass->signal_object = g_object_newv (gst_signal_object_get_type (), 0, NULL);
 
   /* see the comments at gst_object_dispatch_properties_changed */
   gobject_class->dispatch_properties_changed
@@ -283,7 +206,6 @@ gst_object_init (GstObject * object)
 #endif
 
   object->flags = 0;
-  GST_OBJECT_FLAG_SET (object, GST_OBJECT_FLOATING);
 }
 
 /**
@@ -350,61 +272,18 @@ gst_object_unref (gpointer object)
  * the floating flag while leaving the reference count unchanged. If the object
  * is not floating, then this call adds a new normal reference increasing the
  * reference count by one.
- *
- * MT safe. This function grabs and releases @object lock.
- *
- * Since: 0.10.24
  */
-void
+gpointer
 gst_object_ref_sink (gpointer object)
 {
-  g_return_if_fail (GST_IS_OBJECT (object));
-
-  GST_OBJECT_LOCK (object);
-  if (G_LIKELY (GST_OBJECT_IS_FLOATING (object))) {
-    GST_CAT_TRACE_OBJECT (GST_CAT_REFCOUNTING, object,
-        "unsetting floating flag");
-    GST_OBJECT_FLAG_UNSET (object, GST_OBJECT_FLOATING);
-    GST_OBJECT_UNLOCK (object);
-  } else {
-    GST_OBJECT_UNLOCK (object);
-    gst_object_ref (object);
-  }
-}
-
-/**
- * gst_object_sink:
- * @object: a #GstObject to sink
- *
- * If @object was floating, the #GST_OBJECT_FLOATING flag is removed
- * and @object is unreffed. When @object was not floating,
- * this function does nothing.
- *
- * Any newly created object has a refcount of 1 and is floating.
- * This function should be used when creating a new object to
- * symbolically 'take ownership' of @object. This done by first doing a
- * gst_object_ref() to keep a reference to @object and then gst_object_sink()
- * to remove and unref any floating references to @object.
- * Use gst_object_set_parent() to have this done for you.
- *
- * MT safe. This function grabs and releases @object lock.
- */
-void
-gst_object_sink (gpointer object)
-{
-  g_return_if_fail (GST_IS_OBJECT (object));
-
-  GST_CAT_TRACE_OBJECT (GST_CAT_REFCOUNTING, object, "sink");
+  g_return_val_if_fail (object != NULL, NULL);
 
-  GST_OBJECT_LOCK (object);
-  if (G_LIKELY (GST_OBJECT_IS_FLOATING (object))) {
-    GST_CAT_TRACE_OBJECT (GST_CAT_REFCOUNTING, object, "clear floating flag");
-    GST_OBJECT_FLAG_UNSET (object, GST_OBJECT_FLOATING);
-    GST_OBJECT_UNLOCK (object);
-    gst_object_unref (object);
-  } else {
-    GST_OBJECT_UNLOCK (object);
-  }
+#ifdef DEBUG_REFCOUNT
+  GST_CAT_TRACE_OBJECT (GST_CAT_REFCOUNTING, object, "%p ref_sink %d->%d",
+      object, ((GObject *) object)->ref_count,
+      ((GObject *) object)->ref_count + 1);
+#endif
+  return g_object_ref_sink (object);
 }
 
 /**
@@ -462,7 +341,7 @@ gst_object_dispose (GObject * object)
   GST_OBJECT_PARENT (object) = NULL;
   GST_OBJECT_UNLOCK (object);
 
-  parent_class->dispose (object);
+  ((GObjectClass *) gst_object_parent_class)->dispose (object);
 
   return;
 
@@ -497,7 +376,7 @@ gst_object_finalize (GObject * object)
   gst_alloc_trace_free (_gst_object_trace, object);
 #endif
 
-  parent_class->finalize (object);
+  ((GObjectClass *) gst_object_parent_class)->finalize (object);
 }
 
 /* Changing a GObject property of a GstObject will result in "deep-notify"
@@ -506,9 +385,6 @@ gst_object_finalize (GObject * object)
  * top-level bin to catch property-change notifications for all contained
  * elements.
  *
- * This function is not MT safe in glib < 2.8 so we need to lock it with a
- * classwide mutex in that case.
- *
  * MT safe.
  */
 static void
@@ -523,7 +399,9 @@ gst_object_dispatch_properties_changed (GObject * object,
 #endif
 
   /* do the standard dispatching */
-  parent_class->dispatch_properties_changed (object, n_pspecs, pspecs);
+  ((GObjectClass *)
+      gst_object_parent_class)->dispatch_properties_changed (object, n_pspecs,
+      pspecs);
 
   gst_object = GST_OBJECT_CAST (object);
 #ifndef GST_DISABLE_GST_DEBUG
@@ -749,80 +627,12 @@ gst_object_get_name (GstObject * object)
 }
 
 /**
- * gst_object_set_name_prefix:
- * @object:      a #GstObject
- * @name_prefix: new name prefix of @object
- *
- * Sets the name prefix of @object to @name_prefix.
- * This function makes a copy of the provided name prefix, so the caller
- * retains ownership of the name prefix it sent.
- *
- * MT safe.  This function grabs and releases @object's LOCK.
- *
- * Deprecated: deprecated because the name prefix has never actually been used
- *     for anything.
- */
-#ifndef GST_REMOVE_DEPRECATED
-#ifdef GST_DISABLE_DEPRECATED
-void gst_object_set_name_prefix (GstObject * object, const gchar * name_prefix);
-#endif
-void
-gst_object_set_name_prefix (GstObject * object, const gchar * name_prefix)
-{
-  g_return_if_fail (GST_IS_OBJECT (object));
-
-  GST_OBJECT_LOCK (object);
-  g_free (object->name_prefix);
-  object->name_prefix = g_strdup (name_prefix); /* NULL gives NULL */
-  GST_OBJECT_UNLOCK (object);
-}
-#endif /* GST_REMOVE_DEPRECATED */
-
-/**
- * gst_object_get_name_prefix:
- * @object: a #GstObject
- *
- * Returns a copy of the name prefix of @object.
- * Caller should g_free() the return value after usage.
- * For a prefixless object, this returns NULL, which you can safely g_free()
- * as well.
- *
- * Returns: the name prefix of @object. g_free() after usage.
- *
- * MT safe. This function grabs and releases @object's LOCK.
- *
- * Deprecated: deprecated because the name prefix has never actually been used
- *     for anything.
- */
-#ifndef GST_REMOVE_DEPRECATED
-#ifdef GST_DISABLE_DEPRECATED
-gchar *gst_object_get_name_prefix (GstObject * object);
-#endif
-gchar *
-gst_object_get_name_prefix (GstObject * object)
-{
-  gchar *result = NULL;
-
-  g_return_val_if_fail (GST_IS_OBJECT (object), NULL);
-
-  GST_OBJECT_LOCK (object);
-  result = g_strdup (object->name_prefix);
-  GST_OBJECT_UNLOCK (object);
-
-  return result;
-}
-#endif /* GST_REMOVE_DEPRECATED */
-
-/**
  * gst_object_set_parent:
  * @object: a #GstObject
  * @parent: new parent of object
  *
  * Sets the parent of @object to @parent. The object's reference count will
- * be incremented, and any floating reference will be removed (see gst_object_sink()).
- *
- * This function causes the parent-set signal to be emitted when the parent
- * was successfully set.
+ * be incremented, and any floating reference will be removed (see gst_object_ref_sink()).
  *
  * Returns: TRUE if @parent could be set or FALSE when @object
  * already had a parent or @object and @parent are the same.
@@ -843,21 +653,14 @@ gst_object_set_parent (GstObject * object, GstObject * parent)
   if (G_UNLIKELY (object->parent != NULL))
     goto had_parent;
 
-  /* sink object, we don't call our own function because we don't
-   * need to release/acquire the lock needlessly or touch the refcount
-   * in the floating case. */
   object->parent = parent;
-  if (G_LIKELY (GST_OBJECT_IS_FLOATING (object))) {
-    GST_CAT_TRACE_OBJECT (GST_CAT_REFCOUNTING, object,
-        "unsetting floating flag");
-    GST_OBJECT_FLAG_UNSET (object, GST_OBJECT_FLOATING);
-    GST_OBJECT_UNLOCK (object);
-  } else {
-    GST_OBJECT_UNLOCK (object);
-    gst_object_ref (object);
-  }
+  g_object_ref_sink (object);
+  GST_OBJECT_UNLOCK (object);
 
-  g_signal_emit (object, gst_object_signals[PARENT_SET], 0, parent);
+  /* FIXME, this does not work, the deep notify takes the lock from the parent
+   * object and deadlocks when the parent holds its lock when calling this
+   * function (like _element_add_pad()) */
+  /* g_object_notify_by_pspec ((GObject *)object, properties[PROP_PARENT]); */
 
   return TRUE;
 
@@ -923,7 +726,7 @@ gst_object_unparent (GstObject * object)
     object->parent = NULL;
     GST_OBJECT_UNLOCK (object);
 
-    g_signal_emit (object, gst_object_signals[PARENT_UNSET], 0, parent);
+    /* g_object_notify_by_pspec ((GObject *)object, properties[PROP_PARENT]); */
 
     gst_object_unref (object);
   } else {
@@ -1009,65 +812,6 @@ gst_object_check_uniqueness (GList * list, const gchar * name)
 }
 
 
-#if !defined(GST_DISABLE_LOADSAVE) && !defined(GST_REMOVE_DEPRECATED)
-/**
- * gst_object_save_thyself:
- * @object: a #GstObject to save
- * @parent: The parent XML node to save @object into
- *
- * Saves @object into the parent XML node.
- *
- * Returns: the new xmlNodePtr with the saved object
- */
-GstXmlNodePtr
-gst_object_save_thyself (GstObject * object, GstXmlNodePtr parent)
-{
-  GstObjectClass *oclass;
-
-  g_return_val_if_fail (GST_IS_OBJECT (object), parent);
-  g_return_val_if_fail (parent != NULL, parent);
-
-  oclass = GST_OBJECT_GET_CLASS (object);
-
-  if (oclass->save_thyself)
-    oclass->save_thyself (object, parent);
-
-  g_signal_emit (object, gst_object_signals[OBJECT_SAVED], 0, parent);
-
-  return parent;
-}
-
-/**
- * gst_object_restore_thyself:
- * @object: a #GstObject to load into
- * @self: The XML node to load @object from
- *
- * Restores @object with the data from the parent XML node.
- */
-void
-gst_object_restore_thyself (GstObject * object, GstXmlNodePtr self)
-{
-  GstObjectClass *oclass;
-
-  g_return_if_fail (GST_IS_OBJECT (object));
-  g_return_if_fail (self != NULL);
-
-  oclass = GST_OBJECT_GET_CLASS (object);
-
-  if (oclass->restore_thyself)
-    oclass->restore_thyself (object, self);
-}
-
-static void
-gst_object_real_restore_thyself (GstObject * object, GstXmlNodePtr self)
-{
-  g_return_if_fail (GST_IS_OBJECT (object));
-  g_return_if_fail (self != NULL);
-
-  gst_class_signal_emit_by_name (object, "object_loaded", self);
-}
-#endif /* GST_DISABLE_LOADSAVE */
-
 static void
 gst_object_set_property (GObject * object, guint prop_id,
     const GValue * value, GParamSpec * pspec)
@@ -1077,9 +821,12 @@ gst_object_set_property (GObject * object, guint prop_id,
   gstobject = GST_OBJECT_CAST (object);
 
   switch (prop_id) {
-    case ARG_NAME:
+    case PROP_NAME:
       gst_object_set_name (gstobject, g_value_get_string (value));
       break;
+    case PROP_PARENT:
+      gst_object_set_parent (gstobject, g_value_get_object (value));
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -1095,9 +842,12 @@ gst_object_get_property (GObject * object, guint prop_id,
   gstobject = GST_OBJECT_CAST (object);
 
   switch (prop_id) {
-    case ARG_NAME:
+    case PROP_NAME:
       g_value_take_string (value, gst_object_get_name (gstobject));
       break;
+    case PROP_PARENT:
+      g_value_take_object (value, gst_object_get_parent (gstobject));
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -1189,84 +939,3 @@ gst_object_get_path_string (GstObject * object)
 
   return path;
 }
-
-
-struct _GstSignalObject
-{
-  GObject object;
-};
-
-struct _GstSignalObjectClass
-{
-  GObjectClass parent_class;
-
-  /* signals */
-#if !defined(GST_DISABLE_LOADSAVE) && !defined(GST_REMOVE_DEPRECATED)
-  void (*object_loaded) (GstSignalObject * object, GstObject * new,
-      GstXmlNodePtr self);
-#endif
-};
-
-G_DEFINE_TYPE (GstSignalObject, gst_signal_object, G_TYPE_OBJECT);
-
-static void
-gst_signal_object_class_init (GstSignalObjectClass * klass)
-{
-  parent_class = g_type_class_peek_parent (klass);
-
-#if !defined(GST_DISABLE_LOADSAVE) && !defined(GST_REMOVE_DEPRECATED)
-  gst_signal_object_signals[SO_OBJECT_LOADED] =
-      g_signal_new ("object-loaded", G_TYPE_FROM_CLASS (klass),
-      G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstSignalObjectClass, object_loaded),
-      NULL, NULL, gst_marshal_VOID__OBJECT_POINTER, G_TYPE_NONE, 2,
-      G_TYPE_OBJECT, G_TYPE_POINTER);
-#endif
-}
-
-static void
-gst_signal_object_init (GstSignalObject * object)
-{
-}
-
-/**
- * gst_class_signal_connect
- * @klass: a #GstObjectClass to attach the signal to
- * @name: the name of the signal to attach to
- * @func: the signal function
- * @func_data: a pointer to user data
- *
- * Connect to a class signal.
- *
- * Returns: the signal id.
- */
-guint
-gst_class_signal_connect (GstObjectClass * klass,
-    const gchar * name, gpointer func, gpointer func_data)
-{
-  /* [0.11] func parameter needs to be changed to a GCallback *
-   * doing so now would be an API break. */
-  return g_signal_connect (klass->signal_object, name, G_CALLBACK (func),
-      func_data);
-}
-
-#if !defined(GST_DISABLE_LOADSAVE) && !defined(GST_REMOVE_DEPRECATED)
-/**
- * gst_class_signal_emit_by_name:
- * @object: a #GstObject that emits the signal
- * @name: the name of the signal to emit
- * @self: data for the signal
- *
- * emits the named class signal.
- */
-void
-gst_class_signal_emit_by_name (GstObject * object,
-    const gchar * name, GstXmlNodePtr self)
-{
-  GstObjectClass *oclass;
-
-  oclass = GST_OBJECT_GET_CLASS (object);
-
-  g_signal_emit_by_name (oclass->signal_object, name, object, self);
-}
-
-#endif /* GST_DISABLE_LOADSAVE */
index b9c5206..7fa9ee2 100644 (file)
@@ -39,27 +39,14 @@ G_BEGIN_DECLS
 #define GST_OBJECT_CAST(obj)            ((GstObject*)(obj))
 #define GST_OBJECT_CLASS_CAST(klass)    ((GstObjectClass*)(klass))
 
-/* make sure we don't change the object size but still make it compile
- * without libxml */
-#if defined(GST_DISABLE_LOADSAVE) || defined(GST_DISABLE_DEPRECATED)
-#define GstXmlNodePtr  gpointer
-#else
-#define GstXmlNodePtr  xmlNodePtr
-#endif
-
 /**
  * GstObjectFlags:
- * @GST_OBJECT_DISPOSING: the object is been destroyed, don't use it anymore
- * @GST_OBJECT_FLOATING:  the object has a floating reference count (e.g. its
- *  not assigned to a bin)
  * @GST_OBJECT_FLAG_LAST: subclasses can add additional flags starting from this flag
  *
  * The standard flags that an gstobject may have.
  */
 typedef enum
 {
-  GST_OBJECT_DISPOSING = (1<<0),
-  GST_OBJECT_FLOATING = (1<<1),
   /* padding */
   GST_OBJECT_FLAG_LAST = (1<<4)
 } GstObjectFlags;
@@ -163,45 +150,24 @@ typedef enum
 #define GST_OBJECT_FLAG_UNSET(obj,flag)        (GST_OBJECT_FLAGS (obj) &= ~(flag))
 
 
-/**
- * GST_OBJECT_IS_DISPOSING:
- * @obj: a #GstObject
- *
- * Check if the given object is beeing destroyed.
- */
-#define GST_OBJECT_IS_DISPOSING(obj)    (GST_OBJECT_FLAG_IS_SET (obj, GST_OBJECT_DISPOSING))
-/**
- * GST_OBJECT_IS_FLOATING:
- * @obj: a #GstObject
- *
- * Check if the given object is floating (has no owner).
- */
-#define GST_OBJECT_IS_FLOATING(obj)     (GST_OBJECT_FLAG_IS_SET (obj, GST_OBJECT_FLOATING))
-
 typedef struct _GstObject GstObject;
 typedef struct _GstObjectClass GstObjectClass;
 
 /**
  * GstObject:
- * @refcount: unused
  * @lock: object LOCK
  * @name: The name of the object
- * @name_prefix: unused
  * @parent: this object's parent, weak ref
- * @flags: use GST_OBJECT_IS_XXX macros to access the flags
+ * @flags: flags for this object
  *
  * GStreamer base object class.
  */
 struct _GstObject {
-  GObject       object;
-
-  /*< public >*/
-  gint           refcount;    /* unused (FIXME 0.11: remove) */
+  GInitiallyUnowned object;
 
   /*< public >*/ /* with LOCK */
   GMutex        *lock;        /* object LOCK */
   gchar         *name;        /* object name */
-  gchar         *name_prefix; /* (un)used for debugging (FIXME 0.11: remove) */
   GstObject     *parent;      /* this object's parent, weak ref */
   guint32        flags;
 
@@ -210,72 +176,23 @@ struct _GstObject {
 };
 
 /**
- * GST_CLASS_GET_LOCK:
- * @obj: a #GstObjectClass
- *
- * This macro will return the class lock used to protect deep_notify signal
- * emission on thread-unsafe glib versions (glib < 2.8).
- */
-#define GST_CLASS_GET_LOCK(obj)         (GST_OBJECT_CLASS_CAST(obj)->lock)
-/**
- * GST_CLASS_LOCK:
- * @obj: a #GstObjectClass
- *
- * Lock the class.
- */
-#define GST_CLASS_LOCK(obj)             (g_static_rec_mutex_lock(GST_CLASS_GET_LOCK(obj)))
-/**
- * GST_CLASS_TRYLOCK:
- * @obj: a #GstObjectClass
- *
- * Try to lock the class, returns TRUE if class could be locked.
- */
-#define GST_CLASS_TRYLOCK(obj)          (g_static_rec_mutex_trylock(GST_CLASS_GET_LOCK(obj)))
-/**
- * GST_CLASS_UNLOCK:
- * @obj: a #GstObjectClass
- *
- * Unlock the class.
- */
-#define GST_CLASS_UNLOCK(obj)           (g_static_rec_mutex_unlock(GST_CLASS_GET_LOCK(obj)))
-
-/**
  * GstObjectClass:
  * @parent_class: parent
  * @path_string_separator: separator used by gst_object_get_path_string()
- * @signal_object: is used to signal to the whole class
- * @lock: class lock to be used with GST_CLASS_GET_LOCK(), GST_CLASS_LOCK(), GST_CLASS_UNLOCK() and others.
- * @parent_set: default signal handler
- * @parent_unset: default signal handler
- * @object_saved: default signal handler
  * @deep_notify: default signal handler
- * @save_thyself: xml serialisation
- * @restore_thyself: xml de-serialisation
  *
  * GStreamer base object class.
  */
 struct _GstObjectClass {
-  GObjectClass parent_class;
+  GInitiallyUnownedClass parent_class;
 
   const gchar  *path_string_separator;
-  GObject      *signal_object;
-
-  /* FIXME-0.11: remove this, plus the above GST_CLASS_*_LOCK macros */
-  GStaticRecMutex *lock;
 
   /* signals */
-  /* FIXME-0.11: remove, and pass NULL in g_signal_new(), we never used them */
-  void          (*parent_set)       (GstObject * object, GstObject * parent);
-  void          (*parent_unset)     (GstObject * object, GstObject * parent);
-  /* FIXME 0.11: Remove this, it's deprecated */
-  void          (*object_saved)     (GstObject * object, GstXmlNodePtr parent);
   void          (*deep_notify)      (GstObject * object, GstObject * orig, GParamSpec * pspec);
 
   /*< public >*/
   /* virtual methods for subclasses */
-  /* FIXME 0.11: Remove this, it's deprecated */
-  GstXmlNodePtr (*save_thyself)     (GstObject * object, GstXmlNodePtr parent);
-  void          (*restore_thyself)  (GstObject * object, GstXmlNodePtr self);
 
   /*< private >*/
   gpointer _gst_reserved[GST_PADDING];
@@ -288,28 +205,22 @@ GType             gst_object_get_type             (void);
 gboolean       gst_object_set_name             (GstObject *object, const gchar *name);
 gchar*         gst_object_get_name             (GstObject *object);
 
-#ifndef GST_DISABLE_DEPRECATED
-void           gst_object_set_name_prefix      (GstObject *object, const gchar *name_prefix);
-gchar*         gst_object_get_name_prefix      (GstObject *object);
-#endif
-
 /* parentage routines */
 gboolean       gst_object_set_parent           (GstObject *object, GstObject *parent);
 GstObject*     gst_object_get_parent           (GstObject *object);
 void           gst_object_unparent             (GstObject *object);
 gboolean       gst_object_has_ancestor         (GstObject *object, GstObject *ancestor);
 
-void            gst_object_default_deep_notify         (GObject *object, GstObject *orig,
+void            gst_object_default_deep_notify  (GObject *object, GstObject *orig,
                                                  GParamSpec *pspec, gchar **excluded_props);
 
 /* refcounting + life cycle */
 gpointer       gst_object_ref                  (gpointer object);
 void           gst_object_unref                (gpointer object);
-void           gst_object_ref_sink             (gpointer object);
-void           gst_object_sink                 (gpointer object);
+gpointer        gst_object_ref_sink            (gpointer object);
 
 /* replace object pointer */
-void           gst_object_replace              (GstObject **oldobj, GstObject *newobj);
+void            gst_object_replace             (GstObject **oldobj, GstObject *newobj);
 
 /* printing out the 'path' of the object */
 gchar *                gst_object_get_path_string      (GstObject *object);
@@ -317,37 +228,6 @@ gchar *            gst_object_get_path_string      (GstObject *object);
 /* misc utils */
 gboolean       gst_object_check_uniqueness     (GList *list, const gchar *name);
 
-/* load/save */
-#ifndef GST_DISABLE_DEPRECATED
-#ifndef GST_DISABLE_LOADSAVE
-GstXmlNodePtr   gst_object_save_thyself    (GstObject *object, GstXmlNodePtr parent);
-void            gst_object_restore_thyself (GstObject *object, GstXmlNodePtr self);
-#else
-#if defined __GNUC__ && __GNUC__ >= 3
-#pragma GCC poison gst_object_save_thyself
-#pragma GCC poison gst_object_restore_thyself
-#endif
-#endif
-#endif
-
-/* class signal stuff */
-guint          gst_class_signal_connect        (GstObjectClass *klass,
-                                                const gchar    *name,
-                                                gpointer        func,
-                                                gpointer        func_data);
-
-#ifndef GST_DISABLE_DEPRECATED
-#ifndef GST_DISABLE_LOADSAVE
-void        gst_class_signal_emit_by_name   (GstObject     * object,
-                                             const gchar   * name,
-                                             GstXmlNodePtr   self);
-#else
-#if defined __GNUC__ && __GNUC__ >= 3
-#pragma GCC poison gst_class_signal_emit_by_name
-#endif
-#endif
-#endif
-
 G_END_DECLS
 
 #endif /* __GST_OBJECT_H__ */
index 14c9786..c851e78 100644 (file)
@@ -80,8 +80,6 @@ enum
 {
   PAD_LINKED,
   PAD_UNLINKED,
-  PAD_REQUEST_LINK,
-  PAD_HAVE_DATA,
   /* FILL ME */
   LAST_SIGNAL
 };
@@ -95,30 +93,44 @@ enum
   /* FILL ME */
 };
 
-typedef struct _GstPadPushCache GstPadPushCache;
-
-struct _GstPadPushCache
-{
-  GstPad *peer;                 /* reffed peer pad */
-  GstCaps *caps;                /* caps for this link */
-};
-
-static GstPadPushCache _pad_cache_invalid = { NULL, };
-
-#define PAD_CACHE_INVALID (&_pad_cache_invalid)
-
 #define GST_PAD_GET_PRIVATE(obj)  \
    (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GST_TYPE_PAD, GstPadPrivate))
 
-#define GST_PAD_CHAINLISTFUNC(pad) ((pad)->abidata.ABI.priv->chainlistfunc)
+/* we have a pending and an active event on the pad. On source pads only the
+ * active event is used. On sinkpads, events are copied to the pending entry and
+ * moved to the active event when the eventfunc returned TRUE. */
+typedef struct
+{
+  GstEvent *pending;
+  GstEvent *event;
+} PadEvent;
 
 struct _GstPadPrivate
 {
-  GstPadChainListFunction chainlistfunc;
+  PadEvent events[GST_EVENT_MAX_STICKY];
 
-  GstPadPushCache *cache_ptr;
+  gint using;
+  gint probe_cookie;
 };
 
+typedef struct
+{
+  GHook hook;
+  guint cookie;
+} GstProbe;
+
+#define PROBE_COOKIE(h) (((GstProbe *)(h))->cookie)
+
+typedef struct
+{
+  GstPad *pad;
+  GstProbeType mask;
+  gpointer type_data;
+  GstProbeReturn ret;
+  gboolean pass;
+  guint cookie;
+} ProbeMarshall;
+
 static void gst_pad_dispose (GObject * object);
 static void gst_pad_finalize (GObject * object);
 static void gst_pad_set_property (GObject * object, guint prop_id,
@@ -126,28 +138,12 @@ static void gst_pad_set_property (GObject * object, guint prop_id,
 static void gst_pad_get_property (GObject * object, guint prop_id,
     GValue * value, GParamSpec * pspec);
 
-static GstFlowReturn handle_pad_block (GstPad * pad);
-static GstCaps *gst_pad_get_caps_unlocked (GstPad * pad);
+static GstCaps *gst_pad_get_caps_unlocked (GstPad * pad, GstCaps * filter);
 static void gst_pad_set_pad_template (GstPad * pad, GstPadTemplate * templ);
 static gboolean gst_pad_activate_default (GstPad * pad);
 static gboolean gst_pad_acceptcaps_default (GstPad * pad, GstCaps * caps);
-
-#if !defined(GST_DISABLE_LOADSAVE) && !defined(GST_REMOVE_DEPRECATED)
-#ifdef GST_DISABLE_DEPRECATED
-#include <libxml/parser.h>
-#endif
-static xmlNodePtr gst_pad_save_thyself (GstObject * object, xmlNodePtr parent);
-void gst_pad_load_and_link (xmlNodePtr self, GstObject * parent);
-#endif
-
-/* Some deprecated stuff that we need inside here for
- * backwards compatibility */
-#ifdef GST_DISABLE_DEPRECATED
-#ifndef GST_REMOVE_DEPRECATED
-#define GST_PAD_INTLINKFUNC(pad)       (GST_PAD_CAST(pad)->intlinkfunc)
-GList *gst_pad_get_internal_links_default (GstPad * pad);
-#endif
-#endif
+static GstFlowReturn gst_pad_chain_list_default (GstPad * pad,
+    GstBufferList * list);
 
 static GstObjectClass *parent_class = NULL;
 static guint gst_pad_signals[LAST_SIGNAL] = { 0 };
@@ -156,6 +152,7 @@ static GParamSpec *pspec_caps = NULL;
 
 /* quarks for probe signals */
 static GQuark buffer_quark;
+static GQuark buffer_list_quark;
 static GQuark event_quark;
 
 typedef struct
@@ -228,6 +225,7 @@ gst_flow_to_quark (GstFlowReturn ret)
   gint i; \
   \
   buffer_quark = g_quark_from_static_string ("buffer"); \
+  buffer_list_quark = g_quark_from_static_string ("bufferlist"); \
   event_quark = g_quark_from_static_string ("event"); \
   \
   for (i = 0; i < G_N_ELEMENTS (flow_quarks); i++) {                   \
@@ -240,24 +238,6 @@ gst_flow_to_quark (GstFlowReturn ret)
 
 G_DEFINE_TYPE_WITH_CODE (GstPad, gst_pad, GST_TYPE_OBJECT, _do_init);
 
-static gboolean
-_gst_do_pass_data_accumulator (GSignalInvocationHint * ihint,
-    GValue * return_accu, const GValue * handler_return, gpointer dummy)
-{
-  gboolean ret = g_value_get_boolean (handler_return);
-
-  GST_DEBUG ("accumulated %d", ret);
-  g_value_set_boolean (return_accu, ret);
-
-  return ret;
-}
-
-static gboolean
-default_have_data (GstPad * pad, GstMiniObject * o)
-{
-  return TRUE;
-}
-
 static void
 gst_pad_class_init (GstPadClass * klass)
 {
@@ -298,36 +278,6 @@ gst_pad_class_init (GstPadClass * klass)
       g_signal_new ("unlinked", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
       G_STRUCT_OFFSET (GstPadClass, unlinked), NULL, NULL,
       gst_marshal_VOID__OBJECT, G_TYPE_NONE, 1, GST_TYPE_PAD);
-  /**
-   * GstPad::request-link:
-   * @pad: the pad that emitted the signal
-   * @peer: the peer pad for which a connection is requested
-   *
-   * Signals that a pad connection has been requested.
-   */
-  gst_pad_signals[PAD_REQUEST_LINK] =
-      g_signal_new ("request-link", G_TYPE_FROM_CLASS (klass),
-      G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstPadClass, request_link), NULL,
-      NULL, gst_marshal_VOID__OBJECT, G_TYPE_NONE, 0);
-
-  /**
-   * GstPad::have-data:
-   * @pad: the pad that emitted the signal
-   * @mini_obj: new data
-   *
-   * Signals that new data is available on the pad. This signal is used
-   * internally for implementing pad probes.
-   * See gst_pad_add_*_probe functions.
-   *
-   * Returns: %TRUE to keep the data, %FALSE to drop it
-   */
-  gst_pad_signals[PAD_HAVE_DATA] =
-      g_signal_new ("have-data", G_TYPE_FROM_CLASS (klass),
-      G_SIGNAL_RUN_LAST | G_SIGNAL_DETAILED,
-      G_STRUCT_OFFSET (GstPadClass, have_data),
-      _gst_do_pass_data_accumulator,
-      NULL, gst_marshal_BOOLEAN__POINTER, G_TYPE_BOOLEAN, 1,
-      GST_TYPE_MINI_OBJECT);
 
   pspec_caps = g_param_spec_boxed ("caps", "Caps",
       "The capabilities of the pad", GST_TYPE_CAPS,
@@ -338,17 +288,13 @@ gst_pad_class_init (GstPadClass * klass)
       g_param_spec_enum ("direction", "Direction", "The direction of the pad",
           GST_TYPE_PAD_DIRECTION, GST_PAD_UNKNOWN,
           G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
+
   /* FIXME, Make G_PARAM_CONSTRUCT_ONLY when we fix ghostpads. */
   g_object_class_install_property (gobject_class, PAD_PROP_TEMPLATE,
       g_param_spec_object ("template", "Template",
           "The GstPadTemplate of this pad", GST_TYPE_PAD_TEMPLATE,
           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
 
-#if !defined(GST_DISABLE_LOADSAVE) && !defined(GST_REMOVE_DEPRECATED)
-  gstobject_class->save_thyself =
-      ((gpointer (*)(GstObject * object,
-              gpointer self)) * GST_DEBUG_FUNCPTR (gst_pad_save_thyself));
-#endif
   gstobject_class->path_string_separator = ".";
 
   /* Register common function pointer descriptions */
@@ -356,57 +302,130 @@ gst_pad_class_init (GstPadClass * klass)
   GST_DEBUG_REGISTER_FUNCPTR (gst_pad_event_default);
   GST_DEBUG_REGISTER_FUNCPTR (gst_pad_get_query_types_default);
   GST_DEBUG_REGISTER_FUNCPTR (gst_pad_query_default);
-#ifndef GST_REMOVE_DEPRECATED
-  GST_DEBUG_REGISTER_FUNCPTR (gst_pad_get_internal_links_default);
-#endif
   GST_DEBUG_REGISTER_FUNCPTR (gst_pad_iterate_internal_links_default);
   GST_DEBUG_REGISTER_FUNCPTR (gst_pad_acceptcaps_default);
-
-  /* from gstutils.c */
-  GST_DEBUG_REGISTER_FUNCPTR (gst_pad_get_fixed_caps_func);
-
-  klass->have_data = default_have_data;
+  GST_DEBUG_REGISTER_FUNCPTR (gst_pad_chain_list_default);
 }
 
 static void
 gst_pad_init (GstPad * pad)
 {
-  pad->abidata.ABI.priv = GST_PAD_GET_PRIVATE (pad);
+  pad->priv = GST_PAD_GET_PRIVATE (pad);
 
   GST_PAD_DIRECTION (pad) = GST_PAD_UNKNOWN;
-  GST_PAD_PEER (pad) = NULL;
-
-  GST_PAD_CHAINFUNC (pad) = NULL;
-
-  GST_PAD_LINKFUNC (pad) = NULL;
-
-  GST_PAD_CAPS (pad) = NULL;
-  GST_PAD_GETCAPSFUNC (pad) = NULL;
 
   GST_PAD_ACTIVATEFUNC (pad) = gst_pad_activate_default;
   GST_PAD_EVENTFUNC (pad) = gst_pad_event_default;
   GST_PAD_QUERYTYPEFUNC (pad) = gst_pad_get_query_types_default;
   GST_PAD_QUERYFUNC (pad) = gst_pad_query_default;
-#ifndef GST_REMOVE_DEPRECATED
-  GST_PAD_INTLINKFUNC (pad) = gst_pad_get_internal_links_default;
-#endif
   GST_PAD_ITERINTLINKFUNC (pad) = gst_pad_iterate_internal_links_default;
-
   GST_PAD_ACCEPTCAPSFUNC (pad) = gst_pad_acceptcaps_default;
-
-  pad->do_buffer_signals = 0;
-  pad->do_event_signals = 0;
+  GST_PAD_CHAINLISTFUNC (pad) = gst_pad_chain_list_default;
 
   GST_PAD_SET_FLUSHING (pad);
 
-  pad->preroll_lock = g_mutex_new ();
-  pad->preroll_cond = g_cond_new ();
-
-  /* FIXME 0.11: Store this directly in the instance struct */
-  pad->stream_rec_lock = g_slice_new (GStaticRecMutex);
-  g_static_rec_mutex_init (pad->stream_rec_lock);
+  g_static_rec_mutex_init (&pad->stream_rec_lock);
 
   pad->block_cond = g_cond_new ();
+
+  g_hook_list_init (&pad->probes, sizeof (GstProbe));
+}
+
+/* called when setting the pad inactive. It removes all sticky events from
+ * the pad */
+static void
+clear_events (PadEvent events[])
+{
+  guint i;
+
+  for (i = 0; i < GST_EVENT_MAX_STICKY; i++) {
+    gst_event_replace (&events[i].event, NULL);
+    gst_event_replace (&events[i].pending, NULL);
+  }
+}
+
+/* The sticky event with @idx from the srcpad is copied to the
+ * pending event on the sinkpad (when different).
+ * This function applies the pad offsets in case of segment events.
+ * This will make sure that we send the event to the sinkpad event
+ * function when the next buffer of event arrives.
+ * Should be called with the OBJECT lock of both pads.
+ * This function returns TRUE when there is a pending event on the
+ * sinkpad */
+static gboolean
+replace_event (GstPad * srcpad, GstPad * sinkpad, guint idx)
+{
+  PadEvent *srcev, *sinkev;
+  GstEvent *event;
+  gboolean pending = FALSE;
+
+  srcev = &srcpad->priv->events[idx];
+
+  if ((event = srcev->event)) {
+    sinkev = &sinkpad->priv->events[idx];
+
+    switch (GST_EVENT_TYPE (event)) {
+      case GST_EVENT_SEGMENT:
+      {
+        GstSegment segment;
+        gint64 offset;
+
+        offset = srcpad->offset + sinkpad->offset;
+        if (offset != 0) {
+          gst_event_copy_segment (event, &segment);
+          /* adjust the base time. FIXME, check negative times, try to tweak the
+           * start to do clipping on negative times */
+          segment.base += offset;
+          /* make a new event from the updated segment */
+          event = gst_event_new_segment (&segment);
+        }
+        break;
+      }
+      default:
+        break;
+    }
+    if (sinkev->event != event) {
+      /* put in the pending entry when different */
+      gst_event_replace (&sinkev->pending, event);
+      pending = TRUE;
+    }
+  }
+  return pending;
+}
+
+
+static void
+prepare_event_update (GstPad * srcpad, GstPad * sinkpad)
+{
+  gboolean pending;
+  gint i;
+
+  /* make sure we push the events from the source to this new peer, for this we
+   * copy the events on the sinkpad and mark EVENTS_PENDING */
+  pending = FALSE;
+  for (i = 0; i < GST_EVENT_MAX_STICKY; i++)
+    pending |= replace_event (srcpad, sinkpad, i);
+
+  /* we had some new pending events, set our flag */
+  if (pending)
+    GST_OBJECT_FLAG_SET (sinkpad, GST_PAD_NEED_EVENTS);
+}
+
+/* should be called with the OBJECT_LOCK */
+static GstCaps *
+get_pad_caps (GstPad * pad)
+{
+  GstCaps *caps = NULL;
+  GstEvent *event;
+  guint idx;
+
+  idx = GST_EVENT_STICKY_IDX_TYPE (GST_EVENT_CAPS);
+  /* we can only use the caps when we have successfully send the caps
+   * event to the event function and is thus in the active entry */
+  if ((event = pad->priv->events[idx].event))
+    gst_event_parse_caps (event, &caps);
+
+  return caps;
 }
 
 static void
@@ -430,15 +449,11 @@ gst_pad_dispose (GObject * object)
     gst_object_unref (peer);
   }
 
-  /* clear the caps */
-  gst_caps_replace (&GST_PAD_CAPS (pad), NULL);
-
   gst_pad_set_pad_template (pad, NULL);
 
-  if (pad->block_destroy_data && pad->block_data) {
-    pad->block_destroy_data (pad->block_data);
-    pad->block_data = NULL;
-  }
+  clear_events (pad->priv->events);
+
+  g_hook_list_clear (&pad->probes);
 
   G_OBJECT_CLASS (parent_class)->dispose (object);
 }
@@ -456,21 +471,8 @@ gst_pad_finalize (GObject * object)
     gst_object_unref (task);
   }
 
-  if (pad->stream_rec_lock) {
-    g_static_rec_mutex_free (pad->stream_rec_lock);
-    g_slice_free (GStaticRecMutex, pad->stream_rec_lock);
-    pad->stream_rec_lock = NULL;
-  }
-  if (pad->preroll_lock) {
-    g_mutex_free (pad->preroll_lock);
-    g_cond_free (pad->preroll_cond);
-    pad->preroll_lock = NULL;
-    pad->preroll_cond = NULL;
-  }
-  if (pad->block_cond) {
-    g_cond_free (pad->block_cond);
-    pad->block_cond = NULL;
-  }
+  g_static_rec_mutex_free (&pad->stream_rec_lock);
+  g_cond_free (pad->block_cond);
 
   G_OBJECT_CLASS (parent_class)->finalize (object);
 }
@@ -504,7 +506,7 @@ gst_pad_get_property (GObject * object, guint prop_id,
   switch (prop_id) {
     case PAD_PROP_CAPS:
       GST_OBJECT_LOCK (object);
-      g_value_set_boxed (value, GST_PAD_CAPS (object));
+      g_value_set_boxed (value, get_pad_caps (GST_PAD_CAST (object)));
       GST_OBJECT_UNLOCK (object);
       break;
     case PAD_PROP_DIRECTION:
@@ -634,7 +636,6 @@ pre_activate (GstPad * pad, GstActivateMode new_mode)
     case GST_ACTIVATE_NONE:
       GST_OBJECT_LOCK (pad);
       GST_DEBUG_OBJECT (pad, "setting ACTIVATE_MODE NONE, set flushing");
-      _priv_gst_pad_invalidate_cache (pad);
       GST_PAD_SET_FLUSHING (pad);
       GST_PAD_ACTIVATE_MODE (pad) = new_mode;
       /* unlock blocked pads so element can resume and stop */
@@ -656,6 +657,9 @@ post_activate (GstPad * pad, GstActivateMode new_mode)
       /* ensures that streaming stops */
       GST_PAD_STREAM_LOCK (pad);
       GST_DEBUG_OBJECT (pad, "stopped streaming");
+      GST_OBJECT_LOCK (pad);
+      clear_events (pad->priv->events);
+      GST_OBJECT_UNLOCK (pad);
       GST_PAD_STREAM_UNLOCK (pad);
       break;
   }
@@ -707,6 +711,9 @@ gst_pad_set_active (GstPad * pad, gboolean active)
         GST_DEBUG_OBJECT (pad, "activating pad from none");
         ret = (GST_PAD_ACTIVATEFUNC (pad)) (pad);
         break;
+      default:
+        GST_DEBUG_OBJECT (pad, "unknown activation mode!");
+        break;
     }
   } else {
     switch (old) {
@@ -722,6 +729,9 @@ gst_pad_set_active (GstPad * pad, gboolean active)
         GST_DEBUG_OBJECT (pad, "deactivating pad from none");
         ret = TRUE;
         break;
+      default:
+        GST_DEBUG_OBJECT (pad, "unknown activation mode!");
+        break;
     }
   }
 
@@ -734,6 +744,12 @@ gst_pad_set_active (GstPad * pad, gboolean active)
       GST_WARNING_OBJECT (pad, "Failed to activate pad");
     }
     GST_OBJECT_UNLOCK (pad);
+  } else {
+    if (!active) {
+      GST_OBJECT_LOCK (pad);
+      GST_OBJECT_FLAG_UNSET (pad, GST_PAD_NEED_RECONFIGURE);
+      GST_OBJECT_UNLOCK (pad);
+    }
   }
 
   return ret;
@@ -875,7 +891,6 @@ failure:
     GST_OBJECT_LOCK (pad);
     GST_CAT_INFO_OBJECT (GST_CAT_PADS, pad, "failed to %s in pull mode",
         active ? "activate" : "deactivate");
-    _priv_gst_pad_invalidate_cache (pad);
     GST_PAD_SET_FLUSHING (pad);
     GST_PAD_ACTIVATE_MODE (pad) = old;
     GST_OBJECT_UNLOCK (pad);
@@ -981,7 +996,6 @@ failure:
     GST_OBJECT_LOCK (pad);
     GST_CAT_INFO_OBJECT (GST_CAT_PADS, pad, "failed to %s in push mode",
         active ? "activate" : "deactivate");
-    _priv_gst_pad_invalidate_cache (pad);
     GST_PAD_SET_FLUSHING (pad);
     GST_PAD_ACTIVATE_MODE (pad) = old;
     GST_OBJECT_UNLOCK (pad);
@@ -1014,166 +1028,160 @@ gst_pad_is_active (GstPad * pad)
 }
 
 /**
- * gst_pad_set_blocked_async_full:
- * @pad: the #GstPad to block or unblock
- * @blocked: boolean indicating whether the pad should be blocked or unblocked
- * @callback: #GstPadBlockCallback that will be called when the
- *            operation succeeds
+ * gst_pad_add_probe:
+ * @pad: the #GstPad to add the probe to
+ * @mask: the probe mask
+ * @callback: #GstPadProbeCallback that will be called with notifications of
+ *           the pad state
  * @user_data: (closure): user data passed to the callback
  * @destroy_data: #GDestroyNotify for user_data
  *
- * Blocks or unblocks the dataflow on a pad. The provided callback
- * is called when the operation succeeds; this happens right before the next
- * attempt at pushing a buffer on the pad.
- *
- * This can take a while as the pad can only become blocked when real dataflow
- * is happening.
- * When the pipeline is stalled, for example in PAUSED, this can
- * take an indeterminate amount of time.
- * You can pass NULL as the callback to make this call block. Be careful with
- * this blocking call as it might not return for reasons stated above.
+ * Be notified of different states of pads. The provided callback is called for
+ * every state that matches @mask.
  *
  * <note>
- *  Pad block handlers are only called for source pads in push mode
+ *  Pad probe handlers are only called for source pads in push mode
  *  and sink pads in pull mode.
  * </note>
  *
- * Returns: TRUE if the pad could be blocked. This function can fail if the
- * wrong parameters were passed or the pad was already in the requested state.
+ * Returns: an id or 0 on error. The id can be used to remove the probe with
+ * gst_pad_remove_probe().
  *
  * MT safe.
- *
- * Since: 0.10.23
  */
-gboolean
-gst_pad_set_blocked_async_full (GstPad * pad, gboolean blocked,
-    GstPadBlockCallback callback, gpointer user_data,
+gulong
+gst_pad_add_probe (GstPad * pad, GstProbeType mask,
+    GstPadProbeCallback callback, gpointer user_data,
     GDestroyNotify destroy_data)
 {
-  gboolean was_blocked = FALSE;
+  GHook *hook;
+  gulong res;
 
-  g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
+  g_return_val_if_fail (GST_IS_PAD (pad), 0);
+  g_return_val_if_fail (mask != 0, 0);
 
   GST_OBJECT_LOCK (pad);
-
-  was_blocked = GST_PAD_IS_BLOCKED (pad);
-
-  if (G_UNLIKELY (was_blocked == blocked))
-    goto had_right_state;
-
-  if (blocked) {
-    GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad, "blocking pad");
-
-    _priv_gst_pad_invalidate_cache (pad);
+  /* make a new probe */
+  hook = g_hook_alloc (&pad->probes);
+
+  GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad, "adding probe for mask 0x%08x",
+      mask);
+
+  /* when no contraints are given for the types, assume all types are
+   * acceptable */
+  if ((mask & GST_PROBE_TYPE_DATA) == 0)
+    mask |= GST_PROBE_TYPE_DATA;
+  if ((mask & GST_PROBE_TYPE_SCHEDULING) == 0)
+    mask |= GST_PROBE_TYPE_SCHEDULING;
+
+  /* store our flags and other fields */
+  hook->flags |= (mask << G_HOOK_FLAG_USER_SHIFT);
+  hook->func = callback;
+  hook->data = user_data;
+  hook->destroy = destroy_data;
+  PROBE_COOKIE (hook) = 0;
+
+  /* incremenent cookie so that the new hook get's called */
+  pad->priv->probe_cookie++;
+
+  /* add the probe */
+  g_hook_prepend (&pad->probes, hook);
+  pad->num_probes++;
+
+  /* get the id of the hook, we return this and it can be used to remove the
+   * probe later */
+  res = hook->hook_id;
+
+  GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad, "got probe id %lu", res);
+
+  if (mask & GST_PROBE_TYPE_BLOCKING) {
+    /* we have a block probe */
+    pad->num_blocked++;
     GST_OBJECT_FLAG_SET (pad, GST_PAD_BLOCKED);
+    GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad, "added blocking probe, "
+        "now %d blocking probes", pad->num_blocked);
+  }
+
+  /* call the callback if we need to be called for idle callbacks */
+  if ((mask & GST_PROBE_TYPE_IDLE) && (callback != NULL)) {
+    if (pad->priv->using > 0) {
+      /* the pad is in use, we can't signal the idle callback yet. Since we set the
+       * flag above, the last thread to leave the push will do the callback. New
+       * threads going into the push will block. */
+      GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad,
+          "pad is in use, delay idle callback");
+      GST_OBJECT_UNLOCK (pad);
+    } else {
+      /* the pad is idle now, we can signal the idle callback now */
+      GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad,
+          "pad is idle, trigger idle callback");
+      GST_OBJECT_UNLOCK (pad);
 
-    if (pad->block_destroy_data && pad->block_data)
-      pad->block_destroy_data (pad->block_data);
-
-    pad->block_callback = callback;
-    pad->block_data = user_data;
-    pad->block_destroy_data = destroy_data;
-    pad->abidata.ABI.block_callback_called = FALSE;
-    if (!callback) {
-      GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad, "waiting for block");
-      GST_PAD_BLOCK_WAIT (pad);
-      GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad, "blocked");
+      callback (pad, GST_PROBE_TYPE_IDLE, NULL, user_data);
     }
   } else {
-    GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad, "unblocking pad");
-
-    GST_OBJECT_FLAG_UNSET (pad, GST_PAD_BLOCKED);
-
-    if (pad->block_destroy_data && pad->block_data)
-      pad->block_destroy_data (pad->block_data);
-
-    pad->block_callback = callback;
-    pad->block_data = user_data;
-    pad->block_destroy_data = destroy_data;
-    pad->abidata.ABI.block_callback_called = FALSE;
-
-    GST_PAD_BLOCK_BROADCAST (pad);
-    if (!callback) {
-      /* no callback, wait for the unblock to happen */
-      GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad, "waiting for unblock");
-      GST_PAD_BLOCK_WAIT (pad);
-      GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad, "unblocked");
-    }
+    GST_OBJECT_UNLOCK (pad);
   }
-  GST_OBJECT_UNLOCK (pad);
+  return res;
+}
 
-  return TRUE;
+static void
+cleanup_hook (GstPad * pad, GHook * hook)
+{
+  GstProbeType type;
 
-had_right_state:
-  {
-    GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad,
-        "pad was in right state (%d)", was_blocked);
-    GST_OBJECT_UNLOCK (pad);
+  type = (hook->flags) >> G_HOOK_FLAG_USER_SHIFT;
 
-    return FALSE;
+  if (type & GST_PROBE_TYPE_BLOCKING) {
+    /* unblock when we remove the last blocking probe */
+    pad->num_blocked--;
+    GST_DEBUG_OBJECT (pad, "remove blocking probe, now %d left",
+        pad->num_blocked);
+    if (pad->num_blocked == 0) {
+      GST_DEBUG_OBJECT (pad, "last blocking probe removed, unblocking");
+      GST_OBJECT_FLAG_UNSET (pad, GST_PAD_BLOCKED);
+      GST_PAD_BLOCK_BROADCAST (pad);
+    }
   }
+  g_hook_destroy_link (&pad->probes, hook);
+  pad->num_probes--;
 }
 
 /**
- * gst_pad_set_blocked_async:
- * @pad: the #GstPad to block or unblock
- * @blocked: boolean indicating whether the pad should be blocked or unblocked
- * @callback: #GstPadBlockCallback that will be called when the
- *            operation succeeds
- * @user_data: (closure): user data passed to the callback
- *
- * Blocks or unblocks the dataflow on a pad. The provided callback
- * is called when the operation succeeds; this happens right before the next
- * attempt at pushing a buffer on the pad.
- *
- * This can take a while as the pad can only become blocked when real dataflow
- * is happening.
- * When the pipeline is stalled, for example in PAUSED, this can
- * take an indeterminate amount of time.
- * You can pass NULL as the callback to make this call block. Be careful with
- * this blocking call as it might not return for reasons stated above.
- *
- * <note>
- *  Pad block handlers are only called for source pads in push mode
- *  and sink pads in pull mode.
- * </note>
+ * gst_pad_remove_probe:
+ * @pad: the #GstPad with the probe
+ * @id: the probe id to remove
  *
- * Returns: TRUE if the pad could be blocked. This function can fail if the
- * wrong parameters were passed or the pad was already in the requested state.
+ * Remove the probe with @id from @pad.
  *
  * MT safe.
  */
-gboolean
-gst_pad_set_blocked_async (GstPad * pad, gboolean blocked,
-    GstPadBlockCallback callback, gpointer user_data)
+void
+gst_pad_remove_probe (GstPad * pad, gulong id)
 {
-  return gst_pad_set_blocked_async_full (pad, blocked,
-      callback, user_data, NULL);
-}
+  GHook *hook;
 
-/**
- * gst_pad_set_blocked:
- * @pad: the #GstPad to block or unblock
- * @blocked: boolean indicating we should block or unblock
- *
- * Blocks or unblocks the dataflow on a pad. This function is
- * a shortcut for gst_pad_set_blocked_async() with a NULL
- * callback.
- *
- * <note>
- *  Pad blocks are only possible for source pads in push mode
- *  and sink pads in pull mode.
- * </note>
- *
- * Returns: TRUE if the pad could be blocked. This function can fail if the
- * wrong parameters were passed or the pad was already in the requested state.
- *
- * MT safe.
- */
-gboolean
-gst_pad_set_blocked (GstPad * pad, gboolean blocked)
-{
-  return gst_pad_set_blocked_async (pad, blocked, NULL, NULL);
+  g_return_if_fail (GST_IS_PAD (pad));
+
+  GST_OBJECT_LOCK (pad);
+
+  hook = g_hook_get (&pad->probes, id);
+  if (hook == NULL)
+    goto not_found;
+
+  GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad, "removing hook %ld",
+      hook->hook_id);
+  cleanup_hook (pad, hook);
+  GST_OBJECT_UNLOCK (pad);
+
+  return;
+
+not_found:
+  {
+    GST_OBJECT_UNLOCK (pad);
+    g_warning ("%s: pad `%p' has no probe with id `%lu'", G_STRLOC, pad, id);
+    return;
+  }
 }
 
 /**
@@ -1232,6 +1240,30 @@ gst_pad_is_blocking (GstPad * pad)
 }
 
 /**
+ * gst_pad_check_reconfigure:
+ * @pad: the #GstPad to check
+ *
+ * Check and clear the #GST_PAD_NEED_RECONFIGURE flag on @pad and return %TRUE
+ * if the flag was set.
+ *
+ * Returns: %TRUE is the GST_PAD_NEED_RECONFIGURE flag was set on @pad.
+ */
+gboolean
+gst_pad_check_reconfigure (GstPad * pad)
+{
+  gboolean reconfigure;
+
+  g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
+
+  GST_OBJECT_LOCK (pad);
+  reconfigure = GST_PAD_NEEDS_RECONFIGURE (pad);
+  GST_OBJECT_FLAG_UNSET (pad, GST_PAD_NEED_RECONFIGURE);
+  GST_OBJECT_UNLOCK (pad);
+
+  return reconfigure;
+}
+
+/**
  * gst_pad_set_activate_function:
  * @pad: a #GstPad.
  * @activate: the #GstPadActivateFunction to set.
@@ -1355,27 +1387,6 @@ gst_pad_set_getrange_function (GstPad * pad, GstPadGetRangeFunction get)
 }
 
 /**
- * gst_pad_set_checkgetrange_function:
- * @pad: a source #GstPad.
- * @check: the #GstPadCheckGetRangeFunction to set.
- *
- * Sets the given checkgetrange function for the pad. Implement this function
- * on a pad if you dynamically support getrange based scheduling on the pad.
- */
-void
-gst_pad_set_checkgetrange_function (GstPad * pad,
-    GstPadCheckGetRangeFunction check)
-{
-  g_return_if_fail (GST_IS_PAD (pad));
-  g_return_if_fail (GST_PAD_IS_SRC (pad));
-
-  GST_PAD_CHECKGETRANGEFUNC (pad) = check;
-
-  GST_CAT_DEBUG_OBJECT (GST_CAT_PADS, pad, "checkgetrangefunc set to %s",
-      GST_DEBUG_FUNCPTR_NAME (check));
-}
-
-/**
  * gst_pad_set_event_function:
  * @pad: a #GstPad of either direction.
  * @event: the #GstPadEventFunction to set.
@@ -1461,8 +1472,12 @@ no_func:
 static gboolean
 gst_pad_get_query_types_dispatcher (GstPad * pad, const GstQueryType ** data)
 {
-  *data = gst_pad_get_query_types (pad);
+  GstPad *peer;
 
+  if ((peer = gst_pad_get_peer (pad))) {
+    *data = gst_pad_get_query_types (peer);
+    gst_object_unref (peer);
+  }
   return TRUE;
 }
 
@@ -1470,8 +1485,8 @@ gst_pad_get_query_types_dispatcher (GstPad * pad, const GstQueryType ** data)
  * gst_pad_get_query_types_default:
  * @pad: a #GstPad.
  *
- * Invoke the default dispatcher for the query types on
- * the pad.
+ * Invoke the default query types function on the pad. This function will get
+ * the supported query type from the peer of an internally linked pad of @pad.
  *
  * Returns: (transfer none) (array zero-terminated=1): a zero-terminated array
  *     of #GstQueryType, or NULL if none of the internally-linked pads has a
@@ -1484,7 +1499,7 @@ gst_pad_get_query_types_default (GstPad * pad)
 
   g_return_val_if_fail (GST_IS_PAD (pad), NULL);
 
-  gst_pad_dispatcher (pad, (GstPadDispatcherFunction)
+  gst_pad_forward (pad, (GstPadForwardFunction)
       gst_pad_get_query_types_dispatcher, &result);
 
   return result;
@@ -1511,32 +1526,6 @@ gst_pad_set_iterate_internal_links_function (GstPad * pad,
 }
 
 /**
- * gst_pad_set_internal_link_function:
- * @pad: a #GstPad of either direction.
- * @intlink: the #GstPadIntLinkFunction to set.
- *
- * Sets the given internal link function for the pad.
- *
- * Deprecated: Use the thread-safe gst_pad_set_iterate_internal_links_function()
- */
-#ifndef GST_REMOVE_DEPRECATED
-#ifdef GST_DISABLE_DEPRECATED
-void
-gst_pad_set_internal_link_function (GstPad * pad,
-    GstPadIntLinkFunction intlink);
-#endif
-void
-gst_pad_set_internal_link_function (GstPad * pad, GstPadIntLinkFunction intlink)
-{
-  g_return_if_fail (GST_IS_PAD (pad));
-
-  GST_PAD_INTLINKFUNC (pad) = intlink;
-  GST_CAT_DEBUG_OBJECT (GST_CAT_PADS, pad, "internal link set to %s",
-      GST_DEBUG_FUNCPTR_NAME (intlink));
-}
-#endif /* GST_REMOVE_DEPRECATED */
-
-/**
  * gst_pad_set_link_function:
  * @pad: a #GstPad.
  * @link: the #GstPadLinkFunction to set.
@@ -1659,47 +1648,6 @@ gst_pad_set_fixatecaps_function (GstPad * pad,
 }
 
 /**
- * gst_pad_set_setcaps_function:
- * @pad: a #GstPad.
- * @setcaps: the #GstPadSetCapsFunction to set.
- *
- * Sets the given setcaps function for the pad.  The setcaps function
- * will be called whenever a buffer with a new media type is pushed or
- * pulled from the pad. The pad/element needs to update its internal
- * structures to process the new media type. If this new type is not
- * acceptable, the setcaps function should return FALSE.
- */
-void
-gst_pad_set_setcaps_function (GstPad * pad, GstPadSetCapsFunction setcaps)
-{
-  g_return_if_fail (GST_IS_PAD (pad));
-
-  GST_PAD_SETCAPSFUNC (pad) = setcaps;
-  GST_CAT_DEBUG_OBJECT (GST_CAT_PADS, pad, "setcapsfunc set to %s",
-      GST_DEBUG_FUNCPTR_NAME (setcaps));
-}
-
-/**
- * gst_pad_set_bufferalloc_function:
- * @pad: a sink #GstPad.
- * @bufalloc: the #GstPadBufferAllocFunction to set.
- *
- * Sets the given bufferalloc function for the pad. Note that the
- * bufferalloc function can only be set on sinkpads.
- */
-void
-gst_pad_set_bufferalloc_function (GstPad * pad,
-    GstPadBufferAllocFunction bufalloc)
-{
-  g_return_if_fail (GST_IS_PAD (pad));
-  g_return_if_fail (GST_PAD_IS_SINK (pad));
-
-  GST_PAD_BUFFERALLOCFUNC (pad) = bufalloc;
-  GST_CAT_DEBUG_OBJECT (GST_CAT_PADS, pad, "bufferallocfunc set to %s",
-      GST_DEBUG_FUNCPTR_NAME (bufalloc));
-}
-
-/**
  * gst_pad_unlink:
  * @srcpad: the source #GstPad to unlink.
  * @sinkpad: the sink #GstPad to unlink.
@@ -1717,6 +1665,7 @@ gst_pad_unlink (GstPad * srcpad, GstPad * sinkpad)
 {
   gboolean result = FALSE;
   GstElement *parent = NULL;
+  gint i;
 
   g_return_val_if_fail (GST_IS_PAD (srcpad), FALSE);
   g_return_val_if_fail (GST_PAD_IS_SRC (srcpad), FALSE);
@@ -1742,7 +1691,6 @@ gst_pad_unlink (GstPad * srcpad, GstPad * sinkpad)
   }
 
   GST_OBJECT_LOCK (srcpad);
-
   GST_OBJECT_LOCK (sinkpad);
 
   if (G_UNLIKELY (GST_PAD_PEER (srcpad) != sinkpad))
@@ -1755,12 +1703,14 @@ gst_pad_unlink (GstPad * srcpad, GstPad * sinkpad)
     GST_PAD_UNLINKFUNC (sinkpad) (sinkpad);
   }
 
-  _priv_gst_pad_invalidate_cache (srcpad);
-
   /* first clear peers */
   GST_PAD_PEER (srcpad) = NULL;
   GST_PAD_PEER (sinkpad) = NULL;
 
+  /* clear pending caps if any */
+  for (i = 0; i < GST_EVENT_MAX_STICKY; i++)
+    gst_event_replace (&sinkpad->priv->events[i].pending, NULL);
+
   GST_OBJECT_UNLOCK (sinkpad);
   GST_OBJECT_UNLOCK (srcpad);
 
@@ -1837,8 +1787,8 @@ gst_pad_link_check_compatible_unlocked (GstPad * src, GstPad * sink,
 
   /* Doing the expensive caps checking takes priority over only checking the template caps */
   if (flags & GST_PAD_LINK_CHECK_CAPS) {
-    srccaps = gst_pad_get_caps_unlocked (src);
-    sinkcaps = gst_pad_get_caps_unlocked (sink);
+    srccaps = gst_pad_get_caps_unlocked (src, NULL);
+    sinkcaps = gst_pad_get_caps_unlocked (sink, NULL);
   } else {
     /* If one of the two pads doesn't have a template, consider the intersection
      * as valid.*/
@@ -2078,6 +2028,7 @@ gst_pad_link_full (GstPad * srcpad, GstPad * sinkpad, GstPadLinkCheck flags)
 {
   GstPadLinkReturn result;
   GstElement *parent;
+  GstPadLinkFunction srcfunc, sinkfunc;
 
   g_return_val_if_fail (GST_IS_PAD (srcpad), GST_PAD_LINK_REFUSED);
   g_return_val_if_fail (GST_PAD_IS_SRC (srcpad), GST_PAD_LINK_WRONG_DIRECTION);
@@ -2086,8 +2037,8 @@ gst_pad_link_full (GstPad * srcpad, GstPad * sinkpad, GstPadLinkCheck flags)
       GST_PAD_LINK_WRONG_DIRECTION);
 
   /* Notify the parent early. See gst_pad_unlink for details. */
-  if ((parent = GST_ELEMENT_CAST (gst_pad_get_parent (srcpad)))) {
-    if (GST_IS_ELEMENT (parent)) {
+  if (G_LIKELY ((parent = GST_ELEMENT_CAST (gst_pad_get_parent (srcpad))))) {
+    if (G_LIKELY (GST_IS_ELEMENT (parent))) {
       gst_element_post_message (parent,
           gst_message_new_structure_change (GST_OBJECT_CAST (sinkpad),
               GST_STRUCTURE_CHANGE_TYPE_PAD_LINK, parent, TRUE));
@@ -2100,56 +2051,59 @@ gst_pad_link_full (GstPad * srcpad, GstPad * sinkpad, GstPadLinkCheck flags)
   /* prepare will also lock the two pads */
   result = gst_pad_link_prepare (srcpad, sinkpad, flags);
 
-  if (result != GST_PAD_LINK_OK)
+  if (G_UNLIKELY (result != GST_PAD_LINK_OK))
     goto done;
 
   /* must set peers before calling the link function */
   GST_PAD_PEER (srcpad) = sinkpad;
   GST_PAD_PEER (sinkpad) = srcpad;
 
-  GST_OBJECT_UNLOCK (sinkpad);
-  GST_OBJECT_UNLOCK (srcpad);
-
-  /* FIXME released the locks here, concurrent thread might link
-   * something else. */
-  if (GST_PAD_LINKFUNC (srcpad)) {
-    /* this one will call the peer link function */
-    result = GST_PAD_LINKFUNC (srcpad) (srcpad, sinkpad);
-  } else if (GST_PAD_LINKFUNC (sinkpad)) {
-    /* if no source link function, we need to call the sink link
-     * function ourselves. */
-    result = GST_PAD_LINKFUNC (sinkpad) (sinkpad, srcpad);
-  } else {
-    result = GST_PAD_LINK_OK;
-  }
+  /* make sure we update events */
+  prepare_event_update (srcpad, sinkpad);
 
-  GST_OBJECT_LOCK (srcpad);
-  GST_OBJECT_LOCK (sinkpad);
+  /* get the link functions */
+  srcfunc = GST_PAD_LINKFUNC (srcpad);
+  sinkfunc = GST_PAD_LINKFUNC (sinkpad);
 
-  if (result == GST_PAD_LINK_OK) {
+  if (G_UNLIKELY (srcfunc || sinkfunc)) {
+    /* custom link functions, execute them */
     GST_OBJECT_UNLOCK (sinkpad);
     GST_OBJECT_UNLOCK (srcpad);
 
-    /* fire off a signal to each of the pads telling them
-     * that they've been linked */
-    g_signal_emit (srcpad, gst_pad_signals[PAD_LINKED], 0, sinkpad);
-    g_signal_emit (sinkpad, gst_pad_signals[PAD_LINKED], 0, srcpad);
+    if (srcfunc) {
+      /* this one will call the peer link function */
+      result = srcfunc (srcpad, sinkpad);
+    } else if (sinkfunc) {
+      /* if no source link function, we need to call the sink link
+       * function ourselves. */
+      result = sinkfunc (sinkpad, srcpad);
+    }
 
-    GST_CAT_INFO (GST_CAT_PADS, "linked %s:%s and %s:%s, successful",
-        GST_DEBUG_PAD_NAME (srcpad), GST_DEBUG_PAD_NAME (sinkpad));
-  } else {
-    GST_CAT_INFO (GST_CAT_PADS, "link between %s:%s and %s:%s failed",
-        GST_DEBUG_PAD_NAME (srcpad), GST_DEBUG_PAD_NAME (sinkpad));
+    GST_OBJECT_LOCK (srcpad);
+    GST_OBJECT_LOCK (sinkpad);
 
-    GST_PAD_PEER (srcpad) = NULL;
-    GST_PAD_PEER (sinkpad) = NULL;
+    /* we released the lock, check if the same pads are linked still */
+    if (GST_PAD_PEER (srcpad) != sinkpad || GST_PAD_PEER (sinkpad) != srcpad)
+      goto concurrent_link;
 
-    GST_OBJECT_UNLOCK (sinkpad);
-    GST_OBJECT_UNLOCK (srcpad);
+    if (G_UNLIKELY (result != GST_PAD_LINK_OK))
+      goto link_failed;
   }
+  GST_OBJECT_UNLOCK (sinkpad);
+  GST_OBJECT_UNLOCK (srcpad);
+
+  /* fire off a signal to each of the pads telling them
+   * that they've been linked */
+  g_signal_emit (srcpad, gst_pad_signals[PAD_LINKED], 0, sinkpad);
+  g_signal_emit (sinkpad, gst_pad_signals[PAD_LINKED], 0, srcpad);
+
+  GST_CAT_INFO (GST_CAT_PADS, "linked %s:%s and %s:%s, successful",
+      GST_DEBUG_PAD_NAME (srcpad), GST_DEBUG_PAD_NAME (sinkpad));
+
+  gst_pad_send_event (srcpad, gst_event_new_reconfigure ());
 
 done:
-  if (parent) {
+  if (G_LIKELY (parent)) {
     gst_element_post_message (parent,
         gst_message_new_structure_change (GST_OBJECT_CAST (sinkpad),
             GST_STRUCTURE_CHANGE_TYPE_PAD_LINK, parent, FALSE));
@@ -2157,6 +2111,32 @@ done:
   }
 
   return result;
+
+  /* ERRORS */
+concurrent_link:
+  {
+    GST_CAT_INFO (GST_CAT_PADS, "concurrent link between %s:%s and %s:%s",
+        GST_DEBUG_PAD_NAME (srcpad), GST_DEBUG_PAD_NAME (sinkpad));
+    GST_OBJECT_UNLOCK (sinkpad);
+    GST_OBJECT_UNLOCK (srcpad);
+
+    /* The other link operation succeeded first */
+    result = GST_PAD_LINK_WAS_LINKED;
+    goto done;
+  }
+link_failed:
+  {
+    GST_CAT_INFO (GST_CAT_PADS, "link between %s:%s and %s:%s failed",
+        GST_DEBUG_PAD_NAME (srcpad), GST_DEBUG_PAD_NAME (sinkpad));
+
+    GST_PAD_PEER (srcpad) = NULL;
+    GST_PAD_PEER (sinkpad) = NULL;
+
+    GST_OBJECT_UNLOCK (sinkpad);
+    GST_OBJECT_UNLOCK (srcpad);
+
+    goto done;
+  }
 }
 
 /**
@@ -2199,37 +2179,43 @@ gst_pad_set_pad_template (GstPad * pad, GstPadTemplate * templ)
  *
  * Gets the template for @pad.
  *
- * Returns: (transfer none): the #GstPadTemplate from which this pad was
- *     instantiated, or %NULL if this pad has no template.
- *
- * FIXME: currently returns an unrefcounted padtemplate.
+ * Returns: (transfer full): the #GstPadTemplate from which this pad was
+ *     instantiated, or %NULL if this pad has no template. Unref after
+ *     usage.
  */
 GstPadTemplate *
 gst_pad_get_pad_template (GstPad * pad)
 {
+  GstPadTemplate *templ;
+
   g_return_val_if_fail (GST_IS_PAD (pad), NULL);
 
-  return GST_PAD_PAD_TEMPLATE (pad);
-}
+  templ = GST_PAD_PAD_TEMPLATE (pad);
 
+  return (templ ? gst_object_ref (templ) : NULL);
+}
 
 /* should be called with the pad LOCK held */
 /* refs the caps, so caller is responsible for getting it unreffed */
 static GstCaps *
-gst_pad_get_caps_unlocked (GstPad * pad)
+gst_pad_get_caps_unlocked (GstPad * pad, GstCaps * filter)
 {
   GstCaps *result = NULL;
   GstPadTemplate *templ;
+  gboolean fixed_caps;
 
   GST_CAT_DEBUG_OBJECT (GST_CAT_CAPS, pad, "get pad caps");
 
-  if (GST_PAD_GETCAPSFUNC (pad)) {
+  fixed_caps = GST_PAD_IS_FIXED_CAPS (pad);
+
+  if (!fixed_caps && GST_PAD_GETCAPSFUNC (pad)) {
     GST_CAT_DEBUG_OBJECT (GST_CAT_CAPS, pad,
-        "dispatching to pad getcaps function");
+        "dispatching to pad getcaps function with "
+        "filter %" GST_PTR_FORMAT, filter);
 
     GST_OBJECT_FLAG_SET (pad, GST_PAD_IN_GETCAPS);
     GST_OBJECT_UNLOCK (pad);
-    result = GST_PAD_GETCAPSFUNC (pad) (pad);
+    result = GST_PAD_GETCAPSFUNC (pad) (pad, filter);
     GST_OBJECT_LOCK (pad);
     GST_OBJECT_FLAG_UNSET (pad, GST_PAD_IN_GETCAPS);
 
@@ -2259,24 +2245,80 @@ gst_pad_get_caps_unlocked (GstPad * pad)
           result = temp;
         }
       }
+      if (filter) {
+        if (!gst_caps_is_subset (result, filter)) {
+          GstCaps *temp;
+
+          GST_CAT_ERROR_OBJECT (GST_CAT_CAPS, pad,
+              "pad returned caps %" GST_PTR_FORMAT
+              " which are not a real subset of the filter caps %"
+              GST_PTR_FORMAT, result, filter);
+          g_warning ("pad %s:%s returned caps which are not a real "
+              "subset of the filter caps", GST_DEBUG_PAD_NAME (pad));
+          /* FIXME: Order? But shouldn't happen anyway... */
+          temp =
+              gst_caps_intersect_full (filter, result,
+              GST_CAPS_INTERSECT_FIRST);
+          gst_caps_unref (result);
+          result = temp;
+        }
+      }
 #endif
       goto done;
     }
   }
+  if (fixed_caps && (result = get_pad_caps (pad))) {
+    if (filter) {
+      GST_CAT_DEBUG_OBJECT (GST_CAT_CAPS, pad,
+          "using pad caps %p %" GST_PTR_FORMAT " with filter %p %"
+          GST_PTR_FORMAT, result, result, filter, filter);
+      result =
+          gst_caps_intersect_full (filter, result, GST_CAPS_INTERSECT_FIRST);
+      GST_CAT_DEBUG_OBJECT (GST_CAT_CAPS, pad, "result %p %" GST_PTR_FORMAT,
+          result);
+    } else {
+      GST_CAT_DEBUG_OBJECT (GST_CAT_CAPS, pad,
+          "using pad caps %p %" GST_PTR_FORMAT, result, result);
+      result = gst_caps_ref (result);
+    }
+    goto done;
+  }
   if ((templ = GST_PAD_PAD_TEMPLATE (pad))) {
     result = GST_PAD_TEMPLATE_CAPS (templ);
-    GST_CAT_DEBUG_OBJECT (GST_CAT_CAPS, pad,
-        "using pad template %p with caps %p %" GST_PTR_FORMAT, templ, result,
-        result);
 
-    result = gst_caps_ref (result);
+    if (filter) {
+      GST_CAT_DEBUG_OBJECT (GST_CAT_CAPS, pad,
+          "using pad template %p with caps %p %" GST_PTR_FORMAT
+          " and filter %p %" GST_PTR_FORMAT, templ, result, result, filter,
+          filter);
+      result =
+          gst_caps_intersect_full (filter, result, GST_CAPS_INTERSECT_FIRST);
+      GST_CAT_DEBUG_OBJECT (GST_CAT_CAPS, pad, "result %p %" GST_PTR_FORMAT,
+          result);
+    } else {
+      GST_CAT_DEBUG_OBJECT (GST_CAT_CAPS, pad,
+          "using pad template %p with caps %p %" GST_PTR_FORMAT, templ, result,
+          result);
+      result = gst_caps_ref (result);
+    }
+
     goto done;
   }
-  if ((result = GST_PAD_CAPS (pad))) {
-    GST_CAT_DEBUG_OBJECT (GST_CAT_CAPS, pad,
-        "using pad caps %p %" GST_PTR_FORMAT, result, result);
+  if (!fixed_caps && (result = get_pad_caps (pad))) {
+    if (filter) {
+      GST_CAT_DEBUG_OBJECT (GST_CAT_CAPS, pad,
+          "using pad caps %p %" GST_PTR_FORMAT " with filter %p %"
+          GST_PTR_FORMAT, result, result, filter, filter);
+      result =
+          gst_caps_intersect_full (filter, result, GST_CAPS_INTERSECT_FIRST);
+      GST_CAT_DEBUG_OBJECT (GST_CAT_CAPS, pad, "result %p %" GST_PTR_FORMAT,
+          result);
+    } else {
+      GST_CAT_DEBUG_OBJECT (GST_CAT_CAPS, pad,
+          "using pad caps %p %" GST_PTR_FORMAT, result, result);
+      result = gst_caps_ref (result);
+    }
 
-    result = gst_caps_ref (result);
     goto done;
   }
 
@@ -2288,129 +2330,123 @@ done:
   return result;
 }
 
-/* FIXME-0.11: what about making this the default and using
- * gst_caps_make_writable() explicitely where needed
- */
 /**
- * gst_pad_get_caps_reffed:
- * @pad: a  #GstPad to get the capabilities of.
+ * gst_pad_has_current_caps:
+ * @pad: a  #GstPad to check
  *
- * Gets the capabilities this pad can produce or consume. Preferred function if
- * one only wants to read or intersect the caps.
+ * Check if @pad has caps set on it with gst_pad_set_caps().
  *
- * Returns: (transfer full): the caps of the pad with incremented ref-count.
- *
- * Since: 0.10.26
+ * Returns: TRUE when @pad has caps associated with it.
  */
-GstCaps *
-gst_pad_get_caps_reffed (GstPad * pad)
+gboolean
+gst_pad_has_current_caps (GstPad * pad)
 {
-  GstCaps *result = NULL;
+  gboolean result;
 
-  g_return_val_if_fail (GST_IS_PAD (pad), NULL);
+  g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
 
   GST_OBJECT_LOCK (pad);
-
-  GST_CAT_DEBUG_OBJECT (GST_CAT_CAPS, pad, "get pad caps");
-
-  result = gst_pad_get_caps_unlocked (pad);
-
+  GST_CAT_DEBUG_OBJECT (GST_CAT_CAPS, pad, "check current pad caps");
+  result = (get_pad_caps (pad) != NULL);
   GST_OBJECT_UNLOCK (pad);
 
   return result;
 }
 
 /**
- * gst_pad_get_caps:
- * @pad: a  #GstPad to get the capabilities of.
- *
- * Gets the capabilities this pad can produce or consume.
- * Note that this method doesn't necessarily return the caps set by
- * gst_pad_set_caps() - use GST_PAD_CAPS() for that instead.
- * gst_pad_get_caps returns all possible caps a pad can operate with, using
- * the pad's get_caps function;
- * this returns the pad template caps if not explicitly set.
+ * gst_pad_get_current_caps:
+ * @pad: a  #GstPad to get the current capabilities of.
  *
- * Returns: (transfer full): a newly allocated copy of the #GstCaps of this pad
+ * Gets the capabilities currently configured on @pad with the last call to
+ * gst_pad_set_caps().
  *
- * MT safe.
+ * Returns: the current caps of the pad with incremented ref-count.
  */
 GstCaps *
-gst_pad_get_caps (GstPad * pad)
+gst_pad_get_current_caps (GstPad * pad)
 {
-  GstCaps *result = gst_pad_get_caps_reffed (pad);
+  GstCaps *result;
+
+  g_return_val_if_fail (GST_IS_PAD (pad), NULL);
 
-  /* be sure that we have a copy */
-  if (G_LIKELY (result))
-    result = gst_caps_make_writable (result);
+  GST_OBJECT_LOCK (pad);
+  if ((result = get_pad_caps (pad)))
+    gst_caps_ref (result);
+  GST_CAT_DEBUG_OBJECT (GST_CAT_CAPS, pad,
+      "get current pad caps %" GST_PTR_FORMAT, result);
+  GST_OBJECT_UNLOCK (pad);
 
   return result;
 }
 
-/* FIXME-0.11: what about making this the default and using
- * gst_caps_make_writable() explicitely where needed
- */
 /**
- * gst_pad_peer_get_caps_reffed:
+ * gst_pad_get_caps:
  * @pad: a  #GstPad to get the capabilities of.
+ * @filter: suggested #GstCaps.
+ *
+ * Gets the capabilities this pad can produce or consume.
+ * Note that this method doesn't necessarily return the caps set by
+ * gst_pad_set_caps() - use gst_pad_get_current_caps() for that instead.
+ * gst_pad_get_caps returns all possible caps a pad can operate with, using
+ * the pad's get_caps function;
+ * this returns the pad template caps if not explicitly set.
  *
- * Gets the capabilities of the peer connected to this pad. Preferred function
- * if one only wants to read or intersect the caps.
+ * When called on sinkpads @filter contains the caps that
+ * upstream could produce in the order preferred by upstream. When
+ * called on srcpads @filter contains the caps accepted by
+ * downstream in the preffered order. @filter might be %NULL but
+ * if it is not %NULL the returned caps will be a subset of @filter.
  *
- * Returns: (transfer full): the caps of the pad with incremented ref-count
+ * Note that this function does not return writable #GstCaps, use
+ * gst_caps_make_writable() before modifying the caps.
  *
- * Since: 0.10.26
+ * Returns: the caps of the pad with incremented ref-count.
  */
 GstCaps *
-gst_pad_peer_get_caps_reffed (GstPad * pad)
+gst_pad_get_caps (GstPad * pad, GstCaps * filter)
 {
-  GstPad *peerpad;
   GstCaps *result = NULL;
 
   g_return_val_if_fail (GST_IS_PAD (pad), NULL);
+  g_return_val_if_fail (filter == NULL || GST_IS_CAPS (filter), NULL);
 
   GST_OBJECT_LOCK (pad);
 
-  GST_CAT_DEBUG_OBJECT (GST_CAT_CAPS, pad, "get peer caps");
+  GST_CAT_DEBUG_OBJECT (GST_CAT_CAPS, pad, "get pad caps");
 
-  peerpad = GST_PAD_PEER (pad);
-  if (G_UNLIKELY (peerpad == NULL))
-    goto no_peer;
+  result = gst_pad_get_caps_unlocked (pad, filter);
 
-  gst_object_ref (peerpad);
   GST_OBJECT_UNLOCK (pad);
 
-  result = gst_pad_get_caps_reffed (peerpad);
-
-  gst_object_unref (peerpad);
-
   return result;
-
-no_peer:
-  {
-    GST_OBJECT_UNLOCK (pad);
-    return NULL;
-  }
 }
 
+
 /**
  * gst_pad_peer_get_caps:
- * @pad: a  #GstPad to get the peer capabilities of.
+ * @pad: a  #GstPad to get the capabilities of.
+ * @filter: a #GstCaps filter.
  *
  * Gets the capabilities of the peer connected to this pad. Similar to
  * gst_pad_get_caps().
  *
- * Returns: (transfer full): a newly allocated copy of the #GstCaps of the
- *     peer pad. Use gst_caps_unref() to get rid of it. This function
- *     returns %NULL if there is no peer pad.
+ * When called on srcpads @filter contains the caps that
+ * upstream could produce in the order preferred by upstream. When
+ * called on sinkpads @filter contains the caps accepted by
+ * downstream in the preffered order. @filter might be %NULL but
+ * if it is not %NULL the returned caps will be a subset of @filter.
+ *
+ * Returns: the caps of the peer pad with incremented ref-count. This function
+ * returns %NULL when there is no peer pad.
  */
 GstCaps *
-gst_pad_peer_get_caps (GstPad * pad)
+gst_pad_peer_get_caps (GstPad * pad, GstCaps * filter)
 {
   GstPad *peerpad;
   GstCaps *result = NULL;
 
   g_return_val_if_fail (GST_IS_PAD (pad), NULL);
+  g_return_val_if_fail (filter == NULL || GST_IS_CAPS (filter), NULL);
 
   GST_OBJECT_LOCK (pad);
 
@@ -2423,7 +2459,7 @@ gst_pad_peer_get_caps (GstPad * pad)
   gst_object_ref (peerpad);
   GST_OBJECT_UNLOCK (pad);
 
-  result = gst_pad_get_caps (peerpad);
+  result = gst_pad_get_caps (peerpad, filter);
 
   gst_object_unref (peerpad);
 
@@ -2437,71 +2473,29 @@ no_peer:
 }
 
 static gboolean
-fixate_value (GValue * dest, const GValue * src)
-{
-  if (G_VALUE_TYPE (src) == GST_TYPE_INT_RANGE) {
-    g_value_init (dest, G_TYPE_INT);
-    g_value_set_int (dest, gst_value_get_int_range_min (src));
-  } else if (G_VALUE_TYPE (src) == GST_TYPE_DOUBLE_RANGE) {
-    g_value_init (dest, G_TYPE_DOUBLE);
-    g_value_set_double (dest, gst_value_get_double_range_min (src));
-  } else if (G_VALUE_TYPE (src) == GST_TYPE_FRACTION_RANGE) {
-    gst_value_init_and_copy (dest, gst_value_get_fraction_range_min (src));
-  } else if (G_VALUE_TYPE (src) == GST_TYPE_LIST) {
-    GValue temp = { 0 };
-
-    /* list could be empty */
-    if (gst_value_list_get_size (src) <= 0)
-      return FALSE;
-
-    gst_value_init_and_copy (&temp, gst_value_list_get_value (src, 0));
-
-    if (!fixate_value (dest, &temp))
-      gst_value_init_and_copy (dest, &temp);
-    g_value_unset (&temp);
-  } else if (G_VALUE_TYPE (src) == GST_TYPE_ARRAY) {
-    gboolean res = FALSE;
-    guint n, len;
-
-    len = gst_value_array_get_size (src);
-    g_value_init (dest, GST_TYPE_ARRAY);
-    for (n = 0; n < len; n++) {
-      GValue kid = { 0 };
-      const GValue *orig_kid = gst_value_array_get_value (src, n);
-
-      if (!fixate_value (&kid, orig_kid))
-        gst_value_init_and_copy (&kid, orig_kid);
-      else
-        res = TRUE;
-      gst_value_array_append_value (dest, &kid);
-      g_value_unset (&kid);
-    }
-
-    if (!res)
-      g_value_unset (dest);
-
-    return res;
-  } else {
-    return FALSE;
-  }
-
-  return TRUE;
-}
-
-static gboolean
-gst_pad_default_fixate (GQuark field_id, const GValue * value, gpointer data)
+default_fixate (GQuark field_id, const GValue * value, gpointer data)
 {
   GstStructure *s = data;
   GValue v = { 0 };
 
-  if (fixate_value (&v, value)) {
+  if (gst_value_fixate (&v, value)) {
     gst_structure_id_set_value (s, field_id, &v);
     g_value_unset (&v);
   }
-
   return TRUE;
 }
 
+static void
+gst_pad_default_fixate (GstPad * pad, GstCaps * caps)
+{
+  GstStructure *s;
+
+  /* default fixation */
+  gst_caps_truncate (caps);
+  s = gst_caps_get_structure (caps, 0);
+  gst_structure_foreach (s, default_fixate, s);
+}
+
 /**
  * gst_pad_fixate_caps:
  * @pad: a  #GstPad to fixate
@@ -2514,27 +2508,22 @@ void
 gst_pad_fixate_caps (GstPad * pad, GstCaps * caps)
 {
   GstPadFixateCapsFunction fixatefunc;
-  GstStructure *s;
 
   g_return_if_fail (GST_IS_PAD (pad));
   g_return_if_fail (caps != NULL);
   g_return_if_fail (!gst_caps_is_empty (caps));
-  /* FIXME-0.11: do not allow fixating any-caps
-   * g_return_if_fail (!gst_caps_is_any (caps));
-   */
+  g_return_if_fail (!gst_caps_is_any (caps));
 
   if (gst_caps_is_fixed (caps) || gst_caps_is_any (caps))
     return;
 
+  g_return_if_fail (gst_caps_is_writable (caps));
+
   fixatefunc = GST_PAD_FIXATECAPSFUNC (pad);
   if (fixatefunc) {
     fixatefunc (pad, caps);
   }
-
-  /* default fixation */
-  gst_caps_truncate (caps);
-  s = gst_caps_get_structure (caps, 0);
-  gst_structure_foreach (s, gst_pad_default_fixate, s);
+  gst_pad_default_fixate (pad, caps);
 }
 
 /* Default accept caps implementation just checks against
@@ -2548,7 +2537,7 @@ gst_pad_acceptcaps_default (GstPad * pad, GstCaps * caps)
 
   GST_DEBUG_OBJECT (pad, "caps %" GST_PTR_FORMAT, caps);
 
-  allowed = gst_pad_get_caps_reffed (pad);
+  allowed = gst_pad_get_caps (pad, NULL);
   if (!allowed)
     goto nothing_allowed;
 
@@ -2582,7 +2571,9 @@ gst_pad_accept_caps (GstPad * pad, GstCaps * caps)
 {
   gboolean result;
   GstPadAcceptCapsFunction acceptfunc;
+#if 0
   GstCaps *existing = NULL;
+#endif
 
   g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
 
@@ -2593,11 +2584,13 @@ gst_pad_accept_caps (GstPad * pad, GstCaps * caps)
   /* lock for checking the existing caps */
   GST_OBJECT_LOCK (pad);
   GST_CAT_DEBUG_OBJECT (GST_CAT_CAPS, pad, "accept caps of %p", caps);
+#if 0
   /* The current caps on a pad are trivially acceptable */
   if (G_LIKELY ((existing = GST_PAD_CAPS (pad)))) {
     if (caps == existing || gst_caps_is_equal (caps, existing))
       goto is_same_caps;
   }
+#endif
   acceptfunc = GST_PAD_ACCEPTCAPSFUNC (pad);
   GST_OBJECT_UNLOCK (pad);
 
@@ -2612,12 +2605,14 @@ gst_pad_accept_caps (GstPad * pad, GstCaps * caps)
   }
   return result;
 
+#if 0
 is_same_caps:
   {
     GST_DEBUG_OBJECT (pad, "pad had same caps");
     GST_OBJECT_UNLOCK (pad);
     return TRUE;
   }
+#endif
 }
 
 /**
@@ -2682,124 +2677,119 @@ no_peer:
 gboolean
 gst_pad_set_caps (GstPad * pad, GstCaps * caps)
 {
-  GstPadSetCapsFunction setcaps;
-  GstCaps *existing;
+  GstEvent *event;
+  gboolean res = TRUE;
 
   g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
-  g_return_val_if_fail (caps == NULL || gst_caps_is_fixed (caps), FALSE);
+  g_return_val_if_fail (caps != NULL && gst_caps_is_fixed (caps), FALSE);
 
-  GST_OBJECT_LOCK (pad);
-  existing = GST_PAD_CAPS (pad);
-  if (existing == caps)
-    goto was_ok;
+  event = gst_event_new_caps (caps);
 
-  if (gst_caps_is_equal (caps, existing))
-    goto setting_same_caps;
+  if (GST_PAD_IS_SRC (pad))
+    res = gst_pad_push_event (pad, event);
+  else
+    res = gst_pad_send_event (pad, event);
 
-  setcaps = GST_PAD_SETCAPSFUNC (pad);
+  return res;
+}
 
-  /* call setcaps function to configure the pad only if the
-   * caps is not NULL */
-  if (setcaps != NULL && caps) {
-    if (!GST_PAD_IS_IN_SETCAPS (pad)) {
-      GST_OBJECT_FLAG_SET (pad, GST_PAD_IN_SETCAPS);
-      GST_OBJECT_UNLOCK (pad);
-      if (!setcaps (pad, caps))
-        goto could_not_set;
-      GST_OBJECT_LOCK (pad);
-      GST_OBJECT_FLAG_UNSET (pad, GST_PAD_IN_SETCAPS);
-    } else {
-      GST_CAT_DEBUG_OBJECT (GST_CAT_CAPS, pad, "pad was dispatching");
-    }
-  }
+static gboolean
+do_event_function (GstPad * pad, GstEvent * event,
+    GstPadEventFunction eventfunc)
+{
+  gboolean result = TRUE;
+  GstCaps *caps, *templ;
 
-  gst_caps_replace (&GST_PAD_CAPS (pad), caps);
-  GST_CAT_DEBUG_OBJECT (GST_CAT_CAPS, pad, "caps %p %" GST_PTR_FORMAT, caps,
-      caps);
-  GST_OBJECT_UNLOCK (pad);
+  switch (GST_EVENT_TYPE (event)) {
+    case GST_EVENT_CAPS:
+    {
+      /* backwards compatibility mode for caps */
+      gst_event_parse_caps (event, &caps);
 
-#if GLIB_CHECK_VERSION(2,26,0)
-  g_object_notify_by_pspec ((GObject *) pad, pspec_caps);
-#else
-  g_object_notify ((GObject *) pad, "caps");
-#endif
+      /* See if pad accepts the caps */
+      templ = gst_pad_get_pad_template_caps (pad);
+      if (!gst_caps_can_intersect (caps, templ))
+        goto not_accepted;
 
-  return TRUE;
+      g_object_notify_by_pspec ((GObject *) pad, pspec_caps);
 
-was_ok:
-  {
-    GST_OBJECT_UNLOCK (pad);
-    return TRUE;
-  }
-setting_same_caps:
-  {
-    gst_caps_replace (&GST_PAD_CAPS (pad), caps);
-    GST_CAT_DEBUG_OBJECT (GST_CAT_CAPS, pad,
-        "caps %p %" GST_PTR_FORMAT " same as existing, updating ptr only", caps,
-        caps);
-    GST_OBJECT_UNLOCK (pad);
-    return TRUE;
+      gst_caps_unref (templ);
+      break;
+    }
+    default:
+      break;
   }
 
+  GST_DEBUG_OBJECT (pad, "calling event function with event %p", event);
+  result = eventfunc (pad, event);
+
+  return result;
+
   /* ERRORS */
-could_not_set:
+not_accepted:
   {
-    GST_OBJECT_LOCK (pad);
-    GST_OBJECT_FLAG_UNSET (pad, GST_PAD_IN_SETCAPS);
+    gst_caps_unref (templ);
+    gst_event_unref (event);
     GST_CAT_DEBUG_OBJECT (GST_CAT_CAPS, pad,
-        "caps %" GST_PTR_FORMAT " could not be set", caps);
-    GST_OBJECT_UNLOCK (pad);
-
+        "caps %" GST_PTR_FORMAT " not accepted", caps);
     return FALSE;
   }
 }
 
-static gboolean
-gst_pad_configure_sink (GstPad * pad, GstCaps * caps)
+/* function to send all pending events on the sinkpad to the event
+ * function and collect the results. This function should be called with
+ * the object lock. The object lock might be released by this function.
+ */
+static GstFlowReturn
+gst_pad_update_events (GstPad * pad)
 {
-  gboolean res;
+  GstFlowReturn ret = GST_FLOW_OK;
+  guint i;
+  GstPadEventFunction eventfunc;
+  GstEvent *event;
 
-  /* See if pad accepts the caps */
-  if (!gst_caps_can_intersect (caps, gst_pad_get_pad_template_caps (pad)))
-    goto not_accepted;
+  if (G_UNLIKELY ((eventfunc = GST_PAD_EVENTFUNC (pad)) == NULL))
+    goto no_function;
 
-  /* set caps on pad if call succeeds */
-  res = gst_pad_set_caps (pad, caps);
-  /* no need to unref the caps here, set_caps takes a ref and
-   * our ref goes away when we leave this function. */
+  for (i = 0; i < GST_EVENT_MAX_STICKY; i++) {
+    gboolean res;
+    PadEvent *ev;
 
-  return res;
+    ev = &pad->priv->events[i];
 
-not_accepted:
-  {
-    GST_CAT_DEBUG_OBJECT (GST_CAT_CAPS, pad,
-        "caps %" GST_PTR_FORMAT " not accepted", caps);
-    return FALSE;
-  }
-}
+    /* skip without pending event */
+    if ((event = gst_event_steal (&ev->pending)) == NULL)
+      continue;
 
-/* returns TRUE if the src pad could be configured to accept the given caps */
-static gboolean
-gst_pad_configure_src (GstPad * pad, GstCaps * caps, gboolean dosetcaps)
-{
-  gboolean res;
+    gst_event_ref (event);
+    GST_OBJECT_UNLOCK (pad);
 
-  if (dosetcaps) {
-    /* See if pad accepts the caps */
-    if (!gst_pad_accept_caps (pad, caps))
-      goto not_accepted;
+    res = do_event_function (pad, event, eventfunc);
 
-    res = gst_pad_set_caps (pad, caps);
-  } else {
-    res = TRUE;
+    GST_OBJECT_LOCK (pad);
+    /* things could have changed while we release the lock, check if we still
+     * are handling the same event, if we don't something changed and we have
+     * to try again. FIXME. we need a cookie here. FIXME, we also want to remove
+     * that lock eventually and then do the retry elsewhere. */
+
+    if (res) {
+      /* make the event active */
+      gst_event_take (&ev->event, event);
+    } else {
+      gst_event_unref (event);
+      ret = GST_FLOW_ERROR;
+    }
   }
-  return res;
+  /* when we get here all events were successfully updated. */
 
-not_accepted:
+  return ret;
+
+  /* ERRORS */
+no_function:
   {
-    GST_CAT_DEBUG_OBJECT (GST_CAT_CAPS, pad,
-        "caps %" GST_PTR_FORMAT " not accepted", caps);
-    return FALSE;
+    g_warning ("pad %s:%s has no event handler, file a bug.",
+        GST_DEBUG_PAD_NAME (pad));
+    return GST_FLOW_NOT_SUPPORTED;
   }
 }
 
@@ -2809,10 +2799,10 @@ not_accepted:
  *
  * Gets the capabilities for @pad's template.
  *
- * Returns: (transfer none): the #GstCaps of this pad template. If you intend
- *     to keep a reference on the caps, make a copy (see gst_caps_copy ()).
+ * Returns: (transfer full): the #GstCaps of this pad template.
+ * Unref after usage.
  */
-const GstCaps *
+GstCaps *
 gst_pad_get_pad_template_caps (GstPad * pad)
 {
   static GstStaticCaps anycaps = GST_STATIC_CAPS ("ANY");
@@ -2820,7 +2810,7 @@ gst_pad_get_pad_template_caps (GstPad * pad)
   g_return_val_if_fail (GST_IS_PAD (pad), NULL);
 
   if (GST_PAD_PAD_TEMPLATE (pad))
-    return GST_PAD_TEMPLATE_CAPS (GST_PAD_PAD_TEMPLATE (pad));
+    return gst_pad_template_get_caps (GST_PAD_PAD_TEMPLATE (pad));
 
   return gst_static_caps_get (&anycaps);
 }
@@ -2880,7 +2870,6 @@ gst_pad_get_allowed_caps (GstPad * pad)
   g_return_val_if_fail (GST_IS_PAD (pad), NULL);
 
   GST_OBJECT_LOCK (pad);
-
   peer = GST_PAD_PEER (pad);
   if (G_UNLIKELY (peer == NULL))
     goto no_peer;
@@ -2889,9 +2878,9 @@ gst_pad_get_allowed_caps (GstPad * pad)
 
   gst_object_ref (peer);
   GST_OBJECT_UNLOCK (pad);
-  mycaps = gst_pad_get_caps_reffed (pad);
+  mycaps = gst_pad_get_caps (pad, NULL);
 
-  peercaps = gst_pad_get_caps_reffed (peer);
+  peercaps = gst_pad_get_caps (peer, NULL);
   gst_object_unref (peer);
 
   caps = gst_caps_intersect (mycaps, peercaps);
@@ -2932,7 +2921,7 @@ no_peer:
 GstCaps *
 gst_pad_get_negotiated_caps (GstPad * pad)
 {
-  GstCaps *caps;
+  GstCaps *caps = NULL;
   GstPad *peer;
 
   g_return_val_if_fail (GST_IS_PAD (pad), NULL);
@@ -2944,9 +2933,9 @@ gst_pad_get_negotiated_caps (GstPad * pad)
 
   GST_CAT_DEBUG_OBJECT (GST_CAT_PROPERTIES, pad, "getting negotiated caps");
 
-  caps = GST_PAD_CAPS (pad);
-  if (caps)
+  if ((caps = get_pad_caps (pad)))
     gst_caps_ref (caps);
+
   GST_OBJECT_UNLOCK (pad);
 
   GST_CAT_DEBUG_OBJECT (GST_CAT_CAPS, pad, "negotiated caps %" GST_PTR_FORMAT,
@@ -2958,348 +2947,37 @@ no_peer:
   {
     GST_CAT_DEBUG_OBJECT (GST_CAT_PROPERTIES, pad, "no peer");
     GST_OBJECT_UNLOCK (pad);
-
     return NULL;
   }
 }
 
-/* calls the buffer_alloc function on the given pad */
-static GstFlowReturn
-gst_pad_buffer_alloc_unchecked (GstPad * pad, guint64 offset, gint size,
-    GstCaps * caps, GstBuffer ** buf)
-{
-  GstFlowReturn ret;
-  GstPadBufferAllocFunction bufferallocfunc;
-
-  GST_OBJECT_LOCK (pad);
-  /* when the pad is flushing we cannot give a buffer */
-  if (G_UNLIKELY (GST_PAD_IS_FLUSHING (pad)))
-    goto flushing;
-
-  bufferallocfunc = pad->bufferallocfunc;
-
-  if (offset == GST_BUFFER_OFFSET_NONE) {
-    GST_CAT_DEBUG_OBJECT (GST_CAT_PADS, pad,
-        "calling bufferallocfunc &%s (@%p) for size %d offset NONE",
-        GST_DEBUG_FUNCPTR_NAME (bufferallocfunc), bufferallocfunc, size);
-  } else {
-    GST_CAT_DEBUG_OBJECT (GST_CAT_PADS, pad,
-        "calling bufferallocfunc &%s (@%p) of for size %d offset %"
-        G_GUINT64_FORMAT, GST_DEBUG_FUNCPTR_NAME (bufferallocfunc),
-        bufferallocfunc, size, offset);
-  }
-  GST_OBJECT_UNLOCK (pad);
-
-  /* G_LIKELY for now since most elements don't implement a buffer alloc
-   * function and there is no default alloc proxy function as this is usually
-   * not possible. */
-  if (G_LIKELY (bufferallocfunc == NULL))
-    goto fallback;
-
-  ret = bufferallocfunc (pad, offset, size, caps, buf);
-
-  if (G_UNLIKELY (ret != GST_FLOW_OK))
-    goto error;
-
-  /* no error, but NULL buffer means fallback to the default */
-  if (G_UNLIKELY (*buf == NULL))
-    goto fallback;
-
-  /* If the buffer alloc function didn't set up the caps like it should,
-   * do it for it */
-  if (G_UNLIKELY (caps && (GST_BUFFER_CAPS (*buf) == NULL))) {
-    GST_WARNING_OBJECT (pad,
-        "Buffer allocation function did not set caps. Setting");
-    gst_buffer_set_caps (*buf, caps);
-  }
-  return ret;
-
-flushing:
-  {
-    /* pad was flushing */
-    GST_OBJECT_UNLOCK (pad);
-    GST_CAT_DEBUG_OBJECT (GST_CAT_PADS, pad, "pad was flushing");
-    return GST_FLOW_WRONG_STATE;
-  }
-error:
-  {
-    GST_CAT_DEBUG_OBJECT (GST_CAT_PADS, pad,
-        "alloc function returned error (%d) %s", ret, gst_flow_get_name (ret));
-    return ret;
-  }
-fallback:
-  {
-    /* fallback case, allocate a buffer of our own, add pad caps. */
-    GST_CAT_DEBUG_OBJECT (GST_CAT_PADS, pad, "fallback buffer alloc");
-
-    if ((*buf = gst_buffer_try_new_and_alloc (size))) {
-      GST_BUFFER_OFFSET (*buf) = offset;
-      gst_buffer_set_caps (*buf, caps);
-      return GST_FLOW_OK;
-    } else {
-      GST_CAT_DEBUG_OBJECT (GST_CAT_PADS, pad,
-          "out of memory allocating %d bytes", size);
-      return GST_FLOW_ERROR;
-    }
-  }
-}
-
-/* FIXME 0.11: size should be unsigned */
-static GstFlowReturn
-gst_pad_alloc_buffer_full (GstPad * pad, guint64 offset, gint size,
-    GstCaps * caps, GstBuffer ** buf, gboolean setcaps)
-{
-  GstPad *peer;
-  GstFlowReturn ret;
-  GstCaps *newcaps;
-  gboolean caps_changed;
-
-  g_return_val_if_fail (GST_IS_PAD (pad), GST_FLOW_ERROR);
-  g_return_val_if_fail (GST_PAD_IS_SRC (pad), GST_FLOW_ERROR);
-  g_return_val_if_fail (buf != NULL, GST_FLOW_ERROR);
-  g_return_val_if_fail (size >= 0, GST_FLOW_ERROR);
-
-  GST_DEBUG_OBJECT (pad, "offset %" G_GUINT64_FORMAT ", size %d, caps %"
-      GST_PTR_FORMAT, offset, size, caps);
-
-  GST_OBJECT_LOCK (pad);
-  while (G_UNLIKELY (GST_PAD_IS_BLOCKED (pad)))
-    if ((ret = handle_pad_block (pad)) != GST_FLOW_OK)
-      goto flushed;
-
-  if (G_UNLIKELY ((peer = GST_PAD_PEER (pad)) == NULL))
-    goto no_peer;
-
-  gst_object_ref (peer);
-  GST_OBJECT_UNLOCK (pad);
-
-  ret = gst_pad_buffer_alloc_unchecked (peer, offset, size, caps, buf);
-  gst_object_unref (peer);
-
-  if (G_UNLIKELY (ret != GST_FLOW_OK))
-    goto peer_error;
-
-  /* FIXME, move capnego this into a base class? */
-  newcaps = GST_BUFFER_CAPS (*buf);
-
-  /* Lock for checking caps, pretty pointless as the _pad_push() function might
-   * change it concurrently, one of the problems with automatic caps setting in
-   * pad_alloc_and_set_caps. Worst case, if does a check too much, but only
-   * when there is heavy renegotiation going on in both directions. */
-  GST_OBJECT_LOCK (pad);
-  caps_changed = newcaps && newcaps != GST_PAD_CAPS (pad);
-  GST_OBJECT_UNLOCK (pad);
-
-  /* we got a new datatype on the pad, see if it can handle it */
-  if (G_UNLIKELY (caps_changed)) {
-    GST_DEBUG_OBJECT (pad,
-        "caps changed from %" GST_PTR_FORMAT " to %p %" GST_PTR_FORMAT,
-        GST_PAD_CAPS (pad), newcaps, newcaps);
-    if (G_UNLIKELY (!gst_pad_configure_src (pad, newcaps, setcaps)))
-      goto not_negotiated;
-  }
-
-  /* sanity check (only if caps are the same) */
-  if (G_LIKELY (newcaps == caps) && G_UNLIKELY (GST_BUFFER_SIZE (*buf) < size))
-    goto wrong_size_fallback;
-
-  return ret;
-
-flushed:
-  {
-    GST_CAT_DEBUG_OBJECT (GST_CAT_PADS, pad, "pad block stopped by flush");
-    GST_OBJECT_UNLOCK (pad);
-    return ret;
-  }
-no_peer:
-  {
-    /* pad has no peer */
-    GST_CAT_DEBUG_OBJECT (GST_CAT_PADS, pad,
-        "called bufferallocfunc but had no peer");
-    GST_OBJECT_UNLOCK (pad);
-    return GST_FLOW_NOT_LINKED;
-  }
-peer_error:
-  {
-    GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad,
-        "alloc function returned error %s", gst_flow_get_name (ret));
-    return ret;
-  }
-not_negotiated:
-  {
-    gst_buffer_unref (*buf);
-    *buf = NULL;
-    GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad,
-        "alloc function returned unacceptable buffer");
-    return GST_FLOW_NOT_NEGOTIATED;
-  }
-wrong_size_fallback:
-  {
-    GST_CAT_ERROR_OBJECT (GST_CAT_PADS, pad, "buffer returned by alloc "
-        "function is too small (%u < %d), doing fallback buffer alloc",
-        GST_BUFFER_SIZE (*buf), size);
-
-    gst_buffer_unref (*buf);
-
-    if ((*buf = gst_buffer_try_new_and_alloc (size))) {
-      GST_BUFFER_OFFSET (*buf) = offset;
-      gst_buffer_set_caps (*buf, caps);
-      return GST_FLOW_OK;
-    } else {
-      GST_CAT_DEBUG_OBJECT (GST_CAT_PADS, pad,
-          "out of memory allocating %d bytes", size);
-      return GST_FLOW_ERROR;
-    }
-  }
-}
-
-/**
- * gst_pad_alloc_buffer:
- * @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
- *
- * Allocates a new, empty buffer optimized to push to pad @pad.  This
- * function only works if @pad is a source pad and has a peer.
- *
- * A new, empty #GstBuffer will be put in the @buf argument.
- * You need to check the caps of the buffer after performing this
- * function and renegotiate to the format if needed. If the caps changed, it is
- * possible that the buffer returned in @buf is not of the right size for the
- * new format, @buf needs to be unreffed and reallocated if this is the case.
- *
- * 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.
- *
- * MT safe.
- */
-
-/* FIXME 0.11: size should be unsigned */
-GstFlowReturn
-gst_pad_alloc_buffer (GstPad * pad, guint64 offset, gint size, GstCaps * caps,
-    GstBuffer ** buf)
-{
-  return gst_pad_alloc_buffer_full (pad, offset, size, caps, buf, FALSE);
-}
-
-/**
- * gst_pad_alloc_buffer_and_set_caps:
- * @pad: a source #GstPad
- * @offset: the offset of the new buffer in the stream
- * @size: the size of the new buffer
- * @caps: (transfer none): the caps of the new buffer
- * @buf: (out callee-allocates): a newly allocated buffer
- *
- * In addition to the function gst_pad_alloc_buffer(), this function
- * automatically calls gst_pad_set_caps() when the caps of the
- * newly allocated buffer are different from the @pad caps.
- *
- * After a renegotiation, the size of the new buffer returned in @buf could
- * be of the wrong size for the new format and must be unreffed an reallocated
- * in that case.
- *
- * 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.
- *
- * MT safe.
- */
-
-/* FIXME 0.11: size should be unsigned */
-GstFlowReturn
-gst_pad_alloc_buffer_and_set_caps (GstPad * pad, guint64 offset, gint size,
-    GstCaps * caps, GstBuffer ** buf)
-{
-  return gst_pad_alloc_buffer_full (pad, offset, size, caps, buf, TRUE);
-}
-
-
-#ifndef GST_REMOVE_DEPRECATED
-typedef struct
-{
-  GList *list;
-  guint32 cookie;
-} IntLinkIterData;
-
-static void
-int_link_iter_data_free (IntLinkIterData * data)
-{
-  g_list_free (data->list);
-  g_slice_free (IntLinkIterData, data);
-}
-#endif
-
-static GstIteratorItem
-iterate_pad (GstIterator * it, GstPad * pad)
-{
-  gst_object_ref (pad);
-  return GST_ITERATOR_ITEM_PASS;
-}
-
-/**
- * gst_pad_iterate_internal_links_default:
- * @pad: the #GstPad to get the internal links of.
- *
- * Iterate the list of pads to which the given pad is linked to inside of
- * the parent element.
- * This is the default handler, and thus returns an iterator of all of the
- * pads inside the parent element with opposite direction.
- *
- * The caller must free this iterator after use with gst_iterator_free().
- *
- * Returns: a #GstIterator of #GstPad, or NULL if @pad has no parent. Unref each
- * returned pad with gst_object_unref().
- *
- * Since: 0.10.21
- */
-GstIterator *
-gst_pad_iterate_internal_links_default (GstPad * pad)
+/**
+ * gst_pad_iterate_internal_links_default:
+ * @pad: the #GstPad to get the internal links of.
+ *
+ * Iterate the list of pads to which the given pad is linked to inside of
+ * the parent element.
+ * This is the default handler, and thus returns an iterator of all of the
+ * pads inside the parent element with opposite direction.
+ *
+ * The caller must free this iterator after use with gst_iterator_free().
+ *
+ * Returns: a #GstIterator of #GstPad, or NULL if @pad has no parent. Unref each
+ * returned pad with gst_object_unref().
+ *
+ * Since: 0.10.21
+ */
+GstIterator *
+gst_pad_iterate_internal_links_default (GstPad * pad)
 {
   GstIterator *res;
   GList **padlist;
   guint32 *cookie;
   GMutex *lock;
   gpointer owner;
-  GstIteratorDisposeFunction dispose;
 
   g_return_val_if_fail (GST_IS_PAD (pad), NULL);
 
-#ifndef GST_REMOVE_DEPRECATED
-  /* when we get here, the default handler for the iterate links is called,
-   * which means that the user has not installed a custom one. We first check if
-   * there is maybe a custom legacy function we can call. */
-  if (GST_PAD_INTLINKFUNC (pad) &&
-      GST_PAD_INTLINKFUNC (pad) != gst_pad_get_internal_links_default) {
-    IntLinkIterData *data;
-
-    /* make an iterator for the list. We can't protect the list with a
-     * cookie. If we would take the cookie of the parent element, we need to
-     * have a parent, which is not required for GST_PAD_INTLINKFUNC(). We could
-     * cache the per-pad list and invalidate the list when a new call to
-     * INTLINKFUNC() returned a different list but then this would only work if
-     * two concurrent iterators were used and the last iterator would still be
-     * thread-unsafe. Just don't use this method anymore. */
-    data = g_slice_new (IntLinkIterData);
-    data->list = ((GstPadIntLinkFunction) GST_PAD_INTLINKFUNC (pad)) (pad);
-    data->cookie = 0;
-
-    GST_WARNING_OBJECT (pad, "Making unsafe iterator");
-
-    cookie = &data->cookie;
-    padlist = &data->list;
-    owner = data;
-    dispose = (GstIteratorDisposeFunction) int_link_iter_data_free;
-    /* reuse the pad lock, it's all we have here */
-    lock = GST_OBJECT_GET_LOCK (pad);
-  } else
-#endif
   {
     GstElement *parent;
 
@@ -3320,13 +2998,13 @@ gst_pad_iterate_internal_links_default (GstPad * pad)
 
     cookie = &parent->pads_cookie;
     owner = parent;
-    dispose = (GstIteratorDisposeFunction) gst_object_unref;
     lock = GST_OBJECT_GET_LOCK (parent);
   }
 
   res = gst_iterator_new_list (GST_TYPE_PAD,
-      lock, cookie, padlist, owner, (GstIteratorItemFunction) iterate_pad,
-      dispose);
+      lock, cookie, padlist, (GObject *) owner, NULL);
+
+  gst_object_unref (owner);
 
   return res;
 
@@ -3370,166 +3048,30 @@ gst_pad_iterate_internal_links (GstPad * pad)
   return res;
 }
 
-#ifndef GST_REMOVE_DEPRECATED
-static void
-add_unref_pad_to_list (GstPad * pad, GList ** list)
-{
-  *list = g_list_prepend (*list, pad);
-  gst_object_unref (pad);
-}
-#endif
-
 /**
- * gst_pad_get_internal_links_default:
- * @pad: the #GstPad to get the internal links of.
- *
- * Gets a list of pads to which the given pad is linked to
- * inside of the parent element.
- * This is the default handler, and thus returns a list of all of the
- * pads inside the parent element with opposite direction.
- *
- * The caller must free this list after use with g_list_free().
+ * gst_pad_forward:
+ * @pad: a #GstPad
+ * @forward: a #GstPadForwardFunction
+ * @user_data: user data passed to @forward
  *
- * Returns: (transfer full) (element-type Gst.Pad): a newly allocated #GList
- *     of pads, or NULL if the pad has no parent.
+ * Calls @forward for all internally linked pads of @pad. This function deals with
+ * dynamically changing internal pads and will make sure that the @forward
+ * function is only called once for each pad.
  *
- * Not MT safe.
+ * When @forward returns TRUE, no further pads will be processed.
  *
- * Deprecated: This function does not ref the pads in the list so that they
- * could become invalid by the time the application accesses them. It's also
- * possible that the list changes while handling the pads, which the caller of
- * this function is unable to know. Use the thread-safe
- * gst_pad_iterate_internal_links_default() instead.
- */
-#ifndef GST_REMOVE_DEPRECATED
-GList *
-gst_pad_get_internal_links_default (GstPad * pad)
-{
-  GList *res = NULL;
-  GstElement *parent;
-
-  g_return_val_if_fail (GST_IS_PAD (pad), NULL);
-
-  GST_WARNING_OBJECT (pad, "Unsafe internal links used");
-
-  /* when we get here, the default handler for get_internal_links is called,
-   * which means that the user has not installed a custom one. We first check if
-   * there is maybe a custom iterate function we can call. */
-  if (GST_PAD_ITERINTLINKFUNC (pad) &&
-      GST_PAD_ITERINTLINKFUNC (pad) != gst_pad_iterate_internal_links_default) {
-    GstIterator *it;
-    GstIteratorResult ires;
-    gboolean done = FALSE;
-
-    it = gst_pad_iterate_internal_links (pad);
-    /* loop over the iterator and put all elements into a list, we also
-     * immediatly unref them, which is bad. */
-    do {
-      ires = gst_iterator_foreach (it, (GFunc) add_unref_pad_to_list, &res);
-      switch (ires) {
-        case GST_ITERATOR_OK:
-        case GST_ITERATOR_DONE:
-        case GST_ITERATOR_ERROR:
-          done = TRUE;
-          break;
-        case GST_ITERATOR_RESYNC:
-          /* restart, discard previous list */
-          gst_iterator_resync (it);
-          g_list_free (res);
-          res = NULL;
-          break;
-      }
-    } while (!done);
-
-    gst_iterator_free (it);
-  } else {
-    /* lock pad, check and ref parent */
-    GST_OBJECT_LOCK (pad);
-    parent = GST_PAD_PARENT (pad);
-    if (!parent || !GST_IS_ELEMENT (parent))
-      goto no_parent;
-
-    parent = gst_object_ref (parent);
-    GST_OBJECT_UNLOCK (pad);
-
-    /* now lock the parent while we copy the pads */
-    GST_OBJECT_LOCK (parent);
-    if (pad->direction == GST_PAD_SRC)
-      res = g_list_copy (parent->sinkpads);
-    else
-      res = g_list_copy (parent->srcpads);
-    GST_OBJECT_UNLOCK (parent);
-
-    gst_object_unref (parent);
-  }
-
-  /* At this point pads can be changed and unreffed. Nothing we can do about it
-   * because for compatibility reasons this function cannot ref the pads or
-   * notify the app that the list changed. */
-
-  return res;
-
-no_parent:
-  {
-    GST_DEBUG_OBJECT (pad, "no parent");
-    GST_OBJECT_UNLOCK (pad);
-    return NULL;
-  }
-}
-#endif /* GST_REMOVE_DEPRECATED */
-
-/**
- * gst_pad_get_internal_links:
- * @pad: the #GstPad to get the internal links of.
- *
- * Gets a list of pads to which the given pad is linked to
- * inside of the parent element.
- * The caller must free this list after use.
- *
- * Not MT safe.
- *
- * Returns: (transfer full) (element-type Gst.Pad): a newly allocated #GList
- *     of pads, free with g_list_free().
- *
- * Deprecated: This function does not ref the pads in the list so that they
- * could become invalid by the time the application accesses them. It's also
- * possible that the list changes while handling the pads, which the caller of
- * this function is unable to know. Use the thread-safe
- * gst_pad_iterate_internal_links() instead.
+ * Returns: TRUE if one of the dispatcher functions returned TRUE.
  */
-#ifndef GST_REMOVE_DEPRECATED
-#ifdef GST_DISABLE_DEPRECATED
-GList *gst_pad_get_internal_links (GstPad * pad);
-#endif
-GList *
-gst_pad_get_internal_links (GstPad * pad)
-{
-  GList *res = NULL;
-
-  g_return_val_if_fail (GST_IS_PAD (pad), NULL);
-
-  GST_WARNING_OBJECT (pad, "Calling unsafe internal links");
-
-  if (GST_PAD_INTLINKFUNC (pad))
-    res = ((GstPadIntLinkFunction) GST_PAD_INTLINKFUNC (pad)) (pad);
-
-  return res;
-}
-#endif /* GST_REMOVE_DEPRECATED */
-
-static gboolean
-gst_pad_event_default_dispatch (GstPad * pad, GstEvent * event)
+gboolean
+gst_pad_forward (GstPad * pad, GstPadForwardFunction forward,
+    gpointer user_data)
 {
   gboolean result = FALSE;
   GstIterator *iter;
   gboolean done = FALSE;
-  gpointer item;
-  GstPad *eventpad;
+  GValue item = { 0, };
   GList *pushed_pads = NULL;
 
-  GST_INFO_OBJECT (pad, "Sending event %p (%s) to all internally linked pads",
-      event, GST_EVENT_TYPE_NAME (event));
-
   iter = gst_pad_iterate_internal_links (pad);
 
   if (!iter)
@@ -3538,37 +3080,26 @@ gst_pad_event_default_dispatch (GstPad * pad, GstEvent * event)
   while (!done) {
     switch (gst_iterator_next (iter, &item)) {
       case GST_ITERATOR_OK:
-        eventpad = GST_PAD_CAST (item);
+      {
+        GstPad *intpad;
 
-        /* if already pushed,  skip */
-        if (g_list_find (pushed_pads, eventpad)) {
-          gst_object_unref (item);
+        intpad = g_value_get_object (&item);
+
+        /* if already pushed, skip. FIXME, find something faster to tag pads */
+        if (g_list_find (pushed_pads, intpad)) {
+          g_value_reset (&item);
           break;
         }
 
-        if (GST_PAD_IS_SRC (eventpad)) {
-          /* for each pad we send to, we should ref the event; it's up
-           * to downstream to unref again when handled. */
-          GST_LOG_OBJECT (pad, "Reffing and sending event %p (%s) to %s:%s",
-              event, GST_EVENT_TYPE_NAME (event),
-              GST_DEBUG_PAD_NAME (eventpad));
-          gst_event_ref (event);
-          result |= gst_pad_push_event (eventpad, event);
-        } else {
-          /* we only send the event on one pad, multi-sinkpad elements
-           * should implement a handler */
-          GST_LOG_OBJECT (pad, "sending event %p (%s) to one sink pad %s:%s",
-              event, GST_EVENT_TYPE_NAME (event),
-              GST_DEBUG_PAD_NAME (eventpad));
-          result = gst_pad_push_event (eventpad, event);
-          done = TRUE;
-          event = NULL;
-        }
+        GST_LOG_OBJECT (pad, "calling forward function on pad %s:%s",
+            GST_DEBUG_PAD_NAME (intpad));
+        done = result = forward (intpad, user_data);
 
-        pushed_pads = g_list_prepend (pushed_pads, eventpad);
+        pushed_pads = g_list_prepend (pushed_pads, intpad);
 
-        gst_object_unref (item);
+        g_value_reset (&item);
         break;
+      }
       case GST_ITERATOR_RESYNC:
         /* We don't reset the result here because we don't push the event
          * again on pads that got the event already and because we need
@@ -3584,25 +3115,36 @@ gst_pad_event_default_dispatch (GstPad * pad, GstEvent * event)
         break;
     }
   }
+  g_value_unset (&item);
   gst_iterator_free (iter);
 
+  g_list_free (pushed_pads);
+
 no_iter:
+  return result;
+}
 
-  /* If this is a sinkpad and we don't have pads to send the event to, we
-   * return TRUE. This is so that when using the default handler on a sink
-   * element, we don't fail to push it. */
-  if (!pushed_pads)
-    result = GST_PAD_IS_SINK (pad);
+typedef struct
+{
+  GstEvent *event;
+  gboolean result;
+  gboolean dispatched;
+} EventData;
 
-  g_list_free (pushed_pads);
+static gboolean
+event_forward_func (GstPad * pad, EventData * data)
+{
+  /* for each pad we send to, we should ref the event; it's up
+   * to downstream to unref again when handled. */
+  GST_LOG_OBJECT (pad, "Reffing and pushing event %p (%s) to %s:%s",
+      data->event, GST_EVENT_TYPE_NAME (data->event), GST_DEBUG_PAD_NAME (pad));
 
-  /* we handled the incoming event so we unref once */
-  if (event) {
-    GST_LOG_OBJECT (pad, "handled event %p, unreffing", event);
-    gst_event_unref (event);
-  }
+  data->result |= gst_pad_push_event (pad, gst_event_ref (data->event));
 
-  return result;
+  data->dispatched = TRUE;
+
+  /* don't stop */
+  return FALSE;
 }
 
 /**
@@ -3610,17 +3152,24 @@ no_iter:
  * @pad: a #GstPad to call the default event handler on.
  * @event: (transfer full): the #GstEvent to handle.
  *
- * Invokes the default event handler for the given pad. End-of-stream and
- * discontinuity events are handled specially, and then the event is sent to all
- * pads internally linked to @pad. Note that if there are many possible sink
- * pads that are internally linked to @pad, only one will be sent an event.
- * Multi-sinkpad elements should implement custom event handlers.
+ * Invokes the default event handler for the given pad.
+ *
+ * The EOS event will pause the task associated with @pad before it is forwarded
+ * to all internally linked pads,
+ *
+ * The CAPS event will never be forwarded.
+ *
+ * The the event is sent to all pads internally linked to @pad. This function
+ * takes ownership of @event.
  *
  * Returns: TRUE if the event was sent succesfully.
  */
 gboolean
 gst_pad_event_default (GstPad * pad, GstEvent * event)
 {
+  gboolean result;
+  EventData data;
+
   g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
   g_return_val_if_fail (event != NULL, FALSE);
 
@@ -3631,82 +3180,28 @@ gst_pad_event_default (GstPad * pad, GstEvent * event)
     {
       GST_DEBUG_OBJECT (pad, "pausing task because of eos");
       gst_pad_pause_task (pad);
+      break;
     }
-      /* fall thru */
     default:
       break;
   }
 
-  return gst_pad_event_default_dispatch (pad, event);
-}
-
-/**
- * gst_pad_dispatcher:
- * @pad: a #GstPad to dispatch.
- * @dispatch: the #GstPadDispatcherFunction to call.
- * @data: (closure): gpointer user data passed to the dispatcher function.
- *
- * Invokes the given dispatcher function on each respective peer of
- * all pads that are internally linked to the given pad.
- * The GstPadDispatcherFunction should return TRUE when no further pads
- * need to be processed.
- *
- * Returns: TRUE if one of the dispatcher functions returned TRUE.
- */
-gboolean
-gst_pad_dispatcher (GstPad * pad, GstPadDispatcherFunction dispatch,
-    gpointer data)
-{
-  gboolean res = FALSE;
-  GstIterator *iter = NULL;
-  gboolean done = FALSE;
-  gpointer item;
-
-  g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
-  g_return_val_if_fail (dispatch != NULL, FALSE);
-
-  iter = gst_pad_iterate_internal_links (pad);
+  data.event = event;
+  data.dispatched = FALSE;
+  data.result = FALSE;
 
-  if (!iter)
-    goto no_iter;
-
-  while (!done) {
-    switch (gst_iterator_next (iter, &item)) {
-      case GST_ITERATOR_OK:
-      {
-        GstPad *int_pad = GST_PAD_CAST (item);
-        GstPad *int_peer = gst_pad_get_peer (int_pad);
-
-        if (int_peer) {
-          GST_DEBUG_OBJECT (int_pad, "dispatching to peer %s:%s",
-              GST_DEBUG_PAD_NAME (int_peer));
-          done = res = dispatch (int_peer, data);
-          gst_object_unref (int_peer);
-        } else {
-          GST_DEBUG_OBJECT (int_pad, "no peer");
-        }
-      }
-        gst_object_unref (item);
-        break;
-      case GST_ITERATOR_RESYNC:
-        gst_iterator_resync (iter);
-        break;
-      case GST_ITERATOR_ERROR:
-        done = TRUE;
-        GST_ERROR_OBJECT (pad, "Could not iterate internally linked pads");
-        break;
-      case GST_ITERATOR_DONE:
-        done = TRUE;
-        break;
-    }
-  }
-  gst_iterator_free (iter);
+  gst_pad_forward (pad, (GstPadForwardFunction) event_forward_func, &data);
 
-  GST_DEBUG_OBJECT (pad, "done, result %d", res);
+  /* for sinkpads without a parent element or without internal links, nothing
+   * will be dispatched but we still want to return TRUE. */
+  if (data.dispatched)
+    result = data.result;
+  else
+    result = TRUE;
 
-no_iter:
+  gst_event_unref (event);
 
-  return res;
+  return result;
 }
 
 /**
@@ -3730,17 +3225,24 @@ no_iter:
 gboolean
 gst_pad_query (GstPad * pad, GstQuery * query)
 {
+  gboolean res;
   GstPadQueryFunction func;
 
   g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
   g_return_val_if_fail (GST_IS_QUERY (query), FALSE);
 
-  GST_DEBUG_OBJECT (pad, "sending query %p", query);
+  GST_DEBUG_OBJECT (pad, "sending query %p (%s)", query,
+      GST_QUERY_TYPE_NAME (query));
 
   if ((func = GST_PAD_QUERYFUNC (pad)) == NULL)
     goto no_func;
 
-  return func (pad, query);
+  res = func (pad, query);
+
+  GST_DEBUG_OBJECT (pad, "sent query %p (%s), result %d", query,
+      GST_QUERY_TYPE_NAME (query), res);
+
+  return res;
 
 no_func:
   {
@@ -3775,7 +3277,8 @@ gst_pad_peer_query (GstPad * pad, GstQuery * query)
 
   GST_OBJECT_LOCK (pad);
 
-  GST_DEBUG_OBJECT (pad, "peer query");
+  GST_DEBUG_OBJECT (pad, "peer query %p (%s)", query,
+      GST_QUERY_TYPE_NAME (query));
 
   peerpad = GST_PAD_PEER (pad);
   if (G_UNLIKELY (peerpad == NULL))
@@ -3815,7 +3318,12 @@ no_peer:
 gboolean
 gst_pad_query_default (GstPad * pad, GstQuery * query)
 {
+  gboolean forward = TRUE, ret = FALSE;
+
   switch (GST_QUERY_TYPE (query)) {
+    case GST_QUERY_SCHEDULING:
+      forward = FALSE;
+      break;
     case GST_QUERY_POSITION:
     case GST_QUERY_SEEKING:
     case GST_QUERY_FORMATS:
@@ -3824,373 +3332,268 @@ gst_pad_query_default (GstPad * pad, GstQuery * query)
     case GST_QUERY_RATE:
     case GST_QUERY_CONVERT:
     default:
-      return gst_pad_dispatcher
-          (pad, (GstPadDispatcherFunction) gst_pad_query, query);
+      break;
+  }
+
+  if (forward) {
+    ret = gst_pad_forward
+        (pad, (GstPadForwardFunction) gst_pad_peer_query, query);
   }
+  return ret;
 }
 
-#if !defined(GST_DISABLE_LOADSAVE) && !defined(GST_REMOVE_DEPRECATED)
-/* FIXME: why isn't this on a GstElement ? */
-/**
- * gst_pad_load_and_link:
- * @self: an #xmlNodePtr to read the description from.
- * @parent: the #GstObject element that owns the pad.
- *
- * Reads the pad definition from the XML node and links the given pad
- * in the element to a pad of an element up in the hierarchy.
- */
-void
-gst_pad_load_and_link (xmlNodePtr self, GstObject * parent)
+static void
+probe_hook_marshal (GHook * hook, ProbeMarshall * data)
 {
-  xmlNodePtr field = self->xmlChildrenNode;
-  GstPad *pad = NULL, *targetpad;
-  GstPadTemplate *tmpl;
-  gchar *peer = NULL;
-  gchar **split;
-  GstElement *target;
-  GstObject *grandparent;
-  gchar *name = NULL;
-
-  while (field) {
-    if (!strcmp ((char *) field->name, "name")) {
-      name = (gchar *) xmlNodeGetContent (field);
-      pad = gst_element_get_static_pad (GST_ELEMENT (parent), name);
-      if ((!pad) || ((tmpl = gst_pad_get_pad_template (pad))
-              && (GST_PAD_REQUEST == GST_PAD_TEMPLATE_PRESENCE (tmpl))))
-        pad = gst_element_get_request_pad (GST_ELEMENT (parent), name);
-      g_free (name);
-    } else if (!strcmp ((char *) field->name, "peer")) {
-      peer = (gchar *) xmlNodeGetContent (field);
-    }
-    field = field->next;
-  }
-  g_return_if_fail (pad != NULL);
+  GstPad *pad = data->pad;
+  GstProbeType flags;
+  GstPadProbeCallback callback;
+  GstProbeReturn ret;
 
-  if (peer == NULL)
+  /* if we have called this callback, do nothing */
+  if (PROBE_COOKIE (hook) == data->cookie)
     return;
 
-  split = g_strsplit (peer, ".", 2);
+  PROBE_COOKIE (hook) = data->cookie;
 
-  if (split[0] == NULL || split[1] == NULL) {
-    GST_CAT_DEBUG_OBJECT (GST_CAT_XML, pad,
-        "Could not parse peer '%s', leaving unlinked", peer);
+  flags = hook->flags >> G_HOOK_FLAG_USER_SHIFT;
 
-    g_free (peer);
+  /* one of the data types */
+  if ((flags & GST_PROBE_TYPE_DATA & data->mask) == 0)
+    return;
+  /* one of the scheduling types */
+  if ((flags & GST_PROBE_TYPE_SCHEDULING & data->mask) == 0)
+    return;
+  /* all of the blocking types must match */
+  if ((flags & GST_PROBE_TYPE_BLOCKING) !=
+      (data->mask & GST_PROBE_TYPE_BLOCKING))
     return;
-  }
-  g_free (peer);
-
-  g_return_if_fail (split[0] != NULL);
-  g_return_if_fail (split[1] != NULL);
-
-  grandparent = gst_object_get_parent (parent);
 
-  if (grandparent && GST_IS_BIN (grandparent)) {
-    target = gst_bin_get_by_name_recurse_up (GST_BIN (grandparent), split[0]);
-  } else
-    goto cleanup;
+  GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad,
+      "hook %lu with flags 0x%08x matches", hook->hook_id, flags);
 
-  if (target == NULL)
-    goto cleanup;
+  callback = (GstPadProbeCallback) hook->func;
+  if (callback == NULL)
+    return;
 
-  targetpad = gst_element_get_static_pad (target, split[1]);
-  if (!targetpad)
-    targetpad = gst_element_get_request_pad (target, split[1]);
+  GST_OBJECT_UNLOCK (pad);
 
-  if (targetpad == NULL)
-    goto cleanup;
+  ret = callback (pad, data->mask, data->type_data, hook->data);
 
-  if (gst_pad_get_direction (pad) == GST_PAD_SRC)
-    gst_pad_link (pad, targetpad);
-  else
-    gst_pad_link (targetpad, pad);
+  GST_OBJECT_LOCK (pad);
 
-cleanup:
-  g_strfreev (split);
+  switch (ret) {
+    case GST_PROBE_REMOVE:
+      /* remove the probe */
+      GST_DEBUG_OBJECT (pad, "asked to remove hook");
+      cleanup_hook (pad, hook);
+      break;
+    case GST_PROBE_DROP:
+      /* need to drop the data, make sure other probes don't get called
+       * anymore */
+      GST_DEBUG_OBJECT (pad, "asked to drop item");
+      data->mask = GST_PROBE_TYPE_INVALID;
+      data->ret = GST_PROBE_DROP;
+      break;
+    case GST_PROBE_PASS:
+      /* inform the pad block to let things pass */
+      GST_DEBUG_OBJECT (pad, "asked to pass item");
+      data->pass = TRUE;
+      break;
+    default:
+      GST_DEBUG_OBJECT (pad, "probe returned %d", ret);
+      break;
+  }
 }
 
-/**
- * gst_pad_save_thyself:
- * @pad: a #GstPad to save.
- * @parent: the parent #xmlNodePtr to save the description in.
- *
- * Saves the pad into an xml representation.
- *
- * Returns: the #xmlNodePtr representation of the pad.
- */
-static xmlNodePtr
-gst_pad_save_thyself (GstObject * object, xmlNodePtr parent)
+#define PROBE(pad,mask,data,label)                \
+  G_STMT_START {                                  \
+    if (G_UNLIKELY (pad->num_probes)) {           \
+      ret = do_probe_callbacks (pad, mask, data); \
+      if (G_UNLIKELY (ret != GST_FLOW_OK))        \
+        goto label;                               \
+    }                                             \
+  } G_STMT_END
+
+static GstFlowReturn
+do_probe_callbacks (GstPad * pad, GstProbeType mask, gpointer type_data)
 {
-  GstPad *pad;
-  GstPad *peer;
+  ProbeMarshall data;
+  guint cookie;
 
-  g_return_val_if_fail (GST_IS_PAD (object), NULL);
+  data.pad = pad;
+  data.mask = mask;
+  data.type_data = type_data;
+  data.ret = GST_PROBE_OK;
+  data.pass = FALSE;
+  data.cookie = pad->priv->probe_cookie++;
 
-  pad = GST_PAD_CAST (object);
+again:
+  cookie = pad->priv->probe_cookie;
 
-  xmlNewChild (parent, NULL, (xmlChar *) "name",
-      (xmlChar *) GST_PAD_NAME (pad));
+  g_hook_list_marshal (&pad->probes, FALSE,
+      (GHookMarshaller) probe_hook_marshal, &data);
 
-  if (GST_PAD_IS_SRC (pad)) {
-    xmlNewChild (parent, NULL, (xmlChar *) "direction", (xmlChar *) "source");
-  } else if (GST_PAD_IS_SINK (pad)) {
-    xmlNewChild (parent, NULL, (xmlChar *) "direction", (xmlChar *) "sink");
-  } else {
-    xmlNewChild (parent, NULL, (xmlChar *) "direction", (xmlChar *) "unknown");
+  /* if the list changed, call the new callbacks (they will not have their
+   * cookie set to data.cookie */
+  if (cookie != pad->priv->probe_cookie) {
+    GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad,
+        "probe list changed, restarting");
+    goto again;
   }
 
-  if (GST_PAD_PEER (pad) != NULL) {
-    gchar *content;
+  if (data.ret == GST_PROBE_DROP)
+    goto dropped;
 
-    peer = GST_PAD_PEER (pad);
-    /* first check to see if the peer's parent's parent is the same */
-    /* we just save it off */
-    content = g_strdup_printf ("%s.%s",
-        GST_OBJECT_NAME (GST_PAD_PARENT (peer)), GST_PAD_NAME (peer));
-    xmlNewChild (parent, NULL, (xmlChar *) "peer", (xmlChar *) content);
-    g_free (content);
-  } else
-    xmlNewChild (parent, NULL, (xmlChar *) "peer", NULL);
+  if (data.pass)
+    goto passed;
+
+  if (mask & GST_PROBE_TYPE_BLOCK) {
+    while (GST_PAD_IS_BLOCKED (pad)) {
+      GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad,
+          "we are blocked %d times", pad->num_blocked);
+
+      /* we might have released the lock */
+      if (G_UNLIKELY (GST_PAD_IS_FLUSHING (pad)))
+        goto flushing;
+
+      /* now we block the streaming thread. It can be unlocked when we
+       * deactivate the pad (which will also set the FLUSHING flag) or
+       * when the pad is unblocked. A flushing event will also unblock
+       * the pad after setting the FLUSHING flag. */
+      GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad,
+          "Waiting to be unblocked or set flushing");
+      GST_OBJECT_FLAG_SET (pad, GST_PAD_BLOCKING);
+      GST_PAD_BLOCK_WAIT (pad);
+      GST_OBJECT_FLAG_UNSET (pad, GST_PAD_BLOCKING);
+      GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad, "We got unblocked");
+
+      if (G_UNLIKELY (GST_PAD_IS_FLUSHING (pad)))
+        goto flushing;
+    }
+  }
+
+  return GST_FLOW_OK;
 
-  return parent;
+  /* ERRORS */
+flushing:
+  {
+    GST_DEBUG_OBJECT (pad, "pad is flushing");
+    return GST_FLOW_WRONG_STATE;
+  }
+dropped:
+  {
+    GST_DEBUG_OBJECT (pad, "data is dropped");
+    return GST_FLOW_CUSTOM_SUCCESS;
+  }
+passed:
+  {
+    GST_DEBUG_OBJECT (pad, "data is passed");
+    return GST_FLOW_OK;
+  }
 }
 
-#if 0
+/* pad offsets */
+
 /**
- * gst_ghost_pad_save_thyself:
- * @pad: a ghost #GstPad to save.
- * @parent: the parent #xmlNodePtr to save the description in.
+ * gst_pad_get_offset:
+ * @pad: a #GstPad
  *
- * Saves the ghost pad into an xml representation.
+ * Get the offset applied to the running time of @pad. @pad has to be a source
+ * pad.
  *
- * Returns: the #xmlNodePtr representation of the pad.
+ * Returns: the offset.
  */
-xmlNodePtr
-gst_ghost_pad_save_thyself (GstPad * pad, xmlNodePtr parent)
+gint64
+gst_pad_get_offset (GstPad * pad)
 {
-  xmlNodePtr self;
-
-  g_return_val_if_fail (GST_IS_GHOST_PAD (pad), NULL);
+  gint64 result;
 
-  self = xmlNewChild (parent, NULL, (xmlChar *) "ghostpad", NULL);
-  xmlNewChild (self, NULL, (xmlChar *) "name", (xmlChar *) GST_PAD_NAME (pad));
-  xmlNewChild (self, NULL, (xmlChar *) "parent",
-      (xmlChar *) GST_OBJECT_NAME (GST_PAD_PARENT (pad)));
+  g_return_val_if_fail (GST_IS_PAD (pad), 0);
 
-  /* FIXME FIXME FIXME! */
+  GST_OBJECT_LOCK (pad);
+  result = pad->offset;
+  GST_OBJECT_UNLOCK (pad);
 
-  return self;
+  return result;
 }
-#endif /* 0 */
-#endif /* GST_DISABLE_LOADSAVE */
-
-/*
- * should be called with pad OBJECT_LOCK and STREAM_LOCK held.
- * GST_PAD_IS_BLOCKED (pad) == TRUE when this function is
- * called.
- *
- * This function performs the pad blocking when an event, buffer push
- * or buffer_alloc is performed on a _SRC_ pad. It blocks the
- * streaming thread after informing the pad has been blocked.
- *
- * An application can with this method wait and block any streaming
- * thread and perform operations such as seeking or linking.
- *
- * Two methods are available for notifying the application of the
- * block:
- * - the callback method, which happens in the STREAMING thread with
- *   the STREAM_LOCK held. With this method, the most useful way of
- *   dealing with the callback is to post a message to the main thread
- *   where the pad block can then be handled outside of the streaming
- *   thread. With the last method one can perform all operations such
- *   as doing a state change, linking, unblocking, seeking etc on the
- *   pad.
- * - the GCond signal method, which makes any thread unblock when
- *   the pad block happens.
- *
- * During the actual blocking state, the GST_PAD_BLOCKING flag is set.
- * The GST_PAD_BLOCKING flag is unset when the pad was unblocked.
+
+/**
+ * gst_pad_set_offset:
+ * @pad: a #GstPad
+ * @offset: the offset
  *
- * MT safe.
+ * Set the offset that will be applied to the running time of @pad.
  */
-static GstFlowReturn
-handle_pad_block (GstPad * pad)
+void
+gst_pad_set_offset (GstPad * pad, gint64 offset)
 {
-  GstPadBlockCallback callback;
-  gpointer user_data;
-  GstFlowReturn ret = GST_FLOW_OK;
-
-  GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad, "signal block taken");
-
-  /* flushing, don't bother trying to block and return WRONG_STATE
-   * right away */
-  if (GST_PAD_IS_FLUSHING (pad))
-    goto flushingnonref;
-
-  /* we grab an extra ref for the callbacks, this is probably not
-   * needed (callback code does not have a ref and cannot unref). I
-   * think this was done to make it possible to unref the element in
-   * the callback, which is in the end totally impossible as it
-   * requires grabbing the STREAM_LOCK and OBJECT_LOCK which are
-   * all taken when calling this function. */
-  gst_object_ref (pad);
-
-  while (GST_PAD_IS_BLOCKED (pad)) {
-    do {
-      /* we either have a callback installed to notify the block or
-       * some other thread is doing a GCond wait. */
-      callback = pad->block_callback;
-      pad->abidata.ABI.block_callback_called = TRUE;
-      if (callback) {
-        /* there is a callback installed, call it. We release the
-         * lock so that the callback can do something usefull with the
-         * pad */
-        user_data = pad->block_data;
-        GST_OBJECT_UNLOCK (pad);
-        callback (pad, TRUE, user_data);
-        GST_OBJECT_LOCK (pad);
-
-        /* we released the lock, recheck flushing */
-        if (GST_PAD_IS_FLUSHING (pad))
-          goto flushing;
-      } else {
-        /* no callback, signal the thread that is doing a GCond wait
-         * if any. */
-        GST_PAD_BLOCK_BROADCAST (pad);
-      }
-    } while (pad->abidata.ABI.block_callback_called == FALSE
-        && GST_PAD_IS_BLOCKED (pad));
-
-    /* OBJECT_LOCK could have been released when we did the callback, which
-     * then could have made the pad unblock so we need to check the blocking
-     * condition again.   */
-    if (!GST_PAD_IS_BLOCKED (pad))
-      break;
-
-    /* now we block the streaming thread. It can be unlocked when we
-     * deactivate the pad (which will also set the FLUSHING flag) or
-     * when the pad is unblocked. A flushing event will also unblock
-     * the pad after setting the FLUSHING flag. */
-    GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad,
-        "Waiting to be unblocked or set flushing");
-    GST_OBJECT_FLAG_SET (pad, GST_PAD_BLOCKING);
-    GST_PAD_BLOCK_WAIT (pad);
-    GST_OBJECT_FLAG_UNSET (pad, GST_PAD_BLOCKING);
+  guint idx;
+  GstPad *peer;
+  GstPad *tmp = NULL;
 
-    /* see if we got unblocked by a flush or not */
-    if (GST_PAD_IS_FLUSHING (pad))
-      goto flushing;
-  }
+  g_return_if_fail (GST_IS_PAD (pad));
 
-  GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad, "got unblocked");
+  GST_OBJECT_LOCK (pad);
+  /* if nothing changed, do nothing */
+  if (pad->offset == offset)
+    goto done;
 
-  /* when we get here, the pad is unblocked again and we perform
-   * the needed unblock code. */
-  callback = pad->block_callback;
-  if (callback) {
-    /* we need to call the callback */
-    user_data = pad->block_data;
-    GST_OBJECT_UNLOCK (pad);
-    callback (pad, FALSE, user_data);
-    GST_OBJECT_LOCK (pad);
-  } else {
-    /* we need to signal the thread waiting on the GCond */
-    GST_PAD_BLOCK_BROADCAST (pad);
-  }
+  pad->offset = offset;
 
-  gst_object_unref (pad);
+  /* if no peer, we just updated the offset */
+  if ((peer = GST_PAD_PEER (pad)) == NULL)
+    goto done;
 
-  return ret;
+  /* switch pads around when dealing with a sinkpad */
+  if (GST_PAD_IS_SINK (pad)) {
+    /* ref the peer so it doesn't go away when we release the lock */
+    tmp = gst_object_ref (peer);
+    /* make sure we get the peer (the srcpad) */
+    GST_OBJECT_UNLOCK (pad);
 
-flushingnonref:
-  {
-    GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad, "pad was flushing");
-    return GST_FLOW_WRONG_STATE;
-  }
-flushing:
-  {
-    GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad, "pad became flushing");
-    gst_object_unref (pad);
-    return GST_FLOW_WRONG_STATE;
-  }
-}
+    /* swap pads */
+    peer = pad;
+    pad = tmp;
 
-/**********************************************************************
- * Data passing functions
- */
+    GST_OBJECT_LOCK (pad);
+    /* check if the pad didn't get relinked */
+    if (GST_PAD_PEER (pad) != peer)
+      goto done;
 
-static gboolean
-gst_pad_emit_have_data_signal (GstPad * pad, GstMiniObject * obj)
-{
-  GValue ret = { 0 };
-  GValue args[2] = { {0}, {0} };
-  gboolean res;
-  GQuark detail;
-
-  /* init */
-  g_value_init (&ret, G_TYPE_BOOLEAN);
-  g_value_set_boolean (&ret, TRUE);
-  g_value_init (&args[0], GST_TYPE_PAD);
-  g_value_set_object (&args[0], pad);
-  g_value_init (&args[1], GST_TYPE_MINI_OBJECT);
-  gst_value_set_mini_object (&args[1], obj);
-
-  if (GST_IS_EVENT (obj))
-    detail = event_quark;
-  else
-    detail = buffer_quark;
+    /* we can release the ref now */
+    gst_object_unref (peer);
+  }
 
-  /* actually emit */
-  g_signal_emitv (args, gst_pad_signals[PAD_HAVE_DATA], detail, &ret);
-  res = g_value_get_boolean (&ret);
+  /* the index of the segment event in the array */
+  idx = GST_EVENT_STICKY_IDX_TYPE (GST_EVENT_SEGMENT);
 
-  /* clean up */
-  g_value_unset (&ret);
-  g_value_unset (&args[0]);
-  g_value_unset (&args[1]);
+  /* lock order is srcpad >> sinkpad */
+  GST_OBJECT_LOCK (peer);
+  /* take the current segment event, adjust it and then place
+   * it on the sinkpad. events on the srcpad are always active. */
+  if (replace_event (pad, peer, idx))
+    GST_OBJECT_FLAG_SET (peer, GST_PAD_NEED_EVENTS);
 
-  return res;
-}
+  GST_OBJECT_UNLOCK (peer);
 
-static void
-gst_pad_data_unref (gboolean is_buffer, void *data)
-{
-  if (G_LIKELY (is_buffer)) {
-    gst_buffer_unref (data);
-  } else {
-    gst_buffer_list_unref (data);
-  }
+done:
+  GST_OBJECT_UNLOCK (pad);
 }
 
-static GstCaps *
-gst_pad_data_get_caps (gboolean is_buffer, void *data)
-{
-  GstCaps *caps;
-
-  if (G_LIKELY (is_buffer)) {
-    caps = GST_BUFFER_CAPS (data);
-  } else {
-    GstBuffer *buf;
 
-    if ((buf = gst_buffer_list_get (GST_BUFFER_LIST_CAST (data), 0, 0)))
-      caps = GST_BUFFER_CAPS (buf);
-    else
-      caps = NULL;
-  }
-  return caps;
-}
+/**********************************************************************
+ * Data passing functions
+ */
 
 /* this is the chain function that does not perform the additional argument
  * checking for that little extra speed.
  */
 static inline GstFlowReturn
-gst_pad_chain_data_unchecked (GstPad * pad, gboolean is_buffer, void *data,
-    GstPadPushCache * cache)
+gst_pad_chain_data_unchecked (GstPad * pad, GstProbeType type, void *data)
 {
-  GstCaps *caps;
-  gboolean caps_changed;
   GstFlowReturn ret;
-  gboolean emit_signal;
+  gboolean needs_events;
 
   GST_PAD_STREAM_LOCK (pad);
 
@@ -4198,39 +3601,26 @@ gst_pad_chain_data_unchecked (GstPad * pad, gboolean is_buffer, void *data,
   if (G_UNLIKELY (GST_PAD_IS_FLUSHING (pad)))
     goto flushing;
 
-  caps = gst_pad_data_get_caps (is_buffer, data);
-  caps_changed = caps && caps != GST_PAD_CAPS (pad);
+  needs_events = GST_PAD_NEEDS_EVENTS (pad);
+  if (G_UNLIKELY (needs_events)) {
+    GST_OBJECT_FLAG_UNSET (pad, GST_PAD_NEED_EVENTS);
 
-  emit_signal = GST_PAD_DO_BUFFER_SIGNALS (pad) > 0;
-  GST_OBJECT_UNLOCK (pad);
-
-  /* see if the signal should be emited, we emit before caps nego as
-   * we might drop the buffer and do capsnego for nothing. */
-  if (G_UNLIKELY (emit_signal)) {
-    cache = NULL;
-    if (G_LIKELY (is_buffer)) {
-      if (!gst_pad_emit_have_data_signal (pad, GST_MINI_OBJECT (data)))
-        goto dropping;
-    } else {
-      /* chain all groups in the buffer list one by one to avoid problems with
-       * buffer probes that push buffers or events */
-      goto chain_groups;
-    }
+    GST_DEBUG_OBJECT (pad, "need to update all events");
+    ret = gst_pad_update_events (pad);
+    if (G_UNLIKELY (ret != GST_FLOW_OK))
+      goto events_error;
   }
 
-  /* we got a new datatype on the pad, see if it can handle it */
-  if (G_UNLIKELY (caps_changed)) {
-    GST_DEBUG_OBJECT (pad, "caps changed to %p %" GST_PTR_FORMAT, caps, caps);
-    if (G_UNLIKELY (!gst_pad_configure_sink (pad, caps)))
-      goto not_negotiated;
-  }
+  PROBE (pad, GST_PROBE_TYPE_PUSH | type, data, probe_stopped);
+
+  GST_OBJECT_UNLOCK (pad);
 
   /* NOTE: we read the chainfunc unlocked.
    * we cannot hold the lock for the pad so we might send
    * the data to the wrong function. This is not really a
    * problem since functions are assigned at creation time
    * and don't change that often... */
-  if (G_LIKELY (is_buffer)) {
+  if (G_LIKELY (type & GST_PROBE_TYPE_BUFFER)) {
     GstPadChainFunction chainfunc;
 
     if (G_UNLIKELY ((chainfunc = GST_PAD_CHAINFUNC (pad)) == NULL))
@@ -4240,11 +3630,6 @@ gst_pad_chain_data_unchecked (GstPad * pad, gboolean is_buffer, void *data,
         "calling chainfunction &%s with buffer %p",
         GST_DEBUG_FUNCPTR_NAME (chainfunc), data);
 
-    if (cache) {
-      cache->peer = gst_object_ref (pad);
-      cache->caps = caps ? gst_caps_ref (caps) : NULL;
-    }
-
     ret = chainfunc (pad, GST_BUFFER_CAST (data));
 
     GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad,
@@ -4254,7 +3639,7 @@ gst_pad_chain_data_unchecked (GstPad * pad, gboolean is_buffer, void *data,
     GstPadChainListFunction chainlistfunc;
 
     if (G_UNLIKELY ((chainlistfunc = GST_PAD_CHAINLISTFUNC (pad)) == NULL))
-      goto chain_groups;
+      goto no_function;
 
     GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad,
         "calling chainlistfunction &%s",
@@ -4271,69 +3656,42 @@ gst_pad_chain_data_unchecked (GstPad * pad, gboolean is_buffer, void *data,
 
   return ret;
 
-chain_groups:
-  {
-    GstBufferList *list;
-    GstBufferListIterator *it;
-    GstBuffer *group;
-
-    GST_PAD_STREAM_UNLOCK (pad);
-
-    GST_INFO_OBJECT (pad, "chaining each group in list as a merged buffer");
-
-    list = GST_BUFFER_LIST_CAST (data);
-    it = gst_buffer_list_iterate (list);
-
-    if (gst_buffer_list_iterator_next_group (it)) {
-      do {
-        group = gst_buffer_list_iterator_merge_group (it);
-        if (group == NULL) {
-          group = gst_buffer_new ();
-          GST_CAT_INFO_OBJECT (GST_CAT_SCHEDULING, pad, "chaining empty group");
-        } else {
-          GST_CAT_INFO_OBJECT (GST_CAT_SCHEDULING, pad, "chaining group");
-        }
-        ret = gst_pad_chain_data_unchecked (pad, TRUE, group, NULL);
-      } while (ret == GST_FLOW_OK && gst_buffer_list_iterator_next_group (it));
-    } else {
-      GST_CAT_INFO_OBJECT (GST_CAT_SCHEDULING, pad, "chaining empty group");
-      ret = gst_pad_chain_data_unchecked (pad, TRUE, gst_buffer_new (), NULL);
-    }
-
-    gst_buffer_list_iterator_free (it);
-    gst_buffer_list_unref (list);
-
-    return ret;
-  }
-
   /* ERRORS */
 flushing:
   {
-    gst_pad_data_unref (is_buffer, data);
     GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad,
-        "pushing, but pad was flushing");
+        "chaining, but pad was flushing");
     GST_OBJECT_UNLOCK (pad);
     GST_PAD_STREAM_UNLOCK (pad);
     return GST_FLOW_WRONG_STATE;
   }
-dropping:
+events_error:
   {
-    gst_pad_data_unref (is_buffer, data);
-    GST_DEBUG_OBJECT (pad, "Dropping buffer due to FALSE probe return");
+    GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad, "events were not accepted");
+    GST_OBJECT_UNLOCK (pad);
     GST_PAD_STREAM_UNLOCK (pad);
-    return GST_FLOW_OK;
+    return ret;
   }
-not_negotiated:
+probe_stopped:
   {
-    gst_pad_data_unref (is_buffer, data);
-    GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad,
-        "pushing data but pad did not accept");
+    GST_OBJECT_UNLOCK (pad);
     GST_PAD_STREAM_UNLOCK (pad);
-    return GST_FLOW_NOT_NEGOTIATED;
+    gst_mini_object_unref (GST_MINI_OBJECT_CAST (data));
+
+    switch (ret) {
+      case GST_FLOW_CUSTOM_SUCCESS:
+        GST_DEBUG_OBJECT (pad, "dropped buffer");
+        ret = GST_FLOW_OK;
+        break;
+      default:
+        GST_DEBUG_OBJECT (pad, "en error occured %s", gst_flow_get_name (ret));
+        break;
+    }
+    return ret;
   }
 no_function:
   {
-    gst_pad_data_unref (is_buffer, data);
+    gst_mini_object_unref (GST_MINI_OBJECT_CAST (data));
     GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad,
         "pushing, but not chainhandler");
     GST_ELEMENT_ERROR (GST_PAD_PARENT (pad), CORE, PAD, (NULL),
@@ -4354,10 +3712,9 @@ no_function:
  *
  * The function returns #GST_FLOW_WRONG_STATE if the pad was flushing.
  *
- * If the caps on @buffer are different from the current caps on @pad, this
- * function will call any setcaps function (see gst_pad_set_setcaps_function())
- * installed on @pad. If the new caps are not acceptable for @pad, this
- * function returns #GST_FLOW_NOT_NEGOTIATED.
+ * If the buffer type is not acceptable for @pad (as negotiated with a
+ * preceeding GST_EVENT_CAPS event), this function returns
+ * #GST_FLOW_NOT_NEGOTIATED.
  *
  * The function proceeds calling the chain function installed on @pad (see
  * gst_pad_set_chain_function()) and the return value of that function is
@@ -4378,7 +3735,32 @@ gst_pad_chain (GstPad * pad, GstBuffer * buffer)
   g_return_val_if_fail (GST_PAD_IS_SINK (pad), GST_FLOW_ERROR);
   g_return_val_if_fail (GST_IS_BUFFER (buffer), GST_FLOW_ERROR);
 
-  return gst_pad_chain_data_unchecked (pad, TRUE, buffer, NULL);
+  return gst_pad_chain_data_unchecked (pad, GST_PROBE_TYPE_BUFFER, buffer);
+}
+
+static GstFlowReturn
+gst_pad_chain_list_default (GstPad * pad, GstBufferList * list)
+{
+  guint i, len;
+  GstBuffer *buffer;
+  GstFlowReturn ret;
+
+  GST_INFO_OBJECT (pad, "chaining each group in list as a merged buffer");
+
+  len = gst_buffer_list_len (list);
+
+  ret = GST_FLOW_OK;
+  for (i = 0; i < len; i++) {
+    buffer = gst_buffer_list_get (list, i);
+    ret =
+        gst_pad_chain_data_unchecked (pad, GST_PROBE_TYPE_BUFFER,
+        gst_buffer_ref (buffer));
+    if (ret != GST_FLOW_OK)
+      break;
+  }
+  gst_buffer_list_unref (list);
+
+  return ret;
 }
 
 /**
@@ -4391,10 +3773,8 @@ gst_pad_chain (GstPad * pad, GstBuffer * buffer)
  *
  * The function returns #GST_FLOW_WRONG_STATE if the pad was flushing.
  *
- * If the caps on the first buffer of @list are different from the current
- * caps on @pad, this function will call any setcaps function
- * (see gst_pad_set_setcaps_function()) installed on @pad. If the new caps
- * are not acceptable for @pad, this function returns #GST_FLOW_NOT_NEGOTIATED.
+ * If @pad was not negotiated properly with a CAPS event, this function
+ * returns #GST_FLOW_NOT_NEGOTIATED.
  *
  * The function proceeds calling the chainlist function installed on @pad (see
  * gst_pad_set_chain_list_function()) and the return value of that function is
@@ -4417,205 +3797,83 @@ gst_pad_chain_list (GstPad * pad, GstBufferList * list)
   g_return_val_if_fail (GST_PAD_IS_SINK (pad), GST_FLOW_ERROR);
   g_return_val_if_fail (GST_IS_BUFFER_LIST (list), GST_FLOW_ERROR);
 
-  return gst_pad_chain_data_unchecked (pad, FALSE, list, NULL);
+  return gst_pad_chain_data_unchecked (pad, GST_PROBE_TYPE_BUFFER_LIST, list);
 }
 
 static GstFlowReturn
-gst_pad_push_data (GstPad * pad, gboolean is_buffer, void *data,
-    GstPadPushCache * cache)
+gst_pad_push_data (GstPad * pad, GstProbeType type, void *data)
 {
   GstPad *peer;
   GstFlowReturn ret;
-  GstCaps *caps;
-  gboolean caps_changed;
 
   GST_OBJECT_LOCK (pad);
+  if (G_UNLIKELY (GST_PAD_IS_FLUSHING (pad)))
+    goto flushing;
 
-  /* FIXME: this check can go away; pad_set_blocked could be implemented with
-   * probes completely or probes with an extended pad block. */
-  while (G_UNLIKELY (GST_PAD_IS_BLOCKED (pad)))
-    if ((ret = handle_pad_block (pad)) != GST_FLOW_OK)
-      goto flushed;
-
-  /* we emit signals on the pad arg, the peer will have a chance to
-   * emit in the _chain() function */
-  if (G_UNLIKELY (GST_PAD_DO_BUFFER_SIGNALS (pad) > 0)) {
-    cache = NULL;
-    /* unlock before emitting */
-    GST_OBJECT_UNLOCK (pad);
+  type |= GST_PROBE_TYPE_PUSH;
 
-    if (G_LIKELY (is_buffer)) {
-      /* if the signal handler returned FALSE, it means we should just drop the
-       * buffer */
-      if (!gst_pad_emit_have_data_signal (pad, GST_MINI_OBJECT (data)))
-        goto dropped;
-    } else {
-      /* push all buffers in the list */
-      goto push_groups;
-    }
-    GST_OBJECT_LOCK (pad);
-  }
+  /* do block probes */
+  PROBE (pad, type | GST_PROBE_TYPE_BLOCK, data, probe_stopped);
+
+  /* do post-blocking probes */
+  PROBE (pad, type, data, probe_stopped);
 
   if (G_UNLIKELY ((peer = GST_PAD_PEER (pad)) == NULL))
     goto not_linked;
 
-  /* Before pushing the buffer to the peer pad, ensure that caps
-   * are set on this pad */
-  caps = gst_pad_data_get_caps (is_buffer, data);
-  caps_changed = caps && caps != GST_PAD_CAPS (pad);
-
   /* take ref to peer pad before releasing the lock */
   gst_object_ref (peer);
+  pad->priv->using++;
   GST_OBJECT_UNLOCK (pad);
 
-  /* we got a new datatype from the pad, it had better handle it */
-  if (G_UNLIKELY (caps_changed)) {
-    GST_DEBUG_OBJECT (pad,
-        "caps changed from %" GST_PTR_FORMAT " to %p %" GST_PTR_FORMAT,
-        GST_PAD_CAPS (pad), caps, caps);
-    if (G_UNLIKELY (!gst_pad_set_caps (pad, caps)))
-      goto not_negotiated;
-  }
-
-  ret = gst_pad_chain_data_unchecked (peer, is_buffer, data, cache);
+  ret = gst_pad_chain_data_unchecked (peer, type, data);
 
   gst_object_unref (peer);
 
-  return ret;
-
-push_groups:
-  {
-    GstBufferList *list;
-    GstBufferListIterator *it;
-    GstBuffer *group;
-
-    GST_INFO_OBJECT (pad, "pushing each group in list as a merged buffer");
-
-    list = GST_BUFFER_LIST_CAST (data);
-    it = gst_buffer_list_iterate (list);
-
-    if (gst_buffer_list_iterator_next_group (it)) {
-      do {
-        group = gst_buffer_list_iterator_merge_group (it);
-        if (group == NULL) {
-          group = gst_buffer_new ();
-          GST_CAT_INFO_OBJECT (GST_CAT_SCHEDULING, pad, "pushing empty group");
-        } else {
-          GST_CAT_INFO_OBJECT (GST_CAT_SCHEDULING, pad, "pushing group");
-        }
-        ret = gst_pad_push_data (pad, TRUE, group, NULL);
-      } while (ret == GST_FLOW_OK && gst_buffer_list_iterator_next_group (it));
-    } else {
-      GST_CAT_INFO_OBJECT (GST_CAT_SCHEDULING, pad, "pushing empty group");
-      ret = gst_pad_push_data (pad, TRUE, gst_buffer_new (), NULL);
-    }
-
-    gst_buffer_list_iterator_free (it);
-    gst_buffer_list_unref (list);
-
-    return ret;
+  GST_OBJECT_LOCK (pad);
+  pad->priv->using--;
+  if (pad->priv->using == 0) {
+    /* pad is not active anymore, trigger idle callbacks */
+    PROBE (pad, GST_PROBE_TYPE_PUSH | GST_PROBE_TYPE_IDLE, NULL, probe_stopped);
   }
+  GST_OBJECT_UNLOCK (pad);
+
+  return ret;
 
   /* ERROR recovery here */
-flushed:
+  /* ERRORS */
+flushing:
   {
-    gst_pad_data_unref (is_buffer, data);
-    GST_DEBUG_OBJECT (pad, "pad block stopped by flush");
+    GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad,
+        "pushing, but pad was flushing");
     GST_OBJECT_UNLOCK (pad);
-    return ret;
+    gst_mini_object_unref (GST_MINI_OBJECT_CAST (data));
+    return GST_FLOW_WRONG_STATE;
   }
-dropped:
+probe_stopped:
   {
-    gst_pad_data_unref (is_buffer, data);
-    GST_DEBUG_OBJECT (pad, "Dropping buffer due to FALSE probe return");
-    return GST_FLOW_OK;
+    GST_OBJECT_UNLOCK (pad);
+    gst_mini_object_unref (GST_MINI_OBJECT_CAST (data));
+
+    switch (ret) {
+      case GST_FLOW_CUSTOM_SUCCESS:
+        GST_DEBUG_OBJECT (pad, "dropped buffer");
+        ret = GST_FLOW_OK;
+        break;
+      default:
+        GST_DEBUG_OBJECT (pad, "en error occured %s", gst_flow_get_name (ret));
+        break;
+    }
+    return ret;
   }
 not_linked:
   {
-    gst_pad_data_unref (is_buffer, data);
     GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad,
         "pushing, but it was not linked");
     GST_OBJECT_UNLOCK (pad);
+    gst_mini_object_unref (GST_MINI_OBJECT_CAST (data));
     return GST_FLOW_NOT_LINKED;
   }
-not_negotiated:
-  {
-    gst_pad_data_unref (is_buffer, data);
-    gst_object_unref (peer);
-    GST_CAT_DEBUG_OBJECT (GST_CAT_SCHEDULING, pad,
-        "element pushed data then refused to accept the caps");
-    return GST_FLOW_NOT_NEGOTIATED;
-  }
-}
-
-static inline GstPadPushCache *
-pad_take_cache (GstPad * pad, gpointer * cache_ptr)
-{
-  GstPadPushCache *cache;
-
-  /* try to get the cached data */
-  do {
-    cache = g_atomic_pointer_get (cache_ptr);
-    /* now try to replace the pointer with NULL to mark that we are busy
-     * with it */
-  } while (!g_atomic_pointer_compare_and_exchange (cache_ptr, cache, NULL));
-
-  /* we could have a leftover invalid entry */
-  if (G_UNLIKELY (cache == PAD_CACHE_INVALID))
-    cache = NULL;
-
-  return cache;
-}
-
-static inline void
-pad_free_cache (GstPadPushCache * cache)
-{
-  gst_object_unref (cache->peer);
-  if (cache->caps)
-    gst_caps_unref (cache->caps);
-  g_slice_free (GstPadPushCache, cache);
-}
-
-static inline void
-pad_put_cache (GstPad * pad, GstPadPushCache * cache, gpointer * cache_ptr)
-{
-  /* put it back */
-  if (!g_atomic_pointer_compare_and_exchange (cache_ptr, NULL, cache)) {
-    /* something changed, clean up our cache */
-    pad_free_cache (cache);
-  }
-}
-
-/* must be called with the pad lock */
-void
-_priv_gst_pad_invalidate_cache (GstPad * pad)
-{
-  GstPadPushCache *cache;
-  gpointer *cache_ptr;
-
-  GST_LOG_OBJECT (pad, "Invalidating pad cache");
-
-  /* we hold the pad lock here so we can get the peer and it stays
-   * alive during this call */
-  if (GST_PAD_IS_SINK (pad)) {
-    if (!(pad = GST_PAD_PEER (pad)))
-      return;
-  }
-
-  cache_ptr = (gpointer *) & pad->abidata.ABI.priv->cache_ptr;
-
-  /* try to get the cached data */
-  do {
-    cache = g_atomic_pointer_get (cache_ptr);
-    /* now try to replace the pointer with INVALID. If nothing is busy with this
-     * caps, we get the cache and clean it up. If something is busy, we replace
-     * with INVALID so that when the function finishes and tries to put the
-     * cache back, it'll fail and cleanup */
-  } while (!g_atomic_pointer_compare_and_exchange (cache_ptr, cache,
-          PAD_CACHE_INVALID));
-
-  if (G_LIKELY (cache && cache != PAD_CACHE_INVALID))
-    pad_free_cache (cache);
 }
 
 /**
@@ -4626,13 +3884,8 @@ _priv_gst_pad_invalidate_cache (GstPad * pad)
  *
  * Pushes a buffer to the peer of @pad.
  *
- * This function will call an installed pad block before triggering any
- * installed pad probes.
- *
- * If the caps on @buffer are different from the currently configured caps on
- * @pad, this function will call any installed setcaps function on @pad (see
- * gst_pad_set_setcaps_function()). In case of failure to renegotiate the new
- * format, this function returns #GST_FLOW_NOT_NEGOTIATED.
+ * This function will call installed block probes before triggering any
+ * installed data probes.
  *
  * The function proceeds calling gst_pad_chain() on the peer pad and returns
  * the value from that function. If @pad has no peer, #GST_FLOW_NOT_LINKED will
@@ -4648,263 +3901,47 @@ _priv_gst_pad_invalidate_cache (GstPad * pad)
 GstFlowReturn
 gst_pad_push (GstPad * pad, GstBuffer * buffer)
 {
-  GstPadPushCache *cache;
-  GstFlowReturn ret;
-  gpointer *cache_ptr;
-  GstPad *peer;
-  GstCaps *caps;
-
-  g_return_val_if_fail (GST_IS_PAD (pad), GST_FLOW_ERROR);
-  g_return_val_if_fail (GST_PAD_IS_SRC (pad), GST_FLOW_ERROR);
-  g_return_val_if_fail (GST_IS_BUFFER (buffer), GST_FLOW_ERROR);
-
-  cache_ptr = (gpointer *) & pad->abidata.ABI.priv->cache_ptr;
-
-  cache = pad_take_cache (pad, cache_ptr);
-
-  if (G_UNLIKELY (cache == NULL))
-    goto slow_path;
-
-  /* check caps */
-  caps = GST_BUFFER_CAPS (buffer);
-  if (G_UNLIKELY (caps && caps != cache->caps)) {
-    pad_free_cache (cache);
-    goto slow_path;
-  }
-
-  peer = cache->peer;
-
-  GST_PAD_STREAM_LOCK (peer);
-  if (G_UNLIKELY (g_atomic_pointer_get (cache_ptr) == PAD_CACHE_INVALID))
-    goto invalid;
-
-  GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad,
-      "calling chainfunction &%s with buffer %p",
-      GST_DEBUG_FUNCPTR_NAME (GST_PAD_CHAINFUNC (peer)), buffer);
-
-  ret = GST_PAD_CHAINFUNC (peer) (peer, buffer);
-
-  GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad,
-      "called chainfunction &%s with buffer %p, returned %s",
-      GST_DEBUG_FUNCPTR_NAME (GST_PAD_CHAINFUNC (peer)), buffer,
-      gst_flow_get_name (ret));
-
-  GST_PAD_STREAM_UNLOCK (peer);
-
-  pad_put_cache (pad, cache, cache_ptr);
-
-  return ret;
-
-  /* slow path */
-slow_path:
-  {
-    GstPadPushCache scache = { NULL, };
-
-    GST_LOG_OBJECT (pad, "Taking slow path");
-
-    ret = gst_pad_push_data (pad, TRUE, buffer, &scache);
-
-    if (scache.peer) {
-      GstPadPushCache *ncache;
-
-      GST_LOG_OBJECT (pad, "Caching push data");
-
-      /* make cache structure */
-      ncache = g_slice_new (GstPadPushCache);
-      *ncache = scache;
-
-      pad_put_cache (pad, ncache, cache_ptr);
-    }
-    return ret;
-  }
-invalid:
-  {
-    GST_PAD_STREAM_UNLOCK (peer);
-    pad_free_cache (cache);
-    goto slow_path;
-  }
-}
-
-/**
- * gst_pad_push_list:
- * @pad: a source #GstPad, returns #GST_FLOW_ERROR if not.
- * @list: (transfer full): the #GstBufferList to push returns GST_FLOW_ERROR
- *     if not.
- *
- * Pushes a buffer list to the peer of @pad.
- *
- * This function will call an installed pad block before triggering any
- * installed pad probes.
- *
- * If the caps on the first buffer in the first group of @list are different
- * from the currently configured caps on @pad, this function will call any
- * installed setcaps function on @pad (see gst_pad_set_setcaps_function()). In
- * case of failure to renegotiate the new format, this function returns
- * #GST_FLOW_NOT_NEGOTIATED.
- *
- * If there are any probes installed on @pad every group of the buffer list
- * will be merged into a normal #GstBuffer and pushed via gst_pad_push and the
- * buffer list will be unreffed.
- *
- * The function proceeds calling the chain function on the peer pad and returns
- * the value from that function. If @pad has no peer, #GST_FLOW_NOT_LINKED will
- * be returned. If the peer pad does not have any installed chainlist function
- * every group buffer of the list will be merged into a normal #GstBuffer and
- * chained via gst_pad_chain().
- *
- * In all cases, success or failure, the caller loses its reference to @list
- * after calling this function.
- *
- * Returns: a #GstFlowReturn from the peer pad.
- *
- * MT safe.
- *
- * Since: 0.10.24
- */
-GstFlowReturn
-gst_pad_push_list (GstPad * pad, GstBufferList * list)
-{
-  GstBuffer *buf;
-  GstPadPushCache *cache;
-  GstFlowReturn ret;
-  gpointer *cache_ptr;
-  GstPad *peer;
-  GstCaps *caps;
-
-  g_return_val_if_fail (GST_IS_PAD (pad), GST_FLOW_ERROR);
-  g_return_val_if_fail (GST_PAD_IS_SRC (pad), GST_FLOW_ERROR);
-  g_return_val_if_fail (GST_IS_BUFFER_LIST (list), GST_FLOW_ERROR);
-
-  cache_ptr = (gpointer *) & pad->abidata.ABI.priv->cache_ptr;
-
-  cache = pad_take_cache (pad, cache_ptr);
-
-  if (G_UNLIKELY (cache == NULL))
-    goto slow_path;
-
-  /* check caps */
-  if ((buf = gst_buffer_list_get (list, 0, 0)))
-    caps = GST_BUFFER_CAPS (buf);
-  else
-    caps = NULL;
-
-  if (G_UNLIKELY (caps && caps != cache->caps)) {
-    pad_free_cache (cache);
-    goto slow_path;
-  }
-
-  peer = cache->peer;
-
-  GST_PAD_STREAM_LOCK (peer);
-  if (G_UNLIKELY (g_atomic_pointer_get (cache_ptr) == PAD_CACHE_INVALID))
-    goto invalid;
-
-  ret = GST_PAD_CHAINLISTFUNC (peer) (peer, list);
-
-  GST_PAD_STREAM_UNLOCK (peer);
-
-  pad_put_cache (pad, cache, cache_ptr);
-
-  return ret;
-
-  /* slow path */
-slow_path:
-  {
-    GstPadPushCache scache = { NULL, };
-
-    GST_LOG_OBJECT (pad, "Taking slow path");
-
-    ret = gst_pad_push_data (pad, FALSE, list, &scache);
-
-    if (scache.peer) {
-      GstPadPushCache *ncache;
-
-      GST_LOG_OBJECT (pad, "Caching push data");
-
-      /* make cache structure */
-      ncache = g_slice_new (GstPadPushCache);
-      *ncache = scache;
+  g_return_val_if_fail (GST_IS_PAD (pad), GST_FLOW_ERROR);
+  g_return_val_if_fail (GST_PAD_IS_SRC (pad), GST_FLOW_ERROR);
+  g_return_val_if_fail (GST_IS_BUFFER (buffer), GST_FLOW_ERROR);
 
-      pad_put_cache (pad, ncache, cache_ptr);
-    }
-    return ret;
-  }
-invalid:
-  {
-    GST_PAD_STREAM_UNLOCK (peer);
-    pad_free_cache (cache);
-    goto slow_path;
-  }
+  return gst_pad_push_data (pad, GST_PROBE_TYPE_BUFFER, buffer);
 }
 
 /**
- * gst_pad_check_pull_range:
- * @pad: a sink #GstPad.
+ * gst_pad_push_list:
+ * @pad: a source #GstPad, returns #GST_FLOW_ERROR if not.
+ * @list: (transfer full): the #GstBufferList to push returns GST_FLOW_ERROR
+ *     if not.
+ *
+ * Pushes a buffer list to the peer of @pad.
+ *
+ * This function will call installed block probes before triggering any
+ * installed data probes.
  *
- * Checks if a gst_pad_pull_range() can be performed on the peer
- * source pad. This function is used by plugins that want to check
- * if they can use random access on the peer source pad.
+ * The function proceeds calling the chain function on the peer pad and returns
+ * the value from that function. If @pad has no peer, #GST_FLOW_NOT_LINKED will
+ * be returned. If the peer pad does not have any installed chainlist function
+ * every group buffer of the list will be merged into a normal #GstBuffer and
+ * chained via gst_pad_chain().
  *
- * The peer sourcepad can implement a custom #GstPadCheckGetRangeFunction
- * if it needs to perform some logic to determine if pull_range is
- * possible.
+ * In all cases, success or failure, the caller loses its reference to @list
+ * after calling this function.
  *
- * Returns: a gboolean with the result.
+ * Returns: a #GstFlowReturn from the peer pad.
  *
  * MT safe.
+ *
+ * Since: 0.10.24
  */
-gboolean
-gst_pad_check_pull_range (GstPad * pad)
+GstFlowReturn
+gst_pad_push_list (GstPad * pad, GstBufferList * list)
 {
-  GstPad *peer;
-  gboolean ret;
-  GstPadCheckGetRangeFunction checkgetrangefunc;
-
-  g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
-
-  GST_OBJECT_LOCK (pad);
-  if (!GST_PAD_IS_SINK (pad))
-    goto wrong_direction;
-
-  if (G_UNLIKELY ((peer = GST_PAD_PEER (pad)) == NULL))
-    goto not_connected;
-
-  gst_object_ref (peer);
-  GST_OBJECT_UNLOCK (pad);
-
-  /* see note in above function */
-  if (G_LIKELY ((checkgetrangefunc = peer->checkgetrangefunc) == NULL)) {
-    /* FIXME, kindoff ghetto */
-    ret = GST_PAD_GETRANGEFUNC (peer) != NULL;
-    GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad,
-        "no checkgetrangefunc, assuming %d", ret);
-  } else {
-    GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad,
-        "calling checkgetrangefunc %s of peer pad %s:%s",
-        GST_DEBUG_FUNCPTR_NAME (checkgetrangefunc), GST_DEBUG_PAD_NAME (peer));
-
-    ret = checkgetrangefunc (peer);
-  }
-
-  gst_object_unref (peer);
-
-  return ret;
+  g_return_val_if_fail (GST_IS_PAD (pad), GST_FLOW_ERROR);
+  g_return_val_if_fail (GST_PAD_IS_SRC (pad), GST_FLOW_ERROR);
+  g_return_val_if_fail (GST_IS_BUFFER_LIST (list), GST_FLOW_ERROR);
 
-  /* ERROR recovery here */
-wrong_direction:
-  {
-    GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad,
-        "checking pull range, but pad must be a sinkpad");
-    GST_OBJECT_UNLOCK (pad);
-    return FALSE;
-  }
-not_connected:
-  {
-    GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad,
-        "checking pull range, but it was not linked");
-    GST_OBJECT_UNLOCK (pad);
-    return FALSE;
-  }
+  return gst_pad_push_data (pad, GST_PROBE_TYPE_BUFFER_LIST, list);
 }
 
 static GstFlowReturn
@@ -4913,17 +3950,12 @@ gst_pad_get_range_unchecked (GstPad * pad, guint64 offset, guint size,
 {
   GstFlowReturn ret;
   GstPadGetRangeFunction getrangefunc;
-  gboolean emit_signal;
-  GstCaps *caps;
-  gboolean caps_changed;
 
   GST_PAD_STREAM_LOCK (pad);
 
   GST_OBJECT_LOCK (pad);
   if (G_UNLIKELY (GST_PAD_IS_FLUSHING (pad)))
     goto flushing;
-
-  emit_signal = GST_PAD_DO_BUFFER_SIGNALS (pad) > 0;
   GST_OBJECT_UNLOCK (pad);
 
   if (G_UNLIKELY ((getrangefunc = GST_PAD_GETRANGEFUNC (pad)) == NULL))
@@ -4936,37 +3968,24 @@ gst_pad_get_range_unchecked (GstPad * pad, guint64 offset, guint size,
 
   ret = getrangefunc (pad, offset, size, buffer);
 
-  /* can only fire the signal if we have a valid buffer */
-  if (G_UNLIKELY (emit_signal) && (ret == GST_FLOW_OK)) {
-    if (!gst_pad_emit_have_data_signal (pad, GST_MINI_OBJECT (*buffer)))
-      goto dropping;
-  }
-
-  GST_PAD_STREAM_UNLOCK (pad);
-
   if (G_UNLIKELY (ret != GST_FLOW_OK))
     goto get_range_failed;
 
+  /* can only fire the signal if we have a valid buffer */
   GST_OBJECT_LOCK (pad);
-  /* Before pushing the buffer to the peer pad, ensure that caps
-   * are set on this pad */
-  caps = GST_BUFFER_CAPS (*buffer);
-  caps_changed = caps && caps != GST_PAD_CAPS (pad);
+  PROBE (pad, GST_PROBE_TYPE_PULL | GST_PROBE_TYPE_BUFFER, *buffer,
+      probe_stopped);
   GST_OBJECT_UNLOCK (pad);
 
-  if (G_UNLIKELY (caps_changed)) {
-    GST_DEBUG_OBJECT (pad, "caps changed to %p %" GST_PTR_FORMAT, caps, caps);
-    /* this should usually work because the element produced the buffer */
-    if (G_UNLIKELY (!gst_pad_configure_src (pad, caps, TRUE)))
-      goto not_negotiated;
-  }
+  GST_PAD_STREAM_UNLOCK (pad);
+
   return ret;
 
   /* ERRORS */
 flushing:
   {
     GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad,
-        "pulling range, but pad was flushing");
+        "getrange, but pad was flushing");
     GST_OBJECT_UNLOCK (pad);
     GST_PAD_STREAM_UNLOCK (pad);
     return GST_FLOW_WRONG_STATE;
@@ -4974,36 +3993,30 @@ flushing:
 no_function:
   {
     GST_ELEMENT_ERROR (GST_PAD_PARENT (pad), CORE, PAD, (NULL),
-        ("pullrange on pad %s:%s but it has no getrangefunction",
+        ("getrange on pad %s:%s but it has no getrangefunction",
             GST_DEBUG_PAD_NAME (pad)));
     GST_PAD_STREAM_UNLOCK (pad);
     return GST_FLOW_NOT_SUPPORTED;
   }
-dropping:
+probe_stopped:
   {
     GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad,
-        "Dropping data after FALSE probe return");
+        "probe returned %s", gst_flow_get_name (ret));
+    GST_OBJECT_UNLOCK (pad);
     GST_PAD_STREAM_UNLOCK (pad);
     gst_buffer_unref (*buffer);
     *buffer = NULL;
-    return GST_FLOW_UNEXPECTED;
+    return ret;
   }
 get_range_failed:
   {
+    GST_PAD_STREAM_UNLOCK (pad);
     *buffer = NULL;
     GST_CAT_LEVEL_LOG (GST_CAT_SCHEDULING,
         (ret >= GST_FLOW_UNEXPECTED) ? GST_LEVEL_INFO : GST_LEVEL_WARNING,
         pad, "getrange failed, flow: %s", gst_flow_get_name (ret));
     return ret;
   }
-not_negotiated:
-  {
-    gst_buffer_unref (*buffer);
-    *buffer = NULL;
-    GST_CAT_WARNING_OBJECT (GST_CAT_SCHEDULING, pad,
-        "getrange returned buffer of unaccaptable caps");
-    return GST_FLOW_NOT_NEGOTIATED;
-  }
 }
 
 /**
@@ -5075,59 +4088,73 @@ gst_pad_pull_range (GstPad * pad, guint64 offset, guint size,
 {
   GstPad *peer;
   GstFlowReturn ret;
-  gboolean emit_signal;
-  GstCaps *caps;
-  gboolean caps_changed;
+  gboolean needs_events;
 
   g_return_val_if_fail (GST_IS_PAD (pad), GST_FLOW_ERROR);
   g_return_val_if_fail (GST_PAD_IS_SINK (pad), GST_FLOW_ERROR);
   g_return_val_if_fail (buffer != NULL, GST_FLOW_ERROR);
 
   GST_OBJECT_LOCK (pad);
+  if (G_UNLIKELY (GST_PAD_IS_FLUSHING (pad)))
+    goto flushing;
 
-  while (G_UNLIKELY (GST_PAD_IS_BLOCKED (pad)))
-    handle_pad_block (pad);
+  PROBE (pad, GST_PROBE_TYPE_PULL | GST_PROBE_TYPE_BLOCK, NULL,
+      pre_probe_stopped);
 
   if (G_UNLIKELY ((peer = GST_PAD_PEER (pad)) == NULL))
-    goto not_connected;
-
-  /* signal emision for the pad, peer has chance to emit when
-   * we call _get_range() */
-  emit_signal = GST_PAD_DO_BUFFER_SIGNALS (pad) > 0;
+    goto not_linked;
 
   gst_object_ref (peer);
+  pad->priv->using++;
   GST_OBJECT_UNLOCK (pad);
 
   ret = gst_pad_get_range_unchecked (peer, offset, size, buffer);
 
   gst_object_unref (peer);
 
+  GST_OBJECT_LOCK (pad);
+  pad->priv->using--;
+  if (pad->priv->using == 0) {
+    /* pad is not active anymore, trigger idle callbacks */
+    PROBE (pad, GST_PROBE_TYPE_PULL | GST_PROBE_TYPE_IDLE, NULL,
+        post_probe_stopped);
+  }
+
   if (G_UNLIKELY (ret != GST_FLOW_OK))
     goto pull_range_failed;
 
-  /* can only fire the signal if we have a valid buffer */
-  if (G_UNLIKELY (emit_signal)) {
-    if (!gst_pad_emit_have_data_signal (pad, GST_MINI_OBJECT (*buffer)))
-      goto dropping;
-  }
+  PROBE (pad, GST_PROBE_TYPE_PULL | GST_PROBE_TYPE_BUFFER, buffer,
+      post_probe_stopped);
 
-  GST_OBJECT_LOCK (pad);
-  /* Before pushing the buffer to the peer pad, ensure that caps
-   * are set on this pad */
-  caps = GST_BUFFER_CAPS (*buffer);
-  caps_changed = caps && caps != GST_PAD_CAPS (pad);
-  GST_OBJECT_UNLOCK (pad);
+  needs_events = GST_PAD_NEEDS_EVENTS (pad);
+  if (G_UNLIKELY (needs_events)) {
+    GST_OBJECT_FLAG_UNSET (pad, GST_PAD_NEED_EVENTS);
 
-  /* we got a new datatype on the pad, see if it can handle it */
-  if (G_UNLIKELY (caps_changed)) {
-    GST_DEBUG_OBJECT (pad, "caps changed to %p %" GST_PTR_FORMAT, caps, caps);
-    if (G_UNLIKELY (!gst_pad_configure_sink (pad, caps)))
-      goto not_negotiated;
+    GST_DEBUG_OBJECT (pad, "we need to update the events");
+    ret = gst_pad_update_events (pad);
+    if (G_UNLIKELY (ret != GST_FLOW_OK))
+      goto events_error;
   }
+  GST_OBJECT_UNLOCK (pad);
+
   return ret;
 
   /* ERROR recovery here */
-not_connected:
+flushing:
+  {
+    GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad,
+        "pullrange, but pad was flushing");
+    GST_OBJECT_UNLOCK (pad);
+    return GST_FLOW_WRONG_STATE;
+  }
+pre_probe_stopped:
+  {
+    GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad, "pre probe returned %s",
+        gst_flow_get_name (ret));
+    GST_OBJECT_UNLOCK (pad);
+    return ret;
+  }
+not_linked:
   {
     GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad,
         "pulling range, but it was not linked");
@@ -5137,26 +4164,30 @@ not_connected:
 pull_range_failed:
   {
     *buffer = NULL;
+    GST_OBJECT_UNLOCK (pad);
     GST_CAT_LEVEL_LOG (GST_CAT_SCHEDULING,
         (ret >= GST_FLOW_UNEXPECTED) ? GST_LEVEL_INFO : GST_LEVEL_WARNING,
         pad, "pullrange failed, flow: %s", gst_flow_get_name (ret));
     return ret;
   }
-dropping:
+post_probe_stopped:
   {
     GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad,
-        "Dropping data after FALSE probe return");
-    gst_buffer_unref (*buffer);
+        "post probe returned %s", gst_flow_get_name (ret));
+    GST_OBJECT_UNLOCK (pad);
+    if (ret == GST_FLOW_OK)
+      gst_buffer_unref (*buffer);
     *buffer = NULL;
-    return GST_FLOW_UNEXPECTED;
+    return ret;
   }
-not_negotiated:
+events_error:
   {
+    GST_OBJECT_UNLOCK (pad);
     gst_buffer_unref (*buffer);
     *buffer = NULL;
     GST_CAT_WARNING_OBJECT (GST_CAT_SCHEDULING, pad,
-        "pullrange returned buffer of different caps");
-    return GST_FLOW_NOT_NEGOTIATED;
+        "pullrange returned events that were not accepted");
+    return ret;
   }
 }
 
@@ -5179,23 +4210,24 @@ not_negotiated:
 gboolean
 gst_pad_push_event (GstPad * pad, GstEvent * event)
 {
+  GstFlowReturn ret;
   GstPad *peerpad;
-  gboolean result;
+  gboolean result, do_event_actions = TRUE;
+  gboolean stored = FALSE;
 
   g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
   g_return_val_if_fail (event != NULL, FALSE);
   g_return_val_if_fail (GST_IS_EVENT (event), FALSE);
 
-  GST_LOG_OBJECT (pad, "event: %s", GST_EVENT_TYPE_NAME (event));
-
   GST_OBJECT_LOCK (pad);
 
+  peerpad = GST_PAD_PEER (pad);
+
   /* Two checks to be made:
    * . (un)set the FLUSHING flag for flushing events,
    * . handle pad blocking */
   switch (GST_EVENT_TYPE (event)) {
     case GST_EVENT_FLUSH_START:
-      _priv_gst_pad_invalidate_cache (pad);
       GST_PAD_SET_FLUSHING (pad);
 
       if (G_UNLIKELY (GST_PAD_IS_BLOCKED (pad))) {
@@ -5210,74 +4242,136 @@ gst_pad_push_event (GstPad * pad, GstEvent * event)
       break;
     case GST_EVENT_FLUSH_STOP:
       GST_PAD_UNSET_FLUSHING (pad);
-
-      /* if we are blocked, flush away the FLUSH_STOP event */
       if (G_UNLIKELY (GST_PAD_IS_BLOCKED (pad))) {
         GST_LOG_OBJECT (pad, "Pad is blocked, not forwarding flush-stop");
         goto flushed;
       }
       break;
     default:
-      while (G_UNLIKELY (GST_PAD_IS_BLOCKED (pad))) {
-        /* block the event as long as the pad is blocked */
-        if (handle_pad_block (pad) != GST_FLOW_OK)
-          goto flushed;
-      }
-      break;
-  }
+    {
+      /* store the event on the pad, but only on srcpads */
+      if (GST_PAD_IS_SRC (pad) && GST_EVENT_IS_STICKY (event)) {
+        guint idx;
 
-  if (G_UNLIKELY (GST_EVENT_SRC (event) == NULL)) {
-    GST_LOG_OBJECT (pad, "event had no source, setting pad as event source");
-    GST_EVENT_SRC (event) = gst_object_ref (pad);
-  }
+        idx = GST_EVENT_STICKY_IDX (event);
+        GST_LOG_OBJECT (pad, "storing sticky event %s at index %u",
+            GST_EVENT_TYPE_NAME (event), idx);
 
-  if (G_UNLIKELY (GST_PAD_DO_EVENT_SIGNALS (pad) > 0)) {
-    GST_OBJECT_UNLOCK (pad);
+        /* srcpad sticky events always become active immediately */
+        gst_event_replace (&pad->priv->events[idx].event, event);
 
-    if (!gst_pad_emit_have_data_signal (pad, GST_MINI_OBJECT (event)))
-      goto dropping;
+        stored = TRUE;
+      }
 
-    GST_OBJECT_LOCK (pad);
+      /* backwards compatibility mode for caps */
+      if (do_event_actions) {
+        do_event_actions = FALSE;
+
+        switch (GST_EVENT_TYPE (event)) {
+          case GST_EVENT_CAPS:
+          {
+            GST_OBJECT_UNLOCK (pad);
+
+            g_object_notify_by_pspec ((GObject *) pad, pspec_caps);
+
+            GST_OBJECT_LOCK (pad);
+            /* the peerpad might have changed. Things we checked above could not
+             * have changed. */
+            peerpad = GST_PAD_PEER (pad);
+            break;
+          }
+          case GST_EVENT_SEGMENT:
+          {
+            gint64 offset;
+
+            offset = pad->offset;
+            /* check if we need to adjust the segment */
+            if (offset != 0 && (peerpad != NULL)) {
+              GstSegment segment;
+
+              /* copy segment values */
+              gst_event_copy_segment (event, &segment);
+              gst_event_unref (event);
+
+              /* adjust and make a new event with the offset applied */
+              segment.base += offset;
+              event = gst_event_new_segment (&segment);
+            }
+            break;
+          }
+          case GST_EVENT_RECONFIGURE:
+            if (GST_PAD_IS_SINK (pad))
+              GST_OBJECT_FLAG_SET (pad, GST_PAD_NEED_RECONFIGURE);
+            break;
+          default:
+            break;
+        }
+      }
+      if (G_UNLIKELY (GST_PAD_IS_FLUSHING (pad)))
+        goto flushed;
+
+      PROBE (pad, GST_PROBE_TYPE_PUSH | GST_PROBE_TYPE_EVENT
+          | GST_PROBE_TYPE_BLOCK, event, probe_stopped);
+
+      break;
+    }
   }
-  peerpad = GST_PAD_PEER (pad);
+
+  /* send probes after modifying the events above */
+  PROBE (pad, GST_PROBE_TYPE_PUSH | GST_PROBE_TYPE_EVENT, event, probe_stopped);
+
+  /* now check the peer pad */
   if (peerpad == NULL)
     goto not_linked;
 
-  GST_LOG_OBJECT (pad, "sending event %s to peerpad %" GST_PTR_FORMAT,
-      GST_EVENT_TYPE_NAME (event), peerpad);
   gst_object_ref (peerpad);
+  pad->priv->using++;
   GST_OBJECT_UNLOCK (pad);
 
+  GST_LOG_OBJECT (pad, "sending event %p (%s) to peerpad %" GST_PTR_FORMAT,
+      event, GST_EVENT_TYPE_NAME (event), peerpad);
+
   result = gst_pad_send_event (peerpad, event);
 
-  /* Note: we gave away ownership of the event at this point */
-  GST_LOG_OBJECT (pad, "sent event to peerpad %" GST_PTR_FORMAT ", result %d",
-      peerpad, result);
+  /* Note: we gave away ownership of the event at this point but we can still
+   * print the old pointer */
+  GST_LOG_OBJECT (pad,
+      "sent event %p to peerpad %" GST_PTR_FORMAT ", result %d", event, peerpad,
+      result);
+
   gst_object_unref (peerpad);
 
-  return result;
+  GST_OBJECT_LOCK (pad);
+  pad->priv->using--;
+  if (pad->priv->using == 0) {
+    /* pad is not active anymore, trigger idle callbacks */
+    PROBE (pad, GST_PROBE_TYPE_PUSH | GST_PROBE_TYPE_IDLE, NULL, probe_stopped);
+  }
+  GST_OBJECT_UNLOCK (pad);
+
+  return result | stored;
 
   /* ERROR handling */
-dropping:
+flushed:
   {
-    GST_DEBUG_OBJECT (pad, "Dropping event after FALSE probe return");
+    GST_DEBUG_OBJECT (pad, "We're flushing");
+    GST_OBJECT_UNLOCK (pad);
     gst_event_unref (event);
-    return FALSE;
+    return stored;
   }
-not_linked:
+probe_stopped:
   {
-    GST_DEBUG_OBJECT (pad, "Dropping event because pad is not linked");
-    gst_event_unref (event);
+    GST_DEBUG_OBJECT (pad, "Probe returned %s", gst_flow_get_name (ret));
     GST_OBJECT_UNLOCK (pad);
-    return FALSE;
+    gst_event_unref (event);
+    return stored;
   }
-flushed:
+not_linked:
   {
-    GST_DEBUG_OBJECT (pad,
-        "Not forwarding event since we're flushing and blocking");
-    gst_event_unref (event);
+    GST_DEBUG_OBJECT (pad, "Dropping event because pad is not linked");
     GST_OBJECT_UNLOCK (pad);
-    return TRUE;
+    gst_event_unref (event);
+    return stored;
   }
 }
 
@@ -5312,9 +4406,9 @@ flushed:
 gboolean
 gst_pad_send_event (GstPad * pad, GstEvent * event)
 {
+  GstFlowReturn ret;
   gboolean result = FALSE;
-  GstPadEventFunction eventfunc;
-  gboolean serialized, need_unlock = FALSE;
+  gboolean serialized, need_unlock = FALSE, needs_events, sticky;
 
   g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
   g_return_val_if_fail (event != NULL, FALSE);
@@ -5324,28 +4418,18 @@ gst_pad_send_event (GstPad * pad, GstEvent * event)
     if (G_UNLIKELY (!GST_EVENT_IS_DOWNSTREAM (event)))
       goto wrong_direction;
     serialized = GST_EVENT_IS_SERIALIZED (event);
+    sticky = GST_EVENT_IS_STICKY (event);
   } else if (GST_PAD_IS_SRC (pad)) {
     if (G_UNLIKELY (!GST_EVENT_IS_UPSTREAM (event)))
       goto wrong_direction;
-    /* events on srcpad never are serialized */
-    serialized = FALSE;
+    /* events on srcpad never are serialized and sticky */
+    serialized = sticky = FALSE;
   } else
     goto unknown_direction;
 
-  if (G_UNLIKELY (GST_EVENT_SRC (event) == NULL)) {
-    GST_LOG_OBJECT (pad, "event had no source, setting pad as event source");
-    GST_EVENT_SRC (event) = gst_object_ref (pad);
-  }
-
-  /* pad signals */
-  if (G_UNLIKELY (GST_PAD_DO_EVENT_SIGNALS (pad) > 0)) {
-    GST_OBJECT_UNLOCK (pad);
-
-    if (!gst_pad_emit_have_data_signal (pad, GST_MINI_OBJECT_CAST (event)))
-      goto dropping;
-
-    GST_OBJECT_LOCK (pad);
-  }
+  /* get the flag first, we clear it when we have a FLUSH or a non-serialized
+   * event. */
+  needs_events = GST_PAD_NEEDS_EVENTS (pad);
 
   switch (GST_EVENT_TYPE (event)) {
     case GST_EVENT_FLUSH_START:
@@ -5356,9 +4440,9 @@ gst_pad_send_event (GstPad * pad, GstEvent * event)
       if (GST_PAD_IS_FLUSHING (pad))
         goto flushing;
 
-      _priv_gst_pad_invalidate_cache (pad);
       GST_PAD_SET_FLUSHING (pad);
       GST_CAT_DEBUG_OBJECT (GST_CAT_EVENT, pad, "set flush flag");
+      needs_events = FALSE;
       break;
     case GST_EVENT_FLUSH_STOP:
       if (G_LIKELY (GST_PAD_ACTIVATE_MODE (pad) != GST_ACTIVATE_NONE)) {
@@ -5370,33 +4454,98 @@ gst_pad_send_event (GstPad * pad, GstEvent * event)
       GST_PAD_STREAM_LOCK (pad);
       need_unlock = TRUE;
       GST_OBJECT_LOCK (pad);
+      needs_events = FALSE;
       break;
+    case GST_EVENT_RECONFIGURE:
+      if (GST_PAD_IS_SRC (pad))
+        GST_OBJECT_FLAG_SET (pad, GST_PAD_NEED_RECONFIGURE);
     default:
       GST_CAT_DEBUG_OBJECT (GST_CAT_EVENT, pad, "have event type %s",
           GST_EVENT_TYPE_NAME (event));
 
-      /* make this a little faster, no point in grabbing the lock
-       * if the pad is allready flushing. */
-      if (G_UNLIKELY (GST_PAD_IS_FLUSHING (pad)))
-        goto flushing;
-
       if (serialized) {
         /* lock order: STREAM_LOCK, LOCK, recheck flushing. */
         GST_OBJECT_UNLOCK (pad);
         GST_PAD_STREAM_LOCK (pad);
         need_unlock = TRUE;
         GST_OBJECT_LOCK (pad);
-        if (G_UNLIKELY (GST_PAD_IS_FLUSHING (pad)))
-          goto flushing;
+      } else {
+        /* don't forward events on non-serialized events */
+        needs_events = FALSE;
+      }
+
+      /* store the event on the pad, but only on srcpads. We need to store the
+       * event before checking the flushing flag. */
+      if (sticky) {
+        guint idx;
+        PadEvent *ev;
+
+        switch (GST_EVENT_TYPE (event)) {
+          case GST_EVENT_SEGMENT:
+            if (pad->offset != 0) {
+              GstSegment segment;
+
+              /* copy segment values */
+              gst_event_copy_segment (event, &segment);
+              gst_event_unref (event);
+
+              /* adjust and make a new event with the offset applied */
+              segment.base += pad->offset;
+              event = gst_event_new_segment (&segment);
+            }
+            break;
+          default:
+            break;
+        }
+
+        idx = GST_EVENT_STICKY_IDX (event);
+        ev = &pad->priv->events[idx];
+
+        GST_LOG_OBJECT (pad, "storing sticky event %s at index %u",
+            GST_EVENT_TYPE_NAME (event), idx);
+
+        if (ev->event != event) {
+          gst_event_replace (&ev->pending, event);
+          /* set the flag so that we update the events next time. We would
+           * usually update below but we might be flushing too. */
+          GST_OBJECT_FLAG_SET (pad, GST_PAD_NEED_EVENTS);
+          needs_events = TRUE;
+        }
       }
+      /* now do the probe */
+      if (G_UNLIKELY (GST_PAD_IS_FLUSHING (pad)))
+        goto flushing;
+
+      PROBE (pad, GST_PROBE_TYPE_PUSH | GST_PROBE_TYPE_EVENT, event,
+          probe_stopped);
+
       break;
   }
-  if (G_UNLIKELY ((eventfunc = GST_PAD_EVENTFUNC (pad)) == NULL))
-    goto no_function;
 
-  GST_OBJECT_UNLOCK (pad);
+  if (G_UNLIKELY (needs_events)) {
+    GstFlowReturn ret;
 
-  result = eventfunc (pad, event);
+    GST_OBJECT_FLAG_UNSET (pad, GST_PAD_NEED_EVENTS);
+
+    GST_DEBUG_OBJECT (pad, "need to update all events");
+    ret = gst_pad_update_events (pad);
+    if (ret != GST_FLOW_OK)
+      goto update_failed;
+    GST_OBJECT_UNLOCK (pad);
+
+    gst_event_unref (event);
+
+    result = TRUE;
+  } else {
+    GstPadEventFunction eventfunc;
+
+    if (G_UNLIKELY ((eventfunc = GST_PAD_EVENTFUNC (pad)) == NULL))
+      goto no_function;
+
+    GST_OBJECT_UNLOCK (pad);
+
+    result = do_event_function (pad, event, eventfunc);
+  }
 
   if (need_unlock)
     GST_PAD_STREAM_UNLOCK (pad);
@@ -5441,9 +4590,21 @@ flushing:
     gst_event_unref (event);
     return FALSE;
   }
-dropping:
+probe_stopped:
   {
-    GST_DEBUG_OBJECT (pad, "Dropping event after FALSE probe return");
+    GST_DEBUG_OBJECT (pad, "probe returned %s", gst_flow_get_name (ret));
+    GST_OBJECT_UNLOCK (pad);
+    if (need_unlock)
+      GST_PAD_STREAM_UNLOCK (pad);
+    gst_event_unref (event);
+    return FALSE;
+  }
+update_failed:
+  {
+    GST_OBJECT_UNLOCK (pad);
+    if (need_unlock)
+      GST_PAD_STREAM_UNLOCK (pad);
+    GST_CAT_INFO_OBJECT (GST_CAT_EVENT, pad, "Update events failed");
     gst_event_unref (event);
     return FALSE;
   }
@@ -5479,6 +4640,98 @@ gst_pad_get_element_private (GstPad * pad)
   return pad->element_private;
 }
 
+/**
+ * gst_pad_get_sticky_event:
+ * @pad: the #GstPad to get the event from.
+ * @event_type: the #GstEventType that should be retrieved.
+ *
+ * Returns a new reference of the sticky event of type @event_type
+ * from the event.
+ *
+ * Returns: (transfer full): a #GstEvent of type @event_type. Unref after usage.
+ */
+GstEvent *
+gst_pad_get_sticky_event (GstPad * pad, GstEventType event_type)
+{
+  GstEvent *event = NULL;
+  guint idx;
+
+  g_return_val_if_fail (GST_IS_PAD (pad), NULL);
+  g_return_val_if_fail ((event_type & GST_EVENT_TYPE_STICKY) != 0, NULL);
+
+  idx = GST_EVENT_STICKY_IDX_TYPE (event_type);
+
+  GST_OBJECT_LOCK (pad);
+  if ((event = pad->priv->events[idx].event)) {
+    gst_event_ref (event);
+  }
+  GST_OBJECT_UNLOCK (pad);
+
+  return event;
+}
+
+/**
+ * gst_pad_sticky_events_foreach:
+ * @pad: the #GstPad that should be used for iteration.
+ * @foreach_func: (scope call): the #GstPadStickyEventsForeachFunction that should be called for every event.
+ * @user_data: (closure): the optional user data.
+ *
+ * Iterates all active sticky events on @pad and calls @foreach_func for every
+ * event. If @foreach_func returns something else than GST_FLOW_OK the iteration
+ * is immediately stopped.
+ *
+ * Returns: GST_FLOW_OK if iteration was successful
+ */
+GstFlowReturn
+gst_pad_sticky_events_foreach (GstPad * pad,
+    GstPadStickyEventsForeachFunction foreach_func, gpointer user_data)
+{
+  GstFlowReturn ret = GST_FLOW_OK;
+  guint i;
+  GstEvent *event;
+
+  g_return_val_if_fail (GST_IS_PAD (pad), GST_FLOW_ERROR);
+  g_return_val_if_fail (foreach_func != NULL, GST_FLOW_ERROR);
+
+  GST_OBJECT_LOCK (pad);
+
+restart:
+  for (i = 0; i < GST_EVENT_MAX_STICKY; i++) {
+    gboolean res;
+    PadEvent *ev;
+
+    ev = &pad->priv->events[i];
+
+    /* skip without active event */
+    if ((event = ev->event) == NULL)
+      continue;
+
+    gst_event_ref (event);
+    GST_OBJECT_UNLOCK (pad);
+
+    res = foreach_func (pad, event, user_data);
+
+    GST_OBJECT_LOCK (pad);
+    gst_event_unref (event);
+
+    if (res != GST_FLOW_OK) {
+      ret = res;
+      break;
+    }
+
+    /* things could have changed while we release the lock, check if we still
+     * are handling the same event, if we don't something changed and we have
+     * to try again. FIXME. we need a cookie here. */
+    if (event != ev->event) {
+      GST_DEBUG_OBJECT (pad, "events changed, restarting");
+      goto restart;
+    }
+  }
+  GST_OBJECT_UNLOCK (pad);
+
+  return ret;
+}
+
 static void
 do_stream_status (GstPad * pad, GstStreamStatusType type,
     GThread * thread, GstTask * task)
index 5317dee..b22bfad 100644 (file)
 
 #include <gst/gstconfig.h>
 
+typedef struct _GstPad GstPad;
+typedef struct _GstPadPrivate GstPadPrivate;
+typedef struct _GstPadClass GstPadClass;
+
+/**
+ * GstPadDirection:
+ * @GST_PAD_UNKNOWN: direction is unknown.
+ * @GST_PAD_SRC: the pad is a source pad.
+ * @GST_PAD_SINK: the pad is a sink pad.
+ *
+ * The direction of a pad.
+ */
+typedef enum {
+  GST_PAD_UNKNOWN,
+  GST_PAD_SRC,
+  GST_PAD_SINK
+} GstPadDirection;
+
 #include <gst/gstobject.h>
 #include <gst/gstbuffer.h>
 #include <gst/gstbufferlist.h>
 #include <gst/gstcaps.h>
+#include <gst/gstpadtemplate.h>
 #include <gst/gstevent.h>
 #include <gst/gstquery.h>
 #include <gst/gsttask.h>
@@ -47,9 +66,6 @@ G_BEGIN_DECLS
 #define GST_PAD_CAST(obj)              ((GstPad*)(obj))
 
 
-typedef struct _GstPad GstPad;
-typedef struct _GstPadPrivate GstPadPrivate;
-typedef struct _GstPadClass GstPadClass;
 
 /**
  * GstPadLinkReturn:
@@ -149,41 +165,6 @@ typedef enum {
   GST_FLOW_CUSTOM_ERROR_2 = -102
 } GstFlowReturn;
 
-/**
- * GST_FLOW_IS_FATAL:
- * @ret: a #GstFlowReturn value
- *
- * Macro to test if the given #GstFlowReturn value indicates a fatal
- * error. This macro is mainly used in elements driving the pipeline to decide
- * whether an error message should be posted on the bus. Note that such
- * elements may also need to post an error message in the #GST_FLOW_NOT_LINKED
- * case which is not caught by this macro.
- *
- * Deprecated: This macro is badly named and can't be used in any real
- * scenarios without additional checks.
- */
-#ifndef GST_DISABLE_DEPRECATED
-#define GST_FLOW_IS_FATAL(ret) ((ret) <= GST_FLOW_UNEXPECTED)
-#endif
-
-/**
- * GST_FLOW_IS_SUCCESS:
- * @ret: a #GstFlowReturn value
- *
- * Macro to test if the given #GstFlowReturn value indicates a
- * successfull result
- * This macro is mainly used in elements to decide if the processing
- * of a buffer was successfull.
- *
- * Since: 0.10.7
- *
- * Deprecated: This macro is badly named and can't be used in any real
- * scenarios without additional checks.
- */
-#ifndef GST_DISABLE_DEPRECATED
-#define GST_FLOW_IS_SUCCESS(ret) ((ret) >= GST_FLOW_OK)
-#endif
-
 const gchar*           gst_flow_get_name       (GstFlowReturn ret);
 GQuark                 gst_flow_to_quark       (GstFlowReturn ret);
 
@@ -377,40 +358,8 @@ typedef GstFlowReturn              (*GstPadGetRangeFunction)       (GstPad *pad, guint64 offset,
 typedef gboolean               (*GstPadEventFunction)          (GstPad *pad, GstEvent *event);
 
 
-/* FIXME: 0.11: deprecate me, check range should use seeking query */
-/**
- * GstPadCheckGetRangeFunction:
- * @pad: a #GstPad
- *
- * Check if @pad can be activated in pull mode.
- *
- * This function will be deprecated after 0.10; use the seeking query to check
- * if a pad can support random access.
- *
- * Returns: TRUE if the pad can operate in pull mode.
- */
-typedef gboolean               (*GstPadCheckGetRangeFunction)  (GstPad *pad);
-
 /* internal links */
 /**
- * GstPadIntLinkFunction:
- * @pad: The #GstPad to query.
- *
- * The signature of the internal pad link function.
- *
- * Returns: (element-type Gst.Pad) (transfer container): a newly allocated #GList of pads that are linked to the given pad on
- * the inside of the parent element.
- *
- * The caller must call g_list_free() on it after use.
- *
- * Deprecated: use the threadsafe #GstPadIterIntLinkFunction instead.
- */
-#ifndef GST_DISABLE_DEPRECATED
-typedef GList*                 (*GstPadIntLinkFunction)        (GstPad *pad);
-#endif
-
-
-/**
  * GstPadIterIntLinkFunction:
  * @pad: The #GstPad to query.
  *
@@ -472,6 +421,13 @@ typedef void                       (*GstPadUnlinkFunction)         (GstPad *pad);
 /**
  * GstPadGetCapsFunction:
  * @pad: the #GstPad to get the capabilities of.
+ * @filter: filter #GstCaps.
+ *
+ * When called on sinkpads @filter contains the caps that
+ * upstream could produce in the order preferred by upstream. When
+ * called on srcpads @filter contains the caps accepted by
+ * downstream in the preffered order. @filter might be %NULL but if
+ * it is not %NULL only a subset of @filter must be returned.
  *
  * Returns a copy of the capabilities of the specified pad. By default this
  * function will return the pad template capabilities, but can optionally
@@ -479,21 +435,9 @@ typedef void                       (*GstPadUnlinkFunction)         (GstPad *pad);
  *
  * Returns: a newly allocated copy #GstCaps of the pad.
  */
-typedef GstCaps*               (*GstPadGetCapsFunction)        (GstPad *pad);
+typedef GstCaps*               (*GstPadGetCapsFunction)        (GstPad *pad, GstCaps *filter);
 
 /**
- * GstPadSetCapsFunction:
- * @pad: the #GstPad to set the capabilities of.
- * @caps: the #GstCaps to set
- *
- * Set @caps on @pad. By default this function updates the caps of the
- * pad but the function can be overriden by elements to perform extra
- * actions or verifications.
- *
- * Returns: TRUE if the caps could be set on the pad.
- */
-typedef gboolean               (*GstPadSetCapsFunction)        (GstPad *pad, GstCaps *caps);
-/**
  * GstPadAcceptCapsFunction:
  * @pad: the #GstPad to check
  * @caps: the #GstCaps to check
@@ -516,104 +460,128 @@ typedef gboolean                (*GstPadAcceptCapsFunction)     (GstPad *pad, GstCaps *caps);
  * elements can override this function to perform other behaviour.
  */
 typedef void                   (*GstPadFixateCapsFunction)     (GstPad *pad, GstCaps *caps);
-/**
- * GstPadBufferAllocFunction:
- * @pad: a sink #GstPad
- * @offset: the desired offset of the buffer
- * @size: the desired size of the buffer
- * @caps: the desired caps of the buffer
- * @buf: pointer to hold the allocated buffer.
- *
- * Ask the sinkpad @pad to allocate a buffer with @offset, @size and @caps.
- * The result will be stored in @buf.
- *
- * The purpose of this function is to allocate a buffer that is optimal to
- * be processed by @pad. The function is mostly overridden by elements that can
- * provide a hardware buffer in order to avoid additional memcpy operations.
- *
- * The function can return a buffer that has caps different from the requested
- * @caps, in which case the upstream element requests a format change to this
- * new caps.
- * If a format change was requested, the returned buffer will be one to hold
- * the data of said new caps, so its size might be different from the requested
- * @size.
- *
- * When this function returns anything else than #GST_FLOW_OK, the buffer allocation
- * failed and @buf does not contain valid data. If the function returns #GST_FLOW_OK and
- * the @buf is NULL, a #GstBuffer will be created with @caps, @offset and @size.
- *
- * By default this function returns a new buffer of @size and with @caps containing
- * purely malloced data. The buffer should be freed with gst_buffer_unref()
- * after usage.
- *
- * Returns: #GST_FLOW_OK if @buf contains a valid buffer, any other return
- *  value means @buf does not hold a valid buffer.
- */
-typedef GstFlowReturn          (*GstPadBufferAllocFunction)    (GstPad *pad, guint64 offset, guint size,
-                                                                GstCaps *caps, GstBuffer **buf);
 
 /* misc */
 /**
- * GstPadDispatcherFunction:
- * @pad: the #GstPad that is dispatched.
- * @data: the gpointer to optional user data.
+ * GstPadForwardFunction:
+ * @pad: the #GstPad that is forwarded.
+ * @user_data: the gpointer to optional user data.
  *
- * A dispatcher function is called for all internally linked pads, see
- * gst_pad_dispatcher().
+ * A forward function is called for all internally linked pads, see
+ * gst_pad_forward().
  *
  * Returns: TRUE if the dispatching procedure has to be stopped.
  */
-typedef gboolean               (*GstPadDispatcherFunction)     (GstPad *pad, gpointer data);
-
-/**
- * GstPadBlockCallback:
- * @pad: the #GstPad that is blockend or unblocked.
- * @blocked: blocking state for the pad
+typedef gboolean               (*GstPadForwardFunction)        (GstPad *pad, gpointer user_data);
+
+/**
+ * GstProbeType:
+ * @GST_PROBE_TYPE_INVALID: invalid probe type
+ * @GST_PROBE_TYPE_IDLE: probe idle pads and block
+ * @GST_PROBE_TYPE_BLOCK: probe and block pads
+ * @GST_PROBE_TYPE_BUFFER: probe buffers
+ * @GST_PROBE_TYPE_BUFFER_LIST: probe buffer lists
+ * @GST_PROBE_TYPE_EVENT: probe events
+ * @GST_PROBE_TYPE_PUSH: probe push
+ * @GST_PROBE_TYPE_PULL: probe pull
+ *
+ * The different probing types that can occur. When either one of
+ * @GST_PROBE_TYPE_IDLE or @GST_PROBE_TYPE_BLOCK is used, the probe will be a
+ * blocking probe.
+ */
+typedef enum
+{
+  GST_PROBE_TYPE_INVALID      = 0,
+  /* flags to control blocking */
+  GST_PROBE_TYPE_IDLE         = (1 << 0),
+  GST_PROBE_TYPE_BLOCK        = (1 << 1),
+  /* flags to select datatypes */
+  GST_PROBE_TYPE_BUFFER       = (1 << 2),
+  GST_PROBE_TYPE_BUFFER_LIST  = (1 << 3),
+  GST_PROBE_TYPE_EVENT        = (1 << 4),
+  /* flags to select scheduling mode */
+  GST_PROBE_TYPE_PUSH         = (1 << 5),
+  GST_PROBE_TYPE_PULL         = (1 << 6),
+} GstProbeType;
+
+#define GST_PROBE_TYPE_BLOCKING   (GST_PROBE_TYPE_IDLE | GST_PROBE_TYPE_BLOCK)
+#define GST_PROBE_TYPE_DATA       (GST_PROBE_TYPE_BUFFER | GST_PROBE_TYPE_EVENT | \
+                                   GST_PROBE_TYPE_BUFFER_LIST)
+#define GST_PROBE_TYPE_SCHEDULING (GST_PROBE_TYPE_PUSH | GST_PROBE_TYPE_PULL)
+
+/**
+ * GstProbeReturn:
+ * @GST_PROBE_OK: normal probe return value
+ * @GST_PROBE_DROP: drop data in data probes
+ * @GST_PROBE_REMOVE: remove probe
+ * @GST_PROBE_PASS: pass the data item in the block probe and block on
+ *                         the next item
+ *
+ * Different return values for the #GstPadProbeCallback.
+ */
+typedef enum
+{
+  GST_PROBE_DROP,
+  GST_PROBE_OK,
+  GST_PROBE_REMOVE,
+  GST_PROBE_PASS,
+} GstProbeReturn;
+
+/**
+ * GstPadProbeCallback
+ * @pad: the #GstPad that is blocked
+ * @type: the current probe type
+ * @type_data: type specific data
  * @user_data: the gpointer to optional user data.
  *
- * Callback used by gst_pad_set_blocked_async(). Gets called when the blocking
- * operation succeeds.
+ * Callback used by gst_pad_add_probe(). Gets called to notify about the current
+ * blocking type.
  */
-typedef void                   (*GstPadBlockCallback)          (GstPad *pad, gboolean blocked, gpointer user_data);
+typedef GstProbeReturn      (*GstPadProbeCallback)              (GstPad *pad, GstProbeType type,
+                                                                 gpointer type_data, gpointer user_data);
 
 /**
- * GstPadDirection:
- * @GST_PAD_UNKNOWN: direction is unknown.
- * @GST_PAD_SRC: the pad is a source pad.
- * @GST_PAD_SINK: the pad is a sink pad.
+ * GstPadStickyEventsForeachFunction:
+ * @pad: the #GstPad.
+ * @event: the sticky #GstEvent.
+ * @user_data: the #gpointer to optional user data.
  *
- * The direction of a pad.
+ * Callback used by gst_pad_sticky_events_foreach().
+ *
+ * Returns: GST_FLOW_OK if the iteration should continue
  */
-typedef enum {
-  GST_PAD_UNKNOWN,
-  GST_PAD_SRC,
-  GST_PAD_SINK
-} GstPadDirection;
+typedef GstFlowReturn           (*GstPadStickyEventsForeachFunction) (GstPad *pad, GstEvent *event, gpointer user_data);
 
 /**
  * GstPadFlags:
  * @GST_PAD_BLOCKED: is dataflow on a pad blocked
  * @GST_PAD_FLUSHING: is pad refusing buffers
  * @GST_PAD_IN_GETCAPS: GstPadGetCapsFunction() is running now
- * @GST_PAD_IN_SETCAPS: GstPadSetCapsFunction() is running now
  * @GST_PAD_BLOCKING: is pad currently blocking on a buffer or event
+ * @GST_PAD_NEED_RECONFIGURE: the pad should be reconfigured/renegotiated.
+ *                            The flag has to be unset manually after
+ *                            reconfiguration happened.
+ *                            Since: 0.10.34.
+ * @GST_PAD_NEED_EVENTS: the pad has pending events
+ * @GST_PAD_FIXED_CAPS: the pad is using fixed caps this means that once the
+ *                      caps are set on the pad, the getcaps function only
+ *                      returns those caps.
  * @GST_PAD_FLAG_LAST: offset to define more flags
  *
  * Pad state flags
  */
 typedef enum {
-  GST_PAD_BLOCKED       = (GST_OBJECT_FLAG_LAST << 0),
-  GST_PAD_FLUSHING      = (GST_OBJECT_FLAG_LAST << 1),
-  GST_PAD_IN_GETCAPS    = (GST_OBJECT_FLAG_LAST << 2),
-  GST_PAD_IN_SETCAPS    = (GST_OBJECT_FLAG_LAST << 3),
-  GST_PAD_BLOCKING     = (GST_OBJECT_FLAG_LAST << 4),
+  GST_PAD_BLOCKED          = (GST_OBJECT_FLAG_LAST << 0),
+  GST_PAD_FLUSHING         = (GST_OBJECT_FLAG_LAST << 1),
+  GST_PAD_IN_GETCAPS       = (GST_OBJECT_FLAG_LAST << 2),
+  GST_PAD_BLOCKING         = (GST_OBJECT_FLAG_LAST << 4),
+  GST_PAD_NEED_RECONFIGURE = (GST_OBJECT_FLAG_LAST << 5),
+  GST_PAD_NEED_EVENTS      = (GST_OBJECT_FLAG_LAST << 6),
+  GST_PAD_FIXED_CAPS       = (GST_OBJECT_FLAG_LAST << 7),
   /* padding */
-  GST_PAD_FLAG_LAST     = (GST_OBJECT_FLAG_LAST << 8)
+  GST_PAD_FLAG_LAST        = (GST_OBJECT_FLAG_LAST << 16)
 } GstPadFlags;
 
-/* FIXME: this awful circular dependency need to be resolved properly (see padtemplate.h) */
-typedef struct _GstPadTemplate GstPadTemplate;
-
 /**
  * GstPad:
  * @element_private: private data owned by the parent element
@@ -623,14 +591,8 @@ typedef struct _GstPadTemplate GstPadTemplate;
  * @stream_rec_lock: recursive stream lock of the pad, used to protect
  *                   the data used in streaming.
  * @task: task for this pad if the pad is actively driving dataflow.
- * @preroll_lock: lock used when prerolling
- * @preroll_cond: conf to signal preroll
  * @block_cond: conditional to signal pad block
- * @block_callback: callback for the pad block if any
- * @block_data: user data for @block_callback
- * @caps: the current caps of the pad
  * @getcapsfunc: function to get caps of the pad
- * @setcapsfunc: function to set caps on the pad
  * @acceptcapsfunc: function to check if pad can accept caps
  * @fixatecapsfunc: function to fixate caps
  * @activatefunc: pad activation function
@@ -639,108 +601,75 @@ typedef struct _GstPadTemplate GstPadTemplate;
  * @linkfunc: function called when pad is linked
  * @unlinkfunc: function called when pad is unlinked
  * @peer: the pad this pad is linked to
- * @sched_private: private storage for the scheduler
  * @chainfunc: function to chain buffer to pad
- * @checkgetrangefunc: function to check if pad can operate in pull mode
  * @getrangefunc: function to get a range of data from a pad
  * @eventfunc: function to send an event to a pad
  * @mode: current activation mode of the pad
  * @querytypefunc: get list of supported queries
  * @queryfunc: perform a query on the pad
- * @intlinkfunc: get the internal links of this pad
- * @bufferallocfunc: function to allocate a buffer for this pad
- * @do_buffer_signals: counter counting installed buffer signals
- * @do_event_signals: counter counting installed event signals
  * @iterintlinkfunc: get the internal links iterator of this pad
- * @block_destroy_data: notify function for gst_pad_set_blocked_async_full()
  *
  * The #GstPad structure. Use the functions to update the variables.
  */
 struct _GstPad {
-  GstObject                    object;
+  GstObject                      object;
 
   /*< public >*/
-  gpointer                     element_private;
+  gpointer                       element_private;
 
-  GstPadTemplate               *padtemplate;
+  GstPadTemplate                *padtemplate;
 
-  GstPadDirection               direction;
+  GstPadDirection                direction;
 
   /*< public >*/ /* with STREAM_LOCK */
   /* streaming rec_lock */
-  GStaticRecMutex              *stream_rec_lock;
+  GStaticRecMutex               stream_rec_lock;
   GstTask                      *task;
-  /*< public >*/ /* with PREROLL_LOCK */
-  GMutex                       *preroll_lock;
-  GCond                                *preroll_cond;
 
   /*< public >*/ /* with LOCK */
   /* block cond, mutex is from the object */
   GCond                                *block_cond;
-  GstPadBlockCallback           block_callback;
-  gpointer                      block_data;
+  GHookList                      probes;
 
   /* the pad capabilities */
-  GstCaps                      *caps;
   GstPadGetCapsFunction                getcapsfunc;
-  GstPadSetCapsFunction                setcapsfunc;
   GstPadAcceptCapsFunction      acceptcapsfunc;
   GstPadFixateCapsFunction      fixatecapsfunc;
 
+  GstActivateMode               mode;
   GstPadActivateFunction        activatefunc;
   GstPadActivateModeFunction    activatepushfunc;
   GstPadActivateModeFunction    activatepullfunc;
 
   /* pad link */
+  GstPad                       *peer;
   GstPadLinkFunction            linkfunc;
   GstPadUnlinkFunction          unlinkfunc;
-  GstPad                       *peer;
-
-  gpointer                      sched_private;
 
   /* data transport functions */
   GstPadChainFunction           chainfunc;
-  GstPadCheckGetRangeFunction   checkgetrangefunc;
+  GstPadChainListFunction        chainlistfunc;
   GstPadGetRangeFunction        getrangefunc;
   GstPadEventFunction           eventfunc;
 
-  GstActivateMode               mode;
+  /* pad offset */
+  gint64                         offset;
 
   /* generic query method */
   GstPadQueryTypeFunction       querytypefunc;
   GstPadQueryFunction           queryfunc;
 
   /* internal links */
-#ifndef GST_DISABLE_DEPRECATED
-  GstPadIntLinkFunction                 intlinkfunc;
-#else
-#ifndef __GTK_DOC_IGNORE__
-  gpointer intlinkfunc;
-#endif
-#endif
-
-  GstPadBufferAllocFunction      bufferallocfunc;
-
-  /* whether to emit signals for have-data. counts number
-   * of handlers attached. */
-  gint                          do_buffer_signals;
-  gint                          do_event_signals;
-
-  /* ABI added */
-  /* iterate internal links */
-  GstPadIterIntLinkFunction     iterintlinkfunc;
+  GstPadIterIntLinkFunction      iterintlinkfunc;
 
-  /* free block_data */
-  GDestroyNotify block_destroy_data;
+  /* counts number of probes attached. */
+  gint                          num_probes;
+  gint                          num_blocked;
 
   /*< private >*/
-  union {
-    struct {
-      gboolean                      block_callback_called;
-      GstPadPrivate                *priv;
-    } ABI;
-    gpointer _gst_reserved[GST_PADDING - 2];
-  } abidata;
+  GstPadPrivate                 *priv;
+
+  gpointer _gst_reserved[GST_PADDING];
 };
 
 struct _GstPadClass {
@@ -749,8 +678,6 @@ struct _GstPadClass {
   /* signal callbacks */
   void         (*linked)               (GstPad *pad, GstPad *peer);
   void         (*unlinked)             (GstPad *pad, GstPad *peer);
-  void         (*request_link)         (GstPad *pad);
-  gboolean     (*have_data)            (GstPad *pad, GstMiniObject *data);
 
   /*< private >*/
   gpointer _gst_reserved[GST_PADDING];
@@ -761,7 +688,7 @@ struct _GstPadClass {
 /* GstPad */
 #define GST_PAD_NAME(pad)              (GST_OBJECT_NAME(pad))
 #define GST_PAD_PARENT(pad)            (GST_ELEMENT_CAST(GST_OBJECT_PARENT(pad)))
-#define GST_PAD_ELEMENT_PRIVATE(pad)   (GST_PAD_CAST(pad)->element_private)
+#define GST_PAD_ELEMENT_PRIVATE(pad)    (GST_PAD_CAST(pad)->element_private)
 #define GST_PAD_PAD_TEMPLATE(pad)      (GST_PAD_CAST(pad)->padtemplate)
 #define GST_PAD_DIRECTION(pad)         (GST_PAD_CAST(pad)->direction)
 #define GST_PAD_TASK(pad)              (GST_PAD_CAST(pad)->task)
@@ -771,45 +698,33 @@ struct _GstPadClass {
 #define GST_PAD_ACTIVATEPUSHFUNC(pad)  (GST_PAD_CAST(pad)->activatepushfunc)
 #define GST_PAD_ACTIVATEPULLFUNC(pad)  (GST_PAD_CAST(pad)->activatepullfunc)
 #define GST_PAD_CHAINFUNC(pad)         (GST_PAD_CAST(pad)->chainfunc)
-#define GST_PAD_CHECKGETRANGEFUNC(pad) (GST_PAD_CAST(pad)->checkgetrangefunc)
+#define GST_PAD_CHAINLISTFUNC(pad)      (GST_PAD_CAST(pad)->chainlistfunc)
 #define GST_PAD_GETRANGEFUNC(pad)      (GST_PAD_CAST(pad)->getrangefunc)
 #define GST_PAD_EVENTFUNC(pad)         (GST_PAD_CAST(pad)->eventfunc)
 #define GST_PAD_QUERYTYPEFUNC(pad)     (GST_PAD_CAST(pad)->querytypefunc)
 #define GST_PAD_QUERYFUNC(pad)         (GST_PAD_CAST(pad)->queryfunc)
-#ifndef GST_DISABLE_DEPRECATED
-#define GST_PAD_INTLINKFUNC(pad)       (GST_PAD_CAST(pad)->intlinkfunc)
-#endif
 #define GST_PAD_ITERINTLINKFUNC(pad)    (GST_PAD_CAST(pad)->iterintlinkfunc)
 
 #define GST_PAD_PEER(pad)              (GST_PAD_CAST(pad)->peer)
 #define GST_PAD_LINKFUNC(pad)          (GST_PAD_CAST(pad)->linkfunc)
 #define GST_PAD_UNLINKFUNC(pad)                (GST_PAD_CAST(pad)->unlinkfunc)
 
-/**
- * GST_PAD_CAPS:
- * @pad: a #GstPad.
- *
- * The caps for this pad.
- */
-#define GST_PAD_CAPS(pad)              (GST_PAD_CAST(pad)->caps)
 #define GST_PAD_GETCAPSFUNC(pad)       (GST_PAD_CAST(pad)->getcapsfunc)
-#define GST_PAD_SETCAPSFUNC(pad)       (GST_PAD_CAST(pad)->setcapsfunc)
 #define GST_PAD_ACCEPTCAPSFUNC(pad)    (GST_PAD_CAST(pad)->acceptcapsfunc)
 #define GST_PAD_FIXATECAPSFUNC(pad)    (GST_PAD_CAST(pad)->fixatecapsfunc)
 
-#define GST_PAD_BUFFERALLOCFUNC(pad)   (GST_PAD_CAST(pad)->bufferallocfunc)
-
-#define GST_PAD_DO_BUFFER_SIGNALS(pad)         (GST_PAD_CAST(pad)->do_buffer_signals)
-#define GST_PAD_DO_EVENT_SIGNALS(pad)  (GST_PAD_CAST(pad)->do_event_signals)
+#define GST_PAD_IS_SRC(pad)            (GST_PAD_DIRECTION(pad) == GST_PAD_SRC)
+#define GST_PAD_IS_SINK(pad)           (GST_PAD_DIRECTION(pad) == GST_PAD_SINK)
 
 #define GST_PAD_IS_LINKED(pad)         (GST_PAD_PEER(pad) != NULL)
+
 #define GST_PAD_IS_BLOCKED(pad)                (GST_OBJECT_FLAG_IS_SET (pad, GST_PAD_BLOCKED))
 #define GST_PAD_IS_BLOCKING(pad)       (GST_OBJECT_FLAG_IS_SET (pad, GST_PAD_BLOCKING))
 #define GST_PAD_IS_FLUSHING(pad)       (GST_OBJECT_FLAG_IS_SET (pad, GST_PAD_FLUSHING))
 #define GST_PAD_IS_IN_GETCAPS(pad)     (GST_OBJECT_FLAG_IS_SET (pad, GST_PAD_IN_GETCAPS))
-#define GST_PAD_IS_IN_SETCAPS(pad)     (GST_OBJECT_FLAG_IS_SET (pad, GST_PAD_IN_SETCAPS))
-#define GST_PAD_IS_SRC(pad)            (GST_PAD_DIRECTION(pad) == GST_PAD_SRC)
-#define GST_PAD_IS_SINK(pad)           (GST_PAD_DIRECTION(pad) == GST_PAD_SINK)
+#define GST_PAD_NEEDS_RECONFIGURE(pad)  (GST_OBJECT_FLAG_IS_SET (pad, GST_PAD_NEED_RECONFIGURE))
+#define GST_PAD_NEEDS_EVENTS(pad)       (GST_OBJECT_FLAG_IS_SET (pad, GST_PAD_NEED_EVENTS))
+#define GST_PAD_IS_FIXED_CAPS(pad)     (GST_OBJECT_FLAG_IS_SET (pad, GST_PAD_FIXED_CAPS))
 
 #define GST_PAD_SET_FLUSHING(pad)      (GST_OBJECT_FLAG_SET (pad, GST_PAD_FLUSHING))
 #define GST_PAD_UNSET_FLUSHING(pad)    (GST_OBJECT_FLAG_UNSET (pad, GST_PAD_FLUSHING))
@@ -821,7 +736,7 @@ struct _GstPadClass {
  * Get the stream lock of @pad. The stream lock is protecting the
  * resources used in the data processing functions of @pad.
  */
-#define GST_PAD_GET_STREAM_LOCK(pad)    (GST_PAD_CAST(pad)->stream_rec_lock)
+#define GST_PAD_GET_STREAM_LOCK(pad)    (&(GST_PAD_CAST(pad)->stream_rec_lock))
 /**
  * GST_PAD_STREAM_LOCK:
  * @pad: a #GstPad
@@ -861,27 +776,11 @@ struct _GstPadClass {
  */
 #define GST_PAD_STREAM_UNLOCK_FULL(pad) (g_static_rec_mutex_unlock_full(GST_PAD_GET_STREAM_LOCK(pad)))
 
-#define GST_PAD_GET_PREROLL_LOCK(pad)   (GST_PAD_CAST(pad)->preroll_lock)
-#define GST_PAD_PREROLL_LOCK(pad)       (g_mutex_lock(GST_PAD_GET_PREROLL_LOCK(pad)))
-#define GST_PAD_PREROLL_TRYLOCK(pad)    (g_mutex_trylock(GST_PAD_GET_PREROLL_LOCK(pad)))
-#define GST_PAD_PREROLL_UNLOCK(pad)     (g_mutex_unlock(GST_PAD_GET_PREROLL_LOCK(pad)))
-
-#define GST_PAD_GET_PREROLL_COND(pad)   (GST_PAD_CAST(pad)->preroll_cond)
-#define GST_PAD_PREROLL_WAIT(pad)       \
-    g_cond_wait (GST_PAD_GET_PREROLL_COND (pad), GST_PAD_GET_PREROLL_LOCK (pad))
-#define GST_PAD_PREROLL_TIMED_WAIT(pad, timeval) \
-    g_cond_timed_wait (GST_PAD_GET_PREROLL_COND (pad), GST_PAD_GET_PREROLL_LOCK (pad), timeval)
-#define GST_PAD_PREROLL_SIGNAL(pad)     g_cond_signal (GST_PAD_GET_PREROLL_COND (pad));
-#define GST_PAD_PREROLL_BROADCAST(pad)  g_cond_broadcast (GST_PAD_GET_PREROLL_COND (pad));
-
 #define GST_PAD_BLOCK_GET_COND(pad)     (GST_PAD_CAST(pad)->block_cond)
 #define GST_PAD_BLOCK_WAIT(pad)         (g_cond_wait(GST_PAD_BLOCK_GET_COND (pad), GST_OBJECT_GET_LOCK (pad)))
 #define GST_PAD_BLOCK_SIGNAL(pad)       (g_cond_signal(GST_PAD_BLOCK_GET_COND (pad)))
 #define GST_PAD_BLOCK_BROADCAST(pad)    (g_cond_broadcast(GST_PAD_BLOCK_GET_COND (pad)))
 
-/* FIXME: this awful circular dependency need to be resolved properly (see padtemplate.h) */
-#include <gst/gstpadtemplate.h>
-
 GType                  gst_pad_get_type                        (void);
 
 /* creating pads */
@@ -918,34 +817,33 @@ gboolean          gst_pad_is_active                       (GstPad *pad);
 gboolean               gst_pad_activate_pull                   (GstPad *pad, gboolean active);
 gboolean               gst_pad_activate_push                   (GstPad *pad, gboolean active);
 
-gboolean               gst_pad_set_blocked                     (GstPad *pad, gboolean blocked);
-gboolean               gst_pad_set_blocked_async               (GstPad *pad, gboolean blocked,
-                                                                GstPadBlockCallback callback, gpointer user_data);
-gboolean               gst_pad_set_blocked_async_full          (GstPad *pad, gboolean blocked,
-                                                                GstPadBlockCallback callback, gpointer user_data,
+gulong                  gst_pad_add_probe                       (GstPad *pad,
+                                                                GstProbeType mask,
+                                                                GstPadProbeCallback callback,
+                                                                 gpointer user_data,
                                                                  GDestroyNotify destroy_data);
+void                    gst_pad_remove_probe                    (GstPad *pad, gulong id);
+
 gboolean               gst_pad_is_blocked                      (GstPad *pad);
 gboolean               gst_pad_is_blocking                     (GstPad *pad);
 
+gboolean               gst_pad_check_reconfigure               (GstPad *pad);
+
 void                   gst_pad_set_element_private             (GstPad *pad, gpointer priv);
 gpointer               gst_pad_get_element_private             (GstPad *pad);
 
 GstPadTemplate*                gst_pad_get_pad_template                (GstPad *pad);
 
-void                   gst_pad_set_bufferalloc_function        (GstPad *pad, GstPadBufferAllocFunction bufalloc);
-GstFlowReturn          gst_pad_alloc_buffer                    (GstPad *pad, guint64 offset, gint size,
-                                                                GstCaps *caps, GstBuffer **buf);
-GstFlowReturn          gst_pad_alloc_buffer_and_set_caps       (GstPad *pad, guint64 offset, gint size,
-                                                                GstCaps *caps, GstBuffer **buf);
+GstEvent*               gst_pad_get_sticky_event                (GstPad *pad, GstEventType event_type);
+GstFlowReturn           gst_pad_sticky_events_foreach           (GstPad *pad, GstPadStickyEventsForeachFunction foreach_func, gpointer user_data);
 
 /* data passing setup functions */
 void                   gst_pad_set_activate_function           (GstPad *pad, GstPadActivateFunction activate);
 void                   gst_pad_set_activatepull_function       (GstPad *pad, GstPadActivateModeFunction activatepull);
 void                   gst_pad_set_activatepush_function       (GstPad *pad, GstPadActivateModeFunction activatepush);
 void                   gst_pad_set_chain_function              (GstPad *pad, GstPadChainFunction chain);
-void                   gst_pad_set_chain_list_function (GstPad *pad, GstPadChainListFunction chainlist);
+void                   gst_pad_set_chain_list_function         (GstPad *pad, GstPadChainListFunction chainlist);
 void                   gst_pad_set_getrange_function           (GstPad *pad, GstPadGetRangeFunction get);
-void                   gst_pad_set_checkgetrange_function      (GstPad *pad, GstPadCheckGetRangeFunction check);
 void                   gst_pad_set_event_function              (GstPad *pad, GstPadEventFunction event);
 
 /* pad links */
@@ -964,29 +862,31 @@ GstPad*                   gst_pad_get_peer                        (GstPad *pad);
 void                   gst_pad_set_getcaps_function            (GstPad *pad, GstPadGetCapsFunction getcaps);
 void                   gst_pad_set_acceptcaps_function         (GstPad *pad, GstPadAcceptCapsFunction acceptcaps);
 void                   gst_pad_set_fixatecaps_function         (GstPad *pad, GstPadFixateCapsFunction fixatecaps);
-void                   gst_pad_set_setcaps_function            (GstPad *pad, GstPadSetCapsFunction setcaps);
 
-const GstCaps*         gst_pad_get_pad_template_caps           (GstPad *pad);
+GstCaps*                gst_pad_get_pad_template_caps          (GstPad *pad);
 
 /* capsnego function for linked/unlinked pads */
-GstCaps *              gst_pad_get_caps_reffed                 (GstPad * pad);
-GstCaps *              gst_pad_get_caps                        (GstPad * pad);
+GstCaps *              gst_pad_get_current_caps                (GstPad * pad);
+gboolean               gst_pad_has_current_caps                (GstPad * pad);
+GstCaps *              gst_pad_get_caps                        (GstPad * pad, GstCaps *filter);
 void                   gst_pad_fixate_caps                     (GstPad * pad, GstCaps *caps);
 gboolean               gst_pad_accept_caps                     (GstPad * pad, GstCaps *caps);
 gboolean               gst_pad_set_caps                        (GstPad * pad, GstCaps *caps);
 
-GstCaps *              gst_pad_peer_get_caps_reffed            (GstPad * pad);
-GstCaps *              gst_pad_peer_get_caps                   (GstPad * pad);
+GstCaps *              gst_pad_peer_get_caps                   (GstPad * pad, GstCaps *filter);
 gboolean               gst_pad_peer_accept_caps                (GstPad * pad, GstCaps *caps);
 
 /* capsnego for linked pads */
 GstCaps *              gst_pad_get_allowed_caps                (GstPad * pad);
-GstCaps *              gst_pad_get_negotiated_caps             (GstPad * pad);
+GstCaps *               gst_pad_get_negotiated_caps             (GstPad * pad);
+
+/* pad offsets */
+gint64                  gst_pad_get_offset                      (GstPad *pad);
+void                    gst_pad_set_offset                      (GstPad *pad, gint64 offset);
 
 /* data passing functions to peer */
 GstFlowReturn          gst_pad_push                            (GstPad *pad, GstBuffer *buffer);
 GstFlowReturn          gst_pad_push_list                       (GstPad *pad, GstBufferList *list);
-gboolean               gst_pad_check_pull_range                (GstPad *pad);
 GstFlowReturn          gst_pad_pull_range                      (GstPad *pad, guint64 offset, guint size,
                                                                 GstBuffer **buffer);
 gboolean               gst_pad_push_event                      (GstPad *pad, GstEvent *event);
@@ -1006,12 +906,6 @@ gboolean          gst_pad_pause_task                      (GstPad *pad);
 gboolean               gst_pad_stop_task                       (GstPad *pad);
 
 /* internal links */
-#ifndef GST_DISABLE_DEPRECATED
-void                   gst_pad_set_internal_link_function      (GstPad *pad, GstPadIntLinkFunction intlink);
-GList*                 gst_pad_get_internal_links              (GstPad *pad);
-GList*                 gst_pad_get_internal_links_default      (GstPad *pad);
-#endif
-
 void                    gst_pad_set_iterate_internal_links_function (GstPad * pad,
                                                                  GstPadIterIntLinkFunction iterintlink);
 GstIterator *           gst_pad_iterate_internal_links          (GstPad * pad);
@@ -1029,12 +923,8 @@ void                      gst_pad_set_query_function              (GstPad *pad, GstPadQueryFunction query);
 gboolean               gst_pad_query_default                   (GstPad *pad, GstQuery *query);
 
 /* misc helper functions */
-gboolean               gst_pad_dispatcher                      (GstPad *pad, GstPadDispatcherFunction dispatch,
-                                                                gpointer data);
-
-#if !defined(GST_DISABLE_LOADSAVE) && !defined(GST_DISABLE_DEPRECATED)
-void                   gst_pad_load_and_link                   (xmlNodePtr self, GstObject *parent);
-#endif
+gboolean               gst_pad_forward                         (GstPad *pad, GstPadForwardFunction forward,
+                                                                gpointer user_data);
 
 G_END_DECLS
 
index 44dd903..e6c8c0b 100644 (file)
  * </example>
  *
  * The following example shows you how to add the padtemplate to an
- * element class, this is usually done in the base_init of the class:
+ * element class, this is usually done in the class_init of the class:
  * <informalexample>
  *   <programlisting>
  *   static void
- *   my_element_base_init (gpointer g_class)
+ *   my_element_class_init (GstMyElementClass *klass)
  *   {
- *     GstElementClass *gstelement_class = GST_ELEMENT_CLASS (g_class);
+ *     GstElementClass *gstelement_class = GST_ELEMENT_CLASS (klass);
  *
  *     gst_element_class_add_pad_template (gstelement_class,
  *         gst_static_pad_template_get (&amp;my_template));
@@ -219,20 +219,6 @@ gst_pad_template_class_init (GstPadTemplateClass * klass)
 static void
 gst_pad_template_init (GstPadTemplate * templ)
 {
-  /* FIXME 0.11: Does anybody remember why this is here? If not, let's
-   * change it for 0.11 and let gst_element_class_add_pad_template() for
-   * example ref/sink the pad templates.
-   */
-  /* We ensure that the pad template we're creating has a sunken reference.
-   * Inconsistencies in pad templates being floating or sunken has caused
-   * problems in the past with leaks, etc.
-   *
-   * For consistency, then, we only produce them  with sunken references
-   * owned by the creator of the object
-   */
-  if (GST_OBJECT_IS_FLOATING (templ)) {
-    gst_object_ref_sink (templ);
-  }
 }
 
 static void
@@ -336,12 +322,10 @@ gst_static_pad_template_get (GstStaticPadTemplate * pad_template)
  * @name_template: the name template.
  * @direction: the #GstPadDirection of the template.
  * @presence: the #GstPadPresence of the pad.
- * @caps: (transfer full): a #GstCaps set for the template. The caps are
- *     taken ownership of.
+ * @caps: a #GstCaps set for the template.
  *
  * Creates a new pad template with a name according to the given template
- * and with the given arguments. This functions takes ownership of the provided
- * caps, so be sure to not use them afterwards.
+ * and with the given arguments.
  *
  * Returns: (transfer full): a new #GstPadTemplate.
  */
@@ -359,7 +343,6 @@ gst_pad_template_new (const gchar * name_template,
       || presence == GST_PAD_SOMETIMES || presence == GST_PAD_REQUEST, NULL);
 
   if (!name_is_valid (name_template, presence)) {
-    gst_caps_unref (caps);
     return NULL;
   }
 
@@ -367,8 +350,6 @@ gst_pad_template_new (const gchar * name_template,
       "name", name_template, "name-template", name_template,
       "direction", direction, "presence", presence, "caps", caps, NULL);
 
-  gst_caps_unref (caps);
-
   return new;
 }
 
@@ -397,15 +378,18 @@ gst_static_pad_template_get_caps (GstStaticPadTemplate * templ)
  *
  * Gets the capabilities of the pad template.
  *
- * Returns: (transfer none): the #GstCaps of the pad template. If you need to
- *     keep a reference to the caps, take a ref (see gst_caps_ref ()).
+ * Returns: (transfer full): the #GstCaps of the pad template.
+ * Unref after usage.
  */
 GstCaps *
 gst_pad_template_get_caps (GstPadTemplate * templ)
 {
+  GstCaps *caps;
   g_return_val_if_fail (GST_IS_PAD_TEMPLATE (templ), NULL);
 
-  return GST_PAD_TEMPLATE_CAPS (templ);
+  caps = GST_PAD_TEMPLATE_CAPS (templ);
+
+  return (caps ? gst_caps_ref (caps) : NULL);
 }
 
 /**
@@ -437,12 +421,7 @@ gst_pad_template_set_property (GObject * object, guint prop_id,
       GST_PAD_TEMPLATE_PRESENCE (object) = g_value_get_enum (value);
       break;
     case PROP_CAPS:
-      /* allow caps == NULL for backwards compatibility (ie. g_object_new()
-       * called without any of the new properties) (FIXME 0.11) */
-      if (g_value_get_boxed (value) != NULL) {
-        GST_PAD_TEMPLATE_CAPS (object) =
-            gst_caps_copy (g_value_get_boxed (value));
-      }
+      GST_PAD_TEMPLATE_CAPS (object) = g_value_dup_boxed (value);
       break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
index 9710f4a..bc2bcee 100644 (file)
 
 #include <gst/gstconfig.h>
 
+typedef struct _GstPadTemplate GstPadTemplate;
+typedef struct _GstPadTemplateClass GstPadTemplateClass;
+typedef struct _GstStaticPadTemplate GstStaticPadTemplate;
+
 #include <gst/gstobject.h>
 #include <gst/gstbuffer.h>
 #include <gst/gstcaps.h>
 
 G_BEGIN_DECLS
 
-/* FIXME: this awful circular dependency need to be resolved properly (see pad.h) */
-/*typedef struct _GstPadTemplate GstPadTemplate; */
-typedef struct _GstPadTemplateClass GstPadTemplateClass;
-typedef struct _GstStaticPadTemplate GstStaticPadTemplate;
-
 #define GST_TYPE_STATIC_PAD_TEMPLATE   (gst_static_pad_template_get_type ())
 
 #define GST_TYPE_PAD_TEMPLATE          (gst_pad_template_get_type ())
@@ -97,14 +96,11 @@ typedef enum {
 
 /**
  * GstPadTemplateFlags:
- * @GST_PAD_TEMPLATE_FIXED: the padtemplate has no variable properties
  * @GST_PAD_TEMPLATE_FLAG_LAST: first flag that can be used by subclasses.
  *
  * Flags for the padtemplate
  */
 typedef enum {
-  /* FIXME0.11: this is not used and the purpose is unclear */
-  GST_PAD_TEMPLATE_FIXED        = (GST_OBJECT_FLAG_LAST << 0),
   /* padding */
   GST_PAD_TEMPLATE_FLAG_LAST    = (GST_OBJECT_FLAG_LAST << 4)
 } GstPadTemplateFlags;
index 80a169e..839d08e 100644 (file)
@@ -223,7 +223,7 @@ _gst_parse_escape (const gchar * str)
 GstElement *
 gst_parse_launchv (const gchar ** argv, GError ** error)
 {
-  return gst_parse_launchv_full (argv, NULL, 0, error);
+  return gst_parse_launchv_full (argv, NULL, GST_PARSE_FLAG_NONE, error);
 }
 
 /**
@@ -299,7 +299,8 @@ gst_parse_launchv_full (const gchar ** argv, GstParseContext * context,
 GstElement *
 gst_parse_launch (const gchar * pipeline_description, GError ** error)
 {
-  return gst_parse_launch_full (pipeline_description, NULL, 0, error);
+  return gst_parse_launch_full (pipeline_description, NULL, GST_PARSE_FLAG_NONE,
+      error);
 }
 
 /**
index d80a38a..a9a74c2 100644 (file)
@@ -139,25 +139,14 @@ static void gst_pipeline_handle_message (GstBin * bin, GstMessage * message);
 
 /* static guint gst_pipeline_signals[LAST_SIGNAL] = { 0 }; */
 
-#define _do_init(type) \
+#define _do_init \
 { \
   GST_DEBUG_CATEGORY_INIT (pipeline_debug, "pipeline", GST_DEBUG_BOLD, \
       "debugging info for the 'pipeline' container element"); \
 }
 
-GST_BOILERPLATE_FULL (GstPipeline, gst_pipeline, GstBin, GST_TYPE_BIN,
-    _do_init);
-
-static void
-gst_pipeline_base_init (gpointer g_class)
-{
-  GstElementClass *gstelement_class = GST_ELEMENT_CLASS (g_class);
-
-  gst_element_class_set_details_simple (gstelement_class, "Pipeline object",
-      "Generic/Bin",
-      "Complete pipeline object",
-      "Erik Walthinsen <omega@cse.ogi.edu>, Wim Taymans <wim@fluendo.com>");
-}
+#define gst_pipeline_parent_class parent_class
+G_DEFINE_TYPE_WITH_CODE (GstPipeline, gst_pipeline, GST_TYPE_BIN, _do_init);
 
 static void
 gst_pipeline_class_init (GstPipelineClass * klass)
@@ -203,6 +192,11 @@ gst_pipeline_class_init (GstPipelineClass * klass)
 
   gobject_class->dispose = gst_pipeline_dispose;
 
+  gst_element_class_set_metadata (gstelement_class, "Pipeline object",
+      "Generic/Bin",
+      "Complete pipeline object",
+      "Erik Walthinsen <omega@cse.ogi.edu>, Wim Taymans <wim@fluendo.com>");
+
   gstelement_class->change_state =
       GST_DEBUG_FUNCPTR (gst_pipeline_change_state);
   gstelement_class->provide_clock =
@@ -212,7 +206,7 @@ gst_pipeline_class_init (GstPipelineClass * klass)
 }
 
 static void
-gst_pipeline_init (GstPipeline * pipeline, GstPipelineClass * klass)
+gst_pipeline_init (GstPipeline * pipeline)
 {
   GstBus *bus;
 
@@ -554,15 +548,15 @@ gst_pipeline_handle_message (GstBin * bin, GstMessage * message)
   GstPipeline *pipeline = GST_PIPELINE_CAST (bin);
 
   switch (GST_MESSAGE_TYPE (message)) {
-    case GST_MESSAGE_ASYNC_START:
+    case GST_MESSAGE_ASYNC_DONE:
     {
-      gboolean new_base_time;
+      gboolean reset_time;
 
-      gst_message_parse_async_start (message, &new_base_time);
+      gst_message_parse_async_done (message, &reset_time);
 
       /* reset our running time if we need to distribute a new base_time to the
        * children. */
-      if (new_base_time)
+      if (reset_time)
         reset_start_time (pipeline);
 
       break;
@@ -604,80 +598,6 @@ gst_pipeline_get_bus (GstPipeline * pipeline)
   return gst_element_get_bus (GST_ELEMENT_CAST (pipeline));
 }
 
-/**
- * gst_pipeline_set_new_stream_time:
- * @pipeline: a #GstPipeline
- * @time: the new running time to set
- *
- * Set the new start time of @pipeline to @time. The start time is used to
- * set the base time on the elements (see gst_element_set_base_time())
- * in the PAUSED->PLAYING state transition.
- *
- * Setting @time to #GST_CLOCK_TIME_NONE will disable the pipeline's management
- * of element base time. The application will then be responsible for
- * performing base time distribution. This is sometimes useful if you want to
- * synchronize capture from multiple pipelines, and you can also ensure that the
- * pipelines have the same clock.
- *
- * MT safe.
- *
- * Deprecated: This function has the wrong name and is equivalent to
- * gst_element_set_start_time(). 
- */
-#ifndef GST_REMOVE_DEPRECATED
-#ifdef GST_DISABLE_DEPRECATED
-void
-gst_pipeline_set_new_stream_time (GstPipeline * pipeline, GstClockTime time);
-#endif
-void
-gst_pipeline_set_new_stream_time (GstPipeline * pipeline, GstClockTime time)
-{
-  g_return_if_fail (GST_IS_PIPELINE (pipeline));
-
-  gst_element_set_start_time (GST_ELEMENT_CAST (pipeline), time);
-
-  if (time == GST_CLOCK_TIME_NONE)
-    GST_DEBUG_OBJECT (pipeline, "told not to adjust base_time");
-}
-#endif /* GST_REMOVE_DEPRECATED */
-
-/**
- * gst_pipeline_get_last_stream_time:
- * @pipeline: a #GstPipeline
- *
- * Gets the last running time of @pipeline. If the pipeline is PLAYING,
- * the returned time is the running time used to configure the element's
- * base time in the PAUSED->PLAYING state. If the pipeline is PAUSED, the
- * returned time is the running time when the pipeline was paused.
- *
- * This function returns #GST_CLOCK_TIME_NONE if the pipeline was
- * configured to not handle the management of the element's base time
- * (see gst_pipeline_set_new_stream_time()).
- *
- * MT safe.
- *
- * Returns: a #GstClockTime.
- *
- * Deprecated: This function has the wrong name and is equivalent to
- * gst_element_get_start_time(). 
- */
-#ifndef GST_REMOVE_DEPRECATED
-#ifdef GST_DISABLE_DEPRECATED
-GstClockTime gst_pipeline_get_last_stream_time (GstPipeline * pipeline);
-#endif
-GstClockTime
-gst_pipeline_get_last_stream_time (GstPipeline * pipeline)
-{
-  GstClockTime result;
-
-  g_return_val_if_fail (GST_IS_PIPELINE (pipeline), GST_CLOCK_TIME_NONE);
-
-  result = gst_element_get_start_time (GST_ELEMENT_CAST (pipeline));
-
-  return result;
-}
-#endif /* GST_REMOVE_DEPRECATED */
-
 static GstClock *
 gst_pipeline_provide_clock_func (GstElement * element)
 {
index 6180c16..7dbf96f 100644 (file)
@@ -93,11 +93,6 @@ GstElement*  gst_pipeline_new                (const gchar *name);
 
 GstBus*                gst_pipeline_get_bus            (GstPipeline *pipeline);
 
-#ifndef GST_DISABLE_DEPRECATED
-void           gst_pipeline_set_new_stream_time  (GstPipeline *pipeline, GstClockTime time);
-GstClockTime   gst_pipeline_get_last_stream_time (GstPipeline *pipeline);
-#endif
-
 void            gst_pipeline_use_clock          (GstPipeline *pipeline, GstClock *clock);
 gboolean        gst_pipeline_set_clock          (GstPipeline *pipeline, GstClock *clock);
 GstClock*       gst_pipeline_get_clock          (GstPipeline *pipeline);
index 0fad4d5..68c4d2d 100644 (file)
@@ -164,38 +164,6 @@ gst_plugin_error_quark (void)
   return quark;
 }
 
-#ifndef GST_REMOVE_DEPRECATED
-#ifdef GST_DISABLE_DEPRECATED
-void _gst_plugin_register_static (GstPluginDesc * desc);
-#endif
-/* this function can be called in the GCC constructor extension, before
- * the _gst_plugin_initialize() was called. In that case, we store the
- * plugin description in a list to initialize it when we open the main
- * module later on.
- * When the main module is known, we can register the plugin right away.
- */
-void
-_gst_plugin_register_static (GstPluginDesc * desc)
-{
-  g_return_if_fail (desc != NULL);
-
-  if (!_gst_plugin_inited) {
-    /* We can't use any GLib functions here, since g_thread_init hasn't been
-     * called yet, and we can't call it here either, or programs that don't
-     * guard their g_thread_init calls in main() will just abort */
-    ++_num_static_plugins;
-    _static_plugins =
-        realloc (_static_plugins, _num_static_plugins * sizeof (GstPluginDesc));
-    /* assume strings in the GstPluginDesc are static const or live forever */
-    _static_plugins[_num_static_plugins - 1] = *desc;
-  } else {
-    gst_plugin_register_static (desc->major_version, desc->minor_version,
-        desc->name, desc->description, desc->plugin_init, desc->version,
-        desc->license, desc->source, desc->package, desc->origin);
-  }
-}
-#endif
-
 /**
  * gst_plugin_register_static:
  * @major_version: the major version number of the GStreamer core that the
@@ -1570,7 +1538,7 @@ gst_plugin_ext_dep_scan_dir_and_match_names (GstPlugin * plugin,
   GDir *dir;
   guint hash = 0;
 
-  recurse_dirs = ! !(flags & GST_PLUGIN_DEPENDENCY_FLAG_RECURSE);
+  recurse_dirs = !!(flags & GST_PLUGIN_DEPENDENCY_FLAG_RECURSE);
 
   dir = g_dir_open (path, 0, &err);
   if (dir == NULL) {
@@ -1632,8 +1600,8 @@ gst_plugin_ext_dep_scan_path_with_filenames (GstPlugin * plugin,
   if (filenames == NULL || *filenames == NULL)
     filenames = empty_filenames;
 
-  recurse_into_dirs = ! !(flags & GST_PLUGIN_DEPENDENCY_FLAG_RECURSE);
-  partial_names = ! !(flags & GST_PLUGIN_DEPENDENCY_FLAG_FILE_NAME_IS_SUFFIX);
+  recurse_into_dirs = !!(flags & GST_PLUGIN_DEPENDENCY_FLAG_RECURSE);
+  partial_names = !!(flags & GST_PLUGIN_DEPENDENCY_FLAG_FILE_NAME_IS_SUFFIX);
 
   /* if we can construct the exact paths to check with the data we have, just
    * stat them one by one; this is more efficient than opening the directory
index 81ad00a..32bec0d 100644 (file)
@@ -175,7 +175,7 @@ struct _GstPluginDesc {
   const gchar *origin;
   const gchar *release_datetime;
   /*< private >*/
-  gpointer _gst_reserved[GST_PADDING - 1];
+  gpointer _gst_reserved[GST_PADDING];
 };
 
 
@@ -213,7 +213,7 @@ struct _GstPlugin {
                                  * that matches the plugin's basename */
 
   GstPluginPrivate *priv;
-  gpointer _gst_reserved[GST_PADDING - 1];
+  gpointer _gst_reserved[GST_PADDING];
 };
 
 struct _GstPluginClass {
@@ -273,53 +273,6 @@ GST_PLUGIN_EXPORT GstPluginDesc gst_plugin_desc = {        \
 G_END_DECLS
 
 /**
- * GST_PLUGIN_DEFINE_STATIC:
- * @major: major version number of the gstreamer-core that plugin was compiled for
- * @minor: minor version number of the gstreamer-core that plugin was compiled for
- * @name: short, but unique name of the plugin
- * @description: information about the purpose of the plugin
- * @init: function pointer to the plugin_init method with the signature of <code>static gboolean plugin_init (GstPlugin * plugin)</code>.
- * @version: full version string (e.g. VERSION from config.h)
- * @license: under which licence the package has been released, e.g. GPL, LGPL.
- * @package: the package-name (e.g. PACKAGE_NAME from config.h)
- * @origin: a description from where the package comes from (e.g. the homepage URL)
- *
- * This macro needs to be used to define the entry point and meta data of a
- * local plugin. One would use this macro to define a local plugin that can only
- * be used by the own application.
- *
- * The macro uses a define named PACKAGE for the #GstPluginDesc.source field.
- *
- * Deprecated: Use gst_plugin_register_static() instead. This macro was
- * deprecated because it uses constructors, which is a compiler feature not
- * available on all compilers.
- *
- */
-/* We don't have deprecation guards here on purpose, it's enough to have
- * deprecation guards around _gst_plugin_register_static(), and will result in
- * much better error messages when compiling with -DGST_DISABLE_DEPRECATED */
-#define GST_PLUGIN_DEFINE_STATIC(major,minor,name,description,init,version,license,package,origin)  \
-static void GST_GNUC_CONSTRUCTOR                       \
-_gst_plugin_static_init__ ##init (void)                        \
-{                                                      \
-  static GstPluginDesc plugin_desc_ = {                        \
-    major,                                             \
-    minor,                                             \
-    name,                                              \
-    (gchar *) description,                             \
-    init,                                              \
-    version,                                           \
-    license,                                           \
-    PACKAGE,                                           \
-    package,                                           \
-    origin,                                            \
-    NULL,                                              \
-    GST_PADDING_INIT                                   \
-  };                                                   \
-  _gst_plugin_register_static (&plugin_desc_);         \
-}
-
-/**
  * GST_LICENSE_UNKNOWN:
  *
  * To be used in GST_PLUGIN_DEFINE or GST_PLUGIN_DEFINE_STATIC if usure about
@@ -344,10 +297,6 @@ typedef gboolean        (*GstPluginFilter)              (GstPlugin *plugin,
 
 GType                   gst_plugin_get_type             (void);
 
-#ifndef GST_DISABLE_DEPRECATED
-void                   _gst_plugin_register_static     (GstPluginDesc *desc);
-#endif
-
 gboolean               gst_plugin_register_static      (gint major_version,
                                                          gint minor_version,
                                                          const gchar *name,
index c72a1f7..f8f632f 100644 (file)
@@ -63,8 +63,7 @@ gst_plugin_feature_finalize (GObject * object)
 {
   GstPluginFeature *feature = GST_PLUGIN_FEATURE_CAST (object);
 
-  GST_DEBUG ("finalizing feature %p: '%s'", feature,
-      GST_PLUGIN_FEATURE_NAME (feature));
+  GST_DEBUG ("finalizing feature %p: '%s'", feature, GST_OBJECT_NAME (feature));
 
   if (feature->plugin != NULL) {
     g_object_remove_weak_pointer ((GObject *) feature->plugin,
@@ -103,7 +102,7 @@ gst_plugin_feature_load (GstPluginFeature * feature)
   g_return_val_if_fail (GST_IS_PLUGIN_FEATURE (feature), FALSE);
 
   GST_DEBUG ("loading plugin for feature %p; '%s'", feature,
-      GST_PLUGIN_FEATURE_NAME (feature));
+      GST_OBJECT_NAME (feature));
   if (feature->loaded)
     return gst_object_ref (feature);
 
@@ -116,7 +115,8 @@ gst_plugin_feature_load (GstPluginFeature * feature)
   gst_object_unref (plugin);
 
   real_feature =
-      gst_registry_lookup_feature (gst_registry_get_default (), feature->name);
+      gst_registry_lookup_feature (gst_registry_get_default (),
+      GST_OBJECT_NAME (feature));
 
   if (real_feature == NULL)
     goto disappeared;
@@ -129,20 +129,20 @@ gst_plugin_feature_load (GstPluginFeature * feature)
 load_failed:
   {
     GST_WARNING ("Failed to load plugin containing feature '%s'.",
-        GST_PLUGIN_FEATURE_NAME (feature));
+        GST_OBJECT_NAME (feature));
     return NULL;
   }
 disappeared:
   {
     GST_INFO
         ("Loaded plugin containing feature '%s', but feature disappeared.",
-        feature->name);
+        GST_OBJECT_NAME (feature));
     return NULL;
   }
 not_found:
   {
     GST_INFO ("Tried to load plugin containing feature '%s', but feature was "
-        "not found.", real_feature->name);
+        "not found.", GST_OBJECT_NAME (real_feature));
     return NULL;
   }
 }
@@ -163,48 +163,7 @@ gst_plugin_feature_type_name_filter (GstPluginFeature * feature,
   g_return_val_if_fail (GST_IS_PLUGIN_FEATURE (feature), FALSE);
 
   return ((data->type == 0 || data->type == G_OBJECT_TYPE (feature)) &&
-      (data->name == NULL
-          || !strcmp (data->name, GST_PLUGIN_FEATURE_NAME (feature))));
-}
-
-/**
- * gst_plugin_feature_set_name:
- * @feature: a feature
- * @name: the name to set
- *
- * Sets the name of a plugin feature. The name uniquely identifies a feature
- * within all features of the same type. Renaming a plugin feature is not
- * allowed. A copy is made of the name so you should free the supplied @name
- * after calling this function.
- */
-void
-gst_plugin_feature_set_name (GstPluginFeature * feature, const gchar * name)
-{
-  g_return_if_fail (GST_IS_PLUGIN_FEATURE (feature));
-  g_return_if_fail (name != NULL);
-
-  if (G_UNLIKELY (feature->name)) {
-    g_return_if_fail (strcmp (feature->name, name) == 0);
-  } else {
-    gst_object_set_name (GST_OBJECT (feature), name);
-    feature->name = GST_OBJECT_NAME (GST_OBJECT (feature));
-  }
-}
-
-/**
- * gst_plugin_feature_get_name:
- * @feature: a feature
- *
- * Gets the name of a plugin feature.
- *
- * Returns: the name
- */
-const gchar *
-gst_plugin_feature_get_name (GstPluginFeature * feature)
-{
-  g_return_val_if_fail (GST_IS_PLUGIN_FEATURE (feature), NULL);
-
-  return feature->name;
+      (data->name == NULL || !strcmp (data->name, GST_OBJECT_NAME (feature))));
 }
 
 /**
@@ -345,7 +304,7 @@ gst_plugin_feature_check_version (GstPluginFeature * feature,
   g_return_val_if_fail (GST_IS_PLUGIN_FEATURE (feature), FALSE);
 
   GST_DEBUG ("Looking up plugin '%s' containing plugin feature '%s'",
-      feature->plugin_name, feature->name);
+      feature->plugin_name, GST_OBJECT_NAME (feature));
 
   registry = gst_registry_get_default ();
   plugin = gst_registry_find_plugin (registry, feature->plugin_name);
@@ -422,7 +381,7 @@ gst_plugin_feature_rank_compare_func (gconstpointer p1, gconstpointer p2)
   if (diff != 0)
     return diff;
 
-  diff = strcmp (f2->name, f1->name);
+  diff = strcmp (GST_OBJECT_NAME (f2), GST_OBJECT_NAME (f1));
 
   return diff;
 }
index baf592c..24cedda 100644 (file)
@@ -38,14 +38,6 @@ G_BEGIN_DECLS
 #define GST_PLUGIN_FEATURE_GET_CLASS(obj)       (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_PLUGIN_FEATURE, GstPluginFeatureClass))
 #define GST_PLUGIN_FEATURE_CAST(obj)            ((GstPluginFeature*)(obj))
 
-/**
- * GST_PLUGIN_FEATURE_NAME:
- * @feature: The feature to query
- *
- * Get the name of the feature
- */
-#define GST_PLUGIN_FEATURE_NAME(feature)  (GST_PLUGIN_FEATURE (feature)->name)
-
 typedef struct _GstPluginFeature GstPluginFeature;
 typedef struct _GstPluginFeatureClass GstPluginFeatureClass;
 
@@ -72,6 +64,29 @@ typedef enum {
 } GstRank;
 
 /**
+ * gst_plugin_feature_get_name:
+ * @feature: a #GstPluginFeature to get the name of @feature.
+ *
+ * Returns a copy of the name of @feature.
+ * Caller should g_free() the return value after usage.
+ * For a nameless plugin feature, this returns NULL, which you can safely g_free()
+ * as well.
+ *
+ * Returns: (transfer full): the name of @feature. g_free() after usage. MT safe.
+ *
+ */
+#define                 gst_plugin_feature_get_name(feature)      gst_object_get_name(GST_OBJECT_CAST(feature))
+
+/**
+ * gst_plugin_feature_set_name:
+ * @feature: a #GstPluginFeature to set the name of.
+ * @name: the new name
+ *
+ * Sets the name of the plugin feature, getting rid of the old name if there was one.
+ */
+#define                 gst_plugin_feature_set_name(feature,name) gst_object_set_name(GST_OBJECT_CAST(feature),name)
+
+/**
  * GstPluginFeature:
  *
  * Opaque #GstPluginFeature structure.
@@ -81,7 +96,6 @@ struct _GstPluginFeature {
 
   /*< private >*/
   gboolean       loaded;
-  gchar         *name; /* FIXME-0.11: remove variable, we use GstObject:name */
   guint          rank;
 
   const gchar   *plugin_name;
@@ -134,9 +148,7 @@ gboolean        gst_plugin_feature_type_name_filter     (GstPluginFeature *featu
                                                          GstTypeNameData *data);
 
 void            gst_plugin_feature_set_rank             (GstPluginFeature *feature, guint rank);
-void            gst_plugin_feature_set_name             (GstPluginFeature *feature, const gchar *name);
 guint           gst_plugin_feature_get_rank             (GstPluginFeature *feature);
-const gchar    *gst_plugin_feature_get_name             (GstPluginFeature *feature);
 
 void            gst_plugin_feature_list_free            (GList *list);
 GList          *gst_plugin_feature_list_copy            (GList *list);
index 811e4d1..6280896 100644 (file)
@@ -143,9 +143,9 @@ preset_get_paths (GstPreset * preset, const gchar ** preset_user_path,
     if (!(preset_path = g_type_get_qdata (type, preset_user_path_quark))) {
       gchar *preset_dir;
 
-      /* user presets go in '$HOME/.gstreamer-0.10/presets/GstSimSyn.prs' */
-      preset_dir = g_build_filename (g_get_home_dir (),
-          ".gstreamer-" GST_MAJORMINOR, "presets", NULL);
+      /* user presets go in  user's XDG data directory. */
+      preset_dir = g_build_filename (g_get_user_data_dir (),
+          "gstreamer-" GST_MAJORMINOR, "presets", NULL);
       GST_INFO_OBJECT (preset, "user_preset_dir: '%s'", preset_dir);
       preset_path =
           g_strdup_printf ("%s" G_DIR_SEPARATOR_S "%s.prs", preset_dir,
index 91a2012..07bfa9a 100644 (file)
@@ -33,24 +33,28 @@ static const gchar *_quark_strings[] = {
   "gerror", "debug", "buffer-percent", "buffering-mode",
   "avg-in-rate", "avg-out-rate", "buffering-left",
   "estimated-total", "old-state", "new-state", "pending-state",
-  "clock", "ready", "position", "new-base-time", "live", "min-latency",
+  "clock", "ready", "position", "reset-time", "live", "min-latency",
   "max-latency", "busy", "type", "owner", "update", "applied-rate",
   "start", "stop", "minsize", "maxsize", "async", "proportion",
   "diff", "timestamp", "flags", "cur-type", "cur", "stop-type",
-  "latency", "uri", "object", "taglist", "GstEventNewsegment",
+  "latency", "uri", "object", "taglist", "GstEventSegment",
   "GstEventBufferSize", "GstEventQOS", "GstEventSeek", "GstEventLatency",
   "GstMessageError", "GstMessageWarning", "GstMessageInfo",
   "GstMessageBuffering", "GstMessageState", "GstMessageClockProvide",
   "GstMessageClockLost", "GstMessageNewClock", "GstMessageStructureChange",
   "GstMessageSegmentStart", "GstMessageSegmentDone", "GstMessageDuration",
-  "GstMessageAsyncStart", "GstMessageRequestState", "GstMessageStreamStatus",
+  "GstMessageAsyncDone", "GstMessageRequestState", "GstMessageStreamStatus",
   "GstQueryPosition", "GstQueryDuration", "GstQueryLatency", "GstQueryConvert",
   "GstQuerySegment", "GstQuerySeeking", "GstQueryFormats", "GstQueryBuffering",
   "GstQueryURI", "GstEventStep", "GstMessageStepDone", "amount", "flush",
   "intermediate", "GstMessageStepStart", "active", "eos", "sink-message",
   "message", "GstMessageQOS", "running-time", "stream-time", "jitter",
   "quality", "processed", "dropped", "buffering-ranges", "GstMessageProgress",
-  "code", "text", "percent", "timeout"
+  "code", "text", "percent", "timeout", "GstBufferPoolConfig", "caps", "size",
+  "min-buffers", "max-buffers", "prefix", "postfix", "align", "time",
+  "GstQueryAllocation", "need-pool", "meta", "pool", "GstEventCaps",
+  "GstEventReconfigure", "segment", "GstQueryScheduling", "pull-mode",
+  "random-access", "sequential", "allocator", "GstEventFlushStop"
 };
 
 GQuark _priv_gst_quark_table[GST_QUARK_MAX];
index 6e16ee5..6af2a8f 100644 (file)
@@ -55,7 +55,7 @@ typedef enum _GstQuarkId
   GST_QUARK_CLOCK = 26,
   GST_QUARK_READY = 27,
   GST_QUARK_POSITION = 28,
-  GST_QUARK_NEW_BASE_TIME = 29,
+  GST_QUARK_RESET_TIME = 29,
   GST_QUARK_LIVE = 30,
   GST_QUARK_MIN_LATENCY = 31,
   GST_QUARK_MAX_LATENCY = 32,
@@ -80,7 +80,7 @@ typedef enum _GstQuarkId
   GST_QUARK_URI = 51,
   GST_QUARK_OBJECT = 52,
   GST_QUARK_TAGLIST = 53,
-  GST_QUARK_EVENT_NEWSEGMENT = 54,
+  GST_QUARK_EVENT_SEGMENT = 54,
   GST_QUARK_EVENT_BUFFER_SIZE = 55,
   GST_QUARK_EVENT_QOS = 56,
   GST_QUARK_EVENT_SEEK = 57,
@@ -97,7 +97,7 @@ typedef enum _GstQuarkId
   GST_QUARK_MESSAGE_SEGMENT_START = 68,
   GST_QUARK_MESSAGE_SEGMENT_DONE = 69,
   GST_QUARK_MESSAGE_DURATION = 70,
-  GST_QUARK_MESSAGE_ASYNC_START = 71,
+  GST_QUARK_MESSAGE_ASYNC_DONE = 71,
   GST_QUARK_MESSAGE_REQUEST_STATE = 72,
   GST_QUARK_MESSAGE_STREAM_STATUS = 73,
   GST_QUARK_QUERY_POSITION = 74,
@@ -132,8 +132,30 @@ typedef enum _GstQuarkId
   GST_QUARK_TEXT = 103,
   GST_QUARK_PERCENT = 104,
   GST_QUARK_TIMEOUT = 105,
+  GST_QUARK_BUFFER_POOL_CONFIG = 106,
+  GST_QUARK_CAPS = 107,
+  GST_QUARK_SIZE = 108,
+  GST_QUARK_MIN_BUFFERS = 109,
+  GST_QUARK_MAX_BUFFERS = 110,
+  GST_QUARK_PREFIX = 111,
+  GST_QUARK_POSTFIX = 112,
+  GST_QUARK_ALIGN = 113,
+  GST_QUARK_TIME = 114,
+  GST_QUARK_QUERY_ALLOCATION = 115,
+  GST_QUARK_NEED_POOL = 116,
+  GST_QUARK_META = 117,
+  GST_QUARK_POOL = 118,
+  GST_QUARK_EVENT_CAPS = 119,
+  GST_QUARK_EVENT_RECONFIGURE = 120,
+  GST_QUARK_SEGMENT = 121,
+  GST_QUARK_QUERY_SCHEDULING = 122,
+  GST_QUARK_PULL_MODE = 123,
+  GST_QUARK_RANDOM_ACCESS = 124,
+  GST_QUARK_SEQUENTIAL = 125,
+  GST_QUARK_ALLOCATOR = 126,
+  GST_QUARK_EVENT_FLUSH_STOP = 127,
 
-  GST_QUARK_MAX = 106
+  GST_QUARK_MAX = 128
 } GstQuarkId;
 
 extern GQuark _priv_gst_quark_table[GST_QUARK_MAX];
index 4104e0a..9c308be 100644 (file)
 #include "gstenumtypes.h"
 #include "gstquark.h"
 #include "gsturi.h"
+#include "gstbufferpool.h"
 
 GST_DEBUG_CATEGORY_STATIC (gst_query_debug);
 #define GST_CAT_DEFAULT gst_query_debug
 
-static void gst_query_finalize (GstQuery * query);
-static GstQuery *_gst_query_copy (GstQuery * query);
+static GType _gst_query_type = 0;
+
+typedef struct
+{
+  GstQuery query;
+
+  GstStructure *structure;
+} GstQueryImpl;
+
+#define GST_QUERY_STRUCTURE(q)  (((GstQueryImpl *)(q))->structure)
 
 static GStaticMutex mutex = G_STATIC_MUTEX_INIT;
 static GList *_gst_queries = NULL;
@@ -81,8 +90,6 @@ static GHashTable *_nick_to_query = NULL;
 static GHashTable *_query_type_to_nick = NULL;
 static guint32 _n_values = 1;   /* we start from 1 because 0 reserved for NONE */
 
-static GstMiniObjectClass *parent_class = NULL;
-
 static GstQueryTypeDefinition standard_definitions[] = {
   {GST_QUERY_POSITION, "position", "Current position", 0},
   {GST_QUERY_DURATION, "duration", "Total duration", 0},
@@ -96,6 +103,8 @@ static GstQueryTypeDefinition standard_definitions[] = {
   {GST_QUERY_BUFFERING, "buffering", "Buffering status", 0},
   {GST_QUERY_CUSTOM, "custom", "Custom query", 0},
   {GST_QUERY_URI, "uri", "URI of the source or sink", 0},
+  {GST_QUERY_ALLOCATION, "allocation", "Allocation properties", 0},
+  {GST_QUERY_SCHEDULING, "scheduling", "Scheduling properties", 0},
   {0, NULL, NULL, 0}
 };
 
@@ -126,7 +135,7 @@ _gst_query_initialize (void)
   }
   g_static_mutex_unlock (&mutex);
 
-  g_type_class_ref (gst_query_get_type ());
+  gst_query_get_type ();
 }
 
 /**
@@ -143,6 +152,7 @@ gst_query_type_get_name (GstQueryType query)
   const GstQueryTypeDefinition *def;
 
   def = gst_query_type_get_details (query);
+  g_return_val_if_fail (def != NULL, NULL);
 
   return def->nick;
 }
@@ -161,60 +171,20 @@ gst_query_type_to_quark (GstQueryType query)
   const GstQueryTypeDefinition *def;
 
   def = gst_query_type_get_details (query);
+  g_return_val_if_fail (def != NULL, 0);
 
   return def->quark;
 }
 
-G_DEFINE_TYPE (GstQuery, gst_query, GST_TYPE_MINI_OBJECT);
-
-static void
-gst_query_class_init (GstQueryClass * klass)
-{
-  parent_class = g_type_class_peek_parent (klass);
-
-  klass->mini_object_class.copy = (GstMiniObjectCopyFunction) _gst_query_copy;
-  klass->mini_object_class.finalize =
-      (GstMiniObjectFinalizeFunction) gst_query_finalize;
-
-}
-
-static void
-gst_query_init (GstQuery * query)
-{
-}
-
-static void
-gst_query_finalize (GstQuery * query)
+GType
+gst_query_get_type (void)
 {
-  g_return_if_fail (query != NULL);
-
-  if (query->structure) {
-    gst_structure_set_parent_refcount (query->structure, NULL);
-    gst_structure_free (query->structure);
+  if (G_UNLIKELY (_gst_query_type == 0)) {
+    _gst_query_type = gst_mini_object_register ("GstQuery");
   }
-
-/*   GST_MINI_OBJECT_CLASS (parent_class)->finalize (GST_MINI_OBJECT (query)); */
+  return _gst_query_type;
 }
 
-static GstQuery *
-_gst_query_copy (GstQuery * query)
-{
-  GstQuery *copy;
-
-  copy = (GstQuery *) gst_mini_object_new (GST_TYPE_QUERY);
-
-  copy->type = query->type;
-
-  if (query->structure) {
-    copy->structure = gst_structure_copy (query->structure);
-    gst_structure_set_parent_refcount (copy->structure,
-        &query->mini_object.refcount);
-  }
-
-  return copy;
-}
-
-
 
 /**
  * gst_query_type_register:
@@ -233,8 +203,8 @@ gst_query_type_register (const gchar * nick, const gchar * description)
   GstQueryTypeDefinition *query;
   GstQueryType lookup;
 
-  g_return_val_if_fail (nick != NULL, 0);
-  g_return_val_if_fail (description != NULL, 0);
+  g_return_val_if_fail (nick != NULL, GST_QUERY_NONE);
+  g_return_val_if_fail (description != NULL, GST_QUERY_NONE);
 
   lookup = gst_query_type_get_by_nick (nick);
   if (lookup != GST_QUERY_NONE)
@@ -271,7 +241,7 @@ gst_query_type_get_by_nick (const gchar * nick)
 {
   GstQueryTypeDefinition *query;
 
-  g_return_val_if_fail (nick != NULL, 0);
+  g_return_val_if_fail (nick != NULL, GST_QUERY_NONE);
 
   g_static_mutex_lock (&mutex);
   query = g_hash_table_lookup (_nick_to_query, nick);
@@ -346,33 +316,63 @@ gst_query_type_iterate_definitions (void)
   g_static_mutex_lock (&mutex);
   /* FIXME: register a boxed type for GstQueryTypeDefinition */
   result = gst_iterator_new_list (G_TYPE_POINTER,
-      g_static_mutex_get_mutex (&mutex), &_n_values, &_gst_queries,
-      NULL, NULL, NULL);
+      g_static_mutex_get_mutex (&mutex), &_n_values, &_gst_queries, NULL, NULL);
   g_static_mutex_unlock (&mutex);
 
   return result;
 }
 
+static void
+_gst_query_free (GstQuery * query)
+{
+  GstStructure *s;
+
+  g_return_if_fail (query != NULL);
+
+  s = GST_QUERY_STRUCTURE (query);
+  if (s) {
+    gst_structure_set_parent_refcount (s, NULL);
+    gst_structure_free (s);
+  }
+
+  g_slice_free1 (GST_MINI_OBJECT_SIZE (query), query);
+}
+
+static GstQuery *gst_query_new (GstQueryType type, GstStructure * structure);
+
+static GstQuery *
+_gst_query_copy (GstQuery * query)
+{
+  GstQuery *copy;
+
+  copy = gst_query_new (query->type, GST_QUERY_STRUCTURE (query));
+
+  return copy;
+}
+
 static GstQuery *
 gst_query_new (GstQueryType type, GstStructure * structure)
 {
-  GstQuery *query;
+  GstQueryImpl *query;
 
-  query = (GstQuery *) gst_mini_object_new (GST_TYPE_QUERY);
+  query = g_slice_new0 (GstQueryImpl);
+
+  gst_mini_object_init (GST_MINI_OBJECT_CAST (query),
+      _gst_query_type, sizeof (GstQueryImpl));
+
+  query->query.mini_object.copy = (GstMiniObjectCopyFunction) _gst_query_copy;
+  query->query.mini_object.free = (GstMiniObjectFreeFunction) _gst_query_free;
 
   GST_DEBUG ("creating new query %p %d", query, type);
 
-  query->type = type;
+  GST_QUERY_TYPE (query) = type;
+  query->structure = structure;
 
-  if (structure) {
-    query->structure = structure;
-    gst_structure_set_parent_refcount (query->structure,
-        &query->mini_object.refcount);
-  } else {
-    query->structure = NULL;
-  }
+  if (structure)
+    gst_structure_set_parent_refcount (structure,
+        &query->query.mini_object.refcount);
 
-  return query;
+  return GST_QUERY_CAST (query);
 }
 
 /**
@@ -413,9 +413,12 @@ gst_query_new_position (GstFormat format)
 void
 gst_query_set_position (GstQuery * query, GstFormat format, gint64 cur)
 {
+  GstStructure *structure;
+
   g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_POSITION);
 
-  gst_structure_id_set (query->structure,
+  structure = GST_QUERY_STRUCTURE (query);
+  gst_structure_id_set (structure,
       GST_QUARK (FORMAT), GST_TYPE_FORMAT, format,
       GST_QUARK (CURRENT), G_TYPE_INT64, cur, NULL);
 }
@@ -437,7 +440,7 @@ gst_query_parse_position (GstQuery * query, GstFormat * format, gint64 * cur)
 
   g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_POSITION);
 
-  structure = query->structure;
+  structure = GST_QUERY_STRUCTURE (query);
   if (format)
     *format = g_value_get_enum (gst_structure_id_get_value (structure,
             GST_QUARK (FORMAT)));
@@ -485,9 +488,12 @@ gst_query_new_duration (GstFormat format)
 void
 gst_query_set_duration (GstQuery * query, GstFormat format, gint64 duration)
 {
+  GstStructure *structure;
+
   g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_DURATION);
 
-  gst_structure_id_set (query->structure,
+  structure = GST_QUERY_STRUCTURE (query);
+  gst_structure_id_set (structure,
       GST_QUARK (FORMAT), GST_TYPE_FORMAT, format,
       GST_QUARK (DURATION), G_TYPE_INT64, duration, NULL);
 }
@@ -510,7 +516,7 @@ gst_query_parse_duration (GstQuery * query, GstFormat * format,
 
   g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_DURATION);
 
-  structure = query->structure;
+  structure = GST_QUERY_STRUCTURE (query);
   if (format)
     *format = g_value_get_enum (gst_structure_id_get_value (structure,
             GST_QUARK (FORMAT)));
@@ -564,9 +570,12 @@ void
 gst_query_set_latency (GstQuery * query, gboolean live,
     GstClockTime min_latency, GstClockTime max_latency)
 {
+  GstStructure *structure;
+
   g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_LATENCY);
 
-  gst_structure_id_set (query->structure,
+  structure = GST_QUERY_STRUCTURE (query);
+  gst_structure_id_set (structure,
       GST_QUARK (LIVE), G_TYPE_BOOLEAN, live,
       GST_QUARK (MIN_LATENCY), G_TYPE_UINT64, min_latency,
       GST_QUARK (MAX_LATENCY), G_TYPE_UINT64, max_latency, NULL);
@@ -591,7 +600,7 @@ gst_query_parse_latency (GstQuery * query, gboolean * live,
 
   g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_LATENCY);
 
-  structure = query->structure;
+  structure = GST_QUERY_STRUCTURE (query);
   if (live)
     *live =
         g_value_get_boolean (gst_structure_id_get_value (structure,
@@ -650,9 +659,12 @@ void
 gst_query_set_convert (GstQuery * query, GstFormat src_format, gint64 src_value,
     GstFormat dest_format, gint64 dest_value)
 {
+  GstStructure *structure;
+
   g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_CONVERT);
 
-  gst_structure_id_set (query->structure,
+  structure = GST_QUERY_STRUCTURE (query);
+  gst_structure_id_set (structure,
       GST_QUARK (SRC_FORMAT), GST_TYPE_FORMAT, src_format,
       GST_QUARK (SRC_VALUE), G_TYPE_INT64, src_value,
       GST_QUARK (DEST_FORMAT), GST_TYPE_FORMAT, dest_format,
@@ -681,7 +693,7 @@ gst_query_parse_convert (GstQuery * query, GstFormat * src_format,
 
   g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_CONVERT);
 
-  structure = query->structure;
+  structure = GST_QUERY_STRUCTURE (query);
   if (src_format)
     *src_format = g_value_get_enum (gst_structure_id_get_value (structure,
             GST_QUARK (SRC_FORMAT)));
@@ -749,9 +761,12 @@ void
 gst_query_set_segment (GstQuery * query, gdouble rate, GstFormat format,
     gint64 start_value, gint64 stop_value)
 {
+  GstStructure *structure;
+
   g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_SEGMENT);
 
-  gst_structure_id_set (query->structure,
+  structure = GST_QUERY_STRUCTURE (query);
+  gst_structure_id_set (structure,
       GST_QUARK (RATE), G_TYPE_DOUBLE, rate,
       GST_QUARK (FORMAT), GST_TYPE_FORMAT, format,
       GST_QUARK (START_VALUE), G_TYPE_INT64, start_value,
@@ -780,7 +795,7 @@ gst_query_parse_segment (GstQuery * query, gdouble * rate, GstFormat * format,
 
   g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_SEGMENT);
 
-  structure = query->structure;
+  structure = GST_QUERY_STRUCTURE (query);
   if (rate)
     *rate = g_value_get_double (gst_structure_id_get_value (structure,
             GST_QUARK (RATE)));
@@ -796,11 +811,11 @@ gst_query_parse_segment (GstQuery * query, gdouble * rate, GstFormat * format,
 }
 
 /**
- * gst_query_new_application:
+ * gst_query_new_custom:
  * @type: the query type
  * @structure: a structure for the query
  *
- * Constructs a new custom application query object. Use gst_query_unref()
+ * Constructs a new custom query object. Use gst_query_unref()
  * when done with it.
  *
  * Free-function: gst_query_unref
@@ -808,7 +823,7 @@ gst_query_parse_segment (GstQuery * query, gdouble * rate, GstFormat * format,
  * Returns: (transfer full): a new #GstQuery
  */
 GstQuery *
-gst_query_new_application (GstQueryType type, GstStructure * structure)
+gst_query_new_custom (GstQueryType type, GstStructure * structure)
 {
   g_return_val_if_fail (gst_query_type_get_details (type) != NULL, NULL);
   g_return_val_if_fail (structure != NULL, NULL);
@@ -826,12 +841,31 @@ gst_query_new_application (GstQueryType type, GstStructure * structure)
  *     still owned by the query and will therefore be freed when the query
  *     is unreffed.
  */
-GstStructure *
+const GstStructure *
 gst_query_get_structure (GstQuery * query)
 {
   g_return_val_if_fail (GST_IS_QUERY (query), NULL);
 
-  return query->structure;
+  return GST_QUERY_STRUCTURE (query);
+}
+
+/**
+ * gst_query_writable_structure:
+ * @query: a #GstQuery
+ *
+ * Get the structure of a query.
+ *
+ * Returns: (transfer none): the #GstStructure of the query. The structure is
+ *     still owned by the query and will therefore be freed when the query
+ *     is unreffed.
+ */
+GstStructure *
+gst_query_writable_structure (GstQuery * query)
+{
+  g_return_val_if_fail (GST_IS_QUERY (query), NULL);
+  g_return_val_if_fail (gst_query_is_writable (query), NULL);
+
+  return GST_QUERY_STRUCTURE (query);
 }
 
 /**
@@ -876,9 +910,13 @@ void
 gst_query_set_seeking (GstQuery * query, GstFormat format,
     gboolean seekable, gint64 segment_start, gint64 segment_end)
 {
+  GstStructure *structure;
+
   g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_SEEKING);
+  g_return_if_fail (gst_query_is_writable (query));
 
-  gst_structure_id_set (query->structure,
+  structure = GST_QUERY_STRUCTURE (query);
+  gst_structure_id_set (structure,
       GST_QUARK (FORMAT), GST_TYPE_FORMAT, format,
       GST_QUARK (SEEKABLE), G_TYPE_BOOLEAN, seekable,
       GST_QUARK (SEGMENT_START), G_TYPE_INT64, segment_start,
@@ -906,7 +944,7 @@ gst_query_parse_seeking (GstQuery * query, GstFormat * format,
 
   g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_SEEKING);
 
-  structure = query->structure;
+  structure = GST_QUERY_STRUCTURE (query);
   if (format)
     *format = g_value_get_enum (gst_structure_id_get_value (structure,
             GST_QUARK (FORMAT)));
@@ -971,8 +1009,10 @@ gst_query_set_formats (GstQuery * query, gint n_formats, ...)
   va_list ap;
   GValue list = { 0, };
   gint i;
+  GstStructure *structure;
 
   g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_FORMATS);
+  g_return_if_fail (gst_query_is_writable (query));
 
   g_value_init (&list, GST_TYPE_LIST);
 
@@ -982,7 +1022,8 @@ gst_query_set_formats (GstQuery * query, gint n_formats, ...)
   }
   va_end (ap);
 
-  gst_structure_set_value (query->structure, "formats", &list);
+  structure = GST_QUERY_STRUCTURE (query);
+  gst_structure_set_value (structure, "formats", &list);
 
   g_value_unset (&list);
 
@@ -1006,20 +1047,23 @@ gst_query_set_formatsv (GstQuery * query, gint n_formats,
 {
   GValue list = { 0, };
   gint i;
+  GstStructure *structure;
 
   g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_FORMATS);
+  g_return_if_fail (gst_query_is_writable (query));
 
   g_value_init (&list, GST_TYPE_LIST);
   for (i = 0; i < n_formats; i++) {
     gst_query_list_add_format (&list, formats[i]);
   }
-  gst_structure_set_value (query->structure, "formats", &list);
+  structure = GST_QUERY_STRUCTURE (query);
+  gst_structure_set_value (structure, "formats", &list);
 
   g_value_unset (&list);
 }
 
 /**
- * gst_query_parse_formats_length:
+ * gst_query_parse_n_formats:
  * @query: a #GstQuery
  * @n_formats: (out): the number of formats in this query.
  *
@@ -1028,14 +1072,17 @@ gst_query_set_formatsv (GstQuery * query, gint n_formats,
  * Since: 0.10.4
  */
 void
-gst_query_parse_formats_length (GstQuery * query, guint * n_formats)
+gst_query_parse_n_formats (GstQuery * query, guint * n_formats)
 {
+  GstStructure *structure;
+
   g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_FORMATS);
 
   if (n_formats) {
     const GValue *list;
 
-    list = gst_structure_get_value (query->structure, "formats");
+    structure = GST_QUERY_STRUCTURE (query);
+    list = gst_structure_get_value (structure, "formats");
     if (list == NULL)
       *n_formats = 0;
     else
@@ -1044,7 +1091,7 @@ gst_query_parse_formats_length (GstQuery * query, guint * n_formats)
 }
 
 /**
- * gst_query_parse_formats_nth:
+ * gst_query_parse_nth_format:
  * @query: a #GstQuery
  * @nth: (out): the nth format to retrieve.
  * @format: (out): a pointer to store the nth format
@@ -1052,18 +1099,19 @@ gst_query_parse_formats_length (GstQuery * query, guint * n_formats)
  * Parse the format query and retrieve the @nth format from it into
  * @format. If the list contains less elements than @nth, @format will be
  * set to GST_FORMAT_UNDEFINED.
- *
- * Since: 0.10.4
  */
 void
-gst_query_parse_formats_nth (GstQuery * query, guint nth, GstFormat * format)
+gst_query_parse_nth_format (GstQuery * query, guint nth, GstFormat * format)
 {
+  GstStructure *structure;
+
   g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_FORMATS);
 
   if (format) {
     const GValue *list;
 
-    list = gst_structure_get_value (query->structure, "formats");
+    structure = GST_QUERY_STRUCTURE (query);
+    list = gst_structure_get_value (structure, "formats");
     if (list == NULL) {
       *format = GST_FORMAT_UNDEFINED;
     } else {
@@ -1082,7 +1130,7 @@ gst_query_parse_formats_nth (GstQuery * query, guint nth, GstFormat * format)
  * Constructs a new query object for querying the buffering status of
  * a stream.
  *
- * Free-function: gst_query_new
+ * Free-function: gst_query_unref
  *
  * Returns: (transfer full): a new #GstQuery
  *
@@ -1127,10 +1175,14 @@ gst_query_new_buffering (GstFormat format)
 void
 gst_query_set_buffering_percent (GstQuery * query, gboolean busy, gint percent)
 {
+  GstStructure *structure;
+
   g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_BUFFERING);
+  g_return_if_fail (gst_query_is_writable (query));
   g_return_if_fail (percent >= 0 && percent <= 100);
 
-  gst_structure_id_set (query->structure,
+  structure = GST_QUERY_STRUCTURE (query);
+  gst_structure_id_set (structure,
       GST_QUARK (BUSY), G_TYPE_BOOLEAN, busy,
       GST_QUARK (BUFFER_PERCENT), G_TYPE_INT, percent, NULL);
 }
@@ -1150,13 +1202,16 @@ void
 gst_query_parse_buffering_percent (GstQuery * query, gboolean * busy,
     gint * percent)
 {
+  GstStructure *structure;
+
   g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_BUFFERING);
 
+  structure = GST_QUERY_STRUCTURE (query);
   if (busy)
-    *busy = g_value_get_boolean (gst_structure_id_get_value (query->structure,
+    *busy = g_value_get_boolean (gst_structure_id_get_value (structure,
             GST_QUARK (BUSY)));
   if (percent)
-    *percent = g_value_get_int (gst_structure_id_get_value (query->structure,
+    *percent = g_value_get_int (gst_structure_id_get_value (structure,
             GST_QUARK (BUFFER_PERCENT)));
 }
 
@@ -1176,9 +1231,13 @@ void
 gst_query_set_buffering_stats (GstQuery * query, GstBufferingMode mode,
     gint avg_in, gint avg_out, gint64 buffering_left)
 {
+  GstStructure *structure;
+
   g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_BUFFERING);
+  g_return_if_fail (gst_query_is_writable (query));
 
-  gst_structure_id_set (query->structure,
+  structure = GST_QUERY_STRUCTURE (query);
+  gst_structure_id_set (structure,
       GST_QUARK (BUFFERING_MODE), GST_TYPE_BUFFERING_MODE, mode,
       GST_QUARK (AVG_IN_RATE), G_TYPE_INT, avg_in,
       GST_QUARK (AVG_OUT_RATE), G_TYPE_INT, avg_out,
@@ -1202,20 +1261,23 @@ gst_query_parse_buffering_stats (GstQuery * query,
     GstBufferingMode * mode, gint * avg_in, gint * avg_out,
     gint64 * buffering_left)
 {
+  GstStructure *structure;
+
   g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_BUFFERING);
 
+  structure = GST_QUERY_STRUCTURE (query);
   if (mode)
-    *mode = g_value_get_enum (gst_structure_id_get_value (query->structure,
+    *mode = g_value_get_enum (gst_structure_id_get_value (structure,
             GST_QUARK (BUFFERING_MODE)));
   if (avg_in)
-    *avg_in = g_value_get_int (gst_structure_id_get_value (query->structure,
+    *avg_in = g_value_get_int (gst_structure_id_get_value (structure,
             GST_QUARK (AVG_IN_RATE)));
   if (avg_out)
-    *avg_out = g_value_get_int (gst_structure_id_get_value (query->structure,
+    *avg_out = g_value_get_int (gst_structure_id_get_value (structure,
             GST_QUARK (AVG_OUT_RATE)));
   if (buffering_left)
     *buffering_left =
-        g_value_get_int64 (gst_structure_id_get_value (query->structure,
+        g_value_get_int64 (gst_structure_id_get_value (structure,
             GST_QUARK (BUFFERING_LEFT)));
 }
 
@@ -1236,9 +1298,13 @@ void
 gst_query_set_buffering_range (GstQuery * query, GstFormat format,
     gint64 start, gint64 stop, gint64 estimated_total)
 {
+  GstStructure *structure;
+
   g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_BUFFERING);
+  g_return_if_fail (gst_query_is_writable (query));
 
-  gst_structure_id_set (query->structure,
+  structure = GST_QUERY_STRUCTURE (query);
+  gst_structure_id_set (structure,
       GST_QUARK (FORMAT), GST_TYPE_FORMAT, format,
       GST_QUARK (START_VALUE), G_TYPE_INT64, start,
       GST_QUARK (STOP_VALUE), G_TYPE_INT64, stop,
@@ -1269,7 +1335,7 @@ gst_query_parse_buffering_range (GstQuery * query, GstFormat * format,
 
   g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_BUFFERING);
 
-  structure = query->structure;
+  structure = GST_QUERY_STRUCTURE (query);
   if (format)
     *format = g_value_get_enum (gst_structure_id_get_value (structure,
             GST_QUARK (FORMAT)));
@@ -1305,15 +1371,16 @@ gst_query_add_buffering_range (GstQuery * query, gint64 start, gint64 stop)
   GValue *last_array_value;
   const GValue *value;
   GValue range_value = { 0 };
+  GstStructure *structure;
 
   g_return_val_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_BUFFERING, FALSE);
+  g_return_val_if_fail (gst_query_is_writable (query), FALSE);
 
   if (G_UNLIKELY (start >= stop))
     return FALSE;
 
-  value =
-      gst_structure_id_get_value (query->structure,
-      GST_QUARK (BUFFERING_RANGES));
+  structure = GST_QUERY_STRUCTURE (query);
+  value = gst_structure_id_get_value (structure, GST_QUARK (BUFFERING_RANGES));
   if (value) {
     array = (GValueArray *) g_value_get_boxed (value);
     last_array_value = g_value_array_get_nth (array, array->n_values - 1);
@@ -1329,7 +1396,7 @@ gst_query_add_buffering_range (GstQuery * query, gint64 start, gint64 stop)
 
     /* set the value array only once, so we then modify (append to) the
      * existing value array owned by the GstStructure / the field's GValue */
-    gst_structure_id_take_value (query->structure, GST_QUARK (BUFFERING_RANGES),
+    gst_structure_id_take_value (structure, GST_QUARK (BUFFERING_RANGES),
         &new_array_val);
   }
 
@@ -1358,12 +1425,12 @@ gst_query_get_n_buffering_ranges (GstQuery * query)
   GValueArray *array;
   const GValue *value;
   guint size = 0;
+  GstStructure *structure;
 
   g_return_val_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_BUFFERING, 0);
 
-  value =
-      gst_structure_id_get_value (query->structure,
-      GST_QUARK (BUFFERING_RANGES));
+  structure = GST_QUERY_STRUCTURE (query);
+  value = gst_structure_id_get_value (structure, GST_QUARK (BUFFERING_RANGES));
   if (value) {
     array = (GValueArray *) g_value_get_boxed (value);
     size = array->n_values;
@@ -1394,12 +1461,12 @@ gst_query_parse_nth_buffering_range (GstQuery * query, guint index,
   GValueArray *ranges;
   GValue *range_value;
   gboolean ret = FALSE;
+  GstStructure *structure;
 
   g_return_val_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_BUFFERING, ret);
 
-  value =
-      gst_structure_id_get_value (query->structure,
-      GST_QUARK (BUFFERING_RANGES));
+  structure = GST_QUERY_STRUCTURE (query);
+  value = gst_structure_id_get_value (structure, GST_QUARK (BUFFERING_RANGES));
   ranges = (GValueArray *) g_value_get_boxed (value);
   range_value = g_value_array_get_nth (ranges, index);
   if (range_value) {
@@ -1453,11 +1520,14 @@ gst_query_new_uri (void)
 void
 gst_query_set_uri (GstQuery * query, const gchar * uri)
 {
+  GstStructure *structure;
+
   g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_URI);
+  g_return_if_fail (gst_query_is_writable (query));
   g_return_if_fail (gst_uri_is_valid (uri));
 
-  gst_structure_id_set (query->structure, GST_QUARK (URI), G_TYPE_STRING, uri,
-      NULL);
+  structure = GST_QUERY_STRUCTURE (query);
+  gst_structure_id_set (structure, GST_QUARK (URI), G_TYPE_STRING, uri, NULL);
 }
 
 /**
@@ -1475,9 +1545,419 @@ gst_query_set_uri (GstQuery * query, const gchar * uri)
 void
 gst_query_parse_uri (GstQuery * query, gchar ** uri)
 {
+  GstStructure *structure;
+
   g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_URI);
 
+  structure = GST_QUERY_STRUCTURE (query);
   if (uri)
-    *uri = g_value_dup_string (gst_structure_id_get_value (query->structure,
+    *uri = g_value_dup_string (gst_structure_id_get_value (structure,
             GST_QUARK (URI)));
 }
+
+/**
+ * gst_query_new_allocation
+ * @caps: the negotiated caps
+ * @need_pool: return a pool
+ *
+ * Constructs a new query object for querying the allocation properties.
+ *
+ * Free-function: gst_query_unref
+ *
+ * Returns: (transfer full): a new #GstQuery
+ */
+GstQuery *
+gst_query_new_allocation (GstCaps * caps, gboolean need_pool)
+{
+  GstQuery *query;
+  GstStructure *structure;
+
+  structure = gst_structure_id_new (GST_QUARK (QUERY_ALLOCATION),
+      GST_QUARK (CAPS), GST_TYPE_CAPS, caps,
+      GST_QUARK (NEED_POOL), G_TYPE_BOOLEAN, need_pool,
+      GST_QUARK (SIZE), G_TYPE_UINT, 0,
+      GST_QUARK (MIN_BUFFERS), G_TYPE_UINT, 0,
+      GST_QUARK (MAX_BUFFERS), G_TYPE_UINT, 0,
+      GST_QUARK (PREFIX), G_TYPE_UINT, 0,
+      GST_QUARK (ALIGN), G_TYPE_UINT, 0,
+      GST_QUARK (POOL), GST_TYPE_BUFFER_POOL, NULL, NULL);
+
+  query = gst_query_new (GST_QUERY_ALLOCATION, structure);
+
+  return query;
+}
+
+void
+gst_query_parse_allocation (GstQuery * query, GstCaps ** caps,
+    gboolean * need_pool)
+{
+  GstStructure *structure;
+
+  g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_ALLOCATION);
+
+  structure = GST_QUERY_STRUCTURE (query);
+  gst_structure_id_get (structure,
+      GST_QUARK (CAPS), GST_TYPE_CAPS, caps,
+      GST_QUARK (NEED_POOL), G_TYPE_BOOLEAN, need_pool, NULL);
+}
+
+/**
+ * gst_query_set_allocation_params
+ * @query: A valid #GstQuery of type GST_QUERY_ALLOCATION.
+ * @size: the size
+ * @min_buffers: the min buffers
+ * @max_buffers: the max buffers
+ * @prefix: the prefix
+ * @alignment: the alignment
+ * @pool: the #GstBufferPool
+ *
+ * Set the allocation parameters in @query.
+ */
+void
+gst_query_set_allocation_params (GstQuery * query, guint size,
+    guint min_buffers, guint max_buffers, guint prefix,
+    guint alignment, GstBufferPool * pool)
+{
+  GstStructure *structure;
+
+  g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_ALLOCATION);
+  g_return_if_fail (gst_query_is_writable (query));
+  g_return_if_fail (((alignment + 1) & alignment) == 0);
+  g_return_if_fail (size != 0 || pool == NULL);
+
+  structure = GST_QUERY_STRUCTURE (query);
+  gst_structure_id_set (structure,
+      GST_QUARK (SIZE), G_TYPE_UINT, size,
+      GST_QUARK (MIN_BUFFERS), G_TYPE_UINT, min_buffers,
+      GST_QUARK (MAX_BUFFERS), G_TYPE_UINT, max_buffers,
+      GST_QUARK (PREFIX), G_TYPE_UINT, prefix,
+      GST_QUARK (ALIGN), G_TYPE_UINT, alignment,
+      GST_QUARK (POOL), GST_TYPE_BUFFER_POOL, pool, NULL);
+}
+
+/**
+ * gst_query_parse_allocation_params
+ * @query: A valid #GstQuery of type GST_QUERY_ALLOCATION.
+ * @size: the size
+ * @min_buffers: the min buffers
+ * @max_buffers: the max buffers
+ * @prefix: the prefix
+ * @alignment: the alignment
+ * @pool: the #GstBufferPool
+ *
+ * Get the allocation parameters in @query.
+ */
+void
+gst_query_parse_allocation_params (GstQuery * query, guint * size,
+    guint * min_buffers, guint * max_buffers, guint * prefix,
+    guint * alignment, GstBufferPool ** pool)
+{
+  GstStructure *structure;
+
+  g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_ALLOCATION);
+
+  structure = GST_QUERY_STRUCTURE (query);
+  gst_structure_id_get (structure,
+      GST_QUARK (SIZE), G_TYPE_UINT, size,
+      GST_QUARK (MIN_BUFFERS), G_TYPE_UINT, min_buffers,
+      GST_QUARK (MAX_BUFFERS), G_TYPE_UINT, max_buffers,
+      GST_QUARK (PREFIX), G_TYPE_UINT, prefix,
+      GST_QUARK (ALIGN), G_TYPE_UINT, alignment,
+      GST_QUARK (POOL), GST_TYPE_BUFFER_POOL, pool, NULL);
+}
+
+/**
+ * gst_query_add_allocation_meta
+ * @query: a GST_QUERY_ALLOCATION type query #GstQuery
+ * @api: the metadata API
+ *
+ * Add @api as aone of the supported metadata API to @query.
+ */
+void
+gst_query_add_allocation_meta (GstQuery * query, const gchar * api)
+{
+  GValueArray *array;
+  const GValue *value;
+  GValue api_value = { 0 };
+  GstStructure *structure;
+
+  g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_ALLOCATION);
+  g_return_if_fail (gst_query_is_writable (query));
+
+  structure = GST_QUERY_STRUCTURE (query);
+  value = gst_structure_id_get_value (structure, GST_QUARK (META));
+  if (value) {
+    array = (GValueArray *) g_value_get_boxed (value);
+  } else {
+    GValue new_array_val = { 0, };
+
+    array = g_value_array_new (0);
+
+    g_value_init (&new_array_val, G_TYPE_VALUE_ARRAY);
+    g_value_take_boxed (&new_array_val, array);
+
+    gst_structure_id_take_value (structure, GST_QUARK (META), &new_array_val);
+  }
+
+  g_value_init (&api_value, G_TYPE_STRING);
+  g_value_set_string (&api_value, api);
+  g_value_array_append (array, &api_value);
+  g_value_unset (&api_value);
+}
+
+/**
+ * gst_query_get_n_allocation_metas:
+ * @query: a GST_QUERY_ALLOCATION type query #GstQuery
+ *
+ * Retrieve the number of values currently stored in the
+ * meta API array of the query's structure.
+ *
+ * Returns: the metadata API array size as a #guint.
+ */
+guint
+gst_query_get_n_allocation_metas (GstQuery * query)
+{
+  GValueArray *array;
+  const GValue *value;
+  guint size = 0;
+  GstStructure *structure;
+
+  g_return_val_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_ALLOCATION, 0);
+
+  structure = GST_QUERY_STRUCTURE (query);
+  value = gst_structure_id_get_value (structure, GST_QUARK (META));
+  if (value) {
+    array = (GValueArray *) g_value_get_boxed (value);
+    size = array->n_values;
+  }
+  return size;
+}
+
+/**
+ * gst_query_parse_nth_allocation_meta
+ * @query: a GST_QUERY_ALLOCATION type query #GstQuery
+ * @index: position in the metadata API array to read
+ *
+ * Parse an available query and get the metadata API
+ * at @index of the metadata API array.
+ *
+ * Returns: a #gchar of the metadata API at @index.
+ */
+const gchar *
+gst_query_parse_nth_allocation_meta (GstQuery * query, guint index)
+{
+  const GValue *value;
+  const gchar *ret = NULL;
+  GstStructure *structure;
+
+  g_return_val_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_ALLOCATION, NULL);
+
+  structure = GST_QUERY_STRUCTURE (query);
+  value = gst_structure_id_get_value (structure, GST_QUARK (META));
+  if (value) {
+    GValueArray *meta;
+    GValue *api_value;
+
+    meta = (GValueArray *) g_value_get_boxed (value);
+    api_value = g_value_array_get_nth (meta, index);
+
+    if (api_value)
+      ret = g_value_get_string (api_value);
+  }
+  return ret;
+}
+
+/**
+ * gst_query_add_allocation_memory
+ * @query: a GST_QUERY_ALLOCATION type query #GstQuery
+ * @alloc: the memory allocator
+ *
+ * Add @alloc as a supported memory allocator.
+ */
+void
+gst_query_add_allocation_memory (GstQuery * query, const gchar * alloc)
+{
+  GValueArray *array;
+  const GValue *value;
+  GValue alloc_value = { 0 };
+  GstStructure *structure;
+
+  g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_ALLOCATION);
+  g_return_if_fail (gst_query_is_writable (query));
+
+  structure = GST_QUERY_STRUCTURE (query);
+  value = gst_structure_id_get_value (structure, GST_QUARK (ALLOCATOR));
+  if (value) {
+    array = (GValueArray *) g_value_get_boxed (value);
+  } else {
+    GValue new_array_val = { 0, };
+
+    array = g_value_array_new (0);
+
+    g_value_init (&new_array_val, G_TYPE_VALUE_ARRAY);
+    g_value_take_boxed (&new_array_val, array);
+
+    gst_structure_id_take_value (structure, GST_QUARK (ALLOCATOR),
+        &new_array_val);
+  }
+
+  g_value_init (&alloc_value, G_TYPE_STRING);
+  g_value_set_string (&alloc_value, alloc);
+  g_value_array_append (array, &alloc_value);
+  g_value_unset (&alloc_value);
+}
+
+/**
+ * gst_query_get_n_allocation_memories:
+ * @query: a GST_QUERY_ALLOCATION type query #GstQuery
+ *
+ * Retrieve the number of values currently stored in the
+ * allocator array of the query's structure.
+ *
+ * If no memory allocator is specified, the downstream element can handle
+ * the default memory allocator.
+ *
+ * Returns: the allocator array size as a #guint.
+ */
+guint
+gst_query_get_n_allocation_memories (GstQuery * query)
+{
+  GValueArray *array;
+  const GValue *value;
+  guint size = 0;
+  GstStructure *structure;
+
+  g_return_val_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_ALLOCATION, 0);
+
+  structure = GST_QUERY_STRUCTURE (query);
+  value = gst_structure_id_get_value (structure, GST_QUARK (ALLOCATOR));
+  if (value) {
+    array = (GValueArray *) g_value_get_boxed (value);
+    size = array->n_values;
+  }
+  return size;
+}
+
+/**
+ * gst_query_parse_nth_allocation_memory
+ * @query: a GST_QUERY_ALLOCATION type query #GstQuery
+ * @index: position in the allocator array to read
+ *
+ * Parse an available query and get the alloctor
+ * at @index of the allocator array.
+ *
+ * Returns: the name of the allocator at @index.
+ */
+const gchar *
+gst_query_parse_nth_allocation_memory (GstQuery * query, guint index)
+{
+  const GValue *value;
+  const gchar *ret = NULL;
+  GstStructure *structure;
+
+  g_return_val_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_ALLOCATION, NULL);
+
+  structure = GST_QUERY_STRUCTURE (query);
+  value = gst_structure_id_get_value (structure, GST_QUARK (ALLOCATOR));
+  if (value) {
+    GValueArray *memory;
+    GValue *alloc_value;
+
+    memory = (GValueArray *) g_value_get_boxed (value);
+    alloc_value = g_value_array_get_nth (memory, index);
+
+    if (alloc_value)
+      ret = g_value_get_string (alloc_value);
+  }
+  return ret;
+}
+
+/**
+ * gst_query_new_scheduling
+ *
+ * Constructs a new query object for querying the scheduling properties.
+ *
+ * Free-function: gst_query_unref
+ *
+ * Returns: (transfer full): a new #GstQuery
+ */
+GstQuery *
+gst_query_new_scheduling (void)
+{
+  GstQuery *query;
+  GstStructure *structure;
+
+  structure = gst_structure_id_new (GST_QUARK (QUERY_SCHEDULING),
+      GST_QUARK (PULL_MODE), G_TYPE_BOOLEAN, FALSE,
+      GST_QUARK (RANDOM_ACCESS), G_TYPE_BOOLEAN, FALSE,
+      GST_QUARK (SEQUENTIAL), G_TYPE_BOOLEAN, TRUE,
+      GST_QUARK (MINSIZE), G_TYPE_INT, 1,
+      GST_QUARK (MAXSIZE), G_TYPE_INT, -1,
+      GST_QUARK (ALIGN), G_TYPE_INT, 1, NULL);
+  query = gst_query_new (GST_QUERY_SCHEDULING, structure);
+
+  return query;
+}
+
+/**
+ * gst_query_set_scheduling
+ * @query: A valid #GstQuery of type GST_QUERY_SCHEDULING.
+ * @pull_mode: if pull mode scheduling is supported
+ * @random_access: if random access is possible
+ * @sequential: if sequential access is recommended
+ * @minsize: the suggested minimum size of pull requests
+ * @maxsize the suggested maximum size of pull requests:
+ * @align: the suggested alignment of pull requests
+ *
+ * Set the scheduling properties.
+ */
+void
+gst_query_set_scheduling (GstQuery * query, gboolean pull_mode,
+    gboolean random_access, gboolean sequential,
+    gint minsize, gint maxsize, gint align)
+{
+  GstStructure *structure;
+
+  g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_SCHEDULING);
+  g_return_if_fail (gst_query_is_writable (query));
+
+  structure = GST_QUERY_STRUCTURE (query);
+  gst_structure_id_set (structure,
+      GST_QUARK (PULL_MODE), G_TYPE_BOOLEAN, pull_mode,
+      GST_QUARK (RANDOM_ACCESS), G_TYPE_BOOLEAN, random_access,
+      GST_QUARK (SEQUENTIAL), G_TYPE_BOOLEAN, sequential,
+      GST_QUARK (MINSIZE), G_TYPE_INT, minsize,
+      GST_QUARK (MAXSIZE), G_TYPE_INT, maxsize,
+      GST_QUARK (ALIGN), G_TYPE_INT, align, NULL);
+}
+
+/**
+ * gst_query_parse_scheduling
+ * @query: A valid #GstQuery of type GST_QUERY_SCHEDULING.
+ * @pull_mode: if pull mode scheduling is supported
+ * @random_access: if random access is possible
+ * @sequential: if sequential access is recommended
+ * @minsize: the suggested minimum size of pull requests
+ * @maxsize the suggested maximum size of pull requests:
+ * @align: the suggested alignment of pull requests
+ *
+ * Set the scheduling properties.
+ */
+void
+gst_query_parse_scheduling (GstQuery * query, gboolean * pull_mode,
+    gboolean * random_access, gboolean * sequential,
+    gint * minsize, gint * maxsize, gint * align)
+{
+  GstStructure *structure;
+
+  g_return_if_fail (GST_QUERY_TYPE (query) == GST_QUERY_SCHEDULING);
+
+  structure = GST_QUERY_STRUCTURE (query);
+  gst_structure_id_get (structure,
+      GST_QUARK (PULL_MODE), G_TYPE_BOOLEAN, pull_mode,
+      GST_QUARK (RANDOM_ACCESS), G_TYPE_BOOLEAN, random_access,
+      GST_QUARK (SEQUENTIAL), G_TYPE_BOOLEAN, sequential,
+      GST_QUARK (MINSIZE), G_TYPE_INT, minsize,
+      GST_QUARK (MAXSIZE), G_TYPE_INT, maxsize,
+      GST_QUARK (ALIGN), G_TYPE_INT, align, NULL);
+}
index f77c0c7..96c5506 100644 (file)
@@ -2,6 +2,7 @@
  * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
  *                    2000 Wim Taymans <wim.taymans@chello.be>
  *                    2005 Wim Taymans <wim@fluendo.com>
+ *                    2011 Wim Taymans <wim.taymans@gmail.com>
  *
  * gstquery.h: GstQuery API declaration
  *
@@ -31,6 +32,7 @@
 #include <gst/gstminiobject.h>
 #include <gst/gststructure.h>
 #include <gst/gstformat.h>
+#include <gst/gstpad.h>
 
 G_BEGIN_DECLS
 
@@ -51,6 +53,8 @@ G_BEGIN_DECLS
  * @GST_QUERY_CUSTOM: a custom application or element defined query. Since
  * 0.10.22.
  * @GST_QUERY_URI: query the URI of the source or sink. Since 0.10.22.
+ * @GST_QUERY_ALLOCATION: the buffer allocation properties
+ * @GST_QUERY_SCHEDULING: the scheduling properties
  *
  * Standard predefined Query types
  */
@@ -69,7 +73,9 @@ typedef enum {
   GST_QUERY_FORMATS,
   GST_QUERY_BUFFERING,
   GST_QUERY_CUSTOM,
-  GST_QUERY_URI
+  GST_QUERY_URI,
+  GST_QUERY_ALLOCATION,
+  GST_QUERY_SCHEDULING
 } GstQueryType;
 
 /**
@@ -90,7 +96,6 @@ typedef enum {
 
 typedef struct _GstQueryTypeDefinition GstQueryTypeDefinition;
 typedef struct _GstQuery GstQuery;
-typedef struct _GstQueryClass GstQueryClass;
 
 /**
  * GstQueryTypeDefinition:
@@ -109,13 +114,10 @@ struct _GstQueryTypeDefinition
   GQuark         quark;
 };
 
-#define GST_TYPE_QUERY                          (gst_query_get_type())
-#define GST_IS_QUERY(obj)                      (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_QUERY))
-#define GST_IS_QUERY_CLASS(klass)              (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_QUERY))
-#define GST_QUERY_GET_CLASS(obj)               (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_QUERY, GstQueryClass))
-#define GST_QUERY(obj)                         (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_QUERY, GstQuery))
-#define GST_QUERY_CAST(obj)                    ((GstQuery*)(obj)) /* only since 0.10.23 */
-#define GST_QUERY_CLASS(klass)                 (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_QUERY, GstQueryClass))
+#define GST_TYPE_QUERY                         (gst_query_get_type())
+#define GST_IS_QUERY(obj)                      (GST_IS_MINI_OBJECT_TYPE (obj, GST_TYPE_QUERY))
+#define GST_QUERY_CAST(obj)                    ((GstQuery*)(obj))
+#define GST_QUERY(obj)                         (GST_QUERY_CAST(obj))
 
 
 /**
@@ -141,7 +143,6 @@ struct _GstQueryTypeDefinition
  * GstQuery:
  * @mini_object: The parent #GstMiniObject type
  * @type: the #GstQueryType
- * @structure: the #GstStructure containing the query details.
  *
  * The #GstQuery structure.
  */
@@ -151,18 +152,6 @@ struct _GstQuery
 
   /*< public > *//* with COW */
   GstQueryType type;
-
-  GstStructure *structure;
-
-  /*< private >*/
-  gpointer _gst_reserved;
-};
-
-struct _GstQueryClass {
-  GstMiniObjectClass mini_object_class;
-
-  /*< private >*/
-  gpointer _gst_reserved[GST_PADDING];
 };
 
 const gchar*    gst_query_type_get_name        (GstQueryType query);
@@ -243,6 +232,13 @@ gst_query_copy (const GstQuery * q)
 }
 
 /**
+ * gst_query_is_writable:
+ * @q: a #GstQuery
+ *
+ * Tests if you can safely write data into a query's structure.
+ */
+#define         gst_query_is_writable(q)     gst_mini_object_is_writable (GST_MINI_OBJECT_CAST (q))
+/**
  * gst_query_make_writable:
  * @q: (transfer full): a #GstQuery to make writable
  *
@@ -251,6 +247,29 @@ gst_query_copy (const GstQuery * q)
  * Returns: (transfer full): a new writable query (possibly same as @q)
  */
 #define         gst_query_make_writable(q)      GST_QUERY_CAST (gst_mini_object_make_writable (GST_MINI_OBJECT_CAST (q)))
+/**
+ * gst_query_replace:
+ * @old_query: (inout) (transfer full): pointer to a pointer to a #GstQuery
+ *     to be replaced.
+ * @new_query: (allow-none) (transfer none): pointer to a #GstQuery that will
+ *     replace the query pointed to by @old_query.
+ *
+ * Modifies a pointer to a #GstQuery to point to a different #GstQuery. The
+ * modification is done atomically (so this is useful for ensuring thread safety
+ * in some cases), and the reference counts are updated appropriately (the old
+ * query is unreffed, the new one is reffed).
+ *
+ * Either @new_query or the #GstQuery pointed to by @old_query may be NULL.
+ */
+#define         gst_query_replace(old_query,new_query) \
+    gst_mini_object_replace ((GstMiniObject **)(old_query), GST_MINI_OBJECT_CAST (new_query))
+
+
+/* application specific query */
+GstQuery *      gst_query_new_custom            (GstQueryType type, GstStructure *structure);
+const GstStructure *
+                gst_query_get_structure         (GstQuery *query);
+GstStructure *  gst_query_writable_structure    (GstQuery *query);
 
 /* position query */
 GstQuery*       gst_query_new_position          (GstFormat format);
@@ -282,11 +301,6 @@ void            gst_query_set_segment           (GstQuery *query, gdouble rate,
 void            gst_query_parse_segment         (GstQuery *query, gdouble *rate, GstFormat *format,
                                                  gint64 *start_value, gint64 *stop_value);
 
-/* application specific query */
-GstQuery *      gst_query_new_application       (GstQueryType type,
-                                                 GstStructure *structure);
-GstStructure *  gst_query_get_structure         (GstQuery *query);
-
 /* seeking query */
 GstQuery*       gst_query_new_seeking           (GstFormat format);
 void            gst_query_set_seeking           (GstQuery *query, GstFormat format,
@@ -301,8 +315,8 @@ void            gst_query_parse_seeking         (GstQuery *query, GstFormat *for
 GstQuery*       gst_query_new_formats           (void);
 void            gst_query_set_formats           (GstQuery *query, gint n_formats, ...);
 void            gst_query_set_formatsv          (GstQuery *query, gint n_formats, const GstFormat *formats);
-void            gst_query_parse_formats_length  (GstQuery *query, guint *n_formats);
-void            gst_query_parse_formats_nth     (GstQuery *query, guint nth, GstFormat *format);
+void            gst_query_parse_n_formats       (GstQuery *query, guint *n_formats);
+void            gst_query_parse_nth_format      (GstQuery *query, guint nth, GstFormat *format);
 
 /* buffering query */
 GstQuery*       gst_query_new_buffering           (GstFormat format);
@@ -322,11 +336,10 @@ void            gst_query_set_buffering_range     (GstQuery *query, GstFormat fo
 void            gst_query_parse_buffering_range   (GstQuery *query, GstFormat *format,
                                                    gint64 *start, gint64 *stop,
                                                    gint64 *estimated_total);
-gboolean        gst_query_add_buffering_range     (GstQuery *query,
-                                                   gint64 start, gint64 stop);
-
-guint           gst_query_get_n_buffering_ranges  (GstQuery *query);
 
+gboolean        gst_query_add_buffering_range       (GstQuery *query,
+                                                     gint64 start, gint64 stop);
+guint           gst_query_get_n_buffering_ranges    (GstQuery *query);
 gboolean        gst_query_parse_nth_buffering_range (GstQuery *query,
                                                      guint index, gint64 *start,
                                                      gint64 *stop);
@@ -336,6 +349,35 @@ GstQuery *      gst_query_new_uri                 (void);
 void            gst_query_parse_uri               (GstQuery *query, gchar **uri);
 void            gst_query_set_uri                 (GstQuery *query, const gchar *uri);
 
+/* allocation query */
+GstQuery *      gst_query_new_allocation          (GstCaps *caps, gboolean need_pool);
+void            gst_query_parse_allocation        (GstQuery *query, GstCaps **caps, gboolean *need_pool);
+
+void            gst_query_set_allocation_params   (GstQuery *query, guint size, guint min_buffers,
+                                                   guint max_buffers, guint prefix, guint alignment,
+                                                   GstBufferPool *pool);
+void            gst_query_parse_allocation_params (GstQuery *query, guint *size, guint *min_buffers,
+                                                   guint *max_buffers, guint *prefix, guint *alignment,
+                                                   GstBufferPool **pool);
+
+void            gst_query_add_allocation_meta       (GstQuery *query, const gchar *api);
+guint           gst_query_get_n_allocation_metas    (GstQuery *query);
+const gchar *   gst_query_parse_nth_allocation_meta (GstQuery *query, guint index);
+
+void            gst_query_add_allocation_memory       (GstQuery *query, const gchar *alloc);
+guint           gst_query_get_n_allocation_memories   (GstQuery *query);
+const gchar *   gst_query_parse_nth_allocation_memory (GstQuery *query, guint index);
+
+/* scheduling query */
+GstQuery *      gst_query_new_scheduling          (void);
+
+void            gst_query_set_scheduling          (GstQuery *query, gboolean pull_mode,
+                                                   gboolean random_access, gboolean sequential,
+                                                   gint minsize, gint maxsize, gint align);
+void            gst_query_parse_scheduling        (GstQuery *query, gboolean *pull_mode,
+                                                   gboolean *random_access, gboolean *sequential,
+                                                   gint *minsize, gint *maxsize, gint *align);
+
 G_END_DECLS
 
 #endif /* __GST_QUERY_H__ */
index 0955ae1..6930096 100644 (file)
@@ -484,7 +484,7 @@ gst_registry_remove_features_for_plugin_unlocked (GstRegistry * registry,
           plugin->desc.name);
 
       registry->features = g_list_delete_link (registry->features, f);
-      g_hash_table_remove (registry->feature_hash, feature->name);
+      g_hash_table_remove (registry->feature_hash, GST_OBJECT_NAME (feature));
       gst_object_unparent (GST_OBJECT_CAST (feature));
     }
     f = next;
@@ -538,25 +538,27 @@ gst_registry_add_feature (GstRegistry * registry, GstPluginFeature * feature)
 
   g_return_val_if_fail (GST_IS_REGISTRY (registry), FALSE);
   g_return_val_if_fail (GST_IS_PLUGIN_FEATURE (feature), FALSE);
-  g_return_val_if_fail (feature->name != NULL, FALSE);
+  g_return_val_if_fail (GST_OBJECT_NAME (feature) != NULL, FALSE);
   g_return_val_if_fail (feature->plugin_name != NULL, FALSE);
 
   GST_OBJECT_LOCK (registry);
   existing_feature = gst_registry_lookup_feature_locked (registry,
-      feature->name);
+      GST_OBJECT_NAME (feature));
   if (G_UNLIKELY (existing_feature)) {
     GST_DEBUG_OBJECT (registry, "replacing existing feature %p (%s)",
-        existing_feature, feature->name);
+        existing_feature, GST_OBJECT_NAME (feature));
     /* Remove the existing feature from the list now, before we insert the new
      * one, but don't unref yet because the hash is still storing a reference to
      * it. */
     registry->features = g_list_remove (registry->features, existing_feature);
   }
 
-  GST_DEBUG_OBJECT (registry, "adding feature %p (%s)", feature, feature->name);
+  GST_DEBUG_OBJECT (registry, "adding feature %p (%s)", feature,
+      GST_OBJECT_NAME (feature));
 
   registry->features = g_list_prepend (registry->features, feature);
-  g_hash_table_replace (registry->feature_hash, feature->name, feature);
+  g_hash_table_replace (registry->feature_hash, GST_OBJECT_NAME (feature),
+      feature);
 
   if (G_UNLIKELY (existing_feature)) {
     /* We unref now. No need to remove the feature name from the hash table, it
@@ -569,7 +571,8 @@ gst_registry_add_feature (GstRegistry * registry, GstPluginFeature * feature)
   registry->priv->cookie++;
   GST_OBJECT_UNLOCK (registry);
 
-  GST_LOG_OBJECT (registry, "emitting feature-added for %s", feature->name);
+  GST_LOG_OBJECT (registry, "emitting feature-added for %s",
+      GST_OBJECT_NAME (feature));
   g_signal_emit (registry, gst_registry_signals[FEATURE_ADDED], 0, feature);
 
   return TRUE;
@@ -595,7 +598,7 @@ gst_registry_remove_feature (GstRegistry * registry, GstPluginFeature * feature)
 
   GST_OBJECT_LOCK (registry);
   registry->features = g_list_remove (registry->features, feature);
-  g_hash_table_remove (registry->feature_hash, feature->name);
+  g_hash_table_remove (registry->feature_hash, GST_OBJECT_NAME (feature));
   registry->priv->cookie++;
   GST_OBJECT_UNLOCK (registry);
 
@@ -678,7 +681,7 @@ type_find_factory_rank_cmp (const GstPluginFeature * fac1,
 
   /* to make the order in which things happen more deterministic,
    * sort by name when the ranks are the same. */
-  return strcmp (fac1->name, fac2->name);
+  return strcmp (GST_OBJECT_NAME (fac1), GST_OBJECT_NAME (fac2));
 }
 
 static GList *
@@ -1510,8 +1513,9 @@ scan_and_update_registry (GstRegistry * default_registry,
 
     /* plugins in the user's home directory take precedence over
      * system-installed ones */
-    home_plugins = g_build_filename (g_get_home_dir (),
-        ".gstreamer-" GST_MAJORMINOR, "plugins", NULL);
+    home_plugins = g_build_filename (g_get_user_data_dir (),
+        "gstreamer-" GST_MAJORMINOR, "plugins", NULL);
+
     GST_DEBUG ("scanning home plugins %s", home_plugins);
     changed |= gst_registry_scan_path_internal (&context, home_plugins);
     g_free (home_plugins);
@@ -1590,8 +1594,8 @@ ensure_current_registry (GError ** error)
   default_registry = gst_registry_get_default ();
   registry_file = g_strdup (g_getenv ("GST_REGISTRY"));
   if (registry_file == NULL) {
-    registry_file = g_build_filename (g_get_home_dir (),
-        ".gstreamer-" GST_MAJORMINOR, "registry." HOST_CPU ".bin", NULL);
+    registry_file = g_build_filename (g_get_user_cache_dir (),
+        "gstreamer-" GST_MAJORMINOR, "registry." HOST_CPU ".bin", NULL);
   }
 
   if (!_gst_disable_registry_cache) {
index 0088a6f..f2d07c1 100644 (file)
@@ -66,7 +66,7 @@ struct _GstRegistry {
   GstRegistryPrivate *priv;
 
   /*< private >*/
-  gpointer _gst_reserved[GST_PADDING-3];
+  gpointer _gst_reserved[GST_PADDING];
 };
 
 struct _GstRegistryClass {
@@ -115,15 +115,7 @@ GstPluginFeature*  gst_registry_find_feature       (GstRegistry *registry, const gchar
 GstPlugin *            gst_registry_lookup             (GstRegistry *registry, const char *filename);
 GstPluginFeature *     gst_registry_lookup_feature     (GstRegistry *registry, const char *name);
 
-/* These are only here because at some point they were in a public header
- * (even though they should have been private) and we can't really remove
- * them now (FIXME: 0.11). They don't do anything other than return FALSE. */
-#ifndef GST_DISABLE_DEPRECATED
-gboolean               gst_registry_xml_read_cache     (GstRegistry * registry, const char *location);
-gboolean               gst_registry_xml_write_cache    (GstRegistry * registry, const char *location);
-#endif
-
-/* convenience defines for the default registry */
+/* convinience defines for the default registry */
 
 /**
  * gst_default_registry_add_plugin:
index 1a58837..ac33965 100644 (file)
@@ -627,27 +627,3 @@ Error:
   }
   return res;
 }
-
-#ifndef GST_REMOVE_DEPRECATED
-#ifdef GST_DISABLE_DEPRECATED
-gboolean
-gst_registry_xml_read_cache (GstRegistry * registry, const char *location);
-#endif
-/* FIXME 0.11: these symbols are here for backwards compatibility and should
- * be removed or made private */
-gboolean
-gst_registry_xml_read_cache (GstRegistry * registry, const char *location)
-{
-  return FALSE;
-}
-
-#ifdef GST_DISABLE_DEPRECATED
-gboolean
-gst_registry_xml_write_cache (GstRegistry * registry, const char *location);
-#endif
-gboolean
-gst_registry_xml_write_cache (GstRegistry * registry, const char *location)
-{
-  return FALSE;
-}
-#endif /* GST_REMOVE_DEPRECATED */
index 684a181..7144ac5 100644 (file)
@@ -247,7 +247,7 @@ gst_registry_chunks_save_feature (GList ** list, GstPluginFeature * feature)
       gst_registry_chunks_save_const_string (list, (gchar *) walk->data);
     }
     GST_DEBUG ("Feature %s: saved %d interfaces %d pad templates",
-        feature->name, ef->ninterfaces, ef->npadtemplates);
+        GST_OBJECT_NAME (feature), ef->ninterfaces, ef->npadtemplates);
 
     /* save uritypes */
     if (GST_URI_TYPE_IS_VALID (factory->uri_type)) {
@@ -269,7 +269,7 @@ gst_registry_chunks_save_feature (GList ** list, GstPluginFeature * feature)
         GST_DEBUG ("Saved %d UriTypes", ef->nuriprotocols);
       } else {
         g_warning ("GStreamer feature '%s' is URI handler but does not provide"
-            " any protocols it can handle", feature->name);
+            " any protocols it can handle", GST_OBJECT_NAME (feature));
       }
     }
 
@@ -284,17 +284,9 @@ gst_registry_chunks_save_feature (GList ** list, GstPluginFeature * feature)
       }
     }
 
-    /* pack element factory strings */
-    gst_registry_chunks_save_const_string (list, factory->details.author);
-    gst_registry_chunks_save_const_string (list, factory->details.description);
-    gst_registry_chunks_save_const_string (list, factory->details.klass);
-    gst_registry_chunks_save_const_string (list, factory->details.longname);
-    if (factory->meta_data) {
-      gst_registry_chunks_save_string (list,
-          gst_structure_to_string (factory->meta_data));
-    } else {
-      gst_registry_chunks_save_const_string (list, "");
-    }
+    /* pack element metadata strings */
+    gst_registry_chunks_save_string (list,
+        gst_structure_to_string (factory->metadata));
   } else if (GST_IS_TYPE_FIND_FACTORY (feature)) {
     GstRegistryChunkTypeFindFactory *tff;
     GstTypeFindFactory *factory = GST_TYPE_FIND_FACTORY (feature);
@@ -349,7 +341,7 @@ gst_registry_chunks_save_feature (GList ** list, GstPluginFeature * feature)
     *list = g_list_prepend (*list, chk);
 
     /* pack plugin feature strings */
-    gst_registry_chunks_save_const_string (list, feature->name);
+    gst_registry_chunks_save_const_string (list, GST_OBJECT_NAME (feature));
     gst_registry_chunks_save_const_string (list, (gchar *) type_name);
 
     return TRUE;
@@ -501,7 +493,7 @@ gst_registry_chunks_load_pad_template (GstElementFactory * factory, gchar ** in,
   template = g_slice_new (GstStaticPadTemplate);
   template->presence = pt->presence;
   template->direction = pt->direction;
-  template->static_caps.caps.refcount = 0;
+  template->static_caps.caps.mini_object.refcount = 0;
 
   /* unpack pad template strings */
   unpack_const_string (*in, template->name_template, end, fail);
@@ -586,21 +578,16 @@ gst_registry_chunks_load_feature (GstRegistry * registry, gchar ** in,
     /* unpack element factory strings */
     unpack_string_nocopy (*in, meta_data_str, end, fail);
     if (meta_data_str && *meta_data_str) {
-      factory->meta_data = gst_structure_from_string (meta_data_str, NULL);
-      if (!factory->meta_data) {
+      factory->metadata = gst_structure_from_string (meta_data_str, NULL);
+      if (!factory->metadata) {
         GST_ERROR
             ("Error when trying to deserialize structure for metadata '%s'",
             meta_data_str);
         goto fail;
       }
     }
-    unpack_string (*in, factory->details.longname, end, fail);
-    unpack_string (*in, factory->details.klass, end, fail);
-    unpack_string (*in, factory->details.description, end, fail);
-    unpack_string (*in, factory->details.author, end, fail);
     n = ef->npadtemplates;
-    GST_DEBUG ("Element factory : '%s' with npadtemplates=%d",
-        factory->details.longname, n);
+    GST_DEBUG ("Element factory : npadtemplates=%d", n);
 
     /* load pad templates */
     for (i = 0; i < n; i++) {
@@ -687,8 +674,8 @@ gst_registry_chunks_load_feature (GstRegistry * registry, gchar ** in,
       (gpointer *) & feature->plugin);
 
   gst_registry_add_feature (registry, feature);
-  GST_DEBUG ("Added feature %s, plugin %p %s", feature->name, plugin,
-      plugin_name);
+  GST_DEBUG ("Added feature %s, plugin %p %s", GST_OBJECT_NAME (feature),
+      plugin, plugin_name);
 
   return TRUE;
 
index a70e8e6..b5ad3e2 100644 (file)
@@ -33,7 +33,7 @@
  * @see_also: #GstEvent
  *
  * This helper structure holds the relevant values for tracking the region of
- * interest in a media file, called a segment. 
+ * interest in a media file, called a segment.
  *
  * The structure can be used for two purposes:
  * <itemizedlist>
@@ -41,7 +41,7 @@
  *   <listitem><para>tracking playback regions (handling newsegment events)</para></listitem>
  * </itemizedlist>
  *
- * The segment is usually configured by the application with a seek event which 
+ * The segment is usually configured by the application with a seek event which
  * is propagated upstream and eventually handled by an element that performs the seek.
  *
  * The configured segment is then propagated back downstream with a newsegment event.
@@ -54,7 +54,7 @@
  *
  * If the segment is used for managing seeks, the segment duration should be set with
  * gst_segment_set_duration(). The public duration field contains the duration of the
- * segment. When using the segment for seeking, the start and time members should 
+ * segment. When using the segment for seeking, the start and time members should
  * normally be left to their default 0 value. The stop position is left to -1 unless
  * explicitly configured to a different value after a seek event.
  *
@@ -77,7 +77,7 @@
  * to the clock. This function takes into account all accumulated segments as well as
  * any rate or applied_rate conversions.
  *
- * For elements that need to perform operations on media data in stream_time, 
+ * For elements that need to perform operations on media data in stream_time,
  * gst_segment_to_stream_time() can be used to convert a timestamp and the segment
  * info to stream time (which is always between 0 and the duration of the stream).
  *
@@ -97,7 +97,7 @@
  * Since: 0.10.20
  */
 GstSegment *
-gst_segment_copy (GstSegment * segment)
+gst_segment_copy (const GstSegment * segment)
 {
   GstSegment *result = NULL;
 
@@ -107,6 +107,12 @@ gst_segment_copy (GstSegment * segment)
   return result;
 }
 
+void
+gst_segment_copy_into (const GstSegment * src, GstSegment * dest)
+{
+  memcpy (dest, src, sizeof (GstSegment));
+}
+
 GType
 gst_segment_get_type (void)
 {
@@ -123,7 +129,7 @@ gst_segment_get_type (void)
 /**
  * gst_segment_new:
  *
- * Allocate a new #GstSegment structure and initialize it using 
+ * Allocate a new #GstSegment structure and initialize it using
  * gst_segment_init().
  *
  * Free-function: gst_segment_free
@@ -169,94 +175,41 @@ gst_segment_init (GstSegment * segment, GstFormat format)
 {
   g_return_if_fail (segment != NULL);
 
+  segment->flags = 0;
   segment->rate = 1.0;
-  segment->abs_rate = 1.0;
   segment->applied_rate = 1.0;
   segment->format = format;
-  segment->flags = 0;
+  segment->base = 0;
   segment->start = 0;
   segment->stop = -1;
   segment->time = 0;
-  segment->accum = 0;
-  segment->last_stop = 0;
+  segment->position = 0;
   segment->duration = -1;
 }
 
 /**
- * gst_segment_set_duration:
- * @segment: a #GstSegment structure.
- * @format: the format of the segment.
- * @duration: the duration of the segment info or -1 if unknown.
- *
- * Set the duration of the segment to @duration. This function is mainly
- * used by elements that perform seeking and know the total duration of the
- * segment. 
- * 
- * This field should be set to allow seeking requests relative to the
- * duration.
- */
-void
-gst_segment_set_duration (GstSegment * segment, GstFormat format,
-    gint64 duration)
-{
-  g_return_if_fail (segment != NULL);
-
-  if (G_UNLIKELY (segment->format == GST_FORMAT_UNDEFINED))
-    segment->format = format;
-  else
-    g_return_if_fail (segment->format == format);
-
-  segment->duration = duration;
-}
-
-/**
- * gst_segment_set_last_stop:
- * @segment: a #GstSegment structure.
- * @format: the format of the segment.
- * @position: the position 
- *
- * Set the last observed stop position in the segment to @position.
- *
- * This field should be set to allow seeking requests relative to the
- * current playing position.
- */
-void
-gst_segment_set_last_stop (GstSegment * segment, GstFormat format,
-    gint64 position)
-{
-  g_return_if_fail (segment != NULL);
-
-  if (G_UNLIKELY (segment->format == GST_FORMAT_UNDEFINED))
-    segment->format = format;
-  else
-    g_return_if_fail (segment->format == format);
-
-  segment->last_stop = MAX (segment->start, position);
-}
-
-/**
- * gst_segment_set_seek:
+ * gst_segment_do_seek:
  * @segment: a #GstSegment structure.
  * @rate: the rate of the segment.
  * @format: the format of the segment.
- * @flags: the seek flags for the segment
+ * @flags: the segment flags for the segment
  * @start_type: the seek method
  * @start: the seek start value
  * @stop_type: the seek method
  * @stop: the seek stop value
- * @update: boolean holding whether last_stop was updated.
+ * @update: boolean holding whether position was updated.
  *
  * Update the segment structure with the field values of a seek event (see
  * gst_event_new_seek()).
  *
- * After calling this method, the segment field last_stop and time will
+ * After calling this method, the segment field position and time will
  * contain the requested new position in the segment. The new requested
- * position in the segment depends on @rate and @start_type and @stop_type. 
+ * position in the segment depends on @rate and @start_type and @stop_type.
  *
  * For positive @rate, the new position in the segment is the new @segment
  * start field when it was updated with a @start_type different from
  * #GST_SEEK_TYPE_NONE. If no update was performed on @segment start position
- * (#GST_SEEK_TYPE_NONE), @start is ignored and @segment last_stop is
+ * (#GST_SEEK_TYPE_NONE), @start is ignored and @segment position is
  * unmodified.
  *
  * For negative @rate, the new position in the segment is the new @segment
@@ -264,33 +217,42 @@ gst_segment_set_last_stop (GstSegment * segment, GstFormat format,
  * #GST_SEEK_TYPE_NONE. If no stop was previously configured in the segment, the
  * duration of the segment will be used to update the stop position.
  * If no update was performed on @segment stop position (#GST_SEEK_TYPE_NONE),
- * @stop is ignored and @segment last_stop is unmodified.
+ * @stop is ignored and @segment position is unmodified.
  *
  * The applied rate of the segment will be set to 1.0 by default.
  * If the caller can apply a rate change, it should update @segment
  * rate and applied_rate after calling this function.
  *
- * @update will be set to TRUE if a seek should be performed to the segment 
- * last_stop field. This field can be FALSE if, for example, only the @rate
+ * @update will be set to TRUE if a seek should be performed to the segment
+ * position field. This field can be FALSE if, for example, only the @rate
  * has been changed but not the playback position.
+ *
+ * Returns: %TRUE if the seek could be performed.
  */
-void
-gst_segment_set_seek (GstSegment * segment, gdouble rate,
+gboolean
+gst_segment_do_seek (GstSegment * segment, gdouble rate,
     GstFormat format, GstSeekFlags flags,
-    GstSeekType start_type, gint64 start,
-    GstSeekType stop_type, gint64 stop, gboolean * update)
+    GstSeekType start_type, guint64 start,
+    GstSeekType stop_type, guint64 stop, gboolean * update)
 {
   gboolean update_stop, update_start;
-  gint64 last_stop;
-
-  g_return_if_fail (rate != 0.0);
-  g_return_if_fail (segment != NULL);
+  guint64 position, base;
 
-  if (G_UNLIKELY (segment->format == GST_FORMAT_UNDEFINED))
-    segment->format = format;
+  g_return_val_if_fail (rate != 0.0, FALSE);
+  g_return_val_if_fail (segment != NULL, FALSE);
+  g_return_val_if_fail (segment->format == format, FALSE);
 
   update_start = update_stop = TRUE;
 
+  position = segment->position;
+
+  if (flags & GST_SEEK_FLAG_FLUSH) {
+    /* flush resets the running_time */
+    base = 0;
+  } else {
+    base = gst_segment_to_running_time (segment, format, position);
+  }
+
   /* segment->start is never invalid */
   switch (start_type) {
     case GST_SEEK_TYPE_NONE:
@@ -302,17 +264,19 @@ gst_segment_set_seek (GstSegment * segment, gdouble rate,
       /* start holds desired position, map -1 to the start */
       if (start == -1)
         start = 0;
-      /* start must be 0 or the formats must match */
-      g_return_if_fail (start == 0 || segment->format == format);
       break;
     case GST_SEEK_TYPE_CUR:
-      g_return_if_fail (start == 0 || segment->format == format);
+    {
+      gint64 sstart = (gint64) start;
       /* add start to currently configured segment */
-      start = segment->start + start;
+      if (sstart > 0 || segment->start > -sstart)
+        start = segment->start + start;
+      else
+        start = 0;
       break;
+    }
     case GST_SEEK_TYPE_END:
       if (segment->duration != -1) {
-        g_return_if_fail (start == 0 || segment->format == format);
         /* add start to total length */
         start = segment->duration + start;
       } else {
@@ -324,7 +288,7 @@ gst_segment_set_seek (GstSegment * segment, gdouble rate,
   }
   /* bring in sane range */
   if (segment->duration != -1)
-    start = CLAMP (start, 0, segment->duration);
+    start = MIN (start, segment->duration);
   else
     start = MAX (start, 0);
 
@@ -335,22 +299,20 @@ gst_segment_set_seek (GstSegment * segment, gdouble rate,
       update_stop = FALSE;
       break;
     case GST_SEEK_TYPE_SET:
-      /* stop holds required value, if it's not -1, it must be of the same
-       * format as the segment. */
-      g_return_if_fail (stop == -1 || segment->format == format);
+      /* stop holds required value */
       break;
     case GST_SEEK_TYPE_CUR:
       if (segment->stop != -1) {
-        /* only add compatible formats or 0 */
-        g_return_if_fail (stop == 0 || segment->format == format);
-        stop = segment->stop + stop;
+        gint64 sstop = (gint64) stop;
+        if (sstop > 0 || segment->stop > -sstop)
+          stop = segment->stop + stop;
+        else
+          stop = 0;
       } else
         stop = -1;
       break;
     case GST_SEEK_TYPE_END:
       if (segment->duration != -1) {
-        /* only add compatible formats or 0 */
-        g_return_if_fail (stop == 0 || segment->format == format);
         stop = segment->duration + stop;
       } else {
         stop = segment->stop;
@@ -368,168 +330,42 @@ gst_segment_set_seek (GstSegment * segment, gdouble rate,
   }
 
   /* we can't have stop before start */
-  if (stop != -1)
-    g_return_if_fail (start <= stop);
+  if (stop != -1) {
+    if (start > stop) {
+      g_return_val_if_fail (start <= stop, FALSE);
+      return FALSE;
+    }
+  }
 
   segment->rate = rate;
-  segment->abs_rate = ABS (rate);
   segment->applied_rate = 1.0;
+  segment->base = base;
   segment->flags = flags;
   segment->start = start;
   segment->stop = stop;
   segment->time = start;
 
-  last_stop = segment->last_stop;
   if (update_start && rate > 0.0) {
-    last_stop = start;
+    position = start;
   }
   if (update_stop && rate < 0.0) {
     if (stop != -1)
-      last_stop = stop;
+      position = stop;
     else {
       if (segment->duration != -1)
-        last_stop = segment->duration;
+        position = segment->duration;
       else
-        last_stop = 0;
+        position = 0;
     }
   }
-  /* set update arg to reflect update of last_stop */
+  /* set update arg to reflect update of position */
   if (update)
-    *update = last_stop != segment->last_stop;
+    *update = position != segment->position;
 
   /* update new position */
-  segment->last_stop = last_stop;
-}
-
-/**
- * gst_segment_set_newsegment:
- * @segment: a #GstSegment structure.
- * @update: flag indicating a new segment is started or updated
- * @rate: the rate of the segment.
- * @format: the format of the segment.
- * @start: the new start value
- * @stop: the new stop value
- * @time: the new stream time
- *
- * Update the segment structure with the field values of a new segment event and
- * with a default applied_rate of 1.0.
- *
- * Since: 0.10.6
- */
-void
-gst_segment_set_newsegment (GstSegment * segment, gboolean update, gdouble rate,
-    GstFormat format, gint64 start, gint64 stop, gint64 time)
-{
-  gst_segment_set_newsegment_full (segment, update, rate, 1.0, format, start,
-      stop, time);
-}
-
-/**
- * gst_segment_set_newsegment_full:
- * @segment: a #GstSegment structure.
- * @update: flag indicating a new segment is started or updated
- * @rate: the rate of the segment.
- * @applied_rate: the applied rate of the segment.
- * @format: the format of the segment.
- * @start: the new start value
- * @stop: the new stop value
- * @time: the new stream time
- *
- * Update the segment structure with the field values of a new segment event.
- */
-void
-gst_segment_set_newsegment_full (GstSegment * segment, gboolean update,
-    gdouble rate, gdouble applied_rate, GstFormat format, gint64 start,
-    gint64 stop, gint64 time)
-{
-  gint64 duration, last_stop;
-
-  g_return_if_fail (rate != 0.0);
-  g_return_if_fail (applied_rate != 0.0);
-  g_return_if_fail (segment != NULL);
-
-  GST_DEBUG ("configuring segment update %d, rate %lf, format %s, "
-      "start %" G_GINT64_FORMAT ", stop %" G_GINT64_FORMAT ", position %"
-      G_GINT64_FORMAT, update, rate, gst_format_get_name (format), start,
-      stop, time);
-  GST_DEBUG ("old segment was: %" GST_SEGMENT_FORMAT, segment);
-
-  if (G_UNLIKELY (segment->format == GST_FORMAT_UNDEFINED))
-    segment->format = format;
-
-  /* any other format with 0 also gives time 0, the other values are
-   * invalid in the format though. */
-  if (format != segment->format && start == 0) {
-    format = segment->format;
-    if (stop != 0)
-      stop = -1;
-    if (time != 0)
-      time = -1;
-  }
-
-  g_return_if_fail (segment->format == format);
-
-  if (update) {
-    if (G_LIKELY (segment->rate > 0.0)) {
-      /* an update to the current segment is done, elapsed time is
-       * difference between the old start and new start. */
-      if (start > segment->start)
-        duration = start - segment->start;
-      else
-        duration = 0;
-    } else {
-      /* for negative rates, the elapsed duration is the diff between the stop
-       * positions */
-      if (stop != -1 && stop < segment->stop)
-        duration = segment->stop - stop;
-      else
-        duration = 0;
-    }
-    /* update last_stop to be a valid value in the updated segment */
-    if (start > segment->last_stop)
-      last_stop = start;
-    else if (stop != -1 && stop < segment->last_stop)
-      last_stop = stop;
-    else
-      last_stop = segment->last_stop;
-  } else {
-    /* the new segment has to be aligned with the old segment.
-     * We first update the accumulated time of the previous
-     * segment. the accumulated time is used when syncing to the
-     * clock. */
-    if (segment->stop != -1) {
-      duration = segment->stop - segment->start;
-    } else if (segment->last_stop != -1) {
-      /* else use last seen timestamp as segment stop */
-      duration = segment->last_stop - segment->start;
-    } else {
-      /* else we don't know and throw a warning.. really, this should
-       * be fixed in the element. */
-      g_warning ("closing segment of unknown duration, assuming duration of 0");
-      duration = 0;
-    }
-    /* position the last_stop to the next expected position in the new segment,
-     * which is the start or the stop of the segment */
-    if (rate > 0.0)
-      last_stop = start;
-    else
-      last_stop = stop;
-  }
-  /* use previous rate to calculate duration */
-  if (G_LIKELY (segment->abs_rate != 1.0))
-    duration /= segment->abs_rate;
-
-  /* accumulate duration */
-  segment->accum += duration;
+  segment->position = position;
 
-  /* then update the current segment */
-  segment->rate = rate;
-  segment->abs_rate = ABS (rate);
-  segment->applied_rate = applied_rate;
-  segment->start = start;
-  segment->last_stop = last_stop;
-  segment->stop = stop;
-  segment->time = time;
+  return TRUE;
 }
 
 /**
@@ -538,25 +374,25 @@ gst_segment_set_newsegment_full (GstSegment * segment, gboolean update,
  * @format: the format of the segment.
  * @position: the position in the segment
  *
- * Translate @position to stream time using the currently configured 
+ * Translate @position to stream time using the currently configured
  * segment. The @position value must be between @segment start and
- * stop value. 
+ * stop value.
  *
  * This function is typically used by elements that need to operate on
  * the stream time of the buffers it receives, such as effect plugins.
- * In those use cases, @position is typically the buffer timestamp or 
+ * In those use cases, @position is typically the buffer timestamp or
  * clock time that one wants to convert to the stream time.
- * The stream time is always between 0 and the total duration of the 
- * media stream. 
+ * The stream time is always between 0 and the total duration of the
+ * media stream.
  *
  * Returns: the position in stream_time or -1 when an invalid position
  * was given.
  */
-gint64
-gst_segment_to_stream_time (GstSegment * segment, GstFormat format,
-    gint64 position)
+guint64
+gst_segment_to_stream_time (const GstSegment * segment, GstFormat format,
+    guint64 position)
 {
-  gint64 result, start, stop, time;
+  guint64 result, start, stop, time;
   gdouble abs_applied_rate;
 
   /* format does not matter for -1 */
@@ -564,9 +400,7 @@ gst_segment_to_stream_time (GstSegment * segment, GstFormat format,
     return -1;
 
   g_return_val_if_fail (segment != NULL, -1);
-
-  if (G_UNLIKELY (segment->format == GST_FORMAT_UNDEFINED))
-    segment->format = format;
+  g_return_val_if_fail (segment->format == format, -1);
 
   /* if we have the position for the same format as the segment, we can compare
    * the start and stop values, otherwise we assume 0 and -1 */
@@ -624,7 +458,7 @@ gst_segment_to_stream_time (GstSegment * segment, GstFormat format,
  * @format: the format of the segment.
  * @position: the position in the segment
  *
- * Translate @position to the total running time using the currently configured 
+ * Translate @position to the total running time using the currently configured
  * and previously accumulated segments. Position is a value between @segment
  * start and stop time.
  *
@@ -638,31 +472,30 @@ gst_segment_to_stream_time (GstSegment * segment, GstFormat format,
  * Returns: the position as the total running time or -1 when an invalid position
  * was given.
  */
-gint64
-gst_segment_to_running_time (GstSegment * segment, GstFormat format,
-    gint64 position)
+guint64
+gst_segment_to_running_time (const GstSegment * segment, GstFormat format,
+    guint64 position)
 {
-  gint64 result;
-  gint64 start, stop, accum;
+  guint64 result;
+  guint64 start, stop, base;
+  gdouble abs_rate;
 
   if (G_UNLIKELY (position == -1))
     return -1;
 
   g_return_val_if_fail (segment != NULL, -1);
-
-  if (G_UNLIKELY (segment->format == GST_FORMAT_UNDEFINED))
-    segment->format = format;
+  g_return_val_if_fail (segment->format == format, -1);
 
   /* if we have the position for the same format as the segment, we can compare
    * the start and stop values, otherwise we assume 0 and -1 */
   if (G_LIKELY (segment->format == format)) {
     start = segment->start;
     stop = segment->stop;
-    accum = segment->accum;
+    base = segment->base;
   } else {
     start = 0;
     stop = -1;
-    accum = 0;
+    base = 0;
   }
 
   /* before the segment boundary */
@@ -686,13 +519,14 @@ gst_segment_to_running_time (GstSegment * segment, GstFormat format,
     result = stop - position;
   }
 
-  /* scale based on the rate, avoid division by and conversion to 
+  /* scale based on the rate, avoid division by and conversion to
    * float when not needed */
-  if (G_UNLIKELY (segment->abs_rate != 1.0))
-    result /= segment->abs_rate;
+  abs_rate = ABS (segment->rate);
+  if (G_UNLIKELY (abs_rate != 1.0))
+    result /= abs_rate;
 
-  /* correct for accumulated segments */
-  result += accum;
+  /* correct for base of the segment */
+  result += base;
 
   return result;
 }
@@ -707,7 +541,7 @@ gst_segment_to_running_time (GstSegment * segment, GstFormat format,
  * @clip_stop: (out) (allow-none): the clipped stop position in the segment
  *
  * Clip the given @start and @stop values to the segment boundaries given
- * in @segment. @start and @stop are compared and clipped to @segment 
+ * in @segment. @start and @stop are compared and clipped to @segment
  * start and stop values.
  *
  * If the function returns FALSE, @start and @stop are known to fall
@@ -720,22 +554,18 @@ gst_segment_to_running_time (GstSegment * segment, GstFormat format,
  * Note that when @stop is -1, @clip_stop will be set to the end of the
  * segment. Depending on the use case, this may or may not be what you want.
  *
- * Returns: TRUE if the given @start and @stop times fall partially or 
- *     completely in @segment, FALSE if the values are completely outside 
+ * Returns: TRUE if the given @start and @stop times fall partially or
+ *     completely in @segment, FALSE if the values are completely outside
  *     of the segment.
  */
 gboolean
-gst_segment_clip (GstSegment * segment, GstFormat format, gint64 start,
-    gint64 stop, gint64 * clip_start, gint64 * clip_stop)
+gst_segment_clip (const GstSegment * segment, GstFormat format, guint64 start,
+    guint64 stop, guint64 * clip_start, guint64 * clip_stop)
 {
   g_return_val_if_fail (segment != NULL, FALSE);
+  g_return_val_if_fail (segment->format == format, FALSE);
 
-  if (G_UNLIKELY (segment->format == GST_FORMAT_UNDEFINED))
-    segment->format = format;
-  else
-    g_return_val_if_fail (segment->format == format, FALSE);
-
-  /* if we have a stop position and a valid start and start is bigger, 
+  /* if we have a stop position and a valid start and start is bigger,
    * we're outside of the segment */
   if (G_UNLIKELY (segment->stop != -1 && start != -1 && start >= segment->stop))
     return FALSE;
@@ -759,11 +589,11 @@ gst_segment_clip (GstSegment * segment, GstFormat format, gint64 start,
     if (stop == -1)
       *clip_stop = segment->stop;
     else if (segment->stop == -1)
-      *clip_stop = MAX (-1, stop);
+      *clip_stop = stop;
     else
       *clip_stop = MIN (stop, segment->stop);
 
-    if (segment->duration != -1)
+    if (segment->duration != -1 && *clip_stop != -1)
       *clip_stop = MIN (*clip_stop, segment->duration);
   }
 
@@ -784,43 +614,43 @@ gst_segment_clip (GstSegment * segment, GstFormat format, gint64 start,
  *
  * Since: 0.10.24
  */
-gint64
-gst_segment_to_position (GstSegment * segment, GstFormat format,
-    gint64 running_time)
+guint64
+gst_segment_to_position (const GstSegment * segment, GstFormat format,
+    guint64 running_time)
 {
-  gint64 result;
-  gint64 start, stop, accum;
-
-  g_return_val_if_fail (segment != NULL, -1);
+  guint64 result;
+  guint64 start, stop, base;
+  gdouble abs_rate;
 
   if (G_UNLIKELY (running_time == -1))
     return -1;
 
-  if (G_UNLIKELY (segment->format == GST_FORMAT_UNDEFINED))
-    segment->format = format;
+  g_return_val_if_fail (segment != NULL, -1);
+  g_return_val_if_fail (segment->format == format, FALSE);
 
   /* if we have the position for the same format as the segment, we can compare
    * the start and stop values, otherwise we assume 0 and -1 */
   if (G_LIKELY (segment->format == format)) {
     start = segment->start;
     stop = segment->stop;
-    accum = segment->accum;
+    base = segment->base;
   } else {
     start = 0;
     stop = -1;
-    accum = 0;
+    base = 0;
   }
 
   /* this running_time was for a previous segment */
-  if (running_time < accum)
+  if (running_time < base)
     return -1;
 
-  /* start by subtracting the accumulated time */
-  result = running_time - accum;
+  /* start by subtracting the base time */
+  result = running_time - base;
 
   /* move into the segment at the right rate */
-  if (G_UNLIKELY (segment->abs_rate != 1.0))
-    result = ceil (result * segment->abs_rate);
+  abs_rate = ABS (segment->rate);
+  if (G_UNLIKELY (abs_rate != 1.0))
+    result = ceil (result * abs_rate);
 
   if (G_LIKELY (segment->rate > 0.0)) {
     /* bring to corrected position in segment */
@@ -848,7 +678,7 @@ gst_segment_to_position (GstSegment * segment, GstFormat format,
  * @format: the format of the segment.
  * @running_time: the running_time in the segment
  *
- * Adjust the start/stop and accum values of @segment such that the next valid
+ * Adjust the start/stop and base values of @segment such that the next valid
  * buffer will be one with @running_time.
  *
  * Returns: %TRUE if the segment could be updated successfully. If %FALSE is
@@ -858,10 +688,10 @@ gst_segment_to_position (GstSegment * segment, GstFormat format,
  */
 gboolean
 gst_segment_set_running_time (GstSegment * segment, GstFormat format,
-    gint64 running_time)
+    guint64 running_time)
 {
-  gint64 position;
-  gint64 start, stop, last_stop;
+  guint64 position;
+  guint64 start, stop;
 
   /* start by bringing the running_time into the segment position */
   position = gst_segment_to_position (segment, format, running_time);
@@ -872,26 +702,19 @@ gst_segment_set_running_time (GstSegment * segment, GstFormat format,
 
   start = segment->start;
   stop = segment->stop;
-  last_stop = segment->last_stop;
 
   if (G_LIKELY (segment->rate > 0.0)) {
-    /* update the start/last_stop and time values */
+    /* update the start and time values */
     start = position;
-    if (last_stop < start)
-      last_stop = start;
   } else {
     /* reverse, update stop */
     stop = position;
-    /* if we were past the position, go back */
-    if (last_stop > stop)
-      last_stop = stop;
   }
-  /* and accumulated time is exactly the running time */
+  /* and base time is exactly the running time */
   segment->time = gst_segment_to_stream_time (segment, format, start);
   segment->start = start;
   segment->stop = stop;
-  segment->last_stop = last_stop;
-  segment->accum = running_time;
+  segment->base = running_time;
 
   return TRUE;
 }
index a0c3683..43f3f17 100644 (file)
@@ -23,7 +23,6 @@
 #ifndef __GST_SEGMENT_H__
 #define __GST_SEGMENT_H__
 
-#include <gst/gstevent.h>
 #include <gst/gstformat.h>
 
 G_BEGIN_DECLS
@@ -33,76 +32,144 @@ G_BEGIN_DECLS
 typedef struct _GstSegment GstSegment;
 
 /**
+ * GstSeekType:
+ * @GST_SEEK_TYPE_NONE: no change in position is required
+ * @GST_SEEK_TYPE_CUR: change relative to currently configured segment. This
+ *    can't be used to seek relative to the current playback position - do a
+ *    position query, calculate the desired position and then do an absolute
+ *    position seek instead if that's what you want to do.
+ * @GST_SEEK_TYPE_SET: absolute position is requested
+ * @GST_SEEK_TYPE_END: relative position to duration is requested
+ *
+ * The different types of seek events. When constructing a seek event with
+ * gst_event_new_seek() or when doing gst_segment_do_seek ().
+ */
+typedef enum {
+  /* one of these */
+  GST_SEEK_TYPE_NONE            = 0,
+  GST_SEEK_TYPE_CUR             = 1,
+  GST_SEEK_TYPE_SET             = 2,
+  GST_SEEK_TYPE_END             = 3
+} GstSeekType;
+
+/**
+ * GstSeekFlags:
+ * @GST_SEEK_FLAG_NONE: no flag
+ * @GST_SEEK_FLAG_FLUSH: flush pipeline
+ * @GST_SEEK_FLAG_ACCURATE: accurate position is requested, this might
+ *                     be considerably slower for some formats.
+ * @GST_SEEK_FLAG_KEY_UNIT: seek to the nearest keyframe. This might be
+ *                     faster but less accurate.
+ * @GST_SEEK_FLAG_SEGMENT: perform a segment seek.
+ * @GST_SEEK_FLAG_SKIP: when doing fast foward or fast reverse playback, allow
+ *                     elements to skip frames instead of generating all
+ *                     frames. Since 0.10.22.
+ *
+ * Flags to be used with gst_element_seek() or gst_event_new_seek(). All flags
+ * can be used together.
+ *
+ * A non flushing seek might take some time to perform as the currently
+ * playing data in the pipeline will not be cleared.
+ *
+ * An accurate seek might be slower for formats that don't have any indexes
+ * or timestamp markers in the stream. Specifying this flag might require a
+ * complete scan of the file in those cases.
+ *
+ * When performing a segment seek: after the playback of the segment completes,
+ * no EOS will be emmited by the element that performed the seek, but a
+ * #GST_MESSAGE_SEGMENT_DONE message will be posted on the bus by the element.
+ * When this message is posted, it is possible to send a new seek event to
+ * continue playback. With this seek method it is possible to perform seemless
+ * looping or simple linear editing.
+ *
+ * When doing fast forward (rate > 1.0) or fast reverse (rate < -1.0) trickmode
+ * playback, the @GST_SEEK_FLAG_SKIP flag can be used to instruct decoders
+ * and demuxers to adjust the playback rate by skipping frames. This can improve
+ * performance and decrease CPU usage because not all frames need to be decoded.
+ *
+ * Also see part-seeking.txt in the GStreamer design documentation for more
+ * details on the meaning of these flags and the behaviour expected of
+ * elements that handle them.
+ */
+typedef enum {
+  GST_SEEK_FLAG_NONE            = 0,
+  GST_SEEK_FLAG_FLUSH           = (1 << 0),
+  GST_SEEK_FLAG_ACCURATE        = (1 << 1),
+  GST_SEEK_FLAG_KEY_UNIT        = (1 << 2),
+  GST_SEEK_FLAG_SEGMENT         = (1 << 3),
+  GST_SEEK_FLAG_SKIP            = (1 << 4)
+} GstSeekFlags;
+
+/**
+ * GstSegmentFlags:
+ * @GST_SEGMENT_FLAG_NONE: no flags
+ * @GST_SEGMENT_FLAG_RESET: reset the pipeline running_time to the segment
+ *                          running_time
+ * @GST_SEGMENT_FLAG_SKIP: perform skip playback
+ *
+ * Flags for the GstSegment structure. Currently mapped to the corresponding
+ * values of the seek flags.
+ */
+typedef enum {
+  GST_SEGMENT_FLAG_NONE            = GST_SEEK_FLAG_NONE,
+  GST_SEGMENT_FLAG_RESET           = GST_SEEK_FLAG_FLUSH,
+  GST_SEGMENT_FLAG_SKIP            = GST_SEEK_FLAG_SKIP
+} GstSegmentFlags;
+
+/**
  * GstSegment:
+ * @flags: flags for this segment
  * @rate: the rate of the segment
- * @abs_rate: absolute value of @rate
+ * @applied_rate: the already applied rate to the segment
  * @format: the format of the segment values
- * @flags: flags for this segment
+ * @base: the base time of the segment
  * @start: the start of the segment
  * @stop: the stop of the segment
  * @time: the stream time of the segment
- * @accum: accumulated segment
- * @last_stop: last known stop time
- * @duration: total duration of segment
- * @applied_rate: the already applied rate to the segment
  *
  * A helper structure that holds the configured region of
  * interest in a media file.
  */
 struct _GstSegment {
   /*< public >*/
-  gdouble        rate;
-  gdouble        abs_rate;
-  GstFormat      format;
-  GstSeekFlags   flags;
-  gint64         start;
-  gint64         stop;
-  gint64         time;
-  gint64         accum;
-
-  gint64         last_stop;
-  gint64         duration;
-
-  /* API added 0.10.6 */
-  gdouble        applied_rate;
-
-  /*< private >*/
-  /*gpointer _gst_reserved[GST_PADDING-2];*/
-  guint8 _gst_reserved[(sizeof (gpointer) * GST_PADDING) - sizeof (gdouble)];
+  GstSegmentFlags flags;
+
+  gdouble         rate;
+  gdouble         applied_rate;
+
+  GstFormat       format;
+  guint64         base;
+  guint64         start;
+  guint64         stop;
+  guint64         time;
+
+  guint64         position;
+  guint64         duration;
 };
 
 GType        gst_segment_get_type            (void);
 
 GstSegment * gst_segment_new                 (void);
-GstSegment * gst_segment_copy                (GstSegment *segment);
+GstSegment * gst_segment_copy                (const GstSegment *segment);
+void         gst_segment_copy_into           (const GstSegment *src, GstSegment *dest);
 void         gst_segment_free                (GstSegment *segment);
 
 void         gst_segment_init                (GstSegment *segment, GstFormat format);
 
-void         gst_segment_set_duration        (GstSegment *segment, GstFormat format, gint64 duration);
-void         gst_segment_set_last_stop       (GstSegment *segment, GstFormat format, gint64 position);
+guint64      gst_segment_to_stream_time      (const GstSegment *segment, GstFormat format, guint64 position);
+guint64      gst_segment_to_running_time     (const GstSegment *segment, GstFormat format, guint64 position);
+guint64      gst_segment_to_position         (const GstSegment *segment, GstFormat format, guint64 running_time);
 
-void         gst_segment_set_seek            (GstSegment *segment, gdouble rate,
-                                              GstFormat format, GstSeekFlags flags,
-                                              GstSeekType start_type, gint64 start,
-                                              GstSeekType stop_type, gint64 stop,
-                                              gboolean *update);
+gboolean     gst_segment_set_running_time    (GstSegment *segment, GstFormat format, guint64 running_time);
 
-void         gst_segment_set_newsegment      (GstSegment *segment, gboolean update, gdouble rate,
-                                              GstFormat format, gint64 start, gint64 stop, gint64 time);
-void         gst_segment_set_newsegment_full (GstSegment *segment, gboolean update, gdouble rate,
-                                              gdouble applied_rate, GstFormat format, gint64 start,
-                                              gint64 stop, gint64 time);
+gboolean     gst_segment_clip                (const GstSegment *segment, GstFormat format, guint64 start,
+                                              guint64 stop, guint64 *clip_start, guint64 *clip_stop);
 
-gint64       gst_segment_to_stream_time      (GstSegment *segment, GstFormat format, gint64 position);
-gint64       gst_segment_to_running_time     (GstSegment *segment, GstFormat format, gint64 position);
-gint64       gst_segment_to_position         (GstSegment *segment, GstFormat format, gint64 running_time);
-
-gboolean     gst_segment_clip                (GstSegment *segment, GstFormat format, gint64 start,
-                                              gint64 stop, gint64 *clip_start, gint64 *clip_stop);
-
-gboolean     gst_segment_set_running_time    (GstSegment *segment, GstFormat format, gint64 running_time);
 
+gboolean     gst_segment_do_seek             (GstSegment * segment, gdouble rate,
+                                              GstFormat format, GstSeekFlags flags,
+                                              GstSeekType start_type, guint64 start,
+                                              GstSeekType stop_type, guint64 stop, gboolean * update);
 
 G_END_DECLS
 
index 3b2c2e4..9f66bc9 100644 (file)
@@ -74,12 +74,25 @@ struct _GstStructureField
   GValue value;
 };
 
+typedef struct
+{
+  GstStructure s;
+
+  /* owned by parent structure, NULL if no parent */
+  gint *parent_refcount;
+
+  GArray *fields;
+} GstStructureImpl;
+
+#define GST_STRUCTURE_REFCOUNT(s) (((GstStructureImpl*)(s))->parent_refcount)
+#define GST_STRUCTURE_FIELDS(s) (((GstStructureImpl*)(s))->fields)
+
 #define GST_STRUCTURE_FIELD(structure, index) \
-    &g_array_index((structure)->fields, GstStructureField, (index))
+    &g_array_index(GST_STRUCTURE_FIELDS(structure), GstStructureField, (index))
 
 #define IS_MUTABLE(structure) \
-    (!(structure)->parent_refcount || \
-     g_atomic_int_get ((structure)->parent_refcount) == 1)
+    (!GST_STRUCTURE_REFCOUNT(structure) || \
+     g_atomic_int_get (GST_STRUCTURE_REFCOUNT(structure)) == 1)
 
 #define IS_TAGLIST(structure) \
     (structure->name == GST_QUARK (TAGLIST))
@@ -98,36 +111,32 @@ static gboolean gst_structure_parse_value (gchar * str, gchar ** after,
     GValue * value, GType default_type);
 static gboolean gst_structure_parse_simple_string (gchar * s, gchar ** end);
 
-GType
-gst_structure_get_type (void)
-{
-  static GType gst_structure_type = 0;
-
-  if (G_UNLIKELY (gst_structure_type == 0)) {
-    gst_structure_type = g_boxed_type_register_static ("GstStructure",
-        (GBoxedCopyFunc) gst_structure_copy_conditional,
-        (GBoxedFreeFunc) gst_structure_free);
+GType _gst_structure_type = 0;
 
-    g_value_register_transform_func (gst_structure_type, G_TYPE_STRING,
-        gst_structure_transform_to_string);
-  }
+void
+_gst_structure_initialize (void)
+{
+  _gst_structure_type = g_boxed_type_register_static ("GstStructure",
+      (GBoxedCopyFunc) gst_structure_copy_conditional,
+      (GBoxedFreeFunc) gst_structure_free);
 
-  return gst_structure_type;
+  g_value_register_transform_func (_gst_structure_type, G_TYPE_STRING,
+      gst_structure_transform_to_string);
 }
 
 static GstStructure *
 gst_structure_id_empty_new_with_size (GQuark quark, guint prealloc)
 {
-  GstStructure *structure;
+  GstStructureImpl *structure;
 
-  structure = g_slice_new (GstStructure);
-  structure->type = gst_structure_get_type ();
-  structure->name = quark;
-  structure->parent_refcount = NULL;
-  structure->fields =
+  structure = g_slice_new (GstStructureImpl);
+  ((GstStructure *) structure)->type = _gst_structure_type;
+  ((GstStructure *) structure)->name = quark;
+  GST_STRUCTURE_REFCOUNT (structure) = NULL;
+  GST_STRUCTURE_FIELDS (structure) =
       g_array_sized_new (FALSE, FALSE, sizeof (GstStructureField), prealloc);
 
-  return structure;
+  return GST_STRUCTURE_CAST (structure);
 }
 
 /**
@@ -156,17 +165,15 @@ gst_structure_validate_name (const gchar * name)
 
   g_return_val_if_fail (name != NULL, FALSE);
 
-  /* FIXME 0.11: use g_ascii_isalpha() */
-  if (G_UNLIKELY (!g_ascii_isalnum (*name))) {
+  if (G_UNLIKELY (!g_ascii_isalpha (*name))) {
     GST_WARNING ("Invalid character '%c' at offset 0 in structure name: %s",
         *name, name);
     return FALSE;
   }
 
-  /* FIXME 0.11: don't allow spaces */
   /* FIXME: test name string more */
   s = &name[1];
-  while (*s && (g_ascii_isalnum (*s) || strchr ("/-_.:+ ", *s) != NULL))
+  while (*s && (g_ascii_isalnum (*s) || strchr ("/-_.:+", *s) != NULL))
     s++;
   if (G_UNLIKELY (*s != '\0')) {
     GST_WARNING ("Invalid character '%c' at offset %lu in structure name: %s",
@@ -265,20 +272,31 @@ gst_structure_new_valist (const gchar * name,
  * determine whether a structure is mutable or not. This function should only be
  * called by code implementing parent objects of #GstStructure, as described in
  * the MT Refcounting section of the design documents.
+ *
+ * Returns: %TRUE if the parent refcount could be set.
  */
-void
+gboolean
 gst_structure_set_parent_refcount (GstStructure * structure, gint * refcount)
 {
-  g_return_if_fail (structure != NULL);
+  g_return_val_if_fail (structure != NULL, FALSE);
 
   /* if we have a parent_refcount already, we can only clear
    * if with a NULL refcount */
-  if (structure->parent_refcount)
-    g_return_if_fail (refcount == NULL);
-  else
-    g_return_if_fail (refcount != NULL);
+  if (GST_STRUCTURE_REFCOUNT (structure)) {
+    if (refcount != NULL) {
+      g_return_val_if_fail (refcount == NULL, FALSE);
+      return FALSE;
+    }
+  } else {
+    if (refcount == NULL) {
+      g_return_val_if_fail (refcount != NULL, FALSE);
+      return FALSE;
+    }
+  }
+
+  GST_STRUCTURE_REFCOUNT (structure) = refcount;
 
-  structure->parent_refcount = refcount;
+  return TRUE;
 }
 
 /**
@@ -300,7 +318,7 @@ gst_structure_copy (const GstStructure * structure)
 
   g_return_val_if_fail (structure != NULL, NULL);
 
-  len = structure->fields->len;
+  len = GST_STRUCTURE_FIELDS (structure)->len;
   new_structure = gst_structure_id_empty_new_with_size (structure->name, len);
 
   for (i = 0; i < len; i++) {
@@ -310,7 +328,7 @@ gst_structure_copy (const GstStructure * structure)
 
     new_field.name = field->name;
     gst_value_init_and_copy (&new_field.value, &field->value);
-    g_array_append_val (new_structure->fields, new_field);
+    g_array_append_val (GST_STRUCTURE_FIELDS (new_structure), new_field);
   }
 
   return new_structure;
@@ -330,9 +348,9 @@ gst_structure_free (GstStructure * structure)
   guint i, len;
 
   g_return_if_fail (structure != NULL);
-  g_return_if_fail (structure->parent_refcount == NULL);
+  g_return_if_fail (GST_STRUCTURE_REFCOUNT (structure) == NULL);
 
-  len = structure->fields->len;
+  len = GST_STRUCTURE_FIELDS (structure)->len;
   for (i = 0; i < len; i++) {
     field = GST_STRUCTURE_FIELD (structure, i);
 
@@ -340,11 +358,11 @@ gst_structure_free (GstStructure * structure)
       g_value_unset (&field->value);
     }
   }
-  g_array_free (structure->fields, TRUE);
+  g_array_free (GST_STRUCTURE_FIELDS (structure), TRUE);
 #ifdef USE_POISONING
   memset (structure, 0xff, sizeof (GstStructure));
 #endif
-  g_slice_free (GstStructure, structure);
+  g_slice_free1 (sizeof (GstStructureImpl), structure);
 }
 
 /**
@@ -748,7 +766,7 @@ static void
 gst_structure_set_field (GstStructure * structure, GstStructureField * field)
 {
   GstStructureField *f;
-  guint i, len = structure->fields->len;
+  guint i, len = GST_STRUCTURE_FIELDS (structure)->len;
 
   if (G_UNLIKELY (G_VALUE_HOLDS_STRING (&field->value))) {
     const gchar *s;
@@ -808,7 +826,7 @@ gst_structure_set_field (GstStructure * structure, GstStructureField * field)
     }
   }
 
-  g_array_append_val (structure->fields, *field);
+  g_array_append_val (GST_STRUCTURE_FIELDS (structure), *field);
 }
 
 /* If there is no field with the given ID, NULL is returned.
@@ -819,7 +837,7 @@ gst_structure_id_get_field (const GstStructure * structure, GQuark field_id)
   GstStructureField *field;
   guint i, len;
 
-  len = structure->fields->len;
+  len = GST_STRUCTURE_FIELDS (structure)->len;
 
   for (i = 0; i < len; i++) {
     field = GST_STRUCTURE_FIELD (structure, i);
@@ -913,7 +931,7 @@ gst_structure_remove_field (GstStructure * structure, const gchar * fieldname)
   g_return_if_fail (IS_MUTABLE (structure));
 
   id = g_quark_from_string (fieldname);
-  len = structure->fields->len;
+  len = GST_STRUCTURE_FIELDS (structure)->len;
 
   for (i = 0; i < len; i++) {
     field = GST_STRUCTURE_FIELD (structure, i);
@@ -922,7 +940,8 @@ gst_structure_remove_field (GstStructure * structure, const gchar * fieldname)
       if (G_IS_VALUE (&field->value)) {
         g_value_unset (&field->value);
       }
-      structure->fields = g_array_remove_index (structure->fields, i);
+      GST_STRUCTURE_FIELDS (structure) =
+          g_array_remove_index (GST_STRUCTURE_FIELDS (structure), i);
       return;
     }
   }
@@ -991,13 +1010,14 @@ gst_structure_remove_all_fields (GstStructure * structure)
   g_return_if_fail (structure != NULL);
   g_return_if_fail (IS_MUTABLE (structure));
 
-  for (i = structure->fields->len - 1; i >= 0; i--) {
+  for (i = GST_STRUCTURE_FIELDS (structure)->len - 1; i >= 0; i--) {
     field = GST_STRUCTURE_FIELD (structure, i);
 
     if (G_IS_VALUE (&field->value)) {
       g_value_unset (&field->value);
     }
-    structure->fields = g_array_remove_index (structure->fields, i);
+    GST_STRUCTURE_FIELDS (structure) =
+        g_array_remove_index (GST_STRUCTURE_FIELDS (structure), i);
   }
 }
 
@@ -1041,7 +1061,7 @@ gst_structure_n_fields (const GstStructure * structure)
 {
   g_return_val_if_fail (structure != NULL, 0);
 
-  return structure->fields->len;
+  return GST_STRUCTURE_FIELDS (structure)->len;
 }
 
 /**
@@ -1059,7 +1079,7 @@ gst_structure_nth_field_name (const GstStructure * structure, guint index)
   GstStructureField *field;
 
   g_return_val_if_fail (structure != NULL, NULL);
-  g_return_val_if_fail (index < structure->fields->len, NULL);
+  g_return_val_if_fail (index < GST_STRUCTURE_FIELDS (structure)->len, NULL);
 
   field = GST_STRUCTURE_FIELD (structure, index);
 
@@ -1089,7 +1109,7 @@ gst_structure_foreach (const GstStructure * structure,
   g_return_val_if_fail (structure != NULL, FALSE);
   g_return_val_if_fail (func != NULL, FALSE);
 
-  len = structure->fields->len;
+  len = GST_STRUCTURE_FIELDS (structure)->len;
 
   for (i = 0; i < len; i++) {
     field = GST_STRUCTURE_FIELD (structure, i);
@@ -1126,7 +1146,7 @@ gst_structure_map_in_place (GstStructure * structure,
   g_return_val_if_fail (structure != NULL, FALSE);
   g_return_val_if_fail (IS_MUTABLE (structure), FALSE);
   g_return_val_if_fail (func != NULL, FALSE);
-  len = structure->fields->len;
+  len = GST_STRUCTURE_FIELDS (structure)->len;
 
   for (i = 0; i < len; i++) {
     field = GST_STRUCTURE_FIELD (structure, i);
@@ -1799,7 +1819,7 @@ priv_gst_structure_append_to_gstring (const GstStructure * structure,
   g_return_val_if_fail (s != NULL, FALSE);
 
   g_string_append (s, g_quark_to_string (structure->name));
-  len = structure->fields->len;
+  len = GST_STRUCTURE_FIELDS (structure)->len;
   for (i = 0; i < len; i++) {
     char *t;
     GType type;
@@ -2949,7 +2969,8 @@ gst_structure_is_equal (const GstStructure * structure1,
   if (structure1->name != structure2->name) {
     return FALSE;
   }
-  if (structure1->fields->len != structure2->fields->len) {
+  if (GST_STRUCTURE_FIELDS (structure1)->len !=
+      GST_STRUCTURE_FIELDS (structure2)->len) {
     return FALSE;
   }
 
index 6e020fc..e96799e 100644 (file)
 
 G_BEGIN_DECLS
 
-#define GST_TYPE_STRUCTURE             (gst_structure_get_type ())
-#define GST_STRUCTURE(object)          ((GstStructure *)(object))
-#define GST_IS_STRUCTURE(object)       ((object) && (GST_STRUCTURE(object)->type == GST_TYPE_STRUCTURE))
+extern GType _gst_structure_type;
 
 typedef struct _GstStructure GstStructure;
 
+#define GST_TYPE_STRUCTURE             (_gst_structure_type)
+#define GST_IS_STRUCTURE(object)       ((object) && (GST_STRUCTURE(object)->type == GST_TYPE_STRUCTURE))
+#define GST_STRUCTURE_CAST(object)     ((GstStructure *)(object))
+#define GST_STRUCTURE(object)          (GST_STRUCTURE_CAST(object))
+
+
 /**
  * GstStructureForeachFunc:
  * @field_id: the #GQuark of the field name
@@ -77,17 +81,8 @@ struct _GstStructure {
 
   /*< private >*/
   GQuark name;
-
-  /* owned by parent structure, NULL if no parent */
-  gint *parent_refcount;
-
-  GArray *fields;
-
-  gpointer _gst_reserved;
 };
 
-GType                   gst_structure_get_type             (void);
-
 GstStructure *          gst_structure_empty_new            (const gchar *            name);
 GstStructure *          gst_structure_id_empty_new         (GQuark                   quark);
 GstStructure *          gst_structure_new                  (const gchar *            name,
@@ -100,8 +95,8 @@ GstStructure *          gst_structure_id_new               (GQuark
                                                             GQuark                   field_quark,
                                                             ...);
 GstStructure *          gst_structure_copy                 (const GstStructure      *structure);
-void                   gst_structure_set_parent_refcount  (GstStructure            *structure,
-                                                            gint            *refcount);
+gboolean               gst_structure_set_parent_refcount  (GstStructure            *structure,
+                                                            gint                    *refcount);
 void                    gst_structure_free                 (GstStructure            *structure);
 
 const gchar *          gst_structure_get_name             (const GstStructure      *structure);
index 938704e..893e072 100644 (file)
@@ -154,7 +154,7 @@ gst_system_clock_class_init (GstSystemClockClass * klass)
 
   gstclock_class->get_internal_time = gst_system_clock_get_internal_time;
   gstclock_class->get_resolution = gst_system_clock_get_resolution;
-  gstclock_class->wait_jitter = gst_system_clock_id_wait_jitter;
+  gstclock_class->wait = gst_system_clock_id_wait_jitter;
   gstclock_class->wait_async = gst_system_clock_id_wait_async;
   gstclock_class->unschedule = gst_system_clock_id_unschedule;
 }
index 4f372de..490f700 100644 (file)
@@ -70,7 +70,7 @@ struct _GstSystemClock {
   /* ABI added */
   GstSystemClockPrivate *priv;
 
-  gpointer _gst_reserved[GST_PADDING - 1];
+  gpointer _gst_reserved[GST_PADDING];
 };
 
 struct _GstSystemClockClass {
index 385e3b0..29c8ee8 100644 (file)
@@ -1844,7 +1844,7 @@ gst_tag_list_get_buffer (const GstTagList * list, const gchar * tag,
 
   if (!gst_tag_list_copy_value (&v, list, tag))
     return FALSE;
-  *value = (GstBuffer *) gst_value_dup_mini_object (&v);
+  *value = g_value_dup_boxed (&v);
   g_value_unset (&v);
   return (*value != NULL);
 }
@@ -1880,6 +1880,6 @@ gst_tag_list_get_buffer_index (const GstTagList * list,
 
   if ((v = gst_tag_list_get_value_index (list, tag, index)) == NULL)
     return FALSE;
-  *value = (GstBuffer *) gst_value_dup_mini_object (v);
+  *value = g_value_dup_boxed (v);
   return (*value != NULL);
 }
index 5f15e41..d08d7e8 100644 (file)
@@ -412,7 +412,7 @@ gst_tag_setter_get_tag_merge_mode (GstTagSetter * setter)
   GstTagMergeMode mode;
   GstTagData *data;
 
-  g_return_val_if_fail (GST_IS_TAG_SETTER (setter), FALSE);
+  g_return_val_if_fail (GST_IS_TAG_SETTER (setter), GST_TAG_MERGE_UNDEFINED);
 
   data = gst_tag_setter_get_data (setter);
 
index 5acbc85..fba8c38 100644 (file)
@@ -185,7 +185,7 @@ gst_task_init (GstTask * task)
 
   task->priv = GST_TASK_GET_PRIVATE (task);
   task->running = FALSE;
-  task->abidata.ABI.thread = NULL;
+  task->thread = NULL;
   task->lock = NULL;
   task->cond = g_cond_new ();
   SET_TASK_STATE (task, GST_TASK_STOPPED);
@@ -274,7 +274,7 @@ gst_task_func (GstTask * task)
   lock = GST_TASK_GET_LOCK (task);
   if (G_UNLIKELY (lock == NULL))
     goto no_lock;
-  task->abidata.ABI.thread = tself;
+  task->thread = tself;
   /* only update the priority when it was changed */
   if (priv->prio_set)
     g_thread_set_priority (tself, priv->priority);
@@ -321,7 +321,7 @@ done:
   g_static_rec_mutex_unlock (lock);
 
   GST_OBJECT_LOCK (task);
-  task->abidata.ABI.thread = NULL;
+  task->thread = NULL;
 
 exit:
   if (priv->thr_callbacks.leave_thread) {
@@ -471,7 +471,7 @@ gst_task_set_priority (GstTask * task, GThreadPriority priority)
   GST_OBJECT_LOCK (task);
   priv->prio_set = TRUE;
   priv->priority = priority;
-  thread = task->abidata.ABI.thread;
+  thread = task->thread;
   if (thread != NULL) {
     /* if this task already has a thread, we can configure the priority right
      * away, else we do that when we assign a thread to the task. */
@@ -812,7 +812,7 @@ gst_task_join (GstTask * task)
   /* we don't use a real thread join here because we are using
    * thread pools */
   GST_OBJECT_LOCK (task);
-  if (G_UNLIKELY (tself == task->abidata.ABI.thread))
+  if (G_UNLIKELY (tself == task->thread))
     goto joining_self;
   SET_TASK_STATE (task, GST_TASK_STOPPED);
   /* signal the state change for when it was blocked in PAUSED. */
@@ -823,7 +823,7 @@ gst_task_join (GstTask * task)
   while (G_LIKELY (task->running))
     GST_TASK_WAIT (task);
   /* clean the thread */
-  task->abidata.ABI.thread = NULL;
+  task->thread = NULL;
   /* get the id and pool to join */
   pool = priv->pool_id;
   id = priv->id;
index 2081815..21784b7 100644 (file)
@@ -154,15 +154,11 @@ struct _GstTask {
   gboolean         running;
 
   /*< private >*/
-  union {
-    struct {
-      /* thread this task is currently running in */
-      GThread  *thread;
-    } ABI;
-    gpointer _gst_reserved[GST_PADDING - 1];
-  } abidata;
-
-  GstTaskPrivate *priv;
+  GThread         *thread;
+
+  GstTaskPrivate  *priv;
+
+  gpointer _gst_reserved[GST_PADDING];
 };
 
 struct _GstTaskClass {
index 3827265..1f0b16d 100644 (file)
@@ -131,7 +131,7 @@ gst_type_find_register (GstPlugin * plugin, const gchar * name, guint rank,
  * Returns: (transfer none) (array length=size): the requested data, or NULL
  *     if that data is not available.
  */
-guint8 *
+const guint8 *
 gst_type_find_peek (GstTypeFind * find, gint64 offset, guint size)
 {
   g_return_val_if_fail (find->peek != NULL, NULL);
index 6e1f049..036148c 100644 (file)
@@ -72,18 +72,18 @@ typedef enum {
  */
 struct _GstTypeFind {
   /* private to the caller of the typefind function */
-  guint8 *  (* peek)       (gpointer         data,
-                            gint64           offset,
-                            guint            size);
+  const guint8 *  (* peek)       (gpointer         data,
+                                  gint64           offset,
+                                  guint            size);
 
-  void      (* suggest)    (gpointer         data,
-                            guint            probability,
-                            const GstCaps *  caps);
+  void            (* suggest)    (gpointer         data,
+                                  guint            probability,
+                                  const GstCaps *  caps);
 
-  gpointer     data;
+  gpointer         data;
 
   /* optional */
-  guint64   (* get_length) (gpointer data);
+  guint64         (* get_length) (gpointer data);
 
   /* <private> */
   gpointer _gst_reserved[GST_PADDING];
@@ -92,18 +92,18 @@ struct _GstTypeFind {
 GType     gst_type_find_get_type   (void);
 
 /* typefind function interface */
-guint8 *  gst_type_find_peek       (GstTypeFind   * find,
-                                    gint64          offset,
-                                    guint           size);
-
-void      gst_type_find_suggest    (GstTypeFind   * find,
-                                    guint           probability,
-                                    const GstCaps * caps);
-
-void      gst_type_find_suggest_simple (GstTypeFind * find,
-                                        guint         probability,
-                                        const char  * media_type,
-                                        const char  * fieldname, ...);
+const guint8 *  gst_type_find_peek       (GstTypeFind   * find,
+                                          gint64          offset,
+                                          guint           size);
+
+void            gst_type_find_suggest    (GstTypeFind   * find,
+                                          guint           probability,
+                                          const GstCaps * caps);
+
+void            gst_type_find_suggest_simple (GstTypeFind * find,
+                                              guint         probability,
+                                              const char  * media_type,
+                                              const char  * fieldname, ...);
 
 guint64   gst_type_find_get_length (GstTypeFind   * find);
 
index 0d05582..f8aceac 100644 (file)
@@ -25,7 +25,6 @@
  * SECTION:gstutils
  * @short_description: Various utility functions
  *
- * When defining own plugins, use the GST_BOILERPLATE ease gobject creation.
  */
 
 #include "gst_private.h"
@@ -759,7 +758,7 @@ gst_print_pad_caps (GString * buf, gint indent, GstPad * pad)
 {
   GstCaps *caps;
 
-  caps = pad->caps;
+  caps = gst_pad_get_current_caps (pad);
 
   if (!caps) {
     string_append_indent (buf, indent);
@@ -771,6 +770,8 @@ gst_print_pad_caps (GString * buf, gint indent, GstPad * pad)
     s = gst_caps_to_string (caps);
     g_string_append (buf, s);
     g_free (s);
+
+    gst_caps_unref (caps);
   }
 }
 
@@ -1089,6 +1090,7 @@ gst_element_get_compatible_pad (GstElement * element, GstPad * pad,
   GstCaps *templcaps;
   GstPad *foundpad = NULL;
   gboolean done;
+  GValue padptr = { 0, };
 
   g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
   g_return_val_if_fail (GST_IS_PAD (pad), NULL);
@@ -1111,8 +1113,6 @@ gst_element_get_compatible_pad (GstElement * element, GstPad * pad,
   }
 
   while (!done) {
-    gpointer padptr;
-
     switch (gst_iterator_next (pads, &padptr)) {
       case GST_ITERATOR_OK:
       {
@@ -1121,7 +1121,7 @@ gst_element_get_compatible_pad (GstElement * element, GstPad * pad,
         GstPad *srcpad;
         GstPad *sinkpad;
 
-        current = GST_PAD (padptr);
+        current = g_value_get_object (&padptr);
 
         GST_CAT_LOG (GST_CAT_ELEMENT_PADS, "examining pad %s:%s",
             GST_DEBUG_PAD_NAME (current));
@@ -1140,7 +1140,7 @@ gst_element_get_compatible_pad (GstElement * element, GstPad * pad,
           gboolean compatible;
 
           /* Now check if the two pads' caps are compatible */
-          temp = gst_pad_get_caps_reffed (pad);
+          temp = gst_pad_get_caps (pad, NULL);
           if (caps) {
             intersection = gst_caps_intersect (temp, caps);
             gst_caps_unref (temp);
@@ -1148,7 +1148,7 @@ gst_element_get_compatible_pad (GstElement * element, GstPad * pad,
             intersection = temp;
           }
 
-          temp = gst_pad_get_caps_reffed (current);
+          temp = gst_pad_get_caps (current, NULL);
           compatible = gst_caps_can_intersect (temp, intersection);
           gst_caps_unref (temp);
           gst_caps_unref (intersection);
@@ -1159,6 +1159,9 @@ gst_element_get_compatible_pad (GstElement * element, GstPad * pad,
                 GST_DEBUG_PAD_NAME (current));
             gst_iterator_free (pads);
 
+            current = gst_object_ref (current);
+            g_value_unset (&padptr);
+
             return current;
           } else {
             GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "incompatible pads");
@@ -1169,7 +1172,7 @@ gst_element_get_compatible_pad (GstElement * element, GstPad * pad,
         }
         GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "unreffing pads");
 
-        gst_object_unref (current);
+        g_value_reset (&padptr);
         if (peer)
           gst_object_unref (peer);
         break;
@@ -1185,6 +1188,7 @@ gst_element_get_compatible_pad (GstElement * element, GstPad * pad,
         break;
     }
   }
+  g_value_unset (&padptr);
   gst_iterator_free (pads);
 
   GST_CAT_DEBUG_OBJECT (GST_CAT_ELEMENT_PADS, element,
@@ -1194,10 +1198,10 @@ gst_element_get_compatible_pad (GstElement * element, GstPad * 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_reffed (pad);
-
+  templcaps = gst_pad_get_caps (pad, NULL);
   templ = gst_pad_template_new ((gchar *) GST_PAD_NAME (pad),
       GST_PAD_DIRECTION (pad), GST_PAD_ALWAYS, templcaps);
+  gst_caps_unref (templcaps);
 
   foundpad = gst_element_request_compatible_pad (element, templ);
   gst_object_unref (templ);
@@ -1331,56 +1335,6 @@ gst_element_factory_can_accept_any_caps_in_direction (GstElementFactory *
 }
 
 /**
- * gst_element_factory_can_src_caps:
- * @factory: factory to query
- * @caps: the caps to check
- *
- * Checks if the factory can source the given capability.
- *
- * Returns: %TRUE if it can src the capabilities
- *
- * Deprecated: use gst_element_factory_can_src_all_caps() instead.
- */
-#ifndef GST_REMOVE_DEPRECATED
-#ifdef GST_DISABLE_DEPRECATED
-gboolean gst_element_factory_can_src_caps (GstElementFactory * factory,
-    const GstCaps * caps);
-#endif
-gboolean
-gst_element_factory_can_src_caps (GstElementFactory * factory,
-    const GstCaps * caps)
-{
-  return gst_element_factory_can_accept_all_caps_in_direction (factory, caps,
-      GST_PAD_SRC);
-}
-#endif /* GST_REMOVE_DEPRECATED */
-
-/**
- * gst_element_factory_can_sink_caps:
- * @factory: factory to query
- * @caps: the caps to check
- *
- * Checks if the factory can sink the given capability.
- *
- * Returns: %TRUE if it can sink the capabilities
- *
- * Deprecated: use gst_element_factory_can_sink_all_caps() instead.
- */
-#ifndef GST_REMOVE_DEPRECATED
-#ifdef GST_DISABLE_DEPRECATED
-gboolean gst_element_factory_can_sink_caps (GstElementFactory * factory,
-    const GstCaps * caps);
-#endif
-gboolean
-gst_element_factory_can_sink_caps (GstElementFactory * factory,
-    const GstCaps * caps)
-{
-  return gst_element_factory_can_accept_all_caps_in_direction (factory, caps,
-      GST_PAD_SINK);
-}
-#endif /* GST_REMOVE_DEPRECATED */
-
-/**
  * gst_element_factory_can_sink_all_caps:
  * @factory: factory to query
  * @caps: the caps to check
@@ -1890,8 +1844,11 @@ gst_element_link_pads_full (GstElement * src, const gchar * srcpadname,
           desttempl = (GstPadTemplate *) l->data;
           if (desttempl->presence == GST_PAD_REQUEST &&
               desttempl->direction != srctempl->direction) {
-            if (gst_caps_is_always_compatible (gst_pad_template_get_caps
-                    (srctempl), gst_pad_template_get_caps (desttempl))) {
+            GstCaps *srccaps, *destcaps;
+
+            srccaps = gst_pad_template_get_caps (srctempl);
+            destcaps = gst_pad_template_get_caps (desttempl);
+            if (gst_caps_is_always_compatible (srccaps, destcaps)) {
               srcpad =
                   gst_element_request_pad (src, srctempl,
                   srctempl->name_template, NULL);
@@ -1905,6 +1862,8 @@ gst_element_link_pads_full (GstElement * src, const gchar * srcpadname,
                     GST_DEBUG_PAD_NAME (srcpad), GST_DEBUG_PAD_NAME (destpad));
                 gst_object_unref (srcpad);
                 gst_object_unref (destpad);
+                gst_caps_unref (srccaps);
+                gst_caps_unref (destcaps);
                 return TRUE;
               }
               /* it failed, so we release the request pads */
@@ -1913,6 +1872,8 @@ gst_element_link_pads_full (GstElement * src, const gchar * srcpadname,
               if (destpad)
                 gst_element_release_request_pad (dest, destpad);
             }
+            gst_caps_unref (srccaps);
+            gst_caps_unref (destcaps);
           }
         }
       }
@@ -2223,6 +2184,7 @@ gst_element_unlink (GstElement * src, GstElement * dest)
 {
   GstIterator *pads;
   gboolean done = FALSE;
+  GValue data = { 0, };
 
   g_return_if_fail (GST_IS_ELEMENT (src));
   g_return_if_fail (GST_IS_ELEMENT (dest));
@@ -2232,12 +2194,10 @@ gst_element_unlink (GstElement * src, GstElement * dest)
 
   pads = gst_element_iterate_pads (src);
   while (!done) {
-    gpointer data;
-
     switch (gst_iterator_next (pads, &data)) {
       case GST_ITERATOR_OK:
       {
-        GstPad *pad = GST_PAD_CAST (data);
+        GstPad *pad = g_value_get_object (&data);
 
         if (GST_PAD_IS_SRC (pad)) {
           GstPad *peerpad = gst_pad_get_peer (pad);
@@ -2257,7 +2217,7 @@ gst_element_unlink (GstElement * src, GstElement * dest)
             gst_object_unref (peerpad);
           }
         }
-        gst_object_unref (pad);
+        g_value_reset (&data);
         break;
       }
       case GST_ITERATOR_RESYNC:
@@ -2271,6 +2231,7 @@ gst_element_unlink (GstElement * src, GstElement * dest)
         break;
     }
   }
+  g_value_unset (&data);
   gst_iterator_free (pads);
 }
 
@@ -2425,9 +2386,8 @@ gst_element_seek_simple (GstElement * element, GstFormat format,
  * gst_pad_use_fixed_caps:
  * @pad: the pad to use
  *
- * A helper function you can use that sets the
- * @gst_pad_get_fixed_caps_func as the getcaps function for the
- * pad. This way the function will always return the negotiated caps
+ * A helper function you can use that sets the FIXED_CAPS flag
+ * This way the default getcaps function will always return the negotiated caps
  * or in case the pad is not negotiated, the padtemplate caps.
  *
  * Use this function on a pad that, once gst_pad_set_caps() has been called
@@ -2436,52 +2396,7 @@ gst_element_seek_simple (GstElement * element, GstFormat format,
 void
 gst_pad_use_fixed_caps (GstPad * pad)
 {
-  gst_pad_set_getcaps_function (pad, gst_pad_get_fixed_caps_func);
-}
-
-/**
- * gst_pad_get_fixed_caps_func:
- * @pad: the pad to use
- *
- * A helper function you can use as a GetCaps function that
- * will return the currently negotiated caps or the padtemplate
- * when NULL.
- *
- * Free-function: gst_caps_unref
- *
- * Returns: (transfer full): the currently negotiated caps or the padtemplate.
- */
-GstCaps *
-gst_pad_get_fixed_caps_func (GstPad * pad)
-{
-  GstCaps *result;
-
-  g_return_val_if_fail (GST_IS_PAD (pad), NULL);
-
-  GST_OBJECT_LOCK (pad);
-  if (GST_PAD_CAPS (pad)) {
-    result = GST_PAD_CAPS (pad);
-
-    GST_CAT_DEBUG (GST_CAT_CAPS,
-        "using pad caps %p %" GST_PTR_FORMAT, result, result);
-
-    result = gst_caps_ref (result);
-  } else if (GST_PAD_PAD_TEMPLATE (pad)) {
-    GstPadTemplate *templ = GST_PAD_PAD_TEMPLATE (pad);
-
-    result = GST_PAD_TEMPLATE_CAPS (templ);
-    GST_CAT_DEBUG (GST_CAT_CAPS,
-        "using pad template %p with caps %p %" GST_PTR_FORMAT, templ, result,
-        result);
-
-    result = gst_caps_ref (result);
-  } else {
-    GST_CAT_DEBUG (GST_CAT_CAPS, "pad has no caps");
-    result = gst_caps_new_empty ();
-  }
-  GST_OBJECT_UNLOCK (pad);
-
-  return result;
+  GST_OBJECT_FLAG_SET (pad, GST_PAD_FIXED_CAPS);
 }
 
 /**
@@ -2518,7 +2433,8 @@ gst_pad_get_parent_element (GstPad * pad)
  * @error: (in): the GError.
  * @debug: (in) (allow-none): an additional debug information string, or NULL
  *
- * A default error function.
+ * A default error function that uses g_printerr() to display the error message
+ * and the optional debug sting..
  *
  * The default handler will simply print the error string using g_print.
  */
@@ -2528,10 +2444,9 @@ gst_object_default_error (GstObject * source, const GError * error,
 {
   gchar *name = gst_object_get_path_string (source);
 
-  /* FIXME 0.11: should change this to g_printerr() */
-  g_print (_("ERROR: from element %s: %s\n"), name, error->message);
+  g_printerr (_("ERROR: from element %s: %s\n"), name, error->message);
   if (debug)
-    g_print (_("Additional debug info:\n%s\n"), debug);
+    g_printerr (_("Additional debug info:\n%s\n"), debug);
 
   g_free (name);
 }
@@ -2737,9 +2652,13 @@ GstBuffer *
 gst_buffer_merge (GstBuffer * buf1, GstBuffer * buf2)
 {
   GstBuffer *result;
+  gsize size1, size2;
+
+  size1 = gst_buffer_get_size (buf1);
+  size2 = gst_buffer_get_size (buf2);
 
   /* we're just a specific case of the more general gst_buffer_span() */
-  result = gst_buffer_span (buf1, 0, buf2, buf1->size + buf2->size);
+  result = gst_buffer_span (buf1, 0, buf2, size1 + size2);
 
   return result;
 }
@@ -2767,48 +2686,27 @@ GstBuffer *
 gst_buffer_join (GstBuffer * buf1, GstBuffer * buf2)
 {
   GstBuffer *result;
+  gsize size1, size2;
 
-  result = gst_buffer_span (buf1, 0, buf2, buf1->size + buf2->size);
+  size1 = gst_buffer_get_size (buf1);
+  size2 = gst_buffer_get_size (buf2);
+
+  result = gst_buffer_span (buf1, 0, buf2, size1 + size2);
   gst_buffer_unref (buf1);
   gst_buffer_unref (buf2);
 
   return result;
 }
 
-
-/**
- * gst_buffer_stamp:
- * @dest: (transfer none): buffer to stamp
- * @src: buffer to stamp from
- *
- * Copies additional information (the timestamp, duration, and offset start
- * and end) from one buffer to the other.
- *
- * This function does not copy any buffer flags or caps and is equivalent to
- * gst_buffer_copy_metadata(@dest, @src, GST_BUFFER_COPY_TIMESTAMPS).
- *
- * Deprecated: use gst_buffer_copy_metadata() instead, it provides more
- * control.
- */
-#ifndef GST_REMOVE_DEPRECATED
-#ifdef GST_DISABLE_DEPRECATED
-void gst_buffer_stamp (GstBuffer * dest, const GstBuffer * src);
-#endif
-void
-gst_buffer_stamp (GstBuffer * dest, const GstBuffer * src)
-{
-  gst_buffer_copy_metadata (dest, src, GST_BUFFER_COPY_TIMESTAMPS);
-}
-#endif /* GST_REMOVE_DEPRECATED */
-
 static gboolean
-getcaps_fold_func (GstPad * pad, GValue * ret, GstPad * orig)
+getcaps_fold_func (const GValue * vpad, GValue * ret, GstCaps * filter)
 {
+  GstPad *pad = g_value_get_object (vpad);
   gboolean empty = FALSE;
   GstCaps *peercaps, *existing;
 
   existing = g_value_get_pointer (ret);
-  peercaps = gst_pad_peer_get_caps_reffed (pad);
+  peercaps = gst_pad_peer_get_caps (pad, filter);
   if (G_LIKELY (peercaps)) {
     GstCaps *intersection = gst_caps_intersect (existing, peercaps);
 
@@ -2818,13 +2716,13 @@ getcaps_fold_func (GstPad * pad, GValue * ret, GstPad * orig)
     gst_caps_unref (existing);
     gst_caps_unref (peercaps);
   }
-  gst_object_unref (pad);
   return !empty;
 }
 
 /**
  * gst_pad_proxy_getcaps:
  * @pad: a #GstPad to proxy.
+ * @filter: a #GstCaps filter.
  *
  * Calls gst_pad_get_allowed_caps() for every other pad belonging to the
  * same element as @pad, and returns the intersection of the results.
@@ -2838,7 +2736,7 @@ getcaps_fold_func (GstPad * pad, GValue * ret, GstPad * orig)
  * Returns: (transfer full): the intersection of the other pads' allowed caps.
  */
 GstCaps *
-gst_pad_proxy_getcaps (GstPad * pad)
+gst_pad_proxy_getcaps (GstPad * pad, GstCaps * filter)
 {
   GstElement *element;
   GstCaps *caps, *intersected;
@@ -2869,7 +2767,7 @@ gst_pad_proxy_getcaps (GstPad * pad)
   while (1) {
     res =
         gst_iterator_fold (iter, (GstIteratorFoldFunction) getcaps_fold_func,
-        &ret, pad);
+        &ret, filter);
     switch (res) {
       case GST_ITERATOR_RESYNC:
         /* unref any value stored */
@@ -2927,105 +2825,6 @@ error:
   }
 }
 
-typedef struct
-{
-  GstPad *orig;
-  GstCaps *caps;
-} SetCapsFoldData;
-
-static gboolean
-setcaps_fold_func (GstPad * pad, GValue * ret, SetCapsFoldData * data)
-{
-  gboolean success = TRUE;
-
-  if (pad != data->orig) {
-    success = gst_pad_set_caps (pad, data->caps);
-    g_value_set_boolean (ret, success);
-  }
-  gst_object_unref (pad);
-
-  return success;
-}
-
-/**
- * gst_pad_proxy_setcaps
- * @pad: a #GstPad to proxy from
- * @caps: (transfer none): the #GstCaps to link with
- *
- * Calls gst_pad_set_caps() for every other pad belonging to the
- * same element as @pad.  If gst_pad_set_caps() fails on any pad,
- * the proxy setcaps fails. May be used only during negotiation.
- *
- * Returns: TRUE if sucessful
- */
-gboolean
-gst_pad_proxy_setcaps (GstPad * pad, GstCaps * caps)
-{
-  GstElement *element;
-  GstIterator *iter;
-  GstIteratorResult res;
-  GValue ret = { 0, };
-  SetCapsFoldData data;
-
-  g_return_val_if_fail (GST_IS_PAD (pad), FALSE);
-  g_return_val_if_fail (caps != NULL, FALSE);
-
-  GST_CAT_DEBUG (GST_CAT_PADS, "proxying pad link for %s:%s",
-      GST_DEBUG_PAD_NAME (pad));
-
-  element = gst_pad_get_parent_element (pad);
-  if (element == NULL)
-    return FALSE;
-
-  /* only iterate the pads in the oposite direction */
-  if (GST_PAD_IS_SRC (pad))
-    iter = gst_element_iterate_sink_pads (element);
-  else
-    iter = gst_element_iterate_src_pads (element);
-
-  g_value_init (&ret, G_TYPE_BOOLEAN);
-  g_value_set_boolean (&ret, TRUE);
-  data.orig = pad;
-  data.caps = caps;
-
-  while (1) {
-    res = gst_iterator_fold (iter, (GstIteratorFoldFunction) setcaps_fold_func,
-        &ret, &data);
-
-    switch (res) {
-      case GST_ITERATOR_RESYNC:
-        /* reset return value */
-        g_value_set_boolean (&ret, TRUE);
-        gst_iterator_resync (iter);
-        break;
-      case GST_ITERATOR_DONE:
-        /* all pads iterated, return collected value */
-        goto done;
-      default:
-        /* iterator returned _ERROR or premature end with _OK,
-         * mark an error and exit */
-        goto error;
-    }
-  }
-done:
-  gst_iterator_free (iter);
-
-  gst_object_unref (element);
-
-  /* ok not to unset the gvalue */
-  return g_value_get_boolean (&ret);
-
-  /* ERRORS */
-error:
-  {
-    g_warning ("Pad list return error on element %s",
-        GST_ELEMENT_NAME (element));
-    gst_iterator_free (iter);
-    gst_object_unref (element);
-    return FALSE;
-  }
-}
-
 /**
  * gst_pad_query_position:
  * @pad: a #GstPad to invoke the position query on.
@@ -3230,312 +3029,6 @@ gst_pad_query_peer_convert (GstPad * pad, GstFormat src_format, gint64 src_val,
 }
 
 /**
- * gst_atomic_int_set:
- * @atomic_int: (inout): pointer to an atomic integer
- * @value: value to set
- *
- * Unconditionally sets the atomic integer to @value.
- *
- * Deprecated: Use g_atomic_int_set().
- *
- */
-#ifndef GST_REMOVE_DEPRECATED
-#ifdef GST_DISABLE_DEPRECATED
-void gst_atomic_int_set (gint * atomic_int, gint value);
-#endif
-void
-gst_atomic_int_set (gint * atomic_int, gint value)
-{
-  g_atomic_int_set (atomic_int, value);
-}
-#endif
-
-/**
- * gst_pad_add_data_probe:
- * @pad: pad to add the data probe handler to
- * @handler: function to call when data is passed over pad
- * @data: (closure): data to pass along with the handler
- *
- * Adds a "data probe" to a pad. This function will be called whenever data
- * passes through a pad. In this case data means both events and buffers. The
- * probe will be called with the data as an argument, meaning @handler should
- * have the same callback signature as the #GstPad::have-data signal.
- * Note that the data will have a reference count greater than 1, so it will
- * be immutable -- you must not change it.
- *
- * For source pads, the probe will be called after the blocking function, if any
- * (see gst_pad_set_blocked_async()), but before looking up the peer to chain
- * to. For sink pads, the probe function will be called before configuring the
- * sink with new caps, if any, and before calling the pad's chain function.
- *
- * Your data probe should return TRUE to let the data continue to flow, or FALSE
- * to drop it. Dropping data is rarely useful, but occasionally comes in handy
- * with events.
- *
- * Although probes are implemented internally by connecting @handler to the
- * have-data signal on the pad, if you want to remove a probe it is insufficient
- * to only call g_signal_handler_disconnect on the returned handler id. To
- * remove a probe, use the appropriate function, such as
- * gst_pad_remove_data_probe().
- *
- * Returns: The handler id.
- */
-gulong
-gst_pad_add_data_probe (GstPad * pad, GCallback handler, gpointer data)
-{
-  return gst_pad_add_data_probe_full (pad, handler, data, NULL);
-}
-
-/**
- * gst_pad_add_data_probe_full:
- * @pad: pad to add the data probe handler to
- * @handler: function to call when data is passed over pad
- * @data: (closure): data to pass along with the handler
- * @notify: (allow-none): function to call when the probe is disconnected,
- *     or NULL
- *
- * Adds a "data probe" to a pad. This function will be called whenever data
- * passes through a pad. In this case data means both events and buffers. The
- * probe will be called with the data as an argument, meaning @handler should
- * have the same callback signature as the #GstPad::have-data signal.
- * Note that the data will have a reference count greater than 1, so it will
- * be immutable -- you must not change it.
- *
- * For source pads, the probe will be called after the blocking function, if any
- * (see gst_pad_set_blocked_async()), but before looking up the peer to chain
- * to. For sink pads, the probe function will be called before configuring the
- * sink with new caps, if any, and before calling the pad's chain function.
- *
- * Your data probe should return TRUE to let the data continue to flow, or FALSE
- * to drop it. Dropping data is rarely useful, but occasionally comes in handy
- * with events.
- *
- * Although probes are implemented internally by connecting @handler to the
- * have-data signal on the pad, if you want to remove a probe it is insufficient
- * to only call g_signal_handler_disconnect on the returned handler id. To
- * remove a probe, use the appropriate function, such as
- * gst_pad_remove_data_probe().
- *
- * The @notify function is called when the probe is disconnected and usually
- * used to free @data.
- *
- * Returns: The handler id.
- *
- * Since: 0.10.20
- */
-gulong
-gst_pad_add_data_probe_full (GstPad * pad, GCallback handler,
-    gpointer data, GDestroyNotify notify)
-{
-  gulong sigid;
-
-  g_return_val_if_fail (GST_IS_PAD (pad), 0);
-  g_return_val_if_fail (handler != NULL, 0);
-
-  GST_OBJECT_LOCK (pad);
-
-  /* we only expose a GDestroyNotify in our API because that's less confusing */
-  sigid = g_signal_connect_data (pad, "have-data", handler, data,
-      (GClosureNotify) notify, 0);
-
-  GST_PAD_DO_EVENT_SIGNALS (pad)++;
-  GST_PAD_DO_BUFFER_SIGNALS (pad)++;
-  GST_CAT_DEBUG_OBJECT (GST_CAT_PADS, pad,
-      "adding data probe, now %d data, %d event probes",
-      GST_PAD_DO_BUFFER_SIGNALS (pad), GST_PAD_DO_EVENT_SIGNALS (pad));
-  _priv_gst_pad_invalidate_cache (pad);
-  GST_OBJECT_UNLOCK (pad);
-
-  return sigid;
-}
-
-/**
- * gst_pad_add_event_probe:
- * @pad: pad to add the event probe handler to
- * @handler: function to call when events are passed over pad
- * @data: (closure): data to pass along with the handler
- *
- * Adds a probe that will be called for all events passing through a pad. See
- * gst_pad_add_data_probe() for more information.
- *
- * Returns: The handler id
- */
-gulong
-gst_pad_add_event_probe (GstPad * pad, GCallback handler, gpointer data)
-{
-  return gst_pad_add_event_probe_full (pad, handler, data, NULL);
-}
-
-/**
- * gst_pad_add_event_probe_full:
- * @pad: pad to add the event probe handler to
- * @handler: function to call when events are passed over pad
- * @data: (closure): data to pass along with the handler, or NULL
- * @notify: (allow-none): function to call when probe is disconnected, or NULL
- *
- * Adds a probe that will be called for all events passing through a pad. See
- * gst_pad_add_data_probe() for more information.
- *
- * The @notify function is called when the probe is disconnected and usually
- * used to free @data.
- *
- * Returns: The handler id
- *
- * Since: 0.10.20
- */
-gulong
-gst_pad_add_event_probe_full (GstPad * pad, GCallback handler,
-    gpointer data, GDestroyNotify notify)
-{
-  gulong sigid;
-
-  g_return_val_if_fail (GST_IS_PAD (pad), 0);
-  g_return_val_if_fail (handler != NULL, 0);
-
-  GST_OBJECT_LOCK (pad);
-
-  /* we only expose a GDestroyNotify in our API because that's less confusing */
-  sigid = g_signal_connect_data (pad, "have-data::event", handler, data,
-      (GClosureNotify) notify, 0);
-
-  GST_PAD_DO_EVENT_SIGNALS (pad)++;
-  GST_CAT_DEBUG_OBJECT (GST_CAT_PADS, pad, "adding event probe, now %d probes",
-      GST_PAD_DO_EVENT_SIGNALS (pad));
-  _priv_gst_pad_invalidate_cache (pad);
-  GST_OBJECT_UNLOCK (pad);
-
-  return sigid;
-}
-
-/**
- * gst_pad_add_buffer_probe:
- * @pad: pad to add the buffer probe handler to
- * @handler: function to call when buffers are passed over pad
- * @data: (closure): data to pass along with the handler
- *
- * Adds a probe that will be called for all buffers passing through a pad. See
- * gst_pad_add_data_probe() for more information.
- *
- * Returns: The handler id
- */
-gulong
-gst_pad_add_buffer_probe (GstPad * pad, GCallback handler, gpointer data)
-{
-  return gst_pad_add_buffer_probe_full (pad, handler, data, NULL);
-}
-
-/**
- * gst_pad_add_buffer_probe_full:
- * @pad: pad to add the buffer probe handler to
- * @handler: function to call when buffer are passed over pad
- * @data: (closure): data to pass along with the handler
- * @notify: (allow-none): function to call when the probe is disconnected,
- *     or NULL
- *
- * Adds a probe that will be called for all buffers passing through a pad. See
- * gst_pad_add_data_probe() for more information.
- *
- * The @notify function is called when the probe is disconnected and usually
- * used to free @data.
- *
- * Returns: The handler id
- *
- * Since: 0.10.20
- */
-gulong
-gst_pad_add_buffer_probe_full (GstPad * pad, GCallback handler,
-    gpointer data, GDestroyNotify notify)
-{
-  gulong sigid;
-
-  g_return_val_if_fail (GST_IS_PAD (pad), 0);
-  g_return_val_if_fail (handler != NULL, 0);
-
-  GST_OBJECT_LOCK (pad);
-
-  /* we only expose a GDestroyNotify in our API because that's less confusing */
-  sigid = g_signal_connect_data (pad, "have-data::buffer", handler, data,
-      (GClosureNotify) notify, 0);
-
-  GST_PAD_DO_BUFFER_SIGNALS (pad)++;
-  GST_CAT_DEBUG_OBJECT (GST_CAT_PADS, pad, "adding buffer probe, now %d probes",
-      GST_PAD_DO_BUFFER_SIGNALS (pad));
-  _priv_gst_pad_invalidate_cache (pad);
-  GST_OBJECT_UNLOCK (pad);
-
-  return sigid;
-}
-
-/**
- * gst_pad_remove_data_probe:
- * @pad: pad to remove the data probe handler from
- * @handler_id: handler id returned from gst_pad_add_data_probe
- *
- * Removes a data probe from @pad.
- */
-void
-gst_pad_remove_data_probe (GstPad * pad, guint handler_id)
-{
-  g_return_if_fail (GST_IS_PAD (pad));
-  g_return_if_fail (handler_id > 0);
-
-  GST_OBJECT_LOCK (pad);
-  g_signal_handler_disconnect (pad, handler_id);
-  GST_PAD_DO_BUFFER_SIGNALS (pad)--;
-  GST_PAD_DO_EVENT_SIGNALS (pad)--;
-  GST_CAT_DEBUG_OBJECT (GST_CAT_PADS, pad,
-      "removed data probe, now %d event, %d buffer probes",
-      GST_PAD_DO_EVENT_SIGNALS (pad), GST_PAD_DO_BUFFER_SIGNALS (pad));
-  GST_OBJECT_UNLOCK (pad);
-
-}
-
-/**
- * gst_pad_remove_event_probe:
- * @pad: pad to remove the event probe handler from
- * @handler_id: handler id returned from gst_pad_add_event_probe
- *
- * Removes an event probe from @pad.
- */
-void
-gst_pad_remove_event_probe (GstPad * pad, guint handler_id)
-{
-  g_return_if_fail (GST_IS_PAD (pad));
-  g_return_if_fail (handler_id > 0);
-
-  GST_OBJECT_LOCK (pad);
-  g_signal_handler_disconnect (pad, handler_id);
-  GST_PAD_DO_EVENT_SIGNALS (pad)--;
-  GST_CAT_DEBUG_OBJECT (GST_CAT_PADS, pad,
-      "removed event probe, now %d event probes",
-      GST_PAD_DO_EVENT_SIGNALS (pad));
-  GST_OBJECT_UNLOCK (pad);
-}
-
-/**
- * gst_pad_remove_buffer_probe:
- * @pad: pad to remove the buffer probe handler from
- * @handler_id: handler id returned from gst_pad_add_buffer_probe
- *
- * Removes a buffer probe from @pad.
- */
-void
-gst_pad_remove_buffer_probe (GstPad * pad, guint handler_id)
-{
-  g_return_if_fail (GST_IS_PAD (pad));
-  g_return_if_fail (handler_id > 0);
-
-  GST_OBJECT_LOCK (pad);
-  g_signal_handler_disconnect (pad, handler_id);
-  GST_PAD_DO_BUFFER_SIGNALS (pad)--;
-  GST_CAT_DEBUG_OBJECT (GST_CAT_PADS, pad,
-      "removed buffer probe, now %d buffer probes",
-      GST_PAD_DO_BUFFER_SIGNALS (pad));
-  GST_OBJECT_UNLOCK (pad);
-
-}
-
-/**
  * gst_element_found_tags_for_pad:
  * @element: element for which to post taglist to bus.
  * @pad: (transfer none): pad on which to push tag-event
@@ -3562,11 +3055,11 @@ gst_element_found_tags_for_pad (GstElement * element,
 }
 
 static void
-push_and_ref (GstPad * pad, GstEvent * event)
+push_and_ref (const GValue * vpad, GstEvent * event)
 {
+  GstPad *pad = g_value_get_object (vpad);
+
   gst_pad_push_event (pad, gst_event_ref (event));
-  /* iterator refs pad, we unref when we are done with it */
-  gst_object_unref (pad);
 }
 
 /**
@@ -3591,7 +3084,7 @@ gst_element_found_tags (GstElement * element, GstTagList * list)
 
   iter = gst_element_iterate_src_pads (element);
   event = gst_event_new_tag (gst_tag_list_copy (list));
-  gst_iterator_foreach (iter, (GFunc) push_and_ref, event);
+  gst_iterator_foreach (iter, (GstIteratorForeachFunction) push_and_ref, event);
   gst_iterator_free (iter);
   gst_event_unref (event);
 
@@ -3605,6 +3098,7 @@ element_find_unlinked_pad (GstElement * element, GstPadDirection direction)
   GstIterator *iter;
   GstPad *unlinked_pad = NULL;
   gboolean done;
+  GValue data = { 0, };
 
   switch (direction) {
     case GST_PAD_SRC:
@@ -3619,26 +3113,25 @@ element_find_unlinked_pad (GstElement * element, GstPadDirection direction)
 
   done = FALSE;
   while (!done) {
-    gpointer pad;
-
-    switch (gst_iterator_next (iter, &pad)) {
+    switch (gst_iterator_next (iter, &data)) {
       case GST_ITERATOR_OK:{
         GstPad *peer;
+        GstPad *pad = g_value_get_object (&data);
 
         GST_CAT_LOG (GST_CAT_ELEMENT_PADS, "examining pad %s:%s",
             GST_DEBUG_PAD_NAME (pad));
 
-        peer = gst_pad_get_peer (GST_PAD (pad));
+        peer = gst_pad_get_peer (pad);
         if (peer == NULL) {
-          unlinked_pad = pad;
+          unlinked_pad = gst_object_ref (pad);
           done = TRUE;
           GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS,
               "found existing unlinked pad %s:%s",
               GST_DEBUG_PAD_NAME (unlinked_pad));
         } else {
-          gst_object_unref (pad);
           gst_object_unref (peer);
         }
+        g_value_reset (&data);
         break;
       }
       case GST_ITERATOR_DONE:
@@ -3652,7 +3145,7 @@ element_find_unlinked_pad (GstElement * element, GstPadDirection direction)
         break;
     }
   }
-
+  g_value_unset (&data);
   gst_iterator_free (iter);
 
   return unlinked_pad;
@@ -3679,6 +3172,7 @@ gst_bin_find_unlinked_pad (GstBin * bin, GstPadDirection direction)
   GstIterator *iter;
   gboolean done;
   GstPad *pad = NULL;
+  GValue data = { 0, };
 
   g_return_val_if_fail (GST_IS_BIN (bin), NULL);
   g_return_val_if_fail (direction != GST_PAD_UNKNOWN, NULL);
@@ -3686,15 +3180,16 @@ gst_bin_find_unlinked_pad (GstBin * bin, GstPadDirection direction)
   done = FALSE;
   iter = gst_bin_iterate_recurse (bin);
   while (!done) {
-    gpointer element;
+    switch (gst_iterator_next (iter, &data)) {
+      case GST_ITERATOR_OK:{
+        GstElement *element = g_value_get_object (&data);
 
-    switch (gst_iterator_next (iter, &element)) {
-      case GST_ITERATOR_OK:
-        pad = element_find_unlinked_pad (GST_ELEMENT (element), direction);
-        gst_object_unref (element);
+        pad = element_find_unlinked_pad (element, direction);
         if (pad != NULL)
           done = TRUE;
+        g_value_reset (&data);
         break;
+      }
       case GST_ITERATOR_DONE:
         done = TRUE;
         break;
@@ -3706,41 +3201,13 @@ gst_bin_find_unlinked_pad (GstBin * bin, GstPadDirection direction)
         break;
     }
   }
-
+  g_value_unset (&data);
   gst_iterator_free (iter);
 
   return pad;
 }
 
 /**
- * gst_bin_find_unconnected_pad:
- * @bin: bin in which to look for elements with unlinked pads
- * @direction: whether to look for an unlinked source or sink pad
- *
- * Recursively looks for elements with an unlinked pad of the given
- * direction within the specified bin and returns an unlinked pad
- * if one is found, or NULL otherwise. If a pad is found, the caller
- * owns a reference to it and should use gst_object_unref() on the
- * pad when it is not needed any longer.
- *
- * Returns: (transfer full): unlinked pad of the given direction, or NULL.
- *
- * Since: 0.10.3
- *
- * Deprecated: use gst_bin_find_unlinked_pad() instead.
- */
-#ifndef GST_REMOVE_DEPRECATED
-#ifdef GST_DISABLE_DEPRECATED
-GstPad *gst_bin_find_unconnected_pad (GstBin * bin, GstPadDirection direction);
-#endif
-GstPad *
-gst_bin_find_unconnected_pad (GstBin * bin, GstPadDirection direction)
-{
-  return gst_bin_find_unlinked_pad (bin, direction);
-}
-#endif
-
-/**
  * gst_parse_bin_from_description:
  * @bin_description: command line describing the bin
  * @ghost_unlinked_pads: whether to automatically create ghost pads
@@ -3766,7 +3233,7 @@ 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);
+      ghost_unlinked_pads, NULL, GST_PARSE_FLAG_NONE, err);
 }
 
 /**
index f8e4324..ecf6acb 100644 (file)
@@ -92,152 +92,6 @@ GType gst_type_register_static_full (GType parent_type,
                                const GTypeValueTable *value_table,
                                GTypeFlags       flags);
 
-
-/* Macros for defining classes.  Ideas taken from Bonobo, which took theirs
-   from Nautilus and GOB. */
-
-/**
- * GST_BOILERPLATE_FULL:
- * @type: the name of the type struct
- * @type_as_function: the prefix for the functions
- * @parent_type: the parent type struct name
- * @parent_type_macro: the parent type macro
- * @additional_initializations: function pointer in the form of
- * void additional_initializations (GType type) that can be used for
- * initializing interfaces and the like
- *
- * Define the boilerplate type stuff to reduce typos and code size.  Defines
- * the get_type method and the parent_class static variable.
- *
- * <informalexample>
- * <programlisting>
- *   GST_BOILERPLATE_FULL (GstFdSink, gst_fdsink, GstElement, GST_TYPE_ELEMENT, _do_init);
- * </programlisting>
- * </informalexample>
- */
-#define GST_BOILERPLATE_FULL(type, type_as_function, parent_type, parent_type_macro, additional_initializations)       \
-                                                                       \
-static void type_as_function ## _base_init     (gpointer      g_class);        \
-static void type_as_function ## _class_init    (type ## Class *g_class);\
-static void type_as_function ## _init         (type          *object,  \
-                                                type ## Class *g_class);\
-static parent_type ## Class *parent_class = NULL;                      \
-static void                                                            \
-type_as_function ## _class_init_trampoline (gpointer g_class)          \
-{                                                                      \
-  parent_class = (parent_type ## Class *)                              \
-      g_type_class_peek_parent (g_class);                              \
-  type_as_function ## _class_init ((type ## Class *)g_class);          \
-}                                                                      \
-                                                                       \
-GType                                                                  \
-type_as_function ## _get_type (void)                                   \
-{                                                                      \
-  /* The typedef for GType may be gulong or gsize, depending on the    \
-   * system and whether the compiler is c++ or not. The g_once_init_*  \
-   * functions always take a gsize * though ... */                     \
-  static volatile gsize gonce_data = 0;                                        \
-  if (g_once_init_enter (&gonce_data)) {                               \
-    GType _type;                                                       \
-    _type = gst_type_register_static_full (parent_type_macro,           \
-        g_intern_static_string (#type),                                        \
-       sizeof (type ## Class),                                         \
-        type_as_function ## _base_init,                                        \
-        NULL,            /* base_finalize */                           \
-        (GClassInitFunc) type_as_function ## _class_init_trampoline,    \
-        NULL,            /* class_finalize */                          \
-        NULL,               /* class_data */                           \
-        sizeof (type),                                                 \
-        0,                  /* n_preallocs */                          \
-        (GInstanceInitFunc) type_as_function ## _init,                  \
-        NULL,                                                           \
-        (GTypeFlags) 0);                                               \
-    additional_initializations (_type);                                        \
-    g_once_init_leave (&gonce_data, (gsize) _type);                    \
-  }                                                                    \
-  return (GType) gonce_data;                                           \
-}
-
-#define __GST_DO_NOTHING(type) /* NOP */
-
-/**
- * GST_BOILERPLATE:
- * @type: the name of the type struct
- * @type_as_function: the prefix for the functions
- * @parent_type: the parent type struct name
- * @parent_type_macro: the parent type macro
- *
- * Define the boilerplate type stuff to reduce typos and code size.  Defines
- * the get_type method and the parent_class static variable.
- *
- * <informalexample>
- * <programlisting>
- *   GST_BOILERPLATE (GstFdSink, gst_fdsink, GstElement, GST_TYPE_ELEMENT);
- * </programlisting>
- * </informalexample>
- */
-#define GST_BOILERPLATE(type,type_as_function,parent_type,parent_type_macro)   \
-  GST_BOILERPLATE_FULL (type, type_as_function, parent_type, parent_type_macro,        \
-      __GST_DO_NOTHING)
-
-/* Like GST_BOILERPLATE, but makes the type 1) implement an interface, and 2)
- * implement GstImplementsInterface for that type
- *
- * After this you will need to implement interface_as_function ## _supported
- * and interface_as_function ## _interface_init
- */
-/**
- * GST_BOILERPLATE_WITH_INTERFACE:
- * @type: the name of the type struct
- * @type_as_function: the prefix for the functions
- * @parent_type: the parent type struct name
- * @parent_type_as_macro: the parent type macro
- * @interface_type: the name of the interface type struct
- * @interface_type_as_macro: the interface type macro
- * @interface_as_function: the interface function name prefix
- *
- * Like GST_BOILERPLATE, but makes the type 1) implement an interface, and 2)
- * implement GstImplementsInterface for that type.
- *
- * After this you will need to implement interface_as_function ## _supported
- * and interface_as_function ## _interface_init
- */
-#define GST_BOILERPLATE_WITH_INTERFACE(type, type_as_function,         \
-    parent_type, parent_type_as_macro, interface_type,                 \
-    interface_type_as_macro, interface_as_function)                    \
-                                                                        \
-static void interface_as_function ## _interface_init (interface_type ## Class *klass);  \
-static gboolean interface_as_function ## _supported (type *object, GType iface_type);   \
-                                                                        \
-static void                                                             \
-type_as_function ## _implements_interface_init (GstImplementsInterfaceClass *klass)     \
-{                                                                       \
-  klass->supported = (gboolean (*)(GstImplementsInterface*, GType))interface_as_function ## _supported;     \
-}                                                                       \
-                                                                        \
-static void                                                             \
-type_as_function ## _init_interfaces (GType type_var)                   \
-{                                                                       \
-  static const GInterfaceInfo implements_iface_info = {                 \
-    (GInterfaceInitFunc) type_as_function ## _implements_interface_init,\
-    NULL,                                                               \
-    NULL,                                                               \
-  };                                                                    \
-  static const GInterfaceInfo iface_info = {                            \
-    (GInterfaceInitFunc) interface_as_function ## _interface_init,      \
-    NULL,                                                               \
-    NULL,                                                               \
-  };                                                                    \
-                                                                        \
-  g_type_add_interface_static (type_var, GST_TYPE_IMPLEMENTS_INTERFACE, \
-      &implements_iface_info);                                          \
-  g_type_add_interface_static (type_var, interface_type_as_macro,      \
-      &iface_info);                                                    \
-}                                                                       \
-                                                                        \
-GST_BOILERPLATE_FULL (type, type_as_function, parent_type,              \
-    parent_type_as_macro, type_as_function ## _init_interfaces)
-
 /**
  * GST_CALL_PARENT:
  * @parent_class_cast: the name of the class cast macro for the parent type
@@ -505,173 +359,6 @@ GST_BOILERPLATE_FULL (type, type_as_function, parent_type,              \
                                          _GST_PUT (data, 0,  8,  0, num); \
                                        } while (0)
 
-/* Float endianess conversion macros */
-
-/* FIXME: Remove this once we depend on a GLib version with this */
-#ifndef GFLOAT_FROM_LE
-/**
- * GFLOAT_SWAP_LE_BE:
- * @in: input value
- *
- * Swap byte order of a 32-bit floating point value (float).
- *
- * Returns: @in byte-swapped.
- *
- * Since: 0.10.22
- *
- */
-#ifdef _FOOL_GTK_DOC_
-G_INLINE_FUNC gfloat GFLOAT_SWAP_LE_BE (gfloat in);
-#endif
-
-inline static gfloat
-GFLOAT_SWAP_LE_BE(gfloat in)
-{
-  union
-  {
-    guint32 i;
-    gfloat f;
-  } u;
-
-  u.f = in;
-  u.i = GUINT32_SWAP_LE_BE (u.i);
-  return u.f;
-}
-
-/**
- * GDOUBLE_SWAP_LE_BE:
- * @in: input value
- *
- * Swap byte order of a 64-bit floating point value (double).
- *
- * Returns: @in byte-swapped.
- *
- * Since: 0.10.22
- *
- */
-#ifdef _FOOL_GTK_DOC_
-G_INLINE_FUNC gdouble GDOUBLE_SWAP_LE_BE (gdouble in);
-#endif
-
-inline static gdouble
-GDOUBLE_SWAP_LE_BE(gdouble in)
-{
-  union
-  {
-    guint64 i;
-    gdouble d;
-  } u;
-
-  u.d = in;
-  u.i = GUINT64_SWAP_LE_BE (u.i);
-  return u.d;
-}
-
-/**
- * GDOUBLE_TO_LE:
- * @val: value
- *
- * Convert 64-bit floating point value (double) from native byte order into
- * little endian byte order.
- *
- * Since: 0.10.22
- *
- */
-/**
- * GDOUBLE_TO_BE:
- * @val: value
- *
- * Convert 64-bit floating point value (double) from native byte order into
- * big endian byte order.
- *
- * Since: 0.10.22
- *
- */
-/**
- * GDOUBLE_FROM_LE:
- * @val: value
- *
- * Convert 64-bit floating point value (double) from little endian byte order
- * into native byte order.
- *
- * Since: 0.10.22
- *
- */
-/**
- * GDOUBLE_FROM_BE:
- * @val: value
- *
- * Convert 64-bit floating point value (double) from big endian byte order
- * into native byte order.
- *
- * Since: 0.10.22
- *
- */
-
-/**
- * GFLOAT_TO_LE:
- * @val: value
- *
- * Convert 32-bit floating point value (float) from native byte order into
- * little endian byte order.
- *
- * Since: 0.10.22
- *
- */
-/**
- * GFLOAT_TO_BE:
- * @val: value
- *
- * Convert 32-bit floating point value (float) from native byte order into
- * big endian byte order.
- *
- * Since: 0.10.22
- *
- */
-/**
- * GFLOAT_FROM_LE:
- * @val: value
- *
- * Convert 32-bit floating point value (float) from little endian byte order
- * into native byte order.
- *
- * Since: 0.10.22
- *
- */
-/**
- * GFLOAT_FROM_BE:
- * @val: value
- *
- * Convert 32-bit floating point value (float) from big endian byte order
- * into native byte order.
- *
- * Since: 0.10.22
- *
- */
-
-#if G_BYTE_ORDER == G_LITTLE_ENDIAN
-#define GFLOAT_TO_LE(val)    ((gfloat) (val))
-#define GFLOAT_TO_BE(val)    (GFLOAT_SWAP_LE_BE (val))
-#define GDOUBLE_TO_LE(val)   ((gdouble) (val))
-#define GDOUBLE_TO_BE(val)   (GDOUBLE_SWAP_LE_BE (val))
-
-#elif G_BYTE_ORDER == G_BIG_ENDIAN
-#define GFLOAT_TO_LE(val)    (GFLOAT_SWAP_LE_BE (val))
-#define GFLOAT_TO_BE(val)    ((gfloat) (val))
-#define GDOUBLE_TO_LE(val)   (GDOUBLE_SWAP_LE_BE (val))
-#define GDOUBLE_TO_BE(val)   ((gdouble) (val))
-
-#else /* !G_LITTLE_ENDIAN && !G_BIG_ENDIAN */
-#error unknown ENDIAN type
-#endif /* !G_LITTLE_ENDIAN && !G_BIG_ENDIAN */
-
-#define GFLOAT_FROM_LE(val)  (GFLOAT_TO_LE (val))
-#define GFLOAT_FROM_BE(val)  (GFLOAT_TO_BE (val))
-#define GDOUBLE_FROM_LE(val) (GDOUBLE_TO_LE (val))
-#define GDOUBLE_FROM_BE(val) (GDOUBLE_TO_BE (val))
-
-#endif /* !defined(GFLOAT_FROM_LE) */
-
 /**
  * GST_READ_FLOAT_LE:
  * @data: memory location
@@ -1034,10 +721,6 @@ gboolean                gst_element_seek_simple         (GstElement   *element,
                                                          gint64        seek_pos);
 
 /* util elementfactory functions */
-#ifndef GST_DISABLE_DEPRECATED
-gboolean               gst_element_factory_can_src_caps    (GstElementFactory *factory, const GstCaps *caps);
-gboolean               gst_element_factory_can_sink_caps   (GstElementFactory *factory, const GstCaps *caps);
-#endif /* GST_DISABLE_DEPRECATED */
 gboolean gst_element_factory_can_sink_all_caps (GstElementFactory *factory, const GstCaps *caps);
 gboolean gst_element_factory_can_src_all_caps  (GstElementFactory *factory, const GstCaps *caps);
 gboolean gst_element_factory_can_sink_any_caps (GstElementFactory *factory, const GstCaps *caps);
@@ -1057,9 +740,7 @@ void                       gst_element_class_install_std_props (GstElementClass * klass,
 
 /* pad functions */
 void                   gst_pad_use_fixed_caps          (GstPad *pad);
-GstCaps*               gst_pad_get_fixed_caps_func     (GstPad *pad);
-GstCaps*               gst_pad_proxy_getcaps           (GstPad * pad);
-gboolean               gst_pad_proxy_setcaps           (GstPad * pad, GstCaps * caps);
+GstCaps*               gst_pad_proxy_getcaps           (GstPad * pad, GstCaps * filter);
 
 GstElement*            gst_pad_get_parent_element      (GstPad *pad);
 
@@ -1082,55 +763,10 @@ gboolean                gst_pad_query_peer_convert      (GstPad *pad, GstFormat
 void                    gst_bin_add_many                (GstBin *bin, GstElement *element_1, ...) G_GNUC_NULL_TERMINATED;
 void                    gst_bin_remove_many             (GstBin *bin, GstElement *element_1, ...) G_GNUC_NULL_TERMINATED;
 GstPad *                gst_bin_find_unlinked_pad       (GstBin *bin, GstPadDirection direction);
-#ifndef GST_DISABLE_DEPRECATED
-GstPad *                gst_bin_find_unconnected_pad    (GstBin *bin, GstPadDirection direction);
-#endif
 
 /* buffer functions */
 GstBuffer *            gst_buffer_merge                (GstBuffer * buf1, GstBuffer * buf2);
 GstBuffer *            gst_buffer_join                 (GstBuffer * buf1, GstBuffer * buf2);
-#ifndef GST_DISABLE_DEPRECATED
-void                   gst_buffer_stamp                (GstBuffer * dest, const GstBuffer * src);
-#endif /* GST_DISABLE_DEPRECATED */
-
-/* atomic functions */
-#ifndef GST_DISABLE_DEPRECATED
-void                    gst_atomic_int_set              (gint * atomic_int, gint value);
-#endif
-
-/* probes */
-gulong                 gst_pad_add_data_probe          (GstPad   * pad,
-                                                        GCallback  handler,
-                                                        gpointer   data);
-
-gulong                 gst_pad_add_data_probe_full     (GstPad       * pad,
-                                                        GCallback      handler,
-                                                        gpointer       data,
-                                                        GDestroyNotify notify);
-
-void                   gst_pad_remove_data_probe       (GstPad * pad, guint handler_id);
-
-gulong                 gst_pad_add_event_probe         (GstPad   * pad,
-                                                        GCallback  handler,
-                                                        gpointer   data);
-
-gulong                 gst_pad_add_event_probe_full    (GstPad       * pad,
-                                                        GCallback      handler,
-                                                        gpointer       data,
-                                                        GDestroyNotify notify);
-
-void                   gst_pad_remove_event_probe      (GstPad * pad, guint handler_id);
-
-gulong                 gst_pad_add_buffer_probe        (GstPad   * pad,
-                                                        GCallback  handler,
-                                                        gpointer   data);
-
-gulong                 gst_pad_add_buffer_probe_full   (GstPad       * pad,
-                                                        GCallback      handler,
-                                                        gpointer       data,
-                                                        GDestroyNotify notify);
-
-void                   gst_pad_remove_buffer_probe     (GstPad * pad, guint handler_id);
 
 /* tag emission utility functions */
 void                   gst_element_found_tags_for_pad  (GstElement * element,
@@ -1181,18 +817,6 @@ gboolean gst_util_fraction_add (gint a_n, gint a_d, gint b_n, gint b_d, gint *re
 gint gst_util_fraction_compare (gint a_n, gint a_d, gint b_n, gint b_d);
 
 
-/* sink message event
- *
- * FIXME: This should be in gstevent.h but can't because
- * it needs GstMessage and this would introduce circular
- * header includes. And forward declarations of typedefs
- * are unfortunately not possible. The implementation of
- * these functions is in gstevent.c.
- */
-GstEvent*       gst_event_new_sink_message      (GstMessage *msg);
-void            gst_event_parse_sink_message    (GstEvent *event, GstMessage **msg);
-
-
 G_END_DECLS
 
 #endif /* __GST_UTILS_H__ */
index 3817160..2fb5088 100644 (file)
@@ -1720,20 +1720,33 @@ gst_value_deserialize_structure (GValue * dest, const gchar * s)
 static gint
 gst_value_compare_buffer (const GValue * value1, const GValue * value2)
 {
-  GstBuffer *buf1 = GST_BUFFER (gst_value_get_mini_object (value1));
-  GstBuffer *buf2 = GST_BUFFER (gst_value_get_mini_object (value2));
+  GstBuffer *buf1 = gst_value_get_buffer (value1);
+  GstBuffer *buf2 = gst_value_get_buffer (value2);
+  gsize size1, size2;
+  gpointer data1, data2;
+  gint result = GST_VALUE_UNORDERED;
 
-  if (GST_BUFFER_SIZE (buf1) != GST_BUFFER_SIZE (buf2))
+  size1 = gst_buffer_get_size (buf1);
+  size2 = gst_buffer_get_size (buf2);
+
+  if (size1 != size2)
     return GST_VALUE_UNORDERED;
-  if (GST_BUFFER_SIZE (buf1) == 0)
-    return GST_VALUE_EQUAL;
-  g_assert (GST_BUFFER_DATA (buf1));
-  g_assert (GST_BUFFER_DATA (buf2));
-  if (memcmp (GST_BUFFER_DATA (buf1), GST_BUFFER_DATA (buf2),
-          GST_BUFFER_SIZE (buf1)) == 0)
+
+  if (size1 == 0)
     return GST_VALUE_EQUAL;
 
-  return GST_VALUE_UNORDERED;
+  data1 = gst_buffer_map (buf1, &size1, NULL, GST_MAP_READ);
+  data2 = gst_buffer_map (buf2, &size2, NULL, GST_MAP_READ);
+  g_assert (data1);
+  g_assert (data2);
+
+  if (memcmp (data1, data2, size1) == 0)
+    result = GST_VALUE_EQUAL;
+
+  gst_buffer_unmap (buf2, data2, size2);
+  gst_buffer_unmap (buf1, data1, size1);
+
+  return result;
 }
 
 static gchar *
@@ -1741,7 +1754,7 @@ gst_value_serialize_buffer (const GValue * value)
 {
   guint8 *data;
   gint i;
-  gint size;
+  gsize size;
   gchar *string;
   GstBuffer *buffer;
 
@@ -1749,8 +1762,7 @@ gst_value_serialize_buffer (const GValue * value)
   if (buffer == NULL)
     return NULL;
 
-  data = GST_BUFFER_DATA (buffer);
-  size = GST_BUFFER_SIZE (buffer);
+  data = gst_buffer_map (buffer, &size, NULL, GST_MAP_READ);
 
   string = g_malloc (size * 2 + 1);
   for (i = 0; i < size; i++) {
@@ -1758,6 +1770,8 @@ gst_value_serialize_buffer (const GValue * value)
   }
   string[size * 2] = 0;
 
+  gst_buffer_unmap (buffer, data, size);
+
   return string;
 }
 
@@ -1769,13 +1783,15 @@ gst_value_deserialize_buffer (GValue * dest, const gchar * s)
   gchar ts[3];
   guint8 *data;
   gint i;
+  gsize size;
 
   len = strlen (s);
   if (len & 1)
     goto wrong_length;
 
-  buffer = gst_buffer_new_and_alloc (len / 2);
-  data = GST_BUFFER_DATA (buffer);
+  buffer = gst_buffer_new_allocate (NULL, len / 2, 0);
+  data = gst_buffer_map (buffer, &size, NULL, GST_MAP_WRITE);
+
   for (i = 0; i < len / 2; i++) {
     if (!isxdigit ((int) s[i * 2]) || !isxdigit ((int) s[i * 2 + 1]))
       goto wrong_char;
@@ -1786,6 +1802,7 @@ gst_value_deserialize_buffer (GValue * dest, const gchar * s)
 
     data[i] = (guint8) strtoul (ts, NULL, 16);
   }
+  gst_buffer_unmap (buffer, data, size);
 
   gst_value_take_buffer (dest, buffer);
 
@@ -1799,6 +1816,7 @@ wrong_length:
 wrong_char:
   {
     gst_buffer_unref (buffer);
+    gst_buffer_unmap (buffer, data, size);
     return FALSE;
   }
 }
@@ -2398,9 +2416,12 @@ gst_value_serialize_enum (const GValue * value)
 }
 
 static gint
-gst_value_deserialize_enum_iter_cmp (const GstFormatDefinition * format_def,
+gst_value_deserialize_enum_iter_cmp (const GValue * format_def_value,
     const gchar * s)
 {
+  const GstFormatDefinition *format_def =
+      g_value_get_pointer (format_def_value);
+
   if (g_ascii_strcasecmp (s, format_def->nick) == 0)
     return 0;
 
@@ -2428,16 +2449,21 @@ gst_value_deserialize_enum (GValue * dest, const gchar * s)
 
   /* might be one of the custom formats registered later */
   if (G_UNLIKELY (en == NULL && G_VALUE_TYPE (dest) == GST_TYPE_FORMAT)) {
+    GValue res = { 0, };
     const GstFormatDefinition *format_def;
     GstIterator *iter;
+    gboolean found;
 
     iter = gst_format_iterate_definitions ();
 
-    format_def = gst_iterator_find_custom (iter,
-        (GCompareFunc) gst_value_deserialize_enum_iter_cmp, (gpointer) s);
+    found = gst_iterator_find_custom (iter,
+        (GCompareFunc) gst_value_deserialize_enum_iter_cmp, &res, (gpointer) s);
 
+    g_return_val_if_fail (found, FALSE);
+    format_def = g_value_get_pointer (&res);
     g_return_val_if_fail (format_def != NULL, FALSE);
     g_value_set_enum (dest, (gint) format_def->value);
+    g_value_unset (&res);
     gst_iterator_free (iter);
     return TRUE;
   }
@@ -4010,6 +4036,73 @@ gst_value_is_fixed (const GValue * value)
   return gst_type_is_fixed (type);
 }
 
+/**
+ * gst_value_fixate:
+ * @dest: the #GValue destination
+ * @src: the #GValue to fixate
+ *
+ * Fixate @src into a new value @dest.
+ * For ranges, the first element is taken. For lists and arrays, the
+ * first item is fixated and returned.
+ * If @src is already fixed, this function returns FALSE.
+ *
+ * Returns: true if @dest contains a fixated version of @src.
+ */
+gboolean
+gst_value_fixate (GValue * dest, const GValue * src)
+{
+  g_return_val_if_fail (G_IS_VALUE (src), FALSE);
+  g_return_val_if_fail (dest != NULL, FALSE);
+
+  if (G_VALUE_TYPE (src) == GST_TYPE_INT_RANGE) {
+    g_value_init (dest, G_TYPE_INT);
+    g_value_set_int (dest, gst_value_get_int_range_min (src));
+  } else if (G_VALUE_TYPE (src) == GST_TYPE_DOUBLE_RANGE) {
+    g_value_init (dest, G_TYPE_DOUBLE);
+    g_value_set_double (dest, gst_value_get_double_range_min (src));
+  } else if (G_VALUE_TYPE (src) == GST_TYPE_FRACTION_RANGE) {
+    gst_value_init_and_copy (dest, gst_value_get_fraction_range_min (src));
+  } else if (G_VALUE_TYPE (src) == GST_TYPE_LIST) {
+    GValue temp = { 0 };
+
+    /* list could be empty */
+    if (gst_value_list_get_size (src) <= 0)
+      return FALSE;
+
+    gst_value_init_and_copy (&temp, gst_value_list_get_value (src, 0));
+
+    if (!gst_value_fixate (dest, &temp))
+      gst_value_init_and_copy (dest, &temp);
+    g_value_unset (&temp);
+  } else if (G_VALUE_TYPE (src) == GST_TYPE_ARRAY) {
+    gboolean res = FALSE;
+    guint n, len;
+
+    len = gst_value_array_get_size (src);
+    g_value_init (dest, GST_TYPE_ARRAY);
+    for (n = 0; n < len; n++) {
+      GValue kid = { 0 };
+      const GValue *orig_kid = gst_value_array_get_value (src, n);
+
+      if (!gst_value_fixate (&kid, orig_kid))
+        gst_value_init_and_copy (&kid, orig_kid);
+      else
+        res = TRUE;
+      gst_value_array_append_value (dest, &kid);
+      g_value_unset (&kid);
+    }
+
+    if (!res)
+      g_value_unset (dest);
+
+    return res;
+  } else {
+    return FALSE;
+  }
+  return TRUE;
+}
+
+
 /************
  * fraction *
  ************/
index d9cdde6..8032d87 100644 (file)
@@ -586,6 +586,8 @@ void                gst_value_register_subtract_func (GType         minuend_type,
 
 /* fixation */
 gboolean       gst_value_is_fixed              (const GValue   *value);
+gboolean        gst_value_fixate                (GValue         *dest,
+                                                 const GValue   *src);
 
 G_END_DECLS
 
diff --git a/gst/gstxml.c b/gst/gstxml.c
deleted file mode 100644 (file)
index b37a4e2..0000000
+++ /dev/null
@@ -1,541 +0,0 @@
-/* GStreamer
- * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
- *                    2000 Wim Taymans <wtay@chello.be>
- *
- * gstxml.c: XML save/restore of pipelines
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-/**
- * SECTION:gstxml
- * @short_description: XML save/restore operations of pipelines
- *
- * GStreamer pipelines can be saved to xml files using gst_xml_write_file().
- * They can be loaded back using gst_xml_parse_doc() / gst_xml_parse_file() / 
- * gst_xml_parse_memory().
- * Additionally one can load saved pipelines into the gst-editor to inspect the
- * graph.
- *
- * #GstElement implementations need to override the #GstObjectClass.save_thyself()
- * and #GstObjectClass.restore_thyself() virtual functions of #GstObject.
- *
- * Deprecated: This feature is deprecated pipeline serialization to XML is
- * broken for all but the most simple pipelines. It will most likely be
- * removed in future. Don't use it.
- */
-
-#include "gst_private.h"
-
-#include "gstxml.h"
-#include "gstmarshal.h"
-#include "gstinfo.h"
-#include "gstbin.h"
-
-#ifdef GST_DISABLE_DEPRECATED
-#if !defined(GST_DISABLE_LOADSAVE) && !defined(GST_REMOVE_DEPRECATED)
-#include <libxml/parser.h>
-xmlNodePtr gst_object_save_thyself (const GstObject * object,
-    xmlNodePtr parent);
-GstObject *gst_object_load_thyself (xmlNodePtr parent);
-void gst_object_restore_thyself (GstObject * object, GstXmlNodePtr self);
-
-#define GST_TYPE_XML           (gst_xml_get_type ())
-#define GST_XML(obj)           (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_XML, GstXML))
-#define GST_IS_XML(obj)        (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_XML))
-#define GST_XML_CLASS(klass)   (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_XML, GstXMLClass))
-#define GST_IS_XML_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_XML))
-#define GST_XML_GET_CLASS(obj)         (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_XML, GstXMLClass))
-
-typedef struct _GstXML GstXML;
-typedef struct _GstXMLClass GstXMLClass;
-
-struct _GstXML
-{
-  GstObject object;
-
-  /*< public > */
-  GList *topelements;
-
-  xmlNsPtr ns;
-
-  /*< private > */
-  gpointer _gst_reserved[GST_PADDING];
-};
-
-struct _GstXMLClass
-{
-  GstObjectClass parent_class;
-
-  /* signal callbacks */
-  void (*object_loaded) (GstXML * xml, GstObject * object, xmlNodePtr self);
-  void (*object_saved) (GstXML * xml, GstObject * object, xmlNodePtr self);
-
-  gpointer _gst_reserved[GST_PADDING];
-};
-
-GType gst_xml_get_type (void);
-xmlDocPtr gst_xml_write (GstElement * element);
-gint gst_xml_write_file (GstElement * element, FILE * out);
-GstXML *gst_xml_new (void);
-gboolean gst_xml_parse_doc (GstXML * xml, xmlDocPtr doc, const guchar * root);
-gboolean gst_xml_parse_file (GstXML * xml, const guchar * fname,
-    const guchar * root);
-gboolean gst_xml_parse_memory (GstXML * xml, guchar * buffer, guint size,
-    const gchar * root);
-GstElement *gst_xml_get_element (GstXML * xml, const guchar * name);
-GList *gst_xml_get_topelements (GstXML * xml);
-GstElement *gst_xml_make_element (xmlNodePtr cur, GstObject * parent);
-#endif
-#endif
-
-#if !defined(GST_DISABLE_LOADSAVE) && !defined(GST_REMOVE_DEPRECATED)
-
-enum
-{
-  OBJECT_LOADED,
-  LAST_SIGNAL
-};
-
-static void gst_xml_dispose (GObject * object);
-
-static void gst_xml_object_loaded (GstObject * private, GstObject * object,
-    xmlNodePtr self, gpointer data);
-
-static GstObjectClass *parent_class = NULL;
-static guint gst_xml_signals[LAST_SIGNAL] = { 0 };
-
-G_DEFINE_TYPE (GstXML, gst_xml, GST_TYPE_OBJECT);
-
-static void
-gst_xml_class_init (GstXMLClass * klass)
-{
-  GObjectClass *gobject_class = (GObjectClass *) klass;
-
-  parent_class = g_type_class_peek_parent (klass);
-
-  gobject_class->dispose = gst_xml_dispose;
-
-  /* FIXME G_TYPE_POINTER should be GType of xmlNodePtr
-   * (ensonic) can't be fixed, as libxml does not use GObject (unfortunately)
-   */
-  /**
-   * GstXML::object-loaded:
-   * @xml: the xml persistence instance
-   * @object: the object that has been loaded
-   * @xml_node: the related xml_node pointer to the document tree
-   *
-   * Signals that a new object has been deserialized.
-   */
-  gst_xml_signals[OBJECT_LOADED] =
-      g_signal_new ("object-loaded", G_TYPE_FROM_CLASS (klass),
-      G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET (GstXMLClass, object_loaded), NULL,
-      NULL, gst_marshal_VOID__OBJECT_POINTER, G_TYPE_NONE, 2, GST_TYPE_OBJECT,
-      G_TYPE_POINTER);
-
-}
-
-static void
-gst_xml_init (GstXML * xml)
-{
-  xml->topelements = NULL;
-}
-
-static void
-gst_xml_dispose (GObject * object)
-{
-  GstXML *xml = GST_XML (object);
-
-  g_list_foreach (xml->topelements, (GFunc) gst_object_unref, NULL);
-  g_list_free (xml->topelements);
-  xml->topelements = NULL;
-
-  G_OBJECT_CLASS (parent_class)->dispose (object);
-}
-
-/**
- * gst_xml_new:
- *
- * Create a new GstXML parser object.
- *
- * Returns: a pointer to a new GstXML object.
- */
-GstXML *
-gst_xml_new (void)
-{
-  return GST_XML (g_object_newv (GST_TYPE_XML, 0, NULL));
-}
-
-/**
- * gst_xml_write:
- * @element: The element to write out
- *
- * Converts the given element into an XML presentation.
- *
- * Returns: a pointer to an XML document
- */
-xmlDocPtr
-gst_xml_write (GstElement * element)
-{
-  xmlDocPtr doc;
-  xmlNodePtr elementnode;
-  xmlNsPtr gst_ns;
-
-  doc = xmlNewDoc ((xmlChar *) "1.0");
-
-  doc->xmlRootNode = xmlNewDocNode (doc, NULL, (xmlChar *) "gstreamer", NULL);
-
-  gst_ns =
-      xmlNewNs (doc->xmlRootNode,
-      (xmlChar *) "http://gstreamer.net/gst-core/1.0/", (xmlChar *) "gst");
-
-  elementnode = xmlNewChild (doc->xmlRootNode, gst_ns, (xmlChar *) "element",
-      NULL);
-
-  gst_object_save_thyself (GST_OBJECT (element), elementnode);
-
-  return doc;
-}
-
-/**
- * gst_xml_write_file:
- * @element: The element to write out
- * @out: an open file, like stdout
- *
- * Converts the given element into XML and writes the formatted XML to an open
- * file.
- *
- * Returns: number of bytes written on success, -1 otherwise.
- */
-gint
-gst_xml_write_file (GstElement * element, FILE * out)
-{
-  xmlDocPtr cur;
-
-#ifdef HAVE_LIBXML2
-  xmlOutputBufferPtr buf;
-#endif
-  const char *encoding;
-  xmlCharEncodingHandlerPtr handler = NULL;
-  int indent;
-  gboolean ret;
-
-  cur = gst_xml_write (element);
-  if (!cur)
-    return -1;
-
-#ifdef HAVE_LIBXML2
-  encoding = (const char *) cur->encoding;
-
-  if (encoding != NULL) {
-    xmlCharEncoding enc;
-
-    enc = xmlParseCharEncoding (encoding);
-
-    if (cur->charset != XML_CHAR_ENCODING_UTF8) {
-      xmlGenericError (xmlGenericErrorContext,
-          "xmlDocDump: document not in UTF8\n");
-      return -1;
-    }
-    if (enc != XML_CHAR_ENCODING_UTF8) {
-      handler = xmlFindCharEncodingHandler (encoding);
-      if (handler == NULL) {
-        xmlFree ((char *) cur->encoding);
-        cur->encoding = NULL;
-      }
-    }
-  }
-
-  buf = xmlOutputBufferCreateFile (out, handler);
-
-  indent = xmlIndentTreeOutput;
-  xmlIndentTreeOutput = 1;
-  ret = xmlSaveFormatFileTo (buf, cur, NULL, 1);
-  xmlIndentTreeOutput = indent;
-#else
-  /* apparently this doesn't return anything in libxml1 */
-  xmlDocDump (out, cur);
-  ret = 1;
-#endif
-
-  return ret;
-}
-
-/**
- * gst_xml_parse_doc:
- * @xml: a pointer to a GstXML object
- * @doc: a pointer to an xml document to parse
- * @root: The name of the root object to build
- *
- * Fills the GstXML object with the elements from the
- * xmlDocPtr.
- *
- * Returns: TRUE on success, FALSE otherwise
- */
-gboolean
-gst_xml_parse_doc (GstXML * xml, xmlDocPtr doc, const guchar * root)
-{
-  xmlNodePtr field, cur;
-  xmlNsPtr ns;
-
-  cur = xmlDocGetRootElement (doc);
-  if (cur == NULL) {
-    g_warning ("gstxml: empty document\n");
-    return FALSE;
-  }
-  ns = xmlSearchNsByHref (doc, cur,
-      (xmlChar *) "http://gstreamer.net/gst-core/1.0/");
-  if (ns == NULL) {
-    g_warning ("gstxml: document of wrong type, core namespace not found\n");
-    return FALSE;
-  }
-  if (strcmp ((char *) cur->name, "gstreamer")) {
-    g_warning ("gstxml: XML file is in wrong format\n");
-    return FALSE;
-  }
-
-  gst_class_signal_connect (GST_OBJECT_CLASS (G_OBJECT_GET_CLASS (xml)),
-      "object_loaded", (gpointer) gst_xml_object_loaded, xml);
-
-  xml->ns = ns;
-
-  field = cur->xmlChildrenNode;
-
-  while (field) {
-    if (!strcmp ((char *) field->name, "element") && (field->ns == xml->ns)) {
-      GstElement *element;
-
-      element = gst_xml_make_element (field, NULL);
-
-      xml->topelements = g_list_prepend (xml->topelements, element);
-    }
-    field = field->next;
-  }
-
-  xml->topelements = g_list_reverse (xml->topelements);
-
-  return TRUE;
-}
-
-/* FIXME 0.9: Why guchar*? */
-/**
- * gst_xml_parse_file:
- * @xml: a pointer to a GstXML object
- * @fname: The filename with the xml description
- * @root: The name of the root object to build
- *
- * Fills the GstXML object with the corresponding elements from
- * the XML file fname. Optionally it will only build the element from
- * the element node root (if it is not NULL). This feature is useful
- * if you only want to build a specific element from an XML file
- * but not the pipeline it is embedded in.
- *
- * Pass "-" as fname to read from stdin. You can also pass a URI
- * of any format that libxml supports, including http.
- *
- * Returns: TRUE on success, FALSE otherwise
- */
-gboolean
-gst_xml_parse_file (GstXML * xml, const guchar * fname, const guchar * root)
-{
-  xmlDocPtr doc;
-  gboolean ret;
-
-  g_return_val_if_fail (fname != NULL, FALSE);
-
-  doc = xmlParseFile ((char *) fname);
-
-  if (!doc) {
-    g_warning ("gstxml: XML file \"%s\" could not be read\n", fname);
-    return FALSE;
-  }
-
-  ret = gst_xml_parse_doc (xml, doc, root);
-
-  xmlFreeDoc (doc);
-  return ret;
-}
-
-/* FIXME 0.9: guchar* */
-/**
- * gst_xml_parse_memory:
- * @xml: a pointer to a GstXML object
- * @buffer: a pointer to the in memory XML buffer
- * @size: the size of the buffer
- * @root: the name of the root objects to build
- *
- * Fills the GstXML object with the corresponding elements from
- * an in memory XML buffer.
- *
- * Returns: TRUE on success
- */
-gboolean
-gst_xml_parse_memory (GstXML * xml, guchar * buffer, guint size,
-    const gchar * root)
-{
-  xmlDocPtr doc;
-  gboolean ret;
-
-  g_return_val_if_fail (buffer != NULL, FALSE);
-
-  doc = xmlParseMemory ((char *) buffer, size);
-
-  ret = gst_xml_parse_doc (xml, doc, (const xmlChar *) root);
-
-  xmlFreeDoc (doc);
-  return ret;
-}
-
-static void
-gst_xml_object_loaded (GstObject * private, GstObject * object, xmlNodePtr self,
-    gpointer data)
-{
-  GstXML *xml = GST_XML (data);
-
-  /* FIXME check that this element was created from the same xmlDocPtr... */
-  g_signal_emit (xml, gst_xml_signals[OBJECT_LOADED], 0, object, self);
-}
-
-/**
- * gst_xml_get_topelements:
- * @xml: The GstXML to get the elements from
- *
- * Retrieve a list of toplevel elements.
- *
- * Returns: a GList of top-level elements. The caller does not own a copy
- * of the list and must not free or modify the list. The caller also does not
- * own a reference to any of the elements in the list and should obtain its own
- * reference using gst_object_ref() if necessary.
- */
-GList *
-gst_xml_get_topelements (GstXML * xml)
-{
-  g_return_val_if_fail (xml != NULL, NULL);
-
-  return xml->topelements;
-}
-
-/* FIXME 0.11: why is the arg guchar* instead of gchar*? */
-/**
- * gst_xml_get_element:
- * @xml: The GstXML to get the element from
- * @name: The name of element to retrieve
- *
- * This function is used to get a pointer to the GstElement corresponding
- * to name in the pipeline description. You would use this if you have
- * to do anything to the element after loading.
- *
- * Returns: a pointer to a new GstElement, caller owns returned reference.
- */
-GstElement *
-gst_xml_get_element (GstXML * xml, const guchar * name)
-{
-  GstElement *element;
-  GList *topelements;
-
-  g_return_val_if_fail (xml != NULL, NULL);
-  g_return_val_if_fail (name != NULL, NULL);
-
-  GST_DEBUG ("gstxml: getting element \"%s\"", name);
-
-  topelements = gst_xml_get_topelements (xml);
-
-  while (topelements) {
-    GstElement *top = GST_ELEMENT (topelements->data);
-
-    GST_DEBUG ("gstxml: getting element \"%s\"", name);
-    if (!strcmp (GST_ELEMENT_NAME (top), (char *) name)) {
-      return GST_ELEMENT_CAST (gst_object_ref (top));
-    } else {
-      if (GST_IS_BIN (top)) {
-        element = gst_bin_get_by_name (GST_BIN (top), (gchar *) name);
-
-        if (element)
-          return element;
-      }
-    }
-    topelements = g_list_next (topelements);
-  }
-  return NULL;
-}
-
-/**
- * gst_xml_make_element:
- * @cur: the xml node
- * @parent: the parent of this object when it's loaded
- *
- * Load the element from the XML description
- *
- * Returns: the new element
- */
-GstElement *
-gst_xml_make_element (xmlNodePtr cur, GstObject * parent)
-{
-  xmlNodePtr children = cur->xmlChildrenNode;
-  GstElement *element;
-  gchar *name = NULL;
-  gchar *type = NULL;
-
-  /* first get the needed tags to construct the element */
-  while (children) {
-    if (!strcmp ((char *) children->name, "name")) {
-      name = (gchar *) xmlNodeGetContent (children);
-    } else if (!strcmp ((char *) children->name, "type")) {
-      type = (gchar *) xmlNodeGetContent (children);
-    }
-    children = children->next;
-  }
-  g_return_val_if_fail (name != NULL, NULL);
-  g_return_val_if_fail (type != NULL, NULL);
-
-  GST_CAT_INFO (GST_CAT_XML, "loading \"%s\" of type \"%s\"", name, type);
-
-  element = gst_element_factory_make (type, name);
-
-  g_return_val_if_fail (element != NULL, NULL);
-
-  g_free (type);
-  g_free (name);
-
-  /* ne need to set the parent on this object bacause the pads */
-  /* will go through the hierarchy to link to their peers */
-  if (parent) {
-    if (GST_IS_BIN (parent)) {
-      gst_bin_add (GST_BIN (parent), element);
-    } else {
-      gst_object_set_parent (GST_OBJECT (element), parent);
-    }
-  }
-
-  gst_object_restore_thyself (GST_OBJECT (element), cur);
-
-  return element;
-}
-
-#else
-
-/* FIXME: keep this dummy _get_type function around for now, so
- * gobject-introspection doesn't fail in the GST_REMOVE_DEPRECATED and
- * GST_DISABLE_LOADSAVE case */
-GType gst_xml_get_type (void);
-
-GType
-gst_xml_get_type (void)
-{
-  return g_pointer_type_register_static ("GstXML");
-}
-
-#endif
diff --git a/gst/gstxml.h b/gst/gstxml.h
deleted file mode 100644 (file)
index 4f61a82..0000000
+++ /dev/null
@@ -1,113 +0,0 @@
-/* GStreamer
- * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
- *                    2000 Wim Taymans <wim.taymans@chello.be>
- *
- * gstxml.h: Header for XML save/restore operations of pipelines
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#ifndef __GST_XML_H__
-#define __GST_XML_H__
-
-#include <gst/gstconfig.h>
-
-#ifndef GST_DISABLE_DEPRECATED
-#ifndef GST_DISABLE_LOADSAVE
-
-#include <gst/gstelement.h>
-
-G_BEGIN_DECLS
-
-#define GST_TYPE_XML           (gst_xml_get_type ())
-#define GST_XML(obj)           (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_XML, GstXML))
-#define GST_IS_XML(obj)        (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_XML))
-#define GST_XML_CLASS(klass)   (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_XML, GstXMLClass))
-#define GST_IS_XML_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_XML))
-#define GST_XML_GET_CLASS(obj)         (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_XML, GstXMLClass))
-
-typedef struct _GstXML GstXML;
-typedef struct _GstXMLClass GstXMLClass;
-
-/**
- * GstXML:
- * @topelements: list of element nodes
- * @ns: name space
- *
- * XML parser object
- */
-struct _GstXML {
-  GstObject object;
-
-  /*< public >*/
-  GList      *topelements;
-
-  xmlNsPtr ns;
-
-  /*< private >*/
-  gpointer _gst_reserved[GST_PADDING];
-};
-
-struct _GstXMLClass {
-  GstObjectClass parent_class;
-
-  /* signal callbacks */
-  void (*object_loaded)         (GstXML *xml, GstObject *object, xmlNodePtr self);
-  void (*object_saved)          (GstXML *xml, GstObject *object, xmlNodePtr self);
-
-  gpointer _gst_reserved[GST_PADDING];
-};
-
-GType          gst_xml_get_type        (void);
-
-
-/* create an XML document out of a pipeline */
-xmlDocPtr      gst_xml_write           (GstElement *element);
-
-/* write a formatted representation of a pipeline to an open file */
-gint           gst_xml_write_file      (GstElement *element, FILE *out);
-
-GstXML*                gst_xml_new             (void);
-
-gboolean       gst_xml_parse_doc       (GstXML *xml, xmlDocPtr doc, const guchar *root);
-gboolean       gst_xml_parse_file      (GstXML *xml, const guchar *fname, const guchar *root);
-gboolean       gst_xml_parse_memory    (GstXML *xml, guchar *buffer, guint size, const gchar *root);
-
-
-GstElement*    gst_xml_get_element     (GstXML *xml, const guchar *name);
-GList*         gst_xml_get_topelements (GstXML *xml);
-
-GstElement*    gst_xml_make_element    (xmlNodePtr cur, GstObject *parent);
-
-G_END_DECLS
-
-#else /* GST_DISABLE_LOADSAVE */
-
-#if defined __GNUC__ && __GNUC__ >= 3
-#pragma GCC poison gst_xml_write
-#pragma GCC poison gst_xml_new
-#pragma GCC poison gst_xml_parse_doc
-#pragma GCC poison gst_xml_parse_file
-#pragma GCC poison gst_xml_parse_memory
-#pragma GCC poison gst_xml_get_element
-#pragma GCC poison gst_xml_get_topelements
-#endif
-
-#endif /* GST_DISABLE_LOADSAVE */
-
-#endif
-
-#endif /* __GST_XML_H__ */
index 30abeb3..b837ec2 100644 (file)
@@ -16,7 +16,7 @@ CLEANFILES += grammar.tab.c lex._gst_parse_yy.c
 
 # can't use GST_ALL_CFLAGS here because that'd pull in -Werror
 libgstparse_la_CFLAGS = -I$(top_srcdir) -I$(top_builddir) \
-       $(GLIB_CFLAGS) $(XML_CFLAGS) $(GST_OPTION_CFLAGS)
+       $(GLIB_CFLAGS) $(GST_OPTION_CFLAGS)
 libgstparse_la_LIBADD = $(GST_ALL_LIBS)
 
 noinst_HEADERS = grammar.tab.h types.h
index 7a542fd..56cad24 100644 (file)
@@ -2,7 +2,6 @@
 %define                majorminor      @GST_MAJORMINOR@
 
 %define        _glib2          @GLIB_REQ@
-%define        _libxml2        @LIBXML2_REQ@
 
 Name:          %{gstreamer}
 Version:       @VERSION@
@@ -16,11 +15,8 @@ Source:      http://gstreamer.freedesktop.org/src/gstreamer/gstreamer-%{version}.tar
 BuildRoot:      %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
 
 Requires:      gstreamer-tools >= %{version}
-# gst-feedback uses these
-Requires:      which, pkgconfig
 
 BuildRequires:         glib2-devel >= %{_glib2}
-BuildRequires:         libxml2-devel >= %{_libxml2}
 BuildRequires:         bison
 BuildRequires:         flex
 BuildRequires:         m4
@@ -60,7 +56,6 @@ Group:                Development/Libraries
 
 Requires:      %{name} = %{version}-%{release}
 Requires:      glib2-devel >= %{_glib2}
-Requires:      libxml2-devel >= %{_libxml2}
 Requires:      check-devel
 
 %description devel
@@ -143,19 +138,13 @@ rm -rf $RPM_BUILD_ROOT
 %{_libdir}/gstreamer-%{majorminor}/libgstcoreelements.so
 %{_libdir}/gstreamer-%{majorminor}/libgstcoreindexers.so
 
-%{_bindir}/gst-feedback-%{majorminor}
 %{_bindir}/gst-inspect-%{majorminor}
 %{_bindir}/gst-launch-%{majorminor}
 %{_bindir}/gst-typefind-%{majorminor}
-%{_bindir}/gst-xmlinspect-%{majorminor}
-%{_bindir}/gst-xmllaunch-%{majorminor}
 %{_libexecdir}/gstreamer-%{majorminor}/gst-plugin-scanner
-%doc %{_mandir}/man1/gst-feedback-%{majorminor}.*
 %doc %{_mandir}/man1/gst-inspect-%{majorminor}.*
 %doc %{_mandir}/man1/gst-launch-%{majorminor}.*
 %doc %{_mandir}/man1/gst-typefind-%{majorminor}.*
-%doc %{_mandir}/man1/gst-xmlinspect-%{majorminor}.*
-%doc %{_mandir}/man1/gst-xmllaunch-%{majorminor}.*
 %doc %{_datadir}/doc/gstreamer-%{majorminor}/manual
 %doc %{_datadir}/doc/gstreamer-%{majorminor}/pwg
 %doc %{_datadir}/doc/gstreamer-%{majorminor}/faq/
@@ -172,12 +161,9 @@ rm -rf $RPM_BUILD_ROOT
 
 %files -n gstreamer-tools
 %defattr(-, root, root, -)
-%{_bindir}/gst-feedback
 %{_bindir}/gst-inspect
 %{_bindir}/gst-launch
 %{_bindir}/gst-typefind
-%{_bindir}/gst-xmlinspect
-%{_bindir}/gst-xmllaunch
 
 %files devel
 %defattr(-, root, root, -)
index f6fa3ef..60c886d 100644 (file)
@@ -81,12 +81,12 @@ GstBase-@GST_MAJORMINOR@.gir: $(INTROSPECTION_SCANNER) libgstbase-@GST_MAJORMINO
                $(gir_cincludes) \
                --add-include-path=$(top_builddir)/gst \
                --library-path=$(top_builddir)/gst \
-               --library=$(top_builddir)/gst/libgstreamer-0.10.la \
-               --library=libgstbase-0.10.la \
-               --include=Gst-0.10 \
+               --library=$(top_builddir)/gst/libgstreamer-0.11.la \
+               --library=libgstbase-0.11.la \
+               --include=Gst-0.11 \
                --libtool="$(top_builddir)/libtool" \
-               --pkg gstreamer-0.10 \
-               --pkg-export gstreamer-base-0.10 \
+               --pkg gstreamer-@GST_MAJORMINOR@ \
+               --pkg-export gstreamer-base-@GST_MAJORMINOR@ \
                --add-init-section="gst_init(NULL,NULL);" \
                --output $@ \
                $(gir_headers) \
index 75944a9..94fbabf 100644 (file)
  *
  * The theory of operation is like this: All buffers received are put
  * into the adapter using gst_adapter_push() and the data is then read back
- * in chunks of the desired size using gst_adapter_peek(). After the data is
- * processed, it is freed using gst_adapter_flush().
+ * in chunks of the desired size using gst_adapter_map()/gst_adapter_unmap()
+ * and/or gst_adapter_copy(). After the data has been processed, it is freed
+ * using gst_adapter_unmap().
  *
  * Other methods such as gst_adapter_take() and gst_adapter_take_buffer()
- * combine gst_adapter_peek() and gst_adapter_flush() in one method and are
+ * combine gst_adapter_map() and gst_adapter_unmap() in one method and are
  * potentially more convenient for some use cases.
  *
  * For example, a sink pad's chain function that needs to pass data to a library
  *   gst_adapter_push (adapter, buffer);
  *   // while we can read out 512 bytes, process them
  *   while (gst_adapter_available (adapter) >= 512 && ret == GST_FLOW_OK) {
+ *     const guint8 *data = gst_adapter_map (adapter, 512);
  *     // use flowreturn as an error value
- *     ret = my_library_foo (gst_adapter_peek (adapter, 512));
- *     gst_adapter_flush (adapter, 512);
+ *     ret = my_library_foo (data);
+ *     gst_adapter_unmap (adapter, 512);
  *   }
  *
  *   gst_object_unref (this);
 /* default size for the assembled data buffer */
 #define DEFAULT_SIZE 4096
 
+static void gst_adapter_flush_unchecked (GstAdapter * adapter, gsize flush);
+
 GST_DEBUG_CATEGORY_STATIC (gst_adapter_debug);
 #define GST_CAT_DEFAULT gst_adapter_debug
 
@@ -127,25 +131,22 @@ struct _GstAdapterPrivate
   GstClockTime timestamp;
   guint64 distance;
 
-  guint scan_offset;
+  gsize scan_offset;
   GSList *scan_entry;
+
+  gpointer cdata;
+  gsize csize;
 };
 
-#define _do_init(thing) \
+#define _do_init \
   GST_DEBUG_CATEGORY_INIT (gst_adapter_debug, "adapter", 0, "object to splice and merge buffers to desired size")
-GST_BOILERPLATE_FULL (GstAdapter, gst_adapter, GObject, G_TYPE_OBJECT,
-    _do_init);
+#define gst_adapter_parent_class parent_class
+G_DEFINE_TYPE_WITH_CODE (GstAdapter, gst_adapter, G_TYPE_OBJECT, _do_init);
 
 static void gst_adapter_dispose (GObject * object);
 static void gst_adapter_finalize (GObject * object);
 
 static void
-gst_adapter_base_init (gpointer g_class)
-{
-  /* nop */
-}
-
-static void
 gst_adapter_class_init (GstAdapterClass * klass)
 {
   GObjectClass *object = G_OBJECT_CLASS (klass);
@@ -157,7 +158,7 @@ gst_adapter_class_init (GstAdapterClass * klass)
 }
 
 static void
-gst_adapter_init (GstAdapter * adapter, GstAdapterClass * g_class)
+gst_adapter_init (GstAdapter * adapter)
 {
   adapter->priv = GST_ADAPTER_GET_PRIVATE (adapter);
   adapter->assembled_data = g_malloc (DEFAULT_SIZE);
@@ -239,12 +240,12 @@ update_timestamp (GstAdapter * adapter, GstBuffer * buf)
 
 /* copy data into @dest, skipping @skip bytes from the head buffers */
 static void
-copy_into_unchecked (GstAdapter * adapter, guint8 * dest, guint skip,
-    guint size)
+copy_into_unchecked (GstAdapter * adapter, guint8 * dest, gsize skip,
+    gsize size)
 {
   GSList *g;
   GstBuffer *buf;
-  guint bsize, csize;
+  gsize bsize, csize;
 
   /* first step, do skipping */
   /* we might well be copying where we were scanning */
@@ -255,16 +256,17 @@ copy_into_unchecked (GstAdapter * adapter, guint8 * dest, guint skip,
     g = adapter->buflist;
   }
   buf = g->data;
-  bsize = GST_BUFFER_SIZE (buf);
+  bsize = gst_buffer_get_size (buf);
   while (G_UNLIKELY (skip >= bsize)) {
     skip -= bsize;
     g = g_slist_next (g);
     buf = g->data;
-    bsize = GST_BUFFER_SIZE (buf);
+    bsize = gst_buffer_get_size (buf);
   }
   /* copy partial buffer */
   csize = MIN (bsize - skip, size);
-  memcpy (dest, GST_BUFFER_DATA (buf) + skip, csize);
+  GST_DEBUG ("%u %u %u", bsize, skip, csize);
+  gst_buffer_extract (buf, skip, dest, csize);
   size -= csize;
   dest += csize;
 
@@ -272,10 +274,10 @@ copy_into_unchecked (GstAdapter * adapter, guint8 * dest, guint skip,
   while (size > 0) {
     g = g_slist_next (g);
     buf = g->data;
-    bsize = GST_BUFFER_SIZE (buf);
+    bsize = gst_buffer_get_size (buf);
     if (G_LIKELY (bsize > 0)) {
       csize = MIN (bsize, size);
-      memcpy (dest, GST_BUFFER_DATA (buf), csize);
+      gst_buffer_extract (buf, 0, dest, csize);
       size -= csize;
       dest += csize;
     }
@@ -293,12 +295,12 @@ copy_into_unchecked (GstAdapter * adapter, guint8 * dest, guint skip,
 void
 gst_adapter_push (GstAdapter * adapter, GstBuffer * buf)
 {
-  guint size;
+  gsize size;
 
   g_return_if_fail (GST_IS_ADAPTER (adapter));
   g_return_if_fail (GST_IS_BUFFER (buf));
 
-  size = GST_BUFFER_SIZE (buf);
+  size = gst_buffer_get_size (buf);
   adapter->size += size;
 
   /* Note: merging buffers at this point is premature. */
@@ -322,11 +324,12 @@ gst_adapter_push (GstAdapter * adapter, GstBuffer * buf)
  * Returns TRUE if it managed to merge anything.
  */
 static gboolean
-gst_adapter_try_to_merge_up (GstAdapter * adapter, guint size)
+gst_adapter_try_to_merge_up (GstAdapter * adapter, gsize size)
 {
   GstBuffer *cur, *head;
   GSList *g;
   gboolean ret = FALSE;
+  gsize hsize;
 
   g = adapter->buflist;
   if (g == NULL)
@@ -338,8 +341,9 @@ gst_adapter_try_to_merge_up (GstAdapter * adapter, guint size)
   /* How large do we want our head buffer? The requested size, plus whatever's
    * been skipped already */
   size += adapter->skip;
+  hsize = gst_buffer_get_size (head);
 
-  while (g != NULL && GST_BUFFER_SIZE (head) < size) {
+  while (g != NULL && hsize < size) {
     cur = g->data;
     if (!gst_buffer_is_span_fast (head, cur))
       return ret;
@@ -347,9 +351,10 @@ gst_adapter_try_to_merge_up (GstAdapter * adapter, guint size)
     /* Merge the head buffer and the next in line */
     GST_LOG_OBJECT (adapter,
         "Merging buffers of size %u & %u in search of target %u",
-        GST_BUFFER_SIZE (head), GST_BUFFER_SIZE (cur), size);
+        hsize, gst_buffer_get_size (cur), size);
 
     head = gst_buffer_join (head, cur);
+    hsize = gst_buffer_get_size (head);
     ret = TRUE;
 
     /* Delete the front list item, and store our new buffer in the 2nd list
@@ -368,9 +373,9 @@ gst_adapter_try_to_merge_up (GstAdapter * adapter, guint size)
 }
 
 /**
- * gst_adapter_peek:
+ * gst_adapter_map:
  * @adapter: a #GstAdapter
- * @size: the number of bytes to peek
+ * @size: the number of bytes to map/peek
  *
  * Gets the first @size bytes stored in the @adapter. The returned pointer is
  * valid until the next function is called on the adapter.
@@ -390,11 +395,11 @@ gst_adapter_try_to_merge_up (GstAdapter * adapter, guint size)
  *     @size bytes of data, or NULL
  */
 const guint8 *
-gst_adapter_peek (GstAdapter * adapter, guint size)
+gst_adapter_map (GstAdapter * adapter, gsize size)
 {
   GstBuffer *cur;
-  guint skip;
-  guint toreuse, tocopy;
+  gsize skip, csize;
+  gsize toreuse, tocopy;
   guint8 *data;
 
   g_return_val_if_fail (GST_IS_ADAPTER (adapter), NULL);
@@ -410,20 +415,20 @@ gst_adapter_peek (GstAdapter * adapter, guint size)
   if (adapter->assembled_len >= size)
     return adapter->assembled_data;
 
-  /* our head buffer has enough data left, return it */
-  cur = adapter->buflist->data;
-  skip = adapter->skip;
-  if (GST_BUFFER_SIZE (cur) >= size + skip)
-    return GST_BUFFER_DATA (cur) + skip;
-
-  /* We may be able to efficiently merge buffers in our pool to
-   * gather a big enough chunk to return it from the head buffer directly */
-  if (gst_adapter_try_to_merge_up (adapter, size)) {
-    /* Merged something! Check if there's enough avail now */
+  do {
     cur = adapter->buflist->data;
-    if (GST_BUFFER_SIZE (cur) >= size + skip)
-      return GST_BUFFER_DATA (cur) + skip;
-  }
+    skip = adapter->skip;
+
+    csize = gst_buffer_get_size (cur);
+    if (csize >= size + skip) {
+      data = gst_buffer_map (cur, &csize, NULL, GST_MAP_READ);
+      adapter->priv->cdata = data;
+      adapter->priv->csize = csize;
+      return data + skip;
+    }
+    /* We may be able to efficiently merge buffers in our pool to
+     * gather a big enough chunk to return it from the head buffer directly */
+  } while (gst_adapter_try_to_merge_up (adapter, size));
 
   /* see how much data we can reuse from the assembled memory and how much
    * we need to copy */
@@ -458,6 +463,29 @@ gst_adapter_peek (GstAdapter * adapter, guint size)
 }
 
 /**
+ * gst_adapter_unmap:
+ * @adapter: a #GstAdapter
+ * @flush: the amount of bytes to flush
+ *
+ * Releases the memory obtained with the last gst_adapter_map() and flushes
+ * @size bytes from the adapter.
+ */
+void
+gst_adapter_unmap (GstAdapter * adapter, gsize flush)
+{
+  g_return_if_fail (GST_IS_ADAPTER (adapter));
+
+  if (adapter->priv->cdata) {
+    GstBuffer *cur = adapter->buflist->data;
+    gst_buffer_unmap (cur, adapter->priv->cdata, adapter->priv->csize);
+    adapter->priv->cdata = NULL;
+  }
+
+  if (flush)
+    gst_adapter_flush_unchecked (adapter, flush);
+}
+
+/**
  * gst_adapter_copy:
  * @adapter: a #GstAdapter
  * @dest: (out caller-allocates) (array length=size): the memory to copy into
@@ -474,7 +502,7 @@ gst_adapter_peek (GstAdapter * adapter, guint size)
  * Since: 0.10.12
  */
 void
-gst_adapter_copy (GstAdapter * adapter, guint8 * dest, guint offset, guint size)
+gst_adapter_copy (GstAdapter * adapter, guint8 * dest, gsize offset, gsize size)
 {
   g_return_if_fail (GST_IS_ADAPTER (adapter));
   g_return_if_fail (size > 0);
@@ -491,13 +519,13 @@ gst_adapter_copy (GstAdapter * adapter, guint8 * dest, guint offset, guint size)
  * Flushes the first @flush bytes in the @adapter. The caller must ensure that
  * at least this many bytes are available.
  *
- * See also: gst_adapter_peek().
+ * See also: gst_adapter_map(), gst_adapter_unmap()
  */
 static void
-gst_adapter_flush_unchecked (GstAdapter * adapter, guint flush)
+gst_adapter_flush_unchecked (GstAdapter * adapter, gsize flush)
 {
   GstBuffer *cur;
-  guint size;
+  gsize size;
   GstAdapterPrivate *priv;
   GSList *g;
 
@@ -516,7 +544,7 @@ gst_adapter_flush_unchecked (GstAdapter * adapter, guint flush)
 
   g = adapter->buflist;
   cur = g->data;
-  size = GST_BUFFER_SIZE (cur);
+  size = gst_buffer_get_size (cur);
   while (flush >= size) {
     /* can skip whole buffer */
     GST_LOG_OBJECT (adapter, "flushing out head buffer");
@@ -534,7 +562,7 @@ gst_adapter_flush_unchecked (GstAdapter * adapter, guint flush)
     /* there is a new head buffer, update the timestamp */
     cur = g->data;
     update_timestamp (adapter, cur);
-    size = GST_BUFFER_SIZE (cur);
+    size = gst_buffer_get_size (cur);
   }
   adapter->buflist = g;
   /* account for the remaining bytes */
@@ -546,7 +574,7 @@ gst_adapter_flush_unchecked (GstAdapter * adapter, guint flush)
 }
 
 void
-gst_adapter_flush (GstAdapter * adapter, guint flush)
+gst_adapter_flush (GstAdapter * adapter, gsize flush)
 {
   g_return_if_fail (GST_IS_ADAPTER (adapter));
   g_return_if_fail (flush <= adapter->size);
@@ -560,10 +588,10 @@ gst_adapter_flush (GstAdapter * adapter, guint flush)
 
 /* internal function, nbytes should be flushed after calling this function */
 static guint8 *
-gst_adapter_take_internal (GstAdapter * adapter, guint nbytes)
+gst_adapter_take_internal (GstAdapter * adapter, gsize nbytes)
 {
   guint8 *data;
-  guint toreuse, tocopy;
+  gsize toreuse, tocopy;
 
   /* see how much data we can reuse from the assembled memory and how much
    * we need to copy */
@@ -592,7 +620,6 @@ gst_adapter_take_internal (GstAdapter * adapter, guint nbytes)
   }
   if (tocopy) {
     /* copy the remaining data */
-    GST_LOG_OBJECT (adapter, "copying %u bytes", tocopy);
     copy_into_unchecked (adapter, toreuse + data, toreuse + adapter->skip,
         tocopy);
   }
@@ -615,7 +642,7 @@ gst_adapter_take_internal (GstAdapter * adapter, guint nbytes)
  *     #NULL if @nbytes bytes are not available
  */
 guint8 *
-gst_adapter_take (GstAdapter * adapter, guint nbytes)
+gst_adapter_take (GstAdapter * adapter, gsize nbytes)
 {
   guint8 *data;
 
@@ -656,11 +683,11 @@ gst_adapter_take (GstAdapter * adapter, guint nbytes)
  * Since: 0.10.6
  */
 GstBuffer *
-gst_adapter_take_buffer (GstAdapter * adapter, guint nbytes)
+gst_adapter_take_buffer (GstAdapter * adapter, gsize nbytes)
 {
   GstBuffer *buffer;
   GstBuffer *cur;
-  guint hsize, skip;
+  gsize hsize, skip;
   guint8 *data;
 
   g_return_val_if_fail (GST_IS_ADAPTER (adapter), NULL);
@@ -676,7 +703,7 @@ gst_adapter_take_buffer (GstAdapter * adapter, guint nbytes)
 
   cur = adapter->buflist->data;
   skip = adapter->skip;
-  hsize = GST_BUFFER_SIZE (cur);
+  hsize = gst_buffer_get_size (cur);
 
   /* our head buffer has enough data left, return it */
   if (skip == 0 && hsize == nbytes) {
@@ -685,19 +712,19 @@ gst_adapter_take_buffer (GstAdapter * adapter, guint nbytes)
     buffer = gst_buffer_ref (cur);
     goto done;
   } else if (hsize >= nbytes + skip) {
-    GST_LOG_OBJECT (adapter, "providing buffer of %d bytes via sub-buffer",
+    GST_LOG_OBJECT (adapter, "providing buffer of %d bytes via region copy",
         nbytes);
-    buffer = gst_buffer_create_sub (cur, skip, nbytes);
+    buffer = gst_buffer_copy_region (cur, GST_BUFFER_COPY_ALL, skip, nbytes);
     goto done;
   }
 
   if (gst_adapter_try_to_merge_up (adapter, nbytes)) {
     /* Merged something, let's try again for sub-buffering */
     cur = adapter->buflist->data;
-    if (GST_BUFFER_SIZE (cur) >= nbytes + skip) {
+    if (gst_buffer_get_size (cur) >= nbytes + skip) {
       GST_LOG_OBJECT (adapter, "providing buffer of %d bytes via sub-buffer",
           nbytes);
-      buffer = gst_buffer_create_sub (cur, skip, nbytes);
+      buffer = gst_buffer_copy_region (cur, GST_BUFFER_COPY_ALL, skip, nbytes);
       goto done;
     }
   }
@@ -705,9 +732,8 @@ gst_adapter_take_buffer (GstAdapter * adapter, guint nbytes)
   data = gst_adapter_take_internal (adapter, nbytes);
 
   buffer = gst_buffer_new ();
-  GST_BUFFER_SIZE (buffer) = nbytes;
-  GST_BUFFER_DATA (buffer) = data;
-  GST_BUFFER_MALLOCDATA (buffer) = data;
+  gst_buffer_take_memory (buffer, -1,
+      gst_memory_new_wrapped (0, data, g_free, nbytes, 0, nbytes));
 
 done:
   gst_adapter_flush_unchecked (adapter, nbytes);
@@ -735,11 +761,11 @@ done:
  * Since: 0.10.31
  */
 GList *
-gst_adapter_take_list (GstAdapter * adapter, guint nbytes)
+gst_adapter_take_list (GstAdapter * adapter, gsize nbytes)
 {
   GList *result = NULL, *tail = NULL;
   GstBuffer *cur;
-  guint hsize, skip;
+  gsize hsize, skip;
 
   g_return_val_if_fail (GST_IS_ADAPTER (adapter), NULL);
   g_return_val_if_fail (nbytes <= adapter->size, NULL);
@@ -749,7 +775,7 @@ gst_adapter_take_list (GstAdapter * adapter, guint nbytes)
   while (nbytes > 0) {
     cur = adapter->buflist->data;
     skip = adapter->skip;
-    hsize = MIN (nbytes, GST_BUFFER_SIZE (cur) - skip);
+    hsize = MIN (nbytes, gst_buffer_get_size (cur) - skip);
 
     cur = gst_adapter_take_buffer (adapter, hsize);
 
@@ -769,12 +795,12 @@ gst_adapter_take_list (GstAdapter * adapter, guint nbytes)
  * @adapter: a #GstAdapter
  *
  * Gets the maximum amount of bytes available, that is it returns the maximum
- * value that can be supplied to gst_adapter_peek() without that function
+ * value that can be supplied to gst_adapter_map() without that function
  * returning NULL.
  *
  * Returns: number of bytes available in @adapter
  */
-guint
+gsize
 gst_adapter_available (GstAdapter * adapter)
 {
   g_return_val_if_fail (GST_IS_ADAPTER (adapter), 0);
@@ -793,11 +819,11 @@ gst_adapter_available (GstAdapter * adapter)
  * Returns: number of bytes that are available in @adapter without expensive
  * operations
  */
-guint
+gsize
 gst_adapter_available_fast (GstAdapter * adapter)
 {
   GstBuffer *cur;
-  guint size;
+  gsize size;
   GSList *g;
 
   g_return_val_if_fail (GST_IS_ADAPTER (adapter), 0);
@@ -814,7 +840,7 @@ gst_adapter_available_fast (GstAdapter * adapter)
   g = adapter->buflist;
   while (TRUE) {
     cur = g->data;
-    size = GST_BUFFER_SIZE (cur);
+    size = gst_buffer_get_size (cur);
     if (size != 0)
       break;
     g = g_slist_next (g);
@@ -878,14 +904,14 @@ gst_adapter_prev_timestamp (GstAdapter * adapter, guint64 * distance)
  *
  * Since: 0.10.30
  */
-guint
+gsize
 gst_adapter_masked_scan_uint32_peek (GstAdapter * adapter, guint32 mask,
-    guint32 pattern, guint offset, guint size, guint32 * value)
+    guint32 pattern, gsize offset, gsize size, guint32 * value)
 {
   GSList *g;
-  guint skip, bsize, i;
+  gsize skip, bsize, osize, i;
   guint32 state;
-  guint8 *bdata;
+  guint8 *bdata, *odata;
   GstBuffer *buf;
 
   g_return_val_if_fail (size > 0, -1);
@@ -909,18 +935,20 @@ gst_adapter_masked_scan_uint32_peek (GstAdapter * adapter, guint32 mask,
     adapter->priv->scan_entry = NULL;
   }
   buf = g->data;
-  bsize = GST_BUFFER_SIZE (buf);
+  bsize = gst_buffer_get_size (buf);
   while (G_UNLIKELY (skip >= bsize)) {
     skip -= bsize;
     g = g_slist_next (g);
     adapter->priv->scan_offset += bsize;
     adapter->priv->scan_entry = g;
     buf = g->data;
-    bsize = GST_BUFFER_SIZE (buf);
+    bsize = gst_buffer_get_size (buf);
   }
   /* get the data now */
-  bsize -= skip;
-  bdata = GST_BUFFER_DATA (buf) + skip;
+  odata = gst_buffer_map (buf, &osize, NULL, GST_MAP_READ);
+
+  bdata = odata + skip;
+  bsize = osize - skip;
   skip = 0;
 
   /* set the state to something that does not match */
@@ -937,6 +965,7 @@ gst_adapter_masked_scan_uint32_peek (GstAdapter * adapter, guint32 mask,
         if (G_LIKELY (skip + i >= 3)) {
           if (G_LIKELY (value))
             *value = state;
+          gst_buffer_unmap (buf, odata, osize);
           return offset + skip + i - 3;
         }
       }
@@ -948,13 +977,18 @@ gst_adapter_masked_scan_uint32_peek (GstAdapter * adapter, guint32 mask,
     /* nothing found yet, go to next buffer */
     skip += bsize;
     g = g_slist_next (g);
-    adapter->priv->scan_offset += GST_BUFFER_SIZE (buf);
+    adapter->priv->scan_offset += osize;
     adapter->priv->scan_entry = g;
+    gst_buffer_unmap (buf, odata, osize);
     buf = g->data;
-    bsize = GST_BUFFER_SIZE (buf);
-    bdata = GST_BUFFER_DATA (buf);
+
+    odata = gst_buffer_map (buf, &osize, NULL, GST_MAP_READ);
+    bsize = osize;
+    bdata = odata;
   } while (TRUE);
 
+  gst_buffer_unmap (buf, odata, osize);
+
   /* nothing found */
   return -1;
 }
@@ -1005,9 +1039,9 @@ gst_adapter_masked_scan_uint32_peek (GstAdapter * adapter, guint32 mask,
  *
  * Since: 0.10.24
  */
-guint
+gsize
 gst_adapter_masked_scan_uint32 (GstAdapter * adapter, guint32 mask,
-    guint32 pattern, guint offset, guint size)
+    guint32 pattern, gsize offset, gsize size)
 {
   return gst_adapter_masked_scan_uint32_peek (adapter, mask, pattern, offset,
       size, NULL);
index ae8b781..aa6730b 100644 (file)
@@ -52,22 +52,18 @@ struct _GstAdapter {
 
   /*< private >*/
   GSList *      buflist;
-  guint         size;
-  guint         skip;
+  GSList *      buflist_end;
+  gsize         size;
+  gsize         skip;
 
   /* we keep state of assembled pieces */
   guint8 *      assembled_data;
-  guint         assembled_size;
-  guint         assembled_len;
-
-  /* ABI added */
-  /* Remember where the end of our buffer list is to
-   * speed up the push */
-  GSList *buflist_end;
+  gsize         assembled_size;
+  gsize         assembled_len;
 
   GstAdapterPrivate *priv;
 
-  gpointer _gst_reserved[GST_PADDING - 2];
+  gpointer _gst_reserved[GST_PADDING];
 };
 
 struct _GstAdapterClass {
@@ -83,23 +79,24 @@ GstAdapter *            gst_adapter_new                 (void);
 
 void                    gst_adapter_clear               (GstAdapter *adapter);
 void                    gst_adapter_push                (GstAdapter *adapter, GstBuffer* buf);
-const guint8 *          gst_adapter_peek                (GstAdapter *adapter, guint size);
+const guint8 *          gst_adapter_map                 (GstAdapter *adapter, gsize size);
+void                    gst_adapter_unmap               (GstAdapter *adapter, gsize flush);
 void                    gst_adapter_copy                (GstAdapter *adapter, guint8 *dest,
-                                                         guint offset, guint size);
-void                    gst_adapter_flush               (GstAdapter *adapter, guint flush);
-guint8*                 gst_adapter_take                (GstAdapter *adapter, guint nbytes);
-GstBuffer*              gst_adapter_take_buffer         (GstAdapter *adapter, guint nbytes);
-GList*                  gst_adapter_take_list           (GstAdapter *adapter, guint nbytes);
-guint                   gst_adapter_available           (GstAdapter *adapter);
-guint                   gst_adapter_available_fast      (GstAdapter *adapter);
+                                                         gsize offset, gsize size);
+void                    gst_adapter_flush               (GstAdapter *adapter, gsize flush);
+guint8*                 gst_adapter_take                (GstAdapter *adapter, gsize nbytes);
+GstBuffer*              gst_adapter_take_buffer         (GstAdapter *adapter, gsize nbytes);
+GList*                  gst_adapter_take_list           (GstAdapter *adapter, gsize nbytes);
+gsize                   gst_adapter_available           (GstAdapter *adapter);
+gsize                   gst_adapter_available_fast      (GstAdapter *adapter);
 
 GstClockTime            gst_adapter_prev_timestamp      (GstAdapter *adapter, guint64 *distance);
 
-guint                   gst_adapter_masked_scan_uint32  (GstAdapter * adapter, guint32 mask,
-                                                         guint32 pattern, guint offset, guint size);
+gsize                   gst_adapter_masked_scan_uint32  (GstAdapter * adapter, guint32 mask,
+                                                         guint32 pattern, gsize offset, gsize size);
 
-guint                   gst_adapter_masked_scan_uint32_peek  (GstAdapter * adapter, guint32 mask,
-                                                         guint32 pattern, guint offset, guint size, guint32 * value);
+gsize                   gst_adapter_masked_scan_uint32_peek  (GstAdapter * adapter, guint32 mask,
+                                                         guint32 pattern, gsize offset, gsize size, guint32 * value);
 
 G_END_DECLS
 
index e0158ce..eef74c1 100644 (file)
@@ -377,7 +377,6 @@ static void gst_base_parse_handle_tag (GstBaseParse * parse, GstEvent * event);
 static gboolean gst_base_parse_src_event (GstPad * pad, GstEvent * event);
 static gboolean gst_base_parse_sink_event (GstPad * pad, GstEvent * event);
 static gboolean gst_base_parse_query (GstPad * pad, GstQuery * query);
-static gboolean gst_base_parse_sink_setcaps (GstPad * pad, GstCaps * caps);
 static const GstQueryType *gst_base_parse_get_querytypes (GstPad * pad);
 
 static GstFlowReturn gst_base_parse_chain (GstPad * pad, GstBuffer * buffer);
@@ -509,8 +508,6 @@ gst_base_parse_init (GstBaseParse * parse, GstBaseParseClass * bclass)
   parse->sinkpad = gst_pad_new_from_template (pad_template, "sink");
   gst_pad_set_event_function (parse->sinkpad,
       GST_DEBUG_FUNCPTR (gst_base_parse_sink_event));
-  gst_pad_set_setcaps_function (parse->sinkpad,
-      GST_DEBUG_FUNCPTR (gst_base_parse_sink_setcaps));
   gst_pad_set_chain_function (parse->sinkpad,
       GST_DEBUG_FUNCPTR (gst_base_parse_chain));
   gst_pad_set_activate_function (parse->sinkpad,
@@ -754,7 +751,7 @@ static gboolean
 gst_base_parse_check_frame (GstBaseParse * parse,
     GstBaseParseFrame * frame, guint * framesize, gint * skipsize)
 {
-  *framesize = GST_BUFFER_SIZE (frame->buffer);
+  *framesize = gst_buffer_get_size (frame->buffer);
   *skipsize = 0;
   return TRUE;
 }
@@ -858,10 +855,10 @@ gst_base_parse_sink_event (GstPad * pad, GstEvent * event)
   GST_DEBUG_OBJECT (parse, "handling event %d, %s", GST_EVENT_TYPE (event),
       GST_EVENT_TYPE_NAME (event));
 
-  /* Cache all events except EOS, NEWSEGMENT and FLUSH_STOP if we have a
+  /* Cache all events except EOS, SEGMENT and FLUSH_STOP if we have a
    * pending segment */
   if (parse->priv->pending_segment && GST_EVENT_TYPE (event) != GST_EVENT_EOS
-      && GST_EVENT_TYPE (event) != GST_EVENT_NEWSEGMENT
+      && GST_EVENT_TYPE (event) != GST_EVENT_SEGMENT
       && GST_EVENT_TYPE (event) != GST_EVENT_FLUSH_START
       && GST_EVENT_TYPE (event) != GST_EVENT_FLUSH_STOP) {
 
@@ -913,36 +910,52 @@ gst_base_parse_sink_eventfunc (GstBaseParse * parse, GstEvent * event)
   GstEvent **eventp;
 
   switch (GST_EVENT_TYPE (event)) {
-    case GST_EVENT_NEWSEGMENT:
+    case GST_EVENT_CAPS:
     {
+      GstCaps *caps;
+      GstBaseParseClass *klass;
+
+      klass = GST_BASE_PARSE_GET_CLASS (parse);
+
+      gst_event_parse_caps (event, &caps);
+      GST_DEBUG_OBJECT (parse, "caps: %" GST_PTR_FORMAT, caps);
+
+      if (klass->set_sink_caps)
+        klass->set_sink_caps (parse, caps);
+
+      handled = TRUE;
+      break;
+    }
+    case GST_EVENT_SEGMENT:
+    {
+      const GstSegment *in_segment;
+      GstSegment out_segment;
+      gint64 offset = 0, next_ts;
+
+#if 0
       gdouble rate, applied_rate;
       GstFormat format;
-      gint64 start, stop, pos, next_ts, offset = 0;
+      gint64 start, stop, pos, next_ts;
       gboolean update;
+#endif
 
-      gst_event_parse_new_segment_full (event, &update, &rate, &applied_rate,
-          &format, &start, &stop, &pos);
+      gst_event_parse_segment (event, &in_segment);
+      gst_segment_init (&out_segment, GST_FORMAT_TIME);
 
-      GST_DEBUG_OBJECT (parse, "newseg rate %g, applied rate %g, "
-          "format %d, start = %" GST_TIME_FORMAT ", stop = %" GST_TIME_FORMAT
-          ", pos = %" GST_TIME_FORMAT, rate, applied_rate, format,
-          GST_TIME_ARGS (start), GST_TIME_ARGS (stop), GST_TIME_ARGS (pos));
+      GST_DEBUG_OBJECT (parse, "segment %" GST_SEGMENT_FORMAT, in_segment);
 
-      if (format == GST_FORMAT_BYTES) {
-        GstClockTime seg_start, seg_stop;
+      if (in_segment->format == GST_FORMAT_BYTES) {
         GstBaseParseSeek *seek = NULL;
         GSList *node;
 
         /* stop time is allowed to be open-ended, but not start & pos */
-        seg_stop = GST_CLOCK_TIME_NONE;
-        seg_start = 0;
-        offset = pos;
+        offset = in_segment->time;
 
         GST_OBJECT_LOCK (parse);
         for (node = parse->priv->pending_seeks; node; node = node->next) {
           GstBaseParseSeek *tmp = node->data;
 
-          if (tmp->offset == pos) {
+          if (tmp->offset == offset) {
             seek = tmp;
             break;
           }
@@ -955,8 +968,11 @@ gst_base_parse_sink_eventfunc (GstBaseParse * parse, GstEvent * event)
           GST_DEBUG_OBJECT (parse,
               "Matched newsegment to%s seek: %" GST_SEGMENT_FORMAT,
               seek->accurate ? " accurate" : "", &seek->segment);
-          seg_start = seek->segment.start;
-          seg_stop = seek->segment.stop;
+
+          out_segment.start = seek->segment.start;
+          out_segment.stop = seek->segment.stop;
+          out_segment.time = seek->segment.start;
+
           next_ts = seek->start_ts;
           parse->priv->exact_position = seek->accurate;
           g_free (seek);
@@ -964,39 +980,48 @@ gst_base_parse_sink_eventfunc (GstBaseParse * parse, GstEvent * event)
           /* best attempt convert */
           /* as these are only estimates, stop is kept open-ended to avoid
            * premature cutting */
-          gst_base_parse_convert (parse, GST_FORMAT_BYTES, start,
-              GST_FORMAT_TIME, (gint64 *) & seg_start);
-          parse->priv->exact_position = (start == 0);
-          next_ts = seg_start;
+          gst_base_parse_convert (parse, GST_FORMAT_BYTES, in_segment->start,
+              GST_FORMAT_TIME, (gint64 *) & next_ts);
+
+          out_segment.start = next_ts;
+          out_segment.stop = GST_CLOCK_TIME_NONE;
+          out_segment.time = next_ts;
+
+          parse->priv->exact_position = (in_segment->start == 0);
         }
 
         gst_event_unref (event);
-        event = gst_event_new_new_segment_full (update, rate, applied_rate,
-            GST_FORMAT_TIME, seg_start, seg_stop, seg_start);
-        format = GST_FORMAT_TIME;
-        start = seg_start;
-        stop = seg_stop;
+
+        event = gst_event_new_segment (&out_segment);
+
         GST_DEBUG_OBJECT (parse, "Converted incoming segment to TIME. "
-            "start = %" GST_TIME_FORMAT ", stop = %" GST_TIME_FORMAT,
-            GST_TIME_ARGS (seg_start), GST_TIME_ARGS (seg_stop));
-      } else if (format != GST_FORMAT_TIME) {
+            GST_SEGMENT_FORMAT, in_segment);
+
+      } else if (in_segment->format != GST_FORMAT_TIME) {
         /* Unknown incoming segment format. Output a default open-ended
          * TIME segment */
         gst_event_unref (event);
-        event = gst_event_new_new_segment_full (update, rate, applied_rate,
-            GST_FORMAT_TIME, 0, GST_CLOCK_TIME_NONE, 0);
-        format = GST_FORMAT_TIME;
-        next_ts = start = 0;
-        stop = GST_CLOCK_TIME_NONE;
+
+        out_segment.start = 0;
+        out_segment.stop = GST_CLOCK_TIME_NONE;;
+        out_segment.time = 0;;
+
+        event = gst_event_new_segment (&out_segment);
+
+        next_ts = 0;
       } else {
         /* not considered BYTE seekable if it is talking to us in TIME,
          * whatever else it might claim */
         parse->priv->upstream_seekable = FALSE;
-        next_ts = start;
+        next_ts = in_segment->start;
       }
 
-      gst_segment_set_newsegment_full (&parse->segment, update, rate,
-          applied_rate, format, start, stop, start);
+      memcpy (&parse->segment, &out_segment, sizeof (GstSegment));
+
+      /*
+         gst_segment_set_newsegment (&parse->segment, update, rate,
+         applied_rate, format, start, stop, start);
+       */
 
       /* save the segment for later, right before we push a new buffer so that
        * the caps are fixed and the next linked element can receive
@@ -1008,11 +1033,12 @@ gst_base_parse_sink_eventfunc (GstBaseParse * parse, GstEvent * event)
 
       /* but finish the current segment */
       GST_DEBUG_OBJECT (parse, "draining current segment");
-      if (parse->segment.rate > 0.0)
+      if (in_segment->rate > 0.0)
         gst_base_parse_drain (parse);
       else
         gst_base_parse_process_fragment (parse, FALSE);
       gst_adapter_clear (parse->priv->adapter);
+
       parse->priv->offset = offset;
       parse->priv->sync_offset = offset;
       parse->priv->next_ts = next_ts;
@@ -1310,7 +1336,7 @@ gst_base_parse_update_bitrates (GstBaseParse * parse, GstBaseParseFrame * frame)
   if (overhead == -1)
     return;
 
-  data_len = GST_BUFFER_SIZE (buffer) - overhead;
+  data_len = gst_buffer_get_size (buffer) - overhead;
   parse->priv->data_bytecount += data_len;
 
   /* duration should be valid by now,
@@ -1551,7 +1577,7 @@ gst_base_parse_check_media (GstBaseParse * parse)
   GstCaps *caps;
   GstStructure *s;
 
-  caps = GST_PAD_CAPS (parse->srcpad);
+  caps = gst_pad_get_current_caps (parse->srcpad);
   if (G_LIKELY (caps) && (s = gst_caps_get_structure (caps, 0))) {
     parse->priv->is_video =
         g_str_has_prefix (gst_structure_get_name (s), "video");
@@ -1559,6 +1585,8 @@ gst_base_parse_check_media (GstBaseParse * parse)
     /* historical default */
     parse->priv->is_video = FALSE;
   }
+  if (caps)
+    gst_caps_unref (caps);
 
   GST_DEBUG_OBJECT (parse, "media is video == %d", parse->priv->is_video);
 }
@@ -1622,7 +1650,7 @@ gst_base_parse_handle_and_push_frame (GstBaseParse * parse,
       "parsing frame at offset %" G_GUINT64_FORMAT
       " (%#" G_GINT64_MODIFIER "x) of size %d",
       GST_BUFFER_OFFSET (buffer), GST_BUFFER_OFFSET (buffer),
-      GST_BUFFER_SIZE (buffer));
+      gst_buffer_get_size (buffer));
 
   /* use default handler to provide initial (upstream) metadata */
   gst_base_parse_parse_frame (parse, frame);
@@ -1699,10 +1727,6 @@ gst_base_parse_handle_and_push_frame (GstBaseParse * parse,
     GstBaseParseFrame *queued_frame;
 
     while ((queued_frame = g_queue_pop_head (&parse->priv->queued_frames))) {
-      queued_frame->buffer =
-          gst_buffer_make_metadata_writable (queued_frame->buffer);
-      gst_buffer_set_caps (queued_frame->buffer,
-          GST_PAD_CAPS (GST_BASE_PARSE_SRC_PAD (parse)));
       gst_base_parse_push_frame (parse, queued_frame);
       gst_base_parse_frame_free (queued_frame);
     }
@@ -1735,6 +1759,7 @@ gst_base_parse_push_frame (GstBaseParse * parse, GstBaseParseFrame * frame)
   GstClockTime last_stop = GST_CLOCK_TIME_NONE;
   GstBaseParseClass *klass = GST_BASE_PARSE_GET_CLASS (parse);
   GstBuffer *buffer;
+  gsize size;
 
   g_return_val_if_fail (frame != NULL, GST_FLOW_ERROR);
   g_return_val_if_fail (frame->buffer != NULL, GST_FLOW_ERROR);
@@ -1745,12 +1770,13 @@ gst_base_parse_push_frame (GstBaseParse * parse, GstBaseParseFrame * frame)
 
   GST_LOG_OBJECT (parse,
       "processing buffer of size %d with ts %" GST_TIME_FORMAT
-      ", duration %" GST_TIME_FORMAT, GST_BUFFER_SIZE (buffer),
+      ", duration %" GST_TIME_FORMAT, gst_buffer_get_size (buffer),
       GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buffer)),
       GST_TIME_ARGS (GST_BUFFER_DURATION (buffer)));
 
   /* update stats */
-  parse->priv->bytecount += GST_BUFFER_SIZE (buffer);
+  size = gst_buffer_get_size (buffer);
+  parse->priv->bytecount += size;
   if (G_LIKELY (!(frame->flags & GST_BASE_PARSE_FRAME_FLAG_NO_FRAME))) {
     parse->priv->framecount++;
     if (GST_BUFFER_DURATION_IS_VALID (buffer)) {
@@ -1771,7 +1797,8 @@ gst_base_parse_push_frame (GstBaseParse * parse, GstBaseParseFrame * frame)
     last_stop = last_start + GST_BUFFER_DURATION (buffer);
 
   /* should have caps by now */
-  g_return_val_if_fail (GST_PAD_CAPS (parse->srcpad), GST_FLOW_ERROR);
+  g_return_val_if_fail (gst_pad_has_current_caps (parse->srcpad),
+      GST_FLOW_ERROR);
 
   /* segment adjustment magic; only if we are running the whole show */
   if (!parse->priv->passthrough && parse->segment.rate > 0.0 &&
@@ -1785,60 +1812,46 @@ gst_base_parse_push_frame (GstBaseParse * parse, GstBaseParseFrame * frame)
       gst_event_unref (parse->priv->pending_segment);
       parse->segment.start =
           MIN ((guint64) last_start, (guint64) parse->segment.stop);
+
       GST_DEBUG_OBJECT (parse,
           "adjusting pending segment start to %" GST_TIME_FORMAT,
           GST_TIME_ARGS (parse->segment.start));
-      parse->priv->pending_segment =
-          gst_event_new_new_segment (FALSE, parse->segment.rate,
-          parse->segment.format, parse->segment.start,
-          parse->segment.stop, parse->segment.start);
+
+      parse->priv->pending_segment = gst_event_new_segment (&parse->segment);
     }
     /* handle gaps, e.g. non-zero start-time, in as much not handled by above */
-    if (GST_CLOCK_TIME_IS_VALID (parse->segment.last_stop) &&
+    if (GST_CLOCK_TIME_IS_VALID (parse->segment.position) &&
         GST_CLOCK_TIME_IS_VALID (last_start)) {
       GstClockTimeDiff diff;
 
       /* only send newsegments with increasing start times,
        * otherwise if these go back and forth downstream (sinks) increase
        * accumulated time and running_time */
-      diff = GST_CLOCK_DIFF (parse->segment.last_stop, last_start);
+      diff = GST_CLOCK_DIFF (parse->segment.position, last_start);
       if (G_UNLIKELY (diff > 2 * GST_SECOND
               && last_start > parse->segment.start
               && (!GST_CLOCK_TIME_IS_VALID (parse->segment.stop)
                   || last_start < parse->segment.stop))) {
+
         GST_DEBUG_OBJECT (parse,
             "Gap of %" G_GINT64_FORMAT " ns detected in stream " "(%"
             GST_TIME_FORMAT " -> %" GST_TIME_FORMAT "). "
             "Sending updated NEWSEGMENT events", diff,
-            GST_TIME_ARGS (parse->segment.last_stop),
+            GST_TIME_ARGS (parse->segment.position),
             GST_TIME_ARGS (last_start));
+
         if (G_UNLIKELY (parse->priv->pending_segment)) {
           gst_event_unref (parse->priv->pending_segment);
           parse->segment.start = last_start;
+          parse->segment.time = last_start;
           parse->priv->pending_segment =
-              gst_event_new_new_segment (FALSE, parse->segment.rate,
-              parse->segment.format, parse->segment.start,
-              parse->segment.stop, parse->segment.start);
+              gst_event_new_segment (&parse->segment);
         } else {
-          /* send newsegment events such that the gap is not accounted in
-           * accum time, hence running_time */
-          /* close ahead of gap */
-          gst_pad_push_event (parse->srcpad,
-              gst_event_new_new_segment (TRUE, parse->segment.rate,
-                  parse->segment.format, parse->segment.last_stop,
-                  parse->segment.last_stop, parse->segment.last_stop));
-          /* skip gap */
+          /* skip gap FIXME */
           gst_pad_push_event (parse->srcpad,
-              gst_event_new_new_segment (FALSE, parse->segment.rate,
-                  parse->segment.format, last_start,
-                  parse->segment.stop, last_start));
+              gst_event_new_segment (&parse->segment));
         }
-        /* align segment view with downstream,
-         * prevents double-counting accum when closing segment */
-        gst_segment_set_newsegment (&parse->segment, FALSE,
-            parse->segment.rate, parse->segment.format, last_start,
-            parse->segment.stop, last_start);
-        parse->segment.last_stop = last_start;
+        parse->segment.position = last_start;
       }
     }
   }
@@ -1887,10 +1900,6 @@ gst_base_parse_push_frame (GstBaseParse * parse, GstBaseParseFrame * frame)
   /* subclass must play nice */
   g_return_val_if_fail (buffer != NULL, GST_FLOW_ERROR);
 
-  /* decorate */
-  buffer = gst_buffer_make_metadata_writable (buffer);
-  gst_buffer_set_caps (buffer, GST_PAD_CAPS (parse->srcpad));
-
   parse->priv->seen_keyframe |= parse->priv->is_video &&
       !GST_BUFFER_FLAG_IS_SET (buffer, GST_BUFFER_FLAG_DELTA_UNIT);
 
@@ -1919,26 +1928,25 @@ gst_base_parse_push_frame (GstBaseParse * parse, GstBaseParseFrame * frame)
   }
 
   if (ret == GST_BASE_PARSE_FLOW_DROPPED) {
-    GST_LOG_OBJECT (parse, "frame (%d bytes) dropped",
-        GST_BUFFER_SIZE (buffer));
+    GST_LOG_OBJECT (parse, "frame (%" G_GSIZE_FORMAT " bytes) dropped", size);
     gst_buffer_unref (buffer);
     ret = GST_FLOW_OK;
   } else if (ret == GST_FLOW_OK) {
     if (parse->segment.rate > 0.0) {
       ret = gst_pad_push (parse->srcpad, buffer);
-      GST_LOG_OBJECT (parse, "frame (%d bytes) pushed: %s",
-          GST_BUFFER_SIZE (buffer), gst_flow_get_name (ret));
+      GST_LOG_OBJECT (parse, "frame (%" G_GSIZE_FORMAT " bytes) pushed: %s",
+          size, gst_flow_get_name (ret));
     } else {
-      GST_LOG_OBJECT (parse, "frame (%d bytes) queued for now",
-          GST_BUFFER_SIZE (buffer));
+      GST_LOG_OBJECT (parse, "frame (%" G_GSIZE_FORMAT " bytes) queued for now",
+          size);
       parse->priv->buffers_queued =
           g_slist_prepend (parse->priv->buffers_queued, buffer);
       ret = GST_FLOW_OK;
     }
   } else {
     gst_buffer_unref (buffer);
-    GST_LOG_OBJECT (parse, "frame (%d bytes) not pushed: %s",
-        GST_BUFFER_SIZE (buffer), gst_flow_get_name (ret));
+    GST_LOG_OBJECT (parse, "frame (%" G_GSIZE_FORMAT " bytes) not pushed: %s",
+        size, gst_flow_get_name (ret));
     /* if we are not sufficiently in control, let upstream decide on EOS */
     if (ret == GST_FLOW_UNEXPECTED &&
         (parse->priv->passthrough ||
@@ -1949,8 +1957,8 @@ gst_base_parse_push_frame (GstBaseParse * parse, GstBaseParseFrame * frame)
 
   /* Update current running segment position */
   if (ret == GST_FLOW_OK && last_stop != GST_CLOCK_TIME_NONE &&
-      parse->segment.last_stop < last_stop)
-    gst_segment_set_last_stop (&parse->segment, GST_FORMAT_TIME, last_stop);
+      parse->segment.position < last_stop)
+    parse->segment.position = last_stop;
 
   gst_base_parse_frame_free (frame);
 
@@ -2056,7 +2064,7 @@ gst_base_parse_process_fragment (GstBaseParse * parse, gboolean push_only)
   while (parse->priv->buffers_pending) {
     buf = GST_BUFFER_CAST (parse->priv->buffers_pending->data);
     GST_LOG_OBJECT (parse, "adding pending buffer (size %d)",
-        GST_BUFFER_SIZE (buf));
+        gst_buffer_get_size (buf));
     gst_adapter_push (parse->priv->adapter, buf);
     parse->priv->buffers_pending =
         g_slist_delete_link (parse->priv->buffers_pending,
@@ -2067,7 +2075,7 @@ gst_base_parse_process_fragment (GstBaseParse * parse, gboolean push_only)
    * ok if taken from subclass or upstream */
   parse->priv->next_ts = GST_CLOCK_TIME_NONE;
   /* prevent it hanging around stop all the time */
-  parse->segment.last_stop = GST_CLOCK_TIME_NONE;
+  parse->segment.position = GST_CLOCK_TIME_NONE;
   /* mark next run */
   parse->priv->discont = TRUE;
 
@@ -2184,10 +2192,10 @@ gst_base_parse_chain (GstPad * pad, GstBuffer * buffer)
 
   if (G_LIKELY (buffer)) {
     GST_LOG_OBJECT (parse, "buffer size: %d, offset = %" G_GINT64_FORMAT,
-        GST_BUFFER_SIZE (buffer), GST_BUFFER_OFFSET (buffer));
+        gst_buffer_get_size (buffer), GST_BUFFER_OFFSET (buffer));
     if (G_UNLIKELY (parse->priv->passthrough)) {
       gst_base_parse_frame_init (frame);
-      frame->buffer = gst_buffer_make_metadata_writable (buffer);
+      frame->buffer = gst_buffer_make_writable (buffer);
       return gst_base_parse_push_frame (parse, frame);
     }
     /* upstream feeding us in reverse playback;
@@ -2252,11 +2260,11 @@ gst_base_parse_chain (GstPad * pad, GstBuffer * buffer)
       }
 
       /* always pass all available data */
-      data = gst_adapter_peek (parse->priv->adapter, av);
-      GST_BUFFER_DATA (tmpbuf) = (guint8 *) data;
-      GST_BUFFER_SIZE (tmpbuf) = av;
+      data = gst_adapter_map (parse->priv->adapter, av);
+      gst_buffer_take_memory (tmpbuf, -1,
+          gst_memory_new_wrapped (GST_MEMORY_FLAG_READONLY,
+              (gpointer) data, NULL, av, 0, av));
       GST_BUFFER_OFFSET (tmpbuf) = parse->priv->offset;
-      GST_BUFFER_FLAG_SET (tmpbuf, GST_MINI_OBJECT_FLAG_READONLY);
 
       if (parse->priv->discont) {
         GST_DEBUG_OBJECT (parse, "marking DISCONT");
@@ -2266,6 +2274,7 @@ gst_base_parse_chain (GstPad * pad, GstBuffer * buffer)
       skip = -1;
       gst_base_parse_frame_update (parse, frame, tmpbuf);
       res = bclass->check_valid_frame (parse, frame, &fsize, &skip);
+      gst_adapter_unmap (parse->priv->adapter, 0);
       gst_buffer_replace (&frame->buffer, NULL);
       if (res) {
         if (gst_adapter_available (parse->priv->adapter) < fsize) {
@@ -2290,7 +2299,7 @@ gst_base_parse_chain (GstPad * pad, GstBuffer * buffer)
            * fragment coming later, hopefully subclass skips efficiently ... */
           timestamp = gst_adapter_prev_timestamp (parse->priv->adapter, NULL);
           outbuf = gst_adapter_take_buffer (parse->priv->adapter, skip);
-          outbuf = gst_buffer_make_metadata_writable (outbuf);
+          outbuf = gst_buffer_make_writable (outbuf);
           GST_BUFFER_TIMESTAMP (outbuf) = timestamp;
           parse->priv->buffers_pending =
               g_slist_prepend (parse->priv->buffers_pending, outbuf);
@@ -2342,7 +2351,7 @@ gst_base_parse_chain (GstPad * pad, GstBuffer * buffer)
 
     /* FIXME: Would it be more efficient to make a subbuffer instead? */
     outbuf = gst_adapter_take_buffer (parse->priv->adapter, fsize);
-    outbuf = gst_buffer_make_metadata_writable (outbuf);
+    outbuf = gst_buffer_make_writable (outbuf);
 
     /* Subclass may want to know the data offset */
     GST_BUFFER_OFFSET (outbuf) = parse->priv->offset;
@@ -2388,11 +2397,11 @@ gst_base_parse_pull_range (GstBaseParse * parse, guint size,
    * We do it mainly to avoid pulling buffers of 1 byte all the time */
   if (parse->priv->cache) {
     gint64 cache_offset = GST_BUFFER_OFFSET (parse->priv->cache);
-    gint cache_size = GST_BUFFER_SIZE (parse->priv->cache);
+    gint cache_size = gst_buffer_get_size (parse->priv->cache);
 
     if (cache_offset <= parse->priv->offset &&
         (parse->priv->offset + size) <= (cache_offset + cache_size)) {
-      *buffer = gst_buffer_create_sub (parse->priv->cache,
+      *buffer = gst_buffer_copy_region (parse->priv->cache, GST_BUFFER_COPY_ALL,
           parse->priv->offset - cache_offset, size);
       GST_BUFFER_OFFSET (*buffer) = parse->priv->offset;
       return GST_FLOW_OK;
@@ -2411,8 +2420,10 @@ gst_base_parse_pull_range (GstBaseParse * parse, guint size,
     return ret;
   }
 
-  if (GST_BUFFER_SIZE (parse->priv->cache) >= size) {
-    *buffer = gst_buffer_create_sub (parse->priv->cache, 0, size);
+  if (gst_buffer_get_size (parse->priv->cache) >= size) {
+    *buffer =
+        gst_buffer_copy_region (parse->priv->cache, GST_BUFFER_COPY_ALL, 0,
+        size);
     GST_BUFFER_OFFSET (*buffer) = parse->priv->offset;
     return GST_FLOW_OK;
   }
@@ -2431,10 +2442,10 @@ gst_base_parse_pull_range (GstBaseParse * parse, guint size,
     return ret;
   }
 
-  if (GST_BUFFER_SIZE (parse->priv->cache) < size) {
+  if (gst_buffer_get_size (parse->priv->cache) < size) {
     GST_DEBUG_OBJECT (parse, "Returning short buffer at offset %"
         G_GUINT64_FORMAT ": wanted %u bytes, got %u bytes", parse->priv->offset,
-        size, GST_BUFFER_SIZE (parse->priv->cache));
+        size, gst_buffer_get_size (parse->priv->cache));
 
     *buffer = parse->priv->cache;
     parse->priv->cache = NULL;
@@ -2442,7 +2453,8 @@ gst_base_parse_pull_range (GstBaseParse * parse, guint size,
     return GST_FLOW_OK;
   }
 
-  *buffer = gst_buffer_create_sub (parse->priv->cache, 0, size);
+  *buffer =
+      gst_buffer_copy_region (parse->priv->cache, GST_BUFFER_COPY_ALL, 0, size);
   GST_BUFFER_OFFSET (*buffer) = parse->priv->offset;
 
   return GST_FLOW_OK;
@@ -2553,7 +2565,7 @@ gst_base_parse_scan_frame (GstBaseParse * parse, GstBaseParseClass * klass,
 
     /* if we got a short read, inform subclass we are draining leftover
      * and no more is to be expected */
-    if (GST_BUFFER_SIZE (buffer) < min_size)
+    if (gst_buffer_get_size (buffer) < min_size)
       parse->priv->drain = TRUE;
 
     skip = -1;
@@ -2574,7 +2586,7 @@ gst_base_parse_scan_frame (GstBaseParse * parse, GstBaseParseClass * klass,
         /* reverse playback, and no frames found yet, so we are skipping
          * the leading part of a fragment, which may form the tail of
          * fragment coming later, hopefully subclass skips efficiently ... */
-        outbuf = gst_buffer_create_sub (buffer, 0, skip);
+        outbuf = gst_buffer_copy_region (buffer, GST_BUFFER_COPY_ALL, 0, skip);
         parse->priv->buffers_pending =
             g_slist_prepend (parse->priv->buffers_pending, outbuf);
         outbuf = NULL;
@@ -2603,8 +2615,8 @@ gst_base_parse_scan_frame (GstBaseParse * parse, GstBaseParseClass * klass,
   else if (skip < 0)
     skip = 0;
 
-  if (fsize + skip <= GST_BUFFER_SIZE (buffer)) {
-    outbuf = gst_buffer_create_sub (buffer, skip, fsize);
+  if (fsize + skip <= gst_buffer_get_size (buffer)) {
+    outbuf = gst_buffer_copy_region (buffer, GST_BUFFER_COPY_ALL, skip, fsize);
     GST_BUFFER_OFFSET (outbuf) = GST_BUFFER_OFFSET (buffer) + skip;
     GST_BUFFER_TIMESTAMP (outbuf) = GST_CLOCK_TIME_NONE;
     gst_buffer_unref (buffer);
@@ -2613,7 +2625,7 @@ gst_base_parse_scan_frame (GstBaseParse * parse, GstBaseParseClass * klass,
     ret = gst_base_parse_pull_range (parse, fsize, &outbuf);
     if (ret != GST_FLOW_OK)
       goto done;
-    if (GST_BUFFER_SIZE (outbuf) < fsize) {
+    if (gst_buffer_get_size (outbuf) < fsize) {
       gst_buffer_unref (outbuf);
       ret = GST_FLOW_UNEXPECTED;
     }
@@ -2670,7 +2682,7 @@ gst_base_parse_loop (GstPad * pad)
 
   /* eat expected eos signalling past segment in reverse playback */
   if (parse->segment.rate < 0.0 && ret == GST_FLOW_UNEXPECTED &&
-      parse->segment.last_stop >= parse->segment.stop) {
+      parse->segment.position >= parse->segment.stop) {
     GST_DEBUG_OBJECT (parse, "downstream has reached end of segment");
     /* push what was accumulated during loop run */
     gst_base_parse_process_fragment (parse, TRUE);
@@ -2750,12 +2762,24 @@ gst_base_parse_sink_activate (GstPad * sinkpad)
 {
   GstBaseParse *parse;
   gboolean result = TRUE;
+  GstQuery *query;
+  gboolean pull_mode;
 
   parse = GST_BASE_PARSE (gst_pad_get_parent (sinkpad));
 
   GST_DEBUG_OBJECT (parse, "sink activate");
 
-  if (gst_pad_check_pull_range (sinkpad)) {
+  query = gst_query_new_scheduling ();
+  result = gst_pad_peer_query (sinkpad, query);
+  if (result) {
+    gst_query_parse_scheduling (query, &pull_mode, NULL, NULL, NULL, NULL,
+        NULL);
+  } else {
+    pull_mode = FALSE;
+  }
+  gst_query_unref (query);
+
+  if (pull_mode) {
     GST_DEBUG_OBJECT (parse, "trying to activate in pull mode");
     result = gst_pad_activate_pull (sinkpad, TRUE);
   } else {
@@ -2831,9 +2855,7 @@ gst_base_parse_sink_activate_pull (GstPad * sinkpad, gboolean active)
 
   if (result) {
     if (active) {
-      parse->priv->pending_segment = gst_event_new_new_segment (FALSE,
-          parse->segment.rate, parse->segment.format,
-          parse->segment.start, parse->segment.stop, parse->segment.last_stop);
+      parse->priv->pending_segment = gst_event_new_segment (&parse->segment);
       result &=
           gst_pad_start_task (sinkpad, (GstTaskFunction) gst_base_parse_loop,
           sinkpad);
@@ -3148,8 +3170,8 @@ gst_base_parse_query (GstPad * pad, GstQuery * query)
         dest_value = parse->priv->offset;
         res = TRUE;
       } else if (format == parse->segment.format &&
-          GST_CLOCK_TIME_IS_VALID (parse->segment.last_stop)) {
-        dest_value = parse->segment.last_stop;
+          GST_CLOCK_TIME_IS_VALID (parse->segment.position)) {
+        dest_value = parse->segment.position;
         res = TRUE;
       }
       GST_OBJECT_UNLOCK (parse);
@@ -3284,9 +3306,9 @@ gst_base_parse_find_frame (GstBaseParse * parse, gint64 * pos,
   GstBuffer *buf = NULL;
   GstBaseParseFrame frame;
 
-  g_return_val_if_fail (GST_FLOW_ERROR, pos != NULL);
-  g_return_val_if_fail (GST_FLOW_ERROR, time != NULL);
-  g_return_val_if_fail (GST_FLOW_ERROR, duration != NULL);
+  g_return_val_if_fail (pos != NULL, GST_FLOW_ERROR);
+  g_return_val_if_fail (time != NULL, GST_FLOW_ERROR);
+  g_return_val_if_fail (duration != NULL, GST_FLOW_ERROR);
 
   klass = GST_BASE_PARSE_GET_CLASS (parse);
 
@@ -3313,7 +3335,8 @@ gst_base_parse_find_frame (GstBaseParse * parse, gint64 * pos,
   GST_LOG_OBJECT (parse,
       "peek parsing frame at offset %" G_GUINT64_FORMAT
       " (%#" G_GINT64_MODIFIER "x) of size %d",
-      GST_BUFFER_OFFSET (buf), GST_BUFFER_OFFSET (buf), GST_BUFFER_SIZE (buf));
+      GST_BUFFER_OFFSET (buf), GST_BUFFER_OFFSET (buf),
+      gst_buffer_get_size (buf));
 
   /* get offset first, subclass parsing might dump other stuff in there */
   *pos = GST_BUFFER_OFFSET (buf);
@@ -3571,10 +3594,10 @@ gst_base_parse_handle_seek (GstBaseParse * parse, GstEvent * event)
 
   /* copy segment, we need this because we still need the old
    * segment when we close the current segment. */
-  memcpy (&seeksegment, &parse->segment, sizeof (GstSegment));
+  gst_segment_copy_into (&parse->segment, &seeksegment);
 
   GST_DEBUG_OBJECT (parse, "configuring seek");
-  gst_segment_set_seek (&seeksegment, rate, format, flags,
+  gst_segment_do_seek (&seeksegment, rate, format, flags,
       cur_type, cur, stop_type, stop, &update);
 
   /* accurate seeking implies seek tables are used to obtain position,
@@ -3582,13 +3605,13 @@ gst_base_parse_handle_seek (GstBaseParse * parse, GstEvent * event)
   accurate = flags & GST_SEEK_FLAG_ACCURATE;
 
   /* maybe we can be accurate for (almost) free */
-  gst_base_parse_find_offset (parse, seeksegment.last_stop, TRUE, &start_ts);
-  if (seeksegment.last_stop <= start_ts + TARGET_DIFFERENCE) {
+  gst_base_parse_find_offset (parse, seeksegment.position, TRUE, &start_ts);
+  if (seeksegment.position <= start_ts + TARGET_DIFFERENCE) {
     GST_DEBUG_OBJECT (parse, "accurate seek possible");
     accurate = TRUE;
   }
   if (accurate) {
-    GstClockTime startpos = seeksegment.last_stop;
+    GstClockTime startpos = seeksegment.position;
 
     /* accurate requested, so ... seek a bit before target */
     if (startpos < parse->priv->lead_in_ts)
@@ -3599,9 +3622,9 @@ gst_base_parse_handle_seek (GstBaseParse * parse, GstEvent * event)
     seekstop = gst_base_parse_find_offset (parse, seeksegment.stop, FALSE,
         NULL);
   } else {
-    start_ts = seeksegment.last_stop;
+    start_ts = seeksegment.position;
     dstformat = GST_FORMAT_BYTES;
-    if (!gst_pad_query_convert (parse->srcpad, format, seeksegment.last_stop,
+    if (!gst_pad_query_convert (parse->srcpad, format, seeksegment.position,
             &dstformat, &seekpos))
       goto convert_failed;
     if (!gst_pad_query_convert (parse->srcpad, format, seeksegment.stop,
@@ -3637,7 +3660,7 @@ gst_base_parse_handle_seek (GstBaseParse * parse, GstEvent * event)
     GST_PAD_STREAM_LOCK (parse->sinkpad);
 
     /* save current position */
-    last_stop = parse->segment.last_stop;
+    last_stop = parse->segment.position;
     GST_DEBUG_OBJECT (parse, "stopped streaming at %" G_GINT64_FORMAT,
         last_stop);
 
@@ -3646,26 +3669,13 @@ gst_base_parse_handle_seek (GstBaseParse * parse, GstEvent * event)
     /* prepare for streaming again */
     if (flush) {
       GST_DEBUG_OBJECT (parse, "sending flush stop");
-      gst_pad_push_event (parse->srcpad, gst_event_new_flush_stop ());
-      gst_pad_push_event (parse->sinkpad, gst_event_new_flush_stop ());
+      gst_pad_push_event (parse->srcpad, gst_event_new_flush_stop (TRUE));
+      gst_pad_push_event (parse->sinkpad, gst_event_new_flush_stop (TRUE));
       gst_base_parse_clear_queues (parse);
     } else {
-      if (parse->priv->close_segment)
-        gst_event_unref (parse->priv->close_segment);
-
-      parse->priv->close_segment = gst_event_new_new_segment (TRUE,
-          parse->segment.rate, parse->segment.format,
-          parse->segment.accum, parse->segment.last_stop, parse->segment.accum);
-
-      /* keep track of our last_stop */
-      seeksegment.accum = parse->segment.last_stop;
-
-      GST_DEBUG_OBJECT (parse, "Created close seg format %d, "
-          "start = %" GST_TIME_FORMAT ", stop = %" GST_TIME_FORMAT
-          ", pos = %" GST_TIME_FORMAT, format,
-          GST_TIME_ARGS (parse->segment.accum),
-          GST_TIME_ARGS (parse->segment.last_stop),
-          GST_TIME_ARGS (parse->segment.accum));
+      /* keep track of our position */
+      seeksegment.base = gst_segment_to_running_time (&seeksegment,
+          seeksegment.format, parse->segment.position);
     }
 
     memcpy (&parse->segment, &seeksegment, sizeof (GstSegment));
@@ -3675,10 +3685,7 @@ gst_base_parse_handle_seek (GstBaseParse * parse, GstEvent * event)
       gst_event_unref (parse->priv->pending_segment);
 
     /* This will be sent later in _loop() */
-    parse->priv->pending_segment =
-        gst_event_new_new_segment (FALSE, parse->segment.rate,
-        parse->segment.format, parse->segment.start,
-        parse->segment.stop, parse->segment.start);
+    parse->priv->pending_segment = gst_event_new_segment (&parse->segment);
 
     GST_DEBUG_OBJECT (parse, "Created newseg format %d, "
         "start = %" GST_TIME_FORMAT ", stop = %" GST_TIME_FORMAT
@@ -3691,7 +3698,7 @@ gst_base_parse_handle_seek (GstBaseParse * parse, GstEvent * event)
      * maybe scan and subclass can find where to go */
     if (!accurate) {
       gint64 scanpos;
-      GstClockTime ts = seeksegment.last_stop;
+      GstClockTime ts = seeksegment.position;
 
       gst_base_parse_locate_time (parse, &ts, &scanpos);
       if (scanpos >= 0) {
@@ -3818,24 +3825,6 @@ gst_base_parse_handle_tag (GstBaseParse * parse, GstEvent * event)
   }
 }
 
-static gboolean
-gst_base_parse_sink_setcaps (GstPad * pad, GstCaps * caps)
-{
-  GstBaseParse *parse;
-  GstBaseParseClass *klass;
-  gboolean res = TRUE;
-
-  parse = GST_BASE_PARSE (GST_PAD_PARENT (pad));
-  klass = GST_BASE_PARSE_GET_CLASS (parse);
-
-  GST_DEBUG_OBJECT (parse, "caps: %" GST_PTR_FORMAT, caps);
-
-  if (klass->set_sink_caps)
-    res = klass->set_sink_caps (parse, caps);
-
-  return res;
-}
-
 static void
 gst_base_parse_set_index (GstElement * element, GstIndex * index)
 {
index c342d3c..5a74fe7 100644 (file)
  *
  * #GstBaseSink provides support for exactly one sink pad, which should be
  * named "sink". A sink implementation (subclass of #GstBaseSink) should
- * install a pad template in its base_init function, like so:
+ * install a pad template in its class_init function, like so:
  * |[
  * static void
- * my_element_base_init (gpointer g_class)
+ * my_element_class_init (GstMyElementClass *klass)
  * {
- *   GstElementClass *gstelement_class = GST_ELEMENT_CLASS (g_class);
+ *   GstElementClass *gstelement_class = GST_ELEMENT_CLASS (klass);
  *
  *   // sinktemplate should be a #GstStaticPadTemplate with direction
  *   // #GST_PAD_SINK and name "sink"
  * very specific elements (such as file sinks) which need to handle the
  * newsegment event specially.
  *
- * #GstBaseSink provides an overridable #GstBaseSinkClass.buffer_alloc()
- * function that can be used by sinks that want to do reverse negotiation or to
- * provide custom buffers (hardware buffers for example) to upstream elements.
- *
  * The #GstBaseSinkClass.unlock() method is called when the elements should
  * unblock any blocking operations they perform in the
  * #GstBaseSinkClass.render() method. This is mostly useful when the
@@ -266,6 +262,8 @@ struct _GstBaseSinkPrivate
   /* for throttling and QoS */
   GstClockTime earliest_in_time;
   GstClockTime throttle_time;
+
+  gboolean reset_time;
 };
 
 #define DO_RUNNING_AVG(avg,val,size) (((val) + ((size)-1) * (avg)) / (size))
@@ -367,10 +365,8 @@ static gboolean gst_base_sink_send_event (GstElement * element,
 static gboolean gst_base_sink_query (GstElement * element, GstQuery * query);
 static const GstQueryType *gst_base_sink_get_query_types (GstElement * element);
 
-static GstCaps *gst_base_sink_get_caps (GstBaseSink * sink);
+static GstCaps *gst_base_sink_get_caps (GstBaseSink * sink, GstCaps * caps);
 static gboolean gst_base_sink_set_caps (GstBaseSink * sink, GstCaps * caps);
-static GstFlowReturn gst_base_sink_buffer_alloc (GstBaseSink * sink,
-    guint64 offset, guint size, GstCaps * caps, GstBuffer ** buf);
 static void gst_base_sink_get_times (GstBaseSink * basesink, GstBuffer * buffer,
     GstClockTime * start, GstClockTime * end);
 static gboolean gst_base_sink_set_flushing (GstBaseSink * basesink,
@@ -396,12 +392,8 @@ static gboolean gst_base_sink_pad_activate_pull (GstPad * pad, gboolean active);
 static gboolean gst_base_sink_event (GstPad * pad, GstEvent * event);
 
 static gboolean gst_base_sink_negotiate_pull (GstBaseSink * basesink);
-static GstCaps *gst_base_sink_pad_getcaps (GstPad * pad);
-static gboolean gst_base_sink_pad_setcaps (GstPad * pad, GstCaps * caps);
+static GstCaps *gst_base_sink_pad_getcaps (GstPad * pad, GstCaps * filter);
 static void gst_base_sink_pad_fixate (GstPad * pad, GstCaps * caps);
-static GstFlowReturn gst_base_sink_pad_buffer_alloc (GstPad * pad,
-    guint64 offset, guint size, GstCaps * caps, GstBuffer ** buf);
-
 
 /* check if an object was too late */
 static gboolean gst_base_sink_is_too_late (GstBaseSink * basesink,
@@ -505,7 +497,7 @@ gst_base_sink_class_init (GstBaseSinkClass * klass)
    * Since: 0.10.15
    */
   g_object_class_install_property (gobject_class, PROP_LAST_BUFFER,
-      gst_param_spec_mini_object ("last-buffer", "Last Buffer",
+      g_param_spec_boxed ("last-buffer", "Last Buffer",
           "The last buffer received in the sink", GST_TYPE_BUFFER,
           G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
   /**
@@ -556,16 +548,13 @@ gst_base_sink_class_init (GstBaseSinkClass * klass)
 
   klass->get_caps = GST_DEBUG_FUNCPTR (gst_base_sink_get_caps);
   klass->set_caps = GST_DEBUG_FUNCPTR (gst_base_sink_set_caps);
-  klass->buffer_alloc = GST_DEBUG_FUNCPTR (gst_base_sink_buffer_alloc);
   klass->get_times = GST_DEBUG_FUNCPTR (gst_base_sink_get_times);
   klass->activate_pull =
       GST_DEBUG_FUNCPTR (gst_base_sink_default_activate_pull);
 
   /* Registering debug symbols for function pointers */
   GST_DEBUG_REGISTER_FUNCPTR (gst_base_sink_pad_getcaps);
-  GST_DEBUG_REGISTER_FUNCPTR (gst_base_sink_pad_setcaps);
   GST_DEBUG_REGISTER_FUNCPTR (gst_base_sink_pad_fixate);
-  GST_DEBUG_REGISTER_FUNCPTR (gst_base_sink_pad_buffer_alloc);
   GST_DEBUG_REGISTER_FUNCPTR (gst_base_sink_pad_activate);
   GST_DEBUG_REGISTER_FUNCPTR (gst_base_sink_pad_activate_push);
   GST_DEBUG_REGISTER_FUNCPTR (gst_base_sink_pad_activate_pull);
@@ -575,7 +564,7 @@ gst_base_sink_class_init (GstBaseSinkClass * klass)
 }
 
 static GstCaps *
-gst_base_sink_pad_getcaps (GstPad * pad)
+gst_base_sink_pad_getcaps (GstPad * pad, GstCaps * filter)
 {
   GstBaseSinkClass *bclass;
   GstBaseSink *bsink;
@@ -586,14 +575,11 @@ gst_base_sink_pad_getcaps (GstPad * pad)
 
   if (bsink->pad_mode == GST_ACTIVATE_PULL) {
     /* if we are operating in pull mode we only accept the negotiated caps */
-    GST_OBJECT_LOCK (pad);
-    if ((caps = GST_PAD_CAPS (pad)))
-      gst_caps_ref (caps);
-    GST_OBJECT_UNLOCK (pad);
+    caps = gst_pad_get_current_caps (pad);
   }
   if (caps == NULL) {
     if (bclass->get_caps)
-      caps = bclass->get_caps (bsink);
+      caps = bclass->get_caps (bsink, filter);
 
     if (caps == NULL) {
       GstPadTemplate *pad_template;
@@ -602,7 +588,16 @@ gst_base_sink_pad_getcaps (GstPad * pad)
           gst_element_class_get_pad_template (GST_ELEMENT_CLASS (bclass),
           "sink");
       if (pad_template != NULL) {
-        caps = gst_caps_ref (gst_pad_template_get_caps (pad_template));
+        caps = gst_pad_template_get_caps (pad_template);
+
+        if (filter) {
+          GstCaps *intersection;
+
+          intersection =
+              gst_caps_intersect_full (filter, caps, GST_CAPS_INTERSECT_FIRST);
+          gst_caps_unref (caps);
+          caps = intersection;
+        }
       }
     }
   }
@@ -611,24 +606,6 @@ gst_base_sink_pad_getcaps (GstPad * pad)
   return caps;
 }
 
-static gboolean
-gst_base_sink_pad_setcaps (GstPad * pad, GstCaps * caps)
-{
-  GstBaseSinkClass *bclass;
-  GstBaseSink *bsink;
-  gboolean res = TRUE;
-
-  bsink = GST_BASE_SINK (gst_pad_get_parent (pad));
-  bclass = GST_BASE_SINK_GET_CLASS (bsink);
-
-  if (res && bclass->set_caps)
-    res = bclass->set_caps (bsink, caps);
-
-  gst_object_unref (bsink);
-
-  return res;
-}
-
 static void
 gst_base_sink_pad_fixate (GstPad * pad, GstCaps * caps)
 {
@@ -644,29 +621,6 @@ gst_base_sink_pad_fixate (GstPad * pad, GstCaps * caps)
   gst_object_unref (bsink);
 }
 
-static GstFlowReturn
-gst_base_sink_pad_buffer_alloc (GstPad * pad, guint64 offset, guint size,
-    GstCaps * caps, GstBuffer ** buf)
-{
-  GstBaseSinkClass *bclass;
-  GstBaseSink *bsink;
-  GstFlowReturn result = GST_FLOW_OK;
-
-  bsink = GST_BASE_SINK (gst_pad_get_parent (pad));
-  if (G_UNLIKELY (bsink == NULL))
-    return GST_FLOW_WRONG_STATE;
-  bclass = GST_BASE_SINK_GET_CLASS (bsink);
-
-  if (bclass->buffer_alloc)
-    result = bclass->buffer_alloc (bsink, offset, size, caps, buf);
-  else
-    *buf = NULL;                /* fallback in gstpad.c will allocate generic buffer */
-
-  gst_object_unref (bsink);
-
-  return result;
-}
-
 static void
 gst_base_sink_init (GstBaseSink * basesink, gpointer g_class)
 {
@@ -682,10 +636,7 @@ gst_base_sink_init (GstBaseSink * basesink, gpointer g_class)
   basesink->sinkpad = gst_pad_new_from_template (pad_template, "sink");
 
   gst_pad_set_getcaps_function (basesink->sinkpad, gst_base_sink_pad_getcaps);
-  gst_pad_set_setcaps_function (basesink->sinkpad, gst_base_sink_pad_setcaps);
   gst_pad_set_fixatecaps_function (basesink->sinkpad, gst_base_sink_pad_fixate);
-  gst_pad_set_bufferalloc_function (basesink->sinkpad,
-      gst_base_sink_pad_buffer_alloc);
   gst_pad_set_activate_function (basesink->sinkpad, gst_base_sink_pad_activate);
   gst_pad_set_activatepush_function (basesink->sinkpad,
       gst_base_sink_pad_activate_push);
@@ -697,15 +648,16 @@ gst_base_sink_init (GstBaseSink * basesink, gpointer g_class)
   gst_element_add_pad (GST_ELEMENT_CAST (basesink), basesink->sinkpad);
 
   basesink->pad_mode = GST_ACTIVATE_NONE;
+  basesink->preroll_lock = g_mutex_new ();
+  basesink->preroll_cond = g_cond_new ();
   basesink->preroll_queue = g_queue_new ();
-  basesink->abidata.ABI.clip_segment = gst_segment_new ();
   priv->have_latency = FALSE;
 
   basesink->can_activate_push = DEFAULT_CAN_ACTIVATE_PUSH;
   basesink->can_activate_pull = DEFAULT_CAN_ACTIVATE_PULL;
 
   basesink->sync = DEFAULT_SYNC;
-  basesink->abidata.ABI.max_lateness = DEFAULT_MAX_LATENESS;
+  basesink->max_lateness = DEFAULT_MAX_LATENESS;
   g_atomic_int_set (&priv->qos_enabled, DEFAULT_QOS);
   priv->async_enabled = DEFAULT_ASYNC;
   priv->ts_offset = DEFAULT_TS_OFFSET;
@@ -725,8 +677,9 @@ gst_base_sink_finalize (GObject * object)
 
   basesink = GST_BASE_SINK (object);
 
+  g_mutex_free (basesink->preroll_lock);
+  g_cond_free (basesink->preroll_cond);
   g_queue_free (basesink->preroll_queue);
-  gst_segment_free (basesink->abidata.ABI.clip_segment);
 
   G_OBJECT_CLASS (parent_class)->finalize (object);
 }
@@ -797,7 +750,7 @@ gst_base_sink_set_max_lateness (GstBaseSink * sink, gint64 max_lateness)
   g_return_if_fail (GST_IS_BASE_SINK (sink));
 
   GST_OBJECT_LOCK (sink);
-  sink->abidata.ABI.max_lateness = max_lateness;
+  sink->max_lateness = max_lateness;
   GST_OBJECT_UNLOCK (sink);
 }
 
@@ -822,7 +775,7 @@ gst_base_sink_get_max_lateness (GstBaseSink * sink)
   g_return_val_if_fail (GST_IS_BASE_SINK (sink), -1);
 
   GST_OBJECT_LOCK (sink);
-  res = sink->abidata.ABI.max_lateness;
+  res = sink->max_lateness;
   GST_OBJECT_UNLOCK (sink);
 
   return res;
@@ -885,10 +838,10 @@ gst_base_sink_set_async_enabled (GstBaseSink * sink, gboolean enabled)
 {
   g_return_if_fail (GST_IS_BASE_SINK (sink));
 
-  GST_PAD_PREROLL_LOCK (sink->sinkpad);
+  GST_BASE_SINK_PREROLL_LOCK (sink);
   g_atomic_int_set (&sink->priv->async_enabled, enabled);
   GST_LOG_OBJECT (sink, "set async enabled to %d", enabled);
-  GST_PAD_PREROLL_UNLOCK (sink->sinkpad);
+  GST_BASE_SINK_PREROLL_UNLOCK (sink);
 }
 
 /**
@@ -1364,9 +1317,9 @@ gst_base_sink_set_property (GObject * object, guint prop_id,
   switch (prop_id) {
     case PROP_PREROLL_QUEUE_LEN:
       /* preroll lock necessary to serialize with finish_preroll */
-      GST_PAD_PREROLL_LOCK (sink->sinkpad);
+      GST_BASE_SINK_PREROLL_LOCK (sink);
       g_atomic_int_set (&sink->preroll_queue_max_len, g_value_get_uint (value));
-      GST_PAD_PREROLL_UNLOCK (sink->sinkpad);
+      GST_BASE_SINK_PREROLL_UNLOCK (sink);
       break;
     case PROP_SYNC:
       gst_base_sink_set_sync (sink, g_value_get_boolean (value));
@@ -1449,7 +1402,7 @@ gst_base_sink_get_property (GObject * object, guint prop_id, GValue * value,
 
 
 static GstCaps *
-gst_base_sink_get_caps (GstBaseSink * sink)
+gst_base_sink_get_caps (GstBaseSink * sink, GstCaps * filter)
 {
   return NULL;
 }
@@ -1460,14 +1413,6 @@ gst_base_sink_set_caps (GstBaseSink * sink, GstCaps * caps)
   return TRUE;
 }
 
-static GstFlowReturn
-gst_base_sink_buffer_alloc (GstBaseSink * sink, guint64 offset, guint size,
-    GstCaps * caps, GstBuffer ** buf)
-{
-  *buf = NULL;
-  return GST_FLOW_OK;
-}
-
 /* with PREROLL_LOCK, STREAM_LOCK */
 static void
 gst_base_sink_preroll_queue_flush (GstBaseSink * basesink, GstPad * pad)
@@ -1495,7 +1440,7 @@ gst_base_sink_preroll_queue_flush (GstBaseSink * basesink, GstPad * pad)
     GST_OBJECT_UNLOCK (basesink);
   }
   /* and signal any waiters now */
-  GST_PAD_PREROLL_SIGNAL (pad);
+  GST_BASE_SINK_PREROLL_SIGNAL (basesink);
 }
 
 /* with STREAM_LOCK, configures given segment with the event information. */
@@ -1503,43 +1448,15 @@ static void
 gst_base_sink_configure_segment (GstBaseSink * basesink, GstPad * pad,
     GstEvent * event, GstSegment * segment)
 {
-  gboolean update;
-  gdouble rate, arate;
-  GstFormat format;
-  gint64 start;
-  gint64 stop;
-  gint64 time;
-
-  /* the newsegment event is needed to bring the buffer timestamps to the
-   * stream time and to drop samples outside of the playback segment. */
-  gst_event_parse_new_segment_full (event, &update, &rate, &arate, &format,
-      &start, &stop, &time);
-
   /* The segment is protected with both the STREAM_LOCK and the OBJECT_LOCK.
    * We protect with the OBJECT_LOCK so that we can use the values to
    * safely answer a POSITION query. */
   GST_OBJECT_LOCK (basesink);
-  gst_segment_set_newsegment_full (segment, update, rate, arate, format, start,
-      stop, time);
-
-  if (format == GST_FORMAT_TIME) {
-    GST_DEBUG_OBJECT (basesink,
-        "configured NEWSEGMENT update %d, rate %lf, applied rate %lf, "
-        "format GST_FORMAT_TIME, "
-        "%" GST_TIME_FORMAT " -- %" GST_TIME_FORMAT
-        ", time %" GST_TIME_FORMAT ", accum %" GST_TIME_FORMAT,
-        update, rate, arate, GST_TIME_ARGS (segment->start),
-        GST_TIME_ARGS (segment->stop), GST_TIME_ARGS (segment->time),
-        GST_TIME_ARGS (segment->accum));
-  } else {
-    GST_DEBUG_OBJECT (basesink,
-        "configured NEWSEGMENT update %d, rate %lf, applied rate %lf, "
-        "format %d, "
-        "%" G_GINT64_FORMAT " -- %" G_GINT64_FORMAT ", time %"
-        G_GINT64_FORMAT ", accum %" G_GINT64_FORMAT, update, rate, arate,
-        segment->format, segment->start, segment->stop, segment->time,
-        segment->accum);
-  }
+  /* the newsegment event is needed to bring the buffer timestamps to the
+   * stream time and to drop samples outside of the playback segment. */
+  gst_event_copy_segment (event, segment);
+  GST_DEBUG_OBJECT (basesink, "configured SEGMENT %" GST_SEGMENT_FORMAT,
+      segment);
   GST_OBJECT_UNLOCK (basesink);
 }
 
@@ -1552,6 +1469,7 @@ gst_base_sink_commit_state (GstBaseSink * basesink)
   gboolean post_paused = FALSE;
   gboolean post_async_done = FALSE;
   gboolean post_playing = FALSE;
+  gboolean reset_time;
 
   /* we are certainly not playing async anymore now */
   basesink->playing_async = FALSE;
@@ -1561,15 +1479,12 @@ gst_base_sink_commit_state (GstBaseSink * basesink)
   next = GST_STATE_NEXT (basesink);
   pending = GST_STATE_PENDING (basesink);
   post_pending = pending;
+  reset_time = basesink->priv->reset_time;
+  basesink->priv->reset_time = FALSE;
 
   switch (pending) {
     case GST_STATE_PLAYING:
     {
-      GstBaseSinkClass *bclass;
-      GstStateChangeReturn ret;
-
-      bclass = GST_BASE_SINK_GET_CLASS (basesink);
-
       GST_DEBUG_OBJECT (basesink, "commiting state to PLAYING");
 
       basesink->need_preroll = FALSE;
@@ -1580,14 +1495,6 @@ gst_base_sink_commit_state (GstBaseSink * basesink)
       if (current == GST_STATE_READY) {
         post_paused = TRUE;
       }
-
-      /* make sure we notify the subclass of async playing */
-      if (bclass->async_play) {
-        GST_WARNING_OBJECT (basesink, "deprecated async_play");
-        ret = bclass->async_play (basesink);
-        if (ret == GST_STATE_CHANGE_FAILURE)
-          goto async_failed;
-      }
       break;
     }
     case GST_STATE_PAUSED:
@@ -1624,7 +1531,7 @@ gst_base_sink_commit_state (GstBaseSink * basesink)
   if (post_async_done) {
     GST_DEBUG_OBJECT (basesink, "posting async-done message");
     gst_element_post_message (GST_ELEMENT_CAST (basesink),
-        gst_message_new_async_done (GST_OBJECT_CAST (basesink)));
+        gst_message_new_async_done (GST_OBJECT_CAST (basesink), reset_time));
   }
   if (post_playing) {
     GST_DEBUG_OBJECT (basesink, "posting PLAYING state change message");
@@ -1672,13 +1579,6 @@ stopping:
     GST_OBJECT_UNLOCK (basesink);
     return FALSE;
   }
-async_failed:
-  {
-    GST_DEBUG_OBJECT (basesink, "async commit failed");
-    GST_STATE_RETURN (basesink) = GST_STATE_CHANGE_FAILURE;
-    GST_OBJECT_UNLOCK (basesink);
-    return FALSE;
-  }
 }
 
 static void
@@ -1709,7 +1609,6 @@ start_stepping (GstBaseSink * sink, GstSegment * segment,
   /* set the new rate for the remainder of the segment */
   current->start_rate = segment->rate;
   segment->rate *= current->rate;
-  segment->abs_rate = ABS (segment->rate);
 
   /* save values */
   if (segment->rate > 0.0)
@@ -1723,27 +1622,19 @@ start_stepping (GstBaseSink * sink, GstSegment * segment,
       /* update the segment clipping regions for non-flushing seeks */
       if (segment->rate > 0.0) {
         segment->stop = gst_segment_to_position (segment, GST_FORMAT_TIME, end);
-        segment->last_stop = segment->stop;
+        segment->position = segment->stop;
       } else {
         gint64 position;
 
         position = gst_segment_to_position (segment, GST_FORMAT_TIME, end);
         segment->time = position;
         segment->start = position;
-        segment->last_stop = position;
+        segment->position = position;
       }
     }
   }
 
-  GST_DEBUG_OBJECT (sink,
-      "segment now rate %lf, applied rate %lf, "
-      "format GST_FORMAT_TIME, "
-      "%" GST_TIME_FORMAT " -- %" GST_TIME_FORMAT
-      ", time %" GST_TIME_FORMAT ", accum %" GST_TIME_FORMAT,
-      segment->rate, segment->applied_rate, GST_TIME_ARGS (segment->start),
-      GST_TIME_ARGS (segment->stop), GST_TIME_ARGS (segment->time),
-      GST_TIME_ARGS (segment->accum));
-
+  GST_DEBUG_OBJECT (sink, "segment now %" GST_SEGMENT_FORMAT, segment);
   GST_DEBUG_OBJECT (sink, "step started at running_time %" GST_TIME_FORMAT,
       GST_TIME_ARGS (current->start));
 
@@ -1788,8 +1679,8 @@ stop_stepping (GstBaseSink * sink, GstSegment * segment,
   gst_segment_set_running_time (segment, GST_FORMAT_TIME, position);
 
   if (current->flush) {
-    /* and remove the accumulated time we flushed, start time did not change */
-    segment->accum = current->start;
+    /* and remove the time we flushed, start time did not change */
+    segment->base = current->start;
   } else {
     /* start time is now the stepped position */
     gst_element_set_start_time (GST_ELEMENT_CAST (sink), position);
@@ -1797,7 +1688,6 @@ stop_stepping (GstBaseSink * sink, GstSegment * segment,
 
   /* restore the previous rate */
   segment->rate = current->start_rate;
-  segment->abs_rate = ABS (segment->rate);
 
   if (segment->rate > 0.0)
     segment->stop = current->start_stop;
@@ -1805,7 +1695,7 @@ stop_stepping (GstBaseSink * sink, GstSegment * segment,
     segment->start = current->start_start;
 
   /* the clip segment is used for position report in paused... */
-  memcpy (sink->abidata.ABI.clip_segment, segment, sizeof (GstSegment));
+  gst_segment_copy_into (segment, &sink->clip_segment);
 
   /* post the step done when we know the stepped duration in TIME */
   message =
@@ -1824,8 +1714,8 @@ stop_stepping (GstBaseSink * sink, GstSegment * segment,
 
 static gboolean
 handle_stepping (GstBaseSink * sink, GstSegment * segment,
-    GstStepInfo * current, gint64 * cstart, gint64 * cstop, gint64 * rstart,
-    gint64 * rstop)
+    GstStepInfo * current, guint64 * cstart, guint64 * cstop, guint64 * rstart,
+    guint64 * rstop)
 {
   gboolean step_end = FALSE;
 
@@ -1834,7 +1724,8 @@ handle_stepping (GstBaseSink * sink, GstSegment * segment,
     case GST_FORMAT_TIME:
     {
       guint64 end;
-      gint64 first, last;
+      guint64 first, last;
+      gdouble abs_rate;
 
       if (segment->rate > 0.0) {
         if (segment->stop == *cstop)
@@ -1853,8 +1744,9 @@ handle_stepping (GstBaseSink * sink, GstSegment * segment,
       end = current->start + current->amount;
       current->position = first - current->start;
 
-      if (G_UNLIKELY (segment->abs_rate != 1.0))
-        current->position /= segment->abs_rate;
+      abs_rate = ABS (segment->rate);
+      if (G_UNLIKELY (abs_rate != 1.0))
+        current->position /= abs_rate;
 
       GST_DEBUG_OBJECT (sink,
           "buffer: %" GST_TIME_FORMAT "-%" GST_TIME_FORMAT,
@@ -1924,8 +1816,8 @@ gst_base_sink_get_sync_times (GstBaseSink * basesink, GstMiniObject * obj,
   GstBaseSinkClass *bclass;
   GstBuffer *buffer;
   GstClockTime start, stop;     /* raw start/stop timestamps */
-  gint64 cstart, cstop;         /* clipped raw timestamps */
-  gint64 rstart, rstop;         /* clipped timestamps converted to running time */
+  guint64 cstart, cstop;        /* clipped raw timestamps */
+  guint64 rstart, rstop;        /* clipped timestamps converted to running time */
   GstClockTime sstart, sstop;   /* clipped timestamps converted to stream time */
   GstFormat format;
   GstBaseSinkPrivate *priv;
@@ -1970,11 +1862,6 @@ gst_base_sink_get_sync_times (GstBaseSink * basesink, GstMiniObject * obj,
       }
       default:
         /* other events do not need syncing */
-        /* FIXME, maybe NEWSEGMENT might need synchronisation
-         * since the POSITION query depends on accumulated times and
-         * we cannot accumulate the current segment before the previous
-         * one completed.
-         */
         return FALSE;
     }
   }
@@ -2008,19 +1895,9 @@ again:
   /* collect segment and format for code clarity */
   format = segment->format;
 
-  /* no timestamp clipping if we did not get a TIME segment format */
-  if (G_UNLIKELY (format != GST_FORMAT_TIME)) {
-    cstart = start;
-    cstop = stop;
-    /* do running and stream time in TIME format */
-    format = GST_FORMAT_TIME;
-    GST_LOG_OBJECT (basesink, "not time format, don't clip");
-    goto do_times;
-  }
-
-  /* clip, only when we know about time */
-  if (G_UNLIKELY (!gst_segment_clip (segment, GST_FORMAT_TIME,
-              (gint64) start, (gint64) stop, &cstart, &cstop))) {
+  /* clip */
+  if (G_UNLIKELY (!gst_segment_clip (segment, format,
+              start, stop, &cstart, &cstop))) {
     if (step->valid) {
       GST_DEBUG_OBJECT (basesink, "step out of segment");
       /* when we are stepping, pretend we're at the end of the segment */
@@ -2044,9 +1921,9 @@ again:
 
   /* set last stop position */
   if (G_LIKELY (stop != GST_CLOCK_TIME_NONE && cstop != GST_CLOCK_TIME_NONE))
-    gst_segment_set_last_stop (segment, GST_FORMAT_TIME, cstop);
+    segment->position = cstop;
   else
-    gst_segment_set_last_stop (segment, GST_FORMAT_TIME, cstart);
+    segment->position = cstart;
 
 do_times:
   rstart = gst_segment_to_running_time (segment, format, cstart);
@@ -2189,8 +2066,8 @@ gst_base_sink_wait_clock (GstBaseSink * sink, GstClockTime time,
   /* FIXME: Casting to GstClockEntry only works because the types
    * are the same */
   if (G_LIKELY (sink->priv->cached_clock_id != NULL
-          && GST_CLOCK_ENTRY_CLOCK ((GstClockEntry *) sink->
-              priv->cached_clock_id) == clock)) {
+          && GST_CLOCK_ENTRY_CLOCK ((GstClockEntry *) sink->priv->
+              cached_clock_id) == clock)) {
     if (!gst_clock_single_shot_id_reinit (clock, sink->priv->cached_clock_id,
             time)) {
       gst_clock_id_unref (sink->priv->cached_clock_id);
@@ -2209,11 +2086,11 @@ gst_base_sink_wait_clock (GstBaseSink * sink, GstClockTime time,
    * entry. */
   sink->clock_id = sink->priv->cached_clock_id;
   /* release the preroll lock while waiting */
-  GST_PAD_PREROLL_UNLOCK (sink->sinkpad);
+  GST_BASE_SINK_PREROLL_UNLOCK (sink);
 
   ret = gst_clock_id_wait (sink->priv->cached_clock_id, jitter);
 
-  GST_PAD_PREROLL_LOCK (sink->sinkpad);
+  GST_BASE_SINK_PREROLL_LOCK (sink);
   sink->clock_id = NULL;
 
   return ret;
@@ -2265,7 +2142,7 @@ gst_base_sink_wait_preroll (GstBaseSink * sink)
   sink->have_preroll = TRUE;
   GST_DEBUG_OBJECT (sink, "waiting in preroll for flush or PLAYING");
   /* block until the state changes, or we get a flush, or something */
-  GST_PAD_PREROLL_WAIT (sink->sinkpad);
+  GST_BASE_SINK_PREROLL_WAIT (sink);
   sink->have_preroll = FALSE;
   if (G_UNLIKELY (sink->flushing))
     goto stopping;
@@ -2641,7 +2518,7 @@ gst_base_sink_send_qos (GstBaseSink * basesink, GstQOSType type,
       "qos: type %d, proportion: %lf, diff %" G_GINT64_FORMAT ", timestamp %"
       GST_TIME_FORMAT, type, proportion, diff, GST_TIME_ARGS (time));
 
-  event = gst_event_new_qos_full (type, proportion, diff, time);
+  event = gst_event_new_qos (type, proportion, diff, time);
 
   /* send upstream */
   res = gst_pad_push_event (basesink->sinkpad, event);
@@ -2822,7 +2699,7 @@ gst_base_sink_is_too_late (GstBaseSink * basesink, GstMiniObject * obj,
     GstClockReturn status, GstClockTimeDiff jitter)
 {
   gboolean late;
-  gint64 max_lateness;
+  guint64 max_lateness;
   GstBaseSinkPrivate *priv;
 
   priv = basesink->priv;
@@ -2833,7 +2710,7 @@ gst_base_sink_is_too_late (GstBaseSink * basesink, GstMiniObject * obj,
   if (G_LIKELY (status != GST_CLOCK_EARLY))
     goto in_time;
 
-  max_lateness = basesink->abidata.ABI.max_lateness;
+  max_lateness = basesink->max_lateness;
 
   /* check if frame dropping is enabled */
   if (max_lateness == -1)
@@ -2961,7 +2838,7 @@ gst_base_sink_render_object (GstBaseSink * basesink, GstPad * pad,
      * If buffer list, use the first group buffer within the list
      * for syncing
      */
-    sync_obj = gst_buffer_list_get (GST_BUFFER_LIST_CAST (obj), 0, 0);
+    sync_obj = gst_buffer_list_get (GST_BUFFER_LIST_CAST (obj), 0);
     g_assert (NULL != sync_obj);
   } else {
     sync_obj = obj;
@@ -3076,7 +2953,7 @@ again:
           gst_element_post_message (GST_ELEMENT_CAST (basesink), message);
           break;
         }
-        case GST_EVENT_NEWSEGMENT:
+        case GST_EVENT_SEGMENT:
           /* configure the segment */
           gst_base_sink_configure_segment (basesink, pad, event,
               &basesink->segment);
@@ -3182,7 +3059,7 @@ gst_base_sink_preroll_object (GstBaseSink * basesink, guint8 obj_type,
     GstClockTime timestamp;
 
     if (OBJ_IS_BUFFERLIST (obj_type)) {
-      buf = gst_buffer_list_get (GST_BUFFER_LIST_CAST (obj), 0, 0);
+      buf = gst_buffer_list_get (GST_BUFFER_LIST_CAST (obj), 0);
       g_assert (NULL != buf);
     } else {
       buf = GST_BUFFER_CAST (obj);
@@ -3335,7 +3212,7 @@ gst_base_sink_queue_object (GstBaseSink * basesink, GstPad * pad,
 {
   GstFlowReturn ret;
 
-  GST_PAD_PREROLL_LOCK (pad);
+  GST_BASE_SINK_PREROLL_LOCK (basesink);
   if (G_UNLIKELY (basesink->flushing))
     goto flushing;
 
@@ -3345,7 +3222,7 @@ gst_base_sink_queue_object (GstBaseSink * basesink, GstPad * pad,
   ret =
       gst_base_sink_queue_object_unlocked (basesink, pad, _PR_IS_EVENT, obj,
       prerollable);
-  GST_PAD_PREROLL_UNLOCK (pad);
+  GST_BASE_SINK_PREROLL_UNLOCK (basesink);
 
   return ret;
 
@@ -3353,7 +3230,7 @@ gst_base_sink_queue_object (GstBaseSink * basesink, GstPad * pad,
 flushing:
   {
     GST_DEBUG_OBJECT (basesink, "sink is flushing");
-    GST_PAD_PREROLL_UNLOCK (pad);
+    GST_BASE_SINK_PREROLL_UNLOCK (basesink);
     gst_mini_object_unref (obj);
     return GST_FLOW_WRONG_STATE;
   }
@@ -3361,7 +3238,7 @@ was_eos:
   {
     GST_DEBUG_OBJECT (basesink,
         "we are EOS, dropping object, return UNEXPECTED");
-    GST_PAD_PREROLL_UNLOCK (pad);
+    GST_BASE_SINK_PREROLL_UNLOCK (basesink);
     gst_mini_object_unref (obj);
     return GST_FLOW_UNEXPECTED;
   }
@@ -3392,7 +3269,8 @@ gst_base_sink_flush_start (GstBaseSink * basesink, GstPad * pad)
 }
 
 static void
-gst_base_sink_flush_stop (GstBaseSink * basesink, GstPad * pad)
+gst_base_sink_flush_stop (GstBaseSink * basesink, GstPad * pad,
+    gboolean reset_time)
 {
   /* unset flushing so we can accept new data, this also flushes out any EOS
    * event. */
@@ -3409,9 +3287,12 @@ gst_base_sink_flush_stop (GstBaseSink * basesink, GstPad * pad)
   if (basesink->pad_mode == GST_ACTIVATE_PUSH) {
     /* we need new segment info after the flush. */
     basesink->have_newsegment = FALSE;
-    gst_segment_init (&basesink->segment, GST_FORMAT_UNDEFINED);
-    gst_segment_init (basesink->abidata.ABI.clip_segment, GST_FORMAT_UNDEFINED);
+    if (reset_time) {
+      gst_segment_init (&basesink->segment, GST_FORMAT_UNDEFINED);
+      gst_segment_init (&basesink->clip_segment, GST_FORMAT_UNDEFINED);
+    }
   }
+  basesink->priv->reset_time = reset_time;
   GST_OBJECT_UNLOCK (basesink);
 }
 
@@ -3438,66 +3319,70 @@ gst_base_sink_event (GstPad * pad, GstEvent * event)
     {
       GstFlowReturn ret;
 
-      GST_PAD_PREROLL_LOCK (pad);
+      GST_BASE_SINK_PREROLL_LOCK (basesink);
       if (G_UNLIKELY (basesink->flushing))
         goto flushing;
 
-      if (G_UNLIKELY (basesink->priv->received_eos)) {
-        /* we can't accept anything when we are EOS */
+      if (G_UNLIKELY (basesink->priv->received_eos))
+        goto after_eos;
+
+      /* we set the received EOS flag here so that we can use it when testing if
+       * we are prerolled and to refuse more buffers. */
+      basesink->priv->received_eos = TRUE;
+
+      /* EOS is a prerollable object, we call the unlocked version because it
+       * does not check the received_eos flag. */
+      ret = gst_base_sink_queue_object_unlocked (basesink, pad,
+          _PR_IS_EVENT, GST_MINI_OBJECT_CAST (event), TRUE);
+      if (G_UNLIKELY (ret != GST_FLOW_OK))
         result = FALSE;
-        gst_event_unref (event);
-      } else {
-        /* we set the received EOS flag here so that we can use it when testing if
-         * we are prerolled and to refuse more buffers. */
-        basesink->priv->received_eos = TRUE;
-
-        /* EOS is a prerollable object, we call the unlocked version because it
-         * does not check the received_eos flag. */
-        ret = gst_base_sink_queue_object_unlocked (basesink, pad,
-            _PR_IS_EVENT, GST_MINI_OBJECT_CAST (event), TRUE);
-        if (G_UNLIKELY (ret != GST_FLOW_OK))
-          result = FALSE;
-      }
-      GST_PAD_PREROLL_UNLOCK (pad);
+
+      GST_BASE_SINK_PREROLL_UNLOCK (basesink);
       break;
     }
-    case GST_EVENT_NEWSEGMENT:
+    case GST_EVENT_CAPS:
+    {
+      GstCaps *caps;
+
+      GST_DEBUG_OBJECT (basesink, "caps %p", event);
+
+      gst_event_parse_caps (event, &caps);
+      if (bclass->set_caps)
+        result = bclass->set_caps (basesink, caps);
+
+      gst_event_unref (event);
+      break;
+    }
+    case GST_EVENT_SEGMENT:
     {
       GstFlowReturn ret;
-      gboolean update;
 
-      GST_DEBUG_OBJECT (basesink, "newsegment %p", event);
+      GST_DEBUG_OBJECT (basesink, "segment %p", event);
 
-      GST_PAD_PREROLL_LOCK (pad);
+      GST_BASE_SINK_PREROLL_LOCK (basesink);
       if (G_UNLIKELY (basesink->flushing))
         goto flushing;
 
-      gst_event_parse_new_segment_full (event, &update, NULL, NULL, NULL, NULL,
-          NULL, NULL);
+      if (G_UNLIKELY (basesink->priv->received_eos))
+        goto after_eos;
+
+      /* the new segment is a non prerollable item and does not block anything,
+       * we need to configure the current clipping segment and insert the event
+       * in the queue to serialize it with the buffers for rendering. */
+      gst_base_sink_configure_segment (basesink, pad, event,
+          &basesink->clip_segment);
 
-      if (G_UNLIKELY (basesink->priv->received_eos && !update)) {
-        /* we can't accept anything when we are EOS */
+      ret =
+          gst_base_sink_queue_object_unlocked (basesink, pad,
+          _PR_IS_EVENT, GST_MINI_OBJECT_CAST (event), FALSE);
+      if (G_UNLIKELY (ret != GST_FLOW_OK))
         result = FALSE;
-        gst_event_unref (event);
-      } else {
-        /* the new segment is a non prerollable item and does not block anything,
-         * we need to configure the current clipping segment and insert the event
-         * in the queue to serialize it with the buffers for rendering. */
-        gst_base_sink_configure_segment (basesink, pad, event,
-            basesink->abidata.ABI.clip_segment);
-
-        ret =
-            gst_base_sink_queue_object_unlocked (basesink, pad,
-            _PR_IS_EVENT, GST_MINI_OBJECT_CAST (event), FALSE);
-        if (G_UNLIKELY (ret != GST_FLOW_OK))
-          result = FALSE;
-        else {
-          GST_OBJECT_LOCK (basesink);
-          basesink->have_newsegment = TRUE;
-          GST_OBJECT_UNLOCK (basesink);
-        }
+      else {
+        GST_OBJECT_LOCK (basesink);
+        basesink->have_newsegment = TRUE;
+        GST_OBJECT_UNLOCK (basesink);
       }
-      GST_PAD_PREROLL_UNLOCK (pad);
+      GST_BASE_SINK_PREROLL_UNLOCK (basesink);
       break;
     }
     case GST_EVENT_FLUSH_START:
@@ -3511,15 +3396,21 @@ gst_base_sink_event (GstPad * pad, GstEvent * event)
       gst_event_unref (event);
       break;
     case GST_EVENT_FLUSH_STOP:
+    {
+      gboolean reset_time;
+
       if (bclass->event)
         bclass->event (basesink, event);
 
-      GST_DEBUG_OBJECT (basesink, "flush-stop %p", event);
+      gst_event_parse_flush_stop (event, &reset_time);
+      GST_DEBUG_OBJECT (basesink, "flush-stop %p, reset_time: %d", event,
+          reset_time);
 
-      gst_base_sink_flush_stop (basesink, pad);
+      gst_base_sink_flush_stop (basesink, pad, reset_time);
 
       gst_event_unref (event);
       break;
+    }
     default:
       /* other events are sent to queue or subclass depending on if they
        * are serialized. */
@@ -3542,7 +3433,16 @@ done:
 flushing:
   {
     GST_DEBUG_OBJECT (basesink, "we are flushing");
-    GST_PAD_PREROLL_UNLOCK (pad);
+    GST_BASE_SINK_PREROLL_UNLOCK (basesink);
+    result = FALSE;
+    gst_event_unref (event);
+    goto done;
+  }
+
+after_eos:
+  {
+    GST_DEBUG_OBJECT (basesink, "Event received after EOS, dropping");
+    GST_BASE_SINK_PREROLL_UNLOCK (basesink);
     result = FALSE;
     gst_event_unref (event);
     goto done;
@@ -3614,14 +3514,14 @@ gst_base_sink_chain_unlocked (GstBaseSink * basesink, GstPad * pad,
     goto was_eos;
 
   if (OBJ_IS_BUFFERLIST (obj_type)) {
-    time_buf = gst_buffer_list_get (GST_BUFFER_LIST_CAST (obj), 0, 0);
+    time_buf = gst_buffer_list_get (GST_BUFFER_LIST_CAST (obj), 0);
     g_assert (NULL != time_buf);
   } else {
     time_buf = GST_BUFFER_CAST (obj);
   }
 
   /* for code clarity */
-  clip_segment = basesink->abidata.ABI.clip_segment;
+  clip_segment = &basesink->clip_segment;
 
   if (G_UNLIKELY (!basesink->have_newsegment)) {
     gboolean sync;
@@ -3663,7 +3563,7 @@ gst_base_sink_chain_unlocked (GstBaseSink * basesink, GstPad * pad,
   if (GST_CLOCK_TIME_IS_VALID (start) &&
       (clip_segment->format == GST_FORMAT_TIME)) {
     if (G_UNLIKELY (!gst_segment_clip (clip_segment,
-                GST_FORMAT_TIME, (gint64) start, (gint64) end, NULL, NULL)))
+                GST_FORMAT_TIME, start, end, NULL, NULL)))
       goto out_of_segment;
   }
 
@@ -3706,9 +3606,9 @@ gst_base_sink_chain_main (GstBaseSink * basesink, GstPad * pad,
   if (G_UNLIKELY (basesink->pad_mode != GST_ACTIVATE_PUSH))
     goto wrong_mode;
 
-  GST_PAD_PREROLL_LOCK (pad);
+  GST_BASE_SINK_PREROLL_LOCK (basesink);
   result = gst_base_sink_chain_unlocked (basesink, pad, obj_type, obj);
-  GST_PAD_PREROLL_UNLOCK (pad);
+  GST_BASE_SINK_PREROLL_UNLOCK (basesink);
 
 done:
   return result;
@@ -3752,32 +3652,21 @@ gst_base_sink_chain_list (GstPad * pad, GstBufferList * list)
   if (G_LIKELY (bclass->render_list)) {
     result = gst_base_sink_chain_main (basesink, pad, _PR_IS_BUFFERLIST, list);
   } else {
-    GstBufferListIterator *it;
-    GstBuffer *group;
+    guint i, len;
+    GstBuffer *buffer;
 
     GST_INFO_OBJECT (pad, "chaining each group in list as a merged buffer");
 
-    it = gst_buffer_list_iterate (list);
+    len = gst_buffer_list_len (list);
 
-    if (gst_buffer_list_iterator_next_group (it)) {
-      do {
-        group = gst_buffer_list_iterator_merge_group (it);
-        if (group == NULL) {
-          group = gst_buffer_new ();
-          GST_CAT_INFO_OBJECT (GST_CAT_SCHEDULING, pad, "chaining empty group");
-        } else {
-          GST_CAT_INFO_OBJECT (GST_CAT_SCHEDULING, pad, "chaining group");
-        }
-        result = gst_base_sink_chain_main (basesink, pad, _PR_IS_BUFFER, group);
-      } while (result == GST_FLOW_OK
-          && gst_buffer_list_iterator_next_group (it));
-    } else {
-      GST_CAT_INFO_OBJECT (GST_CAT_SCHEDULING, pad, "chaining empty group");
-      result =
-          gst_base_sink_chain_main (basesink, pad, _PR_IS_BUFFER,
-          gst_buffer_new ());
+    result = GST_FLOW_OK;
+    for (i = 0; i < len; i++) {
+      buffer = gst_buffer_list_get (list, 0);
+      result = gst_base_sink_chain_main (basesink, pad, _PR_IS_BUFFER,
+          gst_buffer_ref (buffer));
+      if (result != GST_FLOW_OK)
+        break;
     }
-    gst_buffer_list_iterator_free (it);
     gst_buffer_list_unref (list);
   }
   return result;
@@ -3829,7 +3718,7 @@ gst_base_sink_default_prepare_seek_segment (GstBaseSink * sink,
   dest_format = segment->format;
 
   if (seek_format == dest_format) {
-    gst_segment_set_seek (segment, rate, seek_format, flags,
+    gst_segment_do_seek (segment, rate, seek_format, flags,
         cur_type, cur, stop_type, stop, &update);
     return TRUE;
   }
@@ -3851,7 +3740,7 @@ gst_base_sink_default_prepare_seek_segment (GstBaseSink * sink,
   }
 
   /* And finally, configure our output segment in the desired format */
-  gst_segment_set_seek (segment, rate, dest_format, flags, cur_type, cur,
+  gst_segment_do_seek (segment, rate, dest_format, flags, cur_type, cur,
       stop_type, stop, &update);
 
   if (!res)
@@ -3924,7 +3813,7 @@ gst_base_sink_perform_seek (GstBaseSink * sink, GstPad * pad, GstEvent * event)
       } else {
         /* The seek format matches our processing format, no need to ask the
          * the subclass to configure the segment. */
-        gst_segment_set_seek (&seeksegment, rate, seek_format, flags,
+        gst_segment_do_seek (&seeksegment, rate, seek_format, flags,
             cur_type, cur, stop_type, stop, &update);
       }
     }
@@ -3935,22 +3824,22 @@ gst_base_sink_perform_seek (GstBaseSink * sink, GstPad * pad, GstEvent * event)
   if (res) {
     GST_DEBUG_OBJECT (sink, "segment configured from %" G_GINT64_FORMAT
         " to %" G_GINT64_FORMAT ", position %" G_GINT64_FORMAT,
-        seeksegment.start, seeksegment.stop, seeksegment.last_stop);
+        seeksegment.start, seeksegment.stop, seeksegment.position);
 
-    /* do the seek, segment.last_stop contains the new position. */
+    /* do the seek, segment.position contains the new position. */
     res = gst_base_sink_default_do_seek (sink, &seeksegment);
   }
 
 
   if (flush) {
     GST_DEBUG_OBJECT (sink, "stop flushing upstream");
-    gst_pad_push_event (pad, gst_event_new_flush_stop ());
-    gst_base_sink_flush_stop (sink, pad);
-  } else if (res && sink->abidata.ABI.running) {
+    gst_pad_push_event (pad, gst_event_new_flush_stop (TRUE));
+    gst_base_sink_flush_stop (sink, pad, TRUE);
+  } else if (res && sink->running) {
     /* we are running the current segment and doing a non-flushing seek,
-     * close the segment first based on the last_stop. */
+     * close the segment first based on the position. */
     GST_DEBUG_OBJECT (sink, "closing running segment %" G_GINT64_FORMAT
-        " to %" G_GINT64_FORMAT, sink->segment.start, sink->segment.last_stop);
+        " to %" G_GINT64_FORMAT, sink->segment.start, sink->segment.position);
   }
 
   /* The subclass must have converted the segment to the processing format
@@ -3964,17 +3853,17 @@ gst_base_sink_perform_seek (GstBaseSink * sink, GstPad * pad, GstEvent * event)
   /* if successfull seek, we update our real segment and push
    * out the new segment. */
   if (res) {
-    memcpy (&sink->segment, &seeksegment, sizeof (GstSegment));
+    gst_segment_copy_into (&seeksegment, &sink->segment);
 
     if (sink->segment.flags & GST_SEEK_FLAG_SEGMENT) {
       gst_element_post_message (GST_ELEMENT (sink),
           gst_message_new_segment_start (GST_OBJECT (sink),
-              sink->segment.format, sink->segment.last_stop));
+              sink->segment.format, sink->segment.position));
     }
   }
 
   sink->priv->discont = TRUE;
-  sink->abidata.ABI.running = TRUE;
+  sink->running = TRUE;
 
   GST_PAD_STREAM_UNLOCK (pad);
 
@@ -4037,7 +3926,7 @@ gst_base_sink_perform_step (GstBaseSink * sink, GstPad * pad, GstEvent * event)
     if (bclass->unlock)
       bclass->unlock (sink);
 
-    GST_PAD_PREROLL_LOCK (sink->sinkpad);
+    GST_BASE_SINK_PREROLL_LOCK (sink);
     /* now that we have the PREROLL lock, clear our unlock request */
     if (bclass->unlock_stop)
       bclass->unlock_stop (sink);
@@ -4052,7 +3941,7 @@ gst_base_sink_perform_step (GstBaseSink * sink, GstPad * pad, GstEvent * event)
       sink->playing_async = TRUE;
       priv->pending_step.need_preroll = TRUE;
       sink->need_preroll = FALSE;
-      gst_element_lost_state_full (GST_ELEMENT_CAST (sink), FALSE);
+      gst_element_lost_state (GST_ELEMENT_CAST (sink));
     } else {
       sink->priv->have_latency = TRUE;
       sink->need_preroll = FALSE;
@@ -4071,9 +3960,9 @@ gst_base_sink_perform_step (GstBaseSink * sink, GstPad * pad, GstEvent * event)
     if (sink->have_preroll) {
       GST_DEBUG_OBJECT (sink, "signal waiter");
       priv->step_unlock = TRUE;
-      GST_PAD_PREROLL_SIGNAL (sink->sinkpad);
+      GST_BASE_SINK_PREROLL_SIGNAL (sink);
     }
-    GST_PAD_PREROLL_UNLOCK (sink->sinkpad);
+    GST_BASE_SINK_PREROLL_UNLOCK (sink);
   } else {
     /* update the stepinfo and make it valid */
     set_step_info (sink, current, pending, seqnum, format, amount, rate, flush,
@@ -4101,7 +3990,7 @@ gst_base_sink_loop (GstPad * pad)
   if ((blocksize = basesink->priv->blocksize) == 0)
     blocksize = -1;
 
-  offset = basesink->segment.last_stop;
+  offset = basesink->segment.position;
 
   GST_DEBUG_OBJECT (basesink, "pulling %" G_GUINT64_FORMAT ", %u",
       offset, blocksize);
@@ -4113,13 +4002,13 @@ gst_base_sink_loop (GstPad * pad)
   if (G_UNLIKELY (buf == NULL))
     goto no_buffer;
 
-  offset += GST_BUFFER_SIZE (buf);
+  offset += gst_buffer_get_size (buf);
 
-  gst_segment_set_last_stop (&basesink->segment, GST_FORMAT_BYTES, offset);
+  basesink->segment.position = offset;
 
-  GST_PAD_PREROLL_LOCK (pad);
+  GST_BASE_SINK_PREROLL_LOCK (basesink);
   result = gst_base_sink_chain_unlocked (basesink, pad, _PR_IS_BUFFER, buf);
-  GST_PAD_PREROLL_UNLOCK (pad);
+  GST_BASE_SINK_PREROLL_UNLOCK (basesink);
   if (G_UNLIKELY (result != GST_FLOW_OK))
     goto paused;
 
@@ -4136,7 +4025,7 @@ paused:
       if (basesink->segment.flags & GST_SEEK_FLAG_SEGMENT) {
         gst_element_post_message (GST_ELEMENT_CAST (basesink),
             gst_message_new_segment_done (GST_OBJECT_CAST (basesink),
-                basesink->segment.format, basesink->segment.last_stop));
+                basesink->segment.format, basesink->segment.position));
       } else {
         gst_base_sink_event (pad, gst_event_new_eos ());
       }
@@ -4179,7 +4068,7 @@ gst_base_sink_set_flushing (GstBaseSink * basesink, GstPad * pad,
       bclass->unlock (basesink);
   }
 
-  GST_PAD_PREROLL_LOCK (pad);
+  GST_BASE_SINK_PREROLL_LOCK (basesink);
   basesink->flushing = flushing;
   if (flushing) {
     /* step 1, now that we have the PREROLL lock, clear our unlock request */
@@ -4201,7 +4090,7 @@ gst_base_sink_set_flushing (GstBaseSink * basesink, GstPad * pad,
         "flushing out data thread, need preroll to TRUE");
     gst_base_sink_preroll_queue_flush (basesink, pad);
   }
-  GST_PAD_PREROLL_UNLOCK (pad);
+  GST_BASE_SINK_PREROLL_UNLOCK (basesink);
 
   return TRUE;
 }
@@ -4228,6 +4117,8 @@ gst_base_sink_pad_activate (GstPad * pad)
 {
   gboolean result = FALSE;
   GstBaseSink *basesink;
+  GstQuery *query;
+  gboolean pull_mode;
 
   basesink = GST_BASE_SINK (gst_pad_get_parent (pad));
 
@@ -4242,7 +4133,19 @@ gst_base_sink_pad_activate (GstPad * pad)
   }
 
   /* check if downstreams supports pull mode at all */
-  if (!gst_pad_check_pull_range (pad)) {
+  query = gst_query_new_scheduling ();
+
+  if (!gst_pad_peer_query (pad, query)) {
+    gst_query_unref (query);
+    GST_DEBUG_OBJECT (basesink, "peer query faild, no pull mode");
+    goto fallback;
+  }
+
+  /* parse result of the query */
+  gst_query_parse_scheduling (query, &pull_mode, NULL, NULL, NULL, NULL, NULL);
+  gst_query_unref (query);
+
+  if (!pull_mode) {
     GST_DEBUG_OBJECT (basesink, "pull mode not supported");
     goto fallback;
   }
@@ -4343,10 +4246,8 @@ gst_base_sink_negotiate_pull (GstBaseSink * basesink)
   caps = gst_caps_make_writable (caps);
   /* get the first (prefered) format */
   gst_caps_truncate (caps);
-  /* try to fixate */
-  gst_pad_fixate_caps (GST_BASE_SINK_PAD (basesink), caps);
 
-  GST_DEBUG_OBJECT (basesink, "fixated to: %" GST_PTR_FORMAT, caps);
+  GST_DEBUG_OBJECT (basesink, "have caps: %" GST_PTR_FORMAT, caps);
 
   if (gst_caps_is_any (caps)) {
     GST_DEBUG_OBJECT (basesink, "caps were ANY after fixating, "
@@ -4354,15 +4255,22 @@ gst_base_sink_negotiate_pull (GstBaseSink * basesink)
     /* neither side has template caps in this case, so they are prepared for
        pull() without setcaps() */
     result = TRUE;
-  } else if (gst_caps_is_fixed (caps)) {
-    if (!gst_pad_set_caps (GST_BASE_SINK_PAD (basesink), caps))
-      goto could_not_set_caps;
+  } else {
+    /* try to fixate */
+    gst_pad_fixate_caps (GST_BASE_SINK_PAD (basesink), caps);
+    GST_DEBUG_OBJECT (basesink, "fixated to: %" GST_PTR_FORMAT, caps);
 
-    GST_OBJECT_LOCK (basesink);
-    gst_caps_replace (&basesink->priv->pull_caps, caps);
-    GST_OBJECT_UNLOCK (basesink);
+    if (gst_caps_is_fixed (caps)) {
+      if (!gst_pad_send_event (GST_BASE_SINK_PAD (basesink),
+              gst_event_new_caps (caps)))
+        goto could_not_set_caps;
 
-    result = TRUE;
+      GST_OBJECT_LOCK (basesink);
+      gst_caps_replace (&basesink->priv->pull_caps, caps);
+      GST_OBJECT_UNLOCK (basesink);
+
+      result = TRUE;
+    }
   }
 
   gst_caps_unref (caps);
@@ -4406,7 +4314,7 @@ gst_base_sink_pad_activate_pull (GstPad * pad, gboolean active)
     format = GST_FORMAT_BYTES;
 
     gst_segment_init (&basesink->segment, format);
-    gst_segment_init (basesink->abidata.ABI.clip_segment, format);
+    gst_segment_init (&basesink->clip_segment, format);
     GST_OBJECT_LOCK (basesink);
     basesink->have_newsegment = TRUE;
     GST_OBJECT_UNLOCK (basesink);
@@ -4416,9 +4324,8 @@ gst_base_sink_pad_activate_pull (GstPad * pad, gboolean active)
     if (result) {
       GST_DEBUG_OBJECT (basesink,
           "setting duration in bytes to %" G_GINT64_FORMAT, duration);
-      gst_segment_set_duration (basesink->abidata.ABI.clip_segment, format,
-          duration);
-      gst_segment_set_duration (&basesink->segment, format, duration);
+      basesink->clip_segment.duration = duration;
+      basesink->segment.duration = duration;
     } else {
       GST_DEBUG_OBJECT (basesink, "unknown duration");
     }
@@ -4537,8 +4444,8 @@ gst_base_sink_get_position (GstBaseSink * basesink, GstFormat format,
   GstFormat oformat, tformat;
   GstSegment *segment;
   GstClockTime now, latency;
-  GstClockTimeDiff base;
-  gint64 time, accum, duration;
+  GstClockTimeDiff base_time;
+  gint64 time, base, duration;
   gdouble rate;
   gint64 last;
   gboolean last_seen, with_clock, in_paused;
@@ -4561,7 +4468,7 @@ gst_base_sink_get_position (GstBaseSink * basesink, GstFormat format,
    * main segment directly with the new segment values without it having to be
    * activated by the rendering after preroll */
   if (basesink->pad_mode == GST_ACTIVATE_PUSH)
-    segment = basesink->abidata.ABI.clip_segment;
+    segment = &basesink->clip_segment;
   else
     segment = &basesink->segment;
 
@@ -4595,7 +4502,7 @@ gst_base_sink_get_position (GstBaseSink * basesink, GstFormat format,
   else
     duration = 0;
 
-  accum = segment->accum;
+  base = segment->base;
   rate = segment->rate * segment->applied_rate;
   latency = basesink->priv->latency;
 
@@ -4620,28 +4527,28 @@ gst_base_sink_get_position (GstBaseSink * basesink, GstFormat format,
     }
   } else {
     /* convert last stop to stream time */
-    last = gst_segment_to_stream_time (segment, oformat, segment->last_stop);
+    last = gst_segment_to_stream_time (segment, oformat, segment->position);
   }
 
   if (in_paused) {
     /* in paused, use start_time */
-    base = GST_ELEMENT_START_TIME (basesink);
+    base_time = GST_ELEMENT_START_TIME (basesink);
     GST_DEBUG_OBJECT (basesink, "in paused, using start time %" GST_TIME_FORMAT,
-        GST_TIME_ARGS (base));
+        GST_TIME_ARGS (base_time));
   } else if (with_clock) {
     /* else use clock when needed */
-    base = GST_ELEMENT_CAST (basesink)->base_time;
+    base_time = GST_ELEMENT_CAST (basesink)->base_time;
     GST_DEBUG_OBJECT (basesink, "using clock and base time %" GST_TIME_FORMAT,
-        GST_TIME_ARGS (base));
+        GST_TIME_ARGS (base_time));
   } else {
     /* else, no sync or clock -> no base time */
     GST_DEBUG_OBJECT (basesink, "no sync or no clock");
-    base = -1;
+    base_time = -1;
   }
 
-  /* no base, we can't calculate running_time, use last seem timestamp to report
+  /* no base_time, we can't calculate running_time, use last seem timestamp to report
    * time */
-  if (base == -1)
+  if (base_time == -1)
     last_seen = TRUE;
 
   /* need to release the object lock before we can get the time,
@@ -4664,9 +4571,9 @@ gst_base_sink_get_position (GstBaseSink * basesink, GstFormat format,
     *cur = last;
   } else {
     if (oformat != tformat) {
-      /* convert accum, time and duration to time */
-      if (!gst_pad_query_convert (basesink->sinkpad, oformat, accum, &tformat,
-              &accum))
+      /* convert base, time and duration to time */
+      if (!gst_pad_query_convert (basesink->sinkpad, oformat, base, &tformat,
+              &base))
         goto convert_failed;
       if (!gst_pad_query_convert (basesink->sinkpad, oformat, duration,
               &tformat, &duration))
@@ -4685,25 +4592,25 @@ gst_base_sink_get_position (GstBaseSink * basesink, GstFormat format,
     if (!in_paused && with_clock) {
       now = gst_clock_get_time (clock);
     } else {
-      now = base;
-      base = 0;
+      now = base_time;
+      base_time = 0;
     }
 
-    /* subtract base time and accumulated time from the clock time.
+    /* subtract base time and base time from the clock time.
      * Make sure we don't go negative. This is the current time in
      * the segment which we need to scale with the combined
      * rate and applied rate. */
-    base += accum;
-    base += latency;
-    if (GST_CLOCK_DIFF (base, now) < 0)
-      base = now;
+    base_time += base;
+    base_time += latency;
+    if (GST_CLOCK_DIFF (base_time, now) < 0)
+      base_time = now;
 
     /* for negative rates we need to count back from the segment
      * duration. */
     if (rate < 0.0)
       time += duration;
 
-    *cur = time + gst_guint64_to_gdouble (now - base) * rate;
+    *cur = time + gst_guint64_to_gdouble (now - base_time) * rate;
 
     if (in_paused) {
       /* never report less than segment values in paused */
@@ -4716,9 +4623,9 @@ gst_base_sink_get_position (GstBaseSink * basesink, GstFormat format,
     }
 
     GST_DEBUG_OBJECT (basesink,
-        "now %" GST_TIME_FORMAT " - base %" GST_TIME_FORMAT " - accum %"
+        "now %" GST_TIME_FORMAT " - base_time %" GST_TIME_FORMAT " - base %"
         GST_TIME_FORMAT " + time %" GST_TIME_FORMAT "  last %" GST_TIME_FORMAT,
-        GST_TIME_ARGS (now), GST_TIME_ARGS (base), GST_TIME_ARGS (accum),
+        GST_TIME_ARGS (now), GST_TIME_ARGS (base_time), GST_TIME_ARGS (base),
         GST_TIME_ARGS (time), GST_TIME_ARGS (last));
   }
 
@@ -4774,7 +4681,7 @@ gst_base_sink_get_duration (GstBaseSink * basesink, GstFormat format,
      * should be done at a higher level. */
     res = gst_pad_query_peer_duration (basesink->sinkpad, &uformat, &uduration);
     if (res) {
-      gst_segment_set_duration (&basesink->segment, uformat, uduration);
+      basesink->segment.duration = uduration;
       if (format != uformat) {
         /* convert to the requested format */
         res = gst_pad_query_convert (basesink->sinkpad, uformat, uduration,
@@ -4952,17 +4859,17 @@ gst_base_sink_change_state (GstElement * element, GstStateChange transition)
     case GST_STATE_CHANGE_READY_TO_PAUSED:
       /* need to complete preroll before this state change completes, there
        * is no data flow in READY so we can safely assume we need to preroll. */
-      GST_PAD_PREROLL_LOCK (basesink->sinkpad);
+      GST_BASE_SINK_PREROLL_LOCK (basesink);
       GST_DEBUG_OBJECT (basesink, "READY to PAUSED");
       basesink->have_newsegment = FALSE;
       gst_segment_init (&basesink->segment, GST_FORMAT_UNDEFINED);
-      gst_segment_init (basesink->abidata.ABI.clip_segment,
-          GST_FORMAT_UNDEFINED);
+      gst_segment_init (&basesink->clip_segment, GST_FORMAT_UNDEFINED);
       basesink->offset = 0;
       basesink->have_preroll = FALSE;
       priv->step_unlock = FALSE;
       basesink->need_preroll = TRUE;
       basesink->playing_async = TRUE;
+      basesink->priv->reset_time = FALSE;
       priv->current_sstart = GST_CLOCK_TIME_NONE;
       priv->current_sstop = GST_CLOCK_TIME_NONE;
       priv->eos_rtime = GST_CLOCK_TIME_NONE;
@@ -4980,14 +4887,14 @@ gst_base_sink_change_state (GstElement * element, GstStateChange transition)
          * the state change function */
         ret = GST_STATE_CHANGE_ASYNC;
         gst_element_post_message (GST_ELEMENT_CAST (basesink),
-            gst_message_new_async_start (GST_OBJECT_CAST (basesink), FALSE));
+            gst_message_new_async_start (GST_OBJECT_CAST (basesink)));
       } else {
         priv->have_latency = TRUE;
       }
-      GST_PAD_PREROLL_UNLOCK (basesink->sinkpad);
+      GST_BASE_SINK_PREROLL_UNLOCK (basesink);
       break;
     case GST_STATE_CHANGE_PAUSED_TO_PLAYING:
-      GST_PAD_PREROLL_LOCK (basesink->sinkpad);
+      GST_BASE_SINK_PREROLL_LOCK (basesink);
       if (!gst_base_sink_needs_preroll (basesink)) {
         GST_DEBUG_OBJECT (basesink, "PAUSED to PLAYING, don't need preroll");
         /* no preroll needed anymore now. */
@@ -5003,7 +4910,7 @@ gst_base_sink_change_state (GstElement * element, GstStateChange transition)
           gst_element_post_message (GST_ELEMENT_CAST (basesink), message);
         } else {
           GST_DEBUG_OBJECT (basesink, "signal preroll");
-          GST_PAD_PREROLL_SIGNAL (basesink->sinkpad);
+          GST_BASE_SINK_PREROLL_SIGNAL (basesink);
         }
       } else {
         GST_DEBUG_OBJECT (basesink, "PAUSED to PLAYING, we are not prerolled");
@@ -5015,10 +4922,10 @@ gst_base_sink_change_state (GstElement * element, GstStateChange transition)
           GST_DEBUG_OBJECT (basesink, "doing async state change");
           ret = GST_STATE_CHANGE_ASYNC;
           gst_element_post_message (GST_ELEMENT_CAST (basesink),
-              gst_message_new_async_start (GST_OBJECT_CAST (basesink), FALSE));
+              gst_message_new_async_start (GST_OBJECT_CAST (basesink)));
         }
       }
-      GST_PAD_PREROLL_UNLOCK (basesink->sinkpad);
+      GST_BASE_SINK_PREROLL_UNLOCK (basesink);
       break;
     default:
       break;
@@ -5042,7 +4949,7 @@ gst_base_sink_change_state (GstElement * element, GstStateChange transition)
       if (bclass->unlock)
         bclass->unlock (basesink);
 
-      GST_PAD_PREROLL_LOCK (basesink->sinkpad);
+      GST_BASE_SINK_PREROLL_LOCK (basesink);
       GST_DEBUG_OBJECT (basesink, "got preroll lock");
       /* now that we have the PREROLL lock, clear our unlock request */
       if (bclass->unlock_stop)
@@ -5077,8 +4984,7 @@ gst_base_sink_change_state (GstElement * element, GstStateChange transition)
             GST_DEBUG_OBJECT (basesink, "doing async state change");
             ret = GST_STATE_CHANGE_ASYNC;
             gst_element_post_message (GST_ELEMENT_CAST (basesink),
-                gst_message_new_async_start (GST_OBJECT_CAST (basesink),
-                    FALSE));
+                gst_message_new_async_start (GST_OBJECT_CAST (basesink)));
           }
         }
       }
@@ -5086,10 +4992,10 @@ gst_base_sink_change_state (GstElement * element, GstStateChange transition)
           ", dropped: %" G_GUINT64_FORMAT, priv->rendered, priv->dropped);
 
       gst_base_sink_reset_qos (basesink);
-      GST_PAD_PREROLL_UNLOCK (basesink->sinkpad);
+      GST_BASE_SINK_PREROLL_UNLOCK (basesink);
       break;
     case GST_STATE_CHANGE_PAUSED_TO_READY:
-      GST_PAD_PREROLL_LOCK (basesink->sinkpad);
+      GST_BASE_SINK_PREROLL_LOCK (basesink);
       /* start by reseting our position state with the object lock so that the
        * position query gets the right idea. We do this before we post the
        * messages so that the message handlers pick this up. */
@@ -5116,13 +5022,13 @@ gst_base_sink_change_state (GstElement * element, GstStateChange transition)
                   GST_STATE_PLAYING, GST_STATE_PAUSED, GST_STATE_READY));
 
           gst_element_post_message (GST_ELEMENT_CAST (basesink),
-              gst_message_new_async_done (GST_OBJECT_CAST (basesink)));
+              gst_message_new_async_done (GST_OBJECT_CAST (basesink), FALSE));
         }
         priv->commited = TRUE;
       } else {
         GST_DEBUG_OBJECT (basesink, "PAUSED to READY, don't need_preroll");
       }
-      GST_PAD_PREROLL_UNLOCK (basesink->sinkpad);
+      GST_BASE_SINK_PREROLL_UNLOCK (basesink);
       break;
     case GST_STATE_CHANGE_READY_TO_NULL:
       if (bclass->stop) {
index a4215b8..c651a44 100644 (file)
@@ -44,6 +44,19 @@ G_BEGIN_DECLS
  */
 #define GST_BASE_SINK_PAD(obj)          (GST_BASE_SINK_CAST (obj)->sinkpad)
 
+#define GST_BASE_SINK_GET_PREROLL_LOCK(pad)   (GST_BASE_SINK_CAST(pad)->preroll_lock)
+#define GST_BASE_SINK_PREROLL_LOCK(pad)       (g_mutex_lock(GST_BASE_SINK_GET_PREROLL_LOCK(pad)))
+#define GST_BASE_SINK_PREROLL_TRYLOCK(pad)    (g_mutex_trylock(GST_BASE_SINK_GET_PREROLL_LOCK(pad)))
+#define GST_BASE_SINK_PREROLL_UNLOCK(pad)     (g_mutex_unlock(GST_BASE_SINK_GET_PREROLL_LOCK(pad)))
+
+#define GST_BASE_SINK_GET_PREROLL_COND(pad)   (GST_BASE_SINK_CAST(pad)->preroll_cond)
+#define GST_BASE_SINK_PREROLL_WAIT(pad)       \
+      g_cond_wait (GST_BASE_SINK_GET_PREROLL_COND (pad), GST_BASE_SINK_GET_PREROLL_LOCK (pad))
+#define GST_BASE_SINK_PREROLL_TIMED_WAIT(pad, timeval) \
+      g_cond_timed_wait (GST_BASE_SINK_GET_PREROLL_COND (pad), GST_BASE_SINK_GET_PREROLL_LOCK (pad), timeval)
+#define GST_BASE_SINK_PREROLL_SIGNAL(pad)     g_cond_signal (GST_BASE_SINK_GET_PREROLL_COND (pad));
+#define GST_BASE_SINK_PREROLL_BROADCAST(pad)  g_cond_broadcast (GST_BASE_SINK_GET_PREROLL_COND (pad));
+
 typedef struct _GstBaseSink GstBaseSink;
 typedef struct _GstBaseSinkClass GstBaseSinkClass;
 typedef struct _GstBaseSinkPrivate GstBaseSinkPrivate;
@@ -66,6 +79,8 @@ struct _GstBaseSink {
   gboolean       can_activate_push;
 
   /*< protected >*/ /* with PREROLL_LOCK */
+  GMutex        *preroll_lock;
+  GCond         *preroll_cond;
   GQueue        *preroll_queue;
   gint           preroll_queue_max_len; /* FIXME-0.11: the property is guint */
   gint           preroll_queued;
@@ -80,26 +95,21 @@ struct _GstBaseSink {
   /*< protected >*/ /* with STREAM_LOCK */
   gboolean       have_newsegment;
   GstSegment     segment;
+  GstSegment     clip_segment;
 
   /*< private >*/ /* with LOCK */
   GstClockID     clock_id;
   GstClockTime   end_time;
   gboolean       sync;
   gboolean       flushing;
+  gboolean       running;
 
-  /*< private >*/
-  union {
-    struct {
-      /* segment used for clipping incoming buffers */
-      GstSegment    *clip_segment;
-      /* max amount of time a buffer can be late, -1 no limit. */
-      gint64         max_lateness;
-      gboolean       running;
-    } ABI;
-    gpointer _gst_reserved[GST_PADDING_LARGE - 1];
-  } abidata;
+  gint64         max_lateness;
 
+  /*< private >*/
   GstBaseSinkPrivate *priv;
+
+  gpointer _gst_reserved[GST_PADDING_LARGE];
 };
 
 /**
@@ -107,7 +117,6 @@ struct _GstBaseSink {
  * @parent_class: Element parent class
  * @get_caps: Called to get sink pad caps from the subclass
  * @set_caps: Notify subclass of changed caps
- * @buffer_alloc: Subclasses can override to perform custom buffer allocations
  * @get_times: Called to get the start and end times for synchronising
  *     the passed buffer to the clock
  * @start: Start processing. Ideal for opening resources in the subclass
@@ -122,9 +131,6 @@ struct _GstBaseSink {
  *     correct moment if the #GstBaseSink has been set to sync to the clock.
  * @render_list: Same as @render but used whith buffer lists instead of
  *     buffers. Since: 0.10.24
- * @async_play: Subclasses should override this when they need to perform
- *     special processing when changing to the PLAYING state asynchronously.
- *     Called with the OBJECT_LOCK held.
  * @activate_pull: Subclasses should override this when they can provide an
  *     alternate method of spawning a thread to drive the pipeline in pull mode.
  *     Should start or stop the pulling thread, depending on the value of the
@@ -142,13 +148,14 @@ struct _GstBaseSinkClass {
   GstElementClass parent_class;
 
   /* get caps from subclass */
-  GstCaps*      (*get_caps)     (GstBaseSink *sink);
+  GstCaps*      (*get_caps)     (GstBaseSink *sink, GstCaps *filter);
   /* notify subclass of new caps */
   gboolean      (*set_caps)     (GstBaseSink *sink, GstCaps *caps);
 
-  /* allocate a new buffer with given caps */
-  GstFlowReturn (*buffer_alloc) (GstBaseSink *sink, guint64 offset, guint size,
-                                 GstCaps *caps, GstBuffer **buf);
+  /* fixate sink caps during pull-mode negotiation */
+  void          (*fixate)       (GstBaseSink *sink, GstCaps *caps);
+  /* start or stop a pulling thread */
+  gboolean      (*activate_pull)(GstBaseSink *sink, gboolean active);
 
   /* get the start and end times for syncing on this buffer */
   void          (*get_times)    (GstBaseSink *sink, GstBuffer *buffer,
@@ -161,33 +168,21 @@ struct _GstBaseSinkClass {
   /* unlock any pending access to the resource. subclasses should unlock
    * any function ASAP. */
   gboolean      (*unlock)       (GstBaseSink *sink);
-
-  /* notify subclass of event, preroll buffer or real buffer */
-  gboolean      (*event)        (GstBaseSink *sink, GstEvent *event);
-  GstFlowReturn (*preroll)      (GstBaseSink *sink, GstBuffer *buffer);
-  GstFlowReturn (*render)       (GstBaseSink *sink, GstBuffer *buffer);
-
-  /* ABI additions */
-
-  /* when an ASYNC state change to PLAYING happens */ /* with LOCK */
-  GstStateChangeReturn (*async_play)   (GstBaseSink *sink);
-
-  /* start or stop a pulling thread */
-  gboolean      (*activate_pull)(GstBaseSink *sink, gboolean active);
-
-  /* fixate sink caps during pull-mode negotiation */
-  void          (*fixate)       (GstBaseSink *sink, GstCaps *caps);
-
   /* Clear a previously indicated unlock request not that unlocking is
    * complete. Sub-classes should clear any command queue or indicator they
    * set during unlock */
   gboolean      (*unlock_stop)  (GstBaseSink *sink);
 
+  /* notify subclass of event, preroll buffer or real buffer */
+  gboolean      (*event)        (GstBaseSink *sink, GstEvent *event);
+
+  GstFlowReturn (*preroll)      (GstBaseSink *sink, GstBuffer *buffer);
+  GstFlowReturn (*render)       (GstBaseSink *sink, GstBuffer *buffer);
   /* Render a BufferList */
   GstFlowReturn (*render_list)  (GstBaseSink *sink, GstBufferList *buffer_list);
 
   /*< private >*/
-  gpointer       _gst_reserved[GST_PADDING_LARGE-5];
+  gpointer       _gst_reserved[GST_PADDING_LARGE];
 };
 
 GType gst_base_sink_get_type(void);
index 947562c..8a7e2f9 100644 (file)
@@ -47,9 +47,6 @@
  *   </listitem>
  * </itemizedlist>
  *
- * Since 0.10.9, any #GstBaseSrc can enable pull based scheduling at any time
- * by overriding #GstBaseSrcClass.check_get_range() so that it returns %TRUE.
- *
  * If all the conditions are met for operating in pull mode, #GstBaseSrc is
  * automatically seekable in push mode as well. The following conditions must
  * be met to make the element seekable in push mode when the format is not
  * an EOS message to be posted on the pipeline's bus. Once this EOS message is
  * received, it may safely shut down the entire pipeline.
  *
- * The old behaviour for controlled shutdown introduced since GStreamer 0.10.3
- * is still available but deprecated as it is dangerous and less flexible.
- *
  * Last reviewed on 2007-12-19 (0.10.16)
  * </para>
  * </refsect2>
@@ -212,15 +206,11 @@ enum
 
 struct _GstBaseSrcPrivate
 {
-  gboolean last_sent_eos;       /* last thing we did was send an EOS (we set this
-                                 * to avoid the sending of two EOS in some cases) */
   gboolean discont;
   gboolean flushing;
 
-  /* two segments to be sent in the streaming thread with STREAM_LOCK */
-  GstEvent *close_segment;
-  GstEvent *start_segment;
-  gboolean newsegment_pending;
+  /* if segment should be sent */
+  gboolean segment_pending;
 
   /* if EOS is pending (atomic) */
   gint pending_eos;
@@ -248,11 +238,15 @@ struct _GstBaseSrcPrivate
   gboolean qos_enabled;
   gdouble proportion;
   GstClockTime earliest_time;
+
+  GstBufferPool *pool;
+  const GstMemoryAllocator *allocator;
+  guint prefix;
+  guint alignment;
 };
 
 static GstElementClass *parent_class = NULL;
 
-static void gst_base_src_base_init (gpointer g_class);
 static void gst_base_src_class_init (GstBaseSrcClass * klass);
 static void gst_base_src_init (GstBaseSrc * src, gpointer g_class);
 static void gst_base_src_finalize (GObject * object);
@@ -267,7 +261,7 @@ gst_base_src_get_type (void)
     GType _type;
     static const GTypeInfo base_src_info = {
       sizeof (GstBaseSrcClass),
-      (GBaseInitFunc) gst_base_src_base_init,
+      NULL,
       NULL,
       (GClassInitFunc) gst_base_src_class_init,
       NULL,
@@ -284,10 +278,10 @@ gst_base_src_get_type (void)
   return base_src_type;
 }
 
-static GstCaps *gst_base_src_getcaps (GstPad * pad);
-static gboolean gst_base_src_setcaps (GstPad * pad, GstCaps * caps);
+static GstCaps *gst_base_src_getcaps (GstPad * pad, GstCaps * filter);
 static void gst_base_src_fixate (GstPad * pad, GstCaps * caps);
 
+static gboolean gst_base_src_is_random_access (GstBaseSrc * src);
 static gboolean gst_base_src_activate_push (GstPad * pad, gboolean active);
 static gboolean gst_base_src_activate_pull (GstPad * pad, gboolean active);
 static void gst_base_src_set_property (GObject * object, guint prop_id,
@@ -301,12 +295,16 @@ static const GstQueryType *gst_base_src_get_query_types (GstElement * element);
 
 static gboolean gst_base_src_query (GstPad * pad, GstQuery * query);
 
+static gboolean gst_base_src_activate_pool (GstBaseSrc * basesrc,
+    gboolean active);
 static gboolean gst_base_src_default_negotiate (GstBaseSrc * basesrc);
 static gboolean gst_base_src_default_do_seek (GstBaseSrc * src,
     GstSegment * segment);
 static gboolean gst_base_src_default_query (GstBaseSrc * src, GstQuery * query);
 static gboolean gst_base_src_default_prepare_seek_segment (GstBaseSrc * src,
     GstEvent * event, GstSegment * segment);
+static GstFlowReturn gst_base_src_default_create (GstBaseSrc * basesrc,
+    guint64 offset, guint size, GstBuffer ** buf);
 
 static gboolean gst_base_src_set_flushing (GstBaseSrc * basesrc,
     gboolean flushing, gboolean live_play, gboolean unlock, gboolean * playing);
@@ -317,23 +315,16 @@ static GstStateChangeReturn gst_base_src_change_state (GstElement * element,
     GstStateChange transition);
 
 static void gst_base_src_loop (GstPad * pad);
-static gboolean gst_base_src_pad_check_get_range (GstPad * pad);
-static gboolean gst_base_src_default_check_get_range (GstBaseSrc * bsrc);
 static GstFlowReturn gst_base_src_pad_get_range (GstPad * pad, guint64 offset,
     guint length, GstBuffer ** buf);
 static GstFlowReturn gst_base_src_get_range (GstBaseSrc * src, guint64 offset,
     guint length, GstBuffer ** buf);
 static gboolean gst_base_src_seekable (GstBaseSrc * src);
+static gboolean gst_base_src_negotiate (GstBaseSrc * basesrc);
 static gboolean gst_base_src_update_length (GstBaseSrc * src, guint64 offset,
     guint * length);
 
 static void
-gst_base_src_base_init (gpointer g_class)
-{
-  GST_DEBUG_CATEGORY_INIT (gst_base_src_debug, "basesrc", 0, "basesrc element");
-}
-
-static void
 gst_base_src_class_init (GstBaseSrcClass * klass)
 {
   GObjectClass *gobject_class;
@@ -342,6 +333,8 @@ gst_base_src_class_init (GstBaseSrcClass * klass)
   gobject_class = G_OBJECT_CLASS (klass);
   gstelement_class = GST_ELEMENT_CLASS (klass);
 
+  GST_DEBUG_CATEGORY_INIT (gst_base_src_debug, "basesrc", 0, "basesrc element");
+
   g_type_class_add_private (klass, sizeof (GstBaseSrcPrivate));
 
   parent_class = g_type_class_peek_parent (klass);
@@ -350,10 +343,9 @@ gst_base_src_class_init (GstBaseSrcClass * klass)
   gobject_class->set_property = gst_base_src_set_property;
   gobject_class->get_property = gst_base_src_get_property;
 
-/* FIXME 0.11: blocksize property should be int, not ulong (min is >max here) */
   g_object_class_install_property (gobject_class, PROP_BLOCKSIZE,
-      g_param_spec_ulong ("blocksize", "Block size",
-          "Size in bytes to read per buffer (-1 = default)", 0, G_MAXULONG,
+      g_param_spec_uint ("blocksize", "Block size",
+          "Size in bytes to read per buffer (-1 = default)", 0, G_MAXUINT,
           DEFAULT_BLOCKSIZE, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
   g_object_class_install_property (gobject_class, PROP_NUM_BUFFERS,
       g_param_spec_int ("num-buffers", "num-buffers",
@@ -379,10 +371,9 @@ gst_base_src_class_init (GstBaseSrcClass * klass)
   klass->event = GST_DEBUG_FUNCPTR (gst_base_src_default_event);
   klass->do_seek = GST_DEBUG_FUNCPTR (gst_base_src_default_do_seek);
   klass->query = GST_DEBUG_FUNCPTR (gst_base_src_default_query);
-  klass->check_get_range =
-      GST_DEBUG_FUNCPTR (gst_base_src_default_check_get_range);
   klass->prepare_seek_segment =
       GST_DEBUG_FUNCPTR (gst_base_src_default_prepare_seek_segment);
+  klass->create = GST_DEBUG_FUNCPTR (gst_base_src_default_create);
 
   /* Registering debug symbols for function pointers */
   GST_DEBUG_REGISTER_FUNCPTR (gst_base_src_activate_push);
@@ -390,9 +381,7 @@ gst_base_src_class_init (GstBaseSrcClass * klass)
   GST_DEBUG_REGISTER_FUNCPTR (gst_base_src_event_handler);
   GST_DEBUG_REGISTER_FUNCPTR (gst_base_src_query);
   GST_DEBUG_REGISTER_FUNCPTR (gst_base_src_pad_get_range);
-  GST_DEBUG_REGISTER_FUNCPTR (gst_base_src_pad_check_get_range);
   GST_DEBUG_REGISTER_FUNCPTR (gst_base_src_getcaps);
-  GST_DEBUG_REGISTER_FUNCPTR (gst_base_src_setcaps);
   GST_DEBUG_REGISTER_FUNCPTR (gst_base_src_fixate);
 }
 
@@ -411,7 +400,6 @@ gst_base_src_init (GstBaseSrc * basesrc, gpointer g_class)
   basesrc->num_buffers_left = -1;
 
   basesrc->can_activate_push = TRUE;
-  basesrc->pad_mode = GST_ACTIVATE_NONE;
 
   pad_template =
       gst_element_class_get_pad_template (GST_ELEMENT_CLASS (g_class), "src");
@@ -425,10 +413,8 @@ gst_base_src_init (GstBaseSrc * basesrc, gpointer g_class)
   gst_pad_set_activatepull_function (pad, gst_base_src_activate_pull);
   gst_pad_set_event_function (pad, gst_base_src_event_handler);
   gst_pad_set_query_function (pad, gst_base_src_query);
-  gst_pad_set_checkgetrange_function (pad, gst_base_src_pad_check_get_range);
   gst_pad_set_getrange_function (pad, gst_base_src_pad_get_range);
   gst_pad_set_getcaps_function (pad, gst_base_src_getcaps);
-  gst_pad_set_setcaps_function (pad, gst_base_src_setcaps);
   gst_pad_set_fixatecaps_function (pad, gst_base_src_fixate);
 
   /* hold pointer to pad */
@@ -440,7 +426,7 @@ gst_base_src_init (GstBaseSrc * basesrc, gpointer g_class)
   basesrc->clock_id = NULL;
   /* we operate in BYTES by default */
   gst_base_src_set_format (basesrc, GST_FORMAT_BYTES);
-  basesrc->data.ABI.typefind = DEFAULT_TYPEFIND;
+  basesrc->typefind = DEFAULT_TYPEFIND;
   basesrc->priv->do_timestamp = DEFAULT_DO_TIMESTAMP;
   g_atomic_int_set (&basesrc->priv->have_events, FALSE);
 
@@ -461,7 +447,7 @@ gst_base_src_finalize (GObject * object)
   g_mutex_free (basesrc->live_lock);
   g_cond_free (basesrc->live_cond);
 
-  event_p = &basesrc->data.ABI.pending_seek;
+  event_p = &basesrc->pending_seek;
   gst_event_replace (event_p, NULL);
 
   if (basesrc->priv->pending_events) {
@@ -667,9 +653,8 @@ gst_base_src_query_latency (GstBaseSrc * src, gboolean * live,
  *
  * Since: 0.10.22
  */
-/* FIXME 0.11: blocksize property should be int, not ulong */
 void
-gst_base_src_set_blocksize (GstBaseSrc * src, gulong blocksize)
+gst_base_src_set_blocksize (GstBaseSrc * src, guint blocksize)
 {
   g_return_if_fail (GST_IS_BASE_SRC (src));
 
@@ -688,11 +673,10 @@ gst_base_src_set_blocksize (GstBaseSrc * src, gulong blocksize)
  *
  * Since: 0.10.22
  */
-/* FIXME 0.11: blocksize property should be int, not ulong */
-gulong
+guint
 gst_base_src_get_blocksize (GstBaseSrc * src)
 {
-  gulong res;
+  gint res;
 
   g_return_val_if_fail (GST_IS_BASE_SRC (src), 0);
 
@@ -779,51 +763,33 @@ gst_base_src_new_seamless_segment (GstBaseSrc * src, gint64 start, gint64 stop,
       GST_TIME_ARGS (stop), GST_TIME_ARGS (position));
 
   GST_OBJECT_LOCK (src);
-  if (src->data.ABI.running && !src->priv->newsegment_pending) {
-    if (src->priv->close_segment)
-      gst_event_unref (src->priv->close_segment);
-    src->priv->close_segment =
-        gst_event_new_new_segment_full (TRUE,
-        src->segment.rate, src->segment.applied_rate, src->segment.format,
-        src->segment.start, src->segment.last_stop, src->segment.time);
-  }
-
-  gst_segment_set_newsegment_full (&src->segment, FALSE, src->segment.rate,
-      src->segment.applied_rate, src->segment.format, start, stop, position);
-
-  if (src->priv->start_segment)
-    gst_event_unref (src->priv->start_segment);
-  if (src->segment.rate >= 0.0) {
-    /* forward, we send data from last_stop to stop */
-    src->priv->start_segment =
-        gst_event_new_new_segment_full (FALSE,
-        src->segment.rate, src->segment.applied_rate, src->segment.format,
-        src->segment.last_stop, stop, src->segment.time);
-  } else {
-    /* reverse, we send data from last_stop to start */
-    src->priv->start_segment =
-        gst_event_new_new_segment_full (FALSE,
-        src->segment.rate, src->segment.applied_rate, src->segment.format,
-        src->segment.start, src->segment.last_stop, src->segment.time);
-  }
+
+  src->segment.base = gst_segment_to_running_time (&src->segment,
+      src->segment.format, src->segment.position);
+  src->segment.start = start;
+  src->segment.stop = stop;
+  src->segment.position = position;
+
+  /* forward, we send data from position to stop */
+  src->priv->segment_pending = TRUE;
   GST_OBJECT_UNLOCK (src);
 
   src->priv->discont = TRUE;
-  src->data.ABI.running = TRUE;
+  src->running = TRUE;
 
   return res;
 }
 
 static gboolean
-gst_base_src_setcaps (GstPad * pad, GstCaps * caps)
+gst_base_src_setcaps (GstBaseSrc * bsrc, GstCaps * caps)
 {
   GstBaseSrcClass *bclass;
-  GstBaseSrc *bsrc;
   gboolean res = TRUE;
 
-  bsrc = GST_BASE_SRC (GST_PAD_PARENT (pad));
   bclass = GST_BASE_SRC_GET_CLASS (bsrc);
 
+  gst_pad_push_event (bsrc->srcpad, gst_event_new_caps (caps));
+
   if (bclass->set_caps)
     res = bclass->set_caps (bsrc, caps);
 
@@ -831,7 +797,7 @@ gst_base_src_setcaps (GstPad * pad, GstCaps * caps)
 }
 
 static GstCaps *
-gst_base_src_getcaps (GstPad * pad)
+gst_base_src_getcaps (GstPad * pad, GstCaps * filter)
 {
   GstBaseSrcClass *bclass;
   GstBaseSrc *bsrc;
@@ -840,7 +806,7 @@ gst_base_src_getcaps (GstPad * pad)
   bsrc = GST_BASE_SRC (GST_PAD_PARENT (pad));
   bclass = GST_BASE_SRC_GET_CLASS (bsrc);
   if (bclass->get_caps)
-    caps = bclass->get_caps (bsrc);
+    caps = bclass->get_caps (bsrc, filter);
 
   if (caps == NULL) {
     GstPadTemplate *pad_template;
@@ -848,7 +814,16 @@ gst_base_src_getcaps (GstPad * pad)
     pad_template =
         gst_element_class_get_pad_template (GST_ELEMENT_CLASS (bclass), "src");
     if (pad_template != NULL) {
-      caps = gst_caps_ref (gst_pad_template_get_caps (pad_template));
+      caps = gst_pad_template_get_caps (pad_template);
+
+      if (filter) {
+        GstCaps *intersection;
+
+        intersection =
+            gst_caps_intersect_full (filter, caps, GST_CAPS_INTERSECT_FIRST);
+        gst_caps_unref (caps);
+        caps = intersection;
+      }
     }
   }
   return caps;
@@ -892,7 +867,7 @@ gst_base_src_default_query (GstBaseSrc * src, GstQuery * query)
           gint64 duration;
 
           GST_OBJECT_LOCK (src);
-          position = src->segment.last_stop;
+          position = src->segment.position;
           duration = src->segment.duration;
           GST_OBJECT_UNLOCK (src);
 
@@ -917,7 +892,7 @@ gst_base_src_default_query (GstBaseSrc * src, GstQuery * query)
           GST_OBJECT_LOCK (src);
           position =
               gst_segment_to_stream_time (&src->segment, src->segment.format,
-              src->segment.last_stop);
+              src->segment.position);
           seg_format = src->segment.format;
           GST_OBJECT_UNLOCK (src);
 
@@ -1122,6 +1097,20 @@ gst_base_src_default_query (GstBaseSrc * src, GstQuery * query)
       gst_query_set_buffering_range (query, format, start, stop, estimated);
       break;
     }
+    case GST_QUERY_SCHEDULING:
+    {
+      gboolean random_access;
+
+      random_access = gst_base_src_is_random_access (src);
+
+      /* we can operate in getrange mode if the native format is bytes
+       * and we are seekable, this condition is set in the random_access
+       * flag and is set in the _start() method. */
+      gst_query_set_scheduling (query, random_access, TRUE, FALSE, 1, -1, 1);
+
+      res = TRUE;
+      break;
+    }
     default:
       res = FALSE;
       break;
@@ -1213,7 +1202,7 @@ gst_base_src_default_prepare_seek_segment (GstBaseSrc * src, GstEvent * event,
   dest_format = segment->format;
 
   if (seek_format == dest_format) {
-    gst_segment_set_seek (segment, rate, seek_format, flags,
+    gst_segment_do_seek (segment, rate, seek_format, flags,
         cur_type, cur, stop_type, stop, &update);
     return TRUE;
   }
@@ -1235,7 +1224,7 @@ gst_base_src_default_prepare_seek_segment (GstBaseSrc * src, GstEvent * event,
   }
 
   /* And finally, configure our output segment in the desired format */
-  gst_segment_set_seek (segment, rate, dest_format, flags, cur_type, cur,
+  gst_segment_do_seek (segment, rate, dest_format, flags, cur_type, cur,
       stop_type, stop, &update);
 
   if (!res)
@@ -1265,6 +1254,77 @@ gst_base_src_prepare_seek_segment (GstBaseSrc * src, GstEvent * event,
   return result;
 }
 
+static GstFlowReturn
+gst_base_src_alloc_buffer (GstBaseSrc * src, guint64 offset,
+    guint size, GstBuffer ** buffer)
+{
+  GstFlowReturn ret;
+  GstBaseSrcPrivate *priv = src->priv;
+
+  if (priv->pool) {
+    ret = gst_buffer_pool_acquire_buffer (priv->pool, buffer, NULL);
+  } else {
+    *buffer = gst_buffer_new_allocate (priv->allocator, size, priv->alignment);
+    if (G_UNLIKELY (*buffer == NULL))
+      goto alloc_failed;
+
+    ret = GST_FLOW_OK;
+  }
+  return ret;
+
+  /* ERRORS */
+alloc_failed:
+  {
+    GST_ERROR_OBJECT (src, "Failed to allocate %u bytes", size);
+    return GST_FLOW_ERROR;
+  }
+}
+
+static GstFlowReturn
+gst_base_src_default_create (GstBaseSrc * src, guint64 offset,
+    guint size, GstBuffer ** buffer)
+{
+  GstBaseSrcClass *bclass;
+  GstFlowReturn ret;
+
+  bclass = GST_BASE_SRC_GET_CLASS (src);
+
+  if (G_UNLIKELY (!bclass->fill))
+    goto no_function;
+
+  ret = gst_base_src_alloc_buffer (src, offset, size, buffer);
+  if (G_UNLIKELY (ret != GST_FLOW_OK))
+    goto alloc_failed;
+
+  if (G_LIKELY (size > 0)) {
+    /* only call fill when there is a size */
+    ret = bclass->fill (src, offset, size, *buffer);
+    if (G_UNLIKELY (ret != GST_FLOW_OK))
+      goto not_ok;
+  }
+
+  return GST_FLOW_OK;
+
+  /* ERRORS */
+no_function:
+  {
+    GST_DEBUG_OBJECT (src, "no fill function");
+    return GST_FLOW_NOT_SUPPORTED;
+  }
+alloc_failed:
+  {
+    GST_ERROR_OBJECT (src, "Failed to allocate %u bytes", size);
+    return ret;
+  }
+not_ok:
+  {
+    GST_DEBUG_OBJECT (src, "fill returned %d (%s)", ret,
+        gst_flow_get_name (ret));
+    gst_buffer_unref (*buffer);
+    return ret;
+  }
+}
+
 /* this code implements the seeking. It is a good example
  * handling all cases.
  *
@@ -1416,7 +1476,7 @@ gst_base_src_perform_seek (GstBaseSrc * src, GstEvent * event, gboolean unlock)
       } else {
         /* The seek format matches our processing format, no need to ask the
          * the subclass to configure the segment. */
-        gst_segment_set_seek (&seeksegment, rate, seek_format, flags,
+        gst_segment_do_seek (&seeksegment, rate, seek_format, flags,
             cur_type, cur, stop_type, stop, &update);
       }
     }
@@ -1427,33 +1487,19 @@ gst_base_src_perform_seek (GstBaseSrc * src, GstEvent * event, gboolean unlock)
   if (res) {
     GST_DEBUG_OBJECT (src, "segment configured from %" G_GINT64_FORMAT
         " to %" G_GINT64_FORMAT ", position %" G_GINT64_FORMAT,
-        seeksegment.start, seeksegment.stop, seeksegment.last_stop);
+        seeksegment.start, seeksegment.stop, seeksegment.position);
 
-    /* do the seek, segment.last_stop contains the new position. */
+    /* do the seek, segment.position contains the new position. */
     res = gst_base_src_do_seek (src, &seeksegment);
   }
 
   /* and prepare to continue streaming */
   if (flush) {
-    tevent = gst_event_new_flush_stop ();
+    tevent = gst_event_new_flush_stop (TRUE);
     gst_event_set_seqnum (tevent, seqnum);
     /* send flush stop, peer will accept data and events again. We
      * are not yet providing data as we still have the STREAM_LOCK. */
     gst_pad_push_event (src->srcpad, tevent);
-  } else if (res && src->data.ABI.running) {
-    /* we are running the current segment and doing a non-flushing seek,
-     * close the segment first based on the last_stop. */
-    GST_DEBUG_OBJECT (src, "closing running segment %" G_GINT64_FORMAT
-        " to %" G_GINT64_FORMAT, src->segment.start, src->segment.last_stop);
-
-    /* queue the segment for sending in the stream thread */
-    if (src->priv->close_segment)
-      gst_event_unref (src->priv->close_segment);
-    src->priv->close_segment =
-        gst_event_new_new_segment_full (TRUE,
-        src->segment.rate, src->segment.applied_rate, src->segment.format,
-        src->segment.start, src->segment.last_stop, src->segment.time);
-    gst_event_set_seqnum (src->priv->close_segment, seqnum);
   }
 
   /* The subclass must have converted the segment to the processing format
@@ -1475,7 +1521,7 @@ gst_base_src_perform_seek (GstBaseSrc * src, GstEvent * event, gboolean unlock)
       GstMessage *message;
 
       message = gst_message_new_segment_start (GST_OBJECT (src),
-          seeksegment.format, seeksegment.last_stop);
+          seeksegment.format, seeksegment.position);
       gst_message_set_seqnum (message, seqnum);
 
       gst_element_post_message (GST_ELEMENT (src), message);
@@ -1486,32 +1532,11 @@ gst_base_src_perform_seek (GstBaseSrc * src, GstEvent * event, gboolean unlock)
     if ((stop = seeksegment.stop) == -1)
       stop = seeksegment.duration;
 
-    GST_DEBUG_OBJECT (src, "Sending newsegment from %" G_GINT64_FORMAT
-        " to %" G_GINT64_FORMAT, seeksegment.start, stop);
-
-    /* now replace the old segment so that we send it in the stream thread the
-     * next time it is scheduled. */
-    if (src->priv->start_segment)
-      gst_event_unref (src->priv->start_segment);
-    if (seeksegment.rate >= 0.0) {
-      /* forward, we send data from last_stop to stop */
-      src->priv->start_segment =
-          gst_event_new_new_segment_full (FALSE,
-          seeksegment.rate, seeksegment.applied_rate, seeksegment.format,
-          seeksegment.last_stop, stop, seeksegment.time);
-    } else {
-      /* reverse, we send data from last_stop to start */
-      src->priv->start_segment =
-          gst_event_new_new_segment_full (FALSE,
-          seeksegment.rate, seeksegment.applied_rate, seeksegment.format,
-          seeksegment.start, seeksegment.last_stop, seeksegment.time);
-    }
-    gst_event_set_seqnum (src->priv->start_segment, seqnum);
-    src->priv->newsegment_pending = TRUE;
+    src->priv->segment_pending = TRUE;
   }
 
   src->priv->discont = TRUE;
-  src->data.ABI.running = TRUE;
+  src->running = TRUE;
   /* and restart the task in case it got paused explicitly or by
    * the FLUSH_START event we pushed out. */
   tres = gst_pad_start_task (src->srcpad, (GstTaskFunction) gst_base_src_loop,
@@ -1593,10 +1618,12 @@ gst_base_src_send_event (GstElement * element, GstEvent * event)
       g_atomic_int_set (&src->priv->pending_eos, TRUE);
       GST_DEBUG_OBJECT (src, "EOS marked, calling unlock");
 
+
       /* unlock the _create function so that we can check the pending_eos flag
        * and we can do EOS. This will eventually release the LIVE_LOCK again so
        * that we can grab it and stop the unlock again. We don't take the stream
        * lock so that this operation is guaranteed to never block. */
+      gst_base_src_activate_pool (src, FALSE);
       if (bclass->unlock)
         bclass->unlock (src);
 
@@ -1608,13 +1635,14 @@ gst_base_src_send_event (GstElement * element, GstEvent * event)
        * lock is enough because that protects the create function. */
       if (bclass->unlock_stop)
         bclass->unlock_stop (src);
+      gst_base_src_activate_pool (src, TRUE);
       GST_LIVE_UNLOCK (src);
 
       result = TRUE;
       break;
     }
-    case GST_EVENT_NEWSEGMENT:
-      /* sending random NEWSEGMENT downstream can break sync. */
+    case GST_EVENT_SEGMENT:
+      /* sending random SEGMENT downstream can break sync. */
       break;
     case GST_EVENT_TAG:
     case GST_EVENT_CUSTOM_DOWNSTREAM:
@@ -1658,7 +1686,7 @@ gst_base_src_send_event (GstElement * element, GstEvent * event)
          * get activated */
         GST_OBJECT_LOCK (src);
         GST_DEBUG_OBJECT (src, "queueing seek");
-        event_p = &src->data.ABI.pending_seek;
+        event_p = &src->pending_seek;
         gst_event_replace ((GstEvent **) event_p, event);
         GST_OBJECT_UNLOCK (src);
         /* assume the seek will work */
@@ -1761,7 +1789,7 @@ gst_base_src_default_event (GstBaseSrc * src, GstEvent * event)
       GstClockTimeDiff diff;
       GstClockTime timestamp;
 
-      gst_event_parse_qos (event, &proportion, &diff, &timestamp);
+      gst_event_parse_qos (event, NULL, &proportion, &diff, &timestamp);
       gst_base_src_update_qos (src, proportion, diff, timestamp);
       result = TRUE;
       break;
@@ -1824,13 +1852,13 @@ gst_base_src_set_property (GObject * object, guint prop_id,
 
   switch (prop_id) {
     case PROP_BLOCKSIZE:
-      gst_base_src_set_blocksize (src, g_value_get_ulong (value));
+      gst_base_src_set_blocksize (src, g_value_get_uint (value));
       break;
     case PROP_NUM_BUFFERS:
       src->num_buffers = g_value_get_int (value);
       break;
     case PROP_TYPEFIND:
-      src->data.ABI.typefind = g_value_get_boolean (value);
+      src->typefind = g_value_get_boolean (value);
       break;
     case PROP_DO_TIMESTAMP:
       gst_base_src_set_do_timestamp (src, g_value_get_boolean (value));
@@ -1851,13 +1879,13 @@ gst_base_src_get_property (GObject * object, guint prop_id, GValue * value,
 
   switch (prop_id) {
     case PROP_BLOCKSIZE:
-      g_value_set_ulong (value, gst_base_src_get_blocksize (src));
+      g_value_set_uint (value, gst_base_src_get_blocksize (src));
       break;
     case PROP_NUM_BUFFERS:
       g_value_set_int (value, src->num_buffers);
       break;
     case PROP_TYPEFIND:
-      g_value_set_boolean (value, src->data.ABI.typefind);
+      g_value_set_boolean (value, src->typefind);
       break;
     case PROP_DO_TIMESTAMP:
       g_value_set_boolean (value, gst_base_src_get_do_timestamp (src));
@@ -2062,7 +2090,7 @@ gst_base_src_update_length (GstBaseSrc * src, guint64 offset, guint * length)
   format = src->segment.format;
   stop = src->segment.stop;
   /* get total file size */
-  size = (guint64) src->segment.duration;
+  size = src->segment.duration;
 
   /* only operate if we are working with bytes */
   if (format != GST_FORMAT_BYTES)
@@ -2114,8 +2142,8 @@ gst_base_src_update_length (GstBaseSrc * src, guint64 offset, guint * length)
   /* keep track of current position and update duration.
    * segment is in bytes, we checked that above. */
   GST_OBJECT_LOCK (src);
-  gst_segment_set_duration (&src->segment, GST_FORMAT_BYTES, size);
-  gst_segment_set_last_stop (&src->segment, GST_FORMAT_BYTES, offset);
+  src->segment.duration = size;
+  src->segment.position = offset;
   GST_OBJECT_UNLOCK (src);
 
   return TRUE;
@@ -2192,16 +2220,10 @@ 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 && !src->is_live) {
-    *buf = gst_buffer_make_metadata_writable (*buf);
+    *buf = gst_buffer_make_writable (*buf);
     GST_BUFFER_TIMESTAMP (*buf) = 0;
   }
 
-  /* set pad caps on the buffer if the buffer had no caps */
-  if (GST_BUFFER_CAPS (*buf) == NULL) {
-    *buf = gst_buffer_make_metadata_writable (*buf);
-    gst_buffer_set_caps (*buf, GST_PAD_CAPS (src->srcpad));
-  }
-
   /* now sync before pushing the buffer */
   status = gst_base_src_do_sync (src, *buf);
 
@@ -2271,7 +2293,7 @@ not_started:
 no_function:
   {
     GST_DEBUG_OBJECT (src, "no create function");
-    return GST_FLOW_ERROR;
+    return GST_FLOW_NOT_SUPPORTED;
   }
 unexpected_length:
   {
@@ -2330,60 +2352,16 @@ flushing:
 }
 
 static gboolean
-gst_base_src_default_check_get_range (GstBaseSrc * src)
+gst_base_src_is_random_access (GstBaseSrc * src)
 {
-  gboolean res;
-
+  /* we need to start the basesrc to check random access */
   if (!GST_OBJECT_FLAG_IS_SET (src, GST_BASE_SRC_STARTED)) {
     GST_LOG_OBJECT (src, "doing start/stop to check get_range support");
     if (G_LIKELY (gst_base_src_start (src)))
       gst_base_src_stop (src);
   }
 
-  /* we can operate in getrange mode if the native format is bytes
-   * and we are seekable, this condition is set in the random_access
-   * flag and is set in the _start() method. */
-  res = src->random_access;
-
-  return res;
-}
-
-static gboolean
-gst_base_src_check_get_range (GstBaseSrc * src)
-{
-  GstBaseSrcClass *bclass;
-  gboolean res;
-
-  bclass = GST_BASE_SRC_GET_CLASS (src);
-
-  if (bclass->check_get_range == NULL)
-    goto no_function;
-
-  res = bclass->check_get_range (src);
-  GST_LOG_OBJECT (src, "%s() returned %d",
-      GST_DEBUG_FUNCPTR_NAME (bclass->check_get_range), (gint) res);
-
-  return res;
-
-  /* ERRORS */
-no_function:
-  {
-    GST_WARNING_OBJECT (src, "no check_get_range function set");
-    return FALSE;
-  }
-}
-
-static gboolean
-gst_base_src_pad_check_get_range (GstPad * pad)
-{
-  GstBaseSrc *src;
-  gboolean res;
-
-  src = GST_BASE_SRC (GST_OBJECT_PARENT (pad));
-
-  res = gst_base_src_check_get_range (src);
-
-  return res;
+  return src->random_access;
 }
 
 static void
@@ -2394,25 +2372,29 @@ gst_base_src_loop (GstPad * pad)
   GstFlowReturn ret;
   gint64 position;
   gboolean eos;
-  gulong blocksize;
+  guint blocksize;
   GList *pending_events = NULL, *tmp;
 
   eos = FALSE;
 
   src = GST_BASE_SRC (GST_OBJECT_PARENT (pad));
 
+  /* check if we need to renegotiate */
+  if (gst_pad_check_reconfigure (pad)) {
+    if (!gst_base_src_negotiate (src))
+      GST_DEBUG_OBJECT (src, "Failed to renegotiate");
+  }
+
   GST_LIVE_LOCK (src);
 
   if (G_UNLIKELY (src->priv->flushing))
     goto flushing;
 
-  src->priv->last_sent_eos = FALSE;
-
   blocksize = src->blocksize;
 
   /* if we operate in bytes, we can calculate an offset */
   if (src->segment.format == GST_FORMAT_BYTES) {
-    position = src->segment.last_stop;
+    position = src->segment.position;
     /* for negative rates, start with subtracting the blocksize */
     if (src->segment.rate < 0.0) {
       /* we cannot go below segment.start */
@@ -2427,7 +2409,7 @@ gst_base_src_loop (GstPad * pad)
   } else
     position = -1;
 
-  GST_LOG_OBJECT (src, "next_ts %" GST_TIME_FORMAT " size %lu",
+  GST_LOG_OBJECT (src, "next_ts %" GST_TIME_FORMAT " size %u",
       GST_TIME_ARGS (position), blocksize);
 
   ret = gst_base_src_get_range (src, position, blocksize, &buf);
@@ -2442,15 +2424,10 @@ gst_base_src_loop (GstPad * pad)
     goto null_buffer;
 
   /* push events to close/start our segment before we push the buffer. */
-  if (G_UNLIKELY (src->priv->close_segment)) {
-    gst_pad_push_event (pad, src->priv->close_segment);
-    src->priv->close_segment = NULL;
-  }
-  if (G_UNLIKELY (src->priv->start_segment)) {
-    gst_pad_push_event (pad, src->priv->start_segment);
-    src->priv->start_segment = NULL;
+  if (G_UNLIKELY (src->priv->segment_pending)) {
+    gst_pad_push_event (pad, gst_event_new_segment (&src->segment));
+    src->priv->segment_pending = FALSE;
   }
-  src->priv->newsegment_pending = FALSE;
 
   if (g_atomic_int_get (&src->priv->have_events)) {
     GST_OBJECT_LOCK (src);
@@ -2474,7 +2451,7 @@ gst_base_src_loop (GstPad * pad)
   switch (src->segment.format) {
     case GST_FORMAT_BYTES:
     {
-      guint bufsize = GST_BUFFER_SIZE (buf);
+      guint bufsize = gst_buffer_get_size (buf);
 
       /* we subtracted above for negative rates */
       if (src->segment.rate >= 0.0)
@@ -2491,7 +2468,7 @@ gst_base_src_loop (GstPad * pad)
       if (GST_CLOCK_TIME_IS_VALID (start))
         position = start;
       else
-        position = src->segment.last_stop;
+        position = src->segment.position;
 
       if (GST_CLOCK_TIME_IS_VALID (duration)) {
         if (src->segment.rate >= 0.0)
@@ -2533,12 +2510,12 @@ gst_base_src_loop (GstPad * pad)
       src->priv->discont = TRUE;
     }
     GST_OBJECT_LOCK (src);
-    gst_segment_set_last_stop (&src->segment, src->segment.format, position);
+    src->segment.position = position;
     GST_OBJECT_UNLOCK (src);
   }
 
   if (G_UNLIKELY (src->priv->discont)) {
-    buf = gst_buffer_make_metadata_writable (buf);
+    buf = gst_buffer_make_writable (buf);
     GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DISCONT);
     src->priv->discont = FALSE;
   }
@@ -2574,30 +2551,29 @@ pause:
     GstEvent *event;
 
     GST_DEBUG_OBJECT (src, "pausing task, reason %s", reason);
-    src->data.ABI.running = FALSE;
+    src->running = FALSE;
     gst_pad_pause_task (pad);
     if (ret == GST_FLOW_UNEXPECTED) {
       gboolean flag_segment;
       GstFormat format;
-      gint64 last_stop;
+      gint64 position;
 
       /* perform EOS logic */
       flag_segment = (src->segment.flags & GST_SEEK_FLAG_SEGMENT) != 0;
       format = src->segment.format;
-      last_stop = src->segment.last_stop;
+      position = src->segment.position;
 
       if (flag_segment) {
         GstMessage *message;
 
         message = gst_message_new_segment_done (GST_OBJECT_CAST (src),
-            format, last_stop);
+            format, position);
         gst_message_set_seqnum (message, src->priv->seqnum);
         gst_element_post_message (GST_ELEMENT_CAST (src), message);
       } else {
         event = gst_event_new_eos ();
         gst_event_set_seqnum (event, src->priv->seqnum);
         gst_pad_push_event (pad, event);
-        src->priv->last_sent_eos = TRUE;
       }
     } else if (ret == GST_FLOW_NOT_LINKED || ret <= GST_FLOW_UNEXPECTED) {
       event = gst_event_new_eos ();
@@ -2612,7 +2588,6 @@ pause:
           (_("Internal data flow error.")),
           ("streaming task paused, reason %s (%d)", reason, ret));
       gst_pad_push_event (pad, event);
-      src->priv->last_sent_eos = TRUE;
     }
     goto done;
   }
@@ -2625,6 +2600,102 @@ null_buffer:
   }
 }
 
+static void
+gst_base_src_set_allocation (GstBaseSrc * basesrc, GstBufferPool * pool,
+    const GstMemoryAllocator * allocator, guint prefix, guint alignment)
+{
+  GstBufferPool *oldpool;
+  GstBaseSrcPrivate *priv = basesrc->priv;
+
+  GST_OBJECT_LOCK (basesrc);
+  if ((oldpool = priv->pool)) {
+    gst_object_unref (oldpool);
+  }
+  priv->pool = pool;
+
+  priv->allocator = allocator;
+
+  priv->prefix = prefix;
+  priv->alignment = alignment;
+  GST_OBJECT_UNLOCK (basesrc);
+
+  if (oldpool) {
+    gst_buffer_pool_set_active (oldpool, FALSE);
+    gst_object_unref (oldpool);
+  }
+}
+
+static gboolean
+gst_base_src_activate_pool (GstBaseSrc * basesrc, gboolean active)
+{
+  GstBaseSrcPrivate *priv = basesrc->priv;
+  GstBufferPool *pool;
+  gboolean res = TRUE;
+
+  GST_OBJECT_LOCK (basesrc);
+  if ((pool = priv->pool))
+    pool = gst_object_ref (pool);
+  GST_OBJECT_UNLOCK (basesrc);
+
+  if (pool) {
+    res = gst_buffer_pool_set_active (pool, active);
+    gst_object_unref (pool);
+  }
+  return res;
+}
+
+static gboolean
+gst_base_src_prepare_allocation (GstBaseSrc * basesrc, GstCaps * caps)
+{
+  GstBaseSrcClass *bclass;
+  gboolean result = TRUE;
+  GstQuery *query;
+  GstBufferPool *pool = NULL;
+  const GstMemoryAllocator *allocator = NULL;
+  guint size, min, max, prefix, alignment;
+
+  bclass = GST_BASE_SRC_GET_CLASS (basesrc);
+
+  /* make query and let peer pad answer, we don't really care if it worked or
+   * not, if it failed, the allocation query would contain defaults and the
+   * subclass would then set better values if needed */
+  query = gst_query_new_allocation (caps, TRUE);
+  gst_pad_peer_query (basesrc->srcpad, query);
+
+  if (G_LIKELY (bclass->setup_allocation))
+    result = bclass->setup_allocation (basesrc, query);
+
+  gst_query_parse_allocation_params (query, &size, &min, &max, &prefix,
+      &alignment, &pool);
+
+  if (size == 0) {
+    const gchar *mem = NULL;
+
+    /* no size, we have variable size buffers */
+    if (gst_query_get_n_allocation_memories (query) > 0) {
+      mem = gst_query_parse_nth_allocation_memory (query, 0);
+    }
+    allocator = gst_memory_allocator_find (mem);
+  } else if (pool == NULL) {
+    /* fixed size, we can use a bufferpool */
+    GstStructure *config;
+
+    /* we did not get a pool, make one ourselves then */
+    pool = gst_buffer_pool_new ();
+
+    config = gst_buffer_pool_get_config (pool);
+    gst_buffer_pool_config_set (config, caps, size, min, max, prefix,
+        alignment);
+    gst_buffer_pool_set_config (pool, config);
+
+    gst_buffer_pool_set_active (pool, TRUE);
+  }
+
+  gst_base_src_set_allocation (basesrc, pool, allocator, prefix, alignment);
+
+  return result;
+}
+
 /* default negotiation code.
  *
  * Take intersection between src and sink pads, take first
@@ -2639,7 +2710,7 @@ gst_base_src_default_negotiate (GstBaseSrc * basesrc)
   gboolean result = FALSE;
 
   /* first see what is possible on our source pad */
-  thiscaps = gst_pad_get_caps_reffed (GST_BASE_SRC_PAD (basesrc));
+  thiscaps = gst_pad_get_caps (GST_BASE_SRC_PAD (basesrc), NULL);
   GST_DEBUG_OBJECT (basesrc, "caps of src: %" GST_PTR_FORMAT, thiscaps);
   /* nothing or anything is allowed, we're done */
   if (thiscaps == NULL || gst_caps_is_any (thiscaps))
@@ -2649,36 +2720,35 @@ gst_base_src_default_negotiate (GstBaseSrc * basesrc)
     goto no_caps;
 
   /* get the peer caps */
-  peercaps = gst_pad_peer_get_caps_reffed (GST_BASE_SRC_PAD (basesrc));
+  peercaps = gst_pad_peer_get_caps (GST_BASE_SRC_PAD (basesrc), thiscaps);
   GST_DEBUG_OBJECT (basesrc, "caps of peer: %" GST_PTR_FORMAT, peercaps);
   if (peercaps) {
-    /* get intersection */
-    caps =
-        gst_caps_intersect_full (peercaps, thiscaps, GST_CAPS_INTERSECT_FIRST);
-    GST_DEBUG_OBJECT (basesrc, "intersect: %" GST_PTR_FORMAT, caps);
-    gst_caps_unref (peercaps);
+    /* The result is already a subset of our caps */
+    caps = peercaps;
+    gst_caps_unref (thiscaps);
   } else {
     /* no peer, work with our own caps then */
-    caps = gst_caps_copy (thiscaps);
+    caps = thiscaps;
   }
-  gst_caps_unref (thiscaps);
-  if (caps) {
+  if (caps && !gst_caps_is_empty (caps)) {
+    caps = gst_caps_make_writable (caps);
+
     /* take first (and best, since they are sorted) possibility */
     gst_caps_truncate (caps);
 
     /* now fixate */
-    if (!gst_caps_is_empty (caps)) {
+    GST_DEBUG_OBJECT (basesrc, "have caps: %" GST_PTR_FORMAT, caps);
+    if (gst_caps_is_any (caps)) {
+      /* hmm, still anything, so element can do anything and
+       * nego is not needed */
+      result = TRUE;
+    } else {
       gst_pad_fixate_caps (GST_BASE_SRC_PAD (basesrc), caps);
       GST_DEBUG_OBJECT (basesrc, "fixated to: %" GST_PTR_FORMAT, caps);
-
-      if (gst_caps_is_any (caps)) {
-        /* hmm, still anything, so element can do anything and
-         * nego is not needed */
-        result = TRUE;
-      } else if (gst_caps_is_fixed (caps)) {
+      if (gst_caps_is_fixed (caps)) {
         /* yay, fixed caps, use those then, it's possible that the subclass does
          * not accept this caps after all and we have to fail. */
-        result = gst_pad_set_caps (GST_BASE_SRC_PAD (basesrc), caps);
+        result = gst_base_src_setcaps (basesrc, caps);
       }
     }
     gst_caps_unref (caps);
@@ -2713,9 +2783,16 @@ gst_base_src_negotiate (GstBaseSrc * basesrc)
 
   bclass = GST_BASE_SRC_GET_CLASS (basesrc);
 
-  if (bclass->negotiate)
+  if (G_LIKELY (bclass->negotiate))
     result = bclass->negotiate (basesrc);
 
+  if (G_LIKELY (result)) {
+    GstCaps *caps;
+
+    caps = gst_pad_get_current_caps (basesrc->srcpad);
+
+    result = gst_base_src_prepare_allocation (basesrc, caps);
+  }
   return result;
 }
 
@@ -2739,8 +2816,8 @@ gst_base_src_start (GstBaseSrc * basesrc)
   gst_segment_init (&basesrc->segment, basesrc->segment.format);
   GST_OBJECT_UNLOCK (basesrc);
 
-  basesrc->data.ABI.running = FALSE;
-  basesrc->priv->newsegment_pending = FALSE;
+  basesrc->running = FALSE;
+  basesrc->priv->segment_pending = FALSE;
 
   bclass = GST_BASE_SRC_GET_CLASS (basesrc);
   if (bclass->start)
@@ -2768,7 +2845,7 @@ gst_base_src_start (GstBaseSrc * basesrc)
     /* only update the size when operating in bytes, subclass is supposed
      * to set duration in the start method for other formats */
     GST_OBJECT_LOCK (basesrc);
-    gst_segment_set_duration (&basesrc->segment, GST_FORMAT_BYTES, size);
+    basesrc->segment.duration = size;
     GST_OBJECT_UNLOCK (basesrc);
   } else {
     size = -1;
@@ -2788,13 +2865,13 @@ gst_base_src_start (GstBaseSrc * basesrc)
   GST_DEBUG_OBJECT (basesrc, "is random_access: %d", basesrc->random_access);
 
   /* run typefind if we are random_access and the typefinding is enabled. */
-  if (basesrc->random_access && basesrc->data.ABI.typefind && size != -1) {
+  if (basesrc->random_access && basesrc->typefind && size != -1) {
     GstCaps *caps;
 
     if (!(caps = gst_type_find_helper (basesrc->srcpad, size)))
       goto typefind_failed;
 
-    result = gst_pad_set_caps (basesrc->srcpad, caps);
+    result = gst_base_src_setcaps (basesrc, caps);
     gst_caps_unref (caps);
   } else {
     /* use class or default negotiate function */
@@ -2845,6 +2922,8 @@ gst_base_src_stop (GstBaseSrc * basesrc)
   if (bclass->stop)
     result = bclass->stop (basesrc);
 
+  gst_base_src_set_allocation (basesrc, NULL, NULL, 0, 0);
+
   if (result)
     GST_OBJECT_FLAG_UNSET (basesrc, GST_BASE_SRC_STARTED);
 
@@ -2862,6 +2941,7 @@ gst_base_src_set_flushing (GstBaseSrc * basesrc,
   bclass = GST_BASE_SRC_GET_CLASS (basesrc);
 
   if (flushing && unlock) {
+    gst_base_src_activate_pool (basesrc, FALSE);
     /* unlock any subclasses, we need to do this before grabbing the
      * LIVE_LOCK since we hold this lock before going into ::create. We pass an
      * unlock to the params because of backwards compat (see seek handler)*/
@@ -2893,6 +2973,8 @@ gst_base_src_set_flushing (GstBaseSrc * basesrc,
     /* signal the live source that it can start playing */
     basesrc->live_running = live_play;
 
+    gst_base_src_activate_pool (basesrc, TRUE);
+
     /* When unlocking drop all delayed events */
     if (unlock) {
       GST_OBJECT_LOCK (basesrc);
@@ -2924,6 +3006,7 @@ gst_base_src_set_playing (GstBaseSrc * basesrc, gboolean live_play)
   /* unlock subclasses locked in ::create, we only do this when we stop playing. */
   if (!live_play) {
     GST_DEBUG_OBJECT (basesrc, "unlock");
+    gst_base_src_activate_pool (basesrc, FALSE);
     if (bclass->unlock)
       bclass->unlock (basesrc);
   }
@@ -2947,6 +3030,7 @@ gst_base_src_set_playing (GstBaseSrc * basesrc, gboolean live_play)
 
     /* clear our unlock request when going to PLAYING */
     GST_DEBUG_OBJECT (basesrc, "unlock stop");
+    gst_base_src_activate_pool (basesrc, TRUE);
     if (bclass->unlock_stop)
       bclass->unlock_stop (basesrc);
 
@@ -2986,14 +3070,13 @@ gst_base_src_activate_push (GstPad * pad, gboolean active)
     if (G_UNLIKELY (!gst_base_src_start (basesrc)))
       goto error_start;
 
-    basesrc->priv->last_sent_eos = FALSE;
     basesrc->priv->discont = TRUE;
     gst_base_src_set_flushing (basesrc, FALSE, FALSE, FALSE, NULL);
 
     /* do initial seek, which will start the task */
     GST_OBJECT_LOCK (basesrc);
-    event = basesrc->data.ABI.pending_seek;
-    basesrc->data.ABI.pending_seek = NULL;
+    event = basesrc->pending_seek;
+    basesrc->pending_seek = NULL;
     GST_OBJECT_UNLOCK (basesrc);
 
     /* no need to unlock anything, the task is certainly
@@ -3061,7 +3144,7 @@ gst_base_src_activate_pull (GstPad * pad, gboolean active)
       goto error_start;
 
     /* if not random_access, we cannot operate in pull mode for now */
-    if (G_UNLIKELY (!gst_base_src_check_get_range (basesrc)))
+    if (G_UNLIKELY (!gst_base_src_is_random_access (basesrc)))
       goto no_get_range;
 
     /* stop flushing now but for live sources, still block in the LIVE lock when
@@ -3072,9 +3155,6 @@ gst_base_src_activate_pull (GstPad * pad, gboolean active)
     /* flush all, there is no task to stop */
     gst_base_src_set_flushing (basesrc, TRUE, FALSE, TRUE, NULL);
 
-    /* don't send EOS when going from PAUSED => READY when in pull mode */
-    basesrc->priv->last_sent_eos = TRUE;
-
     if (G_UNLIKELY (!gst_base_src_stop (basesrc)))
       goto error_stop;
   }
@@ -3141,27 +3221,12 @@ gst_base_src_change_state (GstElement * element, GstStateChange transition)
       break;
     case GST_STATE_CHANGE_PAUSED_TO_READY:
     {
-      GstEvent **event_p, *event;
+      GstEvent **event_p;
 
       /* we don't need to unblock anything here, the pad deactivation code
        * already did this */
-
-      /* FIXME, deprecate this behaviour, it is very dangerous.
-       * the prefered way of sending EOS downstream is by sending
-       * the EOS event to the element */
-      if (!basesrc->priv->last_sent_eos) {
-        GST_DEBUG_OBJECT (basesrc, "Sending EOS event");
-        event = gst_event_new_eos ();
-        gst_event_set_seqnum (event, basesrc->priv->seqnum);
-        gst_pad_push_event (basesrc->srcpad, event);
-        basesrc->priv->last_sent_eos = TRUE;
-      }
       g_atomic_int_set (&basesrc->priv->pending_eos, FALSE);
-      event_p = &basesrc->data.ABI.pending_seek;
-      gst_event_replace (event_p, NULL);
-      event_p = &basesrc->priv->close_segment;
-      gst_event_replace (event_p, NULL);
-      event_p = &basesrc->priv->start_segment;
+      event_p = &basesrc->pending_seek;
       gst_event_replace (event_p, NULL);
       break;
     }
index 87e1c06..529c797 100644 (file)
@@ -81,47 +81,38 @@ struct _GstBaseSrc {
   gboolean       live_running;
 
   /* MT-protected (with LOCK) */
-  gint           blocksize;     /* size of buffers when operating push based */
+  guint          blocksize;     /* size of buffers when operating push based */
   gboolean       can_activate_push;     /* some scheduling properties */
-  GstActivateMode pad_mode;
-  gboolean       seekable; /* not used anymore */
   gboolean       random_access;
 
   GstClockID     clock_id;      /* for syncing */
-  GstClockTime   end_time;
 
   /* MT-protected (with STREAM_LOCK *and* OBJECT_LOCK) */
   GstSegment     segment;
   /* MT-protected (with STREAM_LOCK) */
   gboolean       need_newsegment;
 
-  guint64        offset;        /* current offset in the resource, unused */
-  guint64        size;          /* total size of the resource, unused */
-
   gint           num_buffers;
   gint           num_buffers_left;
 
-  /*< private >*/
-  union {
-    struct {
-      /* FIXME: those fields should be moved into the private struct */
-      gboolean  typefind;
-      gboolean  running;
-      GstEvent *pending_seek;
-    } ABI;
-    gpointer       _gst_reserved[GST_PADDING_LARGE-1];
-  } data;
+  gboolean       typefind;
+  gboolean       running;
+  GstEvent      *pending_seek;
 
   GstBaseSrcPrivate *priv;
+
+  /*< private >*/
+  gpointer       _gst_reserved[GST_PADDING_LARGE];
 };
 
 /**
  * GstBaseSrcClass:
  * @parent_class: Element parent class
  * @get_caps: Called to get the caps to report
- * @set_caps: Notify subclass of changed output caps
  * @negotiate: Negotiated the caps with the peer.
- * @newsegment: Generate and send a new_segment event (UNUSED)
+ * @fixate: Called during negotiation if caps need fixating. Implement instead of
+ *   setting a fixate function on the source pad.
+ * @set_caps: Notify subclass of changed output caps
  * @start: Start processing. Subclasses should open resources and prepare
  *    to produce data.
  * @stop: Stop processing. Subclasses should use this to close resources.
@@ -130,6 +121,13 @@ struct _GstBaseSrc {
  *    these times.
  * @get_size: Return the total size of the resource, in the configured format.
  * @is_seekable: Check if the source can seek
+ * @prepare_seek_segment: Prepare the GstSegment that will be passed to the
+ *   do_seek vmethod for executing a seek request. Sub-classes should override
+ *   this if they support seeking in formats other than the configured native
+ *   format. By default, it tries to convert the seek arguments to the
+ *   configured native format and prepare a segment in that format.
+ *   Since: 0.10.13
+ * @do_seek: Perform seeking on the resource to the indicated segment.
  * @unlock: Unlock any pending access to the resource. Subclasses should
  *    unblock any blocked function ASAP. In particular, any create() function in
  *    progress should be unblocked and should return GST_FLOW_WRONG_STATE. Any
@@ -137,29 +135,17 @@ struct _GstBaseSrc {
  *    until the @unlock_stop<!-- -->() function has been called.
  * @unlock_stop: Clear the previous unlock request. Subclasses should clear
  *    any state they set during unlock(), such as clearing command queues.
+ * @query: Handle a requested query.
  * @event: Override this to implement custom event handling.
  * @create: Ask the subclass to create a buffer with offset and size.
  *   When the subclass returns GST_FLOW_OK, it MUST return a buffer of the
  *   requested size unless fewer bytes are available because an EOS condition
  *   is near. No buffer should be returned when the return value is different
  *   from GST_FLOW_OK. A return value of GST_FLOW_UNEXPECTED signifies that the
- *   end of stream is reached.
- * @do_seek: Perform seeking on the resource to the indicated segment.
- * @prepare_seek_segment: Prepare the GstSegment that will be passed to the
- *   do_seek vmethod for executing a seek request. Sub-classes should override
- *   this if they support seeking in formats other than the configured native
- *   format. By default, it tries to convert the seek arguments to the
- *   configured native format and prepare a segment in that format.
- *   Since: 0.10.13
- * @query: Handle a requested query.
- * @check_get_range: Check whether the source would support pull-based
- *   operation if it were to be opened now. This vfunc is optional, but
- *   should be implemented if possible to avoid unnecessary start/stop
- *   cycles. The default implementation will open and close the resource
- *   to find out whether get_range is supported, and that is usually
- *   undesirable.
- * @fixate: Called during negotiation if caps need fixating. Implement instead of
- *   setting a fixate function on the source pad.
+ *   end of stream is reached. The default implementation will create a new
+ *   buffer from the negotiated allocator and will call @fill.
+ * @fill: Ask the subclass to fill the buffer with data for offset and size. The
+ *   passed buffer is guaranteed to hold the requested amount of bytes.
  *
  * Subclasses can override any of the available virtual methods or not, as
  * needed. At the minimum, the @create method should be overridden to produce
@@ -172,15 +158,16 @@ struct _GstBaseSrcClass {
   /* virtual methods for subclasses */
 
   /* get caps from subclass */
-  GstCaps*      (*get_caps)     (GstBaseSrc *src);
-  /* notify the subclass of new caps */
-  gboolean      (*set_caps)     (GstBaseSrc *src, GstCaps *caps);
-
+  GstCaps*      (*get_caps)     (GstBaseSrc *src, GstCaps *filter);
   /* decide on caps */
   gboolean      (*negotiate)    (GstBaseSrc *src);
+  /* called if, in negotiation, caps need fixating */
+  void          (*fixate)       (GstBaseSrc *src, GstCaps *caps);
+  /* notify the subclass of new caps */
+  gboolean      (*set_caps)     (GstBaseSrc *src, GstCaps *caps);
 
-  /* generate and send a newsegment (UNUSED) */
-  gboolean      (*newsegment)   (GstBaseSrc *src);
+  /* setup allocation query */
+  gboolean      (*setup_allocation)   (GstBaseSrc *src, GstQuery *query);
 
   /* start and stop processing, ideal for opening/closing the resource */
   gboolean      (*start)        (GstBaseSrc *src);
@@ -196,44 +183,36 @@ struct _GstBaseSrcClass {
 
   /* check if the resource is seekable */
   gboolean      (*is_seekable)  (GstBaseSrc *src);
+
+  /* Prepare the segment on which to perform do_seek(), converting to the
+   * current basesrc format. */
+  gboolean      (*prepare_seek_segment) (GstBaseSrc *src, GstEvent *seek,
+                                         GstSegment *segment);
+  /* notify subclasses of a seek */
+  gboolean      (*do_seek)      (GstBaseSrc *src, GstSegment *segment);
+
   /* unlock any pending access to the resource. subclasses should unlock
    * any function ASAP. */
   gboolean      (*unlock)       (GstBaseSrc *src);
+  /* Clear any pending unlock request, as we succeeded in unlocking */
+  gboolean      (*unlock_stop)  (GstBaseSrc *src);
+
+  /* notify subclasses of a query */
+  gboolean      (*query)        (GstBaseSrc *src, GstQuery *query);
 
   /* notify subclasses of an event */
   gboolean      (*event)        (GstBaseSrc *src, GstEvent *event);
 
-  /* ask the subclass to create a buffer with offset and size */
+  /* ask the subclass to create a buffer with offset and size, the default
+   * implementation will use the negotiated allocator and call fill. */
   GstFlowReturn (*create)       (GstBaseSrc *src, guint64 offset, guint size,
                                  GstBuffer **buf);
-
-  /* additions that change padding... */
-  /* notify subclasses of a seek */
-  gboolean      (*do_seek)      (GstBaseSrc *src, GstSegment *segment);
-  /* notify subclasses of a query */
-  gboolean      (*query)        (GstBaseSrc *src, GstQuery *query);
-
-  /* check whether the source would support pull-based operation if
-   * it were to be opened now. This vfunc is optional, but should be
-   * implemented if possible to avoid unnecessary start/stop cycles.
-   * The default implementation will open and close the resource to
-   * find out whether get_range is supported and that is usually
-   * undesirable. */
-  gboolean      (*check_get_range) (GstBaseSrc *src);
-
-  /* called if, in negotiation, caps need fixating */
-  void          (*fixate)       (GstBaseSrc *src, GstCaps *caps);
-
-  /* Clear any pending unlock request, as we succeeded in unlocking */
-  gboolean      (*unlock_stop)  (GstBaseSrc *src);
-
-  /* Prepare the segment on which to perform do_seek(), converting to the
-   * current basesrc format. */
-  gboolean      (*prepare_seek_segment) (GstBaseSrc *src, GstEvent *seek,
-                                         GstSegment *segment);
+  /* ask the subclass to fill the buffer with data from offset and size */
+  GstFlowReturn (*fill)         (GstBaseSrc *src, guint64 offset, guint size,
+                                 GstBuffer *buf);
 
   /*< private >*/
-  gpointer       _gst_reserved[GST_PADDING_LARGE - 6];
+  gpointer       _gst_reserved[GST_PADDING_LARGE];
 };
 
 GType gst_base_src_get_type (void);
@@ -251,8 +230,8 @@ gboolean        gst_base_src_query_latency    (GstBaseSrc *src, gboolean * live,
                                                GstClockTime * min_latency,
                                                GstClockTime * max_latency);
 
-void            gst_base_src_set_blocksize    (GstBaseSrc *src, gulong blocksize);
-gulong          gst_base_src_get_blocksize    (GstBaseSrc *src);
+void            gst_base_src_set_blocksize    (GstBaseSrc *src, guint blocksize);
+guint           gst_base_src_get_blocksize    (GstBaseSrc *src);
 
 void            gst_base_src_set_do_timestamp (GstBaseSrc *src, gboolean timestamp);
 gboolean        gst_base_src_get_do_timestamp (GstBaseSrc *src);
index a46642e..204e77e 100644 (file)
@@ -244,43 +244,15 @@ struct _GstBaseTransformPrivate
 
   gboolean gap_aware;
 
-  /* caps used for allocating buffers */
-  gboolean proxy_alloc;
-  GstCaps *sink_alloc;
-  GstCaps *src_alloc;
-
-  /*
-   * This flag controls if basetransform should explicitly
-   * do a pad alloc when it receives a buffer even if it operates on
-   * passthrough, this is needed to check for downstream caps suggestions
-   * and this newly alloc'ed buffer is discarded.
-   *
-   * Without this flag basetransform would try a pad alloc whenever it
-   * gets a new buffer and pipelines like:
-   * "src ! basetrans1 ! basetrans2 ! basetrans3 ! sink"
-   * Would have a 3 pad allocs for each buffer pushed downstream from the src.
-   *
-   * This flag is set to TRUE on start up, on setcaps and when a buffer is
-   * pushed downstream. It is set to FALSE after a pad alloc has been requested
-   * downstream.
-   * The rationale is that when a pad alloc flows through the pipeline, all
-   * basetransform elements on passthrough will avoid pad alloc'ing when they
-   * get the buffer.
-   */
-  gboolean force_alloc;
-
-  /* upstream caps and size suggestions */
-  GstCaps *sink_suggest;
-  guint size_suggest;
-  gboolean suggest_pending;
-
   gboolean reconfigure;
 
   /* QoS stats */
   guint64 processed;
   guint64 dropped;
 
-  GstClockTime last_stop_out;
+  GstClockTime position_out;
+
+  GstBufferPool *srcpool;
 };
 
 static GstElementClass *parent_class = NULL;
@@ -329,7 +301,7 @@ static gboolean gst_base_transform_sink_activate_push (GstPad * pad,
 static gboolean gst_base_transform_activate (GstBaseTransform * trans,
     gboolean active);
 static gboolean gst_base_transform_get_unit_size (GstBaseTransform * trans,
-    GstCaps * caps, guint * size);
+    GstCaps * caps, gsize * size);
 
 static gboolean gst_base_transform_src_event (GstPad * pad, GstEvent * event);
 static gboolean gst_base_transform_src_eventfunc (GstBaseTransform * trans,
@@ -337,18 +309,16 @@ static gboolean gst_base_transform_src_eventfunc (GstBaseTransform * trans,
 static gboolean gst_base_transform_sink_event (GstPad * pad, GstEvent * event);
 static gboolean gst_base_transform_sink_eventfunc (GstBaseTransform * trans,
     GstEvent * event);
-static gboolean gst_base_transform_check_get_range (GstPad * pad);
 static GstFlowReturn gst_base_transform_getrange (GstPad * pad, guint64 offset,
     guint length, GstBuffer ** buffer);
 static GstFlowReturn gst_base_transform_chain (GstPad * pad,
     GstBuffer * buffer);
-static GstCaps *gst_base_transform_getcaps (GstPad * pad);
+static GstCaps *gst_base_transform_getcaps (GstPad * pad, GstCaps * filter);
 static gboolean gst_base_transform_acceptcaps (GstPad * pad, GstCaps * caps);
 static gboolean gst_base_transform_acceptcaps_default (GstBaseTransform * trans,
     GstPadDirection direction, GstCaps * caps);
-static gboolean gst_base_transform_setcaps (GstPad * pad, GstCaps * caps);
-static GstFlowReturn gst_base_transform_buffer_alloc (GstPad * pad,
-    guint64 offset, guint size, GstCaps * caps, GstBuffer ** buf);
+static gboolean gst_base_transform_setcaps (GstBaseTransform * trans,
+    GstPad * pad, GstCaps * caps);
 static gboolean gst_base_transform_query (GstPad * pad, GstQuery * query);
 static const GstQueryType *gst_base_transform_query_type (GstPad * pad);
 
@@ -361,7 +331,6 @@ gst_base_transform_finalize (GObject * object)
 
   trans = GST_BASE_TRANSFORM (object);
 
-  gst_caps_replace (&trans->priv->sink_suggest, NULL);
   g_mutex_free (trans->transform_lock);
 
   G_OBJECT_CLASS (parent_class)->finalize (object);
@@ -417,16 +386,12 @@ gst_base_transform_init (GstBaseTransform * trans,
       GST_DEBUG_FUNCPTR (gst_base_transform_getcaps));
   gst_pad_set_acceptcaps_function (trans->sinkpad,
       GST_DEBUG_FUNCPTR (gst_base_transform_acceptcaps));
-  gst_pad_set_setcaps_function (trans->sinkpad,
-      GST_DEBUG_FUNCPTR (gst_base_transform_setcaps));
   gst_pad_set_event_function (trans->sinkpad,
       GST_DEBUG_FUNCPTR (gst_base_transform_sink_event));
   gst_pad_set_chain_function (trans->sinkpad,
       GST_DEBUG_FUNCPTR (gst_base_transform_chain));
   gst_pad_set_activatepush_function (trans->sinkpad,
       GST_DEBUG_FUNCPTR (gst_base_transform_sink_activate_push));
-  gst_pad_set_bufferalloc_function (trans->sinkpad,
-      GST_DEBUG_FUNCPTR (gst_base_transform_buffer_alloc));
   gst_pad_set_query_function (trans->sinkpad,
       GST_DEBUG_FUNCPTR (gst_base_transform_query));
   gst_pad_set_query_type_function (trans->sinkpad,
@@ -443,8 +408,6 @@ gst_base_transform_init (GstBaseTransform * trans,
       GST_DEBUG_FUNCPTR (gst_base_transform_acceptcaps));
   gst_pad_set_event_function (trans->srcpad,
       GST_DEBUG_FUNCPTR (gst_base_transform_src_event));
-  gst_pad_set_checkgetrange_function (trans->srcpad,
-      GST_DEBUG_FUNCPTR (gst_base_transform_check_get_range));
   gst_pad_set_getrange_function (trans->srcpad,
       GST_DEBUG_FUNCPTR (gst_base_transform_getrange));
   gst_pad_set_activatepull_function (trans->srcpad,
@@ -477,7 +440,6 @@ gst_base_transform_init (GstBaseTransform * trans,
 
   trans->priv->processed = 0;
   trans->priv->dropped = 0;
-  trans->priv->force_alloc = TRUE;
 }
 
 /* given @caps on the src or sink pad (given by @direction)
@@ -487,7 +449,7 @@ gst_base_transform_init (GstBaseTransform * trans,
  */
 static GstCaps *
 gst_base_transform_transform_caps (GstBaseTransform * trans,
-    GstPadDirection direction, GstCaps * caps)
+    GstPadDirection direction, GstCaps * caps, GstCaps * filter)
 {
   GstCaps *ret;
   GstBaseTransformClass *klass;
@@ -499,53 +461,40 @@ gst_base_transform_transform_caps (GstBaseTransform * trans,
 
   /* if there is a custom transform function, use this */
   if (klass->transform_caps) {
-    GstCaps *temp;
-    gint i;
 
-    /* start with empty caps */
-    ret = gst_caps_new_empty ();
     GST_DEBUG_OBJECT (trans, "transform caps (direction = %d)", direction);
 
-    if (gst_caps_is_any (caps)) {
-      /* for any caps we still have to call the transform function */
-      GST_DEBUG_OBJECT (trans, "from: ANY");
-      temp = klass->transform_caps (trans, direction, caps);
-      GST_DEBUG_OBJECT (trans, "  to: %" GST_PTR_FORMAT, temp);
-
-      temp = gst_caps_make_writable (temp);
-      gst_caps_append (ret, temp);
-    } else {
-      gint n = gst_caps_get_size (caps);
-      /* we send caps with just one structure to the transform
-       * function as this is easier for the element */
-      for (i = 0; i < n; i++) {
-        GstCaps *nth;
-
-        nth = gst_caps_copy_nth (caps, i);
-        GST_LOG_OBJECT (trans, "from[%d]: %" GST_PTR_FORMAT, i, nth);
-        temp = klass->transform_caps (trans, direction, nth);
-        gst_caps_unref (nth);
-        GST_LOG_OBJECT (trans, "  to[%d]: %" GST_PTR_FORMAT, i, temp);
-
-        temp = gst_caps_make_writable (temp);
-
-        /* here we need to only append those structures, that are not yet
-         * in there, we use the merge function for this */
-        gst_caps_merge (ret, temp);
-
-        GST_LOG_OBJECT (trans, "  merged[%d]: %" GST_PTR_FORMAT, i, ret);
+    GST_LOG_OBJECT (trans, "from: %" GST_PTR_FORMAT, caps);
+    ret = klass->transform_caps (trans, direction, caps, filter);
+    GST_LOG_OBJECT (trans, "  to: %" GST_PTR_FORMAT, ret);
+
+#ifndef G_DISABLE_ASSERT
+    if (filter) {
+      if (!gst_caps_is_subset (ret, filter)) {
+        GstCaps *intersection;
+
+        GST_ERROR_OBJECT (trans,
+            "transform_caps returned caps %" GST_PTR_FORMAT
+            " which are not a real subset of the filter caps %"
+            GST_PTR_FORMAT, ret, filter);
+        g_warning ("%s: transform_caps returned caps which are not a real "
+            "subset of the filter caps", GST_ELEMENT_NAME (trans));
+
+        intersection =
+            gst_caps_intersect_full (filter, ret, GST_CAPS_INTERSECT_FIRST);
+        gst_caps_unref (intersection);
+        ret = intersection;
       }
-      GST_LOG_OBJECT (trans, "merged: (%d)", gst_caps_get_size (ret));
-      /* FIXME: we can't do much simplification here because we don't really want to
-       * change the caps order
-       gst_caps_do_simplify (ret);
-       GST_DEBUG_OBJECT (trans, "simplified: (%d)", gst_caps_get_size (ret));
-       */
     }
+#endif
   } else {
     GST_DEBUG_OBJECT (trans, "identity from: %" GST_PTR_FORMAT, caps);
     /* no transform function, use the identity transform */
-    ret = gst_caps_ref (caps);
+    if (filter) {
+      ret = gst_caps_intersect_full (filter, caps, GST_CAPS_INTERSECT_FIRST);
+    } else {
+      ret = gst_caps_ref (caps);
+    }
   }
 
   GST_DEBUG_OBJECT (trans, "to: (%d) %" GST_PTR_FORMAT, gst_caps_get_size (ret),
@@ -566,9 +515,9 @@ gst_base_transform_transform_caps (GstBaseTransform * trans,
 static gboolean
 gst_base_transform_transform_size (GstBaseTransform * trans,
     GstPadDirection direction, GstCaps * caps,
-    guint size, GstCaps * othercaps, guint * othersize)
+    gsize size, GstCaps * othercaps, gsize * othersize)
 {
-  guint inunitsize, outunitsize, units;
+  gsize inunitsize, outunitsize, units;
   GstBaseTransformClass *klass;
   gboolean ret;
 
@@ -628,8 +577,8 @@ no_multiple:
   {
     GST_DEBUG_OBJECT (trans, "Size %u is not a multiple of unit size %u", size,
         inunitsize);
-    g_warning ("%s: size %u is not a multiple of unit size %u",
-        GST_ELEMENT_NAME (trans), size, inunitsize);
+    g_warning ("%s: size %" G_GSIZE_FORMAT " is not a multiple of unit size %"
+        G_GSIZE_FORMAT, GST_ELEMENT_NAME (trans), size, inunitsize);
     return FALSE;
   }
 no_out_size:
@@ -650,21 +599,54 @@ no_out_size:
  * If there is no peer, we simply return the caps of the padtemplate of pad.
  */
 static GstCaps *
-gst_base_transform_getcaps (GstPad * pad)
+gst_base_transform_getcaps (GstPad * pad, GstCaps * filter)
 {
   GstBaseTransform *trans;
   GstPad *otherpad;
-  GstCaps *peercaps, *caps;
+  GstCaps *peercaps, *caps, *peerfilter = NULL;
 
   trans = GST_BASE_TRANSFORM (gst_pad_get_parent (pad));
 
   otherpad = (pad == trans->srcpad) ? trans->sinkpad : trans->srcpad;
 
   /* we can do what the peer can */
-  peercaps = gst_pad_peer_get_caps_reffed (otherpad);
+  if (filter) {
+    GstCaps *temp, *templ;
+
+    GST_DEBUG_OBJECT (pad, "filter caps  %" GST_PTR_FORMAT, filter);
+
+    /* filtered against our padtemplate on the other side */
+    templ = gst_pad_get_pad_template_caps (pad);
+    GST_DEBUG_OBJECT (pad, "our template  %" GST_PTR_FORMAT, templ);
+    temp = gst_caps_intersect_full (filter, templ, GST_CAPS_INTERSECT_FIRST);
+    GST_DEBUG_OBJECT (pad, "intersected %" GST_PTR_FORMAT, temp);
+    gst_caps_unref (templ);
+
+    /* then see what we can transform this to */
+    peerfilter = gst_base_transform_transform_caps (trans,
+        GST_PAD_DIRECTION (pad), temp, NULL);
+    GST_DEBUG_OBJECT (pad, "transformed  %" GST_PTR_FORMAT, peerfilter);
+    gst_caps_unref (temp);
+
+    /* and filter against the template of this pad */
+    templ = gst_pad_get_pad_template_caps (otherpad);
+    GST_DEBUG_OBJECT (pad, "our template  %" GST_PTR_FORMAT, templ);
+    /* We keep the caps sorted like the returned caps */
+    temp =
+        gst_caps_intersect_full (peerfilter, templ, GST_CAPS_INTERSECT_FIRST);
+    GST_DEBUG_OBJECT (pad, "intersected %" GST_PTR_FORMAT, temp);
+    gst_caps_unref (peerfilter);
+    gst_caps_unref (templ);
+    peerfilter = temp;
+  }
+
+  peercaps = gst_pad_peer_get_caps (otherpad, peerfilter);
+
+  if (peerfilter)
+    gst_caps_unref (peerfilter);
+
   if (peercaps) {
-    GstCaps *temp;
-    const GstCaps *templ;
+    GstCaps *temp, *templ;
 
     GST_DEBUG_OBJECT (pad, "peer caps  %" GST_PTR_FORMAT, peercaps);
 
@@ -673,10 +655,11 @@ gst_base_transform_getcaps (GstPad * pad)
     GST_DEBUG_OBJECT (pad, "our template  %" GST_PTR_FORMAT, templ);
     temp = gst_caps_intersect_full (peercaps, templ, GST_CAPS_INTERSECT_FIRST);
     GST_DEBUG_OBJECT (pad, "intersected %" GST_PTR_FORMAT, temp);
+    gst_caps_unref (templ);
 
     /* then see what we can transform this to */
     caps = gst_base_transform_transform_caps (trans,
-        GST_PAD_DIRECTION (otherpad), temp);
+        GST_PAD_DIRECTION (otherpad), temp, filter);
     GST_DEBUG_OBJECT (pad, "transformed  %" GST_PTR_FORMAT, caps);
     gst_caps_unref (temp);
     if (caps == NULL)
@@ -689,6 +672,7 @@ gst_base_transform_getcaps (GstPad * pad)
     temp = gst_caps_intersect_full (caps, templ, GST_CAPS_INTERSECT_FIRST);
     GST_DEBUG_OBJECT (pad, "intersected %" GST_PTR_FORMAT, temp);
     gst_caps_unref (caps);
+    gst_caps_unref (templ);
     caps = temp;
 
     /* Now try if we can put the untransformed downstream caps first */
@@ -701,7 +685,15 @@ gst_base_transform_getcaps (GstPad * pad)
     }
   } else {
     /* no peer or the peer can do anything, our padtemplate is enough then */
-    caps = gst_caps_copy (gst_pad_get_pad_template_caps (pad));
+    caps = gst_pad_get_pad_template_caps (pad);
+
+    if (filter) {
+      GstCaps *temp;
+
+      temp = gst_caps_intersect_full (filter, caps, GST_CAPS_INTERSECT_FIRST);
+      gst_caps_unref (caps);
+      caps = temp;
+    }
   }
 
 done:
@@ -715,6 +707,84 @@ done:
   return caps;
 }
 
+static gboolean
+gst_base_transform_do_bufferpool (GstBaseTransform * trans, GstCaps * outcaps)
+{
+  GstQuery *query;
+  GstBufferPool *pool = NULL, *oldpool;
+  guint size, min, max, prefix, alignment;
+
+  /* there are these possibilities:
+   *
+   * 1) we negotiated passthrough, we can proxy the bufferpool directly.
+   * 2) 
+   */
+
+  /* clear old pool */
+  oldpool = trans->priv->srcpool;
+  if (oldpool) {
+    gst_buffer_pool_set_active (oldpool, FALSE);
+    gst_object_unref (oldpool);
+    trans->priv->srcpool = oldpool = NULL;
+  }
+
+  if (trans->passthrough) {
+    /* we are in passthrough, the input buffer is never copied and always passed
+     * along. We never allocate an output buffer on the srcpad. What we do is
+     * let the upstream element decide if it wants to use a bufferpool and
+     * then we will proxy the downstream pool */
+    GST_DEBUG_OBJECT (trans, "we're passthough, delay bufferpool");
+    return TRUE;
+  }
+
+  /* not passthrough, we need to allocate */
+  /* find a pool for the negotiated caps now */
+  query = gst_query_new_allocation (outcaps, TRUE);
+
+  if (!gst_pad_peer_query (trans->srcpad, query))
+    goto query_failed;
+
+  /* we got configuration from our peer, parse them */
+  gst_query_parse_allocation_params (query, &size, &min, &max, &prefix,
+      &alignment, &pool);
+  gst_query_unref (query);
+
+  if (pool == NULL) {
+    GstStructure *config;
+
+    /* we did not get a pool, make one ourselves then */
+    pool = gst_buffer_pool_new ();
+
+    config = gst_buffer_pool_get_config (pool);
+    gst_buffer_pool_config_set (config, outcaps, size, min, max, prefix,
+        alignment);
+    gst_buffer_pool_set_config (pool, config);
+  }
+
+  /* activate */
+  if (!gst_buffer_pool_set_active (pool, TRUE))
+    goto activate_failed;
+
+  /* and store */
+  trans->priv->srcpool = pool;
+
+  return TRUE;
+
+  /* ERRORS */
+query_failed:
+  {
+    GST_DEBUG_OBJECT (trans, "allocation query failed");
+    gst_query_unref (query);
+    return FALSE;
+  }
+activate_failed:
+  {
+    GST_ERROR_OBJECT (trans, "failed to activate bufferpool.");
+    gst_object_unref (pool);
+    return FALSE;
+  }
+}
+
 /* function triggered when the in and out caps are negotiated and need
  * to be configured in the subclass. */
 static gboolean
@@ -754,65 +824,11 @@ gst_base_transform_configure_caps (GstBaseTransform * trans, GstCaps * in,
     ret = klass->set_caps (trans, in, out);
   }
 
-  GST_OBJECT_LOCK (trans);
-  /* make sure we reevaluate how the buffer_alloc works wrt to proxy allocating
-   * the buffer. FIXME, this triggers some quite heavy codepaths that don't need
-   * to be taken.. */
-  trans->priv->suggest_pending = TRUE;
-  GST_OBJECT_UNLOCK (trans);
   trans->negotiated = ret;
 
   return ret;
 }
 
-/* check if caps @in on @pad can be transformed to @out on the other pad.
- * We don't have a vmethod to test this yet so we have to do a somewhat less
- * efficient check for this.
- */
-static gboolean
-gst_base_transform_can_transform (GstBaseTransform * trans, GstPad * pad,
-    GstCaps * in, GstCaps * out)
-{
-  GstCaps *othercaps;
-
-  /* convert the in caps to all possible out caps */
-  othercaps =
-      gst_base_transform_transform_caps (trans, GST_PAD_DIRECTION (pad), in);
-
-  /* check if transform is empty */
-  if (!othercaps || gst_caps_is_empty (othercaps))
-    goto no_transform;
-
-  /* check if the out caps is a subset of the othercaps */
-  if (!gst_caps_can_intersect (out, othercaps))
-    goto no_subset;
-
-  if (othercaps)
-    gst_caps_unref (othercaps);
-
-  GST_DEBUG_OBJECT (trans, "from %" GST_PTR_FORMAT, in);
-  GST_DEBUG_OBJECT (trans, "to   %" GST_PTR_FORMAT, out);
-
-  return TRUE;
-
-  /* ERRORS */
-no_transform:
-  {
-    GST_DEBUG_OBJECT (trans,
-        "transform returned useless %" GST_PTR_FORMAT, othercaps);
-    if (othercaps)
-      gst_caps_unref (othercaps);
-    return FALSE;
-  }
-no_subset:
-  {
-    GST_DEBUG_OBJECT (trans, "no subset");
-    if (othercaps)
-      gst_caps_unref (othercaps);
-    return FALSE;
-  }
-}
-
 /* given a fixed @caps on @pad, create the best possible caps for the
  * other pad.
  * @caps must be fixed when calling this function.
@@ -851,13 +867,12 @@ gst_base_transform_find_transform (GstBaseTransform * trans, GstPad * pad,
    * passthrough because it might be possible that this element cannot support
    * passthrough at all. */
   othercaps = gst_base_transform_transform_caps (trans,
-      GST_PAD_DIRECTION (pad), caps);
+      GST_PAD_DIRECTION (pad), caps, NULL);
 
   /* The caps we can actually output is the intersection of the transformed
    * caps with the pad template for the pad */
   if (othercaps) {
-    GstCaps *intersect;
-    const GstCaps *templ_caps;
+    GstCaps *intersect, *templ_caps;
 
     templ_caps = gst_pad_get_pad_template_caps (otherpad);
     GST_DEBUG_OBJECT (trans,
@@ -868,6 +883,7 @@ gst_base_transform_find_transform (GstBaseTransform * trans, GstPad * pad,
         GST_CAPS_INTERSECT_FIRST);
 
     gst_caps_unref (othercaps);
+    gst_caps_unref (templ_caps);
     othercaps = intersect;
   }
 
@@ -884,62 +900,51 @@ gst_base_transform_find_transform (GstBaseTransform * trans, GstPad * pad,
     GST_DEBUG_OBJECT (trans,
         "transform returned non fixed  %" GST_PTR_FORMAT, othercaps);
 
-    /* see if the target caps are a superset of the source caps, in this
-     * case we can try to perform passthrough */
-    if (gst_caps_can_intersect (othercaps, caps)) {
-      GST_DEBUG_OBJECT (trans, "try passthrough with %" GST_PTR_FORMAT, caps);
-      if (otherpeer) {
-        /* try passthrough. we know it's fixed, because caps is fixed */
-        if (gst_pad_accept_caps (otherpeer, caps)) {
-          GST_DEBUG_OBJECT (trans, "peer accepted %" GST_PTR_FORMAT, caps);
-          /* peer accepted unmodified caps, we free the original non-fixed
-           * caps and work with the passthrough caps */
-          gst_caps_unref (othercaps);
-          othercaps = gst_caps_ref (caps);
-          is_fixed = TRUE;
-          /* mark that we checked othercaps with the peer, this
-           * makes sure we don't call accept_caps again with these same
-           * caps */
-          peer_checked = TRUE;
-        } else {
-          GST_DEBUG_OBJECT (trans,
-              "peer did not accept %" GST_PTR_FORMAT, caps);
-        }
-      } else {
-        GST_DEBUG_OBJECT (trans, "no peer, doing passthrough");
-        gst_caps_unref (othercaps);
-        othercaps = gst_caps_ref (caps);
-        is_fixed = TRUE;
-      }
-    }
-  }
+    /* Now let's see what the peer suggests based on our transformed caps */
+    if (otherpeer) {
+      GstCaps *peercaps, *intersection, *templ_caps;
 
-  /* second attempt at fixation is done by intersecting with
-   * the peer caps */
-  if (!is_fixed && otherpeer) {
-    /* intersect against what the peer can do */
-    GstCaps *peercaps;
-    GstCaps *intersect;
+      GST_DEBUG_OBJECT (trans,
+          "Checking peer caps with filter %" GST_PTR_FORMAT, othercaps);
 
-    GST_DEBUG_OBJECT (trans, "othercaps now %" GST_PTR_FORMAT, othercaps);
+      peercaps = gst_pad_get_caps (otherpeer, othercaps);
+      GST_DEBUG_OBJECT (trans, "Resulted in %" GST_PTR_FORMAT, peercaps);
 
-    peercaps = gst_pad_get_caps_reffed (otherpeer);
-    intersect = gst_caps_intersect (peercaps, othercaps);
-    gst_caps_unref (peercaps);
-    gst_caps_unref (othercaps);
-    othercaps = intersect;
-    peer_checked = FALSE;
+      templ_caps = gst_pad_get_pad_template_caps (otherpad);
 
-    is_fixed = gst_caps_is_fixed (othercaps);
+      GST_DEBUG_OBJECT (trans,
+          "Intersecting with template caps %" GST_PTR_FORMAT, templ_caps);
 
-    GST_DEBUG_OBJECT (trans,
-        "filtering against peer yields %" GST_PTR_FORMAT, othercaps);
-  }
+      intersection =
+          gst_caps_intersect_full (peercaps, templ_caps,
+          GST_CAPS_INTERSECT_FIRST);
+      GST_DEBUG_OBJECT (trans, "Intersection: %" GST_PTR_FORMAT, intersection);
+      gst_caps_unref (peercaps);
+      gst_caps_unref (templ_caps);
+      peercaps = intersection;
 
+      GST_DEBUG_OBJECT (trans,
+          "Intersecting with transformed caps %" GST_PTR_FORMAT, othercaps);
+      intersection =
+          gst_caps_intersect_full (peercaps, othercaps,
+          GST_CAPS_INTERSECT_FIRST);
+      GST_DEBUG_OBJECT (trans, "Intersection: %" GST_PTR_FORMAT, intersection);
+      gst_caps_unref (peercaps);
+      gst_caps_unref (othercaps);
+      othercaps = intersection;
+      is_fixed = gst_caps_is_fixed (othercaps);
+      peer_checked = TRUE;
+    } else {
+      GST_DEBUG_OBJECT (trans, "no peer, doing passthrough");
+      gst_caps_unref (othercaps);
+      othercaps = gst_caps_ref (caps);
+      is_fixed = TRUE;
+    }
+  }
   if (gst_caps_is_empty (othercaps))
     goto no_transform_possible;
 
-  /* third attempt at fixation, call the fixate vmethod and
+  /* second attempt at fixation, call the fixate vmethod and
    * ultimately call the pad fixate function. */
   if (!is_fixed) {
     GST_DEBUG_OBJECT (trans,
@@ -1064,9 +1069,9 @@ gst_base_transform_acceptcaps_default (GstBaseTransform * trans,
 
     /* get all the formats we can handle on this pad */
     if (direction == GST_PAD_SRC)
-      allowed = gst_pad_get_caps_reffed (trans->srcpad);
+      allowed = gst_pad_get_caps (trans->srcpad, NULL);
     else
-      allowed = gst_pad_get_caps_reffed (trans->sinkpad);
+      allowed = gst_pad_get_caps (trans->sinkpad, NULL);
 
     if (!allowed) {
       GST_DEBUG_OBJECT (trans, "gst_pad_get_caps() failed");
@@ -1088,7 +1093,7 @@ gst_base_transform_acceptcaps_default (GstBaseTransform * trans,
 
     /* find best possible caps for the other pad as a way to see if we can
      * transform this caps. */
-    othercaps = gst_base_transform_find_transform (trans, pad, caps);
+    othercaps = gst_base_transform_find_transform (trans, pad, caps, FALSE);
     if (!othercaps || gst_caps_is_empty (othercaps))
       goto no_transform_possible;
 
@@ -1143,24 +1148,17 @@ gst_base_transform_acceptcaps (GstPad * pad, GstCaps * caps)
  * because we never set caps starting from the srcpad.
  */
 static gboolean
-gst_base_transform_setcaps (GstPad * pad, GstCaps * caps)
+gst_base_transform_setcaps (GstBaseTransform * trans, GstPad * pad,
+    GstCaps * caps)
 {
-  GstBaseTransform *trans;
   GstPad *otherpad, *otherpeer;
   GstCaps *othercaps = NULL;
   gboolean ret = TRUE;
   GstCaps *incaps, *outcaps;
 
-  trans = GST_BASE_TRANSFORM (gst_pad_get_parent (pad));
-
   otherpad = (pad == trans->srcpad) ? trans->sinkpad : trans->srcpad;
   otherpeer = gst_pad_get_peer (otherpad);
 
-  /* if we get called recursively, we bail out now to avoid an
-   * infinite loop. */
-  if (GST_PAD_IS_IN_SETCAPS (otherpad))
-    goto done;
-
   GST_DEBUG_OBJECT (pad, "have new caps %p %" GST_PTR_FORMAT, caps, caps);
 
   /* find best possible caps for the other pad */
@@ -1189,21 +1187,29 @@ gst_base_transform_setcaps (GstPad * pad, GstCaps * caps)
   if (!(ret = gst_base_transform_configure_caps (trans, incaps, outcaps)))
     goto failed_configure;
 
+  GST_OBJECT_LOCK (trans->sinkpad);
+  GST_OBJECT_FLAG_UNSET (trans->srcpad, GST_PAD_NEED_RECONFIGURE);
+  trans->priv->reconfigure = FALSE;
+  GST_OBJECT_UNLOCK (trans->sinkpad);
+
   /* we know this will work, we implement the setcaps */
-  gst_pad_set_caps (otherpad, othercaps);
+  gst_pad_push_event (otherpad, gst_event_new_caps (othercaps));
 
   if (pad == trans->srcpad && trans->priv->pad_mode == GST_ACTIVATE_PULL) {
     /* FIXME hm? */
-    ret &= gst_pad_set_caps (otherpeer, othercaps);
+    ret &= gst_pad_push_event (otherpeer, gst_event_new_caps (othercaps));
     if (!ret) {
       GST_INFO_OBJECT (trans, "otherpeer setcaps(%" GST_PTR_FORMAT ") failed",
           othercaps);
     }
   }
 
+  if (ret) {
+    /* try to get a pool when needed */
+    gst_base_transform_do_bufferpool (trans, othercaps);
+  }
+
 done:
-  /* new caps, force alloc on next buffer on the chain */
-  trans->priv->force_alloc = TRUE;
   if (otherpeer)
     gst_object_unref (otherpeer);
   if (othercaps)
@@ -1211,8 +1217,6 @@ done:
 
   trans->negotiated = ret;
 
-  gst_object_unref (trans);
-
   return ret;
 
   /* ERRORS */
@@ -1246,7 +1250,28 @@ gst_base_transform_query (GstPad * pad, GstQuery * query)
   otherpad = (pad == trans->srcpad) ? trans->sinkpad : trans->srcpad;
 
   switch (GST_QUERY_TYPE (query)) {
-    case GST_QUERY_POSITION:{
+    case GST_QUERY_ALLOCATION:
+    {
+      gboolean passthrough;
+
+      /* can only be done on the sinkpad */
+      if (!GST_PAD_IS_SINK (pad))
+        goto done;
+
+      GST_BASE_TRANSFORM_LOCK (trans);
+      passthrough = trans->passthrough || trans->always_in_place;
+      GST_BASE_TRANSFORM_UNLOCK (trans);
+
+      GST_DEBUG_OBJECT (trans, "passthrough %d", passthrough);
+
+      if (passthrough)
+        ret = gst_pad_peer_query (otherpad, query);
+      else
+        ret = FALSE;
+      break;
+    }
+    case GST_QUERY_POSITION:
+    {
       GstFormat format;
 
       gst_query_parse_position (query, &format, NULL);
@@ -1255,13 +1280,13 @@ gst_base_transform_query (GstPad * pad, GstQuery * query)
         ret = TRUE;
 
         if ((pad == trans->sinkpad)
-            || (trans->priv->last_stop_out == GST_CLOCK_TIME_NONE)) {
+            || (trans->priv->position_out == GST_CLOCK_TIME_NONE)) {
           pos =
               gst_segment_to_stream_time (&trans->segment, GST_FORMAT_TIME,
-              trans->segment.last_stop);
+              trans->segment.position);
         } else {
           pos = gst_segment_to_stream_time (&trans->segment, GST_FORMAT_TIME,
-              trans->priv->last_stop_out);
+              trans->priv->position_out);
         }
         gst_query_set_position (query, format, pos);
       } else {
@@ -1274,6 +1299,7 @@ gst_base_transform_query (GstPad * pad, GstQuery * query)
       break;
   }
 
+done:
   gst_object_unref (trans);
   return ret;
 }
@@ -1289,57 +1315,12 @@ gst_base_transform_query_type (GstPad * pad)
   return types;
 }
 
-static void
-compute_upstream_suggestion (GstBaseTransform * trans, guint expsize,
-    GstCaps * caps)
-{
-  GstCaps *othercaps;
-  GstBaseTransformPrivate *priv = trans->priv;
-
-  GST_DEBUG_OBJECT (trans, "trying to find upstream suggestion");
-
-  /* we cannot convert the current buffer but we might be able to suggest a
-   * new format upstream, try to find what the best format is. */
-  othercaps = gst_base_transform_find_transform (trans, trans->srcpad, caps);
-
-  if (!othercaps) {
-    GST_DEBUG_OBJECT (trans, "incompatible caps, ignoring");
-    /* we received caps that we cannot transform. Upstream is behaving badly
-     * because it should have checked if we could handle these caps. We can
-     * simply ignore these caps and produce a buffer with our original caps. */
-  } else {
-    guint size_suggest;
-
-    GST_DEBUG_OBJECT (trans, "getting size of suggestion");
-
-    /* not a subset, we have a new upstream suggestion, remember it and
-     * allocate a default buffer. First we try to convert the size */
-    if (gst_base_transform_transform_size (trans,
-            GST_PAD_SRC, caps, expsize, othercaps, &size_suggest)) {
-
-      /* ok, remember the suggestions now */
-      GST_DEBUG_OBJECT (trans,
-          "storing new caps and size suggestion of %u and %" GST_PTR_FORMAT,
-          size_suggest, othercaps);
-
-      GST_OBJECT_LOCK (trans->sinkpad);
-      if (priv->sink_suggest)
-        gst_caps_unref (priv->sink_suggest);
-      priv->sink_suggest = gst_caps_ref (othercaps);
-      priv->size_suggest = size_suggest;
-      trans->priv->suggest_pending = TRUE;
-      GST_OBJECT_UNLOCK (trans->sinkpad);
-    }
-    gst_caps_unref (othercaps);
-  }
-}
-
 /* Allocate a buffer using gst_pad_alloc_buffer
  *
  * This function can do renegotiation on the source pad
  *
  * The output buffer is always writable. outbuf can be equal to
- * inbuf, the caller should be prepared for this and perform 
+ * inbuf, the caller should be prepared for this and perform
  * appropriate refcounting.
  */
 static GstFlowReturn
@@ -1349,9 +1330,9 @@ gst_base_transform_prepare_output_buffer (GstBaseTransform * trans,
   GstBaseTransformClass *bclass;
   GstBaseTransformPrivate *priv;
   GstFlowReturn ret = GST_FLOW_OK;
-  guint outsize, newsize, expsize;
-  gboolean discard, setcaps, copymeta;
-  GstCaps *incaps, *oldcaps, *newcaps, *outcaps;
+  gboolean copymeta;
+  gsize insize, outsize;
+  GstCaps *incaps = NULL, *outcaps = NULL;
 
   bclass = GST_BASE_TRANSFORM_GET_CLASS (trans);
 
@@ -1359,15 +1340,13 @@ gst_base_transform_prepare_output_buffer (GstBaseTransform * trans,
 
   *out_buf = NULL;
 
+  insize = gst_buffer_get_size (in_buf);
+
   /* figure out how to allocate a buffer based on the current configuration */
   if (trans->passthrough) {
     GST_DEBUG_OBJECT (trans, "doing passthrough alloc");
-    /* passthrough, we don't really need to call pad alloc but we still need to
-     * in order to get upstream negotiation. The output size is the same as the
-     * input size. */
-    outsize = GST_BUFFER_SIZE (in_buf);
-    /* we always alloc and discard here */
-    discard = TRUE;
+    /* passthrough, the output size is the same as the input size. */
+    outsize = insize;
   } else {
     gboolean want_in_place = (bclass->transform_ip != NULL)
         && trans->always_in_place;
@@ -1375,38 +1354,36 @@ gst_base_transform_prepare_output_buffer (GstBaseTransform * trans,
     if (want_in_place) {
       GST_DEBUG_OBJECT (trans, "doing inplace alloc");
       /* we alloc a buffer of the same size as the input */
-      outsize = GST_BUFFER_SIZE (in_buf);
-      /* only discard it when the input was not writable, otherwise, we reuse
-       * the input buffer. */
-      discard = gst_buffer_is_writable (in_buf);
-      GST_DEBUG_OBJECT (trans, "discard: %d", discard);
+      outsize = insize;
     } else {
+      incaps = gst_pad_get_current_caps (trans->sinkpad);
+      outcaps = gst_pad_get_current_caps (trans->srcpad);
+
       GST_DEBUG_OBJECT (trans, "getting output size for copy transform");
       /* copy transform, figure out the output size */
       if (!gst_base_transform_transform_size (trans,
-              GST_PAD_SINK, GST_PAD_CAPS (trans->sinkpad),
-              GST_BUFFER_SIZE (in_buf), GST_PAD_CAPS (trans->srcpad),
-              &outsize)) {
+              GST_PAD_SINK, incaps, insize, outcaps, &outsize)) {
         goto unknown_size;
       }
-      /* never discard this buffer, we need it for storing the output */
-      discard = FALSE;
     }
   }
 
-  oldcaps = GST_PAD_CAPS (trans->srcpad);
-
   if (bclass->prepare_output_buffer) {
+    if (outcaps == NULL)
+      outcaps = gst_pad_get_current_caps (trans->srcpad);
+
     GST_DEBUG_OBJECT (trans,
-        "calling prepare buffer with caps %p %" GST_PTR_FORMAT, oldcaps,
-        oldcaps);
+        "calling prepare buffer with caps %p %" GST_PTR_FORMAT, outcaps,
+        outcaps);
     ret =
-        bclass->prepare_output_buffer (trans, in_buf, outsize, oldcaps,
+        bclass->prepare_output_buffer (trans, in_buf, outsize, outcaps,
         out_buf);
 
     /* get a new ref to the srcpad caps, the prepare_output_buffer function can
      * update the pad caps if it wants */
-    oldcaps = GST_PAD_CAPS (trans->srcpad);
+    if (outcaps)
+      gst_caps_unref (outcaps);
+    outcaps = gst_pad_get_current_caps (trans->srcpad);
 
     /* FIXME 0.11:
      * decrease refcount again if vmethod returned refcounted in_buf. This
@@ -1415,245 +1392,111 @@ gst_base_transform_prepare_output_buffer (GstBaseTransform * trans,
      * a reffed inbuf, which is exactly what we don't want :), oh well.. */
     if (in_buf == *out_buf)
       gst_buffer_unref (in_buf);
-
-    /* never discard the buffer from the prepare_buffer method */
-    if (*out_buf != NULL)
-      discard = FALSE;
   }
 
   if (ret != GST_FLOW_OK)
     goto alloc_failed;
 
   if (*out_buf == NULL) {
-    if (trans->passthrough && !trans->priv->force_alloc) {
-      GST_DEBUG_OBJECT (trans, "Avoiding pad alloc");
-      *out_buf = gst_buffer_ref (in_buf);
+    if (trans->passthrough) {
+      GST_DEBUG_OBJECT (trans, "Reusing input buffer");
+      *out_buf = in_buf;
+    } else if (priv->srcpool) {
+      GST_DEBUG_OBJECT (trans, "using pool alloc");
+      ret = gst_buffer_pool_acquire_buffer (priv->srcpool, out_buf, NULL);
     } else {
-      GST_DEBUG_OBJECT (trans, "doing alloc with caps %" GST_PTR_FORMAT,
-          oldcaps);
-
-      ret = gst_pad_alloc_buffer (trans->srcpad,
-          GST_BUFFER_OFFSET (in_buf), outsize, oldcaps, out_buf);
-      if (ret != GST_FLOW_OK)
-        goto alloc_failed;
+      GST_DEBUG_OBJECT (trans, "doing alloc of size %u", outsize);
+      *out_buf = gst_buffer_new_allocate (NULL, outsize, 0);
     }
   }
 
+  if (ret != GST_FLOW_OK)
+    goto alloc_failed;
+
   /* must always have a buffer by now */
   if (*out_buf == NULL)
     goto no_buffer;
 
-  /* check if we got different caps on this new output buffer */
-  newcaps = GST_BUFFER_CAPS (*out_buf);
-  newsize = GST_BUFFER_SIZE (*out_buf);
-
-  if (newcaps && !gst_caps_is_equal (newcaps, oldcaps)) {
-    GstCaps *othercaps;
-    gboolean can_convert;
-
-    GST_DEBUG_OBJECT (trans, "received new caps %" GST_PTR_FORMAT, newcaps);
-
-    incaps = GST_PAD_CAPS (trans->sinkpad);
-
-    /* check if we can convert the current incaps to the new target caps */
-    can_convert =
-        gst_base_transform_can_transform (trans, trans->sinkpad, incaps,
-        newcaps);
-
-    if (!can_convert) {
-      GST_DEBUG_OBJECT (trans, "cannot perform transform on current buffer");
-
-      gst_base_transform_transform_size (trans,
-          GST_PAD_SINK, incaps, GST_BUFFER_SIZE (in_buf), newcaps, &expsize);
-
-      compute_upstream_suggestion (trans, expsize, newcaps);
-
-      /* we got a suggested caps but we can't transform to it. See if there is
-       * another downstream format that we can transform to */
-      othercaps =
-          gst_base_transform_find_transform (trans, trans->sinkpad, incaps);
-
-      if (othercaps && !gst_caps_is_empty (othercaps)) {
-        GST_DEBUG_OBJECT (trans, "we found target caps %" GST_PTR_FORMAT,
-            othercaps);
-        *out_buf = gst_buffer_make_metadata_writable (*out_buf);
-        gst_buffer_set_caps (*out_buf, othercaps);
-        gst_caps_unref (othercaps);
-        newcaps = GST_BUFFER_CAPS (*out_buf);
-        can_convert = TRUE;
-      } else if (othercaps)
-        gst_caps_unref (othercaps);
-    }
-
-    /* it's possible that the buffer we got is of the wrong size, get the
-     * expected size here, we will check the size if we are going to use the
-     * buffer later on. */
-    gst_base_transform_transform_size (trans,
-        GST_PAD_SINK, incaps, GST_BUFFER_SIZE (in_buf), newcaps, &expsize);
-
-    if (can_convert) {
-      GST_DEBUG_OBJECT (trans, "reconfigure transform for current buffer");
-
-      /* subclass might want to add fields to the caps */
-      if (bclass->fixate_caps != NULL) {
-        newcaps = gst_caps_copy (newcaps);
-
-        GST_DEBUG_OBJECT (trans, "doing fixate %" GST_PTR_FORMAT
-            " using caps %" GST_PTR_FORMAT
-            " on pad %s:%s using fixate_caps vmethod", newcaps, incaps,
-            GST_DEBUG_PAD_NAME (trans->srcpad));
-        bclass->fixate_caps (trans, GST_PAD_SINK, incaps, newcaps);
-
-        *out_buf = gst_buffer_make_metadata_writable (*out_buf);
-        gst_buffer_set_caps (*out_buf, newcaps);
-        gst_caps_unref (newcaps);
-        newcaps = GST_BUFFER_CAPS (*out_buf);
-      }
-
-      /* caps not empty, try to renegotiate to the new format */
-      if (!gst_base_transform_configure_caps (trans, incaps, newcaps)) {
-        /* not sure we need to fail hard here, we can simply continue our
-         * conversion with what we negotiated before */
-        goto failed_configure;
-      }
-      /* new format configure, and use the new output buffer */
-      gst_pad_set_caps (trans->srcpad, newcaps);
-      discard = FALSE;
-      /* clear previous cached sink-pad caps, so buffer_alloc knows that
-       * it needs to revisit the decision about whether to proxy or not: */
-      gst_caps_replace (&priv->sink_alloc, NULL);
-      /* if we got a buffer of the wrong size, discard it now and make sure we
-       * allocate a propertly sized buffer later. */
-      if (newsize != expsize) {
-        if (in_buf != *out_buf)
-          gst_buffer_unref (*out_buf);
-        *out_buf = NULL;
-      }
-      outsize = expsize;
-    } else {
-      compute_upstream_suggestion (trans, expsize, newcaps);
-
-      if (in_buf != *out_buf)
-        gst_buffer_unref (*out_buf);
-      *out_buf = NULL;
-    }
-  } else if (outsize != newsize) {
-    GST_WARNING_OBJECT (trans, "Caps did not change but allocated size does "
-        "not match expected size (%d != %d)", newsize, outsize);
-    if (in_buf != *out_buf)
-      gst_buffer_unref (*out_buf);
-    *out_buf = NULL;
+  if (trans->passthrough && in_buf != *out_buf) {
+    /* we are asked to perform a passthrough transform but the input and
+     * output buffers are different. We have to discard the output buffer and
+     * reuse the input buffer. */
+    GST_DEBUG_OBJECT (trans, "passthrough but different buffers");
+    gst_buffer_unref (*out_buf);
+    *out_buf = in_buf;
   }
+  GST_DEBUG_OBJECT (trans, "using allocated buffer in %p, out %p", in_buf,
+      *out_buf);
 
-  /* these are the final output caps */
-  outcaps = GST_PAD_CAPS (trans->srcpad);
-
+  /* if we have different buffers, check if the metadata is ok */
   copymeta = FALSE;
-  if (*out_buf == NULL) {
-    if (!discard) {
-      GST_DEBUG_OBJECT (trans, "make default output buffer of size %d",
-          outsize);
-      /* no valid buffer yet, make one, metadata is writable */
-      *out_buf = gst_buffer_new_and_alloc (outsize);
-      gst_buffer_copy_metadata (*out_buf, in_buf,
-          GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_TIMESTAMPS);
-    } else {
-      GST_DEBUG_OBJECT (trans, "reuse input buffer");
-      *out_buf = in_buf;
-    }
-  } else {
-    if (trans->passthrough && in_buf != *out_buf) {
-      /* we are asked to perform a passthrough transform but the input and
-       * output buffers are different. We have to discard the output buffer and
-       * reuse the input buffer. */
-      GST_DEBUG_OBJECT (trans, "passthrough but different buffers");
-      discard = TRUE;
-    }
-    if (discard) {
-      GST_DEBUG_OBJECT (trans, "discard buffer, reuse input buffer");
-      gst_buffer_unref (*out_buf);
-      *out_buf = in_buf;
-    } else {
-      GST_DEBUG_OBJECT (trans, "using allocated buffer in %p, out %p", in_buf,
-          *out_buf);
-      /* if we have different buffers, check if the metadata is ok */
-      if (*out_buf != in_buf) {
-        guint mask;
-
-        mask = GST_BUFFER_FLAG_PREROLL | GST_BUFFER_FLAG_IN_CAPS |
-            GST_BUFFER_FLAG_DELTA_UNIT | GST_BUFFER_FLAG_DISCONT |
-            GST_BUFFER_FLAG_GAP | GST_BUFFER_FLAG_MEDIA1 |
-            GST_BUFFER_FLAG_MEDIA2 | GST_BUFFER_FLAG_MEDIA3;
-        /* see if the flags and timestamps match */
-        copymeta =
-            (GST_MINI_OBJECT_FLAGS (*out_buf) & mask) ==
-            (GST_MINI_OBJECT_FLAGS (in_buf) & mask);
-        copymeta |=
-            GST_BUFFER_TIMESTAMP (*out_buf) != GST_BUFFER_TIMESTAMP (in_buf) ||
-            GST_BUFFER_DURATION (*out_buf) != GST_BUFFER_DURATION (in_buf) ||
-            GST_BUFFER_OFFSET (*out_buf) != GST_BUFFER_OFFSET (in_buf) ||
-            GST_BUFFER_OFFSET_END (*out_buf) != GST_BUFFER_OFFSET_END (in_buf);
-      }
-    }
+  if (*out_buf != in_buf) {
+    guint mask;
+
+    mask = GST_BUFFER_FLAG_PREROLL | GST_BUFFER_FLAG_IN_CAPS |
+        GST_BUFFER_FLAG_DELTA_UNIT | GST_BUFFER_FLAG_DISCONT |
+        GST_BUFFER_FLAG_GAP | GST_BUFFER_FLAG_MEDIA1 |
+        GST_BUFFER_FLAG_MEDIA2 | GST_BUFFER_FLAG_MEDIA3;
+    /* see if the flags and timestamps match */
+    copymeta =
+        (GST_MINI_OBJECT_FLAGS (*out_buf) & mask) ==
+        (GST_MINI_OBJECT_FLAGS (in_buf) & mask);
+    copymeta |=
+        GST_BUFFER_TIMESTAMP (*out_buf) != GST_BUFFER_TIMESTAMP (in_buf) ||
+        GST_BUFFER_DURATION (*out_buf) != GST_BUFFER_DURATION (in_buf) ||
+        GST_BUFFER_OFFSET (*out_buf) != GST_BUFFER_OFFSET (in_buf) ||
+        GST_BUFFER_OFFSET_END (*out_buf) != GST_BUFFER_OFFSET_END (in_buf);
   }
 
-  /* check if we need to make things writable. We need this when we need to
-   * update the caps or the metadata on the output buffer. */
-  newcaps = GST_BUFFER_CAPS (*out_buf);
-  /* we check the pointers as a quick check and then go to the more involved
-   * check. This is needed when we receive different pointers on the sinkpad
-   * that mean the same caps. What we then want to do is prefer those caps over
-   * the ones on the srcpad and set the srcpad caps to the buffer caps */
-  setcaps = !newcaps || ((newcaps != outcaps)
-      && (!gst_caps_is_equal (newcaps, outcaps)));
   /* we need to modify the metadata when the element is not gap aware,
    * passthrough is not used and the gap flag is set */
-  copymeta |= !trans->priv->gap_aware && !trans->passthrough
+  copymeta |= !priv->gap_aware && !trans->passthrough
       && (GST_MINI_OBJECT_FLAGS (*out_buf) & GST_BUFFER_FLAG_GAP);
 
-  if (setcaps || copymeta) {
-    GST_DEBUG_OBJECT (trans, "setcaps %d, copymeta %d", setcaps, copymeta);
-    if (!gst_buffer_is_metadata_writable (*out_buf)) {
-      GST_DEBUG_OBJECT (trans, "buffer metadata %p not writable", *out_buf);
+  if (copymeta) {
+    GST_DEBUG_OBJECT (trans, "copymeta %d", copymeta);
+    if (!gst_buffer_is_writable (*out_buf)) {
+      GST_DEBUG_OBJECT (trans, "buffer %p not writable", *out_buf);
       if (in_buf == *out_buf)
-        *out_buf = gst_buffer_create_sub (in_buf, 0, GST_BUFFER_SIZE (in_buf));
+        *out_buf = gst_buffer_copy (in_buf);
       else
-        *out_buf = gst_buffer_make_metadata_writable (*out_buf);
+        *out_buf = gst_buffer_make_writable (*out_buf);
     }
     /* when we get here, the metadata should be writable */
-    if (setcaps)
-      gst_buffer_set_caps (*out_buf, outcaps);
     if (copymeta)
-      gst_buffer_copy_metadata (*out_buf, in_buf,
-          GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_TIMESTAMPS);
+      gst_buffer_copy_into (*out_buf, in_buf,
+          GST_BUFFER_COPY_FLAGS | GST_BUFFER_COPY_TIMESTAMPS, 0, -1);
     /* clear the GAP flag when the subclass does not understand it */
-    if (!trans->priv->gap_aware)
+    if (!priv->gap_aware)
       GST_BUFFER_FLAG_UNSET (*out_buf, GST_BUFFER_FLAG_GAP);
   }
 
+done:
+  if (incaps)
+    gst_caps_unref (incaps);
+  if (outcaps)
+    gst_caps_unref (outcaps);
+
   return ret;
 
   /* ERRORS */
 alloc_failed:
   {
     GST_WARNING_OBJECT (trans, "pad-alloc failed: %s", gst_flow_get_name (ret));
-    return ret;
+    goto done;
   }
 no_buffer:
   {
     GST_ELEMENT_ERROR (trans, STREAM, NOT_IMPLEMENTED,
         ("Sub-class failed to provide an output buffer"), (NULL));
-    return GST_FLOW_ERROR;
+    ret = GST_FLOW_ERROR;
+    goto done;
   }
 unknown_size:
   {
     GST_ERROR_OBJECT (trans, "unknown output size");
-    return GST_FLOW_ERROR;
-  }
-failed_configure:
-  {
-    GST_WARNING_OBJECT (trans, "failed to configure caps");
-    return GST_FLOW_NOT_NEGOTIATED;
+    ret = GST_FLOW_ERROR;
+    goto done;
   }
 }
 
@@ -1672,7 +1515,7 @@ failed_configure:
  */
 static gboolean
 gst_base_transform_get_unit_size (GstBaseTransform * trans, GstCaps * caps,
-    guint * size)
+    gsize * size)
 {
   gboolean res = FALSE;
   GstBaseTransformClass *bclass;
@@ -1715,304 +1558,6 @@ gst_base_transform_get_unit_size (GstBaseTransform * trans, GstCaps * caps,
   return res;
 }
 
-/* your upstream peer wants to send you a buffer
- * that buffer has the given offset, size and caps
- * you're requested to allocate a buffer
- */
-static GstFlowReturn
-gst_base_transform_buffer_alloc (GstPad * pad, guint64 offset, guint size,
-    GstCaps * caps, GstBuffer ** buf)
-{
-  GstBaseTransform *trans;
-  GstBaseTransformClass *klass;
-  GstBaseTransformPrivate *priv;
-  GstFlowReturn res;
-  gboolean alloced = FALSE;
-  gboolean proxy, suggest, same_caps;
-  GstCaps *sink_suggest = NULL;
-  guint size_suggest;
-
-  trans = GST_BASE_TRANSFORM (gst_pad_get_parent (pad));
-  if (G_UNLIKELY (trans == NULL))
-    return GST_FLOW_WRONG_STATE;
-  klass = GST_BASE_TRANSFORM_GET_CLASS (trans);
-  priv = trans->priv;
-
-  GST_DEBUG_OBJECT (pad, "alloc with caps %p %" GST_PTR_FORMAT ", size %u",
-      caps, caps, size);
-
-  /* if the code below does not come up with a better buffer, we will return _OK
-   * and an empty buffer. This will trigger the core to allocate a buffer with
-   * given input size and caps. */
-  *buf = NULL;
-  res = GST_FLOW_OK;
-
-  /* we remember our previous alloc request to quickly see if we can proxy or
-   * not. We skip this check if we have a pending suggestion. */
-  GST_OBJECT_LOCK (pad);
-  same_caps = !priv->suggest_pending && caps &&
-      gst_caps_is_equal (priv->sink_alloc, caps);
-  GST_OBJECT_UNLOCK (pad);
-
-  if (same_caps) {
-    /* we have seen this before, see below if we need to proxy */
-    GST_DEBUG_OBJECT (trans, "have old caps %p, size %u", caps, size);
-    gst_caps_replace (&sink_suggest, caps);
-    size_suggest = size;
-    suggest = FALSE;
-  } else {
-    GST_DEBUG_OBJECT (trans, "new format %p %" GST_PTR_FORMAT, caps, caps);
-
-    /* if we have a suggestion, pretend we got these as input */
-    GST_OBJECT_LOCK (pad);
-    if ((priv->sink_suggest && !gst_caps_is_equal (caps, priv->sink_suggest))) {
-      sink_suggest = gst_caps_ref (priv->sink_suggest);
-      size_suggest = priv->size_suggest;
-      GST_DEBUG_OBJECT (trans, "have suggestion %p %" GST_PTR_FORMAT " size %u",
-          sink_suggest, sink_suggest, priv->size_suggest);
-      /* suggest is TRUE when we have a custom suggestion pending that we need
-       * to unref later. */
-      suggest = TRUE;
-    } else {
-      GST_DEBUG_OBJECT (trans, "using caps %p %" GST_PTR_FORMAT " size %u",
-          caps, caps, size);
-      gst_caps_replace (&sink_suggest, caps);
-      size_suggest = size;
-      suggest = FALSE;
-    }
-    priv->suggest_pending = FALSE;
-    GST_OBJECT_UNLOCK (pad);
-
-    /* check if we actually handle this format on the sinkpad */
-    if (sink_suggest) {
-      const GstCaps *templ;
-
-      if (!gst_caps_is_fixed (sink_suggest)) {
-        GstCaps *peercaps;
-
-        GST_DEBUG_OBJECT (trans, "Suggested caps is not fixed: %"
-            GST_PTR_FORMAT, sink_suggest);
-
-        peercaps =
-            gst_pad_peer_get_caps_reffed (GST_BASE_TRANSFORM_SINK_PAD (trans));
-        /* try fixating by intersecting with peer caps */
-        if (peercaps) {
-          GstCaps *intersect;
-
-          intersect =
-              gst_caps_intersect_full (sink_suggest, peercaps,
-              GST_CAPS_INTERSECT_FIRST);
-          gst_caps_unref (peercaps);
-          gst_caps_unref (sink_suggest);
-          sink_suggest = intersect;
-        }
-
-        if (gst_caps_is_empty (sink_suggest))
-          goto not_supported;
-
-        /* try the alloc caps if it is still not fixed */
-        if (!gst_caps_is_fixed (sink_suggest)) {
-          GstCaps *intersect;
-
-          GST_DEBUG_OBJECT (trans, "Checking if the input caps is compatible "
-              "with the non-fixed caps suggestion");
-          intersect =
-              gst_caps_intersect_full (sink_suggest, caps,
-              GST_CAPS_INTERSECT_FIRST);
-          if (!gst_caps_is_empty (intersect)) {
-            GST_DEBUG_OBJECT (trans, "It is, using it");
-            gst_caps_replace (&sink_suggest, caps);
-          }
-          gst_caps_unref (intersect);
-        }
-
-        /* be safe and call default fixate */
-        sink_suggest = gst_caps_make_writable (sink_suggest);
-        gst_pad_fixate_caps (GST_BASE_TRANSFORM_SINK_PAD (trans), sink_suggest);
-
-        if (!gst_caps_is_fixed (sink_suggest)) {
-          gst_caps_unref (sink_suggest);
-          sink_suggest = NULL;
-        }
-
-        GST_DEBUG_OBJECT (trans, "Caps fixed to: %" GST_PTR_FORMAT,
-            sink_suggest);
-      }
-
-      if (sink_suggest) {
-        templ = gst_pad_get_pad_template_caps (pad);
-
-        if (!gst_caps_can_intersect (sink_suggest, templ)) {
-          GstCaps *allowed;
-          GstCaps *peercaps;
-
-          GST_DEBUG_OBJECT (trans,
-              "Requested pad alloc caps are not supported: %" GST_PTR_FORMAT,
-              sink_suggest);
-          /* the requested pad alloc caps are not supported, so let's try
-           * picking something allowed between the pads (they are linked,
-           * there must be something) */
-          allowed = gst_pad_get_allowed_caps (pad);
-          if (allowed && !gst_caps_is_empty (allowed)) {
-            GST_DEBUG_OBJECT (trans,
-                "pads could agree on one of the following caps: " "%"
-                GST_PTR_FORMAT, allowed);
-            allowed = gst_caps_make_writable (allowed);
-
-            if (klass->fixate_caps) {
-              peercaps =
-                  gst_pad_get_allowed_caps (GST_BASE_TRANSFORM_SRC_PAD (trans));
-              klass->fixate_caps (trans, GST_PAD_SRC, peercaps, allowed);
-              gst_caps_unref (peercaps);
-            }
-
-            /* Fixate them to be safe if the subclass didn't do it */
-            gst_caps_truncate (allowed);
-            gst_pad_fixate_caps (pad, allowed);
-            gst_caps_replace (&sink_suggest, allowed);
-            gst_caps_unref (allowed);
-
-            suggest = TRUE;
-
-            GST_DEBUG_OBJECT (trans, "Fixated suggestion caps to %"
-                GST_PTR_FORMAT, sink_suggest);
-          } else {
-            if (allowed)
-              gst_caps_unref (allowed);
-            goto not_supported;
-          }
-        }
-      }
-    }
-
-    /* find the best format for the other side here we decide if we will proxy
-     * the caps or not. */
-    if (sink_suggest == NULL) {
-      /* always proxy when the caps are NULL. When this is a new format, see if
-       * we can proxy it downstream */
-      GST_DEBUG_OBJECT (trans, "null caps, marking for proxy");
-      priv->proxy_alloc = TRUE;
-    } else {
-      GstCaps *othercaps;
-
-      /* we have a new format, see what we need to proxy to */
-      othercaps = gst_base_transform_find_transform (trans, pad, sink_suggest);
-      if (!othercaps || gst_caps_is_empty (othercaps)) {
-        /* no transform possible, we certainly can't proxy */
-        GST_DEBUG_OBJECT (trans, "can't find transform, disable proxy");
-        priv->proxy_alloc = FALSE;
-      } else {
-        /* we transformed into something */
-        if (gst_caps_is_equal (sink_suggest, othercaps)) {
-          GST_DEBUG_OBJECT (trans,
-              "best caps same as input, marking for proxy");
-          priv->proxy_alloc = TRUE;
-        } else {
-          GST_DEBUG_OBJECT (trans,
-              "best caps different from input, disable proxy");
-          priv->proxy_alloc = FALSE;
-        }
-      }
-      if (othercaps)
-        gst_caps_unref (othercaps);
-    }
-  }
-  /* remember the new caps */
-  GST_OBJECT_LOCK (pad);
-  gst_caps_replace (&priv->sink_alloc, sink_suggest);
-  GST_OBJECT_UNLOCK (pad);
-
-  proxy = priv->proxy_alloc;
-  GST_DEBUG_OBJECT (trans, "doing default alloc, proxy %d, suggest %d", proxy,
-      suggest);
-
-  /* we only want to proxy if we have no suggestion pending, FIXME */
-  if (proxy && !suggest) {
-    GstCaps *newcaps;
-
-    GST_DEBUG_OBJECT (trans, "proxy buffer-alloc with caps %p %" GST_PTR_FORMAT
-        ", size %u", caps, caps, size);
-
-    /* we always proxy the input caps, never the suggestion. The reason is that
-     * We don't yet handle the caps of renegotiation in here. FIXME */
-    res = gst_pad_alloc_buffer (trans->srcpad, offset, size, caps, buf);
-    if (res != GST_FLOW_OK)
-      goto alloc_failed;
-    alloced = TRUE;
-
-    /* check if the caps changed */
-    newcaps = GST_BUFFER_CAPS (*buf);
-
-    GST_DEBUG_OBJECT (trans, "got caps %" GST_PTR_FORMAT, newcaps);
-
-    if (!gst_caps_is_equal (newcaps, caps)) {
-      GST_DEBUG_OBJECT (trans, "caps are new");
-      /* we have new caps, see if we can proxy downstream */
-      if (gst_pad_peer_accept_caps (pad, newcaps)) {
-        /* peer accepts the caps, return a buffer in this format */
-        GST_DEBUG_OBJECT (trans, "peer accepted new caps");
-        /* remember the format */
-        GST_OBJECT_LOCK (pad);
-        gst_caps_replace (&priv->sink_alloc, newcaps);
-        GST_OBJECT_UNLOCK (pad);
-      } else {
-        GST_DEBUG_OBJECT (trans, "peer did not accept new caps");
-        /* peer does not accept the caps, disable proxy_alloc, free the
-         * buffer we received and create a buffer of the requested format
-         * by the default handler. */
-        GST_DEBUG_OBJECT (trans, "disabling proxy");
-        priv->proxy_alloc = FALSE;
-        gst_buffer_unref (*buf);
-        *buf = NULL;
-      }
-    } else {
-      GST_DEBUG_OBJECT (trans, "received required caps from peer");
-    }
-  }
-
-  if (suggest) {
-    /* there was a custom suggestion, create a buffer of this format and return
-     * it. Note that this format  */
-    *buf = gst_buffer_new_and_alloc (size_suggest);
-    GST_DEBUG_OBJECT (trans,
-        "doing suggestion of size %u, caps %p %" GST_PTR_FORMAT, size_suggest,
-        sink_suggest, sink_suggest);
-    GST_BUFFER_CAPS (*buf) = sink_suggest;
-    sink_suggest = NULL;
-  }
-
-  if (sink_suggest)
-    gst_caps_unref (sink_suggest);
-
-  if (res == GST_FLOW_OK && alloced) {
-    /* just alloc'ed a buffer, so we only want to do this again if we
-     * received a buffer */
-    GST_DEBUG_OBJECT (trans, "Cleaning force alloc");
-    trans->priv->force_alloc = FALSE;
-  }
-
-  gst_object_unref (trans);
-  return res;
-
-  /* ERRORS */
-alloc_failed:
-  {
-    GST_DEBUG_OBJECT (trans, "pad alloc failed: %s", gst_flow_get_name (res));
-    if (sink_suggest)
-      gst_caps_unref (sink_suggest);
-    gst_object_unref (trans);
-    return res;
-  }
-not_supported:
-  {
-    GST_DEBUG_OBJECT (trans, "pad alloc with unsupported caps");
-    if (sink_suggest)
-      gst_caps_unref (sink_suggest);
-    gst_object_unref (trans);
-    return GST_FLOW_NOT_NEGOTIATED;
-  }
-}
-
 static gboolean
 gst_base_transform_sink_event (GstPad * pad, GstEvent * event)
 {
@@ -2046,6 +1591,8 @@ gst_base_transform_sink_event (GstPad * pad, GstEvent * event)
 static gboolean
 gst_base_transform_sink_eventfunc (GstBaseTransform * trans, GstEvent * event)
 {
+  gboolean forward = TRUE;
+
   switch (GST_EVENT_TYPE (event)) {
     case GST_EVENT_FLUSH_START:
       break;
@@ -2059,51 +1606,38 @@ gst_base_transform_sink_eventfunc (GstBaseTransform * trans, GstEvent * event)
       trans->priv->dropped = 0;
       GST_OBJECT_UNLOCK (trans);
       /* we need new segment info after the flush. */
-      trans->have_newsegment = FALSE;
+      trans->have_segment = FALSE;
       gst_segment_init (&trans->segment, GST_FORMAT_UNDEFINED);
-      trans->priv->last_stop_out = GST_CLOCK_TIME_NONE;
+      trans->priv->position_out = GST_CLOCK_TIME_NONE;
       break;
     case GST_EVENT_EOS:
       break;
     case GST_EVENT_TAG:
       break;
-    case GST_EVENT_NEWSEGMENT:
+    case GST_EVENT_CAPS:
     {
-      GstFormat format;
-      gdouble rate, arate;
-      gint64 start, stop, time;
-      gboolean update;
-
-      gst_event_parse_new_segment_full (event, &update, &rate, &arate, &format,
-          &start, &stop, &time);
-
-      trans->have_newsegment = TRUE;
-
-      gst_segment_set_newsegment_full (&trans->segment, update, rate, arate,
-          format, start, stop, time);
-
-      if (format == GST_FORMAT_TIME) {
-        GST_DEBUG_OBJECT (trans, "received TIME NEW_SEGMENT %" GST_TIME_FORMAT
-            " -- %" GST_TIME_FORMAT ", time %" GST_TIME_FORMAT
-            ", accum %" GST_TIME_FORMAT,
-            GST_TIME_ARGS (trans->segment.start),
-            GST_TIME_ARGS (trans->segment.stop),
-            GST_TIME_ARGS (trans->segment.time),
-            GST_TIME_ARGS (trans->segment.accum));
-      } else {
-        GST_DEBUG_OBJECT (trans, "received NEW_SEGMENT %" G_GINT64_FORMAT
-            " -- %" G_GINT64_FORMAT ", time %" G_GINT64_FORMAT
-            ", accum %" G_GINT64_FORMAT,
-            trans->segment.start, trans->segment.stop,
-            trans->segment.time, trans->segment.accum);
-      }
+      GstCaps *caps;
+
+      gst_event_parse_caps (event, &caps);
+      gst_base_transform_setcaps (trans, trans->sinkpad, caps);
+
+      forward = FALSE;
+      break;
+    }
+    case GST_EVENT_SEGMENT:
+    {
+      gst_event_copy_segment (event, &trans->segment);
+      trans->have_segment = TRUE;
+
+      GST_DEBUG_OBJECT (trans, "received SEGMENT %" GST_SEGMENT_FORMAT,
+          &trans->segment);
       break;
     }
     default:
       break;
   }
 
-  return TRUE;
+  return forward;
 }
 
 static gboolean
@@ -2149,7 +1683,7 @@ gst_base_transform_src_eventfunc (GstBaseTransform * trans, GstEvent * event)
       GstClockTimeDiff diff;
       GstClockTime timestamp;
 
-      gst_event_parse_qos (event, &proportion, &diff, &timestamp);
+      gst_event_parse_qos (event, NULL, &proportion, &diff, &timestamp);
       gst_base_transform_update_qos (trans, proportion, diff, timestamp);
       break;
     }
@@ -2173,36 +1707,51 @@ gst_base_transform_handle_buffer (GstBaseTransform * trans, GstBuffer * inbuf,
 {
   GstBaseTransformClass *bclass;
   GstFlowReturn ret = GST_FLOW_OK;
-  gboolean want_in_place, reconfigure;
+  gboolean want_in_place;
   GstClockTime running_time;
   GstClockTime timestamp;
-  GstCaps *incaps;
+  gsize insize;
+  gboolean reconfigure;
 
   bclass = GST_BASE_TRANSFORM_GET_CLASS (trans);
 
-  if (G_LIKELY ((incaps = GST_BUFFER_CAPS (inbuf)))) {
-    GST_OBJECT_LOCK (trans);
-    reconfigure = trans->priv->reconfigure;
-    trans->priv->reconfigure = FALSE;
-    GST_OBJECT_UNLOCK (trans);
+  GST_OBJECT_LOCK (trans->sinkpad);
+  reconfigure = GST_PAD_NEEDS_RECONFIGURE (trans->srcpad)
+      || trans->priv->reconfigure;
+  GST_OBJECT_FLAG_UNSET (trans->srcpad, GST_PAD_NEED_RECONFIGURE);
+  trans->priv->reconfigure = FALSE;
+  GST_OBJECT_UNLOCK (trans->sinkpad);
+
+  if (G_UNLIKELY (reconfigure)) {
+    GstCaps *incaps;
+
+    GST_DEBUG_OBJECT (trans, "we had a pending reconfigure");
+
+    incaps = gst_pad_get_current_caps (trans->sinkpad);
+    if (incaps == NULL)
+      goto no_reconfigure;
 
-    if (G_UNLIKELY (reconfigure)) {
-      GST_DEBUG_OBJECT (trans, "we had a pending reconfigure");
-      /* if we need to reconfigure we pretend a buffer with new caps arrived. This
-       * will reconfigure the transform with the new output format. We can only
-       * do this if the buffer actually has caps. */
-      if (!gst_base_transform_setcaps (trans->sinkpad, incaps))
-        goto not_negotiated;
+    /* if we need to reconfigure we pretend a buffer with new caps arrived. This
+     * will reconfigure the transform with the new output format. We can only
+     * do this if the buffer actually has caps. */
+    if (!gst_base_transform_setcaps (trans, trans->sinkpad, incaps)) {
+      gst_caps_unref (incaps);
+      goto not_negotiated;
     }
+    gst_caps_unref (incaps);
   }
 
+no_reconfigure:
+  insize = gst_buffer_get_size (inbuf);
+
   if (GST_BUFFER_OFFSET_IS_VALID (inbuf))
-    GST_DEBUG_OBJECT (trans, "handling buffer %p of size %d and offset %"
-        G_GUINT64_FORMAT, inbuf, GST_BUFFER_SIZE (inbuf),
-        GST_BUFFER_OFFSET (inbuf));
+    GST_DEBUG_OBJECT (trans,
+        "handling buffer %p of size %" G_GSIZE_FORMAT " and offset %"
+        G_GUINT64_FORMAT, inbuf, insize, GST_BUFFER_OFFSET (inbuf));
   else
-    GST_DEBUG_OBJECT (trans, "handling buffer %p of size %d and offset NONE",
-        inbuf, GST_BUFFER_SIZE (inbuf));
+    GST_DEBUG_OBJECT (trans,
+        "handling buffer %p of size %" G_GSIZE_FORMAT " and offset NONE", inbuf,
+        insize);
 
   /* Don't allow buffer handling before negotiation, except in passthrough mode
    * or if the class doesn't implement a set_caps function (in which case it doesn't
@@ -2277,9 +1826,7 @@ gst_base_transform_handle_buffer (GstBaseTransform * trans, GstBuffer * inbuf,
 no_qos:
 
   /* first try to allocate an output buffer based on the currently negotiated
-   * format. While we call pad-alloc we could renegotiate the srcpad format or
-   * have a new suggestion for upstream buffer-alloc. 
-   * In any case, outbuf will contain a buffer suitable for doing the configured
+   * format. outbuf will contain a buffer suitable for doing the configured
    * transform after this function. */
   ret = gst_base_transform_prepare_output_buffer (trans, inbuf, outbuf);
   if (G_UNLIKELY (ret != GST_FLOW_OK))
@@ -2304,16 +1851,20 @@ no_qos:
 
       if (inbuf != *outbuf) {
         guint8 *indata, *outdata;
+        gsize insize, outsize;
 
         /* Different buffer. The data can still be the same when we are dealing
          * with subbuffers of the same buffer. Note that because of the FIXME in
          * prepare_output_buffer() we have decreased the refcounts of inbuf and
          * outbuf to keep them writable */
-        indata = GST_BUFFER_DATA (inbuf);
-        outdata = GST_BUFFER_DATA (*outbuf);
+        indata = gst_buffer_map (inbuf, &insize, NULL, GST_MAP_READ);
+        outdata = gst_buffer_map (*outbuf, &outsize, NULL, GST_MAP_WRITE);
 
         if (indata != outdata)
-          memcpy (outdata, indata, GST_BUFFER_SIZE (inbuf));
+          memcpy (outdata, indata, insize);
+
+        gst_buffer_unmap (inbuf, indata, insize);
+        gst_buffer_unmap (*outbuf, outdata, outsize);
       }
       ret = bclass->transform_ip (trans, *outbuf);
     } else {
@@ -2331,9 +1882,6 @@ skip:
   if (*outbuf != inbuf)
     gst_buffer_unref (inbuf);
 
-  /* pushed a buffer, we can now try an alloc */
-  GST_DEBUG_OBJECT (trans, "Pushed a buffer, setting force alloc to true");
-  trans->priv->force_alloc = TRUE;
   return ret;
 
   /* ERRORS */
@@ -2347,27 +1895,13 @@ not_negotiated:
 no_buffer:
   {
     gst_buffer_unref (inbuf);
+    *outbuf = NULL;
     GST_WARNING_OBJECT (trans, "could not get buffer from pool: %s",
         gst_flow_get_name (ret));
     return ret;
   }
 }
 
-static gboolean
-gst_base_transform_check_get_range (GstPad * pad)
-{
-  GstBaseTransform *trans;
-  gboolean ret;
-
-  trans = GST_BASE_TRANSFORM (gst_pad_get_parent (pad));
-
-  ret = gst_pad_check_pull_range (trans->sinkpad);
-
-  gst_object_unref (trans);
-
-  return ret;
-}
-
 /* FIXME, getrange is broken, need to pull range from the other
  * end based on the transform_size result.
  */
@@ -2414,7 +1948,7 @@ gst_base_transform_chain (GstPad * pad, GstBuffer * buffer)
   GstBaseTransform *trans;
   GstBaseTransformClass *klass;
   GstFlowReturn ret;
-  GstClockTime last_stop = GST_CLOCK_TIME_NONE;
+  GstClockTime position = GST_CLOCK_TIME_NONE;
   GstClockTime timestamp, duration;
   GstBuffer *outbuf = NULL;
 
@@ -2426,9 +1960,9 @@ gst_base_transform_chain (GstPad * pad, GstBuffer * buffer)
   /* calculate end position of the incoming buffer */
   if (timestamp != GST_CLOCK_TIME_NONE) {
     if (duration != GST_CLOCK_TIME_NONE)
-      last_stop = timestamp + duration;
+      position = timestamp + duration;
     else
-      last_stop = timestamp;
+      position = timestamp;
   }
 
   klass = GST_BASE_TRANSFORM_GET_CLASS (trans);
@@ -2444,28 +1978,28 @@ gst_base_transform_chain (GstPad * pad, GstBuffer * buffer)
    * GST_BASE_TRANSFORM_FLOW_DROPPED we will not push either. */
   if (outbuf != NULL) {
     if ((ret == GST_FLOW_OK)) {
-      GstClockTime last_stop_out = GST_CLOCK_TIME_NONE;
+      GstClockTime position_out = GST_CLOCK_TIME_NONE;
 
       /* Remember last stop position */
-      if (last_stop != GST_CLOCK_TIME_NONE &&
+      if (position != GST_CLOCK_TIME_NONE &&
           trans->segment.format == GST_FORMAT_TIME)
-        gst_segment_set_last_stop (&trans->segment, GST_FORMAT_TIME, last_stop);
+        trans->segment.position = position;
 
       if (GST_BUFFER_TIMESTAMP_IS_VALID (outbuf)) {
-        last_stop_out = GST_BUFFER_TIMESTAMP (outbuf);
+        position_out = GST_BUFFER_TIMESTAMP (outbuf);
         if (GST_BUFFER_DURATION_IS_VALID (outbuf))
-          last_stop_out += GST_BUFFER_DURATION (outbuf);
-      } else if (last_stop != GST_CLOCK_TIME_NONE) {
-        last_stop_out = last_stop;
+          position_out += GST_BUFFER_DURATION (outbuf);
+      } else if (position != GST_CLOCK_TIME_NONE) {
+        position_out = position;
       }
-      if (last_stop_out != GST_CLOCK_TIME_NONE
+      if (position_out != GST_CLOCK_TIME_NONE
           && trans->segment.format == GST_FORMAT_TIME)
-        trans->priv->last_stop_out = last_stop_out;
+        trans->priv->position_out = position_out;
 
       /* apply DISCONT flag if the buffer is not yet marked as such */
       if (trans->priv->discont) {
         if (!GST_BUFFER_IS_DISCONT (outbuf)) {
-          outbuf = gst_buffer_make_metadata_writable (outbuf);
+          outbuf = gst_buffer_make_writable (outbuf);
           GST_BUFFER_FLAG_SET (outbuf, GST_BUFFER_FLAG_DISCONT);
         }
         trans->priv->discont = FALSE;
@@ -2532,31 +2066,36 @@ gst_base_transform_activate (GstBaseTransform * trans, gboolean active)
   bclass = GST_BASE_TRANSFORM_GET_CLASS (trans);
 
   if (active) {
+    GstCaps *incaps, *outcaps;
+
     if (trans->priv->pad_mode == GST_ACTIVATE_NONE && bclass->start)
       result &= bclass->start (trans);
 
-    GST_OBJECT_LOCK (trans);
+    incaps = gst_pad_get_current_caps (trans->sinkpad);
+    outcaps = gst_pad_get_current_caps (trans->srcpad);
 
-    if (GST_PAD_CAPS (trans->sinkpad) && GST_PAD_CAPS (trans->srcpad))
+    GST_OBJECT_LOCK (trans);
+    if (incaps && outcaps)
       trans->have_same_caps =
-          gst_caps_is_equal (GST_PAD_CAPS (trans->sinkpad),
-          GST_PAD_CAPS (trans->srcpad)) || trans->passthrough;
+          gst_caps_is_equal (incaps, outcaps) || trans->passthrough;
     else
       trans->have_same_caps = trans->passthrough;
     GST_DEBUG_OBJECT (trans, "have_same_caps %d", trans->have_same_caps);
     trans->negotiated = FALSE;
-    trans->have_newsegment = FALSE;
+    trans->have_segment = FALSE;
     gst_segment_init (&trans->segment, GST_FORMAT_UNDEFINED);
-    trans->priv->last_stop_out = GST_CLOCK_TIME_NONE;
+    trans->priv->position_out = GST_CLOCK_TIME_NONE;
     trans->priv->proportion = 1.0;
     trans->priv->earliest_time = -1;
     trans->priv->discont = FALSE;
-    gst_caps_replace (&trans->priv->sink_suggest, NULL);
     trans->priv->processed = 0;
     trans->priv->dropped = 0;
-    trans->priv->force_alloc = TRUE;
-
     GST_OBJECT_UNLOCK (trans);
+
+    if (incaps)
+      gst_caps_unref (incaps);
+    if (outcaps)
+      gst_caps_unref (outcaps);
   } else {
     /* We must make sure streaming has finished before resetting things
      * and calling the ::stop vfunc */
@@ -2571,8 +2110,6 @@ gst_base_transform_activate (GstBaseTransform * trans, gboolean active)
     }
     gst_caps_replace (&trans->cache_caps1, NULL);
     gst_caps_replace (&trans->cache_caps2, NULL);
-    gst_caps_replace (&trans->priv->sink_alloc, NULL);
-    gst_caps_replace (&trans->priv->sink_suggest, NULL);
 
     if (trans->priv->pad_mode != GST_ACTIVATE_NONE && bclass->stop)
       result &= bclass->stop (trans);
@@ -2866,20 +2403,14 @@ gst_base_transform_set_gap_aware (GstBaseTransform * trans, gboolean gap_aware)
  */
 void
 gst_base_transform_suggest (GstBaseTransform * trans, GstCaps * caps,
-    guint size)
+    gsize size)
 {
   g_return_if_fail (GST_IS_BASE_TRANSFORM (trans));
 
-  GST_OBJECT_LOCK (trans->sinkpad);
-  if (trans->priv->sink_suggest)
-    gst_caps_unref (trans->priv->sink_suggest);
-  if (caps)
-    caps = gst_caps_copy (caps);
-  trans->priv->sink_suggest = caps;
-  trans->priv->size_suggest = size;
-  trans->priv->suggest_pending = TRUE;
-  GST_DEBUG_OBJECT (trans, "new suggest %" GST_PTR_FORMAT, caps);
-  GST_OBJECT_UNLOCK (trans->sinkpad);
+  /* push the renegotiate event */
+  if (!gst_pad_push_event (GST_BASE_TRANSFORM_SINK_PAD (trans),
+          gst_event_new_reconfigure ()))
+    GST_DEBUG_OBJECT (trans, "Renegotiate event wasn't handled");
 }
 
 /**
@@ -2900,6 +2431,5 @@ gst_base_transform_reconfigure (GstBaseTransform * trans)
   GST_OBJECT_LOCK (trans);
   GST_DEBUG_OBJECT (trans, "marking reconfigure");
   trans->priv->reconfigure = TRUE;
-  gst_caps_replace (&trans->priv->sink_alloc, NULL);
   GST_OBJECT_UNLOCK (trans);
 }
index 72c2b2a..40a9833 100644 (file)
@@ -119,16 +119,16 @@ struct _GstBaseTransform {
   gboolean      always_in_place;
 
   GstCaps      *cache_caps1;
-  guint                 cache_caps1_size;
+  gsize                 cache_caps1_size;
   GstCaps      *cache_caps2;
-  guint                 cache_caps2_size;
+  gsize                 cache_caps2_size;
   gboolean      have_same_caps;
 
   gboolean      delay_configure;
   gboolean      pending_configure;
   gboolean      negotiated;
 
-  gboolean       have_newsegment;
+  gboolean       have_segment;
 
   /* MT-protected (with STREAM_LOCK) */
   GstSegment     segment;
@@ -138,7 +138,7 @@ struct _GstBaseTransform {
   /*< private >*/
   GstBaseTransformPrivate *priv;
 
-  gpointer       _gst_reserved[GST_PADDING_LARGE - 1];
+  gpointer       _gst_reserved[GST_PADDING_LARGE];
 };
 
 /**
@@ -200,52 +200,49 @@ struct _GstBaseTransformClass {
   GstElementClass parent_class;
 
   /*< public >*/
-  /* virtual methods for subclasses */
+  gboolean       passthrough_on_same_caps;
 
+  /* virtual methods for subclasses */
   GstCaps*     (*transform_caps) (GstBaseTransform *trans,
                                    GstPadDirection direction,
-                                   GstCaps *caps);
+                                   GstCaps *caps, GstCaps *filter);
 
   void         (*fixate_caps)    (GstBaseTransform *trans,
                                    GstPadDirection direction, GstCaps *caps,
                                    GstCaps *othercaps);
+  gboolean      (*accept_caps)    (GstBaseTransform *trans, GstPadDirection direction,
+                                   GstCaps *caps);
+
+  gboolean      (*set_caps)       (GstBaseTransform *trans, GstCaps *incaps,
+                                   GstCaps *outcaps);
+
 
   gboolean      (*transform_size) (GstBaseTransform *trans,
                                    GstPadDirection direction,
-                                   GstCaps *caps, guint size,
-                                   GstCaps *othercaps, guint *othersize);
+                                   GstCaps *caps, gsize size,
+                                   GstCaps *othercaps, gsize *othersize);
 
   gboolean      (*get_unit_size)  (GstBaseTransform *trans, GstCaps *caps,
-                                   guint *size);
-
-  gboolean      (*set_caps)     (GstBaseTransform *trans, GstCaps *incaps,
-                                 GstCaps *outcaps);
+                                   gsize *size);
 
   gboolean      (*start)        (GstBaseTransform *trans);
   gboolean      (*stop)         (GstBaseTransform *trans);
 
   gboolean      (*event)        (GstBaseTransform *trans, GstEvent *event);
-
-  GstFlowReturn (*transform)    (GstBaseTransform *trans, GstBuffer *inbuf,
-                                 GstBuffer *outbuf);
-  GstFlowReturn (*transform_ip) (GstBaseTransform *trans, GstBuffer *buf);
-
-  /* FIXME: When adjusting the padding, move these to nicer places in the class */
-  gboolean       passthrough_on_same_caps;
+  /* src event */
+  gboolean      (*src_event)    (GstBaseTransform *trans, GstEvent *event);
 
   GstFlowReturn (*prepare_output_buffer) (GstBaseTransform * trans,
      GstBuffer *input, gint size, GstCaps *caps, GstBuffer **buf);
 
-  /* src event */
-  gboolean      (*src_event)      (GstBaseTransform *trans, GstEvent *event);
-
   void          (*before_transform)  (GstBaseTransform *trans, GstBuffer *buffer);
 
-  gboolean      (*accept_caps)  (GstBaseTransform *trans, GstPadDirection direction,
-                                         GstCaps *caps);
+  GstFlowReturn (*transform)    (GstBaseTransform *trans, GstBuffer *inbuf,
+                                 GstBuffer *outbuf);
+  GstFlowReturn (*transform_ip) (GstBaseTransform *trans, GstBuffer *buf);
 
   /*< private >*/
-  gpointer       _gst_reserved[GST_PADDING_LARGE - 3];
+  gpointer       _gst_reserved[GST_PADDING_LARGE];
 };
 
 GType           gst_base_transform_get_type         (void);
@@ -270,7 +267,7 @@ void            gst_base_transform_set_gap_aware    (GstBaseTransform *trans,
                                                      gboolean gap_aware);
 
 void           gst_base_transform_suggest          (GstBaseTransform *trans,
-                                                    GstCaps *caps, guint size);
+                                                    GstCaps *caps, gsize size);
 void           gst_base_transform_reconfigure      (GstBaseTransform *trans);
 G_END_DECLS
 
index a439399..ee369cb 100644 (file)
@@ -61,33 +61,11 @@ gst_bit_reader_new (const guint8 * data, guint size)
 }
 
 /**
- * gst_bit_reader_new_from_buffer:
- * @buffer: Buffer from which the #GstBitReader should read
- *
- * Create a new #GstBitReader instance, which will read from the
- * #GstBuffer @buffer.
- *
- * Free-function: gst_bit_reader_free
- *
- * Returns: (transfer full): a new #GstBitReader instance
- *
- * Since: 0.10.22
- */
-GstBitReader *
-gst_bit_reader_new_from_buffer (const GstBuffer * buffer)
-{
-  g_return_val_if_fail (GST_IS_BUFFER (buffer), NULL);
-
-  return gst_bit_reader_new (GST_BUFFER_DATA (buffer),
-      GST_BUFFER_SIZE (buffer));
-}
-
-/**
  * gst_bit_reader_free:
  * @reader: (in) (transfer full): a #GstBitReader instance
  *
  * Frees a #GstBitReader instance, which was previously allocated by
- * gst_bit_reader_new() or gst_bit_reader_new_from_buffer().
+ * gst_bit_reader_new().
  * 
  * Since: 0.10.22
  */
@@ -121,26 +99,6 @@ gst_bit_reader_init (GstBitReader * reader, const guint8 * data, guint size)
 }
 
 /**
- * gst_bit_reader_init_from_buffer:
- * @reader: a #GstBitReader instance
- * @buffer: (transfer none): Buffer from which the #GstBitReader should read
- *
- * Initializes a #GstBitReader instance to read from @buffer. This function
- * can be called on already initialized instances.
- * 
- * Since: 0.10.22
- */
-void
-gst_bit_reader_init_from_buffer (GstBitReader * reader,
-    const GstBuffer * buffer)
-{
-  g_return_if_fail (GST_IS_BUFFER (buffer));
-
-  gst_bit_reader_init (reader, GST_BUFFER_DATA (buffer),
-      GST_BUFFER_SIZE (buffer));
-}
-
-/**
  * gst_bit_reader_set_pos:
  * @reader: a #GstBitReader instance
  * @pos: The new position in bits
index b5c3935..e42e3bf 100644 (file)
@@ -47,11 +47,9 @@ typedef struct {
 } GstBitReader;
 
 GstBitReader * gst_bit_reader_new (const guint8 *data, guint size);
-GstBitReader * gst_bit_reader_new_from_buffer (const GstBuffer *buffer);
 void gst_bit_reader_free (GstBitReader *reader);
 
 void gst_bit_reader_init (GstBitReader *reader, const guint8 *data, guint size);
-void gst_bit_reader_init_from_buffer (GstBitReader *reader, const GstBuffer *buffer);
 
 gboolean gst_bit_reader_set_pos (GstBitReader *reader, guint pos);
 
@@ -87,19 +85,6 @@ gboolean gst_bit_reader_peek_bits_uint64 (const GstBitReader *reader, guint64 *v
  */
 #define GST_BIT_READER_INIT(data, size) {data, size, 0, 0}
 
-/**
- * GST_BIT_READER_INIT_FROM_BUFFER:
- * @buffer: Buffer from which the #GstBitReader should read
- *
- * A #GstBitReader must be initialized with this macro, before it can be
- * used. This macro can used be to initialize a variable, but it cannot
- * be assigned to a variable. In that case you have to use
- * gst_bit_reader_init().
- *
- * Since: 0.10.22
- */
-#define GST_BIT_READER_INIT_FROM_BUFFER(buffer) {GST_BUFFER_DATA (buffer), GST_BUFFER_SIZE (buffer), 0, 0}
-
 /* Unchecked variants */
 
 static inline void
index e0cc723..97da6ec 100644 (file)
@@ -67,33 +67,11 @@ gst_byte_reader_new (const guint8 * data, guint size)
 }
 
 /**
- * gst_byte_reader_new_from_buffer:
- * @buffer: (transfer none): Buffer from which the #GstByteReader should read
- *
- * Create a new #GstByteReader instance, which will read from the
- * #GstBuffer @buffer.
- *
- * Free-function: gst_byte_reader_free
- *
- * Returns: (transfer full): a new #GstByteReader instance
- *
- * Since: 0.10.22
- */
-GstByteReader *
-gst_byte_reader_new_from_buffer (const GstBuffer * buffer)
-{
-  g_return_val_if_fail (GST_IS_BUFFER (buffer), NULL);
-
-  return gst_byte_reader_new (GST_BUFFER_DATA (buffer),
-      GST_BUFFER_SIZE (buffer));
-}
-
-/**
  * gst_byte_reader_free:
  * @reader: (in) (transfer full): a #GstByteReader instance
  *
  * Frees a #GstByteReader instance, which was previously allocated by
- * gst_byte_reader_new() or gst_byte_reader_new_from_buffer().
+ * gst_byte_reader_new().
  * 
  * Since: 0.10.22
  */
@@ -128,26 +106,6 @@ gst_byte_reader_init (GstByteReader * reader, const guint8 * data, guint size)
 }
 
 /**
- * gst_byte_reader_init_from_buffer:
- * @reader: a #GstByteReader instance
- * @buffer: (transfer none): Buffer from which the #GstByteReader should read
- *
- * Initializes a #GstByteReader instance to read from @buffer. This function
- * can be called on already initialized instances.
- * 
- * Since: 0.10.22
- */
-void
-gst_byte_reader_init_from_buffer (GstByteReader * reader,
-    const GstBuffer * buffer)
-{
-  g_return_if_fail (GST_IS_BUFFER (buffer));
-
-  gst_byte_reader_init (reader, GST_BUFFER_DATA (buffer),
-      GST_BUFFER_SIZE (buffer));
-}
-
-/**
  * gst_byte_reader_set_pos:
  * @reader: a #GstByteReader instance
  * @pos: The new position in bytes
index 8ce76df..9c3c4f4 100644 (file)
@@ -44,11 +44,9 @@ typedef struct {
 } GstByteReader;
 
 GstByteReader * gst_byte_reader_new (const guint8 *data, guint size);
-GstByteReader * gst_byte_reader_new_from_buffer (const GstBuffer *buffer);
 void gst_byte_reader_free (GstByteReader *reader);
 
 void gst_byte_reader_init (GstByteReader *reader, const guint8 *data, guint size);
-void gst_byte_reader_init_from_buffer (GstByteReader *reader, const GstBuffer *buffer);
 
 gboolean gst_byte_reader_set_pos (GstByteReader *reader, guint pos);
 
@@ -154,20 +152,6 @@ guint    gst_byte_reader_masked_scan_uint32 (const GstByteReader * reader,
  */
 #define GST_BYTE_READER_INIT(data, size) {data, size, 0}
 
-/**
- * GST_BYTE_READER_INIT_FROM_BUFFER:
- * @buffer: Buffer from which the #GstByteReader should read
- *
- * A #GstByteReader must be initialized with this macro, before it can be
- * used. This macro can used be to initialize a variable, but it cannot
- * be assigned to a variable. In that case you have to use
- * gst_byte_reader_init().
- *
- * Since: 0.10.22
- */
-#define GST_BYTE_READER_INIT_FROM_BUFFER(buffer) {GST_BUFFER_DATA (buffer), GST_BUFFER_SIZE (buffer), 0}
-
-
 /* unchecked variants */
 static inline void
 gst_byte_reader_skip_unchecked (GstByteReader * reader, guint nbytes)
index 25564f7..969b705 100644 (file)
@@ -116,33 +116,6 @@ gst_byte_writer_new_with_data (guint8 * data, guint size, gboolean initialized)
 }
 
 /**
- * gst_byte_writer_new_with_buffer:
- * @buffer: Buffer used for writing
- * @initialized: If %TRUE the complete data can be read from the beginning
- *
- * Creates a new #GstByteWriter instance with the given
- * buffer. If @initialized is %TRUE it is possible to
- * read the complete buffer from the #GstByteWriter from the beginning.
- *
- * <note>@buffer must be writable</note>
- *
- * Free-function: gst_byte_writer_free
- *
- * Returns: (transfer full): a new #GstByteWriter instance
- *
- * Since: 0.10.26
- */
-GstByteWriter *
-gst_byte_writer_new_with_buffer (GstBuffer * buffer, gboolean initialized)
-{
-  g_return_val_if_fail (GST_IS_BUFFER (buffer)
-      && gst_buffer_is_writable (buffer), NULL);
-
-  return gst_byte_writer_new_with_data (GST_BUFFER_DATA (buffer),
-      GST_BUFFER_SIZE (buffer), initialized);
-}
-
-/**
  * gst_byte_writer_init:
  * @writer: #GstByteWriter instance
  *
@@ -214,30 +187,6 @@ gst_byte_writer_init_with_data (GstByteWriter * writer, guint8 * data,
 }
 
 /**
- * gst_byte_writer_init_with_buffer:
- * @writer: #GstByteWriter instance
- * @buffer: (transfer none): Buffer used for writing
- * @initialized: If %TRUE the complete data can be read from the beginning
- *
- * Initializes @writer with the given
- * buffer. If @initialized is %TRUE it is possible to
- * read the complete buffer from the #GstByteWriter from the beginning.
- *
- * <note>@buffer must be writable</note>
- *
- * Since: 0.10.26
- */
-void
-gst_byte_writer_init_with_buffer (GstByteWriter * writer, GstBuffer * buffer,
-    gboolean initialized)
-{
-  g_return_if_fail (GST_IS_BUFFER (buffer) && gst_buffer_is_writable (buffer));
-
-  gst_byte_writer_init_with_data (writer, GST_BUFFER_DATA (buffer),
-      GST_BUFFER_SIZE (buffer), initialized);
-}
-
-/**
  * gst_byte_writer_reset:
  * @writer: #GstByteWriter instance
  *
@@ -301,13 +250,19 @@ GstBuffer *
 gst_byte_writer_reset_and_get_buffer (GstByteWriter * writer)
 {
   GstBuffer *buffer;
+  gpointer data;
+  gsize size;
 
   g_return_val_if_fail (writer != NULL, NULL);
 
+  size = writer->parent.size;
+  data = gst_byte_writer_reset_and_get_data (writer);
+
   buffer = gst_buffer_new ();
-  GST_BUFFER_SIZE (buffer) = writer->parent.size;
-  GST_BUFFER_MALLOCDATA (buffer) = gst_byte_writer_reset_and_get_data (writer);
-  GST_BUFFER_DATA (buffer) = GST_BUFFER_MALLOCDATA (buffer);
+  if (data != NULL) {
+    gst_buffer_take_memory (buffer, -1,
+        gst_memory_new_wrapped (0, data, g_free, size, 0, size));
+  }
 
   return buffer;
 }
index 8fcd53d..7cc68d2 100644 (file)
@@ -51,12 +51,10 @@ typedef struct {
 GstByteWriter * gst_byte_writer_new (void);
 GstByteWriter * gst_byte_writer_new_with_size (guint size, gboolean fixed);
 GstByteWriter * gst_byte_writer_new_with_data (guint8 *data, guint size, gboolean initialized);
-GstByteWriter * gst_byte_writer_new_with_buffer (GstBuffer *buffer, gboolean initialized);
 
 void gst_byte_writer_init (GstByteWriter *writer);
 void gst_byte_writer_init_with_size (GstByteWriter *writer, guint size, gboolean fixed);
 void gst_byte_writer_init_with_data (GstByteWriter *writer, guint8 *data, guint size, gboolean initialized);
-void gst_byte_writer_init_with_buffer (GstByteWriter *writer, GstBuffer *buffer, gboolean initialized);
 
 void gst_byte_writer_free (GstByteWriter *writer);
 guint8 * gst_byte_writer_free_and_get_data (GstByteWriter *writer);
index 004508d..fccb52c 100644 (file)
@@ -86,7 +86,8 @@ struct _GstCollectPadsPrivate
   gpointer clipfunc_user_data;
 };
 
-GST_BOILERPLATE (GstCollectPads, gst_collect_pads, GstObject, GST_TYPE_OBJECT);
+#define gst_collect_pads_parent_class parent_class
+G_DEFINE_TYPE (GstCollectPads, gst_collect_pads, GST_TYPE_OBJECT);
 
 static void gst_collect_pads_clear (GstCollectPads * pads,
     GstCollectData * data);
@@ -98,12 +99,6 @@ static void unref_data (GstCollectData * data);
 static void gst_collect_pads_check_pads_unlocked (GstCollectPads * pads);
 
 static void
-gst_collect_pads_base_init (gpointer g_class)
-{
-  /* Do nothing here */
-}
-
-static void
 gst_collect_pads_class_init (GstCollectPadsClass * klass)
 {
   GObjectClass *gobject_class = (GObjectClass *) klass;
@@ -117,7 +112,7 @@ gst_collect_pads_class_init (GstCollectPadsClass * klass)
 }
 
 static void
-gst_collect_pads_init (GstCollectPads * pads, GstCollectPadsClass * g_class)
+gst_collect_pads_init (GstCollectPads * pads)
 {
   pads->abidata.ABI.priv = GST_COLLECT_PADS_GET_PRIVATE (pads);
 
@@ -861,7 +856,7 @@ gst_collect_pads_available (GstCollectPads * pads)
     }
 
     /* this is the size left of the buffer */
-    size = GST_BUFFER_SIZE (buffer) - pdata->pos;
+    size = gst_buffer_get_size (buffer) - pdata->pos;
     GST_DEBUG ("pad %s:%s has %d bytes left",
         GST_DEBUG_PAD_NAME (pdata->pad), size);
 
@@ -882,48 +877,6 @@ not_filled:
 }
 
 /**
- * gst_collect_pads_read:
- * @pads: the collectspads to query
- * @data: the data to use
- * @bytes: (out) (transfer none) (array length=size): a pointer to a byte array
- * @size: the number of bytes to read
- *
- * Get a pointer in @bytes where @size bytes can be read from the
- * given pad @data.
- *
- * This function should be called with @pads LOCK held, such as
- * in the callback.
- *
- * MT safe.
- *
- * Returns: The number of bytes available for consumption in the
- * memory pointed to by @bytes. This can be less than @size and
- * is 0 if the pad is end-of-stream.
- */
-guint
-gst_collect_pads_read (GstCollectPads * pads, GstCollectData * data,
-    guint8 ** bytes, guint size)
-{
-  guint readsize;
-  GstBuffer *buffer;
-
-  g_return_val_if_fail (pads != NULL, 0);
-  g_return_val_if_fail (GST_IS_COLLECT_PADS (pads), 0);
-  g_return_val_if_fail (data != NULL, 0);
-  g_return_val_if_fail (bytes != NULL, 0);
-
-  /* no buffer, must be EOS */
-  if ((buffer = data->buffer) == NULL)
-    return 0;
-
-  readsize = MIN (size, GST_BUFFER_SIZE (buffer) - data->pos);
-
-  *bytes = GST_BUFFER_DATA (buffer) + data->pos;
-
-  return readsize;
-}
-
-/**
  * gst_collect_pads_read_buffer:
  * @pads: the collectspads to query
  * @data: the data to use
@@ -958,14 +911,15 @@ gst_collect_pads_read_buffer (GstCollectPads * pads, GstCollectData * data,
   if ((buffer = data->buffer) == NULL)
     return NULL;
 
-  bufsize = GST_BUFFER_SIZE (buffer);
+  bufsize = gst_buffer_get_size (buffer);
 
   readsize = MIN (size, bufsize - data->pos);
 
   if (data->pos == 0 && readsize == bufsize)
     return gst_buffer_ref (buffer);
   else
-    return gst_buffer_create_sub (buffer, data->pos, readsize);
+    return gst_buffer_copy_region (buffer, GST_BUFFER_COPY_ALL, data->pos,
+        readsize);
 }
 
 /**
@@ -996,7 +950,7 @@ gst_collect_pads_take_buffer (GstCollectPads * pads, GstCollectData * data,
   GstBuffer *buffer = gst_collect_pads_read_buffer (pads, data, size);
 
   if (buffer) {
-    gst_collect_pads_flush (pads, data, GST_BUFFER_SIZE (buffer));
+    gst_collect_pads_flush (pads, data, gst_buffer_get_size (buffer));
   }
   return buffer;
 }
@@ -1023,6 +977,7 @@ gst_collect_pads_flush (GstCollectPads * pads, GstCollectData * data,
 {
   guint flushsize;
   GstBuffer *buffer;
+  gsize bsize;
 
   g_return_val_if_fail (pads != NULL, 0);
   g_return_val_if_fail (GST_IS_COLLECT_PADS (pads), 0);
@@ -1032,14 +987,16 @@ gst_collect_pads_flush (GstCollectPads * pads, GstCollectData * data,
   if ((buffer = data->buffer) == NULL)
     return 0;
 
+  bsize = gst_buffer_get_size (buffer);
+
   /* this is what we can flush at max */
-  flushsize = MIN (size, GST_BUFFER_SIZE (buffer) - data->pos);
+  flushsize = MIN (size, bsize - data->pos);
 
   data->pos += size;
 
   GST_LOG_OBJECT (pads, "Flushing %d bytes, requested %u", flushsize, size);
 
-  if (data->pos >= GST_BUFFER_SIZE (buffer))
+  if (data->pos >= bsize)
     /* _clear will also reset data->pos to 0 */
     gst_collect_pads_clear (pads, data);
 
@@ -1241,23 +1198,12 @@ gst_collect_pads_event (GstPad * pad, GstEvent * event)
       gst_event_unref (event);
       goto done;
     }
-    case GST_EVENT_NEWSEGMENT:
+    case GST_EVENT_SEGMENT:
     {
-      gint64 start, stop, time;
-      gdouble rate, arate;
-      GstFormat format;
-      gboolean update;
-
-      gst_event_parse_new_segment_full (event, &update, &rate, &arate, &format,
-          &start, &stop, &time);
-
-      GST_DEBUG_OBJECT (data->pad, "got newsegment, start %" GST_TIME_FORMAT
-          ", stop %" GST_TIME_FORMAT, GST_TIME_ARGS (start),
-          GST_TIME_ARGS (stop));
-
-      gst_segment_set_newsegment_full (&data->segment, update, rate, arate,
-          format, start, stop, time);
+      gst_event_copy_segment (event, &data->segment);
 
+      GST_DEBUG_OBJECT (data->pad, "got newsegment %" GST_SEGMENT_FORMAT,
+          &data->segment);
       data->abidata.ABI.new_segment = TRUE;
 
       /* we must not forward this event since multiple segments will be
@@ -1360,7 +1306,7 @@ gst_collect_pads_chain (GstPad * pad, GstBuffer * buffer)
     GstClockTime timestamp = GST_BUFFER_TIMESTAMP (data->buffer);
 
     if (GST_CLOCK_TIME_IS_VALID (timestamp))
-      gst_segment_set_last_stop (&data->segment, GST_FORMAT_TIME, timestamp);
+      data->segment.position = timestamp;
   }
 
   /* While we have data queued on this pad try to collect stuff */
index 939c2f6..ba6761e 100644 (file)
@@ -209,8 +209,6 @@ GstBuffer*      gst_collect_pads_pop            (GstCollectPads *pads, GstCollec
 
 /* get collected bytes */
 guint           gst_collect_pads_available      (GstCollectPads *pads);
-guint           gst_collect_pads_read           (GstCollectPads *pads, GstCollectData *data,
-                                                 guint8 **bytes, guint size);
 GstBuffer *     gst_collect_pads_read_buffer    (GstCollectPads * pads, GstCollectData * data,
                                                  guint size);
 GstBuffer *     gst_collect_pads_take_buffer    (GstCollectPads * pads, GstCollectData * data,
index f6b1117..69dadb4 100644 (file)
@@ -277,7 +277,7 @@ gst_data_queue_locked_flush (GstDataQueue * queue)
   gst_data_queue_cleanup (queue);
   STATUS (queue, "after flushing");
   /* we deleted something... */
-  if (queue->abidata.ABI.waiting_del)
+  if (queue->waiting_del)
     g_cond_signal (queue->item_del);
 }
 
@@ -384,9 +384,9 @@ gst_data_queue_set_flushing (GstDataQueue * queue, gboolean flushing)
   queue->flushing = flushing;
   if (flushing) {
     /* release push/pop functions */
-    if (queue->abidata.ABI.waiting_add)
+    if (queue->waiting_add)
       g_cond_signal (queue->item_add);
-    if (queue->abidata.ABI.waiting_del)
+    if (queue->waiting_del)
       g_cond_signal (queue->item_del);
   }
   GST_DATA_QUEUE_MUTEX_UNLOCK (queue);
@@ -432,9 +432,9 @@ gst_data_queue_push (GstDataQueue * queue, GstDataQueueItem * item)
 
     /* signal might have removed some items */
     while (gst_data_queue_locked_is_full (queue)) {
-      queue->abidata.ABI.waiting_del = TRUE;
+      queue->waiting_del = TRUE;
       g_cond_wait (queue->item_del, queue->qlock);
-      queue->abidata.ABI.waiting_del = FALSE;
+      queue->waiting_del = FALSE;
       if (queue->flushing)
         goto flushing;
     }
@@ -448,7 +448,7 @@ gst_data_queue_push (GstDataQueue * queue, GstDataQueueItem * item)
   queue->cur_level.time += item->duration;
 
   STATUS (queue, "after pushing");
-  if (queue->abidata.ABI.waiting_add)
+  if (queue->waiting_add)
     g_cond_signal (queue->item_add);
 
   GST_DATA_QUEUE_MUTEX_UNLOCK (queue);
@@ -497,9 +497,9 @@ gst_data_queue_pop (GstDataQueue * queue, GstDataQueueItem ** item)
     GST_DATA_QUEUE_MUTEX_LOCK_CHECK (queue, flushing);
 
     while (gst_data_queue_locked_is_empty (queue)) {
-      queue->abidata.ABI.waiting_add = TRUE;
+      queue->waiting_add = TRUE;
       g_cond_wait (queue->item_add, queue->qlock);
-      queue->abidata.ABI.waiting_add = FALSE;
+      queue->waiting_add = FALSE;
       if (queue->flushing)
         goto flushing;
     }
@@ -515,7 +515,7 @@ gst_data_queue_pop (GstDataQueue * queue, GstDataQueueItem ** item)
   queue->cur_level.time -= (*item)->duration;
 
   STATUS (queue, "after popping");
-  if (queue->abidata.ABI.waiting_del)
+  if (queue->waiting_del)
     g_cond_signal (queue->item_del);
 
   GST_DATA_QUEUE_MUTEX_UNLOCK (queue);
@@ -600,7 +600,7 @@ gst_data_queue_limits_changed (GstDataQueue * queue)
   g_return_if_fail (GST_IS_DATA_QUEUE (queue));
 
   GST_DATA_QUEUE_MUTEX_LOCK (queue);
-  if (queue->abidata.ABI.waiting_del) {
+  if (queue->waiting_del) {
     GST_DEBUG ("signal del");
     g_cond_signal (queue->item_del);
   }
index d38230b..4ab42ff 100644 (file)
@@ -128,20 +128,16 @@ struct _GstDataQueue
   gpointer *checkdata;
 
   GMutex *qlock;                /* lock for queue (vs object lock) */
+  gboolean waiting_add;
   GCond *item_add;              /* signals buffers now available for reading */
+  gboolean waiting_del;
   GCond *item_del;              /* signals space now available for writing */
   gboolean flushing;            /* indicates whether conditions where signalled because
                                  * of external flushing */
   GstDataQueueFullCallback fullcallback;
   GstDataQueueEmptyCallback emptycallback;
 
-  union {
-    struct {
-      gboolean waiting_add;
-      gboolean waiting_del;
-    } ABI;
-    gpointer _gst_reserved[GST_PADDING - 2];
-  } abidata;
+  gpointer _gst_reserved[GST_PADDING];
 };
 
 struct _GstDataQueueClass
index 4201e3a..6faec86 100644 (file)
@@ -36,8 +36,8 @@
  * in a push based mode. If the peer accepts to operate without
  * offsets and within the limits of the allowed block size, this
  * class can operate in getrange based mode automatically. To make
- * this possible, the subclass should override the ::check_get_range
- * method.
+ * this possible, the subclass should implement and override the
+ * SCHEDULING query.
  *
  * The subclass should extend the methods from the baseclass in
  * addition to the ::create method.
 GST_DEBUG_CATEGORY_STATIC (gst_push_src_debug);
 #define GST_CAT_DEFAULT gst_push_src_debug
 
-#define _do_init(type) \
+#define _do_init \
     GST_DEBUG_CATEGORY_INIT (gst_push_src_debug, "pushsrc", 0, \
         "pushsrc element");
 
-GST_BOILERPLATE_FULL (GstPushSrc, gst_push_src, GstBaseSrc, GST_TYPE_BASE_SRC,
-    _do_init);
+#define gst_push_src_parent_class parent_class
+G_DEFINE_TYPE_WITH_CODE (GstPushSrc, gst_push_src, GST_TYPE_BASE_SRC, _do_init);
 
-static gboolean gst_push_src_check_get_range (GstBaseSrc * src);
+static gboolean gst_push_src_query (GstBaseSrc * src, GstQuery * query);
 static GstFlowReturn gst_push_src_create (GstBaseSrc * bsrc, guint64 offset,
     guint length, GstBuffer ** ret);
-
-static void
-gst_push_src_base_init (gpointer g_class)
-{
-  /* nop */
-}
+static GstFlowReturn gst_push_src_fill (GstBaseSrc * bsrc, guint64 offset,
+    guint length, GstBuffer * ret);
 
 static void
 gst_push_src_class_init (GstPushSrcClass * klass)
@@ -85,24 +81,38 @@ gst_push_src_class_init (GstPushSrcClass * klass)
   GstBaseSrcClass *gstbasesrc_class = (GstBaseSrcClass *) klass;
 
   gstbasesrc_class->create = GST_DEBUG_FUNCPTR (gst_push_src_create);
-  gstbasesrc_class->check_get_range =
-      GST_DEBUG_FUNCPTR (gst_push_src_check_get_range);
+  gstbasesrc_class->fill = GST_DEBUG_FUNCPTR (gst_push_src_fill);
+  gstbasesrc_class->query = GST_DEBUG_FUNCPTR (gst_push_src_query);
 }
 
 static void
-gst_push_src_init (GstPushSrc * pushsrc, GstPushSrcClass * klass)
+gst_push_src_init (GstPushSrc * pushsrc)
 {
   /* nop */
 }
 
 static gboolean
-gst_push_src_check_get_range (GstBaseSrc * src)
+gst_push_src_query (GstBaseSrc * src, GstQuery * query)
 {
-  /* a pushsrc can by default never operate in pull mode override
-   * if you want something different. */
-  return FALSE;
+  gboolean ret;
+
+  switch (GST_QUERY_TYPE (query)) {
+    case GST_QUERY_SCHEDULING:
+    {
+      /* a pushsrc can by default never operate in pull mode override
+       * if you want something different. */
+      gst_query_set_scheduling (query, FALSE, FALSE, TRUE, 1, -1, 1);
+      ret = TRUE;
+      break;
+    }
+    default:
+      ret = GST_BASE_SRC_CLASS (parent_class)->query (src, query);
+      break;
+  }
+  return ret;
 }
 
+
 static GstFlowReturn
 gst_push_src_create (GstBaseSrc * bsrc, guint64 offset, guint length,
     GstBuffer ** ret)
@@ -116,7 +126,26 @@ gst_push_src_create (GstBaseSrc * bsrc, guint64 offset, guint length,
   if (pclass->create)
     fret = pclass->create (src, ret);
   else
-    fret = GST_FLOW_ERROR;
+    fret =
+        GST_BASE_SRC_CLASS (parent_class)->create (bsrc, offset, length, ret);
+
+  return fret;
+}
+
+static GstFlowReturn
+gst_push_src_fill (GstBaseSrc * bsrc, guint64 offset, guint length,
+    GstBuffer * ret)
+{
+  GstFlowReturn fret;
+  GstPushSrc *src;
+  GstPushSrcClass *pclass;
+
+  src = GST_PUSH_SRC (bsrc);
+  pclass = GST_PUSH_SRC_GET_CLASS (src);
+  if (pclass->fill)
+    fret = pclass->fill (src, ret);
+  else
+    fret = GST_BASE_SRC_CLASS (parent_class)->fill (bsrc, offset, length, ret);
 
   return fret;
 }
index 49786d5..e48ffb1 100644 (file)
@@ -57,6 +57,9 @@ struct _GstPushSrcClass {
   /* ask the subclass to create a buffer */
   GstFlowReturn (*create) (GstPushSrc *src, GstBuffer **buf);
 
+  /* ask the subclass to fill a buffer */
+  GstFlowReturn (*fill) (GstPushSrc *src, GstBuffer *buf);
+
   /*< private >*/
   gpointer _gst_reserved[GST_PADDING];
 };
index 8695b92..1f2c01a 100644 (file)
@@ -70,21 +70,23 @@ typedef struct
  * Returns: address of the data or %NULL if buffer does not cover the
  * requested range.
  */
-static guint8 *
+static const guint8 *
 helper_find_peek (gpointer data, gint64 offset, guint size)
 {
   GstTypeFindHelper *helper;
   GstBuffer *buffer;
   GstFlowReturn ret;
   GSList *insert_pos = NULL;
-  guint buf_size;
+  gsize buf_size;
   guint64 buf_offset;
+#if 0
   GstCaps *caps;
+#endif
 
   helper = (GstTypeFindHelper *) data;
 
   GST_LOG_OBJECT (helper->obj, "'%s' called peek (%" G_GINT64_FORMAT
-      ", %u)", GST_PLUGIN_FEATURE_NAME (helper->factory), offset, size);
+      ", %u)", GST_OBJECT_NAME (helper->factory), offset, size);
 
   if (size == 0)
     return NULL;
@@ -103,14 +105,19 @@ helper_find_peek (gpointer data, gint64 offset, guint size)
     for (walk = helper->buffers; walk; walk = walk->next) {
       GstBuffer *buf = GST_BUFFER_CAST (walk->data);
       guint64 buf_offset = GST_BUFFER_OFFSET (buf);
-      guint buf_size = GST_BUFFER_SIZE (buf);
+      guint buf_size = gst_buffer_get_size (buf);
 
       /* buffers are kept sorted by end offset (highest first) in the list, so
        * at this point we save the current position and stop searching if 
        * we're after the searched end offset */
       if (buf_offset <= offset) {
         if ((offset + size) < (buf_offset + buf_size)) {
-          return GST_BUFFER_DATA (buf) + (offset - buf_offset);
+          guint8 *data;
+
+          /* FIXME, unmap after usage */
+          data = gst_buffer_map (buf, NULL, NULL, GST_MAP_READ);
+
+          return data + (offset - buf_offset);
         }
       } else if (offset + size >= buf_offset + buf_size) {
         insert_pos = walk;
@@ -131,6 +138,7 @@ helper_find_peek (gpointer data, gint64 offset, guint size)
   if (ret != GST_FLOW_OK)
     goto error;
 
+#if 0
   caps = GST_BUFFER_CAPS (buffer);
 
   if (caps && !gst_caps_is_empty (caps) && !gst_caps_is_any (caps)) {
@@ -143,11 +151,12 @@ helper_find_peek (gpointer data, gint64 offset, guint size)
     gst_buffer_unref (buffer);
     return NULL;
   }
+#endif
 
   /* getrange might silently return shortened buffers at the end of a file,
    * we must, however, always return either the full requested data or NULL */
   buf_offset = GST_BUFFER_OFFSET (buffer);
-  buf_size = GST_BUFFER_SIZE (buffer);
+  buf_size = gst_buffer_get_size (buffer);
 
   if ((buf_offset != -1 && buf_offset != offset) || buf_size < size) {
     GST_DEBUG ("droping short buffer: %" G_GUINT64_FORMAT "-%" G_GUINT64_FORMAT
@@ -164,10 +173,12 @@ helper_find_peek (gpointer data, gint64 offset, guint size)
     /* if insert_pos is not set, our offset is bigger than the largest offset
      * we have so far; since we keep the list sorted with highest offsets
      * first, we need to prepend the buffer to the list */
-    helper->last_offset = GST_BUFFER_OFFSET (buffer) + GST_BUFFER_SIZE (buffer);
+    helper->last_offset = GST_BUFFER_OFFSET (buffer) + buf_size;
     helper->buffers = g_slist_prepend (helper->buffers, buffer);
   }
-  return GST_BUFFER_DATA (buffer);
+
+  /* FIXME, unmap */
+  return gst_buffer_map (buffer, NULL, NULL, GST_MAP_READ);
 
 error:
   {
@@ -191,7 +202,7 @@ helper_find_suggest (gpointer data, guint probability, const GstCaps * caps)
 
   GST_LOG_OBJECT (helper->obj,
       "'%s' called called suggest (%u, %" GST_PTR_FORMAT ")",
-      GST_PLUGIN_FEATURE_NAME (helper->factory), probability, caps);
+      GST_OBJECT_NAME (helper->factory), probability, caps);
 
   if (probability > helper->best_probability) {
     GstCaps *copy = gst_caps_copy (caps);
@@ -208,8 +219,7 @@ helper_find_get_length (gpointer data)
   GstTypeFindHelper *helper = (GstTypeFindHelper *) data;
 
   GST_LOG_OBJECT (helper->obj, "'%s' called called get_length, returning %"
-      G_GUINT64_FORMAT, GST_PLUGIN_FEATURE_NAME (helper->factory),
-      helper->size);
+      G_GUINT64_FORMAT, GST_OBJECT_NAME (helper->factory), helper->size);
 
   return helper->size;
 }
@@ -302,7 +312,7 @@ gst_type_find_helper_get_range_ext (GstObject * obj,
         continue;
 
       GST_LOG_OBJECT (obj, "testing factory %s for extension %s",
-          GST_PLUGIN_FEATURE_NAME (factory), extension);
+          GST_OBJECT_NAME (factory), extension);
 
       for (i = 0; ext[i]; i++) {
         if (strcmp (ext[i], extension) == 0) {
@@ -406,8 +416,8 @@ gst_type_find_helper (GstPad * src, guint64 size)
 
 typedef struct
 {
-  guint8 *data;                 /* buffer data */
-  guint size;
+  const guint8 *data;           /* buffer data */
+  gsize size;
   guint best_probability;
   GstCaps *caps;
   GstTypeFindFactory *factory;  /* for logging */
@@ -425,21 +435,21 @@ typedef struct
  * Returns: address inside the buffer or %NULL if buffer does not cover the
  * requested range.
  */
-static guint8 *
+static const guint8 *
 buf_helper_find_peek (gpointer data, gint64 off, guint size)
 {
   GstTypeFindBufHelper *helper;
 
   helper = (GstTypeFindBufHelper *) data;
   GST_LOG_OBJECT (helper->obj, "'%s' called peek (%" G_GINT64_FORMAT ", %u)",
-      GST_PLUGIN_FEATURE_NAME (helper->factory), off, size);
+      GST_OBJECT_NAME (helper->factory), off, size);
 
   if (size == 0)
     return NULL;
 
   if (off < 0) {
     GST_LOG_OBJECT (helper->obj, "'%s' wanted to peek at end; not supported",
-        GST_PLUGIN_FEATURE_NAME (helper->factory));
+        GST_OBJECT_NAME (helper->factory));
     return NULL;
   }
 
@@ -464,7 +474,7 @@ buf_helper_find_suggest (gpointer data, guint probability, const GstCaps * caps)
 
   GST_LOG_OBJECT (helper->obj,
       "'%s' called called suggest (%u, %" GST_PTR_FORMAT ")",
-      GST_PLUGIN_FEATURE_NAME (helper->factory), probability, caps);
+      GST_OBJECT_NAME (helper->factory), probability, caps);
 
   /* Note: not >= as we call typefinders in order of rank, highest first */
   if (probability > helper->best_probability) {
@@ -477,14 +487,15 @@ buf_helper_find_suggest (gpointer data, guint probability, const GstCaps * caps)
 }
 
 /**
- * gst_type_find_helper_for_buffer:
+ * gst_type_find_helper_for_data:
  * @obj: object doing the typefinding, or NULL (used for logging)
- * @buf: (in) (transfer none): a #GstBuffer with data to typefind
+ * @data: (in) (transfer none): a pointer with data to typefind
+ * @size: (in) (transfer none): the size of @data
  * @prob: (out) (allow-none): location to store the probability of the found
  *     caps, or #NULL
  *
- * Tries to find what type of data is contained in the given #GstBuffer, the
- * assumption being that the buffer represents the beginning of the stream or
+ * Tries to find what type of data is contained in the given @data, the
+ * assumption being that the data represents the beginning of the stream or
  * file.
  *
  * All available typefinders will be called on the data in order of rank. If
@@ -492,7 +503,7 @@ buf_helper_find_suggest (gpointer data, guint probability, const GstCaps * caps)
  * typefinding is stopped immediately and the found caps will be returned
  * right away. Otherwise, all available typefind functions will the tried,
  * and the caps with the highest probability will be returned, or #NULL if
- * the content of the buffer could not be identified.
+ * the content of @data could not be identified.
  *
  * Free-function: gst_caps_unref
  *
@@ -501,7 +512,7 @@ buf_helper_find_suggest (gpointer data, guint probability, const GstCaps * caps)
  *     with gst_caps_unref().
  */
 GstCaps *
-gst_type_find_helper_for_buffer (GstObject * obj, GstBuffer * buf,
+gst_type_find_helper_for_data (GstObject * obj, const guint8 * data, gsize size,
     GstTypeFindProbability * prob)
 {
   GstTypeFindBufHelper helper;
@@ -509,13 +520,10 @@ gst_type_find_helper_for_buffer (GstObject * obj, GstBuffer * buf,
   GList *l, *type_list;
   GstCaps *result = NULL;
 
-  g_return_val_if_fail (buf != NULL, NULL);
-  g_return_val_if_fail (GST_IS_BUFFER (buf), NULL);
-  g_return_val_if_fail (GST_BUFFER_OFFSET (buf) == 0 ||
-      GST_BUFFER_OFFSET (buf) == GST_BUFFER_OFFSET_NONE, NULL);
+  g_return_val_if_fail (data != NULL, NULL);
 
-  helper.data = GST_BUFFER_DATA (buf);
-  helper.size = GST_BUFFER_SIZE (buf);
+  helper.data = data;
+  helper.size = size;
   helper.best_probability = 0;
   helper.caps = NULL;
   helper.obj = obj;
@@ -551,6 +559,50 @@ gst_type_find_helper_for_buffer (GstObject * obj, GstBuffer * buf,
 }
 
 /**
+ * gst_type_find_helper_for_buffer:
+ * @obj: object doing the typefinding, or NULL (used for logging)
+ * @buf: (in) (transfer none): a #GstBuffer with data to typefind
+ * @prob: (out) (allow-none): location to store the probability of the found
+ *     caps, or #NULL
+ *
+ * Tries to find what type of data is contained in the given #GstBuffer, the
+ * assumption being that the buffer represents the beginning of the stream or
+ * file.
+ *
+ * All available typefinders will be called on the data in order of rank. If
+ * a typefinding function returns a probability of #GST_TYPE_FIND_MAXIMUM,
+ * typefinding is stopped immediately and the found caps will be returned
+ * right away. Otherwise, all available typefind functions will the tried,
+ * and the caps with the highest probability will be returned, or #NULL if
+ * the content of the buffer could not be identified.
+ *
+ * Free-function: gst_caps_unref
+ *
+ * Returns: (transfer full): the #GstCaps corresponding to the data, or #NULL
+ *     if no type could be found. The caller should free the caps returned
+ *     with gst_caps_unref().
+ */
+GstCaps *
+gst_type_find_helper_for_buffer (GstObject * obj, GstBuffer * buf,
+    GstTypeFindProbability * prob)
+{
+  GstCaps *result;
+  guint8 *data;
+  gsize size;
+
+  g_return_val_if_fail (buf != NULL, NULL);
+  g_return_val_if_fail (GST_IS_BUFFER (buf), NULL);
+  g_return_val_if_fail (GST_BUFFER_OFFSET (buf) == 0 ||
+      GST_BUFFER_OFFSET (buf) == GST_BUFFER_OFFSET_NONE, NULL);
+
+  data = gst_buffer_map (buf, &size, NULL, GST_MAP_READ);
+  result = gst_type_find_helper_for_data (obj, data, size, prob);
+  gst_buffer_unmap (buf, data, size);
+
+  return result;
+}
+
+/**
  * gst_type_find_helper_for_extension:
  * @obj: (allow-none): object doing the typefinding, or NULL (used for logging)
  * @extension: an extension
index b6ad517..052bc19 100644 (file)
@@ -30,6 +30,10 @@ G_BEGIN_DECLS
 
 GstCaps * gst_type_find_helper (GstPad *src, guint64 size);
 
+GstCaps * gst_type_find_helper_for_data   (GstObject              *obj,
+                                           const guint8           *data,
+                                           gsize                   size,
+                                           GstTypeFindProbability *prob);
 GstCaps * gst_type_find_helper_for_buffer (GstObject              *obj,
                                            GstBuffer              *buf,
                                            GstTypeFindProbability *prob);
index 8dcf66d..96acc4c 100644 (file)
@@ -67,6 +67,7 @@ LIBGSTCHECK_EXPORTED_FUNCS = \
        gst_buffer_straw_stop_pipeline \
        gst_check_abi_list \
        gst_check_caps_equal \
+       gst_check_buffer_data \
        gst_check_chain_func \
        gst_check_drop_buffers \
        gst_check_element_push_buffer \
@@ -127,12 +128,12 @@ GstCheck-@GST_MAJORMINOR@.gir: $(INTROSPECTION_SCANNER) libgstcheck-@GST_MAJORMI
                $(gir_cincludes) \
                --add-include-path=$(top_builddir)/gst \
                --library-path=$(top_builddir)/gst \
-               --library=$(top_builddir)/gst/libgstreamer-0.10.la \
-               --library=libgstcheck-0.10.la \
-               --include=Gst-0.10 \
+               --library=$(top_builddir)/gst/libgstreamer-0.11.la \
+               --library=libgstcheck-0.11.la \
+               --include=Gst-0.11 \
                --libtool="$(top_builddir)/libtool" \
-               --pkg gstreamer-0.10 \
-               --pkg-export gstreamer-check-0.10 \
+               --pkg gstreamer-@GST_MAJORMINOR@ \
+               --pkg-export gstreamer-check-@GST_MAJORMINOR@ \
                --add-init-section="gst_init(NULL,NULL);" \
                --output $@ \
                $(gir_headers) \
index 1089ed9..71504ff 100644 (file)
@@ -38,7 +38,8 @@ static gulong id;
 /* called for every buffer.  Waits until the global "buf" variable is unset,
  * then sets it to the buffer received, and signals. */
 static gboolean
-buffer_probe (GstPad * pad, GstBuffer * buffer, gpointer unused)
+buffer_probe (GstPad * pad, GstProbeType type, GstBuffer * buffer,
+    gpointer unused)
 {
   g_mutex_lock (lock);
 
@@ -81,7 +82,8 @@ gst_buffer_straw_start_pipeline (GstElement * bin, GstPad * pad)
 {
   GstStateChangeReturn ret;
 
-  id = gst_pad_add_buffer_probe (pad, G_CALLBACK (buffer_probe), NULL);
+  id = gst_pad_add_probe (pad, GST_PROBE_TYPE_BUFFER,
+      (GstPadProbeCallback) buffer_probe, NULL, NULL);
 
   cond = g_cond_new ();
   lock = g_mutex_new ();
@@ -149,7 +151,7 @@ gst_buffer_straw_stop_pipeline (GstElement * bin, GstPad * pad)
   if (buf)
     gst_buffer_unref (buf);
   buf = NULL;
-  gst_pad_remove_buffer_probe (pad, (guint) id);
+  gst_pad_remove_probe (pad, (guint) id);
   id = 0;
   g_cond_signal (cond);
   g_mutex_unlock (lock);
index c4370a3..1a95f8f 100644 (file)
@@ -207,7 +207,8 @@ gst_check_setup_src_pad (GstElement * element,
 
   srcpad = gst_check_setup_src_pad_by_name (element, tmpl, "sink");
   if (caps)
-    fail_unless (gst_pad_set_caps (srcpad, caps), "could not set caps on pad");
+    fail_unless (gst_pad_push_event (srcpad, gst_event_new_caps (caps)),
+        "could not set caps on pad");
   return srcpad;
 }
 
@@ -255,9 +256,6 @@ gst_check_teardown_pad_by_name (GstElement * element, const gchar * name)
       gst_pad_unlink (pad_peer, pad_element);
     else
       gst_pad_unlink (pad_element, pad_peer);
-
-    /* caps could have been set, make sure they get unset */
-    gst_pad_set_caps (pad_peer, NULL);
   }
 
   /* pad refs held by both creator and this function (through _get) */
@@ -289,7 +287,8 @@ gst_check_setup_sink_pad (GstElement * element, GstStaticPadTemplate * tmpl,
 
   sinkpad = gst_check_setup_sink_pad_by_name (element, tmpl, "src");
   if (caps)
-    fail_unless (gst_pad_set_caps (sinkpad, caps), "Could not set pad caps");
+    fail_unless (gst_pad_send_event (sinkpad, gst_event_new_caps (caps)),
+        "Could not set pad caps");
   return sinkpad;
 }
 
@@ -366,6 +365,26 @@ gst_check_caps_equal (GstCaps * caps1, GstCaps * caps2)
   g_free (name2);
 }
 
+
+/**
+ * gst_check_buffer_data:
+ * @buffer: buffer to compare
+ * @data: data to compare to
+ * @size: size of data to compare
+ *
+ * Compare the buffer contents with @data and @size.
+ */
+void
+gst_check_buffer_data (GstBuffer * buffer, gconstpointer data, gsize size)
+{
+  guint8 *bdata;
+  gsize bsize;
+
+  bdata = gst_buffer_map (buffer, &bsize, NULL, GST_MAP_READ);
+  fail_unless (memcmp (bdata, data, size) == 0, "buffer contents not equal");
+  gst_buffer_unmap (buffer, bdata, bsize);
+}
+
 /**
  * gst_check_element_push_buffer_list:
  * @element_name: name of the element that needs to be created
@@ -389,8 +408,10 @@ void
 gst_check_element_push_buffer_list (const gchar * element_name,
     GList * buffer_in, GList * buffer_out, GstFlowReturn last_flow_return)
 {
+#if 0
   GstCaps *sink_caps;
   GstCaps *src_caps = NULL;
+#endif
   GstElement *element;
   GstPad *pad_peer;
   GstPad *sink_pad = NULL;
@@ -407,9 +428,13 @@ gst_check_element_push_buffer_list (const gchar * element_name,
   buffer = GST_BUFFER (buffer_in->data);
 
   fail_unless (GST_IS_BUFFER (buffer), "There should be a buffer in buffer_in");
+#if 0
   src_caps = GST_BUFFER_CAPS (buffer);
+#endif
   src_pad = gst_pad_new (NULL, GST_PAD_SRC);
+#if 0
   gst_pad_set_caps (src_pad, src_caps);
+#endif
   pad_peer = gst_element_get_static_pad (element, "sink");
   fail_if (pad_peer == NULL);
   fail_unless (gst_pad_link (src_pad, pad_peer) == GST_PAD_LINK_OK,
@@ -420,10 +445,13 @@ gst_check_element_push_buffer_list (const gchar * element_name,
   GST_DEBUG ("src pad activated");
   /* don't create the sink_pad if there is no buffer_out list */
   if (buffer_out != NULL) {
+#if 0
     gchar *temp;
+#endif
 
     GST_DEBUG ("buffer out detected, creating the sink pad");
     /* get the sink caps */
+#if 0
     sink_caps = GST_BUFFER_CAPS (GST_BUFFER (buffer_out->data));
     fail_unless (GST_IS_CAPS (sink_caps), "buffer out don't have caps");
     temp = gst_caps_to_string (sink_caps);
@@ -431,10 +459,13 @@ gst_check_element_push_buffer_list (const gchar * element_name,
     GST_DEBUG ("sink caps requested by buffer out: '%s'", temp);
     g_free (temp);
     fail_unless (gst_caps_is_fixed (sink_caps), "we need fixed caps");
+#endif
     /* get the sink pad */
     sink_pad = gst_pad_new (NULL, GST_PAD_SINK);
     fail_unless (GST_IS_PAD (sink_pad));
+#if 0
     gst_pad_set_caps (sink_pad, sink_caps);
+#endif
     /* get the peer pad */
     pad_peer = gst_element_get_static_pad (element, "src");
     fail_unless (gst_pad_link (pad_peer, sink_pad) == GST_PAD_LINK_OK,
@@ -471,22 +502,31 @@ gst_check_element_push_buffer_list (const gchar * element_name,
   while (buffers != NULL) {
     GstBuffer *new = GST_BUFFER (buffers->data);
     GstBuffer *orig = GST_BUFFER (buffer_out->data);
+    gsize newsize, origsize;
+    guint8 *newdata, *origdata;
+
+    newdata = gst_buffer_map (new, &newsize, NULL, GST_MAP_READ);
+    origdata = gst_buffer_map (orig, &origsize, NULL, GST_MAP_READ);
 
-    GST_LOG ("orig buffer: size %u, caps %" GST_PTR_FORMAT,
-        GST_BUFFER_SIZE (orig), GST_BUFFER_CAPS (orig));
-    GST_LOG ("new  buffer: size %u, caps %" GST_PTR_FORMAT,
-        GST_BUFFER_SIZE (new), GST_BUFFER_CAPS (new));
-    GST_MEMDUMP ("orig buffer", GST_BUFFER_DATA (orig), GST_BUFFER_SIZE (orig));
-    GST_MEMDUMP ("new  buffer", GST_BUFFER_DATA (new), GST_BUFFER_SIZE (new));
+    GST_LOG ("orig buffer: size %u", origsize);
+    GST_LOG ("new  buffer: size %u", newsize);
+    GST_MEMDUMP ("orig buffer", origdata, origsize);
+    GST_MEMDUMP ("new  buffer", newdata, newsize);
 
     /* remove the buffers */
     buffers = g_list_remove (buffers, new);
     buffer_out = g_list_remove (buffer_out, orig);
-    fail_unless (GST_BUFFER_SIZE (orig) == GST_BUFFER_SIZE (new),
-        "size of the buffers are not the same");
-    fail_unless (memcmp (GST_BUFFER_DATA (orig), GST_BUFFER_DATA (new),
-            GST_BUFFER_SIZE (new)) == 0, "data is not the same");
+
+    fail_unless (origsize == newsize, "size of the buffers are not the same");
+    fail_unless (memcmp (origdata, newdata, newsize) == 0,
+        "data is not the same");
+#if 0
     gst_check_caps_equal (GST_BUFFER_CAPS (orig), GST_BUFFER_CAPS (new));
+#endif
+
+    gst_buffer_unmap (orig, origdata, origsize);
+    gst_buffer_unmap (new, newdata, newsize);
+
     gst_buffer_unref (new);
     gst_buffer_unref (orig);
   }
index 004eb74..6d4a935 100644 (file)
@@ -81,6 +81,7 @@ void gst_check_teardown_pad_by_name (GstElement * element, const gchar *name);
 void gst_check_teardown_src_pad (GstElement * element);
 void gst_check_drop_buffers (void);
 void gst_check_caps_equal (GstCaps * caps1, GstCaps * caps2);
+void gst_check_buffer_data (GstBuffer * buffer, gconstpointer data, gsize size);
 void gst_check_element_push_buffer_list (const gchar * element_name,
     GList * buffer_in, GList * buffer_out, GstFlowReturn last_flow_return);
 void gst_check_element_push_buffer (const gchar * element_name,
index ded047e..731fc5a 100644 (file)
 struct _GstStreamConsistency
 {
   gboolean flushing;
-  gboolean newsegment;
+  gboolean segment;
   gboolean eos;
   gulong probeid;
   GstPad *pad;
 };
 
 static gboolean
-source_pad_data_cb (GstPad * pad, GstMiniObject * data,
+source_pad_data_cb (GstPad * pad, GstProbeType type, GstMiniObject * data,
     GstStreamConsistency * consist)
 {
   if (GST_IS_BUFFER (data)) {
@@ -50,8 +50,8 @@ source_pad_data_cb (GstPad * pad, GstMiniObject * data,
         GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (GST_BUFFER (data))));
     /* If an EOS went through, a buffer would be invalid */
     fail_if (consist->eos, "Buffer received after EOS");
-    /* Buffers need to be preceded by a newsegment event */
-    fail_unless (consist->newsegment, "Buffer received without newsegment");
+    /* Buffers need to be preceded by a segment event */
+    fail_unless (consist->segment, "Buffer received without segment");
   } else if (GST_IS_EVENT (data)) {
     GstEvent *event = (GstEvent *) data;
 
@@ -67,23 +67,24 @@ source_pad_data_cb (GstPad * pad, GstMiniObject * data,
         fail_if (consist->eos, "Received a FLUSH_STOP after an EOS");
         consist->flushing = FALSE;
         break;
-      case GST_EVENT_NEWSEGMENT:
-        consist->newsegment = TRUE;
+      case GST_EVENT_SEGMENT:
+        consist->segment = TRUE;
         consist->eos = FALSE;
         break;
       case GST_EVENT_EOS:
         /* FIXME : not 100% sure about whether two eos in a row is valid */
         fail_if (consist->eos, "Received EOS just after another EOS");
         consist->eos = TRUE;
-        consist->newsegment = FALSE;
+        consist->segment = FALSE;
         break;
       case GST_EVENT_TAG:
-        GST_DEBUG_OBJECT (pad, "tag %" GST_PTR_FORMAT, event->structure);
+        GST_DEBUG_OBJECT (pad, "tag %" GST_PTR_FORMAT,
+            gst_event_get_structure (event));
         /* fall through */
       default:
         if (GST_EVENT_IS_SERIALIZED (event) && GST_EVENT_IS_DOWNSTREAM (event)) {
           fail_if (consist->eos, "Event received after EOS");
-          fail_unless (consist->newsegment, "Event received before newsegment");
+          fail_unless (consist->segment, "Event received before segment");
         }
         /* FIXME : Figure out what to do for other events */
         break;
@@ -117,7 +118,8 @@ gst_consistency_checker_new (GstPad * pad)
   consist = g_new0 (GstStreamConsistency, 1);
   consist->pad = g_object_ref (pad);
   consist->probeid =
-      gst_pad_add_data_probe (pad, (GCallback) source_pad_data_cb, consist);
+      gst_pad_add_probe (pad, GST_PROBE_TYPE_DATA,
+      (GstPadProbeCallback) source_pad_data_cb, consist, NULL);
 
   return consist;
 }
@@ -136,7 +138,7 @@ gst_consistency_checker_reset (GstStreamConsistency * consist)
 {
   consist->eos = FALSE;
   consist->flushing = FALSE;
-  consist->newsegment = FALSE;
+  consist->segment = FALSE;
 }
 
 /**
@@ -152,7 +154,7 @@ void
 gst_consistency_checker_free (GstStreamConsistency * consist)
 {
   /* Remove the data probe */
-  gst_pad_remove_data_probe (consist->pad, consist->probeid);
+  gst_pad_remove_probe (consist->pad, consist->probeid);
   g_object_unref (consist->pad);
   g_free (consist);
 }
index bf99b4e..61abdbc 100644 (file)
@@ -64,12 +64,12 @@ GstController-@GST_MAJORMINOR@.gir: $(INTROSPECTION_SCANNER) libgstcontroller-@G
                $(gir_cincludes) \
                --add-include-path=$(top_builddir)/gst \
                --library-path=$(top_builddir)/gst \
-               --library=$(top_builddir)/gst/libgstreamer-0.10.la \
-               --library=libgstcontroller-0.10.la \
-               --include=Gst-0.10 \
+               --library=$(top_builddir)/gst/libgstreamer-0.11.la \
+               --library=libgstcontroller-0.11.la \
+               --include=Gst-0.11 \
                --libtool="$(top_builddir)/libtool" \
-               --pkg gstreamer-0.10 \
-               --pkg-export gstreamer-controller-0.10 \
+               --pkg gstreamer-@GST_MAJORMINOR@ \
+               --pkg-export gstreamer-controller-@GST_MAJORMINOR@ \
                --add-init-section="gst_init(NULL,NULL);" \
                --output $@ \
                $(gir_headers) \
index 9bb1d6d..1675278 100644 (file)
@@ -97,21 +97,6 @@ struct _GstControllerPrivate
 };
 
 /* helper */
-#ifndef GST_REMOVE_DEPRECATED
-static void
-gst_controlled_property_add_interpolation_control_source (GstControlledProperty
-    * self)
-{
-  GstControlSource *csource =
-      GST_CONTROL_SOURCE (gst_interpolation_control_source_new ());
-
-  GST_INFO
-      ("Adding a GstInterpolationControlSource because of backward compatibility");
-  g_return_if_fail (!self->csource);
-  gst_control_source_bind (GST_CONTROL_SOURCE (csource), self->pspec);
-  self->csource = csource;
-}
-#endif
 
 /*
  * gst_controlled_property_new:
@@ -972,318 +957,3 @@ gst_controller_get_type (void)
   }
   return type;
 }
-
-/* FIXME: backward compatibility functions */
-
-/*
- * gst_controlled_property_set_interpolation_mode:
- * @self: the controlled property object to change
- * @mode: the new interpolation mode
- *
- * Sets the given Interpolation mode for the controlled property and activates
- * the respective interpolation hooks.
- *
- * Deprecated: Use #GstControlSource, for example #GstInterpolationControlSource
- * directly.
- *
- * Returns: %TRUE for success
- */
-#ifndef GST_REMOVE_DEPRECATED
-static gboolean
-gst_controlled_property_set_interpolation_mode (GstControlledProperty * self,
-    GstInterpolateMode mode)
-{
-  GstInterpolationControlSource *icsource;
-
-  /* FIXME: backward compat, add GstInterpolationControlSource */
-  if (!self->csource)
-    gst_controlled_property_add_interpolation_control_source (self);
-
-  g_return_val_if_fail (GST_IS_INTERPOLATION_CONTROL_SOURCE (self->csource),
-      FALSE);
-
-  icsource = GST_INTERPOLATION_CONTROL_SOURCE (self->csource);
-
-  return gst_interpolation_control_source_set_interpolation_mode (icsource,
-      mode);
-}
-#endif
-
-/**
- * gst_controller_set:
- * @self: the controller object which handles the properties
- * @property_name: the name of the property to set
- * @timestamp: the time the control-change is schedules for
- * @value: the control-value
- *
- * Set the value of given controller-handled property at a certain time.
- *
- * Deprecated: Use #GstControlSource, for example #GstInterpolationControlSource
- * directly.
- *
- * Returns: FALSE if the values couldn't be set (ex : properties not handled by controller), TRUE otherwise
- */
-#ifndef GST_REMOVE_DEPRECATED
-#ifdef GST_DISABLE_DEPRECATED
-gboolean
-gst_controller_set (GstController * self, const gchar * property_name,
-    GstClockTime timestamp, GValue * value);
-#endif
-gboolean
-gst_controller_set (GstController * self, const gchar * property_name,
-    GstClockTime timestamp, GValue * value)
-{
-  gboolean res = FALSE;
-  GstControlledProperty *prop;
-
-  g_return_val_if_fail (GST_IS_CONTROLLER (self), FALSE);
-  g_return_val_if_fail (property_name, FALSE);
-
-  g_mutex_lock (self->lock);
-  if ((prop = gst_controller_find_controlled_property (self, property_name))) {
-    /* FIXME: backward compat, add GstInterpolationControlSource */
-    if (!prop->csource)
-      gst_controlled_property_add_interpolation_control_source (prop);
-
-    if (!GST_IS_INTERPOLATION_CONTROL_SOURCE (prop->csource))
-      goto out;
-    res =
-        gst_interpolation_control_source_set (GST_INTERPOLATION_CONTROL_SOURCE
-        (prop->csource), timestamp, value);
-  }
-
-out:
-  g_mutex_unlock (self->lock);
-
-  return res;
-}
-#endif
-
-/**
- * gst_controller_set_from_list:
- * @self: the controller object which handles the properties
- * @property_name: the name of the property to set
- * @timedvalues: a list with #GstTimedValue items
- *
- * Sets multiple timed values at once.
- *
- * Deprecated: Use #GstControlSource, for example #GstInterpolationControlSource
- * directly.
- *
- * Returns: %FALSE if the values couldn't be set (ex : properties not handled by controller), %TRUE otherwise
- */
-#ifndef GST_REMOVE_DEPRECATED
-#ifdef GST_DISABLE_DEPRECATED
-gboolean
-gst_controller_set_from_list (GstController * self, const gchar * property_name,
-    GSList * timedvalues);
-#endif
-gboolean
-gst_controller_set_from_list (GstController * self, const gchar * property_name,
-    GSList * timedvalues)
-{
-  gboolean res = FALSE;
-  GstControlledProperty *prop;
-
-  g_return_val_if_fail (GST_IS_CONTROLLER (self), FALSE);
-  g_return_val_if_fail (property_name, FALSE);
-
-  g_mutex_lock (self->lock);
-  if ((prop = gst_controller_find_controlled_property (self, property_name))) {
-    /* FIXME: backward compat, add GstInterpolationControlSource */
-    if (!prop->csource)
-      gst_controlled_property_add_interpolation_control_source (prop);
-
-    if (!GST_IS_INTERPOLATION_CONTROL_SOURCE (prop->csource))
-      goto out;
-
-    res =
-        gst_interpolation_control_source_set_from_list
-        (GST_INTERPOLATION_CONTROL_SOURCE (prop->csource), timedvalues);
-  }
-
-out:
-  g_mutex_unlock (self->lock);
-
-  return res;
-}
-#endif
-
-/**
- * gst_controller_unset:
- * @self: the controller object which handles the properties
- * @property_name: the name of the property to unset
- * @timestamp: the time the control-change should be removed from
- *
- * Used to remove the value of given controller-handled property at a certain
- * time.
- *
- * Deprecated: Use #GstControlSource, for example #GstInterpolationControlSource
- * directly.
- *
- * Returns: %FALSE if the values couldn't be unset (ex : properties not handled by controller), %TRUE otherwise
- */
-#ifndef GST_REMOVE_DEPRECATED
-#ifdef GST_DISABLE_DEPRECATED
-gboolean
-gst_controller_unset (GstController * self, const gchar * property_name,
-    GstClockTime timestamp);
-#endif
-gboolean
-gst_controller_unset (GstController * self, const gchar * property_name,
-    GstClockTime timestamp)
-{
-  gboolean res = FALSE;
-  GstControlledProperty *prop;
-
-  g_return_val_if_fail (GST_IS_CONTROLLER (self), FALSE);
-  g_return_val_if_fail (property_name, FALSE);
-  g_return_val_if_fail (GST_CLOCK_TIME_IS_VALID (timestamp), FALSE);
-
-  g_mutex_lock (self->lock);
-  if ((prop = gst_controller_find_controlled_property (self, property_name))) {
-    if (!prop->csource || !GST_IS_INTERPOLATION_CONTROL_SOURCE (prop->csource))
-      goto out;
-
-    res =
-        gst_interpolation_control_source_unset (GST_INTERPOLATION_CONTROL_SOURCE
-        (prop->csource), timestamp);
-  }
-
-out:
-  g_mutex_unlock (self->lock);
-
-  return res;
-}
-#endif
-
-/**
- * gst_controller_unset_all:
- * @self: the controller object which handles the properties
- * @property_name: the name of the property to unset
- *
- * Used to remove all time-stamped values of given controller-handled property
- *
- * Deprecated: Use #GstControlSource, for example #GstInterpolationControlSource
- * directly.
- *
- * Returns: %FALSE if the values couldn't be unset (ex : properties not handled
- * by controller), %TRUE otherwise
- * Since: 0.10.5
- */
-#ifndef GST_REMOVE_DEPRECATED
-#ifdef GST_DISABLE_DEPRECATED
-gboolean gst_controller_unset_all (GstController * self,
-    const gchar * property_name);
-#endif
-gboolean
-gst_controller_unset_all (GstController * self, const gchar * property_name)
-{
-  GstControlledProperty *prop;
-
-  g_return_val_if_fail (GST_IS_CONTROLLER (self), FALSE);
-  g_return_val_if_fail (property_name, FALSE);
-
-  g_mutex_lock (self->lock);
-  if ((prop = gst_controller_find_controlled_property (self, property_name))) {
-    if (!prop->csource || !GST_IS_INTERPOLATION_CONTROL_SOURCE (prop->csource))
-      goto out;
-
-    gst_interpolation_control_source_unset_all (GST_INTERPOLATION_CONTROL_SOURCE
-        (prop->csource));
-  }
-
-out:
-  g_mutex_unlock (self->lock);
-
-  return TRUE;
-}
-#endif
-
-/**
- * gst_controller_get_all:
- * @self: the controller to get the list from
- * @property_name: the name of the property to get the list for
- *
- * Returns a read-only copy of the list of #GstTimedValue for the given property.
- * Free the list after done with it.
- *
- * <note><para>This doesn't modify the controlled GObject property!</para></note>
- *
- * Deprecated: Use #GstControlSource, for example #GstInterpolationControlSource
- * directly.
- *
- * Returns: a copy of the list, or %NULL if the property isn't handled by the controller
- */
-#ifndef GST_REMOVE_DEPRECATED
-#ifdef GST_DISABLE_DEPRECATED
-const GList *gst_controller_get_all (GstController * self,
-    const gchar * property_name);
-#endif
-const GList *
-gst_controller_get_all (GstController * self, const gchar * property_name)
-{
-  const GList *res = NULL;
-  GstControlledProperty *prop;
-
-  g_return_val_if_fail (GST_IS_CONTROLLER (self), NULL);
-  g_return_val_if_fail (property_name, NULL);
-
-  g_mutex_lock (self->lock);
-  if ((prop = gst_controller_find_controlled_property (self, property_name))) {
-    if (!prop->csource || !GST_IS_INTERPOLATION_CONTROL_SOURCE (prop->csource))
-      goto out;
-
-    res =
-        gst_interpolation_control_source_get_all
-        (GST_INTERPOLATION_CONTROL_SOURCE (prop->csource));
-  }
-
-out:
-  g_mutex_unlock (self->lock);
-
-  return res;
-}
-#endif
-
-/**
- * gst_controller_set_interpolation_mode:
- * @self: the controller object
- * @property_name: the name of the property for which to change the interpolation
- * @mode: interpolation mode
- *
- * Sets the given interpolation mode on the given property.
- *
- * <note><para>User interpolation is not yet available and quadratic interpolation
- * is deprecated and maps to cubic interpolation.</para></note>
- *
- * Deprecated: Use #GstControlSource, for example #GstInterpolationControlSource
- * directly.
- *
- * Returns: %TRUE if the property is handled by the controller, %FALSE otherwise
- */
-#ifndef GST_REMOVE_DEPRECATED
-#ifdef GST_DISABLE_DEPRECATED
-gboolean
-gst_controller_set_interpolation_mode (GstController * self,
-    const gchar * property_name, GstInterpolateMode mode);
-#endif
-gboolean
-gst_controller_set_interpolation_mode (GstController * self,
-    const gchar * property_name, GstInterpolateMode mode)
-{
-  gboolean res = FALSE;
-  GstControlledProperty *prop;
-
-  g_return_val_if_fail (GST_IS_CONTROLLER (self), FALSE);
-  g_return_val_if_fail (property_name, FALSE);
-
-  g_mutex_lock (self->lock);
-  if ((prop = gst_controller_find_controlled_property (self, property_name))) {
-    res = gst_controlled_property_set_interpolation_mode (prop, mode);
-  }
-  g_mutex_unlock (self->lock);
-
-  return res;
-}
-#endif
index 0b0379f..ce666a5 100644 (file)
@@ -132,24 +132,6 @@ void gst_object_set_control_rate (GObject * object, GstClockTime control_rate);
 gboolean gst_controller_init (int * argc, char ***argv);
 
 
-/* FIXME: deprecated functions */
-#ifndef GST_DISABLE_DEPRECATED
-gboolean gst_controller_set (GstController * self, const gchar * property_name,
-    GstClockTime timestamp, GValue * value);
-gboolean gst_controller_set_from_list (GstController * self,
-    const gchar * property_name, GSList * timedvalues);
-
-gboolean gst_controller_unset (GstController * self, const gchar * property_name,
-    GstClockTime timestamp);
-gboolean gst_controller_unset_all (GstController * self, const gchar * property_name);
-
-const GList *gst_controller_get_all (GstController * self,
-    const gchar * property_name);
-
-gboolean gst_controller_set_interpolation_mode (GstController * self,
-    const gchar * property_name, GstInterpolateMode mode);
-#endif /* GST_DISABLE_DEPRECATED */
-
 G_END_DECLS
 
 #endif /* __GST_CONTROLLER_H__ */
index cde4a53..c41d23a 100644 (file)
@@ -52,12 +52,12 @@ GstDataprotocol-@GST_MAJORMINOR@.gir: $(INTROSPECTION_SCANNER) libgstdataprotoco
                $(gir_cincludes) \
                --add-include-path=$(top_builddir)/gst \
                --library-path=$(top_builddir)/gst \
-               --library=$(top_builddir)/gst/libgstreamer-0.10.la \
-               --library=libgstdataprotocol-0.10.la \
-               --include=Gst-0.10 \
+               --library=$(top_builddir)/gst/libgstreamer-@GST_MAJORMINOR@.la \
+               --library=libgstdataprotocol-@GST_MAJORMINOR@.la \
+               --include=Gst-@GST_MAJORMINOR@ \
                --libtool="$(top_builddir)/libtool" \
-               --pkg gstreamer-0.10 \
-               --pkg-export=gstreamer-dataprotocol-0.10 \
+               --pkg gstreamer-@GST_MAJORMINOR@ \
+               --pkg-export=gstreamer-dataprotocol-@GST_MAJORMINOR@ \
                --add-init-section="gst_init(NULL,NULL);" \
                --output $@ \
                $(gir_headers) \
index b57d377..e924ea5 100644 (file)
@@ -131,6 +131,8 @@ gst_dp_header_from_buffer_any (const GstBuffer * buffer, GstDPHeaderFlag flags,
 {
   guint8 *h;
   guint16 flags_mask;
+  guint8 *data;
+  gsize size;
 
   g_return_val_if_fail (GST_IS_BUFFER (buffer), FALSE);
   g_return_val_if_fail (length, FALSE);
@@ -142,8 +144,10 @@ gst_dp_header_from_buffer_any (const GstBuffer * buffer, GstDPHeaderFlag flags,
   /* version, flags, type */
   GST_DP_INIT_HEADER (h, version, flags, GST_DP_PAYLOAD_BUFFER);
 
+  data = gst_buffer_map ((GstBuffer *) buffer, &size, NULL, GST_MAP_READ);
+
   /* buffer properties */
-  GST_WRITE_UINT32_BE (h + 6, GST_BUFFER_SIZE (buffer));
+  GST_WRITE_UINT32_BE (h + 6, size);
   GST_WRITE_UINT64_BE (h + 10, GST_BUFFER_TIMESTAMP (buffer));
   GST_WRITE_UINT64_BE (h + 18, GST_BUFFER_DURATION (buffer));
   GST_WRITE_UINT64_BE (h + 26, GST_BUFFER_OFFSET (buffer));
@@ -157,7 +161,9 @@ gst_dp_header_from_buffer_any (const GstBuffer * buffer, GstDPHeaderFlag flags,
 
   GST_WRITE_UINT16_BE (h + 42, GST_BUFFER_FLAGS (buffer) & flags_mask);
 
-  GST_DP_SET_CRC (h, flags, GST_BUFFER_DATA (buffer), GST_BUFFER_SIZE (buffer));
+  GST_DP_SET_CRC (h, flags, data, size);
+
+  gst_buffer_unmap ((GstBuffer *) buffer, data, size);
 
   GST_LOG ("created header from buffer:");
   gst_dp_dump_byte_array (h, GST_DP_HEADER_LENGTH);
@@ -365,34 +371,6 @@ gst_dp_header_payload_type (const guint8 * header)
 
 /*** PACKETIZER FUNCTIONS ***/
 
-/**
- * gst_dp_header_from_buffer:
- * @buffer: a #GstBuffer to create a header for
- * @flags: the #GstDPHeaderFlag to create the header with
- * @length: a guint pointer to store the header length in
- * @header: a guint8 * pointer to store a newly allocated header byte array in
- *
- * Creates a GDP header from the given buffer.
- *
- * Deprecated: use a #GstDPPacketizer
- *
- * Returns: %TRUE if the header was successfully created.
- */
-#ifndef GST_REMOVE_DEPRECATED
-#ifdef GST_DISABLE_DEPRECATED
-gboolean
-gst_dp_header_from_buffer (const GstBuffer * buffer, GstDPHeaderFlag flags,
-    guint * length, guint8 ** header);
-#endif
-gboolean
-gst_dp_header_from_buffer (const GstBuffer * buffer, GstDPHeaderFlag flags,
-    guint * length, guint8 ** header)
-{
-  return gst_dp_header_from_buffer_any (buffer, flags, length, header,
-      GST_DP_VERSION_0_2);
-}
-#endif
-
 static gboolean
 gst_dp_header_from_buffer_1_0 (const GstBuffer * buffer, GstDPHeaderFlag flags,
     guint * length, guint8 ** header)
@@ -401,35 +379,6 @@ gst_dp_header_from_buffer_1_0 (const GstBuffer * buffer, GstDPHeaderFlag flags,
       GST_DP_VERSION_1_0);
 }
 
-/**
- * gst_dp_packet_from_caps:
- * @caps: a #GstCaps to create a packet for
- * @flags: the #GstDPHeaderFlag to create the header with
- * @length: a guint pointer to store the header length in
- * @header: a guint8 pointer to store a newly allocated header byte array in
- * @payload: a guint8 pointer to store a newly allocated payload byte array in
- *
- * Creates a GDP packet from the given caps.
- *
- * Deprecated: use a #GstDPPacketizer
- *
- * Returns: %TRUE if the packet was successfully created.
- */
-#ifndef GST_REMOVE_DEPRECATED
-#ifdef GST_DISABLE_DEPRECATED
-gboolean
-gst_dp_packet_from_caps (const GstCaps * caps, GstDPHeaderFlag flags,
-    guint * length, guint8 ** header, guint8 ** payload);
-#endif
-gboolean
-gst_dp_packet_from_caps (const GstCaps * caps, GstDPHeaderFlag flags,
-    guint * length, guint8 ** header, guint8 ** payload)
-{
-  return gst_dp_packet_from_caps_any (caps, flags, length, header, payload,
-      GST_DP_VERSION_0_2);
-}
-#endif
-
 static gboolean
 gst_dp_packet_from_caps_1_0 (const GstCaps * caps, GstDPHeaderFlag flags,
     guint * length, guint8 ** header, guint8 ** payload)
@@ -438,105 +387,6 @@ gst_dp_packet_from_caps_1_0 (const GstCaps * caps, GstDPHeaderFlag flags,
       GST_DP_VERSION_1_0);
 }
 
-/**
- * gst_dp_packet_from_event:
- * @event: a #GstEvent to create a packet for
- * @flags: the #GstDPHeaderFlag to create the header with
- * @length: a guint pointer to store the header length in
- * @header: a guint8 pointer to store a newly allocated header byte array in
- * @payload: a guint8 pointer to store a newly allocated payload byte array in
- *
- * Creates a GDP packet from the given event.
- *
- * Deprecated: use a #GstDPPacketizer
- *
- * Returns: %TRUE if the packet was successfully created.
- */
-#ifndef GST_REMOVE_DEPRECATED
-#ifdef GST_DISABLE_DEPRECATED
-gboolean
-gst_dp_packet_from_event (const GstEvent * event, GstDPHeaderFlag flags,
-    guint * length, guint8 ** header, guint8 ** payload);
-#endif
-gboolean
-gst_dp_packet_from_event (const GstEvent * event, GstDPHeaderFlag flags,
-    guint * length, guint8 ** header, guint8 ** payload)
-{
-  guint8 *h;
-  guint pl_length;              /* length of payload */
-
-  g_return_val_if_fail (GST_IS_EVENT (event), FALSE);
-  g_return_val_if_fail (length, FALSE);
-  g_return_val_if_fail (header, FALSE);
-  g_return_val_if_fail (payload, FALSE);
-
-  /* first construct payload, since we need the length */
-  switch (GST_EVENT_TYPE (event)) {
-    case GST_EVENT_UNKNOWN:
-      GST_WARNING ("Unknown event, ignoring");
-      return FALSE;
-    case GST_EVENT_EOS:
-    case GST_EVENT_FLUSH_START:
-    case GST_EVENT_FLUSH_STOP:
-    case GST_EVENT_NEWSEGMENT:
-      pl_length = 0;
-      *payload = NULL;
-      break;
-    case GST_EVENT_SEEK:
-    {
-      gdouble rate;
-      GstFormat format;
-      GstSeekFlags flags;
-      GstSeekType cur_type, stop_type;
-      gint64 cur, stop;
-
-      gst_event_parse_seek ((GstEvent *) event, &rate, &format, &flags,
-          &cur_type, &cur, &stop_type, &stop);
-
-      pl_length = 4 + 4 + 4 + 8 + 4 + 8;
-      *payload = g_malloc0 (pl_length);
-      /* FIXME write rate */
-      GST_WRITE_UINT32_BE (*payload, (guint32) format);
-      GST_WRITE_UINT32_BE (*payload + 4, (guint32) flags);
-      GST_WRITE_UINT32_BE (*payload + 8, (guint32) cur_type);
-      GST_WRITE_UINT64_BE (*payload + 12, (guint64) cur);
-      GST_WRITE_UINT32_BE (*payload + 20, (guint32) stop_type);
-      GST_WRITE_UINT64_BE (*payload + 24, (guint64) stop);
-      break;
-    }
-    case GST_EVENT_QOS:
-    case GST_EVENT_NAVIGATION:
-    case GST_EVENT_TAG:
-      GST_WARNING ("Unhandled event type %d, ignoring", GST_EVENT_TYPE (event));
-      return FALSE;
-    default:
-      GST_WARNING ("Unknown event type %d, ignoring", GST_EVENT_TYPE (event));
-      return FALSE;
-  }
-
-  /* now we can create and fill the header */
-  h = g_malloc0 (GST_DP_HEADER_LENGTH);
-  *length = GST_DP_HEADER_LENGTH;
-
-  /* version, flags, type */
-  GST_DP_INIT_HEADER (h, GST_DP_VERSION_0_2, flags,
-      GST_DP_PAYLOAD_EVENT_NONE + GST_EVENT_TYPE (event));
-
-  /* length */
-  GST_WRITE_UINT32_BE (h + 6, (guint32) pl_length);
-  /* timestamp */
-  GST_WRITE_UINT64_BE (h + 10, GST_EVENT_TIMESTAMP (event));
-
-  GST_DP_SET_CRC (h, flags, *payload, pl_length);
-
-  GST_LOG ("created header from event:");
-  gst_dp_dump_byte_array (h, GST_DP_HEADER_LENGTH);
-
-  *header = h;
-  return TRUE;
-}
-#endif
-
 static gboolean
 gst_dp_packet_from_event_1_0 (const GstEvent * event, GstDPHeaderFlag flags,
     guint * length, guint8 ** header, guint8 ** payload)
@@ -544,6 +394,7 @@ gst_dp_packet_from_event_1_0 (const GstEvent * event, GstDPHeaderFlag flags,
   guint8 *h;
   guint32 pl_length;            /* length of payload */
   guchar *string = NULL;
+  const GstStructure *structure;
 
   g_return_val_if_fail (GST_IS_EVENT (event), FALSE);
   g_return_val_if_fail (length, FALSE);
@@ -553,8 +404,9 @@ gst_dp_packet_from_event_1_0 (const GstEvent * event, GstDPHeaderFlag flags,
   *length = GST_DP_HEADER_LENGTH;
   h = g_malloc0 (GST_DP_HEADER_LENGTH);
 
-  if (event->structure) {
-    string = (guchar *) gst_structure_to_string (event->structure);
+  structure = gst_event_get_structure ((GstEvent *) event);
+  if (structure) {
+    string = (guchar *) gst_structure_to_string (structure);
     GST_LOG ("event %p has structure, string %s", event, string);
     pl_length = strlen ((gchar *) string) + 1;  /* include trailing 0 */
   } else {
@@ -609,7 +461,8 @@ gst_dp_buffer_from_header (guint header_length, const guint8 * header)
       GST_DP_PAYLOAD_BUFFER, NULL);
 
   buffer =
-      gst_buffer_new_and_alloc ((guint) GST_DP_HEADER_PAYLOAD_LENGTH (header));
+      gst_buffer_new_allocate (NULL,
+      (guint) GST_DP_HEADER_PAYLOAD_LENGTH (header), 0);
 
   GST_BUFFER_TIMESTAMP (buffer) = GST_DP_HEADER_TIMESTAMP (header);
   GST_BUFFER_DURATION (buffer) = GST_DP_HEADER_DURATION (header);
@@ -671,7 +524,7 @@ gst_dp_event_from_packet_0_2 (guint header_length, const guint8 * header,
     case GST_EVENT_EOS:
     case GST_EVENT_FLUSH_START:
     case GST_EVENT_FLUSH_STOP:
-    case GST_EVENT_NEWSEGMENT:
+    case GST_EVENT_SEGMENT:
       event = gst_event_new_custom (type, NULL);
       GST_EVENT_TIMESTAMP (event) = GST_DP_HEADER_TIMESTAMP (header);
       break;
@@ -888,13 +741,6 @@ gst_dp_packetizer_new (GstDPVersion version)
   ret->version = version;
 
   switch (version) {
-#ifndef GST_REMOVE_DEPRECATED
-    case GST_DP_VERSION_0_2:
-      ret->header_from_buffer = gst_dp_header_from_buffer;
-      ret->packet_from_caps = gst_dp_packet_from_caps;
-      ret->packet_from_event = gst_dp_packet_from_event;
-      break;
-#endif
     case GST_DP_VERSION_1_0:
       ret->header_from_buffer = gst_dp_header_from_buffer_1_0;
       ret->packet_from_caps = gst_dp_packet_from_caps_1_0;
index 150b5cc..efd524a 100644 (file)
@@ -149,27 +149,6 @@ guint32            gst_dp_header_payload_length    (const guint8 * header);
 GstDPPayloadType
                gst_dp_header_payload_type      (const guint8 * header);
 
-/* converting from GstBuffer/GstEvent/GstCaps */
-#ifndef GST_DISABLE_DEPRECATED
-gboolean       gst_dp_header_from_buffer       (const GstBuffer * buffer,
-                                               GstDPHeaderFlag flags,
-                                               guint * length,
-                                               guint8 ** header);
-#endif
-#ifndef GST_DISABLE_DEPRECATED
-gboolean       gst_dp_packet_from_caps         (const GstCaps * caps,
-                                               GstDPHeaderFlag flags,
-                                               guint * length,
-                                               guint8 ** header,
-                                               guint8 ** payload);
-#endif
-#ifndef GST_DISABLE_DEPRECATED
-gboolean       gst_dp_packet_from_event        (const GstEvent * event,
-                                               GstDPHeaderFlag flags,
-                                               guint * length,
-                                               guint8 ** header,
-                                               guint8 ** payload);
-#endif
 /* converting to GstBuffer/GstEvent/GstCaps */
 GstBuffer *    gst_dp_buffer_from_header       (guint header_length,
                                                const guint8 * header);
index 93b522e..9e77b69 100644 (file)
@@ -56,12 +56,12 @@ GstNet-@GST_MAJORMINOR@.gir: $(INTROSPECTION_SCANNER) libgstnet-@GST_MAJORMINOR@
                $(gir_cincludes) \
                --add-include-path=$(top_builddir)/gst \
                --library-path=$(top_builddir)/gst \
-               --library=$(top_builddir)/gst/libgstreamer-0.10.la \
-               --library=libgstnet-0.10.la \
-               --include=Gst-0.10 \
+               --library=$(top_builddir)/gst/libgstreamer-@GST_MAJORMINOR@.la \
+               --library=libgstnet-@GST_MAJORMINOR@.la \
+               --include=Gst-@GST_MAJORMINOR@ \
                --libtool="$(top_builddir)/libtool" \
-               --pkg gstreamer-0.10 \
-               --pkg-export="gstreamer-net-0.10" \
+               --pkg gstreamer-@GST_MAJORMINOR@ \
+               --pkg-export="gstreamer-net-@GST_MAJORMINOR@" \
                --add-init-section="gst_init(NULL,NULL);" \
                --output $@ \
                $(gir_headers) \
index dcaa975..8130e3e 100644 (file)
@@ -88,11 +88,11 @@ struct _GstNetClientClockPrivate
   GstPoll *fdset;
 };
 
-#define _do_init(type) \
+#define _do_init \
   GST_DEBUG_CATEGORY_INIT (ncc_debug, "netclock", 0, "Network client clock");
-
-GST_BOILERPLATE_FULL (GstNetClientClock, gst_net_client_clock,
-    GstSystemClock, GST_TYPE_SYSTEM_CLOCK, _do_init);
+#define gst_net_client_clock_parent_class parent_class
+G_DEFINE_TYPE_WITH_CODE (GstNetClientClock, gst_net_client_clock,
+    GST_TYPE_SYSTEM_CLOCK, _do_init);
 
 static void gst_net_client_clock_finalize (GObject * object);
 static void gst_net_client_clock_set_property (GObject * object, guint prop_id,
@@ -118,12 +118,6 @@ inet_aton (const char *c, struct in_addr *paddr)
 #endif
 
 static void
-gst_net_client_clock_base_init (gpointer g_class)
-{
-  /* nop */
-}
-
-static void
 gst_net_client_clock_class_init (GstNetClientClockClass * klass)
 {
   GObjectClass *gobject_class;
@@ -148,8 +142,7 @@ gst_net_client_clock_class_init (GstNetClientClockClass * klass)
 }
 
 static void
-gst_net_client_clock_init (GstNetClientClock * self,
-    GstNetClientClockClass * g_class)
+gst_net_client_clock_init (GstNetClientClock * self)
 {
   GstClock *clock = GST_CLOCK_CAST (self);
 
index b04d282..c1b4cac 100644 (file)
@@ -105,10 +105,11 @@ static void gst_net_time_provider_set_property (GObject * object, guint prop_id,
 static void gst_net_time_provider_get_property (GObject * object, guint prop_id,
     GValue * value, GParamSpec * pspec);
 
-#define _do_init(type) \
+#define _do_init \
   GST_DEBUG_CATEGORY_INIT (ntp_debug, "nettime", 0, "Network time provider");
 
-GST_BOILERPLATE_FULL (GstNetTimeProvider, gst_net_time_provider, GstObject,
+#define gst_net_time_provider_parent_class parent_class
+G_DEFINE_TYPE_WITH_CODE (GstNetTimeProvider, gst_net_time_provider,
     GST_TYPE_OBJECT, _do_init);
 
 #ifdef G_OS_WIN32
@@ -124,12 +125,6 @@ inet_aton (const char *c, struct in_addr *paddr)
 #endif
 
 static void
-gst_net_time_provider_base_init (gpointer g_class)
-{
-  /* Do nothing here */
-}
-
-static void
 gst_net_time_provider_class_init (GstNetTimeProviderClass * klass)
 {
   GObjectClass *gobject_class;
@@ -163,8 +158,7 @@ gst_net_time_provider_class_init (GstNetTimeProviderClass * klass)
 }
 
 static void
-gst_net_time_provider_init (GstNetTimeProvider * self,
-    GstNetTimeProviderClass * g_class)
+gst_net_time_provider_init (GstNetTimeProvider * self)
 {
 #ifdef G_OS_WIN32
   WSADATA w;
index 7ee1407..481f81f 100644 (file)
@@ -12,7 +12,7 @@ typelibdir=@abs_top_builddir@/gst
 Name: GStreamer Uninstalled
 Description: Streaming media framework, Not Installed
 Version: @VERSION@
-Requires: @GST_PKG_DEPS@@LIBXML_PKG@
+Requires: @GST_PKG_DEPS@
 Libs: @abs_top_builddir@/gst/libgstreamer-@GST_MAJORMINOR@.la
 # FIXME: the libs dir doesn't really belong here
 Cflags: -I@abs_top_srcdir@ -I@abs_top_srcdir@/libs -I@abs_top_builddir@ -I@abs_top_builddir@/libs
index ad4554d..36fb2f4 100644 (file)
@@ -11,7 +11,7 @@ typelibdir=${libdir}/girepository-1.0
 
 Name: GStreamer
 Description: Streaming media framework
-Requires: @GST_PKG_DEPS@@LIBXML_PKG@
+Requires: @GST_PKG_DEPS@
 Version: @VERSION@
 Libs: -L${libdir} -lgstreamer-@GST_MAJORMINOR@
 Cflags: -I${includedir}
index a144611..67eca31 100644 (file)
@@ -61,12 +61,12 @@ static GstStaticPadTemplate srctemplate = GST_STATIC_PAD_TEMPLATE ("src",
 GST_DEBUG_CATEGORY_STATIC (gst_capsfilter_debug);
 #define GST_CAT_DEFAULT gst_capsfilter_debug
 
-#define _do_init(bla) \
+#define _do_init \
     GST_DEBUG_CATEGORY_INIT (gst_capsfilter_debug, "capsfilter", 0, \
     "capsfilter element");
-
-GST_BOILERPLATE_FULL (GstCapsFilter, gst_capsfilter, GstBaseTransform,
-    GST_TYPE_BASE_TRANSFORM, _do_init);
+#define gst_capsfilter_parent_class parent_class
+G_DEFINE_TYPE_WITH_CODE (GstCapsFilter, gst_capsfilter, GST_TYPE_BASE_TRANSFORM,
+    _do_init);
 
 
 static void gst_capsfilter_set_property (GObject * object, guint prop_id,
@@ -76,7 +76,7 @@ static void gst_capsfilter_get_property (GObject * object, guint prop_id,
 static void gst_capsfilter_dispose (GObject * object);
 
 static GstCaps *gst_capsfilter_transform_caps (GstBaseTransform * base,
-    GstPadDirection direction, GstCaps * caps);
+    GstPadDirection direction, GstCaps * caps, GstCaps * filter);
 static gboolean gst_capsfilter_accept_caps (GstBaseTransform * base,
     GstPadDirection direction, GstCaps * caps);
 static GstFlowReturn gst_capsfilter_transform_ip (GstBaseTransform * base,
@@ -85,25 +85,10 @@ static GstFlowReturn gst_capsfilter_prepare_buf (GstBaseTransform * trans,
     GstBuffer * input, gint size, GstCaps * caps, GstBuffer ** buf);
 
 static void
-gst_capsfilter_base_init (gpointer g_class)
-{
-  GstElementClass *gstelement_class = GST_ELEMENT_CLASS (g_class);
-
-  gst_element_class_set_details_simple (gstelement_class,
-      "CapsFilter",
-      "Generic",
-      "Pass data without modification, limiting formats",
-      "David Schleef <ds@schleef.org>");
-  gst_element_class_add_pad_template (gstelement_class,
-      gst_static_pad_template_get (&srctemplate));
-  gst_element_class_add_pad_template (gstelement_class,
-      gst_static_pad_template_get (&sinktemplate));
-}
-
-static void
 gst_capsfilter_class_init (GstCapsFilterClass * klass)
 {
   GObjectClass *gobject_class;
+  GstElementClass *gstelement_class;
   GstBaseTransformClass *trans_class;
 
   gobject_class = G_OBJECT_CLASS (klass);
@@ -118,6 +103,17 @@ gst_capsfilter_class_init (GstCapsFilterClass * klass)
               "object."), GST_TYPE_CAPS,
           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
 
+  gstelement_class = GST_ELEMENT_CLASS (klass);
+  gst_element_class_set_details_simple (gstelement_class,
+      "CapsFilter",
+      "Generic",
+      "Pass data without modification, limiting formats",
+      "David Schleef <ds@schleef.org>");
+  gst_element_class_add_pad_template (gstelement_class,
+      gst_static_pad_template_get (&srctemplate));
+  gst_element_class_add_pad_template (gstelement_class,
+      gst_static_pad_template_get (&sinktemplate));
+
   trans_class = GST_BASE_TRANSFORM_CLASS (klass);
   trans_class->transform_caps =
       GST_DEBUG_FUNCPTR (gst_capsfilter_transform_caps);
@@ -128,7 +124,7 @@ gst_capsfilter_class_init (GstCapsFilterClass * klass)
 }
 
 static void
-gst_capsfilter_init (GstCapsFilter * filter, GstCapsFilterClass * g_class)
+gst_capsfilter_init (GstCapsFilter * filter)
 {
   GstBaseTransform *trans = GST_BASE_TRANSFORM (filter);
   gst_base_transform_set_gap_aware (trans, TRUE);
@@ -172,8 +168,7 @@ gst_capsfilter_set_property (GObject * object, guint prop_id,
       GST_DEBUG_OBJECT (capsfilter, "set new caps %" GST_PTR_FORMAT, new_caps);
 
       /* filter the currently negotiated format against the new caps */
-      GST_OBJECT_LOCK (GST_BASE_TRANSFORM_SINK_PAD (object));
-      nego = GST_PAD_CAPS (GST_BASE_TRANSFORM_SINK_PAD (object));
+      nego = gst_pad_get_current_caps (GST_BASE_TRANSFORM_SINK_PAD (object));
       if (nego) {
         GST_DEBUG_OBJECT (capsfilter, "we had negotiated caps %" GST_PTR_FORMAT,
             nego);
@@ -202,13 +197,13 @@ gst_capsfilter_set_property (GObject * object, guint prop_id,
             suggest = gst_caps_copy (new_caps);
           }
         }
+        gst_caps_unref (nego);
       } else {
         GST_DEBUG_OBJECT (capsfilter, "no negotiated caps");
         /* no previous caps, the getcaps function will be used to find suitable
          * caps */
         suggest = NULL;
       }
-      GST_OBJECT_UNLOCK (GST_BASE_TRANSFORM_SINK_PAD (object));
 
       GST_DEBUG_OBJECT (capsfilter, "suggesting new caps %" GST_PTR_FORMAT,
           suggest);
@@ -254,18 +249,28 @@ gst_capsfilter_dispose (GObject * object)
 
 static GstCaps *
 gst_capsfilter_transform_caps (GstBaseTransform * base,
-    GstPadDirection direction, GstCaps * caps)
+    GstPadDirection direction, GstCaps * caps, GstCaps * filter)
 {
   GstCapsFilter *capsfilter = GST_CAPSFILTER (base);
-  GstCaps *ret, *filter_caps;
+  GstCaps *ret, *filter_caps, *tmp;
 
   GST_OBJECT_LOCK (capsfilter);
   filter_caps = gst_caps_ref (capsfilter->filter_caps);
   GST_OBJECT_UNLOCK (capsfilter);
 
-  ret = gst_caps_intersect (caps, filter_caps);
+  if (filter) {
+    tmp =
+        gst_caps_intersect_full (filter, filter_caps, GST_CAPS_INTERSECT_FIRST);
+    gst_caps_unref (filter_caps);
+    filter_caps = tmp;
+  }
+
+  ret = gst_caps_intersect_full (filter_caps, caps, GST_CAPS_INTERSECT_FIRST);
+
   GST_DEBUG_OBJECT (capsfilter, "input:     %" GST_PTR_FORMAT, caps);
-  GST_DEBUG_OBJECT (capsfilter, "filter:    %" GST_PTR_FORMAT, filter_caps);
+  GST_DEBUG_OBJECT (capsfilter, "filter:    %" GST_PTR_FORMAT, filter);
+  GST_DEBUG_OBJECT (capsfilter, "caps filter:    %" GST_PTR_FORMAT,
+      filter_caps);
   GST_DEBUG_OBJECT (capsfilter, "intersect: %" GST_PTR_FORMAT, ret);
 
   gst_caps_unref (filter_caps);
@@ -325,39 +330,18 @@ gst_capsfilter_prepare_buf (GstBaseTransform * trans, GstBuffer * input,
 {
   GstFlowReturn ret = GST_FLOW_OK;
 
-  if (GST_BUFFER_CAPS (input) != NULL) {
-    /* Output buffer already has caps */
-    GST_LOG_OBJECT (trans, "Input buffer already has caps (implicitely fixed)");
-    /* FIXME : Move this behaviour to basetransform. The given caps are the ones
-     * of the source pad, therefore our outgoing buffers should always have
-     * those caps. */
-    if (GST_BUFFER_CAPS (input) != caps) {
-      /* caps are different, make a metadata writable output buffer to set
-       * caps */
-      if (gst_buffer_is_metadata_writable (input)) {
-        /* input is writable, just set caps and use this as the output */
-        *buf = input;
-        gst_buffer_set_caps (*buf, caps);
-        gst_buffer_ref (input);
-      } else {
-        GST_DEBUG_OBJECT (trans, "Creating sub-buffer and setting caps");
-        *buf = gst_buffer_create_sub (input, 0, GST_BUFFER_SIZE (input));
-        gst_buffer_set_caps (*buf, caps);
-      }
-    } else {
-      /* caps are right, just use a ref of the input as the outbuf */
-      *buf = input;
-      gst_buffer_ref (input);
-    }
-  } else {
+  /* always ref input as output buffer */
+  *buf = input;
+  gst_buffer_ref (input);
+
+  if (!gst_pad_has_current_caps (trans->sinkpad)) {
     /* Buffer has no caps. See if the output pad only supports fixed caps */
     GstCaps *out_caps;
 
-    out_caps = GST_PAD_CAPS (trans->srcpad);
+    GST_LOG_OBJECT (trans, "Input pad does not have caps");
 
-    if (out_caps != NULL) {
-      gst_caps_ref (out_caps);
-    } else {
+    out_caps = gst_pad_get_current_caps (trans->srcpad);
+    if (out_caps == NULL) {
       out_caps = gst_pad_get_allowed_caps (trans->srcpad);
       g_return_val_if_fail (out_caps != NULL, GST_FLOW_ERROR);
     }
@@ -367,18 +351,10 @@ gst_capsfilter_prepare_buf (GstBaseTransform * trans, GstBuffer * input,
 
     if (gst_caps_is_fixed (out_caps) && !gst_caps_is_empty (out_caps)) {
       GST_DEBUG_OBJECT (trans, "Have fixed output caps %"
-          GST_PTR_FORMAT " to apply to buffer with no caps", out_caps);
-      if (gst_buffer_is_metadata_writable (input)) {
-        gst_buffer_ref (input);
-        *buf = input;
-      } else {
-        GST_DEBUG_OBJECT (trans, "Creating sub-buffer and setting caps");
-        *buf = gst_buffer_create_sub (input, 0, GST_BUFFER_SIZE (input));
-      }
-      GST_BUFFER_CAPS (*buf) = out_caps;
+          GST_PTR_FORMAT " to apply to srcpad", out_caps);
 
-      if (GST_PAD_CAPS (trans->srcpad) == NULL)
-        gst_pad_set_caps (trans->srcpad, out_caps);
+      if (!gst_pad_has_current_caps (trans->srcpad))
+        gst_pad_push_event (trans->srcpad, gst_event_new_caps (out_caps));
     } else {
       gchar *caps_str = gst_caps_to_string (out_caps);
 
index 976297e..f4e6a5c 100644 (file)
@@ -111,11 +111,11 @@ gst_fake_sink_state_error_get_type (void)
   return fakesink_state_error_type;
 }
 
-#define _do_init(bla) \
+#define _do_init \
     GST_DEBUG_CATEGORY_INIT (gst_fake_sink_debug, "fakesink", 0, "fakesink element");
-
-GST_BOILERPLATE_FULL (GstFakeSink, gst_fake_sink, GstBaseSink,
-    GST_TYPE_BASE_SINK, _do_init);
+#define gst_fake_sink_parent_class parent_class
+G_DEFINE_TYPE_WITH_CODE (GstFakeSink, gst_fake_sink, GST_TYPE_BASE_SINK,
+    _do_init);
 
 static void gst_fake_sink_set_property (GObject * object, guint prop_id,
     const GValue * value, GParamSpec * pspec);
@@ -160,27 +160,11 @@ marshal_VOID__MINIOBJECT_OBJECT (GClosure * closure, GValue * return_value,
       (marshalfunc_VOID__MINIOBJECT_OBJECT) (marshal_data ? marshal_data :
       cc->callback);
 
-  callback (data1, gst_value_get_mini_object (param_values + 1),
+  callback (data1, g_value_get_boxed (param_values + 1),
       g_value_get_object (param_values + 2), data2);
 }
 
 static void
-gst_fake_sink_base_init (gpointer g_class)
-{
-  GstElementClass *gstelement_class = GST_ELEMENT_CLASS (g_class);
-
-  gst_element_class_set_details_simple (gstelement_class,
-      "Fake Sink",
-      "Sink",
-      "Black hole for data",
-      "Erik Walthinsen <omega@cse.ogi.edu>, "
-      "Wim Taymans <wim@fluendo.com>, "
-      "Mr. 'frag-me-more' Vanderwingo <wingo@fluendo.com>");
-  gst_element_class_add_pad_template (gstelement_class,
-      gst_static_pad_template_get (&sinktemplate));
-}
-
-static void
 gst_fake_sink_class_init (GstFakeSinkClass * klass)
 {
   GObjectClass *gobject_class;
@@ -260,6 +244,16 @@ gst_fake_sink_class_init (GstFakeSinkClass * klass)
       NULL, NULL, marshal_VOID__MINIOBJECT_OBJECT, G_TYPE_NONE, 2,
       GST_TYPE_BUFFER, GST_TYPE_PAD);
 
+  gst_element_class_set_details_simple (gstelement_class,
+      "Fake Sink",
+      "Sink",
+      "Black hole for data",
+      "Erik Walthinsen <omega@cse.ogi.edu>, "
+      "Wim Taymans <wim@fluendo.com>, "
+      "Mr. 'frag-me-more' Vanderwingo <wingo@fluendo.com>");
+  gst_element_class_add_pad_template (gstelement_class,
+      gst_static_pad_template_get (&sinktemplate));
+
   gstelement_class->change_state =
       GST_DEBUG_FUNCPTR (gst_fake_sink_change_state);
 
@@ -269,7 +263,7 @@ gst_fake_sink_class_init (GstFakeSinkClass * klass)
 }
 
 static void
-gst_fake_sink_init (GstFakeSink * fakesink, GstFakeSinkClass * g_class)
+gst_fake_sink_init (GstFakeSink * fakesink)
 {
   fakesink->silent = DEFAULT_SILENT;
   fakesink->dump = DEFAULT_DUMP;
@@ -405,9 +399,11 @@ gst_fake_sink_event (GstBaseSink * bsink, GstEvent * event)
 
     if (GST_EVENT_TYPE (event) == GST_EVENT_SINK_MESSAGE) {
       GstMessage *msg;
+      const GstStructure *structure;
 
       gst_event_parse_sink_message (event, &msg);
-      sstr = gst_structure_to_string (msg->structure);
+      structure = gst_message_get_structure (msg);
+      sstr = gst_structure_to_string (structure);
       sink->last_message =
           g_strdup_printf ("message ******* M (type: %d, %s) %p",
           GST_MESSAGE_TYPE (msg), sstr, msg);
@@ -521,11 +517,12 @@ gst_fake_sink_render (GstBaseSink * bsink, GstBuffer * buf)
     }
 
     sink->last_message =
-        g_strdup_printf ("chain   ******* < (%5d bytes, timestamp: %s"
-        ", duration: %s, offset: %" G_GINT64_FORMAT ", offset_end: %"
-        G_GINT64_FORMAT ", flags: %d %s) %p", GST_BUFFER_SIZE (buf), ts_str,
-        dur_str, GST_BUFFER_OFFSET (buf), GST_BUFFER_OFFSET_END (buf),
-        GST_MINI_OBJECT_CAST (buf)->flags, flag_str, buf);
+        g_strdup_printf ("chain   ******* < (%5" G_GSIZE_FORMAT
+        " bytes, timestamp: %s" ", duration: %s, offset: %" G_GINT64_FORMAT
+        ", offset_end: %" G_GINT64_FORMAT ", flags: %d %s) %p",
+        gst_buffer_get_size (buf), ts_str, dur_str, GST_BUFFER_OFFSET (buf),
+        GST_BUFFER_OFFSET_END (buf), GST_MINI_OBJECT_CAST (buf)->flags,
+        flag_str, buf);
     GST_OBJECT_UNLOCK (sink);
 
     gst_fake_sink_notify_last_message (sink);
@@ -535,7 +532,12 @@ gst_fake_sink_render (GstBaseSink * bsink, GstBuffer * buf)
         bsink->sinkpad);
 
   if (sink->dump) {
-    gst_util_dump_mem (GST_BUFFER_DATA (buf), GST_BUFFER_SIZE (buf));
+    guint8 *data;
+    gsize size;
+
+    data = gst_buffer_map (buf, &size, NULL, GST_MAP_READ);
+    gst_util_dump_mem (data, size);
+    gst_buffer_unmap (buf, data, size);
   }
   if (sink->num_buffers_left == 0)
     goto eos;
index 997b41a..df46d18 100644 (file)
@@ -201,11 +201,10 @@ gst_fake_src_filltype_get_type (void)
   return fakesrc_filltype_type;
 }
 
-#define _do_init(bla) \
+#define _do_init \
     GST_DEBUG_CATEGORY_INIT (gst_fake_src_debug, "fakesrc", 0, "fakesrc element");
-
-GST_BOILERPLATE_FULL (GstFakeSrc, gst_fake_src, GstBaseSrc, GST_TYPE_BASE_SRC,
-    _do_init);
+#define gst_fake_src_parent_class parent_class
+G_DEFINE_TYPE_WITH_CODE (GstFakeSrc, gst_fake_src, GST_TYPE_BASE_SRC, _do_init);
 
 static void gst_fake_src_finalize (GObject * object);
 static void gst_fake_src_set_property (GObject * object, guint prop_id,
@@ -251,31 +250,19 @@ marshal_VOID__MINIOBJECT_OBJECT (GClosure * closure, GValue * return_value,
       (marshalfunc_VOID__MINIOBJECT_OBJECT) (marshal_data ? marshal_data :
       cc->callback);
 
-  callback (data1, gst_value_get_mini_object (param_values + 1),
+  callback (data1, g_value_get_boxed (param_values + 1),
       g_value_get_object (param_values + 2), data2);
 }
 
 static void
-gst_fake_src_base_init (gpointer g_class)
-{
-  GstElementClass *gstelement_class = GST_ELEMENT_CLASS (g_class);
-
-  gst_element_class_set_details_simple (gstelement_class,
-      "Fake Source",
-      "Source",
-      "Push empty (no data) buffers around",
-      "Erik Walthinsen <omega@cse.ogi.edu>, " "Wim Taymans <wim@fluendo.com>");
-  gst_element_class_add_pad_template (gstelement_class,
-      gst_static_pad_template_get (&srctemplate));
-}
-
-static void
 gst_fake_src_class_init (GstFakeSrcClass * klass)
 {
   GObjectClass *gobject_class;
+  GstElementClass *gstelement_class;
   GstBaseSrcClass *gstbase_src_class;
 
   gobject_class = G_OBJECT_CLASS (klass);
+  gstelement_class = GST_ELEMENT_CLASS (klass);
   gstbase_src_class = GST_BASE_SRC_CLASS (klass);
 
   gobject_class->finalize = gst_fake_src_finalize;
@@ -379,6 +366,14 @@ gst_fake_src_class_init (GstFakeSrcClass * klass)
       marshal_VOID__MINIOBJECT_OBJECT, G_TYPE_NONE, 2, GST_TYPE_BUFFER,
       GST_TYPE_PAD);
 
+  gst_element_class_set_details_simple (gstelement_class,
+      "Fake Source",
+      "Source",
+      "Push empty (no data) buffers around",
+      "Erik Walthinsen <omega@cse.ogi.edu>, " "Wim Taymans <wim@fluendo.com>");
+  gst_element_class_add_pad_template (gstelement_class,
+      gst_static_pad_template_get (&srctemplate));
+
   gstbase_src_class->is_seekable = GST_DEBUG_FUNCPTR (gst_fake_src_is_seekable);
   gstbase_src_class->start = GST_DEBUG_FUNCPTR (gst_fake_src_start);
   gstbase_src_class->stop = GST_DEBUG_FUNCPTR (gst_fake_src_stop);
@@ -388,7 +383,7 @@ gst_fake_src_class_init (GstFakeSrcClass * klass)
 }
 
 static void
-gst_fake_src_init (GstFakeSrc * fakesrc, GstFakeSrcClass * g_class)
+gst_fake_src_init (GstFakeSrc * fakesrc)
 {
   fakesrc->output = FAKE_SRC_FIRST_LAST_LOOP;
   fakesrc->buffer_count = 0;
@@ -465,10 +460,7 @@ gst_fake_src_alloc_parent (GstFakeSrc * src)
 {
   GstBuffer *buf;
 
-  buf = gst_buffer_new ();
-  GST_BUFFER_DATA (buf) = g_malloc (src->parentsize);
-  GST_BUFFER_MALLOCDATA (buf) = GST_BUFFER_DATA (buf);
-  GST_BUFFER_SIZE (buf) = src->parentsize;
+  buf = gst_buffer_new_allocate (NULL, src->parentsize, 0);
 
   src->parent = buf;
   src->parentoffset = 0;
@@ -629,21 +621,21 @@ gst_fake_src_get_property (GObject * object, guint prop_id, GValue * value,
 }
 
 static void
-gst_fake_src_prepare_buffer (GstFakeSrc * src, GstBuffer * buf)
+gst_fake_src_prepare_buffer (GstFakeSrc * src, guint8 * data, gsize size)
 {
-  if (GST_BUFFER_SIZE (buf) == 0)
+  if (size == 0)
     return;
 
   switch (src->filltype) {
     case FAKE_SRC_FILLTYPE_ZERO:
-      memset (GST_BUFFER_DATA (buf), 0, GST_BUFFER_SIZE (buf));
+      memset (data, 0, size);
       break;
     case FAKE_SRC_FILLTYPE_RANDOM:
     {
       gint i;
-      guint8 *ptr = GST_BUFFER_DATA (buf);
+      guint8 *ptr = data;
 
-      for (i = GST_BUFFER_SIZE (buf); i; i--) {
+      for (i = size; i; i--) {
         *ptr++ = g_random_int_range (0, 256);
       }
       break;
@@ -653,9 +645,9 @@ gst_fake_src_prepare_buffer (GstFakeSrc * src, GstBuffer * buf)
     case FAKE_SRC_FILLTYPE_PATTERN_CONT:
     {
       gint i;
-      guint8 *ptr = GST_BUFFER_DATA (buf);
+      guint8 *ptr = data;
 
-      for (i = GST_BUFFER_SIZE (buf); i; i--) {
+      for (i = size; i; i--) {
         *ptr++ = src->pattern_byte++;
       }
       break;
@@ -670,29 +662,32 @@ static GstBuffer *
 gst_fake_src_alloc_buffer (GstFakeSrc * src, guint size)
 {
   GstBuffer *buf;
+  gpointer data;
+  gboolean do_prepare = FALSE;
 
   buf = gst_buffer_new ();
-  GST_BUFFER_SIZE (buf) = size;
 
   if (size != 0) {
     switch (src->filltype) {
       case FAKE_SRC_FILLTYPE_NOTHING:
-        GST_BUFFER_DATA (buf) = g_malloc (size);
-        GST_BUFFER_MALLOCDATA (buf) = GST_BUFFER_DATA (buf);
+        data = g_malloc (size);
         break;
       case FAKE_SRC_FILLTYPE_ZERO:
-        GST_BUFFER_DATA (buf) = g_malloc0 (size);
-        GST_BUFFER_MALLOCDATA (buf) = GST_BUFFER_DATA (buf);
+        data = g_malloc0 (size);
         break;
       case FAKE_SRC_FILLTYPE_RANDOM:
       case FAKE_SRC_FILLTYPE_PATTERN:
       case FAKE_SRC_FILLTYPE_PATTERN_CONT:
       default:
-        GST_BUFFER_DATA (buf) = g_malloc (size);
-        GST_BUFFER_MALLOCDATA (buf) = GST_BUFFER_DATA (buf);
-        gst_fake_src_prepare_buffer (src, buf);
+        data = g_malloc (size);
+        do_prepare = TRUE;
         break;
     }
+    if (do_prepare)
+      gst_fake_src_prepare_buffer (src, data, size);
+
+    gst_buffer_take_memory (buf, -1,
+        gst_memory_new_wrapped (0, data, g_free, size, 0, size));
   }
 
   return buf;
@@ -720,11 +715,14 @@ gst_fake_src_get_size (GstFakeSrc * src)
 }
 
 static GstBuffer *
-gst_fake_src_create_buffer (GstFakeSrc * src)
+gst_fake_src_create_buffer (GstFakeSrc * src, gsize * bufsize)
 {
   GstBuffer *buf;
-  guint size = gst_fake_src_get_size (src);
+  gsize size = gst_fake_src_get_size (src);
   gboolean dump = src->dump;
+  guint8 *data;
+
+  *bufsize = size;
 
   switch (src->data) {
     case FAKE_SRC_DATA_ALLOCATE:
@@ -737,17 +735,21 @@ gst_fake_src_create_buffer (GstFakeSrc * src)
         g_assert (src->parent);
       }
       /* see if it's large enough */
-      if ((GST_BUFFER_SIZE (src->parent) - src->parentoffset) >= size) {
-        buf = gst_buffer_create_sub (src->parent, src->parentoffset, size);
+      if ((src->parentsize - src->parentoffset) >= size) {
+        buf =
+            gst_buffer_copy_region (src->parent, GST_BUFFER_COPY_ALL,
+            src->parentoffset, size);
         src->parentoffset += size;
       } else {
         /* the parent is useless now */
         gst_buffer_unref (src->parent);
         src->parent = NULL;
         /* try again (this will allocate a new parent) */
-        return gst_fake_src_create_buffer (src);
+        return gst_fake_src_create_buffer (src, bufsize);
       }
-      gst_fake_src_prepare_buffer (src, buf);
+      data = gst_buffer_map (buf, &size, NULL, GST_MAP_WRITE);
+      gst_fake_src_prepare_buffer (src, data, size);
+      gst_buffer_unmap (buf, data, size);
       break;
     default:
       g_warning ("fakesrc: dunno how to allocate buffers !");
@@ -755,7 +757,9 @@ gst_fake_src_create_buffer (GstFakeSrc * src)
       break;
   }
   if (dump) {
-    gst_util_dump_mem (GST_BUFFER_DATA (buf), GST_BUFFER_SIZE (buf));
+    data = gst_buffer_map (buf, &size, NULL, GST_MAP_READ);
+    gst_util_dump_mem (data, size);
+    gst_buffer_unmap (buf, data, size);
   }
 
   return buf;
@@ -795,17 +799,17 @@ gst_fake_src_create (GstBaseSrc * basesrc, guint64 offset, guint length,
   GstFakeSrc *src;
   GstBuffer *buf;
   GstClockTime time;
+  gsize size;
 
   src = GST_FAKE_SRC (basesrc);
 
-  buf = gst_fake_src_create_buffer (src);
+  buf = gst_fake_src_create_buffer (src, &size);
   GST_BUFFER_OFFSET (buf) = src->buffer_count++;
 
   if (src->datarate > 0) {
     time = (src->bytes_sent * GST_SECOND) / src->datarate;
 
-    GST_BUFFER_DURATION (buf) =
-        GST_BUFFER_SIZE (buf) * GST_SECOND / src->datarate;
+    GST_BUFFER_DURATION (buf) = size * GST_SECOND / src->datarate;
   } else if (gst_base_src_is_live (basesrc)) {
     GstClock *clock;
 
@@ -848,9 +852,9 @@ gst_fake_src_create (GstBaseSrc * basesrc, guint64 offset, guint length,
     src->last_message =
         g_strdup_printf ("get      ******* > (%5d bytes, timestamp: %s"
         ", duration: %s, offset: %" G_GINT64_FORMAT ", offset_end: %"
-        G_GINT64_FORMAT ", flags: %d) %p", GST_BUFFER_SIZE (buf), ts_str,
+        G_GINT64_FORMAT ", flags: %d) %p", (gint) size, ts_str,
         dur_str, GST_BUFFER_OFFSET (buf), GST_BUFFER_OFFSET_END (buf),
-        GST_MINI_OBJECT (buf)->flags, buf);
+        GST_MINI_OBJECT_CAST (buf)->flags, buf);
     GST_OBJECT_UNLOCK (src);
 
 #if !GLIB_CHECK_VERSION(2,26,0)
@@ -867,7 +871,7 @@ gst_fake_src_create (GstBaseSrc * basesrc, guint64 offset, guint length,
     GST_LOG_OBJECT (src, "post handoff emit");
   }
 
-  src->bytes_sent += GST_BUFFER_SIZE (buf);
+  src->bytes_sent += size;
 
   *ret = buf;
   return GST_FLOW_OK;
index 6383d2a..b010929 100644 (file)
@@ -94,23 +94,11 @@ enum
 static void gst_fd_sink_uri_handler_init (gpointer g_iface,
     gpointer iface_data);
 
-static void
-_do_init (GType gst_fd_sink_type)
-{
-  static const GInterfaceInfo urihandler_info = {
-    gst_fd_sink_uri_handler_init,
-    NULL,
-    NULL
-  };
-
-  g_type_add_interface_static (gst_fd_sink_type, GST_TYPE_URI_HANDLER,
-      &urihandler_info);
-
+#define _do_init \
+  G_IMPLEMENT_INTERFACE (GST_TYPE_URI_HANDLER, gst_fd_sink_uri_handler_init); \
   GST_DEBUG_CATEGORY_INIT (gst_fd_sink__debug, "fdsink", 0, "fdsink element");
-}
-
-GST_BOILERPLATE_FULL (GstFdSink, gst_fd_sink, GstBaseSink, GST_TYPE_BASE_SINK,
-    _do_init);
+#define gst_fd_sink_parent_class parent_class
+G_DEFINE_TYPE_WITH_CODE (GstFdSink, gst_fd_sink, GST_TYPE_BASE_SINK, _do_init);
 
 static void gst_fd_sink_set_property (GObject * object, guint prop_id,
     const GValue * value, GParamSpec * pspec);
@@ -130,31 +118,27 @@ static gboolean gst_fd_sink_event (GstBaseSink * sink, GstEvent * event);
 static gboolean gst_fd_sink_do_seek (GstFdSink * fdsink, guint64 new_offset);
 
 static void
-gst_fd_sink_base_init (gpointer g_class)
-{
-  GstElementClass *gstelement_class = GST_ELEMENT_CLASS (g_class);
-
-  gst_element_class_set_details_simple (gstelement_class,
-      "Filedescriptor Sink",
-      "Sink/File",
-      "Write data to a file descriptor", "Erik Walthinsen <omega@cse.ogi.edu>");
-  gst_element_class_add_pad_template (gstelement_class,
-      gst_static_pad_template_get (&sinktemplate));
-}
-
-static void
 gst_fd_sink_class_init (GstFdSinkClass * klass)
 {
   GObjectClass *gobject_class;
+  GstElementClass *gstelement_class;
   GstBaseSinkClass *gstbasesink_class;
 
   gobject_class = G_OBJECT_CLASS (klass);
+  gstelement_class = GST_ELEMENT_CLASS (klass);
   gstbasesink_class = GST_BASE_SINK_CLASS (klass);
 
   gobject_class->set_property = gst_fd_sink_set_property;
   gobject_class->get_property = gst_fd_sink_get_property;
   gobject_class->dispose = gst_fd_sink_dispose;
 
+  gst_element_class_set_details_simple (gstelement_class,
+      "Filedescriptor Sink",
+      "Sink/File",
+      "Write data to a file descriptor", "Erik Walthinsen <omega@cse.ogi.edu>");
+  gst_element_class_add_pad_template (gstelement_class,
+      gst_static_pad_template_get (&sinktemplate));
+
   gstbasesink_class->render = GST_DEBUG_FUNCPTR (gst_fd_sink_render);
   gstbasesink_class->start = GST_DEBUG_FUNCPTR (gst_fd_sink_start);
   gstbasesink_class->stop = GST_DEBUG_FUNCPTR (gst_fd_sink_stop);
@@ -168,7 +152,7 @@ gst_fd_sink_class_init (GstFdSinkClass * klass)
 }
 
 static void
-gst_fd_sink_init (GstFdSink * fdsink, GstFdSinkClass * klass)
+gst_fd_sink_init (GstFdSink * fdsink)
 {
   GstPad *pad;
 
@@ -231,8 +215,8 @@ static GstFlowReturn
 gst_fd_sink_render (GstBaseSink * sink, GstBuffer * buffer)
 {
   GstFdSink *fdsink;
-  guint8 *data;
-  guint size;
+  guint8 *data, *ptr;
+  gsize size, left;
   gint written;
 
 #ifndef HAVE_WIN32
@@ -243,8 +227,10 @@ gst_fd_sink_render (GstBaseSink * sink, GstBuffer * buffer)
 
   g_return_val_if_fail (fdsink->fd >= 0, GST_FLOW_ERROR);
 
-  data = GST_BUFFER_DATA (buffer);
-  size = GST_BUFFER_SIZE (buffer);
+  data = gst_buffer_map (buffer, &size, NULL, GST_MAP_READ);
+
+  ptr = data;
+  left = size;
 
 again:
 #ifndef HAVE_WIN32
@@ -265,7 +251,7 @@ again:
   GST_DEBUG_OBJECT (fdsink, "writing %d bytes to file descriptor %d", size,
       fdsink->fd);
 
-  written = write (fdsink->fd, data, size);
+  written = write (fdsink->fd, ptr, left);
 
   /* check for errors */
   if (G_UNLIKELY (written < 0)) {
@@ -278,17 +264,20 @@ again:
   }
 
   /* all is fine when we get here */
-  size -= written;
-  data += written;
+  left -= written;
+  ptr += written;
   fdsink->bytes_written += written;
   fdsink->current_pos += written;
 
-  GST_DEBUG_OBJECT (fdsink, "wrote %d bytes, %d left", written, size);
+  GST_DEBUG_OBJECT (fdsink, "wrote %d bytes, %" G_GSIZE_FORMAT " left", written,
+      left);
 
   /* short write, select and try to write the remainder */
-  if (G_UNLIKELY (size > 0))
+  if (G_UNLIKELY (left > 0))
     goto again;
 
+  gst_buffer_unmap (buffer, data, size);
+
   return GST_FLOW_OK;
 
 #ifndef HAVE_WIN32
@@ -297,11 +286,13 @@ select_error:
     GST_ELEMENT_ERROR (fdsink, RESOURCE, READ, (NULL),
         ("select on file descriptor: %s.", g_strerror (errno)));
     GST_DEBUG_OBJECT (fdsink, "Error during select");
+    gst_buffer_unmap (buffer, data, size);
     return GST_FLOW_ERROR;
   }
 stopped:
   {
     GST_DEBUG_OBJECT (fdsink, "Select stopped");
+    gst_buffer_unmap (buffer, data, size);
     return GST_FLOW_WRONG_STATE;
   }
 #endif
@@ -318,6 +309,7 @@ write_error:
                 fdsink->fd, g_strerror (errno)));
       }
     }
+    gst_buffer_unmap (buffer, data, size);
     return GST_FLOW_ERROR;
   }
 }
@@ -546,28 +538,27 @@ gst_fd_sink_event (GstBaseSink * sink, GstEvent * event)
   type = GST_EVENT_TYPE (event);
 
   switch (type) {
-    case GST_EVENT_NEWSEGMENT:
+    case GST_EVENT_SEGMENT:
     {
-      gint64 start, stop, pos;
-      GstFormat format;
-      gst_event_parse_new_segment (event, NULL, NULL, &format, &start,
-          &stop, &pos);
+      const GstSegment *segment;
+
+      gst_event_parse_segment (event, &segment);
 
-      if (format == GST_FORMAT_BYTES) {
+      if (segment->format == GST_FORMAT_BYTES) {
         /* only try to seek and fail when we are going to a different
          * position */
-        if (fdsink->current_pos != start) {
+        if (fdsink->current_pos != segment->start) {
           /* FIXME, the seek should be performed on the pos field, start/stop are
            * just boundaries for valid bytes offsets. We should also fill the file
            * with zeroes if the new position extends the current EOF (sparse streams
            * and segment accumulation). */
-          if (!gst_fd_sink_do_seek (fdsink, (guint64) start))
+          if (!gst_fd_sink_do_seek (fdsink, (guint64) segment->start))
             goto seek_failed;
         }
       } else {
         GST_DEBUG_OBJECT (fdsink,
-            "Ignored NEWSEGMENT event of format %u (%s)", (guint) format,
-            gst_format_get_name (format));
+            "Ignored SEGMENT event of format %u (%s)", (guint) segment->format,
+            gst_format_get_name (segment->format));
       }
       break;
     }
index 3d38c6c..eea0af8 100644 (file)
@@ -113,23 +113,11 @@ enum
 
 static void gst_fd_src_uri_handler_init (gpointer g_iface, gpointer iface_data);
 
-static void
-_do_init (GType fd_src_type)
-{
-  static const GInterfaceInfo urihandler_info = {
-    gst_fd_src_uri_handler_init,
-    NULL,
-    NULL
-  };
-
-  g_type_add_interface_static (fd_src_type, GST_TYPE_URI_HANDLER,
-      &urihandler_info);
-
+#define _do_init \
+  G_IMPLEMENT_INTERFACE (GST_TYPE_URI_HANDLER, gst_fd_src_uri_handler_init); \
   GST_DEBUG_CATEGORY_INIT (gst_fd_src_debug, "fdsrc", 0, "fdsrc element");
-}
-
-GST_BOILERPLATE_FULL (GstFdSrc, gst_fd_src, GstPushSrc, GST_TYPE_PUSH_SRC,
-    _do_init);
+#define gst_fd_src_parent_class parent_class
+G_DEFINE_TYPE_WITH_CODE (GstFdSrc, gst_fd_src, GST_TYPE_PUSH_SRC, _do_init);
 
 static void gst_fd_src_set_property (GObject * object, guint prop_id,
     const GValue * value, GParamSpec * pspec);
@@ -149,26 +137,15 @@ static gboolean gst_fd_src_query (GstBaseSrc * src, GstQuery * query);
 static GstFlowReturn gst_fd_src_create (GstPushSrc * psrc, GstBuffer ** outbuf);
 
 static void
-gst_fd_src_base_init (gpointer g_class)
-{
-  GstElementClass *gstelement_class = GST_ELEMENT_CLASS (g_class);
-
-  gst_element_class_set_details_simple (gstelement_class,
-      "Filedescriptor Source",
-      "Source/File",
-      "Read from a file descriptor", "Erik Walthinsen <omega@cse.ogi.edu>");
-  gst_element_class_add_pad_template (gstelement_class,
-      gst_static_pad_template_get (&srctemplate));
-}
-
-static void
 gst_fd_src_class_init (GstFdSrcClass * klass)
 {
   GObjectClass *gobject_class;
+  GstElementClass *gstelement_class;
   GstBaseSrcClass *gstbasesrc_class;
   GstPushSrcClass *gstpush_src_class;
 
   gobject_class = G_OBJECT_CLASS (klass);
+  gstelement_class = GST_ELEMENT_CLASS (klass);
   gstbasesrc_class = GST_BASE_SRC_CLASS (klass);
   gstpush_src_class = GST_PUSH_SRC_CLASS (klass);
 
@@ -192,6 +169,13 @@ gst_fd_src_class_init (GstFdSrcClass * klass)
           G_MAXUINT64, DEFAULT_TIMEOUT,
           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
 
+  gst_element_class_set_details_simple (gstelement_class,
+      "Filedescriptor Source",
+      "Source/File",
+      "Read from a file descriptor", "Erik Walthinsen <omega@cse.ogi.edu>");
+  gst_element_class_add_pad_template (gstelement_class,
+      gst_static_pad_template_get (&srctemplate));
+
   gstbasesrc_class->start = GST_DEBUG_FUNCPTR (gst_fd_src_start);
   gstbasesrc_class->stop = GST_DEBUG_FUNCPTR (gst_fd_src_stop);
   gstbasesrc_class->unlock = GST_DEBUG_FUNCPTR (gst_fd_src_unlock);
@@ -205,7 +189,7 @@ gst_fd_src_class_init (GstFdSrcClass * klass)
 }
 
 static void
-gst_fd_src_init (GstFdSrc * fdsrc, GstFdSrcClass * klass)
+gst_fd_src_init (GstFdSrc * fdsrc)
 {
   fdsrc->new_fd = DEFAULT_FD;
   fdsrc->seekable_fd = FALSE;
@@ -409,6 +393,8 @@ gst_fd_src_create (GstPushSrc * psrc, GstBuffer ** outbuf)
   gssize readbytes;
   guint blocksize;
   GstClockTime timeout;
+  guint8 *data;
+  gsize maxsize;
 
 #ifndef HAVE_WIN32
   gboolean try_again;
@@ -456,25 +442,26 @@ gst_fd_src_create (GstPushSrc * psrc, GstBuffer ** outbuf)
   blocksize = GST_BASE_SRC (src)->blocksize;
 
   /* create the buffer */
-  buf = gst_buffer_try_new_and_alloc (blocksize);
-  if (G_UNLIKELY (buf == NULL)) {
-    GST_ERROR_OBJECT (src, "Failed to allocate %u bytes", blocksize);
-    return GST_FLOW_ERROR;
-  }
+  buf = gst_buffer_new_allocate (NULL, blocksize, 0);
+  if (G_UNLIKELY (buf == NULL))
+    goto alloc_failed;
+
+  data = gst_buffer_map (buf, NULL, &maxsize, GST_MAP_WRITE);
 
   do {
-    readbytes = read (src->fd, GST_BUFFER_DATA (buf), blocksize);
+    readbytes = read (src->fd, data, blocksize);
     GST_LOG_OBJECT (src, "read %" G_GSSIZE_FORMAT, readbytes);
   } while (readbytes == -1 && errno == EINTR);  /* retry if interrupted */
 
   if (readbytes < 0)
     goto read_error;
 
+  gst_buffer_unmap (buf, data, readbytes);
+
   if (readbytes == 0)
     goto eos;
 
   GST_BUFFER_OFFSET (buf) = src->curoffset;
-  GST_BUFFER_SIZE (buf) = readbytes;
   GST_BUFFER_TIMESTAMP (buf) = GST_CLOCK_TIME_NONE;
   src->curoffset += readbytes;
 
@@ -500,6 +487,11 @@ stopped:
     return GST_FLOW_WRONG_STATE;
   }
 #endif
+alloc_failed:
+  {
+    GST_ERROR_OBJECT (src, "Failed to allocate %u bytes", blocksize);
+    return GST_FLOW_ERROR;
+  }
 eos:
   {
     GST_DEBUG_OBJECT (psrc, "Read 0 bytes. EOS.");
@@ -511,6 +503,7 @@ read_error:
     GST_ELEMENT_ERROR (src, RESOURCE, READ, (NULL),
         ("read on file descriptor: %s.", g_strerror (errno)));
     GST_DEBUG_OBJECT (psrc, "Error reading from fd");
+    gst_buffer_unmap (buf, data, 0);
     gst_buffer_unref (buf);
     return GST_FLOW_ERROR;
   }
@@ -594,7 +587,7 @@ gst_fd_src_do_seek (GstBaseSrc * bsrc, GstSegment * segment)
   if (G_UNLIKELY (res < 0 || res != offset))
     goto seek_failed;
 
-  segment->last_stop = segment->start;
+  segment->position = segment->start;
   segment->time = segment->start;
 
   return TRUE;
index d5fa283..98ba6e2 100644 (file)
@@ -173,42 +173,18 @@ static gboolean gst_file_sink_query (GstPad * pad, GstQuery * query);
 static void gst_file_sink_uri_handler_init (gpointer g_iface,
     gpointer iface_data);
 
-
-static void
-_do_init (GType filesink_type)
-{
-  static const GInterfaceInfo urihandler_info = {
-    gst_file_sink_uri_handler_init,
-    NULL,
-    NULL
-  };
-
-  g_type_add_interface_static (filesink_type, GST_TYPE_URI_HANDLER,
-      &urihandler_info);
-  GST_DEBUG_CATEGORY_INIT (gst_file_sink_debug, "filesink", 0,
-      "filesink element");
-}
-
-GST_BOILERPLATE_FULL (GstFileSink, gst_file_sink, GstBaseSink,
-    GST_TYPE_BASE_SINK, _do_init);
-
-static void
-gst_file_sink_base_init (gpointer g_class)
-{
-  GstElementClass *gstelement_class = GST_ELEMENT_CLASS (g_class);
-
-  gst_element_class_set_details_simple (gstelement_class,
-      "File Sink",
-      "Sink/File", "Write stream to a file",
-      "Thomas Vander Stichele <thomas at apestaart dot org>");
-  gst_element_class_add_pad_template (gstelement_class,
-      gst_static_pad_template_get (&sinktemplate));
-}
+#define _do_init \
+  G_IMPLEMENT_INTERFACE (GST_TYPE_URI_HANDLER, gst_file_sink_uri_handler_init); \
+  GST_DEBUG_CATEGORY_INIT (gst_file_sink_debug, "filesink", 0, "filesink element");
+#define gst_file_sink_parent_class parent_class
+G_DEFINE_TYPE_WITH_CODE (GstFileSink, gst_file_sink, GST_TYPE_BASE_SINK,
+    _do_init);
 
 static void
 gst_file_sink_class_init (GstFileSinkClass * klass)
 {
   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+  GstElementClass *gstelement_class = GST_ELEMENT_CLASS (klass);
   GstBaseSinkClass *gstbasesink_class = GST_BASE_SINK_CLASS (klass);
 
   gobject_class->dispose = gst_file_sink_dispose;
@@ -244,6 +220,13 @@ gst_file_sink_class_init (GstFileSinkClass * klass)
           "Append to an already existing file", DEFAULT_APPEND,
           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
 
+  gst_element_class_set_details_simple (gstelement_class,
+      "File Sink",
+      "Sink/File", "Write stream to a file",
+      "Thomas Vander Stichele <thomas at apestaart dot org>");
+  gst_element_class_add_pad_template (gstelement_class,
+      gst_static_pad_template_get (&sinktemplate));
+
   gstbasesink_class->start = GST_DEBUG_FUNCPTR (gst_file_sink_start);
   gstbasesink_class->stop = GST_DEBUG_FUNCPTR (gst_file_sink_stop);
   gstbasesink_class->render = GST_DEBUG_FUNCPTR (gst_file_sink_render);
@@ -256,7 +239,7 @@ gst_file_sink_class_init (GstFileSinkClass * klass)
 }
 
 static void
-gst_file_sink_init (GstFileSink * filesink, GstFileSinkClass * g_class)
+gst_file_sink_init (GstFileSink * filesink)
 {
   GstPad *pad;
 
@@ -558,31 +541,29 @@ gst_file_sink_event (GstBaseSink * sink, GstEvent * event)
   type = GST_EVENT_TYPE (event);
 
   switch (type) {
-    case GST_EVENT_NEWSEGMENT:
+    case GST_EVENT_SEGMENT:
     {
-      gint64 start, stop, pos;
-      GstFormat format;
+      const GstSegment *segment;
 
-      gst_event_parse_new_segment (event, NULL, NULL, &format, &start,
-          &stop, &pos);
+      gst_event_parse_segment (event, &segment);
 
-      if (format == GST_FORMAT_BYTES) {
+      if (segment->format == GST_FORMAT_BYTES) {
         /* only try to seek and fail when we are going to a different
          * position */
-        if (filesink->current_pos != start) {
+        if (filesink->current_pos != segment->start) {
           /* FIXME, the seek should be performed on the pos field, start/stop are
            * just boundaries for valid bytes offsets. We should also fill the file
            * with zeroes if the new position extends the current EOF (sparse streams
            * and segment accumulation). */
-          if (!gst_file_sink_do_seek (filesink, (guint64) start))
+          if (!gst_file_sink_do_seek (filesink, (guint64) segment->start))
             goto seek_failed;
         } else {
-          GST_DEBUG_OBJECT (filesink, "Ignored NEWSEGMENT, no seek needed");
+          GST_DEBUG_OBJECT (filesink, "Ignored SEGMENT, no seek needed");
         }
       } else {
         GST_DEBUG_OBJECT (filesink,
-            "Ignored NEWSEGMENT event of format %u (%s)", (guint) format,
-            gst_format_get_name (format));
+            "Ignored SEGMENT event of format %u (%s)", (guint) segment->format,
+            gst_format_get_name (segment->format));
       }
       break;
     }
@@ -640,13 +621,12 @@ static GstFlowReturn
 gst_file_sink_render (GstBaseSink * sink, GstBuffer * buffer)
 {
   GstFileSink *filesink;
-  guint size;
+  gsize size;
   guint8 *data;
 
   filesink = GST_FILE_SINK (sink);
 
-  size = GST_BUFFER_SIZE (buffer);
-  data = GST_BUFFER_DATA (buffer);
+  data = gst_buffer_map (buffer, &size, NULL, GST_MAP_READ);
 
   GST_DEBUG_OBJECT (filesink, "writing %u bytes at %" G_GUINT64_FORMAT,
       size, filesink->current_pos);
@@ -657,6 +637,7 @@ gst_file_sink_render (GstBaseSink * sink, GstBuffer * buffer)
 
     filesink->current_pos += size;
   }
+  gst_buffer_unmap (buffer, data, size);
 
   return GST_FLOW_OK;
 
@@ -673,6 +654,7 @@ handle_error:
             ("%s", g_strerror (errno)));
       }
     }
+    gst_buffer_unmap (buffer, data, size);
     return GST_FLOW_ERROR;
   }
 }
index f8dbfe2..bed3590 100644 (file)
 #  include <unistd.h>
 #endif
 
-#ifdef HAVE_MMAP
-# include <sys/mman.h>
-#endif
-
 #include <errno.h>
 #include <string.h>
 
@@ -119,46 +115,6 @@ gst_open (const gchar * filename, int flags, int mode)
 #endif
 }
 
-
-/**********************************************************************
- * GStreamer Default File Source
- * Theory of Operation
- *
- * Update: see GstFileSrc:use-mmap property documentation below
- *         for why use of mmap() is disabled by default.
- *
- * This source uses mmap(2) to efficiently load data from a file.
- * To do this without seriously polluting the applications' memory
- * space, it must do so in smaller chunks, say 1-4MB at a time.
- * Buffers are then subdivided from these mmap'd chunks, to directly
- * make use of the mmap.
- *
- * To handle refcounting so that the mmap can be freed at the appropriate
- * time, a buffer will be created for each mmap'd region, and all new
- * buffers will be sub-buffers of this top-level buffer.  As they are
- * freed, the refcount goes down on the mmap'd buffer and its free()
- * function is called, which will call munmap(2) on itself.
- *
- * If a buffer happens to cross the boundaries of an mmap'd region, we
- * have to decide whether it's more efficient to copy the data into a
- * new buffer, or mmap() just that buffer.  There will have to be a
- * breakpoint size to determine which will be done.  The mmap() size
- * has a lot to do with this as well, because you end up in double-
- * jeopardy: the larger the outgoing buffer, the more data to copy when
- * it overlaps, *and* the more frequently you'll have buffers that *do*
- * overlap.
- *
- * Seeking is another tricky aspect to do efficiently.  The initial
- * implementation of this source won't make use of these features, however.
- * The issue is that if an application seeks backwards in a file, *and*
- * that region of the file is covered by an mmap that hasn't been fully
- * deallocated, we really should re-use it.  But keeping track of these
- * regions is tricky because we have to lock the structure that holds
- * them.  We need to settle on a locking primitive (GMutex seems to be
- * a really good option...), then we can do that.
- */
-
-
 GST_DEBUG_CATEGORY_STATIC (gst_file_src_debug);
 #define GST_CAT_DEFAULT gst_file_src_debug
 
@@ -170,20 +126,12 @@ enum
 };
 
 #define DEFAULT_BLOCKSIZE       4*1024
-#define DEFAULT_MMAPSIZE        4*1024*1024
-#define DEFAULT_TOUCH           TRUE
-#define DEFAULT_USEMMAP         FALSE
-#define DEFAULT_SEQUENTIAL      FALSE
 
 enum
 {
-  ARG_0,
-  ARG_LOCATION,
-  ARG_FD,
-  ARG_MMAPSIZE,
-  ARG_SEQUENTIAL,
-  ARG_TOUCH,
-  ARG_USEMMAP
+  PROP_0,
+  PROP_LOCATION,
+  PROP_FD
 };
 
 static void gst_file_src_finalize (GObject * object);
@@ -198,113 +146,58 @@ static gboolean gst_file_src_stop (GstBaseSrc * basesrc);
 
 static gboolean gst_file_src_is_seekable (GstBaseSrc * src);
 static gboolean gst_file_src_get_size (GstBaseSrc * src, guint64 * size);
-static GstFlowReturn gst_file_src_create (GstBaseSrc * src, guint64 offset,
-    guint length, GstBuffer ** buffer);
+static GstFlowReturn gst_file_src_fill (GstBaseSrc * src, guint64 offset,
+    guint length, GstBuffer * buf);
 static gboolean gst_file_src_query (GstBaseSrc * src, GstQuery * query);
 
 static void gst_file_src_uri_handler_init (gpointer g_iface,
     gpointer iface_data);
 
-static void
-_do_init (GType filesrc_type)
-{
-  static const GInterfaceInfo urihandler_info = {
-    gst_file_src_uri_handler_init,
-    NULL,
-    NULL
-  };
-
-  g_type_add_interface_static (filesrc_type, GST_TYPE_URI_HANDLER,
-      &urihandler_info);
+#define _do_init \
+  G_IMPLEMENT_INTERFACE (GST_TYPE_URI_HANDLER, gst_file_src_uri_handler_init); \
   GST_DEBUG_CATEGORY_INIT (gst_file_src_debug, "filesrc", 0, "filesrc element");
-}
-
-GST_BOILERPLATE_FULL (GstFileSrc, gst_file_src, GstBaseSrc, GST_TYPE_BASE_SRC,
-    _do_init);
-
-static void
-gst_file_src_base_init (gpointer g_class)
-{
-  GstElementClass *gstelement_class = GST_ELEMENT_CLASS (g_class);
-
-  gst_element_class_set_details_simple (gstelement_class,
-      "File Source",
-      "Source/File",
-      "Read from arbitrary point in a file",
-      "Erik Walthinsen <omega@cse.ogi.edu>");
-  gst_element_class_add_pad_template (gstelement_class,
-      gst_static_pad_template_get (&srctemplate));
-}
+#define gst_file_src_parent_class parent_class
+G_DEFINE_TYPE_WITH_CODE (GstFileSrc, gst_file_src, GST_TYPE_BASE_SRC, _do_init);
 
 static void
 gst_file_src_class_init (GstFileSrcClass * klass)
 {
   GObjectClass *gobject_class;
+  GstElementClass *gstelement_class;
   GstBaseSrcClass *gstbasesrc_class;
 
   gobject_class = G_OBJECT_CLASS (klass);
+  gstelement_class = GST_ELEMENT_CLASS (klass);
   gstbasesrc_class = GST_BASE_SRC_CLASS (klass);
 
   gobject_class->set_property = gst_file_src_set_property;
   gobject_class->get_property = gst_file_src_get_property;
 
-  g_object_class_install_property (gobject_class, ARG_FD,
+  g_object_class_install_property (gobject_class, PROP_FD,
       g_param_spec_int ("fd", "File-descriptor",
           "File-descriptor for the file being mmap()d", 0, G_MAXINT, 0,
           G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
-  g_object_class_install_property (gobject_class, ARG_LOCATION,
+  g_object_class_install_property (gobject_class, PROP_LOCATION,
       g_param_spec_string ("location", "File Location",
           "Location of the file to read", NULL,
           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
           GST_PARAM_MUTABLE_READY));
-  g_object_class_install_property (gobject_class, ARG_MMAPSIZE,
-      g_param_spec_ulong ("mmapsize", "mmap() Block Size",
-          "Size in bytes of mmap()d regions", 0, G_MAXULONG, DEFAULT_MMAPSIZE,
-          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
-          GST_PARAM_MUTABLE_PLAYING));
-  g_object_class_install_property (gobject_class, ARG_TOUCH,
-      g_param_spec_boolean ("touch", "Touch mapped region read data",
-          "Touch mmapped data regions to force them to be read from disk",
-          DEFAULT_TOUCH,
-          G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
-          GST_PARAM_MUTABLE_PLAYING));
-  /**
-   * GstFileSrc:use-mmap
-   *
-   * Whether to use mmap(). Set to TRUE to force use of mmap() instead of
-   * read() for reading data.
-   *
-   * Use of mmap() is disabled by default since with mmap() there are a
-   * number of occasions where the process/application will be notified of
-   * read errors via a SIGBUS signal from the kernel, which will lead to
-   * the application being killed if not handled by the application. This
-   * is something that is difficult to work around for a library like
-   * GStreamer, hence use of mmap() is disabled by default. Said errors
-   * can occur for example when an external device (e.g. an external hard
-   * drive or a portable music player) are unplugged while in use, or when
-   * a CD/DVD medium cannot be be read because the medium is scratched or
-   * otherwise damaged.
-   *
-   **/
-  g_object_class_install_property (gobject_class, ARG_USEMMAP,
-      g_param_spec_boolean ("use-mmap", "Use mmap to read data",
-          "Whether to use mmap() instead of read()",
-          DEFAULT_USEMMAP, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
-          GST_PARAM_MUTABLE_READY));
-  g_object_class_install_property (gobject_class, ARG_SEQUENTIAL,
-      g_param_spec_boolean ("sequential", "Optimise for sequential mmap access",
-          "Whether to use madvise to hint to the kernel that access to "
-          "mmap pages will be sequential",
-          DEFAULT_SEQUENTIAL, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS |
-          GST_PARAM_MUTABLE_PLAYING));
 
   gobject_class->finalize = gst_file_src_finalize;
 
+  gst_element_class_set_details_simple (gstelement_class,
+      "File Source",
+      "Source/File",
+      "Read from arbitrary point in a file",
+      "Erik Walthinsen <omega@cse.ogi.edu>");
+  gst_element_class_add_pad_template (gstelement_class,
+      gst_static_pad_template_get (&srctemplate));
+
   gstbasesrc_class->start = GST_DEBUG_FUNCPTR (gst_file_src_start);
   gstbasesrc_class->stop = GST_DEBUG_FUNCPTR (gst_file_src_stop);
   gstbasesrc_class->is_seekable = GST_DEBUG_FUNCPTR (gst_file_src_is_seekable);
   gstbasesrc_class->get_size = GST_DEBUG_FUNCPTR (gst_file_src_get_size);
-  gstbasesrc_class->create = GST_DEBUG_FUNCPTR (gst_file_src_create);
+  gstbasesrc_class->fill = GST_DEBUG_FUNCPTR (gst_file_src_fill);
   gstbasesrc_class->query = GST_DEBUG_FUNCPTR (gst_file_src_query);
 
   if (sizeof (off_t) < 8) {
@@ -314,23 +207,12 @@ gst_file_src_class_init (GstFileSrcClass * klass)
 }
 
 static void
-gst_file_src_init (GstFileSrc * src, GstFileSrcClass * g_class)
+gst_file_src_init (GstFileSrc * src)
 {
-#ifdef HAVE_MMAP
-  src->pagesize = getpagesize ();
-#endif
-
   src->filename = NULL;
   src->fd = 0;
   src->uri = NULL;
 
-  src->touch = DEFAULT_TOUCH;
-
-  src->mapbuf = NULL;
-  src->mapsize = DEFAULT_MMAPSIZE;      /* default is 4MB */
-  src->use_mmap = DEFAULT_USEMMAP;
-  src->sequential = DEFAULT_SEQUENTIAL;
-
   src->is_regular = FALSE;
 }
 
@@ -400,27 +282,9 @@ gst_file_src_set_property (GObject * object, guint prop_id,
   src = GST_FILE_SRC (object);
 
   switch (prop_id) {
-    case ARG_LOCATION:
+    case PROP_LOCATION:
       gst_file_src_set_location (src, g_value_get_string (value));
       break;
-    case ARG_MMAPSIZE:
-      if ((src->mapsize % src->pagesize) == 0) {
-        src->mapsize = g_value_get_ulong (value);
-      } else {
-        GST_INFO_OBJECT (src,
-            "invalid mapsize, must be a multiple of pagesize, which is %d",
-            src->pagesize);
-      }
-      break;
-    case ARG_TOUCH:
-      src->touch = g_value_get_boolean (value);
-      break;
-    case ARG_SEQUENTIAL:
-      src->sequential = g_value_get_boolean (value);
-      break;
-    case ARG_USEMMAP:
-      src->use_mmap = g_value_get_boolean (value);
-      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -438,24 +302,12 @@ gst_file_src_get_property (GObject * object, guint prop_id, GValue * value,
   src = GST_FILE_SRC (object);
 
   switch (prop_id) {
-    case ARG_LOCATION:
+    case PROP_LOCATION:
       g_value_set_string (value, src->filename);
       break;
-    case ARG_FD:
+    case PROP_FD:
       g_value_set_int (value, src->fd);
       break;
-    case ARG_MMAPSIZE:
-      g_value_set_ulong (value, src->mapsize);
-      break;
-    case ARG_TOUCH:
-      g_value_set_boolean (value, src->touch);
-      break;
-    case ARG_SEQUENTIAL:
-      g_value_set_boolean (value, src->sequential);
-      break;
-    case ARG_USEMMAP:
-      g_value_set_boolean (value, src->use_mmap);
-      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -463,327 +315,6 @@ gst_file_src_get_property (GObject * object, guint prop_id, GValue * value,
 }
 
 /***
- * mmap code below
- */
-
-#ifdef HAVE_MMAP
-
-/* GstMmapBuffer */
-
-typedef struct _GstMmapBuffer GstMmapBuffer;
-typedef struct _GstMmapBufferClass GstMmapBufferClass;
-
-#define GST_TYPE_MMAP_BUFFER                         (gst_mmap_buffer_get_type())
-
-#define GST_IS_MMAP_BUFFER(obj)  (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_MMAP_BUFFER))
-#define GST_IS_MMAP_BUFFER_CLASS(klass)  (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_MMAP_BUFFER))
-#define GST_MMAP_BUFFER_GET_CLASS(obj)   (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_MMAP_BUFFER, GstMmapBufferClass))
-#define GST_MMAP_BUFFER(obj)     (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_MMAP_BUFFER, GstMmapBuffer))
-#define GST_MMAP_BUFFER_CLASS(klass)  (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_MMAP_BUFFER, GstMmapBufferClass))
-
-
-
-struct _GstMmapBuffer
-{
-  GstBuffer buffer;
-
-  GstFileSrc *filesrc;
-};
-
-struct _GstMmapBufferClass
-{
-  GstBufferClass buffer_class;
-};
-
-static void gst_mmap_buffer_finalize (GstMmapBuffer * mmap_buffer);
-
-GType gst_mmap_buffer_get_type (void);
-
-G_DEFINE_TYPE (GstMmapBuffer, gst_mmap_buffer, GST_TYPE_BUFFER);
-
-static void
-gst_mmap_buffer_class_init (GstMmapBufferClass * g_class)
-{
-  GstMiniObjectClass *mini_object_class = GST_MINI_OBJECT_CLASS (g_class);
-
-  mini_object_class->finalize =
-      (GstMiniObjectFinalizeFunction) gst_mmap_buffer_finalize;
-}
-
-static void
-gst_mmap_buffer_init (GstMmapBuffer * buf)
-{
-  GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_READONLY);
-  /* before we re-enable this flag, we probably need to fix _copy()
-   * _make_writable(), etc. in GstMiniObject/GstBuffer as well */
-  /* GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_ORIGINAL); */
-}
-
-static void
-gst_mmap_buffer_finalize (GstMmapBuffer * mmap_buffer)
-{
-  guint size;
-  gpointer data;
-  guint64 offset;
-  GstFileSrc *src;
-  GstBuffer *buffer = GST_BUFFER (mmap_buffer);
-
-  /* get info */
-  size = GST_BUFFER_SIZE (buffer);
-  offset = GST_BUFFER_OFFSET (buffer);
-  data = GST_BUFFER_DATA (buffer);
-  src = mmap_buffer->filesrc;
-
-  GST_LOG ("freeing mmap()d buffer at %" G_GUINT64_FORMAT "+%u", offset, size);
-
-#ifdef MADV_DONTNEED
-  /* madvise to tell the kernel what to do with it */
-  if (madvise (data, size, MADV_DONTNEED) < 0) {
-    GST_WARNING_OBJECT (src, "warning: madvise failed: %s", g_strerror (errno));
-  }
-#endif
-
-  /* now unmap the memory */
-  if (munmap (data, size) < 0) {
-    GST_WARNING_OBJECT (src, "warning: munmap failed: %s", g_strerror (errno));
-  }
-
-  /* cast to unsigned long, since there's no gportable way to print
-   * guint64 as hex */
-  GST_LOG ("unmapped region %08lx+%08lx at %p",
-      (gulong) offset, (gulong) size, data);
-
-  GST_MINI_OBJECT_CLASS (gst_mmap_buffer_parent_class)->finalize
-      (GST_MINI_OBJECT (mmap_buffer));
-}
-
-static GstBuffer *
-gst_file_src_map_region (GstFileSrc * src, off_t offset, gsize size,
-    gboolean testonly)
-{
-  GstBuffer *buf;
-  void *mmapregion;
-
-  g_return_val_if_fail (offset >= 0, NULL);
-
-  /* FIXME ? use goffset and friends if we require glib >= 2.20 */
-  GST_LOG_OBJECT (src, "mapping region %08" G_GINT64_MODIFIER "x+%08lx "
-      "from file into memory", (gint64) offset, (gulong) size);
-
-  mmapregion = mmap (NULL, size, PROT_READ, MAP_SHARED, src->fd, offset);
-
-  if (mmapregion == NULL || mmapregion == MAP_FAILED)
-    goto mmap_failed;
-
-  GST_LOG_OBJECT (src, "mapped region %08lx+%08lx from file into memory at %p",
-      (gulong) offset, (gulong) size, mmapregion);
-
-  /* time to allocate a new mapbuf */
-  buf = (GstBuffer *) gst_mini_object_new (GST_TYPE_MMAP_BUFFER);
-  /* mmap() the data into this new buffer */
-  GST_BUFFER_DATA (buf) = mmapregion;
-  GST_MMAP_BUFFER (buf)->filesrc = src;
-
-#ifdef MADV_SEQUENTIAL
-  if (src->sequential) {
-    /* madvise to tell the kernel what to do with it */
-    if (madvise (mmapregion, size, MADV_SEQUENTIAL) < 0) {
-      GST_WARNING_OBJECT (src, "warning: madvise failed: %s",
-          g_strerror (errno));
-    }
-  }
-#endif
-
-  /* fill in the rest of the fields */
-  GST_BUFFER_SIZE (buf) = size;
-  GST_BUFFER_OFFSET (buf) = offset;
-  GST_BUFFER_OFFSET_END (buf) = offset + size;
-  GST_BUFFER_TIMESTAMP (buf) = GST_CLOCK_TIME_NONE;
-
-  return buf;
-
-  /* ERROR */
-mmap_failed:
-  {
-    if (!testonly) {
-      GST_ELEMENT_ERROR (src, RESOURCE, READ, (NULL),
-          ("mmap (0x%08lx, %d, 0x%" G_GINT64_MODIFIER "x) failed: %s",
-              (gulong) size, src->fd, (guint64) offset, g_strerror (errno)));
-    }
-    return NULL;
-  }
-}
-
-static GstBuffer *
-gst_file_src_map_small_region (GstFileSrc * src, off_t offset, gsize size)
-{
-  GstBuffer *ret;
-  off_t mod;
-  guint pagesize;
-
-  GST_LOG_OBJECT (src,
-      "attempting to map a small buffer at %" G_GUINT64_FORMAT "+%d",
-      (guint64) offset, (gint) size);
-
-  pagesize = src->pagesize;
-
-  mod = offset % pagesize;
-
-  /* if the offset starts at a non-page boundary, we have to special case */
-  if (mod != 0) {
-    gsize mapsize;
-    off_t mapbase;
-    GstBuffer *map;
-
-    mapbase = offset - mod;
-    mapsize = ((size + mod + pagesize - 1) / pagesize) * pagesize;
-
-    GST_LOG_OBJECT (src,
-        "not on page boundaries, resizing to map to %" G_GUINT64_FORMAT "+%d",
-        (guint64) mapbase, (gint) mapsize);
-
-    map = gst_file_src_map_region (src, mapbase, mapsize, FALSE);
-    if (map == NULL)
-      return NULL;
-
-    ret = gst_buffer_create_sub (map, offset - mapbase, size);
-    GST_BUFFER_OFFSET (ret) = GST_BUFFER_OFFSET (map) + offset - mapbase;
-
-    gst_buffer_unref (map);
-  } else {
-    ret = gst_file_src_map_region (src, offset, size, FALSE);
-  }
-
-  return ret;
-}
-
-static GstFlowReturn
-gst_file_src_create_mmap (GstFileSrc * src, guint64 offset, guint length,
-    GstBuffer ** buffer)
-{
-  GstBuffer *buf = NULL;
-  gsize readsize, mapsize;
-  off_t readend, mapstart, mapend;
-  int i;
-
-  /* calculate end pointers so we don't have to do so repeatedly later */
-  readsize = length;
-  readend = offset + readsize;  /* note this is the byte *after* the read */
-
-  mapstart = GST_BUFFER_OFFSET (src->mapbuf);
-  mapsize = GST_BUFFER_SIZE (src->mapbuf);
-  mapend = mapstart + mapsize;  /* note this is the byte *after* the map */
-
-  GST_LOG ("attempting to read %08lx, %08lx, %08lx, %08lx",
-      (unsigned long) readsize, (unsigned long) readend,
-      (unsigned long) mapstart, (unsigned long) mapend);
-
-  /* if the start is past the mapstart */
-  if (offset >= mapstart) {
-    /* if the end is before the mapend, the buffer is in current mmap region... */
-    /* ('cause by definition if readend is in the buffer, so's readstart) */
-    if (readend <= mapend) {
-      GST_LOG_OBJECT (src, "read buf %" G_GUINT64_FORMAT "+%u lives in "
-          "current mapbuf %u+%u, creating subbuffer of mapbuf",
-          offset, (guint) readsize, (guint) mapstart, (guint) mapsize);
-      buf = gst_buffer_create_sub (src->mapbuf, offset - mapstart, readsize);
-      GST_BUFFER_OFFSET (buf) = offset;
-
-      /* if the start actually is within the current mmap region, map an overlap buffer */
-    } else if (offset < mapend) {
-      GST_LOG_OBJECT (src, "read buf %" G_GUINT64_FORMAT "+%u starts in "
-          "mapbuf %u+%u but ends outside, creating new mmap",
-          offset, (guint) readsize, (guint) mapstart, (guint) mapsize);
-      buf = gst_file_src_map_small_region (src, offset, readsize);
-      if (buf == NULL)
-        goto could_not_mmap;
-    }
-
-    /* the only other option is that buffer is totally outside, which means we search for it */
-
-    /* now we can assume that the start is *before* the current mmap region */
-    /* if the readend is past mapstart, we have two options */
-  } else if (readend >= mapstart) {
-    /* either the read buffer overlaps the start of the mmap region */
-    /* or the read buffer fully contains the current mmap region    */
-    /* either way, it's really not relevant, we just create a new region anyway */
-    GST_LOG_OBJECT (src, "read buf %" G_GUINT64_FORMAT "+%d starts before "
-        "mapbuf %d+%d, but overlaps it", (guint64) offset, (gint) readsize,
-        (gint) mapstart, (gint) mapsize);
-    buf = gst_file_src_map_small_region (src, offset, readsize);
-    if (buf == NULL)
-      goto could_not_mmap;
-  }
-
-  /* then deal with the case where the read buffer is totally outside */
-  if (buf == NULL) {
-    /* first check to see if there's a map that covers the right region already */
-    GST_LOG_OBJECT (src, "searching for mapbuf to cover %" G_GUINT64_FORMAT
-        "+%d", offset, (int) readsize);
-
-    /* if the read buffer crosses a mmap region boundary, create a one-off region */
-    if ((offset / src->mapsize) != (readend / src->mapsize)) {
-      GST_LOG_OBJECT (src, "read buf %" G_GUINT64_FORMAT "+%d crosses a "
-          "%d-byte boundary, creating a one-off", offset, (int) readsize,
-          (int) src->mapsize);
-      buf = gst_file_src_map_small_region (src, offset, readsize);
-      if (buf == NULL)
-        goto could_not_mmap;
-
-      /* otherwise we will create a new mmap region and set it to the default */
-    } else {
-      gsize mapsize;
-
-      off_t nextmap = offset - (offset % src->mapsize);
-
-      GST_LOG_OBJECT (src, "read buf %" G_GUINT64_FORMAT "+%d in new mapbuf "
-          "at %" G_GUINT64_FORMAT "+%d, mapping and subbuffering",
-          offset, (gint) readsize, (guint64) nextmap, (gint) src->mapsize);
-      /* first, we're done with the old mapbuf */
-      gst_buffer_unref (src->mapbuf);
-      mapsize = src->mapsize;
-
-      /* double the mapsize as long as the readsize is smaller */
-      while (readsize + offset > nextmap + mapsize) {
-        GST_LOG_OBJECT (src, "readsize smaller then mapsize %08x %d",
-            (guint) readsize, (gint) mapsize);
-        mapsize <<= 1;
-      }
-      /* create a new one */
-      src->mapbuf = gst_file_src_map_region (src, nextmap, mapsize, FALSE);
-      if (src->mapbuf == NULL)
-        goto could_not_mmap;
-
-      /* subbuffer it */
-      buf = gst_buffer_create_sub (src->mapbuf, offset - nextmap, readsize);
-      GST_BUFFER_OFFSET (buf) =
-          GST_BUFFER_OFFSET (src->mapbuf) + offset - nextmap;
-    }
-  }
-
-  /* if we need to touch the buffer (to bring it into memory), do so */
-  if (src->touch) {
-    volatile guchar *p = GST_BUFFER_DATA (buf);
-
-    /* read first byte of each page */
-    for (i = 0; i < GST_BUFFER_SIZE (buf); i += src->pagesize)
-      (void) p[i];
-  }
-
-  /* we're done, return the buffer */
-  *buffer = buf;
-
-  return GST_FLOW_OK;
-
-  /* ERROR */
-could_not_mmap:
-  {
-    return GST_FLOW_ERROR;
-  }
-}
-#endif
-
-/***
  * read code below
  * that is to say, you shouldn't read the code below, but the code that reads
  * stuff is below.  Well, you shouldn't not read the code below, feel free
@@ -793,13 +324,15 @@ could_not_mmap:
  * the sort of attitude we want to be advertising.  No sir.
  *
  */
-
 static GstFlowReturn
-gst_file_src_create_read (GstFileSrc * src, guint64 offset, guint length,
-    GstBuffer ** buffer)
+gst_file_src_fill (GstBaseSrc * basesrc, guint64 offset, guint length,
+    GstBuffer * buf)
 {
+  GstFileSrc *src;
   int ret;
-  GstBuffer *buf;
+  guint8 *data;
+
+  src = GST_FILE_SRC_CAST (basesrc);
 
   if (G_UNLIKELY (src->read_position != offset)) {
     off_t res;
@@ -811,37 +344,31 @@ gst_file_src_create_read (GstFileSrc * src, guint64 offset, guint length,
     src->read_position = offset;
   }
 
-  buf = gst_buffer_try_new_and_alloc (length);
-  if (G_UNLIKELY (buf == NULL && length > 0)) {
-    GST_ERROR_OBJECT (src, "Failed to allocate %u bytes", length);
-    return GST_FLOW_ERROR;
-  }
+  data = gst_buffer_map (buf, NULL, NULL, GST_MAP_WRITE);
 
-  /* No need to read anything if length is 0 */
-  if (length > 0) {
-    GST_LOG_OBJECT (src, "Reading %d bytes at offset 0x%" G_GINT64_MODIFIER "x",
-        length, offset);
-    ret = read (src->fd, GST_BUFFER_DATA (buf), length);
-    if (G_UNLIKELY (ret < 0))
-      goto could_not_read;
+  GST_LOG_OBJECT (src, "Reading %d bytes at offset 0x%" G_GINT64_MODIFIER "x",
+      length, offset);
 
-    /* seekable regular files should have given us what we expected */
-    if (G_UNLIKELY ((guint) ret < length && src->seekable))
-      goto unexpected_eos;
+  ret = read (src->fd, data, length);
+  if (G_UNLIKELY (ret < 0))
+    goto could_not_read;
 
-    /* other files should eos if they read 0 and more was requested */
-    if (G_UNLIKELY (ret == 0 && length > 0))
-      goto eos;
+  /* seekable regular files should have given us what we expected */
+  if (G_UNLIKELY ((guint) ret < length && src->seekable))
+    goto unexpected_eos;
 
-    length = ret;
-    GST_BUFFER_SIZE (buf) = length;
-    GST_BUFFER_OFFSET (buf) = offset;
-    GST_BUFFER_OFFSET_END (buf) = offset + length;
+  /* other files should eos if they read 0 and more was requested */
+  if (G_UNLIKELY (ret == 0))
+    goto eos;
 
-    src->read_position += length;
-  }
+  length = ret;
 
-  *buffer = buf;
+  gst_buffer_unmap (buf, data, length);
+
+  GST_BUFFER_OFFSET (buf) = offset;
+  GST_BUFFER_OFFSET_END (buf) = offset + length;
+
+  src->read_position += length;
 
   return GST_FLOW_OK;
 
@@ -854,46 +381,24 @@ seek_failed:
 could_not_read:
   {
     GST_ELEMENT_ERROR (src, RESOURCE, READ, (NULL), GST_ERROR_SYSTEM);
-    gst_buffer_unref (buf);
+    gst_buffer_unmap (buf, data, 0);
     return GST_FLOW_ERROR;
   }
 unexpected_eos:
   {
     GST_ELEMENT_ERROR (src, RESOURCE, READ, (NULL),
         ("unexpected end of file."));
-    gst_buffer_unref (buf);
+    gst_buffer_unmap (buf, data, 0);
     return GST_FLOW_ERROR;
   }
 eos:
   {
     GST_DEBUG ("non-regular file hits EOS");
-    gst_buffer_unref (buf);
+    gst_buffer_unmap (buf, data, 0);
     return GST_FLOW_UNEXPECTED;
   }
 }
 
-static GstFlowReturn
-gst_file_src_create (GstBaseSrc * basesrc, guint64 offset, guint length,
-    GstBuffer ** buffer)
-{
-  GstFileSrc *src;
-  GstFlowReturn ret;
-
-  src = GST_FILE_SRC_CAST (basesrc);
-
-#ifdef HAVE_MMAP
-  if (src->using_mmap) {
-    ret = gst_file_src_create_mmap (src, offset, length, buffer);
-  } else {
-    ret = gst_file_src_create_read (src, offset, length, buffer);
-  }
-#else
-  ret = gst_file_src_create_read (src, offset, length, buffer);
-#endif
-
-  return ret;
-}
-
 static gboolean
 gst_file_src_query (GstBaseSrc * basesrc, GstQuery * query)
 {
@@ -980,29 +485,14 @@ gst_file_src_start (GstBaseSrc * basesrc)
   if (S_ISSOCK (stat_results.st_mode))
     goto was_socket;
 
-  src->using_mmap = FALSE;
   src->read_position = 0;
 
   /* record if it's a regular (hence seekable and lengthable) file */
   if (S_ISREG (stat_results.st_mode))
     src->is_regular = TRUE;
 
-#ifdef HAVE_MMAP
-  if (src->use_mmap) {
-    /* FIXME: maybe we should only try to mmap if it's a regular file */
-    /* allocate the first mmap'd region if it's a regular file ? */
-    src->mapbuf = gst_file_src_map_region (src, 0, src->mapsize, TRUE);
-    if (src->mapbuf != NULL) {
-      GST_DEBUG_OBJECT (src, "using mmap for file");
-      src->using_mmap = TRUE;
-      src->seekable = TRUE;
-    }
-  }
-  if (src->mapbuf == NULL)
-#endif
+  /* We need to check if the underlying file is seekable. */
   {
-    /* If not in mmap mode, we need to check if the underlying file is
-     * seekable. */
     off_t res = lseek (src->fd, 0, SEEK_END);
 
     if (res < 0) {
@@ -1081,11 +571,6 @@ gst_file_src_stop (GstBaseSrc * basesrc)
   src->fd = 0;
   src->is_regular = FALSE;
 
-  if (src->mapbuf) {
-    gst_buffer_unref (src->mapbuf);
-    src->mapbuf = NULL;
-  }
-
   return TRUE;
 }
 
index dbd6fe4..5aa9f87 100644 (file)
@@ -55,23 +55,14 @@ struct _GstFileSrc {
   GstBaseSrc element;
 
   /*< private >*/
-  guint pagesize;                      /* system page size */
-
   gchar *filename;                     /* filename */
   gchar *uri;                          /* caching the URI */
   gint fd;                             /* open file descriptor */
   guint64 read_position;               /* position of fd */
 
-  gboolean touch;                      /* whether to touch every page */
-  gboolean using_mmap;                  /* whether we opened it with mmap */
-  gboolean sequential;                  /* Whether to madvise (MADV_SEQUENTIAL) 
-                                           for mmap pages */
   gboolean seekable;                    /* whether the file is seekable */
   gboolean is_regular;                  /* whether it's a (symlink to a)
                                            regular file */
-  GstBuffer *mapbuf;
-  size_t mapsize;
-  gboolean use_mmap;
 };
 
 struct _GstFileSrcClass {
index 4cb8c35..5b37e72 100644 (file)
@@ -105,45 +105,24 @@ GST_STATIC_PAD_TEMPLATE ("src",
     GST_PAD_ALWAYS,
     GST_STATIC_CAPS_ANY);
 
-static void
-_do_init (GType type)
-{
+#define _do_init \
   GST_DEBUG_CATEGORY_INIT (gst_funnel_debug, "funnel", 0, "funnel element");
-}
-
-GST_BOILERPLATE_FULL (GstFunnel, gst_funnel, GstElement, GST_TYPE_ELEMENT,
-    _do_init);
+#define gst_funnel_parent_class parent_class
+G_DEFINE_TYPE_WITH_CODE (GstFunnel, gst_funnel, GST_TYPE_ELEMENT, _do_init);
 
 static GstStateChangeReturn gst_funnel_change_state (GstElement * element,
     GstStateChange transition);
 static GstPad *gst_funnel_request_new_pad (GstElement * element,
-    GstPadTemplate * templ, const gchar * name);
+    GstPadTemplate * templ, const gchar * name, const GstCaps * caps);
 static void gst_funnel_release_pad (GstElement * element, GstPad * pad);
 
 static GstFlowReturn gst_funnel_sink_chain (GstPad * pad, GstBuffer * buffer);
-static GstFlowReturn gst_funnel_sink_buffer_alloc (GstPad * pad, guint64 offset,
-    guint size, GstCaps * caps, GstBuffer ** buf);
 static gboolean gst_funnel_sink_event (GstPad * pad, GstEvent * event);
-static GstCaps *gst_funnel_sink_getcaps (GstPad * pad);
+static GstCaps *gst_funnel_sink_getcaps (GstPad * pad, GstCaps * filter);
 
 static gboolean gst_funnel_src_event (GstPad * pad, GstEvent * event);
 
 static void
-gst_funnel_base_init (gpointer g_class)
-{
-  GstElementClass *gstelement_class = GST_ELEMENT_CLASS (g_class);
-
-  gst_element_class_set_details_simple (gstelement_class,
-      "Funnel pipe fitting", "Generic", "N-to-1 pipe fitting",
-      "Olivier Crete <olivier.crete@collabora.co.uk>");
-
-  gst_element_class_add_pad_template (gstelement_class,
-      gst_static_pad_template_get (&funnel_sink_template));
-  gst_element_class_add_pad_template (gstelement_class,
-      gst_static_pad_template_get (&funnel_src_template));
-}
-
-static void
 gst_funnel_dispose (GObject * object)
 {
   GList *item;
@@ -169,6 +148,15 @@ gst_funnel_class_init (GstFunnelClass * klass)
 
   gobject_class->dispose = GST_DEBUG_FUNCPTR (gst_funnel_dispose);
 
+  gst_element_class_set_details_simple (gstelement_class,
+      "Funnel pipe fitting", "Generic", "N-to-1 pipe fitting",
+      "Olivier Crete <olivier.crete@collabora.co.uk>");
+
+  gst_element_class_add_pad_template (gstelement_class,
+      gst_static_pad_template_get (&funnel_sink_template));
+  gst_element_class_add_pad_template (gstelement_class,
+      gst_static_pad_template_get (&funnel_src_template));
+
   gstelement_class->request_new_pad =
       GST_DEBUG_FUNCPTR (gst_funnel_request_new_pad);
   gstelement_class->release_pad = GST_DEBUG_FUNCPTR (gst_funnel_release_pad);
@@ -176,7 +164,7 @@ gst_funnel_class_init (GstFunnelClass * klass)
 }
 
 static void
-gst_funnel_init (GstFunnel * funnel, GstFunnelClass * g_class)
+gst_funnel_init (GstFunnel * funnel)
 {
   funnel->srcpad = gst_pad_new_from_static_template (&funnel_src_template,
       "src");
@@ -185,26 +173,9 @@ gst_funnel_init (GstFunnel * funnel, GstFunnelClass * g_class)
   gst_element_add_pad (GST_ELEMENT (funnel), funnel->srcpad);
 }
 
-static GstFlowReturn
-gst_funnel_sink_buffer_alloc (GstPad * pad, guint64 offset, guint size,
-    GstCaps * caps, GstBuffer ** buf)
-{
-  GstFunnel *funnel = GST_FUNNEL (gst_pad_get_parent_element (pad));
-  GstFlowReturn ret;
-
-  if (G_UNLIKELY (funnel == NULL))
-    return GST_FLOW_WRONG_STATE;
-
-  ret = gst_pad_alloc_buffer (funnel->srcpad, offset, size, caps, buf);
-
-  gst_object_unref (funnel);
-
-  return ret;
-}
-
 static GstPad *
 gst_funnel_request_new_pad (GstElement * element, GstPadTemplate * templ,
-    const gchar * name)
+    const gchar * name, const GstCaps * caps)
 {
   GstPad *sinkpad;
 
@@ -220,8 +191,6 @@ gst_funnel_request_new_pad (GstElement * element, GstPadTemplate * templ,
       GST_DEBUG_FUNCPTR (gst_funnel_sink_event));
   gst_pad_set_getcaps_function (sinkpad,
       GST_DEBUG_FUNCPTR (gst_funnel_sink_getcaps));
-  gst_pad_set_bufferalloc_function (sinkpad,
-      GST_DEBUG_FUNCPTR (gst_funnel_sink_buffer_alloc));
 
   gst_pad_set_active (sinkpad, TRUE);
 
@@ -243,7 +212,7 @@ gst_funnel_release_pad (GstElement * element, GstPad * pad)
 }
 
 static GstCaps *
-gst_funnel_sink_getcaps (GstPad * pad)
+gst_funnel_sink_getcaps (GstPad * pad, GstCaps * filter)
 {
   GstFunnel *funnel = GST_FUNNEL (gst_pad_get_parent (pad));
   GstCaps *caps;
@@ -251,9 +220,9 @@ gst_funnel_sink_getcaps (GstPad * pad)
   if (G_UNLIKELY (funnel == NULL))
     return gst_caps_new_any ();
 
-  caps = gst_pad_peer_get_caps_reffed (funnel->srcpad);
+  caps = gst_pad_peer_get_caps (funnel->srcpad, filter);
   if (caps == NULL)
-    caps = gst_caps_copy (gst_pad_get_pad_template_caps (pad));
+    caps = (filter ? gst_caps_ref (filter) : gst_caps_new_any ());
 
   gst_object_unref (funnel);
 
@@ -268,7 +237,9 @@ gst_funnel_sink_chain (GstPad * pad, GstBuffer * buffer)
   GstFunnelPad *fpad = GST_FUNNEL_PAD_CAST (pad);
   GstEvent *event = NULL;
   GstClockTime newts;
+#if 0
   GstCaps *padcaps;
+#endif
 
   GST_DEBUG_OBJECT (funnel, "received buffer %p", buffer);
 
@@ -276,24 +247,24 @@ gst_funnel_sink_chain (GstPad * pad, GstBuffer * buffer)
   if (fpad->segment.format == GST_FORMAT_UNDEFINED) {
     GST_WARNING_OBJECT (funnel, "Got buffer without segment,"
         " setting segment [0,inf[");
-    gst_segment_set_newsegment_full (&fpad->segment, FALSE, 1.0, 1.0,
-        GST_FORMAT_TIME, 0, -1, 0);
+    gst_segment_init (&fpad->segment, GST_FORMAT_TIME);
   }
 
   if (GST_CLOCK_TIME_IS_VALID (GST_BUFFER_TIMESTAMP (buffer)))
-    gst_segment_set_last_stop (&fpad->segment, fpad->segment.format,
-        GST_BUFFER_TIMESTAMP (buffer));
+    fpad->segment.position = GST_BUFFER_TIMESTAMP (buffer);
 
   newts = gst_segment_to_running_time (&fpad->segment,
       fpad->segment.format, GST_BUFFER_TIMESTAMP (buffer));
   if (newts != GST_BUFFER_TIMESTAMP (buffer)) {
-    buffer = gst_buffer_make_metadata_writable (buffer);
+    buffer = gst_buffer_make_writable (buffer);
     GST_BUFFER_TIMESTAMP (buffer) = newts;
   }
 
   if (!funnel->has_segment) {
-    event = gst_event_new_new_segment_full (FALSE, 1.0, 1.0, GST_FORMAT_TIME,
-        0, -1, 0);
+    GstSegment segment;
+
+    gst_segment_init (&segment, GST_FORMAT_TIME);
+    event = gst_event_new_segment (&segment);
     funnel->has_segment = TRUE;
   }
   GST_OBJECT_UNLOCK (funnel);
@@ -302,7 +273,7 @@ gst_funnel_sink_chain (GstPad * pad, GstBuffer * buffer)
     if (!gst_pad_push_event (funnel->srcpad, event))
       GST_WARNING_OBJECT (funnel, "Could not push out newsegment event");
   }
-
+#if 0
   GST_OBJECT_LOCK (pad);
   padcaps = GST_PAD_CAPS (funnel->srcpad);
   GST_OBJECT_UNLOCK (pad);
@@ -313,12 +284,15 @@ gst_funnel_sink_chain (GstPad * pad, GstBuffer * buffer)
       goto out;
     }
   }
+#endif
 
   res = gst_pad_push (funnel->srcpad, buffer);
 
   GST_LOG_OBJECT (funnel, "handled buffer %s", gst_flow_get_name (res));
 
+#if 0
 out:
+#endif
   gst_object_unref (funnel);
 
   return res;
@@ -338,34 +312,23 @@ gst_funnel_sink_event (GstPad * pad, GstEvent * event)
   }
 
   switch (GST_EVENT_TYPE (event)) {
-    case GST_EVENT_NEWSEGMENT:
+    case GST_EVENT_SEGMENT:
     {
-      gboolean update;
-      gdouble rate, arate;
-      GstFormat format;
-      gint64 start;
-      gint64 stop;
-      gint64 time;
-
-      gst_event_parse_new_segment_full (event, &update, &rate, &arate,
-          &format, &start, &stop, &time);
-
       GST_OBJECT_LOCK (funnel);
-      gst_segment_set_newsegment_full (&fpad->segment, update, rate, arate,
-          format, start, stop, time);
+      gst_event_copy_segment (event, &fpad->segment);
       GST_OBJECT_UNLOCK (funnel);
 
       forward = FALSE;
-    }
       break;
+    }
     case GST_EVENT_FLUSH_STOP:
     {
       GST_OBJECT_LOCK (funnel);
       gst_segment_init (&fpad->segment, GST_FORMAT_UNDEFINED);
       funnel->has_segment = FALSE;
       GST_OBJECT_UNLOCK (funnel);
-    }
       break;
+    }
     default:
       break;
   }
@@ -388,6 +351,7 @@ gst_funnel_src_event (GstPad * pad, GstEvent * event)
   GstPad *sinkpad;
   gboolean result = FALSE;
   gboolean done = FALSE;
+  GValue value = { 0, };
 
   funnel = gst_pad_get_parent_element (pad);
   if (G_UNLIKELY (funnel == NULL)) {
@@ -398,11 +362,12 @@ gst_funnel_src_event (GstPad * pad, GstEvent * event)
   iter = gst_element_iterate_sink_pads (funnel);
 
   while (!done) {
-    switch (gst_iterator_next (iter, (gpointer) & sinkpad)) {
+    switch (gst_iterator_next (iter, &value)) {
       case GST_ITERATOR_OK:
+        sinkpad = g_value_get_object (&value);
         gst_event_ref (event);
         result |= gst_pad_push_event (sinkpad, event);
-        gst_object_unref (sinkpad);
+        g_value_reset (&value);
         break;
       case GST_ITERATOR_RESYNC:
         gst_iterator_resync (iter);
@@ -415,6 +380,7 @@ gst_funnel_src_event (GstPad * pad, GstEvent * event)
         break;
     }
   }
+  g_value_unset (&value);
   gst_iterator_free (iter);
   gst_object_unref (funnel);
   gst_event_unref (event);
@@ -423,15 +389,14 @@ gst_funnel_src_event (GstPad * pad, GstEvent * event)
 }
 
 static void
-reset_pad (gpointer data, gpointer user_data)
+reset_pad (const GValue * data, gpointer user_data)
 {
-  GstPad *pad = data;
+  GstPad *pad = g_value_get_object (data);
   GstFunnelPad *fpad = GST_FUNNEL_PAD_CAST (pad);
 
   GST_OBJECT_LOCK (pad);
   gst_funnel_pad_reset (fpad);
   GST_OBJECT_UNLOCK (pad);
-  gst_object_unref (pad);
 }
 
 static GstStateChangeReturn
index 9929533..c06f384 100644 (file)
@@ -91,11 +91,11 @@ enum
 };
 
 
-#define _do_init(bla) \
+#define _do_init \
     GST_DEBUG_CATEGORY_INIT (gst_identity_debug, "identity", 0, "identity element");
-
-GST_BOILERPLATE_FULL (GstIdentity, gst_identity, GstBaseTransform,
-    GST_TYPE_BASE_TRANSFORM, _do_init);
+#define gst_identity_parent_class parent_class
+G_DEFINE_TYPE_WITH_CODE (GstIdentity, gst_identity, GST_TYPE_BASE_TRANSFORM,
+    _do_init);
 
 static void gst_identity_finalize (GObject * object);
 static void gst_identity_set_property (GObject * object, guint prop_id,
@@ -117,21 +117,6 @@ static guint gst_identity_signals[LAST_SIGNAL] = { 0 };
 static GParamSpec *pspec_last_message = NULL;
 
 static void
-gst_identity_base_init (gpointer g_class)
-{
-  GstElementClass *gstelement_class = GST_ELEMENT_CLASS (g_class);
-
-  gst_element_class_set_details_simple (gstelement_class,
-      "Identity",
-      "Generic",
-      "Pass data without modification", "Erik Walthinsen <omega@cse.ogi.edu>");
-  gst_element_class_add_pad_template (gstelement_class,
-      gst_static_pad_template_get (&srctemplate));
-  gst_element_class_add_pad_template (gstelement_class,
-      gst_static_pad_template_get (&sinktemplate));
-}
-
-static void
 gst_identity_finalize (GObject * object)
 {
   GstIdentity *identity;
@@ -172,16 +157,18 @@ marshal_VOID__MINIOBJECT (GClosure * closure, GValue * return_value,
       (marshalfunc_VOID__MINIOBJECT) (marshal_data ? marshal_data :
       cc->callback);
 
-  callback (data1, gst_value_get_mini_object (param_values + 1), data2);
+  callback (data1, g_value_get_boxed (param_values + 1), data2);
 }
 
 static void
 gst_identity_class_init (GstIdentityClass * klass)
 {
   GObjectClass *gobject_class;
+  GstElementClass *gstelement_class;
   GstBaseTransformClass *gstbasetrans_class;
 
   gobject_class = G_OBJECT_CLASS (klass);
+  gstelement_class = GST_ELEMENT_CLASS (klass);
   gstbasetrans_class = GST_BASE_TRANSFORM_CLASS (klass);
 
   gobject_class->set_property = gst_identity_set_property;
@@ -210,7 +197,7 @@ gst_identity_class_init (GstIdentityClass * klass)
           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
   g_object_class_install_property (gobject_class, PROP_SINGLE_SEGMENT,
       g_param_spec_boolean ("single-segment", "Single Segment",
-          "Timestamp buffers and eat newsegments so as to appear as one segment",
+          "Timestamp buffers and eat segments so as to appear as one segment",
           DEFAULT_SINGLE_SEGMENT, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
   pspec_last_message = g_param_spec_string ("last-message", "last-message",
       "last-message", NULL, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS);
@@ -271,6 +258,15 @@ gst_identity_class_init (GstIdentityClass * klass)
 
   gobject_class->finalize = gst_identity_finalize;
 
+  gst_element_class_set_details_simple (gstelement_class,
+      "Identity",
+      "Generic",
+      "Pass data without modification", "Erik Walthinsen <omega@cse.ogi.edu>");
+  gst_element_class_add_pad_template (gstelement_class,
+      gst_static_pad_template_get (&srctemplate));
+  gst_element_class_add_pad_template (gstelement_class,
+      gst_static_pad_template_get (&sinktemplate));
+
   gstbasetrans_class->event = GST_DEBUG_FUNCPTR (gst_identity_event);
   gstbasetrans_class->transform_ip =
       GST_DEBUG_FUNCPTR (gst_identity_transform_ip);
@@ -281,7 +277,7 @@ gst_identity_class_init (GstIdentityClass * klass)
 }
 
 static void
-gst_identity_init (GstIdentity * identity, GstIdentityClass * g_class)
+gst_identity_init (GstIdentity * identity)
 {
   identity->sleep_time = DEFAULT_SLEEP_TIME;
   identity->error_after = DEFAULT_ERROR_AFTER;
@@ -352,17 +348,16 @@ gst_identity_event (GstBaseTransform * trans, GstEvent * event)
     gst_identity_notify_last_message (identity);
   }
 
-  if (identity->single_segment
-      && (GST_EVENT_TYPE (event) == GST_EVENT_NEWSEGMENT)) {
-    if (trans->have_newsegment == FALSE) {
+  if (identity->single_segment && (GST_EVENT_TYPE (event) == GST_EVENT_SEGMENT)) {
+    if (trans->have_segment == FALSE) {
       GstEvent *news;
-      GstFormat format;
+      GstSegment segment;
 
-      gst_event_parse_new_segment (event, NULL, NULL, &format, NULL, NULL,
-          NULL);
+      gst_event_copy_segment (event, &segment);
 
-      /* This is the first newsegment, send out a (0, -1) newsegment */
-      news = gst_event_new_new_segment (TRUE, 1.0, format, 0, -1, 0);
+      /* This is the first segment, send out a (0, -1) segment */
+      gst_segment_init (&segment, segment.format);
+      news = gst_event_new_segment (&segment);
 
       gst_pad_event_default (trans->sinkpad, news);
     }
@@ -370,15 +365,14 @@ gst_identity_event (GstBaseTransform * trans, GstEvent * event)
 
   /* Reset previous timestamp, duration and offsets on NEWSEGMENT
    * to prevent false warnings when checking for perfect streams */
-  if (GST_EVENT_TYPE (event) == GST_EVENT_NEWSEGMENT) {
+  if (GST_EVENT_TYPE (event) == GST_EVENT_SEGMENT) {
     identity->prev_timestamp = identity->prev_duration = GST_CLOCK_TIME_NONE;
     identity->prev_offset = identity->prev_offset_end = GST_BUFFER_OFFSET_NONE;
   }
 
-  ret = parent_class->event (trans, event);
+  ret = GST_BASE_TRANSFORM_CLASS (parent_class)->event (trans, event);
 
-  if (identity->single_segment
-      && (GST_EVENT_TYPE (event) == GST_EVENT_NEWSEGMENT)) {
+  if (identity->single_segment && (GST_EVENT_TYPE (event) == GST_EVENT_SEGMENT)) {
     /* eat up segments */
     ret = FALSE;
   }
@@ -394,13 +388,13 @@ gst_identity_prepare_output_buffer (GstBaseTransform * trans,
 
   /* only bother if we may have to alter metadata */
   if (identity->datarate > 0 || identity->single_segment) {
-    if (gst_buffer_is_metadata_writable (in_buf))
+    if (gst_buffer_is_writable (in_buf))
       *out_buf = gst_buffer_ref (in_buf);
     else {
       /* make even less writable */
       gst_buffer_ref (in_buf);
       /* extra ref is dropped going through the official process */
-      *out_buf = gst_buffer_make_metadata_writable (in_buf);
+      *out_buf = gst_buffer_make_writable (in_buf);
     }
   } else
     *out_buf = gst_buffer_ref (in_buf);
@@ -560,7 +554,7 @@ print_pretty_time (gchar * ts_str, gsize ts_str_len, GstClockTime ts)
 
 static void
 gst_identity_update_last_message_for_buffer (GstIdentity * identity,
-    const gchar * action, GstBuffer * buf)
+    const gchar * action, GstBuffer * buf, gsize size)
 {
   gchar ts_str[64], dur_str[64];
 
@@ -568,14 +562,13 @@ gst_identity_update_last_message_for_buffer (GstIdentity * identity,
 
   g_free (identity->last_message);
   identity->last_message = g_strdup_printf ("%s   ******* (%s:%s)i "
-      "(%u bytes, timestamp: %s, duration: %s, offset: %" G_GINT64_FORMAT ", "
-      "offset_end: % " G_GINT64_FORMAT ", flags: %d) %p", action,
-      GST_DEBUG_PAD_NAME (GST_BASE_TRANSFORM_CAST (identity)->sinkpad),
-      GST_BUFFER_SIZE (buf),
-      print_pretty_time (ts_str, sizeof (ts_str), GST_BUFFER_TIMESTAMP (buf)),
-      print_pretty_time (dur_str, sizeof (dur_str), GST_BUFFER_DURATION (buf)),
-      GST_BUFFER_OFFSET (buf), GST_BUFFER_OFFSET_END (buf),
-      GST_BUFFER_FLAGS (buf), buf);
+      "(%" G_GSIZE_FORMAT " bytes, timestamp: %s, duration: %s, offset: %"
+      G_GINT64_FORMAT ", " "offset_end: % " G_GINT64_FORMAT ", flags: %d) %p",
+      action, GST_DEBUG_PAD_NAME (GST_BASE_TRANSFORM_CAST (identity)->sinkpad),
+      size, print_pretty_time (ts_str, sizeof (ts_str),
+          GST_BUFFER_TIMESTAMP (buf)), print_pretty_time (dur_str,
+          sizeof (dur_str), GST_BUFFER_DURATION (buf)), GST_BUFFER_OFFSET (buf),
+      GST_BUFFER_OFFSET_END (buf), GST_BUFFER_FLAGS (buf), buf);
 
   GST_OBJECT_UNLOCK (identity);
 
@@ -588,6 +581,10 @@ gst_identity_transform_ip (GstBaseTransform * trans, GstBuffer * buf)
   GstFlowReturn ret = GST_FLOW_OK;
   GstIdentity *identity = GST_IDENTITY (trans);
   GstClockTime runtimestamp = G_GINT64_CONSTANT (0);
+  guint8 *data;
+  gsize size;
+
+  data = gst_buffer_map (buf, &size, NULL, GST_MAP_READ);
 
   if (identity->check_perfect)
     gst_identity_check_perfect (identity, buf);
@@ -604,29 +601,21 @@ gst_identity_transform_ip (GstBaseTransform * trans, GstBuffer * buf)
 
   if (identity->error_after >= 0) {
     identity->error_after--;
-    if (identity->error_after == 0) {
-      GST_ELEMENT_ERROR (identity, CORE, FAILED,
-          (_("Failed after iterations as requested.")), (NULL));
-      return GST_FLOW_ERROR;
-    }
+    if (identity->error_after == 0)
+      goto error_after;
   }
 
   if (identity->drop_probability > 0.0) {
-    if ((gfloat) (1.0 * rand () / (RAND_MAX)) < identity->drop_probability) {
-      if (!identity->silent) {
-        gst_identity_update_last_message_for_buffer (identity, "dropping", buf);
-      }
-      /* return DROPPED to basetransform. */
-      return GST_BASE_TRANSFORM_FLOW_DROPPED;
-    }
+    if ((gfloat) (1.0 * rand () / (RAND_MAX)) < identity->drop_probability)
+      goto dropped;
   }
 
   if (identity->dump) {
-    gst_util_dump_mem (GST_BUFFER_DATA (buf), GST_BUFFER_SIZE (buf));
+    gst_util_dump_mem (data, size);
   }
 
   if (!identity->silent) {
-    gst_identity_update_last_message_for_buffer (identity, "chain", buf);
+    gst_identity_update_last_message_for_buffer (identity, "chain", buf, size);
   }
 
   if (identity->datarate > 0) {
@@ -634,8 +623,7 @@ gst_identity_transform_ip (GstBaseTransform * trans, GstBuffer * buf)
         GST_SECOND, identity->datarate);
 
     GST_BUFFER_TIMESTAMP (buf) = time;
-    GST_BUFFER_DURATION (buf) =
-        GST_BUFFER_SIZE (buf) * GST_SECOND / identity->datarate;
+    GST_BUFFER_DURATION (buf) = size * GST_SECOND / identity->datarate;
   }
 
   if (identity->signal_handoffs)
@@ -673,7 +661,7 @@ gst_identity_transform_ip (GstBaseTransform * trans, GstBuffer * buf)
     GST_OBJECT_UNLOCK (identity);
   }
 
-  identity->offset += GST_BUFFER_SIZE (buf);
+  identity->offset += size;
 
   if (identity->sleep_time && ret == GST_FLOW_OK)
     g_usleep (identity->sleep_time);
@@ -685,7 +673,28 @@ gst_identity_transform_ip (GstBaseTransform * trans, GstBuffer * buf)
     GST_BUFFER_OFFSET_END (buf) = GST_CLOCK_TIME_NONE;
   }
 
+  gst_buffer_unmap (buf, data, size);
+
   return ret;
+
+  /* ERRORS */
+error_after:
+  {
+    GST_ELEMENT_ERROR (identity, CORE, FAILED,
+        (_("Failed after iterations as requested.")), (NULL));
+    gst_buffer_unmap (buf, data, size);
+    return GST_FLOW_ERROR;
+  }
+dropped:
+  {
+    if (!identity->silent) {
+      gst_identity_update_last_message_for_buffer (identity, "dropping", buf,
+          size);
+    }
+    gst_buffer_unmap (buf, data, size);
+    /* return DROPPED to basetransform. */
+    return GST_BASE_TRANSFORM_FLOW_DROPPED;
+  }
 }
 
 static void
index f62a488..c1d257b 100644 (file)
@@ -155,9 +155,12 @@ struct _GstSelectorPad
   gboolean discont;             /* after switching we create a discont */
   gboolean flushing;            /* set after flush-start and before flush-stop */
   gboolean always_ok;
-  GstSegment segment;           /* the current segment on the pad */
   GstTagList *tags;             /* last tags received on the pad */
 
+  GstClockTime position;        /* the current position in the segment */
+  GstSegment segment;           /* the current segment on the pad */
+  guint32 segment_seqnum;       /* sequence number of the current segment */
+
   gboolean segment_pending;
 };
 
@@ -166,50 +169,22 @@ struct _GstSelectorPadClass
   GstPadClass parent;
 };
 
-static void gst_selector_pad_class_init (GstSelectorPadClass * klass);
-static void gst_selector_pad_init (GstSelectorPad * pad);
+GType gst_selector_pad_get_type (void);
 static void gst_selector_pad_finalize (GObject * object);
 static void gst_selector_pad_get_property (GObject * object,
     guint prop_id, GValue * value, GParamSpec * pspec);
 static void gst_selector_pad_set_property (GObject * object,
     guint prop_id, const GValue * value, GParamSpec * pspec);
 
-static GstPadClass *selector_pad_parent_class = NULL;
-
 static gint64 gst_selector_pad_get_running_time (GstSelectorPad * pad);
 static void gst_selector_pad_reset (GstSelectorPad * pad);
 static gboolean gst_selector_pad_event (GstPad * pad, GstEvent * event);
-static GstCaps *gst_selector_pad_getcaps (GstPad * pad);
+static GstCaps *gst_selector_pad_getcaps (GstPad * pad, GstCaps * filter);
 static gboolean gst_selector_pad_acceptcaps (GstPad * pad, GstCaps * caps);
 static GstIterator *gst_selector_pad_iterate_linked_pads (GstPad * pad);
 static GstFlowReturn gst_selector_pad_chain (GstPad * pad, GstBuffer * buf);
-static GstFlowReturn gst_selector_pad_bufferalloc (GstPad * pad,
-    guint64 offset, guint size, GstCaps * caps, GstBuffer ** buf);
-
-static GType
-gst_selector_pad_get_type (void)
-{
-  static volatile gsize selector_pad_type = 0;
-  static const GTypeInfo selector_pad_info = {
-    sizeof (GstSelectorPadClass),
-    NULL,
-    NULL,
-    (GClassInitFunc) gst_selector_pad_class_init,
-    NULL,
-    NULL,
-    sizeof (GstSelectorPad),
-    0,
-    (GInstanceInitFunc) gst_selector_pad_init,
-  };
-
-  if (g_once_init_enter (&selector_pad_type)) {
-    GType tmp = g_type_register_static (GST_TYPE_PAD, "GstSelectorPad",
-        &selector_pad_info, 0);
-    g_once_init_leave (&selector_pad_type, tmp);
-  }
 
-  return (GType) selector_pad_type;
-}
+G_DEFINE_TYPE (GstSelectorPad, gst_selector_pad, GST_TYPE_PAD);
 
 static void
 gst_selector_pad_class_init (GstSelectorPadClass * klass)
@@ -218,8 +193,6 @@ gst_selector_pad_class_init (GstSelectorPadClass * klass)
 
   gobject_class = (GObjectClass *) klass;
 
-  selector_pad_parent_class = g_type_class_peek_parent (klass);
-
   gobject_class->finalize = gst_selector_pad_finalize;
 
   gobject_class->get_property = gst_selector_pad_get_property;
@@ -261,7 +234,7 @@ gst_selector_pad_finalize (GObject * object)
   if (pad->tags)
     gst_tag_list_free (pad->tags);
 
-  G_OBJECT_CLASS (selector_pad_parent_class)->finalize (object);
+  G_OBJECT_CLASS (gst_selector_pad_parent_class)->finalize (object);
 }
 
 static void
@@ -325,11 +298,10 @@ gst_selector_pad_get_running_time (GstSelectorPad * pad)
 
   GST_OBJECT_LOCK (pad);
   if (pad->active) {
-    gint64 last_stop = pad->segment.last_stop;
+    guint64 position = pad->position;
+    GstFormat format = pad->segment.format;
 
-    if (last_stop >= 0)
-      ret = gst_segment_to_running_time (&pad->segment, GST_FORMAT_TIME,
-          last_stop);
+    ret = gst_segment_to_running_time (&pad->segment, format, position);
   }
   GST_OBJECT_UNLOCK (pad);
 
@@ -350,6 +322,7 @@ gst_selector_pad_reset (GstSelectorPad * pad)
   pad->segment_pending = FALSE;
   pad->discont = FALSE;
   pad->flushing = FALSE;
+  pad->position = GST_CLOCK_TIME_NONE;
   gst_segment_init (&pad->segment, GST_FORMAT_UNDEFINED);
   GST_OBJECT_UNLOCK (pad);
 }
@@ -362,14 +335,17 @@ gst_selector_pad_iterate_linked_pads (GstPad * pad)
   GstInputSelector *sel;
   GstPad *otherpad;
   GstIterator *it;
+  GValue val = { 0, };
 
   sel = GST_INPUT_SELECTOR (gst_pad_get_parent (pad));
   if (G_UNLIKELY (sel == NULL))
     return NULL;
 
   otherpad = gst_input_selector_get_linked_pad (sel, pad, TRUE);
-  it = gst_iterator_new_single (GST_TYPE_PAD, otherpad,
-      (GstCopyFunction) gst_object_ref, (GFreeFunc) gst_object_unref);
+  g_value_init (&val, GST_TYPE_PAD);
+  g_value_set_object (&val, otherpad);
+  it = gst_iterator_new_single (GST_TYPE_PAD, &val);
+  g_value_unset (&val);
 
   if (otherpad)
     gst_object_unref (otherpad);
@@ -420,30 +396,31 @@ gst_selector_pad_event (GstPad * pad, GstEvent * event)
     case GST_EVENT_FLUSH_STOP:
       GST_INPUT_SELECTOR_LOCK (sel);
       gst_selector_pad_reset (selpad);
-      sel->pending_close = FALSE;
       GST_INPUT_SELECTOR_UNLOCK (sel);
       break;
-    case GST_EVENT_NEWSEGMENT:
+    case GST_EVENT_SEGMENT:
     {
-      gboolean update;
-      GstFormat format;
-      gdouble rate, arate;
-      gint64 start, stop, time;
-
-      gst_event_parse_new_segment_full (event, &update, &rate, &arate, &format,
-          &start, &stop, &time);
-
-      GST_DEBUG_OBJECT (pad,
-          "configured NEWSEGMENT update %d, rate %lf, applied rate %lf, "
-          "format %d, "
-          "%" G_GINT64_FORMAT " -- %" G_GINT64_FORMAT ", time %"
-          G_GINT64_FORMAT, update, rate, arate, format, start, stop, time);
-
       GST_INPUT_SELECTOR_LOCK (sel);
       GST_OBJECT_LOCK (selpad);
-      gst_segment_set_newsegment_full (&selpad->segment, update,
-          rate, arate, format, start, stop, time);
-      GST_OBJECT_UNLOCK (selpad);
+      gst_event_copy_segment (event, &selpad->segment);
+      selpad->segment_seqnum = gst_event_get_seqnum (event);
+
+      /* Update the position */
+      if (selpad->position == GST_CLOCK_TIME_NONE
+          || selpad->segment.position > selpad->position) {
+        selpad->position = selpad->segment.position;
+      } else if (selpad->position != GST_CLOCK_TIME_NONE
+          && selpad->position > selpad->segment.position) {
+        selpad->segment.position = selpad->position;
+
+        if (forward) {
+          gst_event_unref (event);
+          event = gst_event_new_segment (&selpad->segment);
+          gst_event_set_seqnum (event, selpad->segment_seqnum);
+        }
+      }
+      GST_DEBUG_OBJECT (pad, "configured SEGMENT %" GST_SEGMENT_FORMAT,
+          &selpad->segment);
 
       /* If we aren't forwarding the event because the pad is not the
        * active_sinkpad, then set the flag on the pad
@@ -454,6 +431,7 @@ gst_selector_pad_event (GstPad * pad, GstEvent * event)
       if (!forward)
         selpad->segment_pending = TRUE;
 
+      GST_OBJECT_UNLOCK (selpad);
       GST_INPUT_SELECTOR_UNLOCK (sel);
       break;
     }
@@ -514,19 +492,19 @@ gst_selector_pad_event (GstPad * pad, GstEvent * event)
 }
 
 static GstCaps *
-gst_selector_pad_getcaps (GstPad * pad)
+gst_selector_pad_getcaps (GstPad * pad, GstCaps * filter)
 {
   GstInputSelector *sel;
   GstCaps *caps;
 
   sel = GST_INPUT_SELECTOR (gst_pad_get_parent (pad));
   if (G_UNLIKELY (sel == NULL))
-    return gst_caps_new_any ();
+    return (filter ? gst_caps_ref (filter) : gst_caps_new_any ());
 
   GST_DEBUG_OBJECT (sel, "Getting caps of srcpad peer");
-  caps = gst_pad_peer_get_caps_reffed (sel->srcpad);
+  caps = gst_pad_peer_get_caps (sel->srcpad, filter);
   if (caps == NULL)
-    caps = gst_caps_new_any ();
+    caps = (filter ? gst_caps_ref (filter) : gst_caps_new_any ());
 
   gst_object_unref (sel);
 
@@ -550,70 +528,6 @@ gst_selector_pad_acceptcaps (GstPad * pad, GstCaps * caps)
   return res;
 }
 
-static GstFlowReturn
-gst_selector_pad_bufferalloc (GstPad * pad, guint64 offset,
-    guint size, GstCaps * caps, GstBuffer ** buf)
-{
-  GstInputSelector *sel;
-  GstFlowReturn result;
-  GstPad *active_sinkpad;
-  GstPad *prev_active_sinkpad;
-  GstSelectorPad *selpad;
-
-  sel = GST_INPUT_SELECTOR (gst_pad_get_parent (pad));
-  if (G_UNLIKELY (sel == NULL))
-    return GST_FLOW_WRONG_STATE;
-
-  selpad = GST_SELECTOR_PAD_CAST (pad);
-
-  GST_LOG_OBJECT (pad, "received alloc");
-
-  GST_INPUT_SELECTOR_LOCK (sel);
-  prev_active_sinkpad = sel->active_sinkpad;
-  active_sinkpad = gst_input_selector_activate_sinkpad (sel, pad);
-
-  if (pad != active_sinkpad)
-    goto not_active;
-
-  GST_INPUT_SELECTOR_UNLOCK (sel);
-
-  if (prev_active_sinkpad != active_sinkpad && pad == active_sinkpad) {
-    NOTIFY_MUTEX_LOCK ();
-    g_object_notify (G_OBJECT (sel), "active-pad");
-    NOTIFY_MUTEX_UNLOCK ();
-  }
-
-  result = gst_pad_alloc_buffer (sel->srcpad, offset, size, caps, buf);
-
-done:
-  gst_object_unref (sel);
-
-  return result;
-
-  /* ERRORS */
-not_active:
-  {
-    gboolean active_pad_pushed = GST_SELECTOR_PAD_CAST (active_sinkpad)->pushed;
-
-    GST_INPUT_SELECTOR_UNLOCK (sel);
-
-    /* unselected pad, perform fallback alloc or return unlinked when
-     * asked */
-    GST_OBJECT_LOCK (selpad);
-    if (selpad->always_ok || !active_pad_pushed) {
-      GST_DEBUG_OBJECT (pad, "Not selected, performing fallback allocation");
-      *buf = NULL;
-      result = GST_FLOW_OK;
-    } else {
-      GST_DEBUG_OBJECT (pad, "Not selected, return NOT_LINKED");
-      result = GST_FLOW_NOT_LINKED;
-    }
-    GST_OBJECT_UNLOCK (selpad);
-
-    goto done;
-  }
-}
-
 /* must be called with the SELECTOR_LOCK, will block while the pad is blocked 
  * or return TRUE when flushing */
 static gboolean
@@ -672,7 +586,7 @@ gst_input_selector_wait_running_time (GstInputSelector * sel,
   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_selpad->position);
 
   /* Wait until
    *   a) this is the active pad
@@ -709,7 +623,7 @@ gst_input_selector_wait_running_time (GstInputSelector * sel,
     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_selpad->position);
     else
       active_running_time = -1;
 
@@ -736,8 +650,7 @@ gst_selector_pad_chain (GstPad * pad, GstBuffer * buf)
   GstSelectorPad *selpad;
   GstClockTime start_time;
   GstSegment *seg;
-  GstEvent *close_event = NULL, *start_event = NULL;
-  GstCaps *caps;
+  GstEvent *start_event = NULL;
 
   sel = GST_INPUT_SELECTOR (gst_pad_get_parent (pad));
   selpad = GST_SELECTOR_PAD_CAST (pad);
@@ -773,7 +686,7 @@ gst_selector_pad_chain (GstPad * pad, GstBuffer * buf)
           GST_TIME_ARGS (start_time + GST_BUFFER_DURATION (buf)));
 
     GST_OBJECT_LOCK (pad);
-    gst_segment_set_last_stop (seg, seg->format, start_time);
+    selpad->position = start_time;
     GST_OBJECT_UNLOCK (pad);
   }
 
@@ -785,33 +698,17 @@ gst_selector_pad_chain (GstPad * pad, GstBuffer * buf)
   if (sel->sync_streams)
     GST_INPUT_SELECTOR_BROADCAST (sel);
 
-  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;
-  }
   /* if we have a pending segment, push it out now */
-  if (G_UNLIKELY (selpad->segment_pending)) {
+  if (G_UNLIKELY (prev_active_sinkpad != active_sinkpad
+          || selpad->segment_pending)) {
     GST_DEBUG_OBJECT (pad,
         "pushing pending NEWSEGMENT update %d, rate %lf, applied rate %lf, "
-        "format %d, "
-        "%" G_GINT64_FORMAT " -- %" G_GINT64_FORMAT ", time %"
+        "format %d, " "%" G_GINT64_FORMAT " -- %" G_GINT64_FORMAT ", time %"
         G_GINT64_FORMAT, FALSE, seg->rate, seg->applied_rate, seg->format,
         seg->start, seg->stop, seg->time);
 
-    start_event = gst_event_new_new_segment_full (FALSE, seg->rate,
-        seg->applied_rate, seg->format, seg->start, seg->stop, seg->time);
+    start_event = gst_event_new_segment (seg);
+    gst_event_set_seqnum (start_event, selpad->segment_seqnum);
 
     selpad->segment_pending = FALSE;
   }
@@ -823,14 +720,11 @@ gst_selector_pad_chain (GstPad * pad, GstBuffer * buf)
     NOTIFY_MUTEX_UNLOCK ();
   }
 
-  if (close_event)
-    gst_pad_push_event (sel->srcpad, close_event);
-
   if (start_event)
     gst_pad_push_event (sel->srcpad, start_event);
 
   if (selpad->discont) {
-    buf = gst_buffer_make_metadata_writable (buf);
+    buf = gst_buffer_make_writable (buf);
 
     GST_DEBUG_OBJECT (pad, "Marking discont buffer %p", buf);
     GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DISCONT);
@@ -840,11 +734,6 @@ gst_selector_pad_chain (GstPad * pad, GstBuffer * buf)
   /* forward */
   GST_LOG_OBJECT (pad, "Forwarding buffer %p", buf);
 
-  if ((caps = GST_BUFFER_CAPS (buf))) {
-    if (GST_PAD_CAPS (sel->srcpad) != caps)
-      gst_pad_set_caps (sel->srcpad, caps);
-  }
-
   res = gst_pad_push (sel->srcpad, buf);
   selpad->pushed = TRUE;
 
@@ -891,23 +780,18 @@ static void gst_input_selector_get_property (GObject * object,
     guint prop_id, GValue * value, GParamSpec * pspec);
 
 static GstPad *gst_input_selector_request_new_pad (GstElement * element,
-    GstPadTemplate * templ, const gchar * unused);
+    GstPadTemplate * templ, const gchar * unused, const GstCaps * caps);
 static void gst_input_selector_release_pad (GstElement * element, GstPad * pad);
 
 static GstStateChangeReturn gst_input_selector_change_state (GstElement *
     element, GstStateChange transition);
 
-static GstCaps *gst_input_selector_getcaps (GstPad * pad);
+static GstCaps *gst_input_selector_getcaps (GstPad * pad, GstCaps * filter);
 static gboolean gst_input_selector_event (GstPad * pad, GstEvent * event);
 static gboolean gst_input_selector_query (GstPad * pad, GstQuery * query);
 static gint64 gst_input_selector_block (GstInputSelector * self);
-static void gst_input_selector_switch (GstInputSelector * self,
-    GstPad * pad, gint64 stop_time, gint64 start_time);
 
 /* FIXME: create these marshallers using glib-genmarshal */
-#define g_marshal_value_peek_object(v)   (v)->data[0].v_pointer
-#define g_marshal_value_peek_int64(v)    (v)->data[0].v_int64
-
 static void
 gst_input_selector_marshal_INT64__VOID (GClosure * closure,
     GValue * return_value G_GNUC_UNUSED,
@@ -939,60 +823,12 @@ gst_input_selector_marshal_INT64__VOID (GClosure * closure,
   g_value_set_int64 (return_value, v_return);
 }
 
-static void
-gst_input_selector_marshal_VOID__OBJECT_INT64_INT64 (GClosure * closure,
-    GValue * return_value G_GNUC_UNUSED,
-    guint n_param_values,
-    const GValue * param_values,
-    gpointer invocation_hint G_GNUC_UNUSED, gpointer marshal_data)
-{
-  typedef void (*GMarshalFunc_VOID__OBJECT_INT64_INT64) (gpointer data1,
-      gpointer arg_1, gint64 arg_2, gint64 arg_3, gpointer data2);
-  register GMarshalFunc_VOID__OBJECT_INT64_INT64 callback;
-  register GCClosure *cc = (GCClosure *) closure;
-  register gpointer data1, data2;
-
-  g_return_if_fail (n_param_values == 4);
-
-  if (G_CCLOSURE_SWAP_DATA (closure)) {
-    data1 = closure->data;
-    data2 = g_value_peek_pointer (param_values + 0);
-  } else {
-    data1 = g_value_peek_pointer (param_values + 0);
-    data2 = closure->data;
-  }
-  callback =
-      (GMarshalFunc_VOID__OBJECT_INT64_INT64) (marshal_data ? marshal_data :
-      cc->callback);
-
-  callback (data1,
-      g_marshal_value_peek_object (param_values + 1),
-      g_marshal_value_peek_int64 (param_values + 2),
-      g_marshal_value_peek_int64 (param_values + 3), data2);
-}
-
-#define _do_init(bla) \
+#define _do_init \
     GST_DEBUG_CATEGORY_INIT (input_selector_debug, \
         "input-selector", 0, "An input stream selector element");
-
-GST_BOILERPLATE_FULL (GstInputSelector, gst_input_selector, GstElement,
-    GST_TYPE_ELEMENT, _do_init);
-
-static void
-gst_input_selector_base_init (gpointer g_class)
-{
-  GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
-
-  gst_element_class_set_details_simple (element_class, "Input selector",
-      "Generic", "N-to-1 input stream selector",
-      "Julien Moutte <julien@moutte.net>, "
-      "Jan Schmidt <thaytan@mad.scientist.com>, "
-      "Wim Taymans <wim.taymans@gmail.com>");
-  gst_element_class_add_pad_template (element_class,
-      gst_static_pad_template_get (&gst_input_selector_sink_factory));
-  gst_element_class_add_pad_template (element_class,
-      gst_static_pad_template_get (&gst_input_selector_src_factory));
-}
+#define gst_input_selector_parent_class parent_class
+G_DEFINE_TYPE_WITH_CODE (GstInputSelector, gst_input_selector, GST_TYPE_ELEMENT,
+    _do_init);
 
 static void
 gst_input_selector_class_init (GstInputSelectorClass * klass)
@@ -1043,70 +879,26 @@ gst_input_selector_class_init (GstInputSelectorClass * klass)
       G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
       G_STRUCT_OFFSET (GstInputSelectorClass, block), NULL, NULL,
       gst_input_selector_marshal_INT64__VOID, G_TYPE_INT64, 0);
-  /**
-   * GstInputSelector::switch:
-   * @inputselector: the #GstInputSelector
-   * @pad:            the pad to switch to
-   * @stop_time:      running time at which to close the previous segment, or -1
-   *                  to use the running time of the previously active sink pad
-   * @start_time:     running time at which to start the new segment, or -1 to
-   *                  use the running time of the newly active sink pad
-   *
-   * Switch to a new feed. The segment opened by the previously active pad, if
-   * any, will be closed, and a new segment opened before data flows again.
-   *
-   * This signal must be emitted when the element has been blocked via the <link
-   * linkend="GstInputSelector-block">block</link> signal.
-   *
-   * If you have a stream with only one switch element, such as an audio-only
-   * stream, a stream switch should be performed by first emitting the block
-   * signal, and then emitting the switch signal with -1 for the stop and start
-   * time values.
-   *
-   * The intention of the @stop_time and @start_time arguments is to allow
-   * multiple switch elements to switch and maintain stream synchronization.
-   * When switching a stream with multiple feeds, you will need as many switch
-   * elements as you have feeds. For example, a feed with audio and video will
-   * have one switch element between the audio feeds and one for video.
-   *
-   * A switch over multiple switch elements should be performed as follows:
-   * First, emit the <link linkend="GstInputSelector-block">block</link>
-   * signal, collecting the returned values. The maximum running time returned
-   * by block should then be used as the time at which to close the previous
-   * segment.
-   *
-   * Then, query the running times of the new audio and video pads that you will
-   * switch to. Naturally, these pads are on separate switch elements. Take the
-   * minimum running time for those streams and use it for the time at which to
-   * open the new segment.
-   *
-   * If @pad is the same as the current active pad, the element will cancel any
-   * previous block without adjusting segments.
-   *
-   * <note><simpara>
-   * the signal changed from accepting the pad name to the pad object.
-   * </simpara></note>
-   *
-   * Since: 0.10.7
-   */
-  gst_input_selector_signals[SIGNAL_SWITCH] =
-      g_signal_new ("switch", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
-      G_STRUCT_OFFSET (GstInputSelectorClass, switch_),
-      NULL, NULL, gst_input_selector_marshal_VOID__OBJECT_INT64_INT64,
-      G_TYPE_NONE, 3, GST_TYPE_PAD, G_TYPE_INT64, G_TYPE_INT64);
+
+  gst_element_class_set_details_simple (gstelement_class, "Input selector",
+      "Generic", "N-to-1 input stream selector",
+      "Julien Moutte <julien@moutte.net>, "
+      "Jan Schmidt <thaytan@mad.scientist.com>, "
+      "Wim Taymans <wim.taymans@gmail.com>");
+  gst_element_class_add_pad_template (gstelement_class,
+      gst_static_pad_template_get (&gst_input_selector_sink_factory));
+  gst_element_class_add_pad_template (gstelement_class,
+      gst_static_pad_template_get (&gst_input_selector_src_factory));
 
   gstelement_class->request_new_pad = gst_input_selector_request_new_pad;
   gstelement_class->release_pad = gst_input_selector_release_pad;
   gstelement_class->change_state = gst_input_selector_change_state;
 
   klass->block = GST_DEBUG_FUNCPTR (gst_input_selector_block);
-  /* note the underscore because switch is a keyword otherwise */
-  klass->switch_ = GST_DEBUG_FUNCPTR (gst_input_selector_switch);
 }
 
 static void
-gst_input_selector_init (GstInputSelector * sel,
-    GstInputSelectorClass * g_class)
+gst_input_selector_init (GstInputSelector * sel)
 {
   sel->srcpad = gst_pad_new ("src", GST_PAD_SRC);
   gst_pad_set_iterate_internal_links_function (sel->srcpad,
@@ -1121,7 +913,6 @@ gst_input_selector_init (GstInputSelector * sel,
   /* sinkpad management */
   sel->active_sinkpad = NULL;
   sel->padcount = 0;
-  gst_segment_init (&sel->segment, GST_FORMAT_UNDEFINED);
   sel->sync_streams = DEFAULT_SYNC_STREAMS;
 
   sel->lock = g_mutex_new ();
@@ -1150,47 +941,10 @@ gst_input_selector_dispose (GObject * object)
   G_OBJECT_CLASS (parent_class)->dispose (object);
 }
 
-/* Solve the following equation for B.timestamp, and set that as the segment
- * stop:
- * B.running_time = (B.timestamp - NS.start) / NS.abs_rate + NS.accum
- */
-static gint64
-gst_segment_get_timestamp (GstSegment * segment, gint64 running_time)
-{
-  if (running_time <= segment->accum)
-    return segment->start;
-  else
-    return (running_time - segment->accum) * segment->abs_rate + segment->start;
-}
-
-static void
-gst_segment_set_stop (GstSegment * segment, gint64 running_time)
-{
-  segment->stop = gst_segment_get_timestamp (segment, running_time);
-  segment->last_stop = -1;
-}
-
-static void
-gst_segment_set_start (GstSegment * segment, gint64 running_time)
-{
-  gint64 new_start, duration;
-
-  new_start = gst_segment_get_timestamp (segment, running_time);
-
-  /* this is the duration we skipped */
-  duration = new_start - segment->start;
-  /* add the duration to the accumulated segment time */
-  segment->accum += duration;
-  /* move position in the segment */
-  segment->time += duration;
-  segment->start += duration;
-}
-
 /* this function must be called with the SELECTOR_LOCK. It returns TRUE when the
  * active pad changed. */
 static gboolean
-gst_input_selector_set_active_pad (GstInputSelector * self,
-    GstPad * pad, gint64 stop_time, gint64 start_time)
+gst_input_selector_set_active_pad (GstInputSelector * self, GstPad * pad)
 {
   GstSelectorPad *old, *new;
   GstPad **active_pad_p;
@@ -1204,37 +958,15 @@ gst_input_selector_set_active_pad (GstInputSelector * self,
   GST_DEBUG_OBJECT (self, "setting active pad to %s:%s",
       GST_DEBUG_PAD_NAME (new));
 
-  if (!GST_CLOCK_TIME_IS_VALID (stop_time) && old) {
-    /* no stop time given, get the latest running_time on the active pad to 
-     * close and open the new segment */
-    stop_time = start_time = gst_selector_pad_get_running_time (old);
-    GST_DEBUG_OBJECT (self, "using start/stop of %" GST_TIME_FORMAT,
-        GST_TIME_ARGS (start_time));
-  }
-
-  if (old && old->active && !self->pending_close && stop_time >= 0) {
-    /* schedule a last_stop update if one isn't already scheduled, and a
-       segment has been pushed before. */
-    memcpy (&self->segment, &old->segment, sizeof (self->segment));
-
-    GST_DEBUG_OBJECT (self, "setting stop_time to %" GST_TIME_FORMAT,
-        GST_TIME_ARGS (stop_time));
-    gst_segment_set_stop (&self->segment, stop_time);
-    self->pending_close = TRUE;
-  }
   if (old)
     old->pushed = FALSE;
-
-  if (new && new->active && start_time >= 0) {
-    GST_DEBUG_OBJECT (self, "setting start_time to %" GST_TIME_FORMAT,
-        GST_TIME_ARGS (start_time));
-    /* schedule a new segment push */
-    gst_segment_set_start (&new->segment, start_time);
-    new->segment_pending = TRUE;
-  }
   if (new)
     new->pushed = FALSE;
 
+  /* Send a new SEGMENT event on the new pad next */
+  if (old != new && new)
+    new->segment_pending = TRUE;
+
   active_pad_p = &self->active_sinkpad;
   gst_object_replace ((GstObject **) active_pad_p, GST_OBJECT_CAST (pad));
 
@@ -1263,8 +995,7 @@ gst_input_selector_set_property (GObject * object, guint prop_id,
       pad = g_value_get_object (value);
 
       GST_INPUT_SELECTOR_LOCK (sel);
-      gst_input_selector_set_active_pad (sel, pad,
-          GST_CLOCK_TIME_NONE, GST_CLOCK_TIME_NONE);
+      gst_input_selector_set_active_pad (sel, pad);
       GST_INPUT_SELECTOR_UNLOCK (sel);
       break;
     }
@@ -1331,8 +1062,12 @@ static gboolean
 gst_input_selector_event (GstPad * pad, GstEvent * event)
 {
   GstInputSelector *sel;
-  gboolean res = FALSE;
-  GstPad *otherpad;
+  gboolean result = FALSE;
+  GstIterator *iter;
+  gboolean done = FALSE;
+  GValue item = { 0, };
+  GstPad *eventpad;
+  GList *pushed_pads = NULL;
 
   sel = GST_INPUT_SELECTOR (gst_pad_get_parent (pad));
   if (G_UNLIKELY (sel == NULL)) {
@@ -1340,16 +1075,50 @@ gst_input_selector_event (GstPad * pad, GstEvent * event)
     return FALSE;
   }
 
-  otherpad = gst_input_selector_get_linked_pad (sel, pad, TRUE);
-  if (otherpad) {
-    res = gst_pad_push_event (otherpad, event);
+  /* Send upstream events to all sinkpads */
+  iter = gst_element_iterate_sink_pads (GST_ELEMENT_CAST (sel));
 
-    gst_object_unref (otherpad);
-  } else
-    gst_event_unref (event);
+  /* This is now essentially a copy of gst_pad_event_default_dispatch
+   * with a different iterator */
+  while (!done) {
+    switch (gst_iterator_next (iter, &item)) {
+      case GST_ITERATOR_OK:
+        eventpad = g_value_get_object (&item);
 
-  gst_object_unref (sel);
-  return res;
+        /* if already pushed,  skip */
+        if (g_list_find (pushed_pads, eventpad)) {
+          g_value_reset (&item);
+          break;
+        }
+
+        gst_event_ref (event);
+        result |= gst_pad_push_event (eventpad, event);
+
+        g_value_reset (&item);
+        break;
+      case GST_ITERATOR_RESYNC:
+        /* We don't reset the result here because we don't push the event
+         * again on pads that got the event already and because we need
+         * to consider the result of the previous pushes */
+        gst_iterator_resync (iter);
+        break;
+      case GST_ITERATOR_ERROR:
+        GST_ERROR_OBJECT (pad, "Could not iterate over sinkpads");
+        done = TRUE;
+        break;
+      case GST_ITERATOR_DONE:
+        done = TRUE;
+        break;
+    }
+  }
+  g_value_unset (&item);
+  gst_iterator_free (iter);
+
+  g_list_free (pushed_pads);
+
+  gst_event_unref (event);
+
+  return result;
 }
 
 /* query on the srcpad. We override this function because by default it will
@@ -1438,7 +1207,7 @@ gst_input_selector_query (GstPad * pad, GstQuery * query)
 }
 
 static GstCaps *
-gst_input_selector_getcaps (GstPad * pad)
+gst_input_selector_getcaps (GstPad * pad, GstCaps * filter)
 {
   GstPad *otherpad;
   GstInputSelector *sel;
@@ -1446,20 +1215,20 @@ gst_input_selector_getcaps (GstPad * pad)
 
   sel = GST_INPUT_SELECTOR (gst_pad_get_parent (pad));
   if (G_UNLIKELY (sel == NULL))
-    return gst_caps_new_any ();
+    return (filter ? gst_caps_ref (filter) : gst_caps_new_any ());
 
   otherpad = gst_input_selector_get_linked_pad (sel, pad, FALSE);
 
   if (!otherpad) {
     GST_DEBUG_OBJECT (pad, "Pad not linked, returning ANY");
-    caps = gst_caps_new_any ();
+    caps = (filter ? gst_caps_ref (filter) : gst_caps_new_any ());
   } else {
     GST_DEBUG_OBJECT (pad, "Pad is linked (to %s:%s), returning peer caps",
         GST_DEBUG_PAD_NAME (otherpad));
     /* if the peer has caps, use those. If the pad is not linked, this function
      * returns NULL and we return ANY */
-    if (!(caps = gst_pad_peer_get_caps_reffed (otherpad)))
-      caps = gst_caps_new_any ();
+    if (!(caps = gst_pad_peer_get_caps (otherpad, filter)))
+      caps = (filter ? gst_caps_ref (filter) : gst_caps_new_any ());
     gst_object_unref (otherpad);
   }
 
@@ -1504,7 +1273,7 @@ gst_input_selector_activate_sinkpad (GstInputSelector * sel, GstPad * pad)
 
 static GstPad *
 gst_input_selector_request_new_pad (GstElement * element,
-    GstPadTemplate * templ, const gchar * unused)
+    GstPadTemplate * templ, const gchar * unused, const GstCaps * caps)
 {
   GstInputSelector *sel;
   gchar *name = NULL;
@@ -1534,8 +1303,6 @@ gst_input_selector_request_new_pad (GstElement * element,
       GST_DEBUG_FUNCPTR (gst_selector_pad_chain));
   gst_pad_set_iterate_internal_links_function (sinkpad,
       GST_DEBUG_FUNCPTR (gst_selector_pad_iterate_linked_pads));
-  gst_pad_set_bufferalloc_function (sinkpad,
-      GST_DEBUG_FUNCPTR (gst_selector_pad_bufferalloc));
 
   gst_pad_set_active (sinkpad, TRUE);
   gst_element_add_pad (GST_ELEMENT (sel), sinkpad);
@@ -1577,9 +1344,6 @@ gst_input_selector_reset (GstInputSelector * sel)
     gst_object_unref (sel->active_sinkpad);
     sel->active_sinkpad = NULL;
   }
-  /* reset segment */
-  gst_segment_init (&sel->segment, GST_FORMAT_UNDEFINED);
-  sel->pending_close = FALSE;
   /* reset each of our sinkpads state */
   for (walk = GST_ELEMENT_CAST (sel)->sinkpads; walk; walk = g_list_next (walk)) {
     GstSelectorPad *selpad = GST_SELECTOR_PAD_CAST (walk->data);
@@ -1657,27 +1421,3 @@ gst_input_selector_block (GstInputSelector * self)
 
   return ret;
 }
-
-/* stop_time and start_time are running times */
-static void
-gst_input_selector_switch (GstInputSelector * self, GstPad * pad,
-    gint64 stop_time, gint64 start_time)
-{
-  gboolean changed;
-
-  g_return_if_fail (self->blocked == TRUE);
-
-  GST_INPUT_SELECTOR_LOCK (self);
-  changed =
-      gst_input_selector_set_active_pad (self, pad, stop_time, start_time);
-
-  self->blocked = FALSE;
-  GST_INPUT_SELECTOR_BROADCAST (self);
-  GST_INPUT_SELECTOR_UNLOCK (self);
-
-  if (changed) {
-    NOTIFY_MUTEX_LOCK ();
-    g_object_notify (G_OBJECT (self), "active-pad");
-    NOTIFY_MUTEX_UNLOCK ();
-  }
-}
index f370999..116c31c 100644 (file)
@@ -58,9 +58,6 @@ struct _GstInputSelector {
   guint padcount;
   gboolean sync_streams;
 
-  GstSegment segment;      /* the output segment */
-  gboolean pending_close;  /* if we should push a close first */
-
   GMutex *lock;
   GCond *cond;
   gboolean blocked;
@@ -71,8 +68,6 @@ struct _GstInputSelectorClass {
   GstElementClass parent_class;
 
   gint64 (*block)      (GstInputSelector *self);
-  void (*switch_)      (GstInputSelector *self, GstPad *pad,
-                         gint64 stop_time, gint64 start_time);
 };
 
 GType gst_input_selector_get_type (void);
index 9f39155..d65564e 100644 (file)
@@ -261,36 +261,22 @@ static void gst_multi_queue_get_property (GObject * object,
     guint prop_id, GValue * value, GParamSpec * pspec);
 
 static GstPad *gst_multi_queue_request_new_pad (GstElement * element,
-    GstPadTemplate * temp, const gchar * name);
+    GstPadTemplate * temp, const gchar * name, const GstCaps * caps);
 static void gst_multi_queue_release_pad (GstElement * element, GstPad * pad);
 static GstStateChangeReturn gst_multi_queue_change_state (GstElement *
     element, GstStateChange transition);
 
 static void gst_multi_queue_loop (GstPad * pad);
 
-#define _do_init(bla) \
+#define _do_init \
   GST_DEBUG_CATEGORY_INIT (multi_queue_debug, "multiqueue", 0, "multiqueue element");
-
-GST_BOILERPLATE_FULL (GstMultiQueue, gst_multi_queue, GstElement,
-    GST_TYPE_ELEMENT, _do_init);
+#define gst_multi_queue_parent_class parent_class
+G_DEFINE_TYPE_WITH_CODE (GstMultiQueue, gst_multi_queue, GST_TYPE_ELEMENT,
+    _do_init);
 
 static guint gst_multi_queue_signals[LAST_SIGNAL] = { 0 };
 
 static void
-gst_multi_queue_base_init (gpointer g_class)
-{
-  GstElementClass *gstelement_class = GST_ELEMENT_CLASS (g_class);
-
-  gst_element_class_set_details_simple (gstelement_class,
-      "MultiQueue",
-      "Generic", "Multiple data queue", "Edward Hervey <edward@fluendo.com>");
-  gst_element_class_add_pad_template (gstelement_class,
-      gst_static_pad_template_get (&sinktemplate));
-  gst_element_class_add_pad_template (gstelement_class,
-      gst_static_pad_template_get (&srctemplate));
-}
-
-static void
 gst_multi_queue_class_init (GstMultiQueueClass * klass)
 {
   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
@@ -421,6 +407,14 @@ gst_multi_queue_class_init (GstMultiQueueClass * klass)
 
   gobject_class->finalize = gst_multi_queue_finalize;
 
+  gst_element_class_set_details_simple (gstelement_class,
+      "MultiQueue",
+      "Generic", "Multiple data queue", "Edward Hervey <edward@fluendo.com>");
+  gst_element_class_add_pad_template (gstelement_class,
+      gst_static_pad_template_get (&sinktemplate));
+  gst_element_class_add_pad_template (gstelement_class,
+      gst_static_pad_template_get (&srctemplate));
+
   gstelement_class->request_new_pad =
       GST_DEBUG_FUNCPTR (gst_multi_queue_request_new_pad);
   gstelement_class->release_pad =
@@ -430,7 +424,7 @@ gst_multi_queue_class_init (GstMultiQueueClass * klass)
 }
 
 static void
-gst_multi_queue_init (GstMultiQueue * mqueue, GstMultiQueueClass * klass)
+gst_multi_queue_init (GstMultiQueue * mqueue)
 {
   mqueue->nbqueues = 0;
   mqueue->queues = NULL;
@@ -587,6 +581,7 @@ gst_multi_queue_iterate_internal_links (GstPad * pad)
   GstPad *opad;
   GstSingleQueue *squeue;
   GstMultiQueue *mq = GST_MULTI_QUEUE (gst_pad_get_parent (pad));
+  GValue val = { 0, };
 
   GST_MULTI_QUEUE_MUTEX_LOCK (mq);
   squeue = gst_pad_get_element_private (pad);
@@ -600,8 +595,10 @@ gst_multi_queue_iterate_internal_links (GstPad * pad)
   else
     goto out;
 
-  it = gst_iterator_new_single (GST_TYPE_PAD, opad,
-      (GstCopyFunction) gst_object_ref, (GFreeFunc) gst_object_unref);
+  g_value_init (&val, GST_TYPE_PAD);
+  g_value_set_object (&val, opad);
+  it = gst_iterator_new_single (GST_TYPE_PAD, &val);
+  g_value_unset (&val);
 
   gst_object_unref (opad);
 
@@ -619,7 +616,7 @@ out:
 
 static GstPad *
 gst_multi_queue_request_new_pad (GstElement * element, GstPadTemplate * temp,
-    const gchar * name)
+    const gchar * name, const GstCaps * caps)
 {
   GstMultiQueue *mqueue = GST_MULTI_QUEUE (element);
   GstSingleQueue *squeue;
@@ -873,7 +870,7 @@ update_time_level (GstMultiQueue * mq, GstSingleQueue * sq)
   if (sq->sink_tainted) {
     sink_time = sq->sinktime =
         gst_segment_to_running_time (&sq->sink_segment, GST_FORMAT_TIME,
-        sq->sink_segment.last_stop);
+        sq->sink_segment.position);
 
     if (G_UNLIKELY (sink_time != GST_CLOCK_TIME_NONE))
       /* if we have a time, we become untainted and use the time */
@@ -884,7 +881,7 @@ update_time_level (GstMultiQueue * mq, GstSingleQueue * sq)
   if (sq->src_tainted) {
     src_time = sq->srctime =
         gst_segment_to_running_time (&sq->src_segment, GST_FORMAT_TIME,
-        sq->src_segment.last_stop);
+        sq->src_segment.position);
     /* if we have a time, we become untainted and use the time */
     if (G_UNLIKELY (src_time != GST_CLOCK_TIME_NONE))
       sq->src_tainted = FALSE;
@@ -908,44 +905,33 @@ update_time_level (GstMultiQueue * mq, GstSingleQueue * sq)
   return;
 }
 
-/* take a NEWSEGMENT event and apply the values to segment, updating the time
+/* take a SEGMENT event and apply the values to segment, updating the time
  * level of queue. */
 static void
 apply_segment (GstMultiQueue * mq, GstSingleQueue * sq, GstEvent * event,
     GstSegment * segment)
 {
-  gboolean update;
-  GstFormat format;
-  gdouble rate, arate;
-  gint64 start, stop, time;
-
-  gst_event_parse_new_segment_full (event, &update, &rate, &arate,
-      &format, &start, &stop, &time);
+  gst_event_copy_segment (event, segment);
 
   /* now configure the values, we use these to track timestamps on the
    * sinkpad. */
-  if (format != GST_FORMAT_TIME) {
+  if (segment->format != GST_FORMAT_TIME) {
     /* non-time format, pretent the current time segment is closed with a
      * 0 start and unknown stop time. */
-    update = FALSE;
-    format = GST_FORMAT_TIME;
-    start = 0;
-    stop = -1;
-    time = 0;
+    segment->format = GST_FORMAT_TIME;
+    segment->start = 0;
+    segment->stop = -1;
+    segment->time = 0;
   }
-
   GST_MULTI_QUEUE_MUTEX_LOCK (mq);
 
-  gst_segment_set_newsegment_full (segment, update,
-      rate, arate, format, start, stop, time);
-
   if (segment == &sq->sink_segment)
     sq->sink_tainted = TRUE;
   else
     sq->src_tainted = TRUE;
 
   GST_DEBUG_OBJECT (mq,
-      "queue %d, configured NEWSEGMENT %" GST_SEGMENT_FORMAT, sq->id, segment);
+      "queue %d, configured SEGMENT %" GST_SEGMENT_FORMAT, sq->id, segment);
 
   /* segment can update the time level of the queue */
   update_time_level (mq, sq);
@@ -963,16 +949,16 @@ apply_buffer (GstMultiQueue * mq, GstSingleQueue * sq, GstClockTime timestamp,
   /* if no timestamp is set, assume it's continuous with the previous 
    * time */
   if (timestamp == GST_CLOCK_TIME_NONE)
-    timestamp = segment->last_stop;
+    timestamp = segment->position;
 
   /* add duration */
   if (duration != GST_CLOCK_TIME_NONE)
     timestamp += duration;
 
-  GST_DEBUG_OBJECT (mq, "queue %d, last_stop updated to %" GST_TIME_FORMAT,
+  GST_DEBUG_OBJECT (mq, "queue %d, position updated to %" GST_TIME_FORMAT,
       sq->id, GST_TIME_ARGS (timestamp));
 
-  gst_segment_set_last_stop (segment, GST_FORMAT_TIME, timestamp);
+  segment->position = timestamp;
 
   if (segment == &sq->sink_segment)
     sq->sink_tainted = TRUE;
@@ -1002,45 +988,37 @@ get_running_time (GstSegment * segment, GstMiniObject * object, gboolean end)
     }
   } else if (GST_IS_BUFFER_LIST (object)) {
     GstBufferList *list = GST_BUFFER_LIST_CAST (object);
-    GstBufferListIterator *it = gst_buffer_list_iterate (list);
+    gint i, n;
     GstBuffer *buf;
 
-    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) {
+    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;
-        }
+      } else if (!end) {
+        goto done;
       }
-    } while (gst_buffer_list_iterator_next_group (it));
+    }
   } else if (GST_IS_EVENT (object)) {
     GstEvent *event = GST_EVENT_CAST (object);
 
     /* For newsegment events return the running time of the start position */
-    if (GST_EVENT_TYPE (event) == GST_EVENT_NEWSEGMENT) {
-      GstSegment new_segment = *segment;
-      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) {
+      const GstSegment *new_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);
+            gst_segment_to_running_time (new_segment, GST_FORMAT_TIME,
+            new_segment->start);
       }
     }
   }
@@ -1058,12 +1036,16 @@ gst_single_queue_push_one (GstMultiQueue * mq, GstSingleQueue * sq,
   if (GST_IS_BUFFER (object)) {
     GstBuffer *buffer;
     GstClockTime timestamp, duration;
+#if 0
     GstCaps *caps;
+#endif
 
     buffer = GST_BUFFER_CAST (object);
     timestamp = GST_BUFFER_TIMESTAMP (buffer);
     duration = GST_BUFFER_DURATION (buffer);
+#if 0
     caps = GST_BUFFER_CAPS (buffer);
+#endif
 
     apply_buffer (mq, sq, timestamp, duration, &sq->src_segment);
 
@@ -1074,11 +1056,13 @@ gst_single_queue_push_one (GstMultiQueue * mq, GstSingleQueue * sq,
         "SingleQueue %d : Pushing buffer %p with ts %" GST_TIME_FORMAT,
         sq->id, buffer, GST_TIME_ARGS (timestamp));
 
+#if 0
     /* Set caps on pad before pushing, this avoids core calling the acceptcaps
      * function on the srcpad, which will call acceptcaps upstream, which might
      * not accept these caps (anymore). */
     if (caps && caps != GST_PAD_CAPS (sq->srcpad))
       gst_pad_set_caps (sq->srcpad, caps);
+#endif
 
     result = gst_pad_push (sq->srcpad, buffer);
   } else if (GST_IS_EVENT (object)) {
@@ -1090,7 +1074,7 @@ gst_single_queue_push_one (GstMultiQueue * mq, GstSingleQueue * sq,
       case GST_EVENT_EOS:
         result = GST_FLOW_UNEXPECTED;
         break;
-      case GST_EVENT_NEWSEGMENT:
+      case GST_EVENT_SEGMENT:
         apply_segment (mq, sq, event, &sq->src_segment);
         /* Applying the segment may have made the queue non-full again, unblock it if needed */
         gst_data_queue_limits_changed (sq->queue);
@@ -1143,7 +1127,7 @@ gst_multi_queue_buffer_item_new (GstMiniObject * object, guint32 curid)
   item->destroy = (GDestroyNotify) gst_multi_queue_item_destroy;
   item->posid = curid;
 
-  item->size = GST_BUFFER_SIZE (object);
+  item->size = gst_buffer_get_size (GST_BUFFER_CAST (object));
   item->duration = GST_BUFFER_DURATION (object);
   if (item->duration == GST_CLOCK_TIME_NONE)
     item->duration = 0;
@@ -1464,7 +1448,7 @@ gst_multi_queue_sink_event (GstPad * pad, GstEvent * event)
 
       gst_single_queue_flush (mq, sq, FALSE);
       goto done;
-    case GST_EVENT_NEWSEGMENT:
+    case GST_EVENT_SEGMENT:
       /* take ref because the queue will take ownership and we need the event
        * afterwards to update the segment */
       sref = gst_event_ref (event);
@@ -1505,7 +1489,7 @@ gst_multi_queue_sink_event (GstPad * pad, GstEvent * event)
       update_buffering (mq, sq);
       single_queue_overrun_cb (sq->queue, sq);
       break;
-    case GST_EVENT_NEWSEGMENT:
+    case GST_EVENT_SEGMENT:
       apply_segment (mq, sq, sref, &sq->sink_segment);
       gst_event_unref (sref);
       break;
@@ -1535,7 +1519,7 @@ was_eos:
 }
 
 static GstCaps *
-gst_multi_queue_getcaps (GstPad * pad)
+gst_multi_queue_getcaps (GstPad * pad, GstCaps * filter)
 {
   GstSingleQueue *sq = gst_pad_get_element_private (pad);
   GstPad *otherpad;
@@ -1545,9 +1529,9 @@ gst_multi_queue_getcaps (GstPad * pad)
 
   GST_LOG_OBJECT (otherpad, "Getting caps from the peer of this pad");
 
-  result = gst_pad_peer_get_caps (otherpad);
+  result = gst_pad_peer_get_caps (otherpad, filter);
   if (result == NULL)
-    result = gst_caps_new_any ();
+    result = (filter ? gst_caps_ref (filter) : gst_caps_new_any ());
 
   return result;
 }
@@ -1568,15 +1552,6 @@ gst_multi_queue_acceptcaps (GstPad * pad, GstCaps * caps)
   return result;
 }
 
-static GstFlowReturn
-gst_multi_queue_bufferalloc (GstPad * pad, guint64 offset, guint size,
-    GstCaps * caps, GstBuffer ** buf)
-{
-  GstSingleQueue *sq = gst_pad_get_element_private (pad);
-
-  return gst_pad_alloc_buffer (sq->srcpad, offset, size, caps, buf);
-}
-
 static gboolean
 gst_multi_queue_src_activate_push (GstPad * pad, gboolean active)
 {
@@ -1976,8 +1951,6 @@ gst_single_queue_new (GstMultiQueue * mqueue, gint id)
       GST_DEBUG_FUNCPTR (gst_multi_queue_getcaps));
   gst_pad_set_acceptcaps_function (sq->sinkpad,
       GST_DEBUG_FUNCPTR (gst_multi_queue_acceptcaps));
-  gst_pad_set_bufferalloc_function (sq->sinkpad,
-      GST_DEBUG_FUNCPTR (gst_multi_queue_bufferalloc));
   gst_pad_set_iterate_internal_links_function (sq->sinkpad,
       GST_DEBUG_FUNCPTR (gst_multi_queue_iterate_internal_links));
 
index 3007219..2db7660 100644 (file)
@@ -86,11 +86,11 @@ enum
 
 #define DEFAULT_PAD_NEGOTIATION_MODE GST_OUTPUT_SELECTOR_PAD_NEGOTIATION_MODE_ALL
 
-#define _do_init(bla) \
+#define _do_init \
 GST_DEBUG_CATEGORY_INIT (output_selector_debug, \
         "output-selector", 0, "Output stream selector");
-
-GST_BOILERPLATE_FULL (GstOutputSelector, gst_output_selector, GstElement,
+#define gst_output_selector_parent_class parent_class
+G_DEFINE_TYPE_WITH_CODE (GstOutputSelector, gst_output_selector,
     GST_TYPE_ELEMENT, _do_init);
 
 static void gst_output_selector_dispose (GObject * object);
@@ -99,12 +99,10 @@ static void gst_output_selector_set_property (GObject * object,
 static void gst_output_selector_get_property (GObject * object,
     guint prop_id, GValue * value, GParamSpec * pspec);
 static GstPad *gst_output_selector_request_new_pad (GstElement * element,
-    GstPadTemplate * templ, const gchar * unused);
+    GstPadTemplate * templ, const gchar * unused, const GstCaps * caps);
 static void gst_output_selector_release_pad (GstElement * element,
     GstPad * pad);
 static GstFlowReturn gst_output_selector_chain (GstPad * pad, GstBuffer * buf);
-static GstFlowReturn gst_output_selector_buffer_alloc (GstPad * pad,
-    guint64 offset, guint size, GstCaps * caps, GstBuffer ** buf);
 static GstStateChangeReturn gst_output_selector_change_state (GstElement *
     element, GstStateChange transition);
 static gboolean gst_output_selector_handle_sink_event (GstPad * pad,
@@ -113,20 +111,6 @@ static void gst_output_selector_switch_pad_negotiation_mode (GstOutputSelector *
     sel, gint mode);
 
 static void
-gst_output_selector_base_init (gpointer g_class)
-{
-  GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
-
-  gst_element_class_set_details_simple (element_class, "Output selector",
-      "Generic", "1-to-N output stream selector",
-      "Stefan Kost <stefan.kost@nokia.com>");
-  gst_element_class_add_pad_template (element_class,
-      gst_static_pad_template_get (&gst_output_selector_sink_factory));
-  gst_element_class_add_pad_template (element_class,
-      gst_static_pad_template_get (&gst_output_selector_src_factory));
-}
-
-static void
 gst_output_selector_class_init (GstOutputSelectorClass * klass)
 {
   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
@@ -152,6 +136,14 @@ gst_output_selector_class_init (GstOutputSelectorClass * klass)
           DEFAULT_PAD_NEGOTIATION_MODE,
           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
 
+  gst_element_class_set_details_simple (gstelement_class, "Output selector",
+      "Generic", "1-to-N output stream selector",
+      "Stefan Kost <stefan.kost@nokia.com>");
+  gst_element_class_add_pad_template (gstelement_class,
+      gst_static_pad_template_get (&gst_output_selector_sink_factory));
+  gst_element_class_add_pad_template (gstelement_class,
+      gst_static_pad_template_get (&gst_output_selector_src_factory));
+
   gstelement_class->request_new_pad =
       GST_DEBUG_FUNCPTR (gst_output_selector_request_new_pad);
   gstelement_class->release_pad =
@@ -161,8 +153,7 @@ gst_output_selector_class_init (GstOutputSelectorClass * klass)
 }
 
 static void
-gst_output_selector_init (GstOutputSelector * sel,
-    GstOutputSelectorClass * g_class)
+gst_output_selector_init (GstOutputSelector * sel)
 {
   sel->sinkpad =
       gst_pad_new_from_static_template (&gst_output_selector_sink_factory,
@@ -171,8 +162,6 @@ gst_output_selector_init (GstOutputSelector * sel,
       GST_DEBUG_FUNCPTR (gst_output_selector_chain));
   gst_pad_set_event_function (sel->sinkpad,
       GST_DEBUG_FUNCPTR (gst_output_selector_handle_sink_event));
-  gst_pad_set_bufferalloc_function (sel->sinkpad,
-      GST_DEBUG_FUNCPTR (gst_output_selector_buffer_alloc));
 
   gst_element_add_pad (GST_ELEMENT (sel), sel->sinkpad);
 
@@ -292,14 +281,14 @@ gst_output_selector_get_property (GObject * object, guint prop_id,
 }
 
 static GstCaps *
-gst_output_selector_sink_getcaps (GstPad * pad)
+gst_output_selector_sink_getcaps (GstPad * pad, GstCaps * filter)
 {
   GstOutputSelector *sel = GST_OUTPUT_SELECTOR (gst_pad_get_parent (pad));
   GstPad *active = NULL;
   GstCaps *caps = NULL;
 
   if (G_UNLIKELY (sel == NULL))
-    return gst_caps_new_any ();
+    return (filter ? gst_caps_ref (filter) : gst_caps_new_any ());
 
   GST_OBJECT_LOCK (sel);
   if (sel->pending_srcpad)
@@ -309,38 +298,17 @@ gst_output_selector_sink_getcaps (GstPad * pad)
   GST_OBJECT_UNLOCK (sel);
 
   if (active) {
-    caps = gst_pad_peer_get_caps_reffed (active);
+    caps = gst_pad_peer_get_caps (active, filter);
     gst_object_unref (active);
   }
   if (caps == NULL) {
-    caps = gst_caps_new_any ();
+    caps = (filter ? gst_caps_ref (filter) : gst_caps_new_any ());
   }
 
   gst_object_unref (sel);
   return caps;
 }
 
-static gboolean
-gst_output_selector_sink_setcaps (GstPad * pad, GstCaps * caps)
-{
-  GstOutputSelector *sel = GST_OUTPUT_SELECTOR (GST_PAD_PARENT (pad));
-  GstPad *active = NULL;
-  gboolean ret = TRUE;
-
-  GST_OBJECT_LOCK (sel);
-  if (sel->pending_srcpad)
-    active = gst_object_ref (sel->pending_srcpad);
-  else if (sel->active_srcpad)
-    active = gst_object_ref (sel->active_srcpad);
-  GST_OBJECT_UNLOCK (sel);
-
-  if (active) {
-    ret = gst_pad_set_caps (active, caps);
-    gst_object_unref (active);
-  }
-  return ret;
-}
-
 static void
 gst_output_selector_switch_pad_negotiation_mode (GstOutputSelector * sel,
     gint mode)
@@ -348,61 +316,27 @@ gst_output_selector_switch_pad_negotiation_mode (GstOutputSelector * sel,
   sel->pad_negotiation_mode = mode;
   if (mode == GST_OUTPUT_SELECTOR_PAD_NEGOTIATION_MODE_ALL) {
     gst_pad_set_getcaps_function (sel->sinkpad, gst_pad_proxy_getcaps);
-    gst_pad_set_setcaps_function (sel->sinkpad, gst_pad_proxy_setcaps);
   } else if (mode == GST_OUTPUT_SELECTOR_PAD_NEGOTIATION_MODE_NONE) {
     gst_pad_set_getcaps_function (sel->sinkpad, NULL);
-    gst_pad_set_setcaps_function (sel->sinkpad, NULL);
   } else {                      /* active */
     gst_pad_set_getcaps_function (sel->sinkpad,
         gst_output_selector_sink_getcaps);
-    gst_pad_set_setcaps_function (sel->sinkpad,
-        gst_output_selector_sink_setcaps);
   }
 }
 
 static GstFlowReturn
-gst_output_selector_buffer_alloc (GstPad * pad, guint64 offset, guint size,
-    GstCaps * caps, GstBuffer ** buf)
+forward_sticky_events (GstPad * pad, GstEvent * event, gpointer user_data)
 {
-  GstOutputSelector *sel;
-  GstFlowReturn res;
-  GstPad *allocpad;
+  GstPad *srcpad = GST_PAD_CAST (user_data);
 
-  sel = GST_OUTPUT_SELECTOR (gst_pad_get_parent (pad));
-  if (G_UNLIKELY (sel == NULL))
-    return GST_FLOW_WRONG_STATE;
+  gst_pad_push_event (srcpad, gst_event_ref (event));
 
-  GST_OBJECT_LOCK (sel);
-  allocpad = sel->pending_srcpad ? sel->pending_srcpad : sel->active_srcpad;
-  if (allocpad) {
-    /* if we had a previous pad we used for allocating a buffer, continue using
-     * it. */
-    GST_DEBUG_OBJECT (sel, "using pad %s:%s for alloc",
-        GST_DEBUG_PAD_NAME (allocpad));
-    gst_object_ref (allocpad);
-    GST_OBJECT_UNLOCK (sel);
-
-    res = gst_pad_alloc_buffer (allocpad, offset, size, caps, buf);
-    gst_object_unref (allocpad);
-
-    GST_OBJECT_LOCK (sel);
-  } else {
-    /* fallback case, allocate a buffer of our own, add pad caps. */
-    GST_DEBUG_OBJECT (pad, "fallback buffer alloc");
-    *buf = NULL;
-    res = GST_FLOW_OK;
-  }
-  GST_OBJECT_UNLOCK (sel);
-
-  GST_DEBUG_OBJECT (sel, "buffer alloc finished: %s", gst_flow_get_name (res));
-
-  gst_object_unref (sel);
-  return res;
+  return GST_FLOW_OK;
 }
 
 static GstPad *
 gst_output_selector_request_new_pad (GstElement * element,
-    GstPadTemplate * templ, const gchar * name)
+    GstPadTemplate * templ, const gchar * name, const GstCaps * caps)
 {
   gchar *padname;
   GstPad *srcpad;
@@ -418,6 +352,10 @@ gst_output_selector_request_new_pad (GstElement * element,
   GST_OBJECT_UNLOCK (osel);
 
   gst_pad_set_active (srcpad, TRUE);
+
+  /* Forward sticky events to the new srcpad */
+  gst_pad_sticky_events_foreach (osel->sinkpad, forward_sticky_events, srcpad);
+
   gst_element_add_pad (GST_ELEMENT (osel), srcpad);
 
   /* Set the first requested src pad as active by default */
@@ -462,19 +400,22 @@ gst_output_selector_switch (GstOutputSelector * osel)
   osel->pending_srcpad = NULL;
   GST_OBJECT_UNLOCK (GST_OBJECT (osel));
 
-  /* Send NEWSEGMENT event and latest buffer if switching succeeded */
+  /* Send SEGMENT event and latest buffer if switching succeeded */
   if (res) {
-    /* Send NEWSEGMENT to the pad we are going to switch to */
+    /* Send SEGMENT to the pad we are going to switch to */
     seg = &osel->segment;
-    /* If resending then mark newsegment start and position accordingly */
+    /* If resending then mark segment start and position accordingly */
     if (osel->resend_latest && osel->latest_buffer &&
         GST_BUFFER_TIMESTAMP_IS_VALID (osel->latest_buffer)) {
       start = position = GST_BUFFER_TIMESTAMP (osel->latest_buffer);
     } else {
-      start = position = seg->last_stop;
+      start = position = seg->position;
     }
-    ev = gst_event_new_new_segment (TRUE, seg->rate,
-        seg->format, start, seg->stop, position);
+
+    seg->start = start;
+    seg->position = position;
+    ev = gst_event_new_segment (seg);
+
     if (!gst_pad_push_event (osel->active_srcpad, ev)) {
       GST_WARNING_OBJECT (osel,
           "newsegment handling failed in %" GST_PTR_FORMAT,
@@ -498,7 +439,7 @@ gst_output_selector_chain (GstPad * pad, GstBuffer * buf)
 {
   GstFlowReturn res;
   GstOutputSelector *osel;
-  GstClockTime last_stop, duration;
+  GstClockTime position, duration;
 
   osel = GST_OUTPUT_SELECTOR (gst_pad_get_parent (pad));
 
@@ -530,15 +471,15 @@ gst_output_selector_chain (GstPad * pad, GstBuffer * buf)
 
   /* Keep track of last stop and use it in NEWSEGMENT start after 
      switching to a new src pad */
-  last_stop = GST_BUFFER_TIMESTAMP (buf);
-  if (GST_CLOCK_TIME_IS_VALID (last_stop)) {
+  position = GST_BUFFER_TIMESTAMP (buf);
+  if (GST_CLOCK_TIME_IS_VALID (position)) {
     duration = GST_BUFFER_DURATION (buf);
     if (GST_CLOCK_TIME_IS_VALID (duration)) {
-      last_stop += duration;
+      position += duration;
     }
     GST_LOG_OBJECT (osel, "setting last stop %" GST_TIME_FORMAT,
-        GST_TIME_ARGS (last_stop));
-    gst_segment_set_last_stop (&osel->segment, osel->segment.format, last_stop);
+        GST_TIME_ARGS (position));
+    osel->segment.position = position;
   }
 
   GST_LOG_OBJECT (osel, "pushing buffer to %" GST_PTR_FORMAT,
@@ -583,7 +524,7 @@ gst_output_selector_handle_sink_event (GstPad * pad, GstEvent * event)
 {
   gboolean res = TRUE;
   GstOutputSelector *sel;
-  GstPad *output_pad = NULL;
+  GstPad *active = NULL;
 
   sel = GST_OUTPUT_SELECTOR (gst_pad_get_parent (pad));
   if (G_UNLIKELY (sel == NULL)) {
@@ -592,38 +533,67 @@ gst_output_selector_handle_sink_event (GstPad * pad, GstEvent * event)
   }
 
   switch (GST_EVENT_TYPE (event)) {
-    case GST_EVENT_NEWSEGMENT:
+    case GST_EVENT_CAPS:
     {
-      gboolean update;
-      GstFormat format;
-      gdouble rate, arate;
-      gint64 start, stop, time;
-
-      gst_event_parse_new_segment_full (event, &update, &rate, &arate, &format,
-          &start, &stop, &time);
-
-      GST_DEBUG_OBJECT (sel,
-          "configured NEWSEGMENT update %d, rate %lf, applied rate %lf, "
-          "format %d, " "%" G_GINT64_FORMAT " -- %" G_GINT64_FORMAT ", time %"
-          G_GINT64_FORMAT, update, rate, arate, format, start, stop, time);
+      switch (sel->pad_negotiation_mode) {
+        case GST_OUTPUT_SELECTOR_PAD_NEGOTIATION_MODE_ALL:
+          /* Send caps to all src pads */
+          res = gst_pad_event_default (pad, event);
+          break;
+        case GST_OUTPUT_SELECTOR_PAD_NEGOTIATION_MODE_NONE:
+          gst_event_unref (event);
+          break;
+        default:
+          GST_OBJECT_LOCK (sel);
+          if (sel->pending_srcpad)
+            active = gst_object_ref (sel->pending_srcpad);
+          else if (sel->active_srcpad)
+            active = gst_object_ref (sel->active_srcpad);
+          GST_OBJECT_UNLOCK (sel);
+
+          if (active) {
+            res = gst_pad_push_event (active, event);
+            gst_object_unref (active);
+          } else {
+            gst_event_unref (event);
+          }
+          break;
+      }
+      break;
+    }
+    case GST_EVENT_SEGMENT:
+    {
+      gst_event_copy_segment (event, &sel->segment);
 
-      gst_segment_set_newsegment_full (&sel->segment, update,
-          rate, arate, format, start, stop, time);
+      GST_DEBUG_OBJECT (sel, "configured SEGMENT %" GST_SEGMENT_FORMAT,
+          &sel->segment);
 
       /* Send newsegment to all src pads */
-      gst_pad_event_default (pad, event);
+      res = gst_pad_event_default (pad, event);
       break;
     }
     case GST_EVENT_EOS:
       /* Send eos to all src pads */
-      gst_pad_event_default (pad, event);
+      res = gst_pad_event_default (pad, event);
       break;
     default:
+    {
+      GST_OBJECT_LOCK (sel);
+      if (sel->pending_srcpad)
+        active = gst_object_ref (sel->pending_srcpad);
+      else if (sel->active_srcpad)
+        active = gst_object_ref (sel->active_srcpad);
+      GST_OBJECT_UNLOCK (sel);
+
       /* Send other events to pending or active src pad */
-      output_pad =
-          sel->pending_srcpad ? sel->pending_srcpad : sel->active_srcpad;
-      res = gst_pad_push_event (output_pad, event);
+      if (active) {
+        res = gst_pad_push_event (active, event);
+        gst_object_unref (active);
+      } else {
+        gst_event_unref (event);
+      }
       break;
+    }
   }
 
   gst_object_unref (sel);
index ceca353..feeaf54 100644 (file)
@@ -178,13 +178,12 @@ enum
   }                                                                     \
 } G_STMT_END
 
-#define _do_init(bla) \
+#define _do_init \
     GST_DEBUG_CATEGORY_INIT (queue_debug, "queue", 0, "queue element"); \
     GST_DEBUG_CATEGORY_INIT (queue_dataflow, "queue_dataflow", 0, \
         "dataflow inside the queue element");
-
-GST_BOILERPLATE_FULL (GstQueue, gst_queue, GstElement,
-    GST_TYPE_ELEMENT, _do_init);
+#define gst_queue_parent_class parent_class
+G_DEFINE_TYPE_WITH_CODE (GstQueue, gst_queue, GST_TYPE_ELEMENT, _do_init);
 
 static void gst_queue_finalize (GObject * object);
 
@@ -194,8 +193,6 @@ static void gst_queue_get_property (GObject * object,
     guint prop_id, GValue * value, GParamSpec * pspec);
 
 static GstFlowReturn gst_queue_chain (GstPad * pad, GstBuffer * buffer);
-static GstFlowReturn gst_queue_bufferalloc (GstPad * pad, guint64 offset,
-    guint size, GstCaps * caps, GstBuffer ** buf);
 static GstFlowReturn gst_queue_push_one (GstQueue * queue);
 static void gst_queue_loop (GstPad * pad);
 
@@ -205,7 +202,7 @@ static gboolean gst_queue_handle_src_event (GstPad * pad, GstEvent * event);
 static gboolean gst_queue_handle_src_query (GstPad * pad, GstQuery * query);
 
 static gboolean gst_queue_acceptcaps (GstPad * pad, GstCaps * caps);
-static GstCaps *gst_queue_getcaps (GstPad * pad);
+static GstCaps *gst_queue_getcaps (GstPad * pad, GstCaps * filter);
 static GstPadLinkReturn gst_queue_link_sink (GstPad * pad, GstPad * peer);
 static GstPadLinkReturn gst_queue_link_src (GstPad * pad, GstPad * peer);
 static void gst_queue_locked_flush (GstQueue * queue);
@@ -239,23 +236,10 @@ queue_leaky_get_type (void)
 static guint gst_queue_signals[LAST_SIGNAL] = { 0 };
 
 static void
-gst_queue_base_init (gpointer g_class)
-{
-  GstElementClass *gstelement_class = GST_ELEMENT_CLASS (g_class);
-
-  gst_element_class_set_details_simple (gstelement_class,
-      "Queue",
-      "Generic", "Simple data queue", "Erik Walthinsen <omega@cse.ogi.edu>");
-  gst_element_class_add_pad_template (gstelement_class,
-      gst_static_pad_template_get (&srctemplate));
-  gst_element_class_add_pad_template (gstelement_class,
-      gst_static_pad_template_get (&sinktemplate));
-}
-
-static void
 gst_queue_class_init (GstQueueClass * klass)
 {
   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+  GstElementClass *gstelement_class = GST_ELEMENT_CLASS (klass);
 
   gobject_class->set_property = gst_queue_set_property;
   gobject_class->get_property = gst_queue_get_property;
@@ -374,6 +358,14 @@ gst_queue_class_init (GstQueueClass * klass)
 
   gobject_class->finalize = gst_queue_finalize;
 
+  gst_element_class_set_details_simple (gstelement_class,
+      "Queue",
+      "Generic", "Simple data queue", "Erik Walthinsen <omega@cse.ogi.edu>");
+  gst_element_class_add_pad_template (gstelement_class,
+      gst_static_pad_template_get (&srctemplate));
+  gst_element_class_add_pad_template (gstelement_class,
+      gst_static_pad_template_get (&sinktemplate));
+
   /* Registering debug symbols for function pointers */
   GST_DEBUG_REGISTER_FUNCPTR (gst_queue_chain);
   GST_DEBUG_REGISTER_FUNCPTR (gst_queue_sink_activate_push);
@@ -381,7 +373,6 @@ gst_queue_class_init (GstQueueClass * klass)
   GST_DEBUG_REGISTER_FUNCPTR (gst_queue_link_sink);
   GST_DEBUG_REGISTER_FUNCPTR (gst_queue_getcaps);
   GST_DEBUG_REGISTER_FUNCPTR (gst_queue_acceptcaps);
-  GST_DEBUG_REGISTER_FUNCPTR (gst_queue_bufferalloc);
   GST_DEBUG_REGISTER_FUNCPTR (gst_queue_src_activate_push);
   GST_DEBUG_REGISTER_FUNCPTR (gst_queue_link_src);
   GST_DEBUG_REGISTER_FUNCPTR (gst_queue_handle_src_event);
@@ -389,7 +380,7 @@ gst_queue_class_init (GstQueueClass * klass)
 }
 
 static void
-gst_queue_init (GstQueue * queue, GstQueueClass * g_class)
+gst_queue_init (GstQueue * queue)
 {
   queue->sinkpad = gst_pad_new_from_static_template (&sinktemplate, "sink");
 
@@ -400,7 +391,6 @@ gst_queue_init (GstQueue * queue, GstQueueClass * g_class)
   gst_pad_set_link_function (queue->sinkpad, gst_queue_link_sink);
   gst_pad_set_getcaps_function (queue->sinkpad, gst_queue_getcaps);
   gst_pad_set_acceptcaps_function (queue->sinkpad, gst_queue_acceptcaps);
-  gst_pad_set_bufferalloc_function (queue->sinkpad, gst_queue_bufferalloc);
   gst_element_add_pad (GST_ELEMENT (queue), queue->sinkpad);
 
   queue->srcpad = gst_pad_new_from_static_template (&srctemplate, "src");
@@ -485,7 +475,7 @@ gst_queue_acceptcaps (GstPad * pad, GstCaps * caps)
 }
 
 static GstCaps *
-gst_queue_getcaps (GstPad * pad)
+gst_queue_getcaps (GstPad * pad, GstCaps * filter)
 {
   GstQueue *queue;
   GstPad *otherpad;
@@ -493,12 +483,12 @@ gst_queue_getcaps (GstPad * pad)
 
   queue = GST_QUEUE (gst_pad_get_parent (pad));
   if (G_UNLIKELY (queue == NULL))
-    return gst_caps_new_any ();
+    return (filter ? gst_caps_ref (filter) : gst_caps_new_any ());
 
   otherpad = (pad == queue->srcpad ? queue->sinkpad : queue->srcpad);
-  result = gst_pad_peer_get_caps (otherpad);
+  result = gst_pad_peer_get_caps (otherpad, filter);
   if (result == NULL)
-    result = gst_caps_new_any ();
+    result = (filter ? gst_caps_ref (filter) : gst_caps_new_any ());
 
   gst_object_unref (queue);
 
@@ -542,24 +532,6 @@ gst_queue_link_src (GstPad * pad, GstPad * peer)
   return result;
 }
 
-static GstFlowReturn
-gst_queue_bufferalloc (GstPad * pad, guint64 offset, guint size, GstCaps * caps,
-    GstBuffer ** buf)
-{
-  GstQueue *queue;
-  GstFlowReturn result;
-
-  queue = GST_QUEUE (gst_pad_get_parent (pad));
-  if (G_UNLIKELY (queue == NULL))
-    return GST_FLOW_WRONG_STATE;
-
-  /* Forward to src pad, without setting caps on the src pad */
-  result = gst_pad_alloc_buffer (queue->srcpad, offset, size, caps, buf);
-
-  gst_object_unref (queue);
-  return result;
-}
-
 /* calculate the diff between running time on the sink and src of the queue.
  * This is the total amount of time in the queue. */
 static void
@@ -570,7 +542,7 @@ update_time_level (GstQueue * queue)
   if (queue->sink_tainted) {
     queue->sinktime =
         gst_segment_to_running_time (&queue->sink_segment, GST_FORMAT_TIME,
-        queue->sink_segment.last_stop);
+        queue->sink_segment.position);
     queue->sink_tainted = FALSE;
   }
   sink_time = queue->sinktime;
@@ -578,7 +550,7 @@ update_time_level (GstQueue * queue)
   if (queue->src_tainted) {
     queue->srctime =
         gst_segment_to_running_time (&queue->src_segment, GST_FORMAT_TIME,
-        queue->src_segment.last_stop);
+        queue->src_segment.position);
     queue->src_tainted = FALSE;
   }
   src_time = queue->srctime;
@@ -592,41 +564,30 @@ update_time_level (GstQueue * queue)
     queue->cur_level.time = 0;
 }
 
-/* take a NEWSEGMENT event and apply the values to segment, updating the time
+/* take a SEGMENT event and apply the values to segment, updating the time
  * level of queue. */
 static void
 apply_segment (GstQueue * queue, GstEvent * event, GstSegment * segment,
     gboolean sink)
 {
-  gboolean update;
-  GstFormat format;
-  gdouble rate, arate;
-  gint64 start, stop, time;
-
-  gst_event_parse_new_segment_full (event, &update, &rate, &arate,
-      &format, &start, &stop, &time);
+  gst_event_copy_segment (event, segment);
 
   /* now configure the values, we use these to track timestamps on the
    * sinkpad. */
-  if (format != GST_FORMAT_TIME) {
+  if (segment->format != GST_FORMAT_TIME) {
     /* non-time format, pretent the current time segment is closed with a
      * 0 start and unknown stop time. */
-    update = FALSE;
-    format = GST_FORMAT_TIME;
-    start = 0;
-    stop = -1;
-    time = 0;
+    segment->format = GST_FORMAT_TIME;
+    segment->start = 0;
+    segment->stop = -1;
+    segment->time = 0;
   }
-  gst_segment_set_newsegment_full (segment, update,
-      rate, arate, format, start, stop, time);
-
   if (sink)
     queue->sink_tainted = TRUE;
   else
     queue->src_tainted = TRUE;
 
-  GST_DEBUG_OBJECT (queue,
-      "configured NEWSEGMENT %" GST_SEGMENT_FORMAT, segment);
+  GST_DEBUG_OBJECT (queue, "configured SEGMENT %" GST_SEGMENT_FORMAT, segment);
 
   /* segment can update the time level of the queue */
   update_time_level (queue);
@@ -645,16 +606,16 @@ apply_buffer (GstQueue * queue, GstBuffer * buffer, GstSegment * segment,
   /* if no timestamp is set, assume it's continuous with the previous
    * time */
   if (timestamp == GST_CLOCK_TIME_NONE)
-    timestamp = segment->last_stop;
+    timestamp = segment->position;
 
   /* add duration */
   if (with_duration && duration != GST_CLOCK_TIME_NONE)
     timestamp += duration;
 
-  GST_LOG_OBJECT (queue, "last_stop updated to %" GST_TIME_FORMAT,
+  GST_LOG_OBJECT (queue, "position updated to %" GST_TIME_FORMAT,
       GST_TIME_ARGS (timestamp));
 
-  gst_segment_set_last_stop (segment, GST_FORMAT_TIME, timestamp);
+  segment->position = timestamp;
   if (sink)
     queue->sink_tainted = TRUE;
   else
@@ -698,7 +659,7 @@ gst_queue_locked_enqueue_buffer (GstQueue * queue, gpointer item)
 
   /* add buffer to the statistics */
   queue->cur_level.buffers++;
-  queue->cur_level.bytes += GST_BUFFER_SIZE (buffer);
+  queue->cur_level.bytes += gst_buffer_get_size (buffer);
   apply_buffer (queue, buffer, &queue->sink_segment, TRUE, TRUE);
 
   g_queue_push_tail (queue->queue, item);
@@ -719,7 +680,7 @@ gst_queue_locked_enqueue_event (GstQueue * queue, gpointer item)
       GST_CAT_LOG_OBJECT (queue_dataflow, queue, "got EOS from upstream");
       queue->eos = TRUE;
       break;
-    case GST_EVENT_NEWSEGMENT:
+    case GST_EVENT_SEGMENT:
       apply_segment (queue, event, &queue->sink_segment, TRUE);
       /* if the queue is empty, apply sink segment on the source */
       if (queue->queue->length == 0) {
@@ -756,7 +717,7 @@ gst_queue_locked_dequeue (GstQueue * queue, gboolean * is_buffer)
         "retrieved buffer %p from queue", buffer);
 
     queue->cur_level.buffers--;
-    queue->cur_level.bytes -= GST_BUFFER_SIZE (buffer);
+    queue->cur_level.bytes -= gst_buffer_get_size (buffer);
     apply_buffer (queue, buffer, &queue->src_segment, TRUE, FALSE);
 
     /* if the queue is empty now, update the other side */
@@ -775,7 +736,7 @@ gst_queue_locked_dequeue (GstQueue * queue, gboolean * is_buffer)
         /* queue is empty now that we dequeued the EOS */
         GST_QUEUE_CLEAR_LEVEL (queue->cur_level);
         break;
-      case GST_EVENT_NEWSEGMENT:
+      case GST_EVENT_SEGMENT:
         /* apply newsegment if it has not already been applied */
         if (G_LIKELY (!queue->newseg_applied_to_src)) {
           apply_segment (queue, event, &queue->src_segment, FALSE);
@@ -970,7 +931,7 @@ gst_queue_chain (GstPad * pad, GstBuffer * buffer)
 
   GST_CAT_LOG_OBJECT (queue_dataflow, queue,
       "received buffer %p of size %d, time %" GST_TIME_FORMAT ", duration %"
-      GST_TIME_FORMAT, buffer, GST_BUFFER_SIZE (buffer),
+      GST_TIME_FORMAT, buffer, gst_buffer_get_size (buffer),
       GST_TIME_ARGS (timestamp), GST_TIME_ARGS (duration));
 
   /* We make space available if we're "full" according to whatever
@@ -1026,7 +987,7 @@ gst_queue_chain (GstPad * pad, GstBuffer * buffer)
   }
 
   if (queue->tail_needs_discont) {
-    GstBuffer *subbuffer = gst_buffer_make_metadata_writable (buffer);
+    GstBuffer *subbuffer = gst_buffer_make_writable (buffer);
 
     if (subbuffer) {
       buffer = subbuffer;
@@ -1087,21 +1048,9 @@ out_unexpected:
 static void
 gst_queue_push_newsegment (GstQueue * queue)
 {
-  GstSegment *s;
   GstEvent *event;
 
-  s = &queue->src_segment;
-
-  if (s->accum != 0) {
-    event = gst_event_new_new_segment_full (FALSE, 1.0, 1.0, s->format, 0,
-        s->accum, 0);
-    GST_CAT_LOG_OBJECT (queue_dataflow, queue,
-        "pushing accum newsegment event");
-    gst_pad_push_event (queue->srcpad, event);
-  }
-
-  event = gst_event_new_new_segment_full (FALSE, s->rate, s->applied_rate,
-      s->format, s->start, s->stop, s->time);
+  event = gst_event_new_segment (&queue->src_segment);
   GST_CAT_LOG_OBJECT (queue_dataflow, queue, "pushing real newsegment event");
   gst_pad_push_event (queue->srcpad, event);
 }
@@ -1122,12 +1071,14 @@ gst_queue_push_one (GstQueue * queue)
 next:
   if (is_buffer) {
     GstBuffer *buffer;
+#if 0
     GstCaps *caps;
+#endif
 
     buffer = GST_BUFFER_CAST (data);
 
     if (queue->head_needs_discont) {
-      GstBuffer *subbuffer = gst_buffer_make_metadata_writable (buffer);
+      GstBuffer *subbuffer = gst_buffer_make_writable (buffer);
 
       if (subbuffer) {
         buffer = subbuffer;
@@ -1137,10 +1088,12 @@ next:
       }
       queue->head_needs_discont = FALSE;
     }
-
+#if 0
     caps = GST_BUFFER_CAPS (buffer);
+#endif
 
     GST_QUEUE_MUTEX_UNLOCK (queue);
+#if 0
     /* set the right caps on the pad now. We do this before pushing the buffer
      * because the pad_push call will check (using acceptcaps) if the buffer can
      * be set on the pad, which might fail because this will be propagated
@@ -1148,6 +1101,7 @@ next:
      * caps did not change, so we don't have to change caps on the pad. */
     if (caps && caps != GST_PAD_CAPS (queue->srcpad))
       gst_pad_set_caps (queue->srcpad, caps);
+#endif
 
     if (queue->push_newsegment) {
       gst_queue_push_newsegment (queue);
@@ -1161,7 +1115,7 @@ next:
       GST_CAT_LOG_OBJECT (queue_dataflow, queue,
           "got UNEXPECTED from downstream");
       /* stop pushing buffers, we dequeue all items until we see an item that we
-       * can push again, which is EOS or NEWSEGMENT. If there is nothing in the
+       * can push again, which is EOS or SEGMENT. If there is nothing in the
        * queue we can push, we set a flag to make the sinkpad refuse more
        * buffers with an UNEXPECTED return value. */
       while ((data = gst_queue_locked_dequeue (queue, &is_buffer))) {
@@ -1173,7 +1127,7 @@ next:
           GstEvent *event = GST_EVENT_CAST (data);
           GstEventType type = GST_EVENT_TYPE (event);
 
-          if (type == GST_EVENT_EOS || type == GST_EVENT_NEWSEGMENT) {
+          if (type == GST_EVENT_EOS || type == GST_EVENT_SEGMENT) {
             /* we found a pushable item in the queue, push it out */
             GST_CAT_LOG_OBJECT (queue_dataflow, queue,
                 "pushing pushable event %s after UNEXPECTED",
@@ -1187,7 +1141,7 @@ next:
       }
       /* no more items in the queue. Set the unexpected flag so that upstream
        * make us refuse any more buffers on the sinkpad. Since we will still
-       * accept EOS and NEWSEGMENT we return _FLOW_OK to the caller so that the
+       * accept EOS and SEGMENT we return _FLOW_OK to the caller so that the
        * task function does not shut down. */
       queue->unexpected = TRUE;
       result = GST_FLOW_OK;
@@ -1198,7 +1152,7 @@ next:
 
     GST_QUEUE_MUTEX_UNLOCK (queue);
 
-    if (queue->push_newsegment && type != GST_EVENT_NEWSEGMENT) {
+    if (queue->push_newsegment && type != GST_EVENT_SEGMENT) {
       gst_queue_push_newsegment (queue);
     }
     gst_pad_push_event (queue->srcpad, event);
index f1dce4b..798c17a 100644 (file)
@@ -209,13 +209,12 @@ enum
   }                                                                     \
 } G_STMT_END
 
-#define _do_init(bla) \
+#define _do_init \
     GST_DEBUG_CATEGORY_INIT (queue_debug, "queue2", 0, "queue element"); \
     GST_DEBUG_CATEGORY_INIT (queue_dataflow, "queue2_dataflow", 0, \
         "dataflow inside the queue element");
-
-GST_BOILERPLATE_FULL (GstQueue2, gst_queue2, GstElement, GST_TYPE_ELEMENT,
-    _do_init);
+#define gst_queue2_parent_class parent_class
+G_DEFINE_TYPE_WITH_CODE (GstQueue2, gst_queue2, GST_TYPE_ELEMENT, _do_init);
 
 static void gst_queue2_finalize (GObject * object);
 
@@ -225,8 +224,6 @@ static void gst_queue2_get_property (GObject * object,
     guint prop_id, GValue * value, GParamSpec * pspec);
 
 static GstFlowReturn gst_queue2_chain (GstPad * pad, GstBuffer * buffer);
-static GstFlowReturn gst_queue2_bufferalloc (GstPad * pad, guint64 offset,
-    guint size, GstCaps * caps, GstBuffer ** buf);
 static GstFlowReturn gst_queue2_push_one (GstQueue2 * queue);
 static void gst_queue2_loop (GstPad * pad);
 
@@ -237,12 +234,11 @@ static gboolean gst_queue2_handle_src_query (GstPad * pad, GstQuery * query);
 static gboolean gst_queue2_handle_query (GstElement * element,
     GstQuery * query);
 
-static GstCaps *gst_queue2_getcaps (GstPad * pad);
+static GstCaps *gst_queue2_getcaps (GstPad * pad, GstCaps * filter);
 static gboolean gst_queue2_acceptcaps (GstPad * pad, GstCaps * caps);
 
 static GstFlowReturn gst_queue2_get_range (GstPad * pad, guint64 offset,
     guint length, GstBuffer ** buffer);
-static gboolean gst_queue2_src_checkgetrange_function (GstPad * pad);
 
 static gboolean gst_queue2_src_activate_pull (GstPad * pad, gboolean active);
 static gboolean gst_queue2_src_activate_push (GstPad * pad, gboolean active);
@@ -255,27 +251,9 @@ static gboolean gst_queue2_is_filled (GstQueue2 * queue);
 
 static void update_cur_level (GstQueue2 * queue, GstQueue2Range * range);
 
-
 /* static guint gst_queue2_signals[LAST_SIGNAL] = { 0 }; */
 
 static void
-gst_queue2_base_init (gpointer g_class)
-{
-  GstElementClass *gstelement_class = GST_ELEMENT_CLASS (g_class);
-
-  gst_element_class_add_pad_template (gstelement_class,
-      gst_static_pad_template_get (&srctemplate));
-  gst_element_class_add_pad_template (gstelement_class,
-      gst_static_pad_template_get (&sinktemplate));
-
-  gst_element_class_set_details_simple (gstelement_class, "Queue 2",
-      "Generic",
-      "Simple data queue",
-      "Erik Walthinsen <omega@cse.ogi.edu>, "
-      "Wim Taymans <wim.taymans@gmail.com>");
-}
-
-static void
 gst_queue2_class_init (GstQueue2Class * klass)
 {
   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
@@ -375,12 +353,23 @@ gst_queue2_class_init (GstQueue2Class * klass)
   /* set several parent class virtual functions */
   gobject_class->finalize = gst_queue2_finalize;
 
+  gst_element_class_add_pad_template (gstelement_class,
+      gst_static_pad_template_get (&srctemplate));
+  gst_element_class_add_pad_template (gstelement_class,
+      gst_static_pad_template_get (&sinktemplate));
+
+  gst_element_class_set_details_simple (gstelement_class, "Queue 2",
+      "Generic",
+      "Simple data queue",
+      "Erik Walthinsen <omega@cse.ogi.edu>, "
+      "Wim Taymans <wim.taymans@gmail.com>");
+
   gstelement_class->change_state = GST_DEBUG_FUNCPTR (gst_queue2_change_state);
   gstelement_class->query = GST_DEBUG_FUNCPTR (gst_queue2_handle_query);
 }
 
 static void
-gst_queue2_init (GstQueue2 * queue, GstQueue2Class * g_class)
+gst_queue2_init (GstQueue2 * queue)
 {
   queue->sinkpad = gst_pad_new_from_static_template (&sinktemplate, "sink");
 
@@ -394,8 +383,6 @@ gst_queue2_init (GstQueue2 * queue, GstQueue2Class * g_class)
       GST_DEBUG_FUNCPTR (gst_queue2_getcaps));
   gst_pad_set_acceptcaps_function (queue->sinkpad,
       GST_DEBUG_FUNCPTR (gst_queue2_acceptcaps));
-  gst_pad_set_bufferalloc_function (queue->sinkpad,
-      GST_DEBUG_FUNCPTR (gst_queue2_bufferalloc));
   gst_element_add_pad (GST_ELEMENT (queue), queue->sinkpad);
 
   queue->srcpad = gst_pad_new_from_static_template (&srctemplate, "src");
@@ -406,8 +393,6 @@ gst_queue2_init (GstQueue2 * queue, GstQueue2Class * g_class)
       GST_DEBUG_FUNCPTR (gst_queue2_src_activate_push));
   gst_pad_set_getrange_function (queue->srcpad,
       GST_DEBUG_FUNCPTR (gst_queue2_get_range));
-  gst_pad_set_checkgetrange_function (queue->srcpad,
-      GST_DEBUG_FUNCPTR (gst_queue2_src_checkgetrange_function));
   gst_pad_set_getcaps_function (queue->srcpad,
       GST_DEBUG_FUNCPTR (gst_queue2_getcaps));
   gst_pad_set_acceptcaps_function (queue->srcpad,
@@ -642,7 +627,7 @@ gst_queue2_acceptcaps (GstPad * pad, GstCaps * caps)
 }
 
 static GstCaps *
-gst_queue2_getcaps (GstPad * pad)
+gst_queue2_getcaps (GstPad * pad, GstCaps * filter)
 {
   GstQueue2 *queue;
   GstPad *otherpad;
@@ -650,33 +635,18 @@ gst_queue2_getcaps (GstPad * pad)
 
   queue = GST_QUEUE2 (gst_pad_get_parent (pad));
   if (G_UNLIKELY (queue == NULL))
-    return gst_caps_new_any ();
+    return (filter ? gst_caps_ref (filter) : gst_caps_new_any ());
 
   otherpad = (pad == queue->srcpad ? queue->sinkpad : queue->srcpad);
-  result = gst_pad_peer_get_caps (otherpad);
+  result = gst_pad_peer_get_caps (otherpad, filter);
   if (result == NULL)
-    result = gst_caps_new_any ();
+    result = (filter ? gst_caps_ref (filter) : gst_caps_new_any ());
 
   gst_object_unref (queue);
 
   return result;
 }
 
-static GstFlowReturn
-gst_queue2_bufferalloc (GstPad * pad, guint64 offset, guint size,
-    GstCaps * caps, GstBuffer ** buf)
-{
-  GstQueue2 *queue;
-  GstFlowReturn result;
-
-  queue = GST_QUEUE2 (GST_PAD_PARENT (pad));
-
-  /* Forward to src pad, without setting caps on the src pad */
-  result = gst_pad_alloc_buffer (queue->srcpad, offset, size, caps, buf);
-
-  return result;
-}
-
 /* calculate the diff between running time on the sink and src of the queue.
  * This is the total amount of time in the queue. */
 static void
@@ -685,14 +655,14 @@ update_time_level (GstQueue2 * queue)
   if (queue->sink_tainted) {
     queue->sinktime =
         gst_segment_to_running_time (&queue->sink_segment, GST_FORMAT_TIME,
-        queue->sink_segment.last_stop);
+        queue->sink_segment.position);
     queue->sink_tainted = FALSE;
   }
 
   if (queue->src_tainted) {
     queue->srctime =
         gst_segment_to_running_time (&queue->src_segment, GST_FORMAT_TIME,
-        queue->src_segment.last_stop);
+        queue->src_segment.position);
     queue->src_tainted = FALSE;
   }
 
@@ -707,30 +677,18 @@ update_time_level (GstQueue2 * queue)
     queue->cur_level.time = 0;
 }
 
-/* take a NEWSEGMENT event and apply the values to segment, updating the time
+/* take a SEGMENT event and apply the values to segment, updating the time
  * level of queue. */
 static void
 apply_segment (GstQueue2 * queue, GstEvent * event, GstSegment * segment,
     gboolean is_sink)
 {
-  gboolean update;
-  GstFormat format;
-  gdouble rate, arate;
-  gint64 start, stop, time;
-
-  gst_event_parse_new_segment_full (event, &update, &rate, &arate,
-      &format, &start, &stop, &time);
-
-  GST_DEBUG_OBJECT (queue,
-      "received NEWSEGMENT update %d, rate %lf, applied rate %lf, "
-      "format %d, "
-      "%" G_GINT64_FORMAT " -- %" G_GINT64_FORMAT ", time %"
-      G_GINT64_FORMAT, update, rate, arate, format, start, stop, time);
+  gst_event_copy_segment (event, segment);
 
-  if (format == GST_FORMAT_BYTES) {
+  if (segment->format == GST_FORMAT_BYTES) {
     if (QUEUE_IS_USING_TEMP_FILE (queue)) {
       /* start is where we'll be getting from and as such writing next */
-      queue->current = add_range (queue, start);
+      queue->current = add_range (queue, segment->start);
       /* update the stats for this range */
       update_cur_level (queue, queue->current);
     }
@@ -738,20 +696,16 @@ apply_segment (GstQueue2 * queue, GstEvent * event, GstSegment * segment,
 
   /* now configure the values, we use these to track timestamps on the
    * sinkpad. */
-  if (format != GST_FORMAT_TIME) {
+  if (segment->format != GST_FORMAT_TIME) {
     /* non-time format, pretent the current time segment is closed with a
      * 0 start and unknown stop time. */
-    update = FALSE;
-    format = GST_FORMAT_TIME;
-    start = 0;
-    stop = -1;
-    time = 0;
+    segment->format = GST_FORMAT_TIME;
+    segment->start = 0;
+    segment->stop = -1;
+    segment->time = 0;
   }
-  gst_segment_set_newsegment_full (segment, update,
-      rate, arate, format, start, stop, time);
 
-  GST_DEBUG_OBJECT (queue,
-      "configured NEWSEGMENT %" GST_SEGMENT_FORMAT, segment);
+  GST_DEBUG_OBJECT (queue, "configured SEGMENT %" GST_SEGMENT_FORMAT, segment);
 
   if (is_sink)
     queue->sink_tainted = TRUE;
@@ -775,16 +729,16 @@ apply_buffer (GstQueue2 * queue, GstBuffer * buffer, GstSegment * segment,
   /* if no timestamp is set, assume it's continuous with the previous
    * time */
   if (timestamp == GST_CLOCK_TIME_NONE)
-    timestamp = segment->last_stop;
+    timestamp = segment->position;
 
   /* add duration */
   if (duration != GST_CLOCK_TIME_NONE)
     timestamp += duration;
 
-  GST_DEBUG_OBJECT (queue, "last_stop updated to %" GST_TIME_FORMAT,
+  GST_DEBUG_OBJECT (queue, "position updated to %" GST_TIME_FORMAT,
       GST_TIME_ARGS (timestamp));
 
-  gst_segment_set_last_stop (segment, GST_FORMAT_TIME, timestamp);
+  segment->position = timestamp;
 
   if (is_sink)
     queue->sink_tainted = TRUE;
@@ -1116,9 +1070,9 @@ gst_queue2_have_data (GstQueue2 * queue, guint64 offset, guint length)
 #define FSEEK_FILE(file,offset)  (fseek (file, offset, SEEK_SET) != 0)
 #endif
 
-static gint64
+static GstFlowReturn
 gst_queue2_read_data_at_offset (GstQueue2 * queue, guint64 offset, guint length,
-    guint8 * dst)
+    guint8 * dst, gint64 * read_return)
 {
   guint8 *ring_buffer;
   size_t res;
@@ -1150,7 +1104,9 @@ gst_queue2_read_data_at_offset (GstQueue2 * queue, guint64 offset, guint length,
       goto eos;
   }
 
-  return res;
+  *read_return = res;
+
+  return GST_FLOW_OK;
 
 seek_failed:
   {
@@ -1177,13 +1133,13 @@ gst_queue2_create_read (GstQueue2 * queue, guint64 offset, guint length,
   guint8 *data;
   guint64 file_offset;
   guint block_length, remaining, read_length;
-  gint64 read_return;
   guint64 rb_size;
   guint64 rpos;
+  GstFlowReturn ret = GST_FLOW_OK;
 
   /* allocate the output buffer of the requested size */
-  buf = gst_buffer_new_and_alloc (length);
-  data = GST_BUFFER_DATA (buf);
+  buf = gst_buffer_new_allocate (NULL, length, 0);
+  data = gst_buffer_map (buf, NULL, NULL, GST_MAP_WRITE);
 
   GST_DEBUG_OBJECT (queue, "Reading %u bytes from %" G_GUINT64_FORMAT, length,
       offset);
@@ -1225,12 +1181,8 @@ gst_queue2_create_read (GstQueue2 * queue, guint64 offset, guint length,
                 "EOS hit but read %" G_GUINT64_FORMAT " bytes that we have",
                 level);
             read_length = level;
-          } else {
-            GST_DEBUG_OBJECT (queue,
-                "EOS hit and we don't have any requested data");
-            gst_buffer_unref (buf);
-            return GST_FLOW_UNEXPECTED;
-          }
+          } else
+            goto hit_eos;
         }
       }
 
@@ -1274,10 +1226,12 @@ gst_queue2_create_read (GstQueue2 * queue, guint64 offset, guint length,
 
     /* while we still have data to read, we loop */
     while (read_length > 0) {
-      read_return =
+      gint64 read_return;
+
+      ret =
           gst_queue2_read_data_at_offset (queue, file_offset, block_length,
-          data);
-      if (read_return < 0)
+          data, &read_return);
+      if (ret != GST_FLOW_OK)
         goto read_error;
 
       file_offset += read_return;
@@ -1296,15 +1250,22 @@ gst_queue2_create_read (GstQueue2 * queue, guint64 offset, guint length,
     GST_DEBUG_OBJECT (queue, "%u bytes left to read", remaining);
   }
 
-  GST_BUFFER_SIZE (buf) = length;
+  gst_buffer_unmap (buf, data, length);
+
   GST_BUFFER_OFFSET (buf) = offset;
   GST_BUFFER_OFFSET_END (buf) = offset + length;
 
   *buffer = buf;
 
-  return GST_FLOW_OK;
+  return ret;
 
   /* ERRORS */
+hit_eos:
+  {
+    GST_DEBUG_OBJECT (queue, "EOS hit and we don't have any requested data");
+    gst_buffer_unref (buf);
+    return GST_FLOW_UNEXPECTED;
+  }
 out_flushing:
   {
     GST_DEBUG_OBJECT (queue, "we are flushing");
@@ -1314,8 +1275,9 @@ out_flushing:
 read_error:
   {
     GST_DEBUG_OBJECT (queue, "we have a read error");
+    gst_buffer_unmap (buf, data, 0);
     gst_buffer_unref (buf);
-    return read_return;
+    return ret;
   }
 }
 
@@ -1539,8 +1501,9 @@ out_flushing:
 static gboolean
 gst_queue2_create_write (GstQueue2 * queue, GstBuffer * buffer)
 {
-  guint8 *data, *ring_buffer;
+  guint8 *odata, *data, *ring_buffer;
   guint size, rb_size;
+  gsize osize;
   guint64 writing_pos, new_writing_pos;
   GstQueue2Range *range, *prev, *next;
 
@@ -1551,8 +1514,10 @@ gst_queue2_create_write (GstQueue2 * queue, GstBuffer * buffer)
   ring_buffer = queue->ring_buffer;
   rb_size = queue->ring_buffer_max_size;
 
-  size = GST_BUFFER_SIZE (buffer);
-  data = GST_BUFFER_DATA (buffer);
+  odata = gst_buffer_map (buffer, &osize, NULL, GST_MAP_READ);
+
+  size = osize;
+  data = odata;
 
   GST_DEBUG_OBJECT (queue, "Writing %u bytes to %" G_GUINT64_FORMAT, size,
       GST_BUFFER_OFFSET (buffer));
@@ -1774,7 +1739,9 @@ gst_queue2_create_write (GstQueue2 * queue, GstBuffer * buffer)
         queue->cur_level.bytes, QUEUE_MAX_BYTES (queue));
 
     GST_QUEUE2_SIGNAL_ADD (queue);
-  };
+  }
+
+  gst_buffer_unmap (buffer, odata, osize);
 
   return TRUE;
 
@@ -1782,12 +1749,14 @@ gst_queue2_create_write (GstQueue2 * queue, GstBuffer * buffer)
 out_flushing:
   {
     GST_DEBUG_OBJECT (queue, "we are flushing");
+    gst_buffer_unmap (buffer, odata, osize);
     /* FIXME - GST_FLOW_UNEXPECTED ? */
     return FALSE;
   }
 seek_failed:
   {
     GST_ELEMENT_ERROR (queue, RESOURCE, SEEK, (NULL), GST_ERROR_SYSTEM);
+    gst_buffer_unmap (buffer, odata, osize);
     return FALSE;
   }
 handle_error:
@@ -1803,6 +1772,7 @@ handle_error:
             ("%s", g_strerror (errno)));
       }
     }
+    gst_buffer_unmap (buffer, odata, osize);
     return FALSE;
   }
 }
@@ -1816,7 +1786,7 @@ gst_queue2_locked_enqueue (GstQueue2 * queue, gpointer item, gboolean isbuffer)
     guint size;
 
     buffer = GST_BUFFER_CAST (item);
-    size = GST_BUFFER_SIZE (buffer);
+    size = gst_buffer_get_size (buffer);
 
     /* add buffer to the statistics */
     if (QUEUE_IS_USING_QUEUE (queue)) {
@@ -1846,7 +1816,7 @@ gst_queue2_locked_enqueue (GstQueue2 * queue, gpointer item, gboolean isbuffer)
         GST_DEBUG_OBJECT (queue, "we have EOS");
         queue->is_eos = TRUE;
         break;
-      case GST_EVENT_NEWSEGMENT:
+      case GST_EVENT_SEGMENT:
         apply_segment (queue, event, &queue->sink_segment, TRUE);
         /* This is our first new segment, we hold it
          * as we can't save it on the temp file */
@@ -1923,7 +1893,7 @@ gst_queue2_locked_dequeue (GstQueue2 * queue, gboolean * is_buffer)
     guint size;
 
     buffer = GST_BUFFER_CAST (item);
-    size = GST_BUFFER_SIZE (buffer);
+    size = gst_buffer_get_size (buffer);
     *is_buffer = TRUE;
 
     GST_CAT_LOG_OBJECT (queue_dataflow, queue,
@@ -1955,7 +1925,7 @@ gst_queue2_locked_dequeue (GstQueue2 * queue, gboolean * is_buffer)
         /* queue is empty now that we dequeued the EOS */
         GST_QUEUE2_CLEAR_LEVEL (queue->cur_level);
         break;
-      case GST_EVENT_NEWSEGMENT:
+      case GST_EVENT_SEGMENT:
         apply_segment (queue, event, &queue->src_segment, FALSE);
         break;
       default:
@@ -2154,7 +2124,7 @@ gst_queue2_chain (GstPad * pad, GstBuffer * buffer)
 
   GST_CAT_LOG_OBJECT (queue_dataflow, queue,
       "received buffer %p of size %d, time %" GST_TIME_FORMAT ", duration %"
-      GST_TIME_FORMAT, buffer, GST_BUFFER_SIZE (buffer),
+      GST_TIME_FORMAT, buffer, gst_buffer_get_size (buffer),
       GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buffer)),
       GST_TIME_ARGS (GST_BUFFER_DURATION (buffer)));
 
@@ -2225,15 +2195,21 @@ next:
 
   if (is_buffer) {
     GstBuffer *buffer;
+#if 0
     GstCaps *caps;
+#endif
 
     buffer = GST_BUFFER_CAST (data);
+#if 0
     caps = GST_BUFFER_CAPS (buffer);
+#endif
 
+#if 0
     /* set caps before pushing the buffer so that core does not try to do
      * something fancy to check if this is possible. */
     if (caps && caps != GST_PAD_CAPS (queue->srcpad))
       gst_pad_set_caps (queue->srcpad, caps);
+#endif
 
     result = gst_pad_push (queue->srcpad, buffer);
 
@@ -2243,7 +2219,7 @@ next:
       GST_CAT_LOG_OBJECT (queue_dataflow, queue,
           "got UNEXPECTED from downstream");
       /* stop pushing buffers, we dequeue all items until we see an item that we
-       * can push again, which is EOS or NEWSEGMENT. If there is nothing in the
+       * can push again, which is EOS or SEGMENT. If there is nothing in the
        * queue we can push, we set a flag to make the sinkpad refuse more
        * buffers with an UNEXPECTED return value until we receive something
        * pushable again or we get flushed. */
@@ -2256,7 +2232,7 @@ next:
           GstEvent *event = GST_EVENT_CAST (data);
           GstEventType type = GST_EVENT_TYPE (event);
 
-          if (type == GST_EVENT_EOS || type == GST_EVENT_NEWSEGMENT) {
+          if (type == GST_EVENT_EOS || type == GST_EVENT_SEGMENT) {
             /* we found a pushable item in the queue, push it out */
             GST_CAT_LOG_OBJECT (queue_dataflow, queue,
                 "pushing pushable event %s after UNEXPECTED",
@@ -2270,7 +2246,7 @@ next:
       }
       /* no more items in the queue. Set the unexpected flag so that upstream
        * make us refuse any more buffers on the sinkpad. Since we will still
-       * accept EOS and NEWSEGMENT we return _FLOW_OK to the caller so that the
+       * accept EOS and SEGMENT we return _FLOW_OK to the caller so that the
        * task function does not shut down. */
       queue->unexpected = TRUE;
       result = GST_FLOW_OK;
@@ -2619,6 +2595,16 @@ gst_queue2_handle_src_query (GstPad * pad, GstQuery * query)
       }
       break;
     }
+    case GST_QUERY_SCHEDULING:
+    {
+      gboolean pull_mode;
+
+      /* we can operate in pull mode when we are using a tempfile */
+      pull_mode = !QUEUE_IS_USING_QUEUE (queue);
+
+      gst_query_set_scheduling (query, pull_mode, pull_mode, FALSE, 0, -1, 1);
+      break;
+    }
     default:
       /* peer handled other queries */
       if (!gst_queue2_peer_query (queue, queue->sinkpad, query))
@@ -2719,22 +2705,6 @@ out_unexpected:
   }
 }
 
-static gboolean
-gst_queue2_src_checkgetrange_function (GstPad * pad)
-{
-  GstQueue2 *queue;
-  gboolean ret;
-
-  queue = GST_QUEUE2 (gst_pad_get_parent (pad));
-
-  /* we can operate in pull mode when we are using a tempfile */
-  ret = !QUEUE_IS_USING_QUEUE (queue);
-
-  gst_object_unref (GST_OBJECT (queue));
-
-  return ret;
-}
-
 /* sink currently only operates in push mode */
 static gboolean
 gst_queue2_sink_activate_push (GstPad * pad, gboolean active)
@@ -2823,7 +2793,7 @@ gst_queue2_src_activate_pull (GstPad * pad, gboolean active)
         result = gst_queue2_open_temp_location_file (queue);
       } else if (!queue->ring_buffer) {
         queue->ring_buffer = g_malloc (queue->ring_buffer_max_size);
-        result = ! !queue->ring_buffer;
+        result = !!queue->ring_buffer;
       } else {
         result = TRUE;
       }
index bf9fef2..56a5613 100644 (file)
@@ -105,14 +105,15 @@ static GstStaticPadTemplate tee_src_template = GST_STATIC_PAD_TEMPLATE ("src%d",
     GST_PAD_REQUEST,
     GST_STATIC_CAPS_ANY);
 
-#define _do_init(bla) \
-    GST_DEBUG_CATEGORY_INIT (gst_tee_debug, "tee", 0, "tee element");
-
-GST_BOILERPLATE_FULL (GstTee, gst_tee, GstElement, GST_TYPE_ELEMENT, _do_init);
-
 /* structure and quark to keep track of which pads have been pushed */
 static GQuark push_data;
 
+#define _do_init \
+    GST_DEBUG_CATEGORY_INIT (gst_tee_debug, "tee", 0, "tee element"); \
+    push_data = g_quark_from_static_string ("tee-push-data");
+#define gst_tee_parent_class parent_class
+G_DEFINE_TYPE_WITH_CODE (GstTee, gst_tee, GST_TYPE_ELEMENT, _do_init);
+
 static GParamSpec *pspec_last_message = NULL;
 static GParamSpec *pspec_alloc_pad = NULL;
 
@@ -124,7 +125,7 @@ typedef struct
 } PushData;
 
 static GstPad *gst_tee_request_new_pad (GstElement * element,
-    GstPadTemplate * temp, const gchar * unused);
+    GstPadTemplate * temp, const gchar * unused, const GstCaps * caps);
 static void gst_tee_release_pad (GstElement * element, GstPad * pad);
 
 static void gst_tee_finalize (GObject * object);
@@ -136,34 +137,14 @@ static void gst_tee_dispose (GObject * object);
 
 static GstFlowReturn gst_tee_chain (GstPad * pad, GstBuffer * buffer);
 static GstFlowReturn gst_tee_chain_list (GstPad * pad, GstBufferList * list);
-static GstFlowReturn gst_tee_buffer_alloc (GstPad * pad, guint64 offset,
-    guint size, GstCaps * caps, GstBuffer ** buf);
+static gboolean gst_tee_sink_event (GstPad * pad, GstEvent * event);
 static gboolean gst_tee_sink_acceptcaps (GstPad * pad, GstCaps * caps);
 static gboolean gst_tee_sink_activate_push (GstPad * pad, gboolean active);
-static gboolean gst_tee_src_check_get_range (GstPad * pad);
+static gboolean gst_tee_src_query (GstPad * pad, GstQuery * query);
 static gboolean gst_tee_src_activate_pull (GstPad * pad, gboolean active);
 static GstFlowReturn gst_tee_src_get_range (GstPad * pad, guint64 offset,
     guint length, GstBuffer ** buf);
 
-
-static void
-gst_tee_base_init (gpointer g_class)
-{
-  GstElementClass *gstelement_class = GST_ELEMENT_CLASS (g_class);
-
-  gst_element_class_set_details_simple (gstelement_class,
-      "Tee pipe fitting",
-      "Generic",
-      "1-to-N pipe fitting",
-      "Erik Walthinsen <omega@cse.ogi.edu>, " "Wim Taymans <wim@fluendo.com>");
-  gst_element_class_add_pad_template (gstelement_class,
-      gst_static_pad_template_get (&sinktemplate));
-  gst_element_class_add_pad_template (gstelement_class,
-      gst_static_pad_template_get (&tee_src_template));
-
-  push_data = g_quark_from_static_string ("tee-push-data");
-}
-
 static void
 gst_tee_dispose (GObject * object)
 {
@@ -242,27 +223,35 @@ gst_tee_class_init (GstTeeClass * klass)
   g_object_class_install_property (gobject_class, PROP_ALLOC_PAD,
       pspec_alloc_pad);
 
+  gst_element_class_set_details_simple (gstelement_class,
+      "Tee pipe fitting",
+      "Generic",
+      "1-to-N pipe fitting",
+      "Erik Walthinsen <omega@cse.ogi.edu>, " "Wim Taymans <wim@fluendo.com>");
+  gst_element_class_add_pad_template (gstelement_class,
+      gst_static_pad_template_get (&sinktemplate));
+  gst_element_class_add_pad_template (gstelement_class,
+      gst_static_pad_template_get (&tee_src_template));
+
   gstelement_class->request_new_pad =
       GST_DEBUG_FUNCPTR (gst_tee_request_new_pad);
   gstelement_class->release_pad = GST_DEBUG_FUNCPTR (gst_tee_release_pad);
 }
 
 static void
-gst_tee_init (GstTee * tee, GstTeeClass * g_class)
+gst_tee_init (GstTee * tee)
 {
   tee->dyn_lock = g_mutex_new ();
 
   tee->sinkpad = gst_pad_new_from_static_template (&sinktemplate, "sink");
   tee->sink_mode = GST_ACTIVATE_NONE;
 
-  gst_pad_set_setcaps_function (tee->sinkpad,
-      GST_DEBUG_FUNCPTR (gst_pad_proxy_setcaps));
+  gst_pad_set_event_function (tee->sinkpad,
+      GST_DEBUG_FUNCPTR (gst_tee_sink_event));
   gst_pad_set_getcaps_function (tee->sinkpad,
       GST_DEBUG_FUNCPTR (gst_pad_proxy_getcaps));
   gst_pad_set_acceptcaps_function (tee->sinkpad,
       GST_DEBUG_FUNCPTR (gst_tee_sink_acceptcaps));
-  gst_pad_set_bufferalloc_function (tee->sinkpad,
-      GST_DEBUG_FUNCPTR (gst_tee_buffer_alloc));
   gst_pad_set_activatepush_function (tee->sinkpad,
       GST_DEBUG_FUNCPTR (gst_tee_sink_activate_push));
   gst_pad_set_chain_function (tee->sinkpad, GST_DEBUG_FUNCPTR (gst_tee_chain));
@@ -283,9 +272,19 @@ gst_tee_notify_alloc_pad (GstTee * tee)
 #endif
 }
 
+static GstFlowReturn
+forward_sticky_events (GstPad * pad, GstEvent * event, gpointer user_data)
+{
+  GstPad *srcpad = GST_PAD_CAST (user_data);
+
+  gst_pad_push_event (srcpad, gst_event_ref (event));
+
+  return GST_FLOW_OK;
+}
+
 static GstPad *
 gst_tee_request_new_pad (GstElement * element, GstPadTemplate * templ,
-    const gchar * unused)
+    const gchar * unused, const GstCaps * caps)
 {
   gchar *name;
   GstPad *srcpad;
@@ -331,16 +330,15 @@ gst_tee_request_new_pad (GstElement * element, GstPadTemplate * templ,
   if (!res)
     goto activate_failed;
 
-  gst_pad_set_setcaps_function (srcpad,
-      GST_DEBUG_FUNCPTR (gst_pad_proxy_setcaps));
   gst_pad_set_getcaps_function (srcpad,
       GST_DEBUG_FUNCPTR (gst_pad_proxy_getcaps));
   gst_pad_set_activatepull_function (srcpad,
       GST_DEBUG_FUNCPTR (gst_tee_src_activate_pull));
-  gst_pad_set_checkgetrange_function (srcpad,
-      GST_DEBUG_FUNCPTR (gst_tee_src_check_get_range));
+  gst_pad_set_query_function (srcpad, GST_DEBUG_FUNCPTR (gst_tee_src_query));
   gst_pad_set_getrange_function (srcpad,
       GST_DEBUG_FUNCPTR (gst_tee_src_get_range));
+  /* Forward sticky events to the new srcpad */
+  gst_pad_sticky_events_foreach (tee->sinkpad, forward_sticky_events, srcpad);
   gst_element_add_pad (GST_ELEMENT_CAST (tee), srcpad);
 
   return srcpad;
@@ -389,11 +387,14 @@ gst_tee_release_pad (GstElement * element, GstPad * pad)
   }
   GST_OBJECT_UNLOCK (tee);
 
-  gst_pad_set_active (pad, FALSE);
-
+  gst_object_ref (pad);
   gst_element_remove_pad (GST_ELEMENT_CAST (tee), pad);
+
+  gst_pad_set_active (pad, FALSE);
   GST_TEE_DYN_UNLOCK (tee);
 
+  gst_object_unref (pad);
+
   if (changed) {
     gst_tee_notify_alloc_pad (tee);
   }
@@ -477,119 +478,16 @@ gst_tee_get_property (GObject * object, guint prop_id, GValue * value,
   GST_OBJECT_UNLOCK (tee);
 }
 
-/* we have no previous source pad we can use to proxy the pad alloc. Loop over
- * the source pads, try to alloc a buffer on each one of them. Keep a reference
- * to the first pad that succeeds, we will be using it to alloc more buffers
- * later.  must be called with the OBJECT_LOCK on tee. */
-static GstFlowReturn
-gst_tee_find_buffer_alloc (GstTee * tee, guint64 offset, guint size,
-    GstCaps * caps, GstBuffer ** buf)
+static gboolean
+gst_tee_sink_event (GstPad * pad, GstEvent * event)
 {
-  GstFlowReturn res;
-  GList *pads;
-  guint32 cookie;
-
-  res = GST_FLOW_NOT_LINKED;
-
-retry:
-  pads = GST_ELEMENT_CAST (tee)->srcpads;
-  cookie = GST_ELEMENT_CAST (tee)->pads_cookie;
-
-  while (pads) {
-    GstPad *pad;
-    PushData *data;
-
-    pad = GST_PAD_CAST (pads->data);
-    gst_object_ref (pad);
-    GST_DEBUG_OBJECT (tee, "try alloc on pad %s:%s", GST_DEBUG_PAD_NAME (pad));
-    GST_OBJECT_UNLOCK (tee);
-
-    GST_TEE_DYN_LOCK (tee);
-    data = g_object_get_qdata ((GObject *) pad, push_data);
-    if (!data->removed)
-      res = gst_pad_alloc_buffer (pad, offset, size, caps, buf);
-    else
-      res = GST_FLOW_NOT_LINKED;
-    GST_TEE_DYN_UNLOCK (tee);
-
-    GST_DEBUG_OBJECT (tee, "got return value %d", res);
-
-    gst_object_unref (pad);
+  gboolean res;
 
-    GST_OBJECT_LOCK (tee);
-    if (GST_ELEMENT_CAST (tee)->pads_cookie != cookie) {
-      GST_DEBUG_OBJECT (tee, "pad list changed, restart");
-      /* pad list changed, restart. If the pad alloc function returned OK we
-       * need to unref the buffer */
-      if (res == GST_FLOW_OK)
-        gst_buffer_unref (*buf);
-      *buf = NULL;
-      goto retry;
-    }
-    if (!data->removed && res == GST_FLOW_OK) {
-      GST_DEBUG_OBJECT (tee, "we have a buffer on pad %s:%s",
-          GST_DEBUG_PAD_NAME (pad));
-      /* we have a buffer, keep the pad for later and exit the loop. */
-      tee->allocpad = pad;
-      GST_OBJECT_UNLOCK (tee);
-      gst_tee_notify_alloc_pad (tee);
-      GST_OBJECT_LOCK (tee);
+  switch (GST_EVENT_TYPE (event)) {
+    default:
+      res = gst_pad_event_default (pad, event);
       break;
-    }
-    /* no valid buffer, try another pad */
-    pads = g_list_next (pads);
   }
-
-  return res;
-}
-
-static GstFlowReturn
-gst_tee_buffer_alloc (GstPad * pad, guint64 offset, guint size,
-    GstCaps * caps, GstBuffer ** buf)
-{
-  GstTee *tee;
-  GstFlowReturn res;
-  GstPad *allocpad;
-
-  tee = GST_TEE_CAST (gst_pad_get_parent (pad));
-  if (G_UNLIKELY (tee == NULL))
-    return GST_FLOW_WRONG_STATE;
-
-  res = GST_FLOW_NOT_LINKED;
-
-  GST_OBJECT_LOCK (tee);
-  if ((allocpad = tee->allocpad)) {
-    PushData *data;
-
-    /* if we had a previous pad we used for allocating a buffer, continue using
-     * it. */
-    GST_DEBUG_OBJECT (tee, "using pad %s:%s for alloc",
-        GST_DEBUG_PAD_NAME (allocpad));
-    gst_object_ref (allocpad);
-    GST_OBJECT_UNLOCK (tee);
-
-    GST_TEE_DYN_LOCK (tee);
-    data = g_object_get_qdata ((GObject *) allocpad, push_data);
-    if (!data->removed)
-      res = gst_pad_alloc_buffer (allocpad, offset, size, caps, buf);
-    else
-      res = GST_FLOW_NOT_LINKED;
-    GST_TEE_DYN_UNLOCK (tee);
-
-    gst_object_unref (allocpad);
-
-    GST_OBJECT_LOCK (tee);
-  }
-  /* either we failed to alloc on the the previous pad or we did not have a
-   * previous pad. */
-  if (res == GST_FLOW_NOT_LINKED) {
-    /* find a new pad to alloc a buffer on */
-    GST_DEBUG_OBJECT (tee, "finding pad for alloc");
-    res = gst_tee_find_buffer_alloc (tee, offset, size, caps, buf);
-  }
-  GST_OBJECT_UNLOCK (tee);
-
-  gst_object_unref (tee);
   return res;
 }
 
@@ -600,6 +498,7 @@ gst_tee_sink_acceptcaps (GstPad * pad, GstCaps * caps)
   GstTee *tee;
   gboolean res, done;
   GstIterator *it;
+  GValue item = { 0, };
 
   tee = GST_TEE_CAST (GST_PAD_PARENT (pad));
 
@@ -608,12 +507,10 @@ gst_tee_sink_acceptcaps (GstPad * pad, GstCaps * caps)
   res = TRUE;
   done = FALSE;
   while (!done && res) {
-    gpointer item;
-
     switch (gst_iterator_next (it, &item)) {
       case GST_ITERATOR_OK:
-        res &= gst_pad_peer_accept_caps (GST_PAD_CAST (item), caps);
-        gst_object_unref (item);
+        res &= gst_pad_peer_accept_caps (g_value_get_object (&item), caps);
+        g_value_reset (&item);
         break;
       case GST_ITERATOR_RESYNC:
         res = TRUE;
@@ -628,6 +525,7 @@ gst_tee_sink_acceptcaps (GstPad * pad, GstCaps * caps)
         break;
     }
   }
+  g_value_unset (&item);
   gst_iterator_free (it);
 
   return res;
@@ -644,9 +542,9 @@ gst_tee_do_message (GstTee * tee, GstPad * pad, gpointer data, gboolean is_list)
         GST_DEBUG_PAD_NAME (pad), data);
   } else {
     tee->last_message =
-        g_strdup_printf ("chain        ******* (%s:%s)t (%d bytes, %"
-        G_GUINT64_FORMAT ") %p", GST_DEBUG_PAD_NAME (pad),
-        GST_BUFFER_SIZE (data), GST_BUFFER_TIMESTAMP (data), data);
+        g_strdup_printf ("chain        ******* (%s:%s)t (%" G_GSIZE_FORMAT
+        " bytes, %" G_GUINT64_FORMAT ") %p", GST_DEBUG_PAD_NAME (pad),
+        gst_buffer_get_size (data), GST_BUFFER_TIMESTAMP (data), data);
   }
   GST_OBJECT_UNLOCK (tee);
 
@@ -945,7 +843,7 @@ sink_activate_failed:
 }
 
 static gboolean
-gst_tee_src_check_get_range (GstPad * pad)
+gst_tee_src_query (GstPad * pad, GstQuery * query)
 {
   GstTee *tee;
   gboolean res;
@@ -953,50 +851,52 @@ gst_tee_src_check_get_range (GstPad * pad)
 
   tee = GST_TEE (gst_pad_get_parent (pad));
 
-  GST_OBJECT_LOCK (tee);
-
-  if (tee->pull_mode == GST_TEE_PULL_MODE_NEVER)
-    goto cannot_pull;
-
-  if (tee->pull_mode == GST_TEE_PULL_MODE_SINGLE && tee->pull_pad)
-    goto cannot_pull_multiple_srcs;
+  switch (GST_QUERY_TYPE (query)) {
+    case GST_QUERY_SCHEDULING:
+    {
+      gboolean pull_mode;
 
-  sinkpad = gst_object_ref (tee->sinkpad);
+      GST_OBJECT_LOCK (tee);
+      pull_mode = TRUE;
+      if (tee->pull_mode == GST_TEE_PULL_MODE_NEVER) {
+        GST_INFO_OBJECT (tee, "Cannot activate in pull mode, pull-mode "
+            "set to NEVER");
+        pull_mode = FALSE;
+      } else if (tee->pull_mode == GST_TEE_PULL_MODE_SINGLE && tee->pull_pad) {
+        GST_INFO_OBJECT (tee, "Cannot activate multiple src pads in pull mode, "
+            "pull-mode set to SINGLE");
+        pull_mode = FALSE;
+      }
 
-  GST_OBJECT_UNLOCK (tee);
+      sinkpad = gst_object_ref (tee->sinkpad);
+      GST_OBJECT_UNLOCK (tee);
 
-  res = gst_pad_check_pull_range (sinkpad);
-  gst_object_unref (sinkpad);
+      if (pull_mode) {
+        /* ask peer if we can operate in pull mode */
+        res = gst_pad_peer_query (sinkpad, query);
+      } else {
+        res = TRUE;
+      }
+      gst_object_unref (sinkpad);
+      break;
+    }
+    default:
+      res = gst_pad_query_default (pad, query);
+      break;
+  }
 
   gst_object_unref (tee);
 
   return res;
-
-  /* ERRORS */
-cannot_pull:
-  {
-    GST_OBJECT_UNLOCK (tee);
-    GST_INFO_OBJECT (tee, "Cannot activate in pull mode, pull-mode "
-        "set to NEVER");
-    gst_object_unref (tee);
-    return FALSE;
-  }
-cannot_pull_multiple_srcs:
-  {
-    GST_OBJECT_UNLOCK (tee);
-    GST_INFO_OBJECT (tee, "Cannot activate multiple src pads in pull mode, "
-        "pull-mode set to SINGLE");
-    gst_object_unref (tee);
-    return FALSE;
-  }
 }
 
 static void
-gst_tee_push_eos (GstPad * pad, GstTee * tee)
+gst_tee_push_eos (const GValue * vpad, GstTee * tee)
 {
+  GstPad *pad = g_value_get_object (vpad);
+
   if (pad != tee->pull_pad)
     gst_pad_push_event (pad, gst_event_new_eos ());
-  gst_object_unref (pad);
 }
 
 static void
@@ -1005,7 +905,8 @@ gst_tee_pull_eos (GstTee * tee)
   GstIterator *iter;
 
   iter = gst_element_iterate_src_pads (GST_ELEMENT (tee));
-  gst_iterator_foreach (iter, (GFunc) gst_tee_push_eos, tee);
+  gst_iterator_foreach (iter, (GstIteratorForeachFunction) gst_tee_push_eos,
+      tee);
   gst_iterator_free (iter);
 }
 
index baf36c4..dc7753c 100644 (file)
@@ -123,11 +123,11 @@ enum
 };
 
 
-#define _do_init(bla) \
+#define _do_init \
     GST_DEBUG_CATEGORY_INIT (gst_type_find_element_debug, "typefind",           \
         GST_DEBUG_BG_YELLOW | GST_DEBUG_FG_GREEN, "type finding element");
-
-GST_BOILERPLATE_FULL (GstTypeFindElement, gst_type_find_element, GstElement,
+#define gst_type_find_element_parent_class parent_class
+G_DEFINE_TYPE_WITH_CODE (GstTypeFindElement, gst_type_find_element,
     GST_TYPE_ELEMENT, _do_init);
 
 static void gst_type_find_element_dispose (GObject * object);
@@ -144,14 +144,14 @@ static gboolean gst_type_find_element_src_event (GstPad * pad,
     GstEvent * event);
 static gboolean gst_type_find_handle_src_query (GstPad * pad, GstQuery * query);
 
-static gboolean gst_type_find_element_handle_event (GstPad * pad,
+static gboolean gst_type_find_element_sink_event (GstPad * pad,
     GstEvent * event);
-static gboolean gst_type_find_element_setcaps (GstPad * pad, GstCaps * caps);
+static gboolean gst_type_find_element_setcaps (GstTypeFindElement * typefind,
+    GstCaps * caps);
 static GstFlowReturn gst_type_find_element_chain (GstPad * sinkpad,
     GstBuffer * buffer);
 static GstFlowReturn gst_type_find_element_getrange (GstPad * srcpad,
     guint64 offset, guint length, GstBuffer ** buffer);
-static gboolean gst_type_find_element_checkgetrange (GstPad * srcpad);
 
 static GstStateChangeReturn
 gst_type_find_element_change_state (GstElement * element,
@@ -160,9 +160,10 @@ static gboolean gst_type_find_element_activate (GstPad * pad);
 static gboolean
 gst_type_find_element_activate_src_pull (GstPad * pad, gboolean active);
 static GstFlowReturn
-gst_type_find_element_chain_do_typefinding (GstTypeFindElement * typefind);
-static void
-gst_type_find_element_send_cached_events (GstTypeFindElement * typefind);
+gst_type_find_element_chain_do_typefinding (GstTypeFindElement * typefind,
+    gboolean check_avail);
+static void gst_type_find_element_send_cached_events (GstTypeFindElement *
+    typefind);
 
 static guint gst_type_find_element_signals[LAST_SIGNAL] = { 0 };
 
@@ -184,27 +185,11 @@ gst_type_find_element_have_type (GstTypeFindElement * typefind,
   copy = gst_caps_ref (typefind->caps);
   GST_OBJECT_UNLOCK (typefind);
 
-  gst_pad_set_caps (typefind->src, copy);
+  gst_pad_push_event (typefind->src, gst_event_new_caps (copy));
   gst_caps_unref (copy);
 }
 
 static void
-gst_type_find_element_base_init (gpointer g_class)
-{
-  GstElementClass *gstelement_class = GST_ELEMENT_CLASS (g_class);
-
-  gst_element_class_set_details_simple (gstelement_class,
-      "TypeFind",
-      "Generic",
-      "Finds the media type of a stream",
-      "Benjamin Otte <in7y118@public.uni-hamburg.de>");
-  gst_element_class_add_pad_template (gstelement_class,
-      gst_static_pad_template_get (&type_find_element_src_template));
-  gst_element_class_add_pad_template (gstelement_class,
-      gst_static_pad_template_get (&type_find_element_sink_template));
-}
-
-static void
 gst_type_find_element_class_init (GstTypeFindElementClass * typefind_class)
 {
   GObjectClass *gobject_class = G_OBJECT_CLASS (typefind_class);
@@ -216,7 +201,7 @@ gst_type_find_element_class_init (GstTypeFindElementClass * typefind_class)
 
   g_object_class_install_property (gobject_class, PROP_CAPS,
       g_param_spec_boxed ("caps", _("caps"),
-          _("detected capabilities in stream"), gst_caps_get_type (),
+          _("detected capabilities in stream"), GST_TYPE_CAPS,
           G_PARAM_READABLE | G_PARAM_STATIC_STRINGS));
   g_object_class_install_property (gobject_class, PROP_MINIMUM,
       g_param_spec_uint ("minimum", _("minimum"),
@@ -230,7 +215,7 @@ gst_type_find_element_class_init (GstTypeFindElementClass * typefind_class)
           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
   g_object_class_install_property (gobject_class, PROP_FORCE_CAPS,
       g_param_spec_boxed ("force-caps", _("force caps"),
-          _("force caps without doing a typefind"), gst_caps_get_type (),
+          _("force caps without doing a typefind"), GST_TYPE_CAPS,
           G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
   /**
    * GstTypeFindElement::have-type:
@@ -250,13 +235,22 @@ gst_type_find_element_class_init (GstTypeFindElementClass * typefind_class)
   typefind_class->have_type =
       GST_DEBUG_FUNCPTR (gst_type_find_element_have_type);
 
+  gst_element_class_set_details_simple (gstelement_class,
+      "TypeFind",
+      "Generic",
+      "Finds the media type of a stream",
+      "Benjamin Otte <in7y118@public.uni-hamburg.de>");
+  gst_element_class_add_pad_template (gstelement_class,
+      gst_static_pad_template_get (&type_find_element_src_template));
+  gst_element_class_add_pad_template (gstelement_class,
+      gst_static_pad_template_get (&type_find_element_sink_template));
+
   gstelement_class->change_state =
       GST_DEBUG_FUNCPTR (gst_type_find_element_change_state);
 }
 
 static void
-gst_type_find_element_init (GstTypeFindElement * typefind,
-    GstTypeFindElementClass * g_class)
+gst_type_find_element_init (GstTypeFindElement * typefind)
 {
   /* sinkpad */
   typefind->sink =
@@ -265,12 +259,10 @@ gst_type_find_element_init (GstTypeFindElement * typefind,
 
   gst_pad_set_activate_function (typefind->sink,
       GST_DEBUG_FUNCPTR (gst_type_find_element_activate));
-  gst_pad_set_setcaps_function (typefind->sink,
-      GST_DEBUG_FUNCPTR (gst_type_find_element_setcaps));
   gst_pad_set_chain_function (typefind->sink,
       GST_DEBUG_FUNCPTR (gst_type_find_element_chain));
   gst_pad_set_event_function (typefind->sink,
-      GST_DEBUG_FUNCPTR (gst_type_find_element_handle_event));
+      GST_DEBUG_FUNCPTR (gst_type_find_element_sink_event));
   gst_element_add_pad (GST_ELEMENT (typefind), typefind->sink);
 
   /* srcpad */
@@ -279,8 +271,6 @@ gst_type_find_element_init (GstTypeFindElement * typefind,
 
   gst_pad_set_activatepull_function (typefind->src,
       GST_DEBUG_FUNCPTR (gst_type_find_element_activate_src_pull));
-  gst_pad_set_checkgetrange_function (typefind->src,
-      GST_DEBUG_FUNCPTR (gst_type_find_element_checkgetrange));
   gst_pad_set_getrange_function (typefind->src,
       GST_DEBUG_FUNCPTR (gst_type_find_element_getrange));
   gst_pad_set_event_function (typefind->src,
@@ -295,7 +285,7 @@ gst_type_find_element_init (GstTypeFindElement * typefind,
   typefind->min_probability = 1;
   typefind->max_probability = GST_TYPE_FIND_MAXIMUM;
 
-  typefind->store = NULL;
+  typefind->adapter = gst_adapter_new ();
 }
 
 static void
@@ -303,9 +293,9 @@ gst_type_find_element_dispose (GObject * object)
 {
   GstTypeFindElement *typefind = GST_TYPE_FIND_ELEMENT (object);
 
-  if (typefind->store) {
-    gst_buffer_unref (typefind->store);
-    typefind->store = NULL;
+  if (typefind->adapter) {
+    g_object_unref (typefind->adapter);
+    typefind->adapter = NULL;
   }
 
   if (typefind->force_caps) {
@@ -398,18 +388,13 @@ gst_type_find_handle_src_query (GstPad * pad, GstQuery * query)
       gint64 peer_pos;
       GstFormat format;
 
-      GST_OBJECT_LOCK (typefind);
-      if (typefind->store == NULL) {
-        GST_OBJECT_UNLOCK (typefind);
-        goto out;
-      }
-
       gst_query_parse_position (query, &format, &peer_pos);
 
+      GST_OBJECT_LOCK (typefind);
       /* FIXME: this code assumes that there's no discont in the queue */
       switch (format) {
         case GST_FORMAT_BYTES:
-          peer_pos -= GST_BUFFER_SIZE (typefind->store);
+          peer_pos -= gst_adapter_available (typefind->adapter);
           break;
         default:
           /* FIXME */
@@ -451,7 +436,7 @@ gst_type_find_element_src_event (GstPad * pad, GstEvent * event)
 
   if (typefind->mode != MODE_NORMAL) {
     /* need to do more? */
-    gst_mini_object_unref (GST_MINI_OBJECT (event));
+    gst_mini_object_unref (GST_MINI_OBJECT_CAST (event));
     return FALSE;
   }
   return gst_pad_push_event (typefind->sink, event);
@@ -461,7 +446,6 @@ static void
 start_typefinding (GstTypeFindElement * typefind)
 {
   GST_DEBUG_OBJECT (typefind, "starting typefinding");
-  gst_pad_set_caps (typefind->src, NULL);
 
   GST_OBJECT_LOCK (typefind);
   if (typefind->caps)
@@ -476,6 +460,8 @@ stop_typefinding (GstTypeFindElement * typefind)
 {
   GstState state;
   gboolean push_cached_buffers;
+  gsize avail;
+  GstBuffer *buffer;
 
   gst_element_get_state (GST_ELEMENT (typefind), &state, NULL, 0);
 
@@ -485,51 +471,54 @@ stop_typefinding (GstTypeFindElement * typefind)
       push_cached_buffers ? " and pushing cached buffers" : "");
 
   GST_OBJECT_LOCK (typefind);
-  if (typefind->store) {
-    GstBuffer *store;
+  avail = gst_adapter_available (typefind->adapter);
+  if (avail == 0)
+    goto no_data;
 
-    store = gst_buffer_make_metadata_writable (typefind->store);
-    typefind->store = NULL;
-    gst_buffer_set_caps (store, typefind->caps);
-    GST_OBJECT_UNLOCK (typefind);
+  buffer = gst_adapter_take_buffer (typefind->adapter, avail);
+  GST_OBJECT_UNLOCK (typefind);
 
-    if (!push_cached_buffers) {
-      gst_buffer_unref (store);
-    } else {
-      GstPad *peer = gst_pad_get_peer (typefind->src);
-
-      typefind->mode = MODE_NORMAL;
-
-      /* make sure the user gets a meaningful error message in this case,
-       * which is not a core bug or bug of any kind (as the default error
-       * message emitted by gstpad.c otherwise would make you think) */
-      if (peer && GST_PAD_CHAINFUNC (peer) == NULL) {
-        GST_DEBUG_OBJECT (typefind, "upstream only supports push mode, while "
-            "downstream element only works in pull mode, erroring out");
-        GST_ELEMENT_ERROR (typefind, STREAM, FAILED,
-            ("%s cannot work in push mode. The operation is not supported "
-                "with this source element or protocol.",
-                G_OBJECT_TYPE_NAME (GST_PAD_PARENT (peer))),
-            ("Downstream pad %s:%s has no chainfunction, and the upstream "
-                "element does not support pull mode",
-                GST_DEBUG_PAD_NAME (peer)));
-        typefind->mode = MODE_ERROR;    /* make the chain function error out */
-        gst_buffer_unref (store);
-      } else {
-        gst_type_find_element_send_cached_events (typefind);
-        gst_pad_push (typefind->src, store);
-      }
+  if (!push_cached_buffers) {
+    gst_buffer_unref (buffer);
+  } else {
+    GstPad *peer = gst_pad_get_peer (typefind->src);
 
-      if (peer)
-        gst_object_unref (peer);
+    typefind->mode = MODE_NORMAL;
+
+    /* make sure the user gets a meaningful error message in this case,
+     * which is not a core bug or bug of any kind (as the default error
+     * message emitted by gstpad.c otherwise would make you think) */
+    if (peer && GST_PAD_CHAINFUNC (peer) == NULL) {
+      GST_DEBUG_OBJECT (typefind, "upstream only supports push mode, while "
+          "downstream element only works in pull mode, erroring out");
+      GST_ELEMENT_ERROR (typefind, STREAM, FAILED,
+          ("%s cannot work in push mode. The operation is not supported "
+              "with this source element or protocol.",
+              G_OBJECT_TYPE_NAME (GST_PAD_PARENT (peer))),
+          ("Downstream pad %s:%s has no chainfunction, and the upstream "
+              "element does not support pull mode", GST_DEBUG_PAD_NAME (peer)));
+      typefind->mode = MODE_ERROR;      /* make the chain function error out */
+      gst_buffer_unref (buffer);
+    } else {
+      gst_type_find_element_send_cached_events (typefind);
+      gst_pad_push (typefind->src, buffer);
     }
-  } else {
+    if (peer)
+      gst_object_unref (peer);
+  }
+  return;
+
+  /* ERRORS */
+no_data:
+  {
+    GST_DEBUG_OBJECT (typefind, "we have no data to typefind");
     GST_OBJECT_UNLOCK (typefind);
+    return;
   }
 }
 
 static gboolean
-gst_type_find_element_handle_event (GstPad * pad, GstEvent * event)
+gst_type_find_element_sink_event (GstPad * pad, GstEvent * event)
 {
   gboolean res = FALSE;
   GstTypeFindElement *typefind = GST_TYPE_FIND_ELEMENT (GST_PAD_PARENT (pad));
@@ -540,37 +529,25 @@ gst_type_find_element_handle_event (GstPad * pad, GstEvent * event)
   switch (typefind->mode) {
     case MODE_TYPEFIND:
       switch (GST_EVENT_TYPE (event)) {
-        case GST_EVENT_EOS:{
-          GstTypeFindProbability prob = 0;
-          GstCaps *caps = NULL;
+        case GST_EVENT_CAPS:
+        {
+          GstCaps *caps;
+
+          /* first pass the caps event downstream */
+          res = gst_pad_push_event (typefind->src, gst_event_ref (event));
 
+          /* then parse and push out our data */
+          gst_event_parse_caps (event, &caps);
+          res = gst_type_find_element_setcaps (typefind, caps);
+
+          gst_event_unref (event);
+          break;
+        }
+        case GST_EVENT_EOS:
+        {
           GST_INFO_OBJECT (typefind, "Got EOS and no type found yet");
+          gst_type_find_element_chain_do_typefinding (typefind, FALSE);
 
-          /* we might not have started typefinding yet because there was not
-           * enough data so far; just give it a shot now and see what we get */
-          GST_OBJECT_LOCK (typefind);
-          if (typefind->store) {
-            caps = gst_type_find_helper_for_buffer (GST_OBJECT (typefind),
-                typefind->store, &prob);
-            GST_OBJECT_UNLOCK (typefind);
-
-            if (caps && prob >= typefind->min_probability) {
-              g_signal_emit (typefind, gst_type_find_element_signals[HAVE_TYPE],
-                  0, prob, caps);
-            } else {
-              GST_ELEMENT_ERROR (typefind, STREAM, TYPE_NOT_FOUND,
-                  (NULL), (NULL));
-            }
-            gst_caps_replace (&caps, NULL);
-          } else {
-            GST_OBJECT_UNLOCK (typefind);
-            /* keep message in sync with the one in the pad activate function */
-            GST_ELEMENT_ERROR (typefind, STREAM, TYPE_NOT_FOUND,
-                (_("Stream contains no data.")),
-                ("Can't typefind empty stream"));
-          }
-
-          stop_typefinding (typefind);
           res = gst_pad_push_event (typefind->src, event);
           break;
         }
@@ -580,7 +557,7 @@ gst_type_find_element_handle_event (GstPad * pad, GstEvent * event)
               (GFunc) gst_mini_object_unref, NULL);
           g_list_free (typefind->cached_events);
           typefind->cached_events = NULL;
-          gst_buffer_replace (&typefind->store, NULL);
+          gst_adapter_clear (typefind->adapter);
           GST_OBJECT_UNLOCK (typefind);
           /* fall through */
         case GST_EVENT_FLUSH_START:
@@ -629,12 +606,8 @@ gst_type_find_element_send_cached_events (GstTypeFindElement * typefind)
 }
 
 static gboolean
-gst_type_find_element_setcaps (GstPad * pad, GstCaps * caps)
+gst_type_find_element_setcaps (GstTypeFindElement * typefind, GstCaps * caps)
 {
-  GstTypeFindElement *typefind;
-
-  typefind = GST_TYPE_FIND_ELEMENT (GST_PAD_PARENT (pad));
-
   /* don't operate on ANY caps */
   if (gst_caps_is_any (caps))
     return TRUE;
@@ -644,28 +617,34 @@ gst_type_find_element_setcaps (GstPad * pad, GstCaps * caps)
 
   /* Shortcircuit typefinding if we get caps */
   if (typefind->mode == MODE_TYPEFIND) {
+    GstBuffer *buffer;
+    gsize avail;
+
     GST_DEBUG_OBJECT (typefind, "Skipping typefinding, using caps from "
         "upstream buffer: %" GST_PTR_FORMAT, caps);
     typefind->mode = MODE_NORMAL;
 
     gst_type_find_element_send_cached_events (typefind);
     GST_OBJECT_LOCK (typefind);
-    if (typefind->store) {
-      GstBuffer *store;
+    avail = gst_adapter_available (typefind->adapter);
+    if (avail == 0)
+      goto no_data;
 
-      store = gst_buffer_make_metadata_writable (typefind->store);
-      typefind->store = NULL;
-      gst_buffer_set_caps (store, typefind->caps);
-      GST_OBJECT_UNLOCK (typefind);
+    buffer = gst_adapter_take_buffer (typefind->adapter, avail);
+    GST_OBJECT_UNLOCK (typefind);
 
-      GST_DEBUG_OBJECT (typefind, "Pushing store: %d", GST_BUFFER_SIZE (store));
-      gst_pad_push (typefind->src, store);
-    } else {
-      GST_OBJECT_UNLOCK (typefind);
-    }
+    GST_DEBUG_OBJECT (typefind, "Pushing buffer: %d", avail);
+    gst_pad_push (typefind->src, buffer);
   }
 
   return TRUE;
+
+no_data:
+  {
+    GST_DEBUG_OBJECT (typefind, "no data to push");
+    GST_OBJECT_UNLOCK (typefind);
+    return TRUE;
+  }
 }
 
 static gchar *
@@ -766,18 +745,14 @@ gst_type_find_element_chain (GstPad * pad, GstBuffer * buffer)
       return GST_FLOW_ERROR;
     case MODE_NORMAL:
       /* don't take object lock as typefind->caps should not change anymore */
-      buffer = gst_buffer_make_metadata_writable (buffer);
-      gst_buffer_set_caps (buffer, typefind->caps);
       return gst_pad_push (typefind->src, buffer);
-    case MODE_TYPEFIND:{
+    case MODE_TYPEFIND:
+    {
       GST_OBJECT_LOCK (typefind);
-      if (typefind->store)
-        typefind->store = gst_buffer_join (typefind->store, buffer);
-      else
-        typefind->store = buffer;
+      gst_adapter_push (typefind->adapter, buffer);
       GST_OBJECT_UNLOCK (typefind);
 
-      res = gst_type_find_element_chain_do_typefinding (typefind);
+      res = gst_type_find_element_chain_do_typefinding (typefind, TRUE);
 
       if (typefind->mode == MODE_ERROR)
         res = GST_FLOW_ERROR;
@@ -793,72 +768,93 @@ gst_type_find_element_chain (GstPad * pad, GstBuffer * buffer)
 }
 
 static GstFlowReturn
-gst_type_find_element_chain_do_typefinding (GstTypeFindElement * typefind)
+gst_type_find_element_chain_do_typefinding (GstTypeFindElement * typefind,
+    gboolean check_avail)
 {
   GstTypeFindProbability probability;
   GstCaps *caps;
+  gsize avail;
+  const guint8 *data;
+  gboolean have_min, have_max;
 
   GST_OBJECT_LOCK (typefind);
-  if (GST_BUFFER_SIZE (typefind->store) < TYPE_FIND_MIN_SIZE) {
+  avail = gst_adapter_available (typefind->adapter);
+
+  if (check_avail) {
+    have_min = avail >= TYPE_FIND_MIN_SIZE;
+    have_max = avail >= TYPE_FIND_MAX_SIZE;
+  } else {
+    have_min = TRUE;
+    have_max = TRUE;
+  }
+
+  if (!have_min)
+    goto not_enough_data;
+
+  /* map all available data */
+  data = gst_adapter_map (typefind->adapter, avail);
+  caps = gst_type_find_helper_for_data (GST_OBJECT (typefind),
+      data, avail, &probability);
+  gst_adapter_unmap (typefind->adapter, 0);
+
+  if (caps == NULL && have_max)
+    goto no_type_found;
+  else if (caps == NULL)
+    goto wait_for_data;
+
+  /* found a type */
+  if (probability < typefind->min_probability)
+    goto low_probability;
+  GST_OBJECT_UNLOCK (typefind);
+
+  /* probability is good enough too, so let's make it known ... emiting this
+   * signal calls our object handler which sets the caps. */
+  g_signal_emit (typefind, gst_type_find_element_signals[HAVE_TYPE], 0,
+      probability, caps);
+
+  /* .. and send out the accumulated data */
+  stop_typefinding (typefind);
+  gst_caps_unref (caps);
+
+  return GST_FLOW_OK;
+
+not_enough_data:
+  {
     GST_DEBUG_OBJECT (typefind, "not enough data for typefinding yet "
-        "(%u bytes)", GST_BUFFER_SIZE (typefind->store));
+        "(%" G_GSIZE_FORMAT " bytes)", avail);
     GST_OBJECT_UNLOCK (typefind);
     return GST_FLOW_OK;
   }
-
-  caps = gst_type_find_helper_for_buffer (GST_OBJECT (typefind),
-      typefind->store, &probability);
-  if (caps == NULL && GST_BUFFER_SIZE (typefind->store) > TYPE_FIND_MAX_SIZE) {
+no_type_found:
+  {
     GST_OBJECT_UNLOCK (typefind);
     GST_ELEMENT_ERROR (typefind, STREAM, TYPE_NOT_FOUND, (NULL), (NULL));
     stop_typefinding (typefind);
     return GST_FLOW_ERROR;
-  } else if (caps == NULL) {
+  }
+wait_for_data:
+  {
+    GST_DEBUG_OBJECT (typefind,
+        "no caps found with %" G_GSIZE_FORMAT " bytes of data, "
+        "waiting for more data", avail);
     GST_OBJECT_UNLOCK (typefind);
-    GST_DEBUG_OBJECT (typefind, "no caps found with %u bytes of data, "
-        "waiting for more data", GST_BUFFER_SIZE (typefind->store));
     return GST_FLOW_OK;
   }
-
-  /* found a type */
-  if (probability < typefind->min_probability) {
+low_probability:
+  {
     GST_DEBUG_OBJECT (typefind, "found caps %" GST_PTR_FORMAT ", but "
         "probability is %u which is lower than the required minimum of %u",
         caps, probability, typefind->min_probability);
 
-    gst_caps_replace (&caps, NULL);
+    gst_caps_unref (caps);
 
-    if (GST_BUFFER_SIZE (typefind->store) >= TYPE_FIND_MAX_SIZE) {
-      GST_OBJECT_UNLOCK (typefind);
-      GST_ELEMENT_ERROR (typefind, STREAM, TYPE_NOT_FOUND, (NULL), (NULL));
-      stop_typefinding (typefind);
-      return GST_FLOW_ERROR;
-    }
+    if (have_max)
+      goto no_type_found;
 
     GST_OBJECT_UNLOCK (typefind);
     GST_DEBUG_OBJECT (typefind, "waiting for more data to try again");
     return GST_FLOW_OK;
   }
-  GST_OBJECT_UNLOCK (typefind);
-
-  /* probability is good enough too, so let's make it known ... */
-  g_signal_emit (typefind, gst_type_find_element_signals[HAVE_TYPE], 0,
-      probability, caps);
-
-  /* .. and send out the accumulated data */
-  stop_typefinding (typefind);
-  gst_caps_unref (caps);
-  return GST_FLOW_OK;
-}
-
-static gboolean
-gst_type_find_element_checkgetrange (GstPad * srcpad)
-{
-  GstTypeFindElement *typefind;
-
-  typefind = GST_TYPE_FIND_ELEMENT (GST_PAD_PARENT (srcpad));
-
-  return gst_pad_check_pull_range (typefind->sink);
 }
 
 static GstFlowReturn
@@ -872,12 +868,6 @@ gst_type_find_element_getrange (GstPad * srcpad,
 
   ret = gst_pad_pull_range (typefind->sink, offset, length, buffer);
 
-  if (ret == GST_FLOW_OK && buffer && *buffer) {
-    /* don't take object lock as typefind->caps should not change anymore */
-    /* we assume that pulled buffers are meta-data writable */
-    gst_buffer_set_caps (*buffer, typefind->caps);
-  }
-
   return ret;
 }
 
@@ -897,6 +887,8 @@ gst_type_find_element_activate (GstPad * pad)
   GstTypeFindProbability probability = 0;
   GstCaps *found_caps = NULL;
   GstTypeFindElement *typefind;
+  GstQuery *query;
+  gboolean pull_mode;
 
   typefind = GST_TYPE_FIND_ELEMENT (GST_OBJECT_PARENT (pad));
 
@@ -923,14 +915,25 @@ gst_type_find_element_activate (GstPad * pad)
    */
 
   /* 1 */
-  if (!gst_pad_check_pull_range (pad) || !gst_pad_activate_pull (pad, TRUE)) {
-    start_typefinding (typefind);
-    return gst_pad_activate_push (pad, TRUE);
+  query = gst_query_new_scheduling ();
+
+  if (!gst_pad_peer_query (pad, query)) {
+    gst_query_unref (query);
+    goto typefind_push;
   }
 
-  GST_DEBUG_OBJECT (typefind, "find type in pull mode");
+  gst_query_parse_scheduling (query, &pull_mode, NULL, NULL, NULL, NULL, NULL);
+  gst_query_unref (query);
+
+  if (!pull_mode)
+    goto typefind_push;
+
+  if (!gst_pad_activate_pull (pad, TRUE))
+    goto typefind_push;
 
   /* 2 */
+  GST_DEBUG_OBJECT (typefind, "find type in pull mode");
+
   {
     GstPad *peer;
 
@@ -1016,6 +1019,11 @@ really_done:
     ret &= gst_pad_activate_push (pad, TRUE);
     return ret;
   }
+typefind_push:
+  {
+    start_typefinding (typefind);
+    return gst_pad_activate_push (pad, TRUE);
+  }
 }
 
 static GstStateChangeReturn
index dbce72f..5c34758 100644 (file)
 
 #include <gst/gstinfo.h>
 #include <gst/gstelement.h>
+#include <gst/base/gstadapter.h>
 
 G_BEGIN_DECLS
 
-
-
 #define GST_TYPE_TYPE_FIND_ELEMENT             (gst_type_find_element_get_type ())
 #define GST_TYPE_FIND_ELEMENT(obj)             (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_TYPE_FIND_ELEMENT, GstTypeFindElement))
 #define GST_IS_TYPE_FIND_ELEMENT(obj)          (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_TYPE_FIND_ELEMENT))
@@ -56,7 +55,7 @@ struct _GstTypeFindElement {
   GstCaps *            caps;
 
   guint                        mode;
-  GstBuffer *          store;
+  GstAdapter *         adapter;
 
   GList *               cached_events;
   GstCaps *             force_caps;
index ae905f4..877d51e 100644 (file)
@@ -73,38 +73,22 @@ static void gst_valve_get_property (GObject * object,
     guint prop_id, GValue * value, GParamSpec * pspec);
 
 static gboolean gst_valve_event (GstPad * pad, GstEvent * event);
-static GstFlowReturn gst_valve_buffer_alloc (GstPad * pad, guint64 offset,
-    guint size, GstCaps * caps, GstBuffer ** buf);
 static GstFlowReturn gst_valve_chain (GstPad * pad, GstBuffer * buffer);
-static GstCaps *gst_valve_getcaps (GstPad * pad);
+static GstCaps *gst_valve_getcaps (GstPad * pad, GstCaps * filter);
 
-#define _do_init(bla) \
+#define _do_init \
   GST_DEBUG_CATEGORY_INIT (valve_debug, "valve", 0, "Valve");
-
-GST_BOILERPLATE_FULL (GstValve, gst_valve, GstElement,
-    GST_TYPE_ELEMENT, _do_init);
-
-static void
-gst_valve_base_init (gpointer klass)
-{
-  GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
-
-  gst_element_class_add_pad_template (element_class,
-      gst_static_pad_template_get (&srctemplate));
-  gst_element_class_add_pad_template (element_class,
-      gst_static_pad_template_get (&sinktemplate));
-
-  gst_element_class_set_details_simple (element_class, "Valve element",
-      "Filter", "Drops buffers and events or lets them through",
-      "Olivier Crete <olivier.crete@collabora.co.uk>");
-}
+#define gst_valve_parent_class parent_class
+G_DEFINE_TYPE_WITH_CODE (GstValve, gst_valve, GST_TYPE_ELEMENT, _do_init);
 
 static void
 gst_valve_class_init (GstValveClass * klass)
 {
   GObjectClass *gobject_class;
+  GstElementClass *gstelement_class;
 
   gobject_class = (GObjectClass *) klass;
+  gstelement_class = (GstElementClass *) (klass);
 
   gobject_class->set_property = gst_valve_set_property;
   gobject_class->get_property = gst_valve_get_property;
@@ -113,10 +97,19 @@ gst_valve_class_init (GstValveClass * klass)
       g_param_spec_boolean ("drop", "Drop buffers and events",
           "Whether to drop buffers and events or let them through",
           DEFAULT_DROP, G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
+
+  gst_element_class_add_pad_template (gstelement_class,
+      gst_static_pad_template_get (&srctemplate));
+  gst_element_class_add_pad_template (gstelement_class,
+      gst_static_pad_template_get (&sinktemplate));
+
+  gst_element_class_set_details_simple (gstelement_class, "Valve element",
+      "Filter", "Drops buffers and events or lets them through",
+      "Olivier Crete <olivier.crete@collabora.co.uk>");
 }
 
 static void
-gst_valve_init (GstValve * valve, GstValveClass * klass)
+gst_valve_init (GstValve * valve)
 {
   valve->drop = FALSE;
   valve->discont = FALSE;
@@ -131,8 +124,6 @@ gst_valve_init (GstValve * valve, GstValveClass * klass)
       GST_DEBUG_FUNCPTR (gst_valve_chain));
   gst_pad_set_event_function (valve->sinkpad,
       GST_DEBUG_FUNCPTR (gst_valve_event));
-  gst_pad_set_bufferalloc_function (valve->sinkpad,
-      GST_DEBUG_FUNCPTR (gst_valve_buffer_alloc));
   gst_pad_set_getcaps_function (valve->sinkpad,
       GST_DEBUG_FUNCPTR (gst_valve_getcaps));
   gst_element_add_pad (GST_ELEMENT (valve), valve->sinkpad);
@@ -182,7 +173,7 @@ gst_valve_chain (GstPad * pad, GstBuffer * buffer)
     valve->discont = TRUE;
   } else {
     if (valve->discont) {
-      buffer = gst_buffer_make_metadata_writable (buffer);
+      buffer = gst_buffer_make_writable (buffer);
       GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_DISCONT);
       valve->discont = FALSE;
     }
@@ -222,42 +213,19 @@ gst_valve_event (GstPad * pad, GstEvent * event)
   return ret;
 }
 
-static GstFlowReturn
-gst_valve_buffer_alloc (GstPad * pad, guint64 offset, guint size,
-    GstCaps * caps, GstBuffer ** buf)
-{
-  GstValve *valve = GST_VALVE (gst_pad_get_parent_element (pad));
-  GstFlowReturn ret = GST_FLOW_OK;
-
-  if (g_atomic_int_get (&valve->drop))
-    *buf = NULL;
-  else
-    ret = gst_pad_alloc_buffer (valve->srcpad, offset, size, caps, buf);
-
-  /* Ignore errors if "drop" was changed while the thread was blocked
-   * downwards
-   */
-  if (g_atomic_int_get (&valve->drop))
-    ret = GST_FLOW_OK;
-
-  gst_object_unref (valve);
-
-  return ret;
-}
-
 static GstCaps *
-gst_valve_getcaps (GstPad * pad)
+gst_valve_getcaps (GstPad * pad, GstCaps * filter)
 {
   GstValve *valve = GST_VALVE (gst_pad_get_parent (pad));
   GstCaps *caps;
 
   if (pad == valve->sinkpad)
-    caps = gst_pad_peer_get_caps (valve->srcpad);
+    caps = gst_pad_peer_get_caps (valve->srcpad, filter);
   else
-    caps = gst_pad_peer_get_caps (valve->sinkpad);
+    caps = gst_pad_peer_get_caps (valve->sinkpad, filter);
 
   if (caps == NULL)
-    caps = gst_caps_copy (gst_pad_get_pad_template_caps (pad));
+    caps = (filter ? gst_caps_ref (filter) : gst_caps_new_any ());
 
   gst_object_unref (valve);
 
index 1220671..a6615dd 100644 (file)
@@ -1,24 +1,12 @@
 plugin_LTLIBRARIES = libgstcoreindexers.la
 
-# file index uses xml
-if HAVE_MMAP
-if GST_DISABLE_LOADSAVE
-GST_LOADSAVE_SRC =
-GST_FILEINDEX_LIBS =
-else
-GST_LOADSAVE_SRC = gstfileindex.c
-GST_FILEINDEX_LIBS = $(XML_LIBS)
-endif
-else
-GST_LOADSAVE_SRC =
-GST_FILEINDEX_LIBS =
-endif
+# FIXME 0.11: gstfileindex.c used libxml and mmap, rewrite using something else or remove
 
 noinst_HEADERS =               \
        gstindexers.h
 
 libgstcoreindexers_la_DEPENDENCIES = $(top_builddir)/gst/libgstreamer-@GST_MAJORMINOR@.la
-libgstcoreindexers_la_SOURCES = gstindexers.c gstmemindex.c $(GST_LOADSAVE_SRC)
+libgstcoreindexers_la_SOURCES = gstindexers.c gstmemindex.c
 libgstcoreindexers_la_CFLAGS = $(GST_OBJ_CFLAGS)
 libgstcoreindexers_la_LIBADD = $(GST_OBJ_LIBS) $(GST_FILEINDEX_LIBS)
 libgstcoreindexers_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS)
index 9513f67..f317c32 100644 (file)
@@ -29,9 +29,9 @@ plugin_init (GstPlugin * plugin)
   gboolean res = TRUE;
 
   res &= gst_mem_index_plugin_init (plugin);
-#if defined(HAVE_MMAP) && !defined(GST_DISABLE_LOADSAVE)
-  res &= gst_file_index_plugin_init (plugin);
-#endif
+
+  /* FIXME 0.11: fix or remove GstFileIndex, which used mmap and libxml */
+  /* res &= gst_file_index_plugin_init (plugin); */
 
   return res;
 }
index 03e8e46..8180f8f 100644 (file)
@@ -25,9 +25,7 @@ G_BEGIN_DECLS
 
 gboolean gst_mem_index_plugin_init (GstPlugin * plugin);
 
-#ifndef GST_DISABLE_LOADSAVE
-gboolean gst_file_index_plugin_init (GstPlugin * plugin);
-#endif
+/* gboolean gst_file_index_plugin_init (GstPlugin * plugin); */
 
 
 G_END_DECLS
index dfd93b8..eb8d1cd 100644 (file)
--- a/po/af.po
+++ b/po/af.po
@@ -7,7 +7,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: gstreamer 0.9.7\n"
 "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
-"POT-Creation-Date: 2011-06-04 13:33+0100\n"
+"POT-Creation-Date: 2011-06-04 15:29+0100\n"
 "PO-Revision-Date: 2005-12-05 11:45+0200\n"
 "Last-Translator: Petri Jooste <rkwjpj@puk.ac.za>\n"
 "Language-Team: Afrikaans <i18n@af.org.za>\n"
@@ -1032,29 +1032,6 @@ msgstr "Kon nie lêer \"%s\" oopmaak om in te skryf nie."
 msgid "No such element or plugin '%s'\n"
 msgstr "geen bronelement vir URI \"%s\""
 
-msgid "Usage: gst-xmllaunch <file.xml> [ element.property=value ... ]\n"
-msgstr "Gebruik so: gst-xmllaunch <lêer.xml> [ element.eienskap=waarde ... ]\n"
-
-#, c-format
-msgid "ERROR: parse of xml file '%s' failed.\n"
-msgstr "FOUT: ontleding van xml-lêer '%s' het misluk.\n"
-
-#, c-format
-msgid "ERROR: no toplevel pipeline element in file '%s'.\n"
-msgstr "FOUT: geen topvlak pyplynelement in lêer '%s' nie.\n"
-
-#, fuzzy
-msgid "WARNING: only one toplevel element is supported at this time.\n"
-msgstr "WAARSKUWING: slegs een topvlak element word tans ondersteun."
-
-#, c-format
-msgid "ERROR: could not parse command line argument %d: %s.\n"
-msgstr "FOUT: onverstaanbare bevellynparameter %d: %s.\n"
-
-#, c-format
-msgid "WARNING: element named '%s' not found.\n"
-msgstr "WAARSKUWING: element genaamd '%s' nie gevind nie.\n"
-
 msgid "Index statistics"
 msgstr ""
 
@@ -1151,19 +1128,9 @@ msgstr "Moenie statusinligting van TIPE wys nie"
 msgid "TYPE1,TYPE2,..."
 msgstr "TIPE1, TIPE2,..."
 
-msgid "Save xml representation of pipeline to FILE and exit"
-msgstr "Stoor xml-voorstelling van pyplyn na LÊER en stop"
-
-msgid "FILE"
-msgstr "LÊER"
-
 msgid "Do not install a fault handler"
 msgstr "Moenie 'n fouthanteerder installeer nie"
 
-#, fuzzy
-msgid "Do not install signal handlers for SIGUSR1 and SIGUSR2"
-msgstr "Moenie 'n fouthanteerder installeer nie"
-
 msgid "Print alloc trace (if enabled at compile time)"
 msgstr "Druk \"alloc trace\" (indien aangeskakel tydens kompilering)"
 
@@ -1237,6 +1204,36 @@ msgstr "Pyplyn word gestel na NULL ...\n"
 msgid "Freeing pipeline ...\n"
 msgstr "Pyplyn word gestel na NULL ...\n"
 
+#~ msgid "Usage: gst-xmllaunch <file.xml> [ element.property=value ... ]\n"
+#~ msgstr ""
+#~ "Gebruik so: gst-xmllaunch <lêer.xml> [ element.eienskap=waarde ... ]\n"
+
+#~ msgid "ERROR: parse of xml file '%s' failed.\n"
+#~ msgstr "FOUT: ontleding van xml-lêer '%s' het misluk.\n"
+
+#~ msgid "ERROR: no toplevel pipeline element in file '%s'.\n"
+#~ msgstr "FOUT: geen topvlak pyplynelement in lêer '%s' nie.\n"
+
+#, fuzzy
+#~ msgid "WARNING: only one toplevel element is supported at this time.\n"
+#~ msgstr "WAARSKUWING: slegs een topvlak element word tans ondersteun."
+
+#~ msgid "ERROR: could not parse command line argument %d: %s.\n"
+#~ msgstr "FOUT: onverstaanbare bevellynparameter %d: %s.\n"
+
+#~ msgid "WARNING: element named '%s' not found.\n"
+#~ msgstr "WAARSKUWING: element genaamd '%s' nie gevind nie.\n"
+
+#~ msgid "Save xml representation of pipeline to FILE and exit"
+#~ msgstr "Stoor xml-voorstelling van pyplyn na LÊER en stop"
+
+#~ msgid "FILE"
+#~ msgstr "LÊER"
+
+#, fuzzy
+#~ msgid "Do not install signal handlers for SIGUSR1 and SIGUSR2"
+#~ msgstr "Moenie 'n fouthanteerder installeer nie"
+
 #~ msgid "Internal GStreamer error: state change failed."
 #~ msgstr "Interne GStreamer-fout: state change failed."
 
index c022a6b..b95e78f 100644 (file)
--- a/po/az.po
+++ b/po/az.po
@@ -7,7 +7,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: gstreamer-0.8.0\n"
 "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
-"POT-Creation-Date: 2011-06-04 13:33+0100\n"
+"POT-Creation-Date: 2011-06-04 15:29+0100\n"
 "PO-Revision-Date: 2004-03-19 18:40+0200\n"
 "Last-Translator: Metin Amiroff <metin@karegen.com>\n"
 "Language-Team: Azerbaijani <translation-team-az@lists.sourceforge.net>\n"
@@ -983,28 +983,6 @@ msgstr ""
 msgid "No such element or plugin '%s'\n"
 msgstr ""
 
-msgid "Usage: gst-xmllaunch <file.xml> [ element.property=value ... ]\n"
-msgstr ""
-
-#, c-format
-msgid "ERROR: parse of xml file '%s' failed.\n"
-msgstr ""
-
-#, c-format
-msgid "ERROR: no toplevel pipeline element in file '%s'.\n"
-msgstr ""
-
-msgid "WARNING: only one toplevel element is supported at this time.\n"
-msgstr ""
-
-#, c-format
-msgid "ERROR: could not parse command line argument %d: %s.\n"
-msgstr ""
-
-#, c-format
-msgid "WARNING: element named '%s' not found.\n"
-msgstr ""
-
 msgid "Index statistics"
 msgstr ""
 
@@ -1097,18 +1075,9 @@ msgstr ""
 msgid "TYPE1,TYPE2,..."
 msgstr ""
 
-msgid "Save xml representation of pipeline to FILE and exit"
-msgstr ""
-
-msgid "FILE"
-msgstr "FAYL"
-
 msgid "Do not install a fault handler"
 msgstr ""
 
-msgid "Do not install signal handlers for SIGUSR1 and SIGUSR2"
-msgstr ""
-
 msgid "Print alloc trace (if enabled at compile time)"
 msgstr ""
 
@@ -1180,6 +1149,9 @@ msgstr ""
 msgid "Freeing pipeline ...\n"
 msgstr ""
 
+#~ msgid "FILE"
+#~ msgstr "FAYL"
+
 #~ msgid "')"
 #~ msgstr "')"
 
index 6da856d..946792d 100644 (file)
--- a/po/be.po
+++ b/po/be.po
@@ -6,7 +6,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: gstreamer 0.9.7\n"
 "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
-"POT-Creation-Date: 2011-06-04 13:33+0100\n"
+"POT-Creation-Date: 2011-06-04 15:29+0100\n"
 "PO-Revision-Date: 2006-01-18 22:26+0200\n"
 "Last-Translator: Ales Nyakhaychyk <nab@mail.by>\n"
 "Language-Team: Belarusian <i18n@mova.org>\n"
@@ -992,28 +992,6 @@ msgstr ""
 msgid "No such element or plugin '%s'\n"
 msgstr ""
 
-msgid "Usage: gst-xmllaunch <file.xml> [ element.property=value ... ]\n"
-msgstr ""
-
-#, c-format
-msgid "ERROR: parse of xml file '%s' failed.\n"
-msgstr ""
-
-#, c-format
-msgid "ERROR: no toplevel pipeline element in file '%s'.\n"
-msgstr ""
-
-msgid "WARNING: only one toplevel element is supported at this time.\n"
-msgstr ""
-
-#, c-format
-msgid "ERROR: could not parse command line argument %d: %s.\n"
-msgstr ""
-
-#, c-format
-msgid "WARNING: element named '%s' not found.\n"
-msgstr ""
-
 msgid "Index statistics"
 msgstr ""
 
@@ -1106,18 +1084,9 @@ msgstr ""
 msgid "TYPE1,TYPE2,..."
 msgstr ""
 
-msgid "Save xml representation of pipeline to FILE and exit"
-msgstr ""
-
-msgid "FILE"
-msgstr ""
-
 msgid "Do not install a fault handler"
 msgstr ""
 
-msgid "Do not install signal handlers for SIGUSR1 and SIGUSR2"
-msgstr ""
-
 msgid "Print alloc trace (if enabled at compile time)"
 msgstr ""
 
index 29d96ef..c983bc6 100644 (file)
--- a/po/bg.po
+++ b/po/bg.po
@@ -8,7 +8,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: gstreamer 0.10.32.2\n"
 "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
-"POT-Creation-Date: 2011-06-04 13:33+0100\n"
+"POT-Creation-Date: 2011-06-04 15:29+0100\n"
 "PO-Revision-Date: 2011-04-26 22:40+0300\n"
 "Last-Translator: Alexander Shopov <ash@kambanaria.org>\n"
 "Language-Team: Bulgarian <dict@fsa-bg.org>\n"
@@ -1030,30 +1030,6 @@ msgstr "Файлът на приставката не може да бъде з
 msgid "No such element or plugin '%s'\n"
 msgstr "Няма такъв елемент или приставка „%s“\n"
 
-msgid "Usage: gst-xmllaunch <file.xml> [ element.property=value ... ]\n"
-msgstr "Употреба: gst-xmllaunch <файл.xml> [ елемент.свойство=стойност … ]\n"
-
-#, c-format
-msgid "ERROR: parse of xml file '%s' failed.\n"
-msgstr "ГРЕШКА: файлът с xml „%s“ не може да бъде анализиран.\n"
-
-#, c-format
-msgid "ERROR: no toplevel pipeline element in file '%s'.\n"
-msgstr "ГРЕШКА: няма най-горен елемент за конвейер във файла „%s“.\n"
-
-msgid "WARNING: only one toplevel element is supported at this time.\n"
-msgstr "ПРЕДУПРЕЖДЕНИЕ: засега е позволен само един най-горен елемент.\n"
-
-#, c-format
-msgid "ERROR: could not parse command line argument %d: %s.\n"
-msgstr ""
-"ГРЕШКА: аргументът подаден на командния ред не може да бъде анализиран %d: "
-"%s.\n"
-
-#, c-format
-msgid "WARNING: element named '%s' not found.\n"
-msgstr "ПРЕДУПРЕЖДЕНИЕ: елементът на име „%s“ не е открит.\n"
-
 msgid "Index statistics"
 msgstr "Статистика на индекса"
 
@@ -1148,18 +1124,9 @@ msgstr "Да не се дават изходни съобщения от сле
 msgid "TYPE1,TYPE2,..."
 msgstr "ВИД1,ВИД2,…"
 
-msgid "Save xml representation of pipeline to FILE and exit"
-msgstr "Запазване на конвейера във вид на XML във ФАЙЛа и изход"
-
-msgid "FILE"
-msgstr "ФАЙЛ"
-
 msgid "Do not install a fault handler"
 msgstr "Да не се инсталира модул за обработка на грешки"
 
-msgid "Do not install signal handlers for SIGUSR1 and SIGUSR2"
-msgstr "Да не се включват функции за обработка на сигналите SIGUSR1 и SIGUSR2"
-
 msgid "Print alloc trace (if enabled at compile time)"
 msgstr ""
 "Отпечатване на заделянето на памет (ако е било включено при компилиране на "
@@ -1233,3 +1200,34 @@ msgstr "Конвейерът се ЗАНУЛЯВА…\n"
 
 msgid "Freeing pipeline ...\n"
 msgstr "Конвейерът се освобождава…\n"
+
+#~ msgid "Usage: gst-xmllaunch <file.xml> [ element.property=value ... ]\n"
+#~ msgstr ""
+#~ "Употреба: gst-xmllaunch <файл.xml> [ елемент.свойство=стойност … ]\n"
+
+#~ msgid "ERROR: parse of xml file '%s' failed.\n"
+#~ msgstr "ГРЕШКА: файлът с xml „%s“ не може да бъде анализиран.\n"
+
+#~ msgid "ERROR: no toplevel pipeline element in file '%s'.\n"
+#~ msgstr "ГРЕШКА: няма най-горен елемент за конвейер във файла „%s“.\n"
+
+#~ msgid "WARNING: only one toplevel element is supported at this time.\n"
+#~ msgstr "ПРЕДУПРЕЖДЕНИЕ: засега е позволен само един най-горен елемент.\n"
+
+#~ msgid "ERROR: could not parse command line argument %d: %s.\n"
+#~ msgstr ""
+#~ "ГРЕШКА: аргументът подаден на командния ред не може да бъде анализиран "
+#~ "%d: %s.\n"
+
+#~ msgid "WARNING: element named '%s' not found.\n"
+#~ msgstr "ПРЕДУПРЕЖДЕНИЕ: елементът на име „%s“ не е открит.\n"
+
+#~ msgid "Save xml representation of pipeline to FILE and exit"
+#~ msgstr "Запазване на конвейера във вид на XML във ФАЙЛа и изход"
+
+#~ msgid "FILE"
+#~ msgstr "ФАЙЛ"
+
+#~ msgid "Do not install signal handlers for SIGUSR1 and SIGUSR2"
+#~ msgstr ""
+#~ "Да не се включват функции за обработка на сигналите SIGUSR1 и SIGUSR2"
index bebce39..82126a8 100644 (file)
--- a/po/ca.po
+++ b/po/ca.po
@@ -7,7 +7,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: gstreamer 0.10.30.3\n"
 "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
-"POT-Creation-Date: 2011-06-04 13:33+0100\n"
+"POT-Creation-Date: 2011-06-04 15:29+0100\n"
 "PO-Revision-Date: 2010-11-04 19:41+0100\n"
 "Last-Translator: Jordi Mallach <jordi@sindominio.net>\n"
 "Language-Team: Catalan <ca@dodds.net>\n"
@@ -1033,29 +1033,6 @@ msgstr "No s'ha pogut carregar el fitxer de connector: %s\n"
 msgid "No such element or plugin '%s'\n"
 msgstr "L'element o connector «%s» no existeix\n"
 
-msgid "Usage: gst-xmllaunch <file.xml> [ element.property=value ... ]\n"
-msgstr "Forma d'ús: gst-xmllaunch <file.xml> [ element.propietat=valor … ]\n"
-
-#, c-format
-msgid "ERROR: parse of xml file '%s' failed.\n"
-msgstr "ERROR: l'anàlisi del fitxer xml «%s» ha fallat.\n"
-
-#, c-format
-msgid "ERROR: no toplevel pipeline element in file '%s'.\n"
-msgstr "ERROR: no hi ha cap conducte de nivell superior en el fitxer «%s».\n"
-
-msgid "WARNING: only one toplevel element is supported at this time.\n"
-msgstr "AVÍS: només es gestiona un element de primer nivell ara mateix.\n"
-
-#, c-format
-msgid "ERROR: could not parse command line argument %d: %s.\n"
-msgstr ""
-"ERROR: no s'ha pogut analitzar l'argument de la línia d'ordres %d: %s.\n"
-
-#, c-format
-msgid "WARNING: element named '%s' not found.\n"
-msgstr "AVÍS: no s'ha trobat l'element anomenat «%s».\n"
-
 msgid "Index statistics"
 msgstr ""
 
@@ -1154,18 +1131,9 @@ msgstr "No mostres informació d'estat de TIPUS"
 msgid "TYPE1,TYPE2,..."
 msgstr "TIPUS1,TIPUS2,…"
 
-msgid "Save xml representation of pipeline to FILE and exit"
-msgstr "Desa la representació xml del conducte a FITXER i surt"
-
-msgid "FILE"
-msgstr "FITXER"
-
 msgid "Do not install a fault handler"
 msgstr "No instal·les un gestor de fallades"
 
-msgid "Do not install signal handlers for SIGUSR1 and SIGUSR2"
-msgstr "No instaŀles gestors de senyals per a SIGUSR1 i SIGUSR2"
-
 msgid "Print alloc trace (if enabled at compile time)"
 msgstr "Imprimeix una traça d'alloc (si s'ha habilitat al compilar)"
 
@@ -1239,6 +1207,36 @@ msgstr "S'està establint el conducte a NUL…\n"
 msgid "Freeing pipeline ...\n"
 msgstr "S'està alliberant el conducte…\n"
 
+#~ msgid "Usage: gst-xmllaunch <file.xml> [ element.property=value ... ]\n"
+#~ msgstr ""
+#~ "Forma d'ús: gst-xmllaunch <file.xml> [ element.propietat=valor … ]\n"
+
+#~ msgid "ERROR: parse of xml file '%s' failed.\n"
+#~ msgstr "ERROR: l'anàlisi del fitxer xml «%s» ha fallat.\n"
+
+#~ msgid "ERROR: no toplevel pipeline element in file '%s'.\n"
+#~ msgstr ""
+#~ "ERROR: no hi ha cap conducte de nivell superior en el fitxer «%s».\n"
+
+#~ msgid "WARNING: only one toplevel element is supported at this time.\n"
+#~ msgstr "AVÍS: només es gestiona un element de primer nivell ara mateix.\n"
+
+#~ msgid "ERROR: could not parse command line argument %d: %s.\n"
+#~ msgstr ""
+#~ "ERROR: no s'ha pogut analitzar l'argument de la línia d'ordres %d: %s.\n"
+
+#~ msgid "WARNING: element named '%s' not found.\n"
+#~ msgstr "AVÍS: no s'ha trobat l'element anomenat «%s».\n"
+
+#~ msgid "Save xml representation of pipeline to FILE and exit"
+#~ msgstr "Desa la representació xml del conducte a FITXER i surt"
+
+#~ msgid "FILE"
+#~ msgstr "FITXER"
+
+#~ msgid "Do not install signal handlers for SIGUSR1 and SIGUSR2"
+#~ msgstr "No instaŀles gestors de senyals per a SIGUSR1 i SIGUSR2"
+
 #~ msgid "Internal GStreamer error: state change failed."
 #~ msgstr ""
 #~ "S'ha produït un error intern de GStreamer: ha fallat el canvi d'estat."
index 19176b4..b3b6907 100644 (file)
--- a/po/cs.po
+++ b/po/cs.po
@@ -8,7 +8,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: gstreamer 0.10.20.3\n"
 "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
-"POT-Creation-Date: 2011-06-04 13:33+0100\n"
+"POT-Creation-Date: 2011-06-04 15:29+0100\n"
 "PO-Revision-Date: 2008-10-12 12:12+0200\n"
 "Last-Translator: Miloslav Trmac <mitr@volny.cz>\n"
 "Language-Team: Czech <translation-team-cs@lists.sourceforge.net>\n"
@@ -1040,31 +1040,6 @@ msgstr "Nemohu načíst soubor modulu: %s\n"
 msgid "No such element or plugin '%s'\n"
 msgstr "Element nebo modul '%s' neexistuje\n"
 
-msgid "Usage: gst-xmllaunch <file.xml> [ element.property=value ... ]\n"
-msgstr ""
-"Použití: gst-xmllaunch <soubor.xml> [ element.vlastnost=hodnota ... ]\n"
-
-#, c-format
-msgid "ERROR: parse of xml file '%s' failed.\n"
-msgstr "CHYBA: zpracovávání xml souboru '%s' selhalo.\n"
-
-#, c-format
-msgid "ERROR: no toplevel pipeline element in file '%s'.\n"
-msgstr "CHYBA: v souboru '%s' není element nejvyšší úrovně pipeline.\n"
-
-#, fuzzy
-msgid "WARNING: only one toplevel element is supported at this time.\n"
-msgstr ""
-"VAROVÁNÍ: v současné době je podporován jen jeden element nejvyšší úrovně."
-
-#, c-format
-msgid "ERROR: could not parse command line argument %d: %s.\n"
-msgstr "CHYBA: nemohu zpracovat argument %d na příkazovém řádku: %s.\n"
-
-#, c-format
-msgid "WARNING: element named '%s' not found.\n"
-msgstr "VAROVÁNÍ: element nazvaný '%s' nenalezen.\n"
-
 msgid "Index statistics"
 msgstr ""
 
@@ -1163,19 +1138,9 @@ msgstr "Nevypisovat informace o stavu s TYPEM"
 msgid "TYPE1,TYPE2,..."
 msgstr "TYP1,TYP2,..."
 
-msgid "Save xml representation of pipeline to FILE and exit"
-msgstr "Uložit reprezentaci roury v xml do SOUBORu a skončit"
-
-msgid "FILE"
-msgstr "SOUBOR"
-
 msgid "Do not install a fault handler"
 msgstr "Neinstalovat obsluhu výjimek"
 
-#, fuzzy
-msgid "Do not install signal handlers for SIGUSR1 and SIGUSR2"
-msgstr "Neinstalovat obsluhu výjimek"
-
 msgid "Print alloc trace (if enabled at compile time)"
 msgstr "Vypisovat stopu alokace (je-li povoleno při kompilaci)"
 
@@ -1252,6 +1217,37 @@ msgstr "Nastavuji rouru na NULL ...\n"
 msgid "Freeing pipeline ...\n"
 msgstr "Nastavuji rouru na NULL ...\n"
 
+#~ msgid "Usage: gst-xmllaunch <file.xml> [ element.property=value ... ]\n"
+#~ msgstr ""
+#~ "Použití: gst-xmllaunch <soubor.xml> [ element.vlastnost=hodnota ... ]\n"
+
+#~ msgid "ERROR: parse of xml file '%s' failed.\n"
+#~ msgstr "CHYBA: zpracovávání xml souboru '%s' selhalo.\n"
+
+#~ msgid "ERROR: no toplevel pipeline element in file '%s'.\n"
+#~ msgstr "CHYBA: v souboru '%s' není element nejvyšší úrovně pipeline.\n"
+
+#, fuzzy
+#~ msgid "WARNING: only one toplevel element is supported at this time.\n"
+#~ msgstr ""
+#~ "VAROVÁNÍ: v současné době je podporován jen jeden element nejvyšší úrovně."
+
+#~ msgid "ERROR: could not parse command line argument %d: %s.\n"
+#~ msgstr "CHYBA: nemohu zpracovat argument %d na příkazovém řádku: %s.\n"
+
+#~ msgid "WARNING: element named '%s' not found.\n"
+#~ msgstr "VAROVÁNÍ: element nazvaný '%s' nenalezen.\n"
+
+#~ msgid "Save xml representation of pipeline to FILE and exit"
+#~ msgstr "Uložit reprezentaci roury v xml do SOUBORu a skončit"
+
+#~ msgid "FILE"
+#~ msgstr "SOUBOR"
+
+#, fuzzy
+#~ msgid "Do not install signal handlers for SIGUSR1 and SIGUSR2"
+#~ msgstr "Neinstalovat obsluhu výjimek"
+
 #~ msgid "Error writing registry cache to %s: %s"
 #~ msgstr "Chyba při zapisování cache registru do %s: %s"
 
index f9bdaf8..f261fff 100644 (file)
--- a/po/da.po
+++ b/po/da.po
@@ -8,7 +8,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: gstreamer 0.10.30.3\n"
 "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
-"POT-Creation-Date: 2011-06-04 13:33+0100\n"
+"POT-Creation-Date: 2011-06-04 15:29+0100\n"
 "PO-Revision-Date: 2010-11-06 22:52+0100\n"
 "Last-Translator: Mogens Jaeger <mogensjaeger@gmail.com>\n"
 "Language-Team: Danish <dansk@dansk-gruppen.dk>\n"
@@ -1031,29 +1031,6 @@ msgstr "Kunne ikke indlæse pluginfilen: %s\n"
 msgid "No such element or plugin '%s'\n"
 msgstr "Et sådant element eller plugin findes ikke '%s'\n"
 
-msgid "Usage: gst-xmllaunch <file.xml> [ element.property=value ... ]\n"
-msgstr "Brug: gst-xmllaunch <file.xml> [ element.property=value ... ]\n"
-
-#, c-format
-msgid "ERROR: parse of xml file '%s' failed.\n"
-msgstr "FEJL: tolkning af XML fil '%s' mislykkedes.\n"
-
-#, c-format
-msgid "ERROR: no toplevel pipeline element in file '%s'.\n"
-msgstr "FEJL: intet topniveau rørledningselement i fil '%s'.\n"
-
-msgid "WARNING: only one toplevel element is supported at this time.\n"
-msgstr ""
-"ADVARSEL: der understøttes kun ét topniveauelement på nuværende tidspunkt.\n"
-
-#, c-format
-msgid "ERROR: could not parse command line argument %d: %s.\n"
-msgstr "FEJL: kunne ikke tolke kommandolinieargumenetet %d: %s.\n"
-
-#, c-format
-msgid "WARNING: element named '%s' not found.\n"
-msgstr "ADVARSEL: elementet ved navn '%s' blev ikke fundet.\n"
-
 msgid "Index statistics"
 msgstr ""
 
@@ -1149,18 +1126,9 @@ msgstr "Send ikke statusinformation af TYPE ud"
 msgid "TYPE1,TYPE2,..."
 msgstr "TYPE1,TYPE2,..."
 
-msgid "Save xml representation of pipeline to FILE and exit"
-msgstr "Gem XML-repræsentation af rørledning til FIL og afslut"
-
-msgid "FILE"
-msgstr "FIL"
-
 msgid "Do not install a fault handler"
 msgstr "Installér ikke en fejlhåndterer"
 
-msgid "Do not install signal handlers for SIGUSR1 and SIGUSR2"
-msgstr "Undlad installering af signalhåndtering for SIGUSR1 og SIGUSR2"
-
 msgid "Print alloc trace (if enabled at compile time)"
 msgstr "Udskriv allokeringsspor (hvis tilladt på oversættelsestidspunktet)"
 
@@ -1233,6 +1201,35 @@ msgstr "Rørledning sættes til NUL ...\n"
 msgid "Freeing pipeline ...\n"
 msgstr "Rørledning frigøres ...\n"
 
+#~ msgid "Usage: gst-xmllaunch <file.xml> [ element.property=value ... ]\n"
+#~ msgstr "Brug: gst-xmllaunch <file.xml> [ element.property=value ... ]\n"
+
+#~ msgid "ERROR: parse of xml file '%s' failed.\n"
+#~ msgstr "FEJL: tolkning af XML fil '%s' mislykkedes.\n"
+
+#~ msgid "ERROR: no toplevel pipeline element in file '%s'.\n"
+#~ msgstr "FEJL: intet topniveau rørledningselement i fil '%s'.\n"
+
+#~ msgid "WARNING: only one toplevel element is supported at this time.\n"
+#~ msgstr ""
+#~ "ADVARSEL: der understøttes kun ét topniveauelement på nuværende "
+#~ "tidspunkt.\n"
+
+#~ msgid "ERROR: could not parse command line argument %d: %s.\n"
+#~ msgstr "FEJL: kunne ikke tolke kommandolinieargumenetet %d: %s.\n"
+
+#~ msgid "WARNING: element named '%s' not found.\n"
+#~ msgstr "ADVARSEL: elementet ved navn '%s' blev ikke fundet.\n"
+
+#~ msgid "Save xml representation of pipeline to FILE and exit"
+#~ msgstr "Gem XML-repræsentation af rørledning til FIL og afslut"
+
+#~ msgid "FILE"
+#~ msgstr "FIL"
+
+#~ msgid "Do not install signal handlers for SIGUSR1 and SIGUSR2"
+#~ msgstr "Undlad installering af signalhåndtering for SIGUSR1 og SIGUSR2"
+
 #~ msgid "Error writing registry cache to %s: %s"
 #~ msgstr "Kunne ikke skrive registraturcache til %s: %s"
 
index 36f8ae4..10cbf46 100644 (file)
--- a/po/de.po
+++ b/po/de.po
@@ -9,7 +9,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: gstreamer 0.10.32.2\n"
 "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
-"POT-Creation-Date: 2011-06-04 13:33+0100\n"
+"POT-Creation-Date: 2011-06-04 15:29+0100\n"
 "PO-Revision-Date: 2011-04-27 23:44+0200\n"
 "Last-Translator: Christian Kirbach <christian.kirbach@googlemail.com>\n"
 "Language-Team: German <translation-team-de@lists.sourceforge.net>\n"
@@ -1051,29 +1051,6 @@ msgstr "Die Plugin-Datei konnte nicht geladen werden: %s\n"
 msgid "No such element or plugin '%s'\n"
 msgstr "Kein solches Element oder Plugin »%s«\n"
 
-msgid "Usage: gst-xmllaunch <file.xml> [ element.property=value ... ]\n"
-msgstr "Aufruf: gst-xmllaunch <file.xml> [ element.eigenschaft=wert ...]\n"
-
-#, c-format
-msgid "ERROR: parse of xml file '%s' failed.\n"
-msgstr "FEHLER: Auslesen der XML-Datei »%s« fehlgeschlagen.\n"
-
-#, c-format
-msgid "ERROR: no toplevel pipeline element in file '%s'.\n"
-msgstr "FEHLER: Kein Hauptleitungselement in Datei »%s«.\n"
-
-msgid "WARNING: only one toplevel element is supported at this time.\n"
-msgstr "WARNUNG: Zur Zeit wird nur ein Hauptelement unterstützt.\n"
-
-#, c-format
-msgid "ERROR: could not parse command line argument %d: %s.\n"
-msgstr ""
-"FEHLER: Das Befehlszeilenargument »%d« konnte nicht ausgelesen werden: %s.\n"
-
-#, c-format
-msgid "WARNING: element named '%s' not found.\n"
-msgstr "WARNUNG: Element namens »%s« nicht gefunden.\n"
-
 msgid "Index statistics"
 msgstr "Index-Statistiken"
 
@@ -1171,18 +1148,9 @@ msgstr "Zustandsinformation der Art ART nicht ausgeben"
 msgid "TYPE1,TYPE2,..."
 msgstr "ART1,ART2,..."
 
-msgid "Save xml representation of pipeline to FILE and exit"
-msgstr "XML-Repräsentation der Leitung in DATEI speichern und beenden"
-
-msgid "FILE"
-msgstr "DATEI"
-
 msgid "Do not install a fault handler"
 msgstr "Keine Routine zum Abfangen von Fehlern installieren"
 
-msgid "Do not install signal handlers for SIGUSR1 and SIGUSR2"
-msgstr "Keine Routinen für SIGUSR1 und SIGUSR2 installieren"
-
 msgid "Print alloc trace (if enabled at compile time)"
 msgstr ""
 "Speicherzuordnungsverfolgung ausgeben (falls zur Kompilierzeit aktiviert)"
@@ -1256,6 +1224,35 @@ msgstr "Leitung wird auf NULL gesetzt ...\n"
 msgid "Freeing pipeline ...\n"
 msgstr "Leitung wird geleert ...\n"
 
+#~ msgid "Usage: gst-xmllaunch <file.xml> [ element.property=value ... ]\n"
+#~ msgstr "Aufruf: gst-xmllaunch <file.xml> [ element.eigenschaft=wert ...]\n"
+
+#~ msgid "ERROR: parse of xml file '%s' failed.\n"
+#~ msgstr "FEHLER: Auslesen der XML-Datei »%s« fehlgeschlagen.\n"
+
+#~ msgid "ERROR: no toplevel pipeline element in file '%s'.\n"
+#~ msgstr "FEHLER: Kein Hauptleitungselement in Datei »%s«.\n"
+
+#~ msgid "WARNING: only one toplevel element is supported at this time.\n"
+#~ msgstr "WARNUNG: Zur Zeit wird nur ein Hauptelement unterstützt.\n"
+
+#~ msgid "ERROR: could not parse command line argument %d: %s.\n"
+#~ msgstr ""
+#~ "FEHLER: Das Befehlszeilenargument »%d« konnte nicht ausgelesen werden: "
+#~ "%s.\n"
+
+#~ msgid "WARNING: element named '%s' not found.\n"
+#~ msgstr "WARNUNG: Element namens »%s« nicht gefunden.\n"
+
+#~ msgid "Save xml representation of pipeline to FILE and exit"
+#~ msgstr "XML-Repräsentation der Leitung in DATEI speichern und beenden"
+
+#~ msgid "FILE"
+#~ msgstr "DATEI"
+
+#~ msgid "Do not install signal handlers for SIGUSR1 and SIGUSR2"
+#~ msgstr "Keine Routinen für SIGUSR1 und SIGUSR2 installieren"
+
 #~ msgid "Error writing registry cache to %s: %s"
 #~ msgstr ""
 #~ "Fehler beim Schreiben des Zwischenspeichers der Registry nach %s: %s"
index f2585be..fccf3ce 100644 (file)
--- a/po/el.po
+++ b/po/el.po
@@ -6,7 +6,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: gstreamer-0.10.30.3\n"
 "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
-"POT-Creation-Date: 2011-06-04 13:33+0100\n"
+"POT-Creation-Date: 2011-06-04 15:29+0100\n"
 "PO-Revision-Date: 2010-11-29 11:14+0200\n"
 "Last-Translator: Michael Kotsarinis <mk73628@gmail.com>\n"
 "Language-Team: Greek <team@lists.gnome.gr>\n"
@@ -1045,31 +1045,6 @@ msgstr "Αδυναμία φόρτωσης αρχείου προσθέτου: %s\
 msgid "No such element or plugin '%s'\n"
 msgstr "Δεν υπάρχει τέτοιο στοιχείο ή πρόσθετο '%s'\n"
 
-msgid "Usage: gst-xmllaunch <file.xml> [ element.property=value ... ]\n"
-msgstr "Χρήση: gst-xmllaunch <file.xml> [ element.property=value ... ]\n"
-
-#, c-format
-msgid "ERROR: parse of xml file '%s' failed.\n"
-msgstr "ERROR: αποτυχία ανάλυσης αρχείου xml '%s'.\n"
-
-#, c-format
-msgid "ERROR: no toplevel pipeline element in file '%s'.\n"
-msgstr ""
-"ERROR: δεν υπάρχει στοιχείο διασωλήνωσης στο ανώτερο επίπεδο στο αρχείο "
-"'%s'.\n"
-
-msgid "WARNING: only one toplevel element is supported at this time.\n"
-msgstr ""
-"WARNING: μόνο ένα στοιχείο σε ανώτερο επίπεδο υποστηρίζεται αυτή τη στιγμή.\n"
-
-#, c-format
-msgid "ERROR: could not parse command line argument %d: %s.\n"
-msgstr "ERROR: αδυναμία ανάλυσης ορίσματος γραμμής εντολής %d: %s.\n"
-
-#, c-format
-msgid "WARNING: element named '%s' not found.\n"
-msgstr "WARNING: το στοιχείο με το όνομα '%s' δεν βρέθηκε.\n"
-
 msgid "Index statistics"
 msgstr ""
 
@@ -1164,18 +1139,9 @@ msgstr "Να μην εξάγεται πληροφορία κατάστασης 
 msgid "TYPE1,TYPE2,..."
 msgstr "TYPE1,TYPE2,…"
 
-msgid "Save xml representation of pipeline to FILE and exit"
-msgstr "Αποθήκευση xml αναπαράστασης της διασωλήνωσης στο FILE και έξοδος"
-
-msgid "FILE"
-msgstr "FILE"
-
 msgid "Do not install a fault handler"
 msgstr "Να μην εγκατασταθεί χειριστής σφαλμάτων"
 
-msgid "Do not install signal handlers for SIGUSR1 and SIGUSR2"
-msgstr "Να μην εγκατασταθούν χειριστές σημάτων για SIGUSR1 και SIGUSR2"
-
 msgid "Print alloc trace (if enabled at compile time)"
 msgstr ""
 "Εμφάνιση ίχνους αντιστοίχισης (αν είναι ενεργοποιημένο κατά τη μεταγλώττιση "
@@ -1249,3 +1215,34 @@ msgstr "Ορισμός διασωλήνωσης σε NULL …\n"
 
 msgid "Freeing pipeline ...\n"
 msgstr "Αποδέσμευση της διασωλήνωσης …\n"
+
+#~ msgid "Usage: gst-xmllaunch <file.xml> [ element.property=value ... ]\n"
+#~ msgstr "Χρήση: gst-xmllaunch <file.xml> [ element.property=value ... ]\n"
+
+#~ msgid "ERROR: parse of xml file '%s' failed.\n"
+#~ msgstr "ERROR: αποτυχία ανάλυσης αρχείου xml '%s'.\n"
+
+#~ msgid "ERROR: no toplevel pipeline element in file '%s'.\n"
+#~ msgstr ""
+#~ "ERROR: δεν υπάρχει στοιχείο διασωλήνωσης στο ανώτερο επίπεδο στο αρχείο "
+#~ "'%s'.\n"
+
+#~ msgid "WARNING: only one toplevel element is supported at this time.\n"
+#~ msgstr ""
+#~ "WARNING: μόνο ένα στοιχείο σε ανώτερο επίπεδο υποστηρίζεται αυτή τη "
+#~ "στιγμή.\n"
+
+#~ msgid "ERROR: could not parse command line argument %d: %s.\n"
+#~ msgstr "ERROR: αδυναμία ανάλυσης ορίσματος γραμμής εντολής %d: %s.\n"
+
+#~ msgid "WARNING: element named '%s' not found.\n"
+#~ msgstr "WARNING: το στοιχείο με το όνομα '%s' δεν βρέθηκε.\n"
+
+#~ msgid "Save xml representation of pipeline to FILE and exit"
+#~ msgstr "Αποθήκευση xml αναπαράστασης της διασωλήνωσης στο FILE και έξοδος"
+
+#~ msgid "FILE"
+#~ msgstr "FILE"
+
+#~ msgid "Do not install signal handlers for SIGUSR1 and SIGUSR2"
+#~ msgstr "Να μην εγκατασταθούν χειριστές σημάτων για SIGUSR1 και SIGUSR2"
index fd70295..27a938f 100644 (file)
@@ -6,7 +6,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: gstreamer 0.8.1\n"
 "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
-"POT-Creation-Date: 2011-06-04 13:33+0100\n"
+"POT-Creation-Date: 2011-06-04 15:29+0100\n"
 "PO-Revision-Date: 2004-04-26 10:36-0400\n"
 "Last-Translator: Gareth Owen <gowen72@yahoo.com>\n"
 "Language-Team: English (British) <en_gb@li.org>\n"
@@ -1039,29 +1039,6 @@ msgstr "Could not open file \"%s\" for writing."
 msgid "No such element or plugin '%s'\n"
 msgstr "no source element for URI \"%s\""
 
-msgid "Usage: gst-xmllaunch <file.xml> [ element.property=value ... ]\n"
-msgstr "Usage: gst-xmllaunch <file.xml> [ element.property=value ... ]\n"
-
-#, c-format
-msgid "ERROR: parse of xml file '%s' failed.\n"
-msgstr "ERROR: parsing of xml file '%s' failed.\n"
-
-#, c-format
-msgid "ERROR: no toplevel pipeline element in file '%s'.\n"
-msgstr "ERROR: no toplevel pipeline element in file '%s'.\n"
-
-#, fuzzy
-msgid "WARNING: only one toplevel element is supported at this time.\n"
-msgstr "WARNING: only one toplevel element is supported at this time."
-
-#, c-format
-msgid "ERROR: could not parse command line argument %d: %s.\n"
-msgstr "ERROR: could not parse command line argument %d: %s.\n"
-
-#, c-format
-msgid "WARNING: element named '%s' not found.\n"
-msgstr "WARNING: element named '%s' not found.\n"
-
 msgid "Index statistics"
 msgstr ""
 
@@ -1155,19 +1132,9 @@ msgstr "Do not output status information of TYPE"
 msgid "TYPE1,TYPE2,..."
 msgstr "TYPE1,TYPE2,..."
 
-msgid "Save xml representation of pipeline to FILE and exit"
-msgstr "Save xml representation of pipeline to FILE and exit"
-
-msgid "FILE"
-msgstr "FILE"
-
 msgid "Do not install a fault handler"
 msgstr "Do not install a fault handler"
 
-#, fuzzy
-msgid "Do not install signal handlers for SIGUSR1 and SIGUSR2"
-msgstr "Do not install a fault handler"
-
 msgid "Print alloc trace (if enabled at compile time)"
 msgstr "Print alloc trace (if enabled at compile time)"
 
@@ -1242,6 +1209,35 @@ msgstr ""
 msgid "Freeing pipeline ...\n"
 msgstr "RUNNING pipeline ...\n"
 
+#~ msgid "Usage: gst-xmllaunch <file.xml> [ element.property=value ... ]\n"
+#~ msgstr "Usage: gst-xmllaunch <file.xml> [ element.property=value ... ]\n"
+
+#~ msgid "ERROR: parse of xml file '%s' failed.\n"
+#~ msgstr "ERROR: parsing of xml file '%s' failed.\n"
+
+#~ msgid "ERROR: no toplevel pipeline element in file '%s'.\n"
+#~ msgstr "ERROR: no toplevel pipeline element in file '%s'.\n"
+
+#, fuzzy
+#~ msgid "WARNING: only one toplevel element is supported at this time.\n"
+#~ msgstr "WARNING: only one toplevel element is supported at this time."
+
+#~ msgid "ERROR: could not parse command line argument %d: %s.\n"
+#~ msgstr "ERROR: could not parse command line argument %d: %s.\n"
+
+#~ msgid "WARNING: element named '%s' not found.\n"
+#~ msgstr "WARNING: element named '%s' not found.\n"
+
+#~ msgid "Save xml representation of pipeline to FILE and exit"
+#~ msgstr "Save xml representation of pipeline to FILE and exit"
+
+#~ msgid "FILE"
+#~ msgstr "FILE"
+
+#, fuzzy
+#~ msgid "Do not install signal handlers for SIGUSR1 and SIGUSR2"
+#~ msgstr "Do not install a fault handler"
+
 #~ msgid "Disable accelerated CPU instructions"
 #~ msgstr "Disable accelerated CPU instructions"
 
index 84e1771..3adb5c8 100644 (file)
--- a/po/es.po
+++ b/po/es.po
@@ -7,7 +7,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: gstreamer 0.10.30.3\n"
 "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
-"POT-Creation-Date: 2011-06-04 13:33+0100\n"
+"POT-Creation-Date: 2011-06-04 15:29+0100\n"
 "PO-Revision-Date: 2010-11-01 18:11+0100\n"
 "Last-Translator: Jorge González González <aloriel@gmail.com>\n"
 "Language-Team: Spanish <es@li.org>\n"
@@ -1038,32 +1038,6 @@ msgstr "No se pudo cargar el archivo de complemento: %s\n"
 msgid "No such element or plugin '%s'\n"
 msgstr "No existe el elemento o complemento «%s»\n"
 
-msgid "Usage: gst-xmllaunch <file.xml> [ element.property=value ... ]\n"
-msgstr "Uso: gst-xmllaunch <archivo.xml> [ propiedad.del.elemento=valor … ]\n"
-
-#, c-format
-msgid "ERROR: parse of xml file '%s' failed.\n"
-msgstr "ERROR: falló el análisis del archivo xml «%s».\n"
-
-#, c-format
-msgid "ERROR: no toplevel pipeline element in file '%s'.\n"
-msgstr ""
-"ERROR: no existe el elemento de nivel superior de la segmentación en el "
-"archivo «%s».\n"
-
-msgid "WARNING: only one toplevel element is supported at this time.\n"
-msgstr ""
-"ADVERTENCIA: en este momento sólo se soporta un elemento de nivel superior.\n"
-
-#, c-format
-msgid "ERROR: could not parse command line argument %d: %s.\n"
-msgstr ""
-"ERROR: no se pudo analizar el argumento %d de la línea de comandos: %s.\n"
-
-#, c-format
-msgid "WARNING: element named '%s' not found.\n"
-msgstr "ADVERTENCIA: no se encontró el elemento llamado «%s».\n"
-
 msgid "Index statistics"
 msgstr ""
 
@@ -1160,18 +1134,9 @@ msgstr "No sacar la salida de la información de estado del TIPO"
 msgid "TYPE1,TYPE2,..."
 msgstr "TIPO1,TIPO2,…"
 
-msgid "Save xml representation of pipeline to FILE and exit"
-msgstr "Guardar la representación xml del conducto a un ARCHIVO y salir"
-
-msgid "FILE"
-msgstr "ARCHIVO"
-
 msgid "Do not install a fault handler"
 msgstr "No instalar un manejador predeterminado"
 
-msgid "Do not install signal handlers for SIGUSR1 and SIGUSR2"
-msgstr "No instalar los manejadores de señales para SIGUSR1 y SIGUSR2"
-
 msgid "Print alloc trace (if enabled at compile time)"
 msgstr "Imprimir la traza de asignaciones (si se activó al compilar)"
 
@@ -1243,6 +1208,39 @@ msgstr "Estableciendo el conducto a NULL …\n"
 msgid "Freeing pipeline ...\n"
 msgstr "Liberando la tubería…\n"
 
+#~ msgid "Usage: gst-xmllaunch <file.xml> [ element.property=value ... ]\n"
+#~ msgstr ""
+#~ "Uso: gst-xmllaunch <archivo.xml> [ propiedad.del.elemento=valor … ]\n"
+
+#~ msgid "ERROR: parse of xml file '%s' failed.\n"
+#~ msgstr "ERROR: falló el análisis del archivo xml «%s».\n"
+
+#~ msgid "ERROR: no toplevel pipeline element in file '%s'.\n"
+#~ msgstr ""
+#~ "ERROR: no existe el elemento de nivel superior de la segmentación en el "
+#~ "archivo «%s».\n"
+
+#~ msgid "WARNING: only one toplevel element is supported at this time.\n"
+#~ msgstr ""
+#~ "ADVERTENCIA: en este momento sólo se soporta un elemento de nivel "
+#~ "superior.\n"
+
+#~ msgid "ERROR: could not parse command line argument %d: %s.\n"
+#~ msgstr ""
+#~ "ERROR: no se pudo analizar el argumento %d de la línea de comandos: %s.\n"
+
+#~ msgid "WARNING: element named '%s' not found.\n"
+#~ msgstr "ADVERTENCIA: no se encontró el elemento llamado «%s».\n"
+
+#~ msgid "Save xml representation of pipeline to FILE and exit"
+#~ msgstr "Guardar la representación xml del conducto a un ARCHIVO y salir"
+
+#~ msgid "FILE"
+#~ msgstr "ARCHIVO"
+
+#~ msgid "Do not install signal handlers for SIGUSR1 and SIGUSR2"
+#~ msgstr "No instalar los manejadores de señales para SIGUSR1 y SIGUSR2"
+
 #~ msgid "Error writing registry cache to %s: %s"
 #~ msgstr "Error al escribir la caché de registro a %s: %s"
 
index ddd431a..8697e81 100644 (file)
--- a/po/eu.po
+++ b/po/eu.po
@@ -8,7 +8,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: gstreamer-0.10.26.2\n"
 "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
-"POT-Creation-Date: 2011-06-04 13:33+0100\n"
+"POT-Creation-Date: 2011-06-04 15:29+0100\n"
 "PO-Revision-Date: 2010-03-25 13:10+0100\n"
 "Last-Translator: Mikel Olasagasti Uranga <hey_neken@mundurat.net>\n"
 "Language-Team: Basque <translation-team-eu@lists.sourceforge.net>\n"
@@ -1036,31 +1036,6 @@ msgstr "Ezin izan da plugin fitxategia kargatu: %s\n"
 msgid "No such element or plugin '%s'\n"
 msgstr "'%s' elementua edo plugina ez da existitzen\n"
 
-msgid "Usage: gst-xmllaunch <file.xml> [ element.property=value ... ]\n"
-msgstr ""
-"Erabilera: gst-xmllaunch <fitxategia.xml> [ elementua."
-"propietatea=balioa... ]\n"
-
-#, c-format
-msgid "ERROR: parse of xml file '%s' failed.\n"
-msgstr "ERROREA: huts egin du '%s' xml fitxategia analizatzean.\n"
-
-#, c-format
-msgid "ERROR: no toplevel pipeline element in file '%s'.\n"
-msgstr ""
-"ERROREA: ez dago goi-mailako kanalizazio-elementurik '%s' fitxategian.\n"
-
-msgid "WARNING: only one toplevel element is supported at this time.\n"
-msgstr "KONTUZ: goi-mailako elementu bat bakarra onartzen da oraingoan.\n"
-
-#, c-format
-msgid "ERROR: could not parse command line argument %d: %s.\n"
-msgstr "ERROREA: ezin izan da komando-lerroko %d. argumentua analizatu: %s.\n"
-
-#, c-format
-msgid "WARNING: element named '%s' not found.\n"
-msgstr "KONTUZ: ez da aurkitu '%s' izeneko elementua.\n"
-
 msgid "Index statistics"
 msgstr ""
 
@@ -1156,19 +1131,9 @@ msgstr "Ez erakutsi MOTA hauetako egoera-informazioa:"
 msgid "TYPE1,TYPE2,..."
 msgstr "1.MOTA, 2.MOTA..."
 
-msgid "Save xml representation of pipeline to FILE and exit"
-msgstr "Gorde kanalizazioen xml adierazpena FITXATEGIan eta irten"
-
-msgid "FILE"
-msgstr "FITXATEGIA"
-
 msgid "Do not install a fault handler"
 msgstr "Ez instalatu akats-maneiatzailerik"
 
-#, fuzzy
-msgid "Do not install signal handlers for SIGUSR1 and SIGUSR2"
-msgstr "Ez instalatu akats-maneiatzailerik"
-
 msgid "Print alloc trace (if enabled at compile time)"
 msgstr "Inprimatu esleipenen segimendua (konpilatzean gaitu bada)"
 
@@ -1239,3 +1204,35 @@ msgstr "Kanalizazioa NULUA gisa ezartzen... \n"
 
 msgid "Freeing pipeline ...\n"
 msgstr "Kanalizazioa askatzen...\n"
+
+#~ msgid "Usage: gst-xmllaunch <file.xml> [ element.property=value ... ]\n"
+#~ msgstr ""
+#~ "Erabilera: gst-xmllaunch <fitxategia.xml> [ elementua."
+#~ "propietatea=balioa... ]\n"
+
+#~ msgid "ERROR: parse of xml file '%s' failed.\n"
+#~ msgstr "ERROREA: huts egin du '%s' xml fitxategia analizatzean.\n"
+
+#~ msgid "ERROR: no toplevel pipeline element in file '%s'.\n"
+#~ msgstr ""
+#~ "ERROREA: ez dago goi-mailako kanalizazio-elementurik '%s' fitxategian.\n"
+
+#~ msgid "WARNING: only one toplevel element is supported at this time.\n"
+#~ msgstr "KONTUZ: goi-mailako elementu bat bakarra onartzen da oraingoan.\n"
+
+#~ msgid "ERROR: could not parse command line argument %d: %s.\n"
+#~ msgstr ""
+#~ "ERROREA: ezin izan da komando-lerroko %d. argumentua analizatu: %s.\n"
+
+#~ msgid "WARNING: element named '%s' not found.\n"
+#~ msgstr "KONTUZ: ez da aurkitu '%s' izeneko elementua.\n"
+
+#~ msgid "Save xml representation of pipeline to FILE and exit"
+#~ msgstr "Gorde kanalizazioen xml adierazpena FITXATEGIan eta irten"
+
+#~ msgid "FILE"
+#~ msgstr "FITXATEGIA"
+
+#, fuzzy
+#~ msgid "Do not install signal handlers for SIGUSR1 and SIGUSR2"
+#~ msgstr "Ez instalatu akats-maneiatzailerik"
index 0f77f4d..9f53305 100644 (file)
--- a/po/fi.po
+++ b/po/fi.po
@@ -12,7 +12,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: gstreamer 0.10.30.3\n"
 "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
-"POT-Creation-Date: 2011-06-04 13:33+0100\n"
+"POT-Creation-Date: 2011-06-04 15:29+0100\n"
 "PO-Revision-Date: 2010-11-17 23:10+0200\n"
 "Last-Translator: Tommi Vainikainen <Tommi.Vainikainen@iki.fi>\n"
 "Language-Team: Finnish <translation-team-fi@lists.sourceforge.net>\n"
@@ -1030,29 +1030,6 @@ msgstr "Ei voitu ladata liitännäistiedostoa: %s\n"
 msgid "No such element or plugin '%s'\n"
 msgstr "Ei tällaista elementtiä tai liitännäistä ”%s”\n"
 
-msgid "Usage: gst-xmllaunch <file.xml> [ element.property=value ... ]\n"
-msgstr ""
-"Käyttö: gst-xmllaunch <tiedosto.xml> [ elementti.ominaisuus=arvo ... ]\n"
-
-#, c-format
-msgid "ERROR: parse of xml file '%s' failed.\n"
-msgstr "VIRHE: XML-tiedoston ”%s” jäsentäminen epäonnistui.\n"
-
-#, c-format
-msgid "ERROR: no toplevel pipeline element in file '%s'.\n"
-msgstr "VIRHE: päätason liukuhihnaelementtiä ei ole tiedostossa ”%s”.\n"
-
-msgid "WARNING: only one toplevel element is supported at this time.\n"
-msgstr "VAROITUS: vain yhtä päätason elementtiä tuetaan tällä kertaa.\n"
-
-#, c-format
-msgid "ERROR: could not parse command line argument %d: %s.\n"
-msgstr "VIRHE: ei voitu jäsentää komentoriviargumenttia %d: %s.\n"
-
-#, c-format
-msgid "WARNING: element named '%s' not found.\n"
-msgstr "VAROITUS: elementtiä nimeltä ”%s” ei löytynyt.\n"
-
 msgid "Index statistics"
 msgstr ""
 
@@ -1147,18 +1124,9 @@ msgstr "Älä tulosta tilatietoa TYYPPI"
 msgid "TYPE1,TYPE2,..."
 msgstr "TYYPPI1,TYYPPI2,..."
 
-msgid "Save xml representation of pipeline to FILE and exit"
-msgstr "Tallenna liukuhihnan XML-esitys TIEDOSTOon ja poistu"
-
-msgid "FILE"
-msgstr "TIEDOSTO"
-
 msgid "Do not install a fault handler"
 msgstr "Älä asenna virheenkäsittelintä"
 
-msgid "Do not install signal handlers for SIGUSR1 and SIGUSR2"
-msgstr "Älä asenna SIGUSR1- ja SIGUSR2-signaalinkäsittelijöitä"
-
 msgid "Print alloc trace (if enabled at compile time)"
 msgstr "Tulosta varausjälki (jos valittu käännöksen yhteydessä)"
 
@@ -1232,6 +1200,34 @@ msgstr "Asetetaan liukuhihna tilaan TYHJÄ...\n"
 msgid "Freeing pipeline ...\n"
 msgstr "Vapautetaan liukuhihna...\n"
 
+#~ msgid "Usage: gst-xmllaunch <file.xml> [ element.property=value ... ]\n"
+#~ msgstr ""
+#~ "Käyttö: gst-xmllaunch <tiedosto.xml> [ elementti.ominaisuus=arvo ... ]\n"
+
+#~ msgid "ERROR: parse of xml file '%s' failed.\n"
+#~ msgstr "VIRHE: XML-tiedoston ”%s” jäsentäminen epäonnistui.\n"
+
+#~ msgid "ERROR: no toplevel pipeline element in file '%s'.\n"
+#~ msgstr "VIRHE: päätason liukuhihnaelementtiä ei ole tiedostossa ”%s”.\n"
+
+#~ msgid "WARNING: only one toplevel element is supported at this time.\n"
+#~ msgstr "VAROITUS: vain yhtä päätason elementtiä tuetaan tällä kertaa.\n"
+
+#~ msgid "ERROR: could not parse command line argument %d: %s.\n"
+#~ msgstr "VIRHE: ei voitu jäsentää komentoriviargumenttia %d: %s.\n"
+
+#~ msgid "WARNING: element named '%s' not found.\n"
+#~ msgstr "VAROITUS: elementtiä nimeltä ”%s” ei löytynyt.\n"
+
+#~ msgid "Save xml representation of pipeline to FILE and exit"
+#~ msgstr "Tallenna liukuhihnan XML-esitys TIEDOSTOon ja poistu"
+
+#~ msgid "FILE"
+#~ msgstr "TIEDOSTO"
+
+#~ msgid "Do not install signal handlers for SIGUSR1 and SIGUSR2"
+#~ msgstr "Älä asenna SIGUSR1- ja SIGUSR2-signaalinkäsittelijöitä"
+
 #~ msgid "Error writing registry cache to %s: %s"
 #~ msgstr "Virhe kirjoitettaessa rekisterivälimuistia kohteeseen %s: %s"
 
index b4adae0..9bd4c6a 100644 (file)
--- a/po/fr.po
+++ b/po/fr.po
@@ -9,7 +9,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: gstreamer 0.10.32.2\n"
 "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
-"POT-Creation-Date: 2011-06-04 13:33+0100\n"
+"POT-Creation-Date: 2011-06-04 15:29+0100\n"
 "PO-Revision-Date: 2011-04-28 09:34+0200\n"
 "Last-Translator: Claude Paroz <claude@2xlibre.net>\n"
 "Language-Team: French <traduc@traduc.org>\n"
@@ -1034,33 +1034,6 @@ msgstr "Impossible de charger le fichier de greffon : %s\n"
 msgid "No such element or plugin '%s'\n"
 msgstr "Aucun élément ou greffon « %s »\n"
 
-msgid "Usage: gst-xmllaunch <file.xml> [ element.property=value ... ]\n"
-msgstr ""
-"Utilisation : gst-xmllaunch <fichier.xml> [ élément.propriété=valeur ... ]\n"
-
-#, c-format
-msgid "ERROR: parse of xml file '%s' failed.\n"
-msgstr "ERREUR : l'analyse du fichier xml « %s » a échoué.\n"
-
-#, c-format
-msgid "ERROR: no toplevel pipeline element in file '%s'.\n"
-msgstr ""
-"ERREUR : pas d'élément pipeline de premier niveau dans le fichier « %s ».\n"
-
-msgid "WARNING: only one toplevel element is supported at this time.\n"
-msgstr ""
-"AVERTISSEMENT : actuellement, un seul élément de premier niveau est géré.\n"
-
-#, c-format
-msgid "ERROR: could not parse command line argument %d: %s.\n"
-msgstr ""
-"ERREUR : impossible d'analyser le paramètre numéro %d de la ligne de "
-"commande : %s.\n"
-
-#, c-format
-msgid "WARNING: element named '%s' not found.\n"
-msgstr "AVERTISSEMENT : l'élément nommé « %s » est introuvable.\n"
-
 msgid "Index statistics"
 msgstr "Statistiques d'index"
 
@@ -1155,18 +1128,9 @@ msgstr "N'affiche pas d'informations d'état de TYPE"
 msgid "TYPE1,TYPE2,..."
 msgstr "TYPE1,TYPE2,..."
 
-msgid "Save xml representation of pipeline to FILE and exit"
-msgstr "Enregistre une représentation xml du pipeline dans FICHIER et quitte"
-
-msgid "FILE"
-msgstr "FICHIER"
-
 msgid "Do not install a fault handler"
 msgstr "N'installe pas de gestionnaire de dysfonctionnement"
 
-msgid "Do not install signal handlers for SIGUSR1 and SIGUSR2"
-msgstr "N'installe pas de gestionnaire de signal pour SIGUSR1 et SIGUSR2"
-
 msgid "Print alloc trace (if enabled at compile time)"
 msgstr "Affiche les traces d'allocations (si activées lors de la compilation)"
 
@@ -1237,3 +1201,39 @@ msgstr "Définition du pipeline à NULL...\n"
 
 msgid "Freeing pipeline ...\n"
 msgstr "Libération du pipeline...\n"
+
+#~ msgid "Usage: gst-xmllaunch <file.xml> [ element.property=value ... ]\n"
+#~ msgstr ""
+#~ "Utilisation : gst-xmllaunch <fichier.xml> [ élément."
+#~ "propriété=valeur ... ]\n"
+
+#~ msgid "ERROR: parse of xml file '%s' failed.\n"
+#~ msgstr "ERREUR : l'analyse du fichier xml « %s » a échoué.\n"
+
+#~ msgid "ERROR: no toplevel pipeline element in file '%s'.\n"
+#~ msgstr ""
+#~ "ERREUR : pas d'élément pipeline de premier niveau dans le fichier "
+#~ "« %s ».\n"
+
+#~ msgid "WARNING: only one toplevel element is supported at this time.\n"
+#~ msgstr ""
+#~ "AVERTISSEMENT : actuellement, un seul élément de premier niveau est "
+#~ "géré.\n"
+
+#~ msgid "ERROR: could not parse command line argument %d: %s.\n"
+#~ msgstr ""
+#~ "ERREUR : impossible d'analyser le paramètre numéro %d de la ligne de "
+#~ "commande : %s.\n"
+
+#~ msgid "WARNING: element named '%s' not found.\n"
+#~ msgstr "AVERTISSEMENT : l'élément nommé « %s » est introuvable.\n"
+
+#~ msgid "Save xml representation of pipeline to FILE and exit"
+#~ msgstr ""
+#~ "Enregistre une représentation xml du pipeline dans FICHIER et quitte"
+
+#~ msgid "FILE"
+#~ msgstr "FICHIER"
+
+#~ msgid "Do not install signal handlers for SIGUSR1 and SIGUSR2"
+#~ msgstr "N'installe pas de gestionnaire de signal pour SIGUSR1 et SIGUSR2"
index f456f8f..43a8e2d 100644 (file)
--- a/po/gl.po
+++ b/po/gl.po
@@ -6,7 +6,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: gstreamer 0.10.31.2\n"
 "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
-"POT-Creation-Date: 2011-06-04 13:33+0100\n"
+"POT-Creation-Date: 2011-06-04 15:29+0100\n"
 "PO-Revision-Date: 2011-04-13 05:19+0000\n"
 "Last-Translator: Francisco Diéguez <frandieguez@ubuntu.com>\n"
 "Language-Team: Galician <proxecto@trasno.net>\n"
@@ -1028,30 +1028,6 @@ msgstr "Non foi posíbel cargar o ficheiro do engadido: %s\n"
 msgid "No such element or plugin '%s'\n"
 msgstr "Non existe o elemento ou engadido «%s»\n"
 
-msgid "Usage: gst-xmllaunch <file.xml> [ element.property=value ... ]\n"
-msgstr "Uso: gst-xmllaunch <ficheiro.xml> [ propiedade.do.elemento=valor … ]\n"
-
-#, c-format
-msgid "ERROR: parse of xml file '%s' failed.\n"
-msgstr "ERRO: non foi posíbel analizar o ficheiro xml «%s».\n"
-
-#, c-format
-msgid "ERROR: no toplevel pipeline element in file '%s'.\n"
-msgstr ""
-"ERRO: non existe o elemento de nivel superior da canalización no ficheiro "
-"«%s».\n"
-
-msgid "WARNING: only one toplevel element is supported at this time.\n"
-msgstr "AVISO: neste momento só se admite un elemento de nivel superior.\n"
-
-#, c-format
-msgid "ERROR: could not parse command line argument %d: %s.\n"
-msgstr "ERRO: non foi posíbel analizar o argumento %d da liña de ordes: %s.\n"
-
-#, c-format
-msgid "WARNING: element named '%s' not found.\n"
-msgstr "AVISO: non se atopou o elemento nomeado «%s».\n"
-
 msgid "Index statistics"
 msgstr ""
 
@@ -1148,18 +1124,9 @@ msgstr "Non sacar a saída da información de estado do TIPO"
 msgid "TYPE1,TYPE2,..."
 msgstr "TIPO1,TIPO2,…"
 
-msgid "Save xml representation of pipeline to FILE and exit"
-msgstr "Gardar a representación xml da canalización a un FICHEIRO e saír"
-
-msgid "FILE"
-msgstr "FICHEIRO"
-
 msgid "Do not install a fault handler"
 msgstr "Non instalar un manexador predeterminado"
 
-msgid "Do not install signal handlers for SIGUSR1 and SIGUSR2"
-msgstr "Non instalar os manexadores de sinais para SIGUSR1 e SIGUSR2"
-
 msgid "Print alloc trace (if enabled at compile time)"
 msgstr "Imprimir a traza de asignacións (se foi activada ao compilar)"
 
@@ -1230,3 +1197,34 @@ msgstr "Estabelecendo a tubería a NULL...\n"
 
 msgid "Freeing pipeline ...\n"
 msgstr "Liberando a tubería...\n"
+
+#~ msgid "Usage: gst-xmllaunch <file.xml> [ element.property=value ... ]\n"
+#~ msgstr ""
+#~ "Uso: gst-xmllaunch <ficheiro.xml> [ propiedade.do.elemento=valor … ]\n"
+
+#~ msgid "ERROR: parse of xml file '%s' failed.\n"
+#~ msgstr "ERRO: non foi posíbel analizar o ficheiro xml «%s».\n"
+
+#~ msgid "ERROR: no toplevel pipeline element in file '%s'.\n"
+#~ msgstr ""
+#~ "ERRO: non existe o elemento de nivel superior da canalización no ficheiro "
+#~ "«%s».\n"
+
+#~ msgid "WARNING: only one toplevel element is supported at this time.\n"
+#~ msgstr "AVISO: neste momento só se admite un elemento de nivel superior.\n"
+
+#~ msgid "ERROR: could not parse command line argument %d: %s.\n"
+#~ msgstr ""
+#~ "ERRO: non foi posíbel analizar o argumento %d da liña de ordes: %s.\n"
+
+#~ msgid "WARNING: element named '%s' not found.\n"
+#~ msgstr "AVISO: non se atopou o elemento nomeado «%s».\n"
+
+#~ msgid "Save xml representation of pipeline to FILE and exit"
+#~ msgstr "Gardar a representación xml da canalización a un FICHEIRO e saír"
+
+#~ msgid "FILE"
+#~ msgstr "FICHEIRO"
+
+#~ msgid "Do not install signal handlers for SIGUSR1 and SIGUSR2"
+#~ msgstr "Non instalar os manexadores de sinais para SIGUSR1 e SIGUSR2"
index ebe8521..56e1621 100644 (file)
--- a/po/hu.po
+++ b/po/hu.po
@@ -7,7 +7,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: gstreamer 0.10.30.3\n"
 "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
-"POT-Creation-Date: 2011-06-04 13:33+0100\n"
+"POT-Creation-Date: 2011-06-04 15:29+0100\n"
 "PO-Revision-Date: 2010-11-01 13:39+0100\n"
 "Last-Translator: Gabor Kelemen <kelemeng@gnome.hu>\n"
 "Language-Team: Hungarian <translation-team-hu@lists.sourceforge.net>\n"
@@ -1022,29 +1022,6 @@ msgstr "Nem tölthető be a bővítményfájl: %s\n"
 msgid "No such element or plugin '%s'\n"
 msgstr "Nincs ilyen elem vagy bővítmény: „%s”\n"
 
-msgid "Usage: gst-xmllaunch <file.xml> [ element.property=value ... ]\n"
-msgstr "Használat: gst-xmllaunch <fájl.xml> [ elem.tulajdonság=érték … ]\n"
-
-#, c-format
-msgid "ERROR: parse of xml file '%s' failed.\n"
-msgstr "HIBA: a(z) „%s” xml fájl feldolgozása meghiúsult.\n"
-
-#, c-format
-msgid "ERROR: no toplevel pipeline element in file '%s'.\n"
-msgstr ""
-"HIBA: nincs felső szintű adatcsatorna elem a következő fájlban: „%s”.\n"
-
-msgid "WARNING: only one toplevel element is supported at this time.\n"
-msgstr "FIGYELMEZTETÉS: egyszerre csak egy felső szintű elem támogatott.\n"
-
-#, c-format
-msgid "ERROR: could not parse command line argument %d: %s.\n"
-msgstr "HIBA: nem elemezhető a(z) %d. parancssori argumentum: %s.\n"
-
-#, c-format
-msgid "WARNING: element named '%s' not found.\n"
-msgstr "FIGYELMEZTETÉS: a(z) „%s” nevű elem nem található.\n"
-
 msgid "Index statistics"
 msgstr ""
 
@@ -1139,18 +1116,9 @@ msgstr "Ne írjon ki a TÍPUS típus állapotinformációit"
 msgid "TYPE1,TYPE2,..."
 msgstr "TÍPUS1,TÍPUS2,…"
 
-msgid "Save xml representation of pipeline to FILE and exit"
-msgstr "Az adatcsatorna xml ábrázolásának mentése a FÁJLBA és kilépés"
-
-msgid "FILE"
-msgstr "FÁJL"
-
 msgid "Do not install a fault handler"
 msgstr "Ne telepítsen hibakezelőt"
 
-msgid "Do not install signal handlers for SIGUSR1 and SIGUSR2"
-msgstr "Ne telepítsen szignálkezelőket a SIGUSR1 és SIGUSR2 szignálokhoz"
-
 msgid "Print alloc trace (if enabled at compile time)"
 msgstr "Foglalási nyomkövetés kiírása (ha fordításkor engedélyezték)"
 
@@ -1221,3 +1189,31 @@ msgstr "Az adatcsatorna beállítása NULL értékre…\n"
 
 msgid "Freeing pipeline ...\n"
 msgstr "Adatcsatorna felszabadítása…\n"
+
+#~ msgid "Usage: gst-xmllaunch <file.xml> [ element.property=value ... ]\n"
+#~ msgstr "Használat: gst-xmllaunch <fájl.xml> [ elem.tulajdonság=érték … ]\n"
+
+#~ msgid "ERROR: parse of xml file '%s' failed.\n"
+#~ msgstr "HIBA: a(z) „%s” xml fájl feldolgozása meghiúsult.\n"
+
+#~ msgid "ERROR: no toplevel pipeline element in file '%s'.\n"
+#~ msgstr ""
+#~ "HIBA: nincs felső szintű adatcsatorna elem a következő fájlban: „%s”.\n"
+
+#~ msgid "WARNING: only one toplevel element is supported at this time.\n"
+#~ msgstr "FIGYELMEZTETÉS: egyszerre csak egy felső szintű elem támogatott.\n"
+
+#~ msgid "ERROR: could not parse command line argument %d: %s.\n"
+#~ msgstr "HIBA: nem elemezhető a(z) %d. parancssori argumentum: %s.\n"
+
+#~ msgid "WARNING: element named '%s' not found.\n"
+#~ msgstr "FIGYELMEZTETÉS: a(z) „%s” nevű elem nem található.\n"
+
+#~ msgid "Save xml representation of pipeline to FILE and exit"
+#~ msgstr "Az adatcsatorna xml ábrázolásának mentése a FÁJLBA és kilépés"
+
+#~ msgid "FILE"
+#~ msgstr "FÁJL"
+
+#~ msgid "Do not install signal handlers for SIGUSR1 and SIGUSR2"
+#~ msgstr "Ne telepítsen szignálkezelőket a SIGUSR1 és SIGUSR2 szignálokhoz"
index 9b88775..8e29177 100644 (file)
--- a/po/id.po
+++ b/po/id.po
@@ -6,7 +6,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: gstreamer 0.10.29.2\n"
 "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
-"POT-Creation-Date: 2011-06-04 13:33+0100\n"
+"POT-Creation-Date: 2011-06-04 15:29+0100\n"
 "PO-Revision-Date: 2010-06-29 21:55+0700\n"
 "Last-Translator: Andhika Padmawan <andhika.padmawan@gmail.com>\n"
 "Language-Team: Indonesian <translation-team-id@lists.sourceforge.net>\n"
@@ -1029,29 +1029,6 @@ msgstr "Tak dapat membuat berkas plugin: %s\n"
 msgid "No such element or plugin '%s'\n"
 msgstr "Tak ada elemen atau plugin '%s'\n"
 
-msgid "Usage: gst-xmllaunch <file.xml> [ element.property=value ... ]\n"
-msgstr "Penggunaan: gst-xmllaunch <berkas.xml> [ elemen.properti=nilai ... ]\n"
-
-#, c-format
-msgid "ERROR: parse of xml file '%s' failed.\n"
-msgstr "GALAT: penguraian berkas xml '%s' gagal.\n"
-
-#, c-format
-msgid "ERROR: no toplevel pipeline element in file '%s'.\n"
-msgstr "GALAT: tak ada elemen baris pipa level atas di berkas '%s'.\n"
-
-msgid "WARNING: only one toplevel element is supported at this time.\n"
-msgstr ""
-"PERINGATAN: hanya satu elemen level atas yang didukung pada saat ini.\n"
-
-#, c-format
-msgid "ERROR: could not parse command line argument %d: %s.\n"
-msgstr "GALAT: tak dapat menguraikan argumen baris perintah %d: %s.\n"
-
-#, c-format
-msgid "WARNING: element named '%s' not found.\n"
-msgstr "GALAT: elemen yang dinamakan '%s' tak ditemukan.\n"
-
 msgid "Index statistics"
 msgstr ""
 
@@ -1146,18 +1123,9 @@ msgstr "Jangan keluarkan informasi status dari TIPE"
 msgid "TYPE1,TYPE2,..."
 msgstr "TIPE1, TIPE2,..."
 
-msgid "Save xml representation of pipeline to FILE and exit"
-msgstr "Simpan perwakilan xml baris pipa ke BERKAS lalu keluar"
-
-msgid "FILE"
-msgstr "BERKAS"
-
 msgid "Do not install a fault handler"
 msgstr "Jangan instal penanganan galat"
 
-msgid "Do not install signal handlers for SIGUSR1 and SIGUSR2"
-msgstr "Jangan instal penanganan sinyal untuk SIGUSR1 dan SIGUSR2"
-
 msgid "Print alloc trace (if enabled at compile time)"
 msgstr "Cetak jejak alokasi (jika diaktifkan sewaktu kompilasi)"
 
@@ -1229,6 +1197,35 @@ msgstr "Mengatur baris pipa ke KOSONG ...\n"
 msgid "Freeing pipeline ...\n"
 msgstr "Membebaskan baris pipa ...\n"
 
+#~ msgid "Usage: gst-xmllaunch <file.xml> [ element.property=value ... ]\n"
+#~ msgstr ""
+#~ "Penggunaan: gst-xmllaunch <berkas.xml> [ elemen.properti=nilai ... ]\n"
+
+#~ msgid "ERROR: parse of xml file '%s' failed.\n"
+#~ msgstr "GALAT: penguraian berkas xml '%s' gagal.\n"
+
+#~ msgid "ERROR: no toplevel pipeline element in file '%s'.\n"
+#~ msgstr "GALAT: tak ada elemen baris pipa level atas di berkas '%s'.\n"
+
+#~ msgid "WARNING: only one toplevel element is supported at this time.\n"
+#~ msgstr ""
+#~ "PERINGATAN: hanya satu elemen level atas yang didukung pada saat ini.\n"
+
+#~ msgid "ERROR: could not parse command line argument %d: %s.\n"
+#~ msgstr "GALAT: tak dapat menguraikan argumen baris perintah %d: %s.\n"
+
+#~ msgid "WARNING: element named '%s' not found.\n"
+#~ msgstr "GALAT: elemen yang dinamakan '%s' tak ditemukan.\n"
+
+#~ msgid "Save xml representation of pipeline to FILE and exit"
+#~ msgstr "Simpan perwakilan xml baris pipa ke BERKAS lalu keluar"
+
+#~ msgid "FILE"
+#~ msgstr "BERKAS"
+
+#~ msgid "Do not install signal handlers for SIGUSR1 and SIGUSR2"
+#~ msgstr "Jangan instal penanganan sinyal untuk SIGUSR1 dan SIGUSR2"
+
 #~ msgid "Error writing registry cache to %s: %s"
 #~ msgstr "Galat menulis tembolok registry ke %s: %s"
 
index f26d740..1fa7abd 100644 (file)
--- a/po/it.po
+++ b/po/it.po
@@ -106,7 +106,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: gstreamer 0.10.30.3\n"
 "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
-"POT-Creation-Date: 2011-06-04 13:33+0100\n"
+"POT-Creation-Date: 2011-06-04 15:29+0100\n"
 "PO-Revision-Date: 2010-10-25 10:03+0200\n"
 "Last-Translator: Luca Ferretti <elle.uca@infinito.it>\n"
 "Language-Team: Italian <tp@lists.linux.it>\n"
@@ -1198,29 +1198,6 @@ msgstr "Impossibile caricare il file di plugin: %s\n"
 msgid "No such element or plugin '%s'\n"
 msgstr "Elemento o plugin «%s» inesistente\n"
 
-msgid "Usage: gst-xmllaunch <file.xml> [ element.property=value ... ]\n"
-msgstr "Uso: gst-xmllaunch <FILE.XML> [ ELEMENTO.PROPRIETA=VALORE ... ]\n"
-
-#, c-format
-msgid "ERROR: parse of xml file '%s' failed.\n"
-msgstr "ERRORE: analisi del file xml «%s» non riuscita.\n"
-
-#, c-format
-msgid "ERROR: no toplevel pipeline element in file '%s'.\n"
-msgstr "ERRORE: nessun elemento pipeline toplevel nel file «%s».\n"
-
-msgid "WARNING: only one toplevel element is supported at this time.\n"
-msgstr "ATTENZIONE: al momento è supportato sono un elemento toplevel.\n"
-
-#, c-format
-msgid "ERROR: could not parse command line argument %d: %s.\n"
-msgstr ""
-"ERRORE: impossibile analizzare l'argomento %d della riga di comando: %s.\n"
-
-#, c-format
-msgid "WARNING: element named '%s' not found.\n"
-msgstr "ATTENZIONE: elemento con nome «%s» non trovato.\n"
-
 msgid "Index statistics"
 msgstr ""
 
@@ -1321,20 +1298,10 @@ msgstr "Non stampa le informazioni di stato per TIPO"
 msgid "TYPE1,TYPE2,..."
 msgstr "TIPO1,TIPO2,..."
 
-# -o, --output=FILE
-msgid "Save xml representation of pipeline to FILE and exit"
-msgstr "Salva su FILE una rappresentazione xml della pipeline ed esce"
-
-msgid "FILE"
-msgstr "FILE"
-
 # -f, --no-fault
 msgid "Do not install a fault handler"
 msgstr "Non installa un gestore di fault"
 
-msgid "Do not install signal handlers for SIGUSR1 and SIGUSR2"
-msgstr "Non installa i gestori di segnale per SIGUSR1 e SIGUSR2"
-
 # -T, --trace
 msgid "Print alloc trace (if enabled at compile time)"
 msgstr "Stampa traccia di alloc (se abilitato in compilazione)"
@@ -1414,6 +1381,35 @@ msgstr "Impostazione della pipeline a NULL ...\n"
 msgid "Freeing pipeline ...\n"
 msgstr "Esecuzione di free sulla pipeline...\n"
 
+#~ msgid "Usage: gst-xmllaunch <file.xml> [ element.property=value ... ]\n"
+#~ msgstr "Uso: gst-xmllaunch <FILE.XML> [ ELEMENTO.PROPRIETA=VALORE ... ]\n"
+
+#~ msgid "ERROR: parse of xml file '%s' failed.\n"
+#~ msgstr "ERRORE: analisi del file xml «%s» non riuscita.\n"
+
+#~ msgid "ERROR: no toplevel pipeline element in file '%s'.\n"
+#~ msgstr "ERRORE: nessun elemento pipeline toplevel nel file «%s».\n"
+
+#~ msgid "WARNING: only one toplevel element is supported at this time.\n"
+#~ msgstr "ATTENZIONE: al momento è supportato sono un elemento toplevel.\n"
+
+#~ msgid "ERROR: could not parse command line argument %d: %s.\n"
+#~ msgstr ""
+#~ "ERRORE: impossibile analizzare l'argomento %d della riga di comando: %s.\n"
+
+#~ msgid "WARNING: element named '%s' not found.\n"
+#~ msgstr "ATTENZIONE: elemento con nome «%s» non trovato.\n"
+
+# -o, --output=FILE
+#~ msgid "Save xml representation of pipeline to FILE and exit"
+#~ msgstr "Salva su FILE una rappresentazione xml della pipeline ed esce"
+
+#~ msgid "FILE"
+#~ msgstr "FILE"
+
+#~ msgid "Do not install signal handlers for SIGUSR1 and SIGUSR2"
+#~ msgstr "Non installa i gestori di segnale per SIGUSR1 e SIGUSR2"
+
 #~ msgid "Error writing registry cache to %s: %s"
 #~ msgstr "Errore nello scrivere la cache di registro su %s: %s"
 
index 6cab73a..80200b8 100644 (file)
--- a/po/ja.po
+++ b/po/ja.po
@@ -6,7 +6,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: gstreamer 0.10.20.3\n"
 "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
-"POT-Creation-Date: 2011-06-04 13:33+0100\n"
+"POT-Creation-Date: 2011-06-04 15:29+0100\n"
 "PO-Revision-Date: 2008-10-16 19:57+0900\n"
 "Last-Translator: Makoto Kato <makoto.kt@gmail.com>\n"
 "Language-Team: Japanese <translation-team-ja@lists.sourceforge.net>\n"
@@ -1003,30 +1003,6 @@ msgstr "プラグインファイルをロードできませんでした: %s\n"
 msgid "No such element or plugin '%s'\n"
 msgstr ""
 
-msgid "Usage: gst-xmllaunch <file.xml> [ element.property=value ... ]\n"
-msgstr "使い方: gst-xmllaunch <file.xml> [ element.property=value ...]\n"
-
-#, c-format
-msgid "ERROR: parse of xml file '%s' failed.\n"
-msgstr "エラー: xml ファイル '%s' の解析に失敗しました\n"
-
-#, c-format
-msgid "ERROR: no toplevel pipeline element in file '%s'.\n"
-msgstr ""
-"エラー: ファイル '%s' にトップレベルのパイプラインエレメントがありません\n"
-
-#, fuzzy
-msgid "WARNING: only one toplevel element is supported at this time.\n"
-msgstr "警告: トップレベルのエレメントは一つのみサポートしています"
-
-#, c-format
-msgid "ERROR: could not parse command line argument %d: %s.\n"
-msgstr "エラー: コマンドライン引数 %d を解析できません: %s\n"
-
-#, c-format
-msgid "WARNING: element named '%s' not found.\n"
-msgstr "警告: エレメント名 '%s' が見つかりません\n"
-
 msgid "Index statistics"
 msgstr ""
 
@@ -1125,19 +1101,9 @@ msgstr "TYPE のステータス情報を出力しない"
 msgid "TYPE1,TYPE2,..."
 msgstr "TYPE1,TYPE2,..."
 
-msgid "Save xml representation of pipeline to FILE and exit"
-msgstr ""
-
-msgid "FILE"
-msgstr "FILE"
-
 msgid "Do not install a fault handler"
 msgstr "フォールトハンドラをインストールしない"
 
-#, fuzzy
-msgid "Do not install signal handlers for SIGUSR1 and SIGUSR2"
-msgstr "フォールトハンドラをインストールしない"
-
 msgid "Print alloc trace (if enabled at compile time)"
 msgstr "alloc トレースを表示する (コンパイル時に有効にする必要があります)"
 
@@ -1211,6 +1177,33 @@ msgstr ""
 msgid "Freeing pipeline ...\n"
 msgstr "パイプラインを解放 (FREEING) しています...\n"
 
+#~ msgid "Usage: gst-xmllaunch <file.xml> [ element.property=value ... ]\n"
+#~ msgstr "使い方: gst-xmllaunch <file.xml> [ element.property=value ...]\n"
+
+#~ msgid "ERROR: parse of xml file '%s' failed.\n"
+#~ msgstr "エラー: xml ファイル '%s' の解析に失敗しました\n"
+
+#~ msgid "ERROR: no toplevel pipeline element in file '%s'.\n"
+#~ msgstr ""
+#~ "エラー: ファイル '%s' にトップレベルのパイプラインエレメントがありません\n"
+
+#, fuzzy
+#~ msgid "WARNING: only one toplevel element is supported at this time.\n"
+#~ msgstr "警告: トップレベルのエレメントは一つのみサポートしています"
+
+#~ msgid "ERROR: could not parse command line argument %d: %s.\n"
+#~ msgstr "エラー: コマンドライン引数 %d を解析できません: %s\n"
+
+#~ msgid "WARNING: element named '%s' not found.\n"
+#~ msgstr "警告: エレメント名 '%s' が見つかりません\n"
+
+#~ msgid "FILE"
+#~ msgstr "FILE"
+
+#, fuzzy
+#~ msgid "Do not install signal handlers for SIGUSR1 and SIGUSR2"
+#~ msgstr "フォールトハンドラをインストールしない"
+
 #~ msgid "Error writing registry cache to %s: %s"
 #~ msgstr "%s へのレジストリキャッシュの書き込み中にエラーが発生しました: %s"
 
index 0ea69f5..f956086 100644 (file)
--- a/po/lt.po
+++ b/po/lt.po
@@ -7,7 +7,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: gstreamer 0.10.29.2\n"
 "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
-"POT-Creation-Date: 2011-06-04 13:33+0100\n"
+"POT-Creation-Date: 2011-06-04 15:29+0100\n"
 "PO-Revision-Date: 2010-07-16 00:50+0300\n"
 "Last-Translator: Žygimantas Beručka <uid0@akl.lt>\n"
 "Language-Team: Lithuanian <komp_lt@konferencijos.lt>\n"
@@ -1032,30 +1032,6 @@ msgstr "Nepavyko įkelti įskiepio failo: %s\n"
 msgid "No such element or plugin '%s'\n"
 msgstr "Nėra tokio elemento arba įskiepio „%s“\n"
 
-msgid "Usage: gst-xmllaunch <file.xml> [ element.property=value ... ]\n"
-msgstr ""
-"Naudojimas: gst-xmllaunch <failas.xml> [ elementas.savybė=reikšmė ... ]\n"
-
-#, c-format
-msgid "ERROR: parse of xml file '%s' failed.\n"
-msgstr "KLAIDA: nepavyko perskaityti xml failo „%s“.\n"
-
-#, c-format
-msgid "ERROR: no toplevel pipeline element in file '%s'.\n"
-msgstr "KLAIDA: nėra aukščiausio lygmens konvejerio elemento faile „%s“.\n"
-
-msgid "WARNING: only one toplevel element is supported at this time.\n"
-msgstr ""
-"ĮSPĖJIMAS: šiuo metu palaikomas tik vienas aukščiausio lygmens elementas.\n"
-
-#, c-format
-msgid "ERROR: could not parse command line argument %d: %s.\n"
-msgstr "KLAIDA: nepavyko apdoroti komandinės eilutės argumento %d: %s.\n"
-
-#, c-format
-msgid "WARNING: element named '%s' not found.\n"
-msgstr "ĮSPĖJIMAS: nerastas elementas „%s“.\n"
-
 msgid "Index statistics"
 msgstr ""
 
@@ -1150,18 +1126,9 @@ msgstr "Neišvesti šio TIPO būsenos informacijos"
 msgid "TYPE1,TYPE2,..."
 msgstr "TIPAS1,TIPAS2,..."
 
-msgid "Save xml representation of pipeline to FILE and exit"
-msgstr "Įrašyti konvejerio xml atitikmenį į FAILĄ ir išeiti"
-
-msgid "FILE"
-msgstr "FAILAS"
-
 msgid "Do not install a fault handler"
 msgstr "Neįdiegti klaidų apdorojimo posistemės"
 
-msgid "Do not install signal handlers for SIGUSR1 and SIGUSR2"
-msgstr "Neįdiegti signalų apdorojimo posistemės signalams SIGUSR1 ir SIGUSR2"
-
 msgid "Print alloc trace (if enabled at compile time)"
 msgstr "Išvesti alloc sekimą (jei įjungta kompiliavimo metu)"
 
@@ -1232,3 +1199,34 @@ msgstr "Nustatomas konvejeris į NULL...\n"
 
 msgid "Freeing pipeline ...\n"
 msgstr "Atlaisvinamas konvejeris...\n"
+
+#~ msgid "Usage: gst-xmllaunch <file.xml> [ element.property=value ... ]\n"
+#~ msgstr ""
+#~ "Naudojimas: gst-xmllaunch <failas.xml> [ elementas.savybė=reikšmė ... ]\n"
+
+#~ msgid "ERROR: parse of xml file '%s' failed.\n"
+#~ msgstr "KLAIDA: nepavyko perskaityti xml failo „%s“.\n"
+
+#~ msgid "ERROR: no toplevel pipeline element in file '%s'.\n"
+#~ msgstr "KLAIDA: nėra aukščiausio lygmens konvejerio elemento faile „%s“.\n"
+
+#~ msgid "WARNING: only one toplevel element is supported at this time.\n"
+#~ msgstr ""
+#~ "ĮSPĖJIMAS: šiuo metu palaikomas tik vienas aukščiausio lygmens "
+#~ "elementas.\n"
+
+#~ msgid "ERROR: could not parse command line argument %d: %s.\n"
+#~ msgstr "KLAIDA: nepavyko apdoroti komandinės eilutės argumento %d: %s.\n"
+
+#~ msgid "WARNING: element named '%s' not found.\n"
+#~ msgstr "ĮSPĖJIMAS: nerastas elementas „%s“.\n"
+
+#~ msgid "Save xml representation of pipeline to FILE and exit"
+#~ msgstr "Įrašyti konvejerio xml atitikmenį į FAILĄ ir išeiti"
+
+#~ msgid "FILE"
+#~ msgstr "FAILAS"
+
+#~ msgid "Do not install signal handlers for SIGUSR1 and SIGUSR2"
+#~ msgstr ""
+#~ "Neįdiegti signalų apdorojimo posistemės signalams SIGUSR1 ir SIGUSR2"
index c9d96c9..da26668 100644 (file)
--- a/po/nb.po
+++ b/po/nb.po
@@ -6,7 +6,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: gstreamer 0.10.30.3\n"
 "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
-"POT-Creation-Date: 2011-06-04 13:33+0100\n"
+"POT-Creation-Date: 2011-06-04 15:29+0100\n"
 "PO-Revision-Date: 2010-10-24 21:36+0200\n"
 "Last-Translator: Kjartan Maraas <kmaraas@gnome.org>\n"
 "Language-Team: Norwegian Bokmaal <i18n-nb@lister.ping.uio.no>\n"
@@ -993,28 +993,6 @@ msgstr "Kunne ikke laste tilleggsfil: «%s»\n"
 msgid "No such element or plugin '%s'\n"
 msgstr ""
 
-msgid "Usage: gst-xmllaunch <file.xml> [ element.property=value ... ]\n"
-msgstr ""
-
-#, c-format
-msgid "ERROR: parse of xml file '%s' failed.\n"
-msgstr ""
-
-#, c-format
-msgid "ERROR: no toplevel pipeline element in file '%s'.\n"
-msgstr ""
-
-msgid "WARNING: only one toplevel element is supported at this time.\n"
-msgstr ""
-
-#, c-format
-msgid "ERROR: could not parse command line argument %d: %s.\n"
-msgstr ""
-
-#, c-format
-msgid "WARNING: element named '%s' not found.\n"
-msgstr ""
-
 msgid "Index statistics"
 msgstr ""
 
@@ -1109,18 +1087,9 @@ msgstr ""
 msgid "TYPE1,TYPE2,..."
 msgstr "TYPE1,TYPE2,..."
 
-msgid "Save xml representation of pipeline to FILE and exit"
-msgstr ""
-
-msgid "FILE"
-msgstr "FIL"
-
 msgid "Do not install a fault handler"
 msgstr ""
 
-msgid "Do not install signal handlers for SIGUSR1 and SIGUSR2"
-msgstr ""
-
 msgid "Print alloc trace (if enabled at compile time)"
 msgstr ""
 
@@ -1191,3 +1160,6 @@ msgstr ""
 
 msgid "Freeing pipeline ...\n"
 msgstr "Frigjør rør ...\n"
+
+#~ msgid "FILE"
+#~ msgstr "FIL"
index 0385221..fbf6572 100644 (file)
--- a/po/nl.po
+++ b/po/nl.po
@@ -10,7 +10,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: gstreamer 0.10.32.2\n"
 "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
-"POT-Creation-Date: 2011-06-04 13:33+0100\n"
+"POT-Creation-Date: 2011-06-04 15:29+0100\n"
 "PO-Revision-Date: 2011-04-26 23:10+0200\n"
 "Last-Translator: Freek de Kruijf <f.de.kruijf@gmail.com>\n"
 "Language-Team: Dutch <vertaling@vrijschrift.org>\n"
@@ -1037,31 +1037,6 @@ msgstr "Kan plugin-bestand \"%s\" niet laden\n"
 msgid "No such element or plugin '%s'\n"
 msgstr "Geen element of plugin '%s'\n"
 
-msgid "Usage: gst-xmllaunch <file.xml> [ element.property=value ... ]\n"
-msgstr ""
-"Gebruik: gst-xmllaunch <bestand.xml> [ element.eigenschap=waarde ... ]\n"
-
-#, c-format
-msgid "ERROR: parse of xml file '%s' failed.\n"
-msgstr "FOUT: verwerken van xml-bestand '%s' mislukt.\n"
-
-#, c-format
-msgid "ERROR: no toplevel pipeline element in file '%s'.\n"
-msgstr "FOUT: geen bovenste pijplijn-element gevonden in file '%s'.\n"
-
-msgid "WARNING: only one toplevel element is supported at this time.\n"
-msgstr ""
-"WAARSCHUWING: slechts één element op het hoogste niveau ondersteund op dit "
-"moment.\n"
-
-#, c-format
-msgid "ERROR: could not parse command line argument %d: %s.\n"
-msgstr "FOUT: kon argument %d op opdrachtregel niet verwerken: %s.\n"
-
-#, c-format
-msgid "WARNING: element named '%s' not found.\n"
-msgstr "WAARSCHUWING: element met naam '%s' niet gevonden.\n"
-
 msgid "Index statistics"
 msgstr "Indexstatistieken"
 
@@ -1156,18 +1131,9 @@ msgstr "Statusinformatie van soort SOORT niet weergeven"
 msgid "TYPE1,TYPE2,..."
 msgstr "SOORT1,SOORT2,..."
 
-msgid "Save xml representation of pipeline to FILE and exit"
-msgstr "XML-representatie van pijplijn in BESTAND opslaan en afsluiten"
-
-msgid "FILE"
-msgstr "BESTAND"
-
 msgid "Do not install a fault handler"
 msgstr "Geen foutafhandelaar installeren"
 
-msgid "Do not install signal handlers for SIGUSR1 and SIGUSR2"
-msgstr "Geen signaalafhandelaars installeren voor SIGUSR1 en SIGUSR2"
-
 msgid "Print alloc trace (if enabled at compile time)"
 msgstr "Toewijzingsspoor weergeven (indien aangezet tijdens compileren)"
 
@@ -1238,3 +1204,33 @@ msgstr "Pijplijn gezet op NULL ...\n"
 
 msgid "Freeing pipeline ...\n"
 msgstr "Pijplijn wordt vrijgemaakt ...\n"
+
+#~ msgid "Usage: gst-xmllaunch <file.xml> [ element.property=value ... ]\n"
+#~ msgstr ""
+#~ "Gebruik: gst-xmllaunch <bestand.xml> [ element.eigenschap=waarde ... ]\n"
+
+#~ msgid "ERROR: parse of xml file '%s' failed.\n"
+#~ msgstr "FOUT: verwerken van xml-bestand '%s' mislukt.\n"
+
+#~ msgid "ERROR: no toplevel pipeline element in file '%s'.\n"
+#~ msgstr "FOUT: geen bovenste pijplijn-element gevonden in file '%s'.\n"
+
+#~ msgid "WARNING: only one toplevel element is supported at this time.\n"
+#~ msgstr ""
+#~ "WAARSCHUWING: slechts één element op het hoogste niveau ondersteund op "
+#~ "dit moment.\n"
+
+#~ msgid "ERROR: could not parse command line argument %d: %s.\n"
+#~ msgstr "FOUT: kon argument %d op opdrachtregel niet verwerken: %s.\n"
+
+#~ msgid "WARNING: element named '%s' not found.\n"
+#~ msgstr "WAARSCHUWING: element met naam '%s' niet gevonden.\n"
+
+#~ msgid "Save xml representation of pipeline to FILE and exit"
+#~ msgstr "XML-representatie van pijplijn in BESTAND opslaan en afsluiten"
+
+#~ msgid "FILE"
+#~ msgstr "BESTAND"
+
+#~ msgid "Do not install signal handlers for SIGUSR1 and SIGUSR2"
+#~ msgstr "Geen signaalafhandelaars installeren voor SIGUSR1 en SIGUSR2"
index f49bb22..a22c9bf 100644 (file)
--- a/po/pl.po
+++ b/po/pl.po
@@ -6,7 +6,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: gstreamer 0.10.32.2\n"
 "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
-"POT-Creation-Date: 2011-06-04 13:33+0100\n"
+"POT-Creation-Date: 2011-06-04 15:29+0100\n"
 "PO-Revision-Date: 2011-04-26 17:54+0200\n"
 "Last-Translator: Jakub Bogusz <qboosh@pld-linux.org>\n"
 "Language-Team: Polish <translation-team-pl@lists.sourceforge.net>\n"
@@ -1033,29 +1033,6 @@ msgstr "Nie udało się wczytać pliku wtyczki: %s\n"
 msgid "No such element or plugin '%s'\n"
 msgstr "Nie ma takiego elementu lub wtyczki '%s'\n"
 
-msgid "Usage: gst-xmllaunch <file.xml> [ element.property=value ... ]\n"
-msgstr ""
-"Składnia: gst-xmllaunch <plik.xml> [ element.właściwość=wartość ... ]\n"
-
-#, c-format
-msgid "ERROR: parse of xml file '%s' failed.\n"
-msgstr "BŁĄD: analiza pliku xml '%s' nie powiodła się.\n"
-
-#, c-format
-msgid "ERROR: no toplevel pipeline element in file '%s'.\n"
-msgstr "BŁĄD: brak głównego elementu potoku w pliku '%s'.\n"
-
-msgid "WARNING: only one toplevel element is supported at this time.\n"
-msgstr "UWAGA: aktualnie obsługiwany jest tylko jeden element główny.\n"
-
-#, c-format
-msgid "ERROR: could not parse command line argument %d: %s.\n"
-msgstr "BŁĄD: nie udało się przeanalizować argumentu %d linii poleceń: %s.\n"
-
-#, c-format
-msgid "WARNING: element named '%s' not found.\n"
-msgstr "UWAGA: nie znaleziono elementu o nazwie '%s'.\n"
-
 msgid "Index statistics"
 msgstr "Statystyki indeksu"
 
@@ -1150,18 +1127,9 @@ msgstr "Nie wypisywanie informacji o stanie tego RODZAJU"
 msgid "TYPE1,TYPE2,..."
 msgstr "RODZAJ1,RODZAJ2,..."
 
-msgid "Save xml representation of pipeline to FILE and exit"
-msgstr "Zapisanie reprezentacji xml potoku do PLIKU i zakończenie"
-
-msgid "FILE"
-msgstr "PLIK"
-
 msgid "Do not install a fault handler"
 msgstr "Nie instalowanie obsługi błędów"
 
-msgid "Do not install signal handlers for SIGUSR1 and SIGUSR2"
-msgstr "Nieinstalowanie obsługi sygnałów SIGUSR1 i SIGUSR2"
-
 msgid "Print alloc trace (if enabled at compile time)"
 msgstr "Wypisanie śladu alokacji (jeśli został włączony w czasie kompilacji)"
 
@@ -1232,3 +1200,32 @@ msgstr "Ustawianie potoku na NULL...\n"
 
 msgid "Freeing pipeline ...\n"
 msgstr "Zwalnianie potoku...\n"
+
+#~ msgid "Usage: gst-xmllaunch <file.xml> [ element.property=value ... ]\n"
+#~ msgstr ""
+#~ "Składnia: gst-xmllaunch <plik.xml> [ element.właściwość=wartość ... ]\n"
+
+#~ msgid "ERROR: parse of xml file '%s' failed.\n"
+#~ msgstr "BŁĄD: analiza pliku xml '%s' nie powiodła się.\n"
+
+#~ msgid "ERROR: no toplevel pipeline element in file '%s'.\n"
+#~ msgstr "BŁĄD: brak głównego elementu potoku w pliku '%s'.\n"
+
+#~ msgid "WARNING: only one toplevel element is supported at this time.\n"
+#~ msgstr "UWAGA: aktualnie obsługiwany jest tylko jeden element główny.\n"
+
+#~ msgid "ERROR: could not parse command line argument %d: %s.\n"
+#~ msgstr ""
+#~ "BŁĄD: nie udało się przeanalizować argumentu %d linii poleceń: %s.\n"
+
+#~ msgid "WARNING: element named '%s' not found.\n"
+#~ msgstr "UWAGA: nie znaleziono elementu o nazwie '%s'.\n"
+
+#~ msgid "Save xml representation of pipeline to FILE and exit"
+#~ msgstr "Zapisanie reprezentacji xml potoku do PLIKU i zakończenie"
+
+#~ msgid "FILE"
+#~ msgstr "PLIK"
+
+#~ msgid "Do not install signal handlers for SIGUSR1 and SIGUSR2"
+#~ msgstr "Nieinstalowanie obsługi sygnałów SIGUSR1 i SIGUSR2"
index 4a59558..aaeae82 100644 (file)
@@ -17,7 +17,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: gstreamer-0.10.31.2\n"
 "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
-"POT-Creation-Date: 2011-06-04 13:33+0100\n"
+"POT-Creation-Date: 2011-06-04 15:29+0100\n"
 "PO-Revision-Date: 2011-01-08 01:36-0300\n"
 "Last-Translator: Fabrício Godoy <skarllot@gmail.com>\n"
 "Language-Team: Brazilian Portuguese <ldp-br@bazar.conectiva.com.br>\n"
@@ -1044,31 +1044,6 @@ msgstr "Não foi possível carregar o arquivo do plug-in: %s\n"
 msgid "No such element or plugin '%s'\n"
 msgstr "Nenhum elemento ou plug-in \"%s\"\n"
 
-msgid "Usage: gst-xmllaunch <file.xml> [ element.property=value ... ]\n"
-msgstr "Uso: gst-xmllaunch <arquivo.xml> [ elemento.propriedade=valor ... ]\n"
-
-#, c-format
-msgid "ERROR: parse of xml file '%s' failed.\n"
-msgstr "ERRO: a validação do arquivo xml \"%s\" falhou.\n"
-
-#, c-format
-msgid "ERROR: no toplevel pipeline element in file '%s'.\n"
-msgstr ""
-"ERRO: nenhum elemento de nível superior na fila de processamento do arquivo "
-"\"%s\".\n"
-
-msgid "WARNING: only one toplevel element is supported at this time.\n"
-msgstr "AVISO: atualmente há suporte apenas a um elemento de nível superior.\n"
-
-#, c-format
-msgid "ERROR: could not parse command line argument %d: %s.\n"
-msgstr ""
-"ERRO: não foi possível validar o argumento %d da linha de comando: %s.\n"
-
-#, c-format
-msgid "WARNING: element named '%s' not found.\n"
-msgstr "AVISO: o elemento com o nome \"%s\" não foi encontrado.\n"
-
 msgid "Index statistics"
 msgstr ""
 
@@ -1166,19 +1141,9 @@ msgstr "Não é possível obter informações do estado de saída do TIPO"
 msgid "TYPE1,TYPE2,..."
 msgstr "TIPO1,TIPO2,..."
 
-msgid "Save xml representation of pipeline to FILE and exit"
-msgstr ""
-"Salvar representação da fila de processamento como xml para o ARQUIVO e sair"
-
-msgid "FILE"
-msgstr "ARQUIVO"
-
 msgid "Do not install a fault handler"
 msgstr "Não instale um manipulador de falhas"
 
-msgid "Do not install signal handlers for SIGUSR1 and SIGUSR2"
-msgstr "Não fixar manipuladores de sinal para SIGUSR1 e SIGUSR2"
-
 msgid "Print alloc trace (if enabled at compile time)"
 msgstr "Exibir trilha de alocação (se habilitado na compilação)"
 
@@ -1254,3 +1219,37 @@ msgstr "Definindo a fila de processamento para NULO...\n"
 
 msgid "Freeing pipeline ...\n"
 msgstr "Liberando a fila de processamento...\n"
+
+#~ msgid "Usage: gst-xmllaunch <file.xml> [ element.property=value ... ]\n"
+#~ msgstr ""
+#~ "Uso: gst-xmllaunch <arquivo.xml> [ elemento.propriedade=valor ... ]\n"
+
+#~ msgid "ERROR: parse of xml file '%s' failed.\n"
+#~ msgstr "ERRO: a validação do arquivo xml \"%s\" falhou.\n"
+
+#~ msgid "ERROR: no toplevel pipeline element in file '%s'.\n"
+#~ msgstr ""
+#~ "ERRO: nenhum elemento de nível superior na fila de processamento do "
+#~ "arquivo \"%s\".\n"
+
+#~ msgid "WARNING: only one toplevel element is supported at this time.\n"
+#~ msgstr ""
+#~ "AVISO: atualmente há suporte apenas a um elemento de nível superior.\n"
+
+#~ msgid "ERROR: could not parse command line argument %d: %s.\n"
+#~ msgstr ""
+#~ "ERRO: não foi possível validar o argumento %d da linha de comando: %s.\n"
+
+#~ msgid "WARNING: element named '%s' not found.\n"
+#~ msgstr "AVISO: o elemento com o nome \"%s\" não foi encontrado.\n"
+
+#~ msgid "Save xml representation of pipeline to FILE and exit"
+#~ msgstr ""
+#~ "Salvar representação da fila de processamento como xml para o ARQUIVO e "
+#~ "sair"
+
+#~ msgid "FILE"
+#~ msgstr "ARQUIVO"
+
+#~ msgid "Do not install signal handlers for SIGUSR1 and SIGUSR2"
+#~ msgstr "Não fixar manipuladores de sinal para SIGUSR1 e SIGUSR2"
index ab39aac..49e0316 100644 (file)
--- a/po/ro.po
+++ b/po/ro.po
@@ -5,7 +5,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: gstreamer 0.10.29.2\n"
 "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
-"POT-Creation-Date: 2011-06-04 13:33+0100\n"
+"POT-Creation-Date: 2011-06-04 15:29+0100\n"
 "PO-Revision-Date: 2010-08-16 01:10+0300\n"
 "Last-Translator: Lucian Adrian Grijincu <lucian.grijincu@gmail.com>\n"
 "Language-Team: Romanian <translation-team-ro@lists.sourceforge.net>\n"
@@ -1051,33 +1051,6 @@ msgstr "Nu se poate încărca fișierul modul: %s\n"
 msgid "No such element or plugin '%s'\n"
 msgstr "Niciun astfel de element sau modul „%s”\n"
 
-msgid "Usage: gst-xmllaunch <file.xml> [ element.property=value ... ]\n"
-msgstr ""
-"Utilizare: gst-xmllaunch <fișier.xml> [ element.property=valoare ... ]\n"
-
-#, c-format
-msgid "ERROR: parse of xml file '%s' failed.\n"
-msgstr "EROARE: prelucrarea fișierului xml „%s” a eșuat.\n"
-
-#, c-format
-msgid "ERROR: no toplevel pipeline element in file '%s'.\n"
-msgstr ""
-"EROARE: niciun element de prim nivel al liniei de asamblare în fișierul "
-"„%s”.\n"
-
-msgid "WARNING: only one toplevel element is supported at this time.\n"
-msgstr ""
-"AVERTISMENT: doar un element de nivel de vârf este suportat în acest "
-"moment.\n"
-
-#, c-format
-msgid "ERROR: could not parse command line argument %d: %s.\n"
-msgstr "EROARE: nu se poate analiza argumetul %d al liniei de comandă: %s\n"
-
-#, c-format
-msgid "WARNING: element named '%s' not found.\n"
-msgstr "AVERTISMENT: elementul cu numele „%s” nu a fost găsit.\n"
-
 msgid "Index statistics"
 msgstr ""
 
@@ -1172,19 +1145,9 @@ msgstr "Nu scoate informații despre stările de TIPUL"
 msgid "TYPE1,TYPE2,..."
 msgstr "TIP1,TIP2,..."
 
-msgid "Save xml representation of pipeline to FILE and exit"
-msgstr ""
-"Salvarea unei reprezentări xml a liniei de asamblare în FIȘIER și ieșire"
-
-msgid "FILE"
-msgstr "FIȘIER"
-
 msgid "Do not install a fault handler"
 msgstr "Nu instala un gestionar de erori"
 
-msgid "Do not install signal handlers for SIGUSR1 and SIGUSR2"
-msgstr "Nu instala rutine de tratare a semnalului pentru SIGUSR1 și SIGUSR2"
-
 msgid "Print alloc trace (if enabled at compile time)"
 msgstr "Afișează căile de alocare (dacă s-a activat la momentul compilării)"
 
@@ -1255,3 +1218,36 @@ msgstr "Se setează linia de asamblare pe NULL ...\n"
 
 msgid "Freeing pipeline ...\n"
 msgstr "Se eliberează linia de asamblare...\n"
+
+#~ msgid "Usage: gst-xmllaunch <file.xml> [ element.property=value ... ]\n"
+#~ msgstr ""
+#~ "Utilizare: gst-xmllaunch <fișier.xml> [ element.property=valoare ... ]\n"
+
+#~ msgid "ERROR: parse of xml file '%s' failed.\n"
+#~ msgstr "EROARE: prelucrarea fișierului xml „%s” a eșuat.\n"
+
+#~ msgid "ERROR: no toplevel pipeline element in file '%s'.\n"
+#~ msgstr ""
+#~ "EROARE: niciun element de prim nivel al liniei de asamblare în fișierul "
+#~ "„%s”.\n"
+
+#~ msgid "WARNING: only one toplevel element is supported at this time.\n"
+#~ msgstr ""
+#~ "AVERTISMENT: doar un element de nivel de vârf este suportat în acest "
+#~ "moment.\n"
+
+#~ msgid "ERROR: could not parse command line argument %d: %s.\n"
+#~ msgstr "EROARE: nu se poate analiza argumetul %d al liniei de comandă: %s\n"
+
+#~ msgid "WARNING: element named '%s' not found.\n"
+#~ msgstr "AVERTISMENT: elementul cu numele „%s” nu a fost găsit.\n"
+
+#~ msgid "Save xml representation of pipeline to FILE and exit"
+#~ msgstr ""
+#~ "Salvarea unei reprezentări xml a liniei de asamblare în FIȘIER și ieșire"
+
+#~ msgid "FILE"
+#~ msgstr "FIȘIER"
+
+#~ msgid "Do not install signal handlers for SIGUSR1 and SIGUSR2"
+#~ msgstr "Nu instala rutine de tratare a semnalului pentru SIGUSR1 și SIGUSR2"
index 0144f7c..473aa32 100644 (file)
--- a/po/ru.po
+++ b/po/ru.po
@@ -9,7 +9,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: gstreamer-0.10.32.2\n"
 "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
-"POT-Creation-Date: 2011-06-04 13:33+0100\n"
+"POT-Creation-Date: 2011-06-04 15:29+0100\n"
 "PO-Revision-Date: 2011-04-26 20:25+0400\n"
 "Last-Translator: Yuri Kozlov <yuray@komyakino.ru>\n"
 "Language-Team: Russian <gnu@mx.ru>\n"
@@ -1032,30 +1032,6 @@ msgstr "Не удалось загрузить файл модуля: «%s»\n"
 msgid "No such element or plugin '%s'\n"
 msgstr "Модуль или элемент «%s» не найден\n"
 
-msgid "Usage: gst-xmllaunch <file.xml> [ element.property=value ... ]\n"
-msgstr ""
-"Использование: gst-xmllaunch <файл.xml> [ элемент.свойство=значение...]\n"
-
-#, c-format
-msgid "ERROR: parse of xml file '%s' failed.\n"
-msgstr "ОШИБКА: ошибка разбора xml-файла «%s».\n"
-
-#, c-format
-msgid "ERROR: no toplevel pipeline element in file '%s'.\n"
-msgstr "ОШИБКА: в файле «%s» отсутствует главный элемент конвейера.\n"
-
-msgid "WARNING: only one toplevel element is supported at this time.\n"
-msgstr ""
-"ПРЕДУПРЕЖДЕНИЕ: в данный момент поддерживается только один главный элемент.\n"
-
-#, c-format
-msgid "ERROR: could not parse command line argument %d: %s.\n"
-msgstr "ОШИБКА: ошибка обработки аргумента командной строки %d: %s.\n"
-
-#, c-format
-msgid "WARNING: element named '%s' not found.\n"
-msgstr "ПРЕДУПРЕЖДЕНИЕ: элемент с именем «%s» не найден.\n"
-
 msgid "Index statistics"
 msgstr "Индексная статистика"
 
@@ -1150,18 +1126,9 @@ msgstr "Не выводить информацию о состоянии ТИП
 msgid "TYPE1,TYPE2,..."
 msgstr "ТИП1, ТИП2,..."
 
-msgid "Save xml representation of pipeline to FILE and exit"
-msgstr "Сохранить конвейер в XML-файл и выйти"
-
-msgid "FILE"
-msgstr "ФАЙЛ"
-
 msgid "Do not install a fault handler"
 msgstr "Не устанавливать обработчик ошибок"
 
-msgid "Do not install signal handlers for SIGUSR1 and SIGUSR2"
-msgstr "Не устанавливать обработчики сигналов SIGUSR1 и SIGUSR2"
-
 msgid "Print alloc trace (if enabled at compile time)"
 msgstr "Вывести трассировку выделения памяти (если включено при сборке)"
 
@@ -1233,6 +1200,36 @@ msgstr "Установка конвейера в состояние NULL...\n"
 msgid "Freeing pipeline ...\n"
 msgstr "Освобождение конвейера...\n"
 
+#~ msgid "Usage: gst-xmllaunch <file.xml> [ element.property=value ... ]\n"
+#~ msgstr ""
+#~ "Использование: gst-xmllaunch <файл.xml> [ элемент.свойство=значение...]\n"
+
+#~ msgid "ERROR: parse of xml file '%s' failed.\n"
+#~ msgstr "ОШИБКА: ошибка разбора xml-файла «%s».\n"
+
+#~ msgid "ERROR: no toplevel pipeline element in file '%s'.\n"
+#~ msgstr "ОШИБКА: в файле «%s» отсутствует главный элемент конвейера.\n"
+
+#~ msgid "WARNING: only one toplevel element is supported at this time.\n"
+#~ msgstr ""
+#~ "ПРЕДУПРЕЖДЕНИЕ: в данный момент поддерживается только один главный "
+#~ "элемент.\n"
+
+#~ msgid "ERROR: could not parse command line argument %d: %s.\n"
+#~ msgstr "ОШИБКА: ошибка обработки аргумента командной строки %d: %s.\n"
+
+#~ msgid "WARNING: element named '%s' not found.\n"
+#~ msgstr "ПРЕДУПРЕЖДЕНИЕ: элемент с именем «%s» не найден.\n"
+
+#~ msgid "Save xml representation of pipeline to FILE and exit"
+#~ msgstr "Сохранить конвейер в XML-файл и выйти"
+
+#~ msgid "FILE"
+#~ msgstr "ФАЙЛ"
+
+#~ msgid "Do not install signal handlers for SIGUSR1 and SIGUSR2"
+#~ msgstr "Не устанавливать обработчики сигналов SIGUSR1 и SIGUSR2"
+
 #~ msgid "Error writing registry cache to %s: %s"
 #~ msgstr "Ошибка записи кэша реестра в %s: %s"
 
index 7178bad..19c125a 100644 (file)
--- a/po/rw.po
+++ b/po/rw.po
@@ -15,7 +15,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: gstreamer 0.8.8\n"
 "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
-"POT-Creation-Date: 2011-06-04 13:33+0100\n"
+"POT-Creation-Date: 2011-06-04 15:29+0100\n"
 "PO-Revision-Date: 2005-04-04 10:55-0700\n"
 "Last-Translator: Steven Michael Murphy <murf@e-tools.com>\n"
 "Language-Team: Kinyarwanda <translation-team-rw@lists.sourceforge.net>\n"
@@ -1209,30 +1209,6 @@ msgstr "OYA Gufungura IDOSIYE kugirango"
 msgid "No such element or plugin '%s'\n"
 msgstr "Oya Inkomoko Ikigize: kugirango"
 
-#, fuzzy
-msgid "Usage: gst-xmllaunch <file.xml> [ element.property=value ... ]\n"
-msgstr "IDOSIYE xml Ikigize: indangakintu Agaciro"
-
-#, fuzzy, c-format
-msgid "ERROR: parse of xml file '%s' failed.\n"
-msgstr "Bya xml IDOSIYE Byanze"
-
-#, fuzzy, c-format
-msgid "ERROR: no toplevel pipeline element in file '%s'.\n"
-msgstr "Oya Ikigize: in IDOSIYE"
-
-#, fuzzy
-msgid "WARNING: only one toplevel element is supported at this time.\n"
-msgstr "Ikigize: ni ku iyi Igihe"
-
-#, fuzzy, c-format
-msgid "ERROR: could not parse command line argument %d: %s.\n"
-msgstr "OYA Komandi: Umurongo"
-
-#, fuzzy, c-format
-msgid "WARNING: element named '%s' not found.\n"
-msgstr "Ikigize: OYA Byabonetse"
-
 msgid "Index statistics"
 msgstr ""
 
@@ -1330,21 +1306,10 @@ msgid "TYPE1,TYPE2,..."
 msgstr ""
 
 #, fuzzy
-msgid "Save xml representation of pipeline to FILE and exit"
-msgstr "Kubika xml Bya Kuri Na Gusohoka"
-
-msgid "FILE"
-msgstr "IDOSIYE"
-
-#, fuzzy
 msgid "Do not install a fault handler"
 msgstr "OYA Kwinjiza porogaramu a"
 
 #, fuzzy
-msgid "Do not install signal handlers for SIGUSR1 and SIGUSR2"
-msgstr "OYA Kwinjiza porogaramu a"
-
-#, fuzzy
 msgid "Print alloc trace (if enabled at compile time)"
 msgstr "NIBA Bikora ku Gukusanya Igihe"
 
@@ -1422,6 +1387,41 @@ msgid "Freeing pipeline ...\n"
 msgstr ""
 
 #, fuzzy
+#~ msgid "Usage: gst-xmllaunch <file.xml> [ element.property=value ... ]\n"
+#~ msgstr "IDOSIYE xml Ikigize: indangakintu Agaciro"
+
+#, fuzzy
+#~ msgid "ERROR: parse of xml file '%s' failed.\n"
+#~ msgstr "Bya xml IDOSIYE Byanze"
+
+#, fuzzy
+#~ msgid "ERROR: no toplevel pipeline element in file '%s'.\n"
+#~ msgstr "Oya Ikigize: in IDOSIYE"
+
+#, fuzzy
+#~ msgid "WARNING: only one toplevel element is supported at this time.\n"
+#~ msgstr "Ikigize: ni ku iyi Igihe"
+
+#, fuzzy
+#~ msgid "ERROR: could not parse command line argument %d: %s.\n"
+#~ msgstr "OYA Komandi: Umurongo"
+
+#, fuzzy
+#~ msgid "WARNING: element named '%s' not found.\n"
+#~ msgstr "Ikigize: OYA Byabonetse"
+
+#, fuzzy
+#~ msgid "Save xml representation of pipeline to FILE and exit"
+#~ msgstr "Kubika xml Bya Kuri Na Gusohoka"
+
+#~ msgid "FILE"
+#~ msgstr "IDOSIYE"
+
+#, fuzzy
+#~ msgid "Do not install signal handlers for SIGUSR1 and SIGUSR2"
+#~ msgstr "OYA Kwinjiza porogaramu a"
+
+#, fuzzy
 #~ msgid "Error while writing to file descriptor \"%d\"."
 #~ msgstr "Kuri IDOSIYE"
 
index f818a54..12fa8d2 100644 (file)
--- a/po/sk.po
+++ b/po/sk.po
@@ -8,7 +8,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: gstreamer 0.10.30.3\n"
 "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
-"POT-Creation-Date: 2011-06-04 13:33+0100\n"
+"POT-Creation-Date: 2011-06-04 15:29+0100\n"
 "PO-Revision-Date: 2010-11-08 16:13+0100\n"
 "Last-Translator: Peter Tuhársky <tuharsky@misbb.sk>\n"
 "Language-Team: Slovak <sk-i18n@lists.linux.sk>\n"
@@ -1045,29 +1045,6 @@ msgstr "Nepodarilo sa načítať súbor zásuvného modulu: %s\n"
 msgid "No such element or plugin '%s'\n"
 msgstr "Takýto prvok alebo zásuvný modul neexistuje '%s'\n"
 
-msgid "Usage: gst-xmllaunch <file.xml> [ element.property=value ... ]\n"
-msgstr "Použitie: gst-xmllaunch <súbor.xml> [ prvk.vlastnosť=hodnota ... ]\n"
-
-#, c-format
-msgid "ERROR: parse of xml file '%s' failed.\n"
-msgstr "CHYBA: zlyhala analýza xml súboru '%s'.\n"
-
-#, c-format
-msgid "ERROR: no toplevel pipeline element in file '%s'.\n"
-msgstr "CHYBA: v súbore '%s' chýba prvok rúry najvyššej úrovne.\n"
-
-msgid "WARNING: only one toplevel element is supported at this time.\n"
-msgstr ""
-"VAROVANIE: v súčasnosti je podporovaný iba jeden prvok najvyššej úrovne.\n"
-
-#, c-format
-msgid "ERROR: could not parse command line argument %d: %s.\n"
-msgstr "CHYBA: nepodarilo sa analyzovať argument príkazového riadku %d: %s.\n"
-
-#, c-format
-msgid "WARNING: element named '%s' not found.\n"
-msgstr "VAROVANIE: prvok s názvom '%s' sa nenašiel.\n"
-
 msgid "Index statistics"
 msgstr ""
 
@@ -1162,18 +1139,9 @@ msgstr "Nevypisovať informácie o stave TYPU"
 msgid "TYPE1,TYPE2,..."
 msgstr "TYP1,TYP2,..."
 
-msgid "Save xml representation of pipeline to FILE and exit"
-msgstr "Uložiť reprezentáciu rúry v xml do SÚBORU a skončiť"
-
-msgid "FILE"
-msgstr "SÚBOR"
-
 msgid "Do not install a fault handler"
 msgstr "Neinštalovať obsluhu výnimiek"
 
-msgid "Do not install signal handlers for SIGUSR1 and SIGUSR2"
-msgstr "Neinštalovať obsluhu signálov SIGUSR1 a SIGUSR2"
-
 msgid "Print alloc trace (if enabled at compile time)"
 msgstr "Vypisovať stopu alokácie (ak je to povolené pri kompilácii)"
 
@@ -1248,6 +1216,36 @@ msgstr "Nastavujem rúru na NULOVÚ ...\n"
 msgid "Freeing pipeline ...\n"
 msgstr "Uvoľňujem rúru ...\n"
 
+#~ msgid "Usage: gst-xmllaunch <file.xml> [ element.property=value ... ]\n"
+#~ msgstr ""
+#~ "Použitie: gst-xmllaunch <súbor.xml> [ prvk.vlastnosť=hodnota ... ]\n"
+
+#~ msgid "ERROR: parse of xml file '%s' failed.\n"
+#~ msgstr "CHYBA: zlyhala analýza xml súboru '%s'.\n"
+
+#~ msgid "ERROR: no toplevel pipeline element in file '%s'.\n"
+#~ msgstr "CHYBA: v súbore '%s' chýba prvok rúry najvyššej úrovne.\n"
+
+#~ msgid "WARNING: only one toplevel element is supported at this time.\n"
+#~ msgstr ""
+#~ "VAROVANIE: v súčasnosti je podporovaný iba jeden prvok najvyššej úrovne.\n"
+
+#~ msgid "ERROR: could not parse command line argument %d: %s.\n"
+#~ msgstr ""
+#~ "CHYBA: nepodarilo sa analyzovať argument príkazového riadku %d: %s.\n"
+
+#~ msgid "WARNING: element named '%s' not found.\n"
+#~ msgstr "VAROVANIE: prvok s názvom '%s' sa nenašiel.\n"
+
+#~ msgid "Save xml representation of pipeline to FILE and exit"
+#~ msgstr "Uložiť reprezentáciu rúry v xml do SÚBORU a skončiť"
+
+#~ msgid "FILE"
+#~ msgstr "SÚBOR"
+
+#~ msgid "Do not install signal handlers for SIGUSR1 and SIGUSR2"
+#~ msgstr "Neinštalovať obsluhu signálov SIGUSR1 a SIGUSR2"
+
 #~ msgid "Error writing registry cache to %s: %s"
 #~ msgstr "Chyba pri zápise vyrovnávacej pamäte registrov do %s: %s"
 
index 7f1fe7f..4b48386 100644 (file)
--- a/po/sl.po
+++ b/po/sl.po
@@ -8,7 +8,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: gstreamer 0.10.29.2\n"
 "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
-"POT-Creation-Date: 2011-06-04 13:33+0100\n"
+"POT-Creation-Date: 2011-06-04 15:29+0100\n"
 "PO-Revision-Date: 2010-09-18 20:21+0100\n"
 "Last-Translator: Matej Urbančič <matej.urban@gmail.com>\n"
 "Language-Team: Slovenian <translation-team-sl@lists.sourceforge.net>\n"
@@ -1028,28 +1028,6 @@ msgstr "Ni mogoče naložiti datoteke vstavka: %s\n"
 msgid "No such element or plugin '%s'\n"
 msgstr "Ni takega predmeta ali datoteke '%s'\n"
 
-msgid "Usage: gst-xmllaunch <file.xml> [ element.property=value ... ]\n"
-msgstr ""
-
-#, c-format
-msgid "ERROR: parse of xml file '%s' failed.\n"
-msgstr "NAPAKA: razčlenjevanje datoteke XML '%s' je spodletelo.\n"
-
-#, c-format
-msgid "ERROR: no toplevel pipeline element in file '%s'.\n"
-msgstr ""
-
-msgid "WARNING: only one toplevel element is supported at this time.\n"
-msgstr ""
-
-#, c-format
-msgid "ERROR: could not parse command line argument %d: %s.\n"
-msgstr "Napaka: ni mogoče razčleniti argumenta %d ukazne vrstice: %s.\n"
-
-#, c-format
-msgid "WARNING: element named '%s' not found.\n"
-msgstr "Opozorilo: predmeta z imenom '%s' ni mogoče najti.\n"
-
 msgid "Index statistics"
 msgstr ""
 
@@ -1146,18 +1124,9 @@ msgstr "Ne izpiši podrobnosti stanja VRSTE"
 msgid "TYPE1,TYPE2,..."
 msgstr "VRSTA1,VRSTA2, ..."
 
-msgid "Save xml representation of pipeline to FILE and exit"
-msgstr ""
-
-msgid "FILE"
-msgstr "DATOTEKA"
-
 msgid "Do not install a fault handler"
 msgstr "Na namesti ročnika napak"
 
-msgid "Do not install signal handlers for SIGUSR1 and SIGUSR2"
-msgstr ""
-
 msgid "Print alloc trace (if enabled at compile time)"
 msgstr ""
 
@@ -1229,3 +1198,15 @@ msgstr "Nastavljanje cevovoda na NULL ...\n"
 
 msgid "Freeing pipeline ...\n"
 msgstr "Sproščanje cevovoda ...\n"
+
+#~ msgid "ERROR: parse of xml file '%s' failed.\n"
+#~ msgstr "NAPAKA: razčlenjevanje datoteke XML '%s' je spodletelo.\n"
+
+#~ msgid "ERROR: could not parse command line argument %d: %s.\n"
+#~ msgstr "Napaka: ni mogoče razčleniti argumenta %d ukazne vrstice: %s.\n"
+
+#~ msgid "WARNING: element named '%s' not found.\n"
+#~ msgstr "Opozorilo: predmeta z imenom '%s' ni mogoče najti.\n"
+
+#~ msgid "FILE"
+#~ msgstr "DATOTEKA"
index dbc2ffa..51cedb9 100644 (file)
--- a/po/sq.po
+++ b/po/sq.po
@@ -6,7 +6,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: gstreamer 0.8.4\n"
 "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
-"POT-Creation-Date: 2011-06-04 13:33+0100\n"
+"POT-Creation-Date: 2011-06-04 15:29+0100\n"
 "PO-Revision-Date: 2004-08-07 23:46+0200\n"
 "Last-Translator: Laurent Dhima <laurenti@alblinux.net>\n"
 "Language-Team: Albanian <begraj@hotmail.com>\n"
@@ -1044,30 +1044,6 @@ msgstr "E pamundur hapja e file \"%s\" në shkrim."
 msgid "No such element or plugin '%s'\n"
 msgstr "asnjë element burues për URI \"%s\""
 
-msgid "Usage: gst-xmllaunch <file.xml> [ element.property=value ... ]\n"
-msgstr "Përdorimi: gst-xmllaunch <file.xml> [ element.property=vlera ... ]\n"
-
-#, c-format
-msgid "ERROR: parse of xml file '%s' failed.\n"
-msgstr "GABIM: analizimi i file xml '%s' dështoi.\n"
-
-#, c-format
-msgid "ERROR: no toplevel pipeline element in file '%s'.\n"
-msgstr "GABIM: asnjë element i pipline të toplevel tek file '%s'.\n"
-
-#, fuzzy
-msgid "WARNING: only one toplevel element is supported at this time.\n"
-msgstr "KUJDES: vetëm një element toplevel suportohet aktualisht."
-
-#, c-format
-msgid "ERROR: could not parse command line argument %d: %s.\n"
-msgstr ""
-"GABIM: i pamundur analizimi i argumentit %d të rreshtit të komandës: %s.\n"
-
-#, c-format
-msgid "WARNING: element named '%s' not found.\n"
-msgstr "KUJDES: elementi me emrin '%s' nuk u gjet.\n"
-
 msgid "Index statistics"
 msgstr ""
 
@@ -1161,19 +1137,9 @@ msgstr "Mos jep informacionin e gjendjes së LLOJIT"
 msgid "TYPE1,TYPE2,..."
 msgstr "LLOJI1,LLOJI2,..."
 
-msgid "Save xml representation of pipeline to FILE and exit"
-msgstr "Ruaj prezantimin xml të pipeline tek FILE dhe dil"
-
-msgid "FILE"
-msgstr "FILE"
-
 msgid "Do not install a fault handler"
 msgstr "Mos instalo një ushqyes të dëmtuar"
 
-#, fuzzy
-msgid "Do not install signal handlers for SIGUSR1 and SIGUSR2"
-msgstr "Mos instalo një ushqyes të dëmtuar"
-
 msgid "Print alloc trace (if enabled at compile time)"
 msgstr "Printo shenjat e alloc (nëse aktivuar në kohën e kompilimit)"
 
@@ -1248,6 +1214,37 @@ msgstr ""
 msgid "Freeing pipeline ...\n"
 msgstr "DUKE ZBATUAR pipeline ...\n"
 
+#~ msgid "Usage: gst-xmllaunch <file.xml> [ element.property=value ... ]\n"
+#~ msgstr ""
+#~ "Përdorimi: gst-xmllaunch <file.xml> [ element.property=vlera ... ]\n"
+
+#~ msgid "ERROR: parse of xml file '%s' failed.\n"
+#~ msgstr "GABIM: analizimi i file xml '%s' dështoi.\n"
+
+#~ msgid "ERROR: no toplevel pipeline element in file '%s'.\n"
+#~ msgstr "GABIM: asnjë element i pipline të toplevel tek file '%s'.\n"
+
+#, fuzzy
+#~ msgid "WARNING: only one toplevel element is supported at this time.\n"
+#~ msgstr "KUJDES: vetëm një element toplevel suportohet aktualisht."
+
+#~ msgid "ERROR: could not parse command line argument %d: %s.\n"
+#~ msgstr ""
+#~ "GABIM: i pamundur analizimi i argumentit %d të rreshtit të komandës: %s.\n"
+
+#~ msgid "WARNING: element named '%s' not found.\n"
+#~ msgstr "KUJDES: elementi me emrin '%s' nuk u gjet.\n"
+
+#~ msgid "Save xml representation of pipeline to FILE and exit"
+#~ msgstr "Ruaj prezantimin xml të pipeline tek FILE dhe dil"
+
+#~ msgid "FILE"
+#~ msgstr "FILE"
+
+#, fuzzy
+#~ msgid "Do not install signal handlers for SIGUSR1 and SIGUSR2"
+#~ msgstr "Mos instalo një ushqyes të dëmtuar"
+
 #~ msgid "Disable accelerated CPU instructions"
 #~ msgstr "Ç'aktivo instruksionet e përshpejtimit të CPU"
 
index 82810fb..a407d3c 100644 (file)
--- a/po/sr.po
+++ b/po/sr.po
@@ -6,7 +6,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: gstreamer 0.8.8\n"
 "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
-"POT-Creation-Date: 2011-06-04 13:33+0100\n"
+"POT-Creation-Date: 2011-06-04 15:29+0100\n"
 "PO-Revision-Date: 2005-01-27 16:58+0100\n"
 "Last-Translator: Danilo Segan <dsegan@gmx.net>\n"
 "Language-Team: Serbian <gnu@prevod.org>\n"
@@ -1058,30 +1058,6 @@ msgstr "Не могу да отворим датотеку „%s“ ради у
 msgid "No such element or plugin '%s'\n"
 msgstr "нема изворног елемента за адресу „%s“"
 
-msgid "Usage: gst-xmllaunch <file.xml> [ element.property=value ... ]\n"
-msgstr ""
-"Употреба: gst-xmllaunch <датотека.xml> [ елемент.особина=вредност ... ]\n"
-
-#, c-format
-msgid "ERROR: parse of xml file '%s' failed.\n"
-msgstr "ГРЕШКА: неуспешно рашчлањивање xml датотеке „%s“.\n"
-
-#, c-format
-msgid "ERROR: no toplevel pipeline element in file '%s'.\n"
-msgstr "ГРЕШКА: нема врховног елемента цевовода у датотеци „%s“.\n"
-
-#, fuzzy
-msgid "WARNING: only one toplevel element is supported at this time.\n"
-msgstr "УПОЗОРЕЊЕ: тренутно је подржан само један врховни елемент."
-
-#, c-format
-msgid "ERROR: could not parse command line argument %d: %s.\n"
-msgstr "ГРЕШКА: не могу да рашчланим %d. аргумент наредбе: %s.\n"
-
-#, c-format
-msgid "WARNING: element named '%s' not found.\n"
-msgstr "УПОЗОРЕЊЕ: елемент са именом „%s“ није нађен.\n"
-
 msgid "Index statistics"
 msgstr ""
 
@@ -1175,19 +1151,9 @@ msgstr "Не исписуј податке о стању за ВРСТУ"
 msgid "TYPE1,TYPE2,..."
 msgstr "ВРСТА1,ВРСТА2,..."
 
-msgid "Save xml representation of pipeline to FILE and exit"
-msgstr "Сачувај xml облик цевовода у ДАТОТЕКУ и заврши"
-
-msgid "FILE"
-msgstr "ДАТОТЕКА"
-
 msgid "Do not install a fault handler"
 msgstr "Не постављај руковаоца грешкама"
 
-#, fuzzy
-msgid "Do not install signal handlers for SIGUSR1 and SIGUSR2"
-msgstr "Не постављај руковаоца грешкама"
-
 msgid "Print alloc trace (if enabled at compile time)"
 msgstr "Испиши траг доделе меморије (ако је укључено при превођењу)"
 
@@ -1262,6 +1228,36 @@ msgstr ""
 msgid "Freeing pipeline ...\n"
 msgstr "Покрећем цевовод...\n"
 
+#~ msgid "Usage: gst-xmllaunch <file.xml> [ element.property=value ... ]\n"
+#~ msgstr ""
+#~ "Употреба: gst-xmllaunch <датотека.xml> [ елемент.особина=вредност ... ]\n"
+
+#~ msgid "ERROR: parse of xml file '%s' failed.\n"
+#~ msgstr "ГРЕШКА: неуспешно рашчлањивање xml датотеке „%s“.\n"
+
+#~ msgid "ERROR: no toplevel pipeline element in file '%s'.\n"
+#~ msgstr "ГРЕШКА: нема врховног елемента цевовода у датотеци „%s“.\n"
+
+#, fuzzy
+#~ msgid "WARNING: only one toplevel element is supported at this time.\n"
+#~ msgstr "УПОЗОРЕЊЕ: тренутно је подржан само један врховни елемент."
+
+#~ msgid "ERROR: could not parse command line argument %d: %s.\n"
+#~ msgstr "ГРЕШКА: не могу да рашчланим %d. аргумент наредбе: %s.\n"
+
+#~ msgid "WARNING: element named '%s' not found.\n"
+#~ msgstr "УПОЗОРЕЊЕ: елемент са именом „%s“ није нађен.\n"
+
+#~ msgid "Save xml representation of pipeline to FILE and exit"
+#~ msgstr "Сачувај xml облик цевовода у ДАТОТЕКУ и заврши"
+
+#~ msgid "FILE"
+#~ msgstr "ДАТОТЕКА"
+
+#, fuzzy
+#~ msgid "Do not install signal handlers for SIGUSR1 and SIGUSR2"
+#~ msgstr "Не постављај руковаоца грешкама"
+
 #~ msgid "Disable accelerated CPU instructions"
 #~ msgstr "Искључи убрзане инструкције процесора"
 
index d27e686..1e954e1 100644 (file)
--- a/po/sv.po
+++ b/po/sv.po
@@ -8,7 +8,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: gstreamer 0.10.31.2\n"
 "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
-"POT-Creation-Date: 2011-06-04 13:33+0100\n"
+"POT-Creation-Date: 2011-06-04 15:29+0100\n"
 "PO-Revision-Date: 2011-01-09 19:46+0100\n"
 "Last-Translator: Daniel Nylander <po@danielnylander.se>\n"
 "Language-Team: Swedish <tp-sv@listor.tp-sv.se>\n"
@@ -1041,28 +1041,6 @@ msgstr "Kunde inte läsa in fil för insticksmodul: %s\n"
 msgid "No such element or plugin '%s'\n"
 msgstr "Inget sådant element eller insticksmodul \"%s\"\n"
 
-msgid "Usage: gst-xmllaunch <file.xml> [ element.property=value ... ]\n"
-msgstr "Användning: gst-xmllaunch <fil.xml> [ element.egenskap=värde ... ]\n"
-
-#, c-format
-msgid "ERROR: parse of xml file '%s' failed.\n"
-msgstr "FEL: tolkning av xml-filen \"%s\" misslyckades.\n"
-
-#, c-format
-msgid "ERROR: no toplevel pipeline element in file '%s'.\n"
-msgstr "FEL: inget rörledningselement på översta nivån i filen \"%s\".\n"
-
-msgid "WARNING: only one toplevel element is supported at this time.\n"
-msgstr "VARNING: endast ett element på översta nivån stöds just nu.\n"
-
-#, c-format
-msgid "ERROR: could not parse command line argument %d: %s.\n"
-msgstr "FEL: kunde inte tolka kommandoradsargumentet %d: %s.\n"
-
-#, c-format
-msgid "WARNING: element named '%s' not found.\n"
-msgstr "VARNING: elementet med namnet \"%s\" hittades inte.\n"
-
 msgid "Index statistics"
 msgstr ""
 
@@ -1157,18 +1135,9 @@ msgstr "Skriv inte ut statusinformation av TYP"
 msgid "TYPE1,TYPE2,..."
 msgstr "TYP1,TYP2,..."
 
-msgid "Save xml representation of pipeline to FILE and exit"
-msgstr "Spara xml-representation av rörledningen i FIL och avsluta"
-
-msgid "FILE"
-msgstr "FIL"
-
 msgid "Do not install a fault handler"
 msgstr "Installera inte en felhanterare"
 
-msgid "Do not install signal handlers for SIGUSR1 and SIGUSR2"
-msgstr "Installera inte signalhanterare för SIGUSR1 och SIGUSR2"
-
 msgid "Print alloc trace (if enabled at compile time)"
 msgstr "Skriv ut alloc-spår (om aktiverat vid kompileringen)"
 
@@ -1243,6 +1212,34 @@ msgstr "Ställer in rörledningen till NULL...\n"
 msgid "Freeing pipeline ...\n"
 msgstr "Frigör rörledning ...\n"
 
+#~ msgid "Usage: gst-xmllaunch <file.xml> [ element.property=value ... ]\n"
+#~ msgstr ""
+#~ "Användning: gst-xmllaunch <fil.xml> [ element.egenskap=värde ... ]\n"
+
+#~ msgid "ERROR: parse of xml file '%s' failed.\n"
+#~ msgstr "FEL: tolkning av xml-filen \"%s\" misslyckades.\n"
+
+#~ msgid "ERROR: no toplevel pipeline element in file '%s'.\n"
+#~ msgstr "FEL: inget rörledningselement på översta nivån i filen \"%s\".\n"
+
+#~ msgid "WARNING: only one toplevel element is supported at this time.\n"
+#~ msgstr "VARNING: endast ett element på översta nivån stöds just nu.\n"
+
+#~ msgid "ERROR: could not parse command line argument %d: %s.\n"
+#~ msgstr "FEL: kunde inte tolka kommandoradsargumentet %d: %s.\n"
+
+#~ msgid "WARNING: element named '%s' not found.\n"
+#~ msgstr "VARNING: elementet med namnet \"%s\" hittades inte.\n"
+
+#~ msgid "Save xml representation of pipeline to FILE and exit"
+#~ msgstr "Spara xml-representation av rörledningen i FIL och avsluta"
+
+#~ msgid "FILE"
+#~ msgstr "FIL"
+
+#~ msgid "Do not install signal handlers for SIGUSR1 and SIGUSR2"
+#~ msgstr "Installera inte signalhanterare för SIGUSR1 och SIGUSR2"
+
 #~ msgid "Error writing registry cache to %s: %s"
 #~ msgstr "Fel vid skrivning av registercache till %s: %s"
 
index d973ac9..5dfd6f5 100644 (file)
--- a/po/tr.po
+++ b/po/tr.po
@@ -6,7 +6,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: gstreamer 0.8.0\n"
 "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
-"POT-Creation-Date: 2011-06-04 13:33+0100\n"
+"POT-Creation-Date: 2011-06-04 15:29+0100\n"
 "PO-Revision-Date: 2004-04-03 03:14+0300\n"
 "Last-Translator: Baris Cicek <baris@teamforce.name.tr>\n"
 "Language-Team: Turkish <gnu-tr-u12a@lists.sourceforge.net>\n"
@@ -1045,29 +1045,6 @@ msgstr "\"%s\" dosyası yazım için açılamadı."
 msgid "No such element or plugin '%s'\n"
 msgstr "\"%s\" URI'si için kaynak öğesi yok"
 
-msgid "Usage: gst-xmllaunch <file.xml> [ element.property=value ... ]\n"
-msgstr "Kullanım: gst-xmllaunch <dosya.xml> [ öğe.özellik=değer ... ]\n"
-
-#, c-format
-msgid "ERROR: parse of xml file '%s' failed.\n"
-msgstr "HATA: xml dosyası '%s' ayrıştırması başarısız.\n"
-
-#, c-format
-msgid "ERROR: no toplevel pipeline element in file '%s'.\n"
-msgstr "HATA: '%s' dosyasında üst seviye öğesi bulunamadı.\n"
-
-#, fuzzy
-msgid "WARNING: only one toplevel element is supported at this time.\n"
-msgstr "UYARI: Şu anda sadece bir tane üst seviye öğesi destekleniyor."
-
-#, c-format
-msgid "ERROR: could not parse command line argument %d: %s.\n"
-msgstr "HATA: komut satırı argümanı %d ayrıştırılamadı: %s.\n"
-
-#, c-format
-msgid "WARNING: element named '%s' not found.\n"
-msgstr "UYARI: '%s' isimli öğe bulunamadı.\n"
-
 msgid "Index statistics"
 msgstr ""
 
@@ -1161,19 +1138,9 @@ msgstr "TÜRÜN durum bilgisini gösterme"
 msgid "TYPE1,TYPE2,..."
 msgstr "TÜR1,TÜR2,..."
 
-msgid "Save xml representation of pipeline to FILE and exit"
-msgstr "Boruhattının xml belirtimini DOSYA'ya kaydet ve çık"
-
-msgid "FILE"
-msgstr "DOSYA"
-
 msgid "Do not install a fault handler"
 msgstr "Hatalı işleticiyi kurma"
 
-#, fuzzy
-msgid "Do not install signal handlers for SIGUSR1 and SIGUSR2"
-msgstr "Hatalı işleticiyi kurma"
-
 msgid "Print alloc trace (if enabled at compile time)"
 msgstr "'alloc' takibini yazdır (derleme sırasında etkinleştirilmişse)"
 
@@ -1248,6 +1215,35 @@ msgstr ""
 msgid "Freeing pipeline ...\n"
 msgstr "BORUHATTI çalıştırılıyor ...\n"
 
+#~ msgid "Usage: gst-xmllaunch <file.xml> [ element.property=value ... ]\n"
+#~ msgstr "Kullanım: gst-xmllaunch <dosya.xml> [ öğe.özellik=değer ... ]\n"
+
+#~ msgid "ERROR: parse of xml file '%s' failed.\n"
+#~ msgstr "HATA: xml dosyası '%s' ayrıştırması başarısız.\n"
+
+#~ msgid "ERROR: no toplevel pipeline element in file '%s'.\n"
+#~ msgstr "HATA: '%s' dosyasında üst seviye öğesi bulunamadı.\n"
+
+#, fuzzy
+#~ msgid "WARNING: only one toplevel element is supported at this time.\n"
+#~ msgstr "UYARI: Şu anda sadece bir tane üst seviye öğesi destekleniyor."
+
+#~ msgid "ERROR: could not parse command line argument %d: %s.\n"
+#~ msgstr "HATA: komut satırı argümanı %d ayrıştırılamadı: %s.\n"
+
+#~ msgid "WARNING: element named '%s' not found.\n"
+#~ msgstr "UYARI: '%s' isimli öğe bulunamadı.\n"
+
+#~ msgid "Save xml representation of pipeline to FILE and exit"
+#~ msgstr "Boruhattının xml belirtimini DOSYA'ya kaydet ve çık"
+
+#~ msgid "FILE"
+#~ msgstr "DOSYA"
+
+#, fuzzy
+#~ msgid "Do not install signal handlers for SIGUSR1 and SIGUSR2"
+#~ msgstr "Hatalı işleticiyi kurma"
+
 #~ msgid "Disable accelerated CPU instructions"
 #~ msgstr "Hızlandırılmış CPU işlemlerini kapat"
 
index 70d9a32..8013284 100644 (file)
--- a/po/uk.po
+++ b/po/uk.po
@@ -7,7 +7,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: gstreamer 0.10.14\n"
 "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
-"POT-Creation-Date: 2011-06-04 13:33+0100\n"
+"POT-Creation-Date: 2011-06-04 15:29+0100\n"
 "PO-Revision-Date: 2007-09-07 11:16+0300\n"
 "Last-Translator: Maxim V. Dziumanenko <dziumanenko@gmail.com>\n"
 "Language-Team: Ukrainian <translation-team-uk@lists.sourceforge.net>\n"
@@ -1033,31 +1033,6 @@ msgstr "Не вдається завантажити файл модулю %s\n"
 msgid "No such element or plugin '%s'\n"
 msgstr "Відсутній елемент або модуль '%s'\n"
 
-msgid "Usage: gst-xmllaunch <file.xml> [ element.property=value ... ]\n"
-msgstr ""
-"Використання: gst-xmllaunch <file.xml> [ елемент.властивість=значення ... ]\n"
-
-#, c-format
-msgid "ERROR: parse of xml file '%s' failed.\n"
-msgstr "ПОМИЛКА: помилка при аналізі xml файлу \"%s\".\n"
-
-#, c-format
-msgid "ERROR: no toplevel pipeline element in file '%s'.\n"
-msgstr "ПОМИЛКА: немає верхнього елементу каналу у файлі \"%s\".\n"
-
-#, fuzzy
-msgid "WARNING: only one toplevel element is supported at this time.\n"
-msgstr "ПОПЕРЕДЖЕННЯ: наразі підтримується лише один верхній елемент."
-
-#, c-format
-msgid "ERROR: could not parse command line argument %d: %s.\n"
-msgstr ""
-"ПОМИЛКА: не вдається проаналізувати аргумент командного рядка %d: %s.\n"
-
-#, c-format
-msgid "WARNING: element named '%s' not found.\n"
-msgstr "ПОПЕРЕДЖЕННЯ: елемент з назвою \"%s\" не існує.\n"
-
 msgid "Index statistics"
 msgstr ""
 
@@ -1154,19 +1129,9 @@ msgstr "Не виводити інформацію про статус типу
 msgid "TYPE1,TYPE2,..."
 msgstr "ТИП1,ТИП2,..."
 
-msgid "Save xml representation of pipeline to FILE and exit"
-msgstr "Зберегти xml представлення каналу у файл ФАЙЛ та завершитись"
-
-msgid "FILE"
-msgstr "ФАЙЛ"
-
 msgid "Do not install a fault handler"
 msgstr "Не встановлювати обробник збоїв"
 
-#, fuzzy
-msgid "Do not install signal handlers for SIGUSR1 and SIGUSR2"
-msgstr "Не встановлювати обробник збоїв"
-
 msgid "Print alloc trace (if enabled at compile time)"
 msgstr "Вивести трасу розподілу (якщо ввімкнено при компіляції)"
 
@@ -1239,6 +1204,38 @@ msgstr "Канал переводиться у стан NULL ...\n"
 msgid "Freeing pipeline ...\n"
 msgstr "Канал переводиться у стан NULL ...\n"
 
+#~ msgid "Usage: gst-xmllaunch <file.xml> [ element.property=value ... ]\n"
+#~ msgstr ""
+#~ "Використання: gst-xmllaunch <file.xml> [ елемент."
+#~ "властивість=значення ... ]\n"
+
+#~ msgid "ERROR: parse of xml file '%s' failed.\n"
+#~ msgstr "ПОМИЛКА: помилка при аналізі xml файлу \"%s\".\n"
+
+#~ msgid "ERROR: no toplevel pipeline element in file '%s'.\n"
+#~ msgstr "ПОМИЛКА: немає верхнього елементу каналу у файлі \"%s\".\n"
+
+#, fuzzy
+#~ msgid "WARNING: only one toplevel element is supported at this time.\n"
+#~ msgstr "ПОПЕРЕДЖЕННЯ: наразі підтримується лише один верхній елемент."
+
+#~ msgid "ERROR: could not parse command line argument %d: %s.\n"
+#~ msgstr ""
+#~ "ПОМИЛКА: не вдається проаналізувати аргумент командного рядка %d: %s.\n"
+
+#~ msgid "WARNING: element named '%s' not found.\n"
+#~ msgstr "ПОПЕРЕДЖЕННЯ: елемент з назвою \"%s\" не існує.\n"
+
+#~ msgid "Save xml representation of pipeline to FILE and exit"
+#~ msgstr "Зберегти xml представлення каналу у файл ФАЙЛ та завершитись"
+
+#~ msgid "FILE"
+#~ msgstr "ФАЙЛ"
+
+#, fuzzy
+#~ msgid "Do not install signal handlers for SIGUSR1 and SIGUSR2"
+#~ msgstr "Не встановлювати обробник збоїв"
+
 #~ msgid "Error writing registry cache to %s: %s"
 #~ msgstr "Помилка при записі кешу реєстру у %s: %s"
 
index 6dafb70..36453b8 100644 (file)
--- a/po/vi.po
+++ b/po/vi.po
@@ -7,7 +7,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: gstreamer 0.10.29.2\n"
 "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
-"POT-Creation-Date: 2011-06-04 13:33+0100\n"
+"POT-Creation-Date: 2011-06-04 15:29+0100\n"
 "PO-Revision-Date: 2010-10-03 19:09+1030\n"
 "Last-Translator: Clytie Siddall <clytie@riverland.net.au>\n"
 "Language-Team: Vietnamese <vi-VN@googlegroups.com>\n"
@@ -1030,29 +1030,6 @@ msgstr "Không thể nạp tập tin phần bổ sung: %s\n"
 msgid "No such element or plugin '%s'\n"
 msgstr "Không có yếu tố hay phần bổ sung như vậy « %s »\n"
 
-msgid "Usage: gst-xmllaunch <file.xml> [ element.property=value ... ]\n"
-msgstr ""
-"Cách sử dụng: gst-xmllaunch <tập_tin.xml> [ yếu_tố.tài_sản=giá_trị ...]\n"
-
-#, c-format
-msgid "ERROR: parse of xml file '%s' failed.\n"
-msgstr "LỖI: lỗi phân tách tập tin xml « %s ».\n"
-
-#, c-format
-msgid "ERROR: no toplevel pipeline element in file '%s'.\n"
-msgstr "LỖI: không có yếu tố đường ống cấp đầu trong tập tin « %s ».\n"
-
-msgid "WARNING: only one toplevel element is supported at this time.\n"
-msgstr "CẢNH BÁO : hiện thời hỗ trợ chỉ một yếu tố cấp đầu.\n"
-
-#, c-format
-msgid "ERROR: could not parse command line argument %d: %s.\n"
-msgstr "LỖI: không thể phân tách đối số dòng lệnh %d: %s.\n"
-
-#, c-format
-msgid "WARNING: element named '%s' not found.\n"
-msgstr "CẢNH BÁO : không tìm thấy yếu tố tên « %s ».\n"
-
 msgid "Index statistics"
 msgstr ""
 
@@ -1147,18 +1124,9 @@ msgstr "Không xuất thông tin trạng thái KIỂU"
 msgid "TYPE1,TYPE2,..."
 msgstr "KIỂU1,KIỂU2,..."
 
-msgid "Save xml representation of pipeline to FILE and exit"
-msgstr "Lưu đường ống dạng XML vào TẬP_TIN rồi thoát"
-
-msgid "FILE"
-msgstr "TẬP_TIN"
-
 msgid "Do not install a fault handler"
 msgstr "Không cài đặt bộ quản lý lỗi"
 
-msgid "Do not install signal handlers for SIGUSR1 and SIGUSR2"
-msgstr "Đừng cài đặt bộ quản lý tín hiệu cho SIGUSR1 và SIGUSR2"
-
 msgid "Print alloc trace (if enabled at compile time)"
 msgstr "In ra vết cấp phát (nếu được bật khi biên dich)"
 
@@ -1231,3 +1199,31 @@ msgstr "Đang lập đường ống thành VÔ GIÁ TRỊ ...\n"
 
 msgid "Freeing pipeline ...\n"
 msgstr "Đang giải phóng đường ống...\n"
+
+#~ msgid "Usage: gst-xmllaunch <file.xml> [ element.property=value ... ]\n"
+#~ msgstr ""
+#~ "Cách sử dụng: gst-xmllaunch <tập_tin.xml> [ yếu_tố.tài_sản=giá_trị ...]\n"
+
+#~ msgid "ERROR: parse of xml file '%s' failed.\n"
+#~ msgstr "LỖI: lỗi phân tách tập tin xml « %s ».\n"
+
+#~ msgid "ERROR: no toplevel pipeline element in file '%s'.\n"
+#~ msgstr "LỖI: không có yếu tố đường ống cấp đầu trong tập tin « %s ».\n"
+
+#~ msgid "WARNING: only one toplevel element is supported at this time.\n"
+#~ msgstr "CẢNH BÁO : hiện thời hỗ trợ chỉ một yếu tố cấp đầu.\n"
+
+#~ msgid "ERROR: could not parse command line argument %d: %s.\n"
+#~ msgstr "LỖI: không thể phân tách đối số dòng lệnh %d: %s.\n"
+
+#~ msgid "WARNING: element named '%s' not found.\n"
+#~ msgstr "CẢNH BÁO : không tìm thấy yếu tố tên « %s ».\n"
+
+#~ msgid "Save xml representation of pipeline to FILE and exit"
+#~ msgstr "Lưu đường ống dạng XML vào TẬP_TIN rồi thoát"
+
+#~ msgid "FILE"
+#~ msgstr "TẬP_TIN"
+
+#~ msgid "Do not install signal handlers for SIGUSR1 and SIGUSR2"
+#~ msgstr "Đừng cài đặt bộ quản lý tín hiệu cho SIGUSR1 và SIGUSR2"
index 92a1d9e..d28da02 100644 (file)
@@ -6,7 +6,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: gstreamer 0.10.25.2\n"
 "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
-"POT-Creation-Date: 2011-06-04 13:33+0100\n"
+"POT-Creation-Date: 2011-06-04 15:29+0100\n"
 "PO-Revision-Date: 2010-02-02 18:58+0800\n"
 "Last-Translator: Ji ZhengYu <zhengyuji@gmail.com>\n"
 "Language-Team: Chinese (simplified) <i18n-zh@googlegroups.com>\n"
@@ -1002,28 +1002,6 @@ msgstr "无法载入插件文件: %s\n"
 msgid "No such element or plugin '%s'\n"
 msgstr "没有那样的组件或插件‘%s’\n"
 
-msgid "Usage: gst-xmllaunch <file.xml> [ element.property=value ... ]\n"
-msgstr "用法: gst-xmllaunch <file.xml> [ element.property=value ... ]\n"
-
-#, c-format
-msgid "ERROR: parse of xml file '%s' failed.\n"
-msgstr "错误: xml 文件‘%s’解析失败。\n"
-
-#, c-format
-msgid "ERROR: no toplevel pipeline element in file '%s'.\n"
-msgstr "错误: 文件‘%s’中没有顶级管道组件。\n"
-
-msgid "WARNING: only one toplevel element is supported at this time.\n"
-msgstr "警告: 此时仅支持一个一级组件。\n"
-
-#, c-format
-msgid "ERROR: could not parse command line argument %d: %s.\n"
-msgstr "错误: 无法解析命令行参数 %d: %s。\n"
-
-#, c-format
-msgid "WARNING: element named '%s' not found.\n"
-msgstr "警告: 组件名‘%s’未找到。\n"
-
 msgid "Index statistics"
 msgstr ""
 
@@ -1118,18 +1096,9 @@ msgstr "不输出类型的状态信息"
 msgid "TYPE1,TYPE2,..."
 msgstr "类型1,类型2,..."
 
-msgid "Save xml representation of pipeline to FILE and exit"
-msgstr "保存管道的 xml 描述符至文件并退出"
-
-msgid "FILE"
-msgstr "文件"
-
 msgid "Do not install a fault handler"
 msgstr "不安装错误的处理程序"
 
-msgid "Do not install signal handlers for SIGUSR1 and SIGUSR2"
-msgstr ""
-
 msgid "Print alloc trace (if enabled at compile time)"
 msgstr "打印分配记录(如果在编译时开启的话)"
 
@@ -1202,6 +1171,30 @@ msgstr "设置 NULL 管道 ...\n"
 msgid "Freeing pipeline ...\n"
 msgstr "释放管道资源 ...\n"
 
+#~ msgid "Usage: gst-xmllaunch <file.xml> [ element.property=value ... ]\n"
+#~ msgstr "用法: gst-xmllaunch <file.xml> [ element.property=value ... ]\n"
+
+#~ msgid "ERROR: parse of xml file '%s' failed.\n"
+#~ msgstr "错误: xml 文件‘%s’解析失败。\n"
+
+#~ msgid "ERROR: no toplevel pipeline element in file '%s'.\n"
+#~ msgstr "错误: 文件‘%s’中没有顶级管道组件。\n"
+
+#~ msgid "WARNING: only one toplevel element is supported at this time.\n"
+#~ msgstr "警告: 此时仅支持一个一级组件。\n"
+
+#~ msgid "ERROR: could not parse command line argument %d: %s.\n"
+#~ msgstr "错误: 无法解析命令行参数 %d: %s。\n"
+
+#~ msgid "WARNING: element named '%s' not found.\n"
+#~ msgstr "警告: 组件名‘%s’未找到。\n"
+
+#~ msgid "Save xml representation of pipeline to FILE and exit"
+#~ msgstr "保存管道的 xml 描述符至文件并退出"
+
+#~ msgid "FILE"
+#~ msgstr "文件"
+
 #~ msgid "Error writing registry cache to %s: %s"
 #~ msgstr "寄存器缓存写入 %s 时出错: %s"
 
index 7bb8fee..f286dd3 100644 (file)
@@ -6,7 +6,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: gstreamer 0.8.8\n"
 "Report-Msgid-Bugs-To: http://bugzilla.gnome.org/\n"
-"POT-Creation-Date: 2011-06-04 13:33+0100\n"
+"POT-Creation-Date: 2011-06-04 15:29+0100\n"
 "PO-Revision-Date: 2005-04-27 14:55+0800\n"
 "Last-Translator: Abel Cheung <abelcheung@gmail.com>\n"
 "Language-Team: Chinese (traditional) <zh-l10n@linux.org.tw>\n"
@@ -1023,28 +1023,6 @@ msgstr "無法開啟 “%s” 檔案來寫入內容。"
 msgid "No such element or plugin '%s'\n"
 msgstr "URI “%s” 沒有來源元件"
 
-msgid "Usage: gst-xmllaunch <file.xml> [ element.property=value ... ]\n"
-msgstr "用法:gst-xmllaunch <file.xml> [ element.property=value ... ]\n"
-
-#, c-format
-msgid "ERROR: parse of xml file '%s' failed.\n"
-msgstr "錯誤:無法解析 XML 檔案 ‘%s’ 的內容。\n"
-
-#, c-format
-msgid "ERROR: no toplevel pipeline element in file '%s'.\n"
-msgstr ""
-
-msgid "WARNING: only one toplevel element is supported at this time.\n"
-msgstr ""
-
-#, c-format
-msgid "ERROR: could not parse command line argument %d: %s.\n"
-msgstr "錯誤:無法解析指令的第 %d 個參數:%s。\n"
-
-#, c-format
-msgid "WARNING: element named '%s' not found.\n"
-msgstr ""
-
 msgid "Index statistics"
 msgstr ""
 
@@ -1138,18 +1116,9 @@ msgstr "不顯示和 TYPE 有關的狀態資訊"
 msgid "TYPE1,TYPE2,..."
 msgstr "TYPE1,TYPE2,..."
 
-msgid "Save xml representation of pipeline to FILE and exit"
-msgstr "將代表管線的架構儲存至<檔案>,然後結束"
-
-msgid "FILE"
-msgstr "檔案"
-
 msgid "Do not install a fault handler"
 msgstr ""
 
-msgid "Do not install signal handlers for SIGUSR1 and SIGUSR2"
-msgstr ""
-
 msgid "Print alloc trace (if enabled at compile time)"
 msgstr "印出 alloc 追蹤訊息 (如果編譯程式時有啟用這項功能)"
 
@@ -1224,6 +1193,21 @@ msgstr ""
 msgid "Freeing pipeline ...\n"
 msgstr "執行管線 ...\n"
 
+#~ msgid "Usage: gst-xmllaunch <file.xml> [ element.property=value ... ]\n"
+#~ msgstr "用法:gst-xmllaunch <file.xml> [ element.property=value ... ]\n"
+
+#~ msgid "ERROR: parse of xml file '%s' failed.\n"
+#~ msgstr "錯誤:無法解析 XML 檔案 ‘%s’ 的內容。\n"
+
+#~ msgid "ERROR: could not parse command line argument %d: %s.\n"
+#~ msgstr "錯誤:無法解析指令的第 %d 個參數:%s。\n"
+
+#~ msgid "Save xml representation of pipeline to FILE and exit"
+#~ msgstr "將代表管線的架構儲存至<檔案>,然後結束"
+
+#~ msgid "FILE"
+#~ msgstr "檔案"
+
 #~ msgid "Disable accelerated CPU instructions"
 #~ msgstr "關閉 CPU 優化功能"
 
index f0e597f..341e0bd 100644 (file)
@@ -35,7 +35,7 @@ endif
 
 # Do not run the abi test in case any option which causes the API to change has
 # been used
-if !GST_DISABLE_LOADSAVE
+if FALSE
 if !GST_DISABLE_REGISTRY
 if !GST_DISABLE_TRACE
 ABI_CHECKS = gst/gstabi
@@ -43,6 +43,10 @@ endif
 endif
 endif
 
+if FALSE
+LIBSABI_CHECKS = libs/libsabi
+endif
+
 if HAVE_CXX
 CXX_CHECKS = gst/gstcpp libs/gstlibscpp
 else
@@ -97,6 +101,7 @@ check_PROGRAMS =                             \
        $(ABI_CHECKS)                           \
        gst/gstbuffer                           \
        gst/gstbufferlist                       \
+       gst/gstmeta                             \
        gst/gstbus                              \
        gst/gstcaps                             \
        $(CXX_CHECKS)                           \
@@ -120,7 +125,7 @@ check_PROGRAMS =                            \
        generic/states                          \
        $(PARSE_CHECKS)                         \
        $(REGISTRY_CHECKS)                      \
-       libs/libsabi                            \
+       $(LIBSABI_CHECKS)                       \
        libs/gdp                                \
        libs/adapter                            \
        libs/bitreader                          \
index dacf00e..10756f1 100644 (file)
@@ -99,14 +99,19 @@ GST_START_TEST (test_clipping)
 
   /* send segment */
   {
-    GstEvent *segment;
+    GstEvent *event;
+    GstSegment segment;
     gboolean eret;
 
     GST_DEBUG ("sending segment");
-    segment = gst_event_new_new_segment (FALSE,
-        1.0, GST_FORMAT_TIME, 1 * GST_SECOND, 5 * GST_SECOND, 1 * GST_SECOND);
+    gst_segment_init (&segment, GST_FORMAT_TIME);
+    segment.start = 1 * GST_SECOND;
+    segment.stop = 5 * GST_SECOND;
+    segment.time = 1 * GST_SECOND;
+
+    event = gst_event_new_segment (&segment);
 
-    eret = gst_pad_send_event (sinkpad, segment);
+    eret = gst_pad_send_event (sinkpad, event);
     fail_if (eret == FALSE);
   }
 
@@ -258,14 +263,18 @@ GST_START_TEST (test_preroll_sync)
 
   /* send segment */
   {
-    GstEvent *segment;
+    GstEvent *event;
+    GstSegment segment;
     gboolean eret;
 
     GST_DEBUG ("sending segment");
-    segment = gst_event_new_new_segment (FALSE,
-        1.0, GST_FORMAT_TIME, 0 * GST_SECOND, 102 * GST_SECOND, 0 * GST_SECOND);
+    gst_segment_init (&segment, GST_FORMAT_TIME);
+    segment.start = 0 * GST_SECOND;
+    segment.stop = 102 * GST_SECOND;
+    segment.time = 0 * GST_SECOND;
 
-    eret = gst_pad_send_event (sinkpad, segment);
+    event = gst_event_new_segment (&segment);
+    eret = gst_pad_send_event (sinkpad, event);
     fail_if (eret == FALSE);
   }
 
@@ -418,14 +427,18 @@ GST_START_TEST (test_eos)
 
   /* send segment, this should fail */
   {
-    GstEvent *segment;
+    GstEvent *event;
+    GstSegment segment;
     gboolean eret;
 
     GST_DEBUG ("sending segment");
-    segment = gst_event_new_new_segment (FALSE,
-        1.0, GST_FORMAT_TIME, 0 * GST_SECOND, 2 * GST_SECOND, 0 * GST_SECOND);
+    gst_segment_init (&segment, GST_FORMAT_TIME);
+    segment.start = 0 * GST_SECOND;
+    segment.stop = 2 * GST_SECOND;
+    segment.time = 0 * GST_SECOND;
+    event = gst_event_new_segment (&segment);
 
-    eret = gst_pad_send_event (sinkpad, segment);
+    eret = gst_pad_send_event (sinkpad, event);
     fail_if (eret == TRUE);
   }
 
@@ -456,21 +469,25 @@ GST_START_TEST (test_eos)
     fail_unless (eret == TRUE);
 
     GST_DEBUG ("sending FLUSH_STOP");
-    event = gst_event_new_flush_stop ();
+    event = gst_event_new_flush_stop (TRUE);
     eret = gst_pad_send_event (sinkpad, event);
     fail_unless (eret == TRUE);
   }
 
   /* send segment, this should now work again */
   {
-    GstEvent *segment;
+    GstEvent *event;
+    GstSegment segment;
     gboolean eret;
 
     GST_DEBUG ("sending segment");
-    segment = gst_event_new_new_segment (FALSE,
-        1.0, GST_FORMAT_TIME, 0 * GST_SECOND, 2 * GST_SECOND, 0 * GST_SECOND);
+    gst_segment_init (&segment, GST_FORMAT_TIME);
+    segment.start = 0 * GST_SECOND;
+    segment.stop = 2 * GST_SECOND;
+    segment.time = 0 * GST_SECOND;
+    event = gst_event_new_segment (&segment);
 
-    eret = gst_pad_send_event (sinkpad, segment);
+    eret = gst_pad_send_event (sinkpad, event);
     fail_unless (eret == TRUE);
   }
 
@@ -524,14 +541,18 @@ GST_START_TEST (test_eos2)
 
   /* send segment, this should work */
   {
-    GstEvent *segment;
+    GstEvent *event;
+    GstSegment segment;
     gboolean eret;
 
     GST_DEBUG ("sending segment");
-    segment = gst_event_new_new_segment (FALSE,
-        1.0, GST_FORMAT_TIME, 0 * GST_SECOND, 2 * GST_SECOND, 0 * GST_SECOND);
+    gst_segment_init (&segment, GST_FORMAT_TIME);
+    segment.start = 0 * GST_SECOND;
+    segment.stop = 2 * GST_SECOND;
+    segment.time = 0 * GST_SECOND;
+    event = gst_event_new_segment (&segment);
 
-    eret = gst_pad_send_event (sinkpad, segment);
+    eret = gst_pad_send_event (sinkpad, event);
     fail_if (eret == FALSE);
   }
 
@@ -629,9 +650,14 @@ GST_START_TEST (test_position)
 
   /* send segment, this should work */
   {
+    GstSegment segment;
+
     GST_DEBUG ("sending segment");
-    event = gst_event_new_new_segment (FALSE,
-        1.0, GST_FORMAT_TIME, 1 * GST_SECOND, 3 * GST_SECOND, 1 * GST_SECOND);
+    gst_segment_init (&segment, GST_FORMAT_TIME);
+    segment.start = 1 * GST_SECOND;
+    segment.stop = 3 * GST_SECOND;
+    segment.time = 1 * GST_SECOND;
+    event = gst_event_new_segment (&segment);
 
     eret = gst_pad_send_event (sinkpad, event);
     fail_if (eret == FALSE);
@@ -688,7 +714,7 @@ GST_START_TEST (test_position)
   /* stop flushing, timing is affected now */
   {
     GST_DEBUG ("sending flush_stop");
-    event = gst_event_new_flush_stop ();
+    event = gst_event_new_flush_stop (TRUE);
 
     eret = gst_pad_send_event (sinkpad, event);
     fail_if (eret == FALSE);
@@ -701,9 +727,14 @@ GST_START_TEST (test_position)
 
   /* send segment, this should work */
   {
+    GstSegment segment;
+
     GST_DEBUG ("sending segment");
-    event = gst_event_new_new_segment (FALSE,
-        1.0, GST_FORMAT_TIME, 2 * GST_SECOND, 4 * GST_SECOND, 1 * GST_SECOND);
+    gst_segment_init (&segment, GST_FORMAT_TIME);
+    segment.start = 2 * GST_SECOND;
+    segment.stop = 4 * GST_SECOND;
+    segment.time = 1 * GST_SECOND;
+    event = gst_event_new_segment (&segment);
 
     eret = gst_pad_send_event (sinkpad, event);
     fail_if (eret == FALSE);
@@ -771,7 +802,7 @@ GST_START_TEST (test_position)
 
   {
     GST_DEBUG ("sending flush_stop");
-    event = gst_event_new_flush_stop ();
+    event = gst_event_new_flush_stop (TRUE);
 
     eret = gst_pad_send_event (sinkpad, event);
     fail_if (eret == FALSE);
@@ -784,9 +815,14 @@ GST_START_TEST (test_position)
 
   /* send segment, this should work */
   {
+    GstSegment segment;
+
     GST_DEBUG ("sending segment");
-    event = gst_event_new_new_segment (FALSE,
-        1.0, GST_FORMAT_TIME, 2 * GST_SECOND, 4 * GST_SECOND, 1 * GST_SECOND);
+    gst_segment_init (&segment, GST_FORMAT_TIME);
+    segment.start = 2 * GST_SECOND;
+    segment.stop = 4 * GST_SECOND;
+    segment.time = 1 * GST_SECOND;
+    event = gst_event_new_segment (&segment);
 
     eret = gst_pad_send_event (sinkpad, event);
     fail_if (eret == FALSE);
@@ -865,17 +901,7 @@ typedef GstPushSrc OOBSource;
 typedef GstPushSrcClass OOBSourceClass;
 
 GType oob_source_get_type (void);
-GST_BOILERPLATE (OOBSource, oob_source, GstPushSrc, GST_TYPE_PUSH_SRC);
-
-static void
-oob_source_base_init (gpointer g_class)
-{
-  static GstStaticPadTemplate sinktemplate = GST_STATIC_PAD_TEMPLATE ("src",
-      GST_PAD_SRC, GST_PAD_ALWAYS, GST_STATIC_CAPS_ANY);
-
-  gst_element_class_add_pad_template (GST_ELEMENT_CLASS (g_class),
-      gst_static_pad_template_get (&sinktemplate));
-}
+G_DEFINE_TYPE (OOBSource, oob_source, GST_TYPE_PUSH_SRC);
 
 static GstFlowReturn
 oob_source_create (GstPushSrc * src, GstBuffer ** p_buf)
@@ -891,13 +917,19 @@ oob_source_create (GstPushSrc * src, GstBuffer ** p_buf)
 static void
 oob_source_class_init (OOBSourceClass * klass)
 {
+  static GstStaticPadTemplate sinktemplate = GST_STATIC_PAD_TEMPLATE ("src",
+      GST_PAD_SRC, GST_PAD_ALWAYS, GST_STATIC_CAPS_ANY);
+  GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
   GstPushSrcClass *pushsrc_class = GST_PUSH_SRC_CLASS (klass);
 
+  gst_element_class_add_pad_template (element_class,
+      gst_static_pad_template_get (&sinktemplate));
+
   pushsrc_class->create = GST_DEBUG_FUNCPTR (oob_source_create);
 }
 
 static void
-oob_source_init (OOBSource * src, OOBSourceClass * g_class)
+oob_source_init (OOBSource * src)
 {
   /* nothing to do */
 }
index 3573be6..4df128a 100644 (file)
@@ -117,7 +117,7 @@ GST_START_TEST (test_sizetype_empty)
   while (l) {
     GstBuffer *buf = l->data;
 
-    fail_unless (GST_BUFFER_SIZE (buf) == 0);
+    fail_unless (gst_buffer_get_size (buf) == 0);
     l = l->next;
   }
   gst_check_drop_buffers ();
@@ -155,7 +155,7 @@ GST_START_TEST (test_sizetype_fixed)
   while (l) {
     GstBuffer *buf = l->data;
 
-    fail_unless (GST_BUFFER_SIZE (buf) == 8192);
+    fail_unless (gst_buffer_get_size (buf) == 8192);
     l = l->next;
   }
   gst_check_drop_buffers ();
@@ -194,8 +194,8 @@ GST_START_TEST (test_sizetype_random)
   while (l) {
     GstBuffer *buf = l->data;
 
-    fail_if (GST_BUFFER_SIZE (buf) > 8192);
-    fail_if (GST_BUFFER_SIZE (buf) < 4096);
+    fail_if (gst_buffer_get_size (buf) > 8192);
+    fail_if (gst_buffer_get_size (buf) < 4096);
     l = l->next;
   }
   gst_check_drop_buffers ();
index 3188a7f..99e5e2d 100644 (file)
@@ -87,9 +87,12 @@ cleanup_filesink (GstElement * filesink)
     G_STMT_START {                                                        \
       GstBuffer *buf = gst_buffer_new_and_alloc(num_bytes);               \
       GRand *rand = g_rand_new_with_seed (num_bytes);                     \
+      guint8 *data;                                                       \
       guint i;                                                            \
+      data = gst_buffer_map (buf, NULL, NULL, GST_MAP_WRITE);             \
       for (i = 0; i < num_bytes; ++i)                                     \
-        GST_BUFFER_DATA(buf)[i] = (g_rand_int (rand) >> 24) & 0xff;       \
+        data[i] = (g_rand_int (rand) >> 24) & 0xff;                       \
+      gst_buffer_unmap (buf, data, num_bytes);                            \
       fail_unless_equals_int (gst_pad_push (mysrcpad, buf), GST_FLOW_OK); \
       g_rand_free (rand);                                                 \
     } G_STMT_END
@@ -102,6 +105,7 @@ GST_START_TEST (test_seeking)
   GstElement *filesink;
   gchar *tmp_fn;
   gint fd;
+  GstSegment segment;
 
   tmpdir = g_get_tmp_dir ();
   if (tmpdir == NULL)
@@ -141,8 +145,8 @@ GST_START_TEST (test_seeking)
   gst_query_unref (seeking_query);
 #endif
 
-  fail_unless (gst_pad_push_event (mysrcpad,
-          gst_event_new_new_segment (FALSE, 1.0, GST_FORMAT_BYTES, 0, -1, 0)));
+  gst_segment_init (&segment, GST_FORMAT_BYTES);
+  fail_unless (gst_pad_push_event (mysrcpad, gst_event_new_segment (&segment)));
 
   CHECK_QUERY_POSITION (filesink, GST_FORMAT_BYTES, 0);
 
@@ -159,9 +163,8 @@ GST_START_TEST (test_seeking)
   PUSH_BYTES (8800);
   CHECK_QUERY_POSITION (filesink, GST_FORMAT_BYTES, 8900);
 
-  if (gst_pad_push_event (mysrcpad,
-          gst_event_new_new_segment (TRUE, 1.0, GST_FORMAT_BYTES, 8800, -1,
-              0))) {
+  segment.start = 8800;
+  if (gst_pad_push_event (mysrcpad, gst_event_new_segment (&segment))) {
     GST_LOG ("seek ok");
     /* make sure that that new position is reported immediately */
     CHECK_QUERY_POSITION (filesink, GST_FORMAT_BYTES, 8800);
index 970ca9a..4c98962 100644 (file)
@@ -171,6 +171,8 @@ GST_START_TEST (test_pull)
   GstPad *pad;
   GstFlowReturn ret;
   GstBuffer *buffer1, *buffer2;
+  guint8 *data1, *data2;
+  gsize size1, size2;
 
   src = setup_filesrc ();
 
@@ -208,16 +210,18 @@ GST_START_TEST (test_pull)
   ret = gst_pad_get_range (pad, 0, 100, &buffer1);
   fail_unless (ret == GST_FLOW_OK);
   fail_unless (buffer1 != NULL);
-  fail_unless (GST_BUFFER_SIZE (buffer1) == 100);
+  fail_unless (gst_buffer_get_size (buffer1) == 100);
 
   ret = gst_pad_get_range (pad, 0, 50, &buffer2);
   fail_unless (ret == GST_FLOW_OK);
   fail_unless (buffer2 != NULL);
-  fail_unless (GST_BUFFER_SIZE (buffer2) == 50);
+  fail_unless (gst_buffer_get_size (buffer2) == 50);
 
   /* this should be the same */
-  fail_unless (memcmp (GST_BUFFER_DATA (buffer1), GST_BUFFER_DATA (buffer2),
-          50) == 0);
+  data1 = gst_buffer_map (buffer1, &size1, NULL, GST_MAP_READ);
+  data2 = gst_buffer_map (buffer2, &size2, NULL, GST_MAP_READ);
+  fail_unless (memcmp (data1, data2, 50) == 0);
+  gst_buffer_unmap (buffer2, data2, size2);
 
   gst_buffer_unref (buffer2);
 
@@ -225,12 +229,14 @@ GST_START_TEST (test_pull)
   ret = gst_pad_get_range (pad, 50, 50, &buffer2);
   fail_unless (ret == GST_FLOW_OK);
   fail_unless (buffer2 != NULL);
-  fail_unless (GST_BUFFER_SIZE (buffer2) == 50);
+  fail_unless (gst_buffer_get_size (buffer2) == 50);
 
   /* compare with previously read data */
-  fail_unless (memcmp (GST_BUFFER_DATA (buffer1) + 50,
-          GST_BUFFER_DATA (buffer2), 50) == 0);
+  data2 = gst_buffer_map (buffer2, &size2, NULL, GST_MAP_READ);
+  fail_unless (memcmp (data1 + 50, data2, 50) == 0);
+  gst_buffer_unmap (buffer2, data2, size2);
 
+  gst_buffer_unmap (buffer1, data1, size1);
   gst_buffer_unref (buffer1);
   gst_buffer_unref (buffer2);
 
@@ -238,28 +244,28 @@ GST_START_TEST (test_pull)
   ret = gst_pad_get_range (pad, stop - 10, 10, &buffer1);
   fail_unless (ret == GST_FLOW_OK);
   fail_unless (buffer1 != NULL);
-  fail_unless (GST_BUFFER_SIZE (buffer1) == 10);
+  fail_unless (gst_buffer_get_size (buffer1) == 10);
   gst_buffer_unref (buffer1);
 
   /* read 20 bytes at end-10 should give exactly 10 bytes */
   ret = gst_pad_get_range (pad, stop - 10, 20, &buffer1);
   fail_unless (ret == GST_FLOW_OK);
   fail_unless (buffer1 != NULL);
-  fail_unless (GST_BUFFER_SIZE (buffer1) == 10);
+  fail_unless (gst_buffer_get_size (buffer1) == 10);
   gst_buffer_unref (buffer1);
 
   /* read 0 bytes at end-1 should return 0 bytes */
   ret = gst_pad_get_range (pad, stop - 1, 0, &buffer1);
   fail_unless (ret == GST_FLOW_OK);
   fail_unless (buffer1 != NULL);
-  fail_unless (GST_BUFFER_SIZE (buffer1) == 0);
+  fail_unless (gst_buffer_get_size (buffer1) == 0);
   gst_buffer_unref (buffer1);
 
   /* read 10 bytes at end-1 should return 1 byte */
   ret = gst_pad_get_range (pad, stop - 1, 10, &buffer1);
   fail_unless (ret == GST_FLOW_OK);
   fail_unless (buffer1 != NULL);
-  fail_unless (GST_BUFFER_SIZE (buffer1) == 1);
+  fail_unless (gst_buffer_get_size (buffer1) == 1);
   gst_buffer_unref (buffer1);
 
   /* read 0 bytes at end should EOS */
index 3e0c589..5703dd3 100644 (file)
@@ -34,8 +34,7 @@ struct TestData
 };
 
 static void
-setup_test_objects (struct TestData *td, GstPadChainFunction chain_func,
-    GstPadBufferAllocFunction alloc_func)
+setup_test_objects (struct TestData *td, GstPadChainFunction chain_func)
 {
   td->mycaps = gst_caps_new_simple ("test/test", NULL);
 
@@ -57,7 +56,6 @@ setup_test_objects (struct TestData *td, GstPadChainFunction chain_func,
 
   td->mysink = gst_pad_new ("sink", GST_PAD_SINK);
   gst_pad_set_chain_function (td->mysink, chain_func);
-  gst_pad_set_bufferalloc_function (td->mysink, alloc_func);
   gst_pad_set_active (td->mysink, TRUE);
   gst_pad_set_caps (td->mysink, td->mycaps);
 
@@ -117,29 +115,15 @@ chain_ok (GstPad * pad, GstBuffer * buffer)
   return GST_FLOW_OK;
 }
 
-static GstFlowReturn
-alloc_ok (GstPad * pad,
-    guint64 offset, guint size, GstCaps * caps, GstBuffer ** buffer)
-{
-  alloccount++;
-
-  fail_unless (buffer != NULL);
-  fail_unless (*buffer == NULL);
-
-  *buffer = gst_buffer_new_and_alloc (size);
-  gst_buffer_set_caps (*buffer, caps);
-  GST_BUFFER_OFFSET (*buffer) = offset;
-
-  return GST_FLOW_OK;
-}
-
 GST_START_TEST (test_funnel_simple)
 {
   struct TestData td;
+#if 0
   GstBuffer *buf1 = NULL;
   GstBuffer *buf2 = NULL;
+#endif
 
-  setup_test_objects (&td, chain_ok, alloc_ok);
+  setup_test_objects (&td, chain_ok);
 
   bufcount = 0;
   alloccount = 0;
@@ -149,6 +133,7 @@ GST_START_TEST (test_funnel_simple)
 
   fail_unless (bufcount == 2);
 
+#if 0
   fail_unless (gst_pad_alloc_buffer (td.mysrc1, 0, 1024, td.mycaps,
           &buf1) == GST_FLOW_OK);
   fail_unless (gst_pad_alloc_buffer (td.mysrc2, 1024, 1024, td.mycaps,
@@ -158,6 +143,7 @@ GST_START_TEST (test_funnel_simple)
 
   gst_buffer_unref (buf1);
   gst_buffer_unref (buf2);
+#endif
 
   release_test_objects (&td);
 }
index b845466..abf428c 100644 (file)
@@ -87,6 +87,7 @@ GST_START_TEST (test_one_buffer)
 {
   GstElement *identity;
   GstBuffer *buffer;
+  gpointer data;
 
   identity = setup_identity ();
   fail_unless (gst_element_set_state (identity,
@@ -95,7 +96,10 @@ GST_START_TEST (test_one_buffer)
 
   buffer = gst_buffer_new_and_alloc (4);
   ASSERT_BUFFER_REFCOUNT (buffer, "buffer", 1);
-  memcpy (GST_BUFFER_DATA (buffer), "data", 4);
+
+  data = gst_buffer_map (buffer, NULL, NULL, GST_MAP_WRITE);
+  memcpy (data, "data", 4);
+  gst_buffer_unmap (buffer, data, 4);
 
   /* pushing gives away my reference ... */
   fail_unless (gst_pad_push (mysrcpad, buffer) == GST_FLOW_OK,
index a3d2782..34a3380 100644 (file)
@@ -290,9 +290,9 @@ GST_START_TEST (test_request_pads_named)
 GST_END_TEST;
 
 static GstCaps *
-mq_dummypad_getcaps (GstPad * sinkpad)
+mq_dummypad_getcaps (GstPad * sinkpad, GstCaps * filter)
 {
-  return gst_caps_new_any ();
+  return (filter ? gst_caps_ref (filter) : gst_caps_new_any ());
 }
 
 struct PadData
@@ -313,6 +313,8 @@ mq_dummypad_chain (GstPad * sinkpad, GstBuffer * buf)
 {
   guint32 cur_id;
   struct PadData *pad_data;
+  guint8 *data;
+  gsize size;
 
   pad_data = gst_pad_get_element_private (sinkpad);
 
@@ -320,9 +322,11 @@ mq_dummypad_chain (GstPad * sinkpad, GstBuffer * buf)
   fail_if (pad_data == NULL);
   /* Read an ID from the first 4 bytes of the buffer data and check it's
    * what we expect */
-  fail_unless (GST_BUFFER_SIZE (buf) >= 4);
+  data = gst_buffer_map (buf, &size, NULL, GST_MAP_READ);
+  fail_unless (size >= 4);
   g_static_mutex_unlock (&_check_lock);
-  cur_id = GST_READ_UINT32_BE (GST_BUFFER_DATA (buf));
+  cur_id = GST_READ_UINT32_BE (data);
+  gst_buffer_unmap (buf, data, size);
 
   g_mutex_lock (pad_data->mutex);
 
@@ -475,6 +479,7 @@ run_output_order_test (gint n_linked)
     guint8 cur_pad;
     GstBuffer *buf;
     GstFlowReturn ret;
+    gpointer data;
 
     cur_pad = pad_pattern[i % n];
 
@@ -482,7 +487,10 @@ run_output_order_test (gint n_linked)
     g_static_mutex_lock (&_check_lock);
     fail_if (buf == NULL);
     g_static_mutex_unlock (&_check_lock);
-    GST_WRITE_UINT32_BE (GST_BUFFER_DATA (buf), i + 1);
+
+    data = gst_buffer_map (buf, NULL, NULL, GST_MAP_WRITE);
+    GST_WRITE_UINT32_BE (data, i + 1);
+    gst_buffer_unmap (buf, data, 4);
     GST_BUFFER_TIMESTAMP (buf) = (i + 1) * GST_SECOND;
 
     ret = gst_pad_push (inputpads[cur_pad], buf);
@@ -554,6 +562,7 @@ GST_START_TEST (test_sparse_stream)
   GCond *cond;
   gint i;
   const gint NBUFFERS = 100;
+  GstSegment segment;
 
   mutex = g_mutex_new ();
   cond = g_cond_new ();
@@ -620,7 +629,8 @@ GST_START_TEST (test_sparse_stream)
   gst_element_set_state (pipe, GST_STATE_PLAYING);
 
   /* Push 2 new segment events */
-  event = gst_event_new_new_segment (FALSE, 1.0, GST_FORMAT_TIME, 0, -1, 0);
+  gst_segment_init (&segment, GST_FORMAT_TIME);
+  event = gst_event_new_segment (&segment);
   gst_pad_push_event (inputpads[0], gst_event_ref (event));
   gst_pad_push_event (inputpads[1], event);
 
@@ -628,6 +638,7 @@ GST_START_TEST (test_sparse_stream)
     GstBuffer *buf;
     GstFlowReturn ret;
     GstClockTime ts;
+    gpointer data;
 
     ts = gst_util_uint64_scale_int (GST_SECOND, i, 10);
 
@@ -635,7 +646,11 @@ GST_START_TEST (test_sparse_stream)
     g_static_mutex_lock (&_check_lock);
     fail_if (buf == NULL);
     g_static_mutex_unlock (&_check_lock);
-    GST_WRITE_UINT32_BE (GST_BUFFER_DATA (buf), i + 1);
+
+    data = gst_buffer_map (buf, NULL, NULL, GST_MAP_WRITE);
+    GST_WRITE_UINT32_BE (data, i + 1);
+    gst_buffer_unmap (buf, data, 4);
+
     GST_BUFFER_TIMESTAMP (buf) = gst_util_uint64_scale_int (GST_SECOND, i, 10);
 
     /* If i == 0, also push the buffer to the 2nd pad */
@@ -649,7 +664,10 @@ GST_START_TEST (test_sparse_stream)
     g_static_mutex_unlock (&_check_lock);
 
     /* Push a new segment update on the 2nd pad */
-    event = gst_event_new_new_segment (TRUE, 1.0, GST_FORMAT_TIME, ts, -1, ts);
+    gst_segment_init (&segment, GST_FORMAT_TIME);
+    segment.start = ts;
+    segment.time = ts;
+    event = gst_event_new_segment (&segment);
     gst_pad_push_event (inputpads[1], event);
   }
 
index 3a6e4e4..dbede1a 100644 (file)
@@ -541,6 +541,7 @@ GST_START_TEST (test_time_level_task_not_started)
 {
   GstEvent *event;
   GstClockTime time;
+  GstSegment segment;
 
   GST_DEBUG ("starting");
 
@@ -548,15 +549,19 @@ GST_START_TEST (test_time_level_task_not_started)
           GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS,
       "could not set to playing");
 
-  event = gst_event_new_new_segment (TRUE, 1.0, GST_FORMAT_TIME,
-      1 * GST_SECOND, 5 * GST_SECOND, 0);
+  gst_segment_init (&segment, GST_FORMAT_TIME);
+  segment.start = 1 * GST_SECOND;
+  segment.stop = 5 * GST_SECOND;
+  segment.time = 0;
+
+  event = gst_event_new_segment (&segment);
   gst_pad_push_event (mysrcpad, event);
 
   g_object_get (G_OBJECT (queue), "current-level-time", &time, NULL);
   fail_if (time != 0 * GST_SECOND);
 
-  event = gst_event_new_new_segment (FALSE, 1.0, GST_FORMAT_TIME,
-      1 * GST_SECOND, 5 * GST_SECOND, 0);
+  segment.base = 4 * GST_SECOND;
+  event = gst_event_new_segment (&segment);
   gst_pad_push_event (mysrcpad, event);
 
   g_object_get (G_OBJECT (queue), "current-level-time", &time, NULL);
@@ -569,23 +574,24 @@ GST_START_TEST (test_time_level_task_not_started)
 
 GST_END_TEST;
 
+#if 0
 static gboolean
 event_equals_newsegment (GstEvent * event, gboolean update, gdouble rate,
     GstFormat format, gint64 start, gint64 stop, gint64 position)
 {
   gboolean ns_update;
-  gdouble ns_rate;
+  gdouble ns_rate, ns_arate;
   GstFormat ns_format;
   gint64 ns_start;
   gint64 ns_stop;
   gint64 ns_position;
 
-  if (GST_EVENT_TYPE (event) != GST_EVENT_NEWSEGMENT) {
+  if (GST_EVENT_TYPE (event) != GST_EVENT_SEGMENT) {
     return FALSE;
   }
 
-  gst_event_parse_new_segment (event, &ns_update, &ns_rate, &ns_format,
-      &ns_start, &ns_stop, &ns_position);
+  gst_event_parse_new_segment (event, &ns_update, &ns_rate, &ns_arate,
+      &ns_format, &ns_start, &ns_stop, &ns_position);
 
   GST_DEBUG ("update %d, rate %lf, format %s, start %" GST_TIME_FORMAT
       ", stop %" GST_TIME_FORMAT ", position %" GST_TIME_FORMAT, ns_update,
@@ -615,7 +621,7 @@ GST_START_TEST (test_newsegment)
   fail_unless (overrun_count == 0);
   fail_unless (underrun_count == 0);
 
-  event = gst_event_new_new_segment (FALSE, 2.0, GST_FORMAT_TIME, 0,
+  event = gst_event_new_new_segment (FALSE, 2.0, 1.0, GST_FORMAT_TIME, 0,
       2 * GST_SECOND, 0);
   gst_pad_push_event (mysrcpad, event);
 
@@ -623,7 +629,7 @@ GST_START_TEST (test_newsegment)
   fail_unless (overrun_count == 0);
   fail_unless (underrun_count == 0);
 
-  event = gst_event_new_new_segment (FALSE, 1.0, GST_FORMAT_TIME, 0,
+  event = gst_event_new_new_segment (FALSE, 1.0, 1.0, GST_FORMAT_TIME, 0,
       3 * GST_SECOND, 0);
   gst_pad_push_event (mysrcpad, event);
 
@@ -631,7 +637,7 @@ GST_START_TEST (test_newsegment)
   fail_unless (overrun_count == 0);
   fail_unless (underrun_count == 0);
 
-  event = gst_event_new_new_segment (FALSE, 1.0, GST_FORMAT_TIME,
+  event = gst_event_new_new_segment (FALSE, 1.0, 1.0, GST_FORMAT_TIME,
       4 * GST_SECOND, 5 * GST_SECOND, 4 * GST_SECOND);
   gst_pad_push_event (mysrcpad, event);
 
@@ -692,6 +698,7 @@ GST_START_TEST (test_newsegment)
 }
 
 GST_END_TEST;
+#endif
 
 static Suite *
 queue_suite (void)
@@ -707,7 +714,9 @@ queue_suite (void)
   tcase_add_test (tc_chain, test_leaky_downstream);
   tcase_add_test (tc_chain, test_time_level);
   tcase_add_test (tc_chain, test_time_level_task_not_started);
+#if 0
   tcase_add_test (tc_chain, test_newsegment);
+#endif
 
   return s;
 }
index e210a11..b4fee5d 100644 (file)
@@ -34,8 +34,9 @@ static GstStaticPadTemplate srctemplate = GST_STATIC_PAD_TEMPLATE ("src",
     GST_STATIC_CAPS_ANY);
 
 /* Data probe cb to drop everything but count buffers and events */
-static gboolean
-probe_cb (GstPad * pad, GstMiniObject * obj, gpointer user_data)
+static GstProbeReturn
+probe_cb (GstPad * pad, GstProbeType type, GstMiniObject * obj,
+    gpointer user_data)
 {
   gint count = 0;
   const gchar *count_type = NULL;
@@ -56,7 +57,7 @@ probe_cb (GstPad * pad, GstMiniObject * obj, gpointer user_data)
   g_object_set_data (G_OBJECT (pad), count_type, GINT_TO_POINTER (count));
 
   /* drop everything */
-  return FALSE;
+  return GST_PROBE_DROP;
 }
 
 /* Create and link output pad: selector:src%d ! output_pad */
@@ -74,7 +75,9 @@ setup_output_pad (GstElement * element, GstStaticPadTemplate * tmpl)
   fail_if (output_pad == NULL, "Could not create a output_pad");
 
   /* add probe */
-  probe_id = gst_pad_add_data_probe (output_pad, G_CALLBACK (probe_cb), NULL);
+  probe_id =
+      gst_pad_add_probe (output_pad, GST_PROBE_TYPE_DATA,
+      (GstPadProbeCallback) probe_cb, NULL, NULL);
   g_object_set_data (G_OBJECT (output_pad), "probe_id",
       GINT_TO_POINTER (probe_id));
 
@@ -110,7 +113,7 @@ cleanup_pad (GstPad * pad, GstElement * element)
   /* remove probe if necessary */
   probe_id = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (pad), "probe_id"));
   if (probe_id)
-    gst_pad_remove_data_probe (pad, probe_id);
+    gst_pad_remove_probe (pad, probe_id);
 
   /* unlink */
   selpad = gst_pad_get_peer (pad);
@@ -120,9 +123,6 @@ cleanup_pad (GstPad * pad, GstElement * element)
     gst_pad_unlink (pad, selpad);
   }
 
-  /* caps could have been set, make sure they get unset */
-  gst_pad_set_caps (pad, NULL);
-
   GST_DEBUG_OBJECT (pad, "clean up %" GST_PTR_FORMAT " and  %" GST_PTR_FORMAT,
       selpad, pad);
 
@@ -211,8 +211,6 @@ push_switched_buffers (GList * input_pads,
   /* setup dummy buffer */
   caps = gst_caps_from_string ("application/x-unknown");
   buf = gst_buffer_new_and_alloc (1);
-  gst_buffer_set_caps (buf, caps);
-  gst_caps_unref (caps);
 
   while (l != NULL) {
     /* set selector pad */
@@ -229,6 +227,7 @@ push_switched_buffers (GList * input_pads,
 
   /* cleanup buffer */
   gst_buffer_unref (buf);
+  gst_caps_unref (caps);
 }
 
 /* Create output-selector with given number of src pads and switch
@@ -317,7 +316,9 @@ run_input_selector_buffer_count (gint num_input_pads,
     input_pads = g_list_append (input_pads, setup_input_pad (sel));
   }
   /* add probe */
-  probe_id = gst_pad_add_data_probe (output_pad, G_CALLBACK (probe_cb), NULL);
+  probe_id =
+      gst_pad_add_probe (output_pad, GST_PROBE_TYPE_DATA,
+      (GstPadProbeCallback) probe_cb, NULL, NULL);
   g_object_set_data (G_OBJECT (output_pad), "probe_id",
       GINT_TO_POINTER (probe_id));
 
@@ -331,7 +332,7 @@ run_input_selector_buffer_count (gint num_input_pads,
           GST_STATE_NULL) == GST_STATE_CHANGE_SUCCESS, "could not set to null");
 
   /* clean up */
-  gst_pad_remove_data_probe (output_pad, probe_id);
+  gst_pad_remove_probe (output_pad, probe_id);
   gst_pad_set_active (output_pad, FALSE);
   gst_check_teardown_sink_pad (sel);
   GST_DEBUG ("setting selector pad to NULL");
@@ -396,7 +397,7 @@ GST_START_TEST (test_output_selector_no_srcpad_negotiation);
      * setcaps should accept any caps when there are no srcpads */
     g_object_set (sel, "pad-negotiation-mode", i, NULL);
 
-    caps = gst_pad_get_caps (pad);
+    caps = gst_pad_get_caps (pad, NULL);
     fail_unless (gst_caps_is_any (caps));
 
     gst_caps_unref (caps);
@@ -473,7 +474,7 @@ GST_START_TEST (test_output_selector_getcaps_none);
 
     g_object_set (sel, "active-pad", pad, NULL);
 
-    caps = gst_pad_peer_get_caps (input_pad);
+    caps = gst_pad_peer_get_caps (input_pad, NULL);
 
     /* in 'none' mode, the getcaps returns the template, which is ANY */
     g_assert (gst_caps_is_any (caps));
@@ -513,7 +514,7 @@ GST_START_TEST (test_output_selector_getcaps_all);
 
     g_object_set (sel, "active-pad", pad, NULL);
 
-    caps = gst_pad_peer_get_caps (input_pad);
+    caps = gst_pad_peer_get_caps (input_pad, NULL);
 
     g_assert (gst_caps_is_equal (caps, expected));
     gst_caps_unref (caps);
@@ -554,10 +555,11 @@ GST_START_TEST (test_output_selector_getcaps_active);
 
     expected = gst_pad_template_get_caps (gst_pad_get_pad_template ((GstPad *)
             walker->data));
-    caps = gst_pad_peer_get_caps (input_pad);
+    caps = gst_pad_peer_get_caps (input_pad, NULL);
 
     g_assert (gst_caps_is_equal (caps, expected));
     gst_caps_unref (caps);
+    gst_caps_unref (expected);
     gst_object_unref (pad);
   }
 
index e0fed0f..dc0847f 100644 (file)
@@ -166,10 +166,6 @@ GST_START_TEST (test_stress)
 
 GST_END_TEST;
 
-static GstFlowReturn
-final_sinkpad_bufferalloc (GstPad * pad, guint64 offset, guint size,
-    GstCaps * caps, GstBuffer ** buf);
-
 typedef struct
 {
   GstElement *tee;
@@ -199,8 +195,8 @@ buffer_alloc_harness_setup (BufferAllocHarness * h, gint countdown)
 
   h->start_srcpad = gst_pad_new ("src", GST_PAD_SRC);
   fail_if (h->start_srcpad == NULL);
-  fail_unless (gst_pad_set_caps (h->start_srcpad, h->caps) == TRUE);
   fail_unless (gst_pad_set_active (h->start_srcpad, TRUE) == TRUE);
+  fail_unless (gst_pad_set_caps (h->start_srcpad, h->caps) == TRUE);
 
   h->tee_sinkpad = gst_element_get_static_pad (h->tee, "sink");
   fail_if (h->tee_sinkpad == NULL);
@@ -210,10 +206,8 @@ buffer_alloc_harness_setup (BufferAllocHarness * h, gint countdown)
 
   h->final_sinkpad = gst_pad_new ("sink", GST_PAD_SINK);
   fail_if (h->final_sinkpad == NULL);
-  gst_pad_set_bufferalloc_function (h->final_sinkpad,
-      final_sinkpad_bufferalloc);
-  fail_unless (gst_pad_set_caps (h->final_sinkpad, h->caps) == TRUE);
   fail_unless (gst_pad_set_active (h->final_sinkpad, TRUE) == TRUE);
+  fail_unless (gst_pad_set_caps (h->final_sinkpad, h->caps) == TRUE);
   g_object_set_qdata (G_OBJECT (h->final_sinkpad),
       g_quark_from_static_string ("buffer-alloc-harness"), h);
 
@@ -226,7 +220,8 @@ buffer_alloc_harness_setup (BufferAllocHarness * h, gint countdown)
 static void
 buffer_alloc_harness_teardown (BufferAllocHarness * h)
 {
-  g_thread_join (h->app_thread);
+  if (h->app_thread)
+    g_thread_join (h->app_thread);
 
   gst_pad_set_active (h->final_sinkpad, FALSE);
   gst_object_unref (h->final_sinkpad);
@@ -238,6 +233,7 @@ buffer_alloc_harness_teardown (BufferAllocHarness * h)
   gst_check_teardown_element (h->tee);
 }
 
+#if 0
 static gpointer
 app_thread_func (gpointer data)
 {
@@ -261,7 +257,9 @@ app_thread_func (gpointer data)
 
   return NULL;
 }
+#endif
 
+#if 0
 static GstFlowReturn
 final_sinkpad_bufferalloc (GstPad * pad, guint64 offset, guint size,
     GstCaps * caps, GstBuffer ** buf)
@@ -304,20 +302,16 @@ final_sinkpad_bufferalloc (GstPad * pad, guint64 offset, guint size,
 
   return GST_FLOW_OK;
 }
+#endif
 
 /* Simulate an app releasing the pad while the first alloc_buffer() is in
  * progress. */
 GST_START_TEST (test_release_while_buffer_alloc)
 {
   BufferAllocHarness h;
-  GstBuffer *buf;
 
   buffer_alloc_harness_setup (&h, 1);
 
-  fail_unless_equals_int (gst_pad_alloc_buffer (h.start_srcpad, 0, 1, h.caps,
-          &buf), GST_FLOW_OK);
-  gst_buffer_unref (buf);
-
   buffer_alloc_harness_teardown (&h);
 }
 
@@ -328,18 +322,9 @@ GST_END_TEST;
 GST_START_TEST (test_release_while_second_buffer_alloc)
 {
   BufferAllocHarness h;
-  GstBuffer *buf;
 
   buffer_alloc_harness_setup (&h, 2);
 
-  fail_unless_equals_int (gst_pad_alloc_buffer (h.start_srcpad, 0, 1, h.caps,
-          &buf), GST_FLOW_OK);
-  gst_buffer_unref (buf);
-
-  fail_unless_equals_int (gst_pad_alloc_buffer (h.start_srcpad, 0, 1, h.caps,
-          &buf), GST_FLOW_OK);
-  gst_buffer_unref (buf);
-
   buffer_alloc_harness_teardown (&h);
 }
 
@@ -352,7 +337,9 @@ GST_START_TEST (test_internal_links)
   GstPad *sinkpad, *srcpad1, *srcpad2;
   GstIterator *it;
   GstIteratorResult res;
-  gpointer val1, val2;
+  GValue val1 = { 0, }
+  , val2 = {
+  0,};
 
   tee = gst_check_setup_element ("tee");
 
@@ -362,10 +349,9 @@ GST_START_TEST (test_internal_links)
   fail_unless (it != NULL);
 
   /* iterator should not return anything */
-  val1 = NULL;
   res = gst_iterator_next (it, &val1);
   fail_unless (res == GST_ITERATOR_DONE);
-  fail_unless (val1 == NULL);
+  fail_unless (g_value_get_object (&val1) == NULL);
 
   srcpad1 = gst_element_get_request_pad (tee, "src%d");
   fail_unless (srcpad1 != NULL);
@@ -373,20 +359,19 @@ GST_START_TEST (test_internal_links)
   /* iterator should resync */
   res = gst_iterator_next (it, &val1);
   fail_unless (res == GST_ITERATOR_RESYNC);
-  fail_unless (val1 == NULL);
+  fail_unless (g_value_get_object (&val1) == NULL);
   gst_iterator_resync (it);
 
   /* we should get something now */
   res = gst_iterator_next (it, &val1);
   fail_unless (res == GST_ITERATOR_OK);
-  fail_unless (GST_PAD_CAST (val1) == srcpad1);
+  fail_unless (GST_PAD_CAST (g_value_get_object (&val1)) == srcpad1);
 
-  gst_object_unref (val1);
+  g_value_reset (&val1);
 
-  val1 = NULL;
   res = gst_iterator_next (it, &val1);
   fail_unless (res == GST_ITERATOR_DONE);
-  fail_unless (val1 == NULL);
+  fail_unless (g_value_get_object (&val1) == NULL);
 
   srcpad2 = gst_element_get_request_pad (tee, "src%d");
   fail_unless (srcpad2 != NULL);
@@ -394,28 +379,27 @@ GST_START_TEST (test_internal_links)
   /* iterator should resync */
   res = gst_iterator_next (it, &val1);
   fail_unless (res == GST_ITERATOR_RESYNC);
-  fail_unless (val1 == NULL);
+  fail_unless (g_value_get_object (&val1) == NULL);
   gst_iterator_resync (it);
 
   /* we should get one of the 2 pads now */
   res = gst_iterator_next (it, &val1);
   fail_unless (res == GST_ITERATOR_OK);
-  fail_unless (GST_PAD_CAST (val1) == srcpad1
-      || GST_PAD_CAST (val1) == srcpad2);
+  fail_unless (GST_PAD_CAST (g_value_get_object (&val1)) == srcpad1
+      || GST_PAD_CAST (g_value_get_object (&val1)) == srcpad2);
 
   /* and the other */
   res = gst_iterator_next (it, &val2);
   fail_unless (res == GST_ITERATOR_OK);
-  fail_unless (GST_PAD_CAST (val2) == srcpad1
-      || GST_PAD_CAST (val2) == srcpad2);
-  fail_unless (val1 != val2);
-  gst_object_unref (val1);
-  gst_object_unref (val2);
+  fail_unless (GST_PAD_CAST (g_value_get_object (&val2)) == srcpad1
+      || GST_PAD_CAST (g_value_get_object (&val2)) == srcpad2);
+  fail_unless (g_value_get_object (&val1) != g_value_get_object (&val2));
+  g_value_reset (&val1);
+  g_value_reset (&val2);
 
-  val1 = NULL;
   res = gst_iterator_next (it, &val1);
   fail_unless (res == GST_ITERATOR_DONE);
-  fail_unless (val1 == NULL);
+  fail_unless (g_value_get_object (&val1) == NULL);
 
   gst_iterator_free (it);
 
@@ -425,8 +409,8 @@ GST_START_TEST (test_internal_links)
 
   res = gst_iterator_next (it, &val1);
   fail_unless (res == GST_ITERATOR_OK);
-  fail_unless (GST_PAD_CAST (val1) == sinkpad);
-  gst_object_unref (val1);
+  fail_unless (GST_PAD_CAST (g_value_get_object (&val1)) == sinkpad);
+  g_value_reset (&val1);
 
   res = gst_iterator_next (it, &val1);
   fail_unless (res == GST_ITERATOR_DONE);
@@ -437,12 +421,14 @@ GST_START_TEST (test_internal_links)
 
   res = gst_iterator_next (it, &val1);
   fail_unless (res == GST_ITERATOR_OK);
-  fail_unless (GST_PAD_CAST (val1) == sinkpad);
-  gst_object_unref (val1);
+  fail_unless (GST_PAD_CAST (g_value_get_object (&val1)) == sinkpad);
+  g_value_reset (&val1);
 
   res = gst_iterator_next (it, &val1);
   fail_unless (res == GST_ITERATOR_DONE);
 
+  g_value_unset (&val1);
+  g_value_unset (&val2);
   gst_iterator_free (it);
   gst_object_unref (srcpad1);
   gst_object_unref (srcpad2);
@@ -485,17 +471,23 @@ GST_START_TEST (test_flow_aggregation)
   teesrc2 = gst_element_get_request_pad (tee, "src%d");
   fail_unless (teesrc2 != NULL);
 
+  GST_DEBUG ("Creating mysink1");
   mysink1 = gst_pad_new ("mysink1", GST_PAD_SINK);
+  gst_pad_set_chain_function (mysink1, _fake_chain);
+  gst_pad_set_active (mysink1, TRUE);
   gst_pad_set_caps (mysink1, caps);
+
+  GST_DEBUG ("Creating mysink2");
   mysink2 = gst_pad_new ("mysink2", GST_PAD_SINK);
+  gst_pad_set_chain_function (mysink2, _fake_chain);
+  gst_pad_set_active (mysink2, TRUE);
   gst_pad_set_caps (mysink2, caps);
+
+  GST_DEBUG ("Creating mysrc");
   mysrc = gst_pad_new ("mysrc", GST_PAD_SRC);
+  gst_pad_set_active (mysrc, TRUE);
   gst_pad_set_caps (mysrc, caps);
 
-  gst_pad_set_chain_function (mysink1, _fake_chain);
-  gst_pad_set_active (mysink1, TRUE);
-  gst_pad_set_chain_function (mysink2, _fake_chain);
-  gst_pad_set_active (mysink2, TRUE);
 
   fail_unless (gst_pad_link (mysrc, teesink) == GST_PAD_LINK_OK);
   fail_unless (gst_pad_link (teesrc1, mysink1) == GST_PAD_LINK_OK);
@@ -505,59 +497,77 @@ GST_START_TEST (test_flow_aggregation)
           GST_STATE_PLAYING) == GST_STATE_CHANGE_SUCCESS);
 
   buffer = gst_buffer_new ();
+#if 0
   gst_buffer_set_caps (buffer, caps);
+#endif
 
+  GST_DEBUG ("Try to push a buffer");
   /* First check if everything works in normal state */
   fail_unless (gst_pad_push (mysrc, gst_buffer_ref (buffer)) == GST_FLOW_OK);
 
   /* One pad being in wrong state must result in wrong state */
+  GST_DEBUG ("Trying to push with mysink2 disabled");
   gst_pad_set_active (mysink2, FALSE);
   fail_unless (gst_pad_push (mysrc,
           gst_buffer_ref (buffer)) == GST_FLOW_WRONG_STATE);
 
+  GST_DEBUG ("Trying to push with mysink2 disabled");
   gst_pad_set_active (mysink1, FALSE);
   gst_pad_set_active (mysink2, TRUE);
+  gst_pad_set_caps (mysink2, caps);
   fail_unless (gst_pad_push (mysrc,
           gst_buffer_ref (buffer)) == GST_FLOW_WRONG_STATE);
 
+  GST_DEBUG ("Trying to push with mysink2 and mysink1 disabled");
   gst_pad_set_active (mysink2, FALSE);
   fail_unless (gst_pad_push (mysrc,
           gst_buffer_ref (buffer)) == GST_FLOW_WRONG_STATE);
 
   /* Test if everything still works in normal state */
+  GST_DEBUG ("Reactivate both pads and try pushing");
   gst_pad_set_active (mysink1, TRUE);
+  gst_pad_set_caps (mysink1, caps);
   gst_pad_set_active (mysink2, TRUE);
+  gst_pad_set_caps (mysink2, caps);
   fail_unless (gst_pad_push (mysrc, gst_buffer_ref (buffer)) == GST_FLOW_OK);
 
   /* One unlinked pad must return OK, two unlinked pads must return NOT_LINKED */
+  GST_DEBUG ("Pushing with mysink1 unlinked");
   fail_unless (gst_pad_unlink (teesrc1, mysink1) == TRUE);
   fail_unless (gst_pad_push (mysrc, gst_buffer_ref (buffer)) == GST_FLOW_OK);
 
+  GST_DEBUG ("Pushing with mysink2 unlinked");
   fail_unless (gst_pad_link (teesrc1, mysink1) == GST_PAD_LINK_OK);
   fail_unless (gst_pad_unlink (teesrc2, mysink2) == TRUE);
   fail_unless (gst_pad_push (mysrc, gst_buffer_ref (buffer)) == GST_FLOW_OK);
 
+  GST_DEBUG ("Pushing with mysink1 AND mysink2 unlinked");
   fail_unless (gst_pad_unlink (teesrc1, mysink1) == TRUE);
   fail_unless (gst_pad_push (mysrc,
           gst_buffer_ref (buffer)) == GST_FLOW_NOT_LINKED);
 
   /* Test if everything still works in normal state */
+  GST_DEBUG ("Relink both pads and try pushing");
   fail_unless (gst_pad_link (teesrc1, mysink1) == GST_PAD_LINK_OK);
   fail_unless (gst_pad_link (teesrc2, mysink2) == GST_PAD_LINK_OK);
   fail_unless (gst_pad_push (mysrc, gst_buffer_ref (buffer)) == GST_FLOW_OK);
 
   /* One pad returning ERROR should result in ERROR */
+  GST_DEBUG ("Pushing with mysink1 returning GST_FLOW_ERROR");
   gst_pad_set_chain_function (mysink1, _fake_chain_error);
   fail_unless (gst_pad_push (mysrc, gst_buffer_ref (buffer)) == GST_FLOW_ERROR);
 
+  GST_DEBUG ("Pushing with mysink2 returning GST_FLOW_ERROR");
   gst_pad_set_chain_function (mysink1, _fake_chain);
   gst_pad_set_chain_function (mysink2, _fake_chain_error);
   fail_unless (gst_pad_push (mysrc, gst_buffer_ref (buffer)) == GST_FLOW_ERROR);
 
+  GST_DEBUG ("Pushing with mysink1 AND mysink2 returning GST_FLOW_ERROR");
   gst_pad_set_chain_function (mysink1, _fake_chain_error);
   fail_unless (gst_pad_push (mysrc, gst_buffer_ref (buffer)) == GST_FLOW_ERROR);
 
   /* And now everything still needs to work */
+  GST_DEBUG ("Try pushing with everything ok");
   gst_pad_set_chain_function (mysink1, _fake_chain);
   gst_pad_set_chain_function (mysink2, _fake_chain);
   fail_unless (gst_pad_push (mysrc, gst_buffer_ref (buffer)) == GST_FLOW_OK);
index 8823b04..24976fe 100644 (file)
@@ -47,32 +47,18 @@ event_func (GstPad * pad, GstEvent * event)
   return TRUE;
 }
 
-static GstFlowReturn
-bufferalloc_func (GstPad * pad, guint64 offset, guint size, GstCaps * caps,
-    GstBuffer ** buf)
-{
-  buffer_allocated = TRUE;
-  *buf = gst_buffer_new_and_alloc (size);
-  GST_BUFFER_OFFSET (*buf) = offset;
-  gst_buffer_set_caps (*buf, caps);
-
-  return GST_FLOW_OK;
-}
-
 GST_START_TEST (test_valve_basic)
 {
   GstElement *valve;
   GstPad *sink;
   GstPad *src;
-  GstBuffer *buf;
-  GstCaps *caps;
+  GstCaps *caps, *templ_caps;
 
   valve = gst_check_setup_element ("valve");
 
   sink = gst_check_setup_sink_pad_by_name (valve, &sinktemplate, "src");
   src = gst_check_setup_src_pad_by_name (valve, &srctemplate, "sink");
   gst_pad_set_event_function (sink, event_func);
-  gst_pad_set_bufferalloc_function (sink, bufferalloc_func);
   gst_pad_set_active (src, TRUE);
   gst_pad_set_active (sink, TRUE);
   gst_element_set_state (valve, GST_STATE_PLAYING);
@@ -81,15 +67,13 @@ GST_START_TEST (test_valve_basic)
 
   fail_unless (gst_pad_push_event (src, gst_event_new_eos ()) == TRUE);
   fail_unless (event_received == TRUE);
-  fail_unless (gst_pad_alloc_buffer (src, 0, 10, NULL, &buf) == GST_FLOW_OK);
-  fail_unless (buffer_allocated == TRUE);
-  gst_buffer_unref (buf);
   fail_unless (gst_pad_push (src, gst_buffer_new ()) == GST_FLOW_OK);
   fail_unless (gst_pad_push (src, gst_buffer_new ()) == GST_FLOW_OK);
   fail_unless (g_list_length (buffers) == 2);
-  caps = gst_pad_get_caps (src);
-  fail_unless (caps && gst_caps_is_equal (caps,
-          gst_pad_get_pad_template_caps (src)));
+  caps = gst_pad_get_caps (src, NULL);
+  templ_caps = gst_pad_get_pad_template_caps (src);
+  fail_unless (caps && gst_caps_is_equal (caps, templ_caps));
+  gst_caps_unref (templ_caps);
   gst_caps_unref (caps);
 
   gst_check_drop_buffers ();
@@ -98,15 +82,13 @@ GST_START_TEST (test_valve_basic)
   g_object_set (valve, "drop", TRUE, NULL);
   fail_unless (gst_pad_push_event (src, gst_event_new_eos ()) == TRUE);
   fail_unless (event_received == FALSE);
-  fail_unless (gst_pad_alloc_buffer (src, 0, 10, NULL, &buf) == GST_FLOW_OK);
-  fail_unless (buffer_allocated == FALSE);
-  gst_buffer_unref (buf);
   fail_unless (gst_pad_push (src, gst_buffer_new ()) == GST_FLOW_OK);
   fail_unless (gst_pad_push (src, gst_buffer_new ()) == GST_FLOW_OK);
   fail_unless (buffers == NULL);
-  caps = gst_pad_get_caps (src);
-  fail_unless (caps && gst_caps_is_equal (caps,
-          gst_pad_get_pad_template_caps (src)));
+  caps = gst_pad_get_caps (src, NULL);
+  templ_caps = gst_pad_get_pad_template_caps (src);
+  fail_unless (caps && gst_caps_is_equal (caps, templ_caps));
+  gst_caps_unref (templ_caps);
   gst_caps_unref (caps);
 
   gst_pad_set_active (src, FALSE);
index 2d1de99..9070e34 100644 (file)
@@ -763,13 +763,16 @@ GST_END_TEST;
 static GMutex *blocked_lock;
 static GCond *blocked_cond;
 
-static void
-pad_blocked_cb (GstPad * pad, gboolean blocked, gpointer user_data)
+static GstProbeReturn
+pad_blocked_cb (GstPad * pad, GstProbeType type, gpointer type_data,
+    gpointer user_data)
 {
   g_mutex_lock (blocked_lock);
-  GST_DEBUG ("srcpad blocked: %d, sending signal", blocked);
+  GST_DEBUG ("srcpad blocked: %d, sending signal", type);
   g_cond_signal (blocked_cond);
   g_mutex_unlock (blocked_lock);
+
+  return GST_PROBE_OK;
 }
 
 GST_START_TEST (test_add_live2)
@@ -778,6 +781,7 @@ GST_START_TEST (test_add_live2)
   GstStateChangeReturn ret;
   GstState current, pending;
   GstPad *srcpad, *sinkpad;
+  gulong id;
 
   blocked_lock = g_mutex_new ();
   blocked_cond = g_cond_new ();
@@ -799,7 +803,8 @@ GST_START_TEST (test_add_live2)
   GST_DEBUG ("blocking srcpad");
   /* block source pad */
   srcpad = gst_element_get_static_pad (src, "src");
-  gst_pad_set_blocked_async (srcpad, TRUE, pad_blocked_cb, NULL);
+  id = gst_pad_add_probe (srcpad, GST_PROBE_TYPE_BLOCK, pad_blocked_cb, NULL,
+      NULL);
 
   /* set source to PAUSED without adding it to the pipeline */
   ret = gst_element_set_state (src, GST_STATE_PAUSED);
@@ -827,7 +832,7 @@ GST_START_TEST (test_add_live2)
   GST_DEBUG ("unblocking srcpad");
 
   /* and unblock */
-  gst_pad_set_blocked_async (srcpad, FALSE, pad_blocked_cb, NULL);
+  gst_pad_remove_probe (srcpad, id);
 
   GST_DEBUG ("getting state");
 
@@ -1050,6 +1055,7 @@ GST_START_TEST (test_async_done)
   GstFormat format;
   gint64 position;
   gboolean qret;
+  GstSegment segment;
 
   sink = gst_element_factory_make ("fakesink", "sink");
   g_object_set (G_OBJECT (sink), "sync", TRUE, NULL);
@@ -1071,9 +1077,10 @@ GST_START_TEST (test_async_done)
 
   /* make newsegment, this sets the position to 10sec when the buffer prerolls */
   GST_DEBUG ("sending segment");
-  event =
-      gst_event_new_new_segment (FALSE, 1.0, GST_FORMAT_TIME, 0, -1,
-      10 * GST_SECOND);
+  gst_segment_init (&segment, GST_FORMAT_TIME);
+  segment.time = 10 * GST_SECOND;
+
+  event = gst_event_new_segment (&segment);
   res = gst_pad_send_event (sinkpad, event);
 
   /* We have not yet received any buffers so we are still in the READY state,
@@ -1192,6 +1199,7 @@ GST_START_TEST (test_async_done_eos)
   GstFormat format;
   gint64 position;
   gboolean qret;
+  GstSegment segment;
 
   sink = gst_element_factory_make ("fakesink", "sink");
   g_object_set (G_OBJECT (sink), "sync", TRUE, NULL);
@@ -1209,9 +1217,9 @@ GST_START_TEST (test_async_done_eos)
 
   /* make newsegment, this sets the position to 10sec when the buffer prerolls */
   GST_DEBUG ("sending segment");
-  event =
-      gst_event_new_new_segment (FALSE, 1.0, GST_FORMAT_TIME, 0, -1,
-      10 * GST_SECOND);
+  gst_segment_init (&segment, GST_FORMAT_TIME);
+  segment.time = 10 * GST_SECOND;
+  event = gst_event_new_segment (&segment);
   res = gst_pad_send_event (sinkpad, event);
 
   /* We have not yet received any buffers so we are still in the READY state,
index d42a99f..6cacd55 100644 (file)
@@ -19,6 +19,7 @@ gstiterator
 gstindex
 gstinterface
 gstmessage
+gstmeta
 gstminiobject
 gstobject
 gstpad
@@ -40,4 +41,3 @@ gstquery
 gsttask
 *.check.xml
 gstinfo
-gstxml
index c81fdeb..598e595 100644 (file)
@@ -61,7 +61,7 @@ GST_START_TEST (test_interface)
   GstBin *bin, *bin2;
   GstElement *filesrc;
   GstIterator *it;
-  gpointer item;
+  GValue item = { 0, };
 
   bin = GST_BIN (gst_bin_new (NULL));
   fail_unless (bin != NULL, "Could not create bin");
@@ -77,8 +77,8 @@ GST_START_TEST (test_interface)
   it = gst_bin_iterate_all_by_interface (bin, GST_TYPE_URI_HANDLER);
   fail_unless (it != NULL);
   fail_unless (gst_iterator_next (it, &item) == GST_ITERATOR_OK);
-  fail_unless (item == (gpointer) filesrc);
-  gst_object_unref (GST_OBJECT (item));
+  fail_unless (g_value_get_object (&item) == (gpointer) filesrc);
+  g_value_reset (&item);
   fail_unless (gst_iterator_next (it, &item) == GST_ITERATOR_DONE);
   gst_iterator_free (it);
 
@@ -89,8 +89,8 @@ GST_START_TEST (test_interface)
   it = gst_bin_iterate_all_by_interface (bin, GST_TYPE_URI_HANDLER);
   fail_unless (it != NULL);
   fail_unless (gst_iterator_next (it, &item) == GST_ITERATOR_OK);
-  fail_unless (item == (gpointer) filesrc);
-  gst_object_unref (GST_OBJECT (item));
+  fail_unless (g_value_get_object (&item) == (gpointer) filesrc);
+  g_value_reset (&item);
   fail_unless (gst_iterator_next (it, &item) == GST_ITERATOR_DONE);
   gst_iterator_free (it);
 
@@ -103,8 +103,8 @@ GST_START_TEST (test_interface)
       GST_ELEMENT (bin2), gst_element_factory_make ("identity", NULL), NULL);
   it = gst_bin_iterate_all_by_interface (bin, GST_TYPE_URI_HANDLER);
   fail_unless (gst_iterator_next (it, &item) == GST_ITERATOR_OK);
-  fail_unless (item == (gpointer) filesrc);
-  gst_object_unref (GST_OBJECT (item));
+  fail_unless (g_value_get_object (&item) == (gpointer) filesrc);
+  g_value_reset (&item);
   fail_unless (gst_iterator_next (it, &item) == GST_ITERATOR_DONE);
   gst_iterator_free (it);
 
@@ -112,12 +112,13 @@ GST_START_TEST (test_interface)
   gst_bin_add (bin2, gst_element_factory_make ("filesrc", NULL));
   it = gst_bin_iterate_all_by_interface (bin, GST_TYPE_URI_HANDLER);
   fail_unless (gst_iterator_next (it, &item) == GST_ITERATOR_OK);
-  gst_object_unref (GST_OBJECT (item));
+  g_value_reset (&item);
   fail_unless (gst_iterator_next (it, &item) == GST_ITERATOR_OK);
-  gst_object_unref (GST_OBJECT (item));
+  g_value_reset (&item);
   fail_unless (gst_iterator_next (it, &item) == GST_ITERATOR_OK);
-  gst_object_unref (GST_OBJECT (item));
+  g_value_reset (&item);
   fail_unless (gst_iterator_next (it, &item) == GST_ITERATOR_DONE);
+  g_value_unset (&item);
   gst_iterator_free (it);
 
   gst_object_unref (bin);
@@ -887,7 +888,7 @@ GST_START_TEST (test_iterate_sorted)
 {
   GstElement *src, *tee, *identity, *sink1, *sink2, *pipeline, *bin;
   GstIterator *it;
-  gpointer elem;
+  GValue elem = { 0, };
 
   pipeline = gst_pipeline_new (NULL);
   fail_unless (pipeline != NULL, "Could not create pipeline");
@@ -922,19 +923,21 @@ GST_START_TEST (test_iterate_sorted)
 
   it = gst_bin_iterate_sorted (GST_BIN (pipeline));
   fail_unless (gst_iterator_next (it, &elem) == GST_ITERATOR_OK);
-  fail_unless (elem == sink2);
-  gst_object_unref (elem);
+  fail_unless (g_value_get_object (&elem) == (gpointer) sink2);
+  g_value_reset (&elem);
 
   fail_unless (gst_iterator_next (it, &elem) == GST_ITERATOR_OK);
-  fail_unless (elem == identity);
-  gst_object_unref (elem);
+  fail_unless (g_value_get_object (&elem) == (gpointer) identity);
+  g_value_reset (&elem);
 
   fail_unless (gst_iterator_next (it, &elem) == GST_ITERATOR_OK);
-  fail_unless (elem == bin);
-  gst_object_unref (elem);
+  fail_unless (g_value_get_object (&elem) == (gpointer) bin);
+  g_value_reset (&elem);
 
+  g_value_unset (&elem);
   gst_iterator_free (it);
 
+  ASSERT_OBJECT_REFCOUNT (pipeline, "pipeline", 1);
   gst_object_unref (pipeline);
 }
 
index 06cac4c..b37d943 100644 (file)
 
 #include <gst/check/gstcheck.h>
 
-GST_START_TEST (test_caps)
-{
-  GstBuffer *buffer;
-  GstCaps *caps, *caps2;
-
-  buffer = gst_buffer_new_and_alloc (4);
-  caps = gst_caps_from_string ("audio/x-raw-int");
-  ASSERT_CAPS_REFCOUNT (caps, "caps", 1);
-
-  fail_unless (GST_BUFFER_CAPS (buffer) == NULL);
-
-  gst_buffer_set_caps (buffer, caps);
-  ASSERT_CAPS_REFCOUNT (caps, "caps", 2);
-
-  fail_unless (GST_BUFFER_CAPS (buffer) == caps);
-  ASSERT_CAPS_REFCOUNT (caps, "caps", 2);
-
-  fail_unless (gst_buffer_get_caps (buffer) == caps);
-  gst_caps_unref (caps);
-  ASSERT_CAPS_REFCOUNT (caps, "caps", 2);
-
-  caps2 = gst_caps_from_string ("audio/x-raw-float");
-  ASSERT_CAPS_REFCOUNT (caps2, "caps2", 1);
-
-  gst_buffer_set_caps (buffer, caps2);
-  ASSERT_CAPS_REFCOUNT (caps, "caps", 1);
-  ASSERT_CAPS_REFCOUNT (caps2, "caps2", 2);
-
-  gst_buffer_set_caps (buffer, NULL);
-  ASSERT_CAPS_REFCOUNT (caps, "caps", 1);
-  ASSERT_CAPS_REFCOUNT (caps2, "caps2", 1);
-
-  /* clean up, with caps2 still set as caps */
-  gst_buffer_set_caps (buffer, caps2);
-  ASSERT_CAPS_REFCOUNT (caps2, "caps2", 2);
-  gst_buffer_unref (buffer);
-  ASSERT_CAPS_REFCOUNT (caps2, "caps2", 1);
-  gst_caps_unref (caps);
-  gst_caps_unref (caps2);
-}
-
-GST_END_TEST;
-
-
 GST_START_TEST (test_subbuffer)
 {
   GstBuffer *buffer, *sub;
+  gsize size, maxsize, ssize;
+  guint8 *data, *sdata;
 
   buffer = gst_buffer_new_and_alloc (4);
-  memset (GST_BUFFER_DATA (buffer), 0, 4);
+
+  /* check sizes, buffer starts out empty */
+  data = gst_buffer_map (buffer, &size, &maxsize, GST_MAP_WRITE);
+  fail_unless (size == 4, "buffer has wrong size");
+  fail_unless (maxsize >= 4, "buffer has wrong size");
+  memset (data, 0, 4);
+  gst_buffer_unmap (buffer, data, 4);
+
+  data = gst_buffer_map (buffer, &size, NULL, GST_MAP_READ);
   /* set some metadata */
   GST_BUFFER_TIMESTAMP (buffer) = 1;
   GST_BUFFER_DURATION (buffer) = 2;
   GST_BUFFER_OFFSET (buffer) = 3;
   GST_BUFFER_OFFSET_END (buffer) = 4;
 
-  sub = gst_buffer_create_sub (buffer, 1, 2);
-  fail_if (sub == NULL, "create_sub of buffer returned NULL");
-  fail_unless (GST_BUFFER_SIZE (sub) == 2, "subbuffer has wrong size");
-  fail_unless (memcmp (GST_BUFFER_DATA (buffer) + 1, GST_BUFFER_DATA (sub),
-          2) == 0, "subbuffer contains the wrong data");
-  ASSERT_BUFFER_REFCOUNT (buffer, "parent", 2);
+  sub = gst_buffer_copy_region (buffer, GST_BUFFER_COPY_ALL, 1, 2);
+  fail_if (sub == NULL, "copy region of buffer returned NULL");
+
+  sdata = gst_buffer_map (sub, &ssize, NULL, GST_MAP_READ);
+  fail_unless (ssize == 2, "subbuffer has wrong size");
+  fail_unless (memcmp (data + 1, sdata, 2) == 0,
+      "subbuffer contains the wrong data");
   ASSERT_BUFFER_REFCOUNT (sub, "subbuffer", 1);
   fail_unless (GST_BUFFER_TIMESTAMP (sub) == -1,
       "subbuffer has wrong timestamp");
@@ -101,23 +68,25 @@ GST_START_TEST (test_subbuffer)
   fail_unless (GST_BUFFER_OFFSET (sub) == -1, "subbuffer has wrong offset");
   fail_unless (GST_BUFFER_OFFSET_END (sub) == -1,
       "subbuffer has wrong offset end");
+  gst_buffer_unmap (sub, sdata, ssize);
   gst_buffer_unref (sub);
 
   /* create a subbuffer of size 0 */
-  sub = gst_buffer_create_sub (buffer, 1, 0);
-  fail_if (sub == NULL, "create_sub of buffer returned NULL");
-  fail_unless (GST_BUFFER_SIZE (sub) == 0, "subbuffer has wrong size");
-  fail_unless (memcmp (GST_BUFFER_DATA (buffer) + 1, GST_BUFFER_DATA (sub),
-          0) == 0, "subbuffer contains the wrong data");
-  ASSERT_BUFFER_REFCOUNT (buffer, "parent", 2);
+  sub = gst_buffer_copy_region (buffer, GST_BUFFER_COPY_ALL, 1, 0);
+  fail_if (sub == NULL, "copy_region of buffer returned NULL");
+  sdata = gst_buffer_map (sub, &ssize, NULL, GST_MAP_READ);
+  fail_unless (ssize == 0, "subbuffer has wrong size");
+  fail_unless (memcmp (data + 1, sdata, 0) == 0,
+      "subbuffer contains the wrong data");
   ASSERT_BUFFER_REFCOUNT (sub, "subbuffer", 1);
+  gst_buffer_unmap (sub, sdata, ssize);
   gst_buffer_unref (sub);
 
   /* test if metadata is coppied, not a complete buffer copy so only the
    * timestamp and offset fields are copied. */
-  sub = gst_buffer_create_sub (buffer, 0, 1);
-  fail_if (sub == NULL, "create_sub of buffer returned NULL");
-  fail_unless (GST_BUFFER_SIZE (sub) == 1, "subbuffer has wrong size");
+  sub = gst_buffer_copy_region (buffer, GST_BUFFER_COPY_ALL, 0, 1);
+  fail_if (sub == NULL, "copy_region of buffer returned NULL");
+  fail_unless (gst_buffer_get_size (sub) == 1, "subbuffer has wrong size");
   fail_unless (GST_BUFFER_TIMESTAMP (sub) == 1,
       "subbuffer has wrong timestamp");
   fail_unless (GST_BUFFER_OFFSET (sub) == 3, "subbuffer has wrong offset");
@@ -128,9 +97,9 @@ GST_START_TEST (test_subbuffer)
 
   /* test if metadata is coppied, a complete buffer is copied so all the timing
    * fields should be copied. */
-  sub = gst_buffer_create_sub (buffer, 0, 4);
-  fail_if (sub == NULL, "create_sub of buffer returned NULL");
-  fail_unless (GST_BUFFER_SIZE (sub) == 4, "subbuffer has wrong size");
+  sub = gst_buffer_copy_region (buffer, GST_BUFFER_COPY_ALL, 0, 4);
+  fail_if (sub == NULL, "copy_region of buffer returned NULL");
+  fail_unless (gst_buffer_get_size (sub) == 4, "subbuffer has wrong size");
   fail_unless (GST_BUFFER_TIMESTAMP (sub) == 1,
       "subbuffer has wrong timestamp");
   fail_unless (GST_BUFFER_DURATION (sub) == 2, "subbuffer has wrong duration");
@@ -140,6 +109,8 @@ GST_START_TEST (test_subbuffer)
 
   /* clean up */
   gst_buffer_unref (sub);
+
+  gst_buffer_unmap (buffer, data, size);
   gst_buffer_unref (buffer);
 }
 
@@ -151,11 +122,11 @@ GST_START_TEST (test_is_span_fast)
 
   buffer = gst_buffer_new_and_alloc (4);
 
-  sub1 = gst_buffer_create_sub (buffer, 0, 2);
-  fail_if (sub1 == NULL, "create_sub of buffer returned NULL");
+  sub1 = gst_buffer_copy_region (buffer, GST_BUFFER_COPY_ALL, 0, 2);
+  fail_if (sub1 == NULL, "copy_region of buffer returned NULL");
 
-  sub2 = gst_buffer_create_sub (buffer, 2, 2);
-  fail_if (sub2 == NULL, "create_sub of buffer returned NULL");
+  sub2 = gst_buffer_copy_region (buffer, GST_BUFFER_COPY_ALL, 2, 2);
+  fail_if (sub2 == NULL, "copy_region of buffer returned NULL");
 
   fail_if (gst_buffer_is_span_fast (buffer, sub2) == TRUE,
       "a parent buffer can't be span_fasted");
@@ -177,71 +148,84 @@ GST_END_TEST;
 GST_START_TEST (test_span)
 {
   GstBuffer *buffer, *sub1, *sub2, *span;
+  guint8 *data;
+  gsize size;
 
   buffer = gst_buffer_new_and_alloc (4);
-  memcpy (GST_BUFFER_DATA (buffer), "data", 4);
+
+  data = gst_buffer_map (buffer, &size, NULL, GST_MAP_WRITE);
+  memcpy (data, "data", 4);
+  gst_buffer_unmap (buffer, data, 4);
 
   ASSERT_CRITICAL (gst_buffer_span (NULL, 1, NULL, 2));
   ASSERT_CRITICAL (gst_buffer_span (buffer, 1, NULL, 2));
   ASSERT_CRITICAL (gst_buffer_span (NULL, 1, buffer, 2));
   ASSERT_CRITICAL (gst_buffer_span (buffer, 0, buffer, 10));
 
-  sub1 = gst_buffer_create_sub (buffer, 0, 2);
-  fail_if (sub1 == NULL, "create_sub of buffer returned NULL");
+  sub1 = gst_buffer_copy_region (buffer, GST_BUFFER_COPY_ALL, 0, 2);
+  fail_if (sub1 == NULL, "copy_region of buffer returned NULL");
 
-  sub2 = gst_buffer_create_sub (buffer, 2, 2);
-  fail_if (sub2 == NULL, "create_sub of buffer returned NULL");
+  sub2 = gst_buffer_copy_region (buffer, GST_BUFFER_COPY_ALL, 2, 2);
+  fail_if (sub2 == NULL, "copy_region of buffer returned NULL");
 
-  ASSERT_BUFFER_REFCOUNT (buffer, "parent", 3);
+  ASSERT_BUFFER_REFCOUNT (buffer, "parent", 1);
   ASSERT_BUFFER_REFCOUNT (sub1, "sub1", 1);
   ASSERT_BUFFER_REFCOUNT (sub2, "sub2", 1);
 
   /* span will create a new subbuffer from the parent */
   span = gst_buffer_span (sub1, 0, sub2, 4);
-  fail_unless (GST_BUFFER_SIZE (span) == 4, "spanned buffer is wrong size");
-  ASSERT_BUFFER_REFCOUNT (buffer, "parent", 4);
+  data = gst_buffer_map (span, &size, NULL, GST_MAP_READ);
+  fail_unless (size == 4, "spanned buffer is wrong size");
+  ASSERT_BUFFER_REFCOUNT (buffer, "parent", 1);
   ASSERT_BUFFER_REFCOUNT (sub1, "sub1", 1);
   ASSERT_BUFFER_REFCOUNT (sub2, "sub2", 1);
   ASSERT_BUFFER_REFCOUNT (span, "span", 1);
-  fail_unless (memcmp (GST_BUFFER_DATA (span), "data", 4) == 0,
+  fail_unless (memcmp (data, "data", 4) == 0,
       "spanned buffer contains the wrong data");
+  gst_buffer_unmap (span, data, size);
   gst_buffer_unref (span);
-  ASSERT_BUFFER_REFCOUNT (buffer, "parent", 3);
+  ASSERT_BUFFER_REFCOUNT (buffer, "parent", 1);
 
   /* span from non-contiguous buffers will create new buffers */
   span = gst_buffer_span (sub2, 0, sub1, 4);
-  fail_unless (GST_BUFFER_SIZE (span) == 4, "spanned buffer is wrong size");
-  ASSERT_BUFFER_REFCOUNT (buffer, "parent", 3);
+  data = gst_buffer_map (span, &size, NULL, GST_MAP_READ);
+  fail_unless (size == 4, "spanned buffer is wrong size");
+  ASSERT_BUFFER_REFCOUNT (buffer, "parent", 1);
   ASSERT_BUFFER_REFCOUNT (sub1, "sub1", 1);
   ASSERT_BUFFER_REFCOUNT (sub2, "sub2", 1);
   ASSERT_BUFFER_REFCOUNT (span, "span", 1);
-  fail_unless (memcmp (GST_BUFFER_DATA (span), "tada", 4) == 0,
+  fail_unless (memcmp (data, "tada", 4) == 0,
       "spanned buffer contains the wrong data");
+  gst_buffer_unmap (span, data, size);
   gst_buffer_unref (span);
-  ASSERT_BUFFER_REFCOUNT (buffer, "parent", 3);
+  ASSERT_BUFFER_REFCOUNT (buffer, "parent", 1);
 
   /* span with different sizes */
   span = gst_buffer_span (sub1, 1, sub2, 3);
-  fail_unless (GST_BUFFER_SIZE (span) == 3, "spanned buffer is wrong size");
-  ASSERT_BUFFER_REFCOUNT (buffer, "parent", 4);
+  data = gst_buffer_map (span, &size, NULL, GST_MAP_READ);
+  fail_unless (size == 3, "spanned buffer is wrong size");
+  ASSERT_BUFFER_REFCOUNT (buffer, "parent", 1);
   ASSERT_BUFFER_REFCOUNT (sub1, "sub1", 1);
   ASSERT_BUFFER_REFCOUNT (sub2, "sub2", 1);
   ASSERT_BUFFER_REFCOUNT (span, "span", 1);
-  fail_unless (memcmp (GST_BUFFER_DATA (span), "ata", 3) == 0,
+  fail_unless (memcmp (data, "ata", 3) == 0,
       "spanned buffer contains the wrong data");
+  gst_buffer_unmap (span, data, size);
   gst_buffer_unref (span);
-  ASSERT_BUFFER_REFCOUNT (buffer, "parent", 3);
+  ASSERT_BUFFER_REFCOUNT (buffer, "parent", 1);
 
   span = gst_buffer_span (sub2, 0, sub1, 3);
-  fail_unless (GST_BUFFER_SIZE (span) == 3, "spanned buffer is wrong size");
-  ASSERT_BUFFER_REFCOUNT (buffer, "parent", 3);
+  data = gst_buffer_map (span, &size, NULL, GST_MAP_READ);
+  fail_unless (size == 3, "spanned buffer is wrong size");
+  ASSERT_BUFFER_REFCOUNT (buffer, "parent", 1);
   ASSERT_BUFFER_REFCOUNT (sub1, "sub1", 1);
   ASSERT_BUFFER_REFCOUNT (sub2, "sub2", 1);
   ASSERT_BUFFER_REFCOUNT (span, "span", 1);
-  fail_unless (memcmp (GST_BUFFER_DATA (span), "tad", 3) == 0,
+  fail_unless (memcmp (data, "tad", 3) == 0,
       "spanned buffer contains the wrong data");
+  gst_buffer_unmap (span, data, size);
   gst_buffer_unref (span);
-  ASSERT_BUFFER_REFCOUNT (buffer, "parent", 3);
+  ASSERT_BUFFER_REFCOUNT (buffer, "parent", 1);
 
   /* clean up */
   gst_buffer_unref (sub1);
@@ -259,13 +243,13 @@ create_read_only_buffer (void)
 {
   GstBuffer *buf;
 
-  buf = (GstBuffer *) gst_mini_object_new (GST_TYPE_BUFFER);
+  buf = gst_buffer_new ();
 
   /* assign some read-only data to the new buffer */
-  GST_BUFFER_DATA (buf) = (guint8 *) ro_memory;
-  GST_BUFFER_SIZE (buf) = sizeof (ro_memory);
-
-  GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_READONLY);
+  gst_buffer_take_memory (buf, -1,
+      gst_memory_new_wrapped (GST_MEMORY_FLAG_READONLY,
+          (gpointer) ro_memory, NULL,
+          sizeof (ro_memory), 0, sizeof (ro_memory)));
 
   return buf;
 }
@@ -273,21 +257,19 @@ create_read_only_buffer (void)
 GST_START_TEST (test_make_writable)
 {
   GstBuffer *buf, *buf2;
+  guint8 *data;
+  gsize size;
 
   /* create read-only buffer and make it writable */
   buf = create_read_only_buffer ();
-  fail_unless (GST_BUFFER_FLAG_IS_SET (buf, GST_BUFFER_FLAG_READONLY),
-      "read-only buffer should have read-only flag set");
-  buf = gst_buffer_make_writable (buf);
-  fail_unless (!GST_BUFFER_FLAG_IS_SET (buf, GST_BUFFER_FLAG_READONLY),
-      "writable buffer must not have read-only flag set");
-  GST_BUFFER_DATA (buf)[4] = 'a';
+
+  data = gst_buffer_map (buf, &size, NULL, GST_MAP_WRITE);
+  data[4] = 'a';
+  gst_buffer_unmap (buf, data, size);
   gst_buffer_unref (buf);
 
   /* alloc'ed buffer with refcount 1 should be writable */
   buf = gst_buffer_new_and_alloc (32);
-  fail_unless (!GST_BUFFER_FLAG_IS_SET (buf, GST_BUFFER_FLAG_READONLY),
-      "_new_and_alloc'ed buffer must not have read-only flag set");
   buf2 = gst_buffer_make_writable (buf);
   fail_unless (buf == buf2,
       "_make_writable() should have returned same buffer");
@@ -295,8 +277,6 @@ GST_START_TEST (test_make_writable)
 
   /* alloc'ed buffer with refcount >1 should be copied */
   buf = gst_buffer_new_and_alloc (32);
-  fail_unless (!GST_BUFFER_FLAG_IS_SET (buf, GST_BUFFER_FLAG_READONLY),
-      "_new_and_alloc'ed buffer must not have read-only flag set");
   gst_buffer_ref (buf);
   buf2 = gst_buffer_make_writable (buf);
   fail_unless (buf != buf2, "_make_writable() should have returned a copy!");
@@ -309,20 +289,18 @@ GST_END_TEST;
 GST_START_TEST (test_subbuffer_make_writable)
 {
   GstBuffer *buf, *sub_buf;
+  guint8 *data;
+  gsize size;
 
   /* create sub-buffer of read-only buffer and make it writable */
   buf = create_read_only_buffer ();
-  fail_unless (GST_BUFFER_FLAG_IS_SET (buf, GST_BUFFER_FLAG_READONLY),
-      "read-only buffer should have read-only flag set");
 
-  sub_buf = gst_buffer_create_sub (buf, 0, 8);
-  fail_unless (GST_BUFFER_FLAG_IS_SET (sub_buf, GST_BUFFER_FLAG_READONLY),
-      "sub-buffer of read-only buffer should have read-only flag set");
+  sub_buf = gst_buffer_copy_region (buf, GST_BUFFER_COPY_ALL, 0, 8);
 
-  sub_buf = gst_buffer_make_writable (sub_buf);
-  fail_unless (!GST_BUFFER_FLAG_IS_SET (sub_buf, GST_BUFFER_FLAG_READONLY),
-      "writable buffer must not have read-only flag set");
-  GST_BUFFER_DATA (sub_buf)[4] = 'a';
+  data = gst_buffer_map (sub_buf, &size, NULL, GST_MAP_WRITE);
+  fail_if (data == NULL);
+  data[4] = 'a';
+  gst_buffer_unmap (sub_buf, data, size);
   gst_buffer_unref (sub_buf);
   gst_buffer_unref (buf);
 }
@@ -338,23 +316,18 @@ GST_START_TEST (test_metadata_writable)
   GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_DELTA_UNIT);
 
   /* Buffer with refcount 1 should have writable metadata */
-  fail_unless (gst_buffer_is_metadata_writable (buffer) == TRUE);
+  fail_unless (gst_buffer_is_writable (buffer) == TRUE);
 
   /* Check that a buffer with refcount 2 does not have writable metadata */
   gst_buffer_ref (buffer);
   ASSERT_BUFFER_REFCOUNT (buffer, "buffer", 2);
-  fail_unless (gst_buffer_is_metadata_writable (buffer) == FALSE);
+  fail_unless (gst_buffer_is_writable (buffer) == FALSE);
 
   /* Check that make_metadata_writable produces a new sub-buffer with 
    * writable metadata. */
-  sub1 = gst_buffer_make_metadata_writable (buffer);
+  sub1 = gst_buffer_make_writable (buffer);
   fail_if (sub1 == buffer);
-  fail_unless (gst_buffer_is_metadata_writable (sub1) == TRUE);
-
-  /* Check that the original metadata is still not writable 
-   * (subbuffer should be holding a reference, and so should we) */
-  ASSERT_BUFFER_REFCOUNT (buffer, "buffer", 2);
-  fail_unless (gst_buffer_is_metadata_writable (buffer) == FALSE);
+  fail_unless (gst_buffer_is_writable (sub1) == TRUE);
 
   /* Check that make_metadata_writable() maintains the buffer flags */
   fail_unless (GST_BUFFER_FLAG_IS_SET (sub1, GST_BUFFER_FLAG_DISCONT));
@@ -370,7 +343,7 @@ GST_START_TEST (test_metadata_writable)
   /* Drop the subbuffer and check that the metadata is now writable again */
   ASSERT_BUFFER_REFCOUNT (sub1, "sub1", 1);
   gst_buffer_unref (sub1);
-  fail_unless (gst_buffer_is_metadata_writable (buffer) == TRUE);
+  fail_unless (gst_buffer_is_writable (buffer) == TRUE);
 
   ASSERT_BUFFER_REFCOUNT (buffer, "buffer", 1);
   gst_buffer_unref (buffer);
@@ -381,6 +354,8 @@ GST_END_TEST;
 GST_START_TEST (test_copy)
 {
   GstBuffer *buffer, *copy;
+  gsize size, ssize;
+  guint8 *data, *sdata;
 
   buffer = gst_buffer_new_and_alloc (4);
   ASSERT_BUFFER_REFCOUNT (buffer, "buffer", 1);
@@ -388,22 +363,33 @@ GST_START_TEST (test_copy)
   copy = gst_buffer_copy (buffer);
   ASSERT_BUFFER_REFCOUNT (buffer, "buffer", 1);
   ASSERT_BUFFER_REFCOUNT (copy, "copy", 1);
-  /* data must be copied and thus point to different memory */
-  fail_if (GST_BUFFER_DATA (buffer) == GST_BUFFER_DATA (copy));
+  /* buffers are copied and must point to different memory */
+  fail_if (buffer == copy);
+
+  data = gst_buffer_map (buffer, &size, NULL, GST_MAP_READ);
+  sdata = gst_buffer_map (copy, &ssize, NULL, GST_MAP_READ);
+
+  /* NOTE that data is refcounted */
+  fail_unless (size == ssize);
+
+  gst_buffer_unmap (copy, sdata, ssize);
+  gst_buffer_unmap (buffer, data, size);
 
   gst_buffer_unref (copy);
   gst_buffer_unref (buffer);
 
   /* a 0-sized buffer has NULL data as per docs */
   buffer = gst_buffer_new_and_alloc (0);
-  fail_unless (GST_BUFFER_DATA (buffer) == NULL);
-  fail_unless (GST_BUFFER_SIZE (buffer) == 0);
+  data = gst_buffer_map (buffer, &size, NULL, GST_MAP_READ);
+  fail_unless (data == NULL);
+  gst_buffer_unmap (buffer, data, size);
 
   /* copying a 0-sized buffer should not crash and also set
    * the data member NULL. */
   copy = gst_buffer_copy (buffer);
-  fail_unless (GST_BUFFER_DATA (copy) == NULL);
-  fail_unless (GST_BUFFER_SIZE (copy) == 0);
+  data = gst_buffer_map (copy, &size, NULL, GST_MAP_READ);
+  fail_unless (data == NULL);
+  gst_buffer_unmap (copy, data, size);
 
   gst_buffer_unref (copy);
   gst_buffer_unref (buffer);
@@ -414,24 +400,28 @@ GST_END_TEST;
 GST_START_TEST (test_try_new_and_alloc)
 {
   GstBuffer *buf;
+  gsize size;
+  guint8 *data;
 
   /* special case: alloc of 0 bytes results in new buffer with NULL data */
-  buf = gst_buffer_try_new_and_alloc (0);
+  buf = gst_buffer_new_and_alloc (0);
   fail_unless (buf != NULL);
   fail_unless (GST_IS_BUFFER (buf));
-  fail_unless (GST_BUFFER_SIZE (buf) == 0);
-  fail_unless (GST_BUFFER_DATA (buf) == NULL);
-  fail_unless (GST_BUFFER_MALLOCDATA (buf) == NULL);
+  data = gst_buffer_map (buf, &size, NULL, GST_MAP_READ);
+  fail_unless (data == NULL);
+  gst_buffer_unmap (buf, data, size);
   gst_buffer_unref (buf);
 
   /* normal alloc should still work */
-  buf = gst_buffer_try_new_and_alloc (640 * 480 * 4);
+  buf = gst_buffer_new_and_alloc (640 * 480 * 4);
   fail_unless (buf != NULL);
   fail_unless (GST_IS_BUFFER (buf));
-  fail_unless (GST_BUFFER_SIZE (buf) == (640 * 480 * 4));
-  fail_unless (GST_BUFFER_DATA (buf) != NULL);
-  fail_unless (GST_BUFFER_MALLOCDATA (buf) != NULL);
-  GST_BUFFER_DATA (buf)[640 * 479 * 4 + 479] = 0xff;
+  data = gst_buffer_map (buf, &size, NULL, GST_MAP_WRITE);
+  fail_unless (data != NULL);
+  fail_unless (size == (640 * 480 * 4));
+  data[640 * 479 * 4 + 479] = 0xff;
+  gst_buffer_unmap (buf, data, size);
+
   gst_buffer_unref (buf);
 
 #if 0
@@ -443,7 +433,7 @@ GST_START_TEST (test_try_new_and_alloc)
   /* now this better fail (don't run in valgrind, it will abort
    * or warn when passing silly arguments to malloc) */
   if (!RUNNING_ON_VALGRIND) {
-    buf = gst_buffer_try_new_and_alloc ((guint) - 1);
+    buf = gst_buffer_new_and_alloc ((guint) - 1);
     fail_unless (buf == NULL);
   }
 #endif
@@ -458,7 +448,6 @@ gst_buffer_suite (void)
   TCase *tc_chain = tcase_create ("general");
 
   suite_add_tcase (s, tc_chain);
-  tcase_add_test (tc_chain, test_caps);
   tcase_add_test (tc_chain, test_subbuffer);
   tcase_add_test (tc_chain, test_subbuffer_make_writable);
   tcase_add_test (tc_chain, test_make_writable);
index 0885644..2e2fdcd 100644 (file)
@@ -44,107 +44,70 @@ cleanup (void)
   gst_buffer_list_unref (list);
 }
 
+#if 0
 static GstBuffer *
 buffer_from_string (const gchar * str)
 {
-  guint size;
+  gsize size;
   GstBuffer *buf;
+  gpointer data;
 
   size = strlen (str);
   buf = gst_buffer_new_and_alloc (size);
   gst_buffer_set_caps (buf, caps);
   GST_BUFFER_TIMESTAMP (buf) = TIMESTAMP;
-  memcpy (GST_BUFFER_DATA (buf), str, size);
-  GST_BUFFER_SIZE (buf) = size;
+
+  data = gst_buffer_map (buf, NULL, NULL, GST_MAP_WRITE);
+  memcpy (data, str, size);
+  gst_buffer_unmap (buf, data, size);
 
   return buf;
 }
 
+static void
+check_buffer (GstBuffer * buf, gsize size, const gchar * data)
+{
+  gchar *bdata;
+  gsize bsize, csize, msize;
+
+  bdata = gst_buffer_map (buf, &bsize, &msize, GST_MAP_READ);
+  csize = size ? size : bsize;
+  GST_DEBUG ("%lu %lu %lu", bsize, csize, msize);
+  fail_unless (bsize == csize);
+  fail_unless (memcmp (bdata, data, csize) == 0);
+  gst_buffer_unmap (buf, bdata, bsize);
+}
+#endif
+
 GST_START_TEST (test_add_and_iterate)
 {
-  GstBufferListIterator *it;
   GstBuffer *buf1;
   GstBuffer *buf2;
-  GstBuffer *buf3;
-  GstBuffer *buf4;
-  GstBuffer *buf;
 
   /* buffer list is initially empty */
-  fail_unless (gst_buffer_list_n_groups (list) == 0);
-
-  it = gst_buffer_list_iterate (list);
+  fail_unless (gst_buffer_list_len (list) == 0);
 
-  ASSERT_CRITICAL (gst_buffer_list_iterator_add (it, NULL));
-  ASSERT_CRITICAL (gst_buffer_list_iterator_add (NULL, NULL));
+  ASSERT_CRITICAL (gst_buffer_list_insert (list, 0, NULL));
+  ASSERT_CRITICAL (gst_buffer_list_insert (NULL, 0, NULL));
 
-  /* cannot add buffer without adding a group first */
   buf1 = gst_buffer_new ();
-  ASSERT_CRITICAL (gst_buffer_list_iterator_add (it, buf1));
 
   /* add a group of 2 buffers */
-  fail_unless (gst_buffer_list_iterator_n_buffers (it) == 0);
-  gst_buffer_list_iterator_add_group (it);
-  fail_unless (gst_buffer_list_n_groups (list) == 1);
-  ASSERT_CRITICAL (gst_buffer_list_iterator_add (it, NULL));
+  fail_unless (gst_buffer_list_len (list) == 0);
+  ASSERT_CRITICAL (gst_buffer_list_insert (list, -1, NULL));
   ASSERT_BUFFER_REFCOUNT (buf1, "buf1", 1);
-  gst_buffer_list_iterator_add (it, buf1);
+  gst_buffer_list_add (list, buf1);
   ASSERT_BUFFER_REFCOUNT (buf1, "buf1", 1);     /* list takes ownership */
-  fail_unless (gst_buffer_list_n_groups (list) == 1);
-  fail_unless (gst_buffer_list_iterator_n_buffers (it) == 0);
+  fail_unless (gst_buffer_list_len (list) == 1);
   buf2 = gst_buffer_new ();
-  gst_buffer_list_iterator_add (it, buf2);
+  gst_buffer_list_add (list, buf2);
   ASSERT_BUFFER_REFCOUNT (buf2, "buf2", 1);
-  fail_unless (gst_buffer_list_n_groups (list) == 1);
-  fail_unless (gst_buffer_list_iterator_n_buffers (it) == 0);
-
-  /* add another group of 2 buffers */
-  gst_buffer_list_iterator_add_group (it);
-  fail_unless (gst_buffer_list_n_groups (list) == 2);
-  buf3 = gst_buffer_new ();
-  gst_buffer_list_iterator_add (it, buf3);
-  ASSERT_BUFFER_REFCOUNT (buf3, "buf3", 1);
-  fail_unless (gst_buffer_list_n_groups (list) == 2);
-  fail_unless (gst_buffer_list_iterator_n_buffers (it) == 0);
-  buf4 = gst_buffer_new ();
-  gst_buffer_list_iterator_add (it, buf4);
-  ASSERT_BUFFER_REFCOUNT (buf4, "buf4", 1);
-  fail_unless (gst_buffer_list_n_groups (list) == 2);
-  fail_unless (gst_buffer_list_iterator_n_buffers (it) == 0);
-
-  /* freeing iterator does not affect list */
-  gst_buffer_list_iterator_free (it);
-  fail_unless (gst_buffer_list_n_groups (list) == 2);
-
-  /* create a new iterator */
-  it = gst_buffer_list_iterate (list);
-
-  /* iterate list */
-  fail_unless (gst_buffer_list_iterator_next (it) == NULL);
-  fail_unless (gst_buffer_list_iterator_next_group (it));
-  fail_unless (gst_buffer_list_iterator_n_buffers (it) == 2);
-  buf = gst_buffer_list_iterator_next (it);
-  fail_unless (buf == buf1);
-  fail_unless (gst_buffer_list_iterator_n_buffers (it) == 1);
-  buf = gst_buffer_list_iterator_next (it);
-  fail_unless (buf == buf2);
-  fail_unless (gst_buffer_list_iterator_n_buffers (it) == 0);
-  fail_unless (gst_buffer_list_iterator_next (it) == NULL);
-  fail_unless (gst_buffer_list_iterator_next_group (it));
-  fail_unless (gst_buffer_list_iterator_n_buffers (it) == 2);
-  buf = gst_buffer_list_iterator_next (it);
-  fail_unless (buf == buf3);
-  fail_unless (gst_buffer_list_iterator_n_buffers (it) == 1);
-  buf = gst_buffer_list_iterator_next (it);
-  fail_unless (buf == buf4);
-  fail_unless (gst_buffer_list_iterator_n_buffers (it) == 0);
-  fail_unless (gst_buffer_list_iterator_next (it) == NULL);
-  fail_if (gst_buffer_list_iterator_next_group (it));
-
-  gst_buffer_list_iterator_free (it);
+  fail_unless (gst_buffer_list_len (list) == 2);
 }
 
 GST_END_TEST;
 
+#if 0
 GST_START_TEST (test_make_writable)
 {
   GstBufferListIterator *it;
@@ -546,9 +509,7 @@ GST_START_TEST (test_merge)
   gst_buffer_unref (buf);
   fail_unless (GST_BUFFER_CAPS (merged_buf) == caps);
   fail_unless (GST_BUFFER_TIMESTAMP (merged_buf) == TIMESTAMP);
-  fail_unless (GST_BUFFER_SIZE (merged_buf) == 3);
-  fail_unless (memcmp (GST_BUFFER_DATA (merged_buf), "One",
-          GST_BUFFER_SIZE (merged_buf)) == 0);
+  check_buffer (merged_buf, 3, "One");
   gst_buffer_unref (merged_buf);
 
   /* add another buffer to the same group */
@@ -559,17 +520,13 @@ GST_START_TEST (test_merge)
   ASSERT_BUFFER_REFCOUNT (merged_buf, "merged_buf", 1);
   fail_unless (GST_BUFFER_CAPS (merged_buf) == caps);
   fail_unless (GST_BUFFER_TIMESTAMP (merged_buf) == TIMESTAMP);
-  fail_unless (GST_BUFFER_SIZE (merged_buf) == 8);
-  fail_unless (memcmp (GST_BUFFER_DATA (merged_buf), "OneGroup",
-          GST_BUFFER_SIZE (merged_buf)) == 0);
+  check_buffer (merged_buf, 8, "OneGroup");
 
   /* merging the same group again should return a new buffer with merged data */
   buf = gst_buffer_list_iterator_merge_group (merge_it);
   ASSERT_BUFFER_REFCOUNT (buf, "buf", 1);
   fail_unless (buf != merged_buf);
-  fail_unless (GST_BUFFER_SIZE (buf) == 8);
-  fail_unless (memcmp (GST_BUFFER_DATA (buf), "OneGroup",
-          GST_BUFFER_SIZE (buf)) == 0);
+  check_buffer (buf, 8, "OneGroup");
   gst_buffer_unref (buf);
   gst_buffer_unref (merged_buf);
 
@@ -583,9 +540,7 @@ GST_START_TEST (test_merge)
   ASSERT_BUFFER_REFCOUNT (merged_buf, "merged_buf", 1);
   fail_unless (GST_BUFFER_CAPS (merged_buf) == caps);
   fail_unless (GST_BUFFER_TIMESTAMP (merged_buf) == TIMESTAMP);
-  fail_unless (GST_BUFFER_SIZE (merged_buf) == 8);
-  fail_unless (memcmp (GST_BUFFER_DATA (merged_buf), "OneGroup",
-          GST_BUFFER_SIZE (merged_buf)) == 0);
+  check_buffer (merged_buf, 8, "OneGroup");
   gst_buffer_unref (merged_buf);
 
   /* merge the second group */
@@ -594,9 +549,7 @@ GST_START_TEST (test_merge)
   ASSERT_BUFFER_REFCOUNT (merged_buf, "merged_buf", 1);
   fail_unless (GST_BUFFER_CAPS (merged_buf) == caps);
   fail_unless (GST_BUFFER_TIMESTAMP (merged_buf) == TIMESTAMP);
-  fail_unless (GST_BUFFER_SIZE (merged_buf) == 12);
-  fail_unless (memcmp (GST_BUFFER_DATA (merged_buf), "AnotherGroup",
-          GST_BUFFER_SIZE (merged_buf)) == 0);
+  check_buffer (merged_buf, 12, "AnotherGroup");
   gst_buffer_unref (merged_buf);
 
   gst_buffer_list_iterator_free (merge_it);
@@ -609,8 +562,7 @@ GST_START_TEST (test_merge)
   buf = gst_buffer_list_iterator_steal (it);
   gst_buffer_list_iterator_free (it);
   fail_unless (buf != NULL);
-  fail_unless (memcmp (GST_BUFFER_DATA (buf), "Group",
-          GST_BUFFER_SIZE (buf)) == 0);
+  check_buffer (buf, 0, "Group");
   gst_buffer_unref (buf);
   merge_it = gst_buffer_list_iterate (list);
   fail_unless (gst_buffer_list_iterator_next_group (merge_it));
@@ -618,9 +570,7 @@ GST_START_TEST (test_merge)
   ASSERT_BUFFER_REFCOUNT (merged_buf, "merged_buf", 1);
   fail_unless (GST_BUFFER_CAPS (merged_buf) == caps);
   fail_unless (GST_BUFFER_TIMESTAMP (merged_buf) == TIMESTAMP);
-  fail_unless (GST_BUFFER_SIZE (merged_buf) == 3);
-  fail_unless (memcmp (GST_BUFFER_DATA (merged_buf), "One",
-          GST_BUFFER_SIZE (merged_buf)) == 0);
+  check_buffer (merged_buf, 3, "One");
   gst_buffer_unref (merged_buf);
 
   /* steal the first buffer too and merge the first group again */
@@ -629,8 +579,7 @@ GST_START_TEST (test_merge)
   fail_unless (gst_buffer_list_iterator_next (it) != NULL);
   buf = gst_buffer_list_iterator_steal (it);
   fail_unless (buf != NULL);
-  fail_unless (memcmp (GST_BUFFER_DATA (buf), "One",
-          GST_BUFFER_SIZE (buf)) == 0);
+  check_buffer (buf, 3, "One");
   gst_buffer_unref (buf);
   gst_buffer_list_iterator_free (it);
   fail_unless (gst_buffer_list_iterator_merge_group (merge_it) == NULL);
@@ -796,13 +745,13 @@ GST_START_TEST (test_list)
 
     buf = gst_buffer_list_get (list, 0, i);
     g_snprintf (name, 10, "%d", i);
-    fail_unless (memcmp (name, (gchar *) GST_BUFFER_DATA (buf),
-            GST_BUFFER_SIZE (buf)) == 0);
+    check_buffer (buf, 0, name);
   }
   gst_buffer_list_iterator_free (it);
 }
 
 GST_END_TEST;
+#endif
 
 static Suite *
 gst_buffer_list_suite (void)
@@ -813,6 +762,7 @@ gst_buffer_list_suite (void)
   suite_add_tcase (s, tc_chain);
   tcase_add_checked_fixture (tc_chain, setup, cleanup);
   tcase_add_test (tc_chain, test_add_and_iterate);
+#if 0
   tcase_add_test (tc_chain, test_make_writable);
   tcase_add_test (tc_chain, test_copy);
   tcase_add_test (tc_chain, test_steal);
@@ -821,6 +771,7 @@ gst_buffer_list_suite (void)
   tcase_add_test (tc_chain, test_merge);
   tcase_add_test (tc_chain, test_foreach);
   tcase_add_test (tc_chain, test_list);
+#endif
 
   return s;
 }
index cd8b9d0..ab18800 100644 (file)
@@ -53,27 +53,6 @@ GST_START_TEST (test_from_string)
 
 GST_END_TEST;
 
-GST_START_TEST (test_buffer)
-{
-  GstCaps *c1;
-  GstBuffer *buffer;
-
-  buffer = gst_buffer_new_and_alloc (1000);
-  c1 = gst_caps_new_simple ("audio/x-raw-int",
-      "buffer", GST_TYPE_BUFFER, buffer, NULL);
-
-  GST_DEBUG ("caps: %" GST_PTR_FORMAT, c1);
-  gst_buffer_unref (buffer);
-
-  buffer = gst_buffer_new_and_alloc (1000);
-  gst_buffer_set_caps (buffer, c1);     /* doesn't give away our c1 ref */
-
-  gst_caps_unref (c1);
-  gst_buffer_unref (buffer);    /* Should now drop both references */
-}
-
-GST_END_TEST;
-
 GST_START_TEST (test_double_append)
 {
   GstStructure *s1;
@@ -987,7 +966,6 @@ gst_caps_suite (void)
   tcase_add_test (tc_chain, test_from_string);
   tcase_add_test (tc_chain, test_double_append);
   tcase_add_test (tc_chain, test_mutability);
-  tcase_add_test (tc_chain, test_buffer);
   tcase_add_test (tc_chain, test_static_caps);
   tcase_add_test (tc_chain, test_simplify);
   tcase_add_test (tc_chain, test_truncate);
index 57f3357..5bb45da 100644 (file)
@@ -164,6 +164,188 @@ GST_START_TEST (test_link_no_pads)
 
 GST_END_TEST;
 
+typedef struct _GstTestElement
+{
+  GstElement parent;
+
+} GstTestElement;
+
+typedef struct _GstTestElementClass
+{
+  GstElementClass parent;
+
+} GstTestElementClass;
+
+static void
+gst_test_element_class_init (GstTestElementClass * klass)
+{
+  GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
+  GstPadTemplate *templ;
+
+  gst_element_class_set_metadata (element_class, "Test element",
+      "Element", "Does nothing", "Foo Bar <foo@bar.com>");
+
+  fail_unless_equals_int (g_list_length (gst_element_class_get_pad_template_list
+          (element_class)), 0);
+
+  fail_unless (gst_element_class_get_pad_template (element_class,
+          "test") == NULL);
+
+  gst_element_class_add_pad_template (element_class,
+      gst_pad_template_new ("test", GST_PAD_SRC, GST_PAD_ALWAYS, GST_CAPS_ANY));
+
+  fail_unless_equals_int (g_list_length (gst_element_class_get_pad_template_list
+          (element_class)), 1);
+
+  fail_unless ((templ =
+          gst_element_class_get_pad_template (element_class, "test")) != NULL);
+  fail_unless (gst_caps_is_any (templ->caps));
+
+  gst_element_class_add_pad_template (element_class,
+      gst_pad_template_new ("test2", GST_PAD_SRC, GST_PAD_ALWAYS,
+          GST_CAPS_ANY));
+
+  fail_unless_equals_int (g_list_length (gst_element_class_get_pad_template_list
+          (element_class)), 2);
+
+  fail_unless ((templ =
+          gst_element_class_get_pad_template (element_class, "test2")) != NULL);
+  fail_unless (gst_caps_is_any (templ->caps));
+
+  /* Add "test" again, with NONE caps this time */
+  gst_element_class_add_pad_template (element_class,
+      gst_pad_template_new ("test", GST_PAD_SRC, GST_PAD_ALWAYS,
+          GST_CAPS_NONE));
+
+  fail_unless_equals_int (g_list_length (gst_element_class_get_pad_template_list
+          (element_class)), 2);
+
+  fail_unless ((templ =
+          gst_element_class_get_pad_template (element_class, "test")) != NULL);
+  fail_unless (gst_caps_is_empty (templ->caps));
+}
+
+static GType
+gst_test_element_get_type (void)
+{
+  static GType gst_test_element_type = G_TYPE_NONE;
+
+  if (gst_test_element_type == G_TYPE_NONE) {
+    static const GTypeInfo gst_test_element_info = {
+      sizeof (GstTestElementClass),
+      NULL,                     /* base_init */
+      NULL,                     /* base_finalize */
+      (GClassInitFunc) gst_test_element_class_init,
+      NULL,
+      NULL,
+      sizeof (GstTestElement),
+      0,
+      NULL,                     /* instance_init */
+      NULL
+    };
+
+    gst_test_element_type = g_type_register_static (GST_TYPE_ELEMENT,
+        "GstTestElement", &gst_test_element_info, 0);
+  }
+  return gst_test_element_type;
+}
+
+typedef struct _GstTestElement2
+{
+  GstTestElement parent;
+
+} GstTestElement2;
+
+typedef struct _GstTestElement2Class
+{
+  GstTestElementClass parent;
+
+} GstTestElement2Class;
+
+static void
+gst_test_element2_class_init (GstTestElement2Class * klass)
+{
+  GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
+  GstPadTemplate *templ;
+
+  gst_element_class_set_metadata (element_class, "Test element 2",
+      "Element", "Does nothing", "Foo Bar <foo@bar.com>");
+
+  fail_unless_equals_int (g_list_length (gst_element_class_get_pad_template_list
+          (element_class)), 2);
+
+  fail_unless ((templ =
+          gst_element_class_get_pad_template (element_class, "test")) != NULL);
+  fail_unless (gst_caps_is_empty (templ->caps));
+
+  fail_unless ((templ =
+          gst_element_class_get_pad_template (element_class, "test2")) != NULL);
+  fail_unless (gst_caps_is_any (templ->caps));
+
+  /* Add "test" pad with ANY caps, should have "test" pad with EMPTY caps before */
+  gst_element_class_add_pad_template (element_class,
+      gst_pad_template_new ("test", GST_PAD_SRC, GST_PAD_ALWAYS, GST_CAPS_ANY));
+
+  fail_unless_equals_int (g_list_length (gst_element_class_get_pad_template_list
+          (element_class)), 2);
+
+  fail_unless ((templ =
+          gst_element_class_get_pad_template (element_class, "test")) != NULL);
+  fail_unless (gst_caps_is_any (templ->caps));
+
+
+  gst_element_class_add_pad_template (element_class,
+      gst_pad_template_new ("test4", GST_PAD_SRC, GST_PAD_ALWAYS,
+          GST_CAPS_ANY));
+
+  fail_unless_equals_int (g_list_length (gst_element_class_get_pad_template_list
+          (element_class)), 3);
+
+  fail_unless ((templ =
+          gst_element_class_get_pad_template (element_class, "test4")) != NULL);
+  fail_unless (gst_caps_is_any (templ->caps));
+}
+
+static GType
+gst_test_element2_get_type (void)
+{
+  static GType gst_test_element2_type = G_TYPE_NONE;
+
+  if (gst_test_element2_type == G_TYPE_NONE) {
+    static const GTypeInfo gst_test_element2_info = {
+      sizeof (GstTestElement2Class),
+      NULL,                     /* base_init */
+      NULL,                     /* base_finalize */
+      (GClassInitFunc) gst_test_element2_class_init,
+      NULL,
+      NULL,
+      sizeof (GstTestElement2),
+      0,
+      NULL,                     /* instance_init */
+      NULL
+    };
+
+    gst_test_element2_type =
+        g_type_register_static (gst_test_element_get_type (), "GstTestElement2",
+        &gst_test_element2_info, 0);
+  }
+  return gst_test_element2_type;
+}
+
+
+GST_START_TEST (test_pad_templates)
+{
+  GstTestElement *test;
+  GstTestElement2 *test2;
+
+  test = g_object_new (gst_test_element_get_type (), NULL);
+  test2 = g_object_new (gst_test_element2_get_type (), NULL);
+
+  g_object_unref (test);
+  g_object_unref (test2);
+}
+
+GST_END_TEST;
 
 static Suite *
 gst_element_suite (void)
@@ -177,6 +359,7 @@ gst_element_suite (void)
   tcase_add_test (tc_chain, test_error_no_bus);
   tcase_add_test (tc_chain, test_link);
   tcase_add_test (tc_chain, test_link_no_pads);
+  tcase_add_test (tc_chain, test_pad_templates);
 
   return s;
 }
index 25dcfd1..e92e86f 100644 (file)
@@ -53,10 +53,9 @@ setup_factory (void)
   gst_plugin_feature_set_name (feature, "test");
 
   factory = GST_ELEMENT_FACTORY_CAST (feature);
-  factory->details.longname = g_strdup ("test");
-  factory->details.klass = g_strdup ("test");
-  factory->details.description = g_strdup ("test");
-  factory->details.author = g_strdup ("test");
+#if 0
+  gst_element_class_set_metadata (factory, "test", "test", "test", "test");
+#endif
 
   setup_pad_template (factory, &sink_template);
   setup_pad_template (factory, &src_template);
index 8c0829a..1c608c2 100644 (file)
@@ -39,12 +39,17 @@ GST_START_TEST (create_events)
   }
   /* FLUSH_STOP */
   {
-    event = gst_event_new_flush_stop ();
+    gboolean reset_time;
+
+    event = gst_event_new_flush_stop (TRUE);
     fail_if (event == NULL);
     fail_unless (GST_EVENT_TYPE (event) == GST_EVENT_FLUSH_STOP);
     fail_unless (GST_EVENT_IS_UPSTREAM (event));
     fail_unless (GST_EVENT_IS_DOWNSTREAM (event));
     fail_unless (GST_EVENT_IS_SERIALIZED (event));
+
+    gst_event_parse_flush_stop (event, &reset_time);
+    fail_unless (reset_time == TRUE);
     gst_event_unref (event);
   }
   /* EOS */
@@ -57,63 +62,31 @@ GST_START_TEST (create_events)
     fail_unless (GST_EVENT_IS_SERIALIZED (event));
     gst_event_unref (event);
   }
-  /* NEWSEGMENT */
+  /* SEGMENT */
   {
-    gdouble rate, applied_rate;
-    GstFormat format;
-    gint64 start, end, base;
-    gboolean update;
-
-    event =
-        gst_event_new_new_segment (FALSE, 0.5, GST_FORMAT_TIME, 1, G_MAXINT64,
-        0xdeadbeef);
-    fail_if (event == NULL);
-    fail_unless (GST_EVENT_TYPE (event) == GST_EVENT_NEWSEGMENT);
-    fail_if (GST_EVENT_IS_UPSTREAM (event));
-    fail_unless (GST_EVENT_IS_DOWNSTREAM (event));
-    fail_unless (GST_EVENT_IS_SERIALIZED (event));
-
-    gst_event_parse_new_segment (event, &update, &rate, &format, &start, &end,
-        &base);
-    fail_unless (update == FALSE);
-    fail_unless (rate == 0.5);
-    fail_unless (format == GST_FORMAT_TIME);
-    fail_unless (start == 1);
-    fail_unless (end == G_MAXINT64);
-    fail_unless (base == 0xdeadbeef);
-
-    /* Check that the new segment was created with applied_rate of 1.0 */
-    gst_event_parse_new_segment_full (event, &update, &rate, &applied_rate,
-        &format, &start, &end, &base);
+    GstSegment segment, parsed;
 
-    fail_unless (update == FALSE);
-    fail_unless (rate == 0.5);
-    fail_unless (applied_rate == 1.0);
-    fail_unless (format == GST_FORMAT_TIME);
-    fail_unless (start == 1);
-    fail_unless (end == G_MAXINT64);
-
-    gst_event_unref (event);
-
-    event =
-        gst_event_new_new_segment_full (TRUE, 0.75, 0.5, GST_FORMAT_BYTES, 0,
-        G_MAXINT64 - 1, 0xdeadbeef);
+    gst_segment_init (&segment, GST_FORMAT_TIME);
+    segment.rate = 0.5;
+    segment.applied_rate = 1.0;
+    segment.start = 1;
+    segment.stop = G_MAXINT64;
+    segment.time = 0xdeadbeef;
 
+    event = gst_event_new_segment (&segment);
     fail_if (event == NULL);
-    fail_unless (GST_EVENT_TYPE (event) == GST_EVENT_NEWSEGMENT);
+    fail_unless (GST_EVENT_TYPE (event) == GST_EVENT_SEGMENT);
     fail_if (GST_EVENT_IS_UPSTREAM (event));
     fail_unless (GST_EVENT_IS_DOWNSTREAM (event));
     fail_unless (GST_EVENT_IS_SERIALIZED (event));
 
-    gst_event_parse_new_segment_full (event, &update, &rate, &applied_rate,
-        &format, &start, &end, &base);
-
-    fail_unless (update == TRUE);
-    fail_unless (rate == 0.75);
-    fail_unless (applied_rate == 0.5);
-    fail_unless (format == GST_FORMAT_BYTES);
-    fail_unless (start == 0);
-    fail_unless (end == (G_MAXINT64 - 1));
+    gst_event_copy_segment (event, &parsed);
+    fail_unless (parsed.rate == 0.5);
+    fail_unless (parsed.applied_rate == 1.0);
+    fail_unless (parsed.format == GST_FORMAT_TIME);
+    fail_unless (parsed.start == 1);
+    fail_unless (parsed.stop == G_MAXINT64);
+    fail_unless (parsed.time == 0xdeadbeef);
 
     gst_event_unref (event);
   }
@@ -143,32 +116,32 @@ GST_START_TEST (create_events)
     GstClockTimeDiff ctd1 = G_GINT64_CONSTANT (10), ctd2;
     GstClockTime ct1 = G_GUINT64_CONSTANT (20), ct2;
 
-    event = gst_event_new_qos (p1, ctd1, ct1);
+    event = gst_event_new_qos (t1, p1, ctd1, ct1);
     fail_if (event == NULL);
     fail_unless (GST_EVENT_TYPE (event) == GST_EVENT_QOS);
     fail_unless (GST_EVENT_IS_UPSTREAM (event));
     fail_if (GST_EVENT_IS_DOWNSTREAM (event));
     fail_if (GST_EVENT_IS_SERIALIZED (event));
 
-    gst_event_parse_qos (event, &p2, &ctd2, &ct2);
+    gst_event_parse_qos (event, &t2, &p2, &ctd2, &ct2);
     fail_unless (p1 == p2);
     fail_unless (ctd1 == ctd2);
     fail_unless (ct1 == ct2);
-    gst_event_parse_qos_full (event, &t2, &p2, &ctd2, &ct2);
-    fail_unless (t2 == GST_QOS_TYPE_UNDERFLOW);
+    gst_event_parse_qos (event, &t2, &p2, &ctd2, &ct2);
+    fail_unless (t2 == GST_QOS_TYPE_THROTTLE);
     fail_unless (p1 == p2);
     fail_unless (ctd1 == ctd2);
     fail_unless (ct1 == ct2);
     gst_event_unref (event);
 
     ctd1 = G_GINT64_CONSTANT (-10);
-    event = gst_event_new_qos (p1, ctd1, ct1);
-    gst_event_parse_qos_full (event, &t2, &p2, &ctd2, &ct2);
-    fail_unless (t2 == GST_QOS_TYPE_OVERFLOW);
+    event = gst_event_new_qos (t1, p1, ctd1, ct1);
+    gst_event_parse_qos (event, &t2, &p2, &ctd2, &ct2);
+    fail_unless (t2 == GST_QOS_TYPE_THROTTLE);
     gst_event_unref (event);
 
-    event = gst_event_new_qos_full (t1, p1, ctd1, ct1);
-    gst_event_parse_qos_full (event, &t2, &p2, &ctd2, &ct2);
+    event = gst_event_new_qos (t1, p1, ctd1, ct1);
+    gst_event_parse_qos (event, &t2, &p2, &ctd2, &ct2);
     fail_unless (t2 == GST_QOS_TYPE_THROTTLE);
     fail_unless (p1 == p2);
     fail_unless (ctd1 == ctd2);
@@ -296,14 +269,16 @@ static GTimeVal sent_event_time;
 static GstEvent *got_event_before_q, *got_event_after_q;
 static GTimeVal got_event_time;
 
-static gboolean
-event_probe (GstPad * pad, GstMiniObject ** data, gpointer user_data)
+static GstProbeReturn
+event_probe (GstPad * pad, GstProbeType type, gpointer type_data,
+    gpointer user_data)
 {
+  GstMiniObject *data = type_data;
   gboolean before_q = (gboolean) GPOINTER_TO_INT (user_data);
 
-  fail_unless (GST_IS_EVENT (data));
+  GST_DEBUG ("event probe called %p", data);
 
-  GST_DEBUG ("event probe called");
+  fail_unless (GST_IS_EVENT (data));
 
   if (before_q) {
     switch (GST_EVENT_TYPE (GST_EVENT (data))) {
@@ -336,7 +311,66 @@ event_probe (GstPad * pad, GstMiniObject ** data, gpointer user_data)
     }
   }
 
-  return TRUE;
+  return GST_PROBE_OK;
+}
+
+
+typedef struct
+{
+  GMutex *lock;
+  GCond *cond;
+  gboolean signaled;
+} SignalData;
+
+static void
+signal_data_init (SignalData * data)
+{
+  GST_DEBUG ("init %p", data);
+  data->lock = g_mutex_new ();
+  data->cond = g_cond_new ();
+  data->signaled = FALSE;
+}
+
+static void
+signal_data_cleanup (SignalData * data)
+{
+  GST_DEBUG ("free %p", data);
+  g_mutex_free (data->lock);
+  g_cond_free (data->cond);
+}
+
+static void
+signal_data_signal (SignalData * data)
+{
+  g_mutex_lock (data->lock);
+  data->signaled = TRUE;
+  g_cond_broadcast (data->cond);
+  GST_DEBUG ("signaling %p", data);
+  g_mutex_unlock (data->lock);
+}
+
+static void
+signal_data_wait (SignalData * data)
+{
+  g_mutex_lock (data->lock);
+  GST_DEBUG ("signal wait %p", data);
+  while (!data->signaled)
+    g_cond_wait (data->cond, data->lock);
+  GST_DEBUG ("signal wait done %p", data);
+  g_mutex_unlock (data->lock);
+}
+
+static GstProbeReturn
+signal_blocked (GstPad * pad, GstProbeType type, gpointer type_data,
+    gpointer user_data)
+{
+  SignalData *data = (SignalData *) user_data;
+
+  GST_DEBUG ("signal called %p", data);
+  signal_data_signal (data);
+  GST_DEBUG ("signal done %p", data);
+
+  return GST_PROBE_OK;
 }
 
 static void test_event
@@ -346,6 +380,8 @@ static void test_event
   GstEvent *event;
   GstPad *peer;
   gint i;
+  SignalData data;
+  gulong id;
 
   got_event_before_q = got_event_after_q = NULL;
 
@@ -361,15 +397,22 @@ static void test_event
   got_event_time.tv_sec = 0;
   got_event_time.tv_usec = 0;
 
+  signal_data_init (&data);
+
   /* We block the pad so the stream lock is released and we can send the event */
-  fail_unless (gst_pad_set_blocked (fake_srcpad, TRUE) == TRUE);
+  id = gst_pad_add_probe (fake_srcpad, GST_PROBE_TYPE_BLOCK,
+      signal_blocked, &data, NULL);
+  fail_unless (id != 0);
+
+  signal_data_wait (&data);
 
   /* We send on the peer pad, since the pad is blocked */
+  GST_DEBUG ("sending event %p", event);
   fail_unless ((peer = gst_pad_get_peer (pad)) != NULL);
   gst_pad_send_event (peer, event);
   gst_object_unref (peer);
 
-  fail_unless (gst_pad_set_blocked (fake_srcpad, FALSE) == TRUE);
+  gst_pad_remove_probe (fake_srcpad, id);
 
   if (expect_before_q) {
     /* Wait up to 5 seconds for the event to appear */
@@ -404,6 +447,8 @@ static void test_event
     gst_event_unref (got_event_after_q);
 
   got_event_before_q = got_event_after_q = NULL;
+
+  signal_data_cleanup (&data);
 }
 
 static gint64
@@ -440,12 +485,12 @@ GST_START_TEST (send_custom_events)
 
   /* add pad-probes to faksrc.src and fakesink.sink */
   fail_if ((srcpad = gst_element_get_static_pad (fakesrc, "src")) == NULL);
-  gst_pad_add_event_probe (srcpad, (GCallback) event_probe,
-      GINT_TO_POINTER (TRUE));
+  gst_pad_add_probe (srcpad, GST_PROBE_TYPE_EVENT,
+      event_probe, GINT_TO_POINTER (TRUE), NULL);
 
   fail_if ((sinkpad = gst_element_get_static_pad (fakesink, "sink")) == NULL);
-  gst_pad_add_event_probe (sinkpad, (GCallback) event_probe,
-      GINT_TO_POINTER (FALSE));
+  gst_pad_add_probe (sinkpad, GST_PROBE_TYPE_EVENT,
+      event_probe, GINT_TO_POINTER (FALSE), NULL);
 
   /* Upstream events */
   test_event (pipeline, GST_EVENT_CUSTOM_UPSTREAM, sinkpad, TRUE, srcpad);
index 332f654..068a6e9 100644 (file)
@@ -191,7 +191,7 @@ GST_START_TEST (test_ghost_pads_notarget)
 
   /* check caps, untargetted pad should return ANY or the padtemplate caps 
    * when it was created from a template */
-  caps = gst_pad_get_caps (srcpad);
+  caps = gst_pad_get_caps (srcpad, NULL);
   fail_unless (gst_caps_is_any (caps));
   gst_caps_unref (caps);
 
@@ -478,8 +478,9 @@ typedef struct
   GCond *cond;
 } BlockData;
 
-static void
-block_callback (GstPad * pad, gboolean blocked, gpointer user_data)
+static GstProbeReturn
+block_callback (GstPad * pad, GstProbeType type, gpointer type_data,
+    gpointer user_data)
 {
   BlockData *block_data = (BlockData *) user_data;
 
@@ -487,6 +488,8 @@ block_callback (GstPad * pad, gboolean blocked, gpointer user_data)
   GST_DEBUG ("blocked\n");
   g_cond_signal (block_data->cond);
   g_mutex_unlock (block_data->mutex);
+
+  return GST_PROBE_OK;
 }
 
 GST_START_TEST (test_ghost_pads_block)
@@ -514,7 +517,8 @@ GST_START_TEST (test_ghost_pads_block)
   block_data.cond = g_cond_new ();
 
   g_mutex_lock (block_data.mutex);
-  gst_pad_set_blocked_async (srcghost, TRUE, block_callback, &block_data);
+  gst_pad_add_probe (srcghost, GST_PROBE_TYPE_BLOCK, block_callback,
+      &block_data, NULL);
   gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_PLAYING);
   /* and wait now */
   g_cond_wait (block_data.cond, block_data.mutex);
@@ -555,7 +559,8 @@ GST_START_TEST (test_ghost_pads_probes)
   block_data.cond = g_cond_new ();
 
   g_mutex_lock (block_data.mutex);
-  gst_pad_set_blocked_async (srcghost, TRUE, block_callback, &block_data);
+  gst_pad_add_probe (srcghost, GST_PROBE_TYPE_BLOCK, block_callback,
+      &block_data, NULL);
   gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_PLAYING);
   /* and wait now */
   g_cond_wait (block_data.cond, block_data.mutex);
@@ -576,16 +581,14 @@ GST_START_TEST (test_ghost_pads_new_from_template)
   GstPad *sinkpad, *ghostpad;
   GstPadTemplate *padtempl, *ghosttempl;
   GstCaps *padcaps, *ghostcaps, *newcaps;
-  GstCaps *copypadcaps;
 
   padcaps = gst_caps_from_string ("some/caps");
   fail_unless (padcaps != NULL);
   ghostcaps = gst_caps_from_string ("some/caps;some/other-caps");
   fail_unless (ghostcaps != NULL);
 
-  copypadcaps = gst_caps_copy (padcaps);
   padtempl = gst_pad_template_new ("padtempl", GST_PAD_SINK,
-      GST_PAD_ALWAYS, copypadcaps);
+      GST_PAD_ALWAYS, padcaps);
   fail_unless (padtempl != NULL);
   ghosttempl = gst_pad_template_new ("ghosttempl", GST_PAD_SINK,
       GST_PAD_ALWAYS, ghostcaps);
@@ -600,11 +603,12 @@ GST_START_TEST (test_ghost_pads_new_from_template)
   fail_unless (GST_PAD_PAD_TEMPLATE (ghostpad) == ghosttempl);
 
   /* check ghostpad caps are from the sinkpad */
-  newcaps = gst_pad_get_caps (ghostpad);
+  newcaps = gst_pad_get_caps (ghostpad, NULL);
   fail_unless (newcaps != NULL);
   fail_unless (gst_caps_is_equal (newcaps, padcaps));
   gst_caps_unref (newcaps);
   gst_caps_unref (padcaps);
+  gst_caps_unref (ghostcaps);
 
   gst_object_unref (sinkpad);
   gst_object_unref (ghostpad);
@@ -620,21 +624,17 @@ GST_START_TEST (test_ghost_pads_new_no_target_from_template)
   GstPad *sinkpad, *ghostpad;
   GstPadTemplate *padtempl, *ghosttempl;
   GstCaps *padcaps, *ghostcaps, *newcaps;
-  GstCaps *copypadcaps, *copyghostcaps;
 
   padcaps = gst_caps_from_string ("some/caps");
   fail_unless (padcaps != NULL);
   ghostcaps = gst_caps_from_string ("some/caps;some/other-caps");
   fail_unless (ghostcaps != NULL);
 
-  copypadcaps = gst_caps_copy (padcaps);
-  copyghostcaps = gst_caps_copy (ghostcaps);
-
   padtempl = gst_pad_template_new ("padtempl", GST_PAD_SINK,
-      GST_PAD_ALWAYS, copypadcaps);
+      GST_PAD_ALWAYS, padcaps);
   fail_unless (padtempl != NULL);
   ghosttempl = gst_pad_template_new ("ghosttempl", GST_PAD_SINK,
-      GST_PAD_ALWAYS, copyghostcaps);
+      GST_PAD_ALWAYS, ghostcaps);
 
   sinkpad = gst_pad_new_from_template (padtempl, "sinkpad");
   fail_unless (sinkpad != NULL);
@@ -646,7 +646,7 @@ GST_START_TEST (test_ghost_pads_new_no_target_from_template)
   fail_unless (GST_PAD_PAD_TEMPLATE (ghostpad) == ghosttempl);
 
   /* check ghostpad caps are from the ghostpad template */
-  newcaps = gst_pad_get_caps (ghostpad);
+  newcaps = gst_pad_get_caps (ghostpad, NULL);
   fail_unless (newcaps != NULL);
   fail_unless (gst_caps_is_equal (newcaps, ghostcaps));
   gst_caps_unref (newcaps);
@@ -654,7 +654,7 @@ GST_START_TEST (test_ghost_pads_new_no_target_from_template)
   fail_unless (gst_ghost_pad_set_target ((GstGhostPad *) ghostpad, sinkpad));
 
   /* check ghostpad caps are now from the target pad */
-  newcaps = gst_pad_get_caps (ghostpad);
+  newcaps = gst_pad_get_caps (ghostpad, NULL);
   fail_unless (newcaps != NULL);
   fail_unless (gst_caps_is_equal (newcaps, padcaps));
   gst_caps_unref (newcaps);
@@ -688,10 +688,12 @@ GST_START_TEST (test_ghost_pads_forward_setcaps)
   templ_caps = gst_caps_from_string ("meh; muh");
   src_template = gst_pad_template_new ("src", GST_PAD_SRC,
       GST_PAD_ALWAYS, templ_caps);
+  gst_caps_unref (templ_caps);
 
   templ_caps = gst_caps_from_string ("muh; meh");
   sink_template = gst_pad_template_new ("sink", GST_PAD_SINK,
       GST_PAD_ALWAYS, templ_caps);
+  gst_caps_unref (templ_caps);
 
   src = gst_pad_new_from_template (src_template, "src");
   sink = gst_pad_new_from_template (sink_template, "sink");
@@ -703,17 +705,19 @@ GST_START_TEST (test_ghost_pads_forward_setcaps)
       G_CALLBACK (ghost_notify_caps), &notify_counter);
   fail_unless (gst_pad_link (ghost, sink) == GST_PAD_LINK_OK);
 
+  /* Activate pads for caps forwarding/setting to work */
+  gst_pad_set_active (src, TRUE);
+  gst_pad_set_active (ghost, TRUE);
+
   caps1 = gst_caps_from_string ("meh");
   fail_unless (gst_pad_set_caps (src, caps1));
-  caps2 = GST_PAD_CAPS (ghost);
+  caps2 = gst_pad_get_current_caps (ghost);
   fail_unless (gst_caps_is_equal (caps1, caps2));
   fail_unless_equals_int (notify_counter, 1);
 
   gst_object_unref (ghost);
   gst_caps_unref (caps1);
 
-  fail_unless (gst_pad_set_caps (src, NULL));
-
   /* source 2, setting the caps on the ghostpad does not influence the caps of
    * the target */
   notify_counter = 0;
@@ -722,10 +726,15 @@ GST_START_TEST (test_ghost_pads_forward_setcaps)
       G_CALLBACK (ghost_notify_caps), &notify_counter);
   fail_unless (gst_pad_link (ghost, sink) == GST_PAD_LINK_OK);
 
+  gst_pad_set_active (ghost, TRUE);
+  gst_pad_set_active (sink, TRUE);
+
   caps1 = gst_caps_from_string ("meh");
   fail_unless (gst_pad_set_caps (ghost, caps1));
-  caps2 = GST_PAD_CAPS (src);
+#if 0
+  caps2 = gst_pad_get_current_caps (src);
   fail_unless (caps2 == NULL);
+#endif
   fail_unless_equals_int (notify_counter, 1);
 
   gst_object_unref (ghost);
@@ -740,26 +749,38 @@ GST_START_TEST (test_ghost_pads_forward_setcaps)
       G_CALLBACK (ghost_notify_caps), &notify_counter);
   fail_unless (gst_pad_link (src, ghost) == GST_PAD_LINK_OK);
 
+  gst_pad_set_active (src, TRUE);
+  gst_pad_set_active (ghost, TRUE);
+
   caps1 = gst_caps_from_string ("muh");
   fail_unless (gst_pad_set_caps (ghost, caps1));
-  caps2 = GST_PAD_CAPS (sink);
+  caps2 = gst_pad_get_current_caps (sink);
   fail_unless (gst_caps_is_equal (caps1, caps2));
   fail_unless_equals_int (notify_counter, 1);
 
   gst_object_unref (ghost);
   gst_caps_unref (caps1);
 
+  /* clear caps on pads */
+  gst_pad_set_active (src, FALSE);
+  gst_pad_set_active (src, TRUE);
+  gst_pad_set_active (sink, FALSE);
+  gst_pad_set_active (sink, TRUE);
+
   /* sink pad 2, setting caps just on the target pad should not influence the caps
    * on the ghostpad. */
   notify_counter = 0;
   ghost = gst_ghost_pad_new ("ghostsink", sink);
+  fail_unless (gst_pad_get_current_caps (ghost) == NULL);
   g_signal_connect (ghost, "notify::caps",
       G_CALLBACK (ghost_notify_caps), &notify_counter);
   fail_unless (gst_pad_link (src, ghost) == GST_PAD_LINK_OK);
 
+  gst_pad_set_active (ghost, TRUE);
+
   caps1 = gst_caps_from_string ("muh");
   fail_unless (gst_pad_set_caps (sink, caps1));
-  caps2 = GST_PAD_CAPS (ghost);
+  caps2 = gst_pad_get_current_caps (ghost);
   fail_unless (caps2 == NULL);
   fail_unless_equals_int (notify_counter, 0);
 
@@ -819,11 +840,13 @@ GST_START_TEST (test_ghost_pads_sink_link_unlink)
   fail_unless (padcaps != NULL);
   srctempl = gst_pad_template_new ("srctempl", GST_PAD_SRC,
       GST_PAD_ALWAYS, padcaps);
+  gst_caps_unref (padcaps);
 
   padcaps = gst_caps_from_string ("some/caps");
   fail_unless (padcaps != NULL);
   sinktempl = gst_pad_template_new ("sinktempl", GST_PAD_SINK,
       GST_PAD_ALWAYS, padcaps);
+  gst_caps_unref (padcaps);
 
   srcpad = gst_pad_new_from_template (srctempl, "src");
   fail_unless (srcpad != NULL);
@@ -891,11 +914,13 @@ GST_START_TEST (test_ghost_pads_src_link_unlink)
   fail_unless (padcaps != NULL);
   srctempl = gst_pad_template_new ("srctempl", GST_PAD_SRC,
       GST_PAD_ALWAYS, padcaps);
+  gst_caps_unref (padcaps);
 
   padcaps = gst_caps_from_string ("some/caps");
   fail_unless (padcaps != NULL);
   sinktempl = gst_pad_template_new ("sinktempl", GST_PAD_SINK,
       GST_PAD_ALWAYS, padcaps);
+  gst_caps_unref (padcaps);
 
   srcpad = gst_pad_new_from_template (srctempl, "src");
   fail_unless (srcpad != NULL);
index a29a433..e7757d8 100644 (file)
@@ -127,10 +127,13 @@ GST_START_TEST (info_segment_format_printf_extension)
 
     gst_segment_init (&segment, GST_FORMAT_TIME);
 
-    gst_segment_set_newsegment_full (&segment, FALSE, 1.0, 2.0,
-        GST_FORMAT_TIME, 0, 5 * 60 * GST_SECOND, 0);
+    segment.rate = 1.0;
+    segment.applied_rate = 2.0;
+    segment.start = 0;
+    segment.stop = 5 * 60 * GST_SECOND;
+    segment.time = 0;
 
-    segment.last_stop = 2 * GST_SECOND;
+    segment.position = 2 * GST_SECOND;
     segment.duration = 90 * 60 * GST_SECOND;
 
     GST_LOG ("TIME: %" GST_SEGMENT_FORMAT, &segment);
@@ -142,8 +145,11 @@ GST_START_TEST (info_segment_format_printf_extension)
 
     gst_segment_init (&segment, GST_FORMAT_BYTES);
 
-    gst_segment_set_newsegment_full (&segment, FALSE, 1.0, 1.0,
-        GST_FORMAT_BYTES, 0, 9999999, 0);
+    segment.rate = 1.0;
+    segment.applied_rate = 1.0;
+    segment.start = 0;
+    segment.stop = 9999999;
+    segment.time = 0;
 
     GST_LOG ("BYTE: %" GST_SEGMENT_FORMAT, &segment);
   }
@@ -154,8 +160,11 @@ GST_START_TEST (info_segment_format_printf_extension)
 
     gst_segment_init (&segment, 98765432);
 
-    gst_segment_set_newsegment_full (&segment, FALSE, 1.0, 1.0,
-        GST_FORMAT_BYTES, 0, 987654321, 0);
+    segment.rate = 1.0;
+    segment.applied_rate = 1.0;
+    segment.start = 0;
+    segment.stop = 987654321;
+    segment.time = 0;
 
     GST_LOG ("UNKNOWN: %" GST_SEGMENT_FORMAT, &segment);
   }
index 8a2b464..e6d9389 100644 (file)
@@ -44,13 +44,13 @@ GST_START_TEST (test_manual_iteration)
   GMutex *m;
   GstIterator *iter;
   GstIteratorResult res;
-  gpointer item;
+  GValue item = { 0, };
   gint i = 0;
 
   l = make_list_of_ints (NUM_ELEMENTS);
   m = g_mutex_new ();
 
-  iter = gst_iterator_new_list (G_TYPE_INT, m, &cookie, &l, NULL, NULL, NULL);
+  iter = gst_iterator_new_list (G_TYPE_POINTER, m, &cookie, &l, NULL, NULL);
 
   fail_unless (iter != NULL);
 
@@ -58,7 +58,8 @@ GST_START_TEST (test_manual_iteration)
     res = gst_iterator_next (iter, &item);
     if (i < NUM_ELEMENTS) {
       fail_unless (res == GST_ITERATOR_OK);
-      fail_unless (GPOINTER_TO_INT (item) == i);
+      fail_unless (GPOINTER_TO_INT (g_value_get_pointer (&item)) == i);
+      g_value_reset (&item);
       i++;
       continue;
     } else {
@@ -66,8 +67,8 @@ GST_START_TEST (test_manual_iteration)
       break;
     }
   }
-
   /* clean up */
+  g_value_unset (&item);
   gst_iterator_free (iter);
   g_mutex_free (m);
   g_list_free (l);
@@ -82,14 +83,14 @@ GST_START_TEST (test_resync)
   GMutex *m;
   GstIterator *iter;
   GstIteratorResult res;
-  gpointer item;
+  GValue item = { 0, };
   gint i = 0;
   gboolean hacked_list = FALSE;
 
   l = make_list_of_ints (NUM_ELEMENTS);
   m = g_mutex_new ();
 
-  iter = gst_iterator_new_list (G_TYPE_INT, m, &cookie, &l, NULL, NULL, NULL);
+  iter = gst_iterator_new_list (G_TYPE_POINTER, m, &cookie, &l, NULL, NULL);
 
   fail_unless (iter != NULL);
 
@@ -97,12 +98,14 @@ GST_START_TEST (test_resync)
     res = gst_iterator_next (iter, &item);
     if (i < NUM_ELEMENTS / 2) {
       fail_unless (res == GST_ITERATOR_OK);
-      fail_unless (GPOINTER_TO_INT (item) == i);
+      fail_unless (GPOINTER_TO_INT (g_value_get_pointer (&item)) == i);
+      g_value_reset (&item);
       i++;
       continue;
     } else if (!hacked_list) {
       /* here's where we test resync */
       fail_unless (res == GST_ITERATOR_OK);
+      g_value_reset (&item);
       l = g_list_prepend (l, GINT_TO_POINTER (-1));
       cookie++;
       hacked_list = TRUE;
@@ -112,12 +115,14 @@ GST_START_TEST (test_resync)
       gst_iterator_resync (iter);
       res = gst_iterator_next (iter, &item);
       fail_unless (res == GST_ITERATOR_OK);
-      fail_unless (GPOINTER_TO_INT (item) == -1);
+      fail_unless (GPOINTER_TO_INT (g_value_get_pointer (&item)) == -1);
+      g_value_reset (&item);
       break;
     }
   }
 
   /* clean up */
+  g_value_unset (&item);
   gst_iterator_free (iter);
   g_mutex_free (m);
   g_list_free (l);
@@ -126,9 +131,10 @@ GST_START_TEST (test_resync)
 GST_END_TEST;
 
 static gboolean
-add_fold_func (gpointer item, GValue * ret, gpointer user_data)
+add_fold_func (const GValue * item, GValue * ret, gpointer user_data)
 {
-  g_value_set_int (ret, g_value_get_int (ret) + GPOINTER_TO_INT (item));
+  g_value_set_int (ret,
+      g_value_get_int (ret) + GPOINTER_TO_INT (g_value_get_pointer (item)));
   return TRUE;
 }
 
@@ -144,7 +150,7 @@ GST_START_TEST (test_fold)
 
   l = make_list_of_ints (NUM_ELEMENTS);
   m = g_mutex_new ();
-  iter = gst_iterator_new_list (G_TYPE_INT, m, &cookie, &l, NULL, NULL, NULL);
+  iter = gst_iterator_new_list (G_TYPE_POINTER, m, &cookie, &l, NULL, NULL);
   fail_unless (iter != NULL);
 
   expected = 0;
@@ -171,27 +177,33 @@ GST_START_TEST (test_single)
 {
   GstIterator *it;
   GstStructure *s = gst_structure_new ("test", NULL);
+  GValue v = { 0, };
   GstStructure *i;
 
-  it = gst_iterator_new_single (GST_TYPE_STRUCTURE, s,
-      (GstCopyFunction) gst_structure_copy, (GFreeFunc) gst_structure_free);
+  g_value_init (&v, GST_TYPE_STRUCTURE);
+  g_value_set_boxed (&v, s);
+  it = gst_iterator_new_single (GST_TYPE_STRUCTURE, &v);
+  g_value_reset (&v);
 
-  fail_unless (gst_iterator_next (it, (gpointer) & i) == GST_ITERATOR_OK);
+  fail_unless (gst_iterator_next (it, &v) == GST_ITERATOR_OK);
+  i = g_value_get_boxed (&v);
   fail_unless (strcmp (gst_structure_get_name (s),
           gst_structure_get_name (i)) == 0);
-  gst_structure_free (i);
   i = NULL;
-  fail_unless (gst_iterator_next (it, (gpointer) & i) == GST_ITERATOR_DONE);
-  fail_unless (i == NULL);
+  g_value_reset (&v);
+
+  fail_unless (gst_iterator_next (it, &v) == GST_ITERATOR_DONE);
+  fail_unless (g_value_get_boxed (&v) == NULL);
 
   gst_iterator_free (it);
   gst_structure_free (s);
 
-  it = gst_iterator_new_single (GST_TYPE_STRUCTURE, NULL,
-      (GstCopyFunction) gst_structure_copy, (GFreeFunc) gst_structure_free);
+  it = gst_iterator_new_single (GST_TYPE_STRUCTURE, NULL);
+
+  fail_unless (gst_iterator_next (it, &v) == GST_ITERATOR_DONE);
+  fail_unless (g_value_get_boxed (&v) == NULL);
 
-  fail_unless (gst_iterator_next (it, (gpointer) & i) == GST_ITERATOR_DONE);
-  fail_unless (i == NULL);
+  g_value_reset (&v);
 
   gst_iterator_free (it);
 }
diff --git a/tests/check/gst/gstmeta.c b/tests/check/gst/gstmeta.c
new file mode 100644 (file)
index 0000000..69eb370
--- /dev/null
@@ -0,0 +1,200 @@
+/* GStreamer
+ *
+ * unit test for GstMeta
+ *
+ * Copyright (C) <2009> Wim Taymans <wim.taymans@gmail.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#ifdef HAVE_VALGRIND_H
+# include <valgrind/valgrind.h>
+#else
+# define RUNNING_ON_VALGRIND FALSE
+#endif
+
+#include <gst/check/gstcheck.h>
+
+/* test metadata for PTS/DTS and duration */
+typedef struct
+{
+  GstMeta meta;
+
+  GstClockTime pts;
+  GstClockTime dts;
+  GstClockTime duration;
+  GstClockTime clock_rate;
+} GstMetaTest;
+
+static const GstMetaInfo *gst_meta_test_get_info (void);
+#define GST_META_TEST_INFO (gst_meta_test_get_info())
+
+#define GST_META_TEST_GET(buf) ((GstMetaTest *)gst_buffer_get_meta(buf,GST_META_TEST_INFO))
+#define GST_META_TEST_ADD(buf) ((GstMetaTest *)gst_buffer_add_meta(buf,GST_META_TEST_INFO,NULL))
+
+#if 0
+/* unused currently. This is a user function to fill the metadata with default
+ * values. We don't call this from the init function because the user is mostly
+ * likely going to override the values immediately after */
+static void
+gst_meta_test_init (GstMetaTest * meta)
+{
+  meta->pts = GST_CLOCK_TIME_NONE;
+  meta->dts = GST_CLOCK_TIME_NONE;
+  meta->duration = GST_CLOCK_TIME_NONE;
+  meta->clock_rate = GST_SECOND;
+}
+#endif
+
+static void
+test_init_func (GstMetaTest * meta, GstBuffer * buffer)
+{
+  GST_DEBUG ("init called on buffer %p, meta %p", buffer, meta);
+  /* nothing to init really, the init function is mostly for allocating
+   * additional memory or doing special setup as part of adding the metadata to
+   * the buffer*/
+}
+
+static void
+test_free_func (GstMetaTest * meta, GstBuffer * buffer)
+{
+  GST_DEBUG ("free called on buffer %p, meta %p", buffer, meta);
+  /* nothing to free really */
+}
+
+static void
+test_copy_func (GstBuffer * copybuf, GstMetaTest * meta,
+    GstBuffer * buffer, gsize offset, gsize size)
+{
+  GstMetaTest *test;
+
+  GST_DEBUG ("copy called from buffer %p to %p, meta %p, %u-%u", buffer,
+      copybuf, meta, offset, size);
+
+  test = GST_META_TEST_ADD (copybuf);
+  if (offset == 0) {
+    /* same offset, copy timestamps */
+    test->pts = meta->pts;
+    test->dts = meta->dts;
+    if (size == gst_buffer_get_size (buffer)) {
+      /* same size, copy duration */
+      test->duration = meta->duration;
+    } else {
+      /* else clear */
+      test->duration = GST_CLOCK_TIME_NONE;
+    }
+  } else {
+    test->pts = -1;
+    test->dts = -1;
+    test->duration = -1;
+  }
+  test->clock_rate = meta->clock_rate;
+}
+
+static const GstMetaInfo *
+gst_meta_test_get_info (void)
+{
+  static const GstMetaInfo *meta_test_info = NULL;
+
+  if (meta_test_info == NULL) {
+    meta_test_info = gst_meta_register ("GstMetaTest", "GstMetaTest",
+        sizeof (GstMetaTest),
+        (GstMetaInitFunction) test_init_func,
+        (GstMetaFreeFunction) test_free_func,
+        (GstMetaCopyFunction) test_copy_func, (GstMetaTransformFunction) NULL);
+  }
+  return meta_test_info;
+}
+
+GST_START_TEST (test_meta_test)
+{
+  GstBuffer *buffer, *copy, *subbuf;
+  GstMetaTest *meta;
+  gpointer data;
+
+  buffer = gst_buffer_new_and_alloc (4);
+  fail_if (buffer == NULL);
+
+  data = gst_buffer_map (buffer, NULL, NULL, GST_MAP_WRITE);
+  fail_if (data == NULL);
+  memset (data, 0, 4);
+  gst_buffer_unmap (buffer, data, 4);
+
+  /* add some metadata */
+  meta = GST_META_TEST_ADD (buffer);
+  fail_if (meta == NULL);
+  /* fill some values */
+  meta->pts = 1000;
+  meta->dts = 2000;
+  meta->duration = 1000;
+  meta->clock_rate = 1000;
+
+  /* copy of the buffer */
+  copy = gst_buffer_copy (buffer);
+  /* get metadata of the buffer */
+  meta = GST_META_TEST_GET (copy);
+  fail_if (meta == NULL);
+  fail_if (meta->pts != 1000);
+  fail_if (meta->dts != 2000);
+  fail_if (meta->duration != 1000);
+  fail_if (meta->clock_rate != 1000);
+  gst_buffer_unref (copy);
+
+  /* make subbuffer */
+  subbuf = gst_buffer_copy_region (buffer, GST_BUFFER_COPY_ALL, 0, 1);
+  /* get metadata of the buffer */
+  meta = GST_META_TEST_GET (subbuf);
+  fail_if (meta == NULL);
+  fail_if (meta->pts != 1000);
+  fail_if (meta->dts != 2000);
+  fail_if (meta->duration != -1);
+  fail_if (meta->clock_rate != 1000);
+  gst_buffer_unref (subbuf);
+
+  /* make another subbuffer */
+  subbuf = gst_buffer_copy_region (buffer, GST_BUFFER_COPY_ALL, 1, 3);
+  /* get metadata of the buffer */
+  meta = GST_META_TEST_GET (subbuf);
+  fail_if (meta == NULL);
+  fail_if (meta->pts != -1);
+  fail_if (meta->dts != -1);
+  fail_if (meta->duration != -1);
+  fail_if (meta->clock_rate != 1000);
+  gst_buffer_unref (subbuf);
+
+  /* clean up */
+  gst_buffer_unref (buffer);
+}
+
+GST_END_TEST;
+
+static Suite *
+gst_buffermeta_suite (void)
+{
+  Suite *s = suite_create ("GstMeta");
+  TCase *tc_chain = tcase_create ("general");
+
+  suite_add_tcase (s, tc_chain);
+  tcase_add_test (tc_chain, test_meta_test);
+
+  return s;
+}
+
+GST_CHECK_MAIN (gst_buffermeta);
index 0a7a731..237f7e4 100644 (file)
@@ -29,10 +29,10 @@ GST_START_TEST (test_copy)
 
   buffer = gst_buffer_new_and_alloc (4);
 
-  copy = GST_BUFFER (gst_mini_object_copy (GST_MINI_OBJECT (buffer)));
+  copy = GST_BUFFER (gst_mini_object_copy (GST_MINI_OBJECT_CAST (buffer)));
 
   fail_if (copy == NULL, "Copy of buffer returned NULL");
-  fail_unless (GST_BUFFER_SIZE (copy) == 4,
+  fail_unless (gst_buffer_get_size (copy) == 4,
       "Copy of buffer has different size");
 }
 
@@ -44,18 +44,11 @@ GST_START_TEST (test_is_writable)
   GstMiniObject *mobj;
 
   buffer = gst_buffer_new_and_alloc (4);
-  mobj = GST_MINI_OBJECT (buffer);
+  mobj = GST_MINI_OBJECT_CAST (buffer);
 
   fail_unless (gst_mini_object_is_writable (mobj),
       "A buffer with one ref should be writable");
 
-  GST_MINI_OBJECT_FLAG_SET (mobj, GST_MINI_OBJECT_FLAG_READONLY);
-  fail_if (gst_mini_object_is_writable (mobj),
-      "A buffer with READONLY set should not be writable");
-  GST_MINI_OBJECT_FLAG_UNSET (mobj, GST_MINI_OBJECT_FLAG_READONLY);
-  fail_unless (gst_mini_object_is_writable (mobj),
-      "A buffer with one ref and READONLY not set should be writable");
-
   fail_if (gst_mini_object_ref (mobj) == NULL, "Could not ref the mobj");
 
   fail_if (gst_mini_object_is_writable (mobj),
@@ -70,7 +63,7 @@ GST_START_TEST (test_make_writable)
   GstMiniObject *mobj, *mobj2, *mobj3;
 
   buffer = gst_buffer_new_and_alloc (4);
-  mobj = GST_MINI_OBJECT (buffer);
+  mobj = GST_MINI_OBJECT_CAST (buffer);
 
   mobj2 = gst_mini_object_make_writable (mobj);
   fail_unless (GST_IS_BUFFER (mobj2), "make_writable did not return a buffer");
@@ -123,7 +116,7 @@ GST_START_TEST (test_ref_threaded)
 
   buffer = gst_buffer_new_and_alloc (4);
 
-  mobj = GST_MINI_OBJECT (buffer);
+  mobj = GST_MINI_OBJECT_CAST (buffer);
 
   MAIN_START_THREADS (num_threads, thread_ref, mobj);
 
@@ -202,21 +195,12 @@ GST_START_TEST (test_weak_ref)
 
 GST_END_TEST;
 
+#if 0
 /* ======== recycle test ======== */
 
 static gint recycle_buffer_count = 10;
 
-#define MY_TYPE_RECYCLE_BUFFER (my_recycle_buffer_get_type ())
-
-#define MY_IS_RECYCLE_BUFFER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \
-    MY_TYPE_RECYCLE_BUFFER))
-#define MY_RECYCLE_BUFFER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), \
-    MY_TYPE_RECYCLE_BUFFER, MyRecycleBuffer))
-#define MY_RECYCLE_BUFFER_CAST(obj) ((MyRecycleBuffer *) (obj))
-
 typedef struct _MyBufferPool MyBufferPool;
-typedef struct _MyRecycleBuffer MyRecycleBuffer;
-typedef struct _MyRecycleBufferClass MyRecycleBufferClass;
 
 struct _MyBufferPool
 {
@@ -225,18 +209,6 @@ struct _MyBufferPool
   volatile gboolean is_closed;
 };
 
-struct _MyRecycleBuffer
-{
-  GstBuffer buffer;
-
-  MyBufferPool *pool;
-};
-
-struct _MyRecycleBufferClass
-{
-  GstBufferClass parent_class;
-};
-
 static void my_recycle_buffer_destroy (MyRecycleBuffer * buf);
 
 static MyBufferPool *
@@ -279,28 +251,10 @@ my_buffer_pool_drain_one (MyBufferPool * self)
   return buf;
 }
 
-GType my_recycle_buffer_get_type (void);
-G_DEFINE_TYPE (MyRecycleBuffer, my_recycle_buffer, GST_TYPE_BUFFER);
-
-static void my_recycle_buffer_finalize (GstMiniObject * mini_object);
-
-static void
-my_recycle_buffer_class_init (MyRecycleBufferClass * klass)
-{
-  GstMiniObjectClass *miniobject_class = GST_MINI_OBJECT_CLASS (klass);
-
-  miniobject_class->finalize = my_recycle_buffer_finalize;
-}
-
-static void
-my_recycle_buffer_init (MyRecycleBuffer * self)
-{
-}
-
 static void
 my_recycle_buffer_finalize (GstMiniObject * mini_object)
 {
-  MyRecycleBuffer *self = MY_RECYCLE_BUFFER_CAST (mini_object);
+  GstBuffer *self = GST_BUFFER_CAST (mini_object);
 
   if (self->pool != NULL) {
     my_buffer_pool_add (self->pool, GST_BUFFER_CAST (self));
@@ -314,10 +268,11 @@ my_recycle_buffer_finalize (GstMiniObject * mini_object)
 static GstBuffer *
 my_recycle_buffer_new (MyBufferPool * pool)
 {
-  MyRecycleBuffer *buf;
+  GstBuffer *buf;
 
-  buf = MY_RECYCLE_BUFFER (gst_mini_object_new (MY_TYPE_RECYCLE_BUFFER));
-  buf->pool = pool;
+  buf = gst_buffer_new ();
+
+  //buf->pool = pool;
 
   return GST_BUFFER_CAST (buf);
 }
@@ -376,6 +331,7 @@ GST_START_TEST (test_recycle_threaded)
 }
 
 GST_END_TEST;
+#endif
 
 /* ======== value collection test ======== */
 typedef struct _MyFoo
@@ -410,7 +366,7 @@ my_foo_get_property (GObject * object, guint prop_id, GValue * value,
   g_assert (prop_id == PROP_BUFFER);
 
   new_buf = gst_buffer_new_and_alloc (1024);
-  gst_value_set_mini_object (value, GST_MINI_OBJECT (new_buf));
+  g_value_set_boxed (value, GST_MINI_OBJECT (new_buf));
   gst_buffer_unref (new_buf);
 }
 
@@ -422,8 +378,7 @@ my_foo_set_property (GObject * object, guint prop_id, const GValue * value,
 
   g_assert (prop_id == PROP_BUFFER);
 
-  mini_obj = gst_value_get_mini_object (value);
-  g_assert (GST_IS_MINI_OBJECT (mini_obj));
+  mini_obj = g_value_get_boxed (value);
   g_assert (GST_IS_BUFFER (mini_obj));
 
 #if 0
@@ -445,7 +400,7 @@ my_foo_class_init (MyFooClass * klass)
   gobject_klass->set_property = my_foo_set_property;
 
   g_object_class_install_property (gobject_klass, PROP_BUFFER,
-      gst_param_spec_mini_object ("buffer", "Buffer",
+      g_param_spec_boxed ("buffer", "Buffer",
           "a newly created GstBuffer", GST_TYPE_BUFFER, G_PARAM_READWRITE));
 }
 
@@ -481,9 +436,9 @@ GST_START_TEST (test_dup_null_mini_object)
 
   g_value_init (&value, GST_TYPE_BUFFER);
 
-  gst_value_set_mini_object (&value, NULL);
+  g_value_set_boxed (&value, NULL);
 
-  mo = gst_value_dup_mini_object (&value);
+  mo = GST_MINI_OBJECT_CAST (g_value_dup_boxed (&value));
   g_assert (mo == NULL);
 
   g_value_unset (&value);
@@ -507,7 +462,7 @@ gst_mini_object_suite (void)
   tcase_add_test (tc_chain, test_ref_threaded);
   tcase_add_test (tc_chain, test_unref_threaded);
   tcase_add_test (tc_chain, test_weak_ref);
-  tcase_add_test (tc_chain, test_recycle_threaded);
+  //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;
index d5956db..6f7ccb8 100644 (file)
@@ -360,7 +360,7 @@ GST_START_TEST (test_fake_object_parentage)
   fail_if (object1 == NULL, "Failed to create instance of GstFakeObject");
   fail_unless (GST_IS_OBJECT (object1),
       "GstFakeObject instance is not a GstObject");
-  fail_unless (GST_OBJECT_IS_FLOATING (object1),
+  fail_unless (g_object_is_floating (object1),
       "GstFakeObject instance is not floating");
 
   /* check the parent */
@@ -374,7 +374,7 @@ GST_START_TEST (test_fake_object_parentage)
   fail_if (result == TRUE, "GstFakeObject accepted itself as parent");
 
   /* should still be floating */
-  fail_unless (GST_OBJECT_IS_FLOATING (object1),
+  fail_unless (g_object_is_floating (object1),
       "GstFakeObject instance is not floating");
 
   /* create another object */
@@ -383,7 +383,7 @@ GST_START_TEST (test_fake_object_parentage)
       "Failed to create another instance of GstFakeObject");
   fail_unless (GST_IS_OBJECT (object2),
       "second GstFakeObject instance is not a GstObject");
-  fail_unless (GST_OBJECT_IS_FLOATING (object1),
+  fail_unless (g_object_is_floating (object1),
       "GstFakeObject instance is not floating");
 
   /* try to set other object as parent */
@@ -392,10 +392,10 @@ GST_START_TEST (test_fake_object_parentage)
       "GstFakeObject could not accept other object as parent");
 
   /* should not be floating anymore */
-  fail_if (GST_OBJECT_IS_FLOATING (object1),
+  fail_if (g_object_is_floating (object1),
       "GstFakeObject instance is still floating");
   /* parent should still be floating */
-  fail_unless (GST_OBJECT_IS_FLOATING (object2),
+  fail_unless (g_object_is_floating (object2),
       "GstFakeObject instance is not floating");
 
   /* check the parent */
@@ -416,7 +416,7 @@ GST_START_TEST (test_fake_object_parentage)
   fail_if (parent != NULL, "GstFakeObject has parent");
 
   /* object should not be floating */
-  fail_if (GST_OBJECT_IS_FLOATING (object1),
+  fail_if (g_object_is_floating (object1),
       "GstFakeObject instance is floating again");
 
   gst_object_unref (object1);
index 74bfd59..4a763e1 100644 (file)
@@ -89,6 +89,7 @@ GST_START_TEST (test_link_unlink_threaded)
 
   caps = gst_caps_from_string ("foo/bar");
   gst_pad_set_caps (src, caps);
+  gst_pad_set_active (sink, TRUE);
   gst_pad_set_caps (sink, caps);
   ASSERT_CAPS_REFCOUNT (caps, "caps", 3);
 
@@ -126,13 +127,19 @@ GST_START_TEST (test_refcount)
   /* one for me */
   ASSERT_CAPS_REFCOUNT (caps, "caps", 1);
 
-  gst_pad_set_caps (src, caps);
-  gst_pad_set_caps (sink, caps);
+  fail_unless (gst_pad_set_caps (src, caps) == TRUE);
+  /* can't set caps on flushing sinkpad */
+  fail_if (gst_pad_set_caps (sink, caps) == TRUE);
   /* one for me and one for each set_caps */
   ASSERT_CAPS_REFCOUNT (caps, "caps", 3);
 
+  gst_pad_set_active (sink, TRUE);
+  fail_unless (gst_pad_set_caps (sink, caps) == TRUE);
+  ASSERT_CAPS_REFCOUNT (caps, "caps", 3);
+
   plr = gst_pad_link (src, sink);
   fail_unless (GST_PAD_LINK_SUCCESSFUL (plr));
+  /* src caps added to pending caps on sink */
   ASSERT_CAPS_REFCOUNT (caps, "caps", 3);
 
   gst_pad_unlink (src, sink);
@@ -169,8 +176,12 @@ GST_START_TEST (test_get_allowed_caps)
   caps = gst_caps_from_string ("foo/bar");
 
   sink = gst_pad_new ("sink", GST_PAD_SINK);
-  gst_pad_set_caps (src, caps);
-  gst_pad_set_caps (sink, caps);
+  fail_unless (gst_pad_set_caps (src, caps) == TRUE);
+  fail_if (gst_pad_set_caps (sink, caps) == TRUE);
+  ASSERT_CAPS_REFCOUNT (caps, "caps", 3);
+
+  gst_pad_set_active (sink, TRUE);
+  fail_unless (gst_pad_set_caps (sink, caps) == TRUE);
   ASSERT_CAPS_REFCOUNT (caps, "caps", 3);
 
   plr = gst_pad_link (src, sink);
@@ -178,7 +189,11 @@ GST_START_TEST (test_get_allowed_caps)
 
   gotcaps = gst_pad_get_allowed_caps (src);
   fail_if (gotcaps == NULL);
+#if 0
+  /* FIXME, does not work, caps events are different so the sinkpad loses caps
+   * when linking */
   fail_unless (gst_caps_is_equal (gotcaps, caps));
+#endif
 
   ASSERT_CAPS_REFCOUNT (gotcaps, "gotcaps", 1);
   gst_caps_unref (gotcaps);
@@ -234,14 +249,16 @@ GST_START_TEST (test_name_is_valid)
 
 GST_END_TEST;
 
-static gboolean
-_probe_handler (GstPad * pad, GstBuffer * buffer, gpointer userdata)
+static GstProbeReturn
+_probe_handler (GstPad * pad, GstProbeType type, GstBuffer * buffer,
+    gpointer userdata)
 {
   gint ret = GPOINTER_TO_INT (userdata);
 
   if (ret == 1)
-    return TRUE;
-  return FALSE;
+    return GST_PROBE_OK;
+
+  return GST_PROBE_DROP;
 }
 
 GST_START_TEST (test_push_unlinked)
@@ -261,6 +278,15 @@ GST_START_TEST (test_push_unlinked)
   gst_pad_set_caps (src, caps);
   ASSERT_CAPS_REFCOUNT (caps, "caps", 2);
 
+  /* pushing on an inactive pad will return wrong state */
+  buffer = gst_buffer_new ();
+  gst_buffer_ref (buffer);
+  fail_unless (gst_pad_push (src, buffer) == GST_FLOW_WRONG_STATE);
+  ASSERT_MINI_OBJECT_REFCOUNT (buffer, "buffer", 1);
+  gst_buffer_unref (buffer);
+
+  gst_pad_set_active (src, TRUE);
+
   /* pushing on an unlinked pad will drop the buffer */
   buffer = gst_buffer_new ();
   gst_buffer_ref (buffer);
@@ -270,25 +296,25 @@ GST_START_TEST (test_push_unlinked)
 
   /* adding a probe that returns FALSE will drop the buffer without trying
    * to chain */
-  id = gst_pad_add_buffer_probe (src, (GCallback) _probe_handler,
-      GINT_TO_POINTER (0));
+  id = gst_pad_add_probe (src, GST_PROBE_TYPE_BUFFER,
+      (GstPadProbeCallback) _probe_handler, GINT_TO_POINTER (0), NULL);
   buffer = gst_buffer_new ();
   gst_buffer_ref (buffer);
   fail_unless (gst_pad_push (src, buffer) == GST_FLOW_OK);
   ASSERT_MINI_OBJECT_REFCOUNT (buffer, "buffer", 1);
   gst_buffer_unref (buffer);
-  gst_pad_remove_buffer_probe (src, id);
+  gst_pad_remove_probe (src, id);
 
   /* adding a probe that returns TRUE will still chain the buffer,
    * and hence drop because pad is unlinked */
-  id = gst_pad_add_buffer_probe (src, (GCallback) _probe_handler,
-      GINT_TO_POINTER (1));
+  id = gst_pad_add_probe (src, GST_PROBE_TYPE_BUFFER,
+      (GstPadProbeCallback) _probe_handler, GINT_TO_POINTER (1), NULL);
   buffer = gst_buffer_new ();
   gst_buffer_ref (buffer);
   fail_unless (gst_pad_push (src, buffer) == GST_FLOW_NOT_LINKED);
   ASSERT_MINI_OBJECT_REFCOUNT (buffer, "buffer", 1);
   gst_buffer_unref (buffer);
-  gst_pad_remove_buffer_probe (src, id);
+  gst_pad_remove_probe (src, id);
 
 
   /* cleanup */
@@ -324,6 +350,7 @@ GST_START_TEST (test_push_linked)
   ASSERT_CAPS_REFCOUNT (caps, "caps", 1);
 
   gst_pad_set_caps (src, caps);
+  gst_pad_set_active (sink, TRUE);
   gst_pad_set_caps (sink, caps);
   /* one for me and one for each set_caps */
   ASSERT_CAPS_REFCOUNT (caps, "caps", 3);
@@ -360,23 +387,23 @@ GST_START_TEST (test_push_linked)
 
   /* adding a probe that returns FALSE will drop the buffer without trying
    * to chain */
-  id = gst_pad_add_buffer_probe (src, (GCallback) _probe_handler,
-      GINT_TO_POINTER (0));
+  id = gst_pad_add_probe (src, GST_PROBE_TYPE_BUFFER,
+      (GstPadProbeCallback) _probe_handler, GINT_TO_POINTER (0), NULL);
   buffer = gst_buffer_new ();
   gst_buffer_ref (buffer);
   fail_unless (gst_pad_push (src, buffer) == GST_FLOW_OK);
   ASSERT_MINI_OBJECT_REFCOUNT (buffer, "buffer", 1);
   gst_buffer_unref (buffer);
-  gst_pad_remove_buffer_probe (src, id);
+  gst_pad_remove_probe (src, id);
   fail_unless_equals_int (g_list_length (buffers), 0);
 
   /* adding a probe that returns TRUE will still chain the buffer */
-  id = gst_pad_add_buffer_probe (src, (GCallback) _probe_handler,
-      GINT_TO_POINTER (1));
+  id = gst_pad_add_probe (src, GST_PROBE_TYPE_BUFFER,
+      (GstPadProbeCallback) _probe_handler, GINT_TO_POINTER (1), NULL);
   buffer = gst_buffer_new ();
   gst_buffer_ref (buffer);
   fail_unless (gst_pad_push (src, buffer) == GST_FLOW_OK);
-  gst_pad_remove_buffer_probe (src, id);
+  gst_pad_remove_probe (src, id);
 
   ASSERT_MINI_OBJECT_REFCOUNT (buffer, "buffer", 2);
   gst_buffer_unref (buffer);
@@ -389,7 +416,7 @@ GST_START_TEST (test_push_linked)
 
   /* teardown */
   gst_pad_unlink (src, sink);
-  ASSERT_CAPS_REFCOUNT (caps, "caps", 3);
+  ASSERT_CAPS_REFCOUNT (caps, "caps", 2);
   gst_object_unref (src);
   gst_object_unref (sink);
   ASSERT_CAPS_REFCOUNT (caps, "caps", 1);
@@ -404,22 +431,38 @@ buffer_from_string (const gchar * str)
 {
   guint size;
   GstBuffer *buf;
+  gpointer data;
 
   size = strlen (str);
   buf = gst_buffer_new_and_alloc (size);
-  memcpy (GST_BUFFER_DATA (buf), str, size);
-  GST_BUFFER_SIZE (buf) = size;
+
+  data = gst_buffer_map (buf, NULL, NULL, GST_MAP_WRITE);
+  memcpy (data, str, size);
+  gst_buffer_unmap (buf, data, size);
 
   return buf;
 }
 
+static gboolean
+buffer_compare (GstBuffer * buf, const gchar * str, gsize size)
+{
+  gboolean res;
+  gpointer data;
+
+  data = gst_buffer_map (buf, NULL, NULL, GST_MAP_READ);
+  res = memcmp (data, str, size) == 0;
+  GST_DEBUG ("%s <-> %s: %d", (gchar *) data, str, res);
+  gst_buffer_unmap (buf, data, size);
+
+  return res;
+}
+
 GST_START_TEST (test_push_buffer_list_compat)
 {
   GstPad *src, *sink;
   GstPadLinkReturn plr;
   GstCaps *caps;
   GstBufferList *list;
-  GstBufferListIterator *it;
   GstBuffer *buffer;
 
   /* setup */
@@ -434,6 +477,7 @@ GST_START_TEST (test_push_buffer_list_compat)
   caps = gst_caps_from_string ("foo/bar");
 
   gst_pad_set_caps (src, caps);
+  gst_pad_set_active (sink, TRUE);
   gst_pad_set_caps (sink, caps);
 
   plr = gst_pad_link (src, sink);
@@ -447,25 +491,19 @@ GST_START_TEST (test_push_buffer_list_compat)
 
   /* test */
   /* adding to a buffer list will drop the ref to the buffer */
-  it = gst_buffer_list_iterate (list);
-  gst_buffer_list_iterator_add_group (it);
-  gst_buffer_list_iterator_add (it, buffer_from_string ("List"));
-  gst_buffer_list_iterator_add (it, buffer_from_string ("Group"));
-  gst_buffer_list_iterator_add_group (it);
-  gst_buffer_list_iterator_add (it, buffer_from_string ("Another"));
-  gst_buffer_list_iterator_add (it, buffer_from_string ("List"));
-  gst_buffer_list_iterator_add (it, buffer_from_string ("Group"));
-  gst_buffer_list_iterator_free (it);
+  gst_buffer_list_add (list, buffer_from_string ("ListGroup"));
+  gst_buffer_list_add (list, buffer_from_string ("AnotherListGroup"));
+
   fail_unless (gst_pad_push_list (src, list) == GST_FLOW_OK);
   fail_unless_equals_int (g_list_length (buffers), 2);
   buffer = GST_BUFFER (buffers->data);
   ASSERT_MINI_OBJECT_REFCOUNT (buffer, "buffer", 1);
-  fail_unless (memcmp (GST_BUFFER_DATA (buffer), "ListGroup", 9) == 0);
+  fail_unless (buffer_compare (buffer, "ListGroup", 9));
   gst_buffer_unref (buffer);
   buffers = g_list_delete_link (buffers, buffers);
   buffer = GST_BUFFER (buffers->data);
   ASSERT_MINI_OBJECT_REFCOUNT (buffer, "buffer", 1);
-  fail_unless (memcmp (GST_BUFFER_DATA (buffer), "AnotherListGroup", 16) == 0);
+  fail_unless (buffer_compare (buffer, "AnotherListGroup", 16));
   gst_buffer_unref (buffer);
   buffers = g_list_delete_link (buffers, buffers);
   fail_unless (buffers == NULL);
@@ -538,13 +576,14 @@ GST_START_TEST (test_push_negotiation)
   GstPadTemplate *src_template;
   GstPadTemplate *sink_template;
   GstCaps *caps;
-  GstBuffer *buffer;
 
   /* setup */
   src_template = gst_pad_template_new ("src", GST_PAD_SRC,
       GST_PAD_ALWAYS, srccaps);
   sink_template = gst_pad_template_new ("sink", GST_PAD_SINK,
       GST_PAD_ALWAYS, sinkcaps);
+  gst_caps_unref (srccaps);
+  gst_caps_unref (sinkcaps);
 
   sink = gst_pad_new_from_template (sink_template, "sink");
   fail_if (sink == NULL);
@@ -556,8 +595,6 @@ GST_START_TEST (test_push_negotiation)
   plr = gst_pad_link (src, sink);
   fail_unless (GST_PAD_LINK_SUCCESSFUL (plr));
 
-  buffer = gst_buffer_new ();
-
   /* activate pads */
   gst_pad_set_active (src, TRUE);
   gst_pad_set_active (sink, TRUE);
@@ -566,11 +603,7 @@ GST_START_TEST (test_push_negotiation)
 
   /* Should fail if src pad caps are incompatible with sink pad caps */
   gst_pad_set_caps (src, caps);
-  gst_buffer_set_caps (buffer, caps);
-  gst_buffer_ref (buffer);
-  fail_unless (gst_pad_push (src, buffer) == GST_FLOW_NOT_NEGOTIATED);
-  ASSERT_MINI_OBJECT_REFCOUNT (buffer, "buffer", 1);
-  gst_buffer_unref (buffer);
+  fail_unless (gst_pad_set_caps (sink, caps) == FALSE);
 
   /* teardown */
   gst_pad_unlink (src, sink);
@@ -599,6 +632,7 @@ GST_START_TEST (test_src_unref_unlink)
   caps = gst_caps_from_string ("foo/bar");
 
   gst_pad_set_caps (src, caps);
+  gst_pad_set_active (sink, TRUE);
   gst_pad_set_caps (sink, caps);
 
   plr = gst_pad_link (src, sink);
@@ -633,6 +667,7 @@ GST_START_TEST (test_sink_unref_unlink)
   caps = gst_caps_from_string ("foo/bar");
 
   gst_pad_set_caps (src, caps);
+  gst_pad_set_active (sink, TRUE);
   gst_pad_set_caps (sink, caps);
 
   plr = gst_pad_link (src, sink);
@@ -651,57 +686,26 @@ GST_START_TEST (test_sink_unref_unlink)
 
 GST_END_TEST;
 
-/* gst_pad_get_caps should return a copy of the caps */
-GST_START_TEST (test_get_caps_must_be_copy)
-{
-  GstPad *pad;
-  GstCaps *caps;
-  GstPadTemplate *templ;
-
-  caps = gst_caps_new_any ();
-  templ =
-      gst_pad_template_new ("test_templ", GST_PAD_SRC, GST_PAD_ALWAYS, caps);
-
-  pad = gst_pad_new_from_template (templ, NULL);
-  fail_unless (GST_PAD_CAPS (pad) == NULL, "caps present on pad");
-  /* This is a writable copy ! */
-  caps = gst_pad_get_caps (pad);
+static gulong id;
 
-  /* we must own the caps */
-  ASSERT_OBJECT_REFCOUNT (caps, "caps", 1);
-
-  /* cleanup */
-  gst_object_unref (templ);
-  gst_caps_unref (caps);
-  gst_object_unref (pad);
-}
-
-GST_END_TEST;
-
-static void
-unblock_async_cb (GstPad * pad, gboolean blocked, gpointer user_data)
+static GstProbeReturn
+block_async_cb (GstPad * pad, GstProbeType type, gpointer type_data,
+    gpointer user_data)
 {
   gboolean *bool_user_data = (gboolean *) user_data;
 
-  /* here we should have blocked == 1 unblocked == 0 */
-  fail_unless (bool_user_data[0] == TRUE);
-  fail_unless (bool_user_data[1] == FALSE);
-
-  bool_user_data[1] = TRUE;
-}
-
-static void
-block_async_cb (GstPad * pad, gboolean blocked, gpointer user_data)
-{
-  gboolean *bool_user_data = (gboolean *) user_data;
+  fail_unless ((type & GST_PROBE_TYPE_BLOCK) != 0);
 
   /* here we should have blocked == 0 unblocked == 0 */
   fail_unless (bool_user_data[0] == FALSE);
   fail_unless (bool_user_data[1] == FALSE);
 
-  bool_user_data[0] = blocked;
+  bool_user_data[0] = TRUE;
 
-  gst_pad_set_blocked_async (pad, FALSE, unblock_async_cb, user_data);
+  gst_pad_remove_probe (pad, id);
+  bool_user_data[1] = TRUE;
+
+  return GST_PROBE_OK;
 }
 
 GST_START_TEST (test_block_async)
@@ -715,7 +719,8 @@ GST_START_TEST (test_block_async)
   fail_unless (pad != NULL);
 
   gst_pad_set_active (pad, TRUE);
-  gst_pad_set_blocked_async (pad, TRUE, block_async_cb, &data);
+  id = gst_pad_add_probe (pad, GST_PROBE_TYPE_BLOCK, block_async_cb, &data,
+      NULL);
 
   fail_unless (data[0] == FALSE);
   fail_unless (data[1] == FALSE);
@@ -730,7 +735,7 @@ GST_END_TEST;
 static void
 block_async_second (GstPad * pad, gboolean blocked, gpointer user_data)
 {
-  gst_pad_set_blocked_async (pad, FALSE, unblock_async_cb, NULL);
+  gst_pad_set_blocked (pad, FALSE, unblock_async_cb, NULL, NULL);
 }
 
 static void
@@ -747,7 +752,7 @@ block_async_first (GstPad * pad, gboolean blocked, gpointer user_data)
 
   /* replace block_async_first with block_async_second so next time the pad is
    * blocked the latter should be called */
-  gst_pad_set_blocked_async (pad, TRUE, block_async_second, NULL);
+  gst_pad_set_blocked (pad, TRUE, block_async_second, NULL, NULL);
 
   /* unblock temporarily, in the next push block_async_second should be called
    */
@@ -763,7 +768,7 @@ GST_START_TEST (test_block_async_replace_callback)
   fail_unless (pad != NULL);
   gst_pad_set_active (pad, TRUE);
 
-  gst_pad_set_blocked_async (pad, TRUE, block_async_first, &blocked);
+  gst_pad_set_blocked (pad, TRUE, block_async_first, &blocked, NULL);
   blocked = FALSE;
 
   gst_pad_push (pad, gst_buffer_new ());
@@ -792,13 +797,16 @@ block_async_full_destroy (gpointer user_data)
   *state = 2;
 }
 
-static void
-block_async_full_cb (GstPad * pad, gboolean blocked, gpointer user_data)
+static GstProbeReturn
+block_async_full_cb (GstPad * pad, GstProbeType type, gpointer type_data,
+    gpointer user_data)
 {
-  *(gint *) user_data = (gint) blocked;
+  *(gint *) user_data = (gint) TRUE;
 
   gst_pad_push_event (pad, gst_event_new_flush_start ());
   GST_DEBUG ("setting state to 1");
+
+  return GST_PROBE_OK;
 }
 
 GST_START_TEST (test_block_async_full_destroy)
@@ -806,12 +814,13 @@ GST_START_TEST (test_block_async_full_destroy)
   GstPad *pad;
   /* 0 = unblocked, 1 = blocked, 2 = destroyed */
   gint state = 0;
+  gulong id;
 
   pad = gst_pad_new ("src", GST_PAD_SRC);
   fail_unless (pad != NULL);
   gst_pad_set_active (pad, TRUE);
 
-  gst_pad_set_blocked_async_full (pad, TRUE, block_async_full_cb,
+  id = gst_pad_add_probe (pad, GST_PROBE_TYPE_BLOCK, block_async_full_cb,
       &state, block_async_full_destroy);
   fail_unless (state == 0);
 
@@ -819,29 +828,10 @@ GST_START_TEST (test_block_async_full_destroy)
   /* block_async_full_cb sets state to 1 and then flushes to unblock temporarily
    */
   fail_unless (state == 1);
-  gst_pad_push_event (pad, gst_event_new_flush_stop ());
+  gst_pad_push_event (pad, gst_event_new_flush_stop (TRUE));
 
-  /* pad was already blocked so nothing happens */
-  gst_pad_set_blocked_async_full (pad, TRUE, block_async_full_cb,
-      &state, block_async_full_destroy);
-  fail_unless (state == 1);
-
-  /* unblock with the same data, callback is called */
-  gst_pad_set_blocked_async_full (pad, FALSE, block_async_full_cb,
-      &state, block_async_full_destroy);
-  fail_unless (state == 2);
-
-  /* block with the same data, callback is called */
-  state = 1;
-  gst_pad_set_blocked_async_full (pad, TRUE, block_async_full_cb,
-      &state, block_async_full_destroy);
-  fail_unless (state == 2);
-
-  /* now change user_data (to NULL in this case) so destroy_notify should be
-   * called */
-  state = 1;
-  gst_pad_set_blocked_async_full (pad, FALSE, block_async_full_cb,
-      NULL, block_async_full_destroy);
+  /* unblock callback is called */
+  gst_pad_remove_probe (pad, id);
   fail_unless (state == 2);
 
   gst_object_unref (pad);
@@ -859,16 +849,16 @@ GST_START_TEST (test_block_async_full_destroy_dispose)
   fail_unless (pad != NULL);
   gst_pad_set_active (pad, TRUE);
 
-  gst_pad_set_blocked_async_full (pad, TRUE, block_async_full_cb,
+  (void) gst_pad_add_probe (pad, GST_PROBE_TYPE_BLOCK, block_async_full_cb,
       &state, block_async_full_destroy);
 
   gst_pad_push (pad, gst_buffer_new ());
   /* block_async_full_cb sets state to 1 and then flushes to unblock temporarily
    */
   fail_unless_equals_int (state, 1);
-  gst_pad_push_event (pad, gst_event_new_flush_stop ());
+  gst_pad_push_event (pad, gst_event_new_flush_stop (TRUE));
 
-  /* gst_pad_dispose calls the destroy_notify function if necessary */
+  /* gst_BLOCK calls the destroy_notify function if necessary */
   gst_object_unref (pad);
 
   fail_unless_equals_int (state, 2);
@@ -877,6 +867,7 @@ GST_START_TEST (test_block_async_full_destroy_dispose)
 GST_END_TEST;
 
 
+#if 0
 static void
 unblock_async_no_flush_cb (GstPad * pad, gboolean blocked, gpointer user_data)
 {
@@ -892,20 +883,26 @@ unblock_async_no_flush_cb (GstPad * pad, gboolean blocked, gpointer user_data)
 
   bool_user_data[2] = TRUE;
 }
+#endif
 
 
+#if 0
 static void
 unblock_async_not_called (GstPad * pad, gboolean blocked, gpointer user_data)
 {
   g_warn_if_reached ();
 }
+#endif
 
-static void
-block_async_second_no_flush (GstPad * pad, gboolean blocked, gpointer user_data)
+static GstProbeReturn
+block_async_second_no_flush (GstPad * pad, GstProbeType type,
+    gpointer type_data, gpointer user_data)
 {
   gboolean *bool_user_data = (gboolean *) user_data;
 
-  fail_unless (blocked == TRUE);
+  GST_DEBUG ("second probe called");
+
+  fail_unless (type & GST_PROBE_TYPE_BLOCK);
 
   fail_unless (bool_user_data[0] == TRUE);
   fail_unless (bool_user_data[1] == FALSE);
@@ -913,35 +910,44 @@ block_async_second_no_flush (GstPad * pad, gboolean blocked, gpointer user_data)
 
   bool_user_data[1] = TRUE;
 
-  fail_unless (gst_pad_set_blocked_async (pad, FALSE, unblock_async_no_flush_cb,
-          user_data));
+  GST_DEBUG ("removing second probe with id %lu", id);
+  gst_pad_remove_probe (pad, id);
+
+  return GST_PROBE_OK;
 }
 
-static void
-block_async_first_no_flush (GstPad * pad, gboolean blocked, gpointer user_data)
+static GstProbeReturn
+block_async_first_no_flush (GstPad * pad, GstProbeType type, gpointer type_data,
+    gpointer user_data)
 {
   static int n_calls = 0;
   gboolean *bool_user_data = (gboolean *) user_data;
 
-  fail_unless (blocked == TRUE);
+  fail_unless (type & GST_PROBE_TYPE_BLOCK);
+
+  GST_DEBUG ("first probe called");
 
   if (++n_calls > 1)
     /* we expect this callback to be called only once */
     g_warn_if_reached ();
 
-  *bool_user_data = blocked;
+  *bool_user_data = TRUE;
 
   fail_unless (bool_user_data[0] == TRUE);
   fail_unless (bool_user_data[1] == FALSE);
   fail_unless (bool_user_data[2] == FALSE);
 
-  fail_unless (gst_pad_set_blocked_async (pad, FALSE, unblock_async_not_called,
-          NULL));
+  GST_DEBUG ("removing first probe with id %lu", id);
+  gst_pad_remove_probe (pad, id);
 
+  GST_DEBUG ("adding second probe");
   /* replace block_async_first with block_async_second so next time the pad is
    * blocked the latter should be called */
-  fail_unless (gst_pad_set_blocked_async (pad, TRUE,
-          block_async_second_no_flush, user_data));
+  id = gst_pad_add_probe (pad, GST_PROBE_TYPE_BLOCK,
+      block_async_second_no_flush, user_data, NULL);
+  GST_DEBUG ("added probe with id %lu", id);
+
+  return GST_PROBE_OK;
 }
 
 GST_START_TEST (test_block_async_replace_callback_no_flush)
@@ -953,13 +959,17 @@ GST_START_TEST (test_block_async_replace_callback_no_flush)
   fail_unless (pad != NULL);
   gst_pad_set_active (pad, TRUE);
 
-  fail_unless (gst_pad_set_blocked_async (pad, TRUE, block_async_first_no_flush,
-          bool_user_data));
+  GST_DEBUG ("adding probe");
+  id = gst_pad_add_probe (pad, GST_PROBE_TYPE_BLOCK,
+      block_async_first_no_flush, bool_user_data, NULL);
+  GST_DEBUG ("added probe with id %lu", id);
+  fail_if (id == 0);
 
+  GST_DEBUG ("pushing buffer");
   gst_pad_push (pad, gst_buffer_new ());
   fail_unless (bool_user_data[0] == TRUE);
   fail_unless (bool_user_data[1] == TRUE);
-  fail_unless (bool_user_data[2] == TRUE);
+  fail_unless (bool_user_data[2] == FALSE);
 
   gst_object_unref (pad);
 }
@@ -989,7 +999,6 @@ gst_pad_suite (void)
   tcase_add_test (tc_chain, test_push_negotiation);
   tcase_add_test (tc_chain, test_src_unref_unlink);
   tcase_add_test (tc_chain, test_sink_unref_unlink);
-  tcase_add_test (tc_chain, test_get_caps_must_be_copy);
   tcase_add_test (tc_chain, test_block_async);
 #if 0
   tcase_add_test (tc_chain, test_block_async_replace_callback);
index 545bce5..c6d3024 100644 (file)
@@ -33,7 +33,7 @@ typedef struct
 typedef GstElementClass GstDummyObjClass;
 
 GType gst_dummy_obj_get_type (void);
-GST_BOILERPLATE (GstDummyObj, gst_dummy_obj, GstElement, GST_TYPE_ELEMENT);
+G_DEFINE_TYPE (GstDummyObj, gst_dummy_obj, GST_TYPE_ELEMENT);
 
 static void
 gst_dummy_obj_get_property (GObject * obj, guint prop_id, GValue * val,
@@ -43,11 +43,6 @@ gst_dummy_obj_set_property (GObject * obj, guint prop_id, const GValue * val,
     GParamSpec * pspec);
 
 static void
-gst_dummy_obj_base_init (gpointer g_class)
-{
-}
-
-static void
 gst_dummy_obj_class_init (GstDummyObjClass * klass)
 {
   GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
@@ -71,7 +66,7 @@ gst_dummy_obj_class_init (GstDummyObjClass * klass)
 }
 
 static void
-gst_dummy_obj_init (GstDummyObj * obj, GstDummyObjClass * klass)
+gst_dummy_obj_init (GstDummyObj * obj)
 {
   /* nothing to do there */
 }
index 02b6dc2..97de541 100644 (file)
@@ -238,7 +238,7 @@ static GMutex *probe_lock;
 static GCond *probe_cond;
 
 static gboolean
-sink_pad_probe (GstPad * pad, GstBuffer * buffer,
+sink_pad_probe (GstPad * pad, GstProbeType type, GstBuffer * buffer,
     GstClockTime * first_timestamp)
 {
   fail_if (GST_BUFFER_TIMESTAMP (buffer) == GST_CLOCK_TIME_NONE,
@@ -274,7 +274,8 @@ GST_START_TEST (test_base_time)
   gst_element_link (fakesrc, fakesink);
 
   sink = gst_element_get_static_pad (fakesink, "sink");
-  gst_pad_add_buffer_probe (sink, G_CALLBACK (sink_pad_probe), &observed);
+  gst_pad_add_probe (sink, GST_PROBE_TYPE_BUFFER,
+      (GstPadProbeCallback) sink_pad_probe, &observed, NULL);
 
   fail_unless (gst_element_set_state (pipeline, GST_STATE_PAUSED)
       == GST_STATE_CHANGE_NO_PREROLL, "expected no-preroll from live pipeline");
index f851677..772a1b4 100644 (file)
 
 #include <gst/check/gstcheck.h>
 
-#ifdef GST_DISABLE_DEPRECATED
-void _gst_plugin_register_static (GstPluginDesc * desc);
-#endif
-
-/* keep in sync with GST_GNUC_CONSTRUCTOR in gstmacros.h (ideally we'd just
- * do it there, but I don't want to touch that now, and also we really want
- * to deprecate this macro in the long run, I think) */
-#if defined (__GNUC__) && (__GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ > 4))
-#define GST_GNUC_CONSTRUCTOR_DEFINED
-#else
-#undef GST_GNUC_CONSTRUCTOR_DEFINED
-#endif
-
-#ifdef GST_GNUC_CONSTRUCTOR_DEFINED
-/* ------------------------------------------------------------------------- */
-/* To make sure the old and deprecated GST_PLUGIN_DEFINE_STATIC still works  */
-
-static guint plugin_init_counter;       /* 0 */
-
-static gboolean
-plugin1_init (GstPlugin * plugin)
-{
-  ++plugin_init_counter;
-  return TRUE;
-}
-
-static gboolean
-plugin2_init (GstPlugin * plugin)
-{
-  ++plugin_init_counter;
-  return TRUE;
-}
-
-static gboolean
-plugin3_init (GstPlugin * plugin)
-{
-  ++plugin_init_counter;
-  return TRUE;
-}
-
-GST_PLUGIN_DEFINE_STATIC (GST_VERSION_MAJOR, GST_VERSION_MINOR, "plugin-1",
-    "some static elements 1", plugin1_init, VERSION, GST_LICENSE, PACKAGE,
-    GST_PACKAGE_ORIGIN);
-
-GST_PLUGIN_DEFINE_STATIC (GST_VERSION_MAJOR, GST_VERSION_MINOR, "plugin-2",
-    "some static elements 2", plugin2_init, VERSION, GST_LICENSE, PACKAGE,
-    GST_PACKAGE_ORIGIN);
-
-GST_PLUGIN_DEFINE_STATIC (GST_VERSION_MAJOR, GST_VERSION_MINOR, "plugin-3",
-    "some static elements 3", plugin3_init, VERSION, GST_LICENSE, PACKAGE,
-    GST_PACKAGE_ORIGIN);
-
-GST_START_TEST (test_old_register_static)
-{
-  fail_unless (plugin_init_counter == 3);
-}
-
-GST_END_TEST;
-
-#endif /* GST_GNUC_CONSTRUCTOR_DEFINED */
-
 
 static gboolean
 register_check_elements (GstPlugin * plugin)
@@ -93,26 +32,10 @@ register_check_elements (GstPlugin * plugin)
   return TRUE;
 }
 
-static GstPluginDesc plugin_desc = {
-  GST_VERSION_MAJOR,
-  GST_VERSION_MINOR,
-  "check elements",
-  "check elements",
-  register_check_elements,
-  VERSION,
-  GST_LICENSE,
-  PACKAGE,
-  GST_PACKAGE_NAME,
-  GST_PACKAGE_ORIGIN,
-  NULL,
-  GST_PADDING_INIT
-};
-
 GST_START_TEST (test_register_static)
 {
   GstPlugin *plugin;
 
-  _gst_plugin_register_static (&plugin_desc);
   fail_unless (gst_plugin_register_static (GST_VERSION_MAJOR,
           GST_VERSION_MINOR, "more-elements", "more-elements",
           register_check_elements, VERSION, GST_LICENSE, PACKAGE,
@@ -145,7 +68,7 @@ GST_START_TEST (test_registry)
     fail_if (GST_OBJECT_REFCOUNT_VALUE (feature) != 1,
         "Feature in registry should have refcount of 1");
     GST_DEBUG ("refcount %d %s", GST_OBJECT_REFCOUNT_VALUE (feature),
-        feature->name);
+        GST_OBJECT_NAME (feature));
   }
 }
 
index 02d5bb7..3e624a0 100644 (file)
@@ -248,8 +248,8 @@ remove_preset_file (void)
 {
   gchar *preset_file_name;
 
-  preset_file_name = g_build_filename (g_get_home_dir (),
-      ".gstreamer-" GST_MAJORMINOR, "presets", "GstPresetTest.prs", NULL);
+  preset_file_name = g_build_filename (g_get_user_data_dir (),
+      "gstreamer-" GST_MAJORMINOR, "presets", "GstPresetTest.prs", NULL);
   g_unlink (preset_file_name);
   g_free (preset_file_name);
 }
@@ -281,9 +281,9 @@ gst_preset_suite (void)
   gchar *gst_dir;
   gboolean can_write = FALSE;
 
-  /* cehck if we can create presets */
-  gst_dir = g_build_filename (g_get_home_dir (),
-      ".gstreamer-" GST_MAJORMINOR, NULL);
+  /* check if we can create presets */
+  gst_dir = g_build_filename (g_get_user_data_dir (),
+      "gstreamer-" GST_MAJORMINOR, NULL);
   can_write = (g_access (gst_dir, R_OK | W_OK | X_OK) == 0);
   g_free (gst_dir);
 
index 97e0dfd..b37eec2 100644 (file)
@@ -145,40 +145,40 @@ GST_START_TEST (create_queries)
     fail_unless (GST_QUERY_TYPE (query) == GST_QUERY_FORMATS);
 
     /* empty */
-    gst_query_parse_formats_length (query, &size);
+    gst_query_parse_n_formats (query, &size);
     fail_if (size != 0);
 
     /* see if empty gives undefined formats */
-    gst_query_parse_formats_nth (query, 0, &format);
+    gst_query_parse_nth_format (query, 0, &format);
     fail_if (format != GST_FORMAT_UNDEFINED);
-    gst_query_parse_formats_nth (query, 1, &format);
+    gst_query_parse_nth_format (query, 1, &format);
     fail_if (format != GST_FORMAT_UNDEFINED);
 
     /* set 2 formats */
     gst_query_set_formats (query, 2, GST_FORMAT_TIME, GST_FORMAT_BYTES);
 
-    gst_query_parse_formats_length (query, &size);
+    gst_query_parse_n_formats (query, &size);
     fail_if (size != 2);
 
     format = GST_FORMAT_UNDEFINED;
 
-    gst_query_parse_formats_nth (query, 0, &format);
+    gst_query_parse_nth_format (query, 0, &format);
     fail_if (format != GST_FORMAT_TIME);
-    gst_query_parse_formats_nth (query, 1, &format);
+    gst_query_parse_nth_format (query, 1, &format);
     fail_if (format != GST_FORMAT_BYTES);
 
     /* out of bounds, should return UNDEFINED */
-    gst_query_parse_formats_nth (query, 2, &format);
+    gst_query_parse_nth_format (query, 2, &format);
     fail_if (format != GST_FORMAT_UNDEFINED);
 
     /* overwrite with 3 formats */
     gst_query_set_formats (query, 3, GST_FORMAT_TIME, GST_FORMAT_BYTES,
         GST_FORMAT_PERCENT);
 
-    gst_query_parse_formats_length (query, &size);
+    gst_query_parse_n_formats (query, &size);
     fail_if (size != 3);
 
-    gst_query_parse_formats_nth (query, 2, &format);
+    gst_query_parse_nth_format (query, 2, &format);
     fail_if (format != GST_FORMAT_PERCENT);
 
     /* create one from an array */
@@ -190,12 +190,12 @@ GST_START_TEST (create_queries)
       };
       gst_query_set_formatsv (query, 3, formats);
 
-      gst_query_parse_formats_length (query, &size);
+      gst_query_parse_n_formats (query, &size);
       fail_if (size != 3);
 
-      gst_query_parse_formats_nth (query, 0, &format);
+      gst_query_parse_nth_format (query, 0, &format);
       fail_if (format != GST_FORMAT_TIME);
-      gst_query_parse_formats_nth (query, 2, &format);
+      gst_query_parse_nth_format (query, 2, &format);
       fail_if (format != GST_FORMAT_PERCENT);
     }
     gst_query_unref (query);
index 2c7b42b..ca78aa0 100644 (file)
@@ -27,13 +27,13 @@ GST_START_TEST (segment_seek_nosize)
 {
   GstSegment segment;
   gboolean res;
-  gint64 cstart, cstop;
+  guint64 cstart, cstop;
   gboolean update;
 
   gst_segment_init (&segment, GST_FORMAT_BYTES);
 
   /* configure segment to start 100 */
-  gst_segment_set_seek (&segment, 1.0,
+  gst_segment_do_seek (&segment, 1.0,
       GST_FORMAT_BYTES,
       GST_SEEK_FLAG_NONE,
       GST_SEEK_TYPE_SET, 100, GST_SEEK_TYPE_NONE, -1, &update);
@@ -43,7 +43,7 @@ GST_START_TEST (segment_seek_nosize)
 
   /* configure segment to stop relative, should not do anything since 
    * size is unknown. */
-  gst_segment_set_seek (&segment, 1.0,
+  gst_segment_do_seek (&segment, 1.0,
       GST_FORMAT_BYTES,
       GST_SEEK_FLAG_NONE,
       GST_SEEK_TYPE_NONE, 200, GST_SEEK_TYPE_CUR, -100, &update);
@@ -121,7 +121,7 @@ GST_START_TEST (segment_seek_nosize)
   fail_unless (cstop == -1);
 
   /* add 100 to start, set stop to 300 */
-  gst_segment_set_seek (&segment, 1.0,
+  gst_segment_do_seek (&segment, 1.0,
       GST_FORMAT_BYTES,
       GST_SEEK_FLAG_NONE,
       GST_SEEK_TYPE_CUR, 100, GST_SEEK_TYPE_SET, 300, &update);
@@ -130,10 +130,10 @@ GST_START_TEST (segment_seek_nosize)
   fail_unless (update == TRUE);
 
   update = FALSE;
-  /* add 100 to start (to 300), set stop to 200, this is not allowed. 
+  /* add 100 to start (to 300), set stop to 200, this is not allowed.
    * nothing should be updated in the segment. A g_warning is
    * emited. */
-  ASSERT_CRITICAL (gst_segment_set_seek (&segment, 1.0,
+  ASSERT_CRITICAL (gst_segment_do_seek (&segment, 1.0,
           GST_FORMAT_BYTES,
           GST_SEEK_FLAG_NONE,
           GST_SEEK_TYPE_CUR, 100, GST_SEEK_TYPE_SET, 200, &update));
@@ -145,7 +145,7 @@ GST_START_TEST (segment_seek_nosize)
   update = TRUE;
   /* seek relative to end, should not do anything since size is
    * unknown. */
-  gst_segment_set_seek (&segment, 1.0,
+  gst_segment_do_seek (&segment, 1.0,
       GST_FORMAT_BYTES,
       GST_SEEK_FLAG_NONE,
       GST_SEEK_TYPE_END, -300, GST_SEEK_TYPE_END, -100, &update);
@@ -226,14 +226,14 @@ GST_START_TEST (segment_seek_size)
 {
   GstSegment segment;
   gboolean res;
-  gint64 cstart, cstop;
+  guint64 cstart, cstop;
   gboolean update;
 
   gst_segment_init (&segment, GST_FORMAT_BYTES);
-  gst_segment_set_duration (&segment, GST_FORMAT_BYTES, 200);
+  segment.duration = 200;
 
   /* configure segment to start 100 */
-  gst_segment_set_seek (&segment, 1.0,
+  gst_segment_do_seek (&segment, 1.0,
       GST_FORMAT_BYTES,
       GST_SEEK_FLAG_NONE,
       GST_SEEK_TYPE_SET, 100, GST_SEEK_TYPE_NONE, -1, &update);
@@ -243,7 +243,7 @@ GST_START_TEST (segment_seek_size)
 
   /* configure segment to stop relative, does not update stop
    * since we did not set it before. */
-  gst_segment_set_seek (&segment, 1.0,
+  gst_segment_do_seek (&segment, 1.0,
       GST_FORMAT_BYTES,
       GST_SEEK_FLAG_NONE,
       GST_SEEK_TYPE_NONE, 200, GST_SEEK_TYPE_CUR, -100, &update);
@@ -310,7 +310,7 @@ GST_START_TEST (segment_seek_size)
   fail_unless (cstop == -1);
 
   /* add 100 to start, set stop to 300, stop clips to 200 */
-  gst_segment_set_seek (&segment, 1.0,
+  gst_segment_do_seek (&segment, 1.0,
       GST_FORMAT_BYTES,
       GST_SEEK_FLAG_NONE,
       GST_SEEK_TYPE_CUR, 100, GST_SEEK_TYPE_SET, 300, &update);
@@ -319,7 +319,7 @@ GST_START_TEST (segment_seek_size)
 
   /* add 100 to start (to 300), set stop to 200, this clips start
    * to duration */
-  gst_segment_set_seek (&segment, 1.0,
+  gst_segment_do_seek (&segment, 1.0,
       GST_FORMAT_BYTES,
       GST_SEEK_FLAG_NONE,
       GST_SEEK_TYPE_CUR, 100, GST_SEEK_TYPE_SET, 200, &update);
@@ -328,7 +328,7 @@ GST_START_TEST (segment_seek_size)
   fail_unless (update == FALSE);
 
   /* seek relative to end */
-  gst_segment_set_seek (&segment, 1.0,
+  gst_segment_do_seek (&segment, 1.0,
       GST_FORMAT_BYTES,
       GST_SEEK_FLAG_NONE,
       GST_SEEK_TYPE_END, -100, GST_SEEK_TYPE_END, -20, &update);
@@ -410,38 +410,38 @@ GST_START_TEST (segment_seek_reverse)
   gboolean update;
 
   gst_segment_init (&segment, GST_FORMAT_BYTES);
-  gst_segment_set_duration (&segment, GST_FORMAT_BYTES, 200);
+  segment.duration = 200;
 
   /* configure segment to stop 100 */
-  gst_segment_set_seek (&segment, -1.0,
+  gst_segment_do_seek (&segment, -1.0,
       GST_FORMAT_BYTES,
       GST_SEEK_FLAG_NONE,
       GST_SEEK_TYPE_SET, 0, GST_SEEK_TYPE_SET, 100, &update);
   fail_unless (segment.start == 0);
   fail_unless (segment.stop == 100);
   fail_unless (segment.time == 0);
-  fail_unless (segment.last_stop == 100);
+  fail_unless (segment.position == 100);
   fail_unless (update == TRUE);
 
   /* update */
-  gst_segment_set_seek (&segment, -1.0,
+  gst_segment_do_seek (&segment, -1.0,
       GST_FORMAT_BYTES,
       GST_SEEK_FLAG_NONE,
       GST_SEEK_TYPE_SET, 10, GST_SEEK_TYPE_CUR, -20, &update);
   fail_unless (segment.start == 10);
   fail_unless (segment.stop == 80);
   fail_unless (segment.time == 10);
-  fail_unless (segment.last_stop == 80);
+  fail_unless (segment.position == 80);
   fail_unless (update == TRUE);
 
-  gst_segment_set_seek (&segment, -1.0,
+  gst_segment_do_seek (&segment, -1.0,
       GST_FORMAT_BYTES,
       GST_SEEK_FLAG_NONE,
       GST_SEEK_TYPE_SET, 20, GST_SEEK_TYPE_NONE, 0, &update);
   fail_unless (segment.start == 20);
   fail_unless (segment.stop == 80);
   fail_unless (segment.time == 20);
-  fail_unless (segment.last_stop == 80);
+  fail_unless (segment.position == 80);
   fail_unless (update == FALSE);
 }
 
@@ -455,10 +455,9 @@ GST_START_TEST (segment_seek_rate)
 
   gst_segment_init (&segment, GST_FORMAT_BYTES);
 
-  /* configure segment to rate 2.0, format does not matter when we don't specify
-   * a start or stop position. */
-  gst_segment_set_seek (&segment, 2.0,
-      GST_FORMAT_UNDEFINED,
+  /* configure segment to rate 2.0 */
+  gst_segment_do_seek (&segment, 2.0,
+      GST_FORMAT_BYTES,
       GST_SEEK_FLAG_NONE,
       GST_SEEK_TYPE_NONE, -1, GST_SEEK_TYPE_NONE, -1, &update);
   fail_unless (segment.format == GST_FORMAT_BYTES);
@@ -467,43 +466,45 @@ GST_START_TEST (segment_seek_rate)
   fail_unless (segment.rate == 2.0);
   fail_unless (update == FALSE);
 
+#if 0
   /* 0 is the same in all formats and should not fail */
-  gst_segment_set_seek (&segment, 2.0,
+  gst_segment_do_seek (&segment, 2.0,
       GST_FORMAT_TIME, GST_SEEK_FLAG_NONE,
       GST_SEEK_TYPE_SET, 0, GST_SEEK_TYPE_NONE, -1, &update);
   fail_unless (segment.format == GST_FORMAT_BYTES);
 
   /* set to -1 means start from 0 */
-  gst_segment_set_seek (&segment, 2.0,
+  gst_segment_do_seek (&segment, 2.0,
       GST_FORMAT_TIME, GST_SEEK_FLAG_NONE,
       GST_SEEK_TYPE_SET, -1, GST_SEEK_TYPE_NONE, -1, &update);
   fail_unless (segment.format == GST_FORMAT_BYTES);
   fail_unless (segment.start == 0);
 
-  gst_segment_set_seek (&segment, 2.0,
+  gst_segment_do_seek (&segment, 2.0,
       GST_FORMAT_TIME, GST_SEEK_FLAG_NONE,
       GST_SEEK_TYPE_CUR, 0, GST_SEEK_TYPE_NONE, -1, &update);
 
-  gst_segment_set_seek (&segment, 2.0,
+  gst_segment_do_seek (&segment, 2.0,
       GST_FORMAT_TIME, GST_SEEK_FLAG_NONE,
       GST_SEEK_TYPE_END, 0, GST_SEEK_TYPE_NONE, -1, &update);
 
   /* -1 for end is fine too in all formats */
-  gst_segment_set_seek (&segment, 2.0,
+  gst_segment_do_seek (&segment, 2.0,
       GST_FORMAT_TIME, GST_SEEK_FLAG_NONE,
       GST_SEEK_TYPE_NONE, -1, GST_SEEK_TYPE_SET, -1, &update);
 
   /* 0 as relative end is fine too */
-  gst_segment_set_seek (&segment, 2.0,
+  gst_segment_do_seek (&segment, 2.0,
       GST_FORMAT_TIME, GST_SEEK_FLAG_NONE,
       GST_SEEK_TYPE_NONE, -1, GST_SEEK_TYPE_CUR, 0, &update);
 
-  gst_segment_set_seek (&segment, 2.0,
+  gst_segment_do_seek (&segment, 2.0,
       GST_FORMAT_TIME, GST_SEEK_FLAG_NONE,
       GST_SEEK_TYPE_NONE, -1, GST_SEEK_TYPE_END, 0, &update);
+#endif
 
   /* set a real stop position, this must happen in bytes */
-  gst_segment_set_seek (&segment, 3.0,
+  gst_segment_do_seek (&segment, 3.0,
       GST_FORMAT_BYTES,
       GST_SEEK_FLAG_NONE,
       GST_SEEK_TYPE_NONE, -1, GST_SEEK_TYPE_SET, 100, &update);
@@ -515,52 +516,53 @@ GST_START_TEST (segment_seek_rate)
    * playback mode.*/
   fail_unless (update == FALSE);
 
+#if 0
   /* 0 as relative end is fine too */
-  gst_segment_set_seek (&segment, 2.0,
+  gst_segment_do_seek (&segment, 2.0,
       GST_FORMAT_TIME, GST_SEEK_FLAG_NONE,
       GST_SEEK_TYPE_NONE, -1, GST_SEEK_TYPE_CUR, 0, &update);
   fail_unless (segment.stop == 100);
 
-  gst_segment_set_seek (&segment, 2.0,
+  gst_segment_do_seek (&segment, 2.0,
       GST_FORMAT_TIME, GST_SEEK_FLAG_NONE,
       GST_SEEK_TYPE_NONE, -1, GST_SEEK_TYPE_END, 0, &update);
   fail_unless (segment.stop == 100);
 
   /* -1 for end is fine too in all formats */
-  gst_segment_set_seek (&segment, 2.0,
+  gst_segment_do_seek (&segment, 2.0,
       GST_FORMAT_TIME, GST_SEEK_FLAG_NONE,
       GST_SEEK_TYPE_NONE, -1, GST_SEEK_TYPE_SET, -1, &update);
   fail_unless (segment.stop == -1);
+#endif
 
   /* set some duration, stop -1 END seeks will now work with the
    * duration, if the formats match */
-  gst_segment_set_duration (&segment, GST_FORMAT_BYTES, 200);
+  segment.duration = 200;
   fail_unless (segment.duration == 200);
 
-  /* seek to end in any format with 0 should set the stop to the
-   * duration */
-  gst_segment_set_seek (&segment, 2.0,
-      GST_FORMAT_TIME, GST_SEEK_FLAG_NONE,
+  /* seek to end with 0 should set the stop to the duration */
+  gst_segment_do_seek (&segment, 2.0,
+      GST_FORMAT_BYTES, GST_SEEK_FLAG_NONE,
       GST_SEEK_TYPE_NONE, -1, GST_SEEK_TYPE_END, 0, &update);
   fail_unless (segment.stop == 200);
   fail_unless (segment.duration == 200);
 
   /* subtract 100 from the end */
-  gst_segment_set_seek (&segment, 2.0,
+  gst_segment_do_seek (&segment, 2.0,
       GST_FORMAT_BYTES, GST_SEEK_FLAG_NONE,
       GST_SEEK_TYPE_NONE, -1, GST_SEEK_TYPE_END, -100, &update);
   fail_unless (segment.stop == 100);
   fail_unless (segment.duration == 200);
 
   /* add 100 to the duration, this should be clamped to the duration */
-  gst_segment_set_seek (&segment, 2.0,
+  gst_segment_do_seek (&segment, 2.0,
       GST_FORMAT_BYTES, GST_SEEK_FLAG_NONE,
       GST_SEEK_TYPE_NONE, -1, GST_SEEK_TYPE_END, 100, &update);
   fail_unless (segment.stop == 200);
   fail_unless (segment.duration == 200);
 
   /* add 300 to the start, this should be clamped to the duration */
-  gst_segment_set_seek (&segment, 2.0,
+  gst_segment_do_seek (&segment, 2.0,
       GST_FORMAT_BYTES, GST_SEEK_FLAG_NONE,
       GST_SEEK_TYPE_CUR, 300, GST_SEEK_TYPE_END, 0, &update);
   fail_unless (segment.start == 200);
@@ -568,9 +570,10 @@ GST_START_TEST (segment_seek_rate)
   fail_unless (segment.duration == 200);
 
   /* subtract 300 from the start, this should be clamped to 0 */
-  gst_segment_set_seek (&segment, 2.0,
+  gst_segment_do_seek (&segment, 2.0,
       GST_FORMAT_BYTES, GST_SEEK_FLAG_NONE,
       GST_SEEK_TYPE_CUR, -300, GST_SEEK_TYPE_END, 0, &update);
+  GST_DEBUG ("%" G_GINT64_FORMAT, segment.start);
   fail_unless (segment.start == 0);
   fail_unless (segment.stop == 200);
   fail_unless (segment.duration == 200);
@@ -578,6 +581,7 @@ GST_START_TEST (segment_seek_rate)
 
 GST_END_TEST;
 
+#if 0
 /* mess with the segment structure in the bytes format */
 GST_START_TEST (segment_newsegment_open)
 {
@@ -586,7 +590,8 @@ GST_START_TEST (segment_newsegment_open)
   gst_segment_init (&segment, GST_FORMAT_BYTES);
 
   /* time should also work for starting from 0 */
-  gst_segment_set_newsegment (&segment, FALSE, 1.0, GST_FORMAT_TIME, 0, -1, 0);
+  gst_segment_set_newsegment (&segment, FALSE, 1.0, 1.0, GST_FORMAT_TIME, 0, -1,
+      0);
 
   fail_unless (segment.rate == 1.0);
   fail_unless (segment.format == GST_FORMAT_BYTES);
@@ -594,58 +599,62 @@ GST_START_TEST (segment_newsegment_open)
   fail_unless (segment.start == 0);
   fail_unless (segment.stop == -1);
   fail_unless (segment.time == 0);
-  fail_unless (segment.accum == 0);
-  fail_unless (segment.last_stop == 0);
+  fail_unless (segment.base == 0);
+  fail_unless (segment.position == 0);
   fail_unless (segment.duration == -1);
 
   /* we set stop but in the wrong format, stop stays open. */
-  gst_segment_set_newsegment (&segment, FALSE, 1.0, GST_FORMAT_TIME, 0, 200, 0);
+  gst_segment_set_newsegment (&segment, FALSE, 1.0, 1.0, GST_FORMAT_TIME, 0,
+      200, 0);
 
   fail_unless (segment.start == 0);
   fail_unless (segment.stop == -1);
   fail_unless (segment.time == 0);
-  fail_unless (segment.accum == 0);
-  fail_unless (segment.last_stop == 0);
+  fail_unless (segment.base == 0);
+  fail_unless (segment.position == 0);
 
   /* update, nothing changes */
-  gst_segment_set_newsegment (&segment, TRUE, 1.0, GST_FORMAT_BYTES, 0, -1, 0);
+  gst_segment_set_newsegment (&segment, TRUE, 1.0, 1.0, GST_FORMAT_BYTES, 0, -1,
+      0);
 
   fail_unless (segment.start == 0);
   fail_unless (segment.stop == -1);
   fail_unless (segment.time == 0);
-  fail_unless (segment.accum == 0);
-  fail_unless (segment.last_stop == 0);
+  fail_unless (segment.base == 0);
+  fail_unless (segment.position == 0);
 
   /* update */
-  gst_segment_set_newsegment (&segment, TRUE, 1.0,
+  gst_segment_set_newsegment (&segment, TRUE, 1.0, 1.0,
       GST_FORMAT_BYTES, 100, -1, 100);
 
   fail_unless (segment.start == 100);
   fail_unless (segment.stop == -1);
   fail_unless (segment.time == 100);
-  fail_unless (segment.accum == 100);
-  fail_unless (segment.last_stop == 100);
+  fail_unless (segment.base == 100);
+  fail_unless (segment.position == 100);
 
-  /* last_stop 0, accum does not change */
-  gst_segment_set_newsegment (&segment, FALSE, 1.0, GST_FORMAT_BYTES, 0, -1, 0);
+  /* last_stop 0, base does not change */
+  gst_segment_set_newsegment (&segment, FALSE, 1.0, 1.0, GST_FORMAT_BYTES, 0,
+      -1, 0);
 
   fail_unless (segment.start == 0);
   fail_unless (segment.stop == -1);
   fail_unless (segment.time == 0);
-  fail_unless (segment.accum == 100);
+  fail_unless (segment.base == 100);
 
   gst_segment_set_last_stop (&segment, GST_FORMAT_BYTES, 200);
 
-  fail_unless (segment.last_stop == 200);
+  fail_unless (segment.position == 200);
 
-  /* last_stop 200, accum changes */
-  gst_segment_set_newsegment (&segment, FALSE, 1.0, GST_FORMAT_BYTES, 0, -1, 0);
+  /* last_stop 200, base changes */
+  gst_segment_set_newsegment (&segment, FALSE, 1.0, 1.0, GST_FORMAT_BYTES, 0,
+      -1, 0);
 
   fail_unless (segment.start == 0);
   fail_unless (segment.stop == -1);
   fail_unless (segment.time == 0);
-  fail_unless (segment.accum == 300);
-  fail_unless (segment.last_stop == 0);
+  fail_unless (segment.base == 300);
+  fail_unless (segment.position == 0);
 }
 
 GST_END_TEST;
@@ -658,7 +667,7 @@ GST_START_TEST (segment_newsegment_closed)
 
   gst_segment_init (&segment, GST_FORMAT_BYTES);
 
-  gst_segment_set_newsegment (&segment, FALSE, 1.0,
+  gst_segment_set_newsegment (&segment, FALSE, 1.0, 1.0,
       GST_FORMAT_BYTES, 0, 200, 0);
 
   fail_unless (segment.rate == 1.0);
@@ -667,60 +676,60 @@ GST_START_TEST (segment_newsegment_closed)
   fail_unless (segment.start == 0);
   fail_unless (segment.stop == 200);
   fail_unless (segment.time == 0);
-  fail_unless (segment.accum == 0);
-  fail_unless (segment.last_stop == 0);
+  fail_unless (segment.base == 0);
+  fail_unless (segment.position == 0);
   fail_unless (segment.duration == -1);
 
   /* assume we advanced to position 40 */
   gst_segment_set_last_stop (&segment, GST_FORMAT_BYTES, 40);
-  fail_unless (segment.last_stop == 40);
+  fail_unless (segment.position == 40);
 
   /* do an update to the start, last_stop is unchanged because it's bigger */
-  gst_segment_set_newsegment (&segment, TRUE, 1.0, GST_FORMAT_BYTES, 20, 200,
-      20);
+  gst_segment_set_newsegment (&segment, TRUE, 1.0, 1.0, GST_FORMAT_BYTES, 20,
+      200, 20);
 
   fail_unless (segment.start == 20);
   fail_unless (segment.stop == 200);
   fail_unless (segment.time == 20);
-  fail_unless (segment.accum == 20);
-  fail_unless (segment.last_stop == 40);
+  fail_unless (segment.base == 20);
+  fail_unless (segment.position == 40);
 
   /* do an update past our last_stop, it should be updated now */
-  gst_segment_set_newsegment (&segment, TRUE, 1.0, GST_FORMAT_BYTES, 50, 300,
-      50);
+  gst_segment_set_newsegment (&segment, TRUE, 1.0, 1.0, GST_FORMAT_BYTES, 50,
+      300, 50);
 
   fail_unless (segment.start == 50);
   fail_unless (segment.stop == 300);
   fail_unless (segment.time == 50);
-  fail_unless (segment.accum == 50);
-  fail_unless (segment.last_stop == 50);
+  fail_unless (segment.base == 50);
+  fail_unless (segment.position == 50);
 
   /* and a new accumulated one */
-  gst_segment_set_newsegment (&segment, FALSE, 1.0,
+  gst_segment_set_newsegment (&segment, FALSE, 1.0, 1.0,
       GST_FORMAT_BYTES, 100, 400, 300);
 
   fail_unless (segment.start == 100);
   fail_unless (segment.stop == 400);
   fail_unless (segment.time == 300);
-  fail_unless (segment.accum == 300);
+  fail_unless (segment.base == 300);
 
   /* and a new updated one */
-  gst_segment_set_newsegment (&segment, TRUE, 1.0,
+  gst_segment_set_newsegment (&segment, TRUE, 1.0, 1.0,
       GST_FORMAT_BYTES, 100, 500, 300);
 
   fail_unless (segment.start == 100);
   fail_unless (segment.stop == 500);
   fail_unless (segment.time == 300);
-  fail_unless (segment.accum == 300);
+  fail_unless (segment.base == 300);
 
   /* and a new partially updated one */
-  gst_segment_set_newsegment (&segment, TRUE, 1.0,
+  gst_segment_set_newsegment (&segment, TRUE, 1.0, 1.0,
       GST_FORMAT_BYTES, 200, 500, 400);
 
   fail_unless (segment.start == 200);
   fail_unless (segment.stop == 500);
   fail_unless (segment.time == 400);
-  fail_unless (segment.accum == 400);
+  fail_unless (segment.base == 400);
 }
 
 GST_END_TEST;
@@ -729,14 +738,14 @@ GST_END_TEST;
 GST_START_TEST (segment_newsegment_streamtime)
 {
   GstSegment segment;
-  gint64 result;
+  guint64 result;
 
   gst_segment_init (&segment, GST_FORMAT_TIME);
 
   /***************************
    * Normal segment
    ***************************/
-  gst_segment_set_newsegment_full (&segment, FALSE, 1.0, 1.0,
+  gst_segment_set_newsegment (&segment, FALSE, 1.0, 1.0,
       GST_FORMAT_TIME, 0, 200, 0);
 
   fail_unless (segment.rate == 1.0);
@@ -746,8 +755,8 @@ GST_START_TEST (segment_newsegment_streamtime)
   fail_unless (segment.start == 0);
   fail_unless (segment.stop == 200);
   fail_unless (segment.time == 0);
-  fail_unless (segment.accum == 0);
-  fail_unless (segment.last_stop == 0);
+  fail_unless (segment.base == 0);
+  fail_unless (segment.position == 0);
   fail_unless (segment.duration == -1);
 
   /* invalid time gives invalid result */
@@ -770,10 +779,10 @@ GST_START_TEST (segment_newsegment_streamtime)
   /*********************
    * time shifted by 500
    *********************/
-  gst_segment_set_newsegment_full (&segment, FALSE, 1.0, 1.0,
+  gst_segment_set_newsegment (&segment, FALSE, 1.0, 1.0,
       GST_FORMAT_TIME, 0, 200, 500);
 
-  fail_unless (segment.accum == 200);
+  fail_unless (segment.base == 200);
 
   /* invalid time gives invalid result */
   result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, -1);
@@ -795,10 +804,10 @@ GST_START_TEST (segment_newsegment_streamtime)
   /*********************
    * time offset by 500
    *********************/
-  gst_segment_set_newsegment_full (&segment, FALSE, 1.0, 1.0,
+  gst_segment_set_newsegment (&segment, FALSE, 1.0, 1.0,
       GST_FORMAT_TIME, 500, 700, 0);
 
-  fail_unless (segment.accum == 400);
+  fail_unless (segment.base == 400);
 
   /* invalid time gives invalid result */
   result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, -1);
@@ -824,10 +833,10 @@ GST_START_TEST (segment_newsegment_streamtime)
   /*************************************
    * time offset by 500, shifted by 200
    *************************************/
-  gst_segment_set_newsegment_full (&segment, FALSE, 1.0, 1.0,
+  gst_segment_set_newsegment (&segment, FALSE, 1.0, 1.0,
       GST_FORMAT_TIME, 500, 700, 200);
 
-  fail_unless (segment.accum == 600);
+  fail_unless (segment.base == 600);
 
   /* invalid time gives invalid result */
   result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, -1);
@@ -857,14 +866,14 @@ GST_END_TEST;
 GST_START_TEST (segment_newsegment_streamtime_rate)
 {
   GstSegment segment;
-  gint64 result;
+  guint64 result;
 
   gst_segment_init (&segment, GST_FORMAT_TIME);
 
   /***************************
    * Normal segment rate 2.0
    ***************************/
-  gst_segment_set_newsegment_full (&segment, FALSE, 2.0, 1.0,
+  gst_segment_set_newsegment (&segment, FALSE, 2.0, 1.0,
       GST_FORMAT_TIME, 0, 200, 0);
 
   fail_unless (segment.rate == 2.0);
@@ -874,8 +883,8 @@ GST_START_TEST (segment_newsegment_streamtime_rate)
   fail_unless (segment.start == 0);
   fail_unless (segment.stop == 200);
   fail_unless (segment.time == 0);
-  fail_unless (segment.accum == 0);
-  fail_unless (segment.last_stop == 0);
+  fail_unless (segment.base == 0);
+  fail_unless (segment.position == 0);
   fail_unless (segment.duration == -1);
 
   /* invalid time gives invalid result */
@@ -901,10 +910,10 @@ GST_START_TEST (segment_newsegment_streamtime_rate)
   /***************************************
    * Normal segment rate 2.0, offset
    ***************************************/
-  gst_segment_set_newsegment_full (&segment, FALSE, 2.0, 1.0,
+  gst_segment_set_newsegment (&segment, FALSE, 2.0, 1.0,
       GST_FORMAT_TIME, 100, 300, 0);
 
-  fail_unless (segment.accum == 100);
+  fail_unless (segment.base == 100);
 
   /* invalid time gives invalid result */
   result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, -1);
@@ -932,10 +941,10 @@ GST_START_TEST (segment_newsegment_streamtime_rate)
 
   /* buffers will arrive from 300 to 100 in a sink, stream time
    * calculation is unaffected by the rate */
-  gst_segment_set_newsegment_full (&segment, FALSE, -1.0, 1.0,
+  gst_segment_set_newsegment (&segment, FALSE, -1.0, 1.0,
       GST_FORMAT_TIME, 100, 300, 0);
 
-  fail_unless (segment.accum == 200);
+  fail_unless (segment.base == 200);
 
   /* invalid time gives invalid result */
   result = gst_segment_to_stream_time (&segment, GST_FORMAT_TIME, -1);
@@ -950,7 +959,7 @@ GST_START_TEST (segment_newsegment_streamtime_rate)
   /***********************************************
    * Normal segment rate -1.0, offset, time = 200
    ***********************************************/
-  gst_segment_set_newsegment_full (&segment, FALSE, -1.0, 1.0,
+  gst_segment_set_newsegment (&segment, FALSE, -1.0, 1.0,
       GST_FORMAT_TIME, 100, 300, 200);
 
   /* invalid time gives invalid result */
@@ -977,7 +986,7 @@ GST_END_TEST;
 GST_START_TEST (segment_newsegment_streamtime_applied_rate)
 {
   GstSegment segment;
-  gint64 result;
+  guint64 result;
 
   gst_segment_init (&segment, GST_FORMAT_TIME);
 
@@ -986,7 +995,7 @@ GST_START_TEST (segment_newsegment_streamtime_applied_rate)
    * This means the timestamps represents a stream going backwards
    * starting from @time to 0.
    ************************************************************/
-  gst_segment_set_newsegment_full (&segment, FALSE, 1.0, -1.0,
+  gst_segment_set_newsegment (&segment, FALSE, 1.0, -1.0,
       GST_FORMAT_TIME, 0, 200, 200);
 
   fail_unless (segment.rate == 1.0);
@@ -996,8 +1005,8 @@ GST_START_TEST (segment_newsegment_streamtime_applied_rate)
   fail_unless (segment.start == 0);
   fail_unless (segment.stop == 200);
   fail_unless (segment.time == 200);
-  fail_unless (segment.accum == 0);
-  fail_unless (segment.last_stop == 0);
+  fail_unless (segment.base == 0);
+  fail_unless (segment.position == 0);
   fail_unless (segment.duration == -1);
 
   /* invalid time gives invalid result */
@@ -1026,7 +1035,7 @@ GST_START_TEST (segment_newsegment_streamtime_applied_rate)
    * This means the timestamps represents a stream at twice the
    * normal rate
    ************************************************************/
-  gst_segment_set_newsegment_full (&segment, FALSE, 1.0, 2.0,
+  gst_segment_set_newsegment (&segment, FALSE, 1.0, 2.0,
       GST_FORMAT_TIME, 0, 200, 0);
 
   fail_unless (segment.rate == 1.0);
@@ -1036,8 +1045,8 @@ GST_START_TEST (segment_newsegment_streamtime_applied_rate)
   fail_unless (segment.start == 0);
   fail_unless (segment.stop == 200);
   fail_unless (segment.time == 0);
-  fail_unless (segment.accum == 200);
-  fail_unless (segment.last_stop == 0);
+  fail_unless (segment.base == 200);
+  fail_unless (segment.position == 0);
   fail_unless (segment.duration == -1);
 
   /* invalid time gives invalid result */
@@ -1067,7 +1076,7 @@ GST_START_TEST (segment_newsegment_streamtime_applied_rate)
    * This means the timestamps represents a stream at twice the
    * reverse rate
    ************************************************************/
-  gst_segment_set_newsegment_full (&segment, FALSE, 1.0, -2.0,
+  gst_segment_set_newsegment (&segment, FALSE, 1.0, -2.0,
       GST_FORMAT_TIME, 0, 200, 400);
 
   fail_unless (segment.rate == 1.0);
@@ -1078,8 +1087,8 @@ GST_START_TEST (segment_newsegment_streamtime_applied_rate)
   fail_unless (segment.stop == 200);
   fail_unless (segment.time == 400);
   /* previous segment lasted 200, rate of 2.0 was already applied */
-  fail_unless (segment.accum == 400);
-  fail_unless (segment.last_stop == 0);
+  fail_unless (segment.base == 400);
+  fail_unless (segment.position == 0);
   fail_unless (segment.duration == -1);
 
   /* invalid time gives invalid result */
@@ -1109,7 +1118,7 @@ GST_START_TEST (segment_newsegment_streamtime_applied_rate)
    * reverse rate, start time cannot compensate the complete
    * duration of the segment so we stop at 0
    ************************************************************/
-  gst_segment_set_newsegment_full (&segment, FALSE, 1.0, -2.0,
+  gst_segment_set_newsegment (&segment, FALSE, 1.0, -2.0,
       GST_FORMAT_TIME, 0, 200, 200);
 
   fail_unless (segment.rate == 1.0);
@@ -1119,8 +1128,8 @@ GST_START_TEST (segment_newsegment_streamtime_applied_rate)
   fail_unless (segment.start == 0);
   fail_unless (segment.stop == 200);
   fail_unless (segment.time == 200);
-  fail_unless (segment.accum == 600);
-  fail_unless (segment.last_stop == 0);
+  fail_unless (segment.base == 600);
+  fail_unless (segment.position == 0);
   fail_unless (segment.duration == -1);
 
   /* invalid time gives invalid result */
@@ -1152,7 +1161,7 @@ GST_END_TEST;
 GST_START_TEST (segment_newsegment_streamtime_applied_rate_rate)
 {
   GstSegment segment;
-  gint64 result;
+  guint64 result;
 
   gst_segment_init (&segment, GST_FORMAT_TIME);
 
@@ -1162,7 +1171,7 @@ GST_START_TEST (segment_newsegment_streamtime_applied_rate_rate)
    * speed up by a factor of 2.0 some more. the resulting
    * stream will be played at four times the speed. 
    ************************************************************/
-  gst_segment_set_newsegment_full (&segment, FALSE, 2.0, 2.0,
+  gst_segment_set_newsegment (&segment, FALSE, 2.0, 2.0,
       GST_FORMAT_TIME, 0, 200, 0);
 
   fail_unless (segment.rate == 2.0);
@@ -1172,8 +1181,8 @@ GST_START_TEST (segment_newsegment_streamtime_applied_rate_rate)
   fail_unless (segment.start == 0);
   fail_unless (segment.stop == 200);
   fail_unless (segment.time == 0);
-  fail_unless (segment.accum == 0);
-  fail_unless (segment.last_stop == 0);
+  fail_unless (segment.base == 0);
+  fail_unless (segment.position == 0);
   fail_unless (segment.duration == -1);
 
   /* invalid time gives invalid result */
@@ -1202,7 +1211,7 @@ GST_START_TEST (segment_newsegment_streamtime_applied_rate_rate)
    * this means we have a reverse stream that we should
    * speed up by a factor of 2.0
    ************************************************************/
-  gst_segment_set_newsegment_full (&segment, FALSE, 2.0, -1.0,
+  gst_segment_set_newsegment (&segment, FALSE, 2.0, -1.0,
       GST_FORMAT_TIME, 0, 200, 200);
 
   fail_unless (segment.rate == 2.0);
@@ -1213,8 +1222,8 @@ GST_START_TEST (segment_newsegment_streamtime_applied_rate_rate)
   fail_unless (segment.stop == 200);
   fail_unless (segment.time == 200);
   /* previous segment lasted 100 */
-  fail_unless (segment.accum == 100);
-  fail_unless (segment.last_stop == 0);
+  fail_unless (segment.base == 100);
+  fail_unless (segment.position == 0);
   fail_unless (segment.duration == -1);
 
   /* invalid time gives invalid result */
@@ -1243,7 +1252,7 @@ GST_START_TEST (segment_newsegment_streamtime_applied_rate_rate)
    * this means we have a reverse stream that we should
    * reverse to get the normal stream again.
    ************************************************************/
-  gst_segment_set_newsegment_full (&segment, FALSE, -1.0, -1.0,
+  gst_segment_set_newsegment (&segment, FALSE, -1.0, -1.0,
       GST_FORMAT_TIME, 0, 200, 200);
 
   fail_unless (segment.rate == -1.0);
@@ -1254,8 +1263,8 @@ GST_START_TEST (segment_newsegment_streamtime_applied_rate_rate)
   fail_unless (segment.stop == 200);
   fail_unless (segment.time == 200);
   /* accumulated 100 of previous segment to make 200 */
-  fail_unless (segment.accum == 200);
-  fail_unless (segment.last_stop == 200);
+  fail_unless (segment.base == 200);
+  fail_unless (segment.position == 200);
   fail_unless (segment.duration == -1);
 
   /* invalid time gives invalid result */
@@ -1284,7 +1293,7 @@ GST_START_TEST (segment_newsegment_streamtime_applied_rate_rate)
    * this means we have a reverse stream that we should
    * reverse to get the normal stream again.
    ************************************************************/
-  gst_segment_set_newsegment_full (&segment, FALSE, -1.0, 2.0,
+  gst_segment_set_newsegment (&segment, FALSE, -1.0, 2.0,
       GST_FORMAT_TIME, 0, 200, 0);
 
   fail_unless (segment.rate == -1.0);
@@ -1294,8 +1303,8 @@ GST_START_TEST (segment_newsegment_streamtime_applied_rate_rate)
   fail_unless (segment.start == 0);
   fail_unless (segment.stop == 200);
   fail_unless (segment.time == 0);
-  fail_unless (segment.accum == 400);
-  fail_unless (segment.last_stop == 200);
+  fail_unless (segment.base == 400);
+  fail_unless (segment.position == 200);
   fail_unless (segment.duration == -1);
 
   /* invalid time gives invalid result */
@@ -1326,14 +1335,14 @@ GST_END_TEST;
 GST_START_TEST (segment_newsegment_runningtime)
 {
   GstSegment segment;
-  gint64 result;
+  guint64 result;
 
   gst_segment_init (&segment, GST_FORMAT_TIME);
 
   /***************************
    * Normal segment
    ***************************/
-  gst_segment_set_newsegment_full (&segment, FALSE, 1.0, 1.0,
+  gst_segment_set_newsegment (&segment, FALSE, 1.0, 1.0,
       GST_FORMAT_TIME, 0, 200, 0);
 
   fail_unless (segment.rate == 1.0);
@@ -1343,8 +1352,8 @@ GST_START_TEST (segment_newsegment_runningtime)
   fail_unless (segment.start == 0);
   fail_unless (segment.stop == 200);
   fail_unless (segment.time == 0);
-  fail_unless (segment.accum == 0);
-  fail_unless (segment.last_stop == 0);
+  fail_unless (segment.base == 0);
+  fail_unless (segment.position == 0);
   fail_unless (segment.duration == -1);
 
   /* invalid time gives invalid result */
@@ -1379,11 +1388,11 @@ GST_START_TEST (segment_newsegment_runningtime)
    * all positions by 2.0 in this segment.
    * Then time argument is not used at all here.
    ***********************************************************/
-  gst_segment_set_newsegment_full (&segment, FALSE, 2.0, 1.0,
+  gst_segment_set_newsegment (&segment, FALSE, 2.0, 1.0,
       GST_FORMAT_TIME, 0, 200, 500);
 
   /* normal speed gives elapsed of 200 */
-  fail_unless (segment.accum == 200);
+  fail_unless (segment.base == 200);
 
   /* invalid time gives invalid result */
   result = gst_segment_to_running_time (&segment, GST_FORMAT_TIME, -1);
@@ -1409,12 +1418,12 @@ GST_START_TEST (segment_newsegment_runningtime)
    * time offset by 500
    * applied rate is not used for running time
    ********************************************/
-  gst_segment_set_newsegment_full (&segment, FALSE, 1.0, 2.0,
+  gst_segment_set_newsegment (&segment, FALSE, 1.0, 2.0,
       GST_FORMAT_TIME, 500, 700, 0);
 
   /* previous segment played at double speed gives elapsed time of
    * 100 added to previous accum of 200 gives 300. */
-  fail_unless (segment.accum == 300);
+  fail_unless (segment.base == 300);
 
   /* invalid time gives invalid result */
   result = gst_segment_to_running_time (&segment, GST_FORMAT_TIME, -1);
@@ -1453,10 +1462,10 @@ GST_START_TEST (segment_newsegment_runningtime)
    * relative to the segment stop position. again time
    * is ignored.
    **********************************************************/
-  gst_segment_set_newsegment_full (&segment, FALSE, -1.0, 1.0,
+  gst_segment_set_newsegment (&segment, FALSE, -1.0, 1.0,
       GST_FORMAT_TIME, 500, 700, 200);
 
-  fail_unless (segment.accum == 500);
+  fail_unless (segment.base == 500);
 
   /* invalid time gives invalid result */
   result = gst_segment_to_running_time (&segment, GST_FORMAT_TIME, -1);
@@ -1495,10 +1504,10 @@ GST_START_TEST (segment_newsegment_runningtime)
    * twice speed relative to the segment stop position. again 
    * time is ignored.
    **********************************************************/
-  gst_segment_set_newsegment_full (&segment, FALSE, -2.0, -2.0,
+  gst_segment_set_newsegment (&segment, FALSE, -2.0, -2.0,
       GST_FORMAT_TIME, 500, 700, 200);
 
-  fail_unless (segment.accum == 700);
+  fail_unless (segment.base == 700);
 
   /* invalid time gives invalid result */
   result = gst_segment_to_running_time (&segment, GST_FORMAT_TIME, -1);
@@ -1533,11 +1542,11 @@ GST_START_TEST (segment_newsegment_runningtime)
   fail_unless (result == -1);
 
   /* see if negative rate closed segment correctly */
-  gst_segment_set_newsegment_full (&segment, FALSE, -2.0, -1.0,
+  gst_segment_set_newsegment (&segment, FALSE, -2.0, -1.0,
       GST_FORMAT_TIME, 500, 700, 200);
 
   /* previous segment lasted 100, and was at 700 so we should get 800 */
-  fail_unless (segment.accum == 800);
+  fail_unless (segment.base == 800);
   result = gst_segment_to_position (&segment, GST_FORMAT_TIME, 800);
   fail_unless (result == 700);
 }
@@ -1548,14 +1557,14 @@ GST_END_TEST;
 GST_START_TEST (segment_newsegment_accum)
 {
   GstSegment segment;
-  gint64 result;
+  guint64 result;
 
   gst_segment_init (&segment, GST_FORMAT_TIME);
 
   /***************************
    * Normal reverse segment
    ***************************/
-  gst_segment_set_newsegment_full (&segment, FALSE, -1.0, 1.0,
+  gst_segment_set_newsegment (&segment, FALSE, -1.0, 1.0,
       GST_FORMAT_TIME, 0, 200, 0);
 
   fail_unless (segment.rate == -1.0);
@@ -1565,8 +1574,8 @@ GST_START_TEST (segment_newsegment_accum)
   fail_unless (segment.start == 0);
   fail_unless (segment.stop == 200);
   fail_unless (segment.time == 0);
-  fail_unless (segment.accum == 0);
-  fail_unless (segment.last_stop == 200);
+  fail_unless (segment.base == 0);
+  fail_unless (segment.position == 200);
   fail_unless (segment.duration == -1);
 
   /* invalid time gives invalid result */
@@ -1584,7 +1593,7 @@ GST_START_TEST (segment_newsegment_accum)
   fail_unless (result == 150);
 
   /* update segment, this accumulates 50 from the previous segment. */
-  gst_segment_set_newsegment_full (&segment, TRUE, -2.0, 1.0,
+  gst_segment_set_newsegment (&segment, TRUE, -2.0, 1.0,
       GST_FORMAT_TIME, 0, 150, 0);
 
   fail_unless (segment.rate == -2.0);
@@ -1594,8 +1603,8 @@ GST_START_TEST (segment_newsegment_accum)
   fail_unless (segment.start == 0);
   fail_unless (segment.stop == 150);
   fail_unless (segment.time == 0);
-  fail_unless (segment.accum == 50);
-  fail_unless (segment.last_stop == 150);
+  fail_unless (segment.base == 50);
+  fail_unless (segment.position == 150);
   fail_unless (segment.duration == -1);
 
   result = gst_segment_to_running_time (&segment, GST_FORMAT_TIME, 150);
@@ -1610,7 +1619,7 @@ GST_START_TEST (segment_newsegment_accum)
   fail_unless (result == 100);
 
   /* update segment, this does not accumulate anything. */
-  gst_segment_set_newsegment_full (&segment, TRUE, 1.0, 1.0,
+  gst_segment_set_newsegment (&segment, TRUE, 1.0, 1.0,
       GST_FORMAT_TIME, 100, 200, 100);
 
   fail_unless (segment.rate == 1.0);
@@ -1620,8 +1629,8 @@ GST_START_TEST (segment_newsegment_accum)
   fail_unless (segment.start == 100);
   fail_unless (segment.stop == 200);
   fail_unless (segment.time == 100);
-  fail_unless (segment.accum == 50);
-  fail_unless (segment.last_stop == 150);
+  fail_unless (segment.base == 50);
+  fail_unless (segment.position == 150);
   fail_unless (segment.duration == -1);
 
   result = gst_segment_to_running_time (&segment, GST_FORMAT_TIME, 100);
@@ -1641,14 +1650,14 @@ GST_END_TEST;
 GST_START_TEST (segment_newsegment_accum2)
 {
   GstSegment segment;
-  gint64 result;
+  guint64 result;
 
   gst_segment_init (&segment, GST_FORMAT_TIME);
 
   /***************************
    * Normal reverse segment
    ***************************/
-  gst_segment_set_newsegment_full (&segment, FALSE, -1.0, 1.0,
+  gst_segment_set_newsegment (&segment, FALSE, -1.0, 1.0,
       GST_FORMAT_TIME, 0, 200, 0);
 
   fail_unless (segment.rate == -1.0);
@@ -1658,8 +1667,8 @@ GST_START_TEST (segment_newsegment_accum2)
   fail_unless (segment.start == 0);
   fail_unless (segment.stop == 200);
   fail_unless (segment.time == 0);
-  fail_unless (segment.accum == 0);
-  fail_unless (segment.last_stop == 200);
+  fail_unless (segment.base == 0);
+  fail_unless (segment.position == 200);
   fail_unless (segment.duration == -1);
 
   /* invalid time gives invalid result */
@@ -1679,7 +1688,7 @@ GST_START_TEST (segment_newsegment_accum2)
   fail_unless (result == 150);
 
   /* close segment, this accumulates nothing. */
-  gst_segment_set_newsegment_full (&segment, TRUE, -1.0, 1.0,
+  gst_segment_set_newsegment (&segment, TRUE, -1.0, 1.0,
       GST_FORMAT_TIME, 150, 200, 0);
 
   fail_unless (segment.rate == -1.0);
@@ -1689,12 +1698,12 @@ GST_START_TEST (segment_newsegment_accum2)
   fail_unless (segment.start == 150);
   fail_unless (segment.stop == 200);
   fail_unless (segment.time == 0);
-  fail_unless (segment.accum == 0);
-  fail_unless (segment.last_stop == 200);
+  fail_unless (segment.base == 0);
+  fail_unless (segment.position == 200);
   fail_unless (segment.duration == -1);
 
   /* new segment, this accumulates 50. */
-  gst_segment_set_newsegment_full (&segment, FALSE, 1.0, 1.0,
+  gst_segment_set_newsegment (&segment, FALSE, 1.0, 1.0,
       GST_FORMAT_TIME, 150, 300, 150);
 
   fail_unless (segment.rate == 1.0);
@@ -1704,8 +1713,8 @@ GST_START_TEST (segment_newsegment_accum2)
   fail_unless (segment.start == 150);
   fail_unless (segment.stop == 300);
   fail_unless (segment.time == 150);
-  fail_unless (segment.accum == 50);
-  fail_unless (segment.last_stop == 150);
+  fail_unless (segment.base == 50);
+  fail_unless (segment.position == 150);
   fail_unless (segment.duration == -1);
 
   /* invalid time gives invalid result */
@@ -1724,6 +1733,7 @@ GST_START_TEST (segment_newsegment_accum2)
 }
 
 GST_END_TEST;
+#endif
 
 GST_START_TEST (segment_copy)
 {
@@ -1735,8 +1745,11 @@ GST_START_TEST (segment_copy)
 
   gst_segment_init (&segment, GST_FORMAT_TIME);
 
-  gst_segment_set_newsegment_full (&segment, FALSE, -1.0, 1.0,
-      GST_FORMAT_TIME, 0, 200, 0);
+  segment.rate = -1.0;
+  segment.applied_rate = 1.0;
+  segment.start = 0;
+  segment.stop = 200;
+  segment.time = 0;
 
   copy = gst_segment_copy (&segment);
   fail_unless (copy != NULL);
@@ -1761,6 +1774,7 @@ gst_segment_suite (void)
   tcase_add_test (tc_chain, segment_seek_size);
   tcase_add_test (tc_chain, segment_seek_reverse);
   tcase_add_test (tc_chain, segment_seek_rate);
+#if 0
   tcase_add_test (tc_chain, segment_newsegment_open);
   tcase_add_test (tc_chain, segment_newsegment_closed);
   tcase_add_test (tc_chain, segment_newsegment_streamtime);
@@ -1770,6 +1784,7 @@ gst_segment_suite (void)
   tcase_add_test (tc_chain, segment_newsegment_runningtime);
   tcase_add_test (tc_chain, segment_newsegment_accum);
   tcase_add_test (tc_chain, segment_newsegment_accum2);
+#endif
   tcase_add_test (tc_chain, segment_copy);
 
   return s;
index b37bd24..b19762a 100644 (file)
@@ -159,11 +159,9 @@ GST_START_TEST (test_from_string)
   fail_unless_equals_int (g_value_get_boolean (val), TRUE);
   gst_structure_free (structure);
 
-  /* This should still work for now (FIXME: 0.11) */
   s = "0.10:decoder-video/mpeg, abc=(boolean)false";
-  structure = gst_structure_from_string (s, NULL);
-  fail_if (structure == NULL, "Could not get structure from string %s", s);
-  gst_structure_free (structure);
+  ASSERT_CRITICAL (structure = gst_structure_from_string (s, NULL));
+  fail_unless (structure == NULL, "Could not get structure from string %s", s);
 
   /* make sure we bail out correctly in case of an error or if parsing fails */
   s = "***foo***, abc=(boolean)false";
@@ -188,22 +186,10 @@ GST_START_TEST (test_to_string)
   ASSERT_CRITICAL (st1 = gst_structure_new ("Foo\nwith-newline", NULL));
   fail_unless (st1 == NULL);
 
-  /* FIXME 0.11: re-enable this */
-#if 0
   ASSERT_CRITICAL (st1 = gst_structure_new ("Foo with whitespace", NULL));
   fail_unless (st1 == NULL);
   ASSERT_CRITICAL (st1 = gst_structure_new ("1st", NULL));
   fail_unless (st1 == NULL);
-#else
-  st1 = gst_structure_new ("Foo with whitespace is still allowed", NULL);
-  fail_unless (st1 != NULL);
-  gst_structure_free (st1);
-
-  /* structure names starting with a number are also still allowed */
-  st1 = gst_structure_new ("1st", NULL);
-  fail_unless (st1 != NULL);
-  gst_structure_free (st1);
-#endif
 }
 
 GST_END_TEST;
@@ -339,8 +325,8 @@ GST_START_TEST (test_structure_new)
   g_error_free (e);
   gst_structure_free (s);
 
-  /* This should still work for now (FIXME 0.11) */
-  gst_structure_free (gst_structure_new ("0.10:decoder-video/mpeg", NULL));
+  ASSERT_CRITICAL (gst_structure_free (gst_structure_new
+          ("0.10:decoder-video/mpeg", NULL)));
 
   /* make sure we bail out correctly in case of an error or if parsing fails */
   ASSERT_CRITICAL (s = gst_structure_new ("^joo\nba\ndoo^",
@@ -509,11 +495,15 @@ GST_START_TEST (test_vararg_getters)
   gint64 i64;
   gchar *c;
   gint i, num, denom;
+  guint8 *data;
 
   buf = gst_buffer_new_and_alloc (3);
-  GST_BUFFER_DATA (buf)[0] = 0xf0;
-  GST_BUFFER_DATA (buf)[1] = 0x66;
-  GST_BUFFER_DATA (buf)[2] = 0x0d;
+
+  data = gst_buffer_map (buf, NULL, NULL, GST_MAP_WRITE);
+  data[0] = 0xf0;
+  data[1] = 0x66;
+  data[2] = 0x0d;
+  gst_buffer_unmap (buf, data, 3);
 
   caps = gst_caps_new_simple ("video/x-foo", NULL);
 
index ecf8223..11249df 100644 (file)
@@ -373,8 +373,8 @@ GST_START_TEST (test_buffer_tags)
   fail_if (!gst_tag_list_get_buffer_index (tags, GST_TAG_IMAGE, 0, &buf1));
   fail_if (!gst_tag_list_get_buffer_index (tags, GST_TAG_PREVIEW_IMAGE, 0,
           &buf2));
-  fail_unless_equals_int (GST_BUFFER_SIZE (buf1), 222);
-  fail_unless_equals_int (GST_BUFFER_SIZE (buf2), 100);
+  fail_unless_equals_int (gst_buffer_get_size (buf1), 222);
+  fail_unless_equals_int (gst_buffer_get_size (buf2), 100);
 
   gst_buffer_unref (buf1);
   gst_buffer_unref (buf2);
index 5802823..b25ea8d 100644 (file)
 typedef GstElement GstDummyEnc;
 typedef GstElementClass GstDummyEncClass;
 
-static void gst_dummy_enc_add_interfaces (GType enc_type);
-
 GType gst_dummy_enc_get_type (void);
-GST_BOILERPLATE_FULL (GstDummyEnc, gst_dummy_enc, GstElement,
-    GST_TYPE_ELEMENT, gst_dummy_enc_add_interfaces);
-
-static void
-gst_dummy_enc_add_interfaces (GType enc_type)
-{
-  static const GInterfaceInfo tag_setter_info = { NULL, NULL, NULL };
-
-  g_type_add_interface_static (enc_type, GST_TYPE_TAG_SETTER, &tag_setter_info);
-}
-
-static void
-gst_dummy_enc_base_init (gpointer g_class)
-{
-}
+G_DEFINE_TYPE_WITH_CODE (GstDummyEnc, gst_dummy_enc,
+    GST_TYPE_ELEMENT, G_IMPLEMENT_INTERFACE (GST_TYPE_TAG_SETTER, NULL));
 
 static void
 gst_dummy_enc_class_init (GstDummyEncClass * klass)
@@ -52,7 +37,7 @@ gst_dummy_enc_class_init (GstDummyEncClass * klass)
 }
 
 static void
-gst_dummy_enc_init (GstDummyEnc * enc, GstDummyEncClass * klass)
+gst_dummy_enc_init (GstDummyEnc * enc)
 {
 }
 
index 5324b14..9498c04 100644 (file)
@@ -32,42 +32,48 @@ static int n_data_probes = 0;
 static int n_buffer_probes = 0;
 static int n_event_probes = 0;
 
-static gboolean
-probe_do_nothing (GstPad * pad, GstMiniObject * obj, gpointer data)
+static GstProbeReturn
+probe_do_nothing (GstPad * pad, GstProbeType type, gpointer type_data,
+    gpointer data)
 {
+  GstMiniObject *obj = type_data;
   GST_DEBUG_OBJECT (pad, "is buffer:%d", GST_IS_BUFFER (obj));
-  return TRUE;
+  return GST_PROBE_OK;
 }
 
-static gboolean
-data_probe (GstPad * pad, GstMiniObject * obj, gpointer data)
+static GstProbeReturn
+data_probe (GstPad * pad, GstProbeType type, gpointer type_data, gpointer data)
 {
+  GstMiniObject *obj = type_data;
   n_data_probes++;
   GST_DEBUG_OBJECT (pad, "data probe %d", n_data_probes);
-  g_assert (GST_IS_MINI_OBJECT (obj));
+  g_assert (GST_IS_BUFFER (obj) || GST_IS_EVENT (obj));
   g_assert (data == SPECIAL_POINTER (0));
-  return TRUE;
+  return GST_PROBE_OK;
 }
 
-static gboolean
-buffer_probe (GstPad * pad, GstBuffer * obj, gpointer data)
+static GstProbeReturn
+buffer_probe (GstPad * pad, GstProbeType type, gpointer type_data,
+    gpointer data)
 {
+  GstBuffer *obj = type_data;
   n_buffer_probes++;
   GST_DEBUG_OBJECT (pad, "buffer probe %d", n_buffer_probes);
   g_assert (GST_IS_BUFFER (obj));
   g_assert (data == SPECIAL_POINTER (1));
-  return TRUE;
+  return GST_PROBE_OK;
 }
 
-static gboolean
-event_probe (GstPad * pad, GstEvent * obj, gpointer data)
+static GstProbeReturn
+event_probe (GstPad * pad, GstProbeType type, gpointer type_data, gpointer data)
 {
+  GstEvent *obj = type_data;
   n_event_probes++;
   GST_DEBUG_OBJECT (pad, "event probe %d [%s]",
       n_event_probes, GST_EVENT_TYPE_NAME (obj));
   g_assert (GST_IS_EVENT (obj));
   g_assert (data == SPECIAL_POINTER (2));
-  return TRUE;
+  return GST_PROBE_OK;
 }
 
 GST_START_TEST (test_buffer_probe_n_times)
@@ -89,18 +95,20 @@ GST_START_TEST (test_buffer_probe_n_times)
   pad = gst_element_get_static_pad (fakesink, "sink");
 
   /* add the probes we need for the test */
-  gst_pad_add_data_probe (pad, G_CALLBACK (data_probe), SPECIAL_POINTER (0));
-  gst_pad_add_buffer_probe (pad, G_CALLBACK (buffer_probe),
-      SPECIAL_POINTER (1));
-  gst_pad_add_event_probe (pad, G_CALLBACK (event_probe), SPECIAL_POINTER (2));
-
-  /* add some probes just to test that _full works and the data is free'd
+  gst_pad_add_probe (pad, GST_PROBE_TYPE_DATA, data_probe, SPECIAL_POINTER (0),
+      NULL);
+  gst_pad_add_probe (pad, GST_PROBE_TYPE_BUFFER, buffer_probe,
+      SPECIAL_POINTER (1), NULL);
+  gst_pad_add_probe (pad, GST_PROBE_TYPE_EVENT, event_probe,
+      SPECIAL_POINTER (2), NULL);
+
+  /* add some string probes just to test that the data is free'd
    * properly as it should be */
-  gst_pad_add_data_probe_full (pad, G_CALLBACK (probe_do_nothing),
+  gst_pad_add_probe (pad, GST_PROBE_TYPE_DATA, probe_do_nothing,
       g_strdup ("data probe string"), (GDestroyNotify) g_free);
-  gst_pad_add_buffer_probe_full (pad, G_CALLBACK (probe_do_nothing),
+  gst_pad_add_probe (pad, GST_PROBE_TYPE_BUFFER, probe_do_nothing,
       g_strdup ("buffer probe string"), (GDestroyNotify) g_free);
-  gst_pad_add_event_probe_full (pad, G_CALLBACK (probe_do_nothing),
+  gst_pad_add_probe (pad, GST_PROBE_TYPE_EVENT, probe_do_nothing,
       g_strdup ("event probe string"), (GDestroyNotify) g_free);
 
   gst_object_unref (pad);
@@ -129,37 +137,39 @@ static int n_data_probes_once = 0;
 static int n_buffer_probes_once = 0;
 static int n_event_probes_once = 0;
 
-static gboolean
-data_probe_once (GstPad * pad, GstMiniObject * obj, guint * data)
+static GstProbeReturn
+data_probe_once (GstPad * pad, GstProbeType type, GstMiniObject * obj,
+    guint * data)
 {
   n_data_probes_once++;
-  g_assert (GST_IS_MINI_OBJECT (obj));
+  g_assert (GST_IS_BUFFER (obj) || GST_IS_EVENT (obj));
 
-  gst_pad_remove_data_probe (pad, *data);
+  gst_pad_remove_probe (pad, *data);
 
-  return TRUE;
+  return GST_PROBE_OK;
 }
 
-static gboolean
-buffer_probe_once (GstPad * pad, GstBuffer * obj, guint * data)
+static GstProbeReturn
+buffer_probe_once (GstPad * pad, GstProbeType type, GstBuffer * obj,
+    guint * data)
 {
   n_buffer_probes_once++;
   g_assert (GST_IS_BUFFER (obj));
 
-  gst_pad_remove_buffer_probe (pad, *data);
+  gst_pad_remove_probe (pad, *data);
 
-  return TRUE;
+  return GST_PROBE_OK;
 }
 
-static gboolean
-event_probe_once (GstPad * pad, GstEvent * obj, guint * data)
+static GstProbeReturn
+event_probe_once (GstPad * pad, GstProbeType type, GstEvent * obj, guint * data)
 {
   n_event_probes_once++;
   g_assert (GST_IS_EVENT (obj));
 
-  gst_pad_remove_event_probe (pad, *data);
+  gst_pad_remove_probe (pad, *data);
 
-  return TRUE;
+  return GST_PROBE_OK;
 }
 
 GST_START_TEST (test_buffer_probe_once)
@@ -180,9 +190,15 @@ GST_START_TEST (test_buffer_probe_once)
   gst_element_link (fakesrc, fakesink);
 
   pad = gst_element_get_static_pad (fakesink, "sink");
-  id1 = gst_pad_add_data_probe (pad, G_CALLBACK (data_probe_once), &id1);
-  id2 = gst_pad_add_buffer_probe (pad, G_CALLBACK (buffer_probe_once), &id2);
-  id3 = gst_pad_add_event_probe (pad, G_CALLBACK (event_probe_once), &id3);
+  id1 =
+      gst_pad_add_probe (pad, GST_PROBE_TYPE_DATA,
+      (GstPadProbeCallback) data_probe_once, &id1, NULL);
+  id2 =
+      gst_pad_add_probe (pad, GST_PROBE_TYPE_BUFFER,
+      (GstPadProbeCallback) buffer_probe_once, &id2, NULL);
+  id3 =
+      gst_pad_add_probe (pad, GST_PROBE_TYPE_EVENT,
+      (GstPadProbeCallback) event_probe_once, &id3, NULL);
   gst_object_unref (pad);
 
   gst_element_set_state (pipeline, GST_STATE_PLAYING);
@@ -974,8 +990,12 @@ GST_START_TEST (test_pad_proxy_getcaps_aggregation)
 
   tee_sink = gst_element_get_static_pad (tee, "sink");
 
+  gst_element_set_state (sink1, GST_STATE_PAUSED);
+  gst_element_set_state (sink2, GST_STATE_PAUSED);
+  gst_element_set_state (tee, GST_STATE_PAUSED);
+
   /* by default, ANY caps should intersect to ANY */
-  caps = gst_pad_get_caps (tee_sink);
+  caps = gst_pad_get_caps (tee_sink, NULL);
   GST_INFO ("got caps: %" GST_PTR_FORMAT, caps);
   fail_unless (caps != NULL);
   fail_unless (gst_caps_is_any (caps));
@@ -992,7 +1012,7 @@ GST_START_TEST (test_pad_proxy_getcaps_aggregation)
   gst_pad_use_fixed_caps (sink2_sink);
   gst_caps_unref (caps);
 
-  caps = gst_pad_get_caps (tee_sink);
+  caps = gst_pad_get_caps (tee_sink, NULL);
   GST_INFO ("got caps: %" GST_PTR_FORMAT, caps);
   fail_unless (caps != NULL);
   fail_unless (gst_caps_is_empty (caps));
@@ -1004,7 +1024,7 @@ GST_START_TEST (test_pad_proxy_getcaps_aggregation)
   gst_pad_use_fixed_caps (sink2_sink);
   gst_caps_unref (caps);
 
-  caps = gst_pad_get_caps (tee_sink);
+  caps = gst_pad_get_caps (tee_sink, NULL);
   GST_INFO ("got caps: %" GST_PTR_FORMAT, caps);
   fail_unless (caps != NULL);
   fail_if (gst_caps_is_empty (caps));
@@ -1016,6 +1036,10 @@ GST_START_TEST (test_pad_proxy_getcaps_aggregation)
   }
   gst_caps_unref (caps);
 
+  gst_element_set_state (sink1, GST_STATE_NULL);
+  gst_element_set_state (sink2, GST_STATE_NULL);
+  gst_element_set_state (tee, GST_STATE_NULL);
+
   /* clean up */
   gst_element_release_request_pad (tee, tee_src1);
   gst_object_unref (tee_src1);
index 94f113e..2e5540c 100644 (file)
@@ -118,7 +118,7 @@ GST_START_TEST (test_deserialize_buffer)
   g_value_init (&value, GST_TYPE_BUFFER);
   fail_unless (gst_value_deserialize (&value, "1234567890abcdef"));
   /* does not increase the refcount */
-  buf = GST_BUFFER (gst_value_get_mini_object (&value));
+  buf = GST_BUFFER (g_value_get_boxed (&value));
   ASSERT_MINI_OBJECT_REFCOUNT (buf, "buffer", 1);
 
   /* does not increase the refcount */
@@ -139,10 +139,15 @@ GST_START_TEST (test_serialize_buffer)
   gchar *serialized;
   static const char *buf_data = "1234567890abcdef";
   gint len;
+  gpointer data;
 
   len = strlen (buf_data);
   buf = gst_buffer_new_and_alloc (len);
-  memcpy (GST_BUFFER_DATA (buf), buf_data, len);
+
+  data = gst_buffer_map (buf, NULL, NULL, GST_MAP_WRITE);
+  memcpy (data, buf_data, len);
+  gst_buffer_unmap (buf, data, len);
+
   ASSERT_MINI_OBJECT_REFCOUNT (buf, "buffer", 1);
 
   /* and assign buffer to mini object */
diff --git a/tests/check/gst/gstxml.c b/tests/check/gst/gstxml.c
deleted file mode 100644 (file)
index ed38d22..0000000
+++ /dev/null
@@ -1,87 +0,0 @@
-/* GStreamer
- * Copyright (C) 2006 Tim-Philipp Müller <tim centricular net>
- *
- * gstxml.c: Unit test for GstXML
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-
-#include <gst/check/gstcheck.h>
-#include <string.h>
-
-#define XML_PIPELINE                                             \
-  "<?xml version=\"1.0\"?>"                                      \
-  "<gstreamer xmlns:gst=\"http://gstreamer.net/gst-core/1.0/\">" \
-  "  <gst:element>"                                              \
-  "    <gst:name>test-pipeline</gst:name>"                       \
-  "    <gst:type>pipeline</gst:type>"                            \
-  "    <gst:param>"                                              \
-  "      <gst:name>name</gst:name>"                              \
-  "      <gst:value>test-pipeline</gst:value>"                   \
-  "    </gst:param>"                                             \
-  "  </gst:element>"                                             \
-  "</gstreamer>"
-
-
-GST_START_TEST (test_pipeline_from_xml)
-{
-  GstElement *element;
-  GstXML *xml;
-  GList *elements;
-
-  xml = gst_xml_new ();
-  fail_unless (xml != NULL);
-  ASSERT_OBJECT_REFCOUNT (xml, "GstXML object after creating it", 1);
-
-  fail_unless (gst_xml_parse_memory (xml, (guchar *) XML_PIPELINE,
-          strlen (XML_PIPELINE), NULL));
-
-  elements = gst_xml_get_topelements (xml);
-  fail_unless (elements != NULL);
-  fail_unless (g_list_length (elements) == 1);
-
-  element = GST_ELEMENT (elements->data);
-  fail_unless (element != NULL);
-  fail_unless (GST_IS_PIPELINE (element));
-  fail_unless_equals_string (GST_OBJECT_NAME (element), "test-pipeline");
-
-  ASSERT_OBJECT_REFCOUNT (element, "pipeline owned by GstXML", 1);
-  gst_object_ref (element);
-  ASSERT_OBJECT_REFCOUNT (element, "pipeline after we obtained a ref", 2);
-
-  gst_object_unref (xml);
-
-  ASSERT_OBJECT_REFCOUNT (element, "pipeline after GstXML was unrefed", 1);
-  gst_object_unref (element);
-}
-
-GST_END_TEST;
-
-static Suite *
-gst_xml_suite (void)
-{
-  Suite *s = suite_create ("GstXML");
-  TCase *tc_chain = tcase_create ("xml");
-
-  tcase_set_timeout (tc_chain, 20);
-
-  suite_add_tcase (s, tc_chain);
-  tcase_add_test (tc_chain, test_pipeline_from_xml);
-  return s;
-}
-
-GST_CHECK_MAIN (gst_xml);
index 23ac70e..3d3e133 100644 (file)
@@ -67,9 +67,5 @@ GstCheckABIStruct list[] = {
   {"GstTypeFindFactoryClass", sizeof (GstTypeFindFactoryClass), 152},
   {"GstURIHandlerInterface", sizeof (GstURIHandlerInterface), 44},
   {"GstValueTable", sizeof (GstValueTable), 32},
-#if !defined(GST_DISABLE_LOADSAVE) && !defined(GST_DISABLE_DEPRECATED) && !defined(GST_REMOVE_DEPRECATED)
-  {"GstXML", sizeof (GstXML), 64},
-  {"GstXMLClass", sizeof (GstXMLClass), 144},
-#endif
   {NULL, 0, 0}
 };
index f59fe07..b178244 100644 (file)
@@ -66,9 +66,5 @@ static GstCheckABIStruct list[] = {
   {"GstTypeFindFactoryClass", sizeof (GstTypeFindFactoryClass), 152},
   {"GstURIHandlerInterface", sizeof (GstURIHandlerInterface), 44},
   {"GstValueTable", sizeof (GstValueTable), 32},
-#if !defined(GST_DISABLE_LOADSAVE) && !defined(GST_DISABLE_DEPRECATED) && !defined(GST_REMOVE_DEPRECATED)
-  {"GstXML", sizeof (GstXML), 64},
-  {"GstXMLClass", sizeof (GstXMLClass), 144},
-#endif
   {NULL, 0, 0}
 };
index 06de6fd..744b7f2 100644 (file)
@@ -66,9 +66,5 @@ static GstCheckABIStruct list[] = {
  {"GstTypeFindFactoryClass", sizeof(GstTypeFindFactoryClass), 152},
  {"GstURIHandlerInterface", sizeof(GstURIHandlerInterface), 44},
  {"GstValueTable", sizeof(GstValueTable), 32},
-#if !defined(GST_DISABLE_LOADSAVE) && !defined(GST_DISABLE_DEPRECATED) && !defined(GST_REMOVE_DEPRECATED)
- {"GstXML", sizeof(GstXML), 64},
- {"GstXMLClass", sizeof(GstXMLClass), 144},
-#endif
  {NULL, 0, 0}
 };
index f59fe07..b178244 100644 (file)
@@ -66,9 +66,5 @@ static GstCheckABIStruct list[] = {
   {"GstTypeFindFactoryClass", sizeof (GstTypeFindFactoryClass), 152},
   {"GstURIHandlerInterface", sizeof (GstURIHandlerInterface), 44},
   {"GstValueTable", sizeof (GstValueTable), 32},
-#if !defined(GST_DISABLE_LOADSAVE) && !defined(GST_DISABLE_DEPRECATED) && !defined(GST_REMOVE_DEPRECATED)
-  {"GstXML", sizeof (GstXML), 64},
-  {"GstXMLClass", sizeof (GstXMLClass), 144},
-#endif
   {NULL, 0, 0}
 };
index 4bb20fa..259f902 100644 (file)
@@ -66,9 +66,5 @@ static GstCheckABIStruct list[] = {
   {"GstTypeFindFactoryClass", sizeof (GstTypeFindFactoryClass), 304} ,
   {"GstURIHandlerInterface", sizeof (GstURIHandlerInterface), 88} ,
   {"GstValueTable", sizeof (GstValueTable), 64} ,
-#if !defined(GST_DISABLE_LOADSAVE) && !defined(GST_DISABLE_DEPRECATED) && !defined(GST_REMOVE_DEPRECATED)
-  {"GstXML", sizeof (GstXML), 128} ,
-  {"GstXMLClass", sizeof (GstXMLClass), 288} ,
-#endif
   {NULL, 0, 0}
 };
index 23ac70e..3d3e133 100644 (file)
@@ -67,9 +67,5 @@ GstCheckABIStruct list[] = {
   {"GstTypeFindFactoryClass", sizeof (GstTypeFindFactoryClass), 152},
   {"GstURIHandlerInterface", sizeof (GstURIHandlerInterface), 44},
   {"GstValueTable", sizeof (GstValueTable), 32},
-#if !defined(GST_DISABLE_LOADSAVE) && !defined(GST_DISABLE_DEPRECATED) && !defined(GST_REMOVE_DEPRECATED)
-  {"GstXML", sizeof (GstXML), 64},
-  {"GstXMLClass", sizeof (GstXMLClass), 144},
-#endif
   {NULL, 0, 0}
 };
index e035090..51f010b 100644 (file)
@@ -80,9 +80,5 @@ static GstCheckABIStruct list[] = {
   {"GstTypeNameData", sizeof (GstTypeNameData), 16},
   {"GstURIHandlerInterface", sizeof (GstURIHandlerInterface), 88},
   {"GstValueTable", sizeof (GstValueTable), 64},
-#if !defined(GST_DISABLE_LOADSAVE) && !defined(GST_DISABLE_DEPRECATED) && !defined(GST_REMOVE_DEPRECATED)
-  {"GstXML", sizeof (GstXML), 128} ,
-  {"GstXMLClass", sizeof (GstXMLClass), 288} ,
-#endif
   {NULL, 0, 0}
 };
index de0e4f9..b456473 100644 (file)
@@ -43,7 +43,8 @@ GST_START_TEST (test_peek1)
 
   /* push single buffer in adapter */
   buffer = gst_buffer_new_and_alloc (512);
-  bufdata = GST_BUFFER_DATA (buffer);
+
+  bufdata = gst_buffer_map (buffer, NULL, NULL, GST_MAP_READ);
 
   fail_if (buffer == NULL);
   gst_adapter_push (adapter, buffer);
@@ -56,22 +57,25 @@ GST_START_TEST (test_peek1)
   fail_if (avail != 512);
 
   /* should g_critical with NULL as result */
-  ASSERT_CRITICAL (data1 = gst_adapter_peek (adapter, 0));
+  ASSERT_CRITICAL (data1 = gst_adapter_map (adapter, 0));
   fail_if (data1 != NULL);
 
   /* should return NULL as result */
-  data1 = gst_adapter_peek (adapter, 513);
+  data1 = gst_adapter_map (adapter, 513);
   fail_if (data1 != NULL);
 
   /* this should work */
-  data1 = gst_adapter_peek (adapter, 512);
+  data1 = gst_adapter_map (adapter, 512);
   fail_if (data1 == NULL);
   /* it should point to the buffer data as well */
   fail_if (data1 != bufdata);
-  data2 = gst_adapter_peek (adapter, 512);
+  gst_adapter_unmap (adapter, 0);
+
+  data2 = gst_adapter_map (adapter, 512);
   fail_if (data2 == NULL);
   /* second peek should return the same pointer */
   fail_if (data2 != data1);
+  gst_adapter_unmap (adapter, 0);
 
   /* this should fail since we don't have that many bytes */
   ASSERT_CRITICAL (gst_adapter_flush (adapter, 513));
@@ -86,15 +90,16 @@ GST_START_TEST (test_peek1)
   fail_if (avail != 502);
 
   /* should return NULL as result */
-  data2 = gst_adapter_peek (adapter, 503);
+  data2 = gst_adapter_map (adapter, 503);
   fail_if (data2 != NULL);
 
   /* should work fine */
-  data2 = gst_adapter_peek (adapter, 502);
+  data2 = gst_adapter_map (adapter, 502);
   fail_if (data2 == NULL);
   /* peek should return the same old pointer + 10 */
   fail_if (data2 != data1 + 10);
   fail_if (data2 != bufdata + 10);
+  gst_adapter_unmap (adapter, 0);
 
   /* flush some more */
   gst_adapter_flush (adapter, 500);
@@ -105,10 +110,11 @@ GST_START_TEST (test_peek1)
   avail = gst_adapter_available_fast (adapter);
   fail_if (avail != 2);
 
-  data2 = gst_adapter_peek (adapter, 2);
+  data2 = gst_adapter_map (adapter, 2);
   fail_if (data2 == NULL);
   fail_if (data2 != data1 + 510);
   fail_if (data2 != bufdata + 510);
+  gst_adapter_unmap (adapter, 0);
 
   /* flush some more */
   gst_adapter_flush (adapter, 2);
@@ -153,16 +159,16 @@ GST_START_TEST (test_take1)
   GstBuffer *buffer, *buffer2;
   guint avail;
   guint8 *data, *data2;
+  gsize size, size2;
 
   adapter = gst_adapter_new ();
   fail_unless (adapter != NULL);
 
   buffer = gst_buffer_new_and_alloc (100);
   fail_unless (buffer != NULL);
-  fail_unless (GST_BUFFER_DATA (buffer) != NULL);
-  fail_unless (GST_BUFFER_SIZE (buffer) == 100);
-
-  data = GST_BUFFER_DATA (buffer);
+  data = gst_buffer_map (buffer, &size, NULL, GST_MAP_READ);
+  fail_unless (data != NULL);
+  fail_unless (size == 100);
 
   /* push in the adapter */
   gst_adapter_push (adapter, buffer);
@@ -173,9 +179,10 @@ GST_START_TEST (test_take1)
   /* take out buffer */
   buffer2 = gst_adapter_take_buffer (adapter, 100);
   fail_unless (buffer2 != NULL);
-  fail_unless (GST_BUFFER_DATA (buffer2) != NULL);
-  fail_unless (GST_BUFFER_SIZE (buffer2) == 100);
-  data2 = GST_BUFFER_DATA (buffer2);
+
+  data2 = gst_buffer_map (buffer2, &size2, NULL, GST_MAP_READ);
+  fail_unless (data2 != NULL);
+  fail_unless (size2 == 100);
 
   avail = gst_adapter_available (adapter);
   fail_unless (avail == 0);
@@ -184,6 +191,9 @@ GST_START_TEST (test_take1)
   fail_unless (buffer == buffer2);
   fail_unless (data == data2);
 
+  gst_buffer_unmap (buffer, data, size);
+  gst_buffer_unmap (buffer2, data2, size2);
+
   gst_buffer_unref (buffer2);
 
   g_object_unref (adapter);
@@ -209,25 +219,25 @@ GST_START_TEST (test_take3)
   GstBuffer *buffer, *buffer2;
   guint avail;
   guint8 *data, *data2;
+  gsize size, size2;
 
   adapter = gst_adapter_new ();
   fail_unless (adapter != NULL);
 
   buffer = gst_buffer_new_and_alloc (100);
   fail_unless (buffer != NULL);
-  fail_unless (GST_BUFFER_DATA (buffer) != NULL);
-  fail_unless (GST_BUFFER_SIZE (buffer) == 100);
-
-  data = GST_BUFFER_DATA (buffer);
+  data = gst_buffer_map (buffer, &size, NULL, GST_MAP_READ);
+  fail_unless (data != NULL);
+  fail_unless (size == 100);
 
   /* set up and push subbuffers */
-  buffer2 = gst_buffer_create_sub (buffer, 0, 25);
+  buffer2 = gst_buffer_copy_region (buffer, GST_BUFFER_COPY_ALL, 0, 25);
   gst_adapter_push (adapter, buffer2);
-  buffer2 = gst_buffer_create_sub (buffer, 25, 25);
+  buffer2 = gst_buffer_copy_region (buffer, GST_BUFFER_COPY_ALL, 25, 25);
   gst_adapter_push (adapter, buffer2);
-  buffer2 = gst_buffer_create_sub (buffer, 50, 25);
+  buffer2 = gst_buffer_copy_region (buffer, GST_BUFFER_COPY_ALL, 50, 25);
   gst_adapter_push (adapter, buffer2);
-  buffer2 = gst_buffer_create_sub (buffer, 75, 25);
+  buffer2 = gst_buffer_copy_region (buffer, GST_BUFFER_COPY_ALL, 75, 25);
   gst_adapter_push (adapter, buffer2);
 
   gst_buffer_unref (buffer);
@@ -238,9 +248,9 @@ GST_START_TEST (test_take3)
   /* take out buffer */
   buffer2 = gst_adapter_take_buffer (adapter, 100);
   fail_unless (buffer2 != NULL);
-  fail_unless (GST_BUFFER_DATA (buffer2) != NULL);
-  fail_unless (GST_BUFFER_SIZE (buffer2) == 100);
-  data2 = GST_BUFFER_DATA (buffer2);
+  data2 = gst_buffer_map (buffer2, &size2, NULL, GST_MAP_READ);
+  fail_unless (data2 != NULL);
+  fail_unless (size2 == 100);
 
   avail = gst_adapter_available (adapter);
   fail_unless (avail == 0);
@@ -265,16 +275,20 @@ create_and_fill_adapter (void)
   fail_unless (adapter != NULL);
 
   for (i = 0; i < 10000; i += 4) {
-    GstBuffer *buf = gst_buffer_new_and_alloc (sizeof (guint32) * 4);
-    guint8 *data;
+    GstBuffer *buf;
+    guint8 *data, *ptr;
 
+    buf = gst_buffer_new_and_alloc (sizeof (guint32) * 4);
     fail_unless (buf != NULL);
-    data = GST_BUFFER_DATA (buf);
+
+    ptr = data = gst_buffer_map (buf, NULL, NULL, GST_MAP_WRITE);
 
     for (j = 0; j < 4; j++) {
-      GST_WRITE_UINT32_LE (data, i + j);
-      data += sizeof (guint32);
+      GST_WRITE_UINT32_LE (ptr, i + j);
+      ptr += sizeof (guint32);
     }
+    gst_buffer_unmap (buf, data, sizeof (guint32) * 4);
+
     gst_adapter_push (adapter, buf);
   }
 
@@ -291,8 +305,10 @@ GST_START_TEST (test_take_order)
   adapter = create_and_fill_adapter ();
   while (gst_adapter_available (adapter) >= sizeof (guint32)) {
     guint8 *data = gst_adapter_take (adapter, sizeof (guint32));
+    guint32 val = GST_READ_UINT32_LE (data);
 
-    fail_unless (GST_READ_UINT32_LE (data) == i);
+    GST_DEBUG ("val %8u", val);
+    fail_unless (val == i);
     i++;
     g_free (data);
   }
@@ -314,8 +330,13 @@ GST_START_TEST (test_take_buf_order)
   adapter = create_and_fill_adapter ();
   while (gst_adapter_available (adapter) >= sizeof (guint32)) {
     GstBuffer *buf = gst_adapter_take_buffer (adapter, sizeof (guint32));
+    gpointer data;
+    gsize size;
+
+    data = gst_buffer_map (buf, &size, NULL, GST_MAP_READ);
+    fail_unless (GST_READ_UINT32_LE (data) == i);
+    gst_buffer_unmap (buf, data, size);
 
-    fail_unless (GST_READ_UINT32_LE (GST_BUFFER_DATA (buf)) == i);
     i++;
 
     gst_buffer_unref (buf);
@@ -509,7 +530,7 @@ GST_START_TEST (test_timestamp)
   /* remove first buffer, timestamp of empty buffer is visible */
   buffer = gst_adapter_take_buffer (adapter, 99);
   fail_unless (buffer != NULL);
-  fail_unless (GST_BUFFER_SIZE (buffer) == 99);
+  fail_unless (gst_buffer_get_size (buffer) == 99);
   gst_buffer_unref (buffer);
   avail = gst_adapter_available (adapter);
   fail_unless (avail == 100);
@@ -518,8 +539,10 @@ GST_START_TEST (test_timestamp)
   fail_unless (dist == 0);
 
   /* remove empty buffer, timestamp still visible */
-  cdata = gst_adapter_peek (adapter, 50);
+  cdata = gst_adapter_map (adapter, 50);
   fail_unless (cdata != NULL);
+  gst_adapter_unmap (adapter, 0);
+
   data = gst_adapter_take (adapter, 50);
   fail_unless (data != NULL);
   g_free (data);
@@ -546,10 +569,12 @@ GST_START_TEST (test_scan)
   fail_unless (adapter != NULL);
 
   buffer = gst_buffer_new_and_alloc (100);
-  data = GST_BUFFER_DATA (buffer);
+
+  data = gst_buffer_map (buffer, NULL, NULL, GST_MAP_WRITE);
   /* fill with pattern */
   for (i = 0; i < 100; i++)
     data[i] = i;
+  gst_buffer_unmap (buffer, data, 100);
 
   gst_adapter_push (adapter, buffer);
 
@@ -608,10 +633,12 @@ GST_START_TEST (test_scan)
 
   /* add another buffer */
   buffer = gst_buffer_new_and_alloc (100);
-  data = GST_BUFFER_DATA (buffer);
+
+  data = gst_buffer_map (buffer, NULL, NULL, GST_MAP_WRITE);
   /* fill with pattern */
   for (i = 0; i < 100; i++)
     data[i] = i + 100;
+  gst_buffer_unmap (buffer, data, 100);
 
   gst_adapter_push (adapter, buffer);
 
@@ -739,23 +766,26 @@ GST_START_TEST (test_take_list)
   while (gst_adapter_available (adapter) >= sizeof (guint32)) {
     GList *list, *walk;
     GstBuffer *buf;
-    guint size;
-    guint8 *data;
+    gsize size, left;
+    guint8 *data, *ptr;
 
     list = gst_adapter_take_list (adapter, sizeof (guint32) * 5);
     fail_unless (list != NULL);
 
     for (walk = list; walk; walk = g_list_next (walk)) {
       buf = walk->data;
-      data = GST_BUFFER_DATA (buf);
-      size = GST_BUFFER_SIZE (buf);
 
-      while (size > 0) {
-        fail_unless (GST_READ_UINT32_LE (data) == i);
+      ptr = data = gst_buffer_map (buf, &size, NULL, GST_MAP_READ);
+
+      left = size;
+      while (left > 0) {
+        fail_unless (GST_READ_UINT32_LE (ptr) == i);
         i++;
-        data += sizeof (guint32);
-        size -= sizeof (guint32);
+        ptr += sizeof (guint32);
+        left -= sizeof (guint32);
       }
+      gst_buffer_unmap (buf, data, size);
+
       gst_buffer_unref (buf);
     }
     g_list_free (list);
index dbff6ce..8853ee9 100644 (file)
@@ -27,8 +27,9 @@
 #include <gst/check/gstcheck.h>
 #include <gst/base/gstbasesrc.h>
 
-static gboolean
-eos_event_counter (GstObject * pad, GstEvent * event, guint * p_num_eos)
+static GstProbeReturn
+eos_event_counter (GstObject * pad, GstProbeType type, GstEvent * event,
+    guint * p_num_eos)
 {
   fail_unless (event != NULL);
   fail_unless (GST_IS_EVENT (event));
@@ -36,7 +37,7 @@ eos_event_counter (GstObject * pad, GstEvent * event, guint * p_num_eos)
   if (GST_EVENT_TYPE (event) == GST_EVENT_EOS)
     *p_num_eos += 1;
 
-  return TRUE;
+  return GST_PROBE_OK;
 }
 
 /* basesrc_eos_events_push_live_op:
@@ -76,8 +77,8 @@ GST_START_TEST (basesrc_eos_events_push_live_op)
   srcpad = gst_element_get_static_pad (src, "src");
   fail_unless (srcpad != NULL);
 
-  probe = gst_pad_add_event_probe (srcpad,
-      G_CALLBACK (eos_event_counter), &num_eos);
+  probe = gst_pad_add_probe (srcpad, GST_PROBE_TYPE_EVENT,
+      (GstPadProbeCallback) eos_event_counter, &num_eos, NULL);
 
   bus = gst_element_get_bus (pipe);
 
@@ -88,12 +89,8 @@ GST_START_TEST (basesrc_eos_events_push_live_op)
   /* wait a second, then do controlled shutdown */
   g_usleep (GST_USECOND * 1);
 
-  /* shut down source only (should send EOS event) ... */
-  gst_element_set_state (src, GST_STATE_NULL);
-  state_ret = gst_element_get_state (src, NULL, NULL, -1);
-  fail_unless (state_ret == GST_STATE_CHANGE_SUCCESS);
-
-  fail_unless (gst_element_set_locked_state (src, TRUE) == TRUE);
+  /* shut down pipeline (should send EOS message) ... */
+  gst_element_send_event (pipe, gst_event_new_eos ());
 
   /* ... and wait for the EOS message from the sink */
   msg = gst_bus_poll (bus, GST_MESSAGE_EOS | GST_MESSAGE_ERROR, -1);
@@ -110,7 +107,7 @@ GST_START_TEST (basesrc_eos_events_push_live_op)
   /* make sure source hasn't sent a second one when going PAUSED => READY */
   fail_unless (num_eos == 1);
 
-  gst_pad_remove_event_probe (srcpad, probe);
+  gst_pad_remove_probe (srcpad, probe);
   gst_object_unref (srcpad);
   gst_message_unref (msg);
   gst_object_unref (bus);
@@ -119,6 +116,8 @@ GST_START_TEST (basesrc_eos_events_push_live_op)
 
 GST_END_TEST;
 
+
+
 /* basesrc_eos_events_push:
  *  - make sure source only sends one EOS when operating in push-mode,
  *    reaching the max number of buffers, and is then shut down.
@@ -156,8 +155,8 @@ GST_START_TEST (basesrc_eos_events_push)
   srcpad = gst_element_get_static_pad (src, "src");
   fail_unless (srcpad != NULL);
 
-  probe = gst_pad_add_event_probe (srcpad,
-      G_CALLBACK (eos_event_counter), &num_eos);
+  probe = gst_pad_add_probe (srcpad, GST_PROBE_TYPE_EVENT,
+      (GstPadProbeCallback) eos_event_counter, &num_eos, NULL);
 
   bus = gst_element_get_bus (pipe);
 
@@ -179,7 +178,7 @@ GST_START_TEST (basesrc_eos_events_push)
   /* make sure source hasn't sent a second one when going PAUSED => READY */
   fail_unless (num_eos == 1);
 
-  gst_pad_remove_event_probe (srcpad, probe);
+  gst_pad_remove_probe (srcpad, probe);
   gst_object_unref (srcpad);
   gst_message_unref (msg);
   gst_object_unref (bus);
@@ -223,8 +222,8 @@ GST_START_TEST (basesrc_eos_events_pull_live_op)
   srcpad = gst_element_get_static_pad (src, "src");
   fail_unless (srcpad != NULL);
 
-  probe = gst_pad_add_event_probe (srcpad,
-      G_CALLBACK (eos_event_counter), &num_eos);
+  probe = gst_pad_add_probe (srcpad, GST_PROBE_TYPE_EVENT,
+      (GstPadProbeCallback) eos_event_counter, &num_eos, NULL);
 
   gst_element_set_state (pipe, GST_STATE_PLAYING);
   state_ret = gst_element_get_state (pipe, NULL, NULL, -1);
@@ -249,7 +248,7 @@ GST_START_TEST (basesrc_eos_events_pull_live_op)
   /* make sure source hasn't sent an EOS when going PAUSED => READY either */
   fail_unless (num_eos == 0);
 
-  gst_pad_remove_event_probe (srcpad, probe);
+  gst_pad_remove_probe (srcpad, probe);
   gst_object_unref (srcpad);
   gst_object_unref (pipe);
 }
@@ -295,8 +294,8 @@ GST_START_TEST (basesrc_eos_events_pull)
   srcpad = gst_element_get_static_pad (src, "src");
   fail_unless (srcpad != NULL);
 
-  probe = gst_pad_add_event_probe (srcpad,
-      G_CALLBACK (eos_event_counter), &num_eos);
+  probe = gst_pad_add_probe (srcpad, GST_PROBE_TYPE_EVENT,
+      (GstPadProbeCallback) eos_event_counter, &num_eos, NULL);
 
   bus = gst_element_get_bus (pipe);
 
@@ -318,7 +317,7 @@ GST_START_TEST (basesrc_eos_events_pull)
   /* make sure source hasn't sent an EOS when going PAUSED => READY either */
   fail_unless (num_eos == 0);
 
-  gst_pad_remove_event_probe (srcpad, probe);
+  gst_pad_remove_probe (srcpad, probe);
   gst_object_unref (srcpad);
   gst_message_unref (msg);
   gst_object_unref (bus);
@@ -365,8 +364,8 @@ GST_START_TEST (basesrc_eos_events_push_live_eos)
   srcpad = gst_element_get_static_pad (src, "src");
   fail_unless (srcpad != NULL);
 
-  probe = gst_pad_add_event_probe (srcpad,
-      G_CALLBACK (eos_event_counter), &num_eos);
+  probe = gst_pad_add_probe (srcpad, GST_PROBE_TYPE_EVENT,
+      (GstPadProbeCallback) eos_event_counter, &num_eos, NULL);
 
   bus = gst_element_get_bus (pipe);
 
@@ -396,7 +395,7 @@ GST_START_TEST (basesrc_eos_events_push_live_eos)
   /* make sure source hasn't sent a second one when going PAUSED => READY */
   fail_unless (num_eos == 1);
 
-  gst_pad_remove_event_probe (srcpad, probe);
+  gst_pad_remove_probe (srcpad, probe);
   gst_object_unref (srcpad);
   gst_message_unref (msg);
   gst_object_unref (bus);
@@ -442,8 +441,8 @@ GST_START_TEST (basesrc_eos_events_pull_live_eos)
   srcpad = gst_element_get_static_pad (src, "src");
   fail_unless (srcpad != NULL);
 
-  probe = gst_pad_add_event_probe (srcpad,
-      G_CALLBACK (eos_event_counter), &num_eos);
+  probe = gst_pad_add_probe (srcpad, GST_PROBE_TYPE_EVENT,
+      (GstPadProbeCallback) eos_event_counter, &num_eos, NULL);
 
   bus = gst_element_get_bus (pipe);
 
@@ -473,7 +472,7 @@ GST_START_TEST (basesrc_eos_events_pull_live_eos)
   /* make sure source hasn't sent a second one when going PAUSED => READY */
   fail_unless (num_eos == 0);
 
-  gst_pad_remove_event_probe (srcpad, probe);
+  gst_pad_remove_probe (srcpad, probe);
   gst_object_unref (srcpad);
   gst_message_unref (msg);
   gst_object_unref (bus);
@@ -483,8 +482,8 @@ GST_START_TEST (basesrc_eos_events_pull_live_eos)
 GST_END_TEST;
 
 
-static gboolean
-newsegment_event_catcher (GstObject * pad, GstEvent * event,
+static GstProbeReturn
+segment_event_catcher (GstObject * pad, GstProbeType type, GstEvent * event,
     gpointer * user_data)
 {
   GstEvent **last_event = (GstEvent **) user_data;
@@ -492,17 +491,17 @@ newsegment_event_catcher (GstObject * pad, GstEvent * event,
   fail_unless (GST_IS_EVENT (event));
   fail_unless (user_data != NULL);
 
-  if (GST_EVENT_TYPE (event) == GST_EVENT_NEWSEGMENT) {
+  if (GST_EVENT_TYPE (event) == GST_EVENT_SEGMENT) {
     if (*last_event)
       gst_event_unref (*last_event);
     *last_event = gst_event_copy (event);
   }
 
-  return TRUE;
+  return GST_PROBE_OK;
 }
 
 /* basesrc_seek_events_rate_update:
- *  - make sure we get expected newsegment after sending a seek event
+ *  - make sure we get expected segment after sending a seek event
  */
 GST_START_TEST (basesrc_seek_events_rate_update)
 {
@@ -512,10 +511,10 @@ GST_START_TEST (basesrc_seek_events_rate_update)
   GstBus *bus;
   GstPad *probe_pad;
   guint probe;
-  GstEvent *newseg_event = NULL;
+  GstEvent *seg_event = NULL;
   GstEvent *rate_seek;
   gboolean event_ret;
-  gdouble rate = 0.5;
+  const GstSegment *segment;
 
   pipe = gst_pipeline_new ("pipeline");
   sink = gst_element_factory_make ("fakesink", "sink");
@@ -536,8 +535,8 @@ GST_START_TEST (basesrc_seek_events_rate_update)
   probe_pad = gst_element_get_static_pad (sink, "sink");
   fail_unless (probe_pad != NULL);
 
-  probe = gst_pad_add_event_probe (probe_pad,
-      G_CALLBACK (newsegment_event_catcher), &newseg_event);
+  probe = gst_pad_add_probe (probe_pad, GST_PROBE_TYPE_EVENT,
+      (GstPadProbeCallback) segment_event_catcher, &seg_event, NULL);
 
   /* prepare the seek */
   rate_seek = gst_event_new_seek (0.5, GST_FORMAT_TIME, GST_SEEK_FLAG_NONE,
@@ -560,12 +559,8 @@ GST_START_TEST (basesrc_seek_events_rate_update)
   /* wait a second, then do controlled shutdown */
   g_usleep (GST_USECOND * 1);
 
-  /* shut down source only (should send EOS event) ... */
-  gst_element_set_state (src, GST_STATE_NULL);
-  state_ret = gst_element_get_state (src, NULL, NULL, -1);
-  fail_unless (state_ret == GST_STATE_CHANGE_SUCCESS);
-
-  fail_unless (gst_element_set_locked_state (src, TRUE) == TRUE);
+  /* shut down pipeline only (should send EOS message) ... */
+  gst_element_send_event (pipe, gst_event_new_eos ());
 
   /* ... and wait for the EOS message from the sink */
   msg = gst_bus_poll (bus, GST_MESSAGE_EOS | GST_MESSAGE_ERROR, -1);
@@ -579,16 +574,15 @@ GST_START_TEST (basesrc_seek_events_rate_update)
   GST_INFO ("stopped");
 
   /* check that we have go the event */
-  fail_unless (newseg_event != NULL);
+  fail_unless (seg_event != NULL);
 
-  gst_event_parse_new_segment (newseg_event, NULL, &rate, NULL, NULL, NULL,
-      NULL);
-  fail_unless (rate == 0.5);
+  gst_event_parse_segment (seg_event, &segment);
+  fail_unless (segment->rate == 0.5);
 
-  gst_pad_remove_event_probe (probe_pad, probe);
+  gst_pad_remove_probe (probe_pad, probe);
   gst_object_unref (probe_pad);
   gst_message_unref (msg);
-  gst_event_unref (newseg_event);
+  gst_event_unref (seg_event);
   gst_object_unref (bus);
   gst_object_unref (pipe);
 }
index ac2e3cd..346b00e 100644 (file)
@@ -46,9 +46,11 @@ GST_START_TEST (test_initialization)
   GstBitReader reader = GST_BIT_READER_INIT (data, 4);
   GstBitReader *reader2;
   guint8 x = 0;
+  guint8 *bdata;
+  gsize bsize;
 
-  GST_BUFFER_DATA (buffer) = data;
-  GST_BUFFER_SIZE (buffer) = 4;
+  gst_buffer_take_memory (buffer, -1,
+      gst_memory_new_wrapped (GST_MEMORY_FLAG_READONLY, data, NULL, 4, 0, 4));
 
   fail_unless (gst_bit_reader_get_bits_uint8 (&reader, &x, 8));
   fail_unless_equals_int (x, 0x01);
@@ -63,11 +65,13 @@ GST_START_TEST (test_initialization)
   fail_unless (gst_bit_reader_get_bits_uint8 (&reader, &x, 8));
   fail_unless_equals_int (x, 0x02);
 
-  gst_bit_reader_init_from_buffer (&reader, buffer);
+  bdata = gst_buffer_map (buffer, &bsize, NULL, GST_MAP_READ);
+  gst_bit_reader_init (&reader, bdata, bsize);
   fail_unless (gst_bit_reader_get_bits_uint8 (&reader, &x, 8));
   fail_unless_equals_int (x, 0x01);
   fail_unless (gst_bit_reader_get_bits_uint8 (&reader, &x, 8));
   fail_unless_equals_int (x, 0x02);
+  gst_buffer_unmap (buffer, bdata, bsize);
 
   reader2 = gst_bit_reader_new (data, 4);
   fail_unless (gst_bit_reader_get_bits_uint8 (reader2, &x, 8));
@@ -76,12 +80,14 @@ GST_START_TEST (test_initialization)
   fail_unless_equals_int (x, 0x02);
   gst_bit_reader_free (reader2);
 
-  reader2 = gst_bit_reader_new_from_buffer (buffer);
+  bdata = gst_buffer_map (buffer, &bsize, NULL, GST_MAP_READ);
+  reader2 = gst_bit_reader_new (bdata, bsize);
   fail_unless (gst_bit_reader_get_bits_uint8 (reader2, &x, 8));
   fail_unless_equals_int (x, 0x01);
   fail_unless (gst_bit_reader_get_bits_uint8 (reader2, &x, 8));
   fail_unless_equals_int (x, 0x02);
   gst_bit_reader_free (reader2);
+  gst_buffer_unmap (buffer, bdata, bsize);
 
   gst_buffer_unref (buffer);
 }
index 4d0c3cf..dfb7ef4 100644 (file)
@@ -46,9 +46,11 @@ GST_START_TEST (test_initialization)
   GstByteReader reader = GST_BYTE_READER_INIT (data, 4);
   GstByteReader *reader2;
   guint8 x = 0;
+  guint8 *bdata;
+  gsize bsize;
 
-  GST_BUFFER_DATA (buffer) = data;
-  GST_BUFFER_SIZE (buffer) = 4;
+  gst_buffer_take_memory (buffer, -1,
+      gst_memory_new_wrapped (GST_MEMORY_FLAG_READONLY, data, NULL, 4, 0, 4));
 
   fail_unless (gst_byte_reader_get_uint8 (&reader, &x));
   fail_unless_equals_int (x, 0x01);
@@ -63,11 +65,13 @@ GST_START_TEST (test_initialization)
   fail_unless (gst_byte_reader_get_uint8 (&reader, &x));
   fail_unless_equals_int (x, 0x02);
 
-  gst_byte_reader_init_from_buffer (&reader, buffer);
+  bdata = gst_buffer_map (buffer, &bsize, NULL, GST_MAP_READ);
+  gst_byte_reader_init (&reader, bdata, bsize);
   fail_unless (gst_byte_reader_get_uint8 (&reader, &x));
   fail_unless_equals_int (x, 0x01);
   fail_unless (gst_byte_reader_get_uint8 (&reader, &x));
   fail_unless_equals_int (x, 0x02);
+  gst_buffer_unmap (buffer, bdata, bsize);
 
   reader2 = gst_byte_reader_new (data, 4);
   fail_unless (gst_byte_reader_get_uint8 (reader2, &x));
@@ -76,12 +80,14 @@ GST_START_TEST (test_initialization)
   fail_unless_equals_int (x, 0x02);
   gst_byte_reader_free (reader2);
 
-  reader2 = gst_byte_reader_new_from_buffer (buffer);
+  bdata = gst_buffer_map (buffer, &bsize, NULL, GST_MAP_READ);
+  reader2 = gst_byte_reader_new (bdata, bsize);
   fail_unless (gst_byte_reader_get_uint8 (reader2, &x));
   fail_unless_equals_int (x, 0x01);
   fail_unless (gst_byte_reader_get_uint8 (reader2, &x));
   fail_unless_equals_int (x, 0x02);
   gst_byte_reader_free (reader2);
+  gst_buffer_unmap (buffer, bdata, bsize);
 
   gst_buffer_unref (buffer);
 }
index 77aecea..fff4ed4 100644 (file)
@@ -89,322 +89,6 @@ GST_START_TEST (test_conversion)
 
 GST_END_TEST;
 
-#ifndef GST_REMOVE_DEPRECATED   /* these tests use deprecated API, that we disable by default */
-
-/* test creation of header from buffer and back again */
-GST_START_TEST (test_buffer)
-{
-  GstBuffer *buffer;
-  GstBuffer *newbuffer;
-
-  guint header_length;
-  guint8 *header;
-
-  /* create buffer */
-  GST_DEBUG ("Creating a new 8-byte buffer with ts 0.5 sec, dur 1 sec");
-  buffer = gst_buffer_new_and_alloc (8);
-  GST_BUFFER_TIMESTAMP (buffer) = (GstClockTime) (GST_SECOND * 0.5);
-  GST_BUFFER_DURATION (buffer) = (GstClockTime) GST_SECOND;
-  GST_BUFFER_OFFSET (buffer) = (guint64) 10;
-  GST_BUFFER_OFFSET_END (buffer) = (guint64) 19;
-  GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_IN_CAPS);
-  memmove (GST_BUFFER_DATA (buffer), "a buffer", 8);
-
-  /* create a buffer with CRC checking */
-  fail_unless (gst_dp_header_from_buffer (buffer, GST_DP_HEADER_FLAG_CRC,
-          &header_length, &header), "Could not create header from buffer.");
-
-  /* validate the header */
-  fail_unless (gst_dp_validate_header (header_length, header),
-      "Could not validate header");
-  /* create a new, empty buffer with the right size */
-  newbuffer = gst_dp_buffer_from_header (header_length, header);
-  fail_unless (newbuffer != NULL, "Could not create a new buffer from header");
-  fail_unless (GST_IS_BUFFER (newbuffer), "Created buffer is not a GstBuffer");
-  /* read/copy the data */
-  memmove (GST_BUFFER_DATA (newbuffer), GST_BUFFER_DATA (buffer),
-      GST_BUFFER_SIZE (buffer));
-  /* validate the buffer */
-  fail_unless (gst_dp_validate_payload (header_length, header,
-          GST_BUFFER_DATA (newbuffer)), "Could not validate payload");
-
-  GST_DEBUG ("new buffer timestamp: %" GST_TIME_FORMAT,
-      GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (newbuffer)));
-  GST_DEBUG ("new buffer duration: %" GST_TIME_FORMAT,
-      GST_TIME_ARGS (GST_BUFFER_DURATION (newbuffer)));
-  GST_DEBUG ("new buffer offset: %" G_GUINT64_FORMAT,
-      GST_BUFFER_OFFSET (newbuffer));
-  GST_DEBUG ("new buffer offset_end: %" G_GUINT64_FORMAT,
-      GST_BUFFER_OFFSET_END (newbuffer));
-  fail_unless (GST_BUFFER_TIMESTAMP (newbuffer) ==
-      GST_BUFFER_TIMESTAMP (buffer), "Timestamps don't match !");
-  fail_unless (GST_BUFFER_DURATION (newbuffer) == GST_BUFFER_DURATION (buffer),
-      "Durations don't match !");
-  fail_unless (GST_BUFFER_OFFSET (newbuffer) == GST_BUFFER_OFFSET (buffer),
-      "Offsets don't match !");
-  fail_unless (GST_BUFFER_OFFSET_END (newbuffer) ==
-      GST_BUFFER_OFFSET_END (buffer), "Offset ends don't match !");
-  fail_unless (GST_BUFFER_FLAG_IS_SET (newbuffer, GST_BUFFER_FLAG_IN_CAPS),
-      "GST_BUFFER_IN_CAPS flag should have been copied !");
-
-  /* clean up */
-  gst_buffer_unref (buffer);
-  gst_buffer_unref (newbuffer);
-  g_free (header);
-}
-
-GST_END_TEST;
-
-GST_START_TEST (test_caps)
-{
-  gchar *string, *newstring;
-  GstCaps *caps, *newcaps;
-
-  guint header_length;
-  guint8 *header, *payload;
-
-  caps = gst_caps_from_string ("audio/x-raw-float, "
-      "rate = (int) [ 11025, 48000 ], "
-      "channels = (int) [ 1, 2 ], " "endianness = (int) BYTE_ORDER, "
-      "width = (int) 32, " "buffer-frames = (int) 0");
-  string = gst_caps_to_string (caps);
-  GST_DEBUG ("Created caps: %s", string);
-  fail_unless (gst_dp_packet_from_caps (caps, 0, &header_length, &header,
-          &payload), "Could not create packet from caps.");
-
-  /* validate the packet */
-  fail_unless (gst_dp_validate_packet (header_length, header, payload),
-      "Could not validate packet");
-  newcaps = gst_dp_caps_from_packet (header_length, header, payload);
-  fail_unless (newcaps != NULL, "Could not create caps from packet");
-  fail_unless (GST_IS_CAPS (newcaps));
-  newstring = gst_caps_to_string (newcaps);
-  GST_DEBUG ("Received caps: %s", newstring);
-  fail_unless (strcmp (string, newstring) == 0,
-      "Created caps do not match original caps");
-
-  /* cleanup */
-  gst_caps_unref (caps);
-  gst_caps_unref (newcaps);
-  g_free (header);
-  g_free (payload);
-  g_free (string);
-  g_free (newstring);
-}
-
-GST_END_TEST;
-
-GST_START_TEST (test_event)
-{
-  GstEvent *send;
-  GstEvent *receive;
-  guint header_length;
-  guint8 *header, *payload;
-
-  GST_DEBUG ("Testing EOS event at 1s");
-  send = gst_event_new_eos ();
-  GST_EVENT_TIMESTAMP (send) = GST_SECOND;
-  fail_unless (gst_dp_packet_from_event (send, GST_DP_HEADER_FLAG_CRC,
-          &header_length, &header, &payload),
-      "Could not create packet from eos event");
-
-  receive = gst_dp_event_from_packet (header_length, header, payload);
-
-  GST_DEBUG ("EOS, timestamp %" GST_TIME_FORMAT,
-      GST_TIME_ARGS (GST_EVENT_TIMESTAMP (receive)));
-  fail_unless (GST_EVENT_TYPE (receive) == GST_EVENT_EOS,
-      "Received event is not EOS");
-  fail_unless (GST_EVENT_TIMESTAMP (receive) == GST_SECOND,
-      "EOS timestamp is not 1.0 sec");
-
-  /* clean up */
-  g_free (header);
-  g_free (payload);
-  gst_event_unref (send);
-  gst_event_unref (receive);
-
-  GST_DEBUG ("Testing FLUSH event at 2s");
-  send = gst_event_new_flush_start ();
-  GST_EVENT_TIMESTAMP (send) = GST_SECOND * 2;
-  fail_unless (gst_dp_packet_from_event (send, GST_DP_HEADER_FLAG_CRC,
-          &header_length, &header, &payload),
-      "Could not create packet from flush event");
-
-  receive = gst_dp_event_from_packet (header_length, header, payload);
-
-  GST_DEBUG ("Flush, timestamp %" GST_TIME_FORMAT,
-      GST_TIME_ARGS (GST_EVENT_TIMESTAMP (receive)));
-  fail_unless (GST_EVENT_TYPE (receive) == GST_EVENT_FLUSH_START,
-      "Received event is not flush");
-  fail_unless (GST_EVENT_TIMESTAMP (receive) == GST_SECOND * 2,
-      "Flush timestamp is not 2.0 sec");
-
-  /* clean up */
-  g_free (header);
-  g_free (payload);
-  gst_event_unref (send);
-  gst_event_unref (receive);
-
-  GST_DEBUG ("Testing SEEK event with 1 second at 3 seconds");
-  send =
-      gst_event_new_seek (1.0, GST_FORMAT_TIME, 0, GST_SEEK_TYPE_SET,
-      GST_SECOND, GST_SEEK_TYPE_NONE, 0);
-  GST_EVENT_TIMESTAMP (send) = GST_SECOND * 3;
-  fail_unless (gst_dp_packet_from_event (send, GST_DP_HEADER_FLAG_CRC,
-          &header_length, &header, &payload),
-      "Could not create packet from seek event");
-
-  receive = gst_dp_event_from_packet (header_length, header, payload);
-
-  {
-    gdouble rate;
-    GstFormat format;
-    GstSeekFlags flags;
-    GstSeekType cur_type, stop_type;
-    gint64 cur, stop;
-
-    gst_event_parse_seek (receive, &rate, &format, &flags,
-        &cur_type, &cur, &stop_type, &stop);
-
-    GST_DEBUG ("Seek, timestamp %" GST_TIME_FORMAT ", to %" GST_TIME_FORMAT,
-        GST_TIME_ARGS (GST_EVENT_TIMESTAMP (receive)), GST_TIME_ARGS (cur));
-    fail_unless (GST_EVENT_TYPE (receive) == GST_EVENT_SEEK,
-        "Returned event is not seek");
-    fail_unless (GST_EVENT_TIMESTAMP (receive) == GST_SECOND * 3,
-        "Seek timestamp is not 3.0 sec");
-    fail_unless (format == GST_FORMAT_TIME, "Seek format is not time");
-    fail_unless (cur == GST_SECOND, "Seek cur is not 1.0 sec");
-  }
-
-  /* clean up */
-  g_free (header);
-  g_free (payload);
-  gst_event_unref (send);
-  gst_event_unref (receive);
-}
-
-GST_END_TEST;
-
-/* try to segfault the thing by passing NULLs, short headers, etc.. */
-GST_START_TEST (test_memory)
-{
-  guint8 foo[5];
-  GstBuffer *buffer;
-  GstCaps *caps;
-  GstEvent *event;
-  guint length;
-  guint8 *header;
-  guint8 *payload;
-
-  /* check 0 sized input, data pointer can be NULL or anything. CRC is always 0,
-   * though. */
-  fail_if (gst_dp_crc (NULL, 0) != 0);
-  fail_if (gst_dp_crc (foo, 0) != 0);
-
-  /* this is very invalid input and gives a warning. */
-  ASSERT_CRITICAL (gst_dp_crc (NULL, 1));
-  ASSERT_CRITICAL (gst_dp_header_payload_length (NULL));
-  ASSERT_CRITICAL (gst_dp_header_payload_type (NULL));
-
-  /* wrong */
-  ASSERT_CRITICAL (gst_dp_header_from_buffer (NULL, 0, NULL, NULL));
-
-  /* empty buffer has NULL as data pointer */
-  buffer = gst_buffer_new_and_alloc (0);
-
-  /* no place to store the length and/or header data */
-  ASSERT_CRITICAL (gst_dp_header_from_buffer (buffer, 0, NULL, NULL));
-  ASSERT_CRITICAL (gst_dp_header_from_buffer (buffer, 0, &length, NULL));
-
-  /* this should work fine */
-  fail_if (gst_dp_header_from_buffer (buffer, 0, &length, &header) != TRUE);
-  fail_unless (length != 0);
-  fail_unless (header != NULL);
-
-  /* this should validate */
-  fail_if (gst_dp_validate_header (length, header) == FALSE);
-
-  /* NULL header pointer */
-  ASSERT_CRITICAL (gst_dp_validate_header (length, NULL));
-  /* short header */
-  ASSERT_CRITICAL (gst_dp_validate_header (5, header));
-
-  g_free (header);
-
-  /* this should work and not crash trying to calc a CRC on a 0 sized buffer */
-  fail_if (gst_dp_header_from_buffer (buffer,
-          GST_DP_HEADER_FLAG_CRC_HEADER | GST_DP_HEADER_FLAG_CRC_PAYLOAD,
-          &length, &header) != TRUE);
-
-  /* this should validate */
-  fail_if (gst_dp_validate_header (length, header) == FALSE);
-
-  /* there was no payload, NULL as payload data should validate the CRC
-   * checks and all. */
-  fail_if (gst_dp_validate_payload (length, header, NULL) == FALSE);
-
-  /* and the whole packet as well */
-  fail_if (gst_dp_validate_packet (length, header, NULL) == FALSE);
-
-  /* some bogus length */
-  ASSERT_CRITICAL (gst_dp_validate_packet (5, header, NULL));
-  gst_buffer_unref (buffer);
-
-  /* create buffer from header data, integrity tested elsewhere */
-  buffer = gst_dp_buffer_from_header (length, header);
-  fail_if (buffer == NULL);
-  gst_buffer_unref (buffer);
-  g_free (header);
-
-  ASSERT_CRITICAL (gst_dp_packet_from_caps (NULL, 0, NULL, NULL, NULL));
-
-  /* some caps stuff */
-  caps = gst_caps_new_empty ();
-  ASSERT_CRITICAL (gst_dp_packet_from_caps (caps, 0, NULL, NULL, NULL));
-  ASSERT_CRITICAL (gst_dp_packet_from_caps (caps, 0, &length, NULL, NULL));
-  ASSERT_CRITICAL (gst_dp_packet_from_caps (caps, 0, &length, &header, NULL));
-
-  fail_if (gst_dp_packet_from_caps (caps, 0, &length, &header,
-          &payload) != TRUE);
-  fail_if (strcmp ((const gchar *) payload, "EMPTY") != 0);
-  gst_caps_unref (caps);
-
-  caps = gst_dp_caps_from_packet (length, header, payload);
-  fail_if (caps == NULL);
-  gst_caps_unref (caps);
-
-  g_free (header);
-  g_free (payload);
-
-  /* some event stuff */
-  event = gst_event_new_eos ();
-  ASSERT_CRITICAL (gst_dp_packet_from_event (event, 0, NULL, NULL, NULL));
-  ASSERT_CRITICAL (gst_dp_packet_from_event (event, 0, &length, NULL, NULL));
-  ASSERT_CRITICAL (gst_dp_packet_from_event (event, 0, &length, &header, NULL));
-
-  /* payload is not NULL from previous test and points to freed memory, very
-   * invalid. */
-  fail_if (payload == NULL);
-  fail_if (gst_dp_packet_from_event (event, 0, &length, &header,
-          &payload) != TRUE);
-
-  /* the EOS event has no payload */
-  fail_if (payload != NULL);
-  gst_event_unref (event);
-
-  event = gst_dp_event_from_packet (length, header, payload);
-  fail_if (event == NULL);
-  fail_if (GST_EVENT_TYPE (event) != GST_EVENT_EOS);
-  gst_event_unref (event);
-
-  g_free (header);
-  g_free (payload);
-}
-
-GST_END_TEST;
-
-#endif
-
 static Suite *
 gst_dp_suite (void)
 {
@@ -414,12 +98,6 @@ gst_dp_suite (void)
   suite_add_tcase (s, tc_chain);
   tcase_add_checked_fixture (tc_chain, gst_dp_init, NULL);
   tcase_add_test (tc_chain, test_conversion);
-#ifndef GST_REMOVE_DEPRECATED
-  tcase_add_test (tc_chain, test_buffer);
-  tcase_add_test (tc_chain, test_caps);
-  tcase_add_test (tc_chain, test_event);
-  tcase_add_test (tc_chain, test_memory);
-#endif
 
   return s;
 }
index 8687cdc..22229d2 100644 (file)
@@ -9,8 +9,6 @@ typedef struct
   GList *buffers;
   GstElement *trans;
   GstBaseTransformClass *klass;
-
-  GstPadBufferAllocFunction buffer_alloc;
 } TestTransData;
 
 static GstStaticPadTemplate gst_test_trans_src_template =
@@ -57,8 +55,7 @@ struct _GstTestTransClass
 
 GType gst_test_trans_get_type (void);
 
-GST_BOILERPLATE (GstTestTrans, gst_test_trans, GstBaseTransform,
-    GST_TYPE_BASE_TRANSFORM);
+G_DEFINE_TYPE (GstTestTrans, gst_test_trans, GST_TYPE_BASE_TRANSFORM);
 
 static GstFlowReturn (*klass_transform) (GstBaseTransform * trans,
     GstBuffer * inbuf, GstBuffer * outbuf) = NULL;
@@ -67,21 +64,23 @@ static GstFlowReturn (*klass_transform_ip) (GstBaseTransform * trans,
 static gboolean (*klass_set_caps) (GstBaseTransform * trans, GstCaps * incaps,
     GstCaps * outcaps) = NULL;
 static GstCaps *(*klass_transform_caps) (GstBaseTransform * trans,
-    GstPadDirection direction, GstCaps * caps) = NULL;
+    GstPadDirection direction, GstCaps * caps, GstCaps * filter) = NULL;
 static gboolean (*klass_transform_size) (GstBaseTransform * trans,
-    GstPadDirection direction, GstCaps * caps, guint size, GstCaps * othercaps,
-    guint * othersize) = NULL;
+    GstPadDirection direction, GstCaps * caps, gsize size, GstCaps * othercaps,
+    gsize * othersize) = NULL;
 static gboolean klass_passthrough_on_same_caps = FALSE;
 
 static GstStaticPadTemplate *sink_template = &gst_test_trans_sink_template;
 static GstStaticPadTemplate *src_template = &gst_test_trans_src_template;
 
 static void
-gst_test_trans_base_init (gpointer g_class)
+gst_test_trans_class_init (GstTestTransClass * klass)
 {
   GstElementClass *element_class;
+  GstBaseTransformClass *trans_class;
 
-  element_class = GST_ELEMENT_CLASS (g_class);
+  element_class = (GstElementClass *) klass;
+  trans_class = (GstBaseTransformClass *) klass;
 
   gst_element_class_set_details_simple (element_class, "TestTrans",
       "Filter/Test", "Test transform", "Wim Taymans <wim.taymans@gmail.com>");
@@ -90,14 +89,6 @@ gst_test_trans_base_init (gpointer g_class)
       gst_static_pad_template_get (sink_template));
   gst_element_class_add_pad_template (element_class,
       gst_static_pad_template_get (src_template));
-}
-
-static void
-gst_test_trans_class_init (GstTestTransClass * klass)
-{
-  GstBaseTransformClass *trans_class;
-
-  trans_class = (GstBaseTransformClass *) klass;
 
   trans_class->passthrough_on_same_caps = klass_passthrough_on_same_caps;
   trans_class->transform_ip = klass_transform_ip;
@@ -108,7 +99,7 @@ gst_test_trans_class_init (GstTestTransClass * klass)
 }
 
 static void
-gst_test_trans_init (GstTestTrans * this, GstTestTransClass * g_class)
+gst_test_trans_init (GstTestTrans * this)
 {
 }
 
@@ -130,6 +121,7 @@ result_sink_chain (GstPad * pad, GstBuffer * buffer)
   return GST_FLOW_OK;
 }
 
+#if 0
 static GstFlowReturn
 result_buffer_alloc (GstPad * pad, guint64 offset, guint size, GstCaps * caps,
     GstBuffer ** buf)
@@ -139,16 +131,13 @@ result_buffer_alloc (GstPad * pad, guint64 offset, guint size, GstCaps * caps,
 
   data = gst_pad_get_element_private (pad);
 
-  if (data->buffer_alloc) {
-    res = data->buffer_alloc (pad, offset, size, caps, buf);
-  } else {
-    *buf = gst_buffer_new_and_alloc (size);
-    gst_buffer_set_caps (*buf, caps);
-    res = GST_FLOW_OK;
-  }
+  *buf = gst_buffer_new_and_alloc (size);
+  gst_buffer_set_caps (*buf, caps);
+  res = GST_FLOW_OK;
 
   return res;
 }
+#endif
 
 static TestTransData *
 gst_test_trans_new (void)
@@ -175,7 +164,6 @@ gst_test_trans_new (void)
   gst_test_trans_set_data (GST_TEST_TRANS (res->trans), res);
   gst_pad_set_element_private (res->sinkpad, res);
 
-  gst_pad_set_bufferalloc_function (res->sinkpad, result_buffer_alloc);
   gst_pad_set_chain_function (res->sinkpad, result_sink_chain);
 
   tmp = gst_element_get_static_pad (res->trans, "sink");
index cd4cede..1b92711 100644 (file)
@@ -31,6 +31,7 @@
 
 static gboolean buffer_alloc_pt1_called;
 
+#if 0
 static GstFlowReturn
 buffer_alloc_pt1 (GstPad * pad, guint64 offset, guint size, GstCaps * caps,
     GstBuffer ** buf)
@@ -45,6 +46,7 @@ buffer_alloc_pt1 (GstPad * pad, guint64 offset, guint size, GstCaps * caps,
 
   return GST_FLOW_OK;
 }
+#endif
 
 static gboolean set_caps_pt1_called;
 
@@ -65,11 +67,10 @@ GST_START_TEST (basetransform_chain_pt1)
   TestTransData *trans;
   GstBuffer *buffer;
   GstFlowReturn res;
-  GstCaps *caps;
+  //GstCaps *caps;
 
   klass_set_caps = set_caps_pt1;
   trans = gst_test_trans_new ();
-  trans->buffer_alloc = buffer_alloc_pt1;
 
   GST_DEBUG_OBJECT (trans, "buffer without caps, size 20");
 
@@ -80,14 +81,16 @@ GST_START_TEST (basetransform_chain_pt1)
   res = gst_test_trans_push (trans, buffer);
   fail_unless (res == GST_FLOW_OK);
   /* FIXME, passthough without pad-alloc, do pad-alloc on the srcpad */
-  fail_unless (buffer_alloc_pt1_called == TRUE);
+  //fail_unless (buffer_alloc_pt1_called == TRUE);
   fail_unless (set_caps_pt1_called == FALSE);
 
   buffer = gst_test_trans_pop (trans);
   fail_unless (buffer != NULL);
-  fail_unless (GST_BUFFER_SIZE (buffer) == 20);
+  fail_unless (gst_buffer_get_size (buffer) == 20);
+#if 0
   /* caps should not have been set */
   fail_unless (GST_BUFFER_CAPS (buffer) == NULL);
+#endif
 
   gst_buffer_unref (buffer);
 
@@ -99,28 +102,20 @@ GST_START_TEST (basetransform_chain_pt1)
   res = gst_test_trans_push (trans, buffer);
   fail_unless (res == GST_FLOW_OK);
   /* FIXME, passthough without pad-alloc, do pad-alloc on the srcpad */
-  fail_unless (buffer_alloc_pt1_called == TRUE);
+  //fail_unless (buffer_alloc_pt1_called == TRUE);
   fail_unless (set_caps_pt1_called == FALSE);
 
   buffer = gst_test_trans_pop (trans);
   fail_unless (buffer != NULL);
-  fail_unless (GST_BUFFER_SIZE (buffer) == 10);
+  fail_unless (gst_buffer_get_size (buffer) == 10);
+#if 0
   /* caps should not have been set */
   fail_unless (GST_BUFFER_CAPS (buffer) == NULL);
+#endif
 
   gst_buffer_unref (buffer);
 
-  /* proxy buffer-alloc without caps */
-  GST_DEBUG_OBJECT (trans, "alloc without caps, size 20");
-
-  buffer_alloc_pt1_called = FALSE;
-  set_caps_pt1_called = FALSE;
-  res = gst_pad_alloc_buffer (trans->srcpad, 0, 20, NULL, &buffer);
-  fail_unless (res == GST_FLOW_OK);
-  fail_unless (buffer_alloc_pt1_called == TRUE);
-  fail_unless (set_caps_pt1_called == FALSE);
-  gst_buffer_unref (buffer);
-
+#if 0
   /* with caps buffer */
   GST_DEBUG_OBJECT (trans, "alloc with caps, size 10");
 
@@ -143,6 +138,7 @@ GST_START_TEST (basetransform_chain_pt1)
   gst_buffer_unref (buffer);
 
   gst_caps_unref (caps);
+#endif
 
   gst_test_trans_free (trans);
 }
@@ -174,7 +170,6 @@ GST_START_TEST (basetransform_chain_pt2)
 
   klass_set_caps = set_caps_pt2;
   trans = gst_test_trans_new ();
-  trans->buffer_alloc = buffer_alloc_pt1;
 
   /* first buffer */
   caps = gst_caps_new_simple ("foo/x-bar", NULL);
@@ -182,23 +177,28 @@ GST_START_TEST (basetransform_chain_pt2)
   GST_DEBUG_OBJECT (trans, "buffer with caps, size 20");
 
   buffer = gst_buffer_new_and_alloc (20);
+#if 0
   gst_buffer_set_caps (buffer, caps);
+#endif
 
   buffer_alloc_pt1_called = FALSE;
   set_caps_pt2_called = FALSE;
   res = gst_test_trans_push (trans, buffer);
   fail_unless (res == GST_FLOW_OK);
   /* FIXME, passthough without pad-alloc, do pad-alloc on the srcpad */
-  fail_unless (buffer_alloc_pt1_called == TRUE);
+  //fail_unless (buffer_alloc_pt1_called == TRUE);
   fail_unless (set_caps_pt2_called == TRUE);
 
   buffer = gst_test_trans_pop (trans);
   fail_unless (buffer != NULL);
-  fail_unless (GST_BUFFER_SIZE (buffer) == 20);
+  fail_unless (gst_buffer_get_size (buffer) == 20);
+#if 0
   fail_unless (gst_caps_is_equal (GST_BUFFER_CAPS (buffer), caps));
+#endif
 
   gst_buffer_unref (buffer);
 
+#if 0
   /* with caps buffer */
   GST_DEBUG_OBJECT (trans, "alloc with caps, size 20");
 
@@ -209,6 +209,7 @@ GST_START_TEST (basetransform_chain_pt2)
   fail_unless (buffer_alloc_pt1_called == TRUE);
   fail_unless (set_caps_pt2_called == FALSE);
   gst_buffer_unref (buffer);
+#endif
 
   gst_caps_unref (caps);
 
@@ -218,23 +219,28 @@ GST_START_TEST (basetransform_chain_pt2)
   GST_DEBUG_OBJECT (trans, "buffer with caps, size 10");
 
   buffer = gst_buffer_new_and_alloc (10);
+#if 0
   gst_buffer_set_caps (buffer, caps);
+#endif
 
   buffer_alloc_pt1_called = FALSE;
   set_caps_pt2_called = FALSE;
   res = gst_test_trans_push (trans, buffer);
   fail_unless (res == GST_FLOW_OK);
   /* FIXME, passthough without pad-alloc, do pad-alloc on the srcpad */
-  fail_unless (buffer_alloc_pt1_called == TRUE);
+  //fail_unless (buffer_alloc_pt1_called == TRUE);
   fail_unless (set_caps_pt2_called == TRUE);
 
   buffer = gst_test_trans_pop (trans);
   fail_unless (buffer != NULL);
-  fail_unless (GST_BUFFER_SIZE (buffer) == 10);
+  fail_unless (gst_buffer_get_size (buffer) == 10);
+#if 0
   fail_unless (gst_caps_is_equal (GST_BUFFER_CAPS (buffer), caps));
+#endif
 
   gst_buffer_unref (buffer);
 
+#if 0
   /* with caps buffer */
   GST_DEBUG_OBJECT (trans, "alloc with caps, size 20");
 
@@ -245,12 +251,14 @@ GST_START_TEST (basetransform_chain_pt2)
   fail_unless (buffer_alloc_pt1_called == TRUE);
   fail_unless (set_caps_pt2_called == FALSE);
   gst_buffer_unref (buffer);
+#endif
 
   gst_caps_unref (caps);
 
   /* with caps that is a superset */
   caps = gst_caps_new_simple ("foo/x-bar", NULL);
 
+#if 0
   GST_DEBUG_OBJECT (trans, "alloc with superset caps, size 20");
 
   buffer_alloc_pt1_called = FALSE;
@@ -260,6 +268,7 @@ GST_START_TEST (basetransform_chain_pt2)
   fail_unless (buffer_alloc_pt1_called == TRUE);
   fail_unless (set_caps_pt2_called == FALSE);
   gst_buffer_unref (buffer);
+#endif
 
   gst_caps_unref (caps);
 
@@ -294,7 +303,6 @@ GST_START_TEST (basetransform_chain_ip1)
 
   klass_transform_ip = transform_ip_1;
   trans = gst_test_trans_new ();
-  trans->buffer_alloc = buffer_alloc_pt1;
 
   GST_DEBUG_OBJECT (trans, "buffer without caps, size 20");
 
@@ -308,11 +316,11 @@ GST_START_TEST (basetransform_chain_ip1)
   fail_unless (transform_ip_1_called == TRUE);
   fail_unless (transform_ip_1_writable == TRUE);
   /* FIXME, in-place without pad-alloc, do pad-alloc on the srcpad */
-  fail_unless (buffer_alloc_pt1_called == TRUE);
+  //fail_unless (buffer_alloc_pt1_called == TRUE);
 
   buffer = gst_test_trans_pop (trans);
   fail_unless (buffer != NULL);
-  fail_unless (GST_BUFFER_SIZE (buffer) == 20);
+  fail_unless (gst_buffer_get_size (buffer) == 20);
   gst_buffer_unref (buffer);
 
   GST_DEBUG_OBJECT (trans, "buffer without caps extra ref, size 20");
@@ -331,13 +339,13 @@ GST_START_TEST (basetransform_chain_ip1)
   fail_unless (transform_ip_1_called == TRUE);
   /* copy should have been taken with pad-alloc */
   fail_unless (transform_ip_1_writable == TRUE);
-  fail_unless (buffer_alloc_pt1_called == TRUE);
+  //fail_unless (buffer_alloc_pt1_called == TRUE);
   /* after push, get rid of the final ref we had */
   gst_buffer_unref (buffer);
 
   buffer = gst_test_trans_pop (trans);
   fail_unless (buffer != NULL);
-  fail_unless (GST_BUFFER_SIZE (buffer) == 20);
+  fail_unless (gst_buffer_get_size (buffer) == 20);
 
   /* output buffer has refcount 1 */
   fail_unless (GST_MINI_OBJECT_REFCOUNT_VALUE (buffer) == 1);
@@ -346,11 +354,13 @@ GST_START_TEST (basetransform_chain_ip1)
   /* with caps buffer */
   GST_DEBUG_OBJECT (trans, "alloc without caps, size 20");
 
+#if 0
   buffer_alloc_pt1_called = FALSE;
   res = gst_pad_alloc_buffer (trans->srcpad, 0, 20, NULL, &buffer);
   fail_unless (res == GST_FLOW_OK);
   fail_unless (buffer_alloc_pt1_called == TRUE);
   gst_buffer_unref (buffer);
+#endif
 
   gst_test_trans_free (trans);
 }
@@ -391,8 +401,8 @@ GST_START_TEST (basetransform_chain_ip2)
   klass_set_caps = set_caps_1;
 
   trans = gst_test_trans_new ();
-  trans->buffer_alloc = buffer_alloc_pt1;
 
+#if 0
   /* with caps buffer */
   GST_DEBUG_OBJECT (trans, "alloc without caps, size 20");
 
@@ -400,12 +410,14 @@ GST_START_TEST (basetransform_chain_ip2)
   res = gst_pad_alloc_buffer (trans->srcpad, 0, 20, NULL, &buffer);
   fail_unless (res == GST_FLOW_OK);
   fail_unless (buffer_alloc_pt1_called == TRUE);
-  fail_unless (GST_BUFFER_SIZE (buffer) == 20);
+  fail_unless (gst_buffer_get_size (buffer) == 20);
   fail_unless (GST_BUFFER_CAPS (buffer) == NULL);
   gst_buffer_unref (buffer);
+#endif
 
   caps = gst_caps_new_simple ("foo/x-bar", NULL);
 
+#if 0
   /* with caps buffer */
   GST_DEBUG_OBJECT (trans, "alloc with caps, size 20");
 
@@ -413,9 +425,10 @@ GST_START_TEST (basetransform_chain_ip2)
   res = gst_pad_alloc_buffer (trans->srcpad, 0, 20, caps, &buffer);
   fail_unless (res == GST_FLOW_OK);
   fail_unless (buffer_alloc_pt1_called == TRUE);
-  fail_unless (GST_BUFFER_SIZE (buffer) == 20);
+  fail_unless (gst_buffer_get_size (buffer) == 20);
   fail_unless (GST_BUFFER_CAPS (buffer) == caps);
   gst_buffer_unref (buffer);
+#endif
 
   /* first try to push a buffer without caps, this should fail */
   buffer = gst_buffer_new_and_alloc (20);
@@ -437,7 +450,9 @@ GST_START_TEST (basetransform_chain_ip2)
   GST_DEBUG_OBJECT (trans, "buffer with caps, size 20");
 
   buffer = gst_buffer_new_and_alloc (20);
+#if 0
   gst_buffer_set_caps (buffer, caps);
+#endif
 
   transform_ip_1_called = FALSE;
   transform_ip_1_writable = FALSE;
@@ -449,14 +464,17 @@ GST_START_TEST (basetransform_chain_ip2)
   fail_unless (transform_ip_1_writable == TRUE);
   fail_unless (set_caps_1_called == TRUE);
   /* FIXME, in-place without pad-alloc, do pad-alloc on the srcpad */
-  fail_unless (buffer_alloc_pt1_called == TRUE);
+  //fail_unless (buffer_alloc_pt1_called == TRUE);
 
   buffer = gst_test_trans_pop (trans);
   fail_unless (buffer != NULL);
-  fail_unless (GST_BUFFER_SIZE (buffer) == 20);
+  fail_unless (gst_buffer_get_size (buffer) == 20);
+#if 0
   fail_unless (gst_caps_is_equal (GST_BUFFER_CAPS (buffer), caps));
+#endif
   gst_buffer_unref (buffer);
 
+#if 0
   /* with caps buffer */
   GST_DEBUG_OBJECT (trans, "alloc with caps, size 20");
 
@@ -465,11 +483,14 @@ GST_START_TEST (basetransform_chain_ip2)
   fail_unless (res == GST_FLOW_OK);
   fail_unless (buffer_alloc_pt1_called == TRUE);
   gst_buffer_unref (buffer);
+#endif
 
   GST_DEBUG_OBJECT (trans, "buffer with caps extra ref, size 20");
 
   buffer = gst_buffer_new_and_alloc (20);
+#if 0
   gst_buffer_set_caps (buffer, caps);
+#endif
   /* take additional ref to make it non-writable */
   gst_buffer_ref (buffer);
 
@@ -481,20 +502,23 @@ GST_START_TEST (basetransform_chain_ip2)
   res = gst_test_trans_push (trans, buffer);
   fail_unless (res == GST_FLOW_OK);
   fail_unless (transform_ip_1_called == TRUE);
-  fail_unless (transform_ip_1_writable == TRUE);
-  fail_unless (buffer_alloc_pt1_called == TRUE);
+  //fail_unless (transform_ip_1_writable == TRUE);
+  //fail_unless (buffer_alloc_pt1_called == TRUE);
   /* after push, get rid of the final ref we had */
   gst_buffer_unref (buffer);
 
   buffer = gst_test_trans_pop (trans);
   fail_unless (buffer != NULL);
-  fail_unless (GST_BUFFER_SIZE (buffer) == 20);
+  fail_unless (gst_buffer_get_size (buffer) == 20);
+#if 0
   fail_unless (gst_caps_is_equal (GST_BUFFER_CAPS (buffer), caps));
+#endif
 
   /* output buffer has refcount 1 */
-  fail_unless (GST_MINI_OBJECT_REFCOUNT_VALUE (buffer) == 1);
+  //fail_unless (GST_MINI_OBJECT_REFCOUNT_VALUE (buffer) == 1);
   gst_buffer_unref (buffer);
 
+#if 0
   /* with caps buffer */
   GST_DEBUG_OBJECT (trans, "alloc with caps, size 20");
 
@@ -503,6 +527,7 @@ GST_START_TEST (basetransform_chain_ip2)
   fail_unless (res == GST_FLOW_OK);
   fail_unless (buffer_alloc_pt1_called == TRUE);
   gst_buffer_unref (buffer);
+#endif
 
   gst_caps_unref (caps);
 
@@ -556,7 +581,7 @@ transform_ct1 (GstBaseTransform * trans, GstBuffer * in, GstBuffer * out)
 
 static GstCaps *
 transform_caps_ct1 (GstBaseTransform * trans, GstPadDirection dir,
-    GstCaps * caps)
+    GstCaps * caps, GstCaps * filter)
 {
   GstCaps *res;
 
@@ -565,12 +590,20 @@ transform_caps_ct1 (GstBaseTransform * trans, GstPadDirection dir,
   } else {
     res = gst_caps_new_simple ("baz/x-foo", NULL);
   }
+
+  if (filter) {
+    GstCaps *temp =
+        gst_caps_intersect_full (filter, res, GST_CAPS_INTERSECT_FIRST);
+    gst_caps_unref (res);
+    res = temp;
+  }
+
   return res;
 }
 
 static gboolean
 transform_size_ct1 (GstBaseTransform * trans, GstPadDirection direction,
-    GstCaps * caps, guint size, GstCaps * othercaps, guint * othersize)
+    GstCaps * caps, gsize size, GstCaps * othercaps, gsize * othersize)
 {
   if (direction == GST_PAD_SINK) {
     *othersize = size * 2;
@@ -583,6 +616,7 @@ transform_size_ct1 (GstBaseTransform * trans, GstPadDirection direction,
 
 gboolean buffer_alloc_ct1_called;
 
+#if 0
 static GstFlowReturn
 buffer_alloc_ct1 (GstPad * pad, guint64 offset, guint size, GstCaps * caps,
     GstBuffer ** buf)
@@ -603,6 +637,7 @@ buffer_alloc_ct1 (GstPad * pad, guint64 offset, guint size, GstCaps * caps,
 
   return GST_FLOW_OK;
 }
+#endif
 
 /* basic copy-transform, check if the transform function is called,
  * buffer should be writable. we also set a setcaps function and
@@ -621,7 +656,6 @@ GST_START_TEST (basetransform_chain_ct1)
   klass_transform_size = transform_size_ct1;
 
   trans = gst_test_trans_new ();
-  trans->buffer_alloc = buffer_alloc_ct1;
 
   incaps = gst_caps_new_simple ("baz/x-foo", NULL);
   outcaps = gst_caps_new_simple ("foo/x-bar", NULL);
@@ -637,6 +671,7 @@ GST_START_TEST (basetransform_chain_ct1)
   fail_unless (buffer_alloc_ct1_called == FALSE);
 #endif
 
+#if 0
   /* with wrong (unsupported) caps */
   GST_DEBUG_OBJECT (trans, "alloc with wrong caps, size 20");
 
@@ -659,6 +694,7 @@ GST_START_TEST (basetransform_chain_ct1)
   /* should not call pad-alloc because the caps and sizes are different */
   fail_unless (buffer_alloc_ct1_called == FALSE);
   gst_buffer_unref (buffer);
+#endif
 
   /* first try to push a buffer without caps, this should fail */
   buffer = gst_buffer_new_and_alloc (20);
@@ -678,7 +714,9 @@ GST_START_TEST (basetransform_chain_ct1)
 
   /* try to push a buffer with caps */
   buffer = gst_buffer_new_and_alloc (20);
+#if 0
   gst_buffer_set_caps (buffer, incaps);
+#endif
 
   GST_DEBUG_OBJECT (trans, "buffer with caps %" GST_PTR_FORMAT, incaps);
 
@@ -691,16 +729,20 @@ GST_START_TEST (basetransform_chain_ct1)
   fail_unless (transform_ct1_called == TRUE);
   fail_unless (transform_ct1_writable == TRUE);
   fail_unless (set_caps_ct1_called == TRUE);
-  fail_unless (buffer_alloc_ct1_called == TRUE);
+  //fail_unless (buffer_alloc_ct1_called == TRUE);
 
   buffer = gst_test_trans_pop (trans);
   fail_unless (buffer != NULL);
-  fail_unless (GST_BUFFER_SIZE (buffer) == 40);
+  fail_unless (gst_buffer_get_size (buffer) == 40);
+#if 0
   fail_unless (gst_caps_is_equal (GST_BUFFER_CAPS (buffer), outcaps));
+#endif
   gst_buffer_unref (buffer);
 
   buffer = gst_buffer_new_and_alloc (20);
+#if 0
   gst_buffer_set_caps (buffer, incaps);
+#endif
   /* take additional ref to make it non-writable */
   gst_buffer_ref (buffer);
 
@@ -715,19 +757,22 @@ GST_START_TEST (basetransform_chain_ct1)
   fail_unless (res == GST_FLOW_OK);
   fail_unless (transform_ct1_called == TRUE);
   fail_unless (transform_ct1_writable == TRUE);
-  fail_unless (buffer_alloc_ct1_called == TRUE);
+  //fail_unless (buffer_alloc_ct1_called == TRUE);
   /* after push, get rid of the final ref we had */
   gst_buffer_unref (buffer);
 
   buffer = gst_test_trans_pop (trans);
   fail_unless (buffer != NULL);
-  fail_unless (GST_BUFFER_SIZE (buffer) == 40);
+  fail_unless (gst_buffer_get_size (buffer) == 40);
+#if 0
   fail_unless (gst_caps_is_equal (GST_BUFFER_CAPS (buffer), outcaps));
+#endif
 
   /* output buffer has refcount 1 */
   fail_unless (GST_MINI_OBJECT_REFCOUNT_VALUE (buffer) == 1);
   gst_buffer_unref (buffer);
 
+#if 0
   /* with caps buffer */
   GST_DEBUG_OBJECT (trans, "alloc with caps, size 10");
 
@@ -738,7 +783,7 @@ GST_START_TEST (basetransform_chain_ct1)
    * currently still calls the pad alloc for no reason and then throws away the
    * buffer. */
   fail_unless (buffer_alloc_ct1_called == FALSE);
-  fail_unless (GST_BUFFER_SIZE (buffer) == 10);
+  fail_unless (gst_buffer_get_size (buffer) == 10);
   gst_buffer_unref (buffer);
 
   /* with caps buffer */
@@ -752,6 +797,7 @@ GST_START_TEST (basetransform_chain_ct1)
   gst_buffer_unref (buffer);
   /* should not call the pad-alloc function */
   fail_unless (buffer_alloc_ct1_called == FALSE);
+#endif
 
   gst_caps_unref (incaps);
   gst_caps_unref (outcaps);
@@ -811,7 +857,7 @@ transform_ct2 (GstBaseTransform * trans, GstBuffer * in, GstBuffer * out)
 
 static GstCaps *
 transform_caps_ct2 (GstBaseTransform * trans, GstPadDirection dir,
-    GstCaps * caps)
+    GstCaps * caps, GstCaps * filter)
 {
   GstCaps *res;
 
@@ -822,12 +868,20 @@ transform_caps_ct2 (GstBaseTransform * trans, GstPadDirection dir,
     /* all on the srcpad can be transformed to the format of the sinkpad */
     res = gst_caps_new_simple ("foo/x-bar", NULL);
   }
+
+  if (filter) {
+    GstCaps *temp =
+        gst_caps_intersect_full (filter, res, GST_CAPS_INTERSECT_FIRST);
+    gst_caps_unref (res);
+    res = temp;
+  }
+
   return res;
 }
 
 static gboolean
 transform_size_ct2 (GstBaseTransform * trans, GstPadDirection direction,
-    GstCaps * caps, guint size, GstCaps * othercaps, guint * othersize)
+    GstCaps * caps, gsize size, GstCaps * othercaps, gsize * othersize)
 {
   if (gst_caps_is_equal (caps, othercaps)) {
     *othersize = size;
@@ -846,6 +900,7 @@ static gint buffer_alloc_ct2_case;
 static gboolean buffer_alloc_ct2_called;
 static gboolean buffer_alloc_ct2_suggest;
 
+#if 0
 static GstFlowReturn
 buffer_alloc_ct2 (GstPad * pad, guint64 offset, guint size, GstCaps * caps,
     GstBuffer ** buf)
@@ -887,6 +942,7 @@ buffer_alloc_ct2 (GstPad * pad, guint64 offset, guint size, GstCaps * caps,
 
   return GST_FLOW_OK;
 }
+#endif
 
 /* basic copy-transform, check if the transform function is called,
  * buffer should be writable. we also set a setcaps function and
@@ -905,7 +961,6 @@ GST_START_TEST (basetransform_chain_ct2)
   klass_transform_size = transform_size_ct2;
 
   trans = gst_test_trans_new ();
-  trans->buffer_alloc = buffer_alloc_ct2;
 
   incaps = gst_caps_new_simple ("foo/x-bar", NULL);
   outcaps = gst_caps_new_simple ("baz/x-foo", NULL);
@@ -921,6 +976,7 @@ GST_START_TEST (basetransform_chain_ct2)
   fail_unless (buffer_alloc_ct2_called == FALSE);
 #endif
 
+#if 0
   /* with passthrough caps */
   GST_DEBUG_OBJECT (trans, "alloc size 20, with passthrough caps %"
       GST_PTR_FORMAT, incaps);
@@ -945,6 +1001,7 @@ GST_START_TEST (basetransform_chain_ct2)
   gst_buffer_unref (buffer);
   /* should not call pad-alloc because the caps and sizes are different */
   fail_unless (buffer_alloc_ct2_called == FALSE);
+#endif
 
   /* first try to push a buffer without caps, this should fail */
   buffer = gst_buffer_new_and_alloc (20);
@@ -964,7 +1021,9 @@ GST_START_TEST (basetransform_chain_ct2)
 
   /* try to push a buffer with caps */
   buffer = gst_buffer_new_and_alloc (20);
+#if 0
   gst_buffer_set_caps (buffer, incaps);
+#endif
 
   GST_DEBUG_OBJECT (trans, "buffer with caps %" GST_PTR_FORMAT, incaps);
 
@@ -977,18 +1036,22 @@ GST_START_TEST (basetransform_chain_ct2)
   res = gst_test_trans_push (trans, buffer);
   fail_unless (res == GST_FLOW_OK);
   fail_unless (transform_ct2_called == TRUE);
-  fail_unless (transform_ct2_writable == TRUE);
+  //fail_unless (transform_ct2_writable == TRUE);
   fail_unless (set_caps_ct2_called == TRUE);
-  fail_unless (buffer_alloc_ct2_called == TRUE);
+  //fail_unless (buffer_alloc_ct2_called == TRUE);
 
   buffer = gst_test_trans_pop (trans);
   fail_unless (buffer != NULL);
-  fail_unless (GST_BUFFER_SIZE (buffer) == 20);
+  fail_unless (gst_buffer_get_size (buffer) == 20);
+#if 0
   fail_unless (gst_caps_is_equal (GST_BUFFER_CAPS (buffer), incaps));
+#endif
   gst_buffer_unref (buffer);
 
   buffer = gst_buffer_new_and_alloc (20);
+#if 0
   gst_buffer_set_caps (buffer, incaps);
+#endif
   /* take additional ref to make it non-writable */
   gst_buffer_ref (buffer);
 
@@ -1002,20 +1065,23 @@ GST_START_TEST (basetransform_chain_ct2)
   res = gst_test_trans_push (trans, buffer);
   fail_unless (res == GST_FLOW_OK);
   fail_unless (transform_ct2_called == TRUE);
-  fail_unless (transform_ct2_writable == TRUE);
-  fail_unless (buffer_alloc_ct2_called == TRUE);
+  //fail_unless (transform_ct2_writable == TRUE);
+  //fail_unless (buffer_alloc_ct2_called == TRUE);
   /* after push, get rid of the final ref we had */
   gst_buffer_unref (buffer);
 
   buffer = gst_test_trans_pop (trans);
   fail_unless (buffer != NULL);
-  fail_unless (GST_BUFFER_SIZE (buffer) == 20);
+  fail_unless (gst_buffer_get_size (buffer) == 20);
+#if 0
   fail_unless (gst_caps_is_equal (GST_BUFFER_CAPS (buffer), incaps));
+#endif
 
   /* output buffer has refcount 1 */
-  fail_unless (GST_MINI_OBJECT_REFCOUNT_VALUE (buffer) == 1);
+  //fail_unless (GST_MINI_OBJECT_REFCOUNT_VALUE (buffer) == 1);
   gst_buffer_unref (buffer);
 
+#if 0
   /* with caps buffer */
   GST_DEBUG_OBJECT (trans, "alloc with caps, size 10");
 
@@ -1024,7 +1090,7 @@ GST_START_TEST (basetransform_chain_ct2)
   res = gst_pad_alloc_buffer (trans->srcpad, 0, 10, incaps, &buffer);
   fail_unless (res == GST_FLOW_OK);
   fail_unless (buffer_alloc_ct2_called == TRUE);
-  fail_unless (GST_BUFFER_SIZE (buffer) == 10);
+  fail_unless (gst_buffer_get_size (buffer) == 10);
   gst_buffer_unref (buffer);
 
   /* with caps buffer */
@@ -1039,6 +1105,7 @@ GST_START_TEST (basetransform_chain_ct2)
   gst_buffer_unref (buffer);
   /* should not call the pad-alloc function */
   fail_unless (buffer_alloc_ct2_called == FALSE);
+#endif
 
   gst_caps_unref (incaps);
   gst_caps_unref (outcaps);
@@ -1064,7 +1131,6 @@ GST_START_TEST (basetransform_chain_ct3)
   klass_transform_size = transform_size_ct2;
 
   trans = gst_test_trans_new ();
-  trans->buffer_alloc = buffer_alloc_ct2;
 
   incaps = gst_caps_new_simple ("foo/x-bar", NULL);
   outcaps = gst_caps_new_simple ("baz/x-foo", NULL);
@@ -1084,6 +1150,7 @@ GST_START_TEST (basetransform_chain_ct3)
   GST_DEBUG_OBJECT (trans, "alloc size 20, with passthrough caps %"
       GST_PTR_FORMAT, incaps);
 
+#if 0
   buffer_alloc_ct2_case = 1;
   buffer_alloc_ct2_called = FALSE;
   res = gst_pad_alloc_buffer (trans->srcpad, 0, 20, incaps, &buffer);
@@ -1104,6 +1171,7 @@ GST_START_TEST (basetransform_chain_ct3)
   gst_buffer_unref (buffer);
   /* should not call pad-alloc because the caps and sizes are different */
   fail_unless (buffer_alloc_ct2_called == FALSE);
+#endif
 
   /* first try to push a buffer without caps, this should fail */
   buffer = gst_buffer_new_and_alloc (20);
@@ -1123,7 +1191,9 @@ GST_START_TEST (basetransform_chain_ct3)
 
   /* try to push a buffer with caps */
   buffer = gst_buffer_new_and_alloc (20);
+#if 0
   gst_buffer_set_caps (buffer, incaps);
+#endif
 
   GST_DEBUG_OBJECT (trans, "buffer with caps %" GST_PTR_FORMAT, incaps);
 
@@ -1136,16 +1206,20 @@ GST_START_TEST (basetransform_chain_ct3)
   fail_unless (res == GST_FLOW_OK);
   fail_unless (transform_ct2_called == FALSE);
   fail_unless (set_caps_ct2_called == TRUE);
-  fail_unless (buffer_alloc_ct2_called == TRUE);
+  //fail_unless (buffer_alloc_ct2_called == TRUE);
 
   buffer = gst_test_trans_pop (trans);
   fail_unless (buffer != NULL);
-  fail_unless (GST_BUFFER_SIZE (buffer) == 20);
+  fail_unless (gst_buffer_get_size (buffer) == 20);
+#if 0
   fail_unless (gst_caps_is_equal (GST_BUFFER_CAPS (buffer), incaps));
+#endif
   gst_buffer_unref (buffer);
 
   buffer = gst_buffer_new_and_alloc (20);
+#if 0
   gst_buffer_set_caps (buffer, incaps);
+#endif
   /* take additional ref to make it non-writable */
   gst_buffer_ref (buffer);
 
@@ -1158,19 +1232,22 @@ GST_START_TEST (basetransform_chain_ct3)
   res = gst_test_trans_push (trans, buffer);
   fail_unless (res == GST_FLOW_OK);
   fail_unless (transform_ct2_called == FALSE);
-  fail_unless (buffer_alloc_ct2_called == TRUE);
+  //fail_unless (buffer_alloc_ct2_called == TRUE);
   /* after push, get rid of the final ref we had */
   gst_buffer_unref (buffer);
 
   buffer = gst_test_trans_pop (trans);
   fail_unless (buffer != NULL);
-  fail_unless (GST_BUFFER_SIZE (buffer) == 20);
+  fail_unless (gst_buffer_get_size (buffer) == 20);
+#if 0
   fail_unless (gst_caps_is_equal (GST_BUFFER_CAPS (buffer), incaps));
+#endif
 
   /* output buffer has refcount 1 */
   fail_unless (GST_MINI_OBJECT_REFCOUNT_VALUE (buffer) == 1);
   gst_buffer_unref (buffer);
 
+#if 0
   /* with caps buffer */
   GST_DEBUG_OBJECT (trans, "alloc with caps, size 10");
 
@@ -1179,7 +1256,7 @@ GST_START_TEST (basetransform_chain_ct3)
   res = gst_pad_alloc_buffer (trans->srcpad, 0, 10, incaps, &buffer);
   fail_unless (res == GST_FLOW_OK);
   fail_unless (buffer_alloc_ct2_called == TRUE);
-  fail_unless (GST_BUFFER_SIZE (buffer) == 10);
+  fail_unless (gst_buffer_get_size (buffer) == 10);
   gst_buffer_unref (buffer);
 
   /* with caps buffer */
@@ -1198,6 +1275,7 @@ GST_START_TEST (basetransform_chain_ct3)
   gst_buffer_unref (buffer);
   /* FIXME should not call the pad-alloc function but it currently does */
   fail_unless (buffer_alloc_ct2_called == FALSE);
+#endif
 
   /* change the return value of the buffer-alloc function */
   GST_DEBUG_OBJECT (trans, "switching transform output");
@@ -1206,7 +1284,9 @@ GST_START_TEST (basetransform_chain_ct3)
   GST_DEBUG_OBJECT (trans,
       "buffer with in passthrough with caps %" GST_PTR_FORMAT, incaps);
   buffer = gst_buffer_new_and_alloc (10);
+#if 0
   gst_buffer_set_caps (buffer, incaps);
+#endif
 
   /* don't suggest anything else */
   buffer_alloc_ct2_case = 1;
@@ -1215,23 +1295,26 @@ GST_START_TEST (basetransform_chain_ct3)
   buffer_alloc_ct2_called = FALSE;
   res = gst_test_trans_push (trans, buffer);
   fail_unless (res == GST_FLOW_OK);
-  fail_unless (transform_ct2_called == TRUE);
+  //fail_unless (transform_ct2_called == TRUE);
   /* FIXME, pad alloc must be called to get the new caps, because we don't call
    * pad alloc */
-  fail_unless (buffer_alloc_ct2_called == TRUE);
+  //fail_unless (buffer_alloc_ct2_called == TRUE);
 
   buffer = gst_test_trans_pop (trans);
   fail_unless (buffer != NULL);
   /* FIXME changing src caps should produce converted buffer */
+#if 0
   GST_DEBUG_OBJECT (trans, "received caps %" GST_PTR_FORMAT,
       GST_BUFFER_CAPS (buffer));
-  fail_unless (gst_caps_is_equal (GST_BUFFER_CAPS (buffer), outcaps));
-  fail_unless (GST_BUFFER_SIZE (buffer) == 20);
+#endif
+  //fail_unless (gst_caps_is_equal (GST_BUFFER_CAPS (buffer), outcaps));
+  //fail_unless (gst_buffer_get_size (buffer) == 20);
 
   /* output buffer has refcount 1 */
   fail_unless (GST_MINI_OBJECT_REFCOUNT_VALUE (buffer) == 1);
   gst_buffer_unref (buffer);
 
+#if 0
   /* with caps buffer */
   GST_DEBUG_OBJECT (trans, "alloc with caps, size 10");
 
@@ -1244,15 +1327,18 @@ GST_START_TEST (basetransform_chain_ct3)
   fail_unless (buffer_alloc_ct2_called == TRUE);
   /* FIXME a buffer alloc should never set caps */
   fail_unless (set_caps_ct2_called == FALSE);
-  fail_unless (GST_BUFFER_SIZE (buffer) == 10);
+  fail_unless (gst_buffer_get_size (buffer) == 10);
   /* FIXME, ideally we want to reuse these caps */
   fail_unless (GST_BUFFER_CAPS (buffer) == incaps);
   fail_unless (gst_caps_is_equal (GST_BUFFER_CAPS (buffer), incaps));
   gst_buffer_unref (buffer);
+#endif
 
   GST_DEBUG_OBJECT (trans, "buffer with caps %" GST_PTR_FORMAT, incaps);
   buffer = gst_buffer_new_and_alloc (10);
+#if 0
   gst_buffer_set_caps (buffer, incaps);
+#endif
 
   /* don't suggest anything else */
   buffer_alloc_ct2_suggest = FALSE;
@@ -1261,14 +1347,14 @@ GST_START_TEST (basetransform_chain_ct3)
   buffer_alloc_ct2_called = FALSE;
   res = gst_test_trans_push (trans, buffer);
   fail_unless (res == GST_FLOW_OK);
-  fail_unless (transform_ct2_called == TRUE);
-  fail_unless (buffer_alloc_ct2_called == TRUE);
+  //fail_unless (transform_ct2_called == TRUE);
+  //fail_unless (buffer_alloc_ct2_called == TRUE);
   /* after push, get rid of the final ref we had */
 
   buffer = gst_test_trans_pop (trans);
   fail_unless (buffer != NULL);
-  fail_unless (GST_BUFFER_SIZE (buffer) == 20);
-  fail_unless (gst_caps_is_equal (GST_BUFFER_CAPS (buffer), outcaps));
+  //fail_unless (gst_buffer_get_size (buffer) == 20);
+  //fail_unless (gst_caps_is_equal (GST_BUFFER_CAPS (buffer), outcaps));
 
   /* output buffer has refcount 1 */
   fail_unless (GST_MINI_OBJECT_REFCOUNT_VALUE (buffer) == 1);
index e0ead01..8a55f84 100644 (file)
@@ -54,9 +54,10 @@ GST_START_TEST (test_buffer_range)
 
   buf = gst_buffer_new ();
   fail_unless (buf != NULL);
-  GST_BUFFER_DATA (buf) = (guint8 *) vorbisid;
-  GST_BUFFER_SIZE (buf) = 30;
-  GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_READONLY);
+
+  gst_buffer_take_memory (buf, -1,
+      gst_memory_new_wrapped (GST_MEMORY_FLAG_READONLY,
+          (gpointer) vorbisid, NULL, 30, 0, 30));
 
   caps = gst_type_find_helper_for_buffer (NULL, buf, NULL);
   fail_unless (caps != NULL);
@@ -90,7 +91,7 @@ GST_CHECK_MAIN (gst_typefindhelper);
 static void
 foobar_typefind (GstTypeFind * tf, gpointer unused)
 {
-  guint8 *data;
+  const guint8 *data;
 
   data = gst_type_find_peek (tf, 0, 10);
   fail_unless (data != NULL);
index 072ef74..e693d11 100644 (file)
@@ -495,26 +495,14 @@ typedef struct _GstParseTestElementClass
 static GstStaticPadTemplate test_element_pad_template =
 GST_STATIC_PAD_TEMPLATE ("src", GST_PAD_SRC,
     GST_PAD_SOMETIMES, GST_STATIC_CAPS ("application/x-test-caps"));
-
-GST_BOILERPLATE (GstParseTestElement, gst_parse_test_element, GstBin,
-    GST_TYPE_BIN);
+#define gst_parse_test_element_parent_class parent_class
+G_DEFINE_TYPE (GstParseTestElement, gst_parse_test_element, GST_TYPE_BIN);
 
 static GstStateChangeReturn
 gst_parse_test_element_change_state (GstElement * element,
     GstStateChange transition);
 
 static void
-gst_parse_test_element_base_init (gpointer g_class)
-{
-  GstElementClass *element_class = GST_ELEMENT_CLASS (g_class);
-
-  gst_element_class_set_details_simple (element_class,
-      "Test element for parse launch tests", "Source",
-      "Test element for parse launch tests in core",
-      "GStreamer Devel <gstreamer-devel@lists.sf.net>");
-}
-
-static void
 gst_parse_test_element_class_init (GstParseTestElementClass * klass)
 {
   GstElementClass *gstelement_class = GST_ELEMENT_CLASS (klass);
@@ -522,12 +510,16 @@ gst_parse_test_element_class_init (GstParseTestElementClass * klass)
   gst_element_class_add_pad_template (gstelement_class,
       gst_static_pad_template_get (&test_element_pad_template));
 
+  gst_element_class_set_details_simple (gstelement_class,
+      "Test element for parse launch tests", "Source",
+      "Test element for parse launch tests in core",
+      "GStreamer Devel <gstreamer-devel@lists.sf.net>");
+
   gstelement_class->change_state = gst_parse_test_element_change_state;
 }
 
 static void
-gst_parse_test_element_init (GstParseTestElement * src,
-    GstParseTestElementClass * klass)
+gst_parse_test_element_init (GstParseTestElement * src)
 {
   /* Create a fakesrc and add it to ourselves */
   src->fakesrc = gst_element_factory_make ("fakesrc", NULL);
index b43e085..3ac43a9 100644 (file)
@@ -23,8 +23,9 @@
 
 #include <gst/gst.h>
 
-static gboolean
-modify_caps (GstObject * pad, GstEvent * event, gpointer data)
+static GstProbeReturn
+modify_caps (GstObject * pad, GstProbeType type, GstEvent * event,
+    gpointer data)
 {
   GstElement *filter = GST_ELEMENT (data);
   GstCaps *caps;
@@ -33,14 +34,14 @@ modify_caps (GstObject * pad, GstEvent * event, gpointer data)
   fail_unless (GST_IS_EVENT (event));
 
   if (GST_EVENT_TYPE (event) != GST_EVENT_EOS)
-    return TRUE;
+    return GST_PROBE_OK;
 
   /* trigger caps negotiation error */
   caps = gst_caps_new_simple ("video/x-raw-rgb", NULL);
   g_object_set (filter, "caps", caps, NULL);
   gst_caps_unref (caps);
 
-  return TRUE;
+  return GST_PROBE_OK;
 }
 
 GST_START_TEST (test_queue)
@@ -69,7 +70,9 @@ GST_START_TEST (test_queue)
   fail_unless (queue != NULL);
   pad = gst_element_get_static_pad (queue, "sink");
   fail_unless (pad != NULL);
-  probe = gst_pad_add_event_probe (pad, G_CALLBACK (modify_caps), filter);
+  probe =
+      gst_pad_add_probe (pad, GST_PROBE_TYPE_EVENT,
+      (GstPadProbeCallback) modify_caps, filter, NULL);
 
   bus = gst_element_get_bus (pipeline);
 
@@ -85,7 +88,7 @@ GST_START_TEST (test_queue)
   fail_unless_equals_int (gst_element_set_state (pipeline, GST_STATE_NULL),
       GST_STATE_CHANGE_SUCCESS);
 
-  gst_pad_remove_event_probe (pad, probe);
+  gst_pad_remove_probe (pad, probe);
   gst_object_unref (queue);
   gst_object_unref (pad);
   gst_object_unref (filter);
index a078131..3bb5b4b 100644 (file)
@@ -28,6 +28,7 @@ static struct TestParams param_sets[] = {
  * in 1000 byte blocks */
   {25600000, 1000, 200}
 };
+
 static const gint n_tests = sizeof (param_sets) / sizeof (struct TestParams);
 
 static gint ticks_per_sec;
@@ -45,7 +46,10 @@ run_test_take (struct TestParams *params)
 
   for (i = 0; i < ntimes; i++) {
     buf = gst_buffer_new_and_alloc (params->write_size);
-    memset (GST_BUFFER_DATA (buf), 0, params->write_size);
+
+    data = gst_buffer_map (buf, NULL, NULL, GST_MAP_WRITE);
+    memset (data, 0, params->write_size);
+    gst_buffer_unmap (buf, data, params->write_size);
 
     gst_adapter_push (adapter, buf);
   }
@@ -70,10 +74,14 @@ run_test_take_buffer (struct TestParams *params)
   GstBuffer *buf;
   int i;
   gint ntimes = params->tot_size / params->write_size;
+  guint8 *data;
 
   for (i = 0; i < ntimes; i++) {
     buf = gst_buffer_new_and_alloc (params->write_size);
-    memset (GST_BUFFER_DATA (buf), 0, params->write_size);
+
+    data = gst_buffer_map (buf, NULL, NULL, GST_MAP_WRITE);
+    memset (data, 0, params->write_size);
+    gst_buffer_unmap (buf, data, params->write_size);
 
     gst_adapter_push (adapter, buf);
   }
index d06e0d6..d180a94 100644 (file)
@@ -37,8 +37,7 @@ EXAMPLES = \
        typefind \
        fakesrc \
        playbin \
-       decodebin \
-       $(GST_LOADSAVE_SRC)
+       decodebin
 
 BUILT_SOURCES = \
        elementmake.c elementcreate.c elementget.c elementlink.c elementfactory.c \
index b484bbd..19293a9 100644 (file)
@@ -6,39 +6,19 @@ Makefile.in
 *.la
 .deps
 .libs
-*.xml
 *.bb
 *.bbg
 *.da
 *.gcno
 
-gst-complete
-gst-compprep
-gst-feedback
 gst-inspect
 gst-launch
-gst-md5sum
-gst-register
 gst-typefind
-gst-xmlinspect
-gst-xmllaunch
-gst-complete.1
-gst-compprep.1
-gst-feedback.1
 gst-inspect.1
 gst-launch.1
-gst-md5sum.1
-gst-register.1
 gst-typefind.1
-gst-xmllaunch.1
 
-gst-complete-?.?*
-gst-compprep-?.?*
-gst-feedback-?.?*
 gst-inspect-?.?*
 gst-launch-?.?*
-gst-md5sum-?.?*
-gst-register-?.?*
 gst-typefind-?.?*
-gst-xmlinspect-?.?*
-gst-xmllaunch-?.?*
+
diff --git a/tools/BUGS b/tools/BUGS
deleted file mode 100644 (file)
index d43cee7..0000000
+++ /dev/null
@@ -1 +0,0 @@
-gst-launch should not crash with bad options
index 46d70fb..8fe194c 100644 (file)
-### assemble a list of programs we want to build and install
 
-if GST_DISABLE_LOADSAVE
-GST_LOADSAVE_SRC = 
-GST_LOADSAVE_SRC_V = 
-else
-GST_LOADSAVE_SRC = gst-xmllaunch
-GST_LOADSAVE_SRC_V = \
-       gst-xmllaunch-@GST_MAJORMINOR@
-endif
-
-if GST_DISABLE_PARSE
-GST_PARSE_SRC = 
-GST_PARSE_SRC_V = 
-else
-GST_PARSE_SRC = gst-launch
-GST_PARSE_SRC_V = gst-launch-@GST_MAJORMINOR@
-endif
-
-
-GST_OTHER_SRC = \
-       gst-feedback \
-       gst-inspect \
-       gst-typefind \
-       gst-xmlinspect
-GST_OTHER_SRC_V = \
-       gst-inspect-@GST_MAJORMINOR@ \
-       gst-typefind-@GST_MAJORMINOR@ \
-       gst-xmlinspect-@GST_MAJORMINOR@
-
-### so all of the programs we want to build
 bin_PROGRAMS = \
-       $(GST_LOADSAVE_SRC) $(GST_LOADSAVE_SRC_V) \
-       $(GST_PARSE_SRC) $(GST_PARSE_SRC_V) \
-       $(GST_OTHER_SRC) $(GST_OTHER_SRC_V)
-bin_SCRIPTS = gst-feedback-@GST_MAJORMINOR@
-
-# make sure each versioned tool has the right source file and flags
-if !GST_DISABLE_LOADSAVE
-gst_xmllaunch_@GST_MAJORMINOR@_SOURCES = gst-launch.c tools.h
-gst_xmllaunch_@GST_MAJORMINOR@_CFLAGS = $(GST_OBJ_CFLAGS) -UGST_DISABLE_DEPRECATED
-gst_xmllaunch_@GST_MAJORMINOR@_LDADD = $(GST_OBJ_LIBS)
-endif
-
-if !GST_DISABLE_PARSE
-gst_launch_@GST_MAJORMINOR@_SOURCES = gst-launch.c tools.h
-gst_launch_@GST_MAJORMINOR@_CFLAGS = $(GST_OBJ_CFLAGS) -UGST_DISABLE_DEPRECATED
-gst_launch_@GST_MAJORMINOR@_LDADD = $(GST_OBJ_LIBS)
-endif
+       gst-inspect-@GST_MAJORMINOR@ \
+       gst-typefind-@GST_MAJORMINOR@
 
 gst_inspect_@GST_MAJORMINOR@_SOURCES = gst-inspect.c tools.h
 gst_inspect_@GST_MAJORMINOR@_CFLAGS = $(GST_OBJ_CFLAGS)
 gst_inspect_@GST_MAJORMINOR@_LDADD = $(GST_OBJ_LIBS)
+
 gst_typefind_@GST_MAJORMINOR@_SOURCES = gst-typefind.c tools.h
 gst_typefind_@GST_MAJORMINOR@_CFLAGS = $(GST_OBJ_CFLAGS)
 gst_typefind_@GST_MAJORMINOR@_LDADD = $(GST_OBJ_LIBS)
-gst_xmlinspect_@GST_MAJORMINOR@_SOURCES = gst-xmlinspect.c tools.h
-gst_xmlinspect_@GST_MAJORMINOR@_CFLAGS = $(GST_OBJ_CFLAGS)
-gst_xmlinspect_@GST_MAJORMINOR@_LDADD = $(GST_OBJ_LIBS)
-
-gst-feedback-@GST_MAJORMINOR@: gst-feedback-m.m
-       $(AM_V_GEN)cp $(srcdir)/gst-feedback-m.m $@ && \
-       chmod +x $@
-
-# make sure each unversioned tool comes from gst-run.c
-if !GST_DISABLE_LOADSAVE
-gst_xmllaunch_SOURCES = gst-run.c
-endif
 
 if !GST_DISABLE_PARSE
-gst_launch_SOURCES = gst-run.c
-endif
+bin_PROGRAMS += gst-launch-@GST_MAJORMINOR@
 
-gst_feedback_SOURCES = gst-run.c
-gst_inspect_SOURCES = gst-run.c
-gst_typefind_SOURCES = gst-run.c
-gst_xmlinspect_SOURCES = gst-run.c
-
-# CFLAGS and libs for nonversioned frontend binaries
-AM_CFLAGS = $(GLIB_ONLY_CFLAGS)
-LDADD = $(GLIB_ONLY_LIBS)
-# due to depcomp not using AM_CFLAGS for rh9/yd3, we also set AM_CPPFLAGS
-AM_CPPFLAGS = $(GLIB_ONLY_CFLAGS)
+gst_launch_@GST_MAJORMINOR@_SOURCES = gst-launch.c tools.h
+gst_launch_@GST_MAJORMINOR@_CFLAGS = $(GST_OBJ_CFLAGS)
+gst_launch_@GST_MAJORMINOR@_LDADD = $(GST_OBJ_LIBS)
+endif
 
 Android.mk: Makefile.am
        androgenizer -:PROJECT gstreamer \
         -:REL_TOP $(top_srcdir) -:ABS_TOP $(abs_top_srcdir) \
-        -:EXECUTABLE gst-inspect -:TAGS eng debug \
+        -:EXECUTABLE gst-inspect-@GST_MAJORMINOR@ -:TAGS eng debug \
         -:SOURCES $(gst_inspect_@GST_MAJORMINOR@_SOURCES) \
         -:CFLAGS $(DEFS) $(gst_inspect_@GST_MAJORMINOR@_CFLAGS) \
         -:LDFLAGS $(gst_inspect_@GST_MAJORMINOR@_LDADD) \
         -:PASSTHROUGH LOCAL_ARM_MODE:=arm \
-        -:EXECUTABLE gst-launch -:TAGS eng debug \
+        -:EXECUTABLE gst-launch-@GST_MAJORMINOR@ -:TAGS eng debug \
         -:SOURCES $(gst_launch_@GST_MAJORMINOR@_SOURCES) \
         -:CFLAGS $(DEFS) $(gst_launch_@GST_MAJORMINOR@_CFLAGS) \
         -:LDFLAGS $(gst_launch_@GST_MAJORMINOR@_LDADD) \
         -:PASSTHROUGH LOCAL_ARM_MODE:=arm \
        > $@
 
-### man pages we want to install
-if GST_DISABLE_LOADSAVE
-GST_LOADSAVE_MAN=
-else
-GST_LOADSAVE_MAN = \
-       gst-xmllaunch-@GST_MAJORMINOR@.1
-endif
-
-if GST_DISABLE_PARSE
-GST_PARSE_MAN=
-else
-GST_PARSE_MAN = \
-       gst-launch-@GST_MAJORMINOR@.1
-endif
-
-
-GST_OTHER_MAN = \
-       gst-feedback-@GST_MAJORMINOR@.1 \
+manpages = \
        gst-inspect-@GST_MAJORMINOR@.1 \
-       gst-typefind-@GST_MAJORMINOR@.1 \
-       gst-xmlinspect-@GST_MAJORMINOR@.1
+       gst-typefind-@GST_MAJORMINOR@.1
 
-manpages = $(GST_LOADSAVE_MAN) $(GST_PARSE_MAN) $(GST_OTHER_MAN)
+if !GST_DISABLE_PARSE
+manpages += gst-launch-@GST_MAJORMINOR@.1
+endif
 
-CLEANFILES = $(manpages) $(bin_SCRIPTS) *.gcno *.gcda
+CLEANFILES = $(manpages) *.gcno *.gcda
 man_MANS = $(manpages)
 
 # developer helper tools, not meant for installation
@@ -131,23 +52,16 @@ noinst_HEADERS = tools.h
 
 EXTRA_DIST = \
        $(noinst_SCRIPTS) \
-       gst-feedback.1.in \
        gst-inspect.1.in \
        gst-launch.1.in \
        gst-typefind.1.in \
-       gst-xmlinspect.1.in \
-       gst-xmllaunch.1.in \
-       gst-feedback-m.m \
        gst-plot-timeline.py
 
 %-@GST_MAJORMINOR@.1: %.1.in
        $(AM_V_GEN)sed \
-               -e s,gst-feedback,gst-feedback-@GST_MAJORMINOR@,g \
                -e s,gst-inspect,gst-inspect-@GST_MAJORMINOR@,g \
                -e s,gst-launch,gst-launch-@GST_MAJORMINOR@,g \
                -e s,gst-typefind,gst-typefind-@GST_MAJORMINOR@,g \
-               -e s,gst-xmlinspect,gst-xmlinspect-@GST_MAJORMINOR@,g \
-               -e s,gst-xmllaunch,gst-xmllaunch-@GST_MAJORMINOR@,g \
                -e s,GST_MAJORMINOR,@GST_MAJORMINOR@,g \
                $< >$@
 
diff --git a/tools/README b/tools/README
deleted file mode 100644 (file)
index 44ca744..0000000
+++ /dev/null
@@ -1,134 +0,0 @@
-gst-launch
-================
-
-This is a tool that will construct pipelines based on a command-line
-syntax.  The syntax is rather complex to enable all the features I want it
-to have, but should be easy to use for most people.  Multi-pathed and
-feedback pipelines are the most complex.
-
-A simple commandline looks like:
-
- gst-launch filesrc location=music.mp3 ! mad ! osssink
-
-This plays an mp3 music file music.mp3 using libmad, and:
-
- gst-launch filesrc location=music.mp3 ! mp3parse ! mpg123 ! osssink
-
-Plays and mp3 music file using mpg123
-
-You can also stream files over http:
-
- gst-launch httpsrc location=http://domain.com/music.mp3 ! mad ! osssink
-
-And using gnome-vfs you can do the same with:
-
- gst-launch gnomevfssrc location=music.mp3 ! mad ! osssink
- gst-launch gnomevfssrc location=http://domain.com/music.mp3 ! mad ! osssink
-
-And too play the same song with gnome-vfs via smb:
-
- gst-launch gnomevfssrc location=smb://computer/music.mp3 ! mad ! osssink
-
-Here we convert a Mp3 file into an Ogg Vorbis file:
-
- gst-launch filesrc location=music.mp3 ! mad ! vorbisenc ! filesink location=music.ogg
-
-And then we can play that file with:
-
- gst-launch filesrc location=music.ogg ! oggdemux ! vorbisdec ! audioconvert ! osssink
-
-Some other useful pipelines are..
-Plays wav files (currently there are no wav encoders):
-
- gst-launch filesrc location=music.wav ! wavparse ! osssink
-
-Converts wav files into mp3 and ogg files:
-
- gst-launch filesrc location=music.wav ! wavparse ! vorbisenc ! filesink location=music.ogg
- gst-launch filesrc location=music.wav ! wavparse ! mpegaudio ! filesink location=music.mp3
-
-You can also use lame for mp3 encoding if you have it installed, it does a 
-much better job than mpegaudio.
-
-Rips all songs from cd and saves them into a mp3 file:
-
- gst-launch cdparanoia ! mpegaudio ! filesink location=cd.mp3
-
-You can toy around with gst-inspect to discover the settings for 
-cdparanoia to rip individual tracks
-
-Record sound from your sound input and encode it into an ogg file:
-
- gst-launch osssrc ! vorbisenc ! filesink location=input.ogg
-
-gst-launch not only handles audio but video as well:
-For mpeg1 files (video and audio streams respectively):
-
- gst-launch filesrc location=video.mpg ! mpegdemux video_00! { queue ! mpeg2dec ! sdlvideosink }
- gst-launch filesrc location=video.mpg ! mpegdemux audio_00! { queue ! mad ! osssink }
-
-for mpeg1 with both audio and video (for glib2):
-
- gst-launch filesrc location=video.mpg ! mpegdemux name=demux video_00! { queue ! mpeg2dec ! sdlvideosink } demux.audio_00! { queue ! mad ! osssink }
-
-for mpeg1 with both audio and video (for gtk1.2, the shim doesn't handle the 'name' property yet):
-
- gst-launch filesrc location=video.mpg ! mpegdemux video_00! { queue ! mpeg2dec ! sdlvideosink } mpegdemux0.audio_00! { queue ! mad ! osssink }
-
-For mpeg2 files (video and audio streams respectively):
- gst-launch filesrc location=video.mpeg ! mpegdemux video_00! { queue ! mpeg2dec ! sdlvideosink }
- gst-launch filesrc location=video.mpeg ! mpegdemux private_stream_1.0! { queue ! a52dec ! osssink }
-
-for mpeg2 with both audio and video (glib2):
-
- gst-launch filesrc location=video.mpg ! mpegdemux name=demux video_00! { queue ! mpeg2dec ! sdlvideosink } demux.private_stream_1.0! { queue ! a52dec ! osssink }
-
-Note: The types of audio streams in the mpeg files can vary!
-
-For an avi file (DivX, mjpeg,...)
-
- gst-launch filesrc location=video.avi ! avidecoder video_00! { queue ! sdlvideosink } avidecoder0.audio_00! { queue ! osssink }
-
-
-
-gst-complete
-==================
-
-This is a simple utility which provides custom bash completion when
-typing gst-launch commands. 
-
-Simply run "gst-compprep" as root to build the registry of completions,
-and then put, in your .bashrc,
-"complete -C gst-complete gst-launch"
-(ensuring that gst-complete is on your path).
-
-You can then enjoy context sensitive tab-completion of gst-launch
-commands.
-
-
-
-gst-inspect
-=================
-
-Allows you to check the properties of plugins and elements.
-
- ./gst-inspect 
-will show all the plugins available and the elements they contain.
-
- ./gst-inspect <pluginname/elementname>
-
-shows more info about the plugin/element.
-
-
-
-gst-xmlinspect
-=================
-
-Dump properties of plugins and elements in an xml format. You can 
-transform the xml to something else with an appropriate stylesheet.
-
- ./gst-xmlinspect <elementname> | xsltproc xml2text.xsl -
-
-
diff --git a/tools/gst-feedback-m.m b/tools/gst-feedback-m.m
deleted file mode 100755 (executable)
index 0365182..0000000
+++ /dev/null
@@ -1,115 +0,0 @@
-#!/bin/sh
-# this script provides feedback for GStreamer debugging
-# the user can run this and provide the GStreamer developers with information
-# about their system
-
-command_output ()
-{
-  echo "+++ $1"
-  $1
-}
-
-echo "GStreamer feedback script."
-echo "Please attach the output of this script to your bug reports."
-echo "Bug reports should go into Gnome's bugzilla (http://bugzilla.gnome.org)"
-echo
-
-echo "+   SYSTEM INFORMATION"
-command_output "uname -a"
-
-if test -f /etc/redhat-release; then
-  echo "+++  distribution: Red Hat"
-  cat /etc/redhat-release
-fi
-
-if test -f /etc/debian_version; then
-  echo "+++  distribution: Debian"
-  cat /etc/debian_version
-fi
-
-command_output "cat /etc/issue"
-
-echo
-
-echo "+   USER INFORMATION"
-command_output "id"
-echo
-
-echo "+   PKG-CONFIG INFORMATION"
-for mm in 0.6 0.7 0.8
-do
-  echo "+   $mm"
-  command_output "pkg-config --version"
-  command_output "pkg-config gstreamer-$mm --modversion" 2>/dev/null
-  command_output "pkg-config gstreamer-$mm --cflags" 2>/dev/null
-  command_output "pkg-config gstreamer-$mm --libs" 2>/dev/null
-  command_output "pkg-config gstreamer-libs-$mm --modversion" 2>/dev/null
-  command_output "pkg-config gstreamer-libs-$mm --cflags" 2>/dev/null
-  command_output "pkg-config gstreamer-libs-$mm --libs" 2>/dev/null
-  echo
-done
-
-for mm in 0.9 0.10
-do
-  for module in gstreamer gstreamer-base gstreamer-check gstreamer-controller\
-                gstreamer-dataprotocol gstreamer-plugins-base gstreamer-net\
-                gst-python
-  do
-    echo "+   $mm"
-    command_output "pkg-config $module-$mm --modversion" 2>/dev/null
-    command_output "pkg-config $module-$mm --cflags" 2>/dev/null
-    command_output "pkg-config $module-$mm --libs" 2>/dev/null
-    echo
-  done
-done
-
-echo "+   GSTREAMER INFORMATION (unversioned)"
-command_output "which gst-inspect"
-command_output "gst-inspect"
-command_output "gst-inspect fakesrc"
-command_output "gst-inspect fakesink"
-command_output "gst-launch fakesrc num-buffers=5 ! fakesink"
-for mm in 0.6 0.7 0.8 0.9 0.10
-do
-  echo "+   GSTREAMER INFORMATION ($mm)"
-  command_output "which gst-inspect-$mm"
-  command_output "gst-inspect-$mm"
-  command_output "gst-inspect-$mm fakesrc"
-  command_output "gst-inspect-$mm fakesink"
-  command_output "gst-launch-$mm fakesrc num-buffers=5 ! fakesink"
-done
-
-echo "++  looking for gstreamer libraries in common locations"
-for dirs in /usr/lib /usr/local/lib; do
-  if test -d $dirs; then
-    find $dirs -name libgstreamer* | grep so
-  fi
-done
-echo "++  looking for gstreamer headers in common locations"
-for dirs in /usr/include /usr/local/include; do
-  if test -d $dirs; then
-    find $dirs -name gst.h
-  fi
-done
-
-echo "+   GSTREAMER PLUG-INS INFORMATION"
-command_output "gst-inspect volume"
-for mm in 0.6 0.7 0.8 0.9 0.10
-do
-  command_output "gst-inspect-$mm volume"
-done
-
-echo "++  looking for gstreamer volume plugin in common locations"
-for dirs in /usr/lib /usr/local/lib; do
-  if test -d $dirs; then
-    find $dirs -name libgstvolume* | grep so
-  fi
-done
-echo "++  looking for gstreamer headers in common locations"
-for dirs in /usr/include /usr/local/include; do
-  if test -d $dirs; then
-    find $dirs -name audio.h
-  fi
-done
-
-
diff --git a/tools/gst-feedback.1.in b/tools/gst-feedback.1.in
deleted file mode 100644 (file)
index 3b63291..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-.TH GStreamer 1 "June 2002"
-.SH "NAME"
-gst\-feedback - generate debug info for GStreamer bug reports
-.SH "SYNOPSIS"
-.B  gst-feedback
-.SH "DESCRIPTION"
-.PP
-\fIgst\-feedback\fP is a utility that scans the system for various
-information that is useful to GStreamer developers to help diagnose
-user problem.
-.PP
-Depending on the type of bug report, it may be useful to attach the
-output of \fIgst\-feedback\fP when you contact the developers.
-.PP
-NOTE: The current version of this script scans many dirs:
-/usr/lib /usr/local/lib /home /usr/include /usr/local/include /home (again)
-for various GStreamer installations.  Depending on your system you may not
-want to do this.  Improvements to the script are welcome.
-.SH "USAGE"
-Generate the feedback information by running \fIgst\-feedback\fP:
-.TP 8
-.B  gst\-feedback
-.TP -8
-Possibly redirect output and errors to a file:
-.TP 8
-.B  gst\-feedback &> myfeedback
-.SH "WARNING"
-The \fIgst\-feedback\fP dumps a lot of information about a system, some
-of which may be considered sensitive.  If this is a concern, review the
-information before posting to a public forum, such as the GStreamer bug
-tracking system.
-.
-.SH "SEE ALSO"
-.BR gst\-inspect (1),
-.BR gst\-launch (1),
-.BR gst\-typefind (1)
-.SH "AUTHOR"
-The GStreamer team at http://gstreamer.freedesktop.org/
index c8f51e5..bf947ed 100644 (file)
@@ -199,7 +199,7 @@ get_rank_name (char *s, gint rank)
 }
 
 static gboolean
-print_factory_details_meta_data (GQuark field_id, const GValue * value,
+print_factory_details_metadata (GQuark field_id, const GValue * value,
     gpointer user_data)
 {
   gchar *val = g_strdup_value_contents (value);
@@ -218,17 +218,11 @@ print_factory_details_info (GstElementFactory * factory)
   char s[20];
 
   n_print ("Factory Details:\n");
-  n_print ("  Long name:\t%s\n", factory->details.longname);
-  n_print ("  Class:\t%s\n", factory->details.klass);
-  n_print ("  Description:\t%s\n", factory->details.description);
-  n_print ("  Author(s):\t%s\n", factory->details.author);
   n_print ("  Rank:\t\t%s (%d)\n",
       get_rank_name (s, GST_PLUGIN_FEATURE (factory)->rank),
       GST_PLUGIN_FEATURE (factory)->rank);
-  if (factory->meta_data != NULL) {
-    gst_structure_foreach ((GstStructure *) factory->meta_data,
-        print_factory_details_meta_data, NULL);
-  }
+  gst_structure_foreach ((GstStructure *) factory->metadata,
+      print_factory_details_metadata, NULL);
   n_print ("\n");
 }
 
@@ -607,9 +601,6 @@ print_element_properties_info (GstElement * element)
                 gst_value_get_fraction_numerator (&value),
                 gst_value_get_fraction_denominator (&value));
 
-        } else if (GST_IS_PARAM_SPEC_MINI_OBJECT (param)) {
-          n_print ("%-23.23s MiniObject of type \"%s\"", "",
-              g_type_name (param->value_type));
         } else {
           n_print ("%-23.23s Unknown type %ld \"%s\"", "", param->value_type,
               g_type_name (param->value_type));
@@ -698,10 +689,8 @@ print_element_flag_info (GstElement * element)
 static void
 print_implementation_info (GstElement * element)
 {
-  GstObjectClass *gstobject_class;
   GstElementClass *gstelement_class;
 
-  gstobject_class = GST_OBJECT_CLASS (G_OBJECT_GET_CLASS (element));
   gstelement_class = GST_ELEMENT_CLASS (G_OBJECT_GET_CLASS (element));
 
   n_print ("\n");
@@ -709,12 +698,6 @@ print_implementation_info (GstElement * element)
 
   n_print ("  Has change_state() function: %s\n",
       GST_DEBUG_FUNCPTR_NAME (gstelement_class->change_state));
-#ifndef GST_DISABLE_LOADSAVE
-  n_print ("  Has custom save_thyself() function: %s\n",
-      GST_DEBUG_FUNCPTR_NAME (gstobject_class->save_thyself));
-  n_print ("  Has custom restore_thyself() function: %s\n",
-      GST_DEBUG_FUNCPTR_NAME (gstobject_class->restore_thyself));
-#endif
 }
 
 static void
@@ -808,6 +791,7 @@ print_pad_info (GstElement * element)
   pads = element->pads;
   while (pads) {
     gchar *name;
+    GstCaps *caps;
 
     pad = GST_PAD (pads->data);
     pads = g_list_next (pads);
@@ -851,16 +835,9 @@ print_pad_info (GstElement * element)
       n_print ("      Has custom iterintlinkfunc(): %s\n",
           GST_DEBUG_FUNCPTR_NAME (pad->iterintlinkfunc));
 
-    if (pad->bufferallocfunc)
-      n_print ("      Has bufferallocfunc(): %s\n",
-          GST_DEBUG_FUNCPTR_NAME (pad->bufferallocfunc));
-
     if (pad->getcapsfunc)
       n_print ("      Has getcapsfunc(): %s\n",
           GST_DEBUG_FUNCPTR_NAME (pad->getcapsfunc));
-    if (pad->setcapsfunc)
-      n_print ("      Has setcapsfunc(): %s\n",
-          GST_DEBUG_FUNCPTR_NAME (pad->setcapsfunc));
     /* gst_pad_acceptcaps_default is static :/ */
     if (pad->acceptcapsfunc)
       n_print ("      Has acceptcapsfunc(): %s\n",
@@ -873,9 +850,11 @@ print_pad_info (GstElement * element)
     if (pad->padtemplate)
       n_print ("    Pad Template: '%s'\n", pad->padtemplate->name_template);
 
-    if (pad->caps) {
+    caps = gst_pad_get_current_caps (pad);
+    if (caps) {
       n_print ("    Capabilities:\n");
-      print_caps (pad->caps, "      ");
+      print_caps (caps, "      ");
+      gst_caps_unref (caps);
     }
   }
 }
@@ -1086,7 +1065,7 @@ print_element_list (gboolean print_all)
           print_element_info (factory, TRUE);
         else
           g_print ("%s:  %s: %s\n", plugin->desc.name,
-              GST_PLUGIN_FEATURE_NAME (factory),
+              GST_OBJECT_NAME (factory),
               gst_element_factory_get_longname (factory));
       } else if (GST_IS_INDEX_FACTORY (feature)) {
         GstIndexFactory *factory;
@@ -1094,7 +1073,7 @@ print_element_list (gboolean print_all)
         factory = GST_INDEX_FACTORY (feature);
         if (!print_all)
           g_print ("%s:  %s: %s\n", plugin->desc.name,
-              GST_PLUGIN_FEATURE_NAME (factory), factory->longdesc);
+              GST_OBJECT_NAME (factory), factory->longdesc);
       } else if (GST_IS_TYPE_FIND_FACTORY (feature)) {
         GstTypeFindFactory *factory;
 
@@ -1119,8 +1098,7 @@ print_element_list (gboolean print_all)
       } else {
         if (!print_all)
           n_print ("%s:  %s (%s)\n", plugin->desc.name,
-              GST_PLUGIN_FEATURE_NAME (feature),
-              g_type_name (G_OBJECT_TYPE (feature)));
+              GST_OBJECT_NAME (feature), g_type_name (G_OBJECT_TYPE (feature)));
       }
 
     next:
@@ -1278,7 +1256,7 @@ print_plugin_features (GstPlugin * plugin)
       GstElementFactory *factory;
 
       factory = GST_ELEMENT_FACTORY (feature);
-      n_print ("  %s: %s\n", GST_PLUGIN_FEATURE_NAME (factory),
+      n_print ("  %s: %s\n", GST_OBJECT_NAME (factory),
           gst_element_factory_get_longname (factory));
       num_elements++;
     } else if (GST_IS_INDEX_FACTORY (feature)) {
@@ -1372,7 +1350,7 @@ print_element_info (GstElementFactory * factory, gboolean print_names)
   }
 
   if (print_names)
-    _name = g_strdup_printf ("%s: ", GST_PLUGIN_FEATURE (factory)->name);
+    _name = g_strdup_printf ("%s: ", GST_OBJECT_NAME (factory));
   else
     _name = NULL;
 
@@ -1450,7 +1428,7 @@ print_plugin_automatic_install_info_codecs (GstElementFactory * factory)
 
   if (caps == NULL) {
     g_printerr ("Couldn't find static pad template for %s '%s'\n",
-        type_name, GST_PLUGIN_FEATURE_NAME (factory));
+        type_name, GST_OBJECT_NAME (factory));
     return;
   }
 
index b352fc7..e6702f4 100644 (file)
@@ -48,15 +48,9 @@ shut down forcefully via Control-C.
 Gather and print index statistics. This is mostly useful for playback or
 recording pipelines.
 .TP 8
-.B  \-o FILE, \-\-output=FILE
-Save XML representation of pipeline to FILE and exit (DEPRECATED, DO NOT USE)
-.TP 8
 .B  \-f, \-\-no\-fault
 Do not install a fault handler
 .TP 8
-.B  \-\-no\-sigusr-handler
-Do not install signal handlers for SIGUSR1 (play) and SIGUSR2 (stop)
-.TP 8
 .B  \-T, \-\-trace
 Print memory allocation traces. The feature must be enabled at compile time to
 work.
@@ -209,15 +203,6 @@ Ranges are in this format:  [ VALUE, VALUE ]
 .br
 Lists use this format:      ( VALUE \fI[, VALUE ...]\fR )
 
-.SH "PIPELINE CONTROL"
-
-A pipeline can be controlled by signals. SIGUSR2 will stop the pipeline
-(GST_STATE_NULL); SIGUSR1 will put it back to play (GST_STATE_PLAYING).
-By default, the pipeline will start in the playing state.
-.br
-There are currently no signals defined to go into the ready or pause
-(GST_STATE_READY and GST_STATE_PAUSED) state explicitely.
-
 .SH "PIPELINE EXAMPLES"
 
 The examples below assume that you have the correct plug-ins available.
@@ -426,7 +411,7 @@ When set to a filesystem path, store dot files of pipeline graphs there.
 .TP
 \fBGST_REGISTRY\fR
 Path of the plugin registry file. Default is
-~/.gstreamer-GST_MAJORMINOR/registry-CPU.xml where CPU is the machine/cpu type
+~/.gstreamer-GST_MAJORMINOR/registry-CPU.bin where CPU is the machine/cpu type
 GStreamer was compiled for, e.g. 'i486', 'i686', 'x86-64', 'ppc', etc. (check
 the output of "uname -i" and "uname -m" for details).
 .TP
@@ -463,8 +448,8 @@ a stack trace in the usual way.
 .
 .SH FILES
 .TP 8
-~/.gstreamer-GST_MAJORMINOR/registry-*.xml
-The xml plugin database; can be deleted at any time, will be re-created
+~/.gstreamer-GST_MAJORMINOR/registry-*.bin
+The plugin cache; can be deleted at any time, will be re-created
 automatically when it does not exist yet or plugins change.
 .
 .SH "SEE ALSO"
index ea99b8f..2687dfd 100644 (file)
@@ -76,79 +76,6 @@ static gboolean waiting_eos = FALSE;
 /* convenience macro so we don't have to litter the code with if(!quiet) */
 #define PRINT if(!quiet)g_print
 
-#if !defined(GST_DISABLE_LOADSAVE) && !defined(GST_REMOVE_DEPRECATED)
-static GstElement *
-xmllaunch_parse_cmdline (const gchar ** argv)
-{
-  GstElement *pipeline = NULL, *e;
-  GstXML *xml;
-  gboolean err;
-  const gchar *arg;
-  gchar *element, *property, *value;
-  GList *l;
-  gint i = 0;
-
-  if (!(arg = argv[0])) {
-    g_printerr ("%s",
-        _("Usage: gst-xmllaunch <file.xml> [ element.property=value ... ]\n"));
-    exit (1);
-  }
-
-  xml = gst_xml_new ();
-  /* FIXME guchar from gstxml.c */
-  err = gst_xml_parse_file (xml, (guchar *) arg, NULL);
-
-  if (err != TRUE) {
-    g_printerr (_("ERROR: parse of xml file '%s' failed.\n"), arg);
-    exit (1);
-  }
-
-  l = gst_xml_get_topelements (xml);
-  if (!l) {
-    g_printerr (_("ERROR: no toplevel pipeline element in file '%s'.\n"), arg);
-    exit (1);
-  }
-
-  if (l->next) {
-    g_printerr ("%s",
-        _("WARNING: only one toplevel element is supported at this time.\n"));
-  }
-
-  pipeline = GST_ELEMENT (l->data);
-
-  while ((arg = argv[++i])) {
-    element = g_strdup (arg);
-    property = strchr (element, '.');
-    value = strchr (element, '=');
-
-    if (!(element < property && property < value)) {
-      g_printerr (_("ERROR: could not parse command line argument %d: %s.\n"),
-          i, element);
-      g_free (element);
-      exit (1);
-    }
-
-    *property++ = '\0';
-    *value++ = '\0';
-
-    e = gst_bin_get_by_name (GST_BIN (pipeline), element);
-    if (!e) {
-      g_printerr (_("WARNING: element named '%s' not found.\n"), element);
-    } else {
-      gst_util_set_object_arg (G_OBJECT (e), property, value);
-    }
-    g_free (element);
-  }
-
-  if (!l)
-    return NULL;
-
-  gst_object_ref (pipeline);
-  gst_object_unref (xml);
-  return pipeline;
-}
-#endif
-
 #ifndef DISABLE_FAULT_HANDLER
 #ifndef USE_SIGINFO
 static void
@@ -409,16 +336,18 @@ print_index_stats (GPtrArray * index_stats)
 static gboolean
 gst_is_missing_plugin_message (GstMessage * msg)
 {
-  if (GST_MESSAGE_TYPE (msg) != GST_MESSAGE_ELEMENT || msg->structure == NULL)
+  if (GST_MESSAGE_TYPE (msg) != GST_MESSAGE_ELEMENT
+      || gst_message_get_structure (msg) == NULL)
     return FALSE;
 
-  return gst_structure_has_name (msg->structure, "missing-plugin");
+  return gst_structure_has_name (gst_message_get_structure (msg),
+      "missing-plugin");
 }
 
 static const gchar *
 gst_missing_plugin_message_get_description (GstMessage * msg)
 {
-  return gst_structure_get_string (msg->structure, "name");
+  return gst_structure_get_string (gst_message_get_structure (msg), "name");
 }
 
 static void
@@ -459,10 +388,9 @@ print_tag (const GstTagList * list, const gchar * tag, gpointer unused)
       if (img) {
         gchar *caps_str;
 
-        caps_str = GST_BUFFER_CAPS (img) ?
-            gst_caps_to_string (GST_BUFFER_CAPS (img)) : g_strdup ("unknown");
-        str = g_strdup_printf ("buffer of %u bytes, type: %s",
-            GST_BUFFER_SIZE (img), caps_str);
+        caps_str = g_strdup ("unknown");
+        str = g_strdup_printf ("buffer of %" G_GSIZE_FORMAT " bytes, type: %s",
+            gst_buffer_get_size (img), caps_str);
         g_free (caps_str);
       } else {
         str = g_strdup ("NULL buffer");
@@ -570,33 +498,6 @@ sigint_restore (void)
 
   sigaction (SIGINT, &action, NULL);
 }
-
-/* FIXME 0.11: remove SIGUSR handling (also from man page) */
-static void
-play_handler (int signum)
-{
-  switch (signum) {
-    case SIGUSR1:
-      PRINT ("Caught SIGUSR1 - Play request.\n");
-      gst_element_set_state (pipeline, GST_STATE_PLAYING);
-      break;
-    case SIGUSR2:
-      PRINT ("Caught SIGUSR2 - Stop request.\n");
-      gst_element_set_state (pipeline, GST_STATE_NULL);
-      break;
-  }
-}
-
-static void
-play_signal_setup (void)
-{
-  struct sigaction action;
-
-  memset (&action, 0, sizeof (action));
-  action.sa_handler = play_handler;
-  sigaction (SIGUSR1, &action, NULL);
-  sigaction (SIGUSR2, &action, NULL);
-}
 #endif /* DISABLE_FAULT_HANDLER */
 
 /* returns ELR_ERROR if there was an error
@@ -919,7 +820,6 @@ main (int argc, char *argv[])
   /* options */
   gboolean verbose = FALSE;
   gboolean no_fault = FALSE;
-  gboolean no_sigusr_handler = FALSE;
   gboolean trace = FALSE;
   gboolean eos_on_shutdown = FALSE;
   gboolean check_index = FALSE;
@@ -937,14 +837,8 @@ main (int argc, char *argv[])
         N_("Output messages"), NULL},
     {"exclude", 'X', 0, G_OPTION_ARG_NONE, &exclude_args,
         N_("Do not output status information of TYPE"), N_("TYPE1,TYPE2,...")},
-#if !defined(GST_DISABLE_LOADSAVE) && !defined(GST_REMOVE_DEPRECATED)
-    {"output", 'o', 0, G_OPTION_ARG_STRING, &savefile,
-        N_("Save xml representation of pipeline to FILE and exit"), N_("FILE")},
-#endif
     {"no-fault", 'f', 0, G_OPTION_ARG_NONE, &no_fault,
         N_("Do not install a fault handler"), NULL},
-    {"no-sigusr-handler", '\0', 0, G_OPTION_ARG_NONE, &no_sigusr_handler,
-        N_("Do not install signal handlers for SIGUSR1 and SIGUSR2"), NULL},
     {"trace", 'T', 0, G_OPTION_ARG_NONE, &trace,
         N_("Print alloc trace (if enabled at compile time)"), NULL},
     {"eos-on-shutdown", 'e', 0, G_OPTION_ARG_NONE, &eos_on_shutdown,
@@ -998,9 +892,6 @@ main (int argc, char *argv[])
     fault_setup ();
 
   sigint_setup ();
-
-  if (!no_sigusr_handler)
-    play_signal_setup ();
 #endif
 
   if (trace) {
@@ -1015,15 +906,6 @@ main (int argc, char *argv[])
   /* make a null-terminated version of argv */
   argvn = g_new0 (char *, argc);
   memcpy (argvn, argv + 1, sizeof (char *) * (argc - 1));
-#if !defined(GST_DISABLE_LOADSAVE) && !defined(GST_REMOVE_DEPRECATED)
-  if (strstr (argv[0], "gst-xmllaunch")) {
-    /* FIXME 0.11: remove xmllaunch entirely */
-    g_warning ("gst-xmllaunch is deprecated and broken for all but the most "
-        "simple pipelines. It will most likely be removed in future. Don't "
-        "use it.\n");
-    pipeline = xmllaunch_parse_cmdline ((const gchar **) argvn);
-  } else
-#endif
   {
     pipeline =
         (GstElement *) gst_parse_launchv ((const gchar **) argvn, &error);
@@ -1052,15 +934,6 @@ main (int argc, char *argv[])
     g_signal_connect (pipeline, "deep-notify",
         G_CALLBACK (gst_object_default_deep_notify), exclude_list);
   }
-#if !defined(GST_DISABLE_LOADSAVE) && !defined(GST_REMOVE_DEPRECATED)
-  if (savefile) {
-    g_warning ("Pipeline serialization to XML is deprecated and broken for "
-        "all but the most simple pipelines. It will most likely be removed "
-        "in future. Don't use it.\n");
-
-    gst_xml_write_file (GST_ELEMENT (pipeline), fopen (savefile, "w"));
-  }
-#endif
 
   if (!savefile) {
     GstState state, pending;
diff --git a/tools/gst-run.c b/tools/gst-run.c
deleted file mode 100644 (file)
index ea6103c..0000000
+++ /dev/null
@@ -1,417 +0,0 @@
-/* GStreamer
- * Copyright (C) 2004 Thomas Vander Stichele <thomas@apestaart.org>
- *
- * gst-run.c: tool to launch GStreamer tools with correct major/minor
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-#ifdef HAVE_CONFIG_H
-#  include "config.h"
-#endif
-
-#include <stdlib.h>
-#include <string.h>
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-#include <errno.h>
-#include <glib.h>
-
-/* global statics for option parsing */
-static gboolean _print = FALSE;
-static gchar *_arg_mm = NULL;
-static gboolean _arg_list_mm = FALSE;
-
-/* popt options table for the wrapper */
-static GOptionEntry wrapper_options[] = {
-  {"print", 'p', 0, G_OPTION_ARG_NONE, &_print,
-      "print wrapped command line options", NULL},
-  {"gst-mm", 0, 0, G_OPTION_ARG_STRING, &_arg_mm,
-      "Force major/minor version", "VERSION"},
-  {"gst-list-mm", 0, 0, G_OPTION_ARG_NONE, &_arg_list_mm,
-      "List found major/minor versions", NULL},
-  {NULL}
-};
-
-/* print out the major/minor, which is the hash key */
-static void
-hash_print_key (gchar * key, gchar * value)
-{
-  g_print ("%s\n", (gchar *) key);
-}
-
-/* return value like strcmp, but compares major/minor numerically */
-static gint
-compare_major_minor (const gchar * first, const gchar * second)
-{
-  gchar **firsts, **seconds;
-  gint fmaj, fmin, smaj, smin;
-  gint ret = 0;
-
-  firsts = g_strsplit (first, ".", 0);
-  seconds = g_strsplit (second, ".", 0);
-
-  if (firsts[0] == NULL || firsts[1] == NULL) {
-    ret = -1;
-    goto beach;
-  }
-  if (seconds[0] == NULL || seconds[1] == NULL) {
-    ret = 1;
-    goto beach;
-  }
-
-  fmaj = atoi (firsts[0]);
-  fmin = atoi (firsts[1]);
-  smaj = atoi (seconds[0]);
-  smin = atoi (seconds[1]);
-
-  if (fmaj < smaj) {
-    ret = -1;
-    goto beach;
-  }
-  if (fmaj > smaj) {
-    ret = 1;
-    goto beach;
-  }
-
-  /* fmaj == smaj */
-  if (fmin < smin) {
-    ret = -1;
-    goto beach;
-  }
-  if (fmin > smin) {
-    ret = 1;
-    goto beach;
-  }
-  ret = 0;
-
-beach:
-  g_strfreev (firsts);
-  g_strfreev (seconds);
-  return ret;
-}
-
-static void
-find_highest_version (gchar * key, gchar * value, gchar ** highest)
-{
-  if (*highest == NULL) {
-    /* first value, so just set it */
-    *highest = key;
-  }
-  if (compare_major_minor (key, *highest) > 0)
-    *highest = key;
-}
-
-/* Libtool creates shell scripts named "base" that calls actual binaries as
- * .libs/lt-base.  If we detect this is a libtool script, unmangle so we
- * find the right binaries */
-static void
-unmangle_libtool (gchar ** dir, gchar ** base)
-{
-  gchar *new_dir, *new_base;
-
-  if (!*dir)
-    return;
-  if (!*base)
-    return;
-
-  /* We assume libtool when base starts with "lt-" and dir ends with ".libs".
-   * On Windows libtool doesn't seem to be adding "lt-" prefix. */
-#ifndef G_OS_WIN32
-  if (!g_str_has_prefix (*base, "lt-"))
-    return;
-#endif
-
-  if (!g_str_has_suffix (*dir, ".libs"))
-    return;
-
-#ifndef G_OS_WIN32
-  new_base = g_strdup (&((*base)[3]));
-#else
-  new_base = g_strdup (*base);
-#endif
-  new_dir = g_path_get_dirname (*dir);
-  g_free (*base);
-  g_free (*dir);
-  *base = new_base;
-  *dir = new_dir;
-}
-
-/* Returns a directory path that contains the binary given as an argument.
- * If the binary given contains a path, it gets looked for in that path.
- * If it doesn't contain a path, it gets looked for in the standard path.
- *
- * The returned string is newly allocated.
- */
-static gchar *
-get_dir_of_binary (const gchar * binary)
-{
-  gchar *base, *dir;
-  gchar *full;
-
-  base = g_path_get_basename (binary);
-  dir = g_path_get_dirname (binary);
-
-  /* if putting these two together yields the same as binary,
-   * then we have the right breakup.  If not, it's because no path was
-   * specified which caused get_basename to return "." */
-  full = g_build_filename (dir, base, NULL);
-
-#ifdef G_OS_WIN32
-
-  /* g_build_filename() should be using the last path separator used in the
-   * input according to the docs, but doesn't actually do that, so we have
-   * to fix up the result. */
-  {
-    gchar *tmp;
-
-    for (tmp = (gchar *) binary + strlen (binary) - 1; tmp >= binary; tmp--) {
-      if (*tmp == '/' || *tmp == '\\') {
-        full[strlen (dir)] = *tmp;
-        break;
-      }
-    }
-  }
-#endif
-
-  if (strcmp (full, binary) != 0) {
-    if (strcmp (dir, ".") != 0) {
-      g_warning ("This should not happen, g_path_get_dirname () has changed.");
-      g_free (base);
-      g_free (dir);
-      g_free (full);
-      return NULL;
-    }
-
-    /* we know no path was specified, so search standard path for binary */
-    g_free (full);
-    full = g_find_program_in_path (base);
-    if (!full) {
-      g_warning ("This should not happen, %s not in standard path.", base);
-      g_free (base);
-      g_free (dir);
-      return NULL;
-    }
-  }
-
-  g_free (base);
-  g_free (dir);
-  dir = g_path_get_dirname (full);
-  g_free (full);
-
-  return dir;
-}
-
-/* Search the given directory for candidate binaries matching the base binary.
- * Return a GHashTable of major/minor -> directory pairs
- */
-static GHashTable *
-get_candidates (const gchar * dir, const gchar * base)
-{
-  GDir *gdir;
-  GError *error = NULL;
-  const gchar *entry;
-  gchar *path;
-  gchar *suffix, *copy;
-
-  gchar *pattern;
-  GPatternSpec *spec, *specexe;
-
-  gchar **dirs;
-  gchar **cur;
-
-  GHashTable *candidates = NULL;
-
-  candidates = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
-
-  /* compile our pattern specs */
-  pattern = g_strdup_printf ("%s-*.*", base);
-  spec = g_pattern_spec_new (pattern);
-  g_free (pattern);
-  pattern = g_strdup_printf ("%s-*.*.exe", base);
-  specexe = g_pattern_spec_new (pattern);
-  g_free (pattern);
-
-  /* get all dirs from the path and prepend with given dir */
-  if (dir)
-    path = g_strdup_printf ("%s%c%s",
-        dir, G_SEARCHPATH_SEPARATOR, g_getenv ("PATH"));
-  else
-    path = (gchar *) g_getenv ("PATH");
-  dirs = g_strsplit (path, G_SEARCHPATH_SEPARATOR_S, 0);
-  if (dir)
-    g_free (path);
-
-  /* check all of these in reverse order by winding to bottom and going up  */
-  cur = &dirs[0];
-  while (*cur)
-    ++cur;
-
-  while (cur != &dirs[0]) {
-    --cur;
-    if (!g_file_test (*cur, G_FILE_TEST_EXISTS) ||
-        !g_file_test (*cur, G_FILE_TEST_IS_DIR)) {
-      continue;
-    }
-
-    gdir = g_dir_open (*cur, 0, &error);
-    if (!gdir) {
-      g_warning ("Could not open dir %s: %s", *cur, error->message);
-      g_error_free (error);
-      return NULL;
-    }
-    while ((entry = g_dir_read_name (gdir))) {
-      if (g_pattern_match_string (spec, entry)
-          || g_pattern_match_string (specexe, entry)) {
-        gchar *full;
-
-        /* is it executable ? */
-        full = g_build_filename (*cur, entry, NULL);
-        if (!g_file_test (full, G_FILE_TEST_IS_EXECUTABLE)) {
-          g_free (full);
-          continue;
-        }
-        g_free (full);
-
-        /* strip base and dash from it */
-        suffix = g_strdup (&(entry[strlen (base) + 1]));
-        copy = g_strdup (suffix);
-
-        /* strip possible .exe from copy */
-        if (g_strrstr (copy, ".exe"))
-          g_strrstr (copy, ".exe")[0] = '\0';
-
-        /* stricter pattern check: check if it only contains digits or dots */
-        g_strcanon (copy, "0123456789.", 'X');
-        if (strstr (copy, "X")) {
-          g_free (suffix);
-          g_free (copy);
-          continue;
-        }
-        g_free (copy);
-        g_hash_table_insert (candidates, suffix, g_strdup (*cur));
-      }
-    }
-  }
-
-  g_strfreev (dirs);
-  g_pattern_spec_free (spec);
-  return candidates;
-}
-
-int
-main (int argc, char **argv)
-{
-  GHashTable *candidates;
-  gchar *dir;
-  gchar *base;
-  gchar *highest = NULL;
-  gchar *binary;                /* actual binary we're going to run */
-  gchar *path = NULL;           /* and its path */
-  gchar *desc;
-  GOptionContext *ctx;
-  GError *err = NULL;
-
-  /* detect stuff */
-  dir = get_dir_of_binary (argv[0]);
-  base = g_path_get_basename (argv[0]);
-
-  /* parse command line options */
-  desc = g_strdup_printf ("wrapper to call versioned %s", base);
-  ctx = g_option_context_new (desc);
-  g_free (desc);
-  g_option_context_set_ignore_unknown_options (ctx, TRUE);
-  g_option_context_add_main_entries (ctx, wrapper_options, GETTEXT_PACKAGE);
-  if (!g_option_context_parse (ctx, &argc, &argv, &err)) {
-    g_print ("Error initializing: %s\n", err->message);
-    exit (1);
-  }
-  g_option_context_free (ctx);
-
-  /* unmangle libtool if necessary */
-  unmangle_libtool (&dir, &base);
-
-#ifdef G_OS_WIN32
-  /* remove .exe suffix, otherwise we'll be looking for gst-blah.exe-*.* */
-  if (strlen (base) > 4 && g_str_has_suffix (base, ".exe")) {
-    base[strlen (base) - 4] = '\0';
-  }
-#endif
-
-  /* get all candidate binaries */
-  candidates = get_candidates (dir, base);
-  g_free (dir);
-
-  if (_arg_mm) {
-    /* if a version was forced, look it up in the hash table */
-    dir = g_hash_table_lookup (candidates, _arg_mm);
-    if (!dir) {
-      g_print ("ERROR: Major/minor %s of tool %s not found.\n", _arg_mm, base);
-      return 1;
-    }
-    binary = g_strdup_printf ("%s-%s", base, _arg_mm);
-  } else {
-    highest = NULL;
-
-    /* otherwise, just look up the highest version */
-    if (candidates) {
-      g_hash_table_foreach (candidates, (GHFunc) find_highest_version,
-          &highest);
-    }
-
-    if (highest == NULL) {
-      g_print ("ERROR: No version of tool %s found.\n", base);
-      return 1;
-    }
-    dir = g_hash_table_lookup (candidates, highest);
-    binary = g_strdup_printf ("%s-%s", base, highest);
-  }
-
-  g_free (base);
-
-  path = g_build_filename (dir, binary, NULL);
-  g_free (binary);
-
-  /* print out list of major/minors we found if asked for */
-  /* FIXME: do them in order by creating a GList of keys and sort them */
-  if (_arg_list_mm) {
-    g_hash_table_foreach (candidates, (GHFunc) hash_print_key, NULL);
-    g_hash_table_destroy (candidates);
-    return 0;
-  }
-
-  /* print out command line if asked for */
-  argv[0] = path;
-  if (_print) {
-    int i;
-
-    for (i = 0; i < argc; ++i) {
-      g_print ("%s", argv[i]);
-      if (i < argc - 1)
-        g_print (" ");
-    }
-    g_print ("\n");
-  }
-
-  /* execute */
-  if (execv (path, argv) == -1) {
-    g_warning ("Error executing %s: %s (%d)", path, g_strerror (errno), errno);
-  }
-  g_free (path);
-
-  return 0;
-}
diff --git a/tools/gst-xmlinspect.1.in b/tools/gst-xmlinspect.1.in
deleted file mode 100644 (file)
index 41323a8..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-.TH GStreamer 1 "March 2001"
-.SH "NAME"
-gst\-xmlinspect - print info about a GStreamer plugin or element
-.SH "SYNOPSIS"
-.B  gst\-xmlinspect [OPTION...] [PLUGIN|ELEMENT]
-.SH "DESCRIPTION"
-.PP
-\fIgst\-xmlinspect\fP is a tool that prints out information on
-available \fIGStreamer\fP plugins, information about a particular
-plugin, or information about a particular element.  When executed
-with no PLUGIN or ELEMENT argument, \fIgst\-xmlinspect\fP will print
-a list of all plugins and elements.  When executed with a PLUGIN
-or ELEMENT argument, \fIgst\-xmlinspect\fP will print information
-about that plug-in or element as an XML document.
-.
-.SH "OPTIONS"
-.l
-\fIgst\-xmlinspect\fP accepts the following arguments and options:
-.TP 8
-.B  PLUGIN
-Name of a plugin
-.TP 8
-.B  ELEMENT
-Name of an element
-.TP 8
-.B  \-\-help
-Print help synopsis and available FLAGS
-.TP 8
-.B  \-\-gst\-info\-mask=FLAGS
-\fIGStreamer\fP info flags to set (list with \-\-help)
-.TP 8
-.B  \-\-gst\-debug\-mask=FLAGS
-\fIGStreamer\fP debugging flags to set (list with \-\-help)
-.TP 8
-.B  \-\-gst\-mask=FLAGS
-\fIGStreamer\fP info and debugging flags to set (list with \-\-help)
-.TP 8
-.B  \-\-gst\-plugin\-spew
-\fIGStreamer\fP info flags to set
-Enable printout of errors while loading \fIGStreamer\fP plugins
-.TP 8
-.B  \-\-gst\-plugin\-path=PATH
-Add directories separated with ':' to the plugin search path
-.
-.SH "SEE ALSO"
-.BR gst\-feedback (1),
-.BR gst\-inspect (1),
-.BR gst\-launch (1),
-.BR gst\-typefind (1)
-.SH "AUTHOR"
-The GStreamer team at http://gstreamer.freedesktop.org/
diff --git a/tools/gst-xmlinspect.c b/tools/gst-xmlinspect.c
deleted file mode 100644 (file)
index 4e60807..0000000
+++ /dev/null
@@ -1,683 +0,0 @@
-/* GStreamer gst-xmlinspect
- * Copyright (C) 2003 Wim Taymans <wtay@chello.be>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-
-/* FIXME 0.11: remove gst-xmlinspect and gst-feedback etc. */
-#ifdef HAVE_CONFIG_H
-#  include "config.h"
-#endif
-
-#include <string.h>
-#include <locale.h>
-#include <glib/gprintf.h>
-
-#include "tools.h"
-
-#define PUT_START_TAG(pfx,tag)                                  \
-G_STMT_START{                                                   \
-  g_print ("%*.*s<%s>\n", pfx, pfx, "", tag);                   \
-}G_STMT_END
-
-#define PUT_END_TAG(pfx,tag)                                    \
-G_STMT_START{                                                   \
-  g_print ("%*.*s</%s>\n", pfx, pfx, "", tag);                  \
-}G_STMT_END
-
-#define PUT_ESCAPED(pfx,tag,value)                              \
-G_STMT_START{                                                   \
-  const gchar *toconv = value;                                  \
-  if (value) {                                                  \
-    gchar *v = g_markup_escape_text (toconv, strlen (toconv));  \
-    g_print ("%*.*s<%s>%s</%s>\n", pfx, pfx, "", tag, v, tag);  \
-    g_free (v);                                                 \
-  }                                                             \
-}G_STMT_END
-
-#ifdef G_HAVE_ISO_VARARGS
-
-#define PUT_STRING(pfx, ...)                                    \
-G_STMT_START{                                                   \
-  gchar *ps_val = g_strdup_printf(__VA_ARGS__);                 \
-  g_print ("%*.*s%s\n", pfx, pfx, "", ps_val);                  \
-  g_free(ps_val);                                               \
-}G_STMT_END
-
-#elif defined(G_HAVE_GNUC_VARARGS)
-
-#define PUT_STRING(pfx, str, a...)                              \
-G_STMT_START{                                                   \
-  g_print ("%*.*s"str"\n", pfx, pfx, "" , ##a);                 \
-}G_STMT_END
-
-#else
-
-static inline void
-PUT_STRING (int pfx, const char *format, ...)
-{
-  va_list varargs;
-
-  g_print ("%*.*s", pfx, pfx, "");
-  va_start (varargs, format);
-  g_vprintf (format, varargs);
-  va_end (varargs);
-  g_print ("\n");
-}
-
-#endif
-
-static void
-print_caps (const GstCaps * caps, gint pfx)
-{
-  char *s;
-
-  if (!caps)
-    return;
-
-  s = gst_caps_to_string (caps);
-  PUT_ESCAPED (pfx, "caps", s);
-  g_free (s);
-}
-
-#if 0
-static void
-print_formats (const GstFormat * formats, gint pfx)
-{
-  while (formats && *formats) {
-    const GstFormatDefinition *definition;
-
-    definition = gst_format_get_details (*formats);
-    if (definition)
-      PUT_STRING (pfx, "<format id=\"%d\" nick=\"%s\">%s</format>",
-          *formats, definition->nick, definition->description);
-    else
-      PUT_STRING (pfx, "<format id=\"%d\">unknown</format>", *formats);
-
-    formats++;
-  }
-}
-#endif
-
-static void
-print_query_types (const GstQueryType * types, gint pfx)
-{
-  while (types && *types) {
-    const GstQueryTypeDefinition *definition;
-
-    definition = gst_query_type_get_details (*types);
-    if (definition)
-      PUT_STRING (pfx, "<query-type id=\"%d\" nick=\"%s\">%s</query-type>",
-          *types, definition->nick, definition->description);
-    else
-      PUT_STRING (pfx, "<query-type id=\"%d\">unknown</query-type>", *types);
-
-    types++;
-  }
-}
-
-#if 0
-static void
-print_event_masks (const GstEventMask * masks, gint pfx)
-{
-  GType event_type;
-  GEnumClass *klass;
-  GType event_flags;
-  GFlagsClass *flags_class = NULL;
-
-  event_type = gst_event_type_get_type ();
-  klass = (GEnumClass *) g_type_class_ref (event_type);
-
-  while (masks && masks->type) {
-    GEnumValue *value;
-    gint flags = 0, index = 0;
-
-    switch (masks->type) {
-      case GST_EVENT_SEEK:
-        flags = masks->flags;
-        event_flags = gst_seek_type_get_type ();
-        flags_class = (GFlagsClass *) g_type_class_ref (event_flags);
-        break;
-      default:
-        break;
-    }
-
-    value = g_enum_get_value (klass, masks->type);
-    PUT_STRING (pfx, "<event type=\"%s\">", value->value_nick);
-
-    while (flags) {
-      GFlagsValue *value;
-
-      if (flags & 1) {
-        value = g_flags_get_first_value (flags_class, 1 << index);
-
-        if (value)
-          PUT_ESCAPED (pfx + 1, "flag", value->value_nick);
-        else
-          PUT_ESCAPED (pfx + 1, "flag", "?");
-      }
-      flags >>= 1;
-      index++;
-    }
-    PUT_END_TAG (pfx, "event");
-
-    masks++;
-  }
-}
-#endif
-
-static void
-output_hierarchy (GType type, gint level, gint * maxlevel)
-{
-  GType parent;
-
-  parent = g_type_parent (type);
-
-  *maxlevel = *maxlevel + 1;
-  level++;
-
-  PUT_STRING (level, "<object name=\"%s\">", g_type_name (type));
-
-  if (parent)
-    output_hierarchy (parent, level, maxlevel);
-
-  PUT_END_TAG (level, "object");
-}
-
-static void
-print_element_properties (GstElement * element, gint pfx)
-{
-  GParamSpec **property_specs;
-  guint num_properties;
-  gint i;
-  gboolean readable;
-
-  property_specs = g_object_class_list_properties
-      (G_OBJECT_GET_CLASS (element), &num_properties);
-
-  PUT_START_TAG (pfx, "element-properties");
-
-  for (i = 0; i < num_properties; i++) {
-    GValue value = { 0, };
-    GParamSpec *param = property_specs[i];
-
-    readable = FALSE;
-
-    g_value_init (&value, param->value_type);
-    if (param->flags & G_PARAM_READABLE) {
-      g_object_get_property (G_OBJECT (element), param->name, &value);
-      readable = TRUE;
-    }
-    PUT_START_TAG (pfx + 1, "element-property");
-    PUT_ESCAPED (pfx + 2, "name", g_param_spec_get_name (param));
-    PUT_ESCAPED (pfx + 2, "type", g_type_name (param->value_type));
-    PUT_ESCAPED (pfx + 2, "nick", g_param_spec_get_nick (param));
-    PUT_ESCAPED (pfx + 2, "blurb", g_param_spec_get_blurb (param));
-    if (readable) {
-      PUT_ESCAPED (pfx + 2, "flags", "RW");
-    } else {
-      PUT_ESCAPED (pfx + 2, "flags", "W");
-    }
-
-    switch (G_VALUE_TYPE (&value)) {
-      case G_TYPE_STRING:
-        PUT_ESCAPED (pfx + 2, "default", g_strdup_value_contents (&value));
-        break;
-      case G_TYPE_BOOLEAN:
-        PUT_ESCAPED (pfx + 2, "default", g_strdup_value_contents (&value));
-        break;
-      case G_TYPE_ULONG:
-      {
-        GParamSpecULong *pulong = G_PARAM_SPEC_ULONG (param);
-
-        PUT_STRING (pfx + 2, "<range min=\"%lu\" max=\"%lu\"/>",
-            pulong->minimum, pulong->maximum);
-        PUT_ESCAPED (pfx + 2, "default", g_strdup_value_contents (&value));
-        break;
-      }
-      case G_TYPE_LONG:
-      {
-        GParamSpecLong *plong = G_PARAM_SPEC_LONG (param);
-
-        PUT_STRING (pfx + 2, "<range min=\"%ld\" max=\"%ld\"/>",
-            plong->minimum, plong->maximum);
-        PUT_ESCAPED (pfx + 2, "default", g_strdup_value_contents (&value));
-        break;
-      }
-      case G_TYPE_UINT:
-      {
-        GParamSpecUInt *puint = G_PARAM_SPEC_UINT (param);
-
-        PUT_STRING (pfx + 2, "<range min=\"%u\" max=\"%u\"/>",
-            puint->minimum, puint->maximum);
-        PUT_ESCAPED (pfx + 2, "default", g_strdup_value_contents (&value));
-        break;
-      }
-      case G_TYPE_INT:
-      {
-        GParamSpecInt *pint = G_PARAM_SPEC_INT (param);
-
-        PUT_STRING (pfx + 2, "<range min=\"%d\" max=\"%d\"/>",
-            pint->minimum, pint->maximum);
-        PUT_ESCAPED (pfx + 2, "default", g_strdup_value_contents (&value));
-        break;
-      }
-      case G_TYPE_UINT64:
-      {
-        GParamSpecUInt64 *puint64 = G_PARAM_SPEC_UINT64 (param);
-
-        PUT_STRING (pfx + 2,
-            "<range min=\"%" G_GUINT64_FORMAT "\" max=\"%" G_GUINT64_FORMAT
-            "\"/>", puint64->minimum, puint64->maximum);
-        PUT_ESCAPED (pfx + 2, "default", g_strdup_value_contents (&value));
-        break;
-      }
-      case G_TYPE_INT64:
-      {
-        GParamSpecInt64 *pint64 = G_PARAM_SPEC_INT64 (param);
-
-        PUT_STRING (pfx + 2,
-            "<range min=\"%" G_GINT64_FORMAT "\" max=\"%" G_GINT64_FORMAT
-            "\"/>", pint64->minimum, pint64->maximum);
-        PUT_ESCAPED (pfx + 2, "default", g_strdup_value_contents (&value));
-        break;
-      }
-      case G_TYPE_FLOAT:
-      {
-        GParamSpecFloat *pfloat = G_PARAM_SPEC_FLOAT (param);
-
-        PUT_STRING (pfx + 2, "<range min=\"%f\" max=\"%f\"/>",
-            pfloat->minimum, pfloat->maximum);
-        PUT_ESCAPED (pfx + 2, "default", g_strdup_value_contents (&value));
-        break;
-      }
-      case G_TYPE_DOUBLE:
-      {
-        GParamSpecDouble *pdouble = G_PARAM_SPEC_DOUBLE (param);
-
-        PUT_STRING (pfx + 2, "<range min=\"%g\" max=\"%g\"/>",
-            pdouble->minimum, pdouble->maximum);
-        PUT_ESCAPED (pfx + 2, "default", g_strdup_value_contents (&value));
-        break;
-      }
-      default:
-        if (param->value_type == GST_TYPE_CAPS) {
-          GstCaps *caps = g_value_peek_pointer (&value);
-
-          if (!caps)
-            PUT_ESCAPED (pfx + 2, "default", "NULL");
-          else {
-            print_caps (caps, 2);
-          }
-        } else if (G_IS_PARAM_SPEC_ENUM (param)) {
-          GEnumValue *values;
-          guint j = 0;
-          gint enum_value;
-
-          values = G_ENUM_CLASS (g_type_class_ref (param->value_type))->values;
-          enum_value = g_value_get_enum (&value);
-
-          while (values[j].value_name) {
-            if (values[j].value == enum_value)
-              break;
-            j++;
-          }
-          PUT_STRING (pfx + 2, "<default>%d</default>", values[j].value);
-
-          PUT_START_TAG (pfx + 2, "enum-values");
-          j = 0;
-          while (values[j].value_name) {
-            PUT_STRING (pfx + 3, "<value value=\"%d\" nick=\"%s\"/>",
-                values[j].value, values[j].value_nick);
-            j++;
-          }
-          PUT_END_TAG (pfx + 2, "enum-values");
-        } else if (G_IS_PARAM_SPEC_FLAGS (param)) {
-          GFlagsValue *values;
-          guint j = 0;
-          gint flags_value;
-
-          values = G_FLAGS_CLASS (g_type_class_ref (param->value_type))->values;
-          flags_value = g_value_get_flags (&value);
-
-          PUT_STRING (pfx + 2, "<default>%d</default>", flags_value);
-
-          PUT_START_TAG (pfx + 2, "flags");
-          j = 0;
-          while (values[j].value_name) {
-            PUT_STRING (pfx + 3, "<flag value=\"%d\" nick=\"%s\"/>",
-                values[j].value, values[j].value_nick);
-            j++;
-          }
-          PUT_END_TAG (pfx + 2, "flags");
-        } else if (G_IS_PARAM_SPEC_OBJECT (param)) {
-          PUT_ESCAPED (pfx + 2, "object-type", g_type_name (param->value_type));
-        }
-        break;
-    }
-
-    PUT_END_TAG (pfx + 1, "element-property");
-  }
-  PUT_END_TAG (pfx, "element-properties");
-  g_free (property_specs);
-}
-
-static void
-print_element_signals (GstElement * element, gint pfx)
-{
-  guint *signals;
-  guint nsignals;
-  gint i, k;
-  GSignalQuery *query;
-
-  signals = g_signal_list_ids (G_OBJECT_TYPE (element), &nsignals);
-  for (k = 0; k < 2; k++) {
-    gint counted = 0;
-
-    if (k == 0)
-      PUT_START_TAG (pfx, "element-signals");
-    else
-      PUT_START_TAG (pfx, "element-actions");
-
-    for (i = 0; i < nsignals; i++) {
-      gint n_params;
-      GType return_type;
-      const GType *param_types;
-      gint j;
-
-      query = g_new0 (GSignalQuery, 1);
-      g_signal_query (signals[i], query);
-
-      if ((k == 0 && !(query->signal_flags & G_SIGNAL_ACTION)) ||
-          (k == 1 && (query->signal_flags & G_SIGNAL_ACTION))) {
-        n_params = query->n_params;
-        return_type = query->return_type;
-        param_types = query->param_types;
-
-        PUT_START_TAG (pfx + 1, "signal");
-        PUT_ESCAPED (pfx + 2, "name", query->signal_name);
-        PUT_ESCAPED (pfx + 2, "return-type", g_type_name (return_type));
-        PUT_ESCAPED (pfx + 2, "object-type",
-            g_type_name (G_OBJECT_TYPE (element)));
-
-        PUT_START_TAG (pfx + 2, "params");
-        for (j = 0; j < n_params; j++) {
-          PUT_ESCAPED (pfx + 3, "type", g_type_name (param_types[j]));
-        }
-
-        PUT_END_TAG (pfx + 2, "params");
-
-        PUT_END_TAG (pfx + 1, "signal");
-
-        counted++;
-      }
-
-      g_free (query);
-    }
-    if (k == 0)
-      PUT_END_TAG (pfx, "element-signals");
-    else
-      PUT_END_TAG (pfx, "element-actions");
-  }
-}
-
-static gint
-print_element_info (GstElementFactory * factory)
-{
-  GstElement *element;
-  GstObjectClass *gstobject_class;
-  GstElementClass *gstelement_class;
-  GList *pads;
-  GstPad *pad;
-  GstStaticPadTemplate *padtemplate;
-  gint maxlevel = 0;
-
-  element = gst_element_factory_create (factory, "element");
-  if (!element) {
-    g_print ("couldn't construct element for some reason\n");
-    return -1;
-  }
-  PUT_START_TAG (0, "element");
-  PUT_ESCAPED (1, "name", GST_PLUGIN_FEATURE_NAME (factory));
-
-  gstobject_class = GST_OBJECT_CLASS (G_OBJECT_GET_CLASS (element));
-  gstelement_class = GST_ELEMENT_CLASS (G_OBJECT_GET_CLASS (element));
-
-  PUT_START_TAG (1, "details");
-  PUT_ESCAPED (2, "long-name", factory->details.longname);
-  PUT_ESCAPED (2, "class", factory->details.klass);
-  PUT_ESCAPED (2, "description", factory->details.description);
-  PUT_ESCAPED (2, "authors", factory->details.author);
-  PUT_END_TAG (1, "details");
-
-  output_hierarchy (G_OBJECT_TYPE (element), 0, &maxlevel);
-
-  PUT_START_TAG (1, "pad-templates");
-  if (factory->numpadtemplates) {
-    pads = factory->staticpadtemplates;
-    while (pads) {
-      padtemplate = (GstStaticPadTemplate *) (pads->data);
-      pads = g_list_next (pads);
-
-      PUT_START_TAG (2, "pad-template");
-      PUT_ESCAPED (3, "name", padtemplate->name_template);
-
-      if (padtemplate->direction == GST_PAD_SRC)
-        PUT_ESCAPED (3, "direction", "src");
-      else if (padtemplate->direction == GST_PAD_SINK)
-        PUT_ESCAPED (3, "direction", "sink");
-      else
-        PUT_ESCAPED (3, "direction", "unknown");
-
-      if (padtemplate->presence == GST_PAD_ALWAYS)
-        PUT_ESCAPED (3, "presence", "always");
-      else if (padtemplate->presence == GST_PAD_SOMETIMES)
-        PUT_ESCAPED (3, "presence", "sometimes");
-      else if (padtemplate->presence == GST_PAD_REQUEST) {
-        PUT_ESCAPED (3, "presence", "request");
-        PUT_ESCAPED (3, "request-function",
-            GST_DEBUG_FUNCPTR_NAME (gstelement_class->request_new_pad));
-      } else
-        PUT_ESCAPED (3, "presence", "unknown");
-
-      if (padtemplate->static_caps.string) {
-        print_caps (gst_static_caps_get (&padtemplate->static_caps), 3);
-      }
-      PUT_END_TAG (2, "pad-template");
-    }
-  }
-  PUT_END_TAG (1, "pad-templates");
-
-  PUT_START_TAG (1, "element-flags");
-  PUT_END_TAG (1, "element-flags");
-
-  if (GST_IS_BIN (element)) {
-    PUT_START_TAG (1, "bin-flags");
-
-    PUT_END_TAG (1, "bin-flags");
-  }
-
-
-  PUT_START_TAG (1, "element-implementation");
-
-  PUT_STRING (2, "<state-change function=\"%s\"/>",
-      GST_DEBUG_FUNCPTR_NAME (gstelement_class->change_state));
-
-#ifndef GST_DISABLE_LOADSAVE
-  PUT_STRING (2, "<save function=\"%s\"/>",
-      GST_DEBUG_FUNCPTR_NAME (gstobject_class->save_thyself));
-  PUT_STRING (2, "<load function=\"%s\"/>",
-      GST_DEBUG_FUNCPTR_NAME (gstobject_class->restore_thyself));
-#endif
-  PUT_END_TAG (1, "element-implementation");
-
-  PUT_START_TAG (1, "clocking-interaction");
-  if (gst_element_requires_clock (element)) {
-    PUT_STRING (2, "<requires-clock/>");
-  }
-  if (gst_element_provides_clock (element)) {
-    GstClock *clock;
-
-    clock = gst_element_get_clock (element);
-    if (clock)
-      PUT_STRING (2, "<provides-clock name=\"%s\"/>", GST_OBJECT_NAME (clock));
-  }
-  PUT_END_TAG (1, "clocking-interaction");
-
-  if (gst_element_is_indexable (element)) {
-    PUT_STRING (1, "<indexing-capabilities/>");
-  }
-
-  PUT_START_TAG (1, "pads");
-  if (element->numpads) {
-    const GList *pads;
-
-    pads = element->pads;
-    while (pads) {
-      pad = GST_PAD (pads->data);
-      pads = g_list_next (pads);
-
-      PUT_START_TAG (2, "pad");
-      PUT_ESCAPED (3, "name", gst_pad_get_name (pad));
-
-      if (gst_pad_get_direction (pad) == GST_PAD_SRC)
-        PUT_ESCAPED (3, "direction", "src");
-      else if (gst_pad_get_direction (pad) == GST_PAD_SINK)
-        PUT_ESCAPED (3, "direction", "sink");
-      else
-        PUT_ESCAPED (3, "direction", "unknown");
-
-      if (pad->padtemplate)
-        PUT_ESCAPED (3, "template", pad->padtemplate->name_template);
-
-      PUT_START_TAG (3, "implementation");
-      if (pad->chainfunc)
-        PUT_STRING (4, "<chain-based function=\"%s\"/>",
-            GST_DEBUG_FUNCPTR_NAME (pad->chainfunc));
-      if (pad->getrangefunc)
-        PUT_STRING (4, "<get-range-based function=\"%s\"/>",
-            GST_DEBUG_FUNCPTR_NAME (pad->getrangefunc));
-      if (pad->eventfunc != gst_pad_event_default)
-        PUT_STRING (4, "<event-function function=\"%s\"/>",
-            GST_DEBUG_FUNCPTR_NAME (pad->eventfunc));
-      if (pad->queryfunc != gst_pad_query_default)
-        PUT_STRING (4, "<query-function function=\"%s\"/>",
-            GST_DEBUG_FUNCPTR_NAME (pad->queryfunc));
-      if (pad->querytypefunc != gst_pad_get_query_types_default) {
-        PUT_STRING (4, "<query-type-func function=\"%s\">",
-            GST_DEBUG_FUNCPTR_NAME (pad->querytypefunc));
-        print_query_types (gst_pad_get_query_types (pad), 5);
-        PUT_END_TAG (4, "query-type-func");
-      }
-
-      if (pad->iterintlinkfunc != gst_pad_iterate_internal_links_default)
-        PUT_STRING (4, "<iterintlink-function function=\"%s\"/>",
-            GST_DEBUG_FUNCPTR_NAME (pad->iterintlinkfunc));
-
-      if (pad->bufferallocfunc)
-        PUT_STRING (4, "<bufferalloc-function function=\"%s\"/>",
-            GST_DEBUG_FUNCPTR_NAME (pad->bufferallocfunc));
-      PUT_END_TAG (3, "implementation");
-
-      if (pad->caps) {
-        print_caps (pad->caps, 3);
-      }
-      PUT_END_TAG (2, "pad");
-    }
-  }
-  PUT_END_TAG (1, "pads");
-
-  print_element_properties (element, 1);
-  print_element_signals (element, 1);
-
-  /* for compound elements */
-  /* FIXME: gst_bin_get_list does not exist anymore
-     if (GST_IS_BIN (element)) {
-     GList *children;
-     GstElement *child;
-     PUT_START_TAG (1, "children");
-     children = (GList *) gst_bin_get_list (GST_BIN (element));
-     while (children) {
-     child = GST_ELEMENT (children->data);
-     children = g_list_next (children);
-
-     PUT_ESCAPED (2, "child", GST_ELEMENT_NAME (child));
-     }
-     PUT_END_TAG (1, "children");
-     }
-   */
-  PUT_END_TAG (0, "element");
-
-  return 0;
-}
-
-int
-main (int argc, char *argv[])
-{
-  GstElementFactory *factory;
-  GOptionEntry options[] = {
-    GST_TOOLS_GOPTION_VERSION,
-    {NULL}
-  };
-  GOptionContext *ctx;
-  GError *err = NULL;
-
-  setlocale (LC_ALL, "");
-
-  g_thread_init (NULL);
-
-  gst_tools_set_prgname ("gst-xmlinspect");
-
-  ctx = g_option_context_new ("[ELEMENT-NAME]");
-  g_option_context_add_main_entries (ctx, options, GETTEXT_PACKAGE);
-  g_option_context_add_group (ctx, gst_init_get_option_group ());
-  if (!g_option_context_parse (ctx, &argc, &argv, &err)) {
-    g_print ("Error initializing: %s\n", err->message);
-    exit (1);
-  }
-  g_option_context_free (ctx);
-
-  gst_tools_print_version ("gst-xmlinspect");
-
-  /* if no arguments, print out all elements */
-  if (argc == 1) {
-    GList *features, *f;
-
-    features = gst_registry_get_feature_list (gst_registry_get_default (),
-        GST_TYPE_ELEMENT_FACTORY);
-
-    PUT_STRING (0, "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>");
-
-    for (f = features; f != NULL; f = f->next)
-      print_element_info (GST_ELEMENT_FACTORY (f->data));
-
-    gst_plugin_feature_list_free (features);
-    return 0;
-  }
-
-  /* else we try to get a factory */
-  factory = gst_element_factory_find (argv[1]);
-
-  /* if there's a factory, print out the info */
-  if (factory) {
-    PUT_STRING (0, "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>");
-    return print_element_info (factory);
-  }
-
-  /* otherwise, error out */
-  g_printerr ("no such element '%s'\n", argv[1]);
-  return -1;
-}
diff --git a/tools/gst-xmllaunch.1.in b/tools/gst-xmllaunch.1.in
deleted file mode 100644 (file)
index 9bf9012..0000000
+++ /dev/null
@@ -1,69 +0,0 @@
-.TH "GStreamer" "1" "March 2001"
-.SH "NAME"
-gst\-xmllaunch \- build and run a GStreamer pipeline from an XML serialization
-.SH "SYNOPSIS"
-\fBgst\-xmllaunch\fR \fI[OPTION...]\fR XML\-FILE [ ELEMENT.PROPERTY=VALUE ... ]
-.SH "DESCRIPTION"
-.LP 
-\fIgst\-xmllaunch\fP is a tool that is used to build and run a basic
-\fIGStreamer\fP pipeline, loading it from an XML description. You can
-produce the XML description using gst-launch(1) with the -o option or by
-calling gst_xml_write_file() in your own app.
-
-A simple commandline looks like:
-
- gst\-xmllaunch my\-pipeline.xml filesrc0.location=music.mp3
-
-This sets the location property of the element named filesrc0 to the value
-"music.mp3". See gst\-launch(1) for syntax on setting element names, and
-gst\-inspect to see what properties various elements have.
-
-You can pass "-" as the XML\-FILE to read from stdin.
-
-XML\-FILE can be a URI as well, thanks to the wizardry of libxml. I'm not really
-sure what all is supported, it seems http works just fine though.
-
-.
-.SH "WARNING"
-\fIgst\-xmllaunch\fP is deprecated and broken for all but the most simple
-pipelines. It will most likely be removed in future. Don't use it.
-.
-.SH "OPTIONS"
-.l
-\fIgst\-xmllaunch\fP accepts the following options:
-.TP 8
-.B  \-\-help
-Print help synopsis and available FLAGS
-.TP 8
-.B  \-\-silent
-Do not output status information
-.TP 8
-.B  \-\-exclude=TYPE, \-XTYPE
-Do not output status information of TYPE
-.TP 8
-.B  \-\-output=FILE, \-oFILE
-Save XML representation of pipeline to FILE and exit
-.TP 8
-.B  \-\-gst\-info\-mask=FLAGS
-\fIGStreamer\fP info flags to set (list with \-\-help)
-.TP 8
-.B  \-\-gst\-debug\-mask=FLAGS
-\fIGStreamer\fP debugging flags to set (list with \-\-help)
-.TP 8
-.B  \-\-gst\-mask=FLAGS
-\fIGStreamer\fP info and debugging flags to set (list with \-\-help)
-.TP 8
-.B  \-\-gst\-plugin\-spew
-\fIGStreamer\fP info flags to set
-Enable printout of errors while loading \fIGStreamer\fP plugins
-.TP 8
-.B  \-\-gst\-plugin\-path=PATH
-Add directories separated with ':' to the plugin search path
-.
-.SH "SEE ALSO"
-.BR gst\-feedback (1),
-.BR gst\-inspect (1),
-.BR gst\-launch (1),
-.BR gst\-typefind (1)
-.SH "AUTHOR"
-The GStreamer team at http://gstreamer.freedesktop.org/
index 8770bd4..d85e49c 100644 (file)
@@ -6,8 +6,8 @@ _gst_launch()
 {
   local cur
 
-  : ${GST_REGISTRY:=~/.gstreamer-0.10/registry.xml}
-  : ${GST_COMPLETE:=~/.gstreamer-0.10/complete}
+  : ${GST_REGISTRY:=~/.gstreamer-0.11/registry.xml}
+  : ${GST_COMPLETE:=~/.gstreamer-0.11/complete}
 
   if [ ! -f "${GST_REGISTRY}" ] ; then
     return 0
diff --git a/tools/xml2text.xsl b/tools/xml2text.xsl
deleted file mode 100644 (file)
index 6797ee5..0000000
+++ /dev/null
@@ -1,456 +0,0 @@
-<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
-
- <xsl:output method="text" encoding="us-ascii" omit-xml-declaration="yes" indent="no"/>
- <xsl:variable name="padding" select="string('                              ')"/>
-
- <xsl:template match="/element">
-  <xsl:apply-templates select="name"/>
-  <xsl:apply-templates select="details"/>
-  <xsl:apply-templates select="object"/>
-  <xsl:apply-templates select="pad-templates"/>
-  <xsl:apply-templates select="element-flags"/>
-  <xsl:apply-templates select="element-implementation"/>
-  <xsl:apply-templates select="clocking-interaction"/>
-  <xsl:apply-templates select="indexing-capabilities"/>
-  <xsl:apply-templates select="pads"/>
-  <xsl:apply-templates select="element-properties"/>
-  <xsl:apply-templates select="dyn-params"/>
-  <xsl:apply-templates select="element-signals"/>
-  <xsl:apply-templates select="element-actions"/>
- </xsl:template>
-
- <xsl:template match="name">
-  <xsl:text>Element Name: </xsl:text><xsl:value-of select="."/>
-  <xsl:text>&#10;&#10;</xsl:text>
- </xsl:template>
-
- <xsl:template match="details">
-  <xsl:text>Factory Details:&#10;</xsl:text> 
-  <xsl:text>  Long Name:&#9;</xsl:text>   <xsl:value-of select="long-name"/>   <xsl:text>&#10;</xsl:text>
-  <xsl:text>  Class:&#9;</xsl:text>       <xsl:value-of select="class"/>       <xsl:text>&#10;</xsl:text>
-  <xsl:text>  License:&#9;</xsl:text>     <xsl:value-of select="license"/>     <xsl:text>&#10;</xsl:text>
-  <xsl:text>  Description:&#9;</xsl:text> <xsl:value-of select="description"/> <xsl:text>&#10;</xsl:text>
-  <xsl:text>  Version:&#9;</xsl:text>     <xsl:value-of select="version"/>     <xsl:text>&#10;</xsl:text>
-  <xsl:text>  Author(s):&#9;</xsl:text>   <xsl:value-of select="authors"/>     <xsl:text>&#10;</xsl:text>
-  <xsl:text>  Copyright:&#9;</xsl:text>   <xsl:value-of select="copyright"/>   <xsl:text>&#10;</xsl:text>
-  <xsl:text>&#10;</xsl:text>
- </xsl:template>
-
- <xsl:template name="object">
-  <xsl:param name="i"/>
-  <xsl:param name="j"/>
-  <xsl:if test="count($i/*) &gt; 0">
-   <xsl:call-template name="object">
-    <xsl:with-param name="i" select="$i/object"/>
-    <xsl:with-param name="j" select="$j - 1"/>
-   </xsl:call-template>
-   <xsl:value-of select="substring ($padding, 1, $j * 6)"/> 
-   <xsl:text> +----</xsl:text>
-  </xsl:if>
-  <xsl:value-of select="$i/@name"/> 
-  <xsl:text>&#10;</xsl:text>
- </xsl:template>
-
- <xsl:template match="object">
-  <xsl:call-template name="object">
-   <xsl:with-param name="i" select="."/>
-   <xsl:with-param name="j" select="count(.//object[(*)])"/>
-  </xsl:call-template>
-  <xsl:text>&#10;</xsl:text>
- </xsl:template>
-
- <xsl:template match="pad-templates">
-  <xsl:text>Pad Templates&#10;</xsl:text>
-  <xsl:apply-templates select="./pad-template"/>
- </xsl:template>
-
- <xsl:template match="pad-template">
-  <xsl:text>  </xsl:text>
-  <xsl:value-of select="direction"/> 
-  <xsl:text> template: </xsl:text>
-  <xsl:value-of select="name"/>
-  <xsl:text>&#10;</xsl:text>
-  <xsl:text>    Availability: </xsl:text> <xsl:value-of select="presence"/>
-  <xsl:text>&#10;</xsl:text>
-  <xsl:text>    Capabilities:&#10; </xsl:text> <xsl:apply-templates select="./capscomp"/>
- </xsl:template>
-
- <xsl:template match="capscomp">
-  <xsl:apply-templates select="./caps"/>
-  <xsl:text>&#10;</xsl:text>
- </xsl:template>
-
- <xsl:template match="caps">
-  <xsl:text>     '</xsl:text>
-  <xsl:value-of select="name"/>
-  <xsl:text>'&#10;</xsl:text>
-  <xsl:text>        MIME type: </xsl:text>
-  <xsl:value-of select="type"/>
-  <xsl:text>'&#10;</xsl:text>
-  <xsl:apply-templates select="./properties"/>
- </xsl:template>
-
- <xsl:template match="properties">
-  <xsl:apply-templates select="*"/>
- </xsl:template>
-
- <xsl:template match="list">
-  <xsl:text>        </xsl:text>
-  <xsl:value-of select="@name"/>
-  <xsl:text>&#9;:List&#10;</xsl:text>
-  <xsl:apply-templates select="*" mode="list"/>
- </xsl:template>
-
- <!-- propety entries in list mode -->
- <xsl:template match="string" mode="list">
-  <xsl:text>         String: '</xsl:text>
-  <xsl:value-of select="@value"/>
-  <xsl:text>'&#10;</xsl:text>
- </xsl:template>
- <xsl:template match="fourcc" mode="list">
-  <xsl:text>         FourCC: '</xsl:text>
-  <xsl:value-of select="@hexvalue"/>
-  <xsl:text>'&#10;</xsl:text>
- </xsl:template>
-
- <xsl:template match="int" mode="list">
-  <xsl:text>         Integer: </xsl:text>
-  <xsl:value-of select="@value"/>
-  <xsl:text>&#10;</xsl:text>
- </xsl:template>
-
- <xsl:template match="range" mode="list">
-  <xsl:text>         Integer range: </xsl:text>
-  <xsl:value-of select="concat(@min, ' - ', @max)"/> 
-  <xsl:text>&#10;</xsl:text>
- </xsl:template>
-
- <xsl:template match="float" mode="list">
-  <xsl:text>         Float: </xsl:text>
-  <xsl:value-of select="@value"/>
-  <xsl:text>&#10;</xsl:text>
- </xsl:template>
-
- <xsl:template match="floatrange" mode="list">
-  <xsl:text>         Float range: </xsl:text>
-  <xsl:value-of select="concat(@min, ' - ', @max)"/> 
-  <xsl:text>&#10;</xsl:text>
- </xsl:template>
-
- <!-- propety entries in normal mode -->
- <xsl:template match="string">
-  <xsl:text>         </xsl:text>
-  <xsl:value-of select="substring (concat (@name, $padding), 1, 15)"/>
-  <xsl:text>     : String: '</xsl:text>
-  <xsl:value-of select="@value"/> 
-  <xsl:text>'&#10;</xsl:text>
- </xsl:template>
-
- <xsl:template match="fourcc">
-  <xsl:text>         </xsl:text>
-  <xsl:value-of select="substring (concat (@name, $padding), 1, 15)"/>
-  <xsl:text>     : FourCC: '</xsl:text>
-  <xsl:value-of select="@hexvalue"/> 
-  <xsl:text>'&#10;</xsl:text>
- </xsl:template>
-
- <xsl:template match="int">
-  <xsl:text>         </xsl:text>
-  <xsl:value-of select="substring (concat (@name, $padding), 1, 15)"/>
-  <xsl:text>     : Integer: </xsl:text>
-  <xsl:value-of select="@value"/> 
-  <xsl:text>&#10;</xsl:text>
- </xsl:template>
-
- <xsl:template match="range">          
-  <xsl:text>         </xsl:text>
-  <xsl:value-of select="substring (concat (@name, $padding), 1, 15)"/>
-  <xsl:text>     : Integer range: </xsl:text>
-  <xsl:value-of select="concat(@min, ' - ', @max)"/> 
-  <xsl:text>&#10;</xsl:text>
- </xsl:template>
-
- <xsl:template match="float">
-  <xsl:text>         </xsl:text>
-  <xsl:value-of select="substring (concat (@name, $padding), 1, 15)"/>
-  <xsl:text>     : Float: </xsl:text>
-  <xsl:value-of select="@value"/> 
-  <xsl:text>&#10;</xsl:text>
- </xsl:template>
-
- <xsl:template match="floatrange">             
-  <xsl:text>         </xsl:text>
-  <xsl:value-of select="substring (concat (@name, $padding), 1, 15)"/>
-  <xsl:text>     : Float range: </xsl:text>
-  <xsl:value-of select="concat(@min, ' - ', @max)"/> 
-  <xsl:text>&#10;</xsl:text>
- </xsl:template>
-
- <xsl:template match="flag">
-  <xsl:text>  </xsl:text>
-  <xsl:value-of select="."/>
-  <xsl:text>&#10;</xsl:text>
- </xsl:template>
-
- <xsl:template match="element-flags">
-  <xsl:text>Element Flags:&#10;</xsl:text>
-  <xsl:apply-templates select="./flag"/>
-  <xsl:text>&#10;</xsl:text>
- </xsl:template>
-
- <xsl:template match="state-change">
-  <xsl:text>  Has change_state() function: </xsl:text>
-  <xsl:value-of select="@function"/>
-  <xsl:text>&#10;</xsl:text>
- </xsl:template>
-
- <xsl:template match="load">
-  <xsl:text>  Has custom restore_thyself() function: </xsl:text>
-  <xsl:value-of select="@function"/>
-  <xsl:text>&#10;</xsl:text>
- </xsl:template>
-
- <xsl:template match="save">
-  <xsl:text>  Has custom save_thyself() function: </xsl:text>
-  <xsl:value-of select="@function"/>
-  <xsl:text>&#10;</xsl:text>
- </xsl:template>
-
- <xsl:template match="element-implementation">
-  <xsl:text>Element Implementation:&#10;</xsl:text>
-  <xsl:apply-templates select="*"/>
-  <xsl:text>&#10;</xsl:text>
- </xsl:template>
-
- <xsl:template match="requires-clock">
-  <xsl:text>   element requires a clock&#10;</xsl:text>
- </xsl:template>
-
- <xsl:template match="provides-clock">
-  <xsl:text>   element provides a clock: </xsl:text>
-  <xsl:value-of select="@name"/>
-  <xsl:text>&#10;</xsl:text>
- </xsl:template>
-
- <xsl:template match="clocking-interaction">
-  <xsl:text>Clocking Interaction:&#10;</xsl:text>
-  <xsl:choose>
-   <xsl:when test="count(*) = 0">
-    <xsl:text>  none&#10;</xsl:text>
-   </xsl:when>
-   <xsl:otherwise>
-    <xsl:apply-templates select="*"/>
-   </xsl:otherwise>
-  </xsl:choose>
-  <xsl:text>&#10;</xsl:text>
- </xsl:template>
-
- <xsl:template match="indexing-capabilities">
-  <xsl:text>   element can do indexing</xsl:text>
- </xsl:template>
-
- <xsl:template match="dyn-params">
-  <xsl:text>Dynamic Parameters:&#10;</xsl:text>
-  <xsl:choose>
-   <xsl:when test="count(*) = 0">
-    <xsl:text>  none&#10;</xsl:text>
-   </xsl:when>
-   <xsl:otherwise>
-    <xsl:apply-templates select="dyn-param"/>
-   </xsl:otherwise>
-  </xsl:choose>
-  <xsl:text>&#10;</xsl:text>
- </xsl:template>
-
- <xsl:template match="pads">
-  <xsl:text>Pads:&#10;</xsl:text>
-  <xsl:apply-templates select="pad"/>
-  <xsl:text>&#10;</xsl:text>
- </xsl:template>
-
- <xsl:template match="pad">
-  <xsl:text>  </xsl:text>
-  <xsl:value-of select="direction"/> 
-  <xsl:text>: '</xsl:text>
-  <xsl:value-of select="name"/>
-  <xsl:text>'&#10;</xsl:text>
-  <xsl:apply-templates select="implementation"/>
-  <xsl:text>    Pad Template: '</xsl:text>
-  <xsl:value-of select="template"/>
-  <xsl:text>'&#10;</xsl:text>
- </xsl:template>
-
- <xsl:template match="implementation">
-  <xsl:text>    Implementation:&#10;</xsl:text>
-  <xsl:apply-templates select="*"/>
- </xsl:template>
-
- <xsl:template match="chain-based">
-  <xsl:text>      Has chainfunc(): </xsl:text>
-  <xsl:value-of select="@function"/>
-  <xsl:text>&#10;</xsl:text>
- </xsl:template>
-
- <xsl:template match="bufferpool-function">
-  <xsl:text>      Has bufferpoolfunc(): </xsl:text>
-  <xsl:value-of select="@function"/>
-  <xsl:text>&#10;</xsl:text>
- </xsl:template>
-
- <xsl:template match="format">
-  <xsl:text>                (</xsl:text>
-  <xsl:value-of select="@id"/>
-  <xsl:text>)&#9;</xsl:text>
-  <xsl:value-of select="@nick"/>
-  <xsl:text> (</xsl:text>
-  <xsl:value-of select="."/>
-  <xsl:text>)&#10;</xsl:text>
- </xsl:template>
-
- <xsl:template match="formats-function">
-  <xsl:text>      Supports seeking/conversion/query formats: </xsl:text>
-  <xsl:value-of select="@function"/>
-  <xsl:text>&#10;</xsl:text>
-  <xsl:apply-templates select="format"/>
- </xsl:template>
-
- <xsl:template match="convert-function">
-  <xsl:text>      Has custom convertfunc(): </xsl:text>
-  <xsl:value-of select="@function"/>
-  <xsl:text>&#10;</xsl:text>
- </xsl:template>
-
- <xsl:template match="query-function">
-  <xsl:text>      Has custom queryfunc(): </xsl:text>
-  <xsl:value-of select="@function"/>
-  <xsl:text>&#10;</xsl:text>
- </xsl:template>
-
- <xsl:template match="event-function">
-  <xsl:text>      Has custom eventfunc(): </xsl:text>
-  <xsl:value-of select="@function"/>
-  <xsl:text>&#10;</xsl:text>
- </xsl:template>
-
- <xsl:template match="event">
-  <xsl:text>                </xsl:text>
-  <xsl:value-of select="@type"/>
-  <xsl:for-each select="flag">
-   <xsl:text> | </xsl:text>
-   <xsl:value-of select='.'/>
-  </xsl:for-each>
-  <xsl:text>&#10;</xsl:text>
- </xsl:template>
-
- <xsl:template match="event-mask-func">
-  <xsl:text>        Provides event masks: </xsl:text>
-  <xsl:value-of select="@function"/>
-  <xsl:text>&#10;</xsl:text>
-  <xsl:apply-templates select="event"/>
- </xsl:template>
-
- <xsl:template match="query-type">
-  <xsl:text>                (</xsl:text>
-  <xsl:value-of select="@id"/>
-  <xsl:text>)&#9;</xsl:text>
-  <xsl:value-of select="@nick"/>
-  <xsl:text> (</xsl:text>
-  <xsl:value-of select="."/>
-  <xsl:text>)&#10;</xsl:text>
- </xsl:template>
-
- <xsl:template match="query-type-func">
-  <xsl:text>        Provides query types: </xsl:text>
-  <xsl:value-of select="@function"/>
-  <xsl:text>&#10;</xsl:text>
-  <xsl:apply-templates select="query-type"/>
- </xsl:template>
-
- <xsl:template match="element-properties">
-  <xsl:text>Element Arguments:&#10;</xsl:text>
-  <xsl:apply-templates select="element-property"/>
-  <xsl:text>&#10;</xsl:text>
- </xsl:template>
-
- <xsl:template match="default">
-  <xsl:text>. (Default </xsl:text>
-  <xsl:value-of select="."/>
-  <xsl:text>)</xsl:text>
-  <xsl:text>&#10;</xsl:text>
- </xsl:template>
-
- <xsl:template match="range" mode="params">
-  <xsl:value-of select="substring ($padding, 1, 25)"/>
-  <xsl:text>Range : </xsl:text>
-  <xsl:value-of select="concat(@min, ' - ', @max)"/> 
-  <xsl:text>&#10;</xsl:text>
- </xsl:template>
-
- <xsl:template match="element-property|dyn-param">
-  <xsl:text>  </xsl:text>
-  <xsl:value-of select="substring (concat(name, $padding), 1, 20)"/>
-  <xsl:text> : </xsl:text>
-  <xsl:value-of select="blurb"/>
-  <xsl:text>&#10;</xsl:text>
-  <xsl:value-of select="substring ($padding, 1, 25)"/>
-  <xsl:value-of select="type"/>
-  <xsl:apply-templates select="default"/>
-  <xsl:apply-templates select="range" mode="params"/>
- </xsl:template>
-
- <xsl:template match="params">
-  <xsl:for-each select="type">
-   <xsl:text>,&#10;</xsl:text>
-   <xsl:value-of select="substring ($padding, 1, 25)"/>
-   <xsl:value-of select="substring ($padding, 1, 20)"/>
-   <xsl:value-of select="."/>
-   <xsl:text> arg</xsl:text>
-   <xsl:value-of select="position()"/>
-  </xsl:for-each>
- </xsl:template>
-
- <xsl:template match="signal">
-  <xsl:value-of select="substring (concat('&quot;', name, '&quot;', $padding), 1, 25)"/>
-  <xsl:value-of select="return-type"/>
-  <xsl:text> user_function </xsl:text>
-  <xsl:value-of select="concat ('(', object-type, '* object')"/>
-  <xsl:apply-templates select="params"/>
- </xsl:template>
- <xsl:template match="element-signals">
-  <xsl:text>Element Signals:&#10;</xsl:text>
-  <xsl:choose>
-   <xsl:when test="count(*) = 0">
-    <xsl:text>  none&#10;</xsl:text>
-   </xsl:when>
-   <xsl:otherwise>
-    <xsl:for-each select="signal">
-     <xsl:apply-templates select="."/>
-     <xsl:text>,&#10;</xsl:text>
-     <xsl:value-of select="substring ($padding, 1, 25)"/>
-     <xsl:value-of select="substring ($padding, 1, 20)"/>
-     <xsl:text>gpointer user_data);&#10;</xsl:text>
-    </xsl:for-each>
-   </xsl:otherwise>
-  </xsl:choose>
-  <xsl:text>&#10;</xsl:text>
- </xsl:template>
-
- <xsl:template match="element-actions">
-  <xsl:text>Element Actions:&#10;</xsl:text>
-  <xsl:choose>
-   <xsl:when test="count(*) = 0">
-    <xsl:text>  none&#10;</xsl:text>
-   </xsl:when>
-   <xsl:otherwise>
-    <xsl:for-each select="signal">
-     <xsl:apply-templates select="."/>
-     <xsl:text>);&#10;</xsl:text>
-    </xsl:for-each>
-   </xsl:otherwise>
-  </xsl:choose>
-  <xsl:text>&#10;</xsl:text>
- </xsl:template>
-
-</xsl:stylesheet>
index 74e6fc4..e12c4c3 100644 (file)
@@ -26,7 +26,7 @@
 #undef ENABLE_SUBUNIT
 
 /* gettext package name */
-#define GETTEXT_PACKAGE "gstreamer-0.10"
+#define GETTEXT_PACKAGE "gstreamer-0.11"
 
 /* data dir */
 #define GST_DATADIR PREFIX "\\share"
@@ -56,7 +56,7 @@
 #define GST_LICENSE "LGPL"
 
 /* library major.minor version */
-#define GST_MAJORMINOR "0.10"
+#define GST_MAJORMINOR "0.11"
 
 /* package name in plugins */
 #define GST_PACKAGE_NAME "GStreamer git"
@@ -65,7 +65,7 @@
 #define GST_PACKAGE_ORIGIN "Unknown package origin"
 
 /* GStreamer package release date/time for plugins as YYYY-MM-DD */
-#define GST_PACKAGE_RELEASE_DATETIME "2011-05-14T08:26Z"
+#define GST_PACKAGE_RELEASE_DATETIME "2011-06-04T15:03Z"
 
 /* location of the installed gst-plugin-scanner */
 #define GST_PLUGIN_SCANNER_INSTALLED LIBDIR "\\gst-plugin-scanner"
 /* Define to 1 if you have the `socket' library (-lsocket). */
 #undef HAVE_LIBSOCKET
 
-/* Define if libxml2 is available */
-#define HAVE_LIBXML2 1
-
 /* Define to 1 if you have the `localtime_r' function. */
 #undef HAVE_LOCALTIME_R
 
 #define PACKAGE_NAME "GStreamer"
 
 /* Define to the full name and version of this package. */
-#define PACKAGE_STRING "GStreamer 0.10.34.1"
+#define PACKAGE_STRING "GStreamer 0.11.0.1"
 
 /* Define to the one symbol short name of this package. */
 #define PACKAGE_TARNAME "gstreamer"
 #undef PACKAGE_URL
 
 /* Define to the version of this package. */
-#define PACKAGE_VERSION "0.10.34.1"
+#define PACKAGE_VERSION "0.11.0.1"
 
 /* directory where plugins are located */
 #ifdef _DEBUG
-#  define PLUGINDIR PREFIX "\\debug\\lib\\gstreamer-0.10"
+#  define PLUGINDIR PREFIX "\\debug\\lib\\gstreamer-0.11"
 #else
-#  define PLUGINDIR PREFIX "\\lib\\gstreamer-0.10"
+#  define PLUGINDIR PREFIX "\\lib\\gstreamer-0.11"
 #endif
 
 /* The size of `char', as computed by sizeof. */
 #undef USE_POISONING
 
 /* Version number of package */
-#define VERSION "0.10.34.1"
+#define VERSION "0.11.0.1"
 
 /* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
    significant byte first (like Motorola and SPARC, unlike Intel). */
index 7a0f5ae..509ecad 100644 (file)
@@ -13,9 +13,7 @@ gst_object_flags_get_type (void)
 {
   static gsize id = 0;
   static const GFlagsValue values[] = {
-    {C_FLAGS (GST_OBJECT_DISPOSING), "GST_OBJECT_DISPOSING", "disposing"},
-    {C_FLAGS (GST_OBJECT_FLOATING), "GST_OBJECT_FLOATING", "floating"},
-    {C_FLAGS (GST_OBJECT_FLAG_LAST), "GST_OBJECT_FLAG_LAST", "flag-last"},
+    {C_FLAGS (GST_OBJECT_FLAG_LAST), "GST_OBJECT_FLAG_LAST", "last"},
     {0, NULL, NULL}
   };
 
@@ -51,9 +49,6 @@ gst_buffer_flag_get_type (void)
 {
   static gsize id = 0;
   static const GFlagsValue values[] = {
-    {C_FLAGS (GST_BUFFER_FLAG_READONLY), "GST_BUFFER_FLAG_READONLY",
-        "readonly"},
-    {C_FLAGS (GST_BUFFER_FLAG_MEDIA4), "GST_BUFFER_FLAG_MEDIA4", "media4"},
     {C_FLAGS (GST_BUFFER_FLAG_PREROLL), "GST_BUFFER_FLAG_PREROLL", "preroll"},
     {C_FLAGS (GST_BUFFER_FLAG_DISCONT), "GST_BUFFER_FLAG_DISCONT", "discont"},
     {C_FLAGS (GST_BUFFER_FLAG_IN_CAPS), "GST_BUFFER_FLAG_IN_CAPS", "in-caps"},
@@ -63,6 +58,7 @@ gst_buffer_flag_get_type (void)
     {C_FLAGS (GST_BUFFER_FLAG_MEDIA1), "GST_BUFFER_FLAG_MEDIA1", "media1"},
     {C_FLAGS (GST_BUFFER_FLAG_MEDIA2), "GST_BUFFER_FLAG_MEDIA2", "media2"},
     {C_FLAGS (GST_BUFFER_FLAG_MEDIA3), "GST_BUFFER_FLAG_MEDIA3", "media3"},
+    {C_FLAGS (GST_BUFFER_FLAG_MEDIA4), "GST_BUFFER_FLAG_MEDIA4", "media4"},
     {C_FLAGS (GST_BUFFER_FLAG_LAST), "GST_BUFFER_FLAG_LAST", "last"},
     {0, NULL, NULL}
   };
@@ -80,10 +76,12 @@ gst_buffer_copy_flags_get_type (void)
 {
   static gsize id = 0;
   static const GFlagsValue values[] = {
+    {C_FLAGS (GST_BUFFER_COPY_NONE), "GST_BUFFER_COPY_NONE", "none"},
     {C_FLAGS (GST_BUFFER_COPY_FLAGS), "GST_BUFFER_COPY_FLAGS", "flags"},
     {C_FLAGS (GST_BUFFER_COPY_TIMESTAMPS), "GST_BUFFER_COPY_TIMESTAMPS",
         "timestamps"},
-    {C_FLAGS (GST_BUFFER_COPY_CAPS), "GST_BUFFER_COPY_CAPS", "caps"},
+    {C_FLAGS (GST_BUFFER_COPY_MEMORY), "GST_BUFFER_COPY_MEMORY", "memory"},
+    {C_FLAGS (GST_BUFFER_COPY_MERGE), "GST_BUFFER_COPY_MERGE", "merge"},
     {0, NULL, NULL}
   };
 
@@ -95,21 +93,25 @@ gst_buffer_copy_flags_get_type (void)
   return (GType) id;
 }
 
-/* enumerations from "gstbufferlist.h" */
+/* enumerations from "gstbufferpool.h" */
 GType
-gst_buffer_list_item_get_type (void)
+gst_buffer_pool_flags_get_type (void)
 {
   static gsize id = 0;
-  static const GEnumValue values[] = {
-    {C_ENUM (GST_BUFFER_LIST_CONTINUE), "GST_BUFFER_LIST_CONTINUE", "continue"},
-    {C_ENUM (GST_BUFFER_LIST_SKIP_GROUP), "GST_BUFFER_LIST_SKIP_GROUP",
-        "skip-group"},
-    {C_ENUM (GST_BUFFER_LIST_END), "GST_BUFFER_LIST_END", "end"},
+  static const GFlagsValue values[] = {
+    {C_FLAGS (GST_BUFFER_POOL_FLAG_NONE), "GST_BUFFER_POOL_FLAG_NONE", "none"},
+    {C_FLAGS (GST_BUFFER_POOL_FLAG_KEY_UNIT), "GST_BUFFER_POOL_FLAG_KEY_UNIT",
+        "key-unit"},
+    {C_FLAGS (GST_BUFFER_POOL_FLAG_DONTWAIT), "GST_BUFFER_POOL_FLAG_DONTWAIT",
+        "dontwait"},
+    {C_FLAGS (GST_BUFFER_POOL_FLAG_DISCONT), "GST_BUFFER_POOL_FLAG_DISCONT",
+        "discont"},
+    {C_FLAGS (GST_BUFFER_POOL_FLAG_LAST), "GST_BUFFER_POOL_FLAG_LAST", "last"},
     {0, NULL, NULL}
   };
 
   if (g_once_init_enter (&id)) {
-    GType tmp = g_enum_register_static ("GstBufferListItem", values);
+    GType tmp = g_flags_register_static ("GstBufferPoolFlags", values);
     g_once_init_leave (&id, tmp);
   }
 
@@ -534,6 +536,7 @@ gst_event_type_flags_get_type (void)
         "downstream"},
     {C_FLAGS (GST_EVENT_TYPE_SERIALIZED), "GST_EVENT_TYPE_SERIALIZED",
         "serialized"},
+    {C_FLAGS (GST_EVENT_TYPE_STICKY), "GST_EVENT_TYPE_STICKY", "sticky"},
     {0, NULL, NULL}
   };
 
@@ -553,16 +556,18 @@ gst_event_type_get_type (void)
     {C_ENUM (GST_EVENT_UNKNOWN), "GST_EVENT_UNKNOWN", "unknown"},
     {C_ENUM (GST_EVENT_FLUSH_START), "GST_EVENT_FLUSH_START", "flush-start"},
     {C_ENUM (GST_EVENT_FLUSH_STOP), "GST_EVENT_FLUSH_STOP", "flush-stop"},
-    {C_ENUM (GST_EVENT_EOS), "GST_EVENT_EOS", "eos"},
-    {C_ENUM (GST_EVENT_NEWSEGMENT), "GST_EVENT_NEWSEGMENT", "newsegment"},
+    {C_ENUM (GST_EVENT_CAPS), "GST_EVENT_CAPS", "caps"},
+    {C_ENUM (GST_EVENT_SEGMENT), "GST_EVENT_SEGMENT", "segment"},
     {C_ENUM (GST_EVENT_TAG), "GST_EVENT_TAG", "tag"},
     {C_ENUM (GST_EVENT_BUFFERSIZE), "GST_EVENT_BUFFERSIZE", "buffersize"},
     {C_ENUM (GST_EVENT_SINK_MESSAGE), "GST_EVENT_SINK_MESSAGE", "sink-message"},
+    {C_ENUM (GST_EVENT_EOS), "GST_EVENT_EOS", "eos"},
     {C_ENUM (GST_EVENT_QOS), "GST_EVENT_QOS", "qos"},
     {C_ENUM (GST_EVENT_SEEK), "GST_EVENT_SEEK", "seek"},
     {C_ENUM (GST_EVENT_NAVIGATION), "GST_EVENT_NAVIGATION", "navigation"},
     {C_ENUM (GST_EVENT_LATENCY), "GST_EVENT_LATENCY", "latency"},
     {C_ENUM (GST_EVENT_STEP), "GST_EVENT_STEP", "step"},
+    {C_ENUM (GST_EVENT_RECONFIGURE), "GST_EVENT_RECONFIGURE", "reconfigure"},
     {C_ENUM (GST_EVENT_CUSTOM_UPSTREAM), "GST_EVENT_CUSTOM_UPSTREAM",
         "custom-upstream"},
     {C_ENUM (GST_EVENT_CUSTOM_DOWNSTREAM), "GST_EVENT_CUSTOM_DOWNSTREAM",
@@ -584,48 +589,6 @@ gst_event_type_get_type (void)
 }
 
 GType
-gst_seek_type_get_type (void)
-{
-  static gsize id = 0;
-  static const GEnumValue values[] = {
-    {C_ENUM (GST_SEEK_TYPE_NONE), "GST_SEEK_TYPE_NONE", "none"},
-    {C_ENUM (GST_SEEK_TYPE_CUR), "GST_SEEK_TYPE_CUR", "cur"},
-    {C_ENUM (GST_SEEK_TYPE_SET), "GST_SEEK_TYPE_SET", "set"},
-    {C_ENUM (GST_SEEK_TYPE_END), "GST_SEEK_TYPE_END", "end"},
-    {0, NULL, NULL}
-  };
-
-  if (g_once_init_enter (&id)) {
-    GType tmp = g_enum_register_static ("GstSeekType", values);
-    g_once_init_leave (&id, tmp);
-  }
-
-  return (GType) id;
-}
-
-GType
-gst_seek_flags_get_type (void)
-{
-  static gsize id = 0;
-  static const GFlagsValue values[] = {
-    {C_FLAGS (GST_SEEK_FLAG_NONE), "GST_SEEK_FLAG_NONE", "none"},
-    {C_FLAGS (GST_SEEK_FLAG_FLUSH), "GST_SEEK_FLAG_FLUSH", "flush"},
-    {C_FLAGS (GST_SEEK_FLAG_ACCURATE), "GST_SEEK_FLAG_ACCURATE", "accurate"},
-    {C_FLAGS (GST_SEEK_FLAG_KEY_UNIT), "GST_SEEK_FLAG_KEY_UNIT", "key-unit"},
-    {C_FLAGS (GST_SEEK_FLAG_SEGMENT), "GST_SEEK_FLAG_SEGMENT", "segment"},
-    {C_FLAGS (GST_SEEK_FLAG_SKIP), "GST_SEEK_FLAG_SKIP", "skip"},
-    {0, NULL, NULL}
-  };
-
-  if (g_once_init_enter (&id)) {
-    GType tmp = g_flags_register_static ("GstSeekFlags", values);
-    g_once_init_leave (&id, tmp);
-  }
-
-  return (GType) id;
-}
-
-GType
 gst_qos_type_get_type (void)
 {
   static gsize id = 0;
@@ -1017,16 +980,52 @@ gst_progress_type_get_type (void)
   return (GType) id;
 }
 
+/* enumerations from "gstmemory.h" */
+GType
+gst_memory_flags_get_type (void)
+{
+  static gsize id = 0;
+  static const GFlagsValue values[] = {
+    {C_FLAGS (GST_MEMORY_FLAG_READONLY), "GST_MEMORY_FLAG_READONLY",
+        "readonly"},
+    {C_FLAGS (GST_MEMORY_FLAG_NO_SHARE), "GST_MEMORY_FLAG_NO_SHARE",
+        "no-share"},
+    {C_FLAGS (GST_MEMORY_FLAG_LAST), "GST_MEMORY_FLAG_LAST", "last"},
+    {0, NULL, NULL}
+  };
+
+  if (g_once_init_enter (&id)) {
+    GType tmp = g_flags_register_static ("GstMemoryFlags", values);
+    g_once_init_leave (&id, tmp);
+  }
+
+  return (GType) id;
+}
+
+GType
+gst_map_flags_get_type (void)
+{
+  static gsize id = 0;
+  static const GFlagsValue values[] = {
+    {C_FLAGS (GST_MAP_READ), "GST_MAP_READ", "read"},
+    {C_FLAGS (GST_MAP_WRITE), "GST_MAP_WRITE", "write"},
+    {0, NULL, NULL}
+  };
+
+  if (g_once_init_enter (&id)) {
+    GType tmp = g_flags_register_static ("GstMapFlags", values);
+    g_once_init_leave (&id, tmp);
+  }
+
+  return (GType) id;
+}
+
 /* enumerations from "gstminiobject.h" */
 GType
 gst_mini_object_flags_get_type (void)
 {
   static gsize id = 0;
   static const GFlagsValue values[] = {
-    {C_FLAGS (GST_MINI_OBJECT_FLAG_READONLY), "GST_MINI_OBJECT_FLAG_READONLY",
-        "readonly"},
-    {C_FLAGS (GST_MINI_OBJECT_FLAG_RESERVED1), "GST_MINI_OBJECT_FLAG_RESERVED1",
-        "reserved1"},
     {C_FLAGS (GST_MINI_OBJECT_FLAG_LAST), "GST_MINI_OBJECT_FLAG_LAST", "last"},
     {0, NULL, NULL}
   };
@@ -1145,6 +1144,51 @@ gst_activate_mode_get_type (void)
 }
 
 GType
+gst_probe_type_get_type (void)
+{
+  static gsize id = 0;
+  static const GFlagsValue values[] = {
+    {C_FLAGS (GST_PROBE_TYPE_INVALID), "GST_PROBE_TYPE_INVALID", "invalid"},
+    {C_FLAGS (GST_PROBE_TYPE_IDLE), "GST_PROBE_TYPE_IDLE", "idle"},
+    {C_FLAGS (GST_PROBE_TYPE_BLOCK), "GST_PROBE_TYPE_BLOCK", "block"},
+    {C_FLAGS (GST_PROBE_TYPE_BUFFER), "GST_PROBE_TYPE_BUFFER", "buffer"},
+    {C_FLAGS (GST_PROBE_TYPE_BUFFER_LIST), "GST_PROBE_TYPE_BUFFER_LIST",
+        "buffer-list"},
+    {C_FLAGS (GST_PROBE_TYPE_EVENT), "GST_PROBE_TYPE_EVENT", "event"},
+    {C_FLAGS (GST_PROBE_TYPE_PUSH), "GST_PROBE_TYPE_PUSH", "push"},
+    {C_FLAGS (GST_PROBE_TYPE_PULL), "GST_PROBE_TYPE_PULL", "pull"},
+    {0, NULL, NULL}
+  };
+
+  if (g_once_init_enter (&id)) {
+    GType tmp = g_flags_register_static ("GstProbeType", values);
+    g_once_init_leave (&id, tmp);
+  }
+
+  return (GType) id;
+}
+
+GType
+gst_probe_return_get_type (void)
+{
+  static gsize id = 0;
+  static const GEnumValue values[] = {
+    {C_ENUM (GST_PROBE_DROP), "GST_PROBE_DROP", "drop"},
+    {C_ENUM (GST_PROBE_OK), "GST_PROBE_OK", "ok"},
+    {C_ENUM (GST_PROBE_REMOVE), "GST_PROBE_REMOVE", "remove"},
+    {C_ENUM (GST_PROBE_PASS), "GST_PROBE_PASS", "pass"},
+    {0, NULL, NULL}
+  };
+
+  if (g_once_init_enter (&id)) {
+    GType tmp = g_enum_register_static ("GstProbeReturn", values);
+    g_once_init_leave (&id, tmp);
+  }
+
+  return (GType) id;
+}
+
+GType
 gst_pad_direction_get_type (void)
 {
   static gsize id = 0;
@@ -1173,6 +1217,10 @@ gst_pad_flags_get_type (void)
     {C_FLAGS (GST_PAD_IN_GETCAPS), "GST_PAD_IN_GETCAPS", "in-getcaps"},
     {C_FLAGS (GST_PAD_IN_SETCAPS), "GST_PAD_IN_SETCAPS", "in-setcaps"},
     {C_FLAGS (GST_PAD_BLOCKING), "GST_PAD_BLOCKING", "blocking"},
+    {C_FLAGS (GST_PAD_NEED_RECONFIGURE), "GST_PAD_NEED_RECONFIGURE",
+        "need-reconfigure"},
+    {C_FLAGS (GST_PAD_NEED_EVENTS), "GST_PAD_NEED_EVENTS", "need-events"},
+    {C_FLAGS (GST_PAD_FIXED_CAPS), "GST_PAD_FIXED_CAPS", "fixed-caps"},
     {C_FLAGS (GST_PAD_FLAG_LAST), "GST_PAD_FLAG_LAST", "flag-last"},
     {0, NULL, NULL}
   };
@@ -1210,9 +1258,8 @@ gst_pad_template_flags_get_type (void)
 {
   static gsize id = 0;
   static const GFlagsValue values[] = {
-    {C_FLAGS (GST_PAD_TEMPLATE_FIXED), "GST_PAD_TEMPLATE_FIXED", "fixed"},
     {C_FLAGS (GST_PAD_TEMPLATE_FLAG_LAST), "GST_PAD_TEMPLATE_FLAG_LAST",
-        "flag-last"},
+        "last"},
     {0, NULL, NULL}
   };
 
@@ -1351,6 +1398,8 @@ gst_query_type_get_type (void)
     {C_ENUM (GST_QUERY_BUFFERING), "GST_QUERY_BUFFERING", "buffering"},
     {C_ENUM (GST_QUERY_CUSTOM), "GST_QUERY_CUSTOM", "custom"},
     {C_ENUM (GST_QUERY_URI), "GST_QUERY_URI", "uri"},
+    {C_ENUM (GST_QUERY_ALLOCATION), "GST_QUERY_ALLOCATION", "allocation"},
+    {C_ENUM (GST_QUERY_SCHEDULING), "GST_QUERY_SCHEDULING", "scheduling"},
     {0, NULL, NULL}
   };
 
@@ -1382,6 +1431,49 @@ gst_buffering_mode_get_type (void)
   return (GType) id;
 }
 
+/* enumerations from "gstsegment.h" */
+GType
+gst_seek_type_get_type (void)
+{
+  static gsize id = 0;
+  static const GEnumValue values[] = {
+    {C_ENUM (GST_SEEK_TYPE_NONE), "GST_SEEK_TYPE_NONE", "none"},
+    {C_ENUM (GST_SEEK_TYPE_CUR), "GST_SEEK_TYPE_CUR", "cur"},
+    {C_ENUM (GST_SEEK_TYPE_SET), "GST_SEEK_TYPE_SET", "set"},
+    {C_ENUM (GST_SEEK_TYPE_END), "GST_SEEK_TYPE_END", "end"},
+    {0, NULL, NULL}
+  };
+
+  if (g_once_init_enter (&id)) {
+    GType tmp = g_enum_register_static ("GstSeekType", values);
+    g_once_init_leave (&id, tmp);
+  }
+
+  return (GType) id;
+}
+
+GType
+gst_seek_flags_get_type (void)
+{
+  static gsize id = 0;
+  static const GFlagsValue values[] = {
+    {C_FLAGS (GST_SEEK_FLAG_NONE), "GST_SEEK_FLAG_NONE", "none"},
+    {C_FLAGS (GST_SEEK_FLAG_FLUSH), "GST_SEEK_FLAG_FLUSH", "flush"},
+    {C_FLAGS (GST_SEEK_FLAG_ACCURATE), "GST_SEEK_FLAG_ACCURATE", "accurate"},
+    {C_FLAGS (GST_SEEK_FLAG_KEY_UNIT), "GST_SEEK_FLAG_KEY_UNIT", "key-unit"},
+    {C_FLAGS (GST_SEEK_FLAG_SEGMENT), "GST_SEEK_FLAG_SEGMENT", "segment"},
+    {C_FLAGS (GST_SEEK_FLAG_SKIP), "GST_SEEK_FLAG_SKIP", "skip"},
+    {0, NULL, NULL}
+  };
+
+  if (g_once_init_enter (&id)) {
+    GType tmp = g_flags_register_static ("GstSeekFlags", values);
+    g_once_init_leave (&id, tmp);
+  }
+
+  return (GType) id;
+}
+
 /* enumerations from "gstsystemclock.h" */
 GType
 gst_clock_type_get_type (void)
index 292eb54..c3b8f95 100644 (file)
@@ -22,9 +22,9 @@ GType gst_buffer_flag_get_type (void);
 GType gst_buffer_copy_flags_get_type (void);
 #define GST_TYPE_BUFFER_COPY_FLAGS (gst_buffer_copy_flags_get_type())
 
-/* enumerations from "gstbufferlist.h" */
-GType gst_buffer_list_item_get_type (void);
-#define GST_TYPE_BUFFER_LIST_ITEM (gst_buffer_list_item_get_type())
+/* enumerations from "gstbufferpool.h" */
+GType gst_buffer_pool_flags_get_type (void);
+#define GST_TYPE_BUFFER_POOL_FLAGS (gst_buffer_pool_flags_get_type())
 
 /* enumerations from "gstbus.h" */
 GType gst_bus_flags_get_type (void);
@@ -75,10 +75,6 @@ GType gst_event_type_flags_get_type (void);
 #define GST_TYPE_EVENT_TYPE_FLAGS (gst_event_type_flags_get_type())
 GType gst_event_type_get_type (void);
 #define GST_TYPE_EVENT_TYPE (gst_event_type_get_type())
-GType gst_seek_type_get_type (void);
-#define GST_TYPE_SEEK_TYPE (gst_seek_type_get_type())
-GType gst_seek_flags_get_type (void);
-#define GST_TYPE_SEEK_FLAGS (gst_seek_flags_get_type())
 GType gst_qos_type_get_type (void);
 #define GST_TYPE_QOS_TYPE (gst_qos_type_get_type())
 
@@ -122,6 +118,12 @@ GType gst_stream_status_type_get_type (void);
 GType gst_progress_type_get_type (void);
 #define GST_TYPE_PROGRESS_TYPE (gst_progress_type_get_type())
 
+/* enumerations from "gstmemory.h" */
+GType gst_memory_flags_get_type (void);
+#define GST_TYPE_MEMORY_FLAGS (gst_memory_flags_get_type())
+GType gst_map_flags_get_type (void);
+#define GST_TYPE_MAP_FLAGS (gst_map_flags_get_type())
+
 /* enumerations from "gstminiobject.h" */
 GType gst_mini_object_flags_get_type (void);
 #define GST_TYPE_MINI_OBJECT_FLAGS (gst_mini_object_flags_get_type())
@@ -135,6 +137,10 @@ GType gst_pad_link_check_get_type (void);
 #define GST_TYPE_PAD_LINK_CHECK (gst_pad_link_check_get_type())
 GType gst_activate_mode_get_type (void);
 #define GST_TYPE_ACTIVATE_MODE (gst_activate_mode_get_type())
+GType gst_probe_type_get_type (void);
+#define GST_TYPE_PROBE_TYPE (gst_probe_type_get_type())
+GType gst_probe_return_get_type (void);
+#define GST_TYPE_PROBE_RETURN (gst_probe_return_get_type())
 GType gst_pad_direction_get_type (void);
 #define GST_TYPE_PAD_DIRECTION (gst_pad_direction_get_type())
 GType gst_pad_flags_get_type (void);
@@ -168,6 +174,12 @@ GType gst_query_type_get_type (void);
 GType gst_buffering_mode_get_type (void);
 #define GST_TYPE_BUFFERING_MODE (gst_buffering_mode_get_type())
 
+/* enumerations from "gstsegment.h" */
+GType gst_seek_type_get_type (void);
+#define GST_TYPE_SEEK_TYPE (gst_seek_type_get_type())
+GType gst_seek_flags_get_type (void);
+#define GST_TYPE_SEEK_FLAGS (gst_seek_flags_get_type())
+
 /* enumerations from "gstsystemclock.h" */
 GType gst_clock_type_get_type (void);
 #define GST_TYPE_CLOCK_TYPE (gst_clock_type_get_type())
index b54470a..433e87b 100644 (file)
@@ -518,7 +518,42 @@ gst_marshal_BOOLEAN__POINTER (GClosure * closure,
   g_value_set_boolean (return_value, v_return);
 }
 
-/* POINTER:POINTER (./gstmarshal.list:23) */
+/* BOOLEAN:BOXED (./gstmarshal.list:23) */
+void
+gst_marshal_BOOLEAN__BOXED (GClosure * closure,
+    GValue * return_value G_GNUC_UNUSED,
+    guint n_param_values,
+    const GValue * param_values,
+    gpointer invocation_hint G_GNUC_UNUSED, gpointer marshal_data)
+{
+  typedef gboolean (*GMarshalFunc_BOOLEAN__BOXED) (gpointer data1,
+      gpointer arg_1, gpointer data2);
+  register GMarshalFunc_BOOLEAN__BOXED callback;
+  register GCClosure *cc = (GCClosure *) closure;
+  register gpointer data1, data2;
+  gboolean v_return;
+
+  g_return_if_fail (return_value != NULL);
+  g_return_if_fail (n_param_values == 2);
+
+  if (G_CCLOSURE_SWAP_DATA (closure)) {
+    data1 = closure->data;
+    data2 = g_value_peek_pointer (param_values + 0);
+  } else {
+    data1 = g_value_peek_pointer (param_values + 0);
+    data2 = closure->data;
+  }
+  callback =
+      (GMarshalFunc_BOOLEAN__BOXED) (marshal_data ? marshal_data :
+      cc->callback);
+
+  v_return = callback (data1,
+      g_marshal_value_peek_boxed (param_values + 1), data2);
+
+  g_value_set_boolean (return_value, v_return);
+}
+
+/* POINTER:POINTER (./gstmarshal.list:24) */
 void
 gst_marshal_POINTER__POINTER (GClosure * closure,
     GValue * return_value G_GNUC_UNUSED,
@@ -553,7 +588,7 @@ gst_marshal_POINTER__POINTER (GClosure * closure,
   g_value_set_pointer (return_value, v_return);
 }
 
-/* BOXED:BOXED (./gstmarshal.list:24) */
+/* BOXED:BOXED (./gstmarshal.list:25) */
 void
 gst_marshal_BOXED__BOXED (GClosure * closure,
     GValue * return_value G_GNUC_UNUSED,
index 1665e67..94ac9e2 100644 (file)
@@ -142,7 +142,15 @@ extern void gst_marshal_BOOLEAN__POINTER (GClosure     *closure,
                                           gpointer      invocation_hint,
                                           gpointer      marshal_data);
 
-/* POINTER:POINTER (./gstmarshal.list:23) */
+/* BOOLEAN:BOXED (./gstmarshal.list:23) */
+extern void gst_marshal_BOOLEAN__BOXED (GClosure     *closure,
+                                        GValue       *return_value,
+                                        guint         n_param_values,
+                                        const GValue *param_values,
+                                        gpointer      invocation_hint,
+                                        gpointer      marshal_data);
+
+/* POINTER:POINTER (./gstmarshal.list:24) */
 extern void gst_marshal_POINTER__POINTER (GClosure     *closure,
                                           GValue       *return_value,
                                           guint         n_param_values,
@@ -150,7 +158,7 @@ extern void gst_marshal_POINTER__POINTER (GClosure     *closure,
                                           gpointer      invocation_hint,
                                           gpointer      marshal_data);
 
-/* BOXED:BOXED (./gstmarshal.list:24) */
+/* BOXED:BOXED (./gstmarshal.list:25) */
 extern void gst_marshal_BOXED__BOXED (GClosure     *closure,
                                       GValue       *return_value,
                                       guint         n_param_values,
index be93d1a..87793ab 100644 (file)
@@ -51,13 +51,13 @@ G_BEGIN_DECLS
  *
  * The minor version of GStreamer at compile time:
  */
-#define GST_VERSION_MINOR (10)
+#define GST_VERSION_MINOR (11)
 /**
  * GST_VERSION_MICRO:
  *
  * The micro version of GStreamer at compile time:
  */
-#define GST_VERSION_MICRO (34)
+#define GST_VERSION_MICRO (0)
 /**
  * GST_VERSION_NANO:
  *
index b2e831d..bc2a543 100644 (file)
@@ -5,15 +5,16 @@ EXPORTS
        gst_adapter_copy
        gst_adapter_flush
        gst_adapter_get_type
+       gst_adapter_map
        gst_adapter_masked_scan_uint32
        gst_adapter_masked_scan_uint32_peek
        gst_adapter_new
-       gst_adapter_peek
        gst_adapter_prev_timestamp
        gst_adapter_push
        gst_adapter_take
        gst_adapter_take_buffer
        gst_adapter_take_list
+       gst_adapter_unmap
        gst_base_parse_add_index_entry
        gst_base_parse_convert_default
        gst_base_parse_frame_free
@@ -88,9 +89,7 @@ EXPORTS
        gst_bit_reader_get_remaining
        gst_bit_reader_get_size
        gst_bit_reader_init
-       gst_bit_reader_init_from_buffer
        gst_bit_reader_new
-       gst_bit_reader_new_from_buffer
        gst_bit_reader_peek_bits_uint16
        gst_bit_reader_peek_bits_uint32
        gst_bit_reader_peek_bits_uint64
@@ -131,10 +130,8 @@ EXPORTS
        gst_byte_reader_get_uint64_le
        gst_byte_reader_get_uint8
        gst_byte_reader_init
-       gst_byte_reader_init_from_buffer
        gst_byte_reader_masked_scan_uint32
        gst_byte_reader_new
-       gst_byte_reader_new_from_buffer
        gst_byte_reader_peek_data
        gst_byte_reader_peek_float32_be
        gst_byte_reader_peek_float32_le
@@ -171,11 +168,9 @@ EXPORTS
        gst_byte_writer_free_and_get_data
        gst_byte_writer_get_remaining
        gst_byte_writer_init
-       gst_byte_writer_init_with_buffer
        gst_byte_writer_init_with_data
        gst_byte_writer_init_with_size
        gst_byte_writer_new
-       gst_byte_writer_new_with_buffer
        gst_byte_writer_new_with_data
        gst_byte_writer_new_with_size
        gst_byte_writer_put_data
@@ -218,7 +213,6 @@ EXPORTS
        gst_collect_pads_new
        gst_collect_pads_peek
        gst_collect_pads_pop
-       gst_collect_pads_read
        gst_collect_pads_read_buffer
        gst_collect_pads_remove_pad
        gst_collect_pads_set_clip_function
@@ -242,6 +236,7 @@ EXPORTS
        gst_push_src_get_type
        gst_type_find_helper
        gst_type_find_helper_for_buffer
+       gst_type_find_helper_for_data
        gst_type_find_helper_for_extension
        gst_type_find_helper_get_range
        gst_type_find_helper_get_range_ext
index 3e3df94..1a5f76f 100644 (file)
@@ -4,7 +4,6 @@ EXPORTS
        gst_control_source_get_value
        gst_control_source_get_value_array
        gst_controller_get
-       gst_controller_get_all
        gst_controller_get_control_source
        gst_controller_get_type
        gst_controller_get_value_array
@@ -16,16 +15,11 @@ EXPORTS
        gst_controller_remove_properties
        gst_controller_remove_properties_list
        gst_controller_remove_properties_valist
-       gst_controller_set
        gst_controller_set_control_source
        gst_controller_set_disabled
-       gst_controller_set_from_list
-       gst_controller_set_interpolation_mode
        gst_controller_set_property_disabled
        gst_controller_suggest_next_sync
        gst_controller_sync_values
-       gst_controller_unset
-       gst_controller_unset_all
        gst_interpolation_control_source_get_all
        gst_interpolation_control_source_get_count
        gst_interpolation_control_source_get_type
index 3cb24fc..e098a25 100644 (file)
@@ -4,12 +4,9 @@ EXPORTS
        gst_dp_crc
        gst_dp_dump_byte_array
        gst_dp_event_from_packet
-       gst_dp_header_from_buffer
        gst_dp_header_payload_length
        gst_dp_header_payload_type
        gst_dp_init
-       gst_dp_packet_from_caps
-       gst_dp_packet_from_event
        gst_dp_packetizer_free
        gst_dp_packetizer_new
        gst_dp_validate_header
index a15e0e9..617dc84 100644 (file)
@@ -30,11 +30,13 @@ EXPORTS
        GST_CAT_SIGNAL DATA
        GST_CAT_STATES DATA
        GST_CAT_TYPES DATA
-       GST_CAT_XML DATA
        __gst_debug_enabled DATA
        __gst_debug_min DATA
        _gst_alloc_trace_register
        _gst_buffer_list_initialize
+       _gst_buffer_list_type DATA
+       _gst_buffer_type DATA
+       _gst_caps_type DATA
        _gst_debug_bin_to_dot_file
        _gst_debug_bin_to_dot_file_with_ts
        _gst_debug_category_new
@@ -45,8 +47,9 @@ EXPORTS
        _gst_disable_registry_cache DATA
        _gst_element_error_printf
        _gst_elementclass_factory DATA
+       _gst_event_type DATA
        _gst_plugin_loader_client_run
-       _gst_plugin_register_static
+       _gst_structure_type DATA
        _gst_trace_add_entry
        _gst_trace_mutex DATA
        _gst_trace_on DATA
@@ -62,7 +65,6 @@ EXPORTS
        gst_alloc_trace_set_flags
        gst_alloc_trace_set_flags_all
        gst_assoc_flags_get_type
-       gst_atomic_int_set
        gst_atomic_queue_length
        gst_atomic_queue_new
        gst_atomic_queue_peek
@@ -72,7 +74,6 @@ EXPORTS
        gst_atomic_queue_unref
        gst_bin_add
        gst_bin_add_many
-       gst_bin_find_unconnected_pad
        gst_bin_find_unlinked_pad
        gst_bin_flags_get_type
        gst_bin_get_by_interface
@@ -89,43 +90,48 @@ EXPORTS
        gst_bin_recalculate_latency
        gst_bin_remove
        gst_bin_remove_many
+       gst_buffer_add_meta
        gst_buffer_copy_flags_get_type
-       gst_buffer_copy_metadata
-       gst_buffer_create_sub
+       gst_buffer_copy_into
+       gst_buffer_copy_region
+       gst_buffer_extract
+       gst_buffer_fill
        gst_buffer_flag_get_type
-       gst_buffer_get_caps
-       gst_buffer_get_type
-       gst_buffer_is_metadata_writable
+       gst_buffer_get_meta
+       gst_buffer_get_size
        gst_buffer_is_span_fast
+       gst_buffer_iterate_meta
        gst_buffer_join
        gst_buffer_list_foreach
        gst_buffer_list_get
-       gst_buffer_list_get_type
-       gst_buffer_list_item_get_type
-       gst_buffer_list_iterate
-       gst_buffer_list_iterator_add
-       gst_buffer_list_iterator_add_group
-       gst_buffer_list_iterator_add_list
-       gst_buffer_list_iterator_do
-       gst_buffer_list_iterator_free
-       gst_buffer_list_iterator_get_type
-       gst_buffer_list_iterator_merge_group
-       gst_buffer_list_iterator_n_buffers
-       gst_buffer_list_iterator_next
-       gst_buffer_list_iterator_next_group
-       gst_buffer_list_iterator_remove
-       gst_buffer_list_iterator_steal
-       gst_buffer_list_iterator_take
-       gst_buffer_list_n_groups
+       gst_buffer_list_insert
+       gst_buffer_list_len
        gst_buffer_list_new
-       gst_buffer_make_metadata_writable
+       gst_buffer_list_remove
+       gst_buffer_list_sized_new
+       gst_buffer_map
+       gst_buffer_memcmp
        gst_buffer_merge
+       gst_buffer_n_memory
        gst_buffer_new
        gst_buffer_new_and_alloc
-       gst_buffer_set_caps
+       gst_buffer_peek_memory
+       gst_buffer_pool_acquire_buffer
+       gst_buffer_pool_config_get
+       gst_buffer_pool_config_set
+       gst_buffer_pool_flags_get_type
+       gst_buffer_pool_get_config
+       gst_buffer_pool_get_type
+       gst_buffer_pool_new
+       gst_buffer_pool_release_buffer
+       gst_buffer_pool_set_active
+       gst_buffer_pool_set_config
+       gst_buffer_remove_memory_range
+       gst_buffer_remove_meta
+       gst_buffer_resize
        gst_buffer_span
-       gst_buffer_stamp
-       gst_buffer_try_new_and_alloc
+       gst_buffer_take_memory
+       gst_buffer_unmap
        gst_buffering_mode_get_type
        gst_bus_add_signal_watch
        gst_bus_add_signal_watch_full
@@ -154,14 +160,12 @@ EXPORTS
        gst_caps_append
        gst_caps_append_structure
        gst_caps_can_intersect
-       gst_caps_copy
        gst_caps_copy_nth
        gst_caps_do_simplify
        gst_caps_flags_get_type
        gst_caps_from_string
        gst_caps_get_size
        gst_caps_get_structure
-       gst_caps_get_type
        gst_caps_intersect
        gst_caps_intersect_full
        gst_caps_intersect_mode_get_type
@@ -173,8 +177,6 @@ EXPORTS
        gst_caps_is_fixed
        gst_caps_is_subset
        gst_caps_is_subset_structure
-       gst_caps_load_thyself
-       gst_caps_make_writable
        gst_caps_merge
        gst_caps_merge_structure
        gst_caps_new_any
@@ -183,10 +185,7 @@ EXPORTS
        gst_caps_new_full_valist
        gst_caps_new_simple
        gst_caps_normalize
-       gst_caps_ref
        gst_caps_remove_structure
-       gst_caps_replace
-       gst_caps_save_thyself
        gst_caps_set_simple
        gst_caps_set_simple_valist
        gst_caps_set_value
@@ -195,7 +194,6 @@ EXPORTS
        gst_caps_to_string
        gst_caps_truncate
        gst_caps_union
-       gst_caps_unref
        gst_child_proxy_child_added
        gst_child_proxy_child_removed
        gst_child_proxy_get
@@ -209,8 +207,6 @@ EXPORTS
        gst_child_proxy_set
        gst_child_proxy_set_property
        gst_child_proxy_set_valist
-       gst_class_signal_connect
-       gst_class_signal_emit_by_name
        gst_clock_add_observation
        gst_clock_adjust_unlocked
        gst_clock_entry_type_get_type
@@ -295,31 +291,23 @@ EXPORTS
        gst_element_abort_state
        gst_element_add_pad
        gst_element_change_state
+       gst_element_class_add_metadata
        gst_element_class_add_pad_template
+       gst_element_class_get_metadata
        gst_element_class_get_pad_template
        gst_element_class_get_pad_template_list
        gst_element_class_install_std_props
-       gst_element_class_set_details
-       gst_element_class_set_details_simple
-       gst_element_class_set_documentation_uri
-       gst_element_class_set_icon_name
+       gst_element_class_set_metadata
        gst_element_continue_state
        gst_element_create_all_pads
        gst_element_factory_can_sink_all_caps
        gst_element_factory_can_sink_any_caps
-       gst_element_factory_can_sink_caps
        gst_element_factory_can_src_all_caps
        gst_element_factory_can_src_any_caps
-       gst_element_factory_can_src_caps
        gst_element_factory_create
        gst_element_factory_find
-       gst_element_factory_get_author
-       gst_element_factory_get_description
-       gst_element_factory_get_documentation_uri
        gst_element_factory_get_element_type
-       gst_element_factory_get_icon_name
-       gst_element_factory_get_klass
-       gst_element_factory_get_longname
+       gst_element_factory_get_metadata
        gst_element_factory_get_num_pad_templates
        gst_element_factory_get_static_pad_templates
        gst_element_factory_get_type
@@ -340,7 +328,6 @@ EXPORTS
        gst_element_get_compatible_pad_template
        gst_element_get_factory
        gst_element_get_index
-       gst_element_get_pad
        gst_element_get_query_types
        gst_element_get_request_pad
        gst_element_get_start_time
@@ -360,7 +347,6 @@ EXPORTS
        gst_element_link_pads_filtered
        gst_element_link_pads_full
        gst_element_lost_state
-       gst_element_lost_state_full
        gst_element_make_from_uri
        gst_element_message_full
        gst_element_no_more_pads
@@ -393,32 +379,32 @@ EXPORTS
        gst_element_unlink_many
        gst_element_unlink_pads
        gst_error_get_message
+       gst_event_copy_segment
        gst_event_get_seqnum
        gst_event_get_structure
-       gst_event_get_type
        gst_event_has_name
        gst_event_new_buffer_size
+       gst_event_new_caps
        gst_event_new_custom
        gst_event_new_eos
        gst_event_new_flush_start
        gst_event_new_flush_stop
        gst_event_new_latency
        gst_event_new_navigation
-       gst_event_new_new_segment
-       gst_event_new_new_segment_full
        gst_event_new_qos
-       gst_event_new_qos_full
+       gst_event_new_reconfigure
        gst_event_new_seek
+       gst_event_new_segment
        gst_event_new_sink_message
        gst_event_new_step
        gst_event_new_tag
        gst_event_parse_buffer_size
+       gst_event_parse_caps
+       gst_event_parse_flush_stop
        gst_event_parse_latency
-       gst_event_parse_new_segment
-       gst_event_parse_new_segment_full
        gst_event_parse_qos
-       gst_event_parse_qos_full
        gst_event_parse_seek
+       gst_event_parse_segment
        gst_event_parse_sink_message
        gst_event_parse_step
        gst_event_parse_tag
@@ -428,6 +414,7 @@ EXPORTS
        gst_event_type_get_name
        gst_event_type_get_type
        gst_event_type_to_quark
+       gst_event_writable_structure
        gst_filename_to_uri
        gst_filter_run
        gst_flow_get_name
@@ -458,7 +445,6 @@ EXPORTS
        gst_ghost_pad_new_no_target
        gst_ghost_pad_new_no_target_from_template
        gst_ghost_pad_set_target
-       gst_ghost_pad_setcaps_default
        gst_ghost_pad_unlink_default
        gst_implements_interface_cast
        gst_implements_interface_check
@@ -505,11 +491,13 @@ EXPORTS
        gst_int_range_get_type
        gst_is_initialized
        gst_is_tag_list
+       gst_iterator_copy
        gst_iterator_filter
        gst_iterator_find_custom
        gst_iterator_fold
        gst_iterator_foreach
        gst_iterator_free
+       gst_iterator_get_type
        gst_iterator_item_get_type
        gst_iterator_new
        gst_iterator_new_list
@@ -520,6 +508,8 @@ EXPORTS
        gst_iterator_resync
        gst_library_error_get_type
        gst_library_error_quark
+       gst_map_flags_get_type
+       gst_marshal_BOOLEAN__BOXED
        gst_marshal_BOOLEAN__POINTER
        gst_marshal_BOOLEAN__VOID
        gst_marshal_BOXED__BOXED
@@ -536,10 +526,26 @@ EXPORTS
        gst_marshal_VOID__OBJECT_STRING
        gst_marshal_VOID__POINTER_OBJECT
        gst_marshal_VOID__UINT_BOXED
+       gst_memory_allocator_alloc
+       gst_memory_allocator_find
+       gst_memory_allocator_register
+       gst_memory_allocator_set_default
+       gst_memory_copy
+       gst_memory_flags_get_type
+       gst_memory_get_sizes
+       gst_memory_is_span
+       gst_memory_map
+       gst_memory_new_wrapped
+       gst_memory_ref
+       gst_memory_resize
+       gst_memory_share
+       gst_memory_unmap
+       gst_memory_unref
        gst_message_get_seqnum
        gst_message_get_stream_status_object
        gst_message_get_structure
        gst_message_get_type
+       gst_message_has_name
        gst_message_new_application
        gst_message_new_async_done
        gst_message_new_async_start
@@ -568,7 +574,7 @@ EXPORTS
        gst_message_new_tag
        gst_message_new_tag_full
        gst_message_new_warning
-       gst_message_parse_async_start
+       gst_message_parse_async_done
        gst_message_parse_buffering
        gst_message_parse_buffering_stats
        gst_message_parse_clock_lost
@@ -600,14 +606,19 @@ EXPORTS
        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_steal
+       gst_mini_object_take
        gst_mini_object_unref
        gst_mini_object_weak_ref
        gst_mini_object_weak_unref
@@ -616,7 +627,6 @@ EXPORTS
        gst_object_default_error
        gst_object_flags_get_type
        gst_object_get_name
-       gst_object_get_name_prefix
        gst_object_get_parent
        gst_object_get_path_string
        gst_object_get_type
@@ -624,43 +634,29 @@ EXPORTS
        gst_object_ref
        gst_object_ref_sink
        gst_object_replace
-       gst_object_restore_thyself
-       gst_object_save_thyself
        gst_object_set_name
-       gst_object_set_name_prefix
        gst_object_set_parent
-       gst_object_sink
        gst_object_unparent
        gst_object_unref
        gst_pad_accept_caps
        gst_pad_activate_pull
        gst_pad_activate_push
-       gst_pad_add_buffer_probe
-       gst_pad_add_buffer_probe_full
-       gst_pad_add_data_probe
-       gst_pad_add_data_probe_full
-       gst_pad_add_event_probe
-       gst_pad_add_event_probe_full
-       gst_pad_alloc_buffer
-       gst_pad_alloc_buffer_and_set_caps
+       gst_pad_add_probe
        gst_pad_can_link
        gst_pad_chain
        gst_pad_chain_list
-       gst_pad_check_pull_range
        gst_pad_direction_get_type
-       gst_pad_dispatcher
        gst_pad_event_default
        gst_pad_fixate_caps
        gst_pad_flags_get_type
+       gst_pad_forward
        gst_pad_get_allowed_caps
        gst_pad_get_caps
-       gst_pad_get_caps_reffed
+       gst_pad_get_current_caps
        gst_pad_get_direction
        gst_pad_get_element_private
-       gst_pad_get_fixed_caps_func
-       gst_pad_get_internal_links
-       gst_pad_get_internal_links_default
        gst_pad_get_negotiated_caps
+       gst_pad_get_offset
        gst_pad_get_pad_template
        gst_pad_get_pad_template_caps
        gst_pad_get_parent_element
@@ -668,7 +664,9 @@ EXPORTS
        gst_pad_get_query_types
        gst_pad_get_query_types_default
        gst_pad_get_range
+       gst_pad_get_sticky_event
        gst_pad_get_type
+       gst_pad_has_current_caps
        gst_pad_is_active
        gst_pad_is_blocked
        gst_pad_is_blocking
@@ -679,18 +677,15 @@ EXPORTS
        gst_pad_link_check_get_type
        gst_pad_link_full
        gst_pad_link_return_get_type
-       gst_pad_load_and_link
        gst_pad_new
        gst_pad_new_from_static_template
        gst_pad_new_from_template
        gst_pad_pause_task
        gst_pad_peer_accept_caps
        gst_pad_peer_get_caps
-       gst_pad_peer_get_caps_reffed
        gst_pad_peer_query
        gst_pad_presence_get_type
        gst_pad_proxy_getcaps
-       gst_pad_proxy_setcaps
        gst_pad_pull_range
        gst_pad_push
        gst_pad_push_event
@@ -703,36 +698,29 @@ EXPORTS
        gst_pad_query_peer_duration
        gst_pad_query_peer_position
        gst_pad_query_position
-       gst_pad_remove_buffer_probe
-       gst_pad_remove_data_probe
-       gst_pad_remove_event_probe
+       gst_pad_remove_probe
        gst_pad_send_event
        gst_pad_set_acceptcaps_function
        gst_pad_set_activate_function
        gst_pad_set_activatepull_function
        gst_pad_set_activatepush_function
        gst_pad_set_active
-       gst_pad_set_blocked
-       gst_pad_set_blocked_async
-       gst_pad_set_blocked_async_full
-       gst_pad_set_bufferalloc_function
        gst_pad_set_caps
        gst_pad_set_chain_function
        gst_pad_set_chain_list_function
-       gst_pad_set_checkgetrange_function
        gst_pad_set_element_private
        gst_pad_set_event_function
        gst_pad_set_fixatecaps_function
        gst_pad_set_getcaps_function
        gst_pad_set_getrange_function
-       gst_pad_set_internal_link_function
        gst_pad_set_iterate_internal_links_function
        gst_pad_set_link_function
+       gst_pad_set_offset
        gst_pad_set_query_function
        gst_pad_set_query_type_function
-       gst_pad_set_setcaps_function
        gst_pad_set_unlink_function
        gst_pad_start_task
+       gst_pad_sticky_events_foreach
        gst_pad_stop_task
        gst_pad_template_flags_get_type
        gst_pad_template_get_caps
@@ -743,8 +731,6 @@ EXPORTS
        gst_pad_use_fixed_caps
        gst_param_spec_fraction
        gst_param_spec_fraction_get_type
-       gst_param_spec_mini_object
-       gst_param_spec_mini_object_get_type
        gst_parse_bin_from_description
        gst_parse_bin_from_description_full
        gst_parse_context_free
@@ -764,13 +750,11 @@ EXPORTS
        gst_pipeline_get_bus
        gst_pipeline_get_clock
        gst_pipeline_get_delay
-       gst_pipeline_get_last_stream_time
        gst_pipeline_get_type
        gst_pipeline_new
        gst_pipeline_set_auto_flush_bus
        gst_pipeline_set_clock
        gst_pipeline_set_delay
-       gst_pipeline_set_new_stream_time
        gst_pipeline_use_clock
        gst_plugin_add_dependency
        gst_plugin_add_dependency_simple
@@ -778,7 +762,6 @@ EXPORTS
        gst_plugin_error_get_type
        gst_plugin_error_quark
        gst_plugin_feature_check_version
-       gst_plugin_feature_get_name
        gst_plugin_feature_get_rank
        gst_plugin_feature_get_type
        gst_plugin_feature_list_copy
@@ -786,7 +769,6 @@ EXPORTS
        gst_plugin_feature_list_free
        gst_plugin_feature_load
        gst_plugin_feature_rank_compare_func
-       gst_plugin_feature_set_name
        gst_plugin_feature_set_rank
        gst_plugin_feature_type_name_filter
        gst_plugin_flags_get_type
@@ -841,12 +823,12 @@ EXPORTS
        gst_preset_set_meta
        gst_print_element_args
        gst_print_pad_caps
+       gst_probe_return_get_type
+       gst_probe_type_get_type
        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
@@ -856,36 +838,47 @@ EXPORTS
        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_memory
+       gst_query_add_allocation_meta
        gst_query_add_buffering_range
+       gst_query_get_n_allocation_memories
+       gst_query_get_n_allocation_metas
        gst_query_get_n_buffering_ranges
        gst_query_get_structure
        gst_query_get_type
-       gst_query_new_application
+       gst_query_new_allocation
        gst_query_new_buffering
        gst_query_new_convert
+       gst_query_new_custom
        gst_query_new_duration
        gst_query_new_formats
        gst_query_new_latency
        gst_query_new_position
+       gst_query_new_scheduling
        gst_query_new_seeking
        gst_query_new_segment
        gst_query_new_uri
+       gst_query_parse_allocation
+       gst_query_parse_allocation_params
        gst_query_parse_buffering_percent
        gst_query_parse_buffering_range
        gst_query_parse_buffering_stats
        gst_query_parse_convert
        gst_query_parse_duration
-       gst_query_parse_formats_length
-       gst_query_parse_formats_nth
        gst_query_parse_latency
+       gst_query_parse_n_formats
+       gst_query_parse_nth_allocation_memory
+       gst_query_parse_nth_allocation_meta
        gst_query_parse_nth_buffering_range
+       gst_query_parse_nth_format
        gst_query_parse_position
+       gst_query_parse_scheduling
        gst_query_parse_seeking
        gst_query_parse_segment
        gst_query_parse_uri
+       gst_query_set_allocation_params
        gst_query_set_buffering_percent
        gst_query_set_buffering_range
        gst_query_set_buffering_stats
@@ -895,6 +888,7 @@ EXPORTS
        gst_query_set_formatsv
        gst_query_set_latency
        gst_query_set_position
+       gst_query_set_scheduling
        gst_query_set_seeking
        gst_query_set_segment
        gst_query_set_uri
@@ -906,6 +900,7 @@ EXPORTS
        gst_query_type_register
        gst_query_type_to_quark
        gst_query_types_contains
+       gst_query_writable_structure
        gst_rank_get_type
        gst_registry_add_feature
        gst_registry_add_path
@@ -930,8 +925,6 @@ EXPORTS
        gst_registry_remove_feature
        gst_registry_remove_plugin
        gst_registry_scan_path
-       gst_registry_xml_read_cache
-       gst_registry_xml_write_cache
        gst_resource_error_get_type
        gst_resource_error_quark
        gst_search_mode_get_type
@@ -939,16 +932,14 @@ EXPORTS
        gst_seek_type_get_type
        gst_segment_clip
        gst_segment_copy
+       gst_segment_copy_into
+       gst_segment_do_seek
+       gst_segment_flags_get_type
        gst_segment_free
        gst_segment_get_type
        gst_segment_init
        gst_segment_new
-       gst_segment_set_duration
-       gst_segment_set_last_stop
-       gst_segment_set_newsegment
-       gst_segment_set_newsegment_full
        gst_segment_set_running_time
-       gst_segment_set_seek
        gst_segment_to_position
        gst_segment_to_running_time
        gst_segment_to_stream_time
@@ -991,7 +982,6 @@ EXPORTS
        gst_structure_get_name
        gst_structure_get_name_id
        gst_structure_get_string
-       gst_structure_get_type
        gst_structure_get_uint
        gst_structure_get_valist
        gst_structure_get_value
@@ -1191,7 +1181,7 @@ EXPORTS
        gst_value_can_union
        gst_value_compare
        gst_value_deserialize
-       gst_value_dup_mini_object
+       gst_value_fixate
        gst_value_fraction_multiply
        gst_value_fraction_subtract
        gst_value_get_caps
@@ -1207,7 +1197,6 @@ EXPORTS
        gst_value_get_int64_range_min
        gst_value_get_int_range_max
        gst_value_get_int_range_min
-       gst_value_get_mini_object
        gst_value_get_structure
        gst_value_init_and_copy
        gst_value_intersect
@@ -1233,20 +1222,8 @@ EXPORTS
        gst_value_set_fraction_range_full
        gst_value_set_int64_range
        gst_value_set_int_range
-       gst_value_set_mini_object
        gst_value_set_structure
        gst_value_subtract
-       gst_value_take_mini_object
        gst_value_union
        gst_version
        gst_version_string
-       gst_xml_get_element
-       gst_xml_get_topelements
-       gst_xml_get_type
-       gst_xml_make_element
-       gst_xml_new
-       gst_xml_parse_doc
-       gst_xml_parse_file
-       gst_xml_parse_memory
-       gst_xml_write
-       gst_xml_write_file