merge from EVENTS1 on 20011016
authorErik Walthinsen <omega@temple-baptist.org>
Wed, 17 Oct 2001 10:21:27 +0000 (10:21 +0000)
committerErik Walthinsen <omega@temple-baptist.org>
Wed, 17 Oct 2001 10:21:27 +0000 (10:21 +0000)
Original commit message from CVS:
merge from EVENTS1 on 20011016

135 files changed:
autogen.sh
configure.base
docs/gst/tmpl/gstautoplug.sgml
docs/gst/tmpl/gstbuffer.sgml
docs/gst/tmpl/gstbufferpool.sgml
docs/gst/tmpl/gstdisksrc.sgml
docs/gst/tmpl/gstelement.sgml
docs/gst/tmpl/gstfakesink.sgml
docs/gst/tmpl/gstfakesrc.sgml
docs/gst/tmpl/gstidentity.sgml
docs/gst/tmpl/gstobject.sgml
docs/gst/tmpl/gstpad.sgml
docs/gst/tmpl/gstplugin.sgml
docs/gst/tmpl/gstqueue.sgml
docs/gst/tmpl/gstreamer-unused.sgml
docs/gst/tmpl/gsttee.sgml
docs/gst/tmpl/gstthread.sgml
docs/gst/tmpl/gsttype.sgml
docs/random/wtay/events
docs/random/wtay/events2 [new file with mode: 0644]
editor/gsteditorproject.c
examples/Makefile.am
examples/autoplug/autoplug.c
examples/mixer/mixer.c
gst/Makefile.am
gst/autoplug/gstautoplugger.c
gst/elements/Makefile.am
gst/elements/gstaggregator.c
gst/elements/gstdisksrc.c
gst/elements/gstdisksrc.h
gst/elements/gstfakesink.c
gst/elements/gstfakesink.h
gst/elements/gstfakesrc.c
gst/elements/gstfakesrc.h
gst/elements/gstfilesrc.c
gst/elements/gstsinesrc.c [new file with mode: 0644]
gst/elements/gstsinesrc.h [new file with mode: 0644]
gst/elements/gsttee.c
gst/gobject2gtk.c
gst/gobject2gtk.h
gst/gst.c
gst/gst.h
gst/gstautoplug.c
gst/gstbin.c
gst/gstbuffer.c
gst/gstbuffer.h
gst/gstbufferpool.c
gst/gstcaps.c
gst/gstcaps.h
gst/gstconfig.h [new file with mode: 0644]
gst/gstdata.h [new file with mode: 0644]
gst/gstelement.c
gst/gstelement.h
gst/gstelementfactory.c
gst/gstevent.c [new file with mode: 0644]
gst/gstevent.h
gst/gstinfo.c
gst/gstinfo.h
gst/gstobject.c
gst/gstobject.h
gst/gstpad.c
gst/gstpad.h
gst/gstparse.c
gst/gstplugin.c
gst/gstplugin.h
gst/gstprops.c
gst/gstprops.h
gst/gstscheduler.c
gst/gstthread.c
gst/gstversion.h.in
gst/gstxml.h
gst/utils/gstbytestream.c [new file with mode: 0644]
gst/utils/gstbytestream.h [new file with mode: 0644]
gstplay/gstplay.c
gstplay/main.c
libs/Makefile.am
libs/bytestream/Makefile.am [new file with mode: 0644]
libs/bytestream/gstbstest.c [new file with mode: 0644]
libs/bytestream/gstbytestream.c [new file with mode: 0644]
libs/bytestream/gstbytestream.h [new file with mode: 0644]
plugins/elements/Makefile.am
plugins/elements/gstaggregator.c
plugins/elements/gstdisksrc.c
plugins/elements/gstdisksrc.h
plugins/elements/gstfakesink.c
plugins/elements/gstfakesink.h
plugins/elements/gstfakesrc.c
plugins/elements/gstfakesrc.h
plugins/elements/gstfilesrc.c
plugins/elements/gstsinesrc.c [new file with mode: 0644]
plugins/elements/gstsinesrc.h [new file with mode: 0644]
plugins/elements/gsttee.c
test/ac3play.c
test/aviparse.c
test/bufspeed/.gitignore [new file with mode: 0644]
test/bufspeed/Makefile.am [new file with mode: 0644]
test/bufspeed/README [new file with mode: 0644]
test/bufspeed/gstbuffer.c [new file with mode: 0644]
test/bufspeed/gstbuffer.h [new file with mode: 0644]
test/bufspeed/gstmempool.c [new file with mode: 0644]
test/bufspeed/gstmempool.h [new file with mode: 0644]
test/bufspeed/test1.c [new file with mode: 0644]
test/bufspeed/test2.c [new file with mode: 0644]
test/dvshow.c
test/events/Makefile.am [new file with mode: 0644]
test/events/seek.c [new file with mode: 0644]
test/main.c
test/memchunk/Makefile.am [new file with mode: 0644]
test/memchunk/gmemchunktest.c [new file with mode: 0644]
test/memchunk/gstmemchunk.c [new file with mode: 0644]
test/memchunk/gstmemchunk.h [new file with mode: 0644]
test/memchunk/gstmemchunktest.c [new file with mode: 0644]
test/mpeg2parse2.c
tests/Makefile.am
tests/old/examples/Makefile.am
tests/old/examples/autoplug/autoplug.c
tests/old/examples/mixer/mixer.c
tests/old/testsuite/bytestream/.gitignore [new file with mode: 0644]
tests/old/testsuite/bytestream/Makefile.am [new file with mode: 0644]
tests/old/testsuite/bytestream/gstbstest.c [new file with mode: 0644]
tests/old/testsuite/bytestream/mem.c [new file with mode: 0644]
tests/old/testsuite/bytestream/mem.h [new file with mode: 0644]
tests/old/testsuite/bytestream/test1.c [new file with mode: 0644]
tests/old/testsuite/bytestream/testfile1 [new file with mode: 0644]
tests/sched/Makefile.am
testsuite/bytestream/.gitignore [new file with mode: 0644]
testsuite/bytestream/Makefile.am [new file with mode: 0644]
testsuite/bytestream/gstbstest.c [new file with mode: 0644]
testsuite/bytestream/mem.c [new file with mode: 0644]
testsuite/bytestream/mem.h [new file with mode: 0644]
testsuite/bytestream/test1.c [new file with mode: 0644]
testsuite/bytestream/testfile1 [new file with mode: 0644]
tools/Makefile.am
tools/gstreamer-inspect.c
tools/gstreamer-launch.c

index 42a3281..8a4d60b 100755 (executable)
@@ -191,10 +191,14 @@ automake --add-missing || {
 # now remove the cache, because it can be considered dangerous in this case
 rm -f config.cache
 
-# The new configure options for busy application developers (Hadess)
-#./configure --enable-maintainer-mode --enable-debug --enable-DEBUG "$@" || {
+CONFIGURE_OPT='--enable-maintainer-mode --enable-plugin-builddir --enable-debug --enable-DEBUG'
 
-./configure --enable-maintainer-mode --enable-plugin-builddir --enable-debug --enable-DEBUG "$@" || {
+echo
+echo "./configure default flags: $CONFIGURE_OPT"
+echo "using: $CONFIGURE_OPT $@"
+echo
+
+./configure $CONFIGURE_OPT "$@" || {
        echo
        echo "configure failed"
        exit 1
index de9b815..7597efb 100644 (file)
@@ -216,13 +216,6 @@ GST_CHECK_FEATURE(GLIB2, [use of glib-2.0 and GObject], , [
 ])
 AC_SUBST(USE_GLIB2)
 
-dnl FIXME: check for gtk2 and gnome2 - these conditionals are currently
-dnl always false.
-AM_CONDITIONAL(USE_GTK2, test "x$USE_GTK2" = "xyes")
-AC_SUBST(USE_GTK2)
-AM_CONDITIONAL(USE_GNOME2, test "x$USE_GNOME2" = "xyes")
-AC_SUBST(USE_GNOME2)
-
 if test x$USE_GLIB2 = xno; then
   dnl Check for glib and gtk
   AM_PATH_GLIB(1.2.0,,
@@ -230,11 +223,24 @@ if test x$USE_GLIB2 = xno; then
               glib gmodule gthread)
   AM_PATH_GTK(1.2.0,,
               AC_MSG_ERROR(Cannot find gtk: Is gtk-config in path?))
+  HAVE_GTK=yes
 
   CORE_LIBS="$CORE_LIBS $GLIB_LIBS $GTK_LIBS"
   CORE_CFLAGS="$CORE_CFLAGS $GLIB_CFLAGS $GTK_CFLAGS"
+else
+  PKG_CHECK_MODULES(GTK2, gtk+-2.0, HAVE_GTK=yes, HAVE_GTK=no)
+
+  GTK_FLAGS=$GTK2_CFLAGS
+  GTK_LIBS=$GTK2_LIBS
+
+  dnl FIXME: check for  gnome2 - this conditional is currently
+  dnl always false.
+  AM_CONDITIONAL(USE_GNOME2, test "x$USE_GNOME2" = "xyes")
+  AC_SUBST(USE_GNOME2)
 fi
 
+AC_SUBST(GTK_LIBS)
+AC_SUBST(GTK_CFLAGS)
 
 dnl Check for libxml
 AC_PATH_PROG(XML_CONFIG, xml-config, no)
@@ -926,12 +932,16 @@ if test "x$USE_DEBUG" = xyes; then
 fi
 
 if test "x$USE_PROFILING" = xyes; then
-  CFLAGS="$CFLAGS -pg"
+  CFLAGS="$CFLAGS -pg -fprofile-arcs"
   FOMIT_FRAME_POINTER=""
 else
   FOMIT_FRAME_POINTER="-fomit-frame-pointer"
 fi
 
+dnl
+dnl AC_SUBST(FOMIT_FRAME_POINTER)
+dnl
+
 if test "x$HAVE_LIBXV" = xyes; then
   AC_DEFINE(HAVE_LIBXV)
 fi
@@ -1024,6 +1034,7 @@ AM_CONDITIONAL(HAVE_NASM,           test "x$HAVE_NASM" = "xyes")
 AM_CONDITIONAL(HAVE_LIBGLADE_GNOME, test "x$HAVE_LIBGLADE_GNOME" = "xyes")
 AM_CONDITIONAL(HAVE_GNOME,          test "x$HAVE_GNOME" = "xyes")
 AM_CONDITIONAL(HAVE_LIBXV,          test "x$HAVE_LIBXV" = "xyes")
+AM_CONDITIONAL(HAVE_GTK,            test "x$HAVE_GTK" = "xyes")
 AM_CONDITIONAL(HAVE_GTK_DOC,        $HAVE_GTK_DOC)
 AM_CONDITIONAL(BUILD_DOCS,          test "x$BUILD_DOCS" = "xyes")
 AM_CONDITIONAL(BUILD_TESTS,         test "x$BUILD_TESTS" = "xyes")
@@ -1176,6 +1187,7 @@ libs/getbits/Makefile
 libs/putbits/Makefile
 libs/idct/Makefile
 libs/audio/Makefile
+libs/bytestream/Makefile
 libs/control/Makefile
 plugins/Makefile
 plugins/a52dec/Makefile
@@ -1285,6 +1297,8 @@ test/Makefile
 test/xml/Makefile
 test/bindings/Makefile
 dnl someone should fix this test/misc/Makefile
+test/memchunk/Makefile
+test/events/Makefile
 tests/Makefile
 tests/sched/Makefile
 tests/eos/Makefile
index ff407ea..050429c 100644 (file)
@@ -116,7 +116,7 @@ The type of the autoplugger.
 
 </para>
 
-@name: 
+@feature: 
 @longdesc: 
 @type: 
 
@@ -207,22 +207,3 @@ The type of the autoplugger.
 @Returns: 
 
 
-<!-- ##### FUNCTION gst_autoplugfactory_save_thyself ##### -->
-<para>
-
-</para>
-
-@factory: 
-@parent: 
-@Returns: 
-
-
-<!-- ##### FUNCTION gst_autoplugfactory_load_thyself ##### -->
-<para>
-
-</para>
-
-@parent: 
-@Returns: 
-
-
index 9214caa..94ccbc2 100644 (file)
@@ -239,6 +239,7 @@ used when data in a stream has been skipped
 
 </para>
 
+@data_type: 
 @lock: 
 @data: 
 @size: 
@@ -265,6 +266,8 @@ used when data in a stream has been skipped
 </para>
 
 @pool: 
+@location: 
+@size: 
 @Returns: 
 
 
@@ -293,9 +296,12 @@ used when data in a stream has been skipped
 
 </para>
 
+@buf: 
+@buf2: 
+@Returns: 
+<!-- # Unused Parameters # -->
 @buffer: 
 @append: 
-@Returns: 
 
 
 <!-- ##### FUNCTION gst_buffer_ref ##### -->
index ddcf3da..874a650 100644 (file)
@@ -52,30 +52,10 @@ A bufferpool can be requested from a pad with the gst_pad_get_bufferpool() funct
 </para>
 
 @lock: 
-@new_user_data: 
-@destroy_user_data: 
-@destroy_buffer: 
-
-<!-- ##### USER_FUNCTION GstBufferPoolCreateFunction ##### -->
-<para>
-The function called when a buffer has to be created for this pool.
-</para>
-
-@pool: the pool from which to create the buffer
-@user_data: any user data
-@Returns: a new buffer from the pool
-
-
-<!-- ##### USER_FUNCTION GstBufferPoolDestroyFunction ##### -->
-<para>
-This function will be called when the given buffer has to be returned to
-the pool.
-</para>
-
-@pool: the pool to return the buffer to
-@buffer: the buffer to return
-@user_data: any user data
-
+@buffer_free: 
+@buffer_copy: 
+@destroy_hook: 
+@user_data: 
 
 <!-- ##### FUNCTION gst_buffer_pool_new ##### -->
 <para>
@@ -85,24 +65,6 @@ the pool.
 @Returns: 
 
 
-<!-- ##### FUNCTION gst_buffer_pool_new_buffer ##### -->
-<para>
-
-</para>
-
-@pool: 
-@Returns: 
-
-
-<!-- ##### FUNCTION gst_buffer_pool_destroy_buffer ##### -->
-<para>
-
-</para>
-
-@pool: 
-@buffer: 
-
-
 <!-- ##### FUNCTION gst_buffer_pool_ref ##### -->
 <para>
 
@@ -130,26 +92,6 @@ the pool.
 @pool: 
 
 
-<!-- ##### FUNCTION gst_buffer_pool_set_create_function ##### -->
-<para>
-
-</para>
-
-@pool: 
-@create: 
-@user_data: 
-
-
-<!-- ##### FUNCTION gst_buffer_pool_set_destroy_function ##### -->
-<para>
-
-</para>
-
-@pool: 
-@destroy: 
-@user_data: 
-
-
 <!-- ##### FUNCTION gst_buffer_pool_destroy ##### -->
 <para>
 
@@ -163,9 +105,10 @@ the pool.
 
 </para>
 
-@oldpool: 
 @buffer_size: 
 @pool_size: 
 @Returns: 
+<!-- # Unused Parameters # -->
+@oldpool: 
 
 
index a7d80b5..1dae1ec 100644 (file)
@@ -47,8 +47,8 @@ Specify how many bytes to read at a time.
 Get/set the current offset in the file.
 </para>
 
-<!-- ##### ARG GstDiskSrc:size ##### -->
+<!-- ##### ARG GstDiskSrc:filesize ##### -->
 <para>
-Get the size of the file.
+
 </para>
 
index 8136a4d..496724a 100644 (file)
@@ -225,7 +225,7 @@ of the element, the GtkType value for it, as well as a pointer to the
 GstElementDetails struct for the element.
 </para>
 
-@name: 
+@feature: 
 @type: 
 @details: 
 @padtemplates: 
@@ -241,14 +241,6 @@ circumstances.
 @element: The element in question.
 
 
-<!-- ##### FUNCTION gst_element_new ##### -->
-<para>
-
-</para>
-
-@Returns: 
-
-
 <!-- ##### MACRO gst_element_destroy ##### -->
 <para>
 
@@ -503,14 +495,6 @@ circumstances.
 @Returns: 
 
 
-<!-- ##### FUNCTION gst_elementfactory_destroy ##### -->
-<para>
-
-</para>
-
-@elementfactory: 
-
-
 <!-- ##### FUNCTION gst_elementfactory_add_padtemplate ##### -->
 <para>
 
@@ -580,25 +564,6 @@ circumstances.
 @Returns: 
 
 
-<!-- ##### FUNCTION gst_elementfactory_save_thyself ##### -->
-<para>
-
-</para>
-
-@factory: 
-@parent: 
-@Returns: 
-
-
-<!-- ##### FUNCTION gst_elementfactory_load_thyself ##### -->
-<para>
-
-</para>
-
-@parent: 
-@Returns: 
-
-
 <!-- ##### SIGNAL GstElement::state-change ##### -->
 <para>
 Is trigered whenever the state of an element changes
index 81869b9..1aac92d 100644 (file)
@@ -24,7 +24,7 @@ with the buffer. (fakesink)
 @gstfakesink: the object which received the signal.
 @arg1: 
 
-<!-- ##### ARG GstFakeSink:num_sinks ##### -->
+<!-- ##### ARG GstFakeSink:num-sinks ##### -->
 <para>
 
 </para>
index 9da5699..323cb0b 100644 (file)
@@ -22,12 +22,12 @@ The <classname>GstFakeSrc</classname> generates empty buffers. (fakesrc)
 @gstfakesrc: the object which received the signal.
 @arg1: 
 
-<!-- ##### ARG GstFakeSrc:num_sources ##### -->
+<!-- ##### ARG GstFakeSrc:num-sources ##### -->
 <para>
 
 </para>
 
-<!-- ##### ARG GstFakeSrc:loop_based ##### -->
+<!-- ##### ARG GstFakeSrc:loop-based ##### -->
 <para>
 
 </para>
@@ -42,7 +42,7 @@ The <classname>GstFakeSrc</classname> generates empty buffers. (fakesrc)
 
 </para>
 
-<!-- ##### ARG GstFakeSrc:num_buffers ##### -->
+<!-- ##### ARG GstFakeSrc:num-buffers ##### -->
 <para>
 
 </para>
index c2309bb..70e5009 100644 (file)
@@ -22,12 +22,12 @@ Pass data without modification.
 @gstidentity: the object which received the signal.
 @arg1: 
 
-<!-- ##### ARG GstIdentity:loop_based ##### -->
+<!-- ##### ARG GstIdentity:loop-based ##### -->
 <para>
 
 </para>
 
-<!-- ##### ARG GstIdentity:sleep_time ##### -->
+<!-- ##### ARG GstIdentity:sleep-time ##### -->
 <para>
 
 </para>
index 0698426..6de54c9 100644 (file)
@@ -141,14 +141,6 @@ Check if the object has been destroyed.
 @obj: The Object to check
 
 
-<!-- ##### FUNCTION gst_object_new ##### -->
-<para>
-
-</para>
-
-@Returns: 
-
-
 <!-- ##### FUNCTION gst_object_check_uniqueness ##### -->
 <para>
 
index 85814e8..3c62b9a 100644 (file)
@@ -189,24 +189,6 @@ a start/stop timecode pair.
 @size: the size of the region to get
 
 
-<!-- ##### USER_FUNCTION GstPadQoSFunction ##### -->
-<para>
-The function that will be called when a QoS message is sent.
-</para>
-
-@pad: the pad that sent the QoS message
-@qos_message: the message
-
-
-<!-- ##### USER_FUNCTION GstPadEOSFunction ##### -->
-<para>
-The function that will be called in an EOS case.
-</para>
-
-@pad: the pad that needs to be set to EOS state
-@Returns: TRUE if EOS was successful, FALSE otherwise
-
-
 <!-- ##### USER_FUNCTION GstPadNewCapsFunction ##### -->
 <para>
 The function that will be called when the caps of the pad has
@@ -247,25 +229,6 @@ The function that will be called when negotiating.
 @Returns: The result of the negotiation process
 
 
-<!-- ##### USER_FUNCTION GstPadPushFunction ##### -->
-<para>
-
-The function that will be called when pushing a buffers.
-</para>
-
-@pad: the pad to push
-@buf: a GstBuffer to push
-
-
-<!-- ##### USER_FUNCTION GstPadPullFunction ##### -->
-<para>
-The function that will be called when pulling buffers.
-</para>
-
-@pad: the pad to pull
-@Returns: a GstBuffer
-
-
 <!-- ##### ENUM GstRegionType ##### -->
 <para>
 the region types for #gst_pad_pullregion.
@@ -383,24 +346,6 @@ Destroy the pad.
 @nego: 
 
 
-<!-- ##### FUNCTION gst_pad_set_qos_function ##### -->
-<para>
-
-</para>
-
-@pad: 
-@qos: 
-
-
-<!-- ##### FUNCTION gst_pad_set_eos_function ##### -->
-<para>
-
-</para>
-
-@pad: 
-@eos: 
-
-
 <!-- ##### FUNCTION gst_pad_set_newcaps_function ##### -->
 <para>
 
@@ -627,32 +572,6 @@ Destroy the pad.
 @Returns: 
 
 
-<!-- ##### FUNCTION gst_pad_set_eos ##### -->
-<para>
-
-</para>
-
-@pad: 
-@Returns: 
-
-
-<!-- ##### FUNCTION gst_pad_handle_qos ##### -->
-<para>
-
-</para>
-
-@pad: 
-@qos_message: 
-
-
-<!-- ##### MACRO gst_pad_eos ##### -->
-<para>
-Call the EOS function of the pad
-</para>
-
-@pad: the pad to call the eos function of.
-
-
 <!-- ##### FUNCTION gst_pad_load_and_connect ##### -->
 <para>
 
@@ -706,15 +625,6 @@ Call the EOS function of the pad
 @Returns: 
 
 
-<!-- ##### FUNCTION gst_pad_eos_func ##### -->
-<para>
-
-</para>
-
-@pad: 
-@Returns: 
-
-
 <!-- ##### STRUCT GstRealPad ##### -->
 <para>
 
@@ -731,12 +641,12 @@ Call the EOS function of the pad
 @len: 
 @sched: 
 @chainfunc: 
+@chainhandler: 
 @getfunc: 
+@gethandler: 
+@eventfunc: 
+@eventhandler: 
 @getregionfunc: 
-@qosfunc: 
-@eosfunc: 
-@pushfunc: 
-@pullfunc: 
 @pullregionfunc: 
 @negotiatefunc: 
 @newcapsfunc: 
@@ -831,22 +741,6 @@ Get the getregion function of the real pad.
 @pad: the real pad to query.
 
 
-<!-- ##### MACRO GST_RPAD_PUSHFUNC ##### -->
-<para>
-Get the pushfunction of the real pad.
-</para>
-
-@pad: the real pad to query.
-
-
-<!-- ##### MACRO GST_RPAD_PULLFUNC ##### -->
-<para>
-Get the pullfunction of the real pad.
-</para>
-
-@pad: the real pad to query.
-
-
 <!-- ##### MACRO GST_RPAD_PULLREGIONFUNC ##### -->
 <para>
 Get the pullregion function of the real pad.
@@ -855,22 +749,6 @@ Get the pullregion function of the real pad.
 @pad: the real pad to query.
 
 
-<!-- ##### MACRO GST_RPAD_QOSFUNC ##### -->
-<para>
-Get the QoS function of the real pad.
-</para>
-
-@pad: the real pad to query.
-
-
-<!-- ##### MACRO GST_RPAD_EOSFUNC ##### -->
-<para>
-Get the EOS function of the real pad.
-</para>
-
-@pad: the real pad to query.
-
-
 <!-- ##### MACRO GST_RPAD_NEGOTIATEFUNC ##### -->
 <para>
 Get the negotiate function from the real pad.
index 6d5d7ba..0668663 100644 (file)
@@ -63,11 +63,9 @@ to bring it into memory.
 @name: 
 @longname: 
 @filename: 
-@types: 
-@numtypes: 
-@elements: 
-@numelements: 
-@numautopluggers: 
+@features: 
+@numfeatures: 
+@module: 
 
 <!-- ##### USER_FUNCTION GstPluginInitFunc ##### -->
 <para>
@@ -198,33 +196,6 @@ loaded will use this variable to initialize the plugin.
 @Returns: 
 
 
-<!-- ##### FUNCTION gst_plugin_add_factory ##### -->
-<para>
-
-</para>
-
-@plugin: 
-@factory: 
-
-
-<!-- ##### FUNCTION gst_plugin_add_type ##### -->
-<para>
-
-</para>
-
-@plugin: 
-@factory: 
-
-
-<!-- ##### FUNCTION gst_plugin_add_autoplugger ##### -->
-<para>
-
-</para>
-
-@plugin: 
-@factory: 
-
-
 <!-- ##### FUNCTION gst_plugin_find ##### -->
 <para>
 
@@ -242,59 +213,6 @@ loaded will use this variable to initialize the plugin.
 @Returns: 
 
 
-<!-- ##### FUNCTION gst_plugin_get_factory_list ##### -->
-<para>
-
-</para>
-
-@plugin: 
-@Returns: 
-
-
-<!-- ##### FUNCTION gst_plugin_get_type_list ##### -->
-<para>
-
-</para>
-
-@plugin: 
-@Returns: 
-
-
-<!-- ##### FUNCTION gst_plugin_get_autoplug_list ##### -->
-<para>
-
-</para>
-
-@plugin: 
-@Returns: 
-
-
-<!-- ##### FUNCTION gst_plugin_load_elementfactory ##### -->
-<para>
-
-</para>
-
-@name: 
-@Returns: 
-
-
-<!-- ##### FUNCTION gst_plugin_load_typefactory ##### -->
-<para>
-
-</para>
-
-@mime: 
-
-
-<!-- ##### FUNCTION gst_plugin_load_autoplugfactory ##### -->
-<para>
-
-</para>
-
-@name: 
-@Returns: 
-
-
 <!-- ##### FUNCTION gst_plugin_load_thyself ##### -->
 <para>
 
index 923850a..afac689 100644 (file)
@@ -35,7 +35,7 @@ The queue blocks by default.
 Get the number of buffers in the queue.
 </para>
 
-<!-- ##### ARG GstQueue:max_level ##### -->
+<!-- ##### ARG GstQueue:max-level ##### -->
 <para>
 Specify the maximum number of buffers in the queue before the queue
 blocks.
index 21d14bc..55f641d 100644 (file)
-<!-- ##### FUNCTION gst_fakesink_chain ##### -->
+<!-- ##### SECTION ./tmpl/GstElement.sgml:Long_Description ##### -->
 <para>
 
 </para>
 
-@pad: 
-@buf: 
 
-<!-- ##### ARG GstTypeFind:type ##### -->
+<!-- ##### SECTION ./tmpl/GstElement.sgml:See_Also ##### -->
 <para>
-Query the element for the current mime type
+
 </para>
 
 
-<!-- ##### ARG GstAudioSink:mute ##### -->
+<!-- ##### SECTION ./tmpl/GstElement.sgml:Short_Description ##### -->
+
+
+
+<!-- ##### SECTION ./tmpl/GstElement.sgml:Title ##### -->
+GstElement
+
+
+<!-- ##### SECTION ./tmpl/audioraw.sgml:Long_Description ##### -->
+<para>
+Information about audio buffers.
+</para>
+
+
+<!-- ##### SECTION ./tmpl/audioraw.sgml:See_Also ##### -->
 <para>
 
 </para>
 
 
-<!-- ##### STRUCT GstFakeSrc ##### -->
+<!-- ##### SECTION ./tmpl/audioraw.sgml:Short_Description ##### -->
+Information about audio buffers.
+
+
+<!-- ##### SECTION ./tmpl/audioraw.sgml:Title ##### -->
+audioraw
+
+
+<!-- ##### SECTION ./tmpl/gstasyncdisksrc.sgml:Long_Description ##### -->
+<para>
+Reads data from a file. You can seek to a specific location by setting
+the offset.
+</para>
+
+
+<!-- ##### SECTION ./tmpl/gstasyncdisksrc.sgml:See_Also ##### -->
 <para>
 
 </para>
 
 
-<!-- ##### FUNCTION gst_tee_get_type ##### -->
+<!-- ##### SECTION ./tmpl/gstasyncdisksrc.sgml:Title ##### -->
+GstAsyncDiskSrc
+
+
+<!-- ##### SECTION ./tmpl/gstaudiosink.sgml:Long_Description ##### -->
 <para>
 
 </para>
 
-@Returns: 
 
-<!-- ##### MACRO GST_IS_SINK ##### -->
+<!-- ##### SECTION ./tmpl/gstaudiosink.sgml:See_Also ##### -->
 <para>
 
 </para>
 
-@obj: 
 
-<!-- ##### MACRO GST_META ##### -->
+<!-- ##### SECTION ./tmpl/gstaudiosink.sgml:Short_Description ##### -->
+
+
+
+<!-- ##### SECTION ./tmpl/gstaudiosink.sgml:Title ##### -->
+GstAudioSink
+
+
+<!-- ##### SECTION ./tmpl/gstaudiosrc.sgml:Long_Description ##### -->
 <para>
 
 </para>
 
-@meta: 
 
-<!-- ##### FUNCTION gst_caps_list_check_compatibility ##### -->
+<!-- ##### SECTION ./tmpl/gstaudiosrc.sgml:See_Also ##### -->
 <para>
 
 </para>
 
-@fromcaps: 
-@tocaps: 
-@Returns: 
 
-<!-- ##### MACRO GST_IS_CONNECTION ##### -->
+<!-- ##### SECTION ./tmpl/gstaudiosrc.sgml:Short_Description ##### -->
+
+
+
+<!-- ##### SECTION ./tmpl/gstaudiosrc.sgml:Title ##### -->
+GstAudioSrc
+
+
+<!-- ##### SECTION ./tmpl/gstcolorspace.sgml:Long_Description ##### -->
 <para>
 
 </para>
 
-@obj: 
 
-<!-- ##### MACRO GST_TYPE_FAKESINK ##### -->
+<!-- ##### SECTION ./tmpl/gstcolorspace.sgml:See_Also ##### -->
 <para>
 
 </para>
 
 
-<!-- ##### FUNCTION gst_pad_remove_ghost_parent ##### -->
+<!-- ##### SECTION ./tmpl/gstcolorspace.sgml:Short_Description ##### -->
+
+
+
+<!-- ##### SECTION ./tmpl/gstcolorspace.sgml:Title ##### -->
+GstColorSpace
+
+
+<!-- ##### SECTION ./tmpl/gstconnection.sgml:Long_Description ##### -->
 <para>
+A connection is a bas class for a generic connection between
+elements. A connection is typically a bas class for queues.
 
 </para>
 
-@pad: 
-@parent: 
 
-<!-- ##### FUNCTION gst_fdsink_chain ##### -->
+<!-- ##### SECTION ./tmpl/gstconnection.sgml:See_Also ##### -->
 <para>
 
 </para>
 
-@pad: 
-@buf: 
 
-<!-- ##### FUNCTION gst_identity_chain ##### -->
+<!-- ##### SECTION ./tmpl/gstconnection.sgml:Short_Description ##### -->
+Generic connection between elements.
+
+
+<!-- ##### SECTION ./tmpl/gstconnection.sgml:Title ##### -->
+GstConnection
+
+
+<!-- ##### SECTION ./tmpl/gstesdsink.sgml:Long_Description ##### -->
 <para>
 
 </para>
 
-@pad: 
-@buf: 
 
-<!-- ##### FUNCTION gst_connection_get_type ##### -->
+<!-- ##### SECTION ./tmpl/gstesdsink.sgml:See_Also ##### -->
 <para>
 
 </para>
 
-@Returns: 
 
-<!-- ##### FUNCTION gst_audiosink_chain ##### -->
+<!-- ##### SECTION ./tmpl/gstesdsink.sgml:Short_Description ##### -->
+
+
+
+<!-- ##### SECTION ./tmpl/gstesdsink.sgml:Title ##### -->
+GstEsdSink
+
+
+<!-- ##### SECTION ./tmpl/gstfilter.sgml:Long_Description ##### -->
+<para>
+Filters take data in and spit data out. They are the main Element in a filter graph.
+Filters have zero or more inputs and zero or more outputs. Filters are connected
+together to form filter graphs. A GstFilter is the base class and is not very usefull
+on its own.
+</para>
+
+
+<!-- ##### SECTION ./tmpl/gstfilter.sgml:See_Also ##### -->
 <para>
 
 </para>
 
-@pad: 
-@buf: 
 
-<!-- ##### MACRO GST_PIPELINE_CLASS ##### -->
+<!-- ##### SECTION ./tmpl/gstfilter.sgml:Short_Description ##### -->
+Take data in and spit data out
+
+
+<!-- ##### SECTION ./tmpl/gstfilter.sgml:Title ##### -->
+GstFilter
+
+
+<!-- ##### SECTION ./tmpl/gstgetbits.sgml:Long_Description ##### -->
 <para>
 
 </para>
 
-@klass: 
 
-<!-- ##### FUNCTION gst_elementfactory_add_src ##### -->
+<!-- ##### SECTION ./tmpl/gstgetbits.sgml:See_Also ##### -->
 <para>
 
 </para>
 
-@elementfactory: 
-@id: 
 
-<!-- ##### STRUCT GstConnectionClass ##### -->
+<!-- ##### SECTION ./tmpl/gstgetbits.sgml:Short_Description ##### -->
+
+
+
+<!-- ##### SECTION ./tmpl/gstgetbits.sgml:Title ##### -->
+GstGetbits
+
+
+<!-- ##### SECTION ./tmpl/gstmeta.sgml:Long_Description ##### -->
 <para>
+The point of the metadata is to provide some context for each buffer.  In
+the case of audio data, for instance, it would provide the samplerate, bit
+depth, and channel count.
+</para>
 
+<para>
+The trick is that there may be multiple types of metadata ganged onto a
+single buffer.  This is why they're going to be a GList.  This does mean
+extra overhead in all cases, but I think it's minimal.  The GList type
+uses a chunk allocater so we're not wasting too much memory or time when
+adding to the list.
 </para>
 
+<para>
+The trick is dealing with these structs as they pass through a pipeline,
+since they have potentially different mutability properties.  For
+instance, if you've got a mp3 decoder connected to a tee, which sends the
+buffers off to both the decoder and a spectrum analyzer (and then a
+visualization element).  The preferred setup would be where every time a
+audio/raw metadata comes down the pipe (indicating a potential change in
+audio format), the audiosink and spectrum would just save off pointers.
+</para>
 
-<!-- ##### ARG GstSineSrc:channels ##### -->
 <para>
-The number of channels.
+So when exactly does this metadata go away (deallocated)?  Well, that
+means metadata has to be refcounted.  But that gets rather hairy.  OK, in
+the simple case you create a metadata struct, it comes with refcount set
+to 1.  You pass it through, it stays one, eventually someone drops the
+last reference on the buffer it's tied to, you free the metadata too.
+Easy.  What if you tee?  You could go through and for every metadata in
+the buffer, increment the refcount by the same as the buffer.  So in the
+above case (tee'd), the audiosink and spectrum would get the buffer with a
+refcount of 2, and it'd have a metadata with refcount 2.  Do they ref it
+each themselves, then unref the buffer?  Or do they remove the metadata?
+Removing the metadata would require a buffer CoW, which would suck, so
+yes, they'd just ref the metadata.
+</para>
+
+<para>
+But....  what if they're all in different threads?  Then we're off into
+the magical world of mutexes.  Everything with a refcount in a threaded
+world must be mutexed, else you can do atomic increment and atomic
+dec and test.  Can this be done from C easily?  Perhaps it needs to be found
+from kernel includes via autoconf?
+</para>
+
+<para>
+The goal in designing the way metadata will be defined and used is to keep
+it as simple as possible.  The basis for accomplishing this is the fact
+that in order to actually use (rather than just pass) the metadata, you
+have to know what the fields are, which means you have to have compiled in
+support for that metadata at build time.  Therefore, if you're using
+metadata, you must have build-time access to the necessary include file
+that defines it.
+</para>
+
+<para>
+So, given that you've got an include file, it would be nice if the whole
+thing could be contained there.  This would limit the need to be linked
+against something, or have load-time requirements as to that has to be
+loaded before you are.
+</para>
+
+<para>
+Given that really all metadata is is a region of memory of a given size
+with a certain signature, this isn't all that hard.  First you lay out the
+struct that defines the metadata.  Then you set up #defines that expand to
+the size of the struct in question, as well as the four-cc code that
+defines the type.
+</para>
+
+<para>
+The work is done by a few #defines, a la the #defines used in all Gtk
+objects.  The first is a NEW() method that allocates the memory for the
+metadata and fills in all the normal fields (type, size, utility
+functions).  Because of the way it's defined (as a #define, no less),
+you'll have to invoke it as META_NEW(meta), since it can't return()
+anything.
+</para>
+
+<para>
+Another #define will check to make sure a meta is indeed that type by
+verifying the type code and size.  Theoretically, meta types can overlap
+with the same fourcc code, as long as they have different sizes.  But I
+probably ought to have a global public registry so people writing things
+don't conflict.  MSFT got that right, at least.
+</para>
+
+<para>
+So, a hairy problem is what to do when there are utility functions
+associated with one of these things.  One option is to not bother with
+them.  This is very likely a possible solution, since metadata is supposed
+to be flat memory of a given size.  Not much to do to either free or copy
+it, is there?
+</para>
+
+
+<!-- ##### SECTION ./tmpl/gstmeta.sgml:See_Also ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### SECTION ./tmpl/gstmeta.sgml:Short_Description ##### -->
+Provide context for buffers
+
+
+<!-- ##### SECTION ./tmpl/gstmeta.sgml:Title ##### -->
+GstMeta
+
+
+<!-- ##### SECTION ./tmpl/gstsink.sgml:Long_Description ##### -->
+<para>
+The sink is the end of the filter graph. A typical sink would be an audio
+or a video card.
+
+</para>
+
+
+<!-- ##### SECTION ./tmpl/gstsink.sgml:See_Also ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### SECTION ./tmpl/gstsink.sgml:Short_Description ##### -->
+The end point of a filter graph
+
+
+<!-- ##### SECTION ./tmpl/gstsink.sgml:Title ##### -->
+GstSink
+
+
+<!-- ##### SECTION ./tmpl/gstsrc.sgml:Long_Description ##### -->
+<para>
+A GstSrc is the start of a filter graph. It typically is a file or an
+audio source. It provides data for the next element in the graph.
+
+</para>
+
+
+<!-- ##### SECTION ./tmpl/gstsrc.sgml:See_Also ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### SECTION ./tmpl/gstsrc.sgml:Short_Description ##### -->
+The start point of a filter graph
+
+
+<!-- ##### SECTION ./tmpl/gstsrc.sgml:Title ##### -->
+GstSrc
+
+
+<!-- ##### SECTION ./tmpl/plugin.sgml:Long_Description ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### SECTION ./tmpl/plugin.sgml:See_Also ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### SECTION ./tmpl/plugin.sgml:Short_Description ##### -->
+
+
+
+<!-- ##### SECTION ./tmpl/plugin.sgml:Title ##### -->
+plugin
+
+
+<!-- ##### SECTION ./tmpl/spectrum.sgml:Long_Description ##### -->
+<para>
+Frequencies of a spectrum analysis.
+
+</para>
+
+
+<!-- ##### SECTION ./tmpl/spectrum.sgml:See_Also ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### SECTION ./tmpl/spectrum.sgml:Short_Description ##### -->
+Frequencies of a spectrum analysis.
+
+
+<!-- ##### SECTION ./tmpl/spectrum.sgml:Title ##### -->
+spectrum
+
+
+<!-- ##### SECTION ./tmpl/videoraw.sgml:Long_Description ##### -->
+<para>
+Information about video buffers.
+</para>
+
+
+<!-- ##### SECTION ./tmpl/videoraw.sgml:See_Also ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### SECTION ./tmpl/videoraw.sgml:Short_Description ##### -->
+Information about video buffers.
+
+
+<!-- ##### SECTION ./tmpl/videoraw.sgml:Title ##### -->
+videoraw
+
+
+<!-- ##### MACRO COTHREAD_MAXTHREADS ##### -->
+<para>
+The maximum number of cothreads we are going to support.
+</para>
+
+
+<!-- ##### MACRO COTHREAD_STACKSIZE ##### -->
+<para>
+The default stack size of a cothread.
 </para>
 
 
@@ -144,223 +441,330 @@ g_print messages.
 @format: the format specification as in g_print
 @args...: arguments
 
-<!-- ##### SECTION ./tmpl/gstesdsink.sgml:Title ##### -->
-GstEsdSink
+<!-- ##### MACRO DEBUG_ENTER ##### -->
+<para>
+
+</para>
+
+@format: 
+@args...: 
+
+<!-- ##### MACRO DEBUG_ENTER_STRING ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO DEBUG_LEAVE ##### -->
+<para>
+
+</para>
+
+@format: 
+@args...: 
+
+<!-- ##### MACRO DEBUG_LEAVE_STRING ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### MACRO DEBUG_NOPREFIX ##### -->
+<para>
+
+</para>
+
+@format: 
+@args...: 
+
+<!-- ##### MACRO DEBUG_SET_STRING ##### -->
+<para>
+
+</para>
+
+@format: 
+@args...: 
+
+<!-- ##### MACRO ERROR ##### -->
+<para>
+
+</para>
+
+@element: 
+@format: 
+@args...: 
+
+<!-- ##### MACRO ERROR_OBJECT ##### -->
+<para>
+
+</para>
+
+@element: 
+@object: 
+@format: 
+@args...: 
+
+<!-- ##### MACRO GST_ASYNCDISKSRC ##### -->
+<para>
+
+</para>
+
+@obj: 
+
+<!-- ##### MACRO GST_ASYNCDISKSRC_CLASS ##### -->
+<para>
+
+</para>
+
+@klass: 
+
+<!-- ##### MACRO GST_AUDIOSINK ##### -->
+<para>
+
+</para>
+
+@obj: 
+
+<!-- ##### MACRO GST_AUDIOSINK_CLASS ##### -->
+<para>
+
+</para>
+
+@klass: 
+
+<!-- ##### MACRO GST_AUDIOSRC ##### -->
+<para>
+
+</para>
+
+@obj: 
+
+<!-- ##### MACRO GST_AUDIOSRC_CLASS ##### -->
+<para>
+
+</para>
 
+@klass: 
 
-<!-- ##### MACRO GST_TYPE_IDENTITY ##### -->
+<!-- ##### MACRO GST_BIN ##### -->
 <para>
 
 </para>
 
+@obj: 
 
-<!-- ##### FUNCTION gst_type_save_thyself ##### -->
+<!-- ##### MACRO GST_BIN_CLASS ##### -->
 <para>
 
 </para>
 
-@type: 
-@parent: 
-@Returns: 
+@klass: 
 
-<!-- ##### FUNCTION gst_audiosrc_push ##### -->
+<!-- ##### MACRO GST_BUFFER ##### -->
 <para>
 
 </para>
 
-@src
+@buf
 
-<!-- ##### MACRO GST_IS_FAKESRC_CLASS ##### -->
+<!-- ##### MACRO GST_BUFFER_POOL ##### -->
 <para>
 
 </para>
 
-@obj
+@buf
 
-<!-- ##### SECTION ./tmpl/gstaudiosrc.sgml:See_Also ##### -->
+<!-- ##### MACRO GST_BUFFER_TYPE ##### -->
 <para>
-
+Retrieves the type id of the data in the buffer.
 </para>
 
+@buf: GstBuffer
 
-<!-- ##### MACRO GST_AUDIOSINK ##### -->
+<!-- ##### MACRO GST_CONNECTION ##### -->
 <para>
 
 </para>
 
 @obj: 
 
-<!-- ##### SIGNAL GstSrc::eos ##### -->
+<!-- ##### MACRO GST_CONNECTION_CLASS ##### -->
 <para>
-An eos signal is triggered whenever the GstSrc has reached the end of 
-the stream.
 
 </para>
 
-@gstsrc: the object which received the signal.
-@arg1: the object which received the signal
+@klass: 
 
-<!-- ##### TYPEDEF GstCapsFactoryEntry ##### -->
+<!-- ##### MACRO GST_CPU_FLAG_MMX ##### -->
 <para>
-
+A flag indicating that MMX instructions are supported.
 </para>
 
 
-<!-- ##### FUNCTION gst_disksrc_get_type ##### -->
+<!-- ##### MACRO GST_CPU_FLAG_SSE ##### -->
 <para>
-
+A flag indicating that SSE instructions are supported.
 </para>
 
-@Returns: 
 
-<!-- ##### MACRO GST_IS_DISKSRC_CLASS ##### -->
+<!-- ##### MACRO GST_DEBUG_ENTER_STRING ##### -->
 <para>
-
+Combine #GST_DEBUG_ENTER and #GST_DEBUG_SET_STRING.
 </para>
 
-@obj: 
 
-<!-- ##### SECTION ./tmpl/gstmeta.sgml:Short_Description ##### -->
-Provide context for buffers
+<!-- ##### MACRO GST_DEBUG_LEAVE_STRING ##### -->
+<para>
+
+</para>
 
 
-<!-- ##### MACRO DEBUG_ENTER_STRING ##### -->
+<!-- ##### MACRO GST_DEBUG_NOPREFIX ##### -->
 <para>
 
 </para>
 
+@cat: 
+@format: 
+@args...: 
 
-<!-- ##### SECTION ./tmpl/audioraw.sgml:See_Also ##### -->
+<!-- ##### MACRO GST_DEBUG_PREFIX ##### -->
 <para>
 
 </para>
 
+@cat: 
+@format: 
+@args...: 
 
-<!-- ##### FUNCTION gst_padtemplate_create ##### -->
+<!-- ##### MACRO GST_DEBUG_SET_STRING ##### -->
 <para>
-
+Set the debug string for the current function, typically containing the arguments
+to the current function, i.e. "('element')"
 </para>
 
-@name_template: 
-@direction: 
-@presence: 
-@caps: 
-@Returns: 
+@format: printf-style format string
+@args...: printf arguments
 
-<!-- ##### MACRO GST_IS_ESDSINK_CLASS ##### -->
+<!-- ##### MACRO GST_DISKSRC ##### -->
 <para>
 
 </para>
 
 @obj: 
 
-<!-- ##### SECTION ./tmpl/gstgetbits.sgml:See_Also ##### -->
+<!-- ##### MACRO GST_DISKSRC_CLASS ##### -->
 <para>
 
 </para>
 
+@klass: 
 
-<!-- ##### MACRO GST_SRC ##### -->
+<!-- ##### MACRO GST_ELEMENT ##### -->
 <para>
 
 </para>
 
 @obj: 
 
-<!-- ##### FUNCTION gst_sink_new ##### -->
+<!-- ##### MACRO GST_ELEMENT_CLASS ##### -->
 <para>
 
 </para>
 
-@name: 
-@Returns: 
+@klass: 
 
-<!-- ##### MACRO GST_PAD_CLASS ##### -->
+<!-- ##### MACRO GST_ELEMENT_IS_MULTI_IN ##### -->
 <para>
+Query whether this object has multiple input pads.
 
 </para>
 
-@klass: 
+@obj: Element to query for multiple input pads.
 
-<!-- ##### FUNCTION plugin_load_all ##### -->
+<!-- ##### MACRO GST_ESDSINK ##### -->
 <para>
 
 </para>
 
+@obj: 
 
-<!-- ##### MACRO GST_SINESRC_CLASS ##### -->
+<!-- ##### MACRO GST_ESDSINK_CLASS ##### -->
 <para>
 
 </para>
 
-@klass: 
+@klass: <<<<<<< gstreamer-unused.sgml
 
-<!-- ##### FUNCTION gst_pad_save_thyself ##### -->
+<!-- ##### MACRO GST_FAKESINK ##### -->
 <para>
 
 </para>
 
-@pad: 
-@parent: 
-@Returns: 
+@obj: 
 
-<!-- ##### MACRO GST_IS_AUDIOSINK_CLASS ##### -->
+<!-- ##### MACRO GST_FAKESINK_CLASS ##### -->
 <para>
 
 </para>
 
-@obj
+@klass
 
-<!-- ##### STRUCT GstDiskSrc ##### -->
+<!-- ##### MACRO GST_FAKESRC ##### -->
 <para>
 
 </para>
 
+@obj: 
 
-<!-- ##### ARG GstDiskSink:location ##### -->
+<!-- ##### MACRO GST_FAKESRC_CLASS ##### -->
 <para>
-The filename to write to.
+
 </para>
 
+@klass: 
 
-<!-- ##### MACRO GST_IS_SRC_CLASS ##### -->
+<!-- ##### MACRO GST_FDSINK ##### -->
 <para>
 
 </para>
 
 @obj: 
 
-<!-- ##### ARG GstAsyncDiskSrc:bytesperread ##### -->
+<!-- ##### MACRO GST_FDSINK_CLASS ##### -->
 <para>
-Specify how many bytes to read at a time.
+
 </para>
 
+@klass: 
 
-<!-- ##### FUNCTION gst_filter_new ##### -->
+<!-- ##### MACRO GST_FDSRC ##### -->
 <para>
 
 </para>
 
-@name: 
-@Returns: 
+@obj: 
 
-<!-- ##### SECTION ./tmpl/gstesdsink.sgml:Short_Description ##### -->
+<!-- ##### MACRO GST_FDSRC_CLASS ##### -->
+<para>
 
+</para>
 
+@klass: 
 
-<!-- ##### FUNCTION gst_sink_get_type ##### -->
+<!-- ##### MACRO GST_FILTER ##### -->
 <para>
 
 </para>
 
-@Returns
+@obj
 
-<!-- ##### FUNCTION gst_queue_push ##### -->
+<!-- ##### MACRO GST_FILTER_CLASS ##### -->
 <para>
 
 </para>
 
-@connection
+@klass
 
 <!-- ##### MACRO GST_FILTER_FLAG_LAST ##### -->
 <para>
@@ -368,1090 +772,1001 @@ subclass use this to start their flag enumeration
 </para>
 
 
-<!-- ##### FUNCTION gst_audiosink_set_channels ##### -->
+<!-- ##### MACRO GST_HTTPSRC ##### -->
+>>>>>>> 1.23.2.3
 <para>
 
 </para>
 
-@audiosink: 
-@channels: 
+@obj: 
 
-<!-- ##### SECTION ./tmpl/gstconnection.sgml:Short_Description ##### -->
-Generic connection between elements.
+<!-- ##### MACRO GST_HTTPSRC_CLASS ##### -->
+<para>
 
+</para>
 
-<!-- ##### STRUCT GstSinkClass ##### -->
+@klass: 
+
+<!-- ##### MACRO GST_IDENTITY ##### -->
 <para>
 
 </para>
 
+@obj: 
 
-<!-- ##### STRUCT GstFilterClass ##### -->
+<!-- ##### MACRO GST_IDENTITY_CLASS ##### -->
 <para>
 
 </para>
 
+@klass: 
 
-<!-- ##### MACRO GST_FDSINK ##### -->
+<!-- ##### MACRO GST_IS_ASYNCDISKSRC ##### -->
 <para>
 
 </para>
 
 @obj: 
 
-<!-- ##### FUNCTION gst_bin_schedule ##### -->
+<!-- ##### MACRO GST_IS_ASYNCDISKSRC_CLASS ##### -->
 <para>
 
 </para>
 
-@bin
+@obj
 
-<!-- ##### MACRO ERROR ##### -->
+<!-- ##### MACRO GST_IS_AUDIOSINK ##### -->
 <para>
 
 </para>
 
-@element: 
-@format: 
-@args...: 
+@obj: 
 
-<!-- ##### STRUCT MetaVideoRaw ##### -->
+<!-- ##### MACRO GST_IS_AUDIOSINK_CLASS ##### -->
 <para>
 
 </para>
 
-@meta: 
-@format: 
-@visual: 
-@width: 
-@height: 
-@overlay_info: 
-@dga_info: 
+@obj: 
 
-<!-- ##### FUNCTION gst_meta_ref ##### -->
+<!-- ##### MACRO GST_IS_AUDIOSRC ##### -->
 <para>
 
 </para>
 
-@meta
+@obj
 
-<!-- ##### SECTION ./tmpl/gstaudiosink.sgml:See_Also ##### -->
+<!-- ##### MACRO GST_IS_AUDIOSRC_CLASS ##### -->
 <para>
 
 </para>
 
+@obj: 
 
-<!-- ##### MACRO GST_FILTER ##### -->
+<!-- ##### MACRO GST_IS_BIN ##### -->
 <para>
 
 </para>
 
 @obj: 
 
-<!-- ##### MACRO GST_DEBUG_LEAVE_STRING ##### -->
+<!-- ##### MACRO GST_IS_BIN_CLASS ##### -->
 <para>
 
 </para>
 
+@obj: 
 
-<!-- ##### FUNCTION gst_esdsink_set_channels ##### -->
+<!-- ##### MACRO GST_IS_CONNECTION ##### -->
 <para>
 
 </para>
 
-@esdsink: 
-@channels: 
+@obj: 
 
-<!-- ##### FUNCTION gst_autoplug_caps_list ##### -->
+<!-- ##### MACRO GST_IS_CONNECTION_CLASS ##### -->
 <para>
 
 </para>
 
-@autoplug: 
-@srcpad: 
-@sinkpad: 
-@Varargs: 
-@Returns: 
-@srccaps: 
-@sinkcaps: 
+@obj: 
 
-<!-- ##### MACRO GST_ELEMENT ##### -->
+<!-- ##### MACRO GST_IS_DISKSRC ##### -->
 <para>
 
 </para>
 
 @obj: 
 
-<!-- ##### ARG GstQueue:block ##### -->
+<!-- ##### MACRO GST_IS_DISKSRC_CLASS ##### -->
 <para>
-Specify wether the queue blocks or not. 
+
 </para>
 
+@obj: 
 
-<!-- ##### FUNCTION gst_pad_pull_region ##### -->
+<!-- ##### MACRO GST_IS_ELEMENT ##### -->
 <para>
 
 </para>
 
-@pad: 
-@offset: 
-@size: 
-@Returns: 
+@obj: 
 
-<!-- ##### FUNCTION gst_fdsink_new_with_fd ##### -->
+<!-- ##### MACRO GST_IS_ELEMENT_CLASS ##### -->
 <para>
 
 </para>
 
-@name: 
-@fd: 
-@Returns: 
+@obj: 
 
-<!-- ##### MACRO GST_IS_ELEMENT_CLASS ##### -->
+<!-- ##### MACRO GST_IS_ESDSINK ##### -->
 <para>
 
 </para>
 
 @obj: 
 
-<!-- ##### STRUCT GstSrcClass ##### -->
+<!-- ##### MACRO GST_IS_ESDSINK_CLASS ##### -->
 <para>
 
 </para>
 
+@obj: 
 
-<!-- ##### ARG GstIdentity:control ##### -->
+<!-- ##### MACRO GST_IS_FAKESINK ##### -->
 <para>
 
 </para>
 
+@obj: 
 
-<!-- ##### TYPEDEF GstPropsListFactory[] ##### -->
+<!-- ##### MACRO GST_IS_FAKESINK_CLASS ##### -->
 <para>
 
 </para>
 
+@obj: 
 
-<!-- ##### MACRO GST_PAD ##### -->
+<!-- ##### MACRO GST_IS_FAKESRC ##### -->
 <para>
 
 </para>
 
 @obj: 
 
-<!-- ##### FUNCTION gst_pad_set_pull_function ##### -->
+<!-- ##### MACRO GST_IS_FAKESRC_CLASS ##### -->
 <para>
 
 </para>
 
-@pad: 
-@pull: 
+@obj: 
 
-<!-- ##### STRUCT GstSink ##### -->
+<!-- ##### MACRO GST_IS_FDSINK ##### -->
 <para>
 
 </para>
 
+@obj: 
 
-<!-- ##### FUNCTION gst_pipeline_get_type ##### -->
+<!-- ##### MACRO GST_IS_FDSINK_CLASS ##### -->
 <para>
 
 </para>
 
-@Returns
+@obj
 
-<!-- ##### MACRO GST_IS_THREAD ##### -->
+<!-- ##### MACRO GST_IS_FDSRC ##### -->
 <para>
 
 </para>
 
 @obj: 
 
-<!-- ##### MACRO GST_TYPE_THREAD ##### -->
+<!-- ##### MACRO GST_IS_FDSRC_CLASS ##### -->
 <para>
 
 </para>
 
+@obj: 
 
-<!-- ##### STRUCT GstAsyncDiskSrcClass ##### -->
+<!-- ##### MACRO GST_IS_FILTER ##### -->
 <para>
 
 </para>
 
+@obj: 
 
-<!-- ##### FUNCTION gst_pad_set_caps_list ##### -->
+<!-- ##### MACRO GST_IS_FILTER_CLASS ##### -->
 <para>
 
 </para>
 
-@pad: 
-@caps: 
+@obj: 
 
-<!-- ##### MACRO GST_PROPS_FOURCC_INT ##### -->
+<!-- ##### MACRO GST_IS_HTTPSRC ##### -->
 <para>
-Create a fourcc property out of an integer value.
+
 </para>
 
-@a: the integer value
+@obj: 
 
-<!-- ##### MACRO GST_TYPE_SINK ##### -->
+<!-- ##### MACRO GST_IS_HTTPSRC_CLASS ##### -->
 <para>
 
 </para>
 
+@obj: 
 
-<!-- ##### MACRO DEBUG_SET_STRING ##### -->
+<!-- ##### MACRO GST_IS_IDENTITY ##### -->
 <para>
 
 </para>
 
-@format: 
-@args...: 
+@obj: 
 
-<!-- ##### MACRO GST_IS_THREAD_CLASS ##### -->
+<!-- ##### MACRO GST_IS_IDENTITY_CLASS ##### -->
 <para>
 
 </para>
 
 @obj: 
 
-<!-- ##### FUNCTION gst_bin_get_type ##### -->
+<!-- ##### MACRO GST_IS_OBJECT ##### -->
 <para>
 
 </para>
 
-@Returns
+@obj
 
-<!-- ##### ARG GstAsyncDiskSrc:offset ##### -->
+<!-- ##### MACRO GST_IS_OBJECT_CLASS ##### -->
 <para>
-Specify the current offset in the file.
+
 </para>
 
+@obj: 
 
-<!-- ##### MACRO STACK_SIZE ##### -->
+<!-- ##### MACRO GST_IS_PAD ##### -->
 <para>
 
 </para>
 
+@obj: 
 
-<!-- ##### MACRO GST_TYPE_AUDIOSINK ##### -->
+<!-- ##### MACRO GST_IS_PAD_CLASS ##### -->
 <para>
 
 </para>
 
+@obj: 
 
-<!-- ##### SECTION ./tmpl/plugin.sgml:Long_Description ##### -->
+<!-- ##### MACRO GST_IS_PIPELINE ##### -->
 <para>
 
 </para>
 
+@obj: 
 
-<!-- ##### MACRO GST_FILTER_CLASS ##### -->
+<!-- ##### MACRO GST_IS_PIPELINE_CLASS ##### -->
 <para>
 
 </para>
 
-@klass
+@obj
 
-<!-- ##### FUNCTION gst_pad_select ##### -->
+<!-- ##### MACRO GST_IS_QUEUE ##### -->
 <para>
 
 </para>
 
-@nextpad: 
-@Varargs: 
-@Returns: 
+@obj: 
 
-<!-- ##### FUNCTION gst_identity_get_type ##### -->
+<!-- ##### MACRO GST_IS_QUEUE_CLASS ##### -->
 <para>
 
 </para>
 
-@Returns
+@obj
 
-<!-- ##### TYPEDEF GstCapsFactory[] ##### -->
+<!-- ##### MACRO GST_IS_SINESRC ##### -->
 <para>
 
 </para>
 
+@obj: 
 
-<!-- ##### MACRO GST_PROPS_BOOL_ID ##### -->
+<!-- ##### MACRO GST_IS_SINESRC_CLASS ##### -->
 <para>
 
 </para>
 
+@obj: 
 
-<!-- ##### FUNCTION gst_meta_unref ##### -->
+<!-- ##### MACRO GST_IS_SINK ##### -->
 <para>
 
 </para>
 
-@meta
+@obj
 
-<!-- ##### STRUCT GstSineSrc ##### -->
+<!-- ##### MACRO GST_IS_SINK_CLASS ##### -->
 <para>
 
 </para>
 
+@obj: 
 
-<!-- ##### STRUCT MetaDGA ##### -->
+<!-- ##### MACRO GST_IS_SRC ##### -->
 <para>
 
 </para>
 
-@base: 
-@swidth: 
-@sheight: 
-@bytes_per_line: 
-
-<!-- ##### SECTION ./tmpl/spectrum.sgml:Title ##### -->
-spectrum
-
+@obj: 
 
-<!-- ##### SECTION ./tmpl/GstElement.sgml:Long_Description ##### -->
+<!-- ##### MACRO GST_IS_SRC_CLASS ##### -->
 <para>
 
 </para>
 
+@obj: 
 
-<!-- ##### ARG GstAudioSink:format ##### -->
+<!-- ##### MACRO GST_IS_TEE ##### -->
 <para>
 
 </para>
 
+@obj: 
 
-<!-- ##### MACRO GST_IS_FAKESINK_CLASS ##### -->
+<!-- ##### MACRO GST_IS_TEE_CLASS ##### -->
 <para>
 
 </para>
 
 @obj: 
 
-<!-- ##### MACRO GST_AUDIOSRC_CLASS ##### -->
+<!-- ##### MACRO GST_IS_THREAD ##### -->
 <para>
 
 </para>
 
-@klass
+@obj
 
-<!-- ##### STRUCT GstAudioSrcClass ##### -->
+<!-- ##### MACRO GST_IS_THREAD_CLASS ##### -->
 <para>
 
 </para>
 
+@obj: 
 
-<!-- ##### FUNCTION gst_audiosrc_new ##### -->
+<!-- ##### MACRO GST_META ##### -->
 <para>
 
 </para>
 
-@name: 
-@Returns: 
+@meta: 
 
-<!-- ##### STRUCT GstConnection ##### -->
+<!-- ##### MACRO GST_META_FLAGS ##### -->
 <para>
-
+Retrieve the flags of the given meta information.
 </para>
 
+@meta: the meta information
 
-<!-- ##### STRUCT GstQueueClass ##### -->
+<!-- ##### MACRO GST_META_FLAG_IS_SET ##### -->
 <para>
-
+Check if a given flag is set.
 </para>
 
+@meta: the meta data to test
+@flag: the flag to test
 
-<!-- ##### FUNCTION gst_fakesrc_push ##### -->
+<!-- ##### MACRO GST_META_FLAG_SET ##### -->
 <para>
-
+Set a flag in the meta data.
 </para>
 
-@src: 
+@meta: the meta data
+@flag: the flag to set
 
-<!-- ##### FUNCTION gst_type_add_sink ##### -->
+<!-- ##### MACRO GST_META_FLAG_UNSET ##### -->
 <para>
-
+Clear a flag in the meta data.
 </para>
 
-@id: 
-@sink: 
+@meta: the meta data
+@flag: the flag to clear
 
-<!-- ##### MACRO GST_IS_IDENTITY_CLASS ##### -->
+<!-- ##### MACRO GST_OBJECT ##### -->
 <para>
 
 </para>
 
 @obj: 
 
-<!-- ##### SECTION ./tmpl/gstgetbits.sgml:Title ##### -->
-GstGetbits
-
-
-<!-- ##### SECTION ./tmpl/audioraw.sgml:Title ##### -->
-audioraw
-
-
-<!-- ##### MACRO GST_FDSINK_CLASS ##### -->
+<!-- ##### MACRO GST_OBJECT_CLASS ##### -->
 <para>
 
 </para>
 
 @klass: 
 
-<!-- ##### FUNCTION gst_fdsink_new ##### -->
+<!-- ##### MACRO GST_OBJECT_FLAG_LAST ##### -->
 <para>
-
+subclasses can use this value to start the enumeration of their flags
 </para>
 
-@name: 
-@Returns: 
 
-<!-- ##### FUNCTION gst_element_save_thyself ##### -->
+<!-- ##### MACRO GST_PAD ##### -->
 <para>
 
 </para>
 
-@element: 
-@parent: 
-@Returns: 
+@obj: 
 
-<!-- ##### MACRO GST_IS_TEE ##### -->
+<!-- ##### MACRO GST_PAD_CLASS ##### -->
 <para>
 
 </para>
 
-@obj
+@klass
 
-<!-- ##### FUNCTION gst_type_get_sink_to_src ##### -->
+<!-- ##### MACRO GST_PAD_FACTORY_ALWAYS ##### -->
 <para>
-
+Indicate that this pad will always be available.
+Use this in the factory definition.
 </para>
 
-@sinkid: 
-@srcid: 
-@Returns: 
 
-<!-- ##### MACRO GST_PROPS_INT_ID ##### -->
+<!-- ##### MACRO GST_PAD_FACTORY_CAPS ##### -->
 <para>
-
+Starts the declaration of a the capabilities for this padtemplate.
 </para>
 
+@a...: a capability factory
 
-<!-- ##### STRUCT GstTeeClass ##### -->
+<!-- ##### MACRO GST_PAD_FACTORY_REQUEST ##### -->
 <para>
-
+Indicates that this pad will be available on request. Use 
+this in the factory definition. 
 </para>
 
 
-<!-- ##### MACRO GST_FAKESINK ##### -->
+<!-- ##### MACRO GST_PAD_FACTORY_SINK ##### -->
 <para>
-
+Indicates a sinkpad for the padfactory.
 </para>
 
-@obj: 
 
-<!-- ##### FUNCTION gst_type_get_srcs ##### -->
+<!-- ##### MACRO GST_PAD_FACTORY_SOMETIMES ##### -->
 <para>
-
+Indicate that this pad will become available depending
+on the media type. Use this in the factory definition.
 </para>
 
-@id: 
-@Returns: 
 
-<!-- ##### FUNCTION gst_esdsink_set_frequency ##### -->
+<!-- ##### MACRO GST_PAD_FACTORY_SRC ##### -->
 <para>
-
+Indicates a srcpad for the padfactory.
 </para>
 
-@esdsink: 
-@frequency: 
 
-<!-- ##### SECTION ./tmpl/gstgetbits.sgml:Short_Description ##### -->
+<!-- ##### MACRO GST_PIPELINE ##### -->
+<para>
 
+</para>
 
+@obj: 
 
-<!-- ##### MACRO GST_TYPE_SRC ##### -->
+<!-- ##### MACRO GST_PIPELINE_CLASS ##### -->
 <para>
 
 </para>
 
+@klass: 
 
-<!-- ##### MACRO GST_FAKESRC ##### -->
+<!-- ##### MACRO GST_PROPS_BOOL_ID ##### -->
 <para>
 
 </para>
 
-@obj: 
 
-<!-- ##### MACRO GST_IS_HTTPSRC ##### -->
+<!-- ##### MACRO GST_PROPS_FLOAT_RANGE_STRING ##### -->
 <para>
 
 </para>
 
-@obj: 
+@a: 
+@b: 
 
-<!-- ##### MACRO GST_DEBUG_NOPREFIX ##### -->
+<!-- ##### MACRO GST_PROPS_FLOAT_STRING ##### -->
 <para>
 
 </para>
 
-@cat: 
-@format: 
-@args...: 
+@a: 
 
-<!-- ##### MACRO GST_IDENTITY ##### -->
+<!-- ##### MACRO GST_PROPS_FOURCC_ID ##### -->
 <para>
 
 </para>
 
-@obj: 
 
-<!-- ##### ARG GstAudioSrc:format ##### -->
+<!-- ##### MACRO GST_PROPS_FOURCC_INT ##### -->
 <para>
-The audio format as defined in soundcard.h
+Create a fourcc property out of an integer value.
 </para>
 
+@a: the integer value
 
-<!-- ##### MACRO GST_IS_HTTPSRC_CLASS ##### -->
+<!-- ##### MACRO GST_PROPS_INT_ID ##### -->
 <para>
 
 </para>
 
-@obj: 
-
-<!-- ##### SECTION ./tmpl/gstasyncdisksrc.sgml:Title ##### -->
-GstAsyncDiskSrc
 
-
-<!-- ##### MACRO GST_TYPE_ASYNCDISKSRC ##### -->
->>>>>>> 1.23.2.3
+<!-- ##### MACRO GST_PROPS_INT_RANGE_ID ##### -->
 <para>
 
 </para>
 
 
-<!-- ##### FUNCTION gst_elementfactory_add_sink ##### -->
+<!-- ##### MACRO GST_PROPS_LIST_ID ##### -->
 <para>
 
 </para>
 
-@elementfactory: 
-@id: 
 
-<!-- ##### FUNCTION gst_bin_schedule_func ##### -->
+<!-- ##### MACRO GST_QUEUE ##### -->
 <para>
 
 </para>
 
-@bin
+@obj
 
-<!-- ##### MACRO GST_IS_OBJECT ##### -->
+<!-- ##### MACRO GST_QUEUE_CLASS ##### -->
 <para>
 
 </para>
 
-@obj
+@klass
 
-<!-- ##### MACRO GST_TYPE_OBJECT ##### -->
+<!-- ##### MACRO GST_RPAD_EOSFUNC ##### -->
 <para>
-
+Get the EOS function of the real pad.
 </para>
 
+@pad: the real pad to query.
 
-<!-- ##### ARG GstSineSrc:frequency ##### -->
+<!-- ##### MACRO GST_RPAD_PULLFUNC ##### -->
 <para>
-The fequency.
+Get the pullfunction of the real pad.
 </para>
 
+@pad: the real pad to query.
 
-<!-- ##### FUNCTION gst_src_get_type ##### -->
+<!-- ##### MACRO GST_RPAD_PUSHFUNC ##### -->
 <para>
+Get the pushfunction of the real pad.
+</para>
 
+@pad: the real pad to query.
+
+<!-- ##### MACRO GST_RPAD_QOSFUNC ##### -->
+<para>
+Get the QoS function of the real pad.
 </para>
 
-@Returns: 
+@pad: the real pad to query.
 
-<!-- ##### FUNCTION gst_tee_new ##### -->
+<!-- ##### MACRO GST_SINESRC ##### -->
 <para>
 
 </para>
 
-@name: 
-@Returns: 
+@obj: 
 
-<!-- ##### STRUCT GstAudioSink ##### -->
+<!-- ##### MACRO GST_SINESRC_CLASS ##### -->
 <para>
 
 </para>
 
+@klass: 
 
-<!-- ##### MACRO GST_IS_QUEUE ##### -->
+<!-- ##### MACRO GST_SINK ##### -->
 <para>
 
 </para>
 
 @obj: 
 
-<!-- ##### TYPEDEF GstPropsFactory[] ##### -->
+<!-- ##### MACRO GST_SINK_CLASS ##### -->
 <para>
 
 </para>
 
+@klass: 
 
-<!-- ##### SIGNAL GstAudioSink::handoff ##### -->
+<!-- ##### MACRO GST_SINK_FLAG_LAST ##### -->
 <para>
-The buffer is sent to the sound card.
+
 </para>
 
-@gstaudiosink: the object which received the signal.
-@arg1: the audiosink.
 
-<!-- ##### MACRO GST_IS_FDSRC_CLASS ##### -->
+<!-- ##### MACRO GST_SRC ##### -->
 <para>
 
 </para>
 
 @obj: 
 
-<!-- ##### MACRO GST_IS_OBJECT_CLASS ##### -->
+<!-- ##### MACRO GST_SRC_ASYNC ##### -->
 <para>
-
+This macro checks to see if the GST_SRC_ASYNC flag is set.
 </para>
 
-@obj: 
+@obj: GstSrc to check for flag in.
 
-<!-- ##### FUNCTION gst_esdsink_chain ##### -->
+<!-- ##### MACRO GST_SRC_CLASS ##### -->
 <para>
 
 </para>
 
-@pad: 
-@buf: 
+@klass: 
 
-<!-- ##### FUNCTION gst_buffer_add_meta ##### -->
+<!-- ##### MACRO GST_SRC_FLAGS ##### -->
 <para>
-
+This macro returns the entire set of flags for the object.
 </para>
 
-@buffer: 
-@meta: 
+@obj: GstSrc to return flags for.
 
-<!-- ##### FUNCTION gst_elementfactory_can_src_caps_list ##### -->
+<!-- ##### MACRO GST_SRC_IS_ASYNC ##### -->
 <para>
-
+Query a GstSrc for the ASYNC flag
 </para>
 
-@factory: 
-@caps: 
-@Returns: 
+@obj: The GstSrc to query
 
-<!-- ##### FUNCTION gst_queue_chain ##### -->
+<!-- ##### MACRO GST_SRC_SET_FLAGS ##### -->
 <para>
-
+This macro sets the given flags.
 </para>
 
-@pad: 
-@buf: 
+@src: 
+@flag: Flag to set, can by any number of bits in guint32.
+@obj: GstSrc to set flag in.
 
-<!-- ##### MACRO GST_TYPE_QUEUE ##### -->
+<!-- ##### MACRO GST_SRC_UNSET_FLAGS ##### -->
 <para>
-
+This macro usets the given flags.
 </para>
 
+@src: 
+@flag: Flag to set, must be a single bit in guint32.
+@obj: GstSrc to unset flag in.
 
-<!-- ##### FUNCTION gst_buffer_remove_meta ##### -->
+<!-- ##### MACRO GST_STATE_IS_SET ##### -->
 <para>
-
+This macro checks to see if the given state is set.
 </para>
 
-@buffer: 
-@meta: 
+@obj: Element to check for state.
+@flag: State to check for, must be a single bit in guint32.
 
-<!-- ##### FUNCTION gst_caps_register_count ##### -->
+<!-- ##### MACRO GST_STATE_PLAYING_TO_READY ##### -->
 <para>
-
+The Element is going from the PLAYING state to the READY state.
 </para>
 
-@factory: 
-@counter: 
-@Returns: 
-@count: 
 
-<!-- ##### MACRO GST_TYPE_HTTPSRC ##### -->
+<!-- ##### MACRO GST_STATE_READY_TO_PLAYING ##### -->
 <para>
-
+The Element is going from the READY state to the PLAYING state.
 </para>
 
 
-<!-- ##### MACRO GST_TYPE_PAD ##### -->
+<!-- ##### MACRO GST_STATE_SET ##### -->
 <para>
-
+This macro sets the given state on the element.
 </para>
 
+@obj: Element to set state of.
+@flag: State to set, can be any number of bits in guint32.
 
-<!-- ##### MACRO GST_IS_AUDIOSRC ##### -->
+<!-- ##### MACRO GST_STATE_UNSET ##### -->
 <para>
-
+This macro unsets the given state on the element.
 </para>
 
-@obj: 
+@obj: Element to unset state of.
+@flag: State to unset, can be any number of bits in guint32.
 
-<!-- ##### MACRO GST_DISKSRC ##### -->
+<!-- ##### MACRO GST_TEE ##### -->
 <para>
 
 </para>
 
 @obj: 
 
-<!-- ##### MACRO INFO_ELEMENT ##### -->
+<!-- ##### MACRO GST_TEE_CLASS ##### -->
 <para>
 
 </para>
 
-@cat: 
-@element: 
-@format: 
-@args...: 
+@klass: 
 
-<!-- ##### MACRO GST_SINK_CLASS ##### -->
+<!-- ##### MACRO GST_THREAD ##### -->
 <para>
 
 </para>
 
-@klass
+@obj
 
-<!-- ##### STRUCT GstAudioSinkClass ##### -->
+<!-- ##### MACRO GST_THREAD_CLASS ##### -->
 <para>
 
 </para>
 
+@klass: 
 
-<!-- ##### FUNCTION gst_type_add_src ##### -->
+<!-- ##### MACRO GST_TYPE_ASYNCDISKSRC ##### -->
+>>>>>>> 1.23.2.3
 <para>
 
 </para>
 
-@id: 
-@src: 
 
-<!-- ##### STRUCT GstFdSink ##### -->
+<!-- ##### MACRO GST_TYPE_AUDIOSINK ##### -->
 <para>
 
 </para>
 
 
-<!-- ##### MACRO GST_IS_PIPELINE ##### -->
+<!-- ##### MACRO GST_TYPE_AUDIOSRC ##### -->
 <para>
 
 </para>
 
-@obj: 
 
-<!-- ##### STRUCT GstFdSinkClass ##### -->
+<!-- ##### MACRO GST_TYPE_BIN ##### -->
 <para>
 
 </para>
 
 
-<!-- ##### MACRO GST_IS_SINESRC_CLASS ##### -->
+<!-- ##### MACRO GST_TYPE_CONNECTION ##### -->
 <para>
 
 </para>
 
-@obj: 
 
-<!-- ##### MACRO GST_ASYNCDISKSRC_CLASS ##### -->
+<!-- ##### MACRO GST_TYPE_DISKSRC ##### -->
 <para>
 
 </para>
 
-@klass: 
 
-<!-- ##### FUNCTION gst_esdsink_sync_parms ##### -->
+<!-- ##### MACRO GST_TYPE_ELEMENT ##### -->
 <para>
 
 </para>
 
-@esdsink: 
 
-<!-- ##### FUNCTION gst_connection_push ##### -->
+<!-- ##### MACRO GST_TYPE_ESDSINK ##### -->
 <para>
 
 </para>
 
-@connection: 
 
-<!-- ##### SIGNAL GstDiskSink::handoff ##### -->
+<!-- ##### MACRO GST_TYPE_FAKESINK ##### -->
 <para>
-Is emited after the buffer has been written to the disk.
+
 </para>
 
-@gstdisksink: the object which received the signal.
 
-<!-- ##### FUNCTION gst_audiosink_new ##### -->
+<!-- ##### MACRO GST_TYPE_FAKESRC ##### -->
 <para>
 
 </para>
 
-@name: 
-@Returns: 
 
-<!-- ##### FUNCTION gst_bin_set_element_manager ##### -->
+<!-- ##### MACRO GST_TYPE_FDSINK ##### -->
 <para>
 
 </para>
 
-@element: 
-@manager: 
 
-<!-- ##### MACRO GST_ESDSINK ##### -->
+<!-- ##### MACRO GST_TYPE_FDSRC ##### -->
 <para>
 
 </para>
 
-@obj: 
 
-<!-- ##### FUNCTION gst_type_initialize ##### -->
+<!-- ##### MACRO GST_TYPE_FILTER ##### -->
 <para>
 
 </para>
 
 
-<!-- ##### SECTION ./tmpl/gstfilter.sgml:Title ##### -->
-GstFilter
-
-
-<!-- ##### MACRO GST_TEE ##### -->
+<!-- ##### MACRO GST_TYPE_HTTPSRC ##### -->
 <para>
 
 </para>
 
-@obj: 
 
-<!-- ##### MACRO GST_IS_QUEUE_CLASS ##### -->
+<!-- ##### MACRO GST_TYPE_IDENTITY ##### -->
 <para>
 
 </para>
 
-@obj: 
 
-<!-- ##### FUNCTION gst_fdsrc_get_type ##### -->
+<!-- ##### MACRO GST_TYPE_OBJECT ##### -->
 <para>
 
 </para>
 
-@Returns: 
 
-<!-- ##### FUNCTION gst_pad_get_type_id ##### -->
+<!-- ##### MACRO GST_TYPE_PAD ##### -->
 <para>
 
 </para>
 
-@pad: 
-@Returns: 
 
-<!-- ##### FUNCTION gst_thread_iterate ##### -->
+<!-- ##### MACRO GST_TYPE_PIPELINE ##### -->
 <para>
 
 </para>
 
-@thread: 
 
-<!-- ##### STRUCT OverlayClip ##### -->
+<!-- ##### MACRO GST_TYPE_QUEUE ##### -->
 <para>
 
 </para>
 
-@x1: 
-@x2: 
-@y1: 
-@y2: 
 
-<!-- ##### ENUM GstSrcFlags ##### -->
+<!-- ##### MACRO GST_TYPE_SINESRC ##### -->
 <para>
-Flags for the GstSrc element
-</para>
-
-@GST_SRC_ASYNC: Indicates that this src is asynchronous
-@GST_SRC_FLAG_LAST: subclasses can use this to number their flags
-
-<!-- ##### SECTION ./tmpl/gstaudiosink.sgml:Short_Description ##### -->
 
+</para>
 
 
-<!-- ##### SECTION ./tmpl/gstcolorspace.sgml:Title ##### -->
-GstColorSpace
-
-
-<!-- ##### TYPEDEF GstPadFactoryEntry ##### -->
+<!-- ##### MACRO GST_TYPE_SINK ##### -->
 <para>
-Defines an entry for a padfactory.
+
 </para>
 
 
-<!-- ##### ENUM GstAsyncDiskSrcFlags ##### -->
+<!-- ##### MACRO GST_TYPE_SRC ##### -->
 <para>
-<informaltable pgwide=1 frame="none" role="enum">
-<tgroup cols="2"><colspec colwidth="2*"><colspec colwidth="8*">
-<tbody>
-<row>
-<entry>GST_ASYNCDISKSRC_OPEN</entry>
-<entry>the asyncdisksrc is open for reading</entry>
-</row>
-
-</tbody></tgroup></informaltable>
 
 </para>
 
-@GST_ASYNCDISKSRC_OPEN: 
-@GST_ASYNCDISKSRC_FLAG_LAST: 
 
-<!-- ##### STRUCT GstAsyncDiskSrc ##### -->
+<!-- ##### MACRO GST_TYPE_TEE ##### -->
 <para>
 
 </para>
 
 
-<!-- ##### FUNCTION gst_element_change_state ##### -->
+<!-- ##### MACRO GST_TYPE_THREAD ##### -->
 <para>
 
 </para>
 
-@element: 
-@state: 
-@Returns: 
 
-<!-- ##### FUNCTION gst_pad_get_ghost_parents ##### -->
+<!-- ##### STRUCT GstAsyncDiskSrc ##### -->
 <para>
 
 </para>
 
-@pad: 
-@Returns: 
 
-<!-- ##### STRUCT GstFilter ##### -->
+<!-- ##### ARG GstAsyncDiskSrc:bytesperread ##### -->
 <para>
-
+Specify how many bytes to read at a time.
 </para>
 
 
-<!-- ##### MACRO GST_IS_BIN ##### -->
+<!-- ##### ARG GstAsyncDiskSrc:length ##### -->
 <para>
-
+Get the size of the current file.
 </para>
 
-@obj: 
 
-<!-- ##### MACRO GST_OBJECT_FLAG_LAST ##### -->
+<!-- ##### ARG GstAsyncDiskSrc:location ##### -->
 <para>
-subclasses can use this value to start the enumeration of their flags
+Specify the location of the file to read.
 </para>
 
 
-<!-- ##### SECTION ./tmpl/spectrum.sgml:Short_Description ##### -->
-Frequencies of a spectrum analysis.
+<!-- ##### ARG GstAsyncDiskSrc:offset ##### -->
+<para>
+Specify the current offset in the file.
+</para>
 
 
-<!-- ##### FUNCTION gst_asyncdisksrc_get_type ##### -->
+<!-- ##### ARG GstAsyncDiskSrc:size ##### -->
 <para>
 
 </para>
 
-@Returns: 
 
-<!-- ##### MACRO GST_AUDIOSINK_CLASS ##### -->
+<!-- ##### STRUCT GstAsyncDiskSrcClass ##### -->
 <para>
 
 </para>
 
-@klass: 
 
-<!-- ##### MACRO GST_PAD_FACTORY_SINK ##### -->
+<!-- ##### ENUM GstAsyncDiskSrcFlags ##### -->
 <para>
-Indicates a sinkpad for the padfactory.
-</para>
-
+<informaltable pgwide=1 frame="none" role="enum">
+<tgroup cols="2"><colspec colwidth="2*"><colspec colwidth="8*">
+<tbody>
+<row>
+<entry>GST_ASYNCDISKSRC_OPEN</entry>
+<entry>the asyncdisksrc is open for reading</entry>
+</row>
 
-<!-- ##### MACRO GST_SRC_CLASS ##### -->
-<para>
+</tbody></tgroup></informaltable>
 
 </para>
 
-@klass: 
+@GST_ASYNCDISKSRC_OPEN: 
+@GST_ASYNCDISKSRC_FLAG_LAST: 
 
-<!-- ##### SECTION ./tmpl/gstcolorspace.sgml:Long_Description ##### -->
+<!-- ##### STRUCT GstAudioSink ##### -->
 <para>
 
 </para>
 
 
-<!-- ##### FUNCTION gst_type_load_thyself ##### -->
+<!-- ##### SIGNAL GstAudioSink::handoff ##### -->
 <para>
-
+The buffer is sent to the sound card.
 </para>
 
-@parent: 
-@Returns: 
+@gstaudiosink: the object which received the signal.
+@arg1: the audiosink.
 
-<!-- ##### FUNCTION gst_pad_get_caps_list ##### -->
+<!-- ##### ARG GstAudioSink:channels ##### -->
 <para>
 
 </para>
 
-@pad: 
-@Returns: 
 
-<!-- ##### MACRO GST_PROPS_FOURCC_ID ##### -->
+<!-- ##### ARG GstAudioSink:format ##### -->
 <para>
 
 </para>
 
 
-<!-- ##### FUNCTION gst_esdsink_new ##### -->
+<!-- ##### ARG GstAudioSink:frequency ##### -->
 <para>
 
 </para>
 
-@name: 
-@Returns: 
 
-<!-- ##### MACRO GST_META_FLAGS ##### -->
+<!-- ##### ARG GstAudioSink:mute ##### -->
 <para>
-Retrieve the flags of the given meta information.
+
 </para>
 
-@meta: the meta information
 
-<!-- ##### FUNCTION gst_element_request_pad ##### -->
+<!-- ##### STRUCT GstAudioSinkClass ##### -->
 <para>
 
 </para>
 
-@element: 
-@templ: 
-@Returns: 
-@temp: 
 
-<!-- ##### MACRO GST_SINESRC ##### -->
+<!-- ##### STRUCT GstAudioSrc ##### -->
 <para>
 
 </para>
 
-@obj: 
-
-<!-- ##### SECTION ./tmpl/gstsink.sgml:Short_Description ##### -->
-The end point of a filter graph
-
 
-<!-- ##### STRUCT MetaAudioRaw ##### -->
+<!-- ##### ARG GstAudioSrc:bytes-per-read ##### -->
 <para>
-
+The number of bytes per read.
 </para>
 
-@meta: 
-@format: 
-@channels: 
-@frequency: 
-@bps: 
 
 <!-- ##### ARG GstAudioSrc:channels ##### -->
 <para>
@@ -1459,277 +1774,231 @@ The number of channels (mono, stereo, ...)
 </para>
 
 
-<!-- ##### STRUCT GstFakeSink ##### -->
+<!-- ##### ARG GstAudioSrc:curoffset ##### -->
 <para>
-
+Get the current number of bytes read.
 </para>
 
 
-<!-- ##### MACRO GST_STATE_IS_SET ##### -->
+<!-- ##### ARG GstAudioSrc:format ##### -->
 <para>
-This macro checks to see if the given state is set.
+The audio format as defined in soundcard.h
 </para>
 
-@obj: Element to check for state.
-@flag: State to check for, must be a single bit in guint32.
 
-<!-- ##### STRUCT GstMeta ##### -->
+<!-- ##### ARG GstAudioSrc:frequency ##### -->
 <para>
-
+The frequency.
 </para>
 
-@lock: for locking purposes
-@flags: the flags of the meta data
-@data: the meta data
-@size: the size of the meta data
 
-<!-- ##### FUNCTION gst_xml_new_from_memory ##### -->
+<!-- ##### STRUCT GstAudioSrcClass ##### -->
 <para>
 
 </para>
 
-@buffer: 
-@size: 
-@root: 
-@Returns: 
 
-<!-- ##### MACRO GST_PROPS_LIST_ID ##### -->
+<!-- ##### STRUCT GstBinClass ##### -->
 <para>
 
 </para>
 
 
-<!-- ##### SECTION ./tmpl/gstconnection.sgml:See_Also ##### -->
+<!-- ##### USER_FUNCTION GstBufferPoolCreateFunction ##### -->
 <para>
-
+The function called when a buffer has to be created for this pool.
 </para>
 
+@pool: the pool from which to create the buffer
+@user_data: any user data
+@Returns: a new buffer from the pool
 
-<!-- ##### FUNCTION plugin_load ##### -->
+<!-- ##### USER_FUNCTION GstBufferPoolDestroyFunction ##### -->
 <para>
-
+This function will be called when the given buffer has to be returned to
+the pool.
 </para>
 
-@name: 
-@Returns: 
+@pool: the pool to return the buffer to
+@buffer: the buffer to return
+@user_data: any user data
 
-<!-- ##### MACRO GST_IS_ELEMENT ##### -->
+<!-- ##### ENUM GstCapsDefinition ##### -->
 <para>
 
 </para>
 
-@obj: 
-
-<!-- ##### SECTION ./tmpl/gstaudiosink.sgml:Title ##### -->
-GstAudioSink
-
+@GST_CAPS_ALWAYS: 
+@GST_CAPS_MAYBE: 
 
-<!-- ##### MACRO GST_IS_ASYNCDISKSRC ##### -->
+<!-- ##### TYPEDEF GstCapsFactory ##### -->
 <para>
 
 </para>
 
-@obj: 
 
-<!-- ##### MACRO GST_SRC_SET_FLAGS ##### -->
+<!-- ##### TYPEDEF GstCapsFactoryEntry ##### -->
 <para>
-This macro sets the given flags.
-</para>
-
-@src: 
-@flag: Flag to set, can by any number of bits in guint32.
-@obj: GstSrc to set flag in.
 
-<!-- ##### MACRO GST_BUFFER_TYPE ##### -->
-<para>
-Retrieves the type id of the data in the buffer.
 </para>
 
-@buf: GstBuffer
 
-<!-- ##### MACRO GST_PROPS_FLOAT_STRING ##### -->
+<!-- ##### TYPEDEF GstCapsFactory[] ##### -->
 <para>
 
 </para>
 
-@a: 
 
-<!-- ##### MACRO DEBUG_LEAVE_STRING ##### -->
+<!-- ##### STRUCT GstConnection ##### -->
 <para>
 
 </para>
 
 
-<!-- ##### FUNCTION gst_filter_get_type ##### -->
+<!-- ##### STRUCT GstConnectionClass ##### -->
 <para>
 
 </para>
 
-@Returns: 
 
-<!-- ##### FUNCTION plugin_load_absolute ##### -->
+<!-- ##### SIGNAL GstDiskSink::handoff ##### -->
 <para>
-
+Is emited after the buffer has been written to the disk.
 </para>
 
-@name: 
-@Returns: 
+@gstdisksink: the object which received the signal.
 
-<!-- ##### STRUCT GstObjectClass ##### -->
+<!-- ##### ARG GstDiskSink:closed ##### -->
 <para>
 
 </para>
 
 
-<!-- ##### SECTION ./tmpl/gstsink.sgml:Title ##### -->
-GstSink
-
-
-<!-- ##### MACRO GST_CPU_FLAG_MMX ##### -->
+<!-- ##### ARG GstDiskSink:location ##### -->
 <para>
-A flag indicating that MMX instructions are supported.
+The filename to write to.
 </para>
 
 
-<!-- ##### FUNCTION gst_object_get_type ##### -->
+<!-- ##### STRUCT GstDiskSrc ##### -->
 <para>
 
 </para>
 
-@Returns: 
 
-<!-- ##### STRUCT GstSineSrcClass ##### -->
+<!-- ##### ARG GstDiskSrc:size ##### -->
 <para>
-
+Get the size of the file.
 </para>
 
 
-<!-- ##### FUNCTION gst_elementfactory_can_sink_caps_list ##### -->
+<!-- ##### STRUCT GstDiskSrcClass ##### -->
 <para>
 
 </para>
 
-@factory: 
-@caps: 
-@Returns: 
 
-<!-- ##### MACRO GST_SRC_UNSET_FLAGS ##### -->
+<!-- ##### STRUCT GstElementClass ##### -->
 <para>
-This macro usets the given flags.
+
 </para>
 
-@src: 
-@flag: Flag to set, must be a single bit in guint32.
-@obj: GstSrc to unset flag in.
 
-<!-- ##### ARG GstAudioSrc:frequency ##### -->
+<!-- ##### STRUCT GstEsdSink ##### -->
 <para>
-The frequency.
+
 </para>
 
 
-<!-- ##### MACRO GST_PAD_FACTORY_SRC ##### -->
+<!-- ##### STRUCT GstEsdSinkClass ##### -->
 <para>
-Indicates a srcpad for the padfactory.
+
 </para>
 
 
-<!-- ##### ARG GstDiskSink:closed ##### -->
+<!-- ##### STRUCT GstFakeSink ##### -->
 <para>
 
 </para>
 
 
-<!-- ##### FUNCTION gst_buffer_get_first_meta ##### -->
+<!-- ##### ARG GstFakeSink:num-sources ##### -->
 <para>
 
 </para>
 
-@buffer: 
-@Returns: 
 
-<!-- ##### MACRO GST_IS_SINK_CLASS ##### -->
+<!-- ##### STRUCT GstFakeSinkClass ##### -->
 <para>
 
 </para>
 
-@obj: 
 
-<!-- ##### MACRO GST_IS_PIPELINE_CLASS ##### -->
+<!-- ##### STRUCT GstFakeSrc ##### -->
 <para>
 
 </para>
 
-@obj: 
 
-<!-- ##### MACRO GST_PROPS_INT_RANGE_ID ##### -->
+<!-- ##### ARG GstFakeSrc:patern ##### -->
 <para>
 
 </para>
 
 
-<!-- ##### STRUCT GstAudioSrc ##### -->
+<!-- ##### STRUCT GstFakeSrcClass ##### -->
 <para>
 
 </para>
 
 
-<!-- ##### MACRO GST_TYPE_ELEMENT ##### -->
+<!-- ##### STRUCT GstFdSink ##### -->
 <para>
 
 </para>
 
 
-<!-- ##### ARG GstFakeSrc:patern ##### -->
+<!-- ##### STRUCT GstFdSinkClass ##### -->
 <para>
 
 </para>
 
 
-<!-- ##### FUNCTION gst_pad_get_caps_by_name ##### -->
+<!-- ##### STRUCT GstFdSrc ##### -->
 <para>
 
 </para>
 
-@pad: 
-@name: 
-@Returns: 
 
-<!-- ##### SECTION ./tmpl/gstsrc.sgml:See_Also ##### -->
+<!-- ##### STRUCT GstFdSrcClass ##### -->
 <para>
 
 </para>
 
 
-<!-- ##### FUNCTION gst_esdsink_set_format ##### -->
+<!-- ##### STRUCT GstFilter ##### -->
 <para>
 
 </para>
 
-@esdsink: 
-@format: 
 
-<!-- ##### MACRO GST_DEBUG_PREFIX ##### -->
+<!-- ##### STRUCT GstFilterClass ##### -->
 <para>
 
 </para>
 
-@cat: 
-@format: 
-@args...: 
 
-<!-- ##### SECTION ./tmpl/gstcolorspace.sgml:See_Also ##### -->
+<!-- ##### STRUCT GstHttpSrc ##### -->
 <para>
 
 </para>
 
 
-<!-- ##### MACRO GST_IS_FDSRC ##### -->
+<!-- ##### STRUCT GstHttpSrcClass ##### -->
 <para>
 
 </para>
 
-@obj: 
 
 <!-- ##### STRUCT GstIdentity ##### -->
 <para>
@@ -1737,432 +2006,385 @@ Indicates a srcpad for the padfactory.
 </para>
 
 
-<!-- ##### FUNCTION gst_thread_get_type ##### -->
+<!-- ##### ARG GstIdentity:control ##### -->
 <para>
 
 </para>
 
-@Returns: 
 
-<!-- ##### MACRO GST_QUEUE ##### -->
+<!-- ##### STRUCT GstIdentityClass ##### -->
 <para>
 
 </para>
 
-@obj: 
 
-<!-- ##### MACRO GST_THREAD ##### -->
+<!-- ##### STRUCT GstMeta ##### -->
 <para>
 
 </para>
 
-@obj: 
+@lock: for locking purposes
+@flags: the flags of the meta data
+@data: the meta data
+@size: the size of the meta data
 
-<!-- ##### MACRO COTHREAD_MAXTHREADS ##### -->
+<!-- ##### ENUM GstMetaFlags ##### -->
 <para>
-The maximum number of cothreads we are going to support.
+Flags indicating properties about the meta data.
 </para>
 
+@GST_META_FREEABLE: the meta data can be freed
 
-<!-- ##### FUNCTION gst_fakesink_new ##### -->
+<!-- ##### STRUCT GstObjectClass ##### -->
 <para>
 
 </para>
 
-@name: 
-@Returns: 
 
-<!-- ##### MACRO GST_PAD_FACTORY_CAPS ##### -->
+<!-- ##### ARG GstPad:active ##### -->
 <para>
-Starts the declaration of a the capabilities for this padtemplate.
+Indicates this pad is active
 </para>
 
-@a...: a capability factory
-
-<!-- ##### SECTION ./tmpl/gstsrc.sgml:Title ##### -->
-GstSrc
 
-
-<!-- ##### FUNCTION gst_pad_get_directory ##### -->
+<!-- ##### STRUCT GstPadClass ##### -->
 <para>
 
 </para>
 
-@pad: 
-@Returns: 
-
-<!-- ##### FUNCTION gst_tee_chain ##### -->
-<para>
 
-</para>
+<<<<<<< gstreamer-unused.sgml
 
-@pad: 
-@buf: 
 
-<!-- ##### FUNCTION gst_caps_new_with_props ##### -->
+<!-- ##### USER_FUNCTION GstPadEOSFunction ##### -->
 <para>
-
+The function that will be called in an EOS case.
 </para>
 
-@name: 
-@mime: 
-@props: 
-@Returns: 
+@pad: the pad that needs to be set to EOS state
+@Returns: TRUE if EOS was successful, FALSE otherwise
 
-<!-- ##### MACRO GST_STATE_READY_TO_PLAYING ##### -->
+<!-- ##### TYPEDEF GstPadFactoryEntry ##### -->
 <para>
-The Element is going from the READY state to the PLAYING state.
+Defines an entry for a padfactory.
 </para>
 
 
-<!-- ##### MACRO GST_TYPE_AUDIOSRC ##### -->
+<!-- ##### TYPEDEF GstPadFactory[] ##### -->
 <para>
-
+The padfactory.
 </para>
 
 
-<!-- ##### SECTION ./tmpl/plugin.sgml:See_Also ##### -->
+<!-- ##### USER_FUNCTION GstPadPullFunction ##### -->
 <para>
-
+The function that will be called when pulling buffers.
 </para>
 
+@pad: the pad to pull
+@Returns: a GstBuffer
 
-<!-- ##### SECTION ./tmpl/gstmeta.sgml:See_Also ##### -->
+<!-- ##### USER_FUNCTION GstPadPushFunction ##### -->
 <para>
 
+The function that will be called when pushing a buffers.
 </para>
 
+@pad: the pad to push
+@buf: a GstBuffer to push
 
-<!-- ##### MACRO GST_IS_TEE_CLASS ##### -->
+<!-- ##### USER_FUNCTION GstPadQoSFunction ##### -->
 <para>
-
+The function that will be called when a QoS message is sent.
 </para>
 
-@obj: 
+@pad: the pad that sent the QoS message
+@qos_message: the message
 
-<!-- ##### FUNCTION gst_thread_main_loop ##### -->
+<!-- ##### STRUCT GstPipelineClass ##### -->
 <para>
 
 </para>
 
-@arg: 
 
-<!-- ##### SECTION ./tmpl/gstmeta.sgml:Long_Description ##### -->
+<!-- ##### STRUCT GstPluginElement ##### -->
 <para>
-The point of the metadata is to provide some context for each buffer.  In
-the case of audio data, for instance, it would provide the samplerate, bit
-depth, and channel count.
-</para>
 
-<para>
-The trick is that there may be multiple types of metadata ganged onto a
-single buffer.  This is why they're going to be a GList.  This does mean
-extra overhead in all cases, but I think it's minimal.  The GList type
-uses a chunk allocater so we're not wasting too much memory or time when
-adding to the list.
 </para>
 
-<para>
-The trick is dealing with these structs as they pass through a pipeline,
-since they have potentially different mutability properties.  For
-instance, if you've got a mp3 decoder connected to a tee, which sends the
-buffers off to both the decoder and a spectrum analyzer (and then a
-visualization element).  The preferred setup would be where every time a
-audio/raw metadata comes down the pipe (indicating a potential change in
-audio format), the audiosink and spectrum would just save off pointers.
-</para>
 
+<!-- ##### TYPEDEF GstPropsFactoryEntry ##### -->
 <para>
-So when exactly does this metadata go away (deallocated)?  Well, that
-means metadata has to be refcounted.  But that gets rather hairy.  OK, in
-the simple case you create a metadata struct, it comes with refcount set
-to 1.  You pass it through, it stays one, eventually someone drops the
-last reference on the buffer it's tied to, you free the metadata too.
-Easy.  What if you tee?  You could go through and for every metadata in
-the buffer, increment the refcount by the same as the buffer.  So in the
-above case (tee'd), the audiosink and spectrum would get the buffer with a
-refcount of 2, and it'd have a metadata with refcount 2.  Do they ref it
-each themselves, then unref the buffer?  Or do they remove the metadata?
-Removing the metadata would require a buffer CoW, which would suck, so
-yes, they'd just ref the metadata.
-</para>
 
-<para>
-But....  what if they're all in different threads?  Then we're off into
-the magical world of mutexes.  Everything with a refcount in a threaded
-world must be mutexed, else you can do atomic increment and atomic
-dec and test.  Can this be done from C easily?  Perhaps it needs to be found
-from kernel includes via autoconf?
 </para>
 
-<para>
-The goal in designing the way metadata will be defined and used is to keep
-it as simple as possible.  The basis for accomplishing this is the fact
-that in order to actually use (rather than just pass) the metadata, you
-have to know what the fields are, which means you have to have compiled in
-support for that metadata at build time.  Therefore, if you're using
-metadata, you must have build-time access to the necessary include file
-that defines it.
-</para>
 
+<!-- ##### TYPEDEF GstPropsFactory[] ##### -->
 <para>
-So, given that you've got an include file, it would be nice if the whole
-thing could be contained there.  This would limit the need to be linked
-against something, or have load-time requirements as to that has to be
-loaded before you are.
-</para>
 
-<para>
-Given that really all metadata is is a region of memory of a given size
-with a certain signature, this isn't all that hard.  First you lay out the
-struct that defines the metadata.  Then you set up #defines that expand to
-the size of the struct in question, as well as the four-cc code that
-defines the type.
 </para>
 
-<para>
-The work is done by a few #defines, a la the #defines used in all Gtk
-objects.  The first is a NEW() method that allocates the memory for the
-metadata and fills in all the normal fields (type, size, utility
-functions).  Because of the way it's defined (as a #define, no less),
-you'll have to invoke it as META_NEW(meta), since it can't return()
-anything.
-</para>
 
+<!-- ##### ENUM GstPropsId ##### -->
 <para>
-Another #define will check to make sure a meta is indeed that type by
-verifying the type code and size.  Theoretically, meta types can overlap
-with the same fourcc code, as long as they have different sizes.  But I
-probably ought to have a global public registry so people writing things
-don't conflict.  MSFT got that right, at least.
-</para>
 
-<para>
-So, a hairy problem is what to do when there are utility functions
-associated with one of these things.  One option is to not bother with
-them.  This is very likely a possible solution, since metadata is supposed
-to be flat memory of a given size.  Not much to do to either free or copy
-it, is there?
 </para>
 
+@GST_PROPS_END_ID_NUM: 
+@GST_PROPS_LIST_ID_NUM: 
+@GST_PROPS_INT_ID_NUM: 
+@GST_PROPS_INT_RANGE_ID_NUM: 
+@GST_PROPS_FOURCC_ID_NUM: 
+@GST_PROPS_BOOL_ID_NUM: 
 
-<!-- ##### SECTION ./tmpl/gstconnection.sgml:Title ##### -->
-GstConnection
-
-
-<!-- ##### MACRO GST_TYPE_FDSRC ##### -->
+<!-- ##### TYPEDEF GstPropsListFactory[] ##### -->
 <para>
 
 </para>
 
 
-<!-- ##### MACRO GST_TYPE_PIPELINE ##### -->
+<!-- ##### STRUCT GstQueue ##### -->
 <para>
 
 </para>
 
 
-<!-- ##### STRUCT GstHttpSrcClass ##### -->
+<!-- ##### ARG GstQueue:block ##### -->
 <para>
-
+Specify wether the queue blocks or not. 
 </para>
 
 
-<!-- ##### SECTION ./tmpl/GstElement.sgml:Short_Description ##### -->
+<!-- ##### ARG GstQueue:timeout ##### -->
+<para>
 
+</para>
 
 
-<!-- ##### SECTION ./tmpl/gstesdsink.sgml:See_Also ##### -->
+<!-- ##### STRUCT GstQueueClass ##### -->
 <para>
 
 </para>
 
 
-<!-- ##### MACRO GST_TYPE_TEE ##### -->
+<!-- ##### STRUCT GstSineSrc ##### -->
 <para>
 
 </para>
 
 
-<!-- ##### MACRO GST_BIN ##### -->
+<!-- ##### ARG GstSineSrc:channels ##### -->
 <para>
-
+The number of channels.
 </para>
 
-@obj: 
 
-<!-- ##### SECTION ./tmpl/GstElement.sgml:Title ##### -->
-GstElement
+<!-- ##### ARG GstSineSrc:frequency ##### -->
+<para>
+The fequency.
+</para>
 
 
-<!-- ##### FUNCTION gst_type_get_sinks ##### -->
+<!-- ##### STRUCT GstSineSrcClass ##### -->
 <para>
 
 </para>
 
-@id: 
-@Returns: 
 
-<!-- ##### MACRO GST_BUFFER_POOL ##### -->
+<!-- ##### STRUCT GstSink ##### -->
 <para>
 
 </para>
 
-@buf: 
 
-<!-- ##### STRUCT GstEsdSink ##### -->
+<!-- ##### STRUCT GstSinkClass ##### -->
 <para>
 
 </para>
 
 
-<!-- ##### MACRO GST_META_FLAG_UNSET ##### -->
+<!-- ##### STRUCT GstSrc ##### -->
 <para>
-Clear a flag in the meta data.
+
 </para>
 
-@meta: the meta data
-@flag: the flag to clear
 
-<!-- ##### MACRO GST_IS_FAKESRC ##### -->
+<!-- ##### SIGNAL GstSrc::eos ##### -->
 <para>
+An eos signal is triggered whenever the GstSrc has reached the end of 
+the stream.
 
 </para>
 
-@obj: 
+@gstsrc: the object which received the signal.
+@arg1: the object which received the signal
 
-<!-- ##### SECTION ./tmpl/gstaudiosink.sgml:Long_Description ##### -->
+<!-- ##### STRUCT GstSrcClass ##### -->
 <para>
 
 </para>
 
 
-<!-- ##### SECTION ./tmpl/gstsink.sgml:Long_Description ##### -->
+<!-- ##### ENUM GstSrcFlags ##### -->
 <para>
-The sink is the end of the filter graph. A typical sink would be an audio
-or a video card.
-
+Flags for the GstSrc element
 </para>
 
+@GST_SRC_ASYNC: Indicates that this src is asynchronous
+@GST_SRC_FLAG_LAST: subclasses can use this to number their flags
 
-<!-- ##### MACRO GST_IS_BIN_CLASS ##### -->
+<!-- ##### STRUCT GstTee ##### -->
 <para>
 
 </para>
 
-@obj: 
 
-<!-- ##### FUNCTION gst_esdsink_get_type ##### -->
+<!-- ##### STRUCT GstTeeClass ##### -->
 <para>
 
 </para>
 
-@Returns: 
 
-<!-- ##### SECTION ./tmpl/GstElement.sgml:See_Also ##### -->
+<!-- ##### STRUCT GstThreadClass ##### -->
 <para>
 
 </para>
 
 
-<!-- ##### STRUCT GstEsdSinkClass ##### -->
+<!-- ##### ARG GstTypeFind:type ##### -->
 <para>
-
+Query the element for the current mime type
 </para>
 
 
-<!-- ##### MACRO GST_ELEMENT_IS_MULTI_IN ##### -->
+<!-- ##### SIGNAL GstXML::object-loaded ##### -->
 <para>
-Query whether this object has multiple input pads.
-
+Is trigered whenever the state of an element changes
 </para>
 
-@obj: Element to query for multiple input pads.
+@gstelement: the object which received the signal.
+@arg1: the new state of the object
 
-<!-- ##### SECTION ./tmpl/gstfilter.sgml:See_Also ##### -->
+<!-- ##### MACRO INFO ##### -->
 <para>
 
 </para>
 
+@cat: 
+@format: 
+@args...: 
 
-<!-- ##### MACRO DEBUG_NOPREFIX ##### -->
+<!-- ##### MACRO INFO_ELEMENT ##### -->
 <para>
 
 </para>
 
+@cat: 
+@element: 
 @format: 
 @args...: 
 
-<!-- ##### ARG GstAudioSink:frequency ##### -->
+<!-- ##### STRUCT MetaAudioRaw ##### -->
 <para>
 
 </para>
 
+@meta: 
+@format: 
+@channels: 
+@frequency: 
+@bps: 
 
-<!-- ##### STRUCT GstFdSrc ##### -->
+<!-- ##### STRUCT MetaAudioSpectrum ##### -->
 <para>
 
 </para>
 
+@meta: 
+@bands: 
+@channels: 
+@interleaved: 
+@lowfreq: 
+@highfreq: 
+@steps: 
 
-<!-- ##### FUNCTION gst_props_register ##### -->
+<!-- ##### STRUCT MetaDGA ##### -->
 <para>
 
 </para>
 
-@factory: 
-@Returns: 
+@base: 
+@swidth: 
+@sheight: 
+@bytes_per_line: 
 
-<!-- ##### STRUCT GstThreadClass ##### -->
+<!-- ##### STRUCT MetaOverlay ##### -->
 <para>
 
 </para>
 
+@wx: 
+@wy: 
+@overlay_element: 
+@clip_count: 
+@overlay_clip: 
+@width: 
+@height: 
+@did_overlay: 
+@fully_obscured: 
 
-<!-- ##### FUNCTION gst_element_load_thyself ##### -->
+<!-- ##### STRUCT MetaVideoRaw ##### -->
 <para>
 
 </para>
 
-@self: 
-@parent: 
-@Returns: 
-@elements: 
+@meta: 
+@format: 
+@visual: 
+@width: 
+@height: 
+@overlay_info: 
+@dga_info: 
 
-<!-- ##### FUNCTION gst_src_signal_eos ##### -->
+<!-- ##### STRUCT OverlayClip ##### -->
 <para>
 
 </para>
 
-@src: 
+@x1: 
+@x2: 
+@y1: 
+@y2: 
 
-<!-- ##### STRUCT GstHttpSrc ##### -->
+<!-- ##### MACRO STACK_SIZE ##### -->
 <para>
 
 </para>
 
 
-<!-- ##### STRUCT GstSrc ##### -->
+<!-- ##### FUNCTION gst_asyncdisksrc_get_type ##### -->
 <para>
 
 </para>
 
+@Returns: 
 
-<!-- ##### SECTION ./tmpl/videoraw.sgml:Long_Description ##### -->
+<!-- ##### FUNCTION gst_audiosink_chain ##### -->
 <para>
-Information about video buffers.
+
 </para>
 
+@pad: 
+@buf: 
 
-<!-- ##### FUNCTION gst_bin_add_managed_element ##### -->
+<!-- ##### FUNCTION gst_audiosink_get_type ##### -->
 <para>
 
 </para>
 
-@bin: 
-@element: 
+@Returns: 
 
-<!-- ##### FUNCTION gst_queue_new ##### -->
+<!-- ##### FUNCTION gst_audiosink_new ##### -->
 <para>
 
 </para>
@@ -2170,40 +2392,45 @@ Information about video buffers.
 @name: 
 @Returns: 
 
-<!-- ##### MACRO GST_THREAD_CLASS ##### -->
+<!-- ##### FUNCTION gst_audiosink_set_channels ##### -->
 <para>
 
 </para>
 
-@klass: 
+@audiosink: 
+@channels: 
 
-<!-- ##### TYPEDEF GstPropsFactoryEntry ##### -->
+<!-- ##### FUNCTION gst_audiosink_set_format ##### -->
 <para>
 
 </para>
 
+@audiosink: 
+@format: 
 
-<!-- ##### MACRO GST_IS_FILTER_CLASS ##### -->
+<!-- ##### FUNCTION gst_audiosink_set_frequency ##### -->
 <para>
 
 </para>
 
-@obj: 
+@audiosink: 
+@frequency: 
 
-<!-- ##### MACRO GST_CONNECTION_CLASS ##### -->
+<!-- ##### FUNCTION gst_audiosink_sync_parms ##### -->
 <para>
 
 </para>
 
-@klass
+@audiosink
 
-<!-- ##### SECTION ./tmpl/gstgetbits.sgml:Long_Description ##### -->
+<!-- ##### FUNCTION gst_audiosrc_get_type ##### -->
 <para>
 
 </para>
 
+@Returns: 
 
-<!-- ##### FUNCTION gst_connection_new ##### -->
+<!-- ##### FUNCTION gst_audiosrc_new ##### -->
 <para>
 
 </para>
@@ -2211,1049 +2438,1132 @@ Information about video buffers.
 @name: 
 @Returns: 
 
-<!-- ##### MACRO GST_SINK ##### -->
+<!-- ##### FUNCTION gst_audiosrc_push ##### -->
 <para>
 
 </para>
 
-@obj
+@src
 
-<!-- ##### MACRO GST_FDSRC_CLASS ##### -->
+<!-- ##### FUNCTION gst_autoplug_caps_list ##### -->
 <para>
 
 </para>
 
-@klass: 
+@autoplug: 
+@srcpad: 
+@sinkpad: 
+@Varargs: 
+@Returns: 
+@srccaps: 
+@sinkcaps: 
 
-<!-- ##### MACRO GST_TYPE_FAKESRC ##### -->
+<!-- ##### FUNCTION gst_autoplugfactory_load_thyself ##### -->
 <para>
 
 </para>
 
+@parent: 
+@Returns: 
 
-<!-- ##### SECTION ./tmpl/plugin.sgml:Short_Description ##### -->
-
-
-
-<!-- ##### FUNCTION gst_pad_get_type ##### -->
+<!-- ##### FUNCTION gst_autoplugfactory_save_thyself ##### -->
 <para>
 
 </para>
 
+@factory: 
+@parent: 
 @Returns: 
 
-<!-- ##### SECTION ./tmpl/gstsink.sgml:See_Also ##### -->
+<!-- ##### FUNCTION gst_bin_add_managed_element ##### -->
 <para>
 
 </para>
 
+@bin: 
+@element: 
 
-<!-- ##### MACRO GST_IS_AUDIOSINK ##### -->
+<!-- ##### FUNCTION gst_bin_create_plan ##### -->
 <para>
 
 </para>
 
-@obj
+@bin
 
-<!-- ##### SECTION ./tmpl/gstfilter.sgml:Long_Description ##### -->
+<!-- ##### FUNCTION gst_bin_get_type ##### -->
 <para>
-Filters take data in and spit data out. They are the main Element in a filter graph.
-Filters have zero or more inputs and zero or more outputs. Filters are connected
-together to form filter graphs. A GstFilter is the base class and is not very usefull
-on its own.
+
 </para>
 
+@Returns: 
 
-<!-- ##### FUNCTION gst_tee_new_pad ##### -->
+<!-- ##### FUNCTION gst_bin_remove_managed_element ##### -->
 <para>
 
 </para>
 
-@tee
-@Returns
+@bin
+@element
 
-<!-- ##### MACRO GST_OBJECT ##### -->
+<!-- ##### FUNCTION gst_bin_schedule ##### -->
 <para>
 
 </para>
 
-@obj
+@bin
 
-<!-- ##### MACRO GST_STATE_PLAYING_TO_READY ##### -->
+<!-- ##### FUNCTION gst_bin_schedule_func ##### -->
 <para>
-The Element is going from the PLAYING state to the READY state.
+
 </para>
 
+@bin: 
 
-<!-- ##### MACRO GST_IS_FDSINK ##### -->
+<!-- ##### FUNCTION gst_bin_set_element_manager ##### -->
 <para>
 
 </para>
 
-@obj: 
+@element: 
+@manager: 
 
-<!-- ##### MACRO GST_DEBUG_ENTER_STRING ##### -->
+<!-- ##### FUNCTION gst_buffer_add_meta ##### -->
 <para>
-Combine #GST_DEBUG_ENTER and #GST_DEBUG_SET_STRING.
+
 </para>
 
+@buffer: 
+@meta: 
 
-<!-- ##### MACRO GST_IS_DISKSRC ##### -->
+<!-- ##### FUNCTION gst_buffer_get_first_meta ##### -->
 <para>
 
 </para>
 
-@obj: 
+@buffer: 
+@Returns: 
 
-<!-- ##### MACRO GST_FAKESINK_CLASS ##### -->
+<!-- ##### FUNCTION gst_buffer_get_metas ##### -->
 <para>
 
 </para>
 
-@klass: 
+@buffer: 
+@Returns: 
 
-<!-- ##### MACRO GST_TYPE_FDSINK ##### -->
+<!-- ##### FUNCTION gst_buffer_pool_destroy_buffer ##### -->
 <para>
 
 </para>
 
+@pool: 
+@buffer: 
 
-<!-- ##### SECTION ./tmpl/gstcolorspace.sgml:Short_Description ##### -->
-
-
+<!-- ##### FUNCTION gst_buffer_pool_new_buffer ##### -->
+<para>
 
-<!-- ##### SECTION ./tmpl/videoraw.sgml:Title ##### -->
-videoraw
+</para>
 
+@pool: 
+@Returns: 
 
-<!-- ##### MACRO GST_IS_FILTER ##### -->
+<!-- ##### FUNCTION gst_buffer_pool_set_create_function ##### -->
 <para>
 
 </para>
 
-@obj: 
+@pool: 
+@create: 
+@user_data: 
 
-<!-- ##### STRUCT MetaOverlay ##### -->
+<!-- ##### FUNCTION gst_buffer_pool_set_destroy_function ##### -->
 <para>
 
 </para>
 
-@wx: 
-@wy: 
-@overlay_element: 
-@clip_count: 
-@overlay_clip: 
-@width: 
-@height: 
-@did_overlay: 
-@fully_obscured: 
+@pool: 
+@destroy: 
+@user_data: 
 
-<!-- ##### MACRO GST_TYPE_FILTER ##### -->
+<!-- ##### FUNCTION gst_buffer_remove_meta ##### -->
 <para>
 
 </para>
 
+@buffer: 
+@meta: 
 
-<!-- ##### FUNCTION gst_identity_new ##### -->
+<!-- ##### FUNCTION gst_caps_list_check_compatibility ##### -->
 <para>
 
 </para>
 
-@name: 
+@fromcaps: 
+@tocaps: 
 @Returns: 
 
-<!-- ##### MACRO GST_IS_AUDIOSRC_CLASS ##### -->
+<!-- ##### FUNCTION gst_caps_new_with_props ##### -->
 <para>
 
 </para>
 
-@obj: 
+@name: 
+@mime: 
+@props: 
+@Returns: 
 
-<!-- ##### STRUCT GstIdentityClass ##### -->
+<!-- ##### FUNCTION gst_caps_register ##### -->
 <para>
 
 </para>
 
+@factory: 
+@Returns: 
 
-<!-- ##### MACRO GST_IS_PAD_CLASS ##### -->
+<!-- ##### FUNCTION gst_caps_register_count ##### -->
 <para>
 
 </para>
 
-@obj: 
+@factory: 
+@counter: 
+@Returns: 
+@count: 
 
-<!-- ##### MACRO GST_IDENTITY_CLASS ##### -->
+<!-- ##### FUNCTION gst_connection_get_type ##### -->
 <para>
 
 </para>
 
-@klass: 
+@Returns: 
 
-<!-- ##### MACRO GST_SINK_FLAG_LAST ##### -->
+<!-- ##### FUNCTION gst_connection_new ##### -->
 <para>
 
 </para>
 
+@name: 
+@Returns: 
 
-<!-- ##### MACRO GST_IS_FDSINK_CLASS ##### -->
+<!-- ##### FUNCTION gst_connection_push ##### -->
 <para>
 
 </para>
 
-@obj
+@connection
 
-<!-- ##### MACRO GST_SRC_FLAGS ##### -->
+<!-- ##### FUNCTION gst_disksrc_get_type ##### -->
 <para>
-This macro returns the entire set of flags for the object.
+
 </para>
 
-@obj: GstSrc to return flags for.
+@Returns: 
 
-<!-- ##### STRUCT GstFakeSinkClass ##### -->
+<!-- ##### FUNCTION gst_element_change_state ##### -->
 <para>
 
 </para>
 
+@element: 
+@state: 
+@Returns: 
 
-<!-- ##### ARG GstAsyncDiskSrc:length ##### -->
+<!-- ##### FUNCTION gst_element_get_type ##### -->
 <para>
-Get the size of the current file.
-</para>
 
+</para>
 
-<!-- ##### SECTION ./tmpl/gstaudiosrc.sgml:Short_Description ##### -->
-
+@Returns: 
 
+<!-- ##### FUNCTION gst_element_load_thyself ##### -->
+<para>
 
-<!-- ##### SECTION ./tmpl/gstsrc.sgml:Short_Description ##### -->
-The start point of a filter graph
+</para>
 
+@self: 
+@parent: 
+@Returns: 
+@elements: 
 
-<!-- ##### FUNCTION gst_src_push ##### -->
+<!-- ##### FUNCTION gst_element_loopfunc_wrapper ##### -->
 <para>
-
 </para>
 
-@src: 
+@argc: 
+@argv: 
+@Returns: 
 
-<!-- ##### MACRO GST_IS_ESDSINK ##### -->
+<!-- ##### FUNCTION gst_element_new ##### -->
 <para>
 
 </para>
 
-@obj
+@Returns
 
-<!-- ##### FUNCTION gst_sinesrc_push ##### -->
+<!-- ##### FUNCTION gst_element_request_pad ##### -->
 <para>
 
 </para>
 
-@src: 
+@element: 
+@templ: 
+@Returns: 
+@temp: 
 
-<!-- ##### FUNCTION gst_bin_create_plan ##### -->
+<!-- ##### FUNCTION gst_element_save_thyself ##### -->
 <para>
 
 </para>
 
-@bin: 
+@element: 
+@parent: 
+@Returns: 
 
-<!-- ##### FUNCTION gst_props_register_count ##### -->
+<!-- ##### FUNCTION gst_elementfactory_add_sink ##### -->
 <para>
 
 </para>
 
-@factory: 
-@counter: 
-@Returns: 
+@elementfactory: 
+@id: 
 
-<!-- ##### ARG GstFakeSink:num_sources ##### -->
+<!-- ##### FUNCTION gst_elementfactory_add_src ##### -->
 <para>
 
 </para>
 
+@elementfactory: 
+@id: 
 
-<!-- ##### MACRO GST_PROPS_FLOAT_RANGE_STRING ##### -->
+<!-- ##### FUNCTION gst_elementfactory_can_sink_caps_list ##### -->
 <para>
 
 </para>
 
-@a: 
-@b: 
+@factory: 
+@caps: 
+@Returns: 
 
-<!-- ##### MACRO GST_FAKESRC_CLASS ##### -->
+<!-- ##### FUNCTION gst_elementfactory_can_src_caps_list ##### -->
 <para>
 
 </para>
 
-@klass: 
+@factory: 
+@caps: 
+@Returns: 
 
-<!-- ##### ARG GstQueue:timeout ##### -->
+<!-- ##### FUNCTION gst_elementfactory_destroy ##### -->
 <para>
 
 </para>
 
+@elementfactory: 
 
-<!-- ##### MACRO COTHREAD_STACKSIZE ##### -->
+<!-- ##### FUNCTION gst_elementfactory_load_thyself ##### -->
 <para>
-The default stack size of a cothread.
+
 </para>
 
+@parent: 
+@Returns: 
 
-<!-- ##### SECTION ./tmpl/gstesdsink.sgml:Long_Description ##### -->
+<!-- ##### FUNCTION gst_elementfactory_register ##### -->
 <para>
 
 </para>
 
+@elementfactory: 
 
-<!-- ##### STRUCT GstBinClass ##### -->
+<!-- ##### FUNCTION gst_elementfactory_save_thyself ##### -->
 <para>
 
 </para>
 
+@factory: 
+@parent: 
+@Returns: 
 
-<!-- ##### MACRO GST_TYPE_DISKSRC ##### -->
+<!-- ##### FUNCTION gst_esdsink_chain ##### -->
 <para>
 
 </para>
 
+@pad: 
+@buf: 
 
-<!-- ##### FUNCTION gst_audiosrc_get_type ##### -->
+<!-- ##### FUNCTION gst_esdsink_get_type ##### -->
 <para>
 
 </para>
 
 @Returns: 
 
-<!-- ##### FUNCTION gst_httpsrc_get_type ##### -->
+<!-- ##### FUNCTION gst_esdsink_new ##### -->
 <para>
 
 </para>
 
+@name: 
 @Returns: 
 
-<!-- ##### MACRO GST_DISKSRC_CLASS ##### -->
+<!-- ##### FUNCTION gst_esdsink_set_channels ##### -->
 <para>
 
 </para>
 
-@klass: 
+@esdsink: 
+@channels: 
 
-<!-- ##### MACRO GST_ESDSINK_CLASS ##### -->
+<!-- ##### FUNCTION gst_esdsink_set_format ##### -->
 <para>
 
 </para>
 
-@klass: <<<<<<< gstreamer-unused.sgml
+@esdsink: 
+@format: 
 
-<!-- ##### MACRO GST_PAD_FACTORY_REQUEST ##### -->
+<!-- ##### FUNCTION gst_esdsink_set_frequency ##### -->
 <para>
-Indicates that this pad will be available on request. Use 
-this in the factory definition. 
+
 </para>
 
+@esdsink: 
+@frequency: 
 
-<!-- ##### FUNCTION gst_audiosink_sync_parms ##### -->
+<!-- ##### FUNCTION gst_esdsink_sync_parms ##### -->
 <para>
 
 </para>
 
-@audiosink: 
+@esdsink: 
 
-<!-- ##### MACRO GST_IS_FAKESINK ##### -->
+<!-- ##### FUNCTION gst_fakesink_chain ##### -->
 <para>
 
 </para>
 
-@obj: 
+@pad: 
+@buf: 
 
-<!-- ##### MACRO GST_STATE_UNSET ##### -->
+<!-- ##### FUNCTION gst_fakesink_get_type ##### -->
 <para>
-This macro unsets the given state on the element.
+
 </para>
 
-@obj: Element to unset state of.
-@flag: State to unset, can be any number of bits in guint32.
+@Returns: 
 
-<!-- ##### MACRO GST_QUEUE_CLASS ##### -->
+<!-- ##### FUNCTION gst_fakesink_new ##### -->
 <para>
 
 </para>
 
-@klass: 
+@name: 
+@Returns: 
 
-<!-- ##### FUNCTION gst_pad_set_type_id ##### -->
+<!-- ##### FUNCTION gst_fakesrc_get_type ##### -->
 <para>
 
 </para>
 
-@pad: 
-@id: 
+@Returns: 
 
-<!-- ##### MACRO GST_PAD_FACTORY_ALWAYS ##### -->
+<!-- ##### FUNCTION gst_fakesrc_new ##### -->
 <para>
-Indicate that this pad will always be available.
-Use this in the factory definition.
+
 </para>
 
+@name: 
+@Returns: 
 
-<!-- ##### FUNCTION gst_pad_add_ghost_parent ##### -->
+<!-- ##### FUNCTION gst_fakesrc_push ##### -->
 <para>
 
 </para>
 
-@pad: 
-@parent: 
+@src: 
 
-<!-- ##### FUNCTION gst_audiosink_set_frequency ##### -->
+<!-- ##### FUNCTION gst_fdsink_chain ##### -->
 <para>
 
 </para>
 
-@audiosink
-@frequency
+@pad
+@buf
 
-<!-- ##### MACRO GST_TYPE_BIN ##### -->
+<!-- ##### FUNCTION gst_fdsink_get_type ##### -->
 <para>
 
 </para>
 
+@Returns: 
 
-<!-- ##### FUNCTION gst_elementfactory_register ##### -->
+<!-- ##### FUNCTION gst_fdsink_new ##### -->
 <para>
 
 </para>
 
-@elementfactory: 
+@name: 
+@Returns: 
 
-<!-- ##### ARG GstAudioSrc:bytes_per_read ##### -->
+<!-- ##### FUNCTION gst_fdsink_new_with_fd ##### -->
 <para>
-The number of bytes per read.
+
 </para>
 
+@name: 
+@fd: 
+@Returns: 
 
-<!-- ##### FUNCTION gst_element_loopfunc_wrapper ##### -->
+<!-- ##### FUNCTION gst_fdsrc_get_type ##### -->
 <para>
+
 </para>
 
-@argc: 
-@argv: 
 @Returns: 
 
-<!-- ##### MACRO GST_IS_SINESRC ##### -->
+<!-- ##### FUNCTION gst_filter_get_type ##### -->
 <para>
 
 </para>
 
-@obj
+@Returns
 
-<!-- ##### FUNCTION gst_meta_new_size ##### -->
+<!-- ##### FUNCTION gst_filter_new ##### -->
 <para>
 
 </para>
 
-@size: 
+@name: 
 @Returns: 
 
-<!-- ##### MACRO ERROR_OBJECT ##### -->
+<!-- ##### FUNCTION gst_httpsrc_get_type ##### -->
 <para>
 
 </para>
 
-@element: 
-@object: 
-@format: 
-@args...: 
+@Returns: 
 
-<!-- ##### FUNCTION gst_sinesrc_get_type ##### -->
+<!-- ##### FUNCTION gst_identity_chain ##### -->
 <para>
 
 </para>
 
-@Returns: 
+@pad: 
+@buf: 
 
-<!-- ##### MACRO GST_IS_IDENTITY ##### -->
+<!-- ##### FUNCTION gst_identity_get_type ##### -->
 <para>
 
 </para>
 
-@obj
+@Returns
 
-<!-- ##### MACRO GST_AUDIOSRC ##### -->
+<!-- ##### FUNCTION gst_identity_new ##### -->
 <para>
 
 </para>
 
-@obj: 
+@name: 
+@Returns: 
 
-<!-- ##### MACRO GST_TYPE_ESDSINK ##### -->
+<!-- ##### MACRO gst_meta_new ##### -->
 <para>
-
+Create new meta data.
 </para>
 
+@type: the type of the meta data to create
 
-<!-- ##### MACRO GST_FDSRC ##### -->
+<!-- ##### FUNCTION gst_meta_new_size ##### -->
 <para>
 
 </para>
 
-@obj: 
+@size: 
+@Returns: 
 
-<!-- ##### SECTION ./tmpl/gstaudiosrc.sgml:Long_Description ##### -->
+<!-- ##### FUNCTION gst_meta_ref ##### -->
 <para>
 
 </para>
 
+@meta: 
 
-<!-- ##### FUNCTION gst_audiosink_get_type ##### -->
+<!-- ##### FUNCTION gst_meta_unref ##### -->
 <para>
 
 </para>
 
-@Returns
+@meta
 
-<!-- ##### MACRO GST_OBJECT_CLASS ##### -->
+<!-- ##### FUNCTION gst_object_get_type ##### -->
 <para>
 
 </para>
 
-@klass: 
+@Returns: 
 
-<!-- ##### SECTION ./tmpl/gstconnection.sgml:Long_Description ##### -->
+<!-- ##### FUNCTION gst_object_new ##### -->
 <para>
-A connection is a bas class for a generic connection between
-elements. A connection is typically a bas class for queues.
 
 </para>
 
+@Returns: 
 
-<!-- ##### MACRO GST_BUFFER ##### -->
+<!-- ##### FUNCTION gst_pad_add_ghost_parent ##### -->
 <para>
 
 </para>
 
-@buf: 
+@pad: 
+@parent: 
 
-<!-- ##### MACRO GST_SRC_IS_ASYNC ##### -->
+<!-- ##### MACRO gst_pad_eos ##### -->
 <para>
-Query a GstSrc for the ASYNC flag
+Call the EOS function of the pad
 </para>
 
-@obj: The GstSrc to query
+@pad: the pad to call the eos function of.
 
-<!-- ##### MACRO GST_PIPELINE ##### -->
+<!-- ##### FUNCTION gst_pad_eos_func ##### -->
 <para>
 
 </para>
 
-@obj: 
+@pad: 
+@Returns: 
 
-<!-- ##### MACRO GST_STATE_SET ##### -->
+<!-- ##### FUNCTION gst_pad_get_caps_by_name ##### -->
 <para>
-This macro sets the given state on the element.
+
 </para>
 
-@obj: Element to set state of.
-@flag: State to set, can be any number of bits in guint32.
+@pad: 
+@name: 
+@Returns: 
 
-<!-- ##### FUNCTION gst_fakesink_get_type ##### -->
+<!-- ##### FUNCTION gst_pad_get_caps_list ##### -->
 <para>
 
 </para>
 
+@pad: 
 @Returns: 
 
-<!-- ##### MACRO GST_TYPE_CONNECTION ##### -->
+<!-- ##### FUNCTION gst_pad_get_directory ##### -->
 <para>
 
 </para>
 
+@pad: 
+@Returns: 
 
-<!-- ##### ENUM GstMetaFlags ##### -->
+<!-- ##### FUNCTION gst_pad_get_ghost_parents ##### -->
 <para>
-Flags indicating properties about the meta data.
+
 </para>
 
-@GST_META_FREEABLE: the meta data can be freed
+@pad: 
+@Returns: 
 
-<!-- ##### SECTION ./tmpl/spectrum.sgml:See_Also ##### -->
+<!-- ##### FUNCTION gst_pad_get_type ##### -->
 <para>
 
 </para>
 
+@Returns: 
 
-<!-- ##### MACRO GST_CONNECTION ##### -->
+<!-- ##### FUNCTION gst_pad_get_type_id ##### -->
 <para>
 
 </para>
 
-@obj: 
-
-<!-- ##### SECTION ./tmpl/videoraw.sgml:Short_Description ##### -->
-Information about video buffers.
-
+@pad: 
+@Returns: 
 
-<!-- ##### FUNCTION gst_fdsink_get_type ##### -->
+<!-- ##### FUNCTION gst_pad_handle_qos ##### -->
 <para>
 
 </para>
 
-@Returns: 
+@pad: 
+@qos_message: 
 
-<!-- ##### FUNCTION gst_src_push_region ##### -->
+<!-- ##### FUNCTION gst_pad_pull_region ##### -->
 <para>
 
 </para>
 
-@src
+@pad
 @offset: 
 @size: 
+@Returns: 
 
-<!-- ##### STRUCT GstPipelineClass ##### -->
+<!-- ##### FUNCTION gst_pad_remove_ghost_parent ##### -->
 <para>
 
 </para>
 
+@pad: 
+@parent: 
 
-<!-- ##### MACRO DEBUG_ENTER ##### -->
+<!-- ##### FUNCTION gst_pad_save_thyself ##### -->
 <para>
 
 </para>
 
-@format: 
-@args...: 
+@pad: 
+@parent: 
+@Returns: 
 
-<!-- ##### SIGNAL GstXML::object-loaded ##### -->
+<!-- ##### FUNCTION gst_pad_select ##### -->
 <para>
-Is trigered whenever the state of an element changes
+
 </para>
 
-@gstelement: the object which received the signal.
-@arg1: the new state of the object
+@nextpad: 
+@Varargs: 
+@Returns: 
 
-<!-- ##### MACRO GST_ELEMENT_CLASS ##### -->
+<!-- ##### FUNCTION gst_pad_set_caps_list ##### -->
 <para>
 
 </para>
 
-@klass: 
+@pad: 
+@caps: 
 
-<!-- ##### FUNCTION gst_fakesrc_new ##### -->
+<!-- ##### FUNCTION gst_pad_set_eos ##### -->
 <para>
 
 </para>
 
-@name
+@pad
 @Returns: 
 
-<!-- ##### FUNCTION gst_fakesrc_get_type ##### -->
+<!-- ##### FUNCTION gst_pad_set_eos_function ##### -->
 <para>
 
 </para>
 
-@Returns: 
-
-<!-- ##### SECTION ./tmpl/audioraw.sgml:Short_Description ##### -->
-Information about audio buffers.
-
+@pad: 
+@eos: 
 
-<!-- ##### SECTION ./tmpl/videoraw.sgml:See_Also ##### -->
+<!-- ##### FUNCTION gst_pad_set_pull_function ##### -->
 <para>
 
 </para>
 
+@pad: 
+@pull: 
 
-<!-- ##### SECTION ./tmpl/gstfilter.sgml:Short_Description ##### -->
-Take data in and spit data out
-
-
-<!-- ##### TYPEDEF GstPadFactory[] ##### -->
+<!-- ##### FUNCTION gst_pad_set_qos_function ##### -->
 <para>
-The padfactory.
+
 </para>
 
+@pad: 
+@qos: 
 
-<!-- ##### MACRO GST_SRC_ASYNC ##### -->
+<!-- ##### FUNCTION gst_pad_set_type_id ##### -->
 <para>
-This macro checks to see if the GST_SRC_ASYNC flag is set.
+
 </para>
 
-@obj: GstSrc to check for flag in.
+@pad: 
+@id: 
 
-<!-- ##### STRUCT GstPluginElement ##### -->
+<!-- ##### FUNCTION gst_padtemplate_create ##### -->
 <para>
 
 </para>
 
+@name_template: 
+@direction: 
+@presence: 
+@caps: 
+@Returns: 
 
-<!-- ##### MACRO GST_TYPE_SINESRC ##### -->
+<!-- ##### FUNCTION gst_pipeline_get_type ##### -->
 <para>
 
 </para>
 
+@Returns: 
 
-<!-- ##### SECTION ./tmpl/gstmeta.sgml:Title ##### -->
-GstMeta
-
-
-<!-- ##### TYPEDEF GstCapsFactory ##### -->
+<!-- ##### FUNCTION gst_plugin_add_autoplugger ##### -->
 <para>
 
 </para>
 
+@plugin: 
+@factory: 
 
-<!-- ##### STRUCT GstFdSrcClass ##### -->
+<!-- ##### FUNCTION gst_plugin_add_factory ##### -->
 <para>
 
 </para>
 
+@plugin: 
+@factory: 
 
-<!-- ##### MACRO GST_CPU_FLAG_SSE ##### -->
+<!-- ##### FUNCTION gst_plugin_add_type ##### -->
 <para>
-A flag indicating that SSE instructions are supported.
+
 </para>
 
+@plugin: 
+@factory: 
 
-<!-- ##### MACRO GST_IS_CONNECTION_CLASS ##### -->
+<!-- ##### FUNCTION gst_plugin_get_autoplug_list ##### -->
 <para>
 
 </para>
 
-@obj: 
+@plugin: 
+@Returns: 
 
-<!-- ##### FUNCTION gst_util_get_widget_arg ##### -->
+<!-- ##### FUNCTION gst_plugin_get_factory_list ##### -->
 <para>
 
 </para>
 
-@object: 
-@argname: 
+@plugin: 
 @Returns: 
 
-<!-- ##### ARG GstAsyncDiskSrc:size ##### -->
+<!-- ##### FUNCTION gst_plugin_get_type_list ##### -->
 <para>
 
 </para>
 
+@plugin: 
+@Returns: 
 
-<!-- ##### STRUCT GstDiskSrcClass ##### -->
+<!-- ##### FUNCTION gst_plugin_init ##### -->
 <para>
 
 </para>
 
 
-<!-- ##### MACRO GST_DEBUG_SET_STRING ##### -->
+<!-- ##### FUNCTION gst_plugin_load_autoplugfactory ##### -->
 <para>
-Set the debug string for the current function, typically containing the arguments
-to the current function, i.e. "('element')"
+
 </para>
 
-@format: printf-style format string
-@args...: printf arguments
+@name: 
+@Returns: 
 
-<!-- ##### FUNCTION gst_element_get_type ##### -->
+<!-- ##### FUNCTION gst_plugin_load_elementfactory ##### -->
 <para>
 
 </para>
 
+@name: 
 @Returns: 
 
-<!-- ##### FUNCTION gst_bin_remove_managed_element ##### -->
+<!-- ##### FUNCTION gst_plugin_load_typefactory ##### -->
 <para>
 
 </para>
 
-@bin: 
-@element: 
+@mime: 
 
-<!-- ##### STRUCT GstElementClass ##### -->
+<!-- ##### FUNCTION gst_props_register ##### -->
 <para>
 
 </para>
 
+@factory: 
+@Returns: 
 
-<!-- ##### MACRO GST_META_FLAG_SET ##### -->
+<!-- ##### FUNCTION gst_props_register_count ##### -->
 <para>
-Set a flag in the meta data.
+
 </para>
 
-@meta: the meta data
-@flag: the flag to set
+@factory: 
+@counter: 
+@Returns: 
 
-<!-- ##### MACRO GST_IS_SRC ##### -->
+<!-- ##### FUNCTION gst_queue_chain ##### -->
 <para>
 
 </para>
 
-@obj: 
+@pad: 
+@buf: 
 
-<!-- ##### SECTION ./tmpl/audioraw.sgml:Long_Description ##### -->
+<!-- ##### FUNCTION gst_queue_get_type ##### -->
 <para>
-Information about audio buffers.
+
 </para>
 
+@Returns: 
 
-<!-- ##### ENUM GstPropsId ##### -->
+<!-- ##### FUNCTION gst_queue_new ##### -->
 <para>
 
 </para>
 
-@GST_PROPS_END_ID_NUM: 
-@GST_PROPS_LIST_ID_NUM: 
-@GST_PROPS_INT_ID_NUM: 
-@GST_PROPS_INT_RANGE_ID_NUM: 
-@GST_PROPS_FOURCC_ID_NUM: 
-@GST_PROPS_BOOL_ID_NUM: 
+@name: 
+@Returns: 
 
-<!-- ##### ENUM GstCapsDefinition ##### -->
+<!-- ##### FUNCTION gst_queue_push ##### -->
 <para>
 
 </para>
 
-@GST_CAPS_ALWAYS: 
-@GST_CAPS_MAYBE: 
+@connection: 
 
-<!-- ##### MACRO GST_META_FLAG_IS_SET ##### -->
+<!-- ##### FUNCTION gst_sinesrc_get_type ##### -->
 <para>
-Check if a given flag is set.
+
 </para>
 
-@meta: the meta data to test
-@flag: the flag to test
+@Returns: 
 
-<!-- ##### STRUCT GstPadClass ##### -->
+<!-- ##### FUNCTION gst_sinesrc_new ##### -->
 <para>
 
 </para>
 
+@name: 
+@Returns: 
 
-<<<<<<< gstreamer-unused.sgml
-
-
-<!-- ##### SECTION ./tmpl/gstasyncdisksrc.sgml:See_Also ##### -->
+<!-- ##### FUNCTION gst_sinesrc_push ##### -->
 <para>
 
 </para>
 
+@src: 
 
-<!-- ##### MACRO GST_HTTPSRC ##### -->
->>>>>>> 1.23.2.3
+<!-- ##### FUNCTION gst_sink_get_type ##### -->
 <para>
 
 </para>
 
-@obj
+@Returns
 
-<!-- ##### STRUCT GstQueue ##### -->
+<!-- ##### FUNCTION gst_sink_new ##### -->
 <para>
 
 </para>
 
+@name: 
+@Returns: 
 
-<!-- ##### MACRO gst_meta_new ##### -->
+<!-- ##### FUNCTION gst_src_get_type ##### -->
 <para>
-Create new meta data.
+
 </para>
 
-@type: the type of the meta data to create
+@Returns: 
 
-<!-- ##### FUNCTION plugin_initialize ##### -->
+<!-- ##### FUNCTION gst_src_push ##### -->
 <para>
 
 </para>
 
+@src: 
 
-<!-- ##### FUNCTION gst_caps_register ##### -->
+<!-- ##### FUNCTION gst_src_push_region ##### -->
 <para>
 
 </para>
 
-@factory: 
-@Returns: 
+@src: 
+@offset: 
+@size: 
 
-<!-- ##### ARG GstAsyncDiskSrc:location ##### -->
+<!-- ##### FUNCTION gst_src_signal_eos ##### -->
 <para>
-Specify the location of the file to read.
+
 </para>
 
+@src: 
 
-<!-- ##### MACRO GST_TEE_CLASS ##### -->
+<!-- ##### FUNCTION gst_tee_chain ##### -->
 <para>
 
 </para>
 
-@klass: 
+@pad: 
+@buf: 
 
-<!-- ##### FUNCTION gst_queue_get_type ##### -->
+<!-- ##### FUNCTION gst_tee_get_type ##### -->
 <para>
 
 </para>
 
 @Returns: 
 
-<!-- ##### MACRO DEBUG_LEAVE ##### -->
+<!-- ##### FUNCTION gst_tee_new ##### -->
 <para>
 
 </para>
 
-@format
-@args...
+@name
+@Returns
 
-<!-- ##### FUNCTION gst_audiosink_set_format ##### -->
+<!-- ##### FUNCTION gst_tee_new_pad ##### -->
 <para>
 
 </para>
 
-@audiosink
-@format
+@tee
+@Returns
 
-<!-- ##### SECTION ./tmpl/spectrum.sgml:Long_Description ##### -->
+<!-- ##### FUNCTION gst_thread_get_type ##### -->
 <para>
-Frequencies of a spectrum analysis.
 
 </para>
 
+@Returns: 
 
-<!-- ##### SECTION ./tmpl/gstaudiosrc.sgml:Title ##### -->
-GstAudioSrc
-
-
-<!-- ##### MACRO GST_PAD_FACTORY_SOMETIMES ##### -->
+<!-- ##### FUNCTION gst_thread_iterate ##### -->
 <para>
-Indicate that this pad will become available depending
-on the media type. Use this in the factory definition.
+
 </para>
 
+@thread: 
 
-<!-- ##### MACRO INFO ##### -->
+<!-- ##### FUNCTION gst_thread_main_loop ##### -->
 <para>
 
 </para>
 
-@cat: 
-@format: 
-@args...: 
+@arg: 
 
-<!-- ##### SECTION ./tmpl/gstasyncdisksrc.sgml:Long_Description ##### -->
+<!-- ##### FUNCTION gst_type_add_sink ##### -->
 <para>
-Reads data from a file. You can seek to a specific location by setting
-the offset.
+
 </para>
 
+@id: 
+@sink: 
 
-<!-- ##### FUNCTION gst_sinesrc_new ##### -->
+<!-- ##### FUNCTION gst_type_add_src ##### -->
 <para>
 
 </para>
 
-@name
-@Returns
+@id
+@src
 
-<!-- ##### MACRO GST_IS_ASYNCDISKSRC_CLASS ##### -->
+<!-- ##### FUNCTION gst_type_dump ##### -->
 <para>
 
 </para>
 
-@obj: 
 
-<!-- ##### FUNCTION gst_buffer_get_metas ##### -->
+<!-- ##### FUNCTION gst_type_get_sink_to_src ##### -->
 <para>
 
 </para>
 
-@buffer: 
+@sinkid: 
+@srcid: 
 @Returns: 
 
-<!-- ##### ARG GstAudioSrc:curoffset ##### -->
+<!-- ##### FUNCTION gst_type_get_sinks ##### -->
 <para>
-Get the current number of bytes read.
+
 </para>
 
+@id: 
+@Returns: 
 
-<!-- ##### FUNCTION gst_plugin_init ##### -->
+<!-- ##### FUNCTION gst_type_get_srcs ##### -->
 <para>
 
 </para>
 
+@id: 
+@Returns: 
 
-<!-- ##### STRUCT MetaAudioSpectrum ##### -->
+<!-- ##### FUNCTION gst_type_initialize ##### -->
 <para>
 
 </para>
 
-@meta: 
-@bands: 
-@channels: 
-@interleaved: 
-@lowfreq: 
-@highfreq: 
-@steps: 
-
-<!-- ##### SECTION ./tmpl/plugin.sgml:Title ##### -->
-plugin
-
 
-<!-- ##### MACRO GST_IS_PAD ##### -->
+<!-- ##### FUNCTION gst_type_load_thyself ##### -->
 <para>
 
 </para>
 
-@obj: 
+@parent: 
+@Returns: 
 
-<!-- ##### STRUCT GstFakeSrcClass ##### -->
+<!-- ##### FUNCTION gst_type_save_thyself ##### -->
 <para>
 
 </para>
 
+@type: 
+@parent: 
+@Returns: 
 
-<!-- ##### FUNCTION gst_type_dump ##### -->
+<!-- ##### FUNCTION gst_typefactory_load_thyself ##### -->
 <para>
 
 </para>
 
+@parent: 
+@Returns: 
 
-<!-- ##### ARG GstAudioSink:channels ##### -->
+<!-- ##### FUNCTION gst_typefactory_save_thyself ##### -->
 <para>
 
 </para>
 
+@factory: 
+@parent: 
+@Returns: 
 
-<!-- ##### MACRO GST_BIN_CLASS ##### -->
+<!-- ##### FUNCTION gst_util_get_widget_arg ##### -->
 <para>
 
 </para>
 
-@klass: 
+@object: 
+@argname: 
+@Returns: 
 
-<!-- ##### MACRO GST_HTTPSRC_CLASS ##### -->
+<!-- ##### FUNCTION gst_xml_new_from_memory ##### -->
 <para>
 
 </para>
 
-@klass: 
+@buffer: 
+@size: 
+@root: 
+@Returns: 
 
-<!-- ##### MACRO GST_ASYNCDISKSRC ##### -->
+<!-- ##### FUNCTION plugin_initialize ##### -->
 <para>
 
 </para>
 
-@obj: 
 
-<!-- ##### ARG GstPad:active ##### -->
+<!-- ##### FUNCTION plugin_load ##### -->
 <para>
-Indicates this pad is active
+
 </para>
 
+@name: 
+@Returns: 
 
-<!-- ##### STRUCT GstTee ##### -->
+<!-- ##### FUNCTION plugin_load_absolute ##### -->
 <para>
 
 </para>
 
+@name: 
+@Returns: 
 
-<!-- ##### SECTION ./tmpl/gstsrc.sgml:Long_Description ##### -->
+<!-- ##### FUNCTION plugin_load_all ##### -->
 <para>
-A GstSrc is the start of a filter graph. It typically is a file or an
-audio source. It provides data for the next element in the graph.
 
 </para>
 
index 3152721..972d824 100644 (file)
@@ -14,7 +14,7 @@ A tee can be used to split out the filter graph.
 
 </para>
 
-<!-- ##### ARG GstTee:num_pads ##### -->
+<!-- ##### ARG GstTee:num-pads ##### -->
 <para>
 
 </para>
index bc4f3af..29151cb 100644 (file)
@@ -45,7 +45,7 @@ Thread flags:
 @Returns: 
 
 
-<!-- ##### ARG GstThread:create_thread ##### -->
+<!-- ##### ARG GstThread:create-thread ##### -->
 <para>
 TRUE if the thread should be created.
 
index 472d244..9b2ec82 100644 (file)
@@ -71,13 +71,14 @@ A type.
 @id: 
 @mime: 
 @exts: 
-@typefindfuncs: 
+@factories: 
 
 <!-- ##### STRUCT GstTypeFactory ##### -->
 <para>
 The struct with the typefactory information.
 </para>
 
+@feature: 
 @mime: 
 @exts: 
 @typefindfunc: 
@@ -126,22 +127,3 @@ The struct with the typefactory information.
 @Returns: 
 
 
-<!-- ##### FUNCTION gst_typefactory_load_thyself ##### -->
-<para>
-
-</para>
-
-@parent: 
-@Returns: 
-
-
-<!-- ##### FUNCTION gst_typefactory_save_thyself ##### -->
-<para>
-
-</para>
-
-@factory: 
-@parent: 
-@Returns: 
-
-
index 2e9b7c5..5498a68 100644 (file)
-some random ramblings about the event system:
+This is a round up from our IRC session on events. It's open for
+discussion of course.
 
-Possible candidates for events
+Definition 
+----------
+
+The event system is designed to be a mechanism for _inter_plugin_
+communication. Their scope is therefore limited in a way that they do
+not serve as a way to communicate between plugins and the app (signals
+and properties are still used for plugin-app communication).
+
+Events will be generated by either a plugin or the app. It should be
+possible for a plugin to generate an event on one of its pads and it
+should be possible for an app to insert an event on an abitrary pad in
+the pipeline.
+
+
+Event handling 
+--------------
+
+Events can both travel upstream or downstream. Some events, by nature,
+only travel in one direction.
+
+* downstream events
+
+  - Travel in the same way buffers do. This includes that they are handled
+    by the scheduler. The rationale is that the events should be kept
+    as close to the buffers are possible.
+
+  - plugins should check the type of the GstData passed in the _chain
+    or _loop function and act appropriatly. This can be done by either 
+    doing their own stuff or by calling the default handler.
+
+  - are handled on the sink pad.
+
+* upstream events
+
+  - are handled with an event handler attached to the srcpad. A default
+    handler will be implemented for pads that don't implement their own 
+    handler.
+
+  - travel as fast as possible. the rationale is that a seek event should
+    get to the src element ASAP.
+
+
+Possible candidates for events 
 ------------------------------
 
   - QoS
-  - EOS
-  - Seek
-  - caps nego??
-  - bufferpool get??
-  - ...
-
-Assumptions for events
-----------------------
+   quality of service. Plugins can notify other plugins about the quality
+   of the pipeline. A video element can for example say that it receives
+   too much frames and that plugins connected to it need to slow down.
 
-- They are tied to a pad.
-- get rid of gst_pad_set_*_function (except for the chain/get ones)
-- occur async to dataflow. (need locking?)
-- fixed set of events only for core features. (elements cannot abuse
-     events for doing dataflow)
+  - EOS
+   A plugin can notify other plugins that it has run out-of-data.
 
-Questions
----------
+  - Seek
+   Used to notify plugins that they need to seek to a certain byte offset
+   or timestamp.
 
-limit the valid directions an event can travel in? ie. Can EOS only 
-travel downstream (left to right)? 
+  - discontinuous
+   A plugin has detected a discontinuity in the stream. Other plugins
+   might need to resync.
 
-eg. Seek travels upstream, but it makes sense to also make it travel 
-    downstream (the case of a disksink, where we overwrite the header)
+  - flush
+   Plugins need to get rid of any buffered data ASAP.
 
+  - caps nego??  
+  - bufferpool get??  
+  - ...
 
-Setting an event function
--------------------------
 
-void gst_pad_set_event_function (GstPad *pad, gint event_mask,
-                                GstEventFunction *function);
+application generated events 
+----------------------------
 
+The application can insert events into the pipeline at arbirary
+places. This will be done by calling gst_pad_event() on a pad.
 
-event masks:
+A first implementation will only cover inserting events on src pads
+since inserting events on sinkpads needs changes to the scheduler.
 
-typedef enum {
-  GST_EVENT_EOS                = (1 << 0),
-  GST_EVENT_QOS                        = (1 << 1),
-  GST_EVENT_SEEK               = (1 << 2),
-  GST_EVENT_CAPS               = (1 << 3),
-} GstEventType;
 
-Event structure
----------------
+Effects of events on plugins 
+----------------------------
 
-typedef struct {
-  GstEventType type;
-  GstEventMinorType minor;
-  guint64 timestamp;  /* also sequence number ?? */
+some events are going to change the state of an element. The EOS event
+will for example change the state of an element to the PAUSED state. Not
+sure when or how this will happen.
 
-  union {
-    /* EOS stuff */
-    /* QoS stuff */
-    /* Seek stuff */
-    GstSeekType type; /* time, bytes, ... */
-    gint64 offset;
-    gint64 lenth;
-    /* Caps stuff */
-    GstCaps *caps;
-  } data;
-} GstEvent;
 
+use cases 
+---------
 
-typedef enum {
-  GST_EVENT_MINOR_NONE,
-  /* EOS stuff */
+1) filesrc ! fakesink
 
-  /* QoS stuff */
-  /* Seek stuff */
-  GST_EVENT_MINOR_OFFSET,
-  GST_EVENT_MINOR_TIME,
+filesrc will read until it reaches EOF. It will then create a GstEvent
+of type EOS and return it in the _get function. The event will travel
+downstream and will reach the fakesink element. Fakesink will detect
+the event in the _chain function and will call the default handler. The
+default handler will set the element to the paused state. filesrc will
+eventually change its state to PAUSED, probably before sending out the
+event (TBD)
 
-  /* caps nego stuff */
-  GST_EVENT_MINOR_CAPS_TRY,
-  GST_EVENT_MINOR_CAPS_START,
-  GST_EVENT_MINOR_CAPS_FINAL,
-} GstEventMinorType;  
+2) filesrc ! fakesink
 
+The app wants to perform a seek on filesrc. It'll call the gst_pad_event()
+on filesrcs src pad with the SEEK event type. The event handler will
+react and change filesrcs internal status. filesrc will return a DISCONT
+event before returning the buffer with the new offset.
 
-Receiving events
-----------------
+3) filesrc ! mpeg2parse video_0! queue ! { mpeg2dec ! xvideosink }
 
-a sample GstEventFunction, the event functions returns TRUE if the event is handled, 
-FALSE otherwise.
+lost of possibilities here: The app can choose to insert a seek event
+on the filesrc element (byte offset), it can insert a byte/time offset
+seek on the video_0 pad of mpeg2parse or it can insert a time seek event
+on mpeg2decs src pad.
 
-gboolean
-gst_anelement_handle_event (GstPad *pad, GstEvent *event)
-{
-  if (event->type == GST_EVENT_EOS) {
-    /* do something */
-    return TRUE;
-  }
-  else if (event->type == GST_EVENT_CAPS) {
-    if (event->minor == GST_EVENT_CAPS_TRY) {
-      /* try using this caps structure */
-      return TRUE; /* return FALSE to proxy ???*/
-    }
-  }
-  return FALSE;
-}
+the event will travel upstream using the handlers and the intermediate
+elements can convert the event from a time to a byte offset (possibly
+using GstTimeCache to speed up things).
 
+Filesrc will get a byte seek event on its src pad and will proceed as
+in case 2.
 
-Default event handler for pads
-------------------------------
+As can be seen from this example the app will generate an event in another
+context than those of the plugins, so this will need proper locking.
 
-gboolean
-gst_pad_handle_event (GstPad *pad, GstEvent *event)
-{
-  GstElement *element;
-  GList *pads;
-  GstPad *srcpad;
-  gboolean result = TRUE;
-  GstPadDirection dir = GST_PAD_DIRECTION (pad);
+The app can also choose to insert a flush event on one of the src
+pads. The plugins would clear their cached data and forward the event
+to their upstream peer pad(s).
 
-  g_return_val_if_fail (pad != NULL, FALSE);
-  g_return_val_if_fail (GST_IS_REAL_PAD(pad), FALSE);   // NOTE the restriction
+4)...
 
-  element = GST_ELEMENT (gst_object_get_parent (GST_OBJECT (pad)));
+Insert impossible case here..
 
-  /* send out the events to all pad with opposite direction */
-  pads = gst_element_get_pad_list(element);
-  while (pads) {
-    otherpad = GST_PAD(pads->data);
-    pads = g_list_next(pads);
 
-    if (gst_pad_get_direction(otherpad) != dir) {
-      result &= gst_pad_send_event (GST_REAL_PAD(otherpad), event);
-    }
-  }
 
-  /* result is combined result of all handlers? */
-  return result;
-}
 
-  
diff --git a/docs/random/wtay/events2 b/docs/random/wtay/events2
new file mode 100644 (file)
index 0000000..2e9b7c5
--- /dev/null
@@ -0,0 +1,140 @@
+some random ramblings about the event system:
+
+Possible candidates for events
+------------------------------
+
+  - QoS
+  - EOS
+  - Seek
+  - caps nego??
+  - bufferpool get??
+  - ...
+
+Assumptions for events
+----------------------
+
+- They are tied to a pad.
+- get rid of gst_pad_set_*_function (except for the chain/get ones)
+- occur async to dataflow. (need locking?)
+- fixed set of events only for core features. (elements cannot abuse
+     events for doing dataflow)
+
+Questions
+---------
+
+limit the valid directions an event can travel in? ie. Can EOS only 
+travel downstream (left to right)? 
+
+eg. Seek travels upstream, but it makes sense to also make it travel 
+    downstream (the case of a disksink, where we overwrite the header)
+
+
+Setting an event function
+-------------------------
+
+void gst_pad_set_event_function (GstPad *pad, gint event_mask,
+                                GstEventFunction *function);
+
+
+event masks:
+
+typedef enum {
+  GST_EVENT_EOS                = (1 << 0),
+  GST_EVENT_QOS                        = (1 << 1),
+  GST_EVENT_SEEK               = (1 << 2),
+  GST_EVENT_CAPS               = (1 << 3),
+} GstEventType;
+
+Event structure
+---------------
+
+typedef struct {
+  GstEventType type;
+  GstEventMinorType minor;
+  guint64 timestamp;  /* also sequence number ?? */
+
+  union {
+    /* EOS stuff */
+    /* QoS stuff */
+    /* Seek stuff */
+    GstSeekType type; /* time, bytes, ... */
+    gint64 offset;
+    gint64 lenth;
+    /* Caps stuff */
+    GstCaps *caps;
+  } data;
+} GstEvent;
+
+
+typedef enum {
+  GST_EVENT_MINOR_NONE,
+  /* EOS stuff */
+
+  /* QoS stuff */
+  /* Seek stuff */
+  GST_EVENT_MINOR_OFFSET,
+  GST_EVENT_MINOR_TIME,
+
+  /* caps nego stuff */
+  GST_EVENT_MINOR_CAPS_TRY,
+  GST_EVENT_MINOR_CAPS_START,
+  GST_EVENT_MINOR_CAPS_FINAL,
+} GstEventMinorType;  
+
+
+Receiving events
+----------------
+
+a sample GstEventFunction, the event functions returns TRUE if the event is handled, 
+FALSE otherwise.
+
+gboolean
+gst_anelement_handle_event (GstPad *pad, GstEvent *event)
+{
+  if (event->type == GST_EVENT_EOS) {
+    /* do something */
+    return TRUE;
+  }
+  else if (event->type == GST_EVENT_CAPS) {
+    if (event->minor == GST_EVENT_CAPS_TRY) {
+      /* try using this caps structure */
+      return TRUE; /* return FALSE to proxy ???*/
+    }
+  }
+  return FALSE;
+}
+
+
+Default event handler for pads
+------------------------------
+
+gboolean
+gst_pad_handle_event (GstPad *pad, GstEvent *event)
+{
+  GstElement *element;
+  GList *pads;
+  GstPad *srcpad;
+  gboolean result = TRUE;
+  GstPadDirection dir = GST_PAD_DIRECTION (pad);
+
+  g_return_val_if_fail (pad != NULL, FALSE);
+  g_return_val_if_fail (GST_IS_REAL_PAD(pad), FALSE);   // NOTE the restriction
+
+  element = GST_ELEMENT (gst_object_get_parent (GST_OBJECT (pad)));
+
+  /* send out the events to all pad with opposite direction */
+  pads = gst_element_get_pad_list(element);
+  while (pads) {
+    otherpad = GST_PAD(pads->data);
+    pads = g_list_next(pads);
+
+    if (gst_pad_get_direction(otherpad) != dir) {
+      result &= gst_pad_send_event (GST_REAL_PAD(otherpad), event);
+    }
+  }
+
+  /* result is combined result of all handlers? */
+  return result;
+}
+
+  
index 867972d..e21b563 100644 (file)
@@ -120,6 +120,7 @@ gst_editor_project_new (void)
 GstEditorProject *
 gst_editor_project_new_from_file (const guchar *fname) 
 {
+#ifndef GST_DISABLE_LOADSAVE
   GstEditorProject *editorproject;
   GstXML *xml;
   GList *elements;
@@ -140,8 +141,10 @@ gst_editor_project_new_from_file (const guchar *fname)
     
     elements = g_list_next (elements);
   }
-  
   return editorproject;
+#else
+  return NULL;
+#endif
 }
 
 void
@@ -162,7 +165,9 @@ gst_editor_project_save_as (GstEditorProject *project, const guchar *fname)
   while (elements) {
     GstElement *element = (GstElement *) elements->data;
 
+#ifndef GST_DISABLE_LOADSAVE
     xmlSaveFile (fname, gst_xml_write (element));
+#endif
 
     elements = g_list_next (elements);
   }
index 6fe9c9c..b81c156 100644 (file)
@@ -5,10 +5,16 @@ else
 GNOME_SUBDS =
 endif
 
-SUBDIRS = $(GNOME_SUBDS) \
+if GST_DISABLE_LOADSAVE
+GST_LOADSAVE_DIRS = 
+else
+GST_LOADSAVE_DIRS = xml typefind
+endif
+
+SUBDIRS = $(GNOME_SUBDS) $(GST_LOADSAVE_DIRS) \
           helloworld helloworld2 \
           queue queue2 queue3 queue4 \
-          launch thread xml plugins typefind mixer cutter
+          launch thread plugins mixer cutter
 
 DIST_SUBDIRS = autoplug \
           helloworld helloworld2 \
index 550b182..9de5ba5 100644 (file)
@@ -94,7 +94,9 @@ gst_play_have_type (GstElement *typefind, GstCaps *caps, GstElement *pipeline)
 
   gst_element_set_state (pipeline, GST_STATE_PLAYING);
       
+#ifndef GST_DISABLE_LOADSAVE
   xmlSaveFile("xmlTest.gst", gst_xml_write (GST_ELEMENT (pipeline)));
+#endif
 }
 
 gboolean 
index 0edbfa5..7a02edd 100644 (file)
@@ -182,7 +182,9 @@ int main(int argc,char *argv[])
     }   
     env_register_cp (channel_in->volenv,  num_channels * 10.0      , 1.0 / num_channels); /* to end level */
 
+#ifndef GST_DISABLE_LOADSAVE
     xmlSaveFile("mixer.xml", gst_xml_write(GST_ELEMENT(main_bin)));
+#endif
 
     /* start playing */
     gst_element_set_state(main_bin, GST_STATE_PLAYING);
@@ -356,7 +358,9 @@ create_input_channel (int id, char* location)
                  gst_element_get_pad (decoder, "src"), "src_00");
   
 #endif  
+#ifndef GST_DISABLE_LOADSAVE
   xmlSaveFile ("mixer.gst", gst_xml_write (new_element));
+#endif  
 
   gst_bin_add (GST_BIN(channel->pipe), channel->volenv);
   gst_bin_add (GST_BIN (channel->pipe), new_element);
index 6402882..6e75832 100644 (file)
@@ -8,6 +8,8 @@ else
 GSTARCH_SRCS = 
 endif
 
+#GST_INSTRUMENT_FLAGS = -finstrument-functions -DGST_ENABLE_FUNC_INSTRUMENTATION
+
 if USE_GLIB2
 GST_OBJECT_MODEL_SRC = gstmarshal.c
 GST_OBJECT_MODEL_HDR = gstmarshal.h
@@ -67,6 +69,7 @@ libgst_la_SOURCES =           \
        gstcpu.c                \
        gstelement.c            \
        gstelementfactory.c     \
+       gstevent.c              \
        gstextratypes.c         \
        gstinfo.c               \
        gstpad.c                \
@@ -154,6 +157,7 @@ libgstincludedir = $(includedir)/gst
 libgstinclude_HEADERS =                \
        cothreads.h             \
        gst.h                   \
+       gstconfig.h             \
        $(GST_OBJECT_MODEL_HDR) \
        gstobject.h             \
        gsttypes.h              \
@@ -164,6 +168,7 @@ libgstinclude_HEADERS =             \
        gstcaps.h               \
        gstclock.h              \
        gstcpu.h                \
+       gstdata.h               \
        gstelement.h            \
        gstevent.h              \
        gstextratypes.h         \
@@ -203,6 +208,7 @@ CFLAGS = \
        -Wnested-externs \
        -Winline -Wno-unused
 
+CFLAGS = $(LIBGST_CFLAGS) -D_GNU_SOURCE -DGST_CONFIG_DIR=\""$(GST_CONFIG_DIR)"\" -Wall
 LIBS = $(LIBGST_LIBS)
 LDFLAGS = ""
 libgst_la_LDFLAGS = -version-info $(GST_LIBVERSION)
index 68ed930..6138ff3 100644 (file)
@@ -430,7 +430,7 @@ gst_autoplugger_cache_empty(GstElement *element, GstAutoplugger *autoplugger)
     // try to PLAY the whole thing
     gst_element_set_state(GST_ELEMENT_SCHED(autoplugger)->parent,GST_STATE_PLAYING);
 
-  xmlSaveFile("autoplugger.gst", gst_xml_write(GST_ELEMENT_SCHED(autoplugger)->parent));
+//  xmlSaveFile("autoplugger.gst", gst_xml_write(GST_ELEMENT_SCHED(autoplugger)->parent));
 
   GST_INFO(GST_CAT_AUTOPLUG, "autoplugger_cache_empty finished");
 }
index 61c5ad7..f50e4f7 100644 (file)
@@ -8,6 +8,8 @@ else
 GSTHTTPSRC=
 endif
 
+#CFLAGS += -O2 -Wall -finstrument-functions -DGST_ENABLE_FUNC_INSTRUMENTATION
+
 libgstelements_la_DEPENDENCIES = ../libgst.la
 libgstelements_la_SOURCES =    \
        gstelements.c           \
@@ -37,8 +39,10 @@ noinst_HEADERS =             \
        gstfdsink.h             \
        gstpipefilter.h         \
        gsttee.h                \
-       gstaggregator.h
-CFLAGS += -O2 -Wall
+       gstaggregator.h         \
+       gstsinesrc.h
+
+CFLAGS += -O2 -Wall 
 LDFLAGS += -lm
 
 libgstelements_la_LIBADD = $(GHTTP_LIBS)
index eb6c301..49ec28f 100644 (file)
@@ -76,7 +76,8 @@ gst_aggregator_sched_get_type (void)
 static void    gst_aggregator_class_init       (GstAggregatorClass *klass);
 static void    gst_aggregator_init             (GstAggregator *aggregator);
 
-static GstPad*         gst_aggregator_request_new_pad  (GstElement *element, GstPadTemplate *temp);
+static GstPad*         gst_aggregator_request_new_pad  (GstElement *element, GstPadTemplate *temp, const
+                                                 gchar *unused);
 
 static void    gst_aggregator_set_property     (GObject *object, guint prop_id, 
                                                 const GValue *value, GParamSpec *pspec);
@@ -150,7 +151,7 @@ gst_aggregator_init (GstAggregator *aggregator)
 }
 
 static GstPad*
-gst_aggregator_request_new_pad (GstElement *element, GstPadTemplate *templ) 
+gst_aggregator_request_new_pad (GstElement *element, GstPadTemplate *templ, const gchar *unused
 {
   gchar *name;
   GstPad *sinkpad;
index ab13968..ffe1b35 100644 (file)
@@ -64,8 +64,8 @@ static void           gst_disksrc_set_property        (GObject *object, guint prop_id,
 static void            gst_disksrc_get_property        (GObject *object, guint prop_id, 
                                                         GValue *value, GParamSpec *pspec);
 
-static GstBuffer *     gst_disksrc_get                 (GstPad *pad);
-static GstBuffer *     gst_disksrc_get_region          (GstPad *pad,GstRegionType type,guint64 offset,guint64 len);
+static GstBuffer     gst_disksrc_get                 (GstPad *pad);
+static GstBufferPool*  gst_disksrc_get_bufferpool      (GstPad *pad);
 
 static GstElementStateReturn   
                        gst_disksrc_change_state        (GstElement *element);
@@ -73,7 +73,7 @@ static GstElementStateReturn
 static gboolean                gst_disksrc_open_file           (GstDiskSrc *src);
 static void            gst_disksrc_close_file          (GstDiskSrc *src);
 
-static GstElementClass *parent_class = NULL;
+static GstElementClassparent_class = NULL;
 //static guint gst_disksrc_signals[LAST_SIGNAL] = { 0 };
 
 GType
@@ -133,8 +133,8 @@ gst_disksrc_init (GstDiskSrc *disksrc)
 //  GST_FLAG_SET (disksrc, GST_SRC_);
 
   disksrc->srcpad = gst_pad_new ("src", GST_PAD_SRC);
-  gst_pad_set_get_function (disksrc->srcpad,gst_disksrc_get);
-  gst_pad_set_getregion_function (disksrc->srcpad,gst_disksrc_get_region);
+  gst_pad_set_get_function (disksrc->srcpad, gst_disksrc_get);
+  gst_pad_set_bufferpool_function (disksrc->srcpad, gst_disksrc_get_bufferpool);
   gst_element_add_pad (GST_ELEMENT (disksrc), disksrc->srcpad);
 
   disksrc->filename = NULL;
@@ -220,121 +220,98 @@ gst_disksrc_get_property (GObject *object, guint prop_id, GValue *value, GParamS
   }
 }
 
-/**
- * gst_disksrc_get:
- * @pad: #GstPad to push a buffer from
- *
- * Push a new buffer from the disksrc at the current offset.
- */
-static GstBuffer *
-gst_disksrc_get (GstPad *pad)
+static GstBuffer*
+gst_disksrc_buffer_new (GstBufferPool *pool, gint64 location, gint size, gpointer user_data)
 {
   GstDiskSrc *src;
   GstBuffer *buf;
 
-  g_return_val_if_fail (pad != NULL, NULL);
-  src = GST_DISKSRC (gst_pad_get_parent (pad));
-  g_return_val_if_fail (GST_FLAG_IS_SET (src, GST_DISKSRC_OPEN), NULL);
-
-
-  /* deal with EOF state */
-  if (src->curoffset >= src->size) {
-    GST_DEBUG (0,"map offset %ld >= size %ld --> eos\n", src->curoffset, src->size);
-    gst_pad_event(pad, GST_EVENT_EOS, 0LL, 0);
-    buf =  gst_buffer_new();
-    GST_BUFFER_FLAG_SET (buf, GST_BUFFER_EOS);
-    return buf;
-  }
+  src = GST_DISKSRC (user_data);
 
-  /* create the buffer */
-  // FIXME: should eventually use a bufferpool for this
   buf = gst_buffer_new ();
-
   g_return_val_if_fail (buf != NULL, NULL);
 
   /* simply set the buffer to point to the correct region of the file */
-  GST_BUFFER_DATA (buf) = src->map + src->curoffset;
-  GST_BUFFER_OFFSET (buf) = src->curoffset;
+  GST_BUFFER_DATA (buf) = src->map + location;
+  GST_BUFFER_OFFSET (buf) = location;
   GST_BUFFER_FLAG_SET (buf, GST_BUFFER_DONTFREE);
 
-  if ((src->curoffset + src->bytes_per_read) > src->size) {
-    GST_BUFFER_SIZE (buf) = src->size - src->curoffset;
-    // FIXME: set the buffer's EOF bit here
-  } else
-    GST_BUFFER_SIZE (buf) = src->bytes_per_read;
+  if ((location + size) > src->size) 
+    GST_BUFFER_SIZE (buf) = src->size - location;
+  else
+    GST_BUFFER_SIZE (buf) = size;
 
   GST_DEBUG (0,"map %p, offset %ld (%p), size %d\n", src->map, src->curoffset,
              src->map + src->curoffset, GST_BUFFER_SIZE (buf));
 
-  //gst_util_dump_mem (GST_BUFFER_DATA (buf), GST_BUFFER_SIZE (buf));
+  return buf;
+}
 
-  src->curoffset += GST_BUFFER_SIZE (buf);
+static void
+gst_disksrc_buffer_free (GstBuffer *buf)
+{
+  // FIXME do something here
+}
 
-  if (src->new_seek) {
-    GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLUSH);
-    GST_DEBUG (0,"new seek\n");
-    src->new_seek = FALSE;
+static GstBufferPool*
+gst_disksrc_get_bufferpool (GstPad *pad)
+{
+  GstDiskSrc *src;
+  
+  src = GST_DISKSRC (gst_pad_get_parent (pad));
+
+  if (!src->bufferpool) {
+    src->bufferpool = gst_buffer_pool_new ();
+    gst_buffer_pool_set_buffer_new_function    (src->bufferpool, gst_disksrc_buffer_new);
+    gst_buffer_pool_set_buffer_free_function   (src->bufferpool, gst_disksrc_buffer_free);
+    gst_buffer_pool_set_user_data              (src->bufferpool, src);
   }
 
-  /* we're done, return the buffer */
-  return buf;
+  return src->bufferpool;
 }
 
 /**
- * gst_disksrc_get_region:
- * @src: #GstSrc to push a buffer from
- * @offset: offset in file
- * @size: number of bytes
+ * gst_disksrc_get:
+ * @pad: #GstPad to push a buffer from
  *
- * Push a new buffer from the disksrc of given size at given offset.
+ * Push a new buffer from the disksrc at the current offset.
  */
 static GstBuffer *
-gst_disksrc_get_region (GstPad *pad, GstRegionType type,guint64 offset,guint64 len)
+gst_disksrc_get (GstPad *pad)
 {
   GstDiskSrc *src;
   GstBuffer *buf;
 
   g_return_val_if_fail (pad != NULL, NULL);
-  g_return_val_if_fail (type == GST_REGION_OFFSET_LEN, NULL);
-
   src = GST_DISKSRC (gst_pad_get_parent (pad));
-
-  g_return_val_if_fail (GST_IS_DISKSRC (src), NULL);
   g_return_val_if_fail (GST_FLAG_IS_SET (src, GST_DISKSRC_OPEN), NULL);
 
+
   /* deal with EOF state */
-  if (offset >= src->size) {
-    gst_pad_event (pad, GST_EVENT_EOS, 0LL, 0);
-    GST_DEBUG (0,"map offset %lld >= size %ld --> eos\n", offset, src->size);
-    //FIXME
+  if (src->curoffset >= src->size) {
+    GST_DEBUG (0,"map offset %ld >= size %ld --> eos\n", src->curoffset, src->size);
+    gst_pad_event(pad, GST_EVENT_EOS, 0LL, 0);
     buf =  gst_buffer_new();
     GST_BUFFER_FLAG_SET (buf, GST_BUFFER_EOS);
     return buf;
   }
 
-  /* create the buffer */
-  // FIXME: should eventually use a bufferpool for this
-  buf = gst_buffer_new ();
-  g_return_val_if_fail (buf != NULL, NULL);
-
-  /* simply set the buffer to point to the correct region of the file */
-  GST_BUFFER_DATA (buf) = src->map + offset;
-  GST_BUFFER_OFFSET (buf) = offset;
-  GST_BUFFER_FLAG_SET (buf, GST_BUFFER_DONTFREE);
+  // FIXME use a bufferpool
+  buf = gst_disksrc_buffer_new (NULL, src->curoffset, src->bytes_per_read, src);
 
-  if ((offset + len) > src->size) {
-    GST_BUFFER_SIZE (buf) = src->size - offset;
-    // FIXME: set the buffer's EOF bit here
-  } else
-    GST_BUFFER_SIZE (buf) = len;
+  //gst_util_dump_mem (GST_BUFFER_DATA (buf), GST_BUFFER_SIZE (buf));
+  src->curoffset += GST_BUFFER_SIZE (buf);
 
-  GST_DEBUG (0,"map %p, offset %lld, size %d\n", src->map, offset, GST_BUFFER_SIZE (buf));
+  if (src->new_seek) {
+    GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLUSH);
+    GST_DEBUG (0,"new seek\n");
+    src->new_seek = FALSE;
+  }
 
-  /* we're done, return the buffer off now */
+  /* we're done, return the buffer */
   return buf;
 }
 
-
 /* open the file and mmap it, necessary to go to READY state */
 static gboolean 
 gst_disksrc_open_file (GstDiskSrc *src)
index 155a362..4591254 100644 (file)
@@ -64,6 +64,7 @@ struct _GstDiskSrc {
   gchar *filename;
   /* fd */
   gint fd;
+  GstBufferPool *bufferpool;
 
   /* mapping parameters */
   gulong size;                         /* how long is the file? */
index 11eac00..02eb921 100644 (file)
@@ -45,6 +45,7 @@ enum {
   ARG_0,
   ARG_NUM_SINKS,
   ARG_SILENT,
+  ARG_DUMP,
 };
 
 GST_PADTEMPLATE_FACTORY (fakesink_sink_factory,
@@ -58,7 +59,8 @@ GST_PADTEMPLATE_FACTORY (fakesink_sink_factory,
 static void    gst_fakesink_class_init         (GstFakeSinkClass *klass);
 static void    gst_fakesink_init               (GstFakeSink *fakesink);
 
-static GstPad*         gst_fakesink_request_new_pad    (GstElement *element, GstPadTemplate *templ);
+static GstPad*         gst_fakesink_request_new_pad    (GstElement *element, GstPadTemplate *templ, const
+                                                 gchar *unused);
 
 static void    gst_fakesink_set_property       (GObject *object, guint prop_id, 
                                                 const GValue *value, GParamSpec *pspec);
@@ -66,7 +68,6 @@ static void   gst_fakesink_get_property       (GObject *object, guint prop_id,
                                                 GValue *value, GParamSpec *pspec);
 
 static void    gst_fakesink_chain              (GstPad *pad, GstBuffer *buf);
-static gboolean        gst_fakesink_event              (GstPad *pad, GstEventType event, guint64 timestamp, guint32 data);
 
 static GstElementClass *parent_class = NULL;
 static guint gst_fakesink_signals[LAST_SIGNAL] = { 0 };
@@ -109,6 +110,9 @@ gst_fakesink_class_init (GstFakeSinkClass *klass)
   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_SILENT,
     g_param_spec_boolean ("silent", "silent", "silent",
                           FALSE, G_PARAM_READWRITE)); 
+  g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_DUMP,
+    g_param_spec_boolean ("dump", "dump", "dump",
+                          FALSE, G_PARAM_READWRITE)); 
 
   gst_fakesink_signals[SIGNAL_HANDOFF] =
     g_signal_new ("handoff", G_TYPE_FROM_CLASS(klass), G_SIGNAL_RUN_LAST,
@@ -129,15 +133,15 @@ gst_fakesink_init (GstFakeSink *fakesink)
   pad = gst_pad_new ("sink", GST_PAD_SINK);
   gst_element_add_pad (GST_ELEMENT (fakesink), pad);
   gst_pad_set_chain_function (pad, GST_DEBUG_FUNCPTR (gst_fakesink_chain));
-  gst_pad_set_event_function (pad, GST_DEBUG_FUNCPTR (gst_fakesink_event));
 
   fakesink->sinkpads = g_slist_prepend (NULL, pad);
   fakesink->numsinkpads = 1;
   fakesink->silent = FALSE;
+  fakesink->dump = FALSE;
 }
 
 static GstPad*
-gst_fakesink_request_new_pad (GstElement *element, GstPadTemplate *templ)
+gst_fakesink_request_new_pad (GstElement *element, GstPadTemplate *templ, const gchar *unused)
 {
   gchar *name;
   GstPad *sinkpad;
@@ -175,6 +179,9 @@ gst_fakesink_set_property (GObject *object, guint prop_id, const GValue *value,
     case ARG_SILENT:
       sink->silent = g_value_get_boolean (value);
       break;
+    case ARG_DUMP:
+      sink->dump = g_value_get_boolean (value);
+      break;
     default:
       break;
   }
@@ -197,6 +204,9 @@ gst_fakesink_get_property (GObject *object, guint prop_id, GValue *value, GParam
     case ARG_SILENT:
       g_value_set_boolean (value, sink->silent);
       break;
+    case ARG_DUMP:
+      g_value_set_boolean (value, sink->dump);
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -206,9 +216,9 @@ gst_fakesink_get_property (GObject *object, guint prop_id, GValue *value, GParam
 /**
  * gst_fakesink_chain:
  * @pad: the pad this faksink is connected to
- * @buf: the buffer that has to be absorbed
+ * @buffer: the buffer or event that has to be absorbed
  *
- * take the buffer from the pad and unref it without doing
+ * Take the buffer or event from the pad and unref it without doing
  * anything with it.
  */
 static void 
@@ -221,12 +231,33 @@ gst_fakesink_chain (GstPad *pad, GstBuffer *buf)
   g_return_if_fail (buf != NULL);
 
   fakesink = GST_FAKESINK (gst_pad_get_parent (pad));
+
+  if (GST_IS_EVENT(buf)) {
+    GstEvent *event = GST_EVENT (buf);
+
+    switch (GST_EVENT_TYPE (event)) {
+      case GST_EVENT_EOS:
+        g_print("fakesink: have EOS event!\n");
+        gst_element_set_state (GST_ELEMENT (fakesink), GST_STATE_PAUSED);
+       break;
+      default:
+        g_print("fakesink: have unhandled event!\n");
+       break;
+    }
+    gst_event_free (event);
+    return;
+  }
+
   if (!fakesink->silent)
-    g_print("fakesink: chain   ******* (%s:%s)< (%d bytes, %lld) \n",
-                   GST_DEBUG_PAD_NAME (pad), GST_BUFFER_SIZE (buf), GST_BUFFER_TIMESTAMP (buf));
-  
-  g_signal_emit (G_OBJECT (fakesink), gst_fakesink_signals[SIGNAL_HANDOFF], 0,
-                   buf);
+    g_print("fakesink: chain   ******* (%s:%s)< (%d bytes, %lld) %p\n",
+               GST_DEBUG_PAD_NAME (pad), GST_BUFFER_SIZE (buf), GST_BUFFER_TIMESTAMP (buf), buf);
+
+  g_signal_emit (G_OBJECT (fakesink), gst_fakesink_signals[SIGNAL_HANDOFF], 0, buf, pad);
+
+  if (fakesink->dump)
+  {
+    gst_util_dump_mem (GST_BUFFER_DATA (buf), GST_BUFFER_SIZE (buf));
+  }
 
   gst_buffer_unref (buf);
 }
@@ -238,14 +269,3 @@ gst_fakesink_factory_init (GstElementFactory *factory)
 
   return TRUE;
 }
-
-
-
-static gboolean
-gst_fakesink_event (GstPad *pad, GstEventType event, guint64 timestamp, guint32 data)
-{
-  GST_DEBUG (GST_CAT_EVENT, "fakesink has event %d on pad %s:%s\n",event,GST_DEBUG_PAD_NAME(pad));
-  if (event == GST_EVENT_EOS) {
-    GST_DEBUG(GST_CAT_EVENT, "have EOS\n");
-  }
-}
index cafc18b..85aa9fb 100644 (file)
@@ -57,6 +57,7 @@ struct _GstFakeSink {
   GSList *sinkpads;
   gint numsinkpads;
   gboolean silent;
+  gboolean dump;
 };
 
 struct _GstFakeSinkClass {
index d946529..bed56e4 100644 (file)
@@ -21,6 +21,9 @@
  */
 
 
+#include <stdlib.h>
+#include <string.h>
+
 #include <gstfakesrc.h>
 
 
@@ -47,10 +50,17 @@ enum {
   ARG_NUM_SOURCES,
   ARG_LOOP_BASED,
   ARG_OUTPUT,
+  ARG_DATA,
+  ARG_SIZETYPE,
+  ARG_SIZEMIN,
+  ARG_SIZEMAX,
+  ARG_FILLTYPE,
   ARG_PATTERN,
   ARG_NUM_BUFFERS,
   ARG_EOS,
-  ARG_SILENT
+  ARG_SILENT,
+  ARG_DUMP,
+  ARG_PARENTSIZE
 };
 
 GST_PADTEMPLATE_FACTORY (fakesrc_src_factory,
@@ -82,12 +92,69 @@ gst_fakesrc_output_get_type (void)
   return fakesrc_output_type;
 }
 
+#define GST_TYPE_FAKESRC_DATA (gst_fakesrc_data_get_type())
+static GType
+gst_fakesrc_data_get_type (void) 
+{
+  static GType fakesrc_data_type = 0;
+  static GEnumValue fakesrc_data[] = {
+    { FAKESRC_DATA_ALLOCATE,           "2", "Allocate data"},
+    { FAKESRC_DATA_SUBBUFFER,          "3", "Subbuffer data"},
+    {0, NULL, NULL},
+  };
+  if (!fakesrc_data_type) {
+    fakesrc_data_type = g_enum_register_static ("GstFakeSrcData", fakesrc_data);
+  }
+  return fakesrc_data_type;
+}
+
+#define GST_TYPE_FAKESRC_SIZETYPE (gst_fakesrc_sizetype_get_type())
+static GType
+gst_fakesrc_sizetype_get_type (void) 
+{
+  static GType fakesrc_sizetype_type = 0;
+  static GEnumValue fakesrc_sizetype[] = {
+    { FAKESRC_SIZETYPE_NULL,           "1", "Send empty buffers"},
+    { FAKESRC_SIZETYPE_FIXED,          "2", "Fixed size buffers (sizemax sized)"},
+    { FAKESRC_SIZETYPE_RANDOM,                 "3", "Random sized buffers (sizemin <= size <= sizemax)"},
+    {0, NULL, NULL},
+  };
+  if (!fakesrc_sizetype_type) {
+    fakesrc_sizetype_type = g_enum_register_static ("GstFakeSrcSizeType", fakesrc_sizetype);
+  }
+  return fakesrc_sizetype_type;
+}
+
+#define GST_TYPE_FAKESRC_FILLTYPE (gst_fakesrc_filltype_get_type())
+static GType
+gst_fakesrc_filltype_get_type (void) 
+{
+  static GType fakesrc_filltype_type = 0;
+  static GEnumValue fakesrc_filltype[] = {
+    { FAKESRC_FILLTYPE_NOTHING,        "1", "Leave data as malloced"},
+    { FAKESRC_FILLTYPE_NULL,           "2", "Fill buffers with zeros"},
+    { FAKESRC_FILLTYPE_RANDOM,                 "3", "Fill buffers with random crap"},
+    { FAKESRC_FILLTYPE_PATTERN,        "4", "Fill buffers with pattern 0x00 -> 0xff"},
+    { FAKESRC_FILLTYPE_PATTERN_CONT,   "5", "Fill buffers with pattern 0x00 -> 0xff that spans buffers"},
+    {0, NULL, NULL},
+  };
+  if (!fakesrc_filltype_type) {
+    fakesrc_filltype_type = g_enum_register_static ("GstFakeSrcFillType", fakesrc_filltype);
+  }
+  return fakesrc_filltype_type;
+}
+
 static void            gst_fakesrc_class_init          (GstFakeSrcClass *klass);
 static void            gst_fakesrc_init                (GstFakeSrc *fakesrc);
 
 static GstPad*                 gst_fakesrc_request_new_pad     (GstElement *element, GstPadTemplate *templ);
-static void            gst_fakesrc_set_property        (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec);
-static void            gst_fakesrc_get_property        (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec);
+static void            gst_fakesrc_update_functions    (GstFakeSrc *src);
+static void            gst_fakesrc_set_property        (GObject *object, guint prop_id, 
+                                                        const GValue *value, GParamSpec *pspec);
+static void            gst_fakesrc_get_property        (GObject *object, guint prop_id, 
+                                                        GValue *value, GParamSpec *pspec);
+
+static GstElementStateReturn gst_fakesrc_change_state  (GstElement *element);
 
 static GstBuffer*      gst_fakesrc_get                 (GstPad *pad);
 static void            gst_fakesrc_loop                (GstElement *element);
@@ -137,6 +204,24 @@ gst_fakesrc_class_init (GstFakeSrcClass *klass)
   g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_OUTPUT,
     g_param_spec_enum("output","output","output",
                       GST_TYPE_FAKESRC_OUTPUT,FAKESRC_FIRST_LAST_LOOP,G_PARAM_READWRITE)); // CHECKME!
+  g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_DATA,
+    g_param_spec_enum ("data", "data", "data",
+                       GST_TYPE_FAKESRC_DATA, FAKESRC_DATA_ALLOCATE, G_PARAM_READWRITE)); 
+  g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_SIZETYPE,
+    g_param_spec_enum ("sizetype", "sizetype", "sizetype",
+                       GST_TYPE_FAKESRC_SIZETYPE, FAKESRC_SIZETYPE_NULL, G_PARAM_READWRITE)); 
+  g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_SIZEMIN,
+    g_param_spec_int ("sizemin","sizemin","sizemin",
+                      0, G_MAXINT, 0, G_PARAM_READWRITE)); 
+  g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_SIZEMAX,
+    g_param_spec_int ("sizemax","sizemax","sizemax",
+                      0, G_MAXINT, 4096, G_PARAM_READWRITE)); 
+  g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_PARENTSIZE,
+    g_param_spec_int ("parentsize","parentsize","parentsize",
+                      0, G_MAXINT, 4096 * 10, G_PARAM_READWRITE)); 
+  g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_FILLTYPE,
+    g_param_spec_enum ("filltype", "filltype", "filltype",
+                       GST_TYPE_FAKESRC_FILLTYPE, FAKESRC_FILLTYPE_NULL, G_PARAM_READWRITE)); 
   g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_PATTERN,
     g_param_spec_string("pattern","pattern","pattern",
                         NULL, G_PARAM_READWRITE)); // CHECKME
@@ -149,6 +234,9 @@ gst_fakesrc_class_init (GstFakeSrcClass *klass)
   g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_SILENT,
     g_param_spec_boolean("silent","silent","silent",
                          FALSE, G_PARAM_READWRITE)); // CHECKME
+  g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_DUMP,
+    g_param_spec_boolean ("dump","dump","dump",
+                          FALSE, G_PARAM_READWRITE)); 
 
   gst_fakesrc_signals[SIGNAL_HANDOFF] =
     g_signal_new ("handoff", G_TYPE_FROM_CLASS(klass), G_SIGNAL_RUN_LAST,
@@ -159,7 +247,8 @@ gst_fakesrc_class_init (GstFakeSrcClass *klass)
   gobject_class->set_property = GST_DEBUG_FUNCPTR (gst_fakesrc_set_property);
   gobject_class->get_property = GST_DEBUG_FUNCPTR (gst_fakesrc_get_property);
 
-  gstelement_class->request_new_pad = GST_DEBUG_FUNCPTR (gst_fakesrc_request_new_pad);
+  gstelement_class->request_new_pad =  GST_DEBUG_FUNCPTR (gst_fakesrc_request_new_pad);
+  gstelement_class->change_state =     GST_DEBUG_FUNCPTR (gst_fakesrc_change_state);
 }
 
 static void 
@@ -176,17 +265,21 @@ gst_fakesrc_init (GstFakeSrc *fakesrc)
   fakesrc->srcpads = g_slist_append (NULL, pad);
 
   fakesrc->loop_based = FALSE;
-
-  if (fakesrc->loop_based)
-    gst_element_set_loop_function (GST_ELEMENT (fakesrc), GST_DEBUG_FUNCPTR (gst_fakesrc_loop));
-  else
-    gst_pad_set_get_function (pad, GST_DEBUG_FUNCPTR (gst_fakesrc_get));
+  gst_fakesrc_update_functions (fakesrc);
 
   fakesrc->num_buffers = -1;
   fakesrc->buffer_count = 0;
   fakesrc->silent = FALSE;
-  // we're ready right away, since we don't have any args...
-//  gst_element_set_state(GST_ELEMENT(fakesrc),GST_STATE_READY);
+  fakesrc->dump = FALSE;
+  fakesrc->pattern_byte = 0x00;
+  fakesrc->need_flush = FALSE;
+  fakesrc->data = FAKESRC_DATA_ALLOCATE;
+  fakesrc->sizetype = FAKESRC_SIZETYPE_NULL;
+  fakesrc->filltype = FAKESRC_FILLTYPE_NOTHING;
+  fakesrc->sizemin = 0;
+  fakesrc->sizemax = 4096;
+  fakesrc->parent = NULL;
+  fakesrc->parentsize = 4096 * 10;
 }
 
 static GstPad*
@@ -216,6 +309,34 @@ gst_fakesrc_request_new_pad (GstElement *element, GstPadTemplate *templ)
   return srcpad;
 }
 
+static gboolean
+gst_fakesrc_event_handler (GstPad *pad, GstEvent *event)
+{
+  GstFakeSrc *src;
+
+  src = GST_FAKESRC (gst_pad_get_parent (pad));
+
+  switch (GST_EVENT_TYPE (event)) {
+    case GST_EVENT_SEEK:
+      g_print("fakesrc: have seek event\n");
+      src->buffer_count = GST_EVENT_SEEK_OFFSET (event);
+      if (!GST_EVENT_SEEK_FLUSH (event)) {
+        gst_event_free (event);
+        break;
+      }
+      // else we do a flush too
+    case GST_EVENT_FLUSH:
+      g_print("fakesrc: have flush event\n");
+      src->need_flush = TRUE;
+      break;
+    default:
+      g_print("fakesrc: have unhandled event\n");
+      break;
+  }
+
+  return TRUE;
+}
+
 static void
 gst_fakesrc_update_functions (GstFakeSrc *src)
 {
@@ -238,11 +359,26 @@ gst_fakesrc_update_functions (GstFakeSrc *src)
     else {
       gst_pad_set_get_function (pad, GST_DEBUG_FUNCPTR (gst_fakesrc_get));
     }
+
+    gst_pad_set_event_function (pad, gst_fakesrc_event_handler);
     pads = g_slist_next (pads);
   }
 }
 
 static void
+gst_fakesrc_alloc_parent (GstFakeSrc *src)
+{
+  GstBuffer *buf;
+
+  buf = gst_buffer_new ();
+  GST_BUFFER_DATA (buf) = g_malloc (src->parentsize);
+  GST_BUFFER_SIZE (buf) = src->parentsize;
+
+  src->parent = buf;
+  src->parentoffset = 0;
+}
+
+static void
 gst_fakesrc_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
 {
   GstFakeSrc *src;
@@ -257,6 +393,37 @@ gst_fakesrc_set_property (GObject *object, guint prop_id, const GValue *value, G
       break;
     case ARG_OUTPUT:
       break;
+    case ARG_DATA:
+      src->data = g_value_get_int (value);
+      switch (src->data) {
+       case FAKESRC_DATA_ALLOCATE:
+          if (src->parent) {
+            gst_buffer_unref (src->parent);
+            src->parent = NULL;
+         }
+          break;
+       case FAKESRC_DATA_SUBBUFFER:
+         if (!src->parent)
+           gst_fakesrc_alloc_parent (src);
+       default:
+          break;
+      }
+      break;
+    case ARG_SIZETYPE:
+      src->sizetype = g_value_get_int (value);
+      break;
+    case ARG_SIZEMIN:
+      src->sizemin = g_value_get_int (value);
+      break;
+    case ARG_SIZEMAX:
+      src->sizemax = g_value_get_int (value);
+      break;
+    case ARG_PARENTSIZE:
+      src->parentsize = g_value_get_int (value);
+      break;
+    case ARG_FILLTYPE:
+      src->filltype = g_value_get_int (value);
+      break;
     case ARG_PATTERN:
       break;
     case ARG_NUM_BUFFERS:
@@ -269,6 +436,9 @@ GST_INFO (0, "will EOS on next buffer");
     case ARG_SILENT:
       src->silent = g_value_get_boolean (value);
       break;
+    case ARG_DUMP:
+      src->dump = g_value_get_boolean (value);
+      break;
     default:
       break;
   }
@@ -294,6 +464,24 @@ gst_fakesrc_get_property (GObject *object, guint prop_id, GValue *value, GParamS
     case ARG_OUTPUT:
       g_value_set_int (value, src->output);
       break;
+    case ARG_DATA:
+      g_value_set_int (value, src->data);
+      break;
+    case ARG_SIZETYPE:
+      g_value_set_int (value, src->sizetype);
+      break;
+    case ARG_SIZEMIN:
+      g_value_set_int (value, src->sizemin);
+      break;
+    case ARG_SIZEMAX:
+      g_value_set_int (value, src->sizemax);
+      break;
+    case ARG_PARENTSIZE:
+      g_value_set_int (value, src->parentsize);
+      break;
+    case ARG_FILLTYPE:
+      g_value_set_int (value, src->filltype);
+      break;
     case ARG_PATTERN:
       g_value_set_string (value, src->pattern);
       break;
@@ -306,21 +494,150 @@ gst_fakesrc_get_property (GObject *object, guint prop_id, GValue *value, GParamS
     case ARG_SILENT:
       g_value_set_boolean (value, src->silent);
       break;
+    case ARG_DUMP:
+      g_value_set_boolean (value, src->dump);
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
   }
 }
 
+static void
+gst_fakesrc_prepare_buffer (GstFakeSrc *src, GstBuffer *buf)
+{
+  if (GST_BUFFER_SIZE (buf) == 0) 
+    return;
+
+  switch (src->filltype) {
+    case FAKESRC_FILLTYPE_NULL:
+      memset (GST_BUFFER_DATA (buf), 0, GST_BUFFER_SIZE (buf));
+      break;
+    case FAKESRC_FILLTYPE_RANDOM:
+    {
+      gint i;
+      guint8 *ptr = GST_BUFFER_DATA (buf);
+
+      for (i = GST_BUFFER_SIZE (buf); i; i--) {
+       *ptr++ = (gint8)((255.0)*rand()/(RAND_MAX));
+      }
+      break;
+    }
+    case FAKESRC_FILLTYPE_PATTERN:
+      src->pattern_byte = 0x00;
+    case FAKESRC_FILLTYPE_PATTERN_CONT:
+    {
+      gint i;
+      guint8 *ptr = GST_BUFFER_DATA (buf);
+
+      for (i = GST_BUFFER_SIZE (buf); i; i--) {
+       *ptr++ = src->pattern_byte++;
+      }
+      break;
+    }
+    case FAKESRC_FILLTYPE_NOTHING:
+    default:
+      break;
+  }
+}
+
+static GstBuffer*
+gst_fakesrc_alloc_buffer (GstFakeSrc *src, guint size)
+{
+  GstBuffer *buf;
+
+  buf = gst_buffer_new ();
+  GST_BUFFER_SIZE(buf) = size;
+
+  if (size != 0) { 
+    switch (src->filltype) {
+      case FAKESRC_FILLTYPE_NOTHING:
+        GST_BUFFER_DATA(buf) = g_malloc (size);
+        break;
+      case FAKESRC_FILLTYPE_NULL:
+        GST_BUFFER_DATA(buf) = g_malloc0 (size);
+        break;
+      case FAKESRC_FILLTYPE_RANDOM:
+      case FAKESRC_FILLTYPE_PATTERN:
+      case FAKESRC_FILLTYPE_PATTERN_CONT:
+      default:
+        GST_BUFFER_DATA(buf) = g_malloc (size);
+        gst_fakesrc_prepare_buffer (src, buf);
+        break;
+    }
+  }
+
+  return buf;
+}
+
+static guint
+gst_fakesrc_get_size (GstFakeSrc *src)
+{
+  guint size;
+
+  switch (src->sizetype) {
+    case FAKESRC_SIZETYPE_FIXED:
+      size = src->sizemax;
+      break;
+    case FAKESRC_SIZETYPE_RANDOM:
+      size = src->sizemin + (guint8)(((gfloat)src->sizemax)*rand()/(RAND_MAX + (gfloat)src->sizemin));
+      break;
+    case FAKESRC_SIZETYPE_NULL:
+    default:
+      size = 0; 
+      break;
+  }
+
+  return size;
+}
+
+static GstBuffer *
+gst_fakesrc_create_buffer (GstFakeSrc *src)
+{
+  GstBuffer *buf;
+  guint size;
+  gboolean dump = src->dump;
+
+  size = gst_fakesrc_get_size (src);
+  if (size == 0)
+    return gst_buffer_new();
+
+  switch (src->data) {
+    case FAKESRC_DATA_ALLOCATE:
+      buf = gst_fakesrc_alloc_buffer (src, size);
+      break;
+    case FAKESRC_DATA_SUBBUFFER:
+      // see if we have a parent to subbuffer
+      if (!src->parent) {
+       gst_fakesrc_alloc_parent (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);
+        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_fakesrc_create_buffer (src);
+      }
+      gst_fakesrc_prepare_buffer (src, buf);
+      break;
+    default:
+      g_warning ("fakesrc: dunno how to allocate buffers !");
+      buf = gst_buffer_new();
+      break;
+  }
+  if (dump) {
+    gst_util_dump_mem (GST_BUFFER_DATA (buf), GST_BUFFER_SIZE (buf));
+  }
+
+  return buf;
+}
 
-/**
- * gst_fakesrc_get:
- * @src: the faksesrc to get
- * 
- * generate an empty buffer and return it
- *
- * Returns: a new empty buffer
- */
 static GstBuffer *
 gst_fakesrc_get(GstPad *pad)
 {
@@ -333,9 +650,16 @@ gst_fakesrc_get(GstPad *pad)
 
   g_return_val_if_fail (GST_IS_FAKESRC (src), NULL);
 
+  if (src->need_flush) {
+    src->need_flush = FALSE;
+    g_print("fakesrc: sending FLUSH\n");
+    return GST_BUFFER(gst_event_new (GST_EVENT_FLUSH));
+  }
+
   if (src->num_buffers == 0) {
-    gst_pad_event (pad, GST_EVENT_EOS, 0LL, 0);
-    return NULL;
+    g_print("fakesrc: sending EOS\n");
+    gst_element_set_state (GST_ELEMENT (src), GST_STATE_PAUSED);
+    return GST_BUFFER(gst_event_new (GST_EVENT_EOS));
   }
   else {
     if (src->num_buffers > 0)
@@ -344,11 +668,11 @@ gst_fakesrc_get(GstPad *pad)
 
   if (src->eos) {
     GST_INFO (0, "fakesrc is setting eos on pad");
-    gst_pad_event (pad, GST_EVENT_EOS, 0LL, 0);
-    return NULL;
+    g_print("fakesrc: sending EOS\n");
+    return GST_BUFFER(gst_event_new (GST_EVENT_EOS));
   }
 
-  buf = gst_buffer_new();
+  buf = gst_fakesrc_create_buffer (src);
   GST_BUFFER_TIMESTAMP (buf) = src->buffer_count++;
 
   if (!src->silent)
@@ -356,7 +680,7 @@ gst_fakesrc_get(GstPad *pad)
                GST_DEBUG_PAD_NAME (pad), GST_BUFFER_SIZE (buf), GST_BUFFER_TIMESTAMP (buf));
 
   g_signal_emit (G_OBJECT (src), gst_fakesrc_signals[SIGNAL_HANDOFF], 0,
-                   buf);
+                   buf, pad);
 
   return buf;
 }
@@ -387,21 +711,20 @@ gst_fakesrc_loop(GstElement *element)
       GstBuffer *buf;
 
       if (src->num_buffers == 0) {
-        gst_pad_event (pad, GST_EVENT_EOS, 0LL, 0);
-        return;
+       src->eos = TRUE;
       }
       else {
-      if (src->num_buffers > 0)
-         src->num_buffers--;
+        if (src->num_buffers > 0)
+          src->num_buffers--;
       }
 
       if (src->eos) {
         GST_INFO (0, "fakesrc is setting eos on pad");
-        gst_pad_event (pad, GST_EVENT_EOS, 0LL, 0);
-        return;
+        gst_pad_push(pad, GST_BUFFER(gst_event_new (GST_EVENT_EOS)));
+       return;
       }
 
-      buf = gst_buffer_new();
+      buf = gst_fakesrc_create_buffer (src);
       GST_BUFFER_TIMESTAMP (buf) = src->buffer_count++;
 
       if (!src->silent)
@@ -409,7 +732,7 @@ gst_fakesrc_loop(GstElement *element)
                GST_DEBUG_PAD_NAME (pad), GST_BUFFER_SIZE (buf), GST_BUFFER_TIMESTAMP (buf));
 
       g_signal_emit (G_OBJECT (src), gst_fakesrc_signals[SIGNAL_HANDOFF], 0,
-                       buf);
+                       buf, pad);
       gst_pad_push (pad, buf);
 
       pads = g_slist_next (pads);
@@ -417,6 +740,31 @@ gst_fakesrc_loop(GstElement *element)
   } while (!GST_ELEMENT_IS_COTHREAD_STOPPING (element));
 }
 
+static GstElementStateReturn
+gst_fakesrc_change_state (GstElement *element)
+{
+  GstFakeSrc *fakesrc;
+
+  g_return_val_if_fail (GST_IS_FAKESRC (element), GST_STATE_FAILURE);
+
+  fakesrc = GST_FAKESRC (element);
+
+  if (GST_STATE_PENDING (element) == GST_STATE_READY) {
+    fakesrc->buffer_count = 0;
+    fakesrc->pattern_byte = 0x00;
+    fakesrc->need_flush = FALSE;
+    if (fakesrc->parent) {
+      gst_buffer_unref (fakesrc->parent);
+      fakesrc->parent = NULL;
+    }
+  }
+
+  if (GST_ELEMENT_CLASS (parent_class)->change_state)
+    return GST_ELEMENT_CLASS (parent_class)->change_state (element);
+
+  return GST_STATE_SUCCESS;
+}
+
 gboolean
 gst_fakesrc_factory_init (GstElementFactory *factory)
 {
index ce5c2a9..550015b 100644 (file)
@@ -47,6 +47,25 @@ typedef enum {
   FAKESRC_GET_ALWAYS_SUCEEDS,
 } GstFakeSrcOutputType;
 
+typedef enum {
+  FAKESRC_DATA_ALLOCATE = 1,
+  FAKESRC_DATA_SUBBUFFER,
+} GstFakeSrcDataType;
+
+typedef enum {
+  FAKESRC_SIZETYPE_NULL = 1,
+  FAKESRC_SIZETYPE_FIXED,
+  FAKESRC_SIZETYPE_RANDOM
+} GstFakeSrcSizeType;
+
+typedef enum {
+  FAKESRC_FILLTYPE_NOTHING = 1,
+  FAKESRC_FILLTYPE_NULL,
+  FAKESRC_FILLTYPE_RANDOM,
+  FAKESRC_FILLTYPE_PATTERN,
+  FAKESRC_FILLTYPE_PATTERN_CONT
+} GstFakeSrcFillType;
+
 #define GST_TYPE_FAKESRC \
   (gst_fakesrc_get_type())
 #define GST_FAKESRC(obj) \
@@ -64,16 +83,29 @@ typedef struct _GstFakeSrcClass GstFakeSrcClass;
 struct _GstFakeSrc {
   GstElement element;
 
-  gboolean loop_based;
-  gboolean eos;
-  gint numsrcpads;
-  GSList *srcpads;
+  gboolean     loop_based;
+  gboolean     eos;
+  gint                 numsrcpads;
+  GSList       *srcpads;
+
   GstFakeSrcOutputType output;
-  gchar *pattern;
-  GList *patternlist;
-  gint num_buffers;
-  guint64 buffer_count;
-  gboolean silent;
+  GstFakeSrcDataType data;
+  GstFakeSrcSizeType sizetype;
+  GstFakeSrcFillType filltype;
+
+  guint        sizemin;
+  guint        sizemax;
+  GstBuffer    *parent;
+  guint        parentsize;
+  guint        parentoffset;
+  guint8       pattern_byte;
+  gchar        *pattern;
+  GList        *patternlist;
+  gint                 num_buffers;
+  guint64      buffer_count;
+  gboolean     silent;
+  gboolean     dump;
+  gboolean     need_flush;
 };
 
 struct _GstFakeSrcClass {
index 3621494..f53548f 100644 (file)
@@ -27,6 +27,7 @@
 #include <fcntl.h>
 #include <unistd.h>
 #include <sys/mman.h>
+#include <errno.h>
 
 
 /**********************************************************************
@@ -74,6 +75,9 @@ GstElementDetails gst_filesrc_details = {
   "(C) 1999",
 };
 
+//#define fs_print(format,args...) g_print(format, ## args)
+#define fs_print(format,args...)
+
 
 #define GST_TYPE_FILESRC \
   (gst_filesrc_get_type())
@@ -110,10 +114,12 @@ struct _GstFileSrc {
   gboolean touch;                      // whether to touch every page
 
   GstBuffer *mapbuf;
-  off_t mapsize;
+  size_t mapsize;
 
   GTree *map_regions;
   GMutex *map_regions_lock;
+
+  gboolean seek_happened;
 };
 
 struct _GstFileSrcClass {
@@ -135,6 +141,7 @@ enum {
   ARG_BLOCKSIZE,
   ARG_OFFSET,
   ARG_MAPSIZE,
+  ARG_TOUCH,
 };
 
 
@@ -203,6 +210,9 @@ gst_filesrc_class_init (GstFileSrcClass *klass)
   g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_MAPSIZE,
     g_param_spec_ulong("mmapsize","mmap() Block Size","Size in bytes of mmap()d regions",
                        0,G_MAXULONG,4*1048576,G_PARAM_READWRITE));
+  g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_TOUCH,
+    g_param_spec_boolean("touch","Touch read data","Touch data to force disk read before push()",
+                         TRUE,G_PARAM_READWRITE));
 
   gobject_class->set_property = gst_filesrc_set_property;
   gobject_class->get_property = gst_filesrc_get_property;
@@ -246,6 +256,8 @@ gst_filesrc_init (GstFileSrc *src)
 
   src->map_regions = g_tree_new(gst_filesrc_bufcmp);
   src->map_regions_lock = g_mutex_new();
+
+  src->seek_happened = FALSE;
 }
 
 
@@ -286,6 +298,9 @@ gst_filesrc_set_property (GObject *object, guint prop_id, const GValue *value, G
       else
         GST_INFO(0, "invalid mapsize, must a multiple of pagesize, which is %d\n",src->pagesize);
       break;
+    case ARG_TOUCH:
+      src->touch = g_value_get_boolean (value);
+      break;
     default:
       break;
   }
@@ -320,6 +335,9 @@ gst_filesrc_get_property (GObject *object, guint prop_id, GValue *value, GParamS
     case ARG_MAPSIZE:
       g_value_set_ulong (value, src->mapsize);
       break;
+    case ARG_TOUCH:
+      g_value_set_boolean (value, src->touch);
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -331,7 +349,7 @@ gst_filesrc_free_parent_mmap (GstBuffer *buf)
 {
   GstFileSrc *src = GST_FILESRC(GST_BUFFER_POOL_PRIVATE(buf));
 
-  // fprintf(stderr,"freeing mmap()d buffer at %d+%d\n",GST_BUFFER_OFFSET(buf),GST_BUFFER_SIZE(buf));
+  fs_print ("freeing mmap()d buffer at %d+%d\n",GST_BUFFER_OFFSET(buf),GST_BUFFER_SIZE(buf));
 
   // remove the buffer from the list of available mmap'd regions
   g_mutex_lock(src->map_regions_lock);
@@ -347,21 +365,24 @@ gst_filesrc_free_parent_mmap (GstBuffer *buf)
 }
 
 static GstBuffer *
-gst_filesrc_map_region (GstFileSrc *src, off_t offset, off_t size)
+gst_filesrc_map_region (GstFileSrc *src, off_t offset, size_t size)
 {
   GstBuffer *buf;
   gint retval;
 
-//  fprintf(stderr,"mapping region %d+%d from file into memory\n",offset,size);
+  g_return_val_if_fail (offset >= 0, NULL);
+
+  fs_print  ("mapping region %08lx+%08lx from file into memory\n",offset,size);
 
   // time to allocate a new mapbuf
   buf = gst_buffer_new();
   // mmap() the data into this new buffer
   GST_BUFFER_DATA(buf) = mmap (NULL, size, PROT_READ, MAP_SHARED, src->fd, offset);
   if (GST_BUFFER_DATA(buf) == NULL) {
-    fprintf(stderr, "ERROR: gstfilesrc couldn't map file!\n");
-  } else if (GST_BUFFER_DATA(buf) == (void *)-1) {
-    perror("gstfilesrc:mmap()");
+    fprintf (stderr, "ERROR: gstfilesrc couldn't map file!\n");
+  } else if (GST_BUFFER_DATA(buf) == MAP_FAILED) {
+    g_error ("gstfilesrc mmap(0x%x, %d, 0x%llx) : %s",
+            size, src->fd, offset, sys_errlist[errno]);
   }
   // madvise to tell the kernel what to do with it
   retval = madvise(GST_BUFFER_DATA(buf),GST_BUFFER_SIZE(buf),MADV_SEQUENTIAL);
@@ -382,20 +403,27 @@ gst_filesrc_map_region (GstFileSrc *src, off_t offset, off_t size)
 }
 
 static GstBuffer *
-gst_filesrc_map_small_region (GstFileSrc *src, off_t offset, off_t size)
+gst_filesrc_map_small_region (GstFileSrc *src, off_t offset, size_t size)
 {
-  int mod, mapbase, mapsize;
+  size_t mapsize;
+  off_t mod, mapbase;
   GstBuffer *map;
 
 //  printf("attempting to map a small buffer at %d+%d\n",offset,size);
 
   // if the offset starts at a non-page boundary, we have to special case
   if ((mod = offset % src->pagesize)) {
+    GstBuffer *ret;
+
     mapbase = offset - mod;
     mapsize = ((size + mod + src->pagesize - 1) / src->pagesize) * src->pagesize;
 //    printf("not on page boundaries, resizing map to %d+%d\n",mapbase,mapsize);
     map = gst_filesrc_map_region(src, mapbase, mapsize);
-    return gst_buffer_create_sub (map, offset - mapbase, size);
+    ret = gst_buffer_create_sub (map, offset - mapbase, size);
+
+    gst_buffer_unref (map);
+
+    return ret;
   }
 
   return gst_filesrc_map_region(src,offset,size);
@@ -431,8 +459,8 @@ gst_filesrc_get (GstPad *pad)
 {
   GstFileSrc *src;
   GstBuffer *buf = NULL, *map;
-  off_t readend,readsize,mapstart,mapend;
-  gboolean eof = FALSE;
+  size_t readsize;
+  off_t readend,mapstart,mapend;
   GstFileSrcRegion region;
   int i;
 
@@ -440,6 +468,18 @@ gst_filesrc_get (GstPad *pad)
   src = GST_FILESRC (gst_pad_get_parent (pad));
   g_return_val_if_fail (GST_FLAG_IS_SET (src, GST_FILESRC_OPEN), NULL);
 
+  // check for seek
+  if (src->seek_happened) {
+    src->seek_happened = FALSE;
+    return gst_event_new(GST_EVENT_DISCONTINUOUS);
+  }
+
+  // check for EOF
+  if (src->curoffset == src->filelen) {
+    gst_element_set_state(src,GST_STATE_PAUSED);
+    return gst_event_new(GST_EVENT_EOS);
+  }
+
   // calculate end pointers so we don't have to do so repeatedly later
   readsize = src->block_size;
   readend = src->curoffset + src->block_size;          // note this is the byte *after* the read
@@ -450,7 +490,6 @@ gst_filesrc_get (GstPad *pad)
   if (readend > src->filelen) {
     readsize = src->filelen - src->curoffset;
     readend = src->curoffset;
-    eof = TRUE;
   }
 
   // if the start is past the mapstart
@@ -458,15 +497,15 @@ gst_filesrc_get (GstPad *pad)
     // 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) {
-//      printf("read buf %d+%d lives in current mapbuf %d+%d, creating subbuffer of mapbuf\n",
-//             src->curoffset,readsize,GST_BUFFER_OFFSET(src->mapbuf),GST_BUFFER_SIZE(src->mapbuf));
+      fs_print ("read buf %d+%d lives in current mapbuf %d+%d, creating subbuffer of mapbuf\n",
+             src->curoffset,readsize,GST_BUFFER_OFFSET(src->mapbuf),GST_BUFFER_SIZE(src->mapbuf));
       buf = gst_buffer_create_sub (src->mapbuf, src->curoffset - GST_BUFFER_OFFSET(src->mapbuf),
                                    readsize);
 
     // if the start actually is within the current mmap region, map an overlap buffer
     } else if (src->curoffset < mapend) {
-//      printf("read buf %d+%d starts in mapbuf %d+%d but ends outside, creating new mmap\n",
-//             src->curoffset,readsize,GST_BUFFER_OFFSET(src->mapbuf),GST_BUFFER_SIZE(src->mapbuf));
+      fs_print ("read buf %d+%d starts in mapbuf %d+%d but ends outside, creating new mmap\n",
+             src->curoffset,readsize,GST_BUFFER_OFFSET(src->mapbuf),GST_BUFFER_SIZE(src->mapbuf));
       buf = gst_filesrc_map_small_region (src, src->curoffset, readsize);
     }
 
@@ -478,37 +517,39 @@ gst_filesrc_get (GstPad *pad)
     // 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
-//    printf("read buf %d+%d starts before mapbuf %d+%d, but overlaps it\n",
-//             src->curoffset,readsize,GST_BUFFER_OFFSET(src->mapbuf),GST_BUFFER_SIZE(src->mapbuf));
+    fs_print ("read buf %d+%d starts before mapbuf %d+%d, but overlaps it\n",
+             src->curoffset,readsize,GST_BUFFER_OFFSET(src->mapbuf),GST_BUFFER_SIZE(src->mapbuf));
     buf = gst_filesrc_map_small_region (src, src->curoffset, readsize);
   }
 
   // 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
-//    printf("searching for mapbuf to cover %d+%d\n",src->curoffset,readsize);
+    fs_print ("searching for mapbuf to cover %d+%d\n",src->curoffset,readsize);
     region.offset = src->curoffset;
     region.size = readsize;
-    map = g_tree_search(src->map_regions,gst_filesrc_search_region_match,&region);
+    map = g_tree_search (src->map_regions,
+                        (GCompareFunc) gst_filesrc_search_region_match,
+                        &region);
 
     // if we found an exact match, subbuffer it
     if (map != NULL) {
-//      printf("found mapbuf at %d+%d, creating subbuffer\n",GST_BUFFER_OFFSET(map),GST_BUFFER_SIZE(map));
+      fs_print ("found mapbuf at %d+%d, creating subbuffer\n",GST_BUFFER_OFFSET(map),GST_BUFFER_SIZE(map));
       buf = gst_buffer_create_sub (map, src->curoffset - GST_BUFFER_OFFSET(map), readsize);
 
     // otherwise we need to create something out of thin air
     } else {
       // if the read buffer crosses a mmap region boundary, create a one-off region
       if ((src->curoffset / src->mapsize) != (readend / src->mapsize)) {
-//        printf("read buf %d+%d crosses a %d-byte boundary, creating a one-off\n",
-//               src->curoffset,readsize,src->mapsize);
+        fs_print ("read buf %d+%d crosses a %d-byte boundary, creating a one-off\n",
+               src->curoffset,readsize,src->mapsize);
         buf = gst_filesrc_map_small_region (src, src->curoffset, readsize);
 
       // otherwise we will create a new mmap region and set it to the default
       } else {
         off_t nextmap = src->curoffset - (src->curoffset % src->mapsize);
-//        printf("read buf %d+%d in new mapbuf at %d+%d, mapping and subbuffering\n",
-//               src->curoffset,readsize,nextmap,src->mapsize);
+        fs_print ("read buf %d+%d in new mapbuf at %d+%d, mapping and subbuffering\n",
+               src->curoffset,readsize,nextmap,src->mapsize);
         // first, we're done with the old mapbuf
         gst_buffer_unref(src->mapbuf);
         // create a new one
@@ -525,8 +566,6 @@ gst_filesrc_get (GstPad *pad)
       *(GST_BUFFER_DATA(buf)+i) = *(GST_BUFFER_DATA(buf)+i);
   }
 
-  // if we hit EOF, 
-
   /* we're done, return the buffer */
   src->curoffset += GST_BUFFER_SIZE(buf);
   return buf;
@@ -567,6 +606,7 @@ gst_filesrc_close_file (GstFileSrc *src)
 {
   g_return_if_fail (GST_FLAG_IS_SET (src, GST_FILESRC_OPEN));
 
+  g_print ("close\n");
   /* close the file */
   close (src->fd);
 
@@ -613,6 +653,7 @@ gst_filesrc_srcpad_event(GstPad *pad, GstEventType event, gint64 location, guint
     } else if (data == SEEK_END) {
       src->curoffset = src->filelen - (guint64)location;
     }
+    src->seek_happened = TRUE;
     // push a discontinuous event?
     return TRUE;
   }
diff --git a/gst/elements/gstsinesrc.c b/gst/elements/gstsinesrc.c
new file mode 100644 (file)
index 0000000..75ca6ba
--- /dev/null
@@ -0,0 +1,452 @@
+/* GStreamer
+ * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
+ *                    2000 Wim Taymans <wtay@chello.be>
+ *                    2001 Steve Baker <stevebaker_org@yahoo.co.uk>
+ *
+ * gstsinesrc.c: 
+ *
+ * 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 <math.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <gstsinesrc.h>
+
+
+GstElementDetails gst_sinesrc_details = {
+  "Sine-wave src",
+  "Source/Audio",
+  "Create a sine wave of a given frequency and volume",
+  VERSION,
+  "Erik Walthinsen <omega@cse.ogi.edu>",
+  "(C) 1999",
+};
+
+
+/* SineSrc signals and args */
+enum {
+  /* FILL ME */
+  LAST_SIGNAL
+};
+
+enum {
+  ARG_0,
+  ARG_VOLUME,
+  ARG_FORMAT,
+  ARG_SAMPLERATE,
+  ARG_FREQ,
+  ARG_TABLESIZE,
+  ARG_BUFFER_SIZE,
+};
+
+// FIXME: this is not core business...
+GST_PADTEMPLATE_FACTORY (sinesrc_src_factory,
+  "src",
+  GST_PAD_SRC,
+  GST_PAD_ALWAYS,
+  GST_CAPS_NEW (
+    "sinesrc_src",
+    "audio/raw",
+      "format",        GST_PROPS_STRING ("int"),
+        "law",         GST_PROPS_INT (0),
+        "endianness",  GST_PROPS_INT (G_BYTE_ORDER),
+        "signed",      GST_PROPS_BOOLEAN (TRUE),
+        "width",       GST_PROPS_INT (16),
+        "depth",       GST_PROPS_INT (16),
+        "rate",        GST_PROPS_INT_RANGE (8000, 48000),
+        "channels",    GST_PROPS_INT (1)
+  )
+);
+
+static void                    gst_sinesrc_class_init          (GstSineSrcClass *klass);
+static void                    gst_sinesrc_init                (GstSineSrc *src);
+static GstPadNegotiateReturn   gst_sinesrc_negotiate           (GstPad *pad, GstCaps **caps, gpointer *data); 
+static void                    gst_sinesrc_set_property        (GObject *object, guint prop_id, 
+                                                                const GValue *value, GParamSpec *pspec);
+static void                    gst_sinesrc_get_property        (GObject *object, guint prop_id, 
+                                                                GValue *value, GParamSpec *pspec);
+//static gboolean gst_sinesrc_change_state(GstElement *element,
+//                                          GstElementState state);
+//static void gst_sinesrc_close_audio(GstSineSrc *src);
+//static gboolean gst_sinesrc_open_audio(GstSineSrc *src);
+
+static void gst_sinesrc_update_volume(GValue *value, gpointer data);
+static void gst_sinesrc_update_freq(GValue *value, gpointer data);
+static void                    gst_sinesrc_populate_sinetable  (GstSineSrc *src);
+static inline void             gst_sinesrc_update_table_inc    (GstSineSrc *src);
+static inline void             gst_sinesrc_update_vol_scale    (GstSineSrc *src);
+static void                    gst_sinesrc_force_caps          (GstSineSrc *src);
+
+static GstBuffer*              gst_sinesrc_get                 (GstPad *pad);
+
+static GstElementClass *parent_class = NULL;
+//static guint gst_sinesrc_signals[LAST_SIGNAL] = { 0 };
+
+GType
+gst_sinesrc_get_type (void)
+{
+  static GType sinesrc_type = 0;
+
+  if (!sinesrc_type) {
+    static const GTypeInfo sinesrc_info = {
+      sizeof(GstSineSrcClass),      
+      NULL,
+      NULL,
+      (GClassInitFunc)gst_sinesrc_class_init,
+      NULL,
+      NULL,
+      sizeof(GstSineSrc),
+      0,
+      (GInstanceInitFunc)gst_sinesrc_init,
+    };
+    sinesrc_type = g_type_register_static (GST_TYPE_ELEMENT, "GstSineSrc", &sinesrc_info, 0);
+  }
+  return sinesrc_type;
+}
+
+static void
+gst_sinesrc_class_init (GstSineSrcClass *klass) 
+{
+  GObjectClass *gobject_class;
+  GstElementClass *gstelement_class;
+
+  gobject_class = (GObjectClass*)klass;
+  gstelement_class = (GstElementClass*)klass;
+
+  parent_class = g_type_class_ref(GST_TYPE_ELEMENT);
+
+  g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_VOLUME,
+    g_param_spec_double("volume","volume","volume",
+                        0.0, 1.0, 0.0,G_PARAM_READWRITE)); // CHECKME
+  g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_FORMAT,
+    g_param_spec_int("format","format","format",
+                     G_MININT,G_MAXINT,0,G_PARAM_READWRITE)); // CHECKME
+  g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_SAMPLERATE,
+    g_param_spec_int("samplerate","samplerate","samplerate",
+                     G_MININT,G_MAXINT,0,G_PARAM_READWRITE)); // CHECKME
+  g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_TABLESIZE,
+    g_param_spec_int("tablesize","tablesize","tablesize",
+                     G_MININT,G_MAXINT,0,G_PARAM_READWRITE)); // CHECKME
+  g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_FREQ,
+    g_param_spec_double("freq","freq","freq",
+                        0.0,G_MAXDOUBLE, 440.0,G_PARAM_READWRITE)); // CHECKME
+  g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_BUFFER_SIZE,
+    g_param_spec_int("buffersize","buffersize","buffersize",
+                     0, G_MAXINT, 1024, G_PARAM_READWRITE)); 
+                          
+  gobject_class->set_property = gst_sinesrc_set_property;
+  gobject_class->get_property = gst_sinesrc_get_property;
+
+//  gstelement_class->change_state = gst_sinesrc_change_state;
+}
+
+static void 
+gst_sinesrc_init (GstSineSrc *src) 
+{
+  GstElement *element = GST_ELEMENT(src);
+  GstDParamManager *dpman;
+  
+  src->srcpad = gst_pad_new_from_template (
+                 GST_PADTEMPLATE_GET (sinesrc_src_factory), "src");
+  gst_element_add_pad(GST_ELEMENT(src), src->srcpad);
+  gst_pad_set_negotiate_function (src->srcpad, gst_sinesrc_negotiate);
+  
+  gst_pad_set_get_function(src->srcpad, gst_sinesrc_get);
+
+  src->format = 16;
+  src->samplerate = 44100;
+  
+  src->newcaps = TRUE;
+  
+  src->table_pos = 0.0;
+  src->table_size = 1024;
+  src->buffer_size=1024;
+  
+  src->seq = 0;
+
+  dpman = gst_dpman_new ("sinesrc_dpman", GST_ELEMENT(src));
+  gst_dpman_add_required_dparam (dpman, "volume", G_TYPE_FLOAT, gst_sinesrc_update_volume, src);
+  gst_dpman_add_required_dparam (dpman, "freq", G_TYPE_FLOAT, gst_sinesrc_update_freq, src);
+
+  gst_dpman_set_rate_change_pad(dpman, src->srcpad);
+  
+  GST_ELEMENT_DPARAM_MANAGER(element) = dpman;
+  
+  gst_sinesrc_update_vol_scale(src);
+
+  gst_sinesrc_populate_sinetable(src);
+  gst_sinesrc_update_table_inc(src);
+
+}
+
+static GstPadNegotiateReturn 
+gst_sinesrc_negotiate (GstPad *pad, GstCaps **caps, gpointer *data) 
+{
+  GstSineSrc *src;
+
+  if (*caps) {
+    g_return_val_if_fail (pad != NULL, GST_PAD_NEGOTIATE_FAIL);
+    src = GST_SINESRC(gst_pad_get_parent (pad));
+    src->samplerate = gst_caps_get_int (*caps, "rate");
+    gst_sinesrc_update_table_inc(src);
+    return GST_PAD_NEGOTIATE_AGREE;
+  }
+
+  return GST_PAD_NEGOTIATE_FAIL;
+}
+
+static GstBuffer *
+gst_sinesrc_get(GstPad *pad)
+{
+  GstSineSrc *src;
+  GstBuffer *buf;
+  GstDParamManager *dpman;
+  
+  gint16 *samples;
+  gint i=0, frame_countdown;
+  
+  g_return_val_if_fail (pad != NULL, NULL);
+  src = GST_SINESRC(gst_pad_get_parent (pad));
+
+  buf = gst_buffer_new();
+  g_return_val_if_fail (buf, NULL);
+  samples = g_new(gint16, src->buffer_size);
+  GST_BUFFER_DATA(buf) = (gpointer) samples;
+  GST_BUFFER_SIZE(buf) = 2 * src->buffer_size;
+  
+  dpman = GST_ELEMENT_DPARAM_MANAGER(GST_ELEMENT(src));
+  frame_countdown = GST_DPMAN_FIRST_COUNTDOWN(dpman, src->buffer_size, 0LL);
+
+  while(GST_DPMAN_COUNTDOWN(dpman, frame_countdown, i)) {
+    src->table_lookup = (gint)(src->table_pos);
+    src->table_lookup_next = src->table_lookup + 1;
+    src->table_interp = src->table_pos - src->table_lookup;
+    
+    // wrap the array lookups if we're out of bounds
+    if (src->table_lookup_next >= src->table_size){
+      src->table_lookup_next -= src->table_size;
+      if (src->table_lookup >= src->table_size){
+        src->table_lookup -= src->table_size;
+        src->table_pos -= src->table_size;
+      }
+    }
+    
+    src->table_pos += src->table_inc;
+
+    //no interpolation
+    //samples[i] = src->table_data[src->table_lookup]
+    //               * src->vol_scale;
+                       
+    //linear interpolation
+    samples[i++] = ((src->table_interp
+                   *(src->table_data[src->table_lookup_next]
+                    -src->table_data[src->table_lookup]
+                    )
+                  )+src->table_data[src->table_lookup]
+                 )* src->vol_scale;
+  }
+
+  if (src->newcaps) {
+    gst_sinesrc_force_caps(src);
+  }
+
+  return buf;
+}
+
+static void 
+gst_sinesrc_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) 
+{
+  GstSineSrc *src;
+
+  /* it's not null if we got it, but it might not be ours */
+  g_return_if_fail(GST_IS_SINESRC(object));
+  src = GST_SINESRC(object);
+
+  switch (prop_id) {
+    case ARG_VOLUME:
+      src->volume = (gfloat)g_value_get_double (value);
+      gst_sinesrc_update_vol_scale(src);
+      break;
+    case ARG_FORMAT:
+      src->format = g_value_get_int (value);
+      src->newcaps=TRUE;
+      break;
+    case ARG_SAMPLERATE:
+      src->samplerate = g_value_get_int (value);
+      src->newcaps=TRUE;
+      gst_sinesrc_update_table_inc(src);
+      break;
+    case ARG_FREQ: {
+      if (g_value_get_double (value) <= 0.0 || g_value_get_double (value) > src->samplerate/2)
+        break;
+      src->freq = (gfloat)g_value_get_double (value);
+      gst_sinesrc_update_table_inc(src);
+      break;
+    case ARG_TABLESIZE:
+      src->table_size = g_value_get_int (value);
+      gst_sinesrc_populate_sinetable(src);
+      gst_sinesrc_update_table_inc(src);
+      break;
+    case ARG_BUFFER_SIZE:
+      src->buffer_size = g_value_get_int (value);
+      break;
+    }
+    default:
+      break;
+  }
+}
+
+static void 
+gst_sinesrc_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) 
+{
+  GstSineSrc *src;
+
+  /* it's not null if we got it, but it might not be ours */
+  g_return_if_fail(GST_IS_SINESRC(object));
+  src = GST_SINESRC(object);
+
+  switch (prop_id) {
+    case ARG_VOLUME:
+      g_value_set_double (value, (gdouble)(src->volume));
+      break;
+    case ARG_FORMAT:
+      g_value_set_int (value, src->format);
+      break;
+    case ARG_SAMPLERATE:
+      g_value_set_int (value, src->samplerate);
+      break;
+    case ARG_FREQ:
+      g_value_set_double (value, (gdouble)(src->freq));
+      break;
+    case ARG_TABLESIZE:
+      g_value_set_int (value, src->table_size);
+      break;
+    case ARG_BUFFER_SIZE:
+      g_value_set_int (value, src->buffer_size);
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+  }
+}
+
+/*
+static gboolean gst_sinesrc_change_state(GstElement *element,
+                                          GstElementState state) {
+  g_return_if_fail(GST_IS_SINESRC(element));
+
+  switch (state) {
+    case GST_STATE_RUNNING:
+      if (!gst_sinesrc_open_audio(GST_SINESRC(element)))
+        return FALSE;
+      break;
+    case ~GST_STATE_RUNNING:
+      gst_sinesrc_close_audio(GST_SINESRC(element));
+      break;
+    default:
+      break;
+  }
+
+  if (GST_ELEMENT_CLASS(parent_class)->change_state)
+    return GST_ELEMENT_CLASS(parent_class)->change_state(element,state);
+  return TRUE;
+}
+*/
+
+static void 
+gst_sinesrc_populate_sinetable (GstSineSrc *src)
+{
+  gint i;
+  gdouble pi2scaled = M_PI * 2 / src->table_size;
+  gfloat *table = g_new(gfloat, src->table_size);
+
+  for(i=0 ; i < src->table_size ; i++){
+    table[i] = (gfloat)sin(i * pi2scaled);
+  }
+  
+  g_free(src->table_data);
+  src->table_data = table;
+}
+
+static void
+gst_sinesrc_update_volume(GValue *value, gpointer data)
+{
+  GstSineSrc *src = (GstSineSrc*)data;
+  g_return_if_fail(GST_IS_SINESRC(src));
+
+  src->volume = g_value_get_float(value);
+  src->vol_scale = 32767.0 * src->volume;
+}
+
+static void
+gst_sinesrc_update_freq(GValue *value, gpointer data)
+{
+  GstSineSrc *src = (GstSineSrc*)data;
+  g_return_if_fail(GST_IS_SINESRC(src));
+  
+  src->freq = g_value_get_float(value);
+  src->table_inc = src->table_size * src->freq / src->samplerate;
+}
+
+static inline void 
+gst_sinesrc_update_table_inc (GstSineSrc *src)
+{
+  src->table_inc = src->table_size * src->freq / src->samplerate;
+}
+
+static inline void 
+gst_sinesrc_update_vol_scale (GstSineSrc *src)
+{
+  src->vol_scale = 32767.0 * src->volume;
+}
+
+static void 
+gst_sinesrc_force_caps(GstSineSrc *src) {
+  GstCaps *caps;
+
+  if (!src->newcaps)
+    return;
+  
+  src->newcaps=FALSE;
+
+  caps = gst_caps_new (
+                   "sinesrc_src_caps",
+                   "audio/raw",
+                    gst_props_new (
+                          "format",            GST_PROPS_STRING ("int"),
+                            "law",             GST_PROPS_INT (0),
+                            "endianness",      GST_PROPS_INT (G_BYTE_ORDER),
+                            "signed",          GST_PROPS_BOOLEAN (TRUE),
+                            "width",           GST_PROPS_INT (16),
+                            "depth",           GST_PROPS_INT (16),
+                            "rate",            GST_PROPS_INT (src->samplerate),
+                            "channels",        GST_PROPS_INT (1),
+                            NULL
+                            )
+                   );
+  
+  gst_pad_set_caps (src->srcpad, caps);
+}
+
+gboolean 
+gst_sinesrc_factory_init (GstElementFactory *factory) 
+{
+  gst_elementfactory_add_padtemplate (factory, GST_PADTEMPLATE_GET (sinesrc_src_factory));
+  
+  return TRUE;
+}
diff --git a/gst/elements/gstsinesrc.h b/gst/elements/gstsinesrc.h
new file mode 100644 (file)
index 0000000..58e03fd
--- /dev/null
@@ -0,0 +1,96 @@
+/* GStreamer
+ * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
+ *                    2000 Wim Taymans <wtay@chello.be>
+ *
+ * gstsinesrc.h: 
+ *
+ * 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_SINESRC_H__
+#define __GST_SINESRC_H__
+
+
+#include <config.h>
+#include <gst/gst.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+GstElementDetails gst_sinesrc_details;
+
+
+#define GST_TYPE_SINESRC \
+  (gst_sinesrc_get_type())
+#define GST_SINESRC(obj) \
+  (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_SINESRC,GstSineSrc))
+#define GST_SINESRC_CLASS(klass) \
+  (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_SINESRC,GstSineSrcClass))
+#define GST_IS_SINESRC(obj) \
+  (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_SINESRC))
+#define GST_IS_SINESRC_CLASS(obj) \
+  (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_SINESRC))
+
+typedef struct _GstSineSrc GstSineSrc;
+typedef struct _GstSineSrcClass GstSineSrcClass;
+
+struct _GstSineSrc {
+  GstElement element;
+
+  /* pads */
+  GstPad *srcpad;
+
+  /* parameters */
+  gfloat volume;
+  gfloat freq;
+  gfloat vol_scale;
+  
+  /* lookup table data */
+  gfloat *table_data;
+  gdouble table_pos;
+  gdouble table_inc;
+  gint table_size;
+  gdouble table_interp;
+  gint table_lookup;
+  gint table_lookup_next;
+    
+  /* audio parameters */
+  gint format;
+  gint samplerate;
+
+  gint buffer_size;
+  gulong seq;
+
+  gboolean newcaps;
+
+};
+
+struct _GstSineSrcClass {
+  GstElementClass parent_class;
+};
+
+GType gst_sinesrc_get_type(void);
+gboolean gst_sinesrc_factory_init (GstElementFactory *factory);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif /* __GST_SINESRC_H__ */
index 729b95e..d7e0544 100644 (file)
@@ -56,7 +56,7 @@ GST_PADTEMPLATE_FACTORY (tee_src_factory,
 static void    gst_tee_class_init      (GstTeeClass *klass);
 static void    gst_tee_init            (GstTee *tee);
 
-static GstPad*         gst_tee_request_new_pad (GstElement *element, GstPadTemplate *temp);
+static GstPad*         gst_tee_request_new_pad (GstElement *element, GstPadTemplate *temp, const gchar *unused);
 
 static void    gst_tee_set_property    (GObject *object, guint prop_id, 
                                         const GValue *value, GParamSpec *pspec);
@@ -127,7 +127,7 @@ gst_tee_init (GstTee *tee)
 }
 
 static GstPad*
-gst_tee_request_new_pad (GstElement *element, GstPadTemplate *templ) 
+gst_tee_request_new_pad (GstElement *element, GstPadTemplate *templ, const gchar *unused
 {
   gchar *name;
   GstPad *srcpad;
index c53aa36..72165d3 100644 (file)
@@ -6,6 +6,24 @@
 #include "gobject2gtk.h"
 
 
+// list functions not in glib 1.2
+GList *
+g_list_delete_link (GList *list, GList *llink)
+{
+  GList *temp = g_list_remove_link(list, llink);
+  g_list_free(llink);
+  return temp;
+}
+
+GSList *
+g_slist_delete_link (GSList *list, GSList *llink)
+{
+  GSList *temp = g_slist_remove_link(list, llink);
+  g_slist_free(llink);
+  return temp;
+}
+
+
 
 // GObject dummy implementation
 static void
@@ -324,4 +342,3 @@ gint* g_signal_list_ids (GType type, guint *n_ids)
 
   return class->signals;
 }
-
index 309fe97..6201c12 100644 (file)
 #define G_PI_4  0.78539816339744830962E0
 #define G_SQRT2 1.4142135623730950488E0
 
+// lists functions not in glib 1.2
+GList *g_list_delete_link (GList *list, GList *llink);
+GSList *g_slist_delete_link (GSList *list, GSList *llink);
+  
+
+// GObject
 typedef struct _GObject GObject;
 typedef struct _GObjectClass GObjectClass;
 
@@ -53,35 +59,35 @@ typedef struct _GObjectClass GObjectClass;
 #define G_TYPE_PARAM                           GTK_TYPE_PARAM
 
 // marshallers
-#define g_cclosure_marshal_VOID__VOID          gtk_marshal_NONE__NONE
-#define g_cclosure_marshal_VOID__BOOLEAN       gtk_marshal_NONE__BOOL
-#define g_cclosure_marshal_VOID__CHAR          gtk_marshal_NONE__CHAR
-#define g_cclosure_marshal_VOID__UCHAR         gtk_marshal_NONE__UCHAR
-#define g_cclosure_marshal_VOID__INT           gtk_marshal_NONE__INT
-#define g_cclosure_marshal_VOID__UINT          gtk_marshal_NONE__UINT
-#define g_cclosure_marshal_VOID__LONG          gtk_marshal_NONE__LONG
-#define g_cclosure_marshal_VOID__ULONG         gtk_marshal_NONE__ULONG
-#define g_cclosure_marshal_VOID__ENUM          gtk_marshal_NONE__ENUM
-#define g_cclosure_marshal_VOID__FLAGS         gtk_marshal_NONE__FLAGS
-#define g_cclosure_marshal_VOID__FLOAT         gtk_marshal_NONE__FLOAT
-#define g_cclosure_marshal_VOID__DOUBLE                gtk_marshal_NONE__DOUBLE
-#define g_cclosure_marshal_VOID__STRING                gtk_marshal_NONE__STRING
-#define g_cclosure_marshal_VOID__PARAM         gtk_marshal_NONE__PARAM
-#define g_cclosure_marshal_VOID__BOXED         gtk_marshal_NONE__BOXED
-#define g_cclosure_marshal_VOID__POINTER       gtk_marshal_NONE__POINTER
-#define g_cclosure_marshal_VOID__OBJECT                gtk_marshal_NONE__OBJECT
-#define g_cclosure_marshal_STRING__OBJECT_POINTER      gtk_marshal_STRING__OBJECT_POINTER
-#define g_cclosure_marshal_VOID__UINT_POINTER  gtk_marshal_NONE__UINT_POINTER
+#define g_cclosure_marshal_VOID__VOID                  gtk_marshal_NONE__NONE
+#define g_cclosure_marshal_VOID__BOOLEAN               gtk_marshal_NONE__BOOL
+#define g_cclosure_marshal_VOID__CHAR                  gtk_marshal_NONE__CHAR
+#define g_cclosure_marshal_VOID__UCHAR                 gtk_marshal_NONE__UCHAR
+#define g_cclosure_marshal_VOID__INT                   gtk_marshal_NONE__INT
+#define g_cclosure_marshal_VOID__UINT                  gtk_marshal_NONE__UINT
+#define g_cclosure_marshal_VOID__LONG                  gtk_marshal_NONE__LONG
+#define g_cclosure_marshal_VOID__ULONG                 gtk_marshal_NONE__ULONG
+#define g_cclosure_marshal_VOID__ENUM                  gtk_marshal_NONE__ENUM
+#define g_cclosure_marshal_VOID__FLAGS                 gtk_marshal_NONE__FLAGS
+#define g_cclosure_marshal_VOID__FLOAT                 gtk_marshal_NONE__FLOAT
+#define g_cclosure_marshal_VOID__DOUBLE                        gtk_marshal_NONE__DOUBLE
+#define g_cclosure_marshal_VOID__STRING                        gtk_marshal_NONE__STRING
+#define g_cclosure_marshal_VOID__PARAM                 gtk_marshal_NONE__PARAM
+#define g_cclosure_marshal_VOID__BOXED                 gtk_marshal_NONE__BOXED
+#define g_cclosure_marshal_VOID__POINTER               gtk_marshal_NONE__POINTER
+#define g_cclosure_marshal_VOID__OBJECT                        gtk_marshal_NONE__OBJECT
+#define g_cclosure_marshal_STRING__OBJECT_POINTER      gtk_marshal_STRING__POINTER_POINTER
+#define g_cclosure_marshal_VOID__UINT_POINTER          gtk_marshal_NONE__UINT_POINTER
 
-#define gst_marshal_VOID__INT_INT              gtk_marshal_NONE__INT_INT
-#define gst_marshal_VOID__INT                  gtk_marshal_NONE__INT
-#define gst_marshal_VOID__STRING               gtk_marshal_NONE__STRING
 #define gst_marshal_VOID__VOID                 gtk_marshal_NONE__NONE
 #define gst_marshal_VOID__BOOLEAN              gtk_marshal_NONE__BOOL
+#define gst_marshal_VOID__INT                  gtk_marshal_NONE__INT
+#define gst_marshal_VOID__INT_INT              gtk_marshal_NONE__INT_INT
+#define gst_marshal_VOID__STRING               gtk_marshal_NONE__STRING
 #define gst_marshal_VOID__POINTER              gtk_marshal_NONE__POINTER
-#define gst_marshal_VOID__OBJECT              gtk_marshal_NONE__POINTER
-#define gst_marshal_VOID__OBJECT_POINTER      gtk_marshal_NONE__POINTER_POINTER
-#define gst_marshal_VOID__INT_INT             gtk_marshal_NONE__INT_INT
+#define gst_marshal_VOID__OBJECT               gtk_marshal_NONE__POINTER
+#define gst_marshal_VOID__OBJECT_POINTER       gtk_marshal_NONE__POINTER_POINTER
+#define gst_marshal_VOID__INT_INT              gtk_marshal_NONE__INT_INT
 
 /* General macros */
 #ifdef  __cplusplus
@@ -217,6 +223,10 @@ gtk_signal_handler_pending ((GtkObject *)object,name,may_block)
 
 gint* g_signal_list_ids (GType type, guint *n_ids);
 
+// lists
+GSList*                g_slist_delete_link     (GSList *list, GSList *link) __attribute__ ((no_instrument_function));
+
+
 // arguments/parameters
 
 // first define GValue and GParamSpec
index d3a9f63..8ecacba 100644 (file)
--- a/gst/gst.c
+++ b/gst/gst.c
@@ -24,6 +24,7 @@
 
 #include "gst_private.h"
 
+#include "gstversion.h"
 #include "gstcpu.h"
 #include "gsttype.h"
 #include "gstplugin.h"
@@ -38,6 +39,7 @@
 #endif
 
 #define MAX_PATH_SPLIT 16
+#define GST_PLUGIN_SEPARATOR ","
 
 gchar *_gst_progname;
 
@@ -47,6 +49,9 @@ extern gboolean _gst_plugin_spew;
 
 
 static gboolean        gst_init_check          (int *argc, gchar ***argv);
+static void            load_plugin_func        (gpointer data, gpointer user_data);
+
+static GSList *preload_plugins = NULL;
 
 const gchar *g_log_domain_gstreamer = "GStreamer";
 
@@ -105,7 +110,12 @@ gst_init (int *argc, char **argv[])
 
   GST_INFO (GST_CAT_GST_INIT, "Initializing GStreamer Core Library");
 
+  gst_object_get_type ();
+  gst_pad_get_type ();
+  gst_real_pad_get_type ();
+  gst_ghost_pad_get_type ();
   gst_elementfactory_get_type ();
+  gst_element_get_type ();
   gst_typefactory_get_type ();
 #ifndef GST_DISABLE_AUTOPLUG
   gst_autoplugfactory_get_type ();
@@ -115,9 +125,17 @@ gst_init (int *argc, char **argv[])
   _gst_props_initialize ();
   _gst_caps_initialize ();
   _gst_plugin_initialize ();
+  _gst_event_initialize ();
   _gst_buffer_initialize ();
   _gst_buffer_pool_initialize ();
 
+  /* if we need to preload plugins */
+  if (preload_plugins) {
+    g_slist_foreach (preload_plugins, load_plugin_func, NULL);
+    g_slist_free (preload_plugins);
+    preload_plugins = NULL;
+  }
+
   /* register some standard builtin types */
   gst_elementfactory_new ("bin", gst_bin_get_type (), &gst_bin_details);
   gst_elementfactory_new ("pipeline", gst_pipeline_get_type (), &gst_pipeline_details);
@@ -137,23 +155,23 @@ gst_init (int *argc, char **argv[])
 }
 
 static void
-gst_add_paths_func (const gchar *pathlist
+split_and_iterate (const gchar *stringlist, gchar *separator, GFunc iterator
 {
-  gchar **paths;
+  gchar **strings;
   gint j = 0;
-  gchar *lastpath = g_strdup (pathlist);
+  gchar *lastlist = g_strdup (stringlist);
 
-  while (lastpath) {
-    paths = g_strsplit (lastpath, G_SEARCHPATH_SEPARATOR_S, MAX_PATH_SPLIT);
-    g_free (lastpath);
-    lastpath = NULL;
+  while (lastlist) {
+    strings = g_strsplit (lastlist, separator, MAX_PATH_SPLIT);
+    //strings = g_strsplit (lastlist, G_SEARCHPATH_SEPARATOR_S, MAX_PATH_SPLIT);
+    g_free (lastlist);
+    lastlist = NULL;
 
-    while (paths[j]) {
-      GST_INFO (GST_CAT_GST_INIT, "Adding plugin path: \"%s\"", paths[j]);
-      gst_plugin_add_path (paths[j]);
+    while (strings[j]) {
+      iterator (strings[j], NULL);
       if (++j == MAX_PATH_SPLIT) {
-        lastpath = g_strdup (paths[j]);
-        g_strfreev (paths); 
+        lastlist = g_strdup (strings[j]);
+        g_strfreev (strings); 
         j=0;
         break;
       }
@@ -161,6 +179,33 @@ gst_add_paths_func (const gchar *pathlist)
   }
 }
 
+static void 
+add_path_func (gpointer data, gpointer user_data)
+{
+  GST_INFO (GST_CAT_GST_INIT, "Adding plugin path: \"%s\"", (gchar *)data);
+  gst_plugin_add_path ((gchar *)data);
+}
+
+static void 
+prepare_for_load_plugin_func (gpointer data, gpointer user_data)
+{
+  preload_plugins = g_slist_prepend (preload_plugins, data);
+}
+
+static void 
+load_plugin_func (gpointer data, gpointer user_data)
+{
+  gboolean ret;
+  ret = gst_plugin_load ((gchar *)data);
+  if (ret)
+    GST_INFO (GST_CAT_GST_INIT, "Loaded plugin: \"%s\"", (gchar *)data);
+  else
+    GST_INFO (GST_CAT_GST_INIT, "Failed to load plugin: \"%s\"", (gchar *)data);
+
+  g_free (data);
+}
+
+
 /* returns FALSE if the program can be aborted */
 static gboolean
 gst_init_check (int     *argc,
@@ -226,7 +271,12 @@ gst_init_check (int     *argc,
         (*argv)[i] = NULL;
       }
       else if (!strncmp ("--gst-plugin-path=", (*argv)[i], 17)) {
-       gst_add_paths_func ((*argv)[i]+18);
+        split_and_iterate ((*argv)[i]+18, G_SEARCHPATH_SEPARATOR_S, add_path_func);
+
+        (*argv)[i] = NULL;
+      }
+      else if (!strncmp ("--gst-plugin-load=", (*argv)[i], 17)) {
+        split_and_iterate ((*argv)[i]+18, ",", prepare_for_load_plugin_func);
 
         (*argv)[i] = NULL;
       }
@@ -257,7 +307,7 @@ gst_init_check (int     *argc,
   /* check for ENV variables */
   {
     const gchar *plugin_path = g_getenv("GST_PLUGIN_PATH");
-    gst_add_paths_func (plugin_path);
+    split_and_iterate (plugin_path, G_SEARCHPATH_SEPARATOR_S, add_path_func);
   }
 
   if (showhelp) {
@@ -272,6 +322,8 @@ gst_init_check (int     *argc,
     g_print ("  --gst-plugin-spew                   Enable printout of errors while loading GST plugins\n");
     g_print ("  --gst-plugin-path=PATH              Add directories separated with '%s' to the plugin search path\n",
                    G_SEARCHPATH_SEPARATOR_S);
+    g_print ("  --gst-plugin-load=PLUGINS           Load plugins separated with '%s'\n",
+                   GST_PLUGIN_SEPARATOR);
 
     g_print ("\n  Mask (to be OR'ed)   info/debug         FLAGS   \n");
     g_print ("--------------------------------------------------------\n");
@@ -323,3 +375,24 @@ gst_main_quit (void)
   gtk_main_quit ();
 #endif
 }
+
+/**
+ * gst_version:
+ * @major: pointer to a guint to store the major version number
+ * @minor: pointer to a guint to store the minor version number
+ * @micro: pointer to a guint to store the micro version number
+ *
+ * Gets the version number of the GStreamer library
+ */
+void 
+gst_version (guint *major, guint *minor, guint *micro)
+{
+  g_return_if_fail (major);
+  g_return_if_fail (minor);
+  g_return_if_fail (micro);
+
+  *major = GST_VERSION_MAJOR;
+  *minor = GST_VERSION_MINOR;
+  *micro = GST_VERSION_MICRO;
+}
+
index 2addc92..032d5d2 100644 (file)
--- a/gst/gst.h
+++ b/gst/gst.h
@@ -50,6 +50,7 @@
 #include <gst/cothreads.h>
 #include <gst/gstscheduler.h>
 #include <gst/gsttimecache.h>
+#include <gst/gstevent.h>
 
 #include <gst/gstparse.h>
 #include <gst/gstextratypes.h>
index af6a29f..612cd4b 100644 (file)
@@ -21,6 +21,9 @@
  */
 
 //#define GST_DEBUG_ENABLED
+
+#include <gst/gstconfig.h>
+
 #include "gst_private.h"
 
 #include "gstautoplug.h"
@@ -168,8 +171,10 @@ gst_autoplug_to_renderers (GstAutoplug *autoplug, GstCaps *srccaps, GstElement *
 static void            gst_autoplugfactory_class_init          (GstAutoplugFactoryClass *klass);
 static void            gst_autoplugfactory_init                (GstAutoplugFactory *factory);
 
+#ifndef GST_DISABLE_REGISTRY
 static xmlNodePtr      gst_autoplugfactory_save_thyself        (GstObject *object, xmlNodePtr parent);
 static void            gst_autoplugfactory_restore_thyself     (GstObject *object, xmlNodePtr parent);
+#endif
 
 static GstPluginFeatureClass *factory_parent_class = NULL;
 //static guint gst_autoplugfactory_signals[LAST_SIGNAL] = { 0 };
@@ -211,8 +216,10 @@ gst_autoplugfactory_class_init (GstAutoplugFactoryClass *klass)
 
   factory_parent_class = g_type_class_ref (GST_TYPE_PLUGIN_FEATURE);
 
+#ifndef GST_DISABLE_REGISTRY
   gstobject_class->save_thyself =      GST_DEBUG_FUNCPTR (gst_autoplugfactory_save_thyself);
   gstobject_class->restore_thyself =   GST_DEBUG_FUNCPTR (gst_autoplugfactory_restore_thyself);
+#endif
 
   _gst_autoplugfactories = NULL;
 }
@@ -361,6 +368,7 @@ gst_autoplugfactory_make (const gchar *name)
   return gst_autoplugfactory_create (factory);;
 }
 
+#ifndef GST_DISABLE_REGISTRY
 static xmlNodePtr
 gst_autoplugfactory_save_thyself (GstObject *object, xmlNodePtr parent)
 {
@@ -407,3 +415,4 @@ gst_autoplugfactory_restore_thyself (GstObject *object, xmlNodePtr parent)
     children = children->next;
   }
 }
+#endif /* GST_DISABLE_REGISTRY */
index 1b97b98..4396fe3 100644 (file)
@@ -113,16 +113,17 @@ gst_bin_class_init (GstBinClass *klass)
                     gst_marshal_VOID__OBJECT, G_TYPE_NONE, 1,
                     GST_TYPE_ELEMENT);
 
-  klass->change_state_type =           gst_bin_change_state_type;
-  klass->iterate =                     gst_bin_iterate_func;
+  klass->change_state_type =           GST_DEBUG_FUNCPTR (gst_bin_change_state_type);
+  klass->iterate =                     GST_DEBUG_FUNCPTR (gst_bin_iterate_func);
 
 #ifndef GST_DISABLE_LOADSAVE
-  gstobject_class->save_thyself =      gst_bin_save_thyself;
-  gstobject_class->restore_thyself =   gst_bin_restore_thyself;
+  gstobject_class->save_thyself =      GST_DEBUG_FUNCPTR (gst_bin_save_thyself);
+  gstobject_class->restore_thyself =   GST_DEBUG_FUNCPTR (gst_bin_restore_thyself);
 #endif
 
-  gstelement_class->change_state =     gst_bin_change_state;
-  gobject_class->dispose =             gst_bin_dispose;
+  gstelement_class->change_state =     GST_DEBUG_FUNCPTR (gst_bin_change_state);
+
+  gobject_class->dispose =             GST_DEBUG_FUNCPTR (gst_bin_dispose);
 }
 
 static void
@@ -644,7 +645,7 @@ gst_bin_restore_thyself (GstObject *object,
     field = field->next;
   }
 }
-#endif // GST_DISABLE_LOADSAVE
+#endif /* GST_DISABLE_LOADSAVE */
 
 
 /**
index fc61d55..c330b2e 100644 (file)
@@ -27,6 +27,8 @@
 #include "gstbuffer.h"
 
 
+GType _gst_buffer_type;
+
 static GMemChunk *_gst_buffer_chunk;
 static GMutex *_gst_buffer_chunk_lock;
 
@@ -34,6 +36,17 @@ void
 _gst_buffer_initialize (void) 
 {
   int buffersize = sizeof(GstBuffer);
+  static const GTypeInfo buffer_info = {
+    0, // sizeof(class),
+    NULL,
+    NULL,
+    NULL,
+    NULL,
+    NULL,
+    0, // sizeof(object),
+    0,
+    NULL,
+  };
 
   // round up to the nearest 32 bytes for cache-line and other efficiencies
   buffersize = (((buffersize-1) / 32) + 1) * 32;
@@ -42,6 +55,8 @@ _gst_buffer_initialize (void)
     buffersize * 32, G_ALLOC_AND_FREE);
 
   _gst_buffer_chunk_lock = g_mutex_new ();
+
+  _gst_buffer_type = g_type_register_static (G_TYPE_INT, "GstBuffer", &buffer_info, 0);
 }
 
 /**
@@ -52,7 +67,7 @@ _gst_buffer_initialize (void)
  * Returns: new buffer
  */
 GstBuffer*
-gst_buffer_new(void) 
+gst_buffer_new (void)
 {
   GstBuffer *buffer;
 
@@ -61,6 +76,8 @@ gst_buffer_new(void)
   g_mutex_unlock (_gst_buffer_chunk_lock);
   GST_INFO (GST_CAT_BUFFER,"creating new buffer %p",buffer);
 
+  GST_DATA_TYPE(buffer) = _gst_buffer_type;
+
   buffer->lock = g_mutex_new ();
 #ifdef HAVE_ATOMIC_H
   atomic_set (&buffer->refcount, 1);
@@ -78,7 +95,7 @@ gst_buffer_new(void)
   buffer->pool_private = NULL;
   buffer->free = NULL;
   buffer->copy = NULL;
-  
+
   return buffer;
 }
 
@@ -91,18 +108,21 @@ gst_buffer_new(void)
  * Returns: new buffer
  */
 GstBuffer*
-gst_buffer_new_from_pool (GstBufferPool *pool, guint64 location, gint size)
+gst_buffer_new_from_pool (GstBufferPool *pool, guint32 offset, guint32 size)
 {
   GstBuffer *buffer;
 
   g_return_val_if_fail (pool != NULL, NULL);
   g_return_val_if_fail (pool->buffer_new != NULL, NULL);
   
-  buffer = pool->buffer_new (pool, location, size, pool->user_data);
+  buffer = pool->buffer_new (pool, offset, size, pool->user_data);
   buffer->pool = pool;
   buffer->free = pool->buffer_free;
   buffer->copy = pool->buffer_copy;
   
+  GST_INFO (GST_CAT_BUFFER,"creating new buffer %p from pool %p (size %x, offset %x)", 
+                 buffer, pool, size, offset);
+
   return buffer;
 }
 
@@ -124,13 +144,16 @@ gst_buffer_create_sub (GstBuffer *parent,
   GstBuffer *buffer;
 
   g_return_val_if_fail (parent != NULL, NULL);
+  g_return_val_if_fail (GST_BUFFER_REFCOUNT(parent) > 0, NULL);
   g_return_val_if_fail (size > 0, NULL);
   g_return_val_if_fail ((offset+size) <= parent->size, NULL);
 
   g_mutex_lock (_gst_buffer_chunk_lock);
   buffer = g_mem_chunk_alloc (_gst_buffer_chunk);
+  GST_DATA_TYPE(buffer) = _gst_buffer_type;
   g_mutex_unlock (_gst_buffer_chunk_lock);
-  GST_INFO (GST_CAT_BUFFER,"creating new subbuffer %p from parent %p", buffer, parent);
+  GST_INFO (GST_CAT_BUFFER,"creating new subbuffer %p from parent %p (size %u, offset %u)", 
+                 buffer, parent, size, offset);
 
   buffer->lock = g_mutex_new ();
 #ifdef HAVE_ATOMIC_H
@@ -166,7 +189,7 @@ gst_buffer_create_sub (GstBuffer *parent,
   gst_buffer_ref (parent);
 
   buffer->pool = NULL;
-  // return the new subbuffer
+
   return buffer;
 }
 
@@ -192,6 +215,8 @@ gst_buffer_append (GstBuffer *buffer,
   g_return_val_if_fail (buffer != NULL, NULL);
   g_return_val_if_fail (append != NULL, NULL);
   g_return_val_if_fail (buffer->pool == NULL, NULL);
+  g_return_val_if_fail (GST_BUFFER_REFCOUNT(buffer) > 0, NULL);
+  g_return_val_if_fail (GST_BUFFER_REFCOUNT(append) > 0, NULL);
 
   GST_INFO (GST_CAT_BUFFER,"appending buffers %p and %p",buffer,append);
 
@@ -226,12 +251,15 @@ gst_buffer_append (GstBuffer *buffer,
  *
  * destroy the buffer
  */
-void gst_buffer_destroy (GstBuffer *buffer) 
+void 
+gst_buffer_destroy (GstBuffer *buffer) 
 {
 
   g_return_if_fail (buffer != NULL);
   
-  GST_INFO (GST_CAT_BUFFER,"freeing %sbuffer %p", (buffer->parent?"sub":""),buffer);
+  GST_INFO (GST_CAT_BUFFER, "freeing %sbuffer %p",
+           (buffer->parent?"sub":""),
+           buffer);
   
   // free the data only if there is some, DONTFREE isn't set, and not sub
   if (GST_BUFFER_DATA (buffer) &&
@@ -252,6 +280,11 @@ void gst_buffer_destroy (GstBuffer *buffer)
   g_mutex_free (buffer->lock);
   //g_print("freed mutex\n");
 
+#ifdef GST_DEBUG_ENABLED
+  // make it hard to reuse by mistake
+  memset (buffer, 0, sizeof (GstBuffer));
+#endif
+
   // remove it entirely from memory
   g_mutex_lock (_gst_buffer_chunk_lock);
   g_mem_chunk_free (_gst_buffer_chunk,buffer);
@@ -268,14 +301,13 @@ void
 gst_buffer_ref (GstBuffer *buffer) 
 {
   g_return_if_fail (buffer != NULL);
+  g_return_if_fail (GST_BUFFER_REFCOUNT(buffer) > 0);
 
-  GST_DEBUG (0,"referencing buffer %p\n", buffer);
+  GST_INFO (GST_CAT_BUFFER, "ref buffer %p\n", buffer);
 
 #ifdef HAVE_ATOMIC_H
-  //g_return_if_fail(atomic_read(&(buffer->refcount)) > 0);
   atomic_inc (&(buffer->refcount));
 #else
-  g_return_if_fail (buffer->refcount > 0);
   GST_BUFFER_LOCK (buffer);
   buffer->refcount++;
   GST_BUFFER_UNLOCK (buffer);
@@ -283,30 +315,6 @@ gst_buffer_ref (GstBuffer *buffer)
 }
 
 /**
- * gst_buffer_ref_by_count:
- * @buffer: the GstBuffer to reference
- * @count: a number
- *
- * Increment the refcount of this buffer by the given number.
- */
-void 
-gst_buffer_ref_by_count (GstBuffer *buffer, int count) 
-{
-  g_return_if_fail (buffer != NULL);
-  g_return_if_fail (count > 0);
-
-#ifdef HAVE_ATOMIC_H
-  g_return_if_fail (atomic_read (&(buffer->refcount)) > 0);
-  atomic_add (count, &(buffer->refcount));
-#else
-  g_return_if_fail (buffer->refcount > 0);
-  GST_BUFFER_LOCK (buffer);
-  buffer->refcount += count;
-  GST_BUFFER_UNLOCK (buffer);
-#endif
-}
-
-/**
  * gst_buffer_unref:
  * @buffer: the GstBuffer to unref
  *
@@ -319,14 +327,13 @@ gst_buffer_unref (GstBuffer *buffer)
   gint zero;
 
   g_return_if_fail (buffer != NULL);
+  g_return_if_fail (GST_BUFFER_REFCOUNT(buffer) > 0);
 
-  GST_DEBUG (0,"unreferencing buffer %p\n", buffer);
+  GST_INFO (GST_CAT_BUFFER, "unref buffer %p\n", buffer);
 
 #ifdef HAVE_ATOMIC_H
-  g_return_if_fail (atomic_read (&(buffer->refcount)) > 0);
   zero = atomic_dec_and_test (&(buffer->refcount));
 #else
-  g_return_if_fail (buffer->refcount > 0);
   GST_BUFFER_LOCK (buffer);
   buffer->refcount--;
   zero = (buffer->refcount == 0);
@@ -352,6 +359,8 @@ gst_buffer_copy (GstBuffer *buffer)
 {
   GstBuffer *newbuf;
 
+  g_return_val_if_fail (GST_BUFFER_REFCOUNT(buffer) > 0, NULL);
+
   // if a copy function exists, use it, else copy the bytes
   if (buffer->copy != NULL) {
     newbuf = (buffer->copy)(buffer);
@@ -391,7 +400,11 @@ gst_buffer_copy (GstBuffer *buffer)
 gboolean
 gst_buffer_is_span_fast (GstBuffer *buf1, GstBuffer *buf2)
 {
-  return ((buf1->parent == buf2->parent) &&
+  g_return_val_if_fail (GST_BUFFER_REFCOUNT(buf1) > 0, FALSE);
+  g_return_val_if_fail (GST_BUFFER_REFCOUNT(buf2) > 0, FALSE);
+
+  return (buf1->parent && buf2->parent && 
+         (buf1->parent == buf2->parent) &&
           ((buf1->data + buf1->size) == buf2->data));
 }
 
@@ -420,38 +433,43 @@ gst_buffer_span (GstBuffer *buf1, guint32 offset, GstBuffer *buf2, guint32 len)
 {
   GstBuffer *newbuf;
 
+  g_return_val_if_fail (GST_BUFFER_REFCOUNT(buf1) > 0, NULL);
+  g_return_val_if_fail (GST_BUFFER_REFCOUNT(buf2) > 0, NULL);
+
   // make sure buf1 has a lower address than buf2
   if (buf1->data > buf2->data) {
     GstBuffer *tmp = buf1;
+    g_print ("swapping buffers\n");
     buf1 = buf2;
     buf2 = tmp;
   }
 
   // if the two buffers have the same parent and are adjacent
-//  if ((buf1->parent == buf2->parent) &&
-//      ((buf1->data + buf1->size) == buf2->data)) {
   if (gst_buffer_is_span_fast(buf1,buf2)) {
     // we simply create a subbuffer of the common parent
-    return gst_buffer_create_sub(buf1->parent, buf1->data - (buf1->parent->data) + offset, len);
+    newbuf = gst_buffer_create_sub (buf1->parent, buf1->data - (buf1->parent->data) + offset, len);
   }
+  else {
+    g_print ("slow path taken in buffer_span\n");
+    // otherwise we simply have to brute-force copy the buffers
+    newbuf = gst_buffer_new ();
 
-  // otherwise we simply have to brute-force copy the buffers
-  newbuf = gst_buffer_new();
-
-  // put in new size
-  newbuf->size = len;
-  // allocate space for the copy
-  newbuf->data = (guchar *)g_malloc(len);
-  // 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 + offset, buf2->data, len - (buf1->size - offset));
+    // put in new size
+    newbuf->size = len;
+    // allocate space for the copy
+    newbuf->data = (guchar *)g_malloc(len);
+    // 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));
+
+    if (newbuf->offset != -1)
+      newbuf->offset = buf1->offset + offset;
+    newbuf->timestamp = buf1->timestamp;
+    if (buf2->maxage > buf1->maxage) newbuf->maxage = buf2->maxage;
+    else newbuf->maxage = buf1->maxage;
 
-  if (newbuf->offset != -1)
-    newbuf->offset = buf1->offset + offset;
-  newbuf->timestamp = buf1->timestamp;
-  if (buf2->maxage > buf1->maxage) newbuf->maxage = buf2->maxage;
-  else newbuf->maxage = buf1->maxage;
+  }
 
   return newbuf;
 }
@@ -475,5 +493,5 @@ GstBuffer *
 gst_buffer_merge (GstBuffer *buf1, GstBuffer *buf2)
 {
   // we're just a specific case of the more general gst_buffer_span()
-  return gst_buffer_span(buf1, 0, buf2, buf1->size + buf2->size);
+  return gst_buffer_span (buf1, 0, buf2, buf1->size + buf2->size);
 }
index 269bf3e..9eef49c 100644 (file)
 #ifndef __GST_BUFFER_H__
 #define __GST_BUFFER_H__
 
+//
+// Define this to add file:line info to each GstBuffer showing
+// the location in the source code where the buffer was created.
+// 
+// #define GST_BUFFER_WHERE
+//
+// Then in gdb, you can `call gst_buffer_print_live()' to get a list
+// of allocated GstBuffers and also the file:line where they were
+// allocated.
+//
+
+#include <gst/gstdata.h>
 #include <gst/gstobject.h>
 
 #ifdef HAVE_CONFIG_H
 extern "C" {
 #endif /* __cplusplus */
 
+extern GType _gst_buffer_type;
 
-#define GST_BUFFER(buf) \
-  ((GstBuffer *)(buf))
+#define GST_TYPE_BUFFER                (_gst_buffer_type)
+#define GST_BUFFER(buf)        ((GstBuffer *)(buf))
+#define GST_IS_BUFFER(buf)     (GST_DATA_TYPE(buf) == GST_TYPE_BUFFER)
 
-#define GST_BUFFER_FLAGS(buf) \
-  (GST_BUFFER(buf)->flags)
-#define GST_BUFFER_FLAG_IS_SET(buf,flag) \
-  (GST_BUFFER_FLAGS(buf) & (1<<(flag)))
-#define GST_BUFFER_FLAG_SET(buf,flag) \
-  G_STMT_START{ (GST_BUFFER_FLAGS(buf) |= (1<<(flag))); }G_STMT_END
-#define GST_BUFFER_FLAG_UNSET(buf,flag) \
-  G_STMT_START{ (GST_BUFFER_FLAGS(buf) &= ~(1<<(flag))); }G_STMT_END
+#define GST_BUFFER_FLAGS(buf)                  (GST_BUFFER(buf)->flags)
+#define GST_BUFFER_FLAG_IS_SET(buf,flag)       (GST_BUFFER_FLAGS(buf) & (1<<(flag)))
+#define GST_BUFFER_FLAG_SET(buf,flag)          G_STMT_START{ (GST_BUFFER_FLAGS(buf) |= (1<<(flag))); }G_STMT_END
+#define GST_BUFFER_FLAG_UNSET(buf,flag)        G_STMT_START{ (GST_BUFFER_FLAGS(buf) &= ~(1<<(flag))); }G_STMT_END
 
 
 #define GST_BUFFER_DATA(buf)           (GST_BUFFER(buf)->data)
@@ -82,7 +92,6 @@ typedef enum {
 } GstBufferFlags;
 
 
-
 typedef struct _GstBuffer GstBuffer;
 
 
@@ -93,56 +102,56 @@ typedef GstBuffer *(*GstBufferCopyFunc)    (GstBuffer *srcbuf);
 #include <gst/gstbufferpool.h>
 
 struct _GstBuffer {
+  GstData              data_type;
+
   /* locking */
-  GMutex *lock;
+  GMutex               *lock;
 
   /* refcounting */
 #ifdef HAVE_ATOMIC_H
-  atomic_t refcount;
+  atomic_t             refcount;
 #define GST_BUFFER_REFCOUNT(buf)       (atomic_read(&(GST_BUFFER((buf))->refcount)))
 #else
-  int refcount;
+  int                  refcount;
 #define GST_BUFFER_REFCOUNT(buf)       (GST_BUFFER(buf)->refcount)
 #endif
 
   /* flags */
-  guint16 flags;
+  guint16              flags;
 
   /* pointer to data, its size, and offset in original source if known */
-  guchar *data;
-  guint32 size;
-  guint32 maxsize;
-  guint32 offset;
+  guchar               *data;
+  guint32              size;
+  guint32              maxsize;
+  guint32              offset;
 
   /* timestamp */
-  gint64 timestamp;
-  /* max age */
-  gint64 maxage;
+  gint64               timestamp;
+  gint64               maxage;
 
   /* subbuffer support, who's my parent? */
-  GstBuffer *parent;
+  GstBuffer            *parent;
 
   /* this is a pointer to the buffer pool (if any) */
-  GstBufferPool *pool;
-  gpointer pool_private;
+  GstBufferPool        *pool;
+  gpointer             pool_private;
 
   /* utility function pointers */
-  GstBufferFreeFunc free;              // free the data associated with the buffer
-  GstBufferCopyFunc copy;              // copy the data from one buffer to another
+  GstBufferFreeFunc    free;           // free the data associated with the buffer
+  GstBufferCopyFunc    copy;           // copy the data from one buffer to another
 };
 
 /* initialisation */
 void           _gst_buffer_initialize          (void);
 /* creating a new buffer from scratch */
 GstBuffer*     gst_buffer_new                  (void);
-GstBuffer*     gst_buffer_new_from_pool        (GstBufferPool *pool, guint64 location, gint size);
+GstBuffer*     gst_buffer_new_from_pool        (GstBufferPool *pool, guint32 offset, guint32 size);
 
 /* creating a subbuffer */
 GstBuffer*     gst_buffer_create_sub           (GstBuffer *parent, guint32 offset, guint32 size);
 
 /* refcounting */
 void           gst_buffer_ref                  (GstBuffer *buffer);
-void           gst_buffer_ref_by_count         (GstBuffer *buffer, int count);
 void           gst_buffer_unref                (GstBuffer *buffer);
 
 /* destroying the buffer */
index c742be0..d04c8a2 100644 (file)
@@ -274,6 +274,13 @@ gst_buffer_pool_destroy (GstBufferPool *pool)
   g_free(pool);
 }
 
+//
+// This is so we don't get messed up by GST_BUFFER_WHERE.
+//
+static GstBuffer *
+_pool_gst_buffer_copy (GstBuffer *buffer)
+{ return gst_buffer_copy (buffer); }
+
 /**
  * gst_buffer_pool_get_default:
  * @buffer_size: the number of bytes this buffer will store
@@ -314,7 +321,7 @@ gst_buffer_pool_get_default (guint buffer_size, guint pool_size)
   pool = gst_buffer_pool_new();
   gst_buffer_pool_set_buffer_new_function (pool, gst_buffer_pool_default_buffer_new);
   gst_buffer_pool_set_buffer_free_function (pool, gst_buffer_pool_default_buffer_free);
-  gst_buffer_pool_set_buffer_copy_function (pool, gst_buffer_copy);
+  gst_buffer_pool_set_buffer_copy_function (pool, _pool_gst_buffer_copy);
   gst_buffer_pool_set_destroy_hook (pool, gst_buffer_pool_default_destroy_hook);
   
   def = g_new0 (GstBufferPoolDefault, 1);
index ddb75ad..19f68c5 100644 (file)
@@ -545,7 +545,7 @@ gst_caps_check_compatibility (GstCaps *fromcaps, GstCaps *tocaps)
   return FALSE;
 }
 
-#if (! (defined(GST_DISABLE_LOADSAVE) && defined(GST_DISABLE_REGISTRY)) )
+#ifndef GST_DISABLE_LOADSAVE_REGISTRY
 /**
  * gst_caps_save_thyself:
  * @caps: a capabilty to save
@@ -629,4 +629,4 @@ gst_caps_load_thyself (xmlNodePtr parent)
   return result;
 }
 
-#endif /* (! (defined(GST_DISABLE_LOADSAVE) && defined(GST_DISABLE_REGISTRY)) ) */
+#endif /* GST_DISABLE_LOADSAVE_REGISTRY */
index 8748275..77a8767 100644 (file)
 #ifndef __GST_CAPS_H__
 #define __GST_CAPS_H__
 
-#include <parser.h> // NOTE: this is xml-config's fault
-
-// Include compatability defines: if libxml hasn't already defined these,
-// we have an old version 1.x
-#ifndef xmlChildrenNode
-#define xmlChildrenNode childs
-#define xmlRootNode root
-#endif
+#include <gst/gstconfig.h>
 
 #include <gst/gstprops.h>
 
@@ -118,7 +111,9 @@ GstCaps*    gst_caps_prepend                        (GstCaps *caps, GstCaps *capstoadd);
 
 gboolean       gst_caps_check_compatibility            (GstCaps *fromcaps, GstCaps *tocaps);
 
+#ifndef GST_DISABLE_LOADSAVE
 xmlNodePtr      gst_caps_save_thyself                  (GstCaps *caps, xmlNodePtr parent);
 GstCaps*       gst_caps_load_thyself                   (xmlNodePtr parent);
+#endif
 
 #endif /* __GST_CAPS_H__ */
diff --git a/gst/gstconfig.h b/gst/gstconfig.h
new file mode 100644 (file)
index 0000000..844c2df
--- /dev/null
@@ -0,0 +1,32 @@
+/* This header interprets the various GST_* macros that are typically  *
+ * provided by the gstreamer-config or gstreamer.pc files.             */
+
+#ifndef __GST_CONFIG_H__
+#define __GST_CONFIG_H__
+
+
+/***** We include config.h in case someone perhaps used a gstreamer.m4 or
+       something else that provides funky overrides.  BEWARE! *****/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif /* HAVE_CONFIG_H */
+
+
+/***** Deal with XML stuff, we have to handle both loadsave and registry *****/
+
+#if (! (defined(GST_DISABLE_LOADSAVE) && defined(GST_DISABLE_REGISTRY)) )
+  #include <parser.h>
+  // Include compatability defines: if libxml hasn't already defined these,
+  // we have an old version 1.x
+  #ifndef xmlChildrenNode
+    #define xmlChildrenNode childs
+    #define xmlRootNode root
+  #endif
+  
+#else
+  #define GST_DISABLE_LOADSAVE_REGISTRY
+#endif
+
+#endif /* __GST_CONFIG_H__ */
diff --git a/gst/gstdata.h b/gst/gstdata.h
new file mode 100644 (file)
index 0000000..198ae7e
--- /dev/null
@@ -0,0 +1,46 @@
+/* GStreamer
+ * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
+ *                    2000 Wim Taymans <wim.taymans@chello.be>
+ *
+ * gstdata.h: Header for GstData objects (used for data passing)
+ *
+ * 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_DATA_H__
+#define __GST_DATA_H__
+
+#include <gst/gstobject.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#define GST_DATA(data)         (GstData*)(data)
+#define GST_DATA_TYPE(data)    (((GstData*)(data))->type)
+
+typedef struct _GstData GstData;
+
+struct _GstData {
+  GType type;
+};
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __GST_DATA_H__ */
index e945f40..332c91b 100644 (file)
@@ -65,13 +65,14 @@ static xmlNodePtr           gst_element_save_thyself        (GstObject *object, xmlNodePtr paren
 GstElement*                    gst_element_restore_thyself     (xmlNodePtr self, GstObject *parent);
 #endif
 
+GType _gst_element_type = 0;
+
 static GstObjectClass *parent_class = NULL;
 static guint gst_element_signals[LAST_SIGNAL] = { 0 };
 
-GType gst_element_get_type(void) {
-  static GType element_type = 0;
-
-  if (!element_type) {
+GType gst_element_get_type (void) 
+{
+  if (!_gst_element_type) {
     static const GTypeInfo element_info = {
       sizeof(GstElementClass),
       (GBaseInitFunc)gst_element_base_class_init,
@@ -84,9 +85,9 @@ GType gst_element_get_type(void) {
       (GInstanceInitFunc)gst_element_init,
       NULL
     };
-    element_type = g_type_register_static(GST_TYPE_OBJECT, "GstElement", &element_info, G_TYPE_FLAG_ABSTRACT);
+    _gst_element_type = g_type_register_static(GST_TYPE_OBJECT, "GstElement", &element_info, G_TYPE_FLAG_ABSTRACT);
   }
-  return element_type;
+  return _gst_element_type;
 }
 
 static void
@@ -602,14 +603,14 @@ gst_element_get_padtemplate_by_compatible (GstElement *element, GstPadTemplate *
 }
 
 static GstPad*
-gst_element_request_pad (GstElement *element, GstPadTemplate *templ)
+gst_element_request_pad (GstElement *element, GstPadTemplate *templ, const gchar* name)
 {
   GstPad *newpad = NULL;
   GstElementClass *oclass;
 
   oclass = GST_ELEMENT_CLASS (G_OBJECT_GET_CLASS(element));
   if (oclass->request_new_pad)
-    newpad = (oclass->request_new_pad)(element, templ);
+    newpad = (oclass->request_new_pad)(element, templ, name);
 
   return newpad;
 }
@@ -638,7 +639,7 @@ gst_element_request_compatible_pad (GstElement *element, GstPadTemplate *templ)
 
   templ_new = gst_element_get_padtemplate_by_compatible (element, templ);
   if (templ_new != NULL)
-      pad = gst_element_request_pad (element, templ_new);
+      pad = gst_element_request_pad (element, templ_new, NULL);
 
   return pad;
 }
@@ -658,19 +659,40 @@ gst_element_request_compatible_pad (GstElement *element, GstPadTemplate *templ)
 GstPad*
 gst_element_request_pad_by_name (GstElement *element, const gchar *name)
 {
-  GstPadTemplate *templ;
+  GstPadTemplate *templ = NULL;
   GstPad *pad;
+  const gchar *req_name = NULL;
+  gboolean templ_found = FALSE;
+  GList *list;
+  gint n;
 
   g_return_val_if_fail (element != NULL, NULL);
   g_return_val_if_fail (GST_IS_ELEMENT (element), NULL);
   g_return_val_if_fail (name != NULL, NULL);
 
-  templ = gst_element_get_padtemplate_by_name (element, name);
+  if (strstr (name, "%d")) {
+      templ = gst_element_get_padtemplate_by_name (element, name);
+      req_name = NULL;
+  } else {
+      list = gst_element_get_padtemplate_list(element);
+      while (!templ_found && list) {
+          templ = (GstPadTemplate*) list->data;
+          if (strstr (templ->name_template, "%d")) {
+              if (sscanf(name, templ->name_template, &n)) {
+                  templ_found = TRUE;
+                  req_name = name;
+                  break;
+              }
+          }
+          list = list->next;
+      }
+  }
+  
   if (templ == NULL)
-    return NULL;
-
-  pad = gst_element_request_pad (element, templ);
-
+      return NULL;
+  
+  pad = gst_element_request_pad (element, templ, req_name);
+  
   return pad;
 }
 
@@ -772,6 +794,14 @@ gst_element_error (GstElement *element, const gchar *error)
 }
 
 
+GstElementState
+gst_element_get_state (GstElement *elem)
+{
+  g_return_val_if_fail (GST_IS_ELEMENT (elem), GST_STATE_VOID_PENDING);
+
+  return GST_STATE (elem);
+}
+
 /**
  * gst_element_set_state:
  * @element: element to change state of
@@ -836,7 +866,6 @@ gst_element_set_state (GstElement *element, GstElementState state)
     }
   }
 
-  /* this is redundant, really, it will always return SUCCESS */
   return return_val;
 }
 
@@ -1157,7 +1186,7 @@ gst_element_restore_thyself (xmlNodePtr self, GstObject *parent)
 
   return element;
 }
-#endif // GST_DISABLE_LOADSAVE
+#endif /* GST_DISABLE_LOADSAVE */
 
 /**
  * gst_element_set_sched:
index 22d218b..1d05451 100644 (file)
 #ifndef __GST_ELEMENT_H__
 #define __GST_ELEMENT_H__
 
-#include <parser.h> // NOTE: this is xml-config's fault
-
-// Include compatability defines: if libxml hasn't already defined these,
-// we have an old version 1.x
-#ifndef xmlChildrenNode
-#define xmlChildrenNode childs
-#define xmlRootNode root
-#endif
+#include <gst/gstconfig.h>
 
 #include <gst/gstobject.h>
 #include <gst/gstpad.h>
@@ -72,16 +65,22 @@ typedef enum {
 #define GST_STATE_PAUSED_TO_READY      ((GST_STATE_PAUSED<<8) | GST_STATE_READY)
 #define GST_STATE_READY_TO_NULL                ((GST_STATE_READY<<8) | GST_STATE_NULL)
 
-#define GST_TYPE_ELEMENT \
-  (gst_element_get_type())
-#define GST_ELEMENT(obj) \
-  (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_ELEMENT,GstElement))
-#define GST_ELEMENT_CLASS(klass) \
-  (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_ELEMENT,GstElementClass))
-#define GST_IS_ELEMENT(obj) \
-  (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_ELEMENT))
-#define GST_IS_ELEMENT_CLASS(klass) \
-  (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_ELEMENT))
+extern GType _gst_element_type;
+
+#define GST_TYPE_ELEMENT               (_gst_element_type)
+
+#define GST_ELEMENT_FAST(obj)          ((GstElement*)(obj))
+#define GST_ELEMENT_CLASS_FAST(klass)  ((GstElementClass*)(klass))
+#define GST_IS_ELEMENT(obj)            (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_ELEMENT))
+#define GST_IS_ELEMENT_CLASS(obj)      (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_ELEMENT))
+
+#ifdef GST_TYPE_PARANOID
+# define GST_ELEMENT(obj)              (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_ELEMENT, GstElement))
+# define GST_ELEMENT_CLASS(klass)       (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_ELEMENT, GstElementClass))
+#else
+# define GST_ELEMENT                    GST_ELEMENT_FAST
+# define GST_ELEMENT_CLASS              GST_ELEMENT_CLASS_FAST
+#endif
 
 typedef enum {
   /* element is complex (for some def.) and generally require a cothread */
@@ -132,32 +131,32 @@ typedef struct _GstElementFactoryClass GstElementFactoryClass;
 typedef void (*GstElementLoopFunction) (GstElement *element);
 
 struct _GstElement {
-  GstObject object;
-
-  guint8 current_state;
-  guint8 pending_state;
+  GstObject            object;
 
+  /* element state  and scheduling */
+  guint8               current_state;
+  guint8               pending_state;
+  GstElement           *manager;
+  GstSchedule          *sched;
   GstElementLoopFunction loopfunc;
-  cothread_state *threadstate;
-  GstPad *select_pad;
-
-  guint16 numpads;
-  guint16 numsrcpads;
-  guint16 numsinkpads;
-  GList *pads;
-
-  GstElement *manager;
-  GstSchedule *sched;
+  cothread_state       *threadstate;
+
+  /* element pads */
+  guint16              numpads;
+  guint16              numsrcpads;
+  guint16              numsinkpads;
+  GList                *pads;
+  GstPad               *select_pad;
 };
 
 struct _GstElementClass {
-  GstObjectClass parent_class;
+  GstObjectClass       parent_class;
 
   /* the elementfactory that created us */
-  GstElementFactory *elementfactory;
+  GstElementFactory    *elementfactory;
   /* templates for our pads */
-  GList *padtemplates;
-  gint numpadtemplates;
+  GList                *padtemplates;
+  gint                         numpadtemplates;
   
   /* signal callbacks */
   void (*state_change)         (GstElement *element,GstElementState state);
@@ -169,13 +168,13 @@ struct _GstElementClass {
   void (*eos)                  (GstElement *element);
 
   /* local pointers for get/set */
-  void (*set_property) (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec);
-  void (*get_property) (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec);
+  void (*set_property)         (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec);
+  void (*get_property) (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec);
 
   /* change the element state */
   GstElementStateReturn (*change_state)                (GstElement *element);
   /* request a new pad */
-  GstPad*              (*request_new_pad)      (GstElement *element, GstPadTemplate *templ);
+  GstPad*              (*request_new_pad)      (GstElement *element, GstPadTemplate *templ, const gchar* name);
 };
 
 void                   gst_element_class_add_padtemplate       (GstElementClass *element, GstPadTemplate *templ);
@@ -215,6 +214,7 @@ void                        gst_element_disconnect          (GstElement *src, const gchar *srcpadname,
 void                   gst_element_signal_eos          (GstElement *element);
 
 
+GstElementState         gst_element_get_state           (GstElement *elem);
 /* called by the app to set the state of the element */
 gint                   gst_element_set_state           (GstElement *element, GstElementState state);
 const gchar *          gst_element_statename           (GstElementState state);
@@ -223,8 +223,10 @@ void                       gst_element_error               (GstElement *element, const gchar *error);
 
 GstElementFactory*     gst_element_get_factory         (GstElement *element);
 
+#ifndef GST_DISABLE_LOADSAVE
 /* XML write and read */
 GstElement*            gst_element_restore_thyself     (xmlNodePtr self, GstObject *parent);
+#endif
 
 
 /*
@@ -243,16 +245,13 @@ struct _GstElementDetails {
   gchar *copyright;             /* copyright details (year, etc.) */
 };
 
-#define GST_TYPE_ELEMENTFACTORY \
-  (gst_elementfactory_get_type())
-#define GST_ELEMENTFACTORY(obj) \
-  (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_ELEMENTFACTORY,GstElementFactory))
-#define GST_ELEMENTFACTORY_CLASS(klass) \
-  (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_ELEMENTFACTORY,GstElementFactoryClass))
-#define GST_IS_ELEMENTFACTORY(obj) \
-  (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_ELEMENTFACTORY))
-#define GST_IS_ELEMENTFACTORY_CLASS(klass) \
-  (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_ELEMENTFACTORY))
+#define GST_TYPE_ELEMENTFACTORY                (gst_elementfactory_get_type())
+#define GST_ELEMENTFACTORY(obj)                (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_ELEMENTFACTORY,\
+                                                GstElementFactory))
+#define GST_ELEMENTFACTORY_CLASS(klass)        (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_ELEMENTFACTORY,\
+                                                GstElementFactoryClass))
+#define GST_IS_ELEMENTFACTORY(obj)             (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_ELEMENTFACTORY))
+#define GST_IS_ELEMENTFACTORY_CLASS(klass)     (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_ELEMENTFACTORY))
 
 struct _GstElementFactory {
   GstPluginFeature feature;
index 8ecc553..0f4dde3 100644 (file)
@@ -31,7 +31,7 @@ static void                   gst_elementfactory_init                 (GstElementFactory *factory);
 #ifndef GST_DISABLE_REGISTRY
 static void                    gst_elementfactory_restore_thyself      (GstObject *object, xmlNodePtr parent);
 static xmlNodePtr              gst_elementfactory_save_thyself         (GstObject *object, xmlNodePtr parent);
-#endif /* GST_DISABLE_REGISTRY */
+#endif
 
 static void                    gst_elementfactory_unload_thyself       (GstPluginFeature *feature);
 
@@ -81,7 +81,7 @@ gst_elementfactory_class_init (GstElementFactoryClass *klass)
 #ifndef GST_DISABLE_REGISTRY
   gstobject_class->save_thyself =      GST_DEBUG_FUNCPTR (gst_elementfactory_save_thyself);
   gstobject_class->restore_thyself =   GST_DEBUG_FUNCPTR (gst_elementfactory_restore_thyself);
-#endif /* GST_DISABLE_REGISTRY */
+#endif
 
   gstpluginfeature_class->unload_thyself =     GST_DEBUG_FUNCPTR (gst_elementfactory_unload_thyself);
 
diff --git a/gst/gstevent.c b/gst/gstevent.c
new file mode 100644 (file)
index 0000000..10aa9c3
--- /dev/null
@@ -0,0 +1,96 @@
+/* GStreamer
+ * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
+ *                    2000 Wim Taymans <wim.taymans@chello.be>
+ *
+ * gstevent.h: Header for GstEvent subsystem
+ *
+ * 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/gstinfo.h"
+#include "gst/gstevent.h"
+
+GType _gst_event_type;
+
+static GMemChunk *_gst_event_chunk;
+static GMutex *_gst_event_chunk_lock;
+
+void
+_gst_event_initialize (void)
+{
+  gint eventsize = sizeof(GstEvent);
+  static const GTypeInfo event_info = {
+    0,
+    NULL,
+    NULL,
+    NULL,
+    NULL,
+    NULL,
+    0, 
+    0,
+    NULL,
+  };
+
+  // round up to the nearest 32 bytes for cache-line and other efficiencies
+  eventsize = (((eventsize-1) / 32) + 1) * 32;
+
+  _gst_event_chunk = g_mem_chunk_new ("GstEvent", eventsize,
+                                     eventsize * 32, G_ALLOC_AND_FREE);
+
+  _gst_event_chunk_lock = g_mutex_new ();
+
+  // register the type
+  _gst_event_type = g_type_register_static (G_TYPE_INT, "GstEvent", &event_info, 0);
+}
+
+GstEvent*
+gst_event_new (GstEventType type)
+{
+  GstEvent *event;
+
+  g_mutex_lock (_gst_event_chunk_lock);
+  event = g_mem_chunk_alloc (_gst_event_chunk);
+  g_mutex_unlock (_gst_event_chunk_lock);
+  GST_INFO (GST_CAT_EVENT, "creating new event %p", event);
+
+  GST_DATA_TYPE (event) = _gst_event_type;
+  GST_EVENT_TYPE (event) = type;
+
+  return event;
+}
+
+void
+gst_event_free (GstEvent* event)
+{
+  g_mutex_lock (_gst_event_chunk_lock);
+  g_mem_chunk_free (_gst_event_chunk, event);
+  g_mutex_unlock (_gst_event_chunk_lock);
+}
+
+/* seek stuff */
+GstEvent*       
+gst_event_new_seek (GstSeekType type, guint64 offset, gboolean flush)
+{
+  GstEvent *event;
+
+  event = gst_event_new (GST_EVENT_SEEK);
+  GST_EVENT_SEEK_TYPE (event) = type;
+  GST_EVENT_SEEK_OFFSET (event) = offset;
+  GST_EVENT_SEEK_FLUSH (event) = flush;
+
+  return event;
+}
index 0b5b134..2e45b2b 100644 (file)
@@ -25,6 +25,7 @@
 #define __GST_EVENT_H__
 
 #include <gst/gstobject.h>
+#include <gst/gstdata.h>
 
 #ifdef __cplusplus
 extern "C" {
@@ -36,14 +37,57 @@ typedef enum {
   GST_EVENT_FLUSH,
   GST_EVENT_EMPTY,
   GST_EVENT_SEEK,
+  GST_EVENT_DISCONTINUOUS
 } GstEventType;
 
+extern GType _gst_event_type;
+
+#define GST_TYPE_EVENT         (_gst_event_type)
+#define GST_EVENT(event)       ((GstEvent*)(event))
+#define GST_IS_EVENT(event)    (GST_DATA_TYPE(event) == GST_TYPE_EVENT)
+
+#define GST_EVENT_TYPE(event)          (GST_EVENT(event)->type)
+#define GST_EVENT_TIMESTAMP(event)     (GST_EVENT(event)->timstamp)
+
+/* seek events */
+typedef enum {
+  GST_SEEK_ANY,
+  GST_SEEK_TIMEOFFSET,
+  GST_SEEK_BYTEOFFSET
+} GstSeekType;
+
+#define GST_EVENT_SEEK_TYPE(event)     (GST_EVENT(event)->event_data.seek.type)
+#define GST_EVENT_SEEK_OFFSET(event)   (GST_EVENT(event)->event_data.seek.offset)
+#define GST_EVENT_SEEK_FLUSH(event)    (GST_EVENT(event)->event_data.seek.flush)
+
 typedef struct _GstEvent GstEvent;
 
 struct _GstEvent {
-  GstEventType type;
+  GstData data;
+
+  GstEventType  type;
+  guint64      timestamp;
+
+  union {
+    struct {
+      GstSeekType type;
+      guint64     offset;
+      gboolean   flush;
+    } seek;
+  } event_data;
 };
 
+void           _gst_event_initialize   (void);
+       
+GstEvent*      gst_event_new           (GstEventType type);
+void           gst_event_free          (GstEvent* event);
+
+/* seek events */
+GstEvent*      gst_event_new_seek      (GstSeekType type, guint64 offset, gboolean flush);
+
+/* flush events */
+#define                gst_event_new_flush()   gst_event_new(GST_EVENT_FLUSH)
+
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */
index 3518ec2..ea63ea6 100644 (file)
@@ -459,6 +459,8 @@ gst_default_error_handler (gchar *file, gchar *function,
 
 /***** DEBUG system *****/
 GHashTable *__gst_function_pointers = NULL;
+// FIXME make this thread specific
+static GSList* stack_trace = NULL;
 
 gchar *_gst_debug_nameof_funcptr (void *ptr) __attribute__ ((no_instrument_function));
 
@@ -479,15 +481,52 @@ _gst_debug_nameof_funcptr (void *ptr)
 
 
 #ifdef GST_ENABLE_FUNC_INSTRUMENTATION
-
 void __cyg_profile_func_enter(void *this_fn,void *call_site) __attribute__ ((no_instrument_function));
-void __cyg_profile_func_enter(void *this_fn,void *call_site) {
-  GST_DEBUG(GST_CAT_CALL_TRACE, "entering function %s\n", _gst_debug_nameof_funcptr (this_fn));
+void __cyg_profile_func_enter(void *this_fn,void *call_site) 
+{
+  gchar *name = _gst_debug_nameof_funcptr (this_fn);
+  gchar *site = _gst_debug_nameof_funcptr (call_site);
+       
+  GST_DEBUG(GST_CAT_CALL_TRACE, "entering function %s from %s\n", name, site);
+  stack_trace = g_slist_prepend (stack_trace, g_strdup_printf ("%8p in %s from %p (%s)", this_fn, name, call_site, site));
+
+  g_free (name);
+  g_free (site);
 }
 
 void __cyg_profile_func_exit(void *this_fn,void *call_site) __attribute__ ((no_instrument_function));
-void __cyg_profile_func_exit(void *this_fn,void *call_site) {
-  GST_DEBUG(GST_CAT_CALL_TRACE, "leavinging function %s\n", _gst_debug_nameof_funcptr (this_fn));
+void __cyg_profile_func_exit(void *this_fn,void *call_site) 
+{
+  gchar *name = _gst_debug_nameof_funcptr (this_fn);
+
+  GST_DEBUG(GST_CAT_CALL_TRACE, "leaving function %s\n", name);
+  g_free (stack_trace->data);
+  stack_trace = g_slist_delete_link (stack_trace, stack_trace);
+
+  g_free (name);
+}
+
+void 
+gst_debug_print_stack_trace (void)
+{
+  GSList *walk = stack_trace;
+  gint count = 0;
+
+  if (walk)
+    walk = g_slist_next (walk);
+
+  while (walk) {
+    gchar *name = (gchar *) walk->data;
+
+    g_print ("#%-2d %s\n", count++, name);
+
+    walk = g_slist_next (walk);
+  }
+}
+#else
+void 
+gst_debug_print_stack_trace (void)
+{
 }
 
 #endif /* GST_ENABLE_FUNC_INTSTRUMENTATION */
index f5c06bd..4f3f605 100644 (file)
@@ -341,6 +341,8 @@ _gst_debug_register_funcptr (void *ptr, gchar *ptrname)
 
 gchar *_gst_debug_nameof_funcptr (void *ptr);
 
+void gst_debug_print_stack_trace (void);
+
 
 
 #endif /* __GSTINFO_H__ */
index 3e8d0b9..70d8122 100644 (file)
@@ -27,7 +27,7 @@
 /* Object signals and args */
 enum {
   PARENT_SET,
-#ifndef GST_DISABLE_LOADSAVE
+#ifndef GST_DISABLE_LOADSAVE_REGISTRY
   OBJECT_SAVED,
 #endif
   LAST_SIGNAL
@@ -43,6 +43,8 @@ enum {
   SO_LAST_SIGNAL
 };
 
+GType _gst_object_type = 0;
+
 typedef struct _GstSignalObject GstSignalObject;
 typedef struct _GstSignalObjectClass GstSignalObjectClass;
 
@@ -64,9 +66,7 @@ static guint gst_object_signals[LAST_SIGNAL] = { 0 };
 GType
 gst_object_get_type (void)
 {
-  static GType object_type = 0;
-
-  if (!object_type) {
+  if (!_gst_object_type) {
     static const GTypeInfo object_info = {
       sizeof (GstObjectClass),
       NULL,
@@ -79,9 +79,9 @@ gst_object_get_type (void)
       (GInstanceInitFunc) gst_object_init,
       NULL
     };
-    object_type = g_type_register_static (G_TYPE_OBJECT, "GstObject", &object_info, G_TYPE_FLAG_ABSTRACT);
+    _gst_object_type = g_type_register_static (G_TYPE_OBJECT, "GstObject", &object_info, G_TYPE_FLAG_ABSTRACT);
   }
-  return object_type;
+  return _gst_object_type;
 }
 
 static void
@@ -98,7 +98,7 @@ gst_object_class_init (GstObjectClass *klass)
                   G_STRUCT_OFFSET (GstObjectClass, parent_set), NULL, NULL,
                   g_cclosure_marshal_VOID__OBJECT,G_TYPE_NONE,1,
                   G_TYPE_OBJECT);
-#ifndef GST_DISABLE_LOADSAVE
+#ifndef GST_DISABLE_LOADSAVE_REGISTRY
   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,
@@ -446,7 +446,7 @@ gst_object_check_uniqueness (GList *list, const gchar *name)
 }
 
 
-#ifndef GST_DISABLE_LOADSAVE
+#ifndef GST_DISABLE_LOADSAVE_REGISTRY
 /**
  * gst_object_save_thyself:
  * @object: GstObject to save
@@ -496,7 +496,7 @@ gst_object_restore_thyself (GstObject *object, xmlNodePtr parent)
   if (oclass->restore_thyself)
     oclass->restore_thyself (object, parent);
 }
-#endif // GST_DISABLE_LOADSAVE
+#endif /* GST_DISABLE_LOADSAVE_REGISTRY */
 
 /**
  * gst_object_get_path_string:
@@ -577,9 +577,9 @@ struct _GstSignalObjectClass {
   GObjectClass        parent_class;
 
   /* signals */
-#ifndef GST_DISABLE_LOADSAVE
+#ifndef GST_DISABLE_LOADSAVE_REGISTRY
   void          (*object_loaded)           (GstSignalObject *object, GstObject *new, xmlNodePtr self);
-#endif /* GST_DISABLE_LOADSAVE */
+#endif /* GST_DISABLE_LOADSAVE_REGISTRY */
 };
 
 static GType
@@ -614,7 +614,7 @@ gst_signal_object_class_init (GstSignalObjectClass *klass)
 
   parent_class = g_type_class_ref (G_TYPE_OBJECT);
 
-#ifndef GST_DISABLE_LOADSAVE
+#ifndef GST_DISABLE_LOADSAVE_REGISTRY
   gst_signal_object_signals[SO_OBJECT_LOADED] =
     g_signal_new("object_loaded", G_TYPE_FROM_CLASS(klass), G_SIGNAL_RUN_LAST,
                   G_STRUCT_OFFSET (GstObjectClass, parent_set), NULL, NULL,
@@ -648,7 +648,7 @@ gst_class_signal_connect (GstObjectClass *klass,
   return g_signal_connect (klass->signal_object, name, func, func_data);
 }
 
-#ifndef GST_DISABLE_LOADSAVE
+#ifndef GST_DISABLE_LOADSAVE_REGISTRY
 /**
  * gst_class_signal_emit_by_name:
  * @object: the object that sends the signal
@@ -669,4 +669,4 @@ gst_class_signal_emit_by_name (GstObject *object,
   g_signal_emit_by_name (oclass->signal_object, name, object, self);
 }
 
-#endif // GST_DISABLE_LOADSAVE
+#endif /* GST_DISABLE_LOADSAVE_REGISTRY */
index d8140c7..681dcad 100644 (file)
 #ifndef __GST_OBJECT_H__
 #define __GST_OBJECT_H__
 
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
+#include <gst/gstconfig.h>
 
 #ifdef USE_GLIB2
 #include <glib-object.h>       // note that this gets wrapped in __GST_OBJECT_H__ 
 #include <gst/gobject2gtk.h>
 #endif
 
-#include <gst/gsttrace.h>
-#include <parser.h>
-
-#include <gst/gsttypes.h>
-
 #ifdef HAVE_ATOMIC_H
 #include <asm/atomic.h>
 #endif
 
+#include <gst/gsttrace.h>
+#include <gst/gsttypes.h>
+
 // FIXME
 #include "gstlog.h"
 
 extern "C" {
 #endif /* __cplusplus */
 
+extern GType _gst_object_type;
+
+#define GST_TYPE_OBJECT                 (_gst_object_type)
+# define GST_IS_OBJECT(obj)             (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_OBJECT))
+# define GST_IS_OBJECT_CLASS(obj)       (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_OBJECT))
 
-#define GST_TYPE_OBJECT \
-  (gst_object_get_type())
-#define GST_OBJECT(obj) \
-  (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_OBJECT,GstObject))
-#define GST_OBJECT_CLASS(klass) \
-  (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_OBJECT,GstObjectClass))
-#define GST_IS_OBJECT(obj) \
-  (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_OBJECT))
-#define GST_IS_OBJECT_CLASS(obj) \
-  (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_OBJECT))
+#define GST_OBJECT_FAST(obj)            ((GstObject*)(obj))
+#define GST_OBJECT_CLASS_FAST(klass)    ((GstObjectClass*)(klass))
+
+#ifdef GST_TYPE_PARANOID
+# define GST_OBJECT(obj)                (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_OBJECT, GstObject))
+# define GST_OBJECT_CLASS(klass)        (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_OBJECT, GstObjectClass))
+#else
+# define GST_OBJECT                     GST_OBJECT_FAST
+# define GST_OBJECT_CLASS               GST_OBJECT_CLASS_FAST
+#endif
 
 //typedef struct _GstObject GstObject;
 //typedef struct _GstObjectClass GstObjectClass;
@@ -76,40 +76,43 @@ typedef enum
 } GstObjectFlags;
 
 struct _GstObject {
-  GObject object;
+  GObject      object;
 
-  gchar *name;
+  gchar        *name;
   /* have to have a refcount for the object */
 #ifdef HAVE_ATOMIC_H
-  atomic_t refcount;
+  atomic_t     refcount;
 #else
-  int refcount;
+  gint                 refcount;
 #endif
 
   /* locking for all sorts of things (like the refcount) */
-  GMutex *lock;
-
+  GMutex       *lock;
   /* this objects parent */
-  GstObject *parent;
+  GstObject    *parent;
 
-  guint32 flags;
+  guint32      flags;
 };
 
 struct _GstObjectClass {
   GObjectClass parent_class;
 
-  gchar                        *path_string_separator;
-  GObject              *signal_object;
+  gchar                *path_string_separator;
+  GObject      *signal_object;
 
   /* signals */
   void         (*parent_set)           (GstObject *object, GstObject *parent);
+#ifndef GST_DISABLE_LOADSAVE_REGISTRY
   void         (*object_saved)         (GstObject *object, xmlNodePtr parent);
+#endif
 
   /* functions go here */
   void         (*destroy)              (GstObject *object);
 
+#ifndef GST_DISABLE_LOADSAVE_REGISTRY
   xmlNodePtr   (*save_thyself)         (GstObject *object, xmlNodePtr parent);
   void         (*restore_thyself)      (GstObject *object, xmlNodePtr self);
+#endif
 };
 
 #define GST_FLAGS(obj)                 (GST_OBJECT (obj)->flags)
@@ -144,11 +147,12 @@ void              gst_object_unparent             (GstObject *object);
 
 gboolean       gst_object_check_uniqueness     (GList *list, const gchar *name);
 
-#ifndef GST_DISABLE_LOADSAVE
+#ifndef GST_DISABLE_LOADSAVE_REGISTRY
 xmlNodePtr     gst_object_save_thyself         (GstObject *object, xmlNodePtr parent);
-void           gst_object_restore_thyself              (GstObject *object, xmlNodePtr parent);
+void           gst_object_restore_thyself      (GstObject *object, xmlNodePtr parent);
 #else
 #pragma GCC poison gst_object_save_thyself
+#pragma GCC poison gst_object_restore_thyself
 #endif
 
 /* refcounting */
@@ -166,7 +170,7 @@ guint               gst_class_signal_connect        (GstObjectClass *klass,
                                                 gpointer       func,
                                                 gpointer       func_data);
 
-#ifndef GST_DISABLE_LOADSAVE
+#ifndef GST_DISABLE_LOADSAVE_REGISTRY
 void           gst_class_signal_emit_by_name   (GstObject      *object,
                                                 const gchar    *name,
                                                 xmlNodePtr self);
index a21a964..c5c985d 100644 (file)
@@ -30,6 +30,7 @@
 #include "gstbin.h"
 #include "gstscheduler.h"
 
+GType _gst_pad_type = 0;
 
 /***** Start with the base GstPad class *****/
 static void            gst_pad_class_init              (GstPadClass *klass);
@@ -42,10 +43,9 @@ static xmlNodePtr    gst_pad_save_thyself            (GstObject *object, xmlNodePtr parent);
 static GstObject *pad_parent_class = NULL;
 
 GType
-gst_pad_get_type(void) {
-  static GType pad_type = 0;
-
-  if (!pad_type) {
+gst_pad_get_type(void) 
+{
+  if (!_gst_pad_type) {
     static const GTypeInfo pad_info = {
       sizeof(GstPadClass),
       NULL,
@@ -58,9 +58,9 @@ gst_pad_get_type(void) {
       (GInstanceInitFunc)gst_pad_init,
       NULL
     };
-    pad_type = g_type_register_static(GST_TYPE_OBJECT, "GstPad", &pad_info, 0);
+    _gst_pad_type = g_type_register_static(GST_TYPE_OBJECT, "GstPad", &pad_info, 0);
   }
-  return pad_type;
+  return _gst_pad_type;
 }
 
 static void
@@ -107,15 +107,14 @@ static void       gst_real_pad_dispose            (GObject *object);
 
 static void    gst_pad_push_func               (GstPad *pad, GstBuffer *buf);
 
+GType _gst_real_pad_type = 0;
 
 static GstPad *real_pad_parent_class = NULL;
 static guint gst_real_pad_signals[REAL_LAST_SIGNAL] = { 0 };
 
 GType
 gst_real_pad_get_type(void) {
-  static GType pad_type = 0;
-
-  if (!pad_type) {
+  if (!_gst_real_pad_type) {
     static const GTypeInfo pad_info = {
       sizeof(GstRealPadClass),
       NULL,
@@ -128,9 +127,9 @@ gst_real_pad_get_type(void) {
       (GInstanceInitFunc)gst_real_pad_init,
       NULL
     };
-    pad_type = g_type_register_static(GST_TYPE_PAD, "GstRealPad", &pad_info, 0);
+    _gst_real_pad_type = g_type_register_static(GST_TYPE_PAD, "GstRealPad", &pad_info, 0);
   }
-  return pad_type;
+  return _gst_real_pad_type;
 }
 
 static void
@@ -1432,7 +1431,7 @@ gst_pad_ghost_save_thyself (GstPad *pad,
 
   return self;
 }
-#endif // GST_DISABLE_LOADSAVE
+#endif /* GST_DISABLE_LOADSAVE */
 
 #ifndef gst_pad_push
 /**
@@ -1881,6 +1880,7 @@ gst_pad_get_element_private (GstPad *pad)
 
 
 /***** ghost pads *****/
+GType _gst_ghost_pad_type = 0;
 
 static void     gst_ghost_pad_class_init         (GstGhostPadClass *klass);
 static void     gst_ghost_pad_init               (GstGhostPad *pad);
@@ -1890,9 +1890,7 @@ static GstPad *ghost_pad_parent_class = NULL;
 
 GType
 gst_ghost_pad_get_type(void) {
-  static GType pad_type = 0;
-
-  if (!pad_type) {
+  if (!_gst_ghost_pad_type) {
     static const GTypeInfo pad_info = {
       sizeof(GstGhostPadClass),
       NULL,
@@ -1905,9 +1903,9 @@ gst_ghost_pad_get_type(void) {
       (GInstanceInitFunc)gst_ghost_pad_init,
       NULL
     };
-    pad_type = g_type_register_static(GST_TYPE_PAD, "GstGhostPad", &pad_info, 0);
+    _gst_ghost_pad_type = g_type_register_static(GST_TYPE_PAD, "GstGhostPad", &pad_info, 0);
   }
-  return pad_type;
+  return _gst_ghost_pad_type;
 }
 
 static void
@@ -1985,14 +1983,36 @@ gst_pad_event (GstPad *pad, GstEventType event, gint64 timestamp, guint32 data)
   GST_DEBUG(GST_CAT_EVENT, "have event %d on pad %s:%s\n",(gint)event,GST_DEBUG_PAD_NAME(pad));
 
   peer = GST_RPAD_PEER(pad);
-  if (GST_RPAD_EVENTFUNC(peer))
-    handled = GST_RPAD_EVENTFUNC(peer) (peer, event, timestamp, data);
+  if (GST_RPAD_EVENTFUNC(peer)) {
+    //handled = GST_RPAD_EVENTFUNC(peer) (peer, event, timestamp, data);
+  }
   else {
     GST_DEBUG(GST_CAT_EVENT, "there's no event function for peer %s:%s\n",GST_DEBUG_PAD_NAME(peer));
   }
 
   if (!handled) {
     GST_DEBUG(GST_CAT_EVENT, "would proceed with default behavior here\n");
-    gst_pad_event_default(peer,event, timestamp, data);
+    //gst_pad_event_default(peer,event, timestamp, data);
+  }
+}
+
+gboolean
+gst_pad_send_event (GstPad *pad, GstEvent *event)
+{
+  gboolean handled = FALSE;
+
+  GST_DEBUG (GST_CAT_EVENT, "have event %d on pad %s:%s\n",
+                 GST_EVENT_TYPE (event), GST_DEBUG_PAD_NAME (pad));
+
+  if (GST_RPAD_EVENTFUNC (pad))
+    handled = GST_RPAD_EVENTFUNC (pad) (pad, event);
+  else {
+    GST_DEBUG(GST_CAT_EVENT, "there's no event function for pad %s:%s\n", GST_DEBUG_PAD_NAME (pad));
+  }
+
+  if (!handled) {
+    GST_DEBUG(GST_CAT_EVENT, "would proceed with default behavior here\n");
+    //gst_pad_event_default (pad, event);
   }
 }
+
index cda8b22..70f0a39 100644 (file)
 #ifndef __GST_PAD_H__
 #define __GST_PAD_H__
 
-#include <parser.h> // NOTE: This is xml-config's fault
-
-// Include compatability defines: if libxml hasn't already defined these,
-// we have an old version 1.x
-#ifndef xmlChildrenNode
-#define xmlChildrenNode childs
-#define xmlRootNode root
-#endif
+#include <gst/gstconfig.h>
 
 #include <gst/gstobject.h>
 #include <gst/gstbuffer.h>
 extern "C" {
 #endif /* __cplusplus */
 
+extern GType _gst_pad_type;
+extern GType _gst_real_pad_type;
+extern GType _gst_ghost_pad_type;
+
+//#define GST_TYPE_PARANOID
+
+/* 
+ * Pad base class
+ */
+#define GST_TYPE_PAD                   (_gst_pad_type)
 
-#define GST_TYPE_PAD                   (gst_pad_get_type ())
-#define GST_PAD(obj)                   (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_PAD, GstPad))
-#define GST_PAD_CLASS(klass)           (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_PAD, GstPadClass))
+#define GST_PAD_FAST(obj)              ((GstPad*)(obj))
+#define GST_PAD_CLASS_FAST(klass)      ((GstPadClass*)(klass))
 #define GST_IS_PAD(obj)                        (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_PAD))
+#define GST_IS_PAD_FAST(obj)           (G_OBJECT_TYPE(obj) == GST_TYPE_REAL_PAD || \
+                                        G_OBJECT_TYPE(obj) == GST_TYPE_GHOST_PAD)
 #define GST_IS_PAD_CLASS(obj)          (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_PAD))
 
-#define GST_TYPE_REAL_PAD              (gst_real_pad_get_type ())
-#define GST_REAL_PAD(obj)              (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_REAL_PAD, GstRealPad))
-#define GST_REAL_PAD_CLASS(klass)      (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_REAL_PAD, GstRealPadClass))
+#ifdef GST_TYPE_PARANOID
+# define GST_PAD(obj)                  (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_PAD, GstPad))
+# define GST_PAD_CLASS(klass)          (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_PAD, GstPadClass))
+#else
+# define GST_PAD                       GST_PAD_FAST
+# define GST_PAD_CLASS                 GST_PAD_CLASS_FAST
+#endif
+
+/* 
+ * Real Pads
+ */
+#define GST_TYPE_REAL_PAD              (_gst_real_pad_type)
+
+#define GST_REAL_PAD_FAST(obj)         ((GstRealPad*)(obj))
+#define GST_REAL_PAD_CLASS_FAST(klass) ((GstRealPadClass*)(klass))
 #define GST_IS_REAL_PAD(obj)           (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_REAL_PAD))
+#define GST_IS_REAL_PAD_FAST(obj)      (G_OBJECT_TYPE(obj) == GST_TYPE_REAL_PAD)
 #define GST_IS_REAL_PAD_CLASS(obj)     (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_REAL_PAD))
 
-#define GST_TYPE_GHOST_PAD             (gst_ghost_pad_get_type ())
-#define GST_GHOST_PAD(obj)             (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_GHOST_PAD, GstGhostPad))
-#define GST_GHOST_PAD_CLASS(klass)     (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_GHOST_PAD, GstGhostPadClass))
+#ifdef GST_TYPE_PARANOID
+# define GST_REAL_PAD(obj)             (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_REAL_PAD, GstRealPad))
+# define GST_REAL_PAD_CLASS(klass)     (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_REAL_PAD, GstRealPadClass))
+#else
+# define GST_REAL_PAD                  GST_REAL_PAD_FAST
+# define GST_REAL_PAD_CLASS            GST_REAL_PAD_CLASS_FAST
+#endif
+
+/* 
+ * Ghost Pads
+ */
+#define GST_TYPE_GHOST_PAD             (_gst_ghost_pad_type)
+
+#define GST_GHOST_PAD_FAST(obj)                ((GstGhostPad*)(obj))
+#define GST_GHOST_PAD_CLASS_FAST(klass)        ((GstGhostPadClass*)(klass))
 #define GST_IS_GHOST_PAD(obj)          (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_GHOST_PAD))
+#define GST_IS_GHOST_PAD_FAST(obj)     (G_OBJECT_TYPE(obj) == GST_TYPE_GHOST_PAD)
 #define GST_IS_GHOST_PAD_CLASS(obj)    (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_GHOST_PAD))
 
+#ifdef GST_TYPE_PARANOID
+# define GST_GHOST_PAD(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_GHOST_PAD, GstGhostPad))
+# define GST_GHOST_PAD_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_GHOST_PAD, GstGhostPadClass))
+#else
+# define GST_GHOST_PAD                 GST_GHOST_PAD_FAST
+# define GST_GHOST_PAD_CLASS           GST_GHOST_PAD_CLASS_FAST
+#endif
+
 
 //typedef struct _GstPad GstPad;
 //typedef struct _GstPadClass GstPadClass;
@@ -92,7 +130,7 @@ typedef enum {
  * buf is the buffer being passed */
 typedef void           (*GstPadChainFunction)          (GstPad *pad,GstBuffer *buf);
 typedef GstBuffer*     (*GstPadGetFunction)            (GstPad *pad);
-typedef gboolean       (*GstPadEventFunction)          (GstPad *pad, GstEventType event, gint64 timestamp, guint32 data);
+typedef gboolean       (*GstPadEventFunction)          (GstPad *pad, GstEvent *event);
 
 typedef GstBuffer*     (*GstPadGetRegionFunction)      (GstPad *pad, GstRegionType type, guint64 offset, guint64 len);
 typedef GstBuffer*     (*GstPadPullRegionFunction)     (GstPad *pad, GstRegionType type, guint64 offset, guint64 len);
@@ -375,12 +413,15 @@ FALSE )
 }G_STMT_END
 #endif
 
+gboolean               gst_pad_send_event              (GstPad *pad, GstEvent *event);
 
 GstBuffer*             gst_pad_peek                    (GstPad *pad);
 GstPad*                        gst_pad_select                  (GList *padlist);
 GstPad*                        gst_pad_selectv                 (GstPad *pad, ...);
 
+#ifndef GST_DISABLE_LOADSAVE
 void                   gst_pad_load_and_connect        (xmlNodePtr self, GstObject *parent);
+#endif
 
 
 /* ghostpads */
@@ -397,8 +438,10 @@ GstPadTemplate*            gst_padtemplate_new             (gchar *name_template,
 GstCaps*               gst_padtemplate_get_caps        (GstPadTemplate *templ);
 GstCaps*               gst_padtemplate_get_caps_by_name        (GstPadTemplate *templ, const gchar *name);
 
+#ifndef GST_DISABLE_LOADSAVE
 xmlNodePtr             gst_padtemplate_save_thyself    (GstPadTemplate *templ, xmlNodePtr parent);
 GstPadTemplate*                gst_padtemplate_load_thyself    (xmlNodePtr parent);
+#endif
 
 xmlNodePtr              gst_pad_ghost_save_thyself   (GstPad *pad,
                                                      GstElement *bin,
index cf7fc1f..b7e5191 100644 (file)
@@ -299,7 +299,11 @@ gst_parse_launch_cmdline(int argc,char *argv[],GstBin *parent,gst_parse_priv *pr
         element = gst_elementfactory_make(arg,ptr);
         g_free(ptr);
         if (!element) {
+#ifndef GST_DISABLE_REGISTRY
           fprintf(stderr,"Couldn't create a '%s', no such element or need to run gstreamer-register?\n",arg);
+#else
+          fprintf(stderr,"Couldn't create a '%s', no such element or need to load pluginn?\n",arg);
+#endif
           exit(-1);
         }
         GST_DEBUG(0,"CREATED element %s\n",GST_ELEMENT_NAME(element));
index a540a77..9f1f140 100644 (file)
@@ -105,7 +105,7 @@ _gst_plugin_initialize (void)
   gst_plugin_load_thyself (doc->xmlRootNode);
 
   xmlFreeDoc (doc);
-#endif // GST_DISABLE_REGISTRY
+#endif /* GST_DISABLE_REGISTRY */
 }
 
 void
@@ -845,7 +845,7 @@ gst_plugin_load_thyself (xmlNodePtr parent)
   }
   GST_INFO (GST_CAT_PLUGIN_LOADING, "added %d features ", featurecount);
 }
-#endif // GST_DISABLE_REGISTRY
+#endif /* GST_DISABLE_REGISTRY */
 
 
 /**
index e678f58..58eb018 100644 (file)
 #ifndef __GST_PLUGIN_H__
 #define __GST_PLUGIN_H__
 
-#include <gmodule.h>
-#include <parser.h> // NOTE: this is xml-config's fault
+#include <gst/gstconfig.h>
 
-// Include compatability defines: if libxml hasn't already defined these,
-// we have an old version 1.x
-#ifndef xmlChildrenNode
-#define xmlChildrenNode childs
-#define xmlRootNode root
-#endif
+#include <gmodule.h>
 
 #include <gst/gstpluginfeature.h>
 
index 037eb30..670498d 100644 (file)
@@ -987,7 +987,7 @@ end:
   return compatible;
 }
 
-#if (! (defined(GST_DISABLE_LOADSAVE) && defined(GST_DISABLE_REGISTRY)) )
+#ifndef GST_DISABLE_LOADSAVE_REGISTRY
 static xmlNodePtr
 gst_props_save_thyself_func (GstPropsEntry *entry, xmlNodePtr parent)
 {
@@ -1242,5 +1242,5 @@ gst_props_load_thyself (xmlNodePtr parent)
 
   return props;
 }
-#endif /* (! (defined(GST_DISABLE_LOADSAVE) && defined(GST_DISABLE_REGISTRY)) ) */
+#endif /* GST_DISABLE_LOADSAVE_REGISTRY */
 
index 1d77309..9fc6dce 100644 (file)
 #ifndef __GST_PROPS_H__
 #define __GST_PROPS_H__
 
-#include <glib.h>
-#include <parser.h> // NOTE: this is xml-config's fault
-
-// Include compatability defines: if libxml hasn't already defined these,
-// we have an old version 1.x
-#ifndef xmlChildrenNode
-#define xmlChildrenNode childs
-#define xmlRootNode root
-#endif
+#include <gst/gstconfig.h>
 
+#include <glib.h>
 
 typedef struct _GstProps GstProps;
 
@@ -95,7 +88,9 @@ gulong                gst_props_get_fourcc_int        (GstProps *props, const gchar *name);
 gboolean       gst_props_get_boolean           (GstProps *props, const gchar *name);
 const gchar*   gst_props_get_string            (GstProps *props, const gchar *name);
 
+#ifndef GST_DISABLE_LOADSAVE
 xmlNodePtr     gst_props_save_thyself          (GstProps *props, xmlNodePtr parent);
 GstProps*      gst_props_load_thyself          (xmlNodePtr parent);
+#endif
 
 #endif /* __GST_PROPS_H__ */
index b24012d..fc4abe0 100644 (file)
@@ -1424,7 +1424,7 @@ GST_DEBUG(GST_CAT_SCHEDULING,"there are %d elements in this chain\n",chain->num_
         }
       } else {
         GST_INFO (GST_CAT_DATAFLOW,"NO ENABLED ELEMENTS IN CHAIN!!");
-       //eos = TRUE;
+       eos = TRUE;
       }
 
 /*                
index 322c91b..27ae96c 100644 (file)
@@ -124,16 +124,16 @@ gst_thread_class_init (GstThreadClass *klass)
   gobject_class->dispose =             gst_thread_dispose;
 
 #ifndef GST_DISABLE_LOADSAVE
-  gstobject_class->save_thyself =      gst_thread_save_thyself;
-  gstobject_class->restore_thyself =   gst_thread_restore_thyself;
+  gstobject_class->save_thyself =      GST_DEBUG_FUNCPTR (gst_thread_save_thyself);
+  gstobject_class->restore_thyself =   GST_DEBUG_FUNCPTR(gst_thread_restore_thyself);
 #endif
 
-  gstelement_class->change_state =     gst_thread_change_state;
+  gstelement_class->change_state =     GST_DEBUG_FUNCPTR (gst_thread_change_state);
 
 //  gstbin_class->schedule = gst_thread_schedule_dummy;
 
-  gobject_class->set_property = gst_thread_set_property;
-  gobject_class->get_property = gst_thread_get_property;
+  gobject_class->set_property = GST_DEBUG_FUNCPTR (gst_thread_set_property);
+  gobject_class->get_property = GST_DEBUG_FUNCPTR (gst_thread_get_property);
 
 }
 
index 820e7fc..0cfd4db 100644 (file)
@@ -28,4 +28,6 @@
 #define GST_VERSION_MINOR @GST_VERSION_MINOR@
 #define GST_VERSION_MICRO @GST_VERSION_MICRO@
 
+void    gst_version     (guint *major, guint *minor, guint *micro);
+
 #endif /* __GST_H__ */
index f3fd8d0..b66aba2 100644 (file)
 #ifndef __GST_XML_H__
 #define __GST_XML_H__
 
-#ifndef GST_DISABLE_LOADSAVE
-
-#include <parser.h>
+#include <gst/gstconfig.h>
 
-// Include compatability defines: if libxml hasn't already defined these,
-// we have an old version 1.x
-#ifndef xmlChildrenNode
-#define xmlChildrenNode childs
-#define xmlRootNode root
-#endif
+#ifndef GST_DISABLE_LOADSAVE
 
 #include <gst/gstelement.h>
 
diff --git a/gst/utils/gstbytestream.c b/gst/utils/gstbytestream.c
new file mode 100644 (file)
index 0000000..5cc3663
--- /dev/null
@@ -0,0 +1,113 @@
+/* GStreamer
+ * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
+ *                    2000 Wim Taymans <wtay@chello.be>
+ *
+ * gstbytestreams.c: Utility functions: gtk_get_property stuff, etc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * 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 <stdio.h>
+#include <string.h>
+
+#include "gstbytestreams.h"
+
+/**
+ * gst_bytestream_new:
+ * @pad: the pad to attach the bytstream to
+ *
+ * creates a bytestream from the given pad
+ *
+ * Returns: a new #GstByteStream object
+ */
+GstByteStream *
+gst_bytestream_new (GstPad * pad)
+{
+  GstByteStream *bs = g_new (GstByteStream, 1);
+
+  bs->pad = pad;
+  bs->data = NULL;
+  bs->size = 0;
+  bs->index = 0;
+
+  return bs;
+}
+
+void
+gst_bytestream_destroy (GstByteStream * bs)
+{
+  if (bs->data) {
+    g_free (bs->data);
+  }
+  g_free (bs);
+}
+
+static void
+gst_bytestream_bytes_fill (GstByteStream * bs, guint64 len)
+{
+  size_t oldlen;
+  GstBuffer *buf;
+
+  while ((bs->index + len) > bs->size) {
+    buf = gst_pad_pull (bs->pad);
+    oldlen = bs->size - bs->index;
+    memmove (bs->data, bs->data + bs->index, oldlen);
+    bs->size = oldlen + GST_BUFFER_SIZE (buf);
+    bs->index = 0;
+    bs->data = realloc (bs->data, bs->size);
+    if (!bs->data) {
+      fprintf (stderr, "realloc failed: d:%p s:%d\n", bs->data, bs->size);
+    }
+    memcpy (bs->data + oldlen, GST_BUFFER_DATA (buf), GST_BUFFER_SIZE (buf));
+  }
+  g_assert ((bs->index + len) <= bs->size);
+}
+
+guint8 *
+gst_bytestream_bytes_peek (GstByteStream * bs, guint64 len)
+{
+  g_return_val_if_fail (len > 0, NULL);
+
+  gst_bytestream_bytes_fill (bs, len);
+
+  return gst_bytestream_pos (bs);
+}
+
+guint8 *
+gst_bytestream_bytes_read (GstByteStream * bs, guint64 len)
+{
+  guint8 *ptr;
+
+  g_return_val_if_fail (len > 0, NULL);
+
+  gst_bytestream_bytes_fill (bs, len);
+  ptr = gst_bytestream_pos (bs);
+  bs->index += len;
+
+  return ptr;
+}
+
+gboolean
+gst_bytestream_bytes_seek (GstByteStream * bs, guint64 offset)
+{
+  return FALSE;
+}
+
+void
+gst_bytestream_bytes_flush (GstByteStream * bs, guint64 len)
+{
+  gst_bytestream_bytes_read (bs, len);
+}
diff --git a/gst/utils/gstbytestream.h b/gst/utils/gstbytestream.h
new file mode 100644 (file)
index 0000000..f368bb3
--- /dev/null
@@ -0,0 +1,56 @@
+/* GStreamer
+ * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
+ *                    2000 Wim Taymans <wtay@chello.be>
+ *
+ * gstbytestream.h: Header for various utility functions
+ *
+ * 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_BYTESTREAM_H__
+#define __GST_BYTESTREAM_H__
+
+#include <gst/gstpad.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+typedef struct _GstByteStream GstByteStream;
+
+struct _GstByteStream 
+{
+  GstPad *pad;
+  guint8 *data;
+  guint64 size;
+  guint64 index;
+};
+
+GstByteStream*         gst_bytestream_new              (GstPad *pad);
+void                   gst_bytestream_destroy          (GstByteStream *bs);
+
+gint                   gst_bytestream_bytes_peek       (GstByteStream *bs, guint8 **buf, guint64 len);
+gint                   gst_bytestream_bytes_read       (GstByteStream *bs, guint8 **buf, guint64 len);
+gboolean               gst_bytestream_bytes_seek       (GstByteStream *bs, guint64 offset);
+gint                   gst_bytestream_bytes_flush      (GstByteStream *bs, guint64 len);
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __GST_BYTESTREAM_H__ */
index 4c40732..42071c3 100644 (file)
@@ -402,7 +402,7 @@ gst_play_set_uri (GstPlay *play, const guchar *uri)
        }
        
        if (priv->src == NULL) {
-               priv->src = gst_elementfactory_make ("disksrc", "srcelement");
+               priv->src = gst_elementfactory_make ("filesrc", "srcelement");
        }
        
        priv->uri = g_strdup (uri);
index 0d968dc..f8a6859 100644 (file)
@@ -25,7 +25,9 @@ main (int argc, char *argv[])
                }
        }
        
+#ifndef GST_DISABLE_LOADSAVE
        xmlSaveFile ("gstmediaplay.gst", gst_xml_write (gst_play_get_pipeline (play->play)));
+#endif
        
        gdk_threads_enter();
        gst_main();
index 23bcb8a..581277f 100644 (file)
@@ -1,4 +1,3 @@
+SUBDIRS = riff getbits putbits idct audio bytestream control
 
-SUBDIRS = riff getbits putbits idct audio control
-
-DIST_SUBDIRS = riff getbits putbits audio idct control
+DIST_SUBDIRS = riff getbits putbits audio idct bytestream control
diff --git a/libs/bytestream/Makefile.am b/libs/bytestream/Makefile.am
new file mode 100644 (file)
index 0000000..0a6e8ee
--- /dev/null
@@ -0,0 +1,11 @@
+filterdir = $(libdir)/gst
+
+filter_LTLIBRARIES = libgstbytestream.la libgstbstest.la
+
+libgstbytestream_la_SOURCES = gstbytestream.c 
+libgstbstest_la_SOURCES = gstbstest.c
+
+libgstbytestreamincludedir = $(includedir)/gst/libs/bytestream
+libgstbytestreaminclude_HEADERS = gstbytestream.h
+
+# CFLAGS += -O2 $(FOMIT_FRAME_POINTER) -funroll-all-loops -finline-functions -ffast-math
diff --git a/libs/bytestream/gstbstest.c b/libs/bytestream/gstbstest.c
new file mode 100644 (file)
index 0000000..087d63a
--- /dev/null
@@ -0,0 +1,294 @@
+/* GStreamer
+ * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
+ *                    2000 Wim Taymans <wtay@chello.be>
+ *
+ * gstidentity.c: 
+ *
+ * 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/gst.h>
+#include "gstbytestream.h"
+
+#define GST_TYPE_IDENTITY \
+  (gst_identity_get_type())
+#define GST_IDENTITY(obj) \
+  (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_IDENTITY,GstIdentity))
+#define GST_IDENTITY_CLASS(klass) \
+  (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_IDENTITY,GstIdentityClass))
+#define GST_IS_IDENTITY(obj) \
+  (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_IDENTITY))
+#define GST_IS_IDENTITY_CLASS(obj) \
+  (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_IDENTITY))
+
+typedef struct _GstIdentity GstIdentity;
+typedef struct _GstIdentityClass GstIdentityClass;
+
+struct _GstIdentity {
+  GstElement element;
+
+  GstPad *sinkpad;
+  GstPad *srcpad;
+
+  GstByteStream *bs;
+  gint byte_size;
+  gint count;
+};
+
+struct _GstIdentityClass {
+  GstElementClass parent_class;
+};
+
+GType gst_identity_get_type(void);
+
+
+GstElementDetails gst_identity_details = {
+  "ByteStreamTest",
+  "Filter",
+  "Test for the GstByteStream code",
+  VERSION,
+  "Erik Walthinsen <omega@temple-baptist.com>",
+  "(C) 2001",
+};
+
+
+/* Identity signals and args */
+enum {
+  /* FILL ME */
+  LAST_SIGNAL
+};
+
+enum {
+  ARG_0,
+  ARG_BYTE_SIZE,
+  ARG_COUNT,
+};
+
+
+static void gst_identity_class_init    (GstIdentityClass *klass);
+static void gst_identity_init          (GstIdentity *identity);
+
+static void gst_identity_set_property  (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec);
+static void gst_identity_get_property  (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec);
+
+static void gst_identity_loop          (GstElement *element);
+
+static GstElementClass *parent_class = NULL;
+// static guint gst_identity_signals[LAST_SIGNAL] = { 0 };
+
+GType
+gst_identity_get_type (void) 
+{
+  static GType identity_type = 0;
+
+  if (!identity_type) {
+    static const GTypeInfo identity_info = {
+      sizeof(GstIdentityClass),      NULL,
+      NULL,
+      (GClassInitFunc)gst_identity_class_init,
+      NULL,
+      NULL,
+      sizeof(GstIdentity),
+      0,
+      (GInstanceInitFunc)gst_identity_init,
+    };
+    identity_type = g_type_register_static (GST_TYPE_ELEMENT, "GstBSTest", &identity_info, 0);
+  }
+  return identity_type;
+}
+
+static void 
+gst_identity_class_init (GstIdentityClass *klass) 
+{
+  GObjectClass *gobject_class;
+
+  gobject_class = (GObjectClass*)klass;
+
+  parent_class = g_type_class_ref (GST_TYPE_ELEMENT);
+
+  g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_BYTE_SIZE,
+    g_param_spec_uint ("byte_size", "byte_size", "byte_size",
+                       0, G_MAXUINT, 0, G_PARAM_READWRITE));
+  g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_COUNT,
+    g_param_spec_uint ("count", "count", "count",
+                       0, G_MAXUINT, 0, G_PARAM_READWRITE));
+
+  gobject_class->set_property = GST_DEBUG_FUNCPTR (gst_identity_set_property);  
+  gobject_class->get_property = GST_DEBUG_FUNCPTR (gst_identity_get_property);
+}
+
+static GstPadNegotiateReturn
+gst_identity_negotiate_src (GstPad *pad, GstCaps **caps, gpointer *data)
+{
+  GstIdentity *identity;
+
+  identity = GST_IDENTITY (gst_pad_get_parent (pad));
+
+  return gst_pad_negotiate_proxy (pad, identity->sinkpad, caps);
+}
+
+static GstPadNegotiateReturn
+gst_identity_negotiate_sink (GstPad *pad, GstCaps **caps, gpointer *data)
+{
+  GstIdentity *identity;
+
+  identity = GST_IDENTITY (gst_pad_get_parent (pad));
+
+  return gst_pad_negotiate_proxy (pad, identity->srcpad, caps);
+}
+
+static void 
+gst_identity_init (GstIdentity *identity) 
+{
+  identity->sinkpad = gst_pad_new ("sink", GST_PAD_SINK);
+  gst_element_add_pad (GST_ELEMENT (identity), identity->sinkpad);
+  gst_pad_set_negotiate_function (identity->sinkpad, gst_identity_negotiate_sink);
+  
+  identity->srcpad = gst_pad_new ("src", GST_PAD_SRC);
+  gst_element_add_pad (GST_ELEMENT (identity), identity->srcpad);
+  gst_pad_set_negotiate_function (identity->srcpad, gst_identity_negotiate_src);
+
+  gst_element_set_loop_function (GST_ELEMENT (identity), gst_identity_loop);
+
+  identity->byte_size = 384;
+  identity->count = 5;
+
+  identity->bs = gst_bytestream_new(identity->sinkpad);
+}
+
+static void 
+gst_identity_loop (GstElement *element) 
+{
+  GstIdentity *identity;
+  GstBuffer *buf;
+  int i;
+
+  g_return_if_fail (element != NULL);
+  g_return_if_fail (GST_IS_IDENTITY (element));
+
+  identity = GST_IDENTITY (element);
+
+/* THIS IS THE BUFFER BASED ONE
+  do {
+//    g_print("\n");
+
+    for (i=0;i<identity->count;i++) {
+//      g_print("bstest: getting a buffer of %d bytes\n",identity->byte_size);
+      buf = gst_bytestream_read(identity->bs,identity->byte_size);
+      if (!buf) g_print("BUFFER IS BOGUS\n");
+//      g_print("pushing the buffer, %d bytes at %d\n",GST_BUFFER_SIZE(buf),GST_BUFFER_OFFSET(buf));
+      gst_pad_push(identity->srcpad,buf);
+//      g_print("\n");
+      gst_bytestream_print_status(identity->bs);
+//      g_print("\n\n");
+    }
+
+    exit(1);
+  } while (!GST_ELEMENT_IS_COTHREAD_STOPPING(element));
+*/
+
+/* THIS IS THE BYTE BASED ONE*/
+  do {
+    for (i=0;i<identity->count;i++) {
+      buf = gst_buffer_new();
+      // note that this is dangerous, as it does *NOT* refcount the data, it can go away!!!
+      GST_BUFFER_DATA(buf) = gst_bytestream_peek_bytes(identity->bs,identity->byte_size);
+      GST_BUFFER_SIZE(buf) = identity->byte_size;
+      GST_BUFFER_FLAG_SET(buf,GST_BUFFER_DONTFREE);
+      gst_pad_push(identity->srcpad,buf);
+      gst_bytestream_flush(identity->bs,identity->byte_size);
+    }
+
+    exit(1);
+  } while (!GST_ELEMENT_IS_COTHREAD_STOPPING(element));
+/**/
+}
+
+static void 
+gst_identity_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) 
+{
+  GstIdentity *identity;
+
+  /* it's not null if we got it, but it might not be ours */
+  g_return_if_fail (GST_IS_IDENTITY (object));
+  
+  identity = GST_IDENTITY (object);
+
+  switch (prop_id) {
+    case ARG_BYTE_SIZE:
+      identity->byte_size = g_value_get_uint (value);
+      break;
+    case ARG_COUNT:
+      identity->count = g_value_get_uint (value);
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+  }
+}
+
+static void gst_identity_get_property(GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) {
+  GstIdentity *identity;
+
+  /* it's not null if we got it, but it might not be ours */
+  g_return_if_fail (GST_IS_IDENTITY (object));
+  
+  identity = GST_IDENTITY (object);
+
+  switch (prop_id) {
+    case ARG_BYTE_SIZE:
+      g_value_set_uint (value, identity->byte_size);
+      break;
+    case ARG_COUNT:
+      g_value_set_uint (value, identity->count);
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+  }
+}
+
+static gboolean
+plugin_init (GModule *module, GstPlugin *plugin)
+{
+  GstElementFactory *factory;
+
+  // we need gstbytestream
+  if (!gst_library_load ("gstbytestream")) {
+    g_print("can't load bytestream\n");
+    return FALSE;
+  }
+  
+  /* We need to create an ElementFactory for each element we provide.
+   * This consists of the name of the element, the GType identifier,
+   * and a pointer to the details structure at the top of the file.
+   */
+  factory = gst_elementfactory_new("gstbstest", GST_TYPE_IDENTITY, &gst_identity_details);
+  g_return_val_if_fail(factory != NULL, FALSE);
+
+  /* The very last thing is to register the elementfactory with the plugin. */
+  gst_plugin_add_feature (plugin, GST_PLUGIN_FEATURE (factory));
+  return TRUE;
+}
+
+GstPluginDesc plugin_desc = {
+  GST_VERSION_MAJOR,
+  GST_VERSION_MINOR,
+  "gstbstest",
+  plugin_init
+};
+
diff --git a/libs/bytestream/gstbytestream.c b/libs/bytestream/gstbytestream.c
new file mode 100644 (file)
index 0000000..6f4d18a
--- /dev/null
@@ -0,0 +1,394 @@
+/* GStreamer
+ * Copyright (C) 2001 Erik Walthinsen <omega@temple-baptist.com>
+ *
+ * gstbytestream.c: adds a convenient bytestream based API to a pad.
+ *
+ * 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 <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include <gst/gstinfo.h>
+#include "gstbytestream.h"
+
+//#define BS_DEBUG
+
+#ifdef BS_DEBUG
+# define bs_print(format,args...)      GST_DEBUG (GST_CAT_BUFFER,  format, ## args)
+# define bs_status(bs)                 gst_bytestream_print_status(bs)
+#else
+# define bs_print(format,args...)
+# define bs_status(bs)
+#endif
+
+guint8 *gst_bytestream_assemble (GstByteStream * bs, guint32 len);
+
+/**
+ * gst_bytestream_new:
+ * @pad: the pad to attach the bytestream to
+ *
+ * creates a bytestream from the given pad
+ *
+ * Returns: a new #GstByteStream object
+ */
+GstByteStream *
+gst_bytestream_new (GstPad * pad)
+{
+  GstByteStream *bs = g_new (GstByteStream, 1);
+
+  bs->pad = pad;
+
+  bs->buflist = NULL;
+  bs->headbufavail = 0;
+  bs->listavail = 0;
+  bs->assembled = NULL;
+
+  return bs;
+}
+
+void
+gst_bytestream_destroy (GstByteStream * bs)
+{
+  GSList *walk;
+
+  walk = bs->buflist;
+  while (walk) {
+    gst_buffer_unref (GST_BUFFER (walk->data));
+    walk = g_slist_next (walk);
+  }
+  g_slist_free (bs->buflist);
+  if (bs->assembled)
+    g_free (bs->assembled);
+  g_free (bs);
+}
+
+// HOW THIS WORKS:
+//
+// The fundamental structure is a singly-linked list of buffers.  The
+// buffer on the front is the oldest, and thus the first to read data
+// from.  The number of bytes left to be read in this buffer is stored
+// in bs->headbufavail.  The number of bytes available in the entire
+// list (including the head buffer) is in bs->listavail.
+//
+// When a request is made for data (peek), _fill_bytes is called with
+// the number of bytes needed, but only if the listavail indicates
+// that there aren't already enough.  This calls _get_next_buf until
+// the listavail is sufficient to satisfy the demand.
+//
+// _get_next_buf pulls a buffer from the pad the bytestream is attached
+// to, and shoves it in the list.  There are actually two things it can
+// do.  If there's already a buffer in the list, and the _is_span_fast()
+// test returns true, it will merge it with that last buffer.  Otherwise
+// it will simply tack it onto the end of the list.
+//
+// The _peek itself first checks the simple case of the request fitting
+// within the head buffer, and if so creates a subbuffer and returns.
+// Otherwise, it creates a new buffer and allocates space for the request
+// and calls _assemble to fill it.  We know we have to copy because this
+// case only happens when the _merge wasn't feasible during _get_next_buf.
+//
+// The _flush method repeatedly inspects the head buffer and flushes as
+// much data from it as it needs to, up to the size of the buffer.  If
+// the flush decimates the buffer, it's stripped, unref'd, and removed.
+
+
+// get the next buffer
+// if the buffer can be merged with the head buffer, do so
+// else add it onto the head of the 
+static gboolean
+gst_bytestream_get_next_buf (GstByteStream * bs)
+{
+  GstBuffer *nextbuf, *lastbuf;
+  GSList *end;
+
+  bs_print ("get_next_buf: pulling buffer\n");
+  nextbuf = gst_pad_pull (bs->pad);
+  bs_print ("get_next_buf: got buffer of %d bytes\n", GST_BUFFER_SIZE (nextbuf));
+
+  // first see if there are any buffers in the list at all
+  if (bs->buflist) {
+    bs_print ("gst_next_buf: there is at least one buffer in the list\n");
+    // now find the end of the list
+    end = g_slist_last (bs->buflist);
+    // get the buffer that's there
+    lastbuf = GST_BUFFER (end->data);
+
+    // see if we can marge cheaply
+    if (gst_buffer_is_span_fast (lastbuf, nextbuf)) {
+      bs_print ("get_next_buf: merging new buffer with last buf on list\n");
+      // it is, let's merge them (this is really an append, but...)
+      end->data = gst_buffer_merge (lastbuf, nextbuf);
+      // add to the length of the list
+      bs->listavail += GST_BUFFER_SIZE (nextbuf);
+
+      // have to check to see if we merged with the head buffer
+      if (end == bs->buflist) {
+       bs->headbufavail += GST_BUFFER_SIZE (nextbuf);
+      }
+
+      gst_buffer_unref (lastbuf);
+      gst_buffer_unref (nextbuf);
+
+      // if we can't, we just append this buffer
+    }
+    else {
+      bs_print ("get_next_buf: adding new buffer to the end of the list\n");
+      end = g_slist_append (end, nextbuf);
+      // also need to increment length of list and buffer count
+      bs->listavail += GST_BUFFER_SIZE (nextbuf);
+    }
+
+    // if there are no buffers in the list
+  }
+  else {
+    bs_print ("get_next_buf: buflist is empty, adding new buffer to list\n");
+    // put this on the end of the list
+    bs->buflist = g_slist_append (bs->buflist, nextbuf);
+    // and increment the number of bytes in the list
+    bs->listavail = GST_BUFFER_SIZE (nextbuf);
+    // set the head buffer avail to the size
+    bs->headbufavail = GST_BUFFER_SIZE (nextbuf);
+  }
+
+  return TRUE;
+}
+
+
+static gboolean
+gst_bytestream_fill_bytes (GstByteStream * bs, guint32 len)
+{
+  // as long as we don't have enough, we get more buffers
+  while (bs->listavail < len) {
+    bs_print ("fill_bytes: there are %d bytes in the list, we need %d\n", bs->listavail, len);
+    gst_bytestream_get_next_buf (bs);
+  }
+
+  return TRUE;
+}
+
+
+GstBuffer *
+gst_bytestream_peek (GstByteStream * bs, guint32 len)
+{
+  GstBuffer *headbuf, *retbuf = NULL;
+
+  g_return_val_if_fail (bs != NULL, NULL);
+  g_return_val_if_fail (len > 0, NULL);
+
+  bs_print ("peek: asking for %d bytes\n", len);
+
+  // make sure we have enough
+  bs_print ("peek: there are %d bytes in the list\n", bs->listavail);
+  if (len > bs->listavail) {
+    gst_bytestream_fill_bytes (bs, len);
+    bs_print ("peek: there are now %d bytes in the list\n", bs->listavail);
+  }
+  bs_status (bs);
+
+  // extract the head buffer
+  headbuf = GST_BUFFER (bs->buflist->data);
+
+  // if the requested bytes are in the current buffer
+  bs_print ("peek: headbufavail is %d\n", bs->headbufavail);
+  if (len <= bs->headbufavail) {
+    bs_print ("peek: there are enough bytes in headbuf (need %d, have %d)\n", len, bs->headbufavail);
+    // create a sub-buffer of the headbuf
+    retbuf = gst_buffer_create_sub (headbuf, GST_BUFFER_SIZE (headbuf) - bs->headbufavail, len);
+
+    // otherwise we need to figure out how to assemble one
+  }
+  else {
+    bs_print ("peek: current buffer is not big enough for len %d\n", len);
+
+    retbuf = gst_buffer_new ();
+    GST_BUFFER_SIZE (retbuf) = len;
+    GST_BUFFER_DATA (retbuf) = gst_bytestream_assemble (bs, len);
+    if (GST_BUFFER_OFFSET (headbuf) != -1)
+      GST_BUFFER_OFFSET (retbuf) = GST_BUFFER_OFFSET (headbuf) + (GST_BUFFER_SIZE (headbuf) - bs->headbufavail);
+  }
+
+  return retbuf;
+}
+
+guint8 *
+gst_bytestream_peek_bytes (GstByteStream * bs, guint32 len)
+{
+  GstBuffer *headbuf;
+  guint8 *data = NULL;
+
+  g_return_val_if_fail (bs != NULL, NULL);
+  g_return_val_if_fail (len > 0, NULL);
+
+  bs_print ("peek_bytes: asking for %d bytes\n", len);
+  if (bs->assembled) {
+    g_free (bs->assembled);
+    bs->assembled = NULL;
+  }
+
+  // make sure we have enough
+  bs_print ("peek_bytes: there are %d bytes in the list\n", bs->listavail);
+  if (len > bs->listavail) {
+    gst_bytestream_fill_bytes (bs, len);
+    bs_print ("peek_bytes: there are now %d bytes in the list\n", bs->listavail);
+  }
+  bs_status (bs);
+
+  // extract the head buffer
+  headbuf = GST_BUFFER (bs->buflist->data);
+
+  // if the requested bytes are in the current buffer
+  bs_print ("peek_bytes: headbufavail is %d\n", bs->headbufavail);
+  if (len <= bs->headbufavail) {
+    bs_print ("peek_bytes: there are enough bytes in headbuf (need %d, have %d)\n", len, bs->headbufavail);
+    // create a sub-buffer of the headbuf
+    data = GST_BUFFER_DATA (headbuf) + (GST_BUFFER_SIZE (headbuf) - bs->headbufavail);
+
+    // otherwise we need to figure out how to assemble one
+  }
+  else {
+    bs_print ("peek_bytes: current buffer is not big enough for len %d\n", len);
+
+    data = gst_bytestream_assemble (bs, len);
+    bs->assembled = data;
+    bs->assembled_len = len;
+  }
+
+  return data;
+}
+
+guint8 *
+gst_bytestream_assemble (GstByteStream * bs, guint32 len)
+{
+  guint8 *data = g_malloc (len);
+  GSList *walk;
+  guint32 copied = 0;
+  GstBuffer *buf;
+
+  // copy the data from the curbuf
+  buf = GST_BUFFER (bs->buflist->data);
+  bs_print ("assemble: copying %d bytes from curbuf at %d to *data\n", bs->headbufavail,
+           GST_BUFFER_SIZE (buf) - bs->headbufavail);
+  memcpy (data, GST_BUFFER_DATA (buf) + GST_BUFFER_SIZE (buf) - bs->headbufavail, bs->headbufavail);
+  copied += bs->headbufavail;
+
+  // asumption is made that the buffers all exist in the list
+  walk = g_slist_next (bs->buflist);
+  while (copied < len) {
+    buf = GST_BUFFER (walk->data);
+    if (GST_BUFFER_SIZE (buf) < (len - copied)) {
+      bs_print ("assemble: copying %d bytes from buf to output offset %d\n", GST_BUFFER_SIZE (buf), copied);
+      memcpy (data + copied, GST_BUFFER_DATA (buf), GST_BUFFER_SIZE (buf));
+      copied += GST_BUFFER_SIZE (buf);
+    }
+    else {
+      bs_print ("assemble: copying %d bytes from buf to output offset %d\n", len - copied, copied);
+      memcpy (data + copied, GST_BUFFER_DATA (buf), len - copied);
+      copied = len;
+    }
+    walk = g_slist_next (walk);
+  }
+
+  return data;
+}
+
+gboolean
+gst_bytestream_flush (GstByteStream * bs, guint32 len)
+{
+  GstBuffer *headbuf;
+
+  bs_print ("flush: flushing %d bytes\n", len);
+  if (bs->assembled) {
+    g_free (bs->assembled);
+    bs->assembled = NULL;
+  }
+
+  // make sure we have enough
+  bs_print ("flush: there are %d bytes in the list\n", bs->listavail);
+  if (len > bs->listavail) {
+    gst_bytestream_fill_bytes (bs, len);
+    bs_print ("flush: there are now %d bytes in the list\n", bs->listavail);
+  }
+
+  // repeat until we've flushed enough data
+  while (len > 0) {
+    headbuf = GST_BUFFER (bs->buflist->data);
+
+    bs_print ("flush: analyzing buffer that's %d bytes long, offset %d\n", GST_BUFFER_SIZE (headbuf),
+             GST_BUFFER_OFFSET (headbuf));
+
+    // if there's enough to complete the flush
+    if (bs->headbufavail > len) {
+      // just trim it off
+      bs_print ("flush: trimming %d bytes off end of headbuf\n", len);
+      bs->headbufavail -= len;
+      bs->listavail -= len;
+      len = 0;
+
+      // otherwise we have to trim the whole buffer
+    }
+    else {
+      bs_print ("flush: removing head buffer completely\n");
+      // remove it from the list
+      bs->buflist = g_slist_delete_link (bs->buflist, bs->buflist);
+      // trim it from the avail size
+      bs->listavail -= bs->headbufavail;
+      // record that we've trimmed this many bytes
+      len -= bs->headbufavail;
+      // unref it
+      gst_buffer_unref (headbuf);
+
+      // record the new headbufavail
+      if (bs->buflist) {
+       bs->headbufavail = GST_BUFFER_SIZE (GST_BUFFER (bs->buflist->data));
+       bs_print ("flush: next headbuf is %d bytes\n", bs->headbufavail);
+      }
+      else {
+       bs_print ("flush: no more bytes at all\n");
+      }
+    }
+
+    bs_print ("flush: bottom of while(), len is now %d\n", len);
+  }
+
+  return TRUE;
+}
+
+GstBuffer *
+gst_bytestream_read (GstByteStream * bs, guint32 len)
+{
+  GstBuffer *buf = gst_bytestream_peek (bs, len);
+  gst_bytestream_flush (bs, len);
+  return buf;
+}
+
+void
+gst_bytestream_print_status (GstByteStream * bs)
+{
+  GSList *walk;
+  GstBuffer *buf;
+
+  bs_print ("STATUS: head buffer has %d bytes available\n", bs->headbufavail);
+  bs_print ("STATUS: list has %d bytes available\n", bs->listavail);
+  walk = bs->buflist;
+  while (walk) {
+    buf = GST_BUFFER (walk->data);
+    walk = g_slist_next (walk);
+
+    bs_print ("STATUS: buffer starts at %d and is %d bytes long\n", GST_BUFFER_OFFSET (buf), GST_BUFFER_SIZE (buf));
+  }
+}
diff --git a/libs/bytestream/gstbytestream.h b/libs/bytestream/gstbytestream.h
new file mode 100644 (file)
index 0000000..fd01a97
--- /dev/null
@@ -0,0 +1,53 @@
+/* GStreamer
+ * Copyright (C) 2001 Erik Walthinsen <omega@temple-baptist.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.
+ */
+
+#ifndef __GST_BYTESTREAM_H__
+#define __GST_BYTESTREAM_H__
+
+#include <gst/gstpad.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+typedef struct _GstByteStream GstByteStream;
+
+struct _GstByteStream {
+  GstPad *pad;
+
+  GSList       *buflist;
+  guint32      headbufavail;
+  guint32      listavail;
+
+  // we keep state of assembled pieces
+  guint8       *assembled;
+  guint32      assembled_len;
+};
+
+GstByteStream*         gst_bytestream_new              (GstPad *pad);
+void                   gst_bytestream_destroy          (GstByteStream *bs);
+
+GstBuffer*             gst_bytestream_read             (GstByteStream *bs, guint32 len);
+GstBuffer*             gst_bytestream_peek             (GstByteStream *bs, guint32 len);
+guint8*                        gst_bytestream_peek_bytes       (GstByteStream *bs, guint32 len);
+gboolean               gst_bytestream_flush            (GstByteStream *bs, guint32 len);
+
+void                   gst_bytestream_print_status     (GstByteStream *bs);
+
+#endif /* __GST_BYTESTREAM_H__ */
index 61c5ad7..f50e4f7 100644 (file)
@@ -8,6 +8,8 @@ else
 GSTHTTPSRC=
 endif
 
+#CFLAGS += -O2 -Wall -finstrument-functions -DGST_ENABLE_FUNC_INSTRUMENTATION
+
 libgstelements_la_DEPENDENCIES = ../libgst.la
 libgstelements_la_SOURCES =    \
        gstelements.c           \
@@ -37,8 +39,10 @@ noinst_HEADERS =             \
        gstfdsink.h             \
        gstpipefilter.h         \
        gsttee.h                \
-       gstaggregator.h
-CFLAGS += -O2 -Wall
+       gstaggregator.h         \
+       gstsinesrc.h
+
+CFLAGS += -O2 -Wall 
 LDFLAGS += -lm
 
 libgstelements_la_LIBADD = $(GHTTP_LIBS)
index eb6c301..49ec28f 100644 (file)
@@ -76,7 +76,8 @@ gst_aggregator_sched_get_type (void)
 static void    gst_aggregator_class_init       (GstAggregatorClass *klass);
 static void    gst_aggregator_init             (GstAggregator *aggregator);
 
-static GstPad*         gst_aggregator_request_new_pad  (GstElement *element, GstPadTemplate *temp);
+static GstPad*         gst_aggregator_request_new_pad  (GstElement *element, GstPadTemplate *temp, const
+                                                 gchar *unused);
 
 static void    gst_aggregator_set_property     (GObject *object, guint prop_id, 
                                                 const GValue *value, GParamSpec *pspec);
@@ -150,7 +151,7 @@ gst_aggregator_init (GstAggregator *aggregator)
 }
 
 static GstPad*
-gst_aggregator_request_new_pad (GstElement *element, GstPadTemplate *templ) 
+gst_aggregator_request_new_pad (GstElement *element, GstPadTemplate *templ, const gchar *unused
 {
   gchar *name;
   GstPad *sinkpad;
index ab13968..ffe1b35 100644 (file)
@@ -64,8 +64,8 @@ static void           gst_disksrc_set_property        (GObject *object, guint prop_id,
 static void            gst_disksrc_get_property        (GObject *object, guint prop_id, 
                                                         GValue *value, GParamSpec *pspec);
 
-static GstBuffer *     gst_disksrc_get                 (GstPad *pad);
-static GstBuffer *     gst_disksrc_get_region          (GstPad *pad,GstRegionType type,guint64 offset,guint64 len);
+static GstBuffer     gst_disksrc_get                 (GstPad *pad);
+static GstBufferPool*  gst_disksrc_get_bufferpool      (GstPad *pad);
 
 static GstElementStateReturn   
                        gst_disksrc_change_state        (GstElement *element);
@@ -73,7 +73,7 @@ static GstElementStateReturn
 static gboolean                gst_disksrc_open_file           (GstDiskSrc *src);
 static void            gst_disksrc_close_file          (GstDiskSrc *src);
 
-static GstElementClass *parent_class = NULL;
+static GstElementClassparent_class = NULL;
 //static guint gst_disksrc_signals[LAST_SIGNAL] = { 0 };
 
 GType
@@ -133,8 +133,8 @@ gst_disksrc_init (GstDiskSrc *disksrc)
 //  GST_FLAG_SET (disksrc, GST_SRC_);
 
   disksrc->srcpad = gst_pad_new ("src", GST_PAD_SRC);
-  gst_pad_set_get_function (disksrc->srcpad,gst_disksrc_get);
-  gst_pad_set_getregion_function (disksrc->srcpad,gst_disksrc_get_region);
+  gst_pad_set_get_function (disksrc->srcpad, gst_disksrc_get);
+  gst_pad_set_bufferpool_function (disksrc->srcpad, gst_disksrc_get_bufferpool);
   gst_element_add_pad (GST_ELEMENT (disksrc), disksrc->srcpad);
 
   disksrc->filename = NULL;
@@ -220,121 +220,98 @@ gst_disksrc_get_property (GObject *object, guint prop_id, GValue *value, GParamS
   }
 }
 
-/**
- * gst_disksrc_get:
- * @pad: #GstPad to push a buffer from
- *
- * Push a new buffer from the disksrc at the current offset.
- */
-static GstBuffer *
-gst_disksrc_get (GstPad *pad)
+static GstBuffer*
+gst_disksrc_buffer_new (GstBufferPool *pool, gint64 location, gint size, gpointer user_data)
 {
   GstDiskSrc *src;
   GstBuffer *buf;
 
-  g_return_val_if_fail (pad != NULL, NULL);
-  src = GST_DISKSRC (gst_pad_get_parent (pad));
-  g_return_val_if_fail (GST_FLAG_IS_SET (src, GST_DISKSRC_OPEN), NULL);
-
-
-  /* deal with EOF state */
-  if (src->curoffset >= src->size) {
-    GST_DEBUG (0,"map offset %ld >= size %ld --> eos\n", src->curoffset, src->size);
-    gst_pad_event(pad, GST_EVENT_EOS, 0LL, 0);
-    buf =  gst_buffer_new();
-    GST_BUFFER_FLAG_SET (buf, GST_BUFFER_EOS);
-    return buf;
-  }
+  src = GST_DISKSRC (user_data);
 
-  /* create the buffer */
-  // FIXME: should eventually use a bufferpool for this
   buf = gst_buffer_new ();
-
   g_return_val_if_fail (buf != NULL, NULL);
 
   /* simply set the buffer to point to the correct region of the file */
-  GST_BUFFER_DATA (buf) = src->map + src->curoffset;
-  GST_BUFFER_OFFSET (buf) = src->curoffset;
+  GST_BUFFER_DATA (buf) = src->map + location;
+  GST_BUFFER_OFFSET (buf) = location;
   GST_BUFFER_FLAG_SET (buf, GST_BUFFER_DONTFREE);
 
-  if ((src->curoffset + src->bytes_per_read) > src->size) {
-    GST_BUFFER_SIZE (buf) = src->size - src->curoffset;
-    // FIXME: set the buffer's EOF bit here
-  } else
-    GST_BUFFER_SIZE (buf) = src->bytes_per_read;
+  if ((location + size) > src->size) 
+    GST_BUFFER_SIZE (buf) = src->size - location;
+  else
+    GST_BUFFER_SIZE (buf) = size;
 
   GST_DEBUG (0,"map %p, offset %ld (%p), size %d\n", src->map, src->curoffset,
              src->map + src->curoffset, GST_BUFFER_SIZE (buf));
 
-  //gst_util_dump_mem (GST_BUFFER_DATA (buf), GST_BUFFER_SIZE (buf));
+  return buf;
+}
 
-  src->curoffset += GST_BUFFER_SIZE (buf);
+static void
+gst_disksrc_buffer_free (GstBuffer *buf)
+{
+  // FIXME do something here
+}
 
-  if (src->new_seek) {
-    GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLUSH);
-    GST_DEBUG (0,"new seek\n");
-    src->new_seek = FALSE;
+static GstBufferPool*
+gst_disksrc_get_bufferpool (GstPad *pad)
+{
+  GstDiskSrc *src;
+  
+  src = GST_DISKSRC (gst_pad_get_parent (pad));
+
+  if (!src->bufferpool) {
+    src->bufferpool = gst_buffer_pool_new ();
+    gst_buffer_pool_set_buffer_new_function    (src->bufferpool, gst_disksrc_buffer_new);
+    gst_buffer_pool_set_buffer_free_function   (src->bufferpool, gst_disksrc_buffer_free);
+    gst_buffer_pool_set_user_data              (src->bufferpool, src);
   }
 
-  /* we're done, return the buffer */
-  return buf;
+  return src->bufferpool;
 }
 
 /**
- * gst_disksrc_get_region:
- * @src: #GstSrc to push a buffer from
- * @offset: offset in file
- * @size: number of bytes
+ * gst_disksrc_get:
+ * @pad: #GstPad to push a buffer from
  *
- * Push a new buffer from the disksrc of given size at given offset.
+ * Push a new buffer from the disksrc at the current offset.
  */
 static GstBuffer *
-gst_disksrc_get_region (GstPad *pad, GstRegionType type,guint64 offset,guint64 len)
+gst_disksrc_get (GstPad *pad)
 {
   GstDiskSrc *src;
   GstBuffer *buf;
 
   g_return_val_if_fail (pad != NULL, NULL);
-  g_return_val_if_fail (type == GST_REGION_OFFSET_LEN, NULL);
-
   src = GST_DISKSRC (gst_pad_get_parent (pad));
-
-  g_return_val_if_fail (GST_IS_DISKSRC (src), NULL);
   g_return_val_if_fail (GST_FLAG_IS_SET (src, GST_DISKSRC_OPEN), NULL);
 
+
   /* deal with EOF state */
-  if (offset >= src->size) {
-    gst_pad_event (pad, GST_EVENT_EOS, 0LL, 0);
-    GST_DEBUG (0,"map offset %lld >= size %ld --> eos\n", offset, src->size);
-    //FIXME
+  if (src->curoffset >= src->size) {
+    GST_DEBUG (0,"map offset %ld >= size %ld --> eos\n", src->curoffset, src->size);
+    gst_pad_event(pad, GST_EVENT_EOS, 0LL, 0);
     buf =  gst_buffer_new();
     GST_BUFFER_FLAG_SET (buf, GST_BUFFER_EOS);
     return buf;
   }
 
-  /* create the buffer */
-  // FIXME: should eventually use a bufferpool for this
-  buf = gst_buffer_new ();
-  g_return_val_if_fail (buf != NULL, NULL);
-
-  /* simply set the buffer to point to the correct region of the file */
-  GST_BUFFER_DATA (buf) = src->map + offset;
-  GST_BUFFER_OFFSET (buf) = offset;
-  GST_BUFFER_FLAG_SET (buf, GST_BUFFER_DONTFREE);
+  // FIXME use a bufferpool
+  buf = gst_disksrc_buffer_new (NULL, src->curoffset, src->bytes_per_read, src);
 
-  if ((offset + len) > src->size) {
-    GST_BUFFER_SIZE (buf) = src->size - offset;
-    // FIXME: set the buffer's EOF bit here
-  } else
-    GST_BUFFER_SIZE (buf) = len;
+  //gst_util_dump_mem (GST_BUFFER_DATA (buf), GST_BUFFER_SIZE (buf));
+  src->curoffset += GST_BUFFER_SIZE (buf);
 
-  GST_DEBUG (0,"map %p, offset %lld, size %d\n", src->map, offset, GST_BUFFER_SIZE (buf));
+  if (src->new_seek) {
+    GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLUSH);
+    GST_DEBUG (0,"new seek\n");
+    src->new_seek = FALSE;
+  }
 
-  /* we're done, return the buffer off now */
+  /* we're done, return the buffer */
   return buf;
 }
 
-
 /* open the file and mmap it, necessary to go to READY state */
 static gboolean 
 gst_disksrc_open_file (GstDiskSrc *src)
index 155a362..4591254 100644 (file)
@@ -64,6 +64,7 @@ struct _GstDiskSrc {
   gchar *filename;
   /* fd */
   gint fd;
+  GstBufferPool *bufferpool;
 
   /* mapping parameters */
   gulong size;                         /* how long is the file? */
index 11eac00..02eb921 100644 (file)
@@ -45,6 +45,7 @@ enum {
   ARG_0,
   ARG_NUM_SINKS,
   ARG_SILENT,
+  ARG_DUMP,
 };
 
 GST_PADTEMPLATE_FACTORY (fakesink_sink_factory,
@@ -58,7 +59,8 @@ GST_PADTEMPLATE_FACTORY (fakesink_sink_factory,
 static void    gst_fakesink_class_init         (GstFakeSinkClass *klass);
 static void    gst_fakesink_init               (GstFakeSink *fakesink);
 
-static GstPad*         gst_fakesink_request_new_pad    (GstElement *element, GstPadTemplate *templ);
+static GstPad*         gst_fakesink_request_new_pad    (GstElement *element, GstPadTemplate *templ, const
+                                                 gchar *unused);
 
 static void    gst_fakesink_set_property       (GObject *object, guint prop_id, 
                                                 const GValue *value, GParamSpec *pspec);
@@ -66,7 +68,6 @@ static void   gst_fakesink_get_property       (GObject *object, guint prop_id,
                                                 GValue *value, GParamSpec *pspec);
 
 static void    gst_fakesink_chain              (GstPad *pad, GstBuffer *buf);
-static gboolean        gst_fakesink_event              (GstPad *pad, GstEventType event, guint64 timestamp, guint32 data);
 
 static GstElementClass *parent_class = NULL;
 static guint gst_fakesink_signals[LAST_SIGNAL] = { 0 };
@@ -109,6 +110,9 @@ gst_fakesink_class_init (GstFakeSinkClass *klass)
   g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_SILENT,
     g_param_spec_boolean ("silent", "silent", "silent",
                           FALSE, G_PARAM_READWRITE)); 
+  g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_DUMP,
+    g_param_spec_boolean ("dump", "dump", "dump",
+                          FALSE, G_PARAM_READWRITE)); 
 
   gst_fakesink_signals[SIGNAL_HANDOFF] =
     g_signal_new ("handoff", G_TYPE_FROM_CLASS(klass), G_SIGNAL_RUN_LAST,
@@ -129,15 +133,15 @@ gst_fakesink_init (GstFakeSink *fakesink)
   pad = gst_pad_new ("sink", GST_PAD_SINK);
   gst_element_add_pad (GST_ELEMENT (fakesink), pad);
   gst_pad_set_chain_function (pad, GST_DEBUG_FUNCPTR (gst_fakesink_chain));
-  gst_pad_set_event_function (pad, GST_DEBUG_FUNCPTR (gst_fakesink_event));
 
   fakesink->sinkpads = g_slist_prepend (NULL, pad);
   fakesink->numsinkpads = 1;
   fakesink->silent = FALSE;
+  fakesink->dump = FALSE;
 }
 
 static GstPad*
-gst_fakesink_request_new_pad (GstElement *element, GstPadTemplate *templ)
+gst_fakesink_request_new_pad (GstElement *element, GstPadTemplate *templ, const gchar *unused)
 {
   gchar *name;
   GstPad *sinkpad;
@@ -175,6 +179,9 @@ gst_fakesink_set_property (GObject *object, guint prop_id, const GValue *value,
     case ARG_SILENT:
       sink->silent = g_value_get_boolean (value);
       break;
+    case ARG_DUMP:
+      sink->dump = g_value_get_boolean (value);
+      break;
     default:
       break;
   }
@@ -197,6 +204,9 @@ gst_fakesink_get_property (GObject *object, guint prop_id, GValue *value, GParam
     case ARG_SILENT:
       g_value_set_boolean (value, sink->silent);
       break;
+    case ARG_DUMP:
+      g_value_set_boolean (value, sink->dump);
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -206,9 +216,9 @@ gst_fakesink_get_property (GObject *object, guint prop_id, GValue *value, GParam
 /**
  * gst_fakesink_chain:
  * @pad: the pad this faksink is connected to
- * @buf: the buffer that has to be absorbed
+ * @buffer: the buffer or event that has to be absorbed
  *
- * take the buffer from the pad and unref it without doing
+ * Take the buffer or event from the pad and unref it without doing
  * anything with it.
  */
 static void 
@@ -221,12 +231,33 @@ gst_fakesink_chain (GstPad *pad, GstBuffer *buf)
   g_return_if_fail (buf != NULL);
 
   fakesink = GST_FAKESINK (gst_pad_get_parent (pad));
+
+  if (GST_IS_EVENT(buf)) {
+    GstEvent *event = GST_EVENT (buf);
+
+    switch (GST_EVENT_TYPE (event)) {
+      case GST_EVENT_EOS:
+        g_print("fakesink: have EOS event!\n");
+        gst_element_set_state (GST_ELEMENT (fakesink), GST_STATE_PAUSED);
+       break;
+      default:
+        g_print("fakesink: have unhandled event!\n");
+       break;
+    }
+    gst_event_free (event);
+    return;
+  }
+
   if (!fakesink->silent)
-    g_print("fakesink: chain   ******* (%s:%s)< (%d bytes, %lld) \n",
-                   GST_DEBUG_PAD_NAME (pad), GST_BUFFER_SIZE (buf), GST_BUFFER_TIMESTAMP (buf));
-  
-  g_signal_emit (G_OBJECT (fakesink), gst_fakesink_signals[SIGNAL_HANDOFF], 0,
-                   buf);
+    g_print("fakesink: chain   ******* (%s:%s)< (%d bytes, %lld) %p\n",
+               GST_DEBUG_PAD_NAME (pad), GST_BUFFER_SIZE (buf), GST_BUFFER_TIMESTAMP (buf), buf);
+
+  g_signal_emit (G_OBJECT (fakesink), gst_fakesink_signals[SIGNAL_HANDOFF], 0, buf, pad);
+
+  if (fakesink->dump)
+  {
+    gst_util_dump_mem (GST_BUFFER_DATA (buf), GST_BUFFER_SIZE (buf));
+  }
 
   gst_buffer_unref (buf);
 }
@@ -238,14 +269,3 @@ gst_fakesink_factory_init (GstElementFactory *factory)
 
   return TRUE;
 }
-
-
-
-static gboolean
-gst_fakesink_event (GstPad *pad, GstEventType event, guint64 timestamp, guint32 data)
-{
-  GST_DEBUG (GST_CAT_EVENT, "fakesink has event %d on pad %s:%s\n",event,GST_DEBUG_PAD_NAME(pad));
-  if (event == GST_EVENT_EOS) {
-    GST_DEBUG(GST_CAT_EVENT, "have EOS\n");
-  }
-}
index cafc18b..85aa9fb 100644 (file)
@@ -57,6 +57,7 @@ struct _GstFakeSink {
   GSList *sinkpads;
   gint numsinkpads;
   gboolean silent;
+  gboolean dump;
 };
 
 struct _GstFakeSinkClass {
index d946529..bed56e4 100644 (file)
@@ -21,6 +21,9 @@
  */
 
 
+#include <stdlib.h>
+#include <string.h>
+
 #include <gstfakesrc.h>
 
 
@@ -47,10 +50,17 @@ enum {
   ARG_NUM_SOURCES,
   ARG_LOOP_BASED,
   ARG_OUTPUT,
+  ARG_DATA,
+  ARG_SIZETYPE,
+  ARG_SIZEMIN,
+  ARG_SIZEMAX,
+  ARG_FILLTYPE,
   ARG_PATTERN,
   ARG_NUM_BUFFERS,
   ARG_EOS,
-  ARG_SILENT
+  ARG_SILENT,
+  ARG_DUMP,
+  ARG_PARENTSIZE
 };
 
 GST_PADTEMPLATE_FACTORY (fakesrc_src_factory,
@@ -82,12 +92,69 @@ gst_fakesrc_output_get_type (void)
   return fakesrc_output_type;
 }
 
+#define GST_TYPE_FAKESRC_DATA (gst_fakesrc_data_get_type())
+static GType
+gst_fakesrc_data_get_type (void) 
+{
+  static GType fakesrc_data_type = 0;
+  static GEnumValue fakesrc_data[] = {
+    { FAKESRC_DATA_ALLOCATE,           "2", "Allocate data"},
+    { FAKESRC_DATA_SUBBUFFER,          "3", "Subbuffer data"},
+    {0, NULL, NULL},
+  };
+  if (!fakesrc_data_type) {
+    fakesrc_data_type = g_enum_register_static ("GstFakeSrcData", fakesrc_data);
+  }
+  return fakesrc_data_type;
+}
+
+#define GST_TYPE_FAKESRC_SIZETYPE (gst_fakesrc_sizetype_get_type())
+static GType
+gst_fakesrc_sizetype_get_type (void) 
+{
+  static GType fakesrc_sizetype_type = 0;
+  static GEnumValue fakesrc_sizetype[] = {
+    { FAKESRC_SIZETYPE_NULL,           "1", "Send empty buffers"},
+    { FAKESRC_SIZETYPE_FIXED,          "2", "Fixed size buffers (sizemax sized)"},
+    { FAKESRC_SIZETYPE_RANDOM,                 "3", "Random sized buffers (sizemin <= size <= sizemax)"},
+    {0, NULL, NULL},
+  };
+  if (!fakesrc_sizetype_type) {
+    fakesrc_sizetype_type = g_enum_register_static ("GstFakeSrcSizeType", fakesrc_sizetype);
+  }
+  return fakesrc_sizetype_type;
+}
+
+#define GST_TYPE_FAKESRC_FILLTYPE (gst_fakesrc_filltype_get_type())
+static GType
+gst_fakesrc_filltype_get_type (void) 
+{
+  static GType fakesrc_filltype_type = 0;
+  static GEnumValue fakesrc_filltype[] = {
+    { FAKESRC_FILLTYPE_NOTHING,        "1", "Leave data as malloced"},
+    { FAKESRC_FILLTYPE_NULL,           "2", "Fill buffers with zeros"},
+    { FAKESRC_FILLTYPE_RANDOM,                 "3", "Fill buffers with random crap"},
+    { FAKESRC_FILLTYPE_PATTERN,        "4", "Fill buffers with pattern 0x00 -> 0xff"},
+    { FAKESRC_FILLTYPE_PATTERN_CONT,   "5", "Fill buffers with pattern 0x00 -> 0xff that spans buffers"},
+    {0, NULL, NULL},
+  };
+  if (!fakesrc_filltype_type) {
+    fakesrc_filltype_type = g_enum_register_static ("GstFakeSrcFillType", fakesrc_filltype);
+  }
+  return fakesrc_filltype_type;
+}
+
 static void            gst_fakesrc_class_init          (GstFakeSrcClass *klass);
 static void            gst_fakesrc_init                (GstFakeSrc *fakesrc);
 
 static GstPad*                 gst_fakesrc_request_new_pad     (GstElement *element, GstPadTemplate *templ);
-static void            gst_fakesrc_set_property        (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec);
-static void            gst_fakesrc_get_property        (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec);
+static void            gst_fakesrc_update_functions    (GstFakeSrc *src);
+static void            gst_fakesrc_set_property        (GObject *object, guint prop_id, 
+                                                        const GValue *value, GParamSpec *pspec);
+static void            gst_fakesrc_get_property        (GObject *object, guint prop_id, 
+                                                        GValue *value, GParamSpec *pspec);
+
+static GstElementStateReturn gst_fakesrc_change_state  (GstElement *element);
 
 static GstBuffer*      gst_fakesrc_get                 (GstPad *pad);
 static void            gst_fakesrc_loop                (GstElement *element);
@@ -137,6 +204,24 @@ gst_fakesrc_class_init (GstFakeSrcClass *klass)
   g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_OUTPUT,
     g_param_spec_enum("output","output","output",
                       GST_TYPE_FAKESRC_OUTPUT,FAKESRC_FIRST_LAST_LOOP,G_PARAM_READWRITE)); // CHECKME!
+  g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_DATA,
+    g_param_spec_enum ("data", "data", "data",
+                       GST_TYPE_FAKESRC_DATA, FAKESRC_DATA_ALLOCATE, G_PARAM_READWRITE)); 
+  g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_SIZETYPE,
+    g_param_spec_enum ("sizetype", "sizetype", "sizetype",
+                       GST_TYPE_FAKESRC_SIZETYPE, FAKESRC_SIZETYPE_NULL, G_PARAM_READWRITE)); 
+  g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_SIZEMIN,
+    g_param_spec_int ("sizemin","sizemin","sizemin",
+                      0, G_MAXINT, 0, G_PARAM_READWRITE)); 
+  g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_SIZEMAX,
+    g_param_spec_int ("sizemax","sizemax","sizemax",
+                      0, G_MAXINT, 4096, G_PARAM_READWRITE)); 
+  g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_PARENTSIZE,
+    g_param_spec_int ("parentsize","parentsize","parentsize",
+                      0, G_MAXINT, 4096 * 10, G_PARAM_READWRITE)); 
+  g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_FILLTYPE,
+    g_param_spec_enum ("filltype", "filltype", "filltype",
+                       GST_TYPE_FAKESRC_FILLTYPE, FAKESRC_FILLTYPE_NULL, G_PARAM_READWRITE)); 
   g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_PATTERN,
     g_param_spec_string("pattern","pattern","pattern",
                         NULL, G_PARAM_READWRITE)); // CHECKME
@@ -149,6 +234,9 @@ gst_fakesrc_class_init (GstFakeSrcClass *klass)
   g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_SILENT,
     g_param_spec_boolean("silent","silent","silent",
                          FALSE, G_PARAM_READWRITE)); // CHECKME
+  g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_DUMP,
+    g_param_spec_boolean ("dump","dump","dump",
+                          FALSE, G_PARAM_READWRITE)); 
 
   gst_fakesrc_signals[SIGNAL_HANDOFF] =
     g_signal_new ("handoff", G_TYPE_FROM_CLASS(klass), G_SIGNAL_RUN_LAST,
@@ -159,7 +247,8 @@ gst_fakesrc_class_init (GstFakeSrcClass *klass)
   gobject_class->set_property = GST_DEBUG_FUNCPTR (gst_fakesrc_set_property);
   gobject_class->get_property = GST_DEBUG_FUNCPTR (gst_fakesrc_get_property);
 
-  gstelement_class->request_new_pad = GST_DEBUG_FUNCPTR (gst_fakesrc_request_new_pad);
+  gstelement_class->request_new_pad =  GST_DEBUG_FUNCPTR (gst_fakesrc_request_new_pad);
+  gstelement_class->change_state =     GST_DEBUG_FUNCPTR (gst_fakesrc_change_state);
 }
 
 static void 
@@ -176,17 +265,21 @@ gst_fakesrc_init (GstFakeSrc *fakesrc)
   fakesrc->srcpads = g_slist_append (NULL, pad);
 
   fakesrc->loop_based = FALSE;
-
-  if (fakesrc->loop_based)
-    gst_element_set_loop_function (GST_ELEMENT (fakesrc), GST_DEBUG_FUNCPTR (gst_fakesrc_loop));
-  else
-    gst_pad_set_get_function (pad, GST_DEBUG_FUNCPTR (gst_fakesrc_get));
+  gst_fakesrc_update_functions (fakesrc);
 
   fakesrc->num_buffers = -1;
   fakesrc->buffer_count = 0;
   fakesrc->silent = FALSE;
-  // we're ready right away, since we don't have any args...
-//  gst_element_set_state(GST_ELEMENT(fakesrc),GST_STATE_READY);
+  fakesrc->dump = FALSE;
+  fakesrc->pattern_byte = 0x00;
+  fakesrc->need_flush = FALSE;
+  fakesrc->data = FAKESRC_DATA_ALLOCATE;
+  fakesrc->sizetype = FAKESRC_SIZETYPE_NULL;
+  fakesrc->filltype = FAKESRC_FILLTYPE_NOTHING;
+  fakesrc->sizemin = 0;
+  fakesrc->sizemax = 4096;
+  fakesrc->parent = NULL;
+  fakesrc->parentsize = 4096 * 10;
 }
 
 static GstPad*
@@ -216,6 +309,34 @@ gst_fakesrc_request_new_pad (GstElement *element, GstPadTemplate *templ)
   return srcpad;
 }
 
+static gboolean
+gst_fakesrc_event_handler (GstPad *pad, GstEvent *event)
+{
+  GstFakeSrc *src;
+
+  src = GST_FAKESRC (gst_pad_get_parent (pad));
+
+  switch (GST_EVENT_TYPE (event)) {
+    case GST_EVENT_SEEK:
+      g_print("fakesrc: have seek event\n");
+      src->buffer_count = GST_EVENT_SEEK_OFFSET (event);
+      if (!GST_EVENT_SEEK_FLUSH (event)) {
+        gst_event_free (event);
+        break;
+      }
+      // else we do a flush too
+    case GST_EVENT_FLUSH:
+      g_print("fakesrc: have flush event\n");
+      src->need_flush = TRUE;
+      break;
+    default:
+      g_print("fakesrc: have unhandled event\n");
+      break;
+  }
+
+  return TRUE;
+}
+
 static void
 gst_fakesrc_update_functions (GstFakeSrc *src)
 {
@@ -238,11 +359,26 @@ gst_fakesrc_update_functions (GstFakeSrc *src)
     else {
       gst_pad_set_get_function (pad, GST_DEBUG_FUNCPTR (gst_fakesrc_get));
     }
+
+    gst_pad_set_event_function (pad, gst_fakesrc_event_handler);
     pads = g_slist_next (pads);
   }
 }
 
 static void
+gst_fakesrc_alloc_parent (GstFakeSrc *src)
+{
+  GstBuffer *buf;
+
+  buf = gst_buffer_new ();
+  GST_BUFFER_DATA (buf) = g_malloc (src->parentsize);
+  GST_BUFFER_SIZE (buf) = src->parentsize;
+
+  src->parent = buf;
+  src->parentoffset = 0;
+}
+
+static void
 gst_fakesrc_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
 {
   GstFakeSrc *src;
@@ -257,6 +393,37 @@ gst_fakesrc_set_property (GObject *object, guint prop_id, const GValue *value, G
       break;
     case ARG_OUTPUT:
       break;
+    case ARG_DATA:
+      src->data = g_value_get_int (value);
+      switch (src->data) {
+       case FAKESRC_DATA_ALLOCATE:
+          if (src->parent) {
+            gst_buffer_unref (src->parent);
+            src->parent = NULL;
+         }
+          break;
+       case FAKESRC_DATA_SUBBUFFER:
+         if (!src->parent)
+           gst_fakesrc_alloc_parent (src);
+       default:
+          break;
+      }
+      break;
+    case ARG_SIZETYPE:
+      src->sizetype = g_value_get_int (value);
+      break;
+    case ARG_SIZEMIN:
+      src->sizemin = g_value_get_int (value);
+      break;
+    case ARG_SIZEMAX:
+      src->sizemax = g_value_get_int (value);
+      break;
+    case ARG_PARENTSIZE:
+      src->parentsize = g_value_get_int (value);
+      break;
+    case ARG_FILLTYPE:
+      src->filltype = g_value_get_int (value);
+      break;
     case ARG_PATTERN:
       break;
     case ARG_NUM_BUFFERS:
@@ -269,6 +436,9 @@ GST_INFO (0, "will EOS on next buffer");
     case ARG_SILENT:
       src->silent = g_value_get_boolean (value);
       break;
+    case ARG_DUMP:
+      src->dump = g_value_get_boolean (value);
+      break;
     default:
       break;
   }
@@ -294,6 +464,24 @@ gst_fakesrc_get_property (GObject *object, guint prop_id, GValue *value, GParamS
     case ARG_OUTPUT:
       g_value_set_int (value, src->output);
       break;
+    case ARG_DATA:
+      g_value_set_int (value, src->data);
+      break;
+    case ARG_SIZETYPE:
+      g_value_set_int (value, src->sizetype);
+      break;
+    case ARG_SIZEMIN:
+      g_value_set_int (value, src->sizemin);
+      break;
+    case ARG_SIZEMAX:
+      g_value_set_int (value, src->sizemax);
+      break;
+    case ARG_PARENTSIZE:
+      g_value_set_int (value, src->parentsize);
+      break;
+    case ARG_FILLTYPE:
+      g_value_set_int (value, src->filltype);
+      break;
     case ARG_PATTERN:
       g_value_set_string (value, src->pattern);
       break;
@@ -306,21 +494,150 @@ gst_fakesrc_get_property (GObject *object, guint prop_id, GValue *value, GParamS
     case ARG_SILENT:
       g_value_set_boolean (value, src->silent);
       break;
+    case ARG_DUMP:
+      g_value_set_boolean (value, src->dump);
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
   }
 }
 
+static void
+gst_fakesrc_prepare_buffer (GstFakeSrc *src, GstBuffer *buf)
+{
+  if (GST_BUFFER_SIZE (buf) == 0) 
+    return;
+
+  switch (src->filltype) {
+    case FAKESRC_FILLTYPE_NULL:
+      memset (GST_BUFFER_DATA (buf), 0, GST_BUFFER_SIZE (buf));
+      break;
+    case FAKESRC_FILLTYPE_RANDOM:
+    {
+      gint i;
+      guint8 *ptr = GST_BUFFER_DATA (buf);
+
+      for (i = GST_BUFFER_SIZE (buf); i; i--) {
+       *ptr++ = (gint8)((255.0)*rand()/(RAND_MAX));
+      }
+      break;
+    }
+    case FAKESRC_FILLTYPE_PATTERN:
+      src->pattern_byte = 0x00;
+    case FAKESRC_FILLTYPE_PATTERN_CONT:
+    {
+      gint i;
+      guint8 *ptr = GST_BUFFER_DATA (buf);
+
+      for (i = GST_BUFFER_SIZE (buf); i; i--) {
+       *ptr++ = src->pattern_byte++;
+      }
+      break;
+    }
+    case FAKESRC_FILLTYPE_NOTHING:
+    default:
+      break;
+  }
+}
+
+static GstBuffer*
+gst_fakesrc_alloc_buffer (GstFakeSrc *src, guint size)
+{
+  GstBuffer *buf;
+
+  buf = gst_buffer_new ();
+  GST_BUFFER_SIZE(buf) = size;
+
+  if (size != 0) { 
+    switch (src->filltype) {
+      case FAKESRC_FILLTYPE_NOTHING:
+        GST_BUFFER_DATA(buf) = g_malloc (size);
+        break;
+      case FAKESRC_FILLTYPE_NULL:
+        GST_BUFFER_DATA(buf) = g_malloc0 (size);
+        break;
+      case FAKESRC_FILLTYPE_RANDOM:
+      case FAKESRC_FILLTYPE_PATTERN:
+      case FAKESRC_FILLTYPE_PATTERN_CONT:
+      default:
+        GST_BUFFER_DATA(buf) = g_malloc (size);
+        gst_fakesrc_prepare_buffer (src, buf);
+        break;
+    }
+  }
+
+  return buf;
+}
+
+static guint
+gst_fakesrc_get_size (GstFakeSrc *src)
+{
+  guint size;
+
+  switch (src->sizetype) {
+    case FAKESRC_SIZETYPE_FIXED:
+      size = src->sizemax;
+      break;
+    case FAKESRC_SIZETYPE_RANDOM:
+      size = src->sizemin + (guint8)(((gfloat)src->sizemax)*rand()/(RAND_MAX + (gfloat)src->sizemin));
+      break;
+    case FAKESRC_SIZETYPE_NULL:
+    default:
+      size = 0; 
+      break;
+  }
+
+  return size;
+}
+
+static GstBuffer *
+gst_fakesrc_create_buffer (GstFakeSrc *src)
+{
+  GstBuffer *buf;
+  guint size;
+  gboolean dump = src->dump;
+
+  size = gst_fakesrc_get_size (src);
+  if (size == 0)
+    return gst_buffer_new();
+
+  switch (src->data) {
+    case FAKESRC_DATA_ALLOCATE:
+      buf = gst_fakesrc_alloc_buffer (src, size);
+      break;
+    case FAKESRC_DATA_SUBBUFFER:
+      // see if we have a parent to subbuffer
+      if (!src->parent) {
+       gst_fakesrc_alloc_parent (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);
+        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_fakesrc_create_buffer (src);
+      }
+      gst_fakesrc_prepare_buffer (src, buf);
+      break;
+    default:
+      g_warning ("fakesrc: dunno how to allocate buffers !");
+      buf = gst_buffer_new();
+      break;
+  }
+  if (dump) {
+    gst_util_dump_mem (GST_BUFFER_DATA (buf), GST_BUFFER_SIZE (buf));
+  }
+
+  return buf;
+}
 
-/**
- * gst_fakesrc_get:
- * @src: the faksesrc to get
- * 
- * generate an empty buffer and return it
- *
- * Returns: a new empty buffer
- */
 static GstBuffer *
 gst_fakesrc_get(GstPad *pad)
 {
@@ -333,9 +650,16 @@ gst_fakesrc_get(GstPad *pad)
 
   g_return_val_if_fail (GST_IS_FAKESRC (src), NULL);
 
+  if (src->need_flush) {
+    src->need_flush = FALSE;
+    g_print("fakesrc: sending FLUSH\n");
+    return GST_BUFFER(gst_event_new (GST_EVENT_FLUSH));
+  }
+
   if (src->num_buffers == 0) {
-    gst_pad_event (pad, GST_EVENT_EOS, 0LL, 0);
-    return NULL;
+    g_print("fakesrc: sending EOS\n");
+    gst_element_set_state (GST_ELEMENT (src), GST_STATE_PAUSED);
+    return GST_BUFFER(gst_event_new (GST_EVENT_EOS));
   }
   else {
     if (src->num_buffers > 0)
@@ -344,11 +668,11 @@ gst_fakesrc_get(GstPad *pad)
 
   if (src->eos) {
     GST_INFO (0, "fakesrc is setting eos on pad");
-    gst_pad_event (pad, GST_EVENT_EOS, 0LL, 0);
-    return NULL;
+    g_print("fakesrc: sending EOS\n");
+    return GST_BUFFER(gst_event_new (GST_EVENT_EOS));
   }
 
-  buf = gst_buffer_new();
+  buf = gst_fakesrc_create_buffer (src);
   GST_BUFFER_TIMESTAMP (buf) = src->buffer_count++;
 
   if (!src->silent)
@@ -356,7 +680,7 @@ gst_fakesrc_get(GstPad *pad)
                GST_DEBUG_PAD_NAME (pad), GST_BUFFER_SIZE (buf), GST_BUFFER_TIMESTAMP (buf));
 
   g_signal_emit (G_OBJECT (src), gst_fakesrc_signals[SIGNAL_HANDOFF], 0,
-                   buf);
+                   buf, pad);
 
   return buf;
 }
@@ -387,21 +711,20 @@ gst_fakesrc_loop(GstElement *element)
       GstBuffer *buf;
 
       if (src->num_buffers == 0) {
-        gst_pad_event (pad, GST_EVENT_EOS, 0LL, 0);
-        return;
+       src->eos = TRUE;
       }
       else {
-      if (src->num_buffers > 0)
-         src->num_buffers--;
+        if (src->num_buffers > 0)
+          src->num_buffers--;
       }
 
       if (src->eos) {
         GST_INFO (0, "fakesrc is setting eos on pad");
-        gst_pad_event (pad, GST_EVENT_EOS, 0LL, 0);
-        return;
+        gst_pad_push(pad, GST_BUFFER(gst_event_new (GST_EVENT_EOS)));
+       return;
       }
 
-      buf = gst_buffer_new();
+      buf = gst_fakesrc_create_buffer (src);
       GST_BUFFER_TIMESTAMP (buf) = src->buffer_count++;
 
       if (!src->silent)
@@ -409,7 +732,7 @@ gst_fakesrc_loop(GstElement *element)
                GST_DEBUG_PAD_NAME (pad), GST_BUFFER_SIZE (buf), GST_BUFFER_TIMESTAMP (buf));
 
       g_signal_emit (G_OBJECT (src), gst_fakesrc_signals[SIGNAL_HANDOFF], 0,
-                       buf);
+                       buf, pad);
       gst_pad_push (pad, buf);
 
       pads = g_slist_next (pads);
@@ -417,6 +740,31 @@ gst_fakesrc_loop(GstElement *element)
   } while (!GST_ELEMENT_IS_COTHREAD_STOPPING (element));
 }
 
+static GstElementStateReturn
+gst_fakesrc_change_state (GstElement *element)
+{
+  GstFakeSrc *fakesrc;
+
+  g_return_val_if_fail (GST_IS_FAKESRC (element), GST_STATE_FAILURE);
+
+  fakesrc = GST_FAKESRC (element);
+
+  if (GST_STATE_PENDING (element) == GST_STATE_READY) {
+    fakesrc->buffer_count = 0;
+    fakesrc->pattern_byte = 0x00;
+    fakesrc->need_flush = FALSE;
+    if (fakesrc->parent) {
+      gst_buffer_unref (fakesrc->parent);
+      fakesrc->parent = NULL;
+    }
+  }
+
+  if (GST_ELEMENT_CLASS (parent_class)->change_state)
+    return GST_ELEMENT_CLASS (parent_class)->change_state (element);
+
+  return GST_STATE_SUCCESS;
+}
+
 gboolean
 gst_fakesrc_factory_init (GstElementFactory *factory)
 {
index ce5c2a9..550015b 100644 (file)
@@ -47,6 +47,25 @@ typedef enum {
   FAKESRC_GET_ALWAYS_SUCEEDS,
 } GstFakeSrcOutputType;
 
+typedef enum {
+  FAKESRC_DATA_ALLOCATE = 1,
+  FAKESRC_DATA_SUBBUFFER,
+} GstFakeSrcDataType;
+
+typedef enum {
+  FAKESRC_SIZETYPE_NULL = 1,
+  FAKESRC_SIZETYPE_FIXED,
+  FAKESRC_SIZETYPE_RANDOM
+} GstFakeSrcSizeType;
+
+typedef enum {
+  FAKESRC_FILLTYPE_NOTHING = 1,
+  FAKESRC_FILLTYPE_NULL,
+  FAKESRC_FILLTYPE_RANDOM,
+  FAKESRC_FILLTYPE_PATTERN,
+  FAKESRC_FILLTYPE_PATTERN_CONT
+} GstFakeSrcFillType;
+
 #define GST_TYPE_FAKESRC \
   (gst_fakesrc_get_type())
 #define GST_FAKESRC(obj) \
@@ -64,16 +83,29 @@ typedef struct _GstFakeSrcClass GstFakeSrcClass;
 struct _GstFakeSrc {
   GstElement element;
 
-  gboolean loop_based;
-  gboolean eos;
-  gint numsrcpads;
-  GSList *srcpads;
+  gboolean     loop_based;
+  gboolean     eos;
+  gint                 numsrcpads;
+  GSList       *srcpads;
+
   GstFakeSrcOutputType output;
-  gchar *pattern;
-  GList *patternlist;
-  gint num_buffers;
-  guint64 buffer_count;
-  gboolean silent;
+  GstFakeSrcDataType data;
+  GstFakeSrcSizeType sizetype;
+  GstFakeSrcFillType filltype;
+
+  guint        sizemin;
+  guint        sizemax;
+  GstBuffer    *parent;
+  guint        parentsize;
+  guint        parentoffset;
+  guint8       pattern_byte;
+  gchar        *pattern;
+  GList        *patternlist;
+  gint                 num_buffers;
+  guint64      buffer_count;
+  gboolean     silent;
+  gboolean     dump;
+  gboolean     need_flush;
 };
 
 struct _GstFakeSrcClass {
index 3621494..f53548f 100644 (file)
@@ -27,6 +27,7 @@
 #include <fcntl.h>
 #include <unistd.h>
 #include <sys/mman.h>
+#include <errno.h>
 
 
 /**********************************************************************
@@ -74,6 +75,9 @@ GstElementDetails gst_filesrc_details = {
   "(C) 1999",
 };
 
+//#define fs_print(format,args...) g_print(format, ## args)
+#define fs_print(format,args...)
+
 
 #define GST_TYPE_FILESRC \
   (gst_filesrc_get_type())
@@ -110,10 +114,12 @@ struct _GstFileSrc {
   gboolean touch;                      // whether to touch every page
 
   GstBuffer *mapbuf;
-  off_t mapsize;
+  size_t mapsize;
 
   GTree *map_regions;
   GMutex *map_regions_lock;
+
+  gboolean seek_happened;
 };
 
 struct _GstFileSrcClass {
@@ -135,6 +141,7 @@ enum {
   ARG_BLOCKSIZE,
   ARG_OFFSET,
   ARG_MAPSIZE,
+  ARG_TOUCH,
 };
 
 
@@ -203,6 +210,9 @@ gst_filesrc_class_init (GstFileSrcClass *klass)
   g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_MAPSIZE,
     g_param_spec_ulong("mmapsize","mmap() Block Size","Size in bytes of mmap()d regions",
                        0,G_MAXULONG,4*1048576,G_PARAM_READWRITE));
+  g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_TOUCH,
+    g_param_spec_boolean("touch","Touch read data","Touch data to force disk read before push()",
+                         TRUE,G_PARAM_READWRITE));
 
   gobject_class->set_property = gst_filesrc_set_property;
   gobject_class->get_property = gst_filesrc_get_property;
@@ -246,6 +256,8 @@ gst_filesrc_init (GstFileSrc *src)
 
   src->map_regions = g_tree_new(gst_filesrc_bufcmp);
   src->map_regions_lock = g_mutex_new();
+
+  src->seek_happened = FALSE;
 }
 
 
@@ -286,6 +298,9 @@ gst_filesrc_set_property (GObject *object, guint prop_id, const GValue *value, G
       else
         GST_INFO(0, "invalid mapsize, must a multiple of pagesize, which is %d\n",src->pagesize);
       break;
+    case ARG_TOUCH:
+      src->touch = g_value_get_boolean (value);
+      break;
     default:
       break;
   }
@@ -320,6 +335,9 @@ gst_filesrc_get_property (GObject *object, guint prop_id, GValue *value, GParamS
     case ARG_MAPSIZE:
       g_value_set_ulong (value, src->mapsize);
       break;
+    case ARG_TOUCH:
+      g_value_set_boolean (value, src->touch);
+      break;
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
       break;
@@ -331,7 +349,7 @@ gst_filesrc_free_parent_mmap (GstBuffer *buf)
 {
   GstFileSrc *src = GST_FILESRC(GST_BUFFER_POOL_PRIVATE(buf));
 
-  // fprintf(stderr,"freeing mmap()d buffer at %d+%d\n",GST_BUFFER_OFFSET(buf),GST_BUFFER_SIZE(buf));
+  fs_print ("freeing mmap()d buffer at %d+%d\n",GST_BUFFER_OFFSET(buf),GST_BUFFER_SIZE(buf));
 
   // remove the buffer from the list of available mmap'd regions
   g_mutex_lock(src->map_regions_lock);
@@ -347,21 +365,24 @@ gst_filesrc_free_parent_mmap (GstBuffer *buf)
 }
 
 static GstBuffer *
-gst_filesrc_map_region (GstFileSrc *src, off_t offset, off_t size)
+gst_filesrc_map_region (GstFileSrc *src, off_t offset, size_t size)
 {
   GstBuffer *buf;
   gint retval;
 
-//  fprintf(stderr,"mapping region %d+%d from file into memory\n",offset,size);
+  g_return_val_if_fail (offset >= 0, NULL);
+
+  fs_print  ("mapping region %08lx+%08lx from file into memory\n",offset,size);
 
   // time to allocate a new mapbuf
   buf = gst_buffer_new();
   // mmap() the data into this new buffer
   GST_BUFFER_DATA(buf) = mmap (NULL, size, PROT_READ, MAP_SHARED, src->fd, offset);
   if (GST_BUFFER_DATA(buf) == NULL) {
-    fprintf(stderr, "ERROR: gstfilesrc couldn't map file!\n");
-  } else if (GST_BUFFER_DATA(buf) == (void *)-1) {
-    perror("gstfilesrc:mmap()");
+    fprintf (stderr, "ERROR: gstfilesrc couldn't map file!\n");
+  } else if (GST_BUFFER_DATA(buf) == MAP_FAILED) {
+    g_error ("gstfilesrc mmap(0x%x, %d, 0x%llx) : %s",
+            size, src->fd, offset, sys_errlist[errno]);
   }
   // madvise to tell the kernel what to do with it
   retval = madvise(GST_BUFFER_DATA(buf),GST_BUFFER_SIZE(buf),MADV_SEQUENTIAL);
@@ -382,20 +403,27 @@ gst_filesrc_map_region (GstFileSrc *src, off_t offset, off_t size)
 }
 
 static GstBuffer *
-gst_filesrc_map_small_region (GstFileSrc *src, off_t offset, off_t size)
+gst_filesrc_map_small_region (GstFileSrc *src, off_t offset, size_t size)
 {
-  int mod, mapbase, mapsize;
+  size_t mapsize;
+  off_t mod, mapbase;
   GstBuffer *map;
 
 //  printf("attempting to map a small buffer at %d+%d\n",offset,size);
 
   // if the offset starts at a non-page boundary, we have to special case
   if ((mod = offset % src->pagesize)) {
+    GstBuffer *ret;
+
     mapbase = offset - mod;
     mapsize = ((size + mod + src->pagesize - 1) / src->pagesize) * src->pagesize;
 //    printf("not on page boundaries, resizing map to %d+%d\n",mapbase,mapsize);
     map = gst_filesrc_map_region(src, mapbase, mapsize);
-    return gst_buffer_create_sub (map, offset - mapbase, size);
+    ret = gst_buffer_create_sub (map, offset - mapbase, size);
+
+    gst_buffer_unref (map);
+
+    return ret;
   }
 
   return gst_filesrc_map_region(src,offset,size);
@@ -431,8 +459,8 @@ gst_filesrc_get (GstPad *pad)
 {
   GstFileSrc *src;
   GstBuffer *buf = NULL, *map;
-  off_t readend,readsize,mapstart,mapend;
-  gboolean eof = FALSE;
+  size_t readsize;
+  off_t readend,mapstart,mapend;
   GstFileSrcRegion region;
   int i;
 
@@ -440,6 +468,18 @@ gst_filesrc_get (GstPad *pad)
   src = GST_FILESRC (gst_pad_get_parent (pad));
   g_return_val_if_fail (GST_FLAG_IS_SET (src, GST_FILESRC_OPEN), NULL);
 
+  // check for seek
+  if (src->seek_happened) {
+    src->seek_happened = FALSE;
+    return gst_event_new(GST_EVENT_DISCONTINUOUS);
+  }
+
+  // check for EOF
+  if (src->curoffset == src->filelen) {
+    gst_element_set_state(src,GST_STATE_PAUSED);
+    return gst_event_new(GST_EVENT_EOS);
+  }
+
   // calculate end pointers so we don't have to do so repeatedly later
   readsize = src->block_size;
   readend = src->curoffset + src->block_size;          // note this is the byte *after* the read
@@ -450,7 +490,6 @@ gst_filesrc_get (GstPad *pad)
   if (readend > src->filelen) {
     readsize = src->filelen - src->curoffset;
     readend = src->curoffset;
-    eof = TRUE;
   }
 
   // if the start is past the mapstart
@@ -458,15 +497,15 @@ gst_filesrc_get (GstPad *pad)
     // 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) {
-//      printf("read buf %d+%d lives in current mapbuf %d+%d, creating subbuffer of mapbuf\n",
-//             src->curoffset,readsize,GST_BUFFER_OFFSET(src->mapbuf),GST_BUFFER_SIZE(src->mapbuf));
+      fs_print ("read buf %d+%d lives in current mapbuf %d+%d, creating subbuffer of mapbuf\n",
+             src->curoffset,readsize,GST_BUFFER_OFFSET(src->mapbuf),GST_BUFFER_SIZE(src->mapbuf));
       buf = gst_buffer_create_sub (src->mapbuf, src->curoffset - GST_BUFFER_OFFSET(src->mapbuf),
                                    readsize);
 
     // if the start actually is within the current mmap region, map an overlap buffer
     } else if (src->curoffset < mapend) {
-//      printf("read buf %d+%d starts in mapbuf %d+%d but ends outside, creating new mmap\n",
-//             src->curoffset,readsize,GST_BUFFER_OFFSET(src->mapbuf),GST_BUFFER_SIZE(src->mapbuf));
+      fs_print ("read buf %d+%d starts in mapbuf %d+%d but ends outside, creating new mmap\n",
+             src->curoffset,readsize,GST_BUFFER_OFFSET(src->mapbuf),GST_BUFFER_SIZE(src->mapbuf));
       buf = gst_filesrc_map_small_region (src, src->curoffset, readsize);
     }
 
@@ -478,37 +517,39 @@ gst_filesrc_get (GstPad *pad)
     // 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
-//    printf("read buf %d+%d starts before mapbuf %d+%d, but overlaps it\n",
-//             src->curoffset,readsize,GST_BUFFER_OFFSET(src->mapbuf),GST_BUFFER_SIZE(src->mapbuf));
+    fs_print ("read buf %d+%d starts before mapbuf %d+%d, but overlaps it\n",
+             src->curoffset,readsize,GST_BUFFER_OFFSET(src->mapbuf),GST_BUFFER_SIZE(src->mapbuf));
     buf = gst_filesrc_map_small_region (src, src->curoffset, readsize);
   }
 
   // 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
-//    printf("searching for mapbuf to cover %d+%d\n",src->curoffset,readsize);
+    fs_print ("searching for mapbuf to cover %d+%d\n",src->curoffset,readsize);
     region.offset = src->curoffset;
     region.size = readsize;
-    map = g_tree_search(src->map_regions,gst_filesrc_search_region_match,&region);
+    map = g_tree_search (src->map_regions,
+                        (GCompareFunc) gst_filesrc_search_region_match,
+                        &region);
 
     // if we found an exact match, subbuffer it
     if (map != NULL) {
-//      printf("found mapbuf at %d+%d, creating subbuffer\n",GST_BUFFER_OFFSET(map),GST_BUFFER_SIZE(map));
+      fs_print ("found mapbuf at %d+%d, creating subbuffer\n",GST_BUFFER_OFFSET(map),GST_BUFFER_SIZE(map));
       buf = gst_buffer_create_sub (map, src->curoffset - GST_BUFFER_OFFSET(map), readsize);
 
     // otherwise we need to create something out of thin air
     } else {
       // if the read buffer crosses a mmap region boundary, create a one-off region
       if ((src->curoffset / src->mapsize) != (readend / src->mapsize)) {
-//        printf("read buf %d+%d crosses a %d-byte boundary, creating a one-off\n",
-//               src->curoffset,readsize,src->mapsize);
+        fs_print ("read buf %d+%d crosses a %d-byte boundary, creating a one-off\n",
+               src->curoffset,readsize,src->mapsize);
         buf = gst_filesrc_map_small_region (src, src->curoffset, readsize);
 
       // otherwise we will create a new mmap region and set it to the default
       } else {
         off_t nextmap = src->curoffset - (src->curoffset % src->mapsize);
-//        printf("read buf %d+%d in new mapbuf at %d+%d, mapping and subbuffering\n",
-//               src->curoffset,readsize,nextmap,src->mapsize);
+        fs_print ("read buf %d+%d in new mapbuf at %d+%d, mapping and subbuffering\n",
+               src->curoffset,readsize,nextmap,src->mapsize);
         // first, we're done with the old mapbuf
         gst_buffer_unref(src->mapbuf);
         // create a new one
@@ -525,8 +566,6 @@ gst_filesrc_get (GstPad *pad)
       *(GST_BUFFER_DATA(buf)+i) = *(GST_BUFFER_DATA(buf)+i);
   }
 
-  // if we hit EOF, 
-
   /* we're done, return the buffer */
   src->curoffset += GST_BUFFER_SIZE(buf);
   return buf;
@@ -567,6 +606,7 @@ gst_filesrc_close_file (GstFileSrc *src)
 {
   g_return_if_fail (GST_FLAG_IS_SET (src, GST_FILESRC_OPEN));
 
+  g_print ("close\n");
   /* close the file */
   close (src->fd);
 
@@ -613,6 +653,7 @@ gst_filesrc_srcpad_event(GstPad *pad, GstEventType event, gint64 location, guint
     } else if (data == SEEK_END) {
       src->curoffset = src->filelen - (guint64)location;
     }
+    src->seek_happened = TRUE;
     // push a discontinuous event?
     return TRUE;
   }
diff --git a/plugins/elements/gstsinesrc.c b/plugins/elements/gstsinesrc.c
new file mode 100644 (file)
index 0000000..75ca6ba
--- /dev/null
@@ -0,0 +1,452 @@
+/* GStreamer
+ * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
+ *                    2000 Wim Taymans <wtay@chello.be>
+ *                    2001 Steve Baker <stevebaker_org@yahoo.co.uk>
+ *
+ * gstsinesrc.c: 
+ *
+ * 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 <math.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <gstsinesrc.h>
+
+
+GstElementDetails gst_sinesrc_details = {
+  "Sine-wave src",
+  "Source/Audio",
+  "Create a sine wave of a given frequency and volume",
+  VERSION,
+  "Erik Walthinsen <omega@cse.ogi.edu>",
+  "(C) 1999",
+};
+
+
+/* SineSrc signals and args */
+enum {
+  /* FILL ME */
+  LAST_SIGNAL
+};
+
+enum {
+  ARG_0,
+  ARG_VOLUME,
+  ARG_FORMAT,
+  ARG_SAMPLERATE,
+  ARG_FREQ,
+  ARG_TABLESIZE,
+  ARG_BUFFER_SIZE,
+};
+
+// FIXME: this is not core business...
+GST_PADTEMPLATE_FACTORY (sinesrc_src_factory,
+  "src",
+  GST_PAD_SRC,
+  GST_PAD_ALWAYS,
+  GST_CAPS_NEW (
+    "sinesrc_src",
+    "audio/raw",
+      "format",        GST_PROPS_STRING ("int"),
+        "law",         GST_PROPS_INT (0),
+        "endianness",  GST_PROPS_INT (G_BYTE_ORDER),
+        "signed",      GST_PROPS_BOOLEAN (TRUE),
+        "width",       GST_PROPS_INT (16),
+        "depth",       GST_PROPS_INT (16),
+        "rate",        GST_PROPS_INT_RANGE (8000, 48000),
+        "channels",    GST_PROPS_INT (1)
+  )
+);
+
+static void                    gst_sinesrc_class_init          (GstSineSrcClass *klass);
+static void                    gst_sinesrc_init                (GstSineSrc *src);
+static GstPadNegotiateReturn   gst_sinesrc_negotiate           (GstPad *pad, GstCaps **caps, gpointer *data); 
+static void                    gst_sinesrc_set_property        (GObject *object, guint prop_id, 
+                                                                const GValue *value, GParamSpec *pspec);
+static void                    gst_sinesrc_get_property        (GObject *object, guint prop_id, 
+                                                                GValue *value, GParamSpec *pspec);
+//static gboolean gst_sinesrc_change_state(GstElement *element,
+//                                          GstElementState state);
+//static void gst_sinesrc_close_audio(GstSineSrc *src);
+//static gboolean gst_sinesrc_open_audio(GstSineSrc *src);
+
+static void gst_sinesrc_update_volume(GValue *value, gpointer data);
+static void gst_sinesrc_update_freq(GValue *value, gpointer data);
+static void                    gst_sinesrc_populate_sinetable  (GstSineSrc *src);
+static inline void             gst_sinesrc_update_table_inc    (GstSineSrc *src);
+static inline void             gst_sinesrc_update_vol_scale    (GstSineSrc *src);
+static void                    gst_sinesrc_force_caps          (GstSineSrc *src);
+
+static GstBuffer*              gst_sinesrc_get                 (GstPad *pad);
+
+static GstElementClass *parent_class = NULL;
+//static guint gst_sinesrc_signals[LAST_SIGNAL] = { 0 };
+
+GType
+gst_sinesrc_get_type (void)
+{
+  static GType sinesrc_type = 0;
+
+  if (!sinesrc_type) {
+    static const GTypeInfo sinesrc_info = {
+      sizeof(GstSineSrcClass),      
+      NULL,
+      NULL,
+      (GClassInitFunc)gst_sinesrc_class_init,
+      NULL,
+      NULL,
+      sizeof(GstSineSrc),
+      0,
+      (GInstanceInitFunc)gst_sinesrc_init,
+    };
+    sinesrc_type = g_type_register_static (GST_TYPE_ELEMENT, "GstSineSrc", &sinesrc_info, 0);
+  }
+  return sinesrc_type;
+}
+
+static void
+gst_sinesrc_class_init (GstSineSrcClass *klass) 
+{
+  GObjectClass *gobject_class;
+  GstElementClass *gstelement_class;
+
+  gobject_class = (GObjectClass*)klass;
+  gstelement_class = (GstElementClass*)klass;
+
+  parent_class = g_type_class_ref(GST_TYPE_ELEMENT);
+
+  g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_VOLUME,
+    g_param_spec_double("volume","volume","volume",
+                        0.0, 1.0, 0.0,G_PARAM_READWRITE)); // CHECKME
+  g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_FORMAT,
+    g_param_spec_int("format","format","format",
+                     G_MININT,G_MAXINT,0,G_PARAM_READWRITE)); // CHECKME
+  g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_SAMPLERATE,
+    g_param_spec_int("samplerate","samplerate","samplerate",
+                     G_MININT,G_MAXINT,0,G_PARAM_READWRITE)); // CHECKME
+  g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_TABLESIZE,
+    g_param_spec_int("tablesize","tablesize","tablesize",
+                     G_MININT,G_MAXINT,0,G_PARAM_READWRITE)); // CHECKME
+  g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_FREQ,
+    g_param_spec_double("freq","freq","freq",
+                        0.0,G_MAXDOUBLE, 440.0,G_PARAM_READWRITE)); // CHECKME
+  g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_BUFFER_SIZE,
+    g_param_spec_int("buffersize","buffersize","buffersize",
+                     0, G_MAXINT, 1024, G_PARAM_READWRITE)); 
+                          
+  gobject_class->set_property = gst_sinesrc_set_property;
+  gobject_class->get_property = gst_sinesrc_get_property;
+
+//  gstelement_class->change_state = gst_sinesrc_change_state;
+}
+
+static void 
+gst_sinesrc_init (GstSineSrc *src) 
+{
+  GstElement *element = GST_ELEMENT(src);
+  GstDParamManager *dpman;
+  
+  src->srcpad = gst_pad_new_from_template (
+                 GST_PADTEMPLATE_GET (sinesrc_src_factory), "src");
+  gst_element_add_pad(GST_ELEMENT(src), src->srcpad);
+  gst_pad_set_negotiate_function (src->srcpad, gst_sinesrc_negotiate);
+  
+  gst_pad_set_get_function(src->srcpad, gst_sinesrc_get);
+
+  src->format = 16;
+  src->samplerate = 44100;
+  
+  src->newcaps = TRUE;
+  
+  src->table_pos = 0.0;
+  src->table_size = 1024;
+  src->buffer_size=1024;
+  
+  src->seq = 0;
+
+  dpman = gst_dpman_new ("sinesrc_dpman", GST_ELEMENT(src));
+  gst_dpman_add_required_dparam (dpman, "volume", G_TYPE_FLOAT, gst_sinesrc_update_volume, src);
+  gst_dpman_add_required_dparam (dpman, "freq", G_TYPE_FLOAT, gst_sinesrc_update_freq, src);
+
+  gst_dpman_set_rate_change_pad(dpman, src->srcpad);
+  
+  GST_ELEMENT_DPARAM_MANAGER(element) = dpman;
+  
+  gst_sinesrc_update_vol_scale(src);
+
+  gst_sinesrc_populate_sinetable(src);
+  gst_sinesrc_update_table_inc(src);
+
+}
+
+static GstPadNegotiateReturn 
+gst_sinesrc_negotiate (GstPad *pad, GstCaps **caps, gpointer *data) 
+{
+  GstSineSrc *src;
+
+  if (*caps) {
+    g_return_val_if_fail (pad != NULL, GST_PAD_NEGOTIATE_FAIL);
+    src = GST_SINESRC(gst_pad_get_parent (pad));
+    src->samplerate = gst_caps_get_int (*caps, "rate");
+    gst_sinesrc_update_table_inc(src);
+    return GST_PAD_NEGOTIATE_AGREE;
+  }
+
+  return GST_PAD_NEGOTIATE_FAIL;
+}
+
+static GstBuffer *
+gst_sinesrc_get(GstPad *pad)
+{
+  GstSineSrc *src;
+  GstBuffer *buf;
+  GstDParamManager *dpman;
+  
+  gint16 *samples;
+  gint i=0, frame_countdown;
+  
+  g_return_val_if_fail (pad != NULL, NULL);
+  src = GST_SINESRC(gst_pad_get_parent (pad));
+
+  buf = gst_buffer_new();
+  g_return_val_if_fail (buf, NULL);
+  samples = g_new(gint16, src->buffer_size);
+  GST_BUFFER_DATA(buf) = (gpointer) samples;
+  GST_BUFFER_SIZE(buf) = 2 * src->buffer_size;
+  
+  dpman = GST_ELEMENT_DPARAM_MANAGER(GST_ELEMENT(src));
+  frame_countdown = GST_DPMAN_FIRST_COUNTDOWN(dpman, src->buffer_size, 0LL);
+
+  while(GST_DPMAN_COUNTDOWN(dpman, frame_countdown, i)) {
+    src->table_lookup = (gint)(src->table_pos);
+    src->table_lookup_next = src->table_lookup + 1;
+    src->table_interp = src->table_pos - src->table_lookup;
+    
+    // wrap the array lookups if we're out of bounds
+    if (src->table_lookup_next >= src->table_size){
+      src->table_lookup_next -= src->table_size;
+      if (src->table_lookup >= src->table_size){
+        src->table_lookup -= src->table_size;
+        src->table_pos -= src->table_size;
+      }
+    }
+    
+    src->table_pos += src->table_inc;
+
+    //no interpolation
+    //samples[i] = src->table_data[src->table_lookup]
+    //               * src->vol_scale;
+                       
+    //linear interpolation
+    samples[i++] = ((src->table_interp
+                   *(src->table_data[src->table_lookup_next]
+                    -src->table_data[src->table_lookup]
+                    )
+                  )+src->table_data[src->table_lookup]
+                 )* src->vol_scale;
+  }
+
+  if (src->newcaps) {
+    gst_sinesrc_force_caps(src);
+  }
+
+  return buf;
+}
+
+static void 
+gst_sinesrc_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) 
+{
+  GstSineSrc *src;
+
+  /* it's not null if we got it, but it might not be ours */
+  g_return_if_fail(GST_IS_SINESRC(object));
+  src = GST_SINESRC(object);
+
+  switch (prop_id) {
+    case ARG_VOLUME:
+      src->volume = (gfloat)g_value_get_double (value);
+      gst_sinesrc_update_vol_scale(src);
+      break;
+    case ARG_FORMAT:
+      src->format = g_value_get_int (value);
+      src->newcaps=TRUE;
+      break;
+    case ARG_SAMPLERATE:
+      src->samplerate = g_value_get_int (value);
+      src->newcaps=TRUE;
+      gst_sinesrc_update_table_inc(src);
+      break;
+    case ARG_FREQ: {
+      if (g_value_get_double (value) <= 0.0 || g_value_get_double (value) > src->samplerate/2)
+        break;
+      src->freq = (gfloat)g_value_get_double (value);
+      gst_sinesrc_update_table_inc(src);
+      break;
+    case ARG_TABLESIZE:
+      src->table_size = g_value_get_int (value);
+      gst_sinesrc_populate_sinetable(src);
+      gst_sinesrc_update_table_inc(src);
+      break;
+    case ARG_BUFFER_SIZE:
+      src->buffer_size = g_value_get_int (value);
+      break;
+    }
+    default:
+      break;
+  }
+}
+
+static void 
+gst_sinesrc_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) 
+{
+  GstSineSrc *src;
+
+  /* it's not null if we got it, but it might not be ours */
+  g_return_if_fail(GST_IS_SINESRC(object));
+  src = GST_SINESRC(object);
+
+  switch (prop_id) {
+    case ARG_VOLUME:
+      g_value_set_double (value, (gdouble)(src->volume));
+      break;
+    case ARG_FORMAT:
+      g_value_set_int (value, src->format);
+      break;
+    case ARG_SAMPLERATE:
+      g_value_set_int (value, src->samplerate);
+      break;
+    case ARG_FREQ:
+      g_value_set_double (value, (gdouble)(src->freq));
+      break;
+    case ARG_TABLESIZE:
+      g_value_set_int (value, src->table_size);
+      break;
+    case ARG_BUFFER_SIZE:
+      g_value_set_int (value, src->buffer_size);
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+  }
+}
+
+/*
+static gboolean gst_sinesrc_change_state(GstElement *element,
+                                          GstElementState state) {
+  g_return_if_fail(GST_IS_SINESRC(element));
+
+  switch (state) {
+    case GST_STATE_RUNNING:
+      if (!gst_sinesrc_open_audio(GST_SINESRC(element)))
+        return FALSE;
+      break;
+    case ~GST_STATE_RUNNING:
+      gst_sinesrc_close_audio(GST_SINESRC(element));
+      break;
+    default:
+      break;
+  }
+
+  if (GST_ELEMENT_CLASS(parent_class)->change_state)
+    return GST_ELEMENT_CLASS(parent_class)->change_state(element,state);
+  return TRUE;
+}
+*/
+
+static void 
+gst_sinesrc_populate_sinetable (GstSineSrc *src)
+{
+  gint i;
+  gdouble pi2scaled = M_PI * 2 / src->table_size;
+  gfloat *table = g_new(gfloat, src->table_size);
+
+  for(i=0 ; i < src->table_size ; i++){
+    table[i] = (gfloat)sin(i * pi2scaled);
+  }
+  
+  g_free(src->table_data);
+  src->table_data = table;
+}
+
+static void
+gst_sinesrc_update_volume(GValue *value, gpointer data)
+{
+  GstSineSrc *src = (GstSineSrc*)data;
+  g_return_if_fail(GST_IS_SINESRC(src));
+
+  src->volume = g_value_get_float(value);
+  src->vol_scale = 32767.0 * src->volume;
+}
+
+static void
+gst_sinesrc_update_freq(GValue *value, gpointer data)
+{
+  GstSineSrc *src = (GstSineSrc*)data;
+  g_return_if_fail(GST_IS_SINESRC(src));
+  
+  src->freq = g_value_get_float(value);
+  src->table_inc = src->table_size * src->freq / src->samplerate;
+}
+
+static inline void 
+gst_sinesrc_update_table_inc (GstSineSrc *src)
+{
+  src->table_inc = src->table_size * src->freq / src->samplerate;
+}
+
+static inline void 
+gst_sinesrc_update_vol_scale (GstSineSrc *src)
+{
+  src->vol_scale = 32767.0 * src->volume;
+}
+
+static void 
+gst_sinesrc_force_caps(GstSineSrc *src) {
+  GstCaps *caps;
+
+  if (!src->newcaps)
+    return;
+  
+  src->newcaps=FALSE;
+
+  caps = gst_caps_new (
+                   "sinesrc_src_caps",
+                   "audio/raw",
+                    gst_props_new (
+                          "format",            GST_PROPS_STRING ("int"),
+                            "law",             GST_PROPS_INT (0),
+                            "endianness",      GST_PROPS_INT (G_BYTE_ORDER),
+                            "signed",          GST_PROPS_BOOLEAN (TRUE),
+                            "width",           GST_PROPS_INT (16),
+                            "depth",           GST_PROPS_INT (16),
+                            "rate",            GST_PROPS_INT (src->samplerate),
+                            "channels",        GST_PROPS_INT (1),
+                            NULL
+                            )
+                   );
+  
+  gst_pad_set_caps (src->srcpad, caps);
+}
+
+gboolean 
+gst_sinesrc_factory_init (GstElementFactory *factory) 
+{
+  gst_elementfactory_add_padtemplate (factory, GST_PADTEMPLATE_GET (sinesrc_src_factory));
+  
+  return TRUE;
+}
diff --git a/plugins/elements/gstsinesrc.h b/plugins/elements/gstsinesrc.h
new file mode 100644 (file)
index 0000000..58e03fd
--- /dev/null
@@ -0,0 +1,96 @@
+/* GStreamer
+ * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
+ *                    2000 Wim Taymans <wtay@chello.be>
+ *
+ * gstsinesrc.h: 
+ *
+ * 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_SINESRC_H__
+#define __GST_SINESRC_H__
+
+
+#include <config.h>
+#include <gst/gst.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+GstElementDetails gst_sinesrc_details;
+
+
+#define GST_TYPE_SINESRC \
+  (gst_sinesrc_get_type())
+#define GST_SINESRC(obj) \
+  (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_SINESRC,GstSineSrc))
+#define GST_SINESRC_CLASS(klass) \
+  (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_SINESRC,GstSineSrcClass))
+#define GST_IS_SINESRC(obj) \
+  (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_SINESRC))
+#define GST_IS_SINESRC_CLASS(obj) \
+  (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_SINESRC))
+
+typedef struct _GstSineSrc GstSineSrc;
+typedef struct _GstSineSrcClass GstSineSrcClass;
+
+struct _GstSineSrc {
+  GstElement element;
+
+  /* pads */
+  GstPad *srcpad;
+
+  /* parameters */
+  gfloat volume;
+  gfloat freq;
+  gfloat vol_scale;
+  
+  /* lookup table data */
+  gfloat *table_data;
+  gdouble table_pos;
+  gdouble table_inc;
+  gint table_size;
+  gdouble table_interp;
+  gint table_lookup;
+  gint table_lookup_next;
+    
+  /* audio parameters */
+  gint format;
+  gint samplerate;
+
+  gint buffer_size;
+  gulong seq;
+
+  gboolean newcaps;
+
+};
+
+struct _GstSineSrcClass {
+  GstElementClass parent_class;
+};
+
+GType gst_sinesrc_get_type(void);
+gboolean gst_sinesrc_factory_init (GstElementFactory *factory);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif /* __GST_SINESRC_H__ */
index 729b95e..d7e0544 100644 (file)
@@ -56,7 +56,7 @@ GST_PADTEMPLATE_FACTORY (tee_src_factory,
 static void    gst_tee_class_init      (GstTeeClass *klass);
 static void    gst_tee_init            (GstTee *tee);
 
-static GstPad*         gst_tee_request_new_pad (GstElement *element, GstPadTemplate *temp);
+static GstPad*         gst_tee_request_new_pad (GstElement *element, GstPadTemplate *temp, const gchar *unused);
 
 static void    gst_tee_set_property    (GObject *object, guint prop_id, 
                                         const GValue *value, GParamSpec *pspec);
@@ -127,7 +127,7 @@ gst_tee_init (GstTee *tee)
 }
 
 static GstPad*
-gst_tee_request_new_pad (GstElement *element, GstPadTemplate *templ) 
+gst_tee_request_new_pad (GstElement *element, GstPadTemplate *templ, const gchar *unused
 {
   gchar *name;
   GstPad *srcpad;
index 292440e..23f6fa7 100644 (file)
@@ -55,7 +55,9 @@ int main(int argc,char *argv[]) {
   gst_pad_connect(gst_element_get_pad(queue,"src"),
                   gst_element_get_pad(play,"sink"));
 
+#ifndef GST_DISABLE_LOADSAVE
   xmlSaveFile("ac3play.gst", gst_xml_write(GST_ELEMENT(pipeline)));
+#endif
 
   // set thread start state
   g_object_set(G_OBJECT(decodethread),"create_thread",TRUE,NULL);
index 1cb4313..44f876a 100644 (file)
@@ -128,7 +128,9 @@ int main(int argc,char *argv[]) {
   gst_element_set_state(GST_ELEMENT(pipeline),GST_STATE_READY);
   gst_element_set_state(GST_ELEMENT(pipeline),GST_STATE_PLAYING);
 
+#ifndef GST_DISABLE_LOADSAVE
   xmlSaveFile("aviparse.xml",gst_xml_write(GST_ELEMENT(pipeline)));
+#endif
 
   g_print("about to enter loop\n");
 
diff --git a/test/bufspeed/.gitignore b/test/bufspeed/.gitignore
new file mode 100644 (file)
index 0000000..25d1705
--- /dev/null
@@ -0,0 +1,10 @@
+Makefile
+Makefile.in
+*.o
+*.lo
+*.la
+.deps
+.libs
+*.xml
+test1
+test2
diff --git a/test/bufspeed/Makefile.am b/test/bufspeed/Makefile.am
new file mode 100644 (file)
index 0000000..e86b7a7
--- /dev/null
@@ -0,0 +1,6 @@
+noinst_PROGRAMS = test1 test2
+
+test1_SOURCES = test1.c gstbuffer.c gstmempool.c
+
+#LIBS += $(GST_LIBS)
+CFLAGS += $(GST_CFLAGS) 
diff --git a/test/bufspeed/README b/test/bufspeed/README
new file mode 100644 (file)
index 0000000..8bb6600
--- /dev/null
@@ -0,0 +1,6 @@
+benchmark of 5000000 gst_buffer_new/free on 0.2.1 code
+------------------------------------------------------
+gstmemchunk, no lock:   real    0m1.309s user   0m1.220s sys    0m0.070s
+gmemchunk, no lock:     real    0m3.872s user   0m3.740s sys    0m0.090s
+gstmemchunk, lock:      real    0m5.306s user   0m5.160s sys    0m0.100s
+gmemchunk, lock:        real    0m8.001s user   0m7.890s sys    0m0.080s
diff --git a/test/bufspeed/gstbuffer.c b/test/bufspeed/gstbuffer.c
new file mode 100644 (file)
index 0000000..35a92ee
--- /dev/null
@@ -0,0 +1,495 @@
+/* GStreamer
+ * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
+ *                    2000 Wim Taymans <wtay@chello.be>
+ *
+ * gstbuffer.c: Buffer 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.
+ */
+
+/* this file makes too much noise for most debugging sessions */
+#define GST_DEBUG_FORCE_DISABLE
+#include "gst/gst_private.h"
+
+#include "gstbuffer.h"
+#include "gstmempool.h"
+
+GType _gst_buffer_type;
+
+static GstMemPool *_gst_buffer_pool;
+
+static void
+gst_buffer_alloc_func (GstMemPool *pool, gpointer data)
+{
+  GstBuffer *buffer = GST_BUFFER (data);
+
+  GST_DATA_TYPE(buffer) = _gst_buffer_type;
+  buffer->lock = g_mutex_new ();
+}
+
+static void
+gst_buffer_free_func (GstMemPool *pool, gpointer data)
+{
+  GstBuffer *buffer = GST_BUFFER (data);
+
+  g_mutex_free (buffer->lock);
+}
+
+void 
+_gst_buffer_initialize (void) 
+{
+  int buffersize = sizeof(GstBuffer);
+  static const GTypeInfo buffer_info = {
+    0, // sizeof(class),
+    NULL,
+    NULL,
+    NULL,
+    NULL,
+    NULL,
+    0, // sizeof(object),
+    0,
+    NULL,
+  };
+
+  // round up to the nearest 32 bytes for cache-line and other efficiencies
+  buffersize = (((buffersize-1) / 32) + 1) * 32;
+
+  _gst_buffer_pool = gst_mem_pool_new ("GstBuffer", buffersize,
+    buffersize * 32, G_ALLOC_AND_FREE, gst_buffer_alloc_func, gst_buffer_free_func);
+
+  _gst_buffer_type = g_type_register_static (G_TYPE_INT, "GstBuffer", &buffer_info, 0);
+}
+
+/**
+ * gst_buffer_new:
+ *
+ * Create a new buffer.
+ *
+ * Returns: new buffer
+ */
+GstBuffer*
+gst_buffer_new (void)
+{
+  GstBuffer *buffer;
+
+  buffer = gst_mem_pool_alloc (_gst_buffer_pool);
+
+  GST_INFO (GST_CAT_BUFFER,"creating new buffer %p",buffer);
+
+#ifdef HAVE_ATOMIC_H
+  atomic_set (&buffer->refcount, 1);
+#else
+  buffer->refcount = 1;
+#endif
+  buffer->offset = -1;
+  buffer->flags = 0;
+  buffer->data = NULL;
+  buffer->size = 0;
+  buffer->maxsize = 0;
+  buffer->timestamp = 0;
+  buffer->parent = NULL;
+  buffer->pool = NULL;
+  buffer->pool_private = NULL;
+  buffer->free = NULL;
+  buffer->copy = NULL;
+
+  return buffer;
+}
+
+/**
+ * gst_buffer_new_from_pool:
+ * @pool: the buffer pool to use
+ *
+ * Create a new buffer using the specified bufferpool.
+ *
+ * Returns: new buffer
+ */
+GstBuffer*
+gst_buffer_new_from_pool (GstBufferPool *pool, guint32 offset, guint32 size)
+{
+  GstBuffer *buffer;
+
+  g_return_val_if_fail (pool != NULL, NULL);
+  g_return_val_if_fail (pool->buffer_new != NULL, NULL);
+  
+  buffer = pool->buffer_new (pool, offset, size, pool->user_data);
+  buffer->pool = pool;
+  buffer->free = pool->buffer_free;
+  buffer->copy = pool->buffer_copy;
+  
+  GST_INFO (GST_CAT_BUFFER,"creating new buffer %p from pool %p (size %x, offset %x)", 
+                 buffer, pool, size, offset);
+
+  return buffer;
+}
+
+/**
+ * gst_buffer_create_sub:
+ * @parent: parent buffer
+ * @offset: offset into parent buffer
+ * @size: size of new subbuffer
+ *
+ * Creates a sub-buffer from the parent at a given offset.
+ *
+ * Returns: new buffer
+ */
+GstBuffer*
+gst_buffer_create_sub (GstBuffer *parent,
+                      guint32 offset,
+                      guint32 size) 
+{
+  GstBuffer *buffer;
+
+  g_return_val_if_fail (parent != NULL, NULL);
+  g_return_val_if_fail (GST_BUFFER_REFCOUNT(parent) > 0, NULL);
+  g_return_val_if_fail (size > 0, NULL);
+  g_return_val_if_fail ((offset+size) <= parent->size, NULL);
+
+  buffer = gst_mem_pool_alloc (_gst_buffer_pool);
+  GST_DATA_TYPE(buffer) = _gst_buffer_type;
+
+  GST_INFO (GST_CAT_BUFFER,"creating new subbuffer %p from parent %p (size %u, offset %u)", 
+                 buffer, parent, size, offset);
+
+#ifdef HAVE_ATOMIC_H
+  atomic_set (&buffer->refcount, 1);
+#else
+  buffer->refcount = 1;
+#endif
+
+  // copy flags and type from parent, for lack of better
+  buffer->flags = parent->flags;
+
+  // set the data pointer, size, offset, and maxsize
+  buffer->data = parent->data + offset;
+  buffer->size = size;
+  buffer->maxsize = parent->size - offset;
+
+  // deal with bogus/unknown offsets
+  if (parent->offset != -1)
+    buffer->offset = parent->offset + offset;
+  else
+    buffer->offset = -1;
+
+  // again, for lack of better, copy parent's timestamp
+  buffer->timestamp = parent->timestamp;
+  buffer->maxage = parent->maxage;
+
+  // if the parent buffer is a subbuffer itself, use its parent, a real buffer
+  if (parent->parent != NULL)
+    parent = parent->parent;
+
+  // set parentage and reference the parent
+  buffer->parent = parent;
+  gst_buffer_ref (parent);
+
+  buffer->pool = NULL;
+
+  return buffer;
+}
+
+
+// FIXME FIXME: how does this overlap with the newly-added gst_buffer_span() ???
+/**
+ * gst_buffer_append:
+ * @buffer: a buffer
+ * @append: the buffer to append
+ *
+ * Creates a new buffer by appending the data of append to the
+ * existing data of buffer.
+ *
+ * Returns: new buffer
+ */
+GstBuffer*
+gst_buffer_append (GstBuffer *buffer, 
+                  GstBuffer *append) 
+{
+  guint size;
+  GstBuffer *newbuf;
+
+  g_return_val_if_fail (buffer != NULL, NULL);
+  g_return_val_if_fail (append != NULL, NULL);
+  g_return_val_if_fail (buffer->pool == NULL, NULL);
+  g_return_val_if_fail (GST_BUFFER_REFCOUNT(buffer) > 0, NULL);
+  g_return_val_if_fail (GST_BUFFER_REFCOUNT(append) > 0, NULL);
+
+  GST_INFO (GST_CAT_BUFFER,"appending buffers %p and %p",buffer,append);
+
+  GST_BUFFER_LOCK (buffer);
+  // the buffer is not used by anyone else
+  if (GST_BUFFER_REFCOUNT (buffer) == 1 && buffer->parent == NULL 
+         && !GST_BUFFER_FLAG_IS_SET (buffer, GST_BUFFER_DONTFREE)) {
+    // save the old size
+    size = buffer->size;
+    buffer->size += append->size;
+    buffer->data = g_realloc (buffer->data, buffer->size);
+    memcpy(buffer->data + size, append->data, append->size);
+    GST_BUFFER_UNLOCK (buffer);
+  }
+  // the buffer is used, create a new one 
+  else {
+    newbuf = gst_buffer_new ();
+    newbuf->size = buffer->size+append->size;
+    newbuf->data = g_malloc (newbuf->size);
+    memcpy (newbuf->data, buffer->data, buffer->size);
+    memcpy (newbuf->data+buffer->size, append->data, append->size);
+    GST_BUFFER_UNLOCK (buffer);
+    gst_buffer_unref (buffer);
+    buffer = newbuf;
+  }
+  return buffer;
+}
+
+/**
+ * gst_buffer_destroy:
+ * @buffer: the GstBuffer to destroy
+ *
+ * destroy the buffer
+ */
+void 
+gst_buffer_destroy (GstBuffer *buffer) 
+{
+
+  g_return_if_fail (buffer != NULL);
+  
+  GST_INFO (GST_CAT_BUFFER, "freeing %sbuffer %p",
+           (buffer->parent?"sub":""),
+           buffer);
+  
+  // free the data only if there is some, DONTFREE isn't set, and not sub
+  if (GST_BUFFER_DATA (buffer) &&
+      !GST_BUFFER_FLAG_IS_SET (buffer, GST_BUFFER_DONTFREE) &&
+      (buffer->parent == NULL)) {
+    // if there's a free function, use it
+    if (buffer->free != NULL) {
+      (buffer->free)(buffer);
+    } else {
+      g_free (GST_BUFFER_DATA (buffer));
+    }
+  }
+
+  // unreference the parent if there is one
+  if (buffer->parent != NULL)
+    gst_buffer_unref (buffer->parent);
+
+  // remove it entirely from memory
+  gst_mem_pool_free (_gst_buffer_pool,buffer);
+}
+
+/**
+ * gst_buffer_ref:
+ * @buffer: the GstBuffer to reference
+ *
+ * Increment the refcount of this buffer.
+ */
+void 
+gst_buffer_ref (GstBuffer *buffer) 
+{
+  g_return_if_fail (buffer != NULL);
+  g_return_if_fail (GST_BUFFER_REFCOUNT(buffer) > 0);
+
+  GST_INFO (GST_CAT_BUFFER, "ref buffer %p\n", buffer);
+
+#ifdef HAVE_ATOMIC_H
+  atomic_inc (&(buffer->refcount));
+#else
+  GST_BUFFER_LOCK (buffer);
+  buffer->refcount++;
+  GST_BUFFER_UNLOCK (buffer);
+#endif
+}
+
+/**
+ * gst_buffer_unref:
+ * @buffer: the GstBuffer to unref
+ *
+ * Decrement the refcount of this buffer. If the refcount is
+ * zero, the buffer will be destroyed.
+ */
+void 
+gst_buffer_unref (GstBuffer *buffer) 
+{
+  gint zero;
+
+  g_return_if_fail (buffer != NULL);
+  g_return_if_fail (GST_BUFFER_REFCOUNT(buffer) > 0);
+
+  GST_INFO (GST_CAT_BUFFER, "unref buffer %p\n", buffer);
+
+#ifdef HAVE_ATOMIC_H
+  zero = atomic_dec_and_test (&(buffer->refcount));
+#else
+  GST_BUFFER_LOCK (buffer);
+  buffer->refcount--;
+  zero = (buffer->refcount == 0);
+  GST_BUFFER_UNLOCK (buffer);
+#endif
+
+  /* if we ended up with the refcount at zero, destroy the buffer */
+  if (zero) {
+    gst_buffer_destroy (buffer);
+  }
+}
+
+/**
+ * gst_buffer_copy:
+ * @buffer: the orignal GstBuffer to make a copy of
+ *
+ * Make a full copy of the give buffer, data and all.
+ *
+ * Returns: new buffer
+ */
+GstBuffer *
+gst_buffer_copy (GstBuffer *buffer)
+{
+  GstBuffer *newbuf;
+
+  g_return_val_if_fail (GST_BUFFER_REFCOUNT(buffer) > 0, NULL);
+
+  // if a copy function exists, use it, else copy the bytes
+  if (buffer->copy != NULL) {
+    newbuf = (buffer->copy)(buffer);
+  } else {
+    // allocate a new buffer
+    newbuf = gst_buffer_new();
+
+    // copy the absolute size
+    newbuf->size = buffer->size;
+    // allocate space for the copy
+    newbuf->data = (guchar *)g_malloc (buffer->size);
+    // copy the data straight across
+    memcpy(newbuf->data,buffer->data,buffer->size);
+    // the new maxsize is the same as the size, since we just malloc'd it
+    newbuf->maxsize = newbuf->size;
+  }
+  newbuf->offset = buffer->offset;
+  newbuf->timestamp = buffer->timestamp;
+  newbuf->maxage = buffer->maxage;
+
+  // since we just created a new buffer, so we have no ties to old stuff
+  newbuf->parent = NULL;
+  newbuf->pool = NULL;
+
+  return newbuf;
+}
+
+/*
+ * gst_buffer_is_span_fast
+ * @buf1: first source buffer
+ * @buf2: second source buffer
+ *
+ * Determines whether a gst_buffer_span is free, or requires a memcpy. 
+ *
+ * Returns: TRUE if the buffers are contiguous, FALSE if a copy would be required.
+ */
+gboolean
+gst_buffer_is_span_fast (GstBuffer *buf1, GstBuffer *buf2)
+{
+  g_return_val_if_fail (GST_BUFFER_REFCOUNT(buf1) > 0, FALSE);
+  g_return_val_if_fail (GST_BUFFER_REFCOUNT(buf2) > 0, FALSE);
+
+  return (buf1->parent && buf2->parent && 
+         (buf1->parent == buf2->parent) &&
+          ((buf1->data + buf1->size) == buf2->data));
+}
+
+
+/**
+ * gst_buffer_span:
+ * @buf1: first source buffer to merge
+ * @offset: offset in first buffer to start new buffer
+ * @buf2: second source buffer to merge
+ * @len: length of new buffer
+ *
+ * Create a new buffer that consists of part of buf1 and buf2.
+ * Logically, buf1 and buf2 are concatenated into a single larger
+ * buffer, and a new buffer is created at the given offset inside
+ * this space, with a given length.
+ *
+ * If the two source buffers are children of the same larger buffer,
+ * and are contiguous, the new buffer will be a child of the shared
+ * parent, and thus no copying is necessary.
+ *
+ * Returns: new buffer that spans the two source buffers
+ */
+// FIXME need to think about CoW and such...
+GstBuffer *
+gst_buffer_span (GstBuffer *buf1, guint32 offset, GstBuffer *buf2, guint32 len)
+{
+  GstBuffer *newbuf;
+
+  g_return_val_if_fail (GST_BUFFER_REFCOUNT(buf1) > 0, NULL);
+  g_return_val_if_fail (GST_BUFFER_REFCOUNT(buf2) > 0, NULL);
+
+  // make sure buf1 has a lower address than buf2
+  if (buf1->data > buf2->data) {
+    GstBuffer *tmp = buf1;
+    g_print ("swapping buffers\n");
+    buf1 = buf2;
+    buf2 = tmp;
+  }
+
+  // if the two buffers have the same parent and are adjacent
+  if (gst_buffer_is_span_fast(buf1,buf2)) {
+    // we simply create a subbuffer of the common parent
+    newbuf = gst_buffer_create_sub (buf1->parent, buf1->data - (buf1->parent->data) + offset, len);
+  }
+  else {
+    g_print ("slow path taken in buffer_span\n");
+    // otherwise we simply have to brute-force copy the buffers
+    newbuf = gst_buffer_new ();
+
+    // put in new size
+    newbuf->size = len;
+    // allocate space for the copy
+    newbuf->data = (guchar *)g_malloc(len);
+    // 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));
+
+    if (newbuf->offset != -1)
+      newbuf->offset = buf1->offset + offset;
+    newbuf->timestamp = buf1->timestamp;
+    if (buf2->maxage > buf1->maxage) newbuf->maxage = buf2->maxage;
+    else newbuf->maxage = buf1->maxage;
+
+  }
+
+  return newbuf;
+}
+
+
+/**
+ * gst_buffer_merge:
+ * @buf1: first source buffer to merge
+ * @buf2: second source buffer to merge
+ *
+ * Create a new buffer that is the concatenation of the two source
+ * buffers.  The original source buffers will not be modified or
+ * unref'd.
+ *
+ * Internally is nothing more than a specialized gst_buffer_span,
+ * so the same optimizations can occur.
+ *
+ * Returns: new buffer that's the concatenation of the source buffers
+ */
+GstBuffer *
+gst_buffer_merge (GstBuffer *buf1, GstBuffer *buf2)
+{
+  // we're just a specific case of the more general gst_buffer_span()
+  return gst_buffer_span (buf1, 0, buf2, buf1->size + buf2->size);
+}
diff --git a/test/bufspeed/gstbuffer.h b/test/bufspeed/gstbuffer.h
new file mode 100644 (file)
index 0000000..d3a5a87
--- /dev/null
@@ -0,0 +1,174 @@
+/* GStreamer
+ * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
+ *                    2000 Wim Taymans <wtay@chello.be>
+ *
+ * gstbuffer.h: Header for GstBuffer 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_H__
+#define __GST_BUFFER_H__
+
+//
+// Define this to add file:line info to each GstBuffer showing
+// the location in the source code where the buffer was created.
+// 
+// #define GST_BUFFER_WHERE
+//
+// Then in gdb, you can `call gst_buffer_print_live()' to get a list
+// of allocated GstBuffers and also the file:line where they were
+// allocated.
+//
+
+#include <gst/gstdata.h>
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#ifdef HAVE_ATOMIC_H
+#include <asm/atomic.h>
+#endif
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+extern GType _gst_buffer_type;
+
+#define GST_TYPE_BUFFER                (_gst_buffer_type)
+#define GST_BUFFER(buf)        ((GstBuffer *)(buf))
+#define GST_IS_BUFFER(buf)     (GST_DATA_TYPE(buf) == GST_TYPE_BUFFER)
+
+#define GST_BUFFER_FLAGS(buf)                  (GST_BUFFER(buf)->flags)
+#define GST_BUFFER_FLAG_IS_SET(buf,flag)       (GST_BUFFER_FLAGS(buf) & (1<<(flag)))
+#define GST_BUFFER_FLAG_SET(buf,flag)          G_STMT_START{ (GST_BUFFER_FLAGS(buf) |= (1<<(flag))); }G_STMT_END
+#define GST_BUFFER_FLAG_UNSET(buf,flag)        G_STMT_START{ (GST_BUFFER_FLAGS(buf) &= ~(1<<(flag))); }G_STMT_END
+
+
+#define GST_BUFFER_DATA(buf)           (GST_BUFFER(buf)->data)
+#define GST_BUFFER_SIZE(buf)           (GST_BUFFER(buf)->size)
+#define GST_BUFFER_OFFSET(buf)         (GST_BUFFER(buf)->offset)
+#define GST_BUFFER_MAXSIZE(buf)                (GST_BUFFER(buf)->maxsize)
+#define GST_BUFFER_TIMESTAMP(buf)      (GST_BUFFER(buf)->timestamp)
+#define GST_BUFFER_MAXAGE(buf)         (GST_BUFFER(buf)->maxage)
+#define GST_BUFFER_BUFFERPOOL(buf)     (GST_BUFFER(buf)->pool)
+#define GST_BUFFER_PARENT(buf)         (GST_BUFFER(buf)->parent)
+#define GST_BUFFER_POOL_PRIVATE(buf)   (GST_BUFFER(buf)->pool_private)
+#define GST_BUFFER_COPY_FUNC(buf)      (GST_BUFFER(buf)->copy)
+#define GST_BUFFER_FREE_FUNC(buf)      (GST_BUFFER(buf)->free)
+
+
+#define GST_BUFFER_LOCK(buf)   (g_mutex_lock(GST_BUFFER(buf)->lock))
+#define GST_BUFFER_TRYLOCK(buf)        (g_mutex_trylock(GST_BUFFER(buf)->lock))
+#define GST_BUFFER_UNLOCK(buf) (g_mutex_unlock(GST_BUFFER(buf)->lock))
+
+
+typedef enum {
+  GST_BUFFER_READONLY,
+  GST_BUFFER_ORIGINAL,
+  GST_BUFFER_DONTFREE,
+
+  GST_BUFFER_FLUSH,
+  GST_BUFFER_EOS,
+  GST_BUFFER_DISCONTINUOUS,
+} GstBufferFlags;
+
+
+typedef struct _GstBuffer GstBuffer;
+
+
+typedef void       (*GstBufferFreeFunc)        (GstBuffer *buf);
+typedef GstBuffer *(*GstBufferCopyFunc)        (GstBuffer *srcbuf);
+
+
+#include <gst/gstbufferpool.h>
+
+struct _GstBuffer {
+  GstData              data_type;
+
+  /* locking */
+  GMutex               *lock;
+
+  /* refcounting */
+#ifdef HAVE_ATOMIC_H
+  atomic_t             refcount;
+#define GST_BUFFER_REFCOUNT(buf)       (atomic_read(&(GST_BUFFER((buf))->refcount)))
+#else
+  int                  refcount;
+#define GST_BUFFER_REFCOUNT(buf)       (GST_BUFFER(buf)->refcount)
+#endif
+
+  /* flags */
+  guint16              flags;
+
+  /* pointer to data, its size, and offset in original source if known */
+  guchar               *data;
+  guint32              size;
+  guint32              maxsize;
+  guint32              offset;
+
+  /* timestamp */
+  gint64               timestamp;
+  gint64               maxage;
+
+  /* subbuffer support, who's my parent? */
+  GstBuffer            *parent;
+
+  /* this is a pointer to the buffer pool (if any) */
+  GstBufferPool        *pool;
+  gpointer             pool_private;
+
+  /* utility function pointers */
+  GstBufferFreeFunc    free;           // free the data associated with the buffer
+  GstBufferCopyFunc    copy;           // copy the data from one buffer to another
+};
+
+/* initialisation */
+void           _gst_buffer_initialize          (void);
+/* creating a new buffer from scratch */
+GstBuffer*     gst_buffer_new                  (void);
+GstBuffer*     gst_buffer_new_from_pool        (GstBufferPool *pool, guint32 offset, guint32 size);
+
+/* creating a subbuffer */
+GstBuffer*     gst_buffer_create_sub           (GstBuffer *parent, guint32 offset, guint32 size);
+
+/* refcounting */
+void           gst_buffer_ref                  (GstBuffer *buffer);
+void           gst_buffer_unref                (GstBuffer *buffer);
+
+/* destroying the buffer */
+void           gst_buffer_destroy              (GstBuffer *buffer);
+
+/* copy buffer */
+GstBuffer*     gst_buffer_copy                 (GstBuffer *buffer);
+
+/* merge, span, or append two buffers, intelligently */
+GstBuffer*     gst_buffer_merge                (GstBuffer *buf1, GstBuffer *buf2);
+GstBuffer*     gst_buffer_span                 (GstBuffer *buf1,guint32 offset,GstBuffer *buf2,guint32 len);
+GstBuffer*     gst_buffer_append               (GstBuffer *buf, GstBuffer *buf2);
+
+gboolean       gst_buffer_is_span_fast         (GstBuffer *buf1, GstBuffer *buf2);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif /* __GST_BUFFER_H__ */
diff --git a/test/bufspeed/gstmempool.c b/test/bufspeed/gstmempool.c
new file mode 100644 (file)
index 0000000..c9f956e
--- /dev/null
@@ -0,0 +1,191 @@
+#include "gstmempool.h"
+
+#ifdef __SMP__
+#define POOL_LOCK "lock ; "
+#else
+#define POOL_LOCK ""
+#endif
+
+#define GST_MEM_POOL_AREA(pool)        (((GstMemPoolElement*)(pool))->area)
+#define GST_MEM_POOL_DATA(pool)        ((gpointer)(((GstMemPoolElement*)(pool)) + 1))
+#define GST_MEM_POOL_LINK(mem)                 ((GstMemPoolElement*)((guint8*)(mem) - sizeof (GstMemPoolElement)))
+
+#define USE_ASM
+
+/*******************************************************
+ *         area size
+ * +-----------------------------------------+
+ *   pool size
+ * +------------+
+ *
+ * !next!data... !next!data.... !next!data...
+ *  !             ^ !            ^ !
+ *  +-------------+ +------------+ +---> NULL
+ *
+ */
+static gboolean
+populate (GstMemPool *mem_pool) 
+{
+  guint8 *area;
+  gint i;
+
+  if (mem_pool->cleanup)
+    return FALSE;
+
+  area = (guint8 *) g_malloc (mem_pool->area_size);
+
+  for (i=0; i < mem_pool->area_size; i += mem_pool->pool_size) { 
+    guint8 *areap = area + i;
+
+    GST_MEM_POOL_AREA (areap) = (GstMemPoolElement *)area;
+
+    if (mem_pool->alloc_func) {
+      mem_pool->alloc_func (mem_pool, GST_MEM_POOL_DATA (areap));
+    }
+
+    gst_mem_pool_free (mem_pool, GST_MEM_POOL_DATA (areap));
+  }
+
+  return TRUE;
+}
+
+
+GstMemPool*
+gst_mem_pool_new (gchar* name, gint atom_size, gulong area_size, gint type, 
+                 GstMemPoolAllocFunc alloc_func,
+                 GstMemPoolFreeFunc free_func)
+{
+  GstMemPool *mem_pool;
+
+  g_return_val_if_fail (atom_size > 0, NULL);
+  g_return_val_if_fail (area_size >= atom_size, NULL);
+
+  mem_pool = g_malloc (sizeof (GstMemPool));
+
+  mem_pool->pool_size = atom_size + sizeof (GstMemPoolElement);
+  area_size = (area_size/atom_size) * mem_pool->pool_size;
+
+  mem_pool->name = g_strdup (name);
+  mem_pool->free = NULL;
+  mem_pool->cnt = 0;
+  mem_pool->atom_size = atom_size;
+  mem_pool->area_size = area_size;
+  mem_pool->cleanup = FALSE;
+  mem_pool->alloc_func = alloc_func;
+  mem_pool->free_func = free_func;
+  mem_pool->chunk_lock = g_mutex_new ();
+
+  populate (mem_pool);
+
+  return mem_pool;
+}
+
+static gboolean
+free_area (gpointer key, gpointer value, gpointer user_data)
+{
+  g_print ("free %p\n", key);
+  g_free (key);
+
+  return TRUE;
+}
+
+void
+gst_mem_pool_destroy (GstMemPool *mem_pool) 
+{
+  GHashTable *elements = g_hash_table_new (NULL, NULL);
+  gpointer data;
+
+  mem_pool->cleanup = TRUE;
+
+  data = gst_mem_pool_alloc (mem_pool);
+  while (data) {
+    GstMemPoolElement *elem = GST_MEM_POOL_LINK (data);
+
+    g_hash_table_insert (elements, GST_MEM_POOL_AREA (elem), NULL); 
+    
+    data = gst_mem_pool_alloc (mem_pool);
+  } 
+  g_hash_table_foreach_remove (elements, free_area, NULL);
+
+  g_hash_table_destroy (elements);
+  g_free (mem_pool->name);
+  g_free (mem_pool);
+}
+
+gpointer
+gst_mem_pool_alloc (GstMemPool *mem_pool)
+{
+  GstMemPoolElement *pool = NULL;
+  
+  g_return_val_if_fail (mem_pool != NULL, NULL);
+
+again:
+#ifdef USE_ASM
+  __asm__ __volatile__ ("  testl %%eax, %%eax          \n\t"
+                       "  jz 20f                       \n"
+                       "10:                            \t"
+                       "  movl (%%eax), %%ebx          \n\t"
+                       "  movl %%edx, %%ecx            \n\t"
+                       "  incl %%ecx                   \n\t"
+                       POOL_LOCK "cmpxchg8b %1         \n\t"
+                       "  jz 20f                       \n\t"
+                       "  testl %%eax, %%eax           \n\t"
+                       "  jnz 10b                      \n"
+                       "20:\t"
+                       :"=a" (pool)
+                       :"m" (*mem_pool), "a" (mem_pool->free), "d" (mem_pool->cnt)
+                       :"ecx", "ebx");
+#else
+  g_mutex_lock (mem_pool->chunk_lock);
+  if (mem_pool->free) {
+    pool = mem_pool->free;
+    mem_pool->free = pool->link;
+  }
+  g_mutex_unlock (mem_pool->chunk_lock);
+#endif
+
+  if (!pool) {
+    //g_print ("extending\n");
+    if (populate (mem_pool))
+      goto again;
+    else 
+      return NULL;
+  }
+  return GST_MEM_POOL_DATA (pool);
+}
+
+gpointer
+gst_mem_pool_alloc0 (GstMemPool *mem_pool)
+{
+  gpointer mem = gst_mem_pool_alloc (mem_pool);
+
+  if (mem)
+    memset (mem, 0, mem_pool->atom_size);
+  
+  return mem;
+}
+
+void
+gst_mem_pool_free (GstMemPool *mem_pool, gpointer mem)
+{
+  GstMemPoolElement *pool;
+  
+  g_return_if_fail (mem_pool != NULL);
+  g_return_if_fail (mem != NULL);
+
+  pool = GST_MEM_POOL_LINK (mem);
+
+#ifdef USE_ASM
+  __asm__ __volatile__ ( "1:                           \t"
+                       "  movl %2, (%1)                \n"
+                       POOL_LOCK "cmpxchg %1, %0       \n\t"
+                       "  jnz 1b                       \n\t"
+                       :
+                       :"m" (*mem_pool), "r" (pool), "a" (mem_pool->free));
+#else
+  g_mutex_lock (mem_pool->chunk_lock);
+  pool->link = mem_pool->free;
+  mem_pool->free = pool;
+  g_mutex_unlock (mem_pool->chunk_lock);
+#endif
+}
diff --git a/test/bufspeed/gstmempool.h b/test/bufspeed/gstmempool.h
new file mode 100644 (file)
index 0000000..307b768
--- /dev/null
@@ -0,0 +1,43 @@
+#include <glib.h>
+
+typedef struct _GstMemPool GstMemPool;
+typedef struct _GstMemPoolElement GstMemPoolElement;
+
+typedef void (*GstMemPoolAllocFunc) (GstMemPool *pool, gpointer data);
+typedef void (*GstMemPoolFreeFunc)  (GstMemPool *pool, gpointer data);
+
+struct _GstMemPoolElement
+{
+  GstMemPoolElement *link;             /* next cell in the lifo */
+  GstMemPoolElement *area;
+};
+
+struct _GstMemPool
+{
+  volatile GstMemPoolElement *free;    /* the first free element */
+  volatile gulong cnt;                 /* used to avoid ABA problem */
+
+  gchar *name;
+  gulong area_size;
+  gulong pool_size;
+  gulong atom_size;
+  gboolean cleanup;
+  GstMemPoolAllocFunc alloc_func;
+  GstMemPoolFreeFunc free_func;
+  GMutex *chunk_lock;
+};
+
+
+GstMemPool*    gst_mem_pool_new                (gchar *name,
+                                                gint atom_size,
+                                                gulong area_size,
+                                                gint type,
+                                                GstMemPoolAllocFunc alloc_func,
+                                                GstMemPoolFreeFunc free_func);
+
+void           gst_mem_pool_destroy            (GstMemPool *mem_pool);
+
+gpointer       gst_mem_pool_alloc              (GstMemPool *mem_pool);
+gpointer       gst_mem_pool_alloc0             (GstMemPool *mem_pool);
+void           gst_mem_pool_free               (GstMemPool *mem_pool,
+                                                gpointer mem);
diff --git a/test/bufspeed/test1.c b/test/bufspeed/test1.c
new file mode 100644 (file)
index 0000000..951af46
--- /dev/null
@@ -0,0 +1,19 @@
+#include "gstbuffer.h"
+
+int 
+main (int argc, char *argv[])
+{
+  GstBuffer *buf;
+  guint i;
+  
+  g_thread_init (NULL);
+  gtk_init (&argc, &argv);
+  _gst_buffer_initialize ();
+
+  for (i=0; i<5000000; i++) {
+    buf = gst_buffer_new ();
+    gst_buffer_unref (buf);
+  }
+
+  return 0;
+}
diff --git a/test/bufspeed/test2.c b/test/bufspeed/test2.c
new file mode 100644 (file)
index 0000000..616ad1f
--- /dev/null
@@ -0,0 +1,19 @@
+#include <gst/gst.h>
+
+int 
+main (int argc, char *argv[])
+{
+  GstBuffer *buf;
+  guint i;
+  
+  g_thread_init (NULL);
+  gtk_init (&argc, &argv);
+  _gst_buffer_initialize ();
+
+  for (i=0; i<5000000; i++) {
+    buf = gst_buffer_new ();
+    gst_buffer_unref (buf);
+  }
+
+  return 0;
+}
index 833e3fe..d82c4d0 100644 (file)
@@ -86,7 +86,9 @@ main (int argc,char *argv[])
 
   gtk_widget_show_all(appwindow);
 
+#ifndef GST_DISABLE_LOADSAVE
   xmlSaveFile("dvshow.xml",gst_xml_write(GST_ELEMENT(bin)));
+#endif
 
   gst_element_set_state(GST_ELEMENT(bin),GST_STATE_PLAYING);
 
diff --git a/test/events/Makefile.am b/test/events/Makefile.am
new file mode 100644 (file)
index 0000000..f2300be
--- /dev/null
@@ -0,0 +1,4 @@
+noinst_PROGRAMS = seek
+
+LIBS += $(GST_LIBS)
+CFLAGS += $(GST_CFLAGS) 
diff --git a/test/events/seek.c b/test/events/seek.c
new file mode 100644 (file)
index 0000000..89a6e27
--- /dev/null
@@ -0,0 +1,68 @@
+#include <gst/gst.h>
+
+int
+main (int argc, char *argv[])
+{
+  GstBin *bin;
+  GstElement *src, *sink;
+  GstPad *srcpad, *sinkpad;
+
+//  _gst_plugin_spew = TRUE;
+  gst_init (&argc, &argv);
+
+  bin = GST_BIN (gst_pipeline_new ("pipeline"));
+  g_return_val_if_fail (bin != NULL, -1);
+
+  g_print ("--- creating src and sink elements\n");
+  src = gst_elementfactory_make ("fakesrc", "src");
+  g_return_val_if_fail (src != NULL, -1);
+  sink = gst_elementfactory_make ("fakesink", "sink");
+  g_return_val_if_fail (sink != NULL, -1);
+
+  g_print ("--- about to add the elements to the bin\n");
+  gst_bin_add (bin, GST_ELEMENT (src));
+  gst_bin_add (bin, GST_ELEMENT (sink));
+
+  g_print ("--- getting pads\n");
+  srcpad = gst_element_get_pad (src, "src");
+  g_return_val_if_fail (srcpad != NULL, -1);
+  sinkpad = gst_element_get_pad (sink, "sink");
+  g_return_val_if_fail (srcpad != NULL, -1);
+
+  g_print ("--- connecting\n");
+  gst_pad_connect (srcpad, sinkpad);
+
+  g_print ("--- setting up\n");
+  gst_element_set_state (GST_ELEMENT (bin), GST_STATE_PLAYING);
+
+  g_print ("--- iterating\n");
+  gst_bin_iterate (bin);
+  gst_bin_iterate (bin);
+
+  g_print ("--- seek to 100\n");
+  gst_pad_send_event (srcpad, gst_event_new_seek (GST_SEEK_ANY, 100, FALSE));
+
+  g_print ("--- seek done, iterating\n");
+  gst_bin_iterate (bin);
+  gst_bin_iterate (bin);
+
+  g_print ("--- seek to 200 with flush\n");
+  gst_pad_send_event (srcpad, gst_event_new_seek (GST_SEEK_ANY, 200, TRUE));
+
+  g_print ("--- seek done, iterating\n");
+  gst_bin_iterate (bin);
+  gst_bin_iterate (bin);
+  gst_bin_iterate (bin);
+
+  g_print ("--- flush\n");
+  gst_pad_send_event (srcpad, gst_event_new_flush ());
+
+  g_print ("--- flush done, iterating\n");
+  gst_bin_iterate (bin);
+  gst_bin_iterate (bin);
+
+  g_print ("--- cleaning up\n");
+  gst_element_set_state (GST_ELEMENT (bin), GST_STATE_NULL);
+
+  return 0;
+}
index 35f23d0..5c71c6f 100644 (file)
@@ -140,7 +140,9 @@ gst_play_have_type (GstElement *typefind, GstCaps *caps, GstPlayInfo *info)
 
   gst_element_set_state (pipeline, GST_STATE_PLAYING);
       
+#ifndef GST_DISABLE_LOADSAVE
   xmlSaveFile("xmlTest.gst", gst_xml_write (GST_ELEMENT (pipeline)));
+#endif
 }
 
 
diff --git a/test/memchunk/Makefile.am b/test/memchunk/Makefile.am
new file mode 100644 (file)
index 0000000..e3198c2
--- /dev/null
@@ -0,0 +1,7 @@
+noinst_PROGRAMS = gmemchunktest gstmemchunktest
+
+gmemchunktest_SOURCES = gmemchunktest.c
+gstmemchunktest_SOURCES = gstmemchunktest.c gstmemchunk.c gstmemchunk.h
+
+LIBS += $(GST_LIBS)
+CFLAGS += $(GST_CFLAGS) 
diff --git a/test/memchunk/gmemchunktest.c b/test/memchunk/gmemchunktest.c
new file mode 100644 (file)
index 0000000..b3301f1
--- /dev/null
@@ -0,0 +1,78 @@
+#include <gst/gst.h>
+
+#define MAX_THREADS  100
+
+static GMemChunk *_chunks;
+static GMutex *_lock;
+
+static gint num_allocs;
+static gint num_threads;
+
+static gpointer 
+alloc_chunk (void)
+{
+  gpointer ret;
+  g_mutex_lock (_lock); 
+  ret = g_mem_chunk_alloc (_chunks);
+  g_mutex_unlock (_lock); 
+
+  return ret;
+}
+
+static void 
+free_chunk (gpointer chunk)
+{
+  g_mutex_lock (_lock); 
+  g_mem_chunk_free (_chunks, chunk);
+  g_mutex_unlock (_lock); 
+}
+
+
+void*
+run_test (void *threadid)
+{
+  gint i;
+  gpointer chunk;
+  sleep(1);
+
+  for (i = 0; i<num_allocs; i++) {
+    chunk = alloc_chunk ();
+    free_chunk (chunk);
+  }
+
+  pthread_exit(NULL);
+}
+
+
+gint 
+main (gint argc, gchar *argv[]) 
+{
+  pthread_t threads[MAX_THREADS];
+  int rc, t;
+  gst_init (&argc, &argv);
+
+  if (argc != 3) {
+    g_print ("usage: %s <num_threads> <num_allocs>\n", argv[0]);
+    exit (-1);
+  }
+
+  num_threads = atoi (argv[1]);
+  num_allocs = atoi (argv[2]);
+
+  _chunks = g_mem_chunk_new ("test", 32, 32 * 16, G_ALLOC_AND_FREE);
+  _lock = g_mutex_new ();
+
+  for(t=0; t < num_threads; t++) {
+    rc = pthread_create (&threads[t], NULL, run_test, (void *)t);
+    if (rc) {
+      printf ("ERROR: return code from pthread_create() is %d\n", rc);
+      printf ("Code %d= %s\n", rc, strerror(rc));
+      exit (-1);
+    }
+  }
+  printf ("main(): Created %d threads.\n", t);
+
+  pthread_exit (NULL);
+  g_mem_chunk_info();
+}
diff --git a/test/memchunk/gstmemchunk.c b/test/memchunk/gstmemchunk.c
new file mode 100644 (file)
index 0000000..be99be5
--- /dev/null
@@ -0,0 +1,162 @@
+#include "gstmemchunk.h"
+
+#ifdef __SMP__
+#define CHUNK_LOCK "lock ; "
+#else
+#define CHUNK_LOCK ""
+#endif
+
+#define GST_MEM_CHUNK_AREA(chunk)      (((GstMemChunkElement*)(chunk))->area)
+#define GST_MEM_CHUNK_DATA(chunk)      ((gpointer)(((GstMemChunkElement*)(chunk)) + 1))
+#define GST_MEM_CHUNK_LINK(mem)        ((GstMemChunkElement*)((guint8*)(mem) - sizeof (GstMemChunkElement)))
+
+/*******************************************************
+ *         area size
+ * +-----------------------------------------+
+ *   chunk size
+ * +------------+
+ *
+ * !next!data... !next!data.... !next!data...
+ *  !             ^ !            ^ !
+ *  +-------------+ +------------+ +---> NULL
+ *
+ */
+static gboolean
+populate (GstMemChunk *mem_chunk) 
+{
+  guint8 *area;
+  gint i;
+
+  if (mem_chunk->cleanup)
+    return FALSE;
+
+  area = (guint8 *) g_malloc (mem_chunk->area_size);
+  g_print ("alloc %p\n", area);
+
+  for (i=0; i < mem_chunk->area_size; i += mem_chunk->chunk_size) { 
+    GST_MEM_CHUNK_AREA (area + i) = (GstMemChunkElement *)area;
+    gst_mem_chunk_free (mem_chunk, GST_MEM_CHUNK_DATA (area + i));
+  }
+
+  return TRUE;
+}
+
+
+GstMemChunk*
+gst_mem_chunk_new (gchar* name, gint atom_size, gulong area_size, gint type)
+{
+  GstMemChunk *mem_chunk;
+
+  g_return_val_if_fail (atom_size > 0, NULL);
+  g_return_val_if_fail (area_size >= atom_size, NULL);
+
+  mem_chunk = g_malloc (sizeof (GstMemChunk));
+
+  mem_chunk->chunk_size = atom_size + sizeof (GstMemChunkElement);
+  area_size = (area_size/atom_size) * mem_chunk->chunk_size;
+
+  mem_chunk->name = g_strdup (name);
+  mem_chunk->free = NULL;
+  mem_chunk->cnt = 0;
+  mem_chunk->atom_size = atom_size;
+  mem_chunk->area_size = area_size;
+  mem_chunk->cleanup = FALSE;
+
+  populate (mem_chunk);
+
+  return mem_chunk;
+}
+
+static gboolean
+free_area (gpointer key, gpointer value, gpointer user_data)
+{
+  g_print ("free %p\n", key);
+  g_free (key);
+
+  return TRUE;
+}
+
+void
+gst_mem_chunk_destroy (GstMemChunk *mem_chunk) 
+{
+  GHashTable *elements = g_hash_table_new (NULL, NULL);
+  gpointer data;
+
+  mem_chunk->cleanup = TRUE;
+
+  data = gst_mem_chunk_alloc (mem_chunk);
+  while (data) {
+    GstMemChunkElement *elem = GST_MEM_CHUNK_LINK (data);
+
+    g_hash_table_insert (elements, GST_MEM_CHUNK_AREA (elem), NULL); 
+    
+    data = gst_mem_chunk_alloc (mem_chunk);
+  } 
+  g_hash_table_foreach_remove (elements, free_area, NULL);
+
+  g_hash_table_destroy (elements);
+  g_free (mem_chunk->name);
+  g_free (mem_chunk);
+}
+
+gpointer
+gst_mem_chunk_alloc (GstMemChunk *mem_chunk)
+{
+  GstMemChunkElement *chunk = NULL;
+  
+  g_return_val_if_fail (mem_chunk != NULL, NULL);
+
+again:
+  __asm__ __volatile__ ("  testl %%eax, %%eax          \n\t"
+                       "  jz 20f                       \n"
+                       "10:                            \t"
+                       "  movl (%%eax), %%ebx          \n\t"
+                       "  movl %%edx, %%ecx            \n\t"
+                       "  incl %%ecx                   \n\t"
+                       CHUNK_LOCK "cmpxchg8b %1        \n\t"
+                       "  jz 20f                       \n\t"
+                       "  testl %%eax, %%eax           \n\t"
+                       "  jnz 10b                      \n"
+                       "20:\t"
+                       :"=a" (chunk)
+                       :"m" (*mem_chunk), "a" (mem_chunk->free), "d" (mem_chunk->cnt)
+                       :"ecx", "ebx");
+
+  if (!chunk) {
+    //g_print ("extending\n");
+    if (populate (mem_chunk))
+      goto again;
+    else 
+      return NULL;
+  }
+  return GST_MEM_CHUNK_DATA (chunk);
+}
+
+gpointer
+gst_mem_chunk_alloc0 (GstMemChunk *mem_chunk)
+{
+  gpointer mem = gst_mem_chunk_alloc (mem_chunk);
+
+  if (mem)
+    memset (mem, 0, mem_chunk->atom_size);
+  
+  return mem;
+}
+
+void
+gst_mem_chunk_free (GstMemChunk *mem_chunk, gpointer mem)
+{
+  GstMemChunkElement *chunk;
+  
+  g_return_if_fail (mem_chunk != NULL);
+  g_return_if_fail (mem != NULL);
+
+  chunk = GST_MEM_CHUNK_LINK (mem);
+
+  __asm__ __volatile__ ( "1:                           \t"
+                       "  movl %2, (%1)                \n"
+                       CHUNK_LOCK "cmpxchg %1, %0      \n\t"
+                       "  jnz 1b                       \n\t"
+                       :
+                       :"m" (*mem_chunk), "r" (chunk), "a" (mem_chunk->free));
+}
diff --git a/test/memchunk/gstmemchunk.h b/test/memchunk/gstmemchunk.h
new file mode 100644 (file)
index 0000000..c71660a
--- /dev/null
@@ -0,0 +1,34 @@
+
+#include <gst/gst.h>
+
+typedef struct _GstMemChunk GstMemChunk;
+typedef struct _GstMemChunkElement GstMemChunkElement;
+
+struct _GstMemChunkElement
+{
+  GstMemChunkElement *link;            /* next cell in the lifo */
+  GstMemChunkElement *area;
+};
+
+struct _GstMemChunk
+{
+  volatile GstMemChunkElement *free;   /* the first free element */
+  volatile gulong cnt;                 /* used to avoid ABA problem */
+
+  gchar *name;
+  gulong area_size;
+  gulong chunk_size;
+  gulong atom_size;
+  gboolean cleanup;
+};
+
+GstMemChunk*   gst_mem_chunk_new       (gchar *name,
+                                        gint atom_size,
+                                        gulong area_size,
+                                        gint type);
+
+void           gst_mem_chunk_destroy   (GstMemChunk *mem_chunk);
+
+gpointer       gst_mem_chunk_alloc     (GstMemChunk *mem_chunk);
+void           gst_mem_chunk_free      (GstMemChunk *mem_chunk,
+                                        gpointer mem);
diff --git a/test/memchunk/gstmemchunktest.c b/test/memchunk/gstmemchunktest.c
new file mode 100644 (file)
index 0000000..05acccb
--- /dev/null
@@ -0,0 +1,79 @@
+#include <gst/gst.h>
+#include "gstmemchunk.h"
+
+#define MAX_THREADS  100
+
+static GstMemChunk *_chunks;
+
+static gint num_allocs;
+static gint num_threads;
+
+static gpointer 
+alloc_chunk (void)
+{
+  gpointer ret;
+  ret = gst_mem_chunk_alloc (_chunks);
+
+  return ret;
+}
+
+static void 
+free_chunk (gpointer chunk)
+{
+  gst_mem_chunk_free (_chunks, chunk);
+}
+
+
+void*
+run_test (void *threadid)
+{
+  gint i;
+  gpointer chunk;
+  sleep(1);
+
+  for (i = 0; i<num_allocs; i++) {
+    chunk = alloc_chunk ();
+    free_chunk (chunk);
+  }
+
+  pthread_exit(NULL);
+}
+
+
+gint 
+main (gint argc, gchar *argv[]) 
+{
+  pthread_t threads[MAX_THREADS];
+  int rc, t;
+  gst_init (&argc, &argv);
+
+  if (argc != 3) {
+    g_print ("usage: %s <num_threads> <num_allocs>\n", argv[0]);
+    exit (-1);
+  }
+
+  num_threads = atoi (argv[1]);
+  num_allocs = atoi (argv[2]);
+
+  _chunks = gst_mem_chunk_new ("test", 32, 32 * 16, G_ALLOC_AND_FREE);
+
+  for(t=0; t < num_threads; t++) {
+    rc = pthread_create (&threads[t], NULL, run_test, (void *)t);
+    if (rc) {
+      printf ("ERROR: return code from pthread_create() is %d\n", rc);
+      printf ("Code %d= %s\n", rc, strerror(rc));
+      exit (-1);
+    }
+  }
+  printf ("main(): Created %d threads.\n", t);
+
+  for(t=0; t < num_threads; t++) {
+    pthread_join (threads[t], NULL);
+  }
+  g_mem_chunk_info();
+
+  gst_mem_chunk_destroy (_chunks);
+
+  return 0;
+}
index 75a04c4..29f2d98 100644 (file)
@@ -16,7 +16,7 @@ gboolean idle_func(gpointer data) {
 
 void mpeg2parse_newpad(GstElement *parser,GstPad *pad, GstElement *pipeline) {
 
-  g_print("***** a new pad %s was created\n", gst_pad_get_name(pad));
+  g_print("***** a new pad %s was created %p\n", gst_pad_get_name(pad), pipeline);
   gst_element_set_state(GST_ELEMENT(pipeline),GST_STATE_PAUSED);
 
   if (strncmp(gst_pad_get_name(pad), "video_", 6) == 0) {
index 257a9ed..43ac340 100644 (file)
@@ -1,8 +1,15 @@
 SUBDIRS = sched eos nego muxing
 
-noinst_PROGRAMS = init loadall simplefake states caps queue registry \
-paranoia rip mp3encode autoplug props case4 markup load tee autoplug2 autoplug3 \
-capsconnect padfactory autoplug4 incsched reaping threadlock mp1vid reconnect \
+if GST_DISABLE_LOADSAVE
+GST_LOADSAVE_PROG =
+else
+GST_LOADSAVE_PROG = caps registry autoplug props tee autoplug2 capsconnect \
+                   padfactory autoplug4
+endif
+
+noinst_PROGRAMS = $(GST_LOADSAVE_PROG) init loadall simplefake states queue \
+paranoia rip mp3encode case4 markup load autoplug3 \
+incsched reaping threadlock mp1vid reconnect \
 faketest events timecache
 
 # we have nothing but apps here, we can do this safely
index 6fe9c9c..b81c156 100644 (file)
@@ -5,10 +5,16 @@ else
 GNOME_SUBDS =
 endif
 
-SUBDIRS = $(GNOME_SUBDS) \
+if GST_DISABLE_LOADSAVE
+GST_LOADSAVE_DIRS = 
+else
+GST_LOADSAVE_DIRS = xml typefind
+endif
+
+SUBDIRS = $(GNOME_SUBDS) $(GST_LOADSAVE_DIRS) \
           helloworld helloworld2 \
           queue queue2 queue3 queue4 \
-          launch thread xml plugins typefind mixer cutter
+          launch thread plugins mixer cutter
 
 DIST_SUBDIRS = autoplug \
           helloworld helloworld2 \
index 550b182..9de5ba5 100644 (file)
@@ -94,7 +94,9 @@ gst_play_have_type (GstElement *typefind, GstCaps *caps, GstElement *pipeline)
 
   gst_element_set_state (pipeline, GST_STATE_PLAYING);
       
+#ifndef GST_DISABLE_LOADSAVE
   xmlSaveFile("xmlTest.gst", gst_xml_write (GST_ELEMENT (pipeline)));
+#endif
 }
 
 gboolean 
index 0edbfa5..7a02edd 100644 (file)
@@ -182,7 +182,9 @@ int main(int argc,char *argv[])
     }   
     env_register_cp (channel_in->volenv,  num_channels * 10.0      , 1.0 / num_channels); /* to end level */
 
+#ifndef GST_DISABLE_LOADSAVE
     xmlSaveFile("mixer.xml", gst_xml_write(GST_ELEMENT(main_bin)));
+#endif
 
     /* start playing */
     gst_element_set_state(main_bin, GST_STATE_PLAYING);
@@ -356,7 +358,9 @@ create_input_channel (int id, char* location)
                  gst_element_get_pad (decoder, "src"), "src_00");
   
 #endif  
+#ifndef GST_DISABLE_LOADSAVE
   xmlSaveFile ("mixer.gst", gst_xml_write (new_element));
+#endif  
 
   gst_bin_add (GST_BIN(channel->pipe), channel->volenv);
   gst_bin_add (GST_BIN (channel->pipe), new_element);
diff --git a/tests/old/testsuite/bytestream/.gitignore b/tests/old/testsuite/bytestream/.gitignore
new file mode 100644 (file)
index 0000000..7df60c9
--- /dev/null
@@ -0,0 +1,8 @@
+Makefile
+Makefile.in
+*.o
+*.lo
+*.la
+.deps
+.libs
+test1
diff --git a/tests/old/testsuite/bytestream/Makefile.am b/tests/old/testsuite/bytestream/Makefile.am
new file mode 100644 (file)
index 0000000..75aeed7
--- /dev/null
@@ -0,0 +1,13 @@
+filterdir = $(libdir)/gst
+
+testprogs = test1 
+
+check_PROGRAMS = $(testprogs)
+
+test1_SOURCES = test1.c gstbstest.c mem.c
+test1_LDFLAGS = -L$(top_builddir)/libs/bytestream/ -lgstbytestream
+
+
+# we have nothing but apps here, we can do this safely
+LIBS += $(GST_LIBS)
+CFLAGS += $(GST_CFLAGS)
diff --git a/tests/old/testsuite/bytestream/gstbstest.c b/tests/old/testsuite/bytestream/gstbstest.c
new file mode 100644 (file)
index 0000000..4199a90
--- /dev/null
@@ -0,0 +1,407 @@
+/* GStreamer
+ * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
+ *                    2000 Wim Taymans <wtay@chello.be>
+ *
+ * gstbstest.c: 
+ *
+ * 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 <stdlib.h>
+#include <string.h>
+
+#include <gst/gst.h>
+#include <libs/bytestream/gstbytestream.h>
+
+#define GST_TYPE_BSTEST                (gst_bstest_get_type())
+#define GST_BSTEST(obj)                (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_BSTEST,GstBsTest))
+#define GST_BSTEST_CLASS(klass)        (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_BSTEST,GstBsTestClass))
+#define GST_IS_BSTEST(obj)             (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_BSTEST))
+#define GST_IS_BSTEST_CLASS(obj)       (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_BSTEST))
+
+typedef struct _GstBsTest GstBsTest;
+typedef struct _GstBsTestClass GstBsTestClass;
+
+struct _GstBsTest
+{
+  GstElement element;
+
+  GstPad *sinkpad;
+  GstPad *srcpad;
+
+  GstByteStream *bs;
+  
+  gchar        *accesspattern;
+  guint        num_patterns;
+  gchar                **patterns;
+  guint        sizemin;
+  guint        sizemax;
+  gint                 count;
+  gboolean     silent;
+};
+
+struct _GstBsTestClass
+{
+  GstElementClass parent_class;
+};
+
+GType gst_bstest_get_type (void);
+
+
+GstElementDetails gst_bstest_details = {
+  "ByteStreamTest",
+  "Filter",
+  "Test for the GstByteStream code",
+  VERSION,
+  "Erik Walthinsen <omega@temple-baptist.com>," "Wim Taymans <wim.taymans@chello.be>",
+  "(C) 2001",
+};
+
+
+/* BsTest signals and args */
+enum
+{
+  /* FILL ME */
+  LAST_SIGNAL
+};
+
+enum
+{
+  ARG_0,
+  ARG_SIZEMIN,
+  ARG_SIZEMAX,
+  ARG_COUNT,
+  ARG_SILENT,
+  ARG_ACCESSPATTERN,
+};
+
+
+static void    gst_bstest_class_init           (GstBsTestClass * klass);
+static void    gst_bstest_init                 (GstBsTest * bstest);
+
+static void gst_bstest_set_property (GObject * object, guint prop_id, const GValue * value,
+                                    GParamSpec * pspec);
+static void gst_bstest_get_property (GObject * object, guint prop_id, GValue * value,
+                                    GParamSpec * pspec);
+
+static GstElementStateReturn   gst_bstest_change_state         (GstElement *element);
+static void                    gst_bstest_loop                 (GstElement * element);
+
+static GstElementClass *parent_class = NULL;
+
+// static guint gst_bstest_signals[LAST_SIGNAL] = { 0 };
+
+GType
+gst_bstest_get_type (void)
+{
+  static GType bstest_type = 0;
+
+  if (!bstest_type) {
+    static const GTypeInfo bstest_info = {
+      sizeof (GstBsTestClass), NULL,
+      NULL,
+      (GClassInitFunc) gst_bstest_class_init,
+      NULL,
+      NULL,
+      sizeof (GstBsTest),
+      0,
+      (GInstanceInitFunc) gst_bstest_init,
+    };
+
+    bstest_type = g_type_register_static (GST_TYPE_ELEMENT, "BSTest", &bstest_info, 0);
+  }
+  return bstest_type;
+}
+
+static void
+gst_bstest_class_init (GstBsTestClass * klass)
+{
+  GObjectClass *gobject_class;
+  GstElementClass *gstelement_class;
+
+  gobject_class = (GObjectClass *) klass;
+  gstelement_class = (GstElementClass*)klass;
+
+  parent_class = g_type_class_ref (GST_TYPE_ELEMENT);
+
+  g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_SIZEMIN,
+                                  g_param_spec_int ("sizemin", "sizemin", "sizemin", 0, G_MAXINT,
+                                                    0, G_PARAM_READWRITE));
+  g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_SIZEMAX,
+                                  g_param_spec_int ("sizemax", "sizemax", "sizemax", 0, G_MAXINT,
+                                                    384, G_PARAM_READWRITE));
+  g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_ACCESSPATTERN,
+                                  g_param_spec_string ("accesspattern", "accesspattern", "accesspattern",
+                                                     "r", G_PARAM_READWRITE));
+  g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_COUNT,
+                                  g_param_spec_uint ("count", "count", "count",
+                                                     0, G_MAXUINT, 0, G_PARAM_READWRITE));
+  g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_SILENT,
+                                  g_param_spec_boolean ("silent", "silent", "silent",
+                                                         FALSE, G_PARAM_READWRITE));
+
+  gobject_class->set_property = GST_DEBUG_FUNCPTR (gst_bstest_set_property);
+  gobject_class->get_property = GST_DEBUG_FUNCPTR (gst_bstest_get_property);
+
+  gstelement_class->change_state = gst_bstest_change_state;
+
+}
+
+static GstPadNegotiateReturn
+gst_bstest_negotiate_src (GstPad * pad, GstCaps ** caps, gpointer * data)
+{
+  GstBsTest *bstest;
+
+  bstest = GST_BSTEST (gst_pad_get_parent (pad));
+
+  return gst_pad_negotiate_proxy (pad, bstest->sinkpad, caps);
+}
+
+static GstPadNegotiateReturn
+gst_bstest_negotiate_sink (GstPad * pad, GstCaps ** caps, gpointer * data)
+{
+  GstBsTest *bstest;
+
+  bstest = GST_BSTEST (gst_pad_get_parent (pad));
+
+  return gst_pad_negotiate_proxy (pad, bstest->srcpad, caps);
+}
+
+static void
+gst_bstest_init (GstBsTest * bstest)
+{
+  bstest->sinkpad = gst_pad_new ("sink", GST_PAD_SINK);
+  gst_element_add_pad (GST_ELEMENT (bstest), bstest->sinkpad);
+  gst_pad_set_negotiate_function (bstest->sinkpad, gst_bstest_negotiate_sink);
+
+  bstest->srcpad = gst_pad_new ("src", GST_PAD_SRC);
+  gst_element_add_pad (GST_ELEMENT (bstest), bstest->srcpad);
+  gst_pad_set_negotiate_function (bstest->srcpad, gst_bstest_negotiate_src);
+
+  gst_element_set_loop_function (GST_ELEMENT (bstest), gst_bstest_loop);
+
+  bstest->sizemin = 0;
+  bstest->sizemax = 384;
+  bstest->accesspattern = g_strdup ("r");
+  bstest->patterns = g_strsplit (bstest->accesspattern, ":", 0);
+  bstest->count = 5;
+  bstest->silent = FALSE;
+  bstest->bs = NULL;
+}
+
+static guint
+gst_bstest_get_size (GstBsTest *bstest, gchar *sizestring, guint prevsize)
+{
+  guint size;
+
+  if (sizestring[0] == 0) {
+    size = bstest->sizemax;
+  }
+  else if (sizestring[0] == 'r') {
+    size = bstest->sizemin + (guint8)(((gfloat)bstest->sizemax)*rand()/(RAND_MAX + (gfloat)bstest->sizemin));
+  }
+  else if (sizestring[0] == '<') {
+    size = prevsize;
+  }
+  else {
+    size = atoi (sizestring);
+  }
+
+  if (size == 0) size++;
+
+  return size;
+}
+
+static void
+gst_bstest_loop (GstElement * element)
+{
+  GstBsTest *bstest;
+  GstBuffer *buf = NULL;
+
+  g_return_if_fail (element != NULL);
+  g_return_if_fail (GST_IS_BSTEST (element));
+
+  bstest = GST_BSTEST (element);
+
+  do {
+    guint size = 0;
+    guint i = 0;
+
+    while (i < bstest->num_patterns) {
+      buf = NULL;
+
+      if (bstest->patterns[i][0] == 'r') {
+       size = gst_bstest_get_size (bstest, &bstest->patterns[i][1], size);
+        if (!bstest->silent) g_print ("bstest: ***** read %d bytes\n", size);
+        buf = gst_bytestream_read (bstest->bs, size);
+      }
+      else if (bstest->patterns[i][0] == 'f') {
+       size = gst_bstest_get_size (bstest, &bstest->patterns[i][1], size);
+        if (!bstest->silent) g_print ("bstest: ***** flush %d bytes\n", size);
+        gst_bytestream_flush (bstest->bs, size);
+      }
+      else if (!strncmp (bstest->patterns[i], "pb", 2)) {
+       size = gst_bstest_get_size (bstest, &bstest->patterns[i][2], size);
+        if (!bstest->silent) g_print ("bstest: ***** peek bytes %d bytes\n", size);
+        gst_bytestream_peek_bytes (bstest->bs, size);
+      }
+      else if (bstest->patterns[i][0] == 'p') {
+       size = gst_bstest_get_size (bstest, &bstest->patterns[i][1], size);
+        if (!bstest->silent) g_print ("bstest: ***** peek %d bytes\n", size);
+        buf = gst_bytestream_peek (bstest->bs, size);
+       gst_buffer_unref (buf);
+       buf = NULL;
+      }
+
+      if (buf)
+        gst_pad_push (bstest->srcpad, buf);
+      
+      i++;
+    }
+  } while (!GST_ELEMENT_IS_COTHREAD_STOPPING (element));
+}
+
+static void
+gst_bstest_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec)
+{
+  GstBsTest *bstest;
+
+  /* it's not null if we got it, but it might not be ours */
+  g_return_if_fail (GST_IS_BSTEST (object));
+
+  bstest = GST_BSTEST (object);
+
+  switch (prop_id) {
+    case ARG_SIZEMIN:
+      bstest->sizemin = g_value_get_int (value);
+      break;
+    case ARG_SIZEMAX:
+      bstest->sizemax = g_value_get_int (value);
+      break;
+    case ARG_ACCESSPATTERN:
+      if (bstest->accesspattern) {
+       g_free (bstest->accesspattern);
+       g_strfreev (bstest->patterns);
+      }
+      if (g_value_get_string (value) == NULL) {
+        gst_element_set_state (GST_ELEMENT (object), GST_STATE_NULL);
+        bstest->accesspattern = NULL;
+        bstest->num_patterns = 0;
+      } else {
+       guint i = 0;
+
+        bstest->accesspattern = g_strdup (g_value_get_string (value));
+        bstest->patterns = g_strsplit (bstest->accesspattern, ":", 0);
+        while (bstest->patterns[i++]);
+        bstest->num_patterns = i-1;
+      }
+      break;
+    case ARG_COUNT:
+      bstest->count = g_value_get_uint (value);
+      break;
+    case ARG_SILENT:
+      bstest->silent = g_value_get_boolean (value);
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+  }
+}
+
+static void
+gst_bstest_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec)
+{
+  GstBsTest *bstest;
+
+  /* it's not null if we got it, but it might not be ours */
+  g_return_if_fail (GST_IS_BSTEST (object));
+
+  bstest = GST_BSTEST (object);
+
+  switch (prop_id) {
+    case ARG_SIZEMIN:
+      g_value_set_int (value, bstest->sizemin);
+      break;
+    case ARG_SIZEMAX:
+      g_value_set_int (value, bstest->sizemax);
+      break;
+    case ARG_ACCESSPATTERN:
+      g_value_set_string (value, bstest->accesspattern);
+      break;
+    case ARG_COUNT:
+      g_value_set_uint (value, bstest->count);
+      break;
+    case ARG_SILENT:
+      g_value_set_boolean (value, bstest->silent);
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+  }
+}
+
+static GstElementStateReturn
+gst_bstest_change_state (GstElement *element)
+{
+  GstBsTest *bstest;
+
+  g_return_val_if_fail (GST_IS_BSTEST (element), GST_STATE_FAILURE);
+
+  bstest = GST_BSTEST (element);
+
+  if (GST_STATE_PENDING (element) == GST_STATE_NULL) {
+    if (bstest->bs) {
+      gst_bytestream_destroy (bstest->bs);
+      bstest->bs = NULL;
+    }
+  }
+  else {
+    if (!bstest->bs) {
+      bstest->bs = gst_bytestream_new (bstest->sinkpad);
+    }
+  }
+
+  if (GST_ELEMENT_CLASS (parent_class)->change_state)
+    return GST_ELEMENT_CLASS (parent_class)->change_state (element);
+
+  return GST_STATE_SUCCESS;
+}
+
+static gboolean
+plugin_init (GModule * module, GstPlugin * plugin)
+{
+  GstElementFactory *factory;
+
+  // we need gstbytestream
+  if (!gst_library_load ("gstbytestream")) {
+    g_print ("can't load bytestream\n");
+    return FALSE;
+  }
+
+  /* We need to create an ElementFactory for each element we provide.
+   * This consists of the name of the element, the GType identifier,
+   * and a pointer to the details structure at the top of the file.
+   */
+  factory = gst_elementfactory_new ("bstest", GST_TYPE_BSTEST, &gst_bstest_details);
+  g_return_val_if_fail (factory != NULL, FALSE);
+
+  /* The very last thing is to register the elementfactory with the plugin. */
+  gst_plugin_add_feature (plugin, GST_PLUGIN_FEATURE (factory));
+
+  return TRUE;
+}
+
+GST_PLUGIN_DESC (GST_VERSION_MAJOR, GST_VERSION_MINOR, "bstest", plugin_init);
diff --git a/tests/old/testsuite/bytestream/mem.c b/tests/old/testsuite/bytestream/mem.c
new file mode 100644 (file)
index 0000000..d1c36cb
--- /dev/null
@@ -0,0 +1,23 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <string.h>
+
+int vmsize() {
+  int pid,fd,size,i,mem;
+  char filename[17], buf[256], *ptr, *end;
+
+  pid = getpid();
+  snprintf(filename,17,"/proc/%d/stat",pid);
+  fd = open(filename,O_RDONLY);
+  size = read(fd,buf,240);
+  ptr = buf;
+  for (i=0;i<22;i++)
+    ptr = (char *)strchr(ptr,' ') + 1;
+  end = (char *)strchr(ptr,' ');
+  *end = 0;
+  sscanf(ptr,"%d",&mem);
+  close(fd);
+  return mem;
+}
diff --git a/tests/old/testsuite/bytestream/mem.h b/tests/old/testsuite/bytestream/mem.h
new file mode 100644 (file)
index 0000000..28999db
--- /dev/null
@@ -0,0 +1 @@
+int vmsize();
diff --git a/tests/old/testsuite/bytestream/test1.c b/tests/old/testsuite/bytestream/test1.c
new file mode 100644 (file)
index 0000000..0670849
--- /dev/null
@@ -0,0 +1,230 @@
+#include <string.h>
+#include <stdlib.h>
+
+#include <gst/gst.h>
+#include "mem.h"
+
+#define VM_THRES 1000
+#define MAX_CONFIG_LINE 255
+#define MAX_CONFIG_PATTERN 64
+
+typedef struct
+{
+  gint src_data;
+  gint src_sizetype;
+
+  gchar *bs_accesspattern;
+
+  gboolean integrity_check;
+} TestParam;
+
+static GSList *params = NULL;
+
+static guint8 count;
+static guint iterations;
+static gboolean integrity_check = TRUE;
+static gboolean verbose = FALSE;
+static gboolean dump = FALSE;
+
+static void
+handoff (GstElement *element, GstBuffer *buf, GstPad *pad, gpointer data)
+{
+  if (GST_IS_BUFFER (buf)) {
+    if (integrity_check) {
+      gint i;
+      guint8 *ptr = GST_BUFFER_DATA (buf);
+    
+      for (i=0; i<GST_BUFFER_SIZE (buf); i++) {
+        if (*ptr++ != count++) {
+         g_print ("data error!\n");
+         return;
+        }
+      }
+    }
+  }
+  else {
+    g_print ("not a buffer ! %p\n", buf);
+  }
+}
+static gchar*
+create_desc (TestParam *param) 
+{
+  gchar *desc;
+
+  desc = g_strdup_printf ("%s %s, pattern %s",  (param->src_sizetype == 2 ? "fixed" : "random"), 
+                                               (param->src_data == 1 ? "src" : "subbuffer"),
+                                               param->bs_accesspattern);
+  return desc;
+}
+
+static gboolean 
+read_param_file (gchar *filename) 
+{
+  FILE *fp;
+  gchar line[MAX_CONFIG_LINE+1];
+  guint linenr = 0;
+  gchar pattern[MAX_CONFIG_PATTERN];
+  gint data, sizetype, integrity_check;
+  gchar *scan_str;
+  gboolean res = TRUE;
+
+  fp = fopen (filename, "r");
+  if (fp == NULL) 
+    return FALSE;
+
+  scan_str = g_strdup_printf ("%%d %%d %%%ds %%d", MAX_CONFIG_PATTERN-1);
+  
+  while (fgets (line, MAX_CONFIG_LINE, fp)) { 
+    linenr++;
+
+    if (line[0] == '\n' || line[0] == '#')
+      continue;
+
+    if (sscanf (line, scan_str, &data, &sizetype, pattern, &integrity_check) != 4) {
+      g_print ("error on line: %d\n", linenr);
+      res = FALSE;
+      break;
+    }
+    else {
+      TestParam *param = g_malloc (sizeof (TestParam));
+
+      param->src_data = data;
+      param->src_sizetype = sizetype;
+      param->bs_accesspattern = g_strdup (pattern);
+      param->integrity_check = (integrity_check == 0 ? FALSE : TRUE);
+
+      params = g_slist_append (params, param);
+    }
+  }
+  g_free (scan_str);
+  
+  return res;
+}
+
+static void 
+run_test (GstBin *pipeline, gint iters)
+{
+  gint vm = 0;
+  gint maxiters = iters;
+  gint prev_percent = -1;
+
+  count = 0;
+  gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_PLAYING);
+
+  while (iters) {
+    gint newvm = vmsize();
+    gint percent;
+
+    percent = (gint)((maxiters-iters+1)*100.0/maxiters);
+
+    if (percent != prev_percent || newvm - vm > VM_THRES) {
+      g_print ("\r%d (delta %d) %.3d%%               ", newvm, newvm - vm, percent);
+      prev_percent = percent;
+      vm = newvm;
+    }
+    gst_bin_iterate (pipeline);
+
+    if (iters > 0) iters--;
+  }
+  gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_NULL);
+}
+
+static void 
+usage (char *argv[])
+{
+  g_print ("usage: %s [--verbose] [--dump] <paramfile> <iterations>\n", argv[0]);
+}
+
+int
+main (int argc, char *argv[]) 
+{
+  GstElement *src;
+  GstElement *sink;
+  GstElement *bs;
+  GstElement *pipeline;
+  gint testnum = 0;
+  GSList *walk;
+  gint arg_walk;
+
+  gst_init (&argc, &argv);
+
+  arg_walk = 1;
+  while ((arg_walk < argc)  && (argv[arg_walk][0] == '-')) {
+    if (!strncmp (argv[arg_walk], "--verbose", 9))
+      verbose = TRUE;
+    else if (!strncmp (argv[arg_walk], "--dump", 6))
+      dump = TRUE;
+    else {
+      g_print ("unknown option %s (ignored)\n", argv[arg_walk]);
+    }
+
+    arg_walk++;
+  }
+  if (argc - arg_walk < 2) {
+    usage(argv);
+    return -1;
+  }
+  if (!read_param_file (argv[arg_walk])) { 
+    g_print ("error reading file %s\n", argv[arg_walk]);
+    usage (argv);
+    return -1;
+  }
+  arg_walk++;
+  iterations = atoi (argv[arg_walk]);
+
+  pipeline = gst_elementfactory_make ("pipeline", "pipeline");
+  g_assert (pipeline);
+
+  src = gst_elementfactory_make ("fakesrc", "src");
+  g_assert (src);
+
+  sink = gst_elementfactory_make ("fakesink", "sink");
+  g_assert (sink);
+  g_signal_connect (G_OBJECT (sink), "handoff", G_CALLBACK (handoff), NULL);
+
+  bs = gst_elementfactory_make ("bstest", "bs");
+  g_assert (bs);
+
+  gst_element_connect (src, "src", bs, "sink");
+  gst_element_connect (bs, "src", sink, "sink");
+
+  gst_bin_add (GST_BIN (pipeline), src);
+  gst_bin_add (GST_BIN (pipeline), bs);
+  gst_bin_add (GST_BIN (pipeline), sink);
+
+  walk = params;
+
+  while (walk) {
+    gchar *desc;
+    TestParam *param = (TestParam *) (walk->data);
+
+    integrity_check = param->integrity_check;
+
+    g_print ("\n\nrunning test %d (%d iterations):\n", testnum+1, iterations);
+    desc = create_desc (param);
+    g_print ("%s\n", desc);
+    g_free (desc);
+
+    g_object_set (G_OBJECT (src), "data", param->src_data, 
+                                 "sizetype", param->src_sizetype, 
+                                 "filltype", (integrity_check?5:0),
+                                 "silent", !verbose, NULL);
+
+    g_object_set (G_OBJECT (bs),  "accesspattern", param->bs_accesspattern, 
+                                 "silent", !verbose, NULL);
+
+    g_object_set (G_OBJECT (sink), "dump", dump,
+                                  "silent", !verbose, NULL);
+
+    run_test (GST_BIN (pipeline), iterations);
+
+    testnum++;
+
+    walk = g_slist_next (walk);
+  }
+
+  g_print ("\n\ndone\n");
+
+  return 0;
+
+}
diff --git a/tests/old/testsuite/bytestream/testfile1 b/tests/old/testsuite/bytestream/testfile1
new file mode 100644 (file)
index 0000000..68a32dd
--- /dev/null
@@ -0,0 +1,93 @@
+# lots of parameters here. values for the columns are like:
+# 
+# - data property in fakesrc: 1 = allocate, 2 = subbuffer
+# - sizetype property in fakesrc: 2 = fixed, 3 = random
+#
+# - accesspattern for bstest
+#    <action><size>[:<action><size>...]
+#
+#    <action> can be:
+#      r   = read 
+#      p   = peek
+#      pb  = peek bytes
+#      f   = flush
+#    <size> can be:
+#      <empty> = fixed size
+#      r       = random size
+#      <       = previous size
+#      <int>   = this size
+#
+# - integrity check: 0 = no, 1 = yes
+#
+1 2  r 1
+1 2  rr 1
+1 3  r  1
+1 3  rr 1
+2 2  r  1
+2 2  rr 1
+2 3  r  1
+2 3  rr 1
+1 2  p:r< 1
+1 2  pr:r< 1
+1 3  p:r< 1
+1 3  pr:r< 1
+2 2  p:r< 1
+2 2  pr:r< 1
+2 3  p:r< 1
+2 3  pr:r< 1
+1 2  p:rr 1
+1 2  pr:rr 1
+1 3  p:rr 1
+1 3  pr:rr 1
+2 2  p:rr 1
+2 2  pr:rr 1
+2 3  p:rr 1
+2 3  pr:rr 1
+1 2  pb:r 1
+1 2  pbr:r 1
+1 3  pb:r 1
+1 3  pbr:r 1
+2 2  pb:r 1
+2 2  pbr:r 1
+2 3  pb:r 1
+2 3  pbr:r 1
+1 2  pb:rr 1
+1 2  pbr:rr 1
+1 3  pb:rr 1
+1 3  pbr:rr 1
+2 2  pb:rr 1
+2 2  pbr:rr 1
+2 3  pb:rr 1
+2 3  pbr:rr 1
+1 2  p:fr:rr 0
+1 2  pr:fr:rr 0
+1 3  p:fr:rr 0
+1 3  pr:fr:rr 0
+2 2  p:fr:rr 0
+2 2  pr:fr:rr 0
+2 3  p:fr:rr 0
+2 3  pr:fr:rr 0
+1 2  fr:rr 0
+1 2  fr:rr 0
+1 3  fr:rr 0
+1 3  fr:rr 0
+2 2  fr:rr 0
+2 2  fr:rr 0
+2 3  fr:rr 0
+2 3  fr:rr 0
+1 2  fr:fr:rr 0
+1 2  fr:fr:rr 0
+1 3  fr:fr:rr 0
+1 3  fr:fr:rr 0
+2 2  fr:fr:rr 0
+2 2  fr:fr:rr 0
+2 3  fr:fr:rr 0
+2 3  fr:fr:rr 0
+1 2  pbr:pbr:rr 1
+1 2  pbr:pbr:rr 1
+1 3  pbr:pbr:rr 1
+1 3  pbr:pbr:rr 1
+2 2  pbr:pbr:rr 1
+2 2  pbr:pbr:rr 1
+2 3  pbr:pbr:rr 1
+2 3  pbr:pbr:rr 1
index c1ca852..2894b4c 100644 (file)
@@ -1,4 +1,8 @@
+if GST_DISABLE_LOADSAVE
+noinst_PROGRAMS =
+else
 noinst_PROGRAMS = runxml
+endif
 
 # nothing but apps here, this is safe
 LIBS += $(GST_LIBS)
diff --git a/testsuite/bytestream/.gitignore b/testsuite/bytestream/.gitignore
new file mode 100644 (file)
index 0000000..7df60c9
--- /dev/null
@@ -0,0 +1,8 @@
+Makefile
+Makefile.in
+*.o
+*.lo
+*.la
+.deps
+.libs
+test1
diff --git a/testsuite/bytestream/Makefile.am b/testsuite/bytestream/Makefile.am
new file mode 100644 (file)
index 0000000..75aeed7
--- /dev/null
@@ -0,0 +1,13 @@
+filterdir = $(libdir)/gst
+
+testprogs = test1 
+
+check_PROGRAMS = $(testprogs)
+
+test1_SOURCES = test1.c gstbstest.c mem.c
+test1_LDFLAGS = -L$(top_builddir)/libs/bytestream/ -lgstbytestream
+
+
+# we have nothing but apps here, we can do this safely
+LIBS += $(GST_LIBS)
+CFLAGS += $(GST_CFLAGS)
diff --git a/testsuite/bytestream/gstbstest.c b/testsuite/bytestream/gstbstest.c
new file mode 100644 (file)
index 0000000..4199a90
--- /dev/null
@@ -0,0 +1,407 @@
+/* GStreamer
+ * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
+ *                    2000 Wim Taymans <wtay@chello.be>
+ *
+ * gstbstest.c: 
+ *
+ * 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 <stdlib.h>
+#include <string.h>
+
+#include <gst/gst.h>
+#include <libs/bytestream/gstbytestream.h>
+
+#define GST_TYPE_BSTEST                (gst_bstest_get_type())
+#define GST_BSTEST(obj)                (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_BSTEST,GstBsTest))
+#define GST_BSTEST_CLASS(klass)        (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_BSTEST,GstBsTestClass))
+#define GST_IS_BSTEST(obj)             (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_BSTEST))
+#define GST_IS_BSTEST_CLASS(obj)       (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_BSTEST))
+
+typedef struct _GstBsTest GstBsTest;
+typedef struct _GstBsTestClass GstBsTestClass;
+
+struct _GstBsTest
+{
+  GstElement element;
+
+  GstPad *sinkpad;
+  GstPad *srcpad;
+
+  GstByteStream *bs;
+  
+  gchar        *accesspattern;
+  guint        num_patterns;
+  gchar                **patterns;
+  guint        sizemin;
+  guint        sizemax;
+  gint                 count;
+  gboolean     silent;
+};
+
+struct _GstBsTestClass
+{
+  GstElementClass parent_class;
+};
+
+GType gst_bstest_get_type (void);
+
+
+GstElementDetails gst_bstest_details = {
+  "ByteStreamTest",
+  "Filter",
+  "Test for the GstByteStream code",
+  VERSION,
+  "Erik Walthinsen <omega@temple-baptist.com>," "Wim Taymans <wim.taymans@chello.be>",
+  "(C) 2001",
+};
+
+
+/* BsTest signals and args */
+enum
+{
+  /* FILL ME */
+  LAST_SIGNAL
+};
+
+enum
+{
+  ARG_0,
+  ARG_SIZEMIN,
+  ARG_SIZEMAX,
+  ARG_COUNT,
+  ARG_SILENT,
+  ARG_ACCESSPATTERN,
+};
+
+
+static void    gst_bstest_class_init           (GstBsTestClass * klass);
+static void    gst_bstest_init                 (GstBsTest * bstest);
+
+static void gst_bstest_set_property (GObject * object, guint prop_id, const GValue * value,
+                                    GParamSpec * pspec);
+static void gst_bstest_get_property (GObject * object, guint prop_id, GValue * value,
+                                    GParamSpec * pspec);
+
+static GstElementStateReturn   gst_bstest_change_state         (GstElement *element);
+static void                    gst_bstest_loop                 (GstElement * element);
+
+static GstElementClass *parent_class = NULL;
+
+// static guint gst_bstest_signals[LAST_SIGNAL] = { 0 };
+
+GType
+gst_bstest_get_type (void)
+{
+  static GType bstest_type = 0;
+
+  if (!bstest_type) {
+    static const GTypeInfo bstest_info = {
+      sizeof (GstBsTestClass), NULL,
+      NULL,
+      (GClassInitFunc) gst_bstest_class_init,
+      NULL,
+      NULL,
+      sizeof (GstBsTest),
+      0,
+      (GInstanceInitFunc) gst_bstest_init,
+    };
+
+    bstest_type = g_type_register_static (GST_TYPE_ELEMENT, "BSTest", &bstest_info, 0);
+  }
+  return bstest_type;
+}
+
+static void
+gst_bstest_class_init (GstBsTestClass * klass)
+{
+  GObjectClass *gobject_class;
+  GstElementClass *gstelement_class;
+
+  gobject_class = (GObjectClass *) klass;
+  gstelement_class = (GstElementClass*)klass;
+
+  parent_class = g_type_class_ref (GST_TYPE_ELEMENT);
+
+  g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_SIZEMIN,
+                                  g_param_spec_int ("sizemin", "sizemin", "sizemin", 0, G_MAXINT,
+                                                    0, G_PARAM_READWRITE));
+  g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_SIZEMAX,
+                                  g_param_spec_int ("sizemax", "sizemax", "sizemax", 0, G_MAXINT,
+                                                    384, G_PARAM_READWRITE));
+  g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_ACCESSPATTERN,
+                                  g_param_spec_string ("accesspattern", "accesspattern", "accesspattern",
+                                                     "r", G_PARAM_READWRITE));
+  g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_COUNT,
+                                  g_param_spec_uint ("count", "count", "count",
+                                                     0, G_MAXUINT, 0, G_PARAM_READWRITE));
+  g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_SILENT,
+                                  g_param_spec_boolean ("silent", "silent", "silent",
+                                                         FALSE, G_PARAM_READWRITE));
+
+  gobject_class->set_property = GST_DEBUG_FUNCPTR (gst_bstest_set_property);
+  gobject_class->get_property = GST_DEBUG_FUNCPTR (gst_bstest_get_property);
+
+  gstelement_class->change_state = gst_bstest_change_state;
+
+}
+
+static GstPadNegotiateReturn
+gst_bstest_negotiate_src (GstPad * pad, GstCaps ** caps, gpointer * data)
+{
+  GstBsTest *bstest;
+
+  bstest = GST_BSTEST (gst_pad_get_parent (pad));
+
+  return gst_pad_negotiate_proxy (pad, bstest->sinkpad, caps);
+}
+
+static GstPadNegotiateReturn
+gst_bstest_negotiate_sink (GstPad * pad, GstCaps ** caps, gpointer * data)
+{
+  GstBsTest *bstest;
+
+  bstest = GST_BSTEST (gst_pad_get_parent (pad));
+
+  return gst_pad_negotiate_proxy (pad, bstest->srcpad, caps);
+}
+
+static void
+gst_bstest_init (GstBsTest * bstest)
+{
+  bstest->sinkpad = gst_pad_new ("sink", GST_PAD_SINK);
+  gst_element_add_pad (GST_ELEMENT (bstest), bstest->sinkpad);
+  gst_pad_set_negotiate_function (bstest->sinkpad, gst_bstest_negotiate_sink);
+
+  bstest->srcpad = gst_pad_new ("src", GST_PAD_SRC);
+  gst_element_add_pad (GST_ELEMENT (bstest), bstest->srcpad);
+  gst_pad_set_negotiate_function (bstest->srcpad, gst_bstest_negotiate_src);
+
+  gst_element_set_loop_function (GST_ELEMENT (bstest), gst_bstest_loop);
+
+  bstest->sizemin = 0;
+  bstest->sizemax = 384;
+  bstest->accesspattern = g_strdup ("r");
+  bstest->patterns = g_strsplit (bstest->accesspattern, ":", 0);
+  bstest->count = 5;
+  bstest->silent = FALSE;
+  bstest->bs = NULL;
+}
+
+static guint
+gst_bstest_get_size (GstBsTest *bstest, gchar *sizestring, guint prevsize)
+{
+  guint size;
+
+  if (sizestring[0] == 0) {
+    size = bstest->sizemax;
+  }
+  else if (sizestring[0] == 'r') {
+    size = bstest->sizemin + (guint8)(((gfloat)bstest->sizemax)*rand()/(RAND_MAX + (gfloat)bstest->sizemin));
+  }
+  else if (sizestring[0] == '<') {
+    size = prevsize;
+  }
+  else {
+    size = atoi (sizestring);
+  }
+
+  if (size == 0) size++;
+
+  return size;
+}
+
+static void
+gst_bstest_loop (GstElement * element)
+{
+  GstBsTest *bstest;
+  GstBuffer *buf = NULL;
+
+  g_return_if_fail (element != NULL);
+  g_return_if_fail (GST_IS_BSTEST (element));
+
+  bstest = GST_BSTEST (element);
+
+  do {
+    guint size = 0;
+    guint i = 0;
+
+    while (i < bstest->num_patterns) {
+      buf = NULL;
+
+      if (bstest->patterns[i][0] == 'r') {
+       size = gst_bstest_get_size (bstest, &bstest->patterns[i][1], size);
+        if (!bstest->silent) g_print ("bstest: ***** read %d bytes\n", size);
+        buf = gst_bytestream_read (bstest->bs, size);
+      }
+      else if (bstest->patterns[i][0] == 'f') {
+       size = gst_bstest_get_size (bstest, &bstest->patterns[i][1], size);
+        if (!bstest->silent) g_print ("bstest: ***** flush %d bytes\n", size);
+        gst_bytestream_flush (bstest->bs, size);
+      }
+      else if (!strncmp (bstest->patterns[i], "pb", 2)) {
+       size = gst_bstest_get_size (bstest, &bstest->patterns[i][2], size);
+        if (!bstest->silent) g_print ("bstest: ***** peek bytes %d bytes\n", size);
+        gst_bytestream_peek_bytes (bstest->bs, size);
+      }
+      else if (bstest->patterns[i][0] == 'p') {
+       size = gst_bstest_get_size (bstest, &bstest->patterns[i][1], size);
+        if (!bstest->silent) g_print ("bstest: ***** peek %d bytes\n", size);
+        buf = gst_bytestream_peek (bstest->bs, size);
+       gst_buffer_unref (buf);
+       buf = NULL;
+      }
+
+      if (buf)
+        gst_pad_push (bstest->srcpad, buf);
+      
+      i++;
+    }
+  } while (!GST_ELEMENT_IS_COTHREAD_STOPPING (element));
+}
+
+static void
+gst_bstest_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec)
+{
+  GstBsTest *bstest;
+
+  /* it's not null if we got it, but it might not be ours */
+  g_return_if_fail (GST_IS_BSTEST (object));
+
+  bstest = GST_BSTEST (object);
+
+  switch (prop_id) {
+    case ARG_SIZEMIN:
+      bstest->sizemin = g_value_get_int (value);
+      break;
+    case ARG_SIZEMAX:
+      bstest->sizemax = g_value_get_int (value);
+      break;
+    case ARG_ACCESSPATTERN:
+      if (bstest->accesspattern) {
+       g_free (bstest->accesspattern);
+       g_strfreev (bstest->patterns);
+      }
+      if (g_value_get_string (value) == NULL) {
+        gst_element_set_state (GST_ELEMENT (object), GST_STATE_NULL);
+        bstest->accesspattern = NULL;
+        bstest->num_patterns = 0;
+      } else {
+       guint i = 0;
+
+        bstest->accesspattern = g_strdup (g_value_get_string (value));
+        bstest->patterns = g_strsplit (bstest->accesspattern, ":", 0);
+        while (bstest->patterns[i++]);
+        bstest->num_patterns = i-1;
+      }
+      break;
+    case ARG_COUNT:
+      bstest->count = g_value_get_uint (value);
+      break;
+    case ARG_SILENT:
+      bstest->silent = g_value_get_boolean (value);
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+  }
+}
+
+static void
+gst_bstest_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec)
+{
+  GstBsTest *bstest;
+
+  /* it's not null if we got it, but it might not be ours */
+  g_return_if_fail (GST_IS_BSTEST (object));
+
+  bstest = GST_BSTEST (object);
+
+  switch (prop_id) {
+    case ARG_SIZEMIN:
+      g_value_set_int (value, bstest->sizemin);
+      break;
+    case ARG_SIZEMAX:
+      g_value_set_int (value, bstest->sizemax);
+      break;
+    case ARG_ACCESSPATTERN:
+      g_value_set_string (value, bstest->accesspattern);
+      break;
+    case ARG_COUNT:
+      g_value_set_uint (value, bstest->count);
+      break;
+    case ARG_SILENT:
+      g_value_set_boolean (value, bstest->silent);
+      break;
+    default:
+      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+      break;
+  }
+}
+
+static GstElementStateReturn
+gst_bstest_change_state (GstElement *element)
+{
+  GstBsTest *bstest;
+
+  g_return_val_if_fail (GST_IS_BSTEST (element), GST_STATE_FAILURE);
+
+  bstest = GST_BSTEST (element);
+
+  if (GST_STATE_PENDING (element) == GST_STATE_NULL) {
+    if (bstest->bs) {
+      gst_bytestream_destroy (bstest->bs);
+      bstest->bs = NULL;
+    }
+  }
+  else {
+    if (!bstest->bs) {
+      bstest->bs = gst_bytestream_new (bstest->sinkpad);
+    }
+  }
+
+  if (GST_ELEMENT_CLASS (parent_class)->change_state)
+    return GST_ELEMENT_CLASS (parent_class)->change_state (element);
+
+  return GST_STATE_SUCCESS;
+}
+
+static gboolean
+plugin_init (GModule * module, GstPlugin * plugin)
+{
+  GstElementFactory *factory;
+
+  // we need gstbytestream
+  if (!gst_library_load ("gstbytestream")) {
+    g_print ("can't load bytestream\n");
+    return FALSE;
+  }
+
+  /* We need to create an ElementFactory for each element we provide.
+   * This consists of the name of the element, the GType identifier,
+   * and a pointer to the details structure at the top of the file.
+   */
+  factory = gst_elementfactory_new ("bstest", GST_TYPE_BSTEST, &gst_bstest_details);
+  g_return_val_if_fail (factory != NULL, FALSE);
+
+  /* The very last thing is to register the elementfactory with the plugin. */
+  gst_plugin_add_feature (plugin, GST_PLUGIN_FEATURE (factory));
+
+  return TRUE;
+}
+
+GST_PLUGIN_DESC (GST_VERSION_MAJOR, GST_VERSION_MINOR, "bstest", plugin_init);
diff --git a/testsuite/bytestream/mem.c b/testsuite/bytestream/mem.c
new file mode 100644 (file)
index 0000000..d1c36cb
--- /dev/null
@@ -0,0 +1,23 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <string.h>
+
+int vmsize() {
+  int pid,fd,size,i,mem;
+  char filename[17], buf[256], *ptr, *end;
+
+  pid = getpid();
+  snprintf(filename,17,"/proc/%d/stat",pid);
+  fd = open(filename,O_RDONLY);
+  size = read(fd,buf,240);
+  ptr = buf;
+  for (i=0;i<22;i++)
+    ptr = (char *)strchr(ptr,' ') + 1;
+  end = (char *)strchr(ptr,' ');
+  *end = 0;
+  sscanf(ptr,"%d",&mem);
+  close(fd);
+  return mem;
+}
diff --git a/testsuite/bytestream/mem.h b/testsuite/bytestream/mem.h
new file mode 100644 (file)
index 0000000..28999db
--- /dev/null
@@ -0,0 +1 @@
+int vmsize();
diff --git a/testsuite/bytestream/test1.c b/testsuite/bytestream/test1.c
new file mode 100644 (file)
index 0000000..0670849
--- /dev/null
@@ -0,0 +1,230 @@
+#include <string.h>
+#include <stdlib.h>
+
+#include <gst/gst.h>
+#include "mem.h"
+
+#define VM_THRES 1000
+#define MAX_CONFIG_LINE 255
+#define MAX_CONFIG_PATTERN 64
+
+typedef struct
+{
+  gint src_data;
+  gint src_sizetype;
+
+  gchar *bs_accesspattern;
+
+  gboolean integrity_check;
+} TestParam;
+
+static GSList *params = NULL;
+
+static guint8 count;
+static guint iterations;
+static gboolean integrity_check = TRUE;
+static gboolean verbose = FALSE;
+static gboolean dump = FALSE;
+
+static void
+handoff (GstElement *element, GstBuffer *buf, GstPad *pad, gpointer data)
+{
+  if (GST_IS_BUFFER (buf)) {
+    if (integrity_check) {
+      gint i;
+      guint8 *ptr = GST_BUFFER_DATA (buf);
+    
+      for (i=0; i<GST_BUFFER_SIZE (buf); i++) {
+        if (*ptr++ != count++) {
+         g_print ("data error!\n");
+         return;
+        }
+      }
+    }
+  }
+  else {
+    g_print ("not a buffer ! %p\n", buf);
+  }
+}
+static gchar*
+create_desc (TestParam *param) 
+{
+  gchar *desc;
+
+  desc = g_strdup_printf ("%s %s, pattern %s",  (param->src_sizetype == 2 ? "fixed" : "random"), 
+                                               (param->src_data == 1 ? "src" : "subbuffer"),
+                                               param->bs_accesspattern);
+  return desc;
+}
+
+static gboolean 
+read_param_file (gchar *filename) 
+{
+  FILE *fp;
+  gchar line[MAX_CONFIG_LINE+1];
+  guint linenr = 0;
+  gchar pattern[MAX_CONFIG_PATTERN];
+  gint data, sizetype, integrity_check;
+  gchar *scan_str;
+  gboolean res = TRUE;
+
+  fp = fopen (filename, "r");
+  if (fp == NULL) 
+    return FALSE;
+
+  scan_str = g_strdup_printf ("%%d %%d %%%ds %%d", MAX_CONFIG_PATTERN-1);
+  
+  while (fgets (line, MAX_CONFIG_LINE, fp)) { 
+    linenr++;
+
+    if (line[0] == '\n' || line[0] == '#')
+      continue;
+
+    if (sscanf (line, scan_str, &data, &sizetype, pattern, &integrity_check) != 4) {
+      g_print ("error on line: %d\n", linenr);
+      res = FALSE;
+      break;
+    }
+    else {
+      TestParam *param = g_malloc (sizeof (TestParam));
+
+      param->src_data = data;
+      param->src_sizetype = sizetype;
+      param->bs_accesspattern = g_strdup (pattern);
+      param->integrity_check = (integrity_check == 0 ? FALSE : TRUE);
+
+      params = g_slist_append (params, param);
+    }
+  }
+  g_free (scan_str);
+  
+  return res;
+}
+
+static void 
+run_test (GstBin *pipeline, gint iters)
+{
+  gint vm = 0;
+  gint maxiters = iters;
+  gint prev_percent = -1;
+
+  count = 0;
+  gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_PLAYING);
+
+  while (iters) {
+    gint newvm = vmsize();
+    gint percent;
+
+    percent = (gint)((maxiters-iters+1)*100.0/maxiters);
+
+    if (percent != prev_percent || newvm - vm > VM_THRES) {
+      g_print ("\r%d (delta %d) %.3d%%               ", newvm, newvm - vm, percent);
+      prev_percent = percent;
+      vm = newvm;
+    }
+    gst_bin_iterate (pipeline);
+
+    if (iters > 0) iters--;
+  }
+  gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_NULL);
+}
+
+static void 
+usage (char *argv[])
+{
+  g_print ("usage: %s [--verbose] [--dump] <paramfile> <iterations>\n", argv[0]);
+}
+
+int
+main (int argc, char *argv[]) 
+{
+  GstElement *src;
+  GstElement *sink;
+  GstElement *bs;
+  GstElement *pipeline;
+  gint testnum = 0;
+  GSList *walk;
+  gint arg_walk;
+
+  gst_init (&argc, &argv);
+
+  arg_walk = 1;
+  while ((arg_walk < argc)  && (argv[arg_walk][0] == '-')) {
+    if (!strncmp (argv[arg_walk], "--verbose", 9))
+      verbose = TRUE;
+    else if (!strncmp (argv[arg_walk], "--dump", 6))
+      dump = TRUE;
+    else {
+      g_print ("unknown option %s (ignored)\n", argv[arg_walk]);
+    }
+
+    arg_walk++;
+  }
+  if (argc - arg_walk < 2) {
+    usage(argv);
+    return -1;
+  }
+  if (!read_param_file (argv[arg_walk])) { 
+    g_print ("error reading file %s\n", argv[arg_walk]);
+    usage (argv);
+    return -1;
+  }
+  arg_walk++;
+  iterations = atoi (argv[arg_walk]);
+
+  pipeline = gst_elementfactory_make ("pipeline", "pipeline");
+  g_assert (pipeline);
+
+  src = gst_elementfactory_make ("fakesrc", "src");
+  g_assert (src);
+
+  sink = gst_elementfactory_make ("fakesink", "sink");
+  g_assert (sink);
+  g_signal_connect (G_OBJECT (sink), "handoff", G_CALLBACK (handoff), NULL);
+
+  bs = gst_elementfactory_make ("bstest", "bs");
+  g_assert (bs);
+
+  gst_element_connect (src, "src", bs, "sink");
+  gst_element_connect (bs, "src", sink, "sink");
+
+  gst_bin_add (GST_BIN (pipeline), src);
+  gst_bin_add (GST_BIN (pipeline), bs);
+  gst_bin_add (GST_BIN (pipeline), sink);
+
+  walk = params;
+
+  while (walk) {
+    gchar *desc;
+    TestParam *param = (TestParam *) (walk->data);
+
+    integrity_check = param->integrity_check;
+
+    g_print ("\n\nrunning test %d (%d iterations):\n", testnum+1, iterations);
+    desc = create_desc (param);
+    g_print ("%s\n", desc);
+    g_free (desc);
+
+    g_object_set (G_OBJECT (src), "data", param->src_data, 
+                                 "sizetype", param->src_sizetype, 
+                                 "filltype", (integrity_check?5:0),
+                                 "silent", !verbose, NULL);
+
+    g_object_set (G_OBJECT (bs),  "accesspattern", param->bs_accesspattern, 
+                                 "silent", !verbose, NULL);
+
+    g_object_set (G_OBJECT (sink), "dump", dump,
+                                  "silent", !verbose, NULL);
+
+    run_test (GST_BIN (pipeline), iterations);
+
+    testnum++;
+
+    walk = g_slist_next (walk);
+  }
+
+  g_print ("\n\ndone\n");
+
+  return 0;
+
+}
diff --git a/testsuite/bytestream/testfile1 b/testsuite/bytestream/testfile1
new file mode 100644 (file)
index 0000000..68a32dd
--- /dev/null
@@ -0,0 +1,93 @@
+# lots of parameters here. values for the columns are like:
+# 
+# - data property in fakesrc: 1 = allocate, 2 = subbuffer
+# - sizetype property in fakesrc: 2 = fixed, 3 = random
+#
+# - accesspattern for bstest
+#    <action><size>[:<action><size>...]
+#
+#    <action> can be:
+#      r   = read 
+#      p   = peek
+#      pb  = peek bytes
+#      f   = flush
+#    <size> can be:
+#      <empty> = fixed size
+#      r       = random size
+#      <       = previous size
+#      <int>   = this size
+#
+# - integrity check: 0 = no, 1 = yes
+#
+1 2  r 1
+1 2  rr 1
+1 3  r  1
+1 3  rr 1
+2 2  r  1
+2 2  rr 1
+2 3  r  1
+2 3  rr 1
+1 2  p:r< 1
+1 2  pr:r< 1
+1 3  p:r< 1
+1 3  pr:r< 1
+2 2  p:r< 1
+2 2  pr:r< 1
+2 3  p:r< 1
+2 3  pr:r< 1
+1 2  p:rr 1
+1 2  pr:rr 1
+1 3  p:rr 1
+1 3  pr:rr 1
+2 2  p:rr 1
+2 2  pr:rr 1
+2 3  p:rr 1
+2 3  pr:rr 1
+1 2  pb:r 1
+1 2  pbr:r 1
+1 3  pb:r 1
+1 3  pbr:r 1
+2 2  pb:r 1
+2 2  pbr:r 1
+2 3  pb:r 1
+2 3  pbr:r 1
+1 2  pb:rr 1
+1 2  pbr:rr 1
+1 3  pb:rr 1
+1 3  pbr:rr 1
+2 2  pb:rr 1
+2 2  pbr:rr 1
+2 3  pb:rr 1
+2 3  pbr:rr 1
+1 2  p:fr:rr 0
+1 2  pr:fr:rr 0
+1 3  p:fr:rr 0
+1 3  pr:fr:rr 0
+2 2  p:fr:rr 0
+2 2  pr:fr:rr 0
+2 3  p:fr:rr 0
+2 3  pr:fr:rr 0
+1 2  fr:rr 0
+1 2  fr:rr 0
+1 3  fr:rr 0
+1 3  fr:rr 0
+2 2  fr:rr 0
+2 2  fr:rr 0
+2 3  fr:rr 0
+2 3  fr:rr 0
+1 2  fr:fr:rr 0
+1 2  fr:fr:rr 0
+1 3  fr:fr:rr 0
+1 3  fr:fr:rr 0
+2 2  fr:fr:rr 0
+2 2  fr:fr:rr 0
+2 3  fr:fr:rr 0
+2 3  fr:fr:rr 0
+1 2  pbr:pbr:rr 1
+1 2  pbr:pbr:rr 1
+1 3  pbr:pbr:rr 1
+1 3  pbr:pbr:rr 1
+2 2  pbr:pbr:rr 1
+2 2  pbr:pbr:rr 1
+2 3  pbr:pbr:rr 1
+2 3  pbr:pbr:rr 1
index b45f29d..bef06f9 100644 (file)
@@ -5,6 +5,12 @@ else
 GST_REGISTRY_SRC = gstreamer-register
 endif
 
+if GST_DISABLE_LOADSAVE
+GST_LOADSAVE_SRC = 
+else
+GST_LOADSAVE_SRC = gstreamer-compprep
+endif
+
 if USE_GLIB2
 GST_GUI_LAUNCH = 
 else
@@ -12,16 +18,16 @@ GST_GUI_LAUNCH = gstreamer-guilaunch
 endif
 
 bin_PROGRAMS =         gstreamer-launch        \
-               $(GST_GUI_LAUNCH)     \
+               $(GST_GUI_LAUNCH)       \
                $(GST_REGISTRY_SRC)     \
                gstreamer-inspect       \
-               gstreamer-compprep      \
+               $(GST_LOADSAVE_SRC)     \
                gstreamer-complete
 
 man_MANS = gstreamer-launch.1 gstreamer-register.1 gstreamer-inspect.1 \
        gstreamer-complete.1 gstreamer-compprep.1
 
 LDADD = $(GST_LIBS)
-CFLAGS = $(LIBGST_CFLAGS) -DGST_CONFIG_DIR=\"$(GST_CONFIG_DIR)\"
+CFLAGS = $(LIBGST_CFLAGS) -DGST_CONFIG_DIR=\"$(GST_CONFIG_DIR)\" 
 
 EXTRA_DIST = $(man_MANS)
index 2ec45ac..6ac84be 100644 (file)
@@ -221,10 +221,12 @@ print_element_info (GstElementFactory *factory)
 
   printf("  Has change_state() function: %s\n",
          GST_DEBUG_FUNCPTR_NAME(gstelement_class->change_state));
+#ifndef GST_DISABLE_LOADSAVE
   printf("  Has custom save_thyself() function: %s\n",
          GST_DEBUG_FUNCPTR_NAME(gstobject_class->save_thyself));
   printf("  Has custom restore_thyself() function: %s\n",
          GST_DEBUG_FUNCPTR_NAME(gstobject_class->restore_thyself));
+#endif
 
 
 
index af7a494..821bb38 100644 (file)
@@ -61,7 +61,11 @@ arg_search (GstBin *bin, gchar *argname, found_handler handler, void *priv)
 gboolean
 idle_func (gpointer data)
 {
-  return gst_bin_iterate (GST_BIN (data));
+  if (!gst_bin_iterate (GST_BIN (data))) {
+    gtk_main_quit ();
+    return FALSE;
+  }
+  return TRUE;
 }
 
 void 
@@ -148,9 +152,11 @@ main(int argc, char *argv[])
 
   gst_parse_launch (cmdline, GST_BIN (pipeline));
 
+#ifndef GST_DISABLE_LOADSAVE
   if (save_pipeline) {
     xmlSaveFile (savefile, gst_xml_write (pipeline));
   }
+#endif
   if (run_pipeline) {
     arg_search(GST_BIN(pipeline),"xid",xid_handler,NULL);