Merged from HEAD to INCSCHED1 on 200104251 BRANCH-INCSCHED1-200104251
authorErik Walthinsen <omega@temple-baptist.org>
Thu, 26 Apr 2001 01:53:20 +0000 (01:53 +0000)
committerErik Walthinsen <omega@temple-baptist.org>
Thu, 26 Apr 2001 01:53:20 +0000 (01:53 +0000)
Original commit message from CVS:
Merged from HEAD to INCSCHED1 on 200104251

99 files changed:
autogen.sh
configure.in
docs/gst/gstreamer-docs.sgml
docs/gst/gstreamer-sections.txt
docs/gst/gstreamer.hierarchy
docs/gst/tmpl/gst.sgml
docs/gst/tmpl/gstautoplug.sgml
docs/gst/tmpl/gstbin.sgml
docs/gst/tmpl/gstbuffer.sgml
docs/gst/tmpl/gstbufferpool.sgml
docs/gst/tmpl/gstcaps.sgml
docs/gst/tmpl/gstcpu.sgml
docs/gst/tmpl/gstdisksink.sgml [new file with mode: 0644]
docs/gst/tmpl/gstfakesink.sgml
docs/gst/tmpl/gstidentity.sgml
docs/gst/tmpl/gstpad.sgml
docs/gst/tmpl/gstparse.sgml
docs/gst/tmpl/gstpipeline.sgml
docs/gst/tmpl/gstplugin.sgml
docs/gst/tmpl/gstprops.sgml
docs/gst/tmpl/gstreamer-unused.sgml
docs/libs/Makefile.am
examples/Makefile.am
examples/autoplug/autoplug.c
examples/mixer/.gitignore [new file with mode: 0644]
examples/mixer/Makefile.am [new file with mode: 0644]
examples/mixer/mixer.c [new file with mode: 0644]
examples/mixer/mixer.h [new file with mode: 0644]
examples/plugins/example.c
gst/.gitignore
gst/Makefile.am
gst/Makefile.am.future
gst/autoplug/Makefile.am
gst/autoplug/gststaticautoplug.c
gst/autoplug/gststaticautoplugrender.c
gst/elements/Makefile.am
gst/elements/gstdisksink.c [new file with mode: 0644]
gst/elements/gstdisksink.h [new file with mode: 0644]
gst/elements/gstdisksrc.c
gst/elements/gstelements.c
gst/elements/gstfakesink.c
gst/elements/gstfakesink.h
gst/elements/gstidentity.c
gst/elements/gstidentity.h
gst/gst.h
gst/gstbuffer.c
gst/gstbuffer.h
gst/gstcaps.c
gst/gstcaps.h
gst/gstobject.c
gst/gstpad.c
gst/gstpad.h
gst/gstplugin.c
gst/gstplugin.h
gst/gstprops.h
gst/gstqueue.c
gst/gstutils.c
gst/gstversion.h.in [new file with mode: 0644]
gst/types/Makefile.am
gst/types/gsttypes.c
libs/putbits/gstputbits.c
plugins/elements/Makefile.am
plugins/elements/gstdisksink.c [new file with mode: 0644]
plugins/elements/gstdisksink.h [new file with mode: 0644]
plugins/elements/gstdisksrc.c
plugins/elements/gstelements.c
plugins/elements/gstfakesink.c
plugins/elements/gstfakesink.h
plugins/elements/gstidentity.c
plugins/elements/gstidentity.h
plugins/elements/gstqueue.c
test/.gitignore
test/Makefile.am
test/dv2mp1.c [new file with mode: 0644]
test/dvshow.c [new file with mode: 0644]
test/mp2tomp1.c
test/mp3.c
test/mp3mad.c [new file with mode: 0644]
test/video2mp1.c [new file with mode: 0644]
test/xmmstest.c
tests/Makefile.am
tests/autoplug3.c
tests/autoplug4.c [new file with mode: 0644]
tests/old/examples/Makefile.am
tests/old/examples/autoplug/autoplug.c
tests/old/examples/mixer/.gitignore [new file with mode: 0644]
tests/old/examples/mixer/Makefile.am [new file with mode: 0644]
tests/old/examples/mixer/mixer.c [new file with mode: 0644]
tests/old/examples/mixer/mixer.h [new file with mode: 0644]
tests/old/examples/plugins/example.c
tests/old/testsuite/capsnego/capsnego.c
tests/old/testsuite/capsnego/converter.c
tests/old/testsuite/capsnego/converter2.c
tests/old/testsuite/capsnego/enum.c
tests/padfactory.c
testsuite/capsnego/capsnego.c
testsuite/capsnego/converter.c
testsuite/capsnego/converter2.c
testsuite/capsnego/enum.c

index 5f4751c35e6f3aa99eb6dee9bfa1b4b8863ff88e..5507330d48980f6d206b598508d06594df64eaa7 100755 (executable)
@@ -71,6 +71,9 @@ fi
 #  popd > /dev/null
 #done
 
+# now remove the cache, because it can be considered dangerous in this case
+rm -f config.cache
+
 ./configure --enable-maintainer-mode --enable-plugin-srcdir --enable-debug --enable-debug-verbose "$@"
 
 echo 
index 9cea36dbd8ab734098c58cf8ebf399c89aff2d31..c3d4238b82fa7872e4ad8760f4f5756651287f2e 100644 (file)
@@ -4,44 +4,45 @@ AC_CANONICAL_SYSTEM
 
 AM_CONFIG_HEADER(config.h)
 
-dnl FIXME this should be GSTREAMER_ now
-STREAMER_MAJOR_VERSION=0
-STREAMER_MINOR_VERSION=1
-STREAMER_MICRO_VERSION=1
-STREAMER_VERSION=$STREAMER_MAJOR_VERSION.$STREAMER_MINOR_VERSION.$STREAMER_MICRO_VERSION
+GST_VERSION_MAJOR=0
+GST_VERSION_MINOR=1
+GST_VERSION_MICRO=1
+GST_VERSION=$GST_VERSION_MAJOR.$GST_VERSION_MINOR.$GST_VERSION_MICRO
 
 PACKAGE=gstreamer
-VERSION=$STREAMER_VERSION
+VERSION=$GST_VERSION
 AC_DEFINE_UNQUOTED(PACKAGE, "$PACKAGE")
 AC_DEFINE_UNQUOTED(VERSION, "$VERSION")
 AC_SUBST(PACKAGE)
 AC_SUBST(VERSION)
 
 dnl libtool
-STREAMER_CURRENT=0
-STREAMER_REVISION=0
-STREAMER_AGE=0
-GSTREAMER_LIBVERSION=$STREAMER_CURRENT:$STREAMER_REVISION:$STREAMER_AGE
+GST_CURRENT=0
+GST_REVISION=0
+GST_AGE=0
+GST_LIBVERSION=$GST_CURRENT:$GST_REVISION:$GST_AGE
 
 AM_INIT_AUTOMAKE($PACKAGE, $VERSION)
 dnl Add parameters for aclocal
 dnl (This must come after AM_INIT_AUTOMAKE, since it modifies ACLOCAL)
 ACLOCAL="$ACLOCAL $ACLOCAL_FLAGS"
 
-AC_SUBST(STREAMER_MAJOR_VERSION)
-AC_SUBST(STREAMER_MINOR_VERSION)
-AC_SUBST(STREAMER_MICRO_VERSION)
-AC_SUBST(STREAMER_VERSION)
+AC_SUBST(GST_VERSION_MAJOR)
+AC_SUBST(GST_VERSION_MINOR)
+AC_SUBST(GST_VERSION_MICRO)
+AC_SUBST(GST_VERSION)
 
-AC_SUBST(STREAMER_CURRENT)
-AC_SUBST(STREAMER_REVISION)
-AC_SUBST(STREAMER_AGE)
-AC_SUBST(GSTREAMER_LIBVERSION)
+AC_SUBST(GST_CURRENT)
+AC_SUBST(GST_REVISION)
+AC_SUBST(GST_AGE)
+AC_SUBST(GST_LIBVERSION)
 
 
 AM_MAINTAINER_MODE
 
 AC_PROG_CC
+AC_PROG_CXX
+AC_PROG_CXXCPP
 AC_ISC_POSIX
 AC_STDC_HEADERS
 AC_ARG_PROGRAM
@@ -432,6 +433,26 @@ dnl Check for librtp
 AC_MSG_CHECKING(rtp library)
 AC_CHECK_LIB(rtp, rtp_packet_new_take_data, HAVE_LIBRTP=yes, HAVE_LIBRTP=no, $GLIB_LIBS $GLIB_CFLAGS)
 
+dnl Check for arts
+AC_LANG_SAVE
+AC_LANG_CPLUSPLUS
+AC_MSG_CHECKING(arts library)
+dnl AC_CHECK_LIB(artsflow, convert_stereo_ifloat_2float, HAVE_ARTS=yes, HAVE_ARTS=no, -lmcop -lartsflow_idl)
+AC_CHECK_HEADER(arts/artsflow.h, HAVE_ARTS=yes, HAVE_ARTS=no)
+AC_LANG_RESTORE
+
+dnl Check for libraw1394
+AC_MSG_CHECKING(raw1394 library)
+AC_CHECK_LIB(raw1394, raw1394_get_handle, HAVE_RAW1394=yes, HAVE_RAW1394=no, )
+
+dnl Check for libdv
+AC_MSG_CHECKING(libdv)
+AC_CHECK_LIB(dv, dv_init, HAVE_LIBDV=yes, HAVE_LIBDV=no, -lm $GLIB_LIBS $GLIB_CFLAGS)
+
+dnl Check for aalib
+AC_MSG_CHECKING(aalib)
+AC_CHECK_LIB(aa, aa_init, HAVE_LIBAA=yes, HAVE_LIBAA=no, )
+
 
 dnl check if css-auth.c exists (FIXME)
 AC_MSG_CHECKING(DVD CSS code)
@@ -695,6 +716,10 @@ AM_CONDITIONAL(HAVE_LIBASOUND,      test "x$HAVE_LIBASOUND" = "xyes")
 AM_CONDITIONAL(HAVE_MPEG2DEC,       test "x$HAVE_MPEG2DEC" = "xyes")
 AM_CONDITIONAL(HAVE_LIBXMMS,        test "x$HAVE_LIBXMMS" = "xyes")
 AM_CONDITIONAL(HAVE_LIBRTP,         test "x$HAVE_LIBRTP" = "xyes")
+AM_CONDITIONAL(HAVE_ARTS,           test "x$HAVE_ARTS" = "xyes")
+AM_CONDITIONAL(HAVE_RAW1394,        test "x%HAVE_RAW1394" = "xyes")
+AM_CONDITIONAL(HAVE_LIBDV,          test "x%HAVE_LIBDV" = "xyes")
+AM_CONDITIONAL(HAVE_LIBAA,          test "x%HAVE_LIBAA" = "xyes")
 
 
 
@@ -779,6 +804,7 @@ AC_OUTPUT([Makefile
 include/Makefile
 include/wine/Makefile
 gst/Makefile
+gst/gstversion.h
 gst/types/Makefile
 gst/meta/Makefile
 gst/elements/Makefile
@@ -792,6 +818,7 @@ libs/putbits/Makefile
 libs/winloader/Makefile
 libs/idct/Makefile
 plugins/Makefile
+plugins/aasink/Makefile
 plugins/alsa/Makefile
 plugins/au/Makefile
 plugins/audioscale/Makefile
@@ -837,8 +864,10 @@ plugins/filters/median/Makefile
 plugins/filters/ladspa/Makefile
 plugins/filters/stereo2mono/Makefile
 plugins/filters/passthrough/Makefile
+plugins/filters/adder/Makefile
 plugins/filters/colorspace/Makefile
 plugins/filters/volenv/Makefile
+plugins/filters/adder/Makefile
 plugins/icecast/Makefile
 plugins/icecast/icecastsend/Makefile
 plugins/effects/Makefile
@@ -864,7 +893,9 @@ plugins/esd/Makefile
 plugins/esd/esdsink/Makefile
 plugins/artsd/Makefile
 plugins/xmms/Makefile
-plugins/mulaw/Makefile
+plugins/arts/Makefile
+plugins/1394/Makefile
+plugins/dv/Makefile
 gstplay/Makefile
 dnl components/bonobo-gstmediaplay/Makefile
 test/Makefile
@@ -886,10 +917,12 @@ examples/queue2/Makefile
 examples/queue3/Makefile
 examples/queue4/Makefile
 examples/thread/Makefile
+examples/mixer/Makefile
 examples/launch/Makefile
 examples/xml/Makefile
 examples/plugins/Makefile
 examples/typefind/Makefile
+examples/mixer/Makefile
 editor/Makefile
 editor/pixmaps/Makefile
 tools/Makefile
index 5d4f9574ed0286e5af6fa217949bcf1cb1e93eb5..50ddbc9f84e11658b246ac6bc2ffe67a6d3c384e 100644 (file)
@@ -32,6 +32,7 @@
 <!entity GstFakeSrc SYSTEM "sgml/gstfakesrc.sgml">
 <!entity GstFakeSink SYSTEM "sgml/gstfakesink.sgml">
 <!entity GstDiskSrc SYSTEM "sgml/gstdisksrc.sgml">
+<!entity GstDiskSink SYSTEM "sgml/gstdisksink.sgml">
 <!entity GstHttpSrc SYSTEM "sgml/gsthttpsrc.sgml">
 <!entity GstFdSrc SYSTEM "sgml/gstfdsrc.sgml">
 <!entity GstSineSrc SYSTEM "sgml/gstsinesrc.sgml">
@@ -122,6 +123,8 @@ with some more specialized elements.</para>
     &GstFakeSink;
 
     &GstDiskSrc;
+    &GstDiskSink;
+
     &GstHttpSrc;
     
     &GstSineSrc;
index ca9923f14c341a586e179d3916d56d5a5666611c..6962909f91b2f5f6110fab3d5c50d4cffade66b4 100644 (file)
@@ -27,6 +27,9 @@ cothread_get_data
 gst_init
 gst_main
 gst_main_quit
+GST_VERSION_MICRO
+GST_VERSION_MAJOR
+GST_VERSION_MINOR
 <SUBSECTION Standard>
 </SECTION>
 
@@ -130,19 +133,25 @@ GST_BUFFER_FLAGS
 GST_BUFFER_FLAG_IS_SET
 GST_BUFFER_FLAG_SET
 GST_BUFFER_FLAG_UNSET
-GST_BUFFER_TYPE
 GST_BUFFER_DATA
 GST_BUFFER_SIZE
 GST_BUFFER_OFFSET
 GST_BUFFER_MAXSIZE
 GST_BUFFER_TIMESTAMP
+GST_BUFFER_BUFFERPOOL
+GST_BUFFER_POOL_PRIVATE
 GST_BUFFER_LOCK
 GST_BUFFER_TRYLOCK
 GST_BUFFER_UNLOCK
+GST_BUFFER_PARENT
+GST_BUFFER_MAXAGE
+
+
 GstBufferFlags
 GstBuffer
 gst_buffer_new
 gst_buffer_new_from_pool
+gst_buffer_copy
 gst_buffer_create_sub
 gst_buffer_append
 gst_buffer_ref
@@ -367,12 +376,11 @@ GstPadGetRegionFunction
 GstPadQoSFunction
 GstPadEOSFunction
 GstPadNewCapsFunction
-
+GstPadBufferPoolFunction
 
 GstPadNegotiateReturn
 GstPadNegotiateFunction
 
-
 GstPadPushFunction
 GstPadPullFunction
 GstRegionType
@@ -391,6 +399,7 @@ gst_pad_set_negotiate_function
 gst_pad_set_qos_function
 gst_pad_set_eos_function
 gst_pad_set_newcaps_function
+gst_pad_set_bufferpool_function
 gst_pad_set_caps
 gst_pad_get_caps
 gst_pad_check_compatibility
@@ -410,6 +419,7 @@ gst_pad_disconnect
 gst_pad_push
 gst_pad_pull
 gst_pad_pullregion
+gst_pad_get_bufferpool
 gst_pad_set_eos
 gst_pad_handle_qos
 gst_pad_eos
@@ -439,6 +449,7 @@ GST_RPAD_QOSFUNC
 GST_RPAD_EOSFUNC
 GST_RPAD_NEGOTIATEFUNC
 GST_RPAD_NEWCAPSFUNC
+GST_RPAD_BUFFERPOOLFUNC
 
 GST_GPAD_REALPAD
 GstGhostPad
@@ -450,6 +461,9 @@ GST_PADTEMPLATE_CAPS
 GST_PADTEMPLATE_DIRECTION
 GST_PADTEMPLATE_NAME_TEMPLATE
 GST_PADTEMPLATE_PRESENCE
+GST_PADTEMPLATE_NEW
+GST_PADTEMPLATE_FACTORY
+GST_PADTEMPLATE_GET
 gst_padtemplate_new
 gst_padtemplate_load_thyself
 gst_padtemplate_save_thyself
@@ -512,8 +526,8 @@ gst_pipeline_details
 <FILE>gstplugin</FILE>
 <TITLE>GstPlugin</TITLE>
 GstPlugin
-GstPluginElement
 GstPluginInitFunc
+GstPluginDesc
 gst_plugin_new
 gst_plugin_set_name
 gst_plugin_get_name
@@ -615,6 +629,9 @@ gst_typefactory_save_thyself
 GST_CAPS_LOCK
 GST_CAPS_TRYLOCK
 GST_CAPS_UNLOCK
+GST_CAPS_NEW
+GST_CAPS_FACTORY
+GST_CAPS_GET
 GstCaps
 gst_caps_new
 gst_caps_destroy
@@ -622,6 +639,7 @@ gst_caps_ref
 gst_caps_unref
 gst_caps_copy
 gst_caps_copy_on_write
+gst_caps_chain
 gst_caps_append
 gst_caps_prepend
 gst_caps_set_name
@@ -652,6 +670,7 @@ GST_CAPS
 <TITLE>GstProps</TITLE>
 GstProps
 GST_MAKE_FOURCC
+GST_STR_FOURCC
 GST_PROPS_LIST
 GST_PROPS_INT
 GST_PROPS_INT_RANGE
@@ -911,6 +930,20 @@ GST_IS_TYPEFIND
 GST_IS_TYPEFIND_CLASS
 </SECTION>
 
+<SECTION>
+<FILE>gstdisksink</FILE>
+<TITLE>GstDiskSink</TITLE>
+GstDiskSinkFlags
+<SUBSECTION Standard>
+GstDiskSink
+GST_DISKSINK
+GST_IS_DISKSINK
+GST_TYPE_DISKSINK
+gst_disksink_get_type
+GST_DISKSINK_CLASS
+GST_IS_DISKSINK_CLASS
+</SECTION>
+
 <SECTION>
 <FILE>gstmultidisksrc</FILE>
 <TITLE>GstMultiDiskSrc</TITLE>
index 3fcebbbbf3437bfa9f7052d4b97bb9ff34b7f972..758dabba475c5ba9f9aff72f7cf5f8e1d1f2a88d 100644 (file)
@@ -9,6 +9,7 @@ GtkObject
       GstFakeSrc
       GstFakeSink
       GstDiskSrc
+      GstDiskSink
       GstHttpSrc
       GstFdSrc
       GstSineSrc
index c254b7790ab18b5204e0ef2b42ad8ce574f13b47..546b49c6825edfc9f1e7ad4cb31755ff1620baab 100644 (file)
@@ -53,3 +53,24 @@ pipeline</ulink> and Microsoft's DirectShow for some background.
 
 
 
+<!-- ##### MACRO GST_VERSION_MICRO ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO GST_VERSION_MAJOR ##### -->
+<para>
+
+</para>
+
+
+
+<!-- ##### MACRO GST_VERSION_MINOR ##### -->
+<para>
+
+</para>
+
+
+
index 528b68724e4464775b9101893805226b482fdbc5..ff407eac19459683ce2539822b3d4b55e3690e55 100644 (file)
@@ -7,12 +7,92 @@ Automatically create and connect elements
 <!-- ##### SECTION Long_Description ##### -->
 <para>
 GstAutoplug is an abstract class that is used for constructing and 
-connecting elements. 
+connecting elements. Two types og autopluggers exist: renderer ones and non
+renderer ones. the renderer autopluggers will not have any src pads while the
+non renderer ones do.
+</para>
+
+<para>
+You first need to create a suitable autoplugger with gst_autoplugfactory_make().
+The name of the autoplugger must be one of the registered autopluggers 
+(see #GstStaticAutoplug and #GstStaticAutoplugRender).
+</para>
+<para>
+A list of all available autopluggers can be obtained with gst_autoplugfactory_get_list().
+</para>
+<para>
+If the autoplugger supports the RENDERER API, use gst_autoplug_to_renderers() call to
+create a bin that connectes the src caps to the specified rendrer elements. You can 
+then add the bin to a pipeline and run it.
+
+  <programlisting>
+  GstAutoplug *autoplug;
+  GstElement  *element;
+  GstElement  *sink;
+
+  /* create a static autoplugger */
+  autoplug = gst_autoplugfactory_make ("staticrender");
+
+  /* create an osssink */
+  sink = gst_elementfactory_make ("osssink", "our_sink");
+
+  /* create an element that can play audio/mp3 through osssink */
+  element = gst_autoplug_to_renderers (autoplug, 
+                                      gst_caps_new (
+                                        "sink_audio_caps",
+                                        "audio/mp3",
+                                        NULL
+                                      ),
+                                      sink,
+                                      NULL);
+
+  /* add the element to a bin and connect the sink pad */
+  ...
+  </programlisting>
+</para>
+<para>
+If the autoplugger supports the CAPS API, use gst_autoplug_to_caps() call to
+connect the src caps to the destination caps. The created bin will have src pads 
+compatible with the provided sink caps.
+
+  <programlisting>
+  GstAutoplug *autoplug;
+  GstElement  *element;
+
+  /* create a static autoplugger */
+  autoplug = gst_autoplugfactory_make ("static");
+
+  /* create an element that converts audio/mp3 to audio/raw */
+  element = gst_autoplug_to_caps (autoplug, 
+                                 gst_caps_new (
+                                   "sink_audio_caps",
+                                   "audio/mp3",
+                                   NULL
+                                 ),
+                                 gst_caps_new (
+                                   "src_audio_caps",
+                                   "audio/raw",
+                                   NULL
+                                 ),
+                                 NULL);
+
+  /* add the element to a bin and connect the src/sink pads */
+  ...
+  </programlisting>
 </para>
 
-<!-- ##### SECTION See_Also ##### -->
 <para>
+Optionally you can get a notification when a new object is added to the created
+pipeline with a gtk_signal_connect to the "new_object" signal.
+</para>
 
+<para>
+Use the regular gst_object_destroy() call to destroy the autoplugger.
+</para>
+
+<!-- ##### SECTION See_Also ##### -->
+<para>
+GstStaticAutoplug, GstStaticAutoplugRender
 </para>
 
 <!-- ##### STRUCT GstAutoplug ##### -->
@@ -24,7 +104,7 @@ connecting elements.
 
 <!-- ##### ENUM GstAutoplugFlags ##### -->
 <para>
-
+The type of the autoplugger.
 </para>
 
 @GST_AUTOPLUG_TO_CAPS: 
index f4840c49687154c131cf9c7f05cb0bb37bb17fac..780ad46c7772f8ebb569ac800cbd7029ec77ee16 100644 (file)
@@ -11,6 +11,32 @@ become children of itself.  Pads from the child elements can be ghosted to
 the bin, making the bin itself look transparently like any other element,
 allowing for deep nesting of predefined sub-pipelines.
 </para>
+<para>
+A new GstBin is created with gst_bin_new()
+</para>
+<para>
+After the bin has been created you will typically add elements to it with
+gst_bin_add(). You can remove elements with gst_bin_remove().
+</para>
+<para>
+An element can be retrieved from a bin with gst_bin_get_by_name(), using the
+elements name. gst_bin_get_by_name_recurse_up() is mainly used for internal
+purposes and will query the parent bins when the element is not found in the
+current bin.
+</para>
+<para>
+The list of elements in a bin can be retrieved with gst_bin_get_list().
+</para>
+<para>
+After the bin has been set to the PLAYING state (with gst_element_set_state()), 
+gst_bin_iterate() is used to process the elements in the bin.
+</para>
+<para>
+The "object_added" signal is fired whenever a new object is added to the bin.
+</para>
+<para>
+gst_bin_destroy() is used to destroy the bin. 
+</para>
 
 <!-- ##### SECTION See_Also ##### -->
 <para>
@@ -43,10 +69,10 @@ Flags for a bin.
 
 <!-- ##### MACRO gst_bin_destroy ##### -->
 <para>
-
+Free the memory allocated by this bin
 </para>
 
-@bin: 
+@bin: the bin to free
 
 
 <!-- ##### FUNCTION gst_bin_add ##### -->
index 9e6f6a2913204ef44561d6fafe99f6011ca26990..c57caf70fd8ea421f849d74f628d83816b6d19e4 100644 (file)
@@ -10,13 +10,54 @@ Buffers are the basic unit of data transfer in GST.  The GstBuffer type
 provides all the state necessary to define a region of memory as part of a
 stream.  Sub-buffer are also supported, allowing a smaller region of a
 buffer to become its own buffer, with mechanisms in place to ensure that
-nither memory space goes away.  Metadata is supported as a list of
+neither memory space goes away.  Metadata is supported as a list of
 pointers to arbitrary metadata.
 </para>
+<para>
+Buffers are usually created with gst_buffer_new(). After a buffer has been 
+created one will typically allocate memory for it and set the size of the 
+buffer data.
+<programlisting>
+  GstBuffer *buffer;
+  gint size, widht, height, bpp;
+
+  size = width * height * bpp;
+
+  buffer = gst_buffer_new ();
+  GST_BUFFER_SIZE (buffer) = size;
+  GST_BUFFER_DATA (buffer) = g_alloc (size);
+  ...
+  
+</programlisting>
+</para>
+<para>
+GstBuffers can also be created from a GstBufferPool with 
+gst_buffer_new_from_pool(). The bufferpool can be obtained from a
+peer element with gst_pad_get_bufferpool().
+</para>
+<para>
+gst_buffer_ref() is used to increase the refcount of a buffer. This must be
+done when you want to keep a handle to the buffer after pushing it to the
+next element.
+</para>
+<para>
+To efficiently create a smaller buffer out of an existing one, you can
+use gst_buffer_create_sub().
+</para>
+<para>
+Several flags of the buffer can be set and unset with the GST_BUFFER_FLAG_SET()
+and GST_BUFFER_FLAG_UNSET() macros. Use GST_BUFFER_FLAG_IS_SET() to test it
+a certain flag is set.
+</para>
+<para>
+Buffers usually are freed by unreffing them with gst_buffer_unref().
+gst_buffer_destroy() can also be used to effectively destroy the buffer
+regardless of the refcount (dangerous).
+</para>
 
 <!-- ##### SECTION See_Also ##### -->
 <para>
-
+#GstBufferPool, #GstPad
 </para>
 
 <!-- ##### MACRO GST_BUFFER_FLAGS ##### -->
@@ -54,14 +95,6 @@ Clear a flag in a buffer.
 @flag: the flag to clear
 
 
-<!-- ##### MACRO GST_BUFFER_TYPE ##### -->
-<para>
-Retrieves the type id of the data in the buffer.
-</para>
-
-@buf: GstBuffer
-
-
 <!-- ##### MACRO GST_BUFFER_DATA ##### -->
 <para>
 Retrieves a pointer to the data element of this buffer
@@ -88,7 +121,7 @@ Get the offset in the source file of this buffer.
 
 <!-- ##### MACRO GST_BUFFER_MAXSIZE ##### -->
 <para>
-
+Gets the maximun size of this buffer.
 </para>
 
 @buf: GstBuffer
@@ -102,6 +135,22 @@ Get the timestamp for this buffer.
 @buf: GstBuffer
 
 
+<!-- ##### MACRO GST_BUFFER_BUFFERPOOL ##### -->
+<para>
+Get the bufferpool for this buffer.
+</para>
+
+@buf: GstBuffer
+
+
+<!-- ##### MACRO GST_BUFFER_POOL_PRIVATE ##### -->
+<para>
+Get the bufferpool private data.
+</para>
+
+@buf: GstBuffer
+
+
 <!-- ##### MACRO GST_BUFFER_LOCK ##### -->
 <para>
 This macro will obtain a lock on the object, making serialization
@@ -131,6 +180,22 @@ This macro releases a lock on the object.
 @buf: GstBuffer to unlock.
 
 
+<!-- ##### MACRO GST_BUFFER_PARENT ##### -->
+<para>
+Get the parent of this buffer. The parent is set on subbuffers.
+</para>
+
+@buf: GstBuffer to get the parent of.
+
+
+<!-- ##### MACRO GST_BUFFER_MAXAGE ##### -->
+<para>
+Get the maximun age of a buffer.
+</para>
+
+@buf: GstBuffer to get the maxage of.
+
+
 <!-- ##### ENUM GstBufferFlags ##### -->
 <para>
 
@@ -150,7 +215,6 @@ used when data in a stream has been skipped
 </para>
 
 @lock: 
-@flags: 
 @data: 
 @size: 
 @maxsize: 
@@ -160,6 +224,7 @@ used when data in a stream has been skipped
 @metas: 
 @parent: 
 @pool: 
+@pool_private: 
 
 <!-- ##### FUNCTION gst_buffer_new ##### -->
 <para>
@@ -178,6 +243,15 @@ used when data in a stream has been skipped
 @Returns: 
 
 
+<!-- ##### FUNCTION gst_buffer_copy ##### -->
+<para>
+
+</para>
+
+@buffer: 
+@Returns: 
+
+
 <!-- ##### FUNCTION gst_buffer_create_sub ##### -->
 <para>
 
index 24243edbae185a7f796c9cf904788e507e4c25e2..075f996f9a45ee5f19d51401b2e68b4dbb1e4729 100644 (file)
@@ -10,17 +10,40 @@ A bufferpool is used to create buffers in an efficient way. En element
 can maintain a bufferpool with a fixed number of buffers. This will reduce
 the g_malloc and g_free overhead.
 </para>
-
 <para>
 A bufferpool can also be used to implement direct access. A bufferpool can be
 sent from one element to another so that the latter can directly write into
 the memory of the element that maintains the bufferpool. This can greatly reduce
 the number of memcpy operations.
 </para>
+<para>
+A bufferpool is created with gst_buffer_pool_new(). You'll have to set the
+buffer allocation and destroy function afterwards with gst_buffer_pool_set_create_function() and
+gst_buffer_pool_set_destroy_function().
+</para>
+<para>
+To create a buffer from the bufferpool use gst_buffer_pool_new_buffer(), which is 
+functionally equivalent to gst_buffer_new_from_pool().
+</para>
+<para>
+When the buffer is unreffed and has reached a refcount of 0, the bufferpools destroy
+function is called with the buffer as an argument.
+</para>
+<para>
+A bufferpool can store private data in the buffer it creates with the GST_BUFFER_POOL_PRIVATE()
+macro. To check it a buffer was made by a specific bufferpool, use the GST_BUFFER_BUFFERPOOL()
+macro to get it's bufferpool.
+</para>
+<para>
+Destroy the bufferpool with gst_buffer_pool_destroy().
+</para>
+<para>
+A bufferpool can be requested from a pad with the gst_pad_get_bufferpool() function.
+</para>
 
 <!-- ##### SECTION See_Also ##### -->
 <para>
-
+#GstBuffer, #GstPad
 </para>
 
 <!-- ##### STRUCT GstBufferPool ##### -->
index 9f1e9f3fc439bcfccd33c7eb98ddeb7f56512d68..b3e9fb9b4d2d37d047f805568a69ac09c2914ba5 100644 (file)
@@ -7,12 +7,72 @@ Capabilities of pads
 <!-- ##### SECTION Long_Description ##### -->
 <para>
 GstCaps is used to attach capabilities to a pad. Capabilities are made of
-a mime-type and a set of properties.
+a mime-type and a set of properties. GstCaps can be named and chained into
+a list, which is then a GstCaps on its own.
 </para>
+<para>
+GstCaps are created with gst_caps_new(), which takes a name, a mime type and
+a pointer to a #GstProps. A convenience macro with a cleaner syntax is 
+available to create a caps with GST_CAPS_NEW(). The following example shows how
+to create a GstCaps.
+<programlisting>
+  GstCaps *caps;
+
+  caps = gst_caps_new (
+          "my_caps",           /* capability name */
+         "audio/raw",          /* mime type */
+         gst_props_new (       /* properties */
+           "format",   GST_PROPS_STRING ("float"),
+           "layout",   GST_PROPS_INT (5),
+           NULL));
+</programlisting>
+
+The following code example is equivalent to the above example:
+<programlisting>
+  GstCaps *caps;
+
+  caps = GST_CAPS_NEW (
+          "my_caps",           /* capability name */
+         "audio/raw",          /* mime type */
+           "format",   GST_PROPS_STRING ("float"),
+           "channels", GST_PROPS_INT (5)
+         );
+</programlisting>
+</para>
+<para>
+GstCaps are refcounted with gst_caps_ref() and gst_caps_unref().
+</para>
+<para>
+GstCaps can be chained with the gst_caps_append(), gst_caps_prepend() and
+gst_caps_chain() functions. Use gst_caps_get_by_name() to get a named caps
+structure from a chained list.
+</para>
+<para>
+To get the properties of a caps structure the functions 
+gst_caps_get_boolean(), gst_caps_get_fourcc_int(), gst_caps_get_int(),
+gst_caps_get_string(), which all take a property name as an argument.
+</para>
+<para>
+The properties of the caps structure can be modified with gst_caps_set, which
+takes a list of key value pairs in the #GstProps syntax as shown by this example:
 
-<!-- ##### SECTION See_Also ##### -->
+<programlisting>
+  GstCaps *caps;
+   ....
+
+  gst_caps_set (caps, "format", GST_PROPS_STRING ("int"), NULL);
+  gst_caps_set (caps, "channels", GST_PROPS_INT (20), NULL);
+</programlisting>
+</para>
 <para>
+before modifying a GstCaps, it is a good idea to make a copy if it first with
+gst_caps_copy_on_write(). This will copy thr GstCaps if the refcount is &gt;1.
+</para>
 
+<!-- ##### SECTION See_Also ##### -->
+<para>
+#GstProps, #GstPad
 </para>
 
 <!-- ##### MACRO GST_CAPS_LOCK ##### -->
@@ -39,6 +99,34 @@ Unlock the caps structure
 @caps: The caps structure to unlock
 
 
+<!-- ##### MACRO GST_CAPS_NEW ##### -->
+<para>
+A convenience macro to create a new GstCaps structure.
+</para>
+
+@name: the name of the caps structure
+@type: the mime type of the caps structure
+@a...: the properties of this caps stucture.
+
+
+<!-- ##### MACRO GST_CAPS_FACTORY ##### -->
+<para>
+A convenience macro to create a GstCaps factory.
+</para>
+
+@factoryname: the name of the factory
+@a...: the caps to create with this factory, usualy specified
+with GST_CAPS_NEW()
+
+
+<!-- ##### MACRO GST_CAPS_GET ##### -->
+<para>
+A convenience macro to get a GstCaps from the given capsfactory.
+</para>
+
+@fact: the factory to use.
+
+
 <!-- ##### STRUCT GstCaps ##### -->
 <para>
 
@@ -76,6 +164,7 @@ Unlock the caps structure
 </para>
 
 @caps: 
+@Returns: 
 
 
 <!-- ##### FUNCTION gst_caps_unref ##### -->
@@ -84,6 +173,7 @@ Unlock the caps structure
 </para>
 
 @caps: 
+@Returns: 
 
 
 <!-- ##### FUNCTION gst_caps_copy ##### -->
@@ -104,6 +194,16 @@ Unlock the caps structure
 @Returns: 
 
 
+<!-- ##### FUNCTION gst_caps_chain ##### -->
+<para>
+
+</para>
+
+@caps: 
+@Varargs: 
+@Returns: 
+
+
 <!-- ##### FUNCTION gst_caps_append ##### -->
 <para>
 
@@ -212,21 +312,21 @@ Unlock the caps structure
 
 <!-- ##### MACRO gst_caps_set ##### -->
 <para>
-
+Set a property of a caps structure.
 </para>
 
-@caps: 
-@name: 
-@args...: 
+@caps: the caps structure to modify
+@name: the name of the property to change
+@args...: the new value of the property
 
 
 <!-- ##### MACRO gst_caps_get_boolean ##### -->
 <para>
-
+Get the value of the named property as a boolean.
 </para>
 
-@caps: 
-@name: 
+@caps: the caps to query
+@name: the name of the property to get
 
 
 <!-- ##### FUNCTION gst_caps_get_by_name ##### -->
@@ -241,29 +341,29 @@ Unlock the caps structure
 
 <!-- ##### MACRO gst_caps_get_fourcc_int ##### -->
 <para>
-
+Get the value of the named property as a fourcc.
 </para>
 
-@caps: 
-@name: 
+@caps: the caps to query
+@name: the name of the property to get
 
 
 <!-- ##### MACRO gst_caps_get_int ##### -->
 <para>
-
+Get the value of the named property as an int.
 </para>
 
-@caps: 
-@name: 
+@caps: the caps to query
+@name: the name of the property to get
 
 
 <!-- ##### MACRO gst_caps_get_string ##### -->
 <para>
-
+Get the value of the named property as a string.
 </para>
 
-@caps: 
-@name: 
+@caps: the caps to query
+@name: the name of the property to get
 
 
 <!-- ##### FUNCTION gst_caps_save_thyself ##### -->
index cbf398b4a3ddcb62ac258a47c5ddd9786fcbc92d..0c3c2e5f89637c6969f48acd457f479b11775cd1 100644 (file)
@@ -10,7 +10,9 @@ Request the features of the CPU.
 This module can be used when developing plugins. It is
 typically used to enable special optimisations based on the
 features of the CPU.
-
+</para>
+<para>
+You'll get a bitmask of flags with gst_cpu_get_flags().
 </para>
 
 <!-- ##### SECTION See_Also ##### -->
diff --git a/docs/gst/tmpl/gstdisksink.sgml b/docs/gst/tmpl/gstdisksink.sgml
new file mode 100644 (file)
index 0000000..1f446df
--- /dev/null
@@ -0,0 +1,36 @@
+<!-- ##### SECTION Title ##### -->
+GstDiskSink
+
+<!-- ##### SECTION Short_Description ##### -->
+Write to a file
+
+<!-- ##### SECTION Long_Description ##### -->
+<para>
+The disksink write to a file. The filename can be given as an argument.
+</para>
+
+<!-- ##### SECTION See_Also ##### -->
+<para>
+#GstFdSink
+</para>
+
+<!-- ##### ENUM GstDiskSinkFlags ##### -->
+<para>
+
+</para>
+
+@GST_DISKSINK_OPEN: 
+@GST_DISKSINK_FLAG_LAST: 
+
+<!-- ##### SIGNAL GstDiskSink::handoff ##### -->
+<para>
+Is emited after the buffer has been written to the disk.
+</para>
+
+@gstdisksink: the object which received the signal.
+
+<!-- ##### ARG GstDiskSink:location ##### -->
+<para>
+The filename to write to.
+</para>
+
index 9d405d62f44de8265d68a338940bf297572f4225..091729ef4a14561c2e41cd8fa5cd7b85450444b6 100644 (file)
@@ -28,3 +28,8 @@ with the buffer. (fakesink)
 
 </para>
 
+<!-- ##### ARG GstFakeSink:silent ##### -->
+<para>
+
+</para>
+
index 996a7a7041b747b92a13b67aa91e583561c70658..0a059cf4324f56f923c834aa83ca128a7a1e62ea 100644 (file)
@@ -24,3 +24,8 @@ Pass data without modification.
 
 </para>
 
+<!-- ##### ARG GstIdentity:silent ##### -->
+<para>
+
+</para>
+
index bc51b8eb220c3f5230e96a3ee122af70ac311eb2..d4ba5205223dbcb11ee5e9456aa7ff712137f2bc 100644 (file)
@@ -6,14 +6,66 @@ The connection between Elements
 
 <!-- ##### SECTION Long_Description ##### -->
 <para>
-Elements are connected to each other via "pads", which are extremely light-weight generic 
-connections. 
+#GstElement are connected to each other via "pads", which are extremely light-weight generic 
+connections. After two pad are retrieved from an element with gst_element_get_pad(), the pads
+can be connected with gst_pad_connect().
+</para>
+<para>
+PedTemplates are use to describe the runtime behaviour of an element and what pads it
+will have during its lifetime. Pads are typically created from a padtemplate with 
+GST_PADTEMPLATE_NEW() or with the factory macro GST_PADTEMPLATE_FACTORY().
+</para>
+<para>
+Pad and PadTemplates have #GstCaps attached to it to describe the media type they
+are capable of dealing with. gst_pad_get_caps() and gst_pad_set_caps() are used to
+manipulate the caps of the pads. gst_padtemplate_get_caps() is used to get the
+caps of a padtemplate. It's not possible to modify the caps of a padtemplate after
+creation. The following code example shows the code to create a pad from a padtemplate.
+<programlisting>
+GST_PADTEMPLATE_FACTORY (my_factory,
+  "sink",              /* the name of the pad */
+  GST_PAD_SINK,                /* the direction of the pad */
+  GST_PAD_ALWAYS,      /* when this pad will be present */
+  GST_CAPS_NEW (       /* the capabilities of the padtemplate */
+    "my_caps",
+    "audio/raw",
+      "format",                GST_PROPS_STRING ("int"),
+      "channels",      GST_PROPS_INT_RANGE (1, 6)
+  )
+)
 
+void
+my_method (void) 
+{
+  GstPad *pad;
+  
+  pad = gst_pad_new_from_template (GST_PADTEMPLATE_GET (my_factory), "sink");
+  ...
+}
+</programlisting>
+Pads created from a padtemplate cannot set capabilities that are incompatible with
+the padtemplates capabilities.
+</para>
+<para>
+Pads without padtemplates can be created with gst_pad_new() which takes a direction and
+a name as an argument.
+</para>
+<para>
+gst_pad_get_parent() will retrieve the GstElement that owns the pad.
+</para>
+<para>
+GstElements creating a pad will typicilally use the various gst_pad_set_*_function() calls
+to register callbacks for various events on the pads.
+</para>
+<para>
+GstElements will use gst_pad_push() and gst_pad_pull() to push out or pull a buffer in. The
+gst_pad_pullregion() function can be used to request for a buffer with a specific offset (in
+time or in bytes).
 </para>
 
 <!-- ##### SECTION See_Also ##### -->
 <para>
-
+#GstCaps, #GstElement
 </para>
 
 <!-- ##### MACRO GST_PAD_NAME ##### -->
@@ -157,11 +209,22 @@ The function that will be called in an EOS case.
 
 <!-- ##### USER_FUNCTION GstPadNewCapsFunction ##### -->
 <para>
+The function that will be called when the caps of the pad has
+changed.
+</para>
+
+@pad: The pad that has its caps changed
+@caps: the new caps of the pad
 
+
+<!-- ##### USER_FUNCTION GstPadBufferPoolFunction ##### -->
+<para>
+The function that will be called when a bufferpool is requested
+from this pad.
 </para>
 
-@pad: 
-@caps: 
+@pad: the pad with the bufferpool
+@Returns: the GstBufferPool associated with this pad.
 
 
 <!-- ##### ENUM GstPadNegotiateReturn ##### -->
@@ -180,10 +243,8 @@ The function that will be called when negotiating.
 
 @pad: The pad that is being negotiated
 @caps: The current caps that are being negotiated
-@data: 
+@data: A generic gpointer that can be used to store user_data
 @Returns: The result of the negotiation process
-<!-- # Unused Parameters # -->
-@count: A counter to keep track of the negotiation process
 
 
 <!-- ##### USER_FUNCTION GstPadPushFunction ##### -->
@@ -349,6 +410,15 @@ Destroy the pad.
 @newcaps: 
 
 
+<!-- ##### FUNCTION gst_pad_set_bufferpool_function ##### -->
+<para>
+
+</para>
+
+@pad: 
+@bufpool: 
+
+
 <!-- ##### FUNCTION gst_pad_set_caps ##### -->
 <para>
 
@@ -530,6 +600,15 @@ Destroy the pad.
 @size: 
 
 
+<!-- ##### FUNCTION gst_pad_get_bufferpool ##### -->
+<para>
+
+</para>
+
+@pad: 
+@Returns: 
+
+
 <!-- ##### FUNCTION gst_pad_set_eos ##### -->
 <para>
 
@@ -611,26 +690,26 @@ Call the EOS function of the pad
 
 <!-- ##### MACRO GST_RPAD_LEN ##### -->
 <para>
-
+Get the length of the region that is being pulled.
 </para>
 
-@pad: 
+@pad: the real pad to query.
 
 
 <!-- ##### MACRO GST_RPAD_OFFSET ##### -->
 <para>
-
+Get the offset of the region that is being pulled.
 </para>
 
-@pad: 
+@pad: the real pad to query.
 
 
 <!-- ##### MACRO GST_RPAD_REGIONTYPE ##### -->
 <para>
-
+Get the type of the region that is being pulled.
 </para>
 
-@pad: 
+@pad: the real pad to query.
 
 
 <!-- ##### STRUCT GstRealPad ##### -->
@@ -657,6 +736,7 @@ Call the EOS function of the pad
 @pullregionfunc: 
 @negotiatefunc: 
 @newcapsfunc: 
+@bufferpoolfunc: 
 @ghostpads: 
 
 <!-- ##### MACRO GST_RPAD_DIRECTION ##### -->
@@ -757,18 +837,26 @@ Get the EOS function of the real pad.
 
 <!-- ##### MACRO GST_RPAD_NEGOTIATEFUNC ##### -->
 <para>
-
+Get the negotiate function from the real pad.
 </para>
 
-@pad: 
+@pad: the real pad to query.
 
 
 <!-- ##### MACRO GST_RPAD_NEWCAPSFUNC ##### -->
 <para>
+Get the newcaps function from the real pad.
+</para>
+
+@pad: the real pad to query.
+
 
+<!-- ##### MACRO GST_RPAD_BUFFERPOOLFUNC ##### -->
+<para>
+Get the bufferpoolfunction from the real pad.
 </para>
 
-@pad: 
+@pad: the real pad to query.
 
 
 <!-- ##### MACRO GST_GPAD_REALPAD ##### -->
@@ -804,7 +892,8 @@ Indicates when this pad will become available.
 
 @GST_PAD_ALWAYS: the pad is always available
 @GST_PAD_SOMETIMES: the pad will become available depending on the media stream
-@GST_PAD_REQUEST: 
+@GST_PAD_REQUEST: th pad is only available on request with 
+gst_element_request_pad_by_name() or gst_element_request_compatible_pad().
 
 <!-- ##### STRUCT GstPadTemplate ##### -->
 <para>
@@ -819,34 +908,66 @@ Indicates when this pad will become available.
 
 <!-- ##### MACRO GST_PADTEMPLATE_CAPS ##### -->
 <para>
-
+Get a handle to the padtemplate #GstCaps
 </para>
 
-@templ: 
+@templ: the template to query
 
 
 <!-- ##### MACRO GST_PADTEMPLATE_DIRECTION ##### -->
 <para>
-
+Get the direction of the padtemplate.
 </para>
 
-@templ: 
+@templ: the template to query
 
 
 <!-- ##### MACRO GST_PADTEMPLATE_NAME_TEMPLATE ##### -->
 <para>
-
+Get the nametemplate of the padtemplate.
 </para>
 
-@templ: 
+@templ: the template to query
 
 
 <!-- ##### MACRO GST_PADTEMPLATE_PRESENCE ##### -->
 <para>
+Get the presence of the padtemplate.
+</para>
+
+@templ: the template to query
 
+
+<!-- ##### MACRO GST_PADTEMPLATE_NEW ##### -->
+<para>
+Create a new padtemplate.
 </para>
 
-@templ: 
+@padname: the nametemplate for the pads that will be created with this template
+@dir: the direction of the pads.
+@pres: the presence of the pads.
+@a...: the capabilities of this padtemplate usually created with GST_CAPS_NEW()
+
+
+<!-- ##### MACRO GST_PADTEMPLATE_FACTORY ##### -->
+<para>
+Create a factory for a padtemplate. This can be used if you only want one instance
+of the padtemplate. Use GST_PADTEMPLATE_GET() to get the unique padtemplate.
+</para>
+
+@name: th name of the factory
+@padname: the nametemplate of the pads
+@dir: the direction of the pads.
+@pres: the presence of the pads.
+@a...: the capabilities of this padtemplate, usually created with GST_CAPS_NEW()
+
+
+<!-- ##### MACRO GST_PADTEMPLATE_GET ##### -->
+<para>
+Get the padtemplate of the factory created with GST_PADTEMPLATE_FACTORY()
+</para>
+
+@fact: the factory name to get the padtemplate from.
 
 
 <!-- ##### FUNCTION gst_padtemplate_new ##### -->
@@ -860,8 +981,6 @@ Indicates when this pad will become available.
 @caps: 
 @Varargs: 
 @Returns: 
-<!-- # Unused Parameters # -->
-@factory: 
 
 
 <!-- ##### FUNCTION gst_padtemplate_load_thyself ##### -->
@@ -881,8 +1000,6 @@ Indicates when this pad will become available.
 @templ: 
 @parent: 
 @Returns: 
-<!-- # Unused Parameters # -->
-@pad: 
 
 
 <!-- ##### FUNCTION gst_padtemplate_get_caps ##### -->
index 5cd6fc2996a47c53bed4c8e5b9b578e5ae404c8e..44961a548fe002b53032a78d4dcedab59cc97849 100644 (file)
@@ -7,7 +7,36 @@ Parses commandline syntax into a pipeline.
 <!-- ##### SECTION Long_Description ##### -->
 <para>
 This method allows you to create a pipeline from a command
-line syntax description.
+line syntax description. The following example creates a simple
+mp3 player.
+<programlisting>
+  GstElement *pipeline;
+
+  /* create a pipeline to hold our elements */
+  pipeline = gst_pipeline_new ("launch");
+
+  /* build a pipeline in the pipeline */
+  gst_parse_launch ("disksrc location=some.mp3 ! mad ! osssink", GST_BIN (pipeline));
+
+  /* play the thing */
+  gst_element_set_state (pipeline, GST_STATE_PLAYING);
+
+  while (gst_bin_iterate (GST_BIN (pipeline)));
+
+  gst_element_set_state (pipeline, GST_STATE_NULL);
+
+</programlisting>
+</para>
+
+<para>
+Elements are separated with a <option>!</option>, properties are set with 
+<replaceable>property</replaceable>=<replaceable>value</replaceable>, specific pads
+of an element are selected by replacing the <option>!</option> with 
+<replaceable>padname</replaceable><option>!</option>.
+</para>
+<para>
+Elements can be added to a bin by embracing them with <option>()</option>. Threads
+can be made with <option>{}</option>. 
 </para>
 
 <!-- ##### SECTION See_Also ##### -->
index f486cfb19374298f5c7b4547f6fbb0659447334e..05c2302598045c1f7e74790d1a0a878a137b4e2e 100644 (file)
@@ -12,12 +12,6 @@ including threading, as well as provide simple interfaces to common
 functions, like 'Play'.
 </para>
 
-<para>
-The pipeline also has the capability to autoplug. This feature
-allows you to only define the input/output plugins and let the
-pipeline figure out what plugins to use.
-</para>
-
 <!-- ##### SECTION See_Also ##### -->
 <para>
 
index ff213c93272c29b34d998fb98eb06563914d9ce1..1b67696aa1c03d899bc0797d7c2726acc3ea3f95 100644 (file)
@@ -6,13 +6,51 @@ Dynamically loadable Elements
 
 <!-- ##### SECTION Long_Description ##### -->
 <para>
-GStreamer is extensible so <classname>GstElements</classname> can be loaded at runtime.
-
+GStreamer is extensible so <classname>GstElements</classname> can be loaded at runtime. A plugin
+system can provide one or more of the following basic <application>GStreamer</application> 
+objects factories:
+ <itemizedlist>
+  <listitem>
+   <para>
+    A #GstElementFactory: the components to build a pipeline.
+   </para>
+  </listitem>
+  <listitem>
+   <para>
+    A #GstTypeFactory: A MIME type and an optional typefind function.
+   </para>
+  </listitem>
+  <listitem>
+   <para>
+    A #GstAutoplugFactory: An object used to automatically construct pipelines.
+   </para>
+  </listitem>
+ </itemizedlist>
+</para>
+<para>
+A new plugin is created with gst_plugin_new(). this function will return a handle
+to the GstPlugin or NULL if the plugin could not be created.
+</para>
+<para>
+Once a GstPlugin element has been created, you can add the different types of factories
+to it with gst_plugin_add_factory(), gst_plugin_add_type(), gst_plugin_add_autoplugger().
+</para>
+<para>
+<application>Gstreamer</application> plugins should have a method plugin_init that is called
+by the loader.
+</para>
+<para>
+use gst_plugin_find(), gst_plugin_get_list(), gst_plugin_get_factory_list(), gst_plugin_get_type_list() and
+gst_plugin_get_autoplug_list() to query the plugin repository.
+</para>
+<para>
+Plugins are always automaticlly loaded  so you don't need to call gst_plugin_load() explicitly 
+to bring it into memory. 
 </para>
 
 <!-- ##### SECTION See_Also ##### -->
 <para>
-
+#GstElement, #GstType, #GstAutoplug
 </para>
 
 <!-- ##### STRUCT GstPlugin ##### -->
@@ -31,12 +69,6 @@ GStreamer is extensible so <classname>GstElements</classname> can be loaded at r
 @numautopluggers: 
 @loaded: 
 
-<!-- ##### STRUCT GstPluginElement ##### -->
-<para>
-
-</para>
-
-
 <!-- ##### USER_FUNCTION GstPluginInitFunc ##### -->
 <para>
 A plugin should implement this function called plugin_init. It will be called
@@ -44,15 +76,28 @@ by the loader at statup.
 </para>
 
 @module: The <classname>GModule</classname> it was loaded from
+@plugin: 
 @Returns: The plugin or NULL is an error was detected.
 
 
+<!-- ##### STRUCT GstPluginDesc ##### -->
+<para>
+
+</para>
+
+@major_version: 
+@minor_version: 
+@name: 
+@plugin_init: 
+
 <!-- ##### FUNCTION gst_plugin_new ##### -->
 <para>
 
 </para>
 
 @name: 
+@major: 
+@minor: 
 @Returns: 
 
 
index 2c5f0eaf16f5c1d99b7d7cf7d3d0442bc1d81835..7b318cbd046c0e44c4d65f4bf0b294c6f28ec2f6 100644 (file)
@@ -12,7 +12,7 @@ are usually used in conjunction with GstCaps.
 
 <!-- ##### SECTION See_Also ##### -->
 <para>
-GstCaps
+#GstCaps
 </para>
 
 <!-- ##### STRUCT GstProps ##### -->
@@ -26,13 +26,32 @@ GstCaps
 
 <!-- ##### MACRO GST_MAKE_FOURCC ##### -->
 <para>
+Create a FOURCC value that can easily be used to construct
+a fourcc property.
+<programlisting>
+  ...
+  "format", GST_PROPS_FOURCC (GST_MAKE_FOURCC ('Y','U','Y','2')),
+  ...
+</programlisting>
+</para>
+
+@a: first fourcc byte
+@b: second fourcc byte
+@c: third fourcc byte
+@d: fourth fourcc byte
+
 
+<!-- ##### MACRO GST_STR_FOURCC ##### -->
+<para>
+Create a FOURCC value from a string. example:
+<programlisting>
+  ...
+  "format", GST_PROPS_FOURCC (GST_STR_FOURCC ("YUY2")),
+  ...
+</programlisting>
 </para>
 
-@a: 
-@b: 
-@c: 
-@d: 
+@f: the string describing the fourcc value.
 
 
 <!-- ##### MACRO GST_PROPS_LIST ##### -->
@@ -65,11 +84,7 @@ Create an integer range property.
 Construct a fourcc property out of four bytes.
 </para>
 
-@a: first byte
-<!-- # Unused Parameters # -->
-@b: second byte
-@c: third byte
-@d: fourth byte
+@a: a fourcc value usualy created with GST_FOURCC_MAKE ()
 
 
 <!-- ##### MACRO GST_PROPS_BOOLEAN ##### -->
@@ -82,27 +97,27 @@ Create a boolean property.
 
 <!-- ##### MACRO GST_PROPS_STRING ##### -->
 <para>
-
+Create a string value.
 </para>
 
-@a: 
+@a: the string value.
 
 
 <!-- ##### MACRO GST_PROPS_FLOAT ##### -->
 <para>
-
+Create a floating point value.
 </para>
 
-@a: 
+@a: the float value
 
 
 <!-- ##### MACRO GST_PROPS_FLOAT_RANGE ##### -->
 <para>
-
+Create a float range value.
 </para>
 
-@a: 
-@b: 
+@a: lower float bounds
+@b: upper float bounds
 
 
 <!-- ##### FUNCTION gst_props_new ##### -->
@@ -113,8 +128,6 @@ Create a boolean property.
 @firstname: 
 @Varargs: 
 @Returns: 
-<!-- # Unused Parameters # -->
-@entry: 
 
 
 <!-- ##### FUNCTION gst_props_newv ##### -->
index c750b5e1da43d37ee1107a68b596ce60f5441f0e..fe8813185c258db9dca346654b27bbde43e6a6a4 100644 (file)
@@ -1421,6 +1421,13 @@ This macro sets the given flags.
 @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 DEBUG_LEAVE_STRING ##### -->
 <para>
 
@@ -1508,6 +1515,12 @@ Indicates a srcpad for the padfactory.
 </para>
 
 
+<!-- ##### ARG GstDiskSink:closed ##### -->
+<para>
+
+</para>
+
+
 <!-- ##### MACRO GST_IS_SINK_CLASS ##### -->
 <para>
 
@@ -2541,6 +2554,12 @@ This macro checks to see if the GST_SRC_ASYNC flag is set.
 </para>
 
 
+<!-- ##### STRUCT GstPluginElement ##### -->
+<para>
+
+</para>
+
+
 <!-- ##### TYPEDEF GstCapsFactory ##### -->
 <para>
 
index 765237b7adaa8ee2ef43d13f42355aafde02cfbf..953e67606fe57b8c5512a99d941d2f692ab74f2d 100644 (file)
@@ -41,7 +41,7 @@ sgml/$(DOC_MODULE)-doc.bottom: tmpl/$(DOC_MODULE)-unused.sgml
 all-local: html
 
 clean-local:
-       $(RM) -rf *~ *.bak *.signals *-unused.txt *.args tmpl html sgml tmpl/*.bak $(DOC_MODULE)-decl-list.txt $(DOC_MODULE)-decl.txt 
+       $(RM) -rf *~ *.bak *.signals *-unused.txt *.args html sgml tmpl/*.bak $(DOC_MODULE)-decl-list.txt $(DOC_MODULE)-decl.txt 
 
 install-data-local: html
        @$(mkinstalldirs) $(DESTDIR)$(TARGET_DIR)
index 17a14055c2d85c51c8bb056c5c352e068d8f8a83..c251eabb68f5fc73e52c33b88ff4ceb3026e0a94 100644 (file)
@@ -1,4 +1,11 @@
-SUBDIRS = autoplug \
+
+if HAVE_GNOME
+GNOME_SUBDS = autoplug
+else
+GNOME_SUBDS =
+endif
+
+SUBDIRS = $(GNOME_SUBDS) \
           helloworld helloworld2 \
           queue queue2 queue3 queue4 \
           launch thread xml plugins typefind
index 4a3453552cc83e2927768032614d4294ed28d4bc..e9135fb8d22479608811406ee0c7192d1bf378da 100644 (file)
@@ -1,26 +1,67 @@
 #include <gst/gst.h>
 #include <gnome.h>
 
-static gboolean playing;
-
-/* eos will be called when the src element has an end of stream */
-void eos(GstElement *element) 
+static void
+gst_play_have_type (GstElement *sink, GstElement *sink2, gpointer data)
 {
-  g_print("have eos, quitting\n");
+  GST_DEBUG (0,"GstPipeline: play have type %p\n", (gboolean *)data);
 
-  playing = FALSE;
+  *(gboolean *)data = TRUE;
 }
 
-gboolean idle_func(gpointer data) {
-  gst_bin_iterate(GST_BIN(data));
-  return TRUE;
+gboolean 
+idle_func (gpointer data)
+{
+  return gst_bin_iterate (GST_BIN (data));
+}
+
+static GstCaps*
+gst_play_typefind (GstBin *bin, GstElement *element)
+{
+  gboolean found = FALSE;
+  GstElement *typefind;
+  GstCaps *caps = NULL;
+
+  GST_DEBUG (0,"GstPipeline: typefind for element \"%s\" %p\n",
+             GST_ELEMENT_NAME(element), &found);
+
+  typefind = gst_elementfactory_make ("typefind", "typefind");
+  g_return_val_if_fail (typefind != NULL, FALSE);
+
+  gtk_signal_connect (GTK_OBJECT (typefind), "have_type",
+                      GTK_SIGNAL_FUNC (gst_play_have_type), &found);
+
+  gst_pad_connect (gst_element_get_pad (element, "src"),
+                   gst_element_get_pad (typefind, "sink"));
+
+  gst_bin_add (bin, typefind);
+
+  gst_element_set_state (GST_ELEMENT (bin), GST_STATE_PLAYING);
+
+  // push a buffer... the have_type signal handler will set the found flag
+  gst_bin_iterate (bin);
+
+  gst_element_set_state (GST_ELEMENT (bin), GST_STATE_NULL);
+
+  caps = gst_pad_get_caps (gst_element_get_pad (element, "src"));
+
+  gst_pad_disconnect (gst_element_get_pad (element, "src"),
+                      gst_element_get_pad (typefind, "sink"));
+  gst_bin_remove (bin, typefind);
+  gst_object_unref (GST_OBJECT (typefind));
+
+  return caps;
 }
 
 int main(int argc,char *argv[]) 
 {
-  GstElement *disksrc, *audiosink, *videosink;
-  GstElement *pipeline;
+  GstElement *disksrc, *osssink, *videosink;
+  GstElement *bin;
   GtkWidget *appwindow;
+  GstCaps *srccaps;
+  GstElement *new_element;
+  GstAutoplug *autoplug;
+  GtkWidget *socket;
 
   g_thread_init(NULL);
   gst_init(&argc,&argv);
@@ -31,58 +72,82 @@ int main(int argc,char *argv[])
     exit(-1);
   }
 
-
-
   /* create a new bin to hold the elements */
-  pipeline = gst_pipeline_new("pipeline");
-  g_assert(pipeline != NULL);
+  bin = gst_pipeline_new("pipeline");
+  g_assert(bin != NULL);
 
   /* create a disk reader */
   disksrc = gst_elementfactory_make("disksrc", "disk_source");
   g_assert(disksrc != NULL);
   gtk_object_set(GTK_OBJECT(disksrc),"location", argv[1],NULL);
-  gtk_signal_connect(GTK_OBJECT(disksrc),"eos",
-                     GTK_SIGNAL_FUNC(eos),NULL);
 
+  gst_bin_add (GST_BIN (bin), disksrc);
+
+  srccaps = gst_play_typefind (GST_BIN (bin), disksrc);
+
+  if (!srccaps) {
+    g_print ("could not autoplug, unknown media type...\n");
+    exit (-1);
+  }
+  
   /* and an audio sink */
-  audiosink = gst_elementfactory_make("audiosink", "play_audio");
-  g_assert(audiosink != NULL);
+  osssink = gst_elementfactory_make("osssink", "play_audio");
+  g_assert(osssink != NULL);
 
   /* and an video sink */
-  videosink = gst_elementfactory_make("videosink", "play_video");
+  videosink = gst_elementfactory_make("xvideosink", "play_video");
   g_assert(videosink != NULL);
-  gtk_object_set(GTK_OBJECT(videosink),"xv_enabled", FALSE,NULL);
+
+  autoplug = gst_autoplugfactory_make ("staticrender");
+  g_assert (autoplug != NULL);
+
+  new_element = gst_autoplug_to_renderers (autoplug,
+           srccaps,
+           videosink,
+           osssink,
+           NULL);
+
+  if (!new_element) {
+    g_print ("could not autoplug, no suitable codecs found...\n");
+    exit (-1);
+  }
+
+  gst_bin_remove (GST_BIN (bin), disksrc);
+  // FIXME hack, reparent the disksrc so the scheduler doesn't break
+  bin = gst_pipeline_new("pipeline");
+
+  gst_bin_add (GST_BIN (bin), disksrc);
+  gst_bin_add (GST_BIN (bin), new_element);
+
+  gst_element_connect (disksrc, "src", new_element, "sink");
 
   appwindow = gnome_app_new("autoplug demo","autoplug demo");
+
+  socket = gtk_socket_new ();
+  gtk_widget_show (socket);
+
   gnome_app_set_contents(GNOME_APP(appwindow),
-    gst_util_get_widget_arg(GTK_OBJECT(videosink),"widget"));
-  gtk_widget_show_all(appwindow);
+               GTK_WIDGET (socket));
 
-  /* add objects to the main pipeline */
-  gst_pipeline_add_src(GST_PIPELINE(pipeline), disksrc);
-  gst_pipeline_add_sink(GST_PIPELINE(pipeline), videosink);
-  gst_pipeline_add_sink(GST_PIPELINE(pipeline), audiosink);
+  gtk_widget_realize (socket);
+  gtk_socket_steal (GTK_SOCKET (socket), 
+                   gst_util_get_int_arg (GTK_OBJECT (videosink), "xid"));
 
-  if (!gst_pipeline_autoplug(GST_PIPELINE(pipeline))) {
-    g_print("unable to handle stream\n");
-    exit(-1);
-  }
+  gtk_widget_show_all(appwindow);
 
-  xmlSaveFile("xmlTest.gst", gst_xml_write(GST_ELEMENT(pipeline)));
+  xmlSaveFile("xmlTest.gst", gst_xml_write(GST_ELEMENT(bin)));
 
   /* start playing */
-  gst_element_set_state(GST_ELEMENT(pipeline), GST_STATE_PLAYING);
-
-  playing = TRUE;
+  gst_element_set_state(GST_ELEMENT(bin), GST_STATE_PLAYING);
 
-  gtk_idle_add(idle_func, pipeline);
+  gtk_idle_add(idle_func, bin);
 
   gst_main();
 
   /* stop the bin */
-  gst_element_set_state(GST_ELEMENT(pipeline), GST_STATE_NULL);
+  gst_element_set_state(GST_ELEMENT(bin), GST_STATE_NULL);
 
-  gst_pipeline_destroy(pipeline);
+  gst_pipeline_destroy(bin);
 
   exit(0);
 }
diff --git a/examples/mixer/.gitignore b/examples/mixer/.gitignore
new file mode 100644 (file)
index 0000000..31e0fce
--- /dev/null
@@ -0,0 +1 @@
+helloworld
diff --git a/examples/mixer/Makefile.am b/examples/mixer/Makefile.am
new file mode 100644 (file)
index 0000000..9c5573b
--- /dev/null
@@ -0,0 +1,4 @@
+noinst_PROGRAMS = mixer
+
+LIBS += $(GST_LIBS)
+CFLAGS += $(GST_CFLAGS)
diff --git a/examples/mixer/mixer.c b/examples/mixer/mixer.c
new file mode 100644 (file)
index 0000000..205d073
--- /dev/null
@@ -0,0 +1,360 @@
+/*
+ * mixer.c - stereo audio mixer - thomas@apestaart.org
+ * example based on helloworld
+ * demonstrates the adder plugin and the volume envelope plugin 
+ * work in progress but do try it out 
+ * 
+ * Latest change :     16/04/2001
+ *                                     multiple input channels allowed
+ *                                     volume envelope adapted 
+ * Version :           0.3
+ */
+
+#include <stdlib.h>
+#include <gst/gst.h>
+#include "mixer.h"
+#include <unistd.h>
+
+//#define DEBUG
+
+/* function prototypes */
+
+input_channel_t*       create_input_channel (int id, char* location);
+void                           destroy_input_channel (input_channel_t *pipe);
+void                           env_register_cp (GstElement *volenv, double cp_time, double cp_level);
+
+
+gboolean playing;
+
+
+/* eos will be called when the src element has an end of stream */
+void eos(GstElement *element) 
+{
+  g_print("have eos, quitting ?\n");
+
+//  playing = FALSE;
+}
+
+static void
+gst_play_have_type (GstElement *sink, GstElement *sink2, gpointer data)
+{
+  GST_DEBUG (0,"GstPipeline: play have type %p\n", (gboolean *)data);
+  *(gboolean *)data = TRUE;
+}
+
+static GstCaps*
+gst_play_typefind (GstBin *bin, GstElement *element)
+{
+  gboolean found = FALSE;
+  GstElement *typefind;
+  GstCaps *caps = NULL;
+
+  GST_DEBUG (0,"GstPipeline: typefind for element \"%s\" %p\n",
+             GST_ELEMENT_NAME(element), &found);
+  typefind = gst_elementfactory_make ("typefind", "typefind");
+  g_return_val_if_fail (typefind != NULL, FALSE);
+
+  gtk_signal_connect (GTK_OBJECT (typefind), "have_type",  
+                      GTK_SIGNAL_FUNC (gst_play_have_type), &found);
+  gst_pad_connect (gst_element_get_pad (element, "src"),
+                   gst_element_get_pad (typefind, "sink"));
+  gst_bin_add (bin, typefind);
+  
+  gst_element_set_state (GST_ELEMENT (bin), GST_STATE_PLAYING);
+  
+  // push a buffer... the have_type signal handler will set the found flag
+  gst_bin_iterate (bin);
+  
+  gst_element_set_state (GST_ELEMENT (bin), GST_STATE_NULL);
+
+  caps = gst_pad_get_caps (gst_element_get_pad (element, "src"));
+
+  gst_pad_disconnect (gst_element_get_pad (element, "src"),
+                      gst_element_get_pad (typefind, "sink"));
+  gst_bin_remove (bin, typefind);
+  gst_object_unref (GST_OBJECT (typefind));
+                   
+  return caps;
+}
+
+int main(int argc,char *argv[]) 
+{
+  int i;
+  int num_channels;
+  
+  char buffer[20];
+  
+  GList *input_channels;               /* structure holding all the input channels */
+  
+  input_channel_t *channel_in;
+  
+  GstElement *main_bin;
+  GstElement *adder;
+  GstElement *audiosink;
+
+  GstPad *pad; /* to request pads for the adder */
+
+  gst_init(&argc,&argv);
+
+  if (argc == 1) {
+    g_print("usage: %s <filename1> <filename2> <...>\n", argv[0]);
+    exit(-1);
+  }
+  num_channels = argc - 1;
+  
+  /* set up output channel and main bin */
+  
+  /* create adder */
+  adder = gst_elementfactory_make("adder", "adderel");
+
+  /* create an audio sink */
+  audiosink = gst_elementfactory_make("esdsink", "play_audio");
+
+  /* create main bin */
+  main_bin = gst_bin_new("bin");
+
+  /* connect adder and output to bin */
+
+  gst_bin_add(GST_BIN(main_bin), adder);
+  gst_bin_add(GST_BIN(main_bin), audiosink);
+
+  /* connect adder and audiosink */
+
+  gst_pad_connect(gst_element_get_pad(adder,"src"),
+                  gst_element_get_pad(audiosink,"sink"));
+  
+  /* create input channels, add to bin and connect */
+
+  input_channels = NULL;
+  
+  for (i = 1; i < argc; ++i)
+  {
+    printf ("Opening channel %d from file %s...\n", i, argv[i]);
+    channel_in = create_input_channel (i, argv[i]);
+    input_channels = g_list_append (input_channels, channel_in);  
+    gst_bin_add(GST_BIN(main_bin), channel_in->pipe);
+
+    /* request pads and connect to adder */
+    pad = gst_element_request_pad_by_name (adder, "sink%d");
+    g_print ("\tGot new adder sink pad %s\n", gst_pad_get_name (pad));
+    sprintf (buffer, "channel%d", i);
+    gst_pad_connect (gst_element_get_pad (channel_in->pipe, buffer), pad);
+
+    /* register a volume envelope */
+    printf ("\tregistering volume envelope...\n");
+
+    /* 
+     * this is the volenv :
+     * each song gets a slot of 5 seconds, with a 5 second fadeout
+     * at the end of that, all audio streams play simultaneously
+     * at a level ensuring no distortion
+     * example for three songs :
+     * song1 : starts at full level, plays 5 seconds, faded out at 10 seconds,
+     *                    sleep until 25, fade to end level at 30
+     * song2 : starts silent, fades in at 5 seconds, full blast at 10 seconds,
+     *            full level until 15, faded out at 20, sleep until 25, fade to end at 30
+     * song3 : starts muted, fades in from 15, full at 20, until 25, fade to end level
+     */
+
+    if (i == 1)
+    {
+      /* first song gets special treatment for end style */
+      env_register_cp (channel_in->volenv,  0.0, 1.0);
+    }
+    else
+    {
+      env_register_cp (channel_in->volenv,  0.0            , 0.0000001); /* start muted */
+      env_register_cp (channel_in->volenv,  i * 10.0 - 15.0, 0.0000001); /* start fade in */
+      env_register_cp (channel_in->volenv,  i * 10.0 - 10.0, 1.0);
+    }
+    env_register_cp (channel_in->volenv,  i * 10.0 -  5.0, 1.0); /* end of full level */
+
+    if (i != num_channels)
+    {
+      env_register_cp (channel_in->volenv,  i * 10.0         , 0.0000001); /* fade to black */
+      env_register_cp (channel_in->volenv,  num_channels * 10.0 - 5.0, 0.0000001); /* start fade in */
+    }   
+    env_register_cp (channel_in->volenv,  num_channels * 10.0      , 1.0 / num_channels); /* to end level */
+  }
+
+  /* sleep a few seconds doesn't seem to help anyway */
+
+  printf ("Sleeping a few seconds ...\n");
+  sleep (2);
+  printf ("Waking up ...\n");
+
+  
+  /* start playing */
+  gst_element_set_state(main_bin, GST_STATE_PLAYING);
+
+  playing = TRUE;
+
+  while (playing) {
+    gst_bin_iterate(GST_BIN(main_bin));
+  }
+
+  /* stop the bin */
+  gst_element_set_state(main_bin, GST_STATE_NULL);
+
+  while (input_channels)
+  {
+    destroy_input_channel (input_channels->data);
+    input_channels = g_list_next (input_channels);
+  }
+  g_list_free (input_channels);
+  
+  gst_object_destroy(GST_OBJECT(audiosink));
+
+  gst_object_destroy(GST_OBJECT(main_bin));
+
+  exit(0);
+}
+
+input_channel_t*
+create_input_channel (int id, char* location)
+{
+  /* create an input channel, reading from location
+   * return a pointer to the channel
+   * return NULL if failed
+   */
+
+  input_channel_t *channel;
+  
+  char buffer[20];             /* hold the names */
+
+  GstAutoplug *autoplug;
+  GstCaps *srccaps;
+  GstElement *new_element;  
+
+#ifdef DEBUG
+  printf ("DEBUG : c_i_p : creating channel with id %d for file %s\n",
+                 id, location);
+#endif
+  
+  /* allocate channel */
+
+  channel = (input_channel_t *) malloc (sizeof (input_channel_t));
+  if (channel == NULL)
+  {
+    printf ("create_input_channel : could not allocate memory for channel !\n");
+    return NULL;
+  }
+
+  /* create channel */
+
+#ifdef DEBUG
+  printf ("DEBUG : c_i_p : creating pipeline\n");
+#endif
+
+  channel->pipe = gst_bin_new ("pipeline");
+  g_assert(channel->pipe != NULL);    
+    
+  /* create elements */
+
+#ifdef DEBUG
+  printf ("DEBUG : c_i_p : creating disksrc\n");
+#endif
+
+  sprintf (buffer, "disksrc%d", id);
+  channel->disksrc = gst_elementfactory_make ("disksrc", buffer);
+  g_assert(channel->disksrc != NULL);    
+  
+  gtk_object_set(GTK_OBJECT(channel->disksrc),"location", location, NULL);
+
+  /* add disksrc to the bin before autoplug */
+  gst_bin_add(GST_BIN(channel->pipe), channel->disksrc);
+
+  /* connect signal to eos of disksrc */
+  gtk_signal_connect(GTK_OBJECT(channel->disksrc),"eos",
+                     GTK_SIGNAL_FUNC(eos),NULL);
+
+
+#ifdef DEBUG
+  printf ("DEBUG : c_i_p : creating volume envelope\n");
+#endif
+
+  sprintf (buffer, "volenv%d", id);
+  channel->volenv = gst_elementfactory_make ("volenv", buffer);
+  g_assert(channel->volenv != NULL);    
+
+  /* autoplug the pipe */
+
+#ifdef DEBUG
+  printf ("DEBUG : c_i_p : getting srccaps\n");
+#endif
+
+  srccaps = gst_play_typefind (GST_BIN (channel->pipe), channel->disksrc);
+
+  if (!srccaps) {
+    g_print ("could not autoplug, unknown media type...\n");
+    exit (-1);
+  }
+
+#ifdef DEBUG
+  printf ("DEBUG : c_i_p : creating autoplug\n");
+#endif
+
+  autoplug = gst_autoplugfactory_make ("static");
+  g_assert (autoplug != NULL);
+
+#ifdef DEBUG
+  printf ("DEBUG : c_i_p : autoplugging\n");
+#endif
+  new_element = gst_autoplug_to_caps (autoplug, srccaps, 
+                                       gst_caps_new ("audio", "audio/raw", NULL), NULL);
+  if (!new_element) {
+    g_print ("could not autoplug, no suitable codecs found...\n");
+    exit (-1);
+  }
+  
+  gst_bin_add (GST_BIN(channel->pipe), channel->volenv);
+  gst_bin_add (GST_BIN (channel->pipe), new_element);
+  
+  gst_element_connect (channel->disksrc, "src", new_element, "sink");
+  gst_element_connect (new_element, "src_00", channel->volenv, "sink");
+  
+  /* add a ghost pad */
+  sprintf (buffer, "channel%d", id);
+  gst_element_add_ghost_pad (channel->pipe,
+                             gst_element_get_pad (channel->volenv, "src"), buffer);
+
+   
+#ifdef DEBUG
+  printf ("DEBUG : c_i_p : end function\n");
+#endif
+
+  return channel;
+}
+
+void
+destroy_input_channel (input_channel_t *channel)
+{
+  /* 
+   * destroy an input channel
+   */
+   
+#ifdef DEBUG
+  printf ("DEBUG : d_i_p : start\n");
+#endif
+
+  /* destroy elements */
+
+  gst_object_destroy (GST_OBJECT (channel->pipe));
+
+  free (channel);
+}
+
+void env_register_cp (GstElement *volenv, double cp_time, double cp_level)
+{
+  char buffer[30];
+
+  sprintf (buffer, "%f:%f", cp_time, cp_level);
+  gtk_object_set(GTK_OBJECT(volenv), "controlpoint", buffer, NULL);
+
+}
+
diff --git a/examples/mixer/mixer.h b/examples/mixer/mixer.h
new file mode 100644 (file)
index 0000000..b967141
--- /dev/null
@@ -0,0 +1,12 @@
+/*
+ * mixer.h header file
+ * thomas@apestaart.org
+ */
+
+typedef struct 
+{
+  GstElement *pipe, *disksrc, *volenv;
+  
+  char *location;
+  int channel_id;
+} input_channel_t;
index 75e5c78ce65ffadd1cf4c39a09d7818e2c1c9f92..a2dad208cf5f302f3b4b404b5f034780e9de173d 100644 (file)
@@ -335,23 +335,17 @@ gst_example_get_arg (GtkObject *object,GtkArg *arg,guint id)
 /* This is the entry into the plugin itself.  When the plugin loads,
  * this function is called to register everything that the plugin provides.
  */
-GstPlugin*
-plugin_init (GModule *module)
+static gboolean
+plugin_init (GModule *module, GstPlugin *plugin)
 {
-  GstPlugin *plugin;
   GstElementFactory *factory;
 
-  /* First we try to create a new Plugin structure. */
-  plugin = gst_plugin_new("example");
-  /* If we get a NULL back, chances are we're already loaded. */
-  g_return_val_if_fail(plugin != NULL, NULL);
-
   /* We need to create an ElementFactory for each element we provide.
    * This consists of the name of the element, the GtkType identifier,
    * and a pointer to the details structure at the top of the file.
    */
   factory = gst_elementfactory_new("example", GST_TYPE_EXAMPLE, &example_details);
-  g_return_val_if_fail(factory != NULL, NULL);
+  g_return_val_if_fail(factory != NULL, FALSE);
 
   /* The pad templates can be easily generated from the factories above,
    * and then added to the list of padtemplates for the elementfactory.
@@ -367,10 +361,27 @@ plugin_init (GModule *module)
   /* The very last thing is to register the elementfactory with the plugin. */
   gst_plugin_add_factory (plugin, factory);
 
-  /* Now we can return the pointer to the newly created Plugin object. */
-  return plugin;
+  /* Now we can return successfully. */
+  return TRUE;
 
   /* At this point, the GStreamer core registers the plugin, its
    * elementfactories, padtemplates, etc., for use in you application.
    */
 }
+
+/* This structure describes the plugin to the system for dynamically loading
+ * plugins, so that the version number and name can be checked in a uniform
+ * way.
+ *
+ * The symbol pointing to this structure is the only symbol looked up when
+ * loading the plugin.
+ */
+GstPluginDesc plugin_desc = {
+  GST_VERSION_MAJOR, /* The major version of the core that this was built with */
+  GST_VERSION_MINOR, /* The minor version of the core that this was built with */
+  "example",         /* The name of the plugin.  This must be unique: plugins with
+                     * the same name will be assumed to be identical, and only
+                     * one will be loaded. */
+  plugin_init        /* Pointer to the initialisation function for the plugin. */
+};
+
index 08f5ed37d82a2eaae7ee0e85c70e5a73d2e1f731..8e3b99e373f1f8575edca4b0e7d38475725d87b7 100644 (file)
@@ -5,3 +5,4 @@ Makefile.in
 *.la
 .deps
 .libs
+gstversion.h
index f4f8aada27581799588cfb8bddff4a5b0a42eebf..1b4323c3f872928e98d62af20b6d2c5112a6efa0 100644 (file)
@@ -116,7 +116,8 @@ libgstinclude_HEADERS =             \
        gsttypefind.h           \
        gstutils.h              \
        gstparse.h              \
-       gstxml.h
+       gstxml.h                \
+       gstversion.h
 
 noinst_HEADERS =       \
        gst_private.h   \
@@ -130,6 +131,6 @@ noinst_HEADERS =    \
 
 CFLAGS = $(LIBGST_CFLAGS)
 LIBS = $(LIBGST_LIBS)
-libgst_la_LDFLAGS = -version-info $(GSTREAMER_LIBVERSION)
+libgst_la_LDFLAGS = -version-info $(GST_LIBVERSION)
 
 EXTRA_DIST = ROADMAP
index 8b7e666cedbdf7d177c3e49345f022ea662c1ed7..c31bf57ff6900bd301bf229313defba3c598ae0b 100644 (file)
@@ -80,7 +80,8 @@ libgstinclude_HEADERS =               \
        gsttypefind.h           \
        gstutils.h              \
        gstparse.h              \
-       gstxml.h
+       gstxml.h                \
+       gstversion.h
 
 noinst_HEADERS =       \
        gst_private.h   \
@@ -92,7 +93,7 @@ noinst_HEADERS =      \
        gstsparc.h      \
        gstpropsprivate.h
 
-libgst_la_LDFLAGS = -version-info $(GSTREAMER_LIBVERSION) $(LIBGST_LIBS)
+libgst_la_LDFLAGS = -version-info $(GST_LIBVERSION) $(LIBGST_LIBS)
 libgst_la_LIBADD = libcothreads.la
 
 EXTRA_DIST = ROADMAP
index 0ddb2a8a740463d052bdbbfa2fa44cd1a094daeb..8050727ae134a3aa798227c70a2bda85923aa34d 100644 (file)
@@ -8,5 +8,5 @@ libgststaticautoplug_la_SOURCES =       \
 libgststaticautoplugrender_la_SOURCES =        \
        gststaticautoplugrender.c
 
-libgststaticautoplug_la_LDFLAGS = -version-info $(GSTREAMER_LIBVERSION)
-libgststaticautoplugrender_la_LDFLAGS = -version-info $(GSTREAMER_LIBVERSION)
+libgststaticautoplug_la_LDFLAGS = -version-info $(GST_LIBVERSION)
+libgststaticautoplugrender_la_LDFLAGS = -version-info $(GST_LIBVERSION)
index ca06fe9398b784396a8a7f7b7fd6cc029b166ffa..11403a069df30aae87966a13149cfa964e02b717 100644 (file)
@@ -80,15 +80,11 @@ gst_static_autoplug_class_init(GstStaticAutoplugClass *klass)
 static void gst_static_autoplug_init(GstStaticAutoplug *autoplug) {
 }
 
-GstPlugin*
-plugin_init (GModule *module)
+static gboolean
+plugin_init (GModule *module, GstPlugin *plugin)
 {
-  GstPlugin *plugin;
   GstAutoplugFactory *factory;
 
-  plugin = gst_plugin_new("gststaticautoplug");
-  g_return_val_if_fail(plugin != NULL,NULL);
-
   gst_plugin_set_longname (plugin, "A static autoplugger");
 
   factory = gst_autoplugfactory_new ("static",
@@ -98,9 +94,16 @@ plugin_init (GModule *module)
   if (factory != NULL) {
      gst_plugin_add_autoplugger (plugin, factory);
   }
-  return plugin;
+  return TRUE;
 }
 
+GstPluginDesc plugin_desc = {
+  GST_VERSION_MAJOR,
+  GST_VERSION_MINOR,
+  "gststaticautoplug",
+  plugin_init
+};
+
 static gboolean
 gst_autoplug_can_match (GstElementFactory *src, GstElementFactory *dest)
 {
index ec30e374a235b649c8253ec1391661a3e76863b1..c544f7f1899fd80df54953f20cf255c1d5264708 100644 (file)
@@ -80,15 +80,11 @@ gst_static_autoplug_render_class_init(GstStaticAutoplugRenderClass *klass)
 static void gst_static_autoplug_render_init(GstStaticAutoplugRender *autoplug) {
 }
 
-GstPlugin*
-plugin_init (GModule *module)
+static gboolean
+plugin_init (GModule *module, GstPlugin *plugin)
 {
-  GstPlugin *plugin;
   GstAutoplugFactory *factory;
 
-  plugin = gst_plugin_new("gststaticautoplugrender");
-  g_return_val_if_fail(plugin != NULL,NULL);
-
   gst_plugin_set_longname (plugin, "A static autoplugger");
 
   factory = gst_autoplugfactory_new ("staticrender",
@@ -98,9 +94,16 @@ plugin_init (GModule *module)
   if (factory != NULL) {
      gst_plugin_add_autoplugger (plugin, factory);
   }
-  return plugin;
+  return TRUE;
 }
 
+GstPluginDesc plugin_desc = {
+  GST_VERSION_MAJOR,
+  GST_VERSION_MINOR,
+  "gststaticautoplugrender",
+  plugin_init
+};
+
 static gboolean
 gst_autoplug_can_match (GstElementFactory *src, GstElementFactory *dest)
 {
@@ -267,7 +270,10 @@ gst_static_autoplug_to_render (GstAutoplug *autoplug, GstCaps *srccaps, GstEleme
     pad = GST_PAD_REALIZE (gst_element_get_pad_list (targetelement)->data);
     templ = GST_PAD_PADTEMPLATE (pad);
 
-    caps.sink = GST_PADTEMPLATE_CAPS (templ);
+    if (templ)
+      caps.sink = GST_PADTEMPLATE_CAPS (templ);
+    else 
+      goto next;
 
     GST_INFO (GST_CAT_AUTOPLUG_ATTEMPT,"autoplugging two caps structures");
 
@@ -283,7 +289,7 @@ gst_static_autoplug_to_render (GstAutoplug *autoplug, GstCaps *srccaps, GstEleme
     }
     else {
     }
-
+next:
     targetelement = va_arg (args, GstElement *);
   }
 
index e41a972f4025560b7dd3ecb90a8b1c15aa66e1d5..e29530e06968e2a1dfbdd14bbd69ea1eff1f8a38 100644 (file)
@@ -15,6 +15,7 @@ libgstelements_la_SOURCES =   \
        gstidentity.c           \
        gstfakesink.c           \
        gstdisksrc.c            \
+       gstdisksink.c           \
        gstfdsrc.c              \
        gstfdsink.c             \
        gstmultidisksrc.c       \
@@ -28,6 +29,7 @@ noinst_HEADERS =              \
        gstidentity.h           \
        gstfakesink.h           \
        gstdisksrc.h            \
+       gstdisksink.h           \
        gstfdsrc.h              \
        gstmultidisksrc.h       \
        gsthttpsrc.h            \
@@ -39,4 +41,4 @@ noinst_HEADERS =              \
 CFLAGS += -O2 -Wall
 
 libgstelements_la_LIBADD = $(GHTTP_LIBS)
-libgstelements_la_LDFLAGS = -version-info $(GSTREAMER_LIBVERSION)
+libgstelements_la_LDFLAGS = -version-info $(GST_LIBVERSION)
diff --git a/gst/elements/gstdisksink.c b/gst/elements/gstdisksink.c
new file mode 100644 (file)
index 0000000..0861149
--- /dev/null
@@ -0,0 +1,254 @@
+/* GStreamer
+ * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
+ *                    2000 Wim Taymans <wtay@chello.be>
+ *
+ * gstdisksink.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 "gstdisksink.h"
+
+
+GstElementDetails gst_disksink_details = {
+  "Disk Sink",
+  "Sink",
+  "Disk hole for data",
+  VERSION,
+  "Thomas <thomas@apestaart.org>",
+  "(C) 2001"
+};
+
+
+/* DiskSink signals and args */
+enum {
+  /* FILL ME */
+  SIGNAL_HANDOFF,
+  LAST_SIGNAL
+};
+
+enum {
+  ARG_0,
+  ARG_LOCATION,
+};
+
+
+static void    gst_disksink_class_init (GstDiskSinkClass *klass);
+static void    gst_disksink_init       (GstDiskSink *disksink);
+
+static void    gst_disksink_set_arg    (GtkObject *object, GtkArg *arg, guint id);
+static void    gst_disksink_get_arg    (GtkObject *object, GtkArg *arg, guint id);
+
+static gboolean gst_disksink_open_file         (GstDiskSink *sink);
+static void    gst_disksink_close_file (GstDiskSink *sink);
+
+static void    gst_disksink_chain      (GstPad *pad,GstBuffer *buf);
+
+static GstElementStateReturn gst_disksink_change_state (GstElement *element);
+
+static GstElementClass *parent_class = NULL;
+static guint gst_disksink_signals[LAST_SIGNAL] = { 0 };
+
+GtkType
+gst_disksink_get_type (void) 
+{
+  static GtkType disksink_type = 0;
+
+  if (!disksink_type) {
+    static const GtkTypeInfo disksink_info = {
+      "GstDiskSink",
+      sizeof(GstDiskSink),
+      sizeof(GstDiskSinkClass),
+      (GtkClassInitFunc)gst_disksink_class_init,
+      (GtkObjectInitFunc)gst_disksink_init,
+      (GtkArgSetFunc)gst_disksink_set_arg,
+      (GtkArgGetFunc)gst_disksink_get_arg,
+      (GtkClassInitFunc)NULL,  /* deprecated, do not use ! */
+    };
+    disksink_type = gtk_type_unique (GST_TYPE_ELEMENT, &disksink_info);
+  }
+  return disksink_type;
+}
+
+static void
+gst_disksink_class_init (GstDiskSinkClass *klass) 
+{
+  GtkObjectClass *gtkobject_class;
+  GstElementClass *gstelement_class;
+
+  gtkobject_class = (GtkObjectClass*)klass;
+  gstelement_class = (GstElementClass*)klass;
+
+  parent_class = gtk_type_class (GST_TYPE_ELEMENT);
+
+  gtk_object_add_arg_type ("GstDiskSink::location", GST_TYPE_FILENAME,
+                           GTK_ARG_READWRITE, ARG_LOCATION);
+
+  gst_disksink_signals[SIGNAL_HANDOFF] =
+    gtk_signal_new ("handoff", GTK_RUN_LAST, gtkobject_class->type,
+                    GTK_SIGNAL_OFFSET (GstDiskSinkClass, handoff),
+                    gtk_marshal_NONE__NONE, GTK_TYPE_NONE, 0);
+
+  gtk_object_class_add_signals (gtkobject_class, gst_disksink_signals,
+                                    LAST_SIGNAL);
+
+  gtkobject_class->set_arg = gst_disksink_set_arg;
+  gtkobject_class->get_arg = gst_disksink_get_arg;
+
+  gstelement_class->change_state = gst_disksink_change_state;
+}
+
+static void 
+gst_disksink_init (GstDiskSink *disksink) 
+{
+  GstPad *pad;
+  pad = gst_pad_new ("sink", GST_PAD_SINK);
+  gst_element_add_pad (GST_ELEMENT (disksink), pad);
+  gst_pad_set_chain_function (pad, gst_disksink_chain);
+
+  disksink->filename = NULL;
+  disksink->file = NULL;
+}
+
+static void
+gst_disksink_set_arg (GtkObject *object, GtkArg *arg, guint id)
+{
+  GstDiskSink *sink;
+
+  /* it's not null if we got it, but it might not be ours */
+  sink = GST_DISKSINK (object);
+
+  switch(id) {
+    case ARG_LOCATION:
+      if (sink->filename)
+       g_free (sink->filename);
+      sink->filename = g_strdup (GTK_VALUE_STRING (*arg));
+      break;
+    default:
+      break;
+  }
+}
+
+static void   
+gst_disksink_get_arg (GtkObject *object, GtkArg *arg, guint id)
+{
+  GstDiskSink *sink;
+  /* it's not null if we got it, but it might not be ours */
+  g_return_if_fail (GST_IS_DISKSINK (object));
+  sink = GST_DISKSINK (object);
+  
+  switch (id) {
+    case ARG_LOCATION:
+      GTK_VALUE_STRING (*arg) = sink->filename;
+      break;
+    default:
+      arg->type = GTK_TYPE_INVALID;
+      break;
+  }
+}
+
+static gboolean
+gst_disksink_open_file (GstDiskSink *sink)
+{
+  g_return_val_if_fail (!GST_FLAG_IS_SET (sink, GST_DISKSINK_OPEN), FALSE);
+
+  /* open the file */
+  sink->file = fopen (sink->filename, "w");
+  if (sink->file == NULL) {
+    perror ("open");
+    gst_element_error (GST_ELEMENT (sink), g_strconcat("opening file \"", sink->filename, "\"", NULL));
+    return FALSE;
+  } 
+
+  GST_FLAG_SET (sink, GST_DISKSINK_OPEN);
+
+  return TRUE;
+}
+
+static void
+gst_disksink_close_file (GstDiskSink *sink)
+{
+  g_return_if_fail (GST_FLAG_IS_SET (sink, GST_DISKSINK_OPEN));
+
+  if (fclose (sink->file) != 0)
+  {
+    perror ("close");
+    gst_element_error (GST_ELEMENT (sink), g_strconcat("closing file \"", sink->filename, "\"", NULL));
+  }
+  else {
+    GST_FLAG_UNSET (sink, GST_DISKSINK_OPEN);
+  }
+}
+
+/**
+ * gst_disksink_chain:
+ * @pad: the pad this disksink is connected to
+ * @buf: the buffer that has to be absorbed
+ *
+ * take the buffer from the pad and write to file if it's open
+ */
+static void 
+gst_disksink_chain (GstPad *pad, GstBuffer *buf) 
+{
+  GstDiskSink *disksink;
+  guint16 bytes_written = 0;
+
+  g_return_if_fail (pad != NULL);
+  g_return_if_fail (GST_IS_PAD (pad));
+  g_return_if_fail (buf != NULL);
+
+  disksink = GST_DISKSINK (gst_pad_get_parent (pad));
+
+  if (GST_FLAG_IS_SET (disksink, GST_DISKSINK_OPEN))
+  {
+    bytes_written = fwrite (GST_BUFFER_DATA (buf), 1, GST_BUFFER_SIZE (buf), disksink->file);
+    if (bytes_written < GST_BUFFER_SIZE (buf))
+    {
+      printf ("disksink : Warning : %d bytes should be written, only %d bytes written\n",
+                 GST_BUFFER_SIZE (buf), bytes_written);
+    }
+  }
+  gst_buffer_unref (buf);
+
+  gtk_signal_emit (GTK_OBJECT (disksink), gst_disksink_signals[SIGNAL_HANDOFF],
+                             disksink);
+}
+
+static GstElementStateReturn
+gst_disksink_change_state (GstElement *element)
+{
+  g_return_val_if_fail (GST_IS_DISKSINK (element), GST_STATE_FAILURE);
+
+  if (GST_STATE_PENDING (element) == GST_STATE_NULL) {
+    if (GST_FLAG_IS_SET (element, GST_DISKSINK_OPEN))
+      gst_disksink_close_file (GST_DISKSINK (element));
+  } else {
+    if (!GST_FLAG_IS_SET (element, GST_DISKSINK_OPEN)) {
+      if (!gst_disksink_open_file (GST_DISKSINK (element)))
+        return GST_STATE_FAILURE;
+    }
+  }
+
+  if (GST_ELEMENT_CLASS (parent_class)->change_state)
+    return GST_ELEMENT_CLASS (parent_class)->change_state (element);
+
+  return GST_STATE_SUCCESS;
+}
+
diff --git a/gst/elements/gstdisksink.h b/gst/elements/gstdisksink.h
new file mode 100644 (file)
index 0000000..15f3d32
--- /dev/null
@@ -0,0 +1,82 @@
+/* GStreamer
+ * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
+ *                    2000 Wim Taymans <wtay@chello.be>
+ *
+ * gstdisksink.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_DISKSINK_H__
+#define __GST_DISKSINK_H__
+
+
+#include <config.h>
+#include <gst/gst.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+GstElementDetails gst_disksink_details;
+
+
+#define GST_TYPE_DISKSINK \
+  (gst_disksink_get_type())
+#define GST_DISKSINK(obj) \
+  (GTK_CHECK_CAST((obj),GST_TYPE_DISKSINK,GstDiskSink))
+#define GST_DISKSINK_CLASS(klass) \
+  (GTK_CHECK_CLASS_CAST((klass),GST_TYPE_DISKSINK,GstDiskSinkClass))
+#define GST_IS_DISKSINK(obj) \
+  (GTK_CHECK_TYPE((obj),GST_TYPE_DISKSINK))
+#define GST_IS_DISKSINK_CLASS(obj) \
+  (GTK_CHECK_CLASS_TYPE((klass),GST_TYPE_DISKSINK))
+
+typedef struct _GstDiskSink GstDiskSink;
+typedef struct _GstDiskSinkClass GstDiskSinkClass;
+
+typedef enum {
+  GST_DISKSINK_OPEN             = GST_ELEMENT_FLAG_LAST,
+
+  GST_DISKSINK_FLAG_LAST       = GST_ELEMENT_FLAG_LAST + 2,
+} GstDiskSinkFlags;
+
+struct _GstDiskSink {
+  GstElement element;
+
+  gchar *filename;
+  FILE *file;
+};
+
+struct _GstDiskSinkClass {
+  GstElementClass parent_class;
+
+  /* signals */
+  void (*handoff) (GstElement *element,GstPad *pad);
+};
+
+GtkType gst_disksink_get_type(void);
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif /* __GST_DISKSINK_H__ */
index 9e81eb9b739796d65997eebcd44da29bf0c3665b..72d454d510cc8a03b7ec5eeeb9e2041172facb6b 100644 (file)
@@ -312,8 +312,8 @@ gst_disksrc_get_region (GstPad *pad, GstRegionType type,guint64 offset,guint64 l
 
 
 /* open the file and mmap it, necessary to go to READY state */
-static
-gboolean gst_disksrc_open_file (GstDiskSrc *src)
+static gboolean 
+gst_disksrc_open_file (GstDiskSrc *src)
 {
   g_return_val_if_fail (!GST_FLAG_IS_SET (src ,GST_DISKSRC_OPEN), FALSE);
 
index 326d0e3aaf6cb7b77837f53964e430f34245cba8..afd086212628faf55e1aa4e1d329ef107f81083b 100644 (file)
@@ -24,6 +24,7 @@
 #include <gst/gst.h>
 
 #include "gstdisksrc.h"
+#include "gstdisksink.h"
 #include "gstidentity.h"
 #include "gstfakesink.h"
 #include "gstfakesrc.h"
@@ -50,6 +51,7 @@ static struct _elements_entry _elements[] = {
   { "fakesrc",             gst_fakesrc_get_type,       &gst_fakesrc_details,           NULL },
   { "fakesink",     gst_fakesink_get_type,     &gst_fakesink_details,          NULL },
   { "disksrc",             gst_disksrc_get_type,       &gst_disksrc_details,           NULL },
+  { "disksink",            gst_disksink_get_type,      &gst_disksink_details,          NULL },
   { "identity",     gst_identity_get_type,     &gst_identity_details,          NULL },
   { "fdsink",       gst_fdsink_get_type,       &gst_fdsink_details,            NULL },
   { "fdsrc",       gst_fdsrc_get_type,         &gst_fdsrc_details,             NULL },
@@ -65,15 +67,12 @@ static struct _elements_entry _elements[] = {
   { NULL, 0 },
 };
 
-GstPlugin *plugin_init (GModule *module)
+static gboolean
+plugin_init (GModule *module, GstPlugin *plugin)
 {
-  GstPlugin *plugin;
   GstElementFactory *factory;
   gint i = 0;
 
-  plugin = gst_plugin_new("gstelements");
-  g_return_val_if_fail(plugin != NULL,NULL);
-
   gst_plugin_set_longname (plugin, "Standard GST Elements");
 
   while (_elements[i].name) {
@@ -92,5 +91,13 @@ GstPlugin *plugin_init (GModule *module)
 
 //  INFO (GST_INFO_PLUGIN_LOAD,"gstelements: loaded %d standard elements", i);
 
-  return plugin;
+  return TRUE;
 }
+
+GstPluginDesc plugin_desc = {
+  GST_VERSION_MAJOR,
+  GST_VERSION_MINOR,
+  "gstelements",
+  plugin_init
+};
+
index 81709b764bb4dba8913c6fd4af7da989418ed922..11590c4bab13e0be62137e86638815ef4c947695 100644 (file)
@@ -44,6 +44,7 @@ enum {
 enum {
   ARG_0,
   ARG_NUM_SOURCES,
+  ARG_SILENT,
 };
 
 
@@ -90,6 +91,8 @@ gst_fakesink_class_init (GstFakeSinkClass *klass)
 
   gtk_object_add_arg_type ("GstFakeSink::num_sources", GTK_TYPE_INT,
                            GTK_ARG_READWRITE, ARG_NUM_SOURCES);
+  gtk_object_add_arg_type ("GstFakeSink::silent", GTK_TYPE_BOOL,
+                           GTK_ARG_READWRITE, ARG_SILENT);
 
   gst_fakesink_signals[SIGNAL_HANDOFF] =
     gtk_signal_new ("handoff", GTK_RUN_LAST, gtkobject_class->type,
@@ -112,6 +115,7 @@ gst_fakesink_init (GstFakeSink *fakesink)
   gst_pad_set_chain_function (pad, gst_fakesink_chain);
   fakesink->sinkpads = g_slist_prepend (NULL, pad);
   fakesink->numsinkpads = 1;
+  fakesink->silent = FALSE;
 
   // we're ready right away, since we don't have any args...
 //  gst_element_set_state(GST_ELEMENT(fakesink),GST_STATE_READY);
@@ -138,6 +142,9 @@ gst_fakesink_set_arg (GtkObject *object, GtkArg *arg, guint id)
         sink->numsinkpads++;
       }
       break;
+    case ARG_SILENT:
+      sink->silent = GTK_VALUE_BOOL (*arg);
+      break;
     default:
       break;
   }
@@ -157,6 +164,9 @@ gst_fakesink_get_arg (GtkObject *object, GtkArg *arg, guint id)
     case ARG_NUM_SOURCES:
       GTK_VALUE_INT (*arg) = sink->numsinkpads;
       break;
+    case ARG_SILENT:
+      GTK_VALUE_BOOL (*arg) = sink->silent;
+      break;
     default:
       arg->type = GTK_TYPE_INVALID;
       break;
@@ -181,7 +191,8 @@ gst_fakesink_chain (GstPad *pad, GstBuffer *buf)
   g_return_if_fail (buf != NULL);
 
   fakesink = GST_FAKESINK (gst_pad_get_parent (pad));
-  g_print("fakesink: ******* (%s:%s)< \n",GST_DEBUG_PAD_NAME(pad));
+  if (!fakesink->silent)
+    g_print("fakesink: ******* (%s:%s)< (%d bytes) \n",GST_DEBUG_PAD_NAME(pad),GST_BUFFER_SIZE(buf));
   
   gst_buffer_unref (buf);
 
index 74df38700d94c44e8080bccf91d14df0698d4443..573e8e512c5706e416ad59dbed8b952260f3f4b8 100644 (file)
@@ -56,6 +56,7 @@ struct _GstFakeSink {
 
   GSList *sinkpads;
   gint numsinkpads;
+  gboolean silent;
 };
 
 struct _GstFakeSinkClass {
index a9126b671d1c54f13517b5ce608170327e0c225b..1e92dc5094f1b4b7514377b77747a559b4c5d9da 100644 (file)
@@ -44,6 +44,7 @@ enum {
   ARG_0,
   ARG_LOOP_BASED,
   ARG_SLEEP_TIME,
+  ARG_SILENT,
 };
 
 
@@ -92,24 +93,59 @@ gst_identity_class_init (GstIdentityClass *klass)
                            GTK_ARG_READWRITE, ARG_LOOP_BASED);
   gtk_object_add_arg_type ("GstIdentity::sleep_time", GTK_TYPE_UINT,
                            GTK_ARG_READWRITE, ARG_SLEEP_TIME);
+  gtk_object_add_arg_type ("GstIdentity::silent", GTK_TYPE_BOOL,
+                           GTK_ARG_READWRITE, ARG_SILENT);
 
   gtkobject_class->set_arg = gst_identity_set_arg;  
   gtkobject_class->get_arg = gst_identity_get_arg;
 }
 
+static GstBufferPool*
+gst_identity_get_bufferpool (GstPad *pad)
+{
+  GstIdentity *identity;
+
+  identity = GST_IDENTITY (gst_pad_get_parent (pad));
+
+  return gst_pad_get_bufferpool (identity->srcpad);
+}
+
+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_chain_function (identity->sinkpad, gst_identity_chain);
+  gst_pad_set_bufferpool_function (identity->sinkpad, gst_identity_get_bufferpool);
+  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);
 
   identity->loop_based = FALSE;
-//  identity->sleep_time = 10000;
   identity->sleep_time = 0;
+  identity->silent = FALSE;
 }
 
 static void 
@@ -122,7 +158,9 @@ gst_identity_chain (GstPad *pad, GstBuffer *buf)
   g_return_if_fail (buf != NULL);
 
   identity = GST_IDENTITY (gst_pad_get_parent (pad));
-  g_print("identity: ******* (%s:%s)i \n",GST_DEBUG_PAD_NAME(pad));
+
+  if (!identity->silent)
+    g_print("identity: ******* (%s:%s)i \n",GST_DEBUG_PAD_NAME(pad));
   
   gst_pad_push (identity->srcpad, buf);
 
@@ -147,7 +185,8 @@ gst_identity_loop (GstElement *element)
 
     gst_pad_push (identity->srcpad, buf);
 
-    usleep (identity->sleep_time);
+    if (identity->sleep_time)
+      usleep (identity->sleep_time);
 
   } while (!GST_ELEMENT_IS_COTHREAD_STOPPING(element));
 }
@@ -177,6 +216,9 @@ gst_identity_set_arg (GtkObject *object, GtkArg *arg, guint id)
     case ARG_SLEEP_TIME:
       identity->sleep_time = GTK_VALUE_UINT (*arg);
       break;
+    case ARG_SILENT:
+      identity->silent = GTK_VALUE_BOOL (*arg);
+      break;
     default:
       break;
   }
@@ -197,6 +239,9 @@ static void gst_identity_get_arg(GtkObject *object,GtkArg *arg,guint id) {
     case ARG_SLEEP_TIME:
       GTK_VALUE_UINT (*arg) = identity->sleep_time;
       break;
+    case ARG_SILENT:
+      GTK_VALUE_BOOL (*arg) = identity->silent;
+      break;
     default:
       arg->type = GTK_TYPE_INVALID;
       break;
index 3c536484ecf16bcf7872425436b9452a652721bd..129c4922a6cfe9e599a5da4bf98d34a0b7871e47 100644 (file)
@@ -60,6 +60,7 @@ struct _GstIdentity {
   gboolean loop_based;
 
   guint sleep_time;
+  gboolean silent;
 };
 
 struct _GstIdentityClass {
index 1294aeb9fb1572f8a2b09bdd59e76e5414058ee2..cddf7151736783d5e2a97ffe2a95e1073cdbcf39 100644 (file)
--- a/gst/gst.h
+++ b/gst/gst.h
@@ -26,8 +26,8 @@
 
 #include <glib.h>
 
+#include <gst/gstversion.h>
 #include <gst/gsttypes.h>
-
 #include <gst/gstinfo.h>
 #include <gst/gstobject.h>
 #include <gst/gstpad.h>
index 5f29ab84d1f6cfc6c00d758b0a6aaabe9b16c882..23f68e73a0088f0588abe4f719b4d8d7e7ab5ce6 100644 (file)
@@ -33,8 +33,13 @@ static GMutex *_gst_buffer_chunk_lock;
 void 
 _gst_buffer_initialize (void) 
 {
-  _gst_buffer_chunk = g_mem_chunk_new ("GstBuffer", sizeof(GstBuffer),
-    sizeof(GstBuffer) * 16, G_ALLOC_AND_FREE);
+  int buffersize = sizeof(GstBuffer);
+
+  // round up to the nearest 32 bytes for cache-line and other efficiencies
+  buffersize = ((buffersize-1 / 32) + 1) * 32;
+
+  _gst_buffer_chunk = g_mem_chunk_new ("GstBuffer", buffersize,
+    buffersize * 32, G_ALLOC_AND_FREE);
 
   _gst_buffer_chunk_lock = g_mutex_new ();
 }
@@ -56,7 +61,6 @@ gst_buffer_new(void)
   g_mutex_unlock (_gst_buffer_chunk_lock);
   GST_INFO (GST_CAT_BUFFER,"creating new buffer %p",buffer);
 
-//  g_print("allocating new mutex\n");
   buffer->lock = g_mutex_new ();
 #ifdef HAVE_ATOMIC_H
   atomic_set (&buffer->refcount, 1);
@@ -64,15 +68,16 @@ gst_buffer_new(void)
   buffer->refcount = 1;
 #endif
   buffer->flags = 0;
-  buffer->type = 0;
   buffer->data = NULL;
   buffer->size = 0;
   buffer->maxsize = 0;
   buffer->offset = 0;
   buffer->timestamp = 0;
-  buffer->metas = NULL;
+//  buffer->metas = NULL;
   buffer->parent = NULL;
   buffer->pool = NULL;
+  buffer->free = NULL;
+  buffer->copy = NULL;
   
   return buffer;
 }
@@ -126,7 +131,6 @@ gst_buffer_create_sub (GstBuffer *parent,
 
   // copy flags and type from parent, for lack of better
   buffer->flags = parent->flags;
-  buffer->type = parent->type;
 
   // set the data pointer, size, offset, and maxsize
   buffer->data = parent->data + offset;
@@ -136,9 +140,14 @@ gst_buffer_create_sub (GstBuffer *parent,
 
   // again, for lack of better, copy parent's timestamp
   buffer->timestamp = parent->timestamp;
+  buffer->maxage = parent->maxage;
 
   // no metas, this is sane I think
-  buffer->metas = NULL;
+//  buffer->metas = NULL;
+
+  // 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;
@@ -205,7 +214,7 @@ gst_buffer_append (GstBuffer *buffer,
  */
 void gst_buffer_destroy (GstBuffer *buffer) 
 {
-  GSList *metas;
+//  GSList *metas;
 
   g_return_if_fail (buffer != NULL);
 
@@ -215,10 +224,15 @@ void gst_buffer_destroy (GstBuffer *buffer)
   if (GST_BUFFER_DATA (buffer) &&
       !GST_BUFFER_FLAG_IS_SET (buffer, GST_BUFFER_DONTFREE) &&
       (buffer->parent == NULL)) {
-    g_free (GST_BUFFER_DATA (buffer));
-//    g_print("freed data in buffer\n");
+    // if there's a free function, use it
+    if (buffer->free != NULL) {
+      (buffer->free)(buffer);
+    } else {
+      g_free (GST_BUFFER_DATA (buffer));
+    }
   }
 
+/* DEPRACATED!!!
   // unreference any metadata attached to this buffer
   metas = buffer->metas;
   while (metas) {
@@ -226,6 +240,7 @@ void gst_buffer_destroy (GstBuffer *buffer)
     metas = g_slist_next (metas);
   }
   g_slist_free (buffer->metas);
+*/
 
   // unreference the parent if there is one
   if (buffer->parent != NULL)
@@ -334,7 +349,9 @@ gst_buffer_unref (GstBuffer *buffer)
  * @meta: the metadata to add to this buffer
  *
  * Add the meta data to the buffer.
+ * DEPRACATED!!!
  */
+/* DEPRACATED!!!
 void 
 gst_buffer_add_meta (GstBuffer *buffer, GstMeta *meta) 
 {
@@ -344,15 +361,18 @@ gst_buffer_add_meta (GstBuffer *buffer, GstMeta *meta)
   gst_meta_ref (meta);
   buffer->metas = g_slist_append (buffer->metas,meta);
 }
+*/
 
 /**
  * gst_buffer_get_metas:
  * @buffer: the GstBuffer to get the metadata from
  *
  * Get the metadatas from the buffer.
+ * DEPRACATED!!!
  *
  * Returns: a GSList of metadata
  */
+/* DEPRACATED!!!
 GSList*
 gst_buffer_get_metas (GstBuffer *buffer) 
 {
@@ -360,15 +380,18 @@ gst_buffer_get_metas (GstBuffer *buffer)
 
   return buffer->metas;
 }
+*/
 
 /**
  * gst_buffer_get_first_meta:
  * @buffer: the GstBuffer to get the metadata from
  *
  * Get the first metadata from the buffer.
+ * DEPRACATED!!!
  *
  * Returns: the first metadata from the buffer
  */
+/* DEPRACATED!!!
 GstMeta*
 gst_buffer_get_first_meta (GstBuffer *buffer) 
 {
@@ -378,6 +401,7 @@ gst_buffer_get_first_meta (GstBuffer *buffer)
     return NULL;
   return GST_META (buffer->metas->data);
 }
+*/
 
 /**
  * gst_buffer_remove_meta:
@@ -385,7 +409,9 @@ gst_buffer_get_first_meta (GstBuffer *buffer)
  * @meta: the metadata to remove
  *
  * Remove the given metadata from the buffer.
+ * DEPRACATED!!!
  */
+/* DEPRACATED!!!
 void 
 gst_buffer_remove_meta (GstBuffer *buffer, GstMeta *meta) 
 {
@@ -395,3 +421,46 @@ gst_buffer_remove_meta (GstBuffer *buffer, GstMeta *meta)
   buffer->metas = g_slist_remove (buffer->metas, meta);
   gst_meta_unref (meta);
 }
+*/
+
+
+
+/**
+ * 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;
+
+  // allocate a new buffer
+  newbuf = gst_buffer_new();
+
+  // if a copy function exists, use it, else copy the bytes
+  if (buffer->copy != NULL) {
+    (buffer->copy)(buffer,newbuf);
+  } else {
+    // copy the absolute size
+    newbuf->size = buffer->size;
+    // allocate space for the copy
+    newbuf->data = (guchar *)g_malloc (buffer->data);
+    // copy the data straight across
+    memcpy(newbuf,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;
+}
index fe7e1fc7824c10eb2081286a73b80cfd3cf930a9..375c27f1823fba9eaf2caee35e87d444eeacfd0c 100644 (file)
@@ -25,7 +25,7 @@
 #define __GST_BUFFER_H__
 
 #include <gst/gstobject.h>
-#include <gst/gstmeta.h>
+//#include <gst/gstmeta.h>
 
 #ifdef HAVE_CONFIG_H
 #include "config.h"
@@ -54,12 +54,15 @@ extern "C" {
   G_STMT_START{ (GST_BUFFER_FLAGS(buf) &= ~(1<<(flag))); }G_STMT_END
 
 
-#define GST_BUFFER_TYPE(buf)           (GST_BUFFER(buf)->type)
 #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_LOCK(buf)   (g_mutex_lock(GST_BUFFER(buf)->lock))
@@ -77,8 +80,14 @@ typedef enum {
 } GstBufferFlags;
 
 
+
 typedef struct _GstBuffer GstBuffer;
 
+
+typedef void   (*GstBufferFreeFunc)    (GstBuffer *buf);
+typedef void   (*GstBufferCopyFunc)    (GstBuffer *srcbuf,GstBuffer *dstbuf);
+
+
 #include <gst/gstbufferpool.h>
 
 struct _GstBuffer {
@@ -94,8 +103,6 @@ struct _GstBuffer {
 #define GST_BUFFER_REFCOUNT(buf)       (GST_BUFFER(buf)->refcount)
 #endif
 
-  /* data type of this buffer */
-  guint16 type;
   /* flags */
   guint16 flags;
 
@@ -111,13 +118,18 @@ struct _GstBuffer {
   guint64 maxage;
 
   /* pointer to metadata, is really lame right now */
-  GSList *metas;
+//  GSList *metas;
 
   /* 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 */
@@ -140,11 +152,16 @@ void              gst_buffer_unref                (GstBuffer *buffer);
 /* destroying the buffer */
 void           gst_buffer_destroy              (GstBuffer *buffer);
 
+/* copy buffer */
+GstBuffer*     gst_buffer_copy                 (GstBuffer *buffer);
+
 /* add, retrieve, and remove metadata from the buffer */
+/* DEPRACATED!!!
 void           gst_buffer_add_meta             (GstBuffer *buffer, GstMeta *meta);
 void           gst_buffer_remove_meta          (GstBuffer *buffer, GstMeta *meta);
 GstMeta*       gst_buffer_get_first_meta       (GstBuffer *buffer);
 GSList*                gst_buffer_get_metas            (GstBuffer *buffer);
+*/
 
 #ifdef __cplusplus
 }
index c77d9bdafb2d3764974410b6845b6992935f9109..df122b58b24146caa859da1092c7f8a10fc44f2a 100644 (file)
@@ -119,26 +119,32 @@ gst_caps_destroy (GstCaps *caps)
  *
  * Decrease the refcount of this caps structure, 
  * destroying it when the refcount is 0
+ *
+ * Returns: caps or NULL if the refcount reached 0
  */
-void
+GstCaps*
 gst_caps_unref (GstCaps *caps)
 {
   gboolean zero;
-  GstCaps *next;
+  GstCaps **next;
 
-  g_return_if_fail (caps != NULL);
+  g_return_val_if_fail (caps != NULL, NULL);
+  g_return_val_if_fail (caps->refcount > 0, NULL);
 
   GST_CAPS_LOCK (caps);
   caps->refcount--;
   zero = (caps->refcount == 0);
-  next = caps->next;
+  next = &caps->next;
   GST_CAPS_UNLOCK (caps);
 
-  if (next)
-    gst_caps_unref (next);
+  if (*next)
+    *next = gst_caps_unref (*next);
 
-  if (zero)
+  if (zero) {
     gst_caps_destroy (caps);
+    caps = NULL;
+  }
+  return caps;
 }
 
 /**
@@ -146,15 +152,19 @@ gst_caps_unref (GstCaps *caps)
  * @caps: the caps to ref
  *
  * Increase the refcount of this caps structure
+ *
+ * Returns: the caps with the refcount incremented
  */
-void
+GstCaps*
 gst_caps_ref (GstCaps *caps)
 {
-  g_return_if_fail (caps != NULL);
+  g_return_val_if_fail (caps != NULL, NULL);
 
   GST_CAPS_LOCK (caps);
   caps->refcount++;
   GST_CAPS_UNLOCK (caps);
+
+  return caps;
 }
 
 /**
@@ -352,6 +362,36 @@ gst_caps_get_props (GstCaps *caps)
   return caps->properties;
 }
 
+/**
+ * gst_caps_chain:
+ * @caps: a capabilty
+ * @...: more capabilities
+ *
+ * chains the given capabilities
+ *
+ * Returns: the new capability
+ */
+GstCaps*
+gst_caps_chain (GstCaps *caps, ...)
+{
+  GstCaps *orig = caps;
+  va_list var_args;
+
+  va_start (var_args, caps);
+
+  while (caps) {
+    GstCaps *toadd;
+    
+    toadd = va_arg (var_args, GstCaps*);
+    gst_caps_append (caps, toadd);
+    
+    caps = toadd;
+  }
+  va_end (var_args);
+  
+  return orig;
+}
+
 /**
  * gst_caps_append:
  * @caps: a capabilty
index c3c619ec9d1e10f527a006d6194b565a8c0bdb34..0f47c73b65e4362a52a6e30af96002c5bfb92e54 100644 (file)
@@ -56,13 +56,35 @@ struct _GstCaps {
   GstCaps *next;
 };
 
+#define GST_CAPS_NEW(name, type, a...)          \
+gst_caps_new (                                  \
+  name,                                         \
+  type,                                         \
+  gst_props_new (                               \
+    a,                                          \
+    NULL))
+
+#define GST_CAPS_FACTORY(factoryname, a...)    \
+static GstCaps*                                \
+factoryname (void)                              \
+{                                               \
+  static GstCaps *caps = NULL;                 \
+  if (!caps) {                                 \
+    caps = gst_caps_chain (a, NULL);           \
+  }                                             \
+  return caps;                                 \
+}
+
+#define GST_CAPS_GET(fact) (fact)()
+
+
 /* initialize the subsystem */
 void           _gst_caps_initialize                    (void);
 
 GstCaps*       gst_caps_new                            (const gchar *name, const gchar *mime, GstProps *props);
 
-void           gst_caps_unref                          (GstCaps *caps);
-void           gst_caps_ref                            (GstCaps *caps);
+GstCaps*       gst_caps_unref                          (GstCaps *caps);
+GstCaps*       gst_caps_ref                            (GstCaps *caps);
 void           gst_caps_destroy                        (GstCaps *caps);
 
 GstCaps*       gst_caps_copy                           (GstCaps *caps);
@@ -89,6 +111,7 @@ GstProps*    gst_caps_get_props                      (GstCaps *caps);
 
 GstCaps*       gst_caps_get_by_name                    (GstCaps *caps, const gchar *name);
 
+GstCaps*       gst_caps_chain                          (GstCaps *caps, ...); 
 GstCaps*       gst_caps_append                         (GstCaps *caps, GstCaps *capstoadd); 
 GstCaps*       gst_caps_prepend                        (GstCaps *caps, GstCaps *capstoadd); 
 
index e7fa7ce21d3fdd7a88df4209178b41b4ec17ef4e..589cf8f39d87c43c22675d501fca3089090d2510 100644 (file)
@@ -363,6 +363,15 @@ gst_object_check_uniqueness (GList *list, const gchar *name)
 }
 
 
+/**
+ * gst_object_save_thyself:
+ * @object: GstObject to save
+ * @parent: The parent XML node to save the object into
+ *
+ * Saves the given object into the parent XML node.
+ *
+ * Returns: the new xmlNodePtr with the saved object
+ */
 xmlNodePtr
 gst_object_save_thyself (GstObject *object, xmlNodePtr parent)
 {
@@ -546,6 +555,3 @@ gst_class_signal_emit_by_name (GstObject *object,
 
   gtk_signal_emit_by_name (oclass->signal_object, name, object, self);
 }
-
-
-
index 154e0e595cefe1ec0eafb6957538603ea29ab519..abfdc39da444a1e2d0fb48f11ab71214492f5df4 100644 (file)
@@ -186,6 +186,7 @@ gst_real_pad_init (GstRealPad *pad)
   pad->pullfunc = NULL;
   pad->pullregionfunc = NULL;
 
+  pad->bufferpoolfunc = NULL;
   pad->ghostpads = NULL;
   pad->caps = NULL;
 }
@@ -460,7 +461,24 @@ gst_pad_set_newcaps_function (GstPad *pad,
              GST_DEBUG_PAD_NAME(pad),pad,&GST_RPAD_NEWCAPSFUNC(pad),newcaps);
 }
 
+/**
+ * gst_pad_set_bufferpool_function:
+ * @pad: the pad to set the bufferpool function for
+ * @bufpool: the bufferpool function
+ *
+ * Set the given bufferpool function for the pad.
+ */
+void
+gst_pad_set_bufferpool_function (GstPad *pad,
+                                GstPadBufferPoolFunction bufpool)
+{
+  g_return_if_fail (pad != NULL);
+  g_return_if_fail (GST_IS_REAL_PAD (pad));
 
+  GST_RPAD_BUFFERPOOLFUNC (pad) = bufpool;
+  GST_DEBUG (0,"bufferpoolfunc for %s:%s(@%p) at %p is set to %p\n",
+             GST_DEBUG_PAD_NAME (pad), pad, &GST_RPAD_BUFFERPOOLFUNC (pad), bufpool);
+}
 
 static void
 gst_pad_push_func(GstPad *pad, GstBuffer *buf)
@@ -802,22 +820,29 @@ gboolean
 gst_pad_set_caps (GstPad *pad,
                   GstCaps *caps)
 {
+  GstCaps *oldcaps;
+
   g_return_val_if_fail (pad != NULL, FALSE);
   g_return_val_if_fail (GST_IS_REAL_PAD (pad), FALSE);         // NOTE this restriction
 
+  GST_INFO (GST_CAT_CAPS, "setting caps %p on pad %s:%s",
+            caps, GST_DEBUG_PAD_NAME(pad));
+
   if (!gst_caps_check_compatibility (caps, gst_pad_get_padtemplate_caps (pad))) {
     g_warning ("pad %s:%s tried to set caps incompatible with its padtemplate\n",
                    GST_DEBUG_PAD_NAME (pad));
     //return FALSE;
   }
   
-  if (GST_PAD_CAPS (pad))
-    gst_caps_unref (GST_PAD_CAPS (pad));
+  oldcaps = GST_PAD_CAPS (pad);
 
   if (caps)
     gst_caps_ref (caps);
   GST_PAD_CAPS(pad) = caps;
 
+  if (oldcaps)
+    gst_caps_unref (oldcaps);
+
   return gst_pad_renegotiate (pad);
 }
 
@@ -938,6 +963,40 @@ gst_pad_get_peer (GstPad *pad)
   return GST_PAD(GST_PAD_PEER(pad));
 }
 
+/**
+ * gst_pad_get_bufferpool:
+ * @pad: the pad to get the bufferpool from
+ *
+ * Get the bufferpool of the peer pad of the given
+ * pad
+ *
+ * Returns: The GstBufferPool or NULL.
+ */
+GstBufferPool*          
+gst_pad_get_bufferpool (GstPad *pad)
+{
+  GstRealPad *peer;
+
+  g_return_val_if_fail (pad != NULL, NULL);
+  g_return_val_if_fail (GST_IS_PAD (pad), NULL);
+   
+  peer = GST_RPAD_PEER(pad);
+
+  g_return_val_if_fail (peer != NULL, NULL);
+
+  GST_DEBUG_ENTER("(%s:%s)",GST_DEBUG_PAD_NAME(pad));
+
+  if (peer->bufferpoolfunc) {
+    GST_DEBUG (0,"calling bufferpoolfunc &%s (@%p) of peer pad %s:%s\n",
+      GST_DEBUG_FUNCPTR_NAME(peer->bufferpoolfunc),&peer->bufferpoolfunc,GST_DEBUG_PAD_NAME(((GstPad*)peer)));
+    return (peer->bufferpoolfunc)(((GstPad*)peer));
+  } else {
+    GST_DEBUG (0,"no bufferpoolfunc for peer pad %s:%s at %p\n",GST_DEBUG_PAD_NAME(((GstPad*)peer)),&peer->bufferpoolfunc);
+    return NULL;
+  }
+}
+
+
 // FIXME this needs to be rethought soon
 static void
 gst_real_pad_destroy (GtkObject *object)
@@ -1162,11 +1221,11 @@ gst_pad_renegotiate (GstPad *pad)
     GST_DEBUG (GST_CAT_NEGOTIATION, "pads aggreed on caps :)\n");
 
     /* here we have some sort of aggreement of the caps */
-    GST_PAD_CAPS (currentpad) = newcaps;
+    GST_PAD_CAPS (currentpad) = gst_caps_ref (newcaps);
     if (GST_RPAD_NEWCAPSFUNC (currentpad))
       GST_RPAD_NEWCAPSFUNC (currentpad) (GST_PAD (currentpad), newcaps);
 
-    GST_PAD_CAPS (otherpad) = newcaps;
+    GST_PAD_CAPS (otherpad) = gst_caps_ref (newcaps);
     if (GST_RPAD_NEWCAPSFUNC (otherpad))
       GST_RPAD_NEWCAPSFUNC (otherpad) (GST_PAD (otherpad), newcaps);
   }
@@ -1444,11 +1503,12 @@ gst_padtemplate_init (GstPadTemplate *templ)
 }
 
 /**
- * gst_padtemplate_create:
+ * gst_padtemplate_new:
  * @name_template: the name template
  * @direction: the direction for the template
  * @presence: the presence of the pad
  * @caps: a list of capabilities for the template
+ * @...: more capabilities
  *
  * Creates a new padtemplate from the given arguments.
  *
index aa253112bafb28fe13301571f8fb8e20c3c25d70..9390d9960a1154e8d6ec6f794e251d07ff1ecfd7 100644 (file)
@@ -100,6 +100,7 @@ typedef GstBuffer*  (*GstPadPullRegionFunction)     (GstPad *pad, GstRegionType type
 typedef gboolean       (*GstPadEOSFunction)            (GstPad *pad);
 typedef GstPadNegotiateReturn (*GstPadNegotiateFunction)       (GstPad *pad, GstCaps **caps, gpointer *data);
 typedef void           (*GstPadNewCapsFunction)        (GstPad *pad, GstCaps *caps);
+typedef GstBufferPool* (*GstPadBufferPoolFunction)     (GstPad *pad);
 
 typedef enum {
   GST_PAD_UNKNOWN,
@@ -155,6 +156,7 @@ struct _GstRealPad {
 
   GstPadNegotiateFunction      negotiatefunc;
   GstPadNewCapsFunction        newcapsfunc;
+  GstPadBufferPoolFunction     bufferpoolfunc;
 
   GList *ghostpads;
 };
@@ -205,6 +207,7 @@ struct _GstGhostPadClass {
 #define GST_RPAD_EOSFUNC(pad)          (((GstRealPad *)(pad))->eosfunc)
 #define GST_RPAD_NEGOTIATEFUNC(pad)    (((GstRealPad *)(pad))->negotiatefunc)
 #define GST_RPAD_NEWCAPSFUNC(pad)      (((GstRealPad *)(pad))->newcapsfunc)
+#define GST_RPAD_BUFFERPOOLFUNC(pad)   (((GstRealPad *)(pad))->bufferpoolfunc)
 
 #define GST_RPAD_REGIONTYPE(pad)       (((GstRealPad *)(pad))->regiontype)
 #define GST_RPAD_OFFSET(pad)           (((GstRealPad *)(pad))->offset)
@@ -258,6 +261,31 @@ struct _GstPadTemplateClass {
   void (*pad_created)  (GstPadTemplate *templ, GstPad *pad);
 };
 
+#define GST_PADTEMPLATE_NEW(padname, dir, pres, a...) \
+  gst_padtemplate_new (                         \
+    padname,                                    \
+    dir,                                        \
+    pres,                                       \
+    a ,                                                \
+    NULL)
+
+#define GST_PADTEMPLATE_FACTORY(name, padname, dir, pres, a...)         \
+static GstPadTemplate*                          \
+name (void)                                     \
+{                                               \
+  static GstPadTemplate *templ = NULL;         \
+  if (!templ) {                                \
+    templ = GST_PADTEMPLATE_NEW (              \
+      padname,                                 \
+      dir,                                      \
+      pres,                                     \
+      a );                                     \
+  }                                             \
+  return templ;                                \
+}
+
+#define GST_PADTEMPLATE_GET(fact) (fact)()
+
 
 GtkType                        gst_pad_get_type                (void);
 GtkType                        gst_real_pad_get_type           (void);
@@ -276,6 +304,7 @@ void                        gst_pad_set_qos_function        (GstPad *pad, GstPadQoSFunction qos);
 void                   gst_pad_set_eos_function        (GstPad *pad, GstPadEOSFunction eos);
 void                   gst_pad_set_negotiate_function  (GstPad *pad, GstPadNegotiateFunction nego);
 void                   gst_pad_set_newcaps_function    (GstPad *pad, GstPadNewCapsFunction newcaps);
+void                   gst_pad_set_bufferpool_function (GstPad *pad, GstPadBufferPoolFunction bufpool);
 
 gboolean               gst_pad_set_caps                (GstPad *pad, GstCaps *caps);
 GstCaps*               gst_pad_get_caps                (GstPad *pad);
@@ -303,6 +332,8 @@ GstPadTemplate*             gst_pad_get_padtemplate         (GstPad *pad);
 
 GstPad*                        gst_pad_get_peer                (GstPad *pad);
 
+GstBufferPool*         gst_pad_get_bufferpool          (GstPad *pad);
+
 gboolean               gst_pad_connect                 (GstPad *srcpad, GstPad *sinkpad);
 void                   gst_pad_disconnect              (GstPad *srcpad, GstPad *sinkpad);
 
index 2e5362a2aea5aaf1a70f4d0660ea1bcb76312680..fdbbd22b6cba16e9816212b0daf94e0542202c55 100644 (file)
@@ -27,6 +27,7 @@
 
 #include "gst_private.h"
 #include "gstplugin.h"
+#include "gstversion.h"
 #include "config.h"
 
 
@@ -347,7 +348,7 @@ gboolean
 gst_plugin_load_absolute (const gchar *name)
 {
   GModule *module;
-  GstPluginInitFunc initfunc;
+  GstPluginDesc *desc;
   GstPlugin *plugin;
   struct stat file_status;
 
@@ -363,10 +364,19 @@ gst_plugin_load_absolute (const gchar *name)
 
   module = g_module_open(name,G_MODULE_BIND_LAZY);
   if (module != NULL) {
-    if (g_module_symbol(module,"plugin_init",(gpointer *)&initfunc)) {
-      GST_INFO (GST_CAT_PLUGIN_LOADING,"loading plugin \"%s\"...",
-           name);
-      if ((plugin = (initfunc)(module))) {
+    if (g_module_symbol(module,"plugin_desc",(gpointer *)&desc)) {
+      GST_INFO (GST_CAT_PLUGIN_LOADING,"loading plugin \"%s\"...", name);
+      plugin = gst_plugin_new(desc->name, desc->major_version, desc->minor_version);
+      if (plugin != NULL) {
+       if (!((desc->plugin_init)(module, plugin))) {
+          GST_INFO (GST_CAT_PLUGIN_LOADING,"plugin \"%s\" failed to initialise",
+             plugin->name);
+         g_free(plugin);
+         plugin = NULL;
+       }
+      }
+
+      if (plugin != NULL) {
         GST_INFO (GST_CAT_PLUGIN_LOADING,"plugin \"%s\" loaded: %d elements, %d types",
              plugin->name,plugin->numelements,plugin->numtypes);
         plugin->filename = g_strdup(name);
@@ -392,16 +402,23 @@ gst_plugin_load_absolute (const gchar *name)
 /**
  * gst_plugin_new:
  * @name: name of new plugin
+ * @major: major version number of core that plugin is compatible with
+ * @minor: minor version number of core that plugin is compatible with
  *
  * Create a new plugin with given name.
  *
- * Returns: new plugin
+ * Returns: new plugin, or NULL if plugin couldn't be created, due to
+ * incompatible version number, or name already being allocated)
  */
 GstPlugin*
-gst_plugin_new (const gchar *name)
+gst_plugin_new (const gchar *name, gint major, gint minor)
 {
   GstPlugin *plugin;
 
+  // return NULL if the major and minor version numbers are not compatible
+  // with ours.
+  if (major != GST_VERSION_MAJOR || minor != GST_VERSION_MINOR) return NULL;
+
   // return NULL if the plugin is allready loaded
   plugin = gst_plugin_find (name);
   if (plugin) return NULL;
index 299d10edc15bb167c43e3d719cc779873fe38d24..48b9c9466991e88057068ad03adb2fc77f6b063e 100644 (file)
@@ -40,7 +40,7 @@
 
 
 typedef struct _GstPlugin              GstPlugin;
-typedef struct _GstPluginElement       GstPluginElement;
+typedef struct _GstPluginDesc          GstPluginDesc;
 
 struct _GstPlugin {
   gchar *name;                 /* name of the plugin */
@@ -57,12 +57,19 @@ struct _GstPlugin {
   gboolean loaded;              /* if the plugin is in memory */
 };
 
+/* Initialiser function: returns TRUE if plugin initialised successfully */
+typedef gboolean (*GstPluginInitFunc) (GModule *module, GstPlugin *plugin);
 
-typedef GstPlugin* (*GstPluginInitFunc) (GModule *module);
+struct _GstPluginDesc {
+  gint major_version; /* major version of core that plugin was compiled for */
+  gint minor_version; /* minor version of core that plugin was compiled for */
+  gchar *name;        /* name of plugin */
+  GstPluginInitFunc plugin_init; /* pointer to plugin_init function */
+};
 
 void                   _gst_plugin_initialize          (void);
 
-GstPlugin*             gst_plugin_new                  (const gchar *name);
+GstPlugin*             gst_plugin_new                  (const gchar *name, gint major, gint minor);
 
 void                   gst_plugin_add_path             (const gchar *path);
 
index a67acf8aea85439250da528de9ff2cac17c71973..07cab144bc241d8cb97ceb8d3771715defdf3bda 100644 (file)
@@ -51,6 +51,7 @@ typedef enum {
 } GstPropsId;
 
 #define GST_MAKE_FOURCC(a,b,c,d)       ((a)|(b)<<8|(c)<<16|(d)<<24)
+#define GST_STR_FOURCC(f)              (((f)[0])|((f)[1]<<8)|((f)[2]<<16)|((f)[3]<<24))
 
 #define GST_PROPS_LIST(a...)           GST_PROPS_LIST_ID,##a,NULL
 #define GST_PROPS_INT(a)               GST_PROPS_INT_ID,(a)
index 7e8c92e56aa9144355ed5d31ddadcb8fe6b3126d..258eb928ed7906a4bfb6fddb9e07110d5889f3e2 100644 (file)
@@ -70,7 +70,8 @@ static GstPadNegotiateReturn  gst_queue_handle_negotiate_src (GstPad *pad, GstCa
 static GstPadNegotiateReturn   gst_queue_handle_negotiate_sink (GstPad *pad, GstCaps **caps, gpointer *data);
 static void                    gst_queue_chain         (GstPad *pad, GstBuffer *buf);
 static GstBuffer *             gst_queue_get           (GstPad *pad);
-
+static GstBufferPool*          gst_queue_get_bufferpool (GstPad *pad);
+       
 static void                    gst_queue_flush         (GstQueue *queue);
 
 static GstElementStateReturn   gst_queue_change_state  (GstElement *element);
@@ -134,6 +135,7 @@ gst_queue_init (GstQueue *queue)
   gst_element_add_pad (GST_ELEMENT (queue), queue->sinkpad);
   gst_pad_set_eos_function (queue->sinkpad, gst_queue_handle_eos);
   gst_pad_set_negotiate_function (queue->sinkpad, gst_queue_handle_negotiate_sink);
+  gst_pad_set_bufferpool_function (queue->sinkpad, gst_queue_get_bufferpool);
 
   queue->srcpad = gst_pad_new ("src", GST_PAD_SRC);
   gst_pad_set_get_function (queue->srcpad, GST_DEBUG_FUNCPTR(gst_queue_get));
@@ -152,6 +154,16 @@ gst_queue_init (GstQueue *queue)
   queue->fullcond = g_cond_new ();
 }
 
+static GstBufferPool*
+gst_queue_get_bufferpool (GstPad *pad)
+{
+  GstQueue *queue;
+
+  queue = GST_QUEUE (GST_OBJECT_PARENT (pad));
+
+  return gst_pad_get_bufferpool (queue->srcpad);
+}
+
 static GstPadNegotiateReturn
 gst_queue_handle_negotiate_src (GstPad *pad, GstCaps **caps, gpointer *data)
 {
index 2ade4a50539aafdc20d5a599df9c919c51288c77..3e4f6648d9c7a8ea1df6d7b0c77e36be4e08229b 100644 (file)
@@ -21,6 +21,7 @@
  */
 
 #include <stdio.h>
+#include <string.h>
 
 #include "gstextratypes.h"
 
@@ -254,7 +255,7 @@ gst_util_set_object_arg (GtkObject *object, guchar *name, gchar *value)
        }
         case GTK_TYPE_BOOL: {
          gboolean i = FALSE;
-         if (!strcmp ("true", value)) i = TRUE;
+         if (!strncmp ("true", value, 4)) i = TRUE;
           gtk_object_set (GTK_OBJECT (object), name, i, NULL);
          break;
        }
diff --git a/gst/gstversion.h.in b/gst/gstversion.h.in
new file mode 100644 (file)
index 0000000..820e7fc
--- /dev/null
@@ -0,0 +1,31 @@
+/* GStreamer
+ * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
+ *                    2000 Wim Taymans <wtay@chello.be>
+ *
+ * gstversion.h: Version information for GStreamer
+ *
+ * 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_VERSION_H__
+#define __GST_VERSION_H__
+
+#define GST_VERSION_MAJOR @GST_VERSION_MAJOR@
+#define GST_VERSION_MINOR @GST_VERSION_MINOR@
+#define GST_VERSION_MICRO @GST_VERSION_MICRO@
+
+#endif /* __GST_H__ */
index ce8ad093d1c75e783c5acf372c0fdc90677f0e7f..7de9743a3ba67bfae2b4232011f5146c5c9d09cd 100644 (file)
@@ -5,4 +5,4 @@ filter_LTLIBRARIES = libgsttypes.la
 libgsttypes_la_SOURCES =       \
        gsttypes.c
 
-libgsttypes_la_LDFLAGS = -version-info $(GSTREAMER_LIBVERSION)
+libgsttypes_la_LDFLAGS = -version-info $(GST_LIBVERSION)
index 9fe885b644b63ce6e0fb4e9762c6867e8e938a34..0723f3db002fbf07f4f8c82e03bc0909c57c5ea9 100644 (file)
@@ -28,15 +28,11 @@ GstTypeFactory _factories[] = {
 };
 
 
-GstPlugin*
-plugin_init (GModule *module
+static gboolean
+plugin_init (GModule *module, GstPlugin *plugin)
 {
-  GstPlugin *plugin;
   gint i = 0;
 
-  plugin = gst_plugin_new ("gsttypes");
-  g_return_val_if_fail (plugin != NULL,NULL);
-
   while (_factories[i].mime) {
     gst_type_register (&_factories[i]);
     gst_plugin_add_type (plugin, &_factories[i]);
@@ -46,5 +42,12 @@ plugin_init (GModule *module)
 
   //gst_info ("gsttypes: loaded %d standard types\n",i);
 
-  return plugin;
+  return TRUE;
 }
+
+GstPluginDesc plugin_desc = {
+  GST_VERSION_MAJOR,
+  GST_VERSION_MINOR,
+  "gsttypes",
+  plugin_init
+};
index 9ec9750bb5b6ae1e78e9a1da22e813ee225e273c..cf4a4c17c41b2c0facc172a0142434c736176c11 100644 (file)
@@ -63,7 +63,7 @@ void gst_putbits(gst_putbits_t *pb, int val, int n)
   int i;
   unsigned int mask;
 
-  //printf("putbits: %d %d %ld %ld\n", val, n, pb->outcnt, pb->newlen);
+  //printf("putbits: %p %08x %d %d %d\n", pb, val, n, pb->outcnt, pb->newlen);
   mask = 1 << (n-1); /* selects first (leftmost) bit */
 
   for (i=0; i<n; i++)
index e41a972f4025560b7dd3ecb90a8b1c15aa66e1d5..e29530e06968e2a1dfbdd14bbd69ea1eff1f8a38 100644 (file)
@@ -15,6 +15,7 @@ libgstelements_la_SOURCES =   \
        gstidentity.c           \
        gstfakesink.c           \
        gstdisksrc.c            \
+       gstdisksink.c           \
        gstfdsrc.c              \
        gstfdsink.c             \
        gstmultidisksrc.c       \
@@ -28,6 +29,7 @@ noinst_HEADERS =              \
        gstidentity.h           \
        gstfakesink.h           \
        gstdisksrc.h            \
+       gstdisksink.h           \
        gstfdsrc.h              \
        gstmultidisksrc.h       \
        gsthttpsrc.h            \
@@ -39,4 +41,4 @@ noinst_HEADERS =              \
 CFLAGS += -O2 -Wall
 
 libgstelements_la_LIBADD = $(GHTTP_LIBS)
-libgstelements_la_LDFLAGS = -version-info $(GSTREAMER_LIBVERSION)
+libgstelements_la_LDFLAGS = -version-info $(GST_LIBVERSION)
diff --git a/plugins/elements/gstdisksink.c b/plugins/elements/gstdisksink.c
new file mode 100644 (file)
index 0000000..0861149
--- /dev/null
@@ -0,0 +1,254 @@
+/* GStreamer
+ * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
+ *                    2000 Wim Taymans <wtay@chello.be>
+ *
+ * gstdisksink.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 "gstdisksink.h"
+
+
+GstElementDetails gst_disksink_details = {
+  "Disk Sink",
+  "Sink",
+  "Disk hole for data",
+  VERSION,
+  "Thomas <thomas@apestaart.org>",
+  "(C) 2001"
+};
+
+
+/* DiskSink signals and args */
+enum {
+  /* FILL ME */
+  SIGNAL_HANDOFF,
+  LAST_SIGNAL
+};
+
+enum {
+  ARG_0,
+  ARG_LOCATION,
+};
+
+
+static void    gst_disksink_class_init (GstDiskSinkClass *klass);
+static void    gst_disksink_init       (GstDiskSink *disksink);
+
+static void    gst_disksink_set_arg    (GtkObject *object, GtkArg *arg, guint id);
+static void    gst_disksink_get_arg    (GtkObject *object, GtkArg *arg, guint id);
+
+static gboolean gst_disksink_open_file         (GstDiskSink *sink);
+static void    gst_disksink_close_file (GstDiskSink *sink);
+
+static void    gst_disksink_chain      (GstPad *pad,GstBuffer *buf);
+
+static GstElementStateReturn gst_disksink_change_state (GstElement *element);
+
+static GstElementClass *parent_class = NULL;
+static guint gst_disksink_signals[LAST_SIGNAL] = { 0 };
+
+GtkType
+gst_disksink_get_type (void) 
+{
+  static GtkType disksink_type = 0;
+
+  if (!disksink_type) {
+    static const GtkTypeInfo disksink_info = {
+      "GstDiskSink",
+      sizeof(GstDiskSink),
+      sizeof(GstDiskSinkClass),
+      (GtkClassInitFunc)gst_disksink_class_init,
+      (GtkObjectInitFunc)gst_disksink_init,
+      (GtkArgSetFunc)gst_disksink_set_arg,
+      (GtkArgGetFunc)gst_disksink_get_arg,
+      (GtkClassInitFunc)NULL,  /* deprecated, do not use ! */
+    };
+    disksink_type = gtk_type_unique (GST_TYPE_ELEMENT, &disksink_info);
+  }
+  return disksink_type;
+}
+
+static void
+gst_disksink_class_init (GstDiskSinkClass *klass) 
+{
+  GtkObjectClass *gtkobject_class;
+  GstElementClass *gstelement_class;
+
+  gtkobject_class = (GtkObjectClass*)klass;
+  gstelement_class = (GstElementClass*)klass;
+
+  parent_class = gtk_type_class (GST_TYPE_ELEMENT);
+
+  gtk_object_add_arg_type ("GstDiskSink::location", GST_TYPE_FILENAME,
+                           GTK_ARG_READWRITE, ARG_LOCATION);
+
+  gst_disksink_signals[SIGNAL_HANDOFF] =
+    gtk_signal_new ("handoff", GTK_RUN_LAST, gtkobject_class->type,
+                    GTK_SIGNAL_OFFSET (GstDiskSinkClass, handoff),
+                    gtk_marshal_NONE__NONE, GTK_TYPE_NONE, 0);
+
+  gtk_object_class_add_signals (gtkobject_class, gst_disksink_signals,
+                                    LAST_SIGNAL);
+
+  gtkobject_class->set_arg = gst_disksink_set_arg;
+  gtkobject_class->get_arg = gst_disksink_get_arg;
+
+  gstelement_class->change_state = gst_disksink_change_state;
+}
+
+static void 
+gst_disksink_init (GstDiskSink *disksink) 
+{
+  GstPad *pad;
+  pad = gst_pad_new ("sink", GST_PAD_SINK);
+  gst_element_add_pad (GST_ELEMENT (disksink), pad);
+  gst_pad_set_chain_function (pad, gst_disksink_chain);
+
+  disksink->filename = NULL;
+  disksink->file = NULL;
+}
+
+static void
+gst_disksink_set_arg (GtkObject *object, GtkArg *arg, guint id)
+{
+  GstDiskSink *sink;
+
+  /* it's not null if we got it, but it might not be ours */
+  sink = GST_DISKSINK (object);
+
+  switch(id) {
+    case ARG_LOCATION:
+      if (sink->filename)
+       g_free (sink->filename);
+      sink->filename = g_strdup (GTK_VALUE_STRING (*arg));
+      break;
+    default:
+      break;
+  }
+}
+
+static void   
+gst_disksink_get_arg (GtkObject *object, GtkArg *arg, guint id)
+{
+  GstDiskSink *sink;
+  /* it's not null if we got it, but it might not be ours */
+  g_return_if_fail (GST_IS_DISKSINK (object));
+  sink = GST_DISKSINK (object);
+  
+  switch (id) {
+    case ARG_LOCATION:
+      GTK_VALUE_STRING (*arg) = sink->filename;
+      break;
+    default:
+      arg->type = GTK_TYPE_INVALID;
+      break;
+  }
+}
+
+static gboolean
+gst_disksink_open_file (GstDiskSink *sink)
+{
+  g_return_val_if_fail (!GST_FLAG_IS_SET (sink, GST_DISKSINK_OPEN), FALSE);
+
+  /* open the file */
+  sink->file = fopen (sink->filename, "w");
+  if (sink->file == NULL) {
+    perror ("open");
+    gst_element_error (GST_ELEMENT (sink), g_strconcat("opening file \"", sink->filename, "\"", NULL));
+    return FALSE;
+  } 
+
+  GST_FLAG_SET (sink, GST_DISKSINK_OPEN);
+
+  return TRUE;
+}
+
+static void
+gst_disksink_close_file (GstDiskSink *sink)
+{
+  g_return_if_fail (GST_FLAG_IS_SET (sink, GST_DISKSINK_OPEN));
+
+  if (fclose (sink->file) != 0)
+  {
+    perror ("close");
+    gst_element_error (GST_ELEMENT (sink), g_strconcat("closing file \"", sink->filename, "\"", NULL));
+  }
+  else {
+    GST_FLAG_UNSET (sink, GST_DISKSINK_OPEN);
+  }
+}
+
+/**
+ * gst_disksink_chain:
+ * @pad: the pad this disksink is connected to
+ * @buf: the buffer that has to be absorbed
+ *
+ * take the buffer from the pad and write to file if it's open
+ */
+static void 
+gst_disksink_chain (GstPad *pad, GstBuffer *buf) 
+{
+  GstDiskSink *disksink;
+  guint16 bytes_written = 0;
+
+  g_return_if_fail (pad != NULL);
+  g_return_if_fail (GST_IS_PAD (pad));
+  g_return_if_fail (buf != NULL);
+
+  disksink = GST_DISKSINK (gst_pad_get_parent (pad));
+
+  if (GST_FLAG_IS_SET (disksink, GST_DISKSINK_OPEN))
+  {
+    bytes_written = fwrite (GST_BUFFER_DATA (buf), 1, GST_BUFFER_SIZE (buf), disksink->file);
+    if (bytes_written < GST_BUFFER_SIZE (buf))
+    {
+      printf ("disksink : Warning : %d bytes should be written, only %d bytes written\n",
+                 GST_BUFFER_SIZE (buf), bytes_written);
+    }
+  }
+  gst_buffer_unref (buf);
+
+  gtk_signal_emit (GTK_OBJECT (disksink), gst_disksink_signals[SIGNAL_HANDOFF],
+                             disksink);
+}
+
+static GstElementStateReturn
+gst_disksink_change_state (GstElement *element)
+{
+  g_return_val_if_fail (GST_IS_DISKSINK (element), GST_STATE_FAILURE);
+
+  if (GST_STATE_PENDING (element) == GST_STATE_NULL) {
+    if (GST_FLAG_IS_SET (element, GST_DISKSINK_OPEN))
+      gst_disksink_close_file (GST_DISKSINK (element));
+  } else {
+    if (!GST_FLAG_IS_SET (element, GST_DISKSINK_OPEN)) {
+      if (!gst_disksink_open_file (GST_DISKSINK (element)))
+        return GST_STATE_FAILURE;
+    }
+  }
+
+  if (GST_ELEMENT_CLASS (parent_class)->change_state)
+    return GST_ELEMENT_CLASS (parent_class)->change_state (element);
+
+  return GST_STATE_SUCCESS;
+}
+
diff --git a/plugins/elements/gstdisksink.h b/plugins/elements/gstdisksink.h
new file mode 100644 (file)
index 0000000..15f3d32
--- /dev/null
@@ -0,0 +1,82 @@
+/* GStreamer
+ * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
+ *                    2000 Wim Taymans <wtay@chello.be>
+ *
+ * gstdisksink.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_DISKSINK_H__
+#define __GST_DISKSINK_H__
+
+
+#include <config.h>
+#include <gst/gst.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+GstElementDetails gst_disksink_details;
+
+
+#define GST_TYPE_DISKSINK \
+  (gst_disksink_get_type())
+#define GST_DISKSINK(obj) \
+  (GTK_CHECK_CAST((obj),GST_TYPE_DISKSINK,GstDiskSink))
+#define GST_DISKSINK_CLASS(klass) \
+  (GTK_CHECK_CLASS_CAST((klass),GST_TYPE_DISKSINK,GstDiskSinkClass))
+#define GST_IS_DISKSINK(obj) \
+  (GTK_CHECK_TYPE((obj),GST_TYPE_DISKSINK))
+#define GST_IS_DISKSINK_CLASS(obj) \
+  (GTK_CHECK_CLASS_TYPE((klass),GST_TYPE_DISKSINK))
+
+typedef struct _GstDiskSink GstDiskSink;
+typedef struct _GstDiskSinkClass GstDiskSinkClass;
+
+typedef enum {
+  GST_DISKSINK_OPEN             = GST_ELEMENT_FLAG_LAST,
+
+  GST_DISKSINK_FLAG_LAST       = GST_ELEMENT_FLAG_LAST + 2,
+} GstDiskSinkFlags;
+
+struct _GstDiskSink {
+  GstElement element;
+
+  gchar *filename;
+  FILE *file;
+};
+
+struct _GstDiskSinkClass {
+  GstElementClass parent_class;
+
+  /* signals */
+  void (*handoff) (GstElement *element,GstPad *pad);
+};
+
+GtkType gst_disksink_get_type(void);
+
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif /* __GST_DISKSINK_H__ */
index 9e81eb9b739796d65997eebcd44da29bf0c3665b..72d454d510cc8a03b7ec5eeeb9e2041172facb6b 100644 (file)
@@ -312,8 +312,8 @@ gst_disksrc_get_region (GstPad *pad, GstRegionType type,guint64 offset,guint64 l
 
 
 /* open the file and mmap it, necessary to go to READY state */
-static
-gboolean gst_disksrc_open_file (GstDiskSrc *src)
+static gboolean 
+gst_disksrc_open_file (GstDiskSrc *src)
 {
   g_return_val_if_fail (!GST_FLAG_IS_SET (src ,GST_DISKSRC_OPEN), FALSE);
 
index 326d0e3aaf6cb7b77837f53964e430f34245cba8..afd086212628faf55e1aa4e1d329ef107f81083b 100644 (file)
@@ -24,6 +24,7 @@
 #include <gst/gst.h>
 
 #include "gstdisksrc.h"
+#include "gstdisksink.h"
 #include "gstidentity.h"
 #include "gstfakesink.h"
 #include "gstfakesrc.h"
@@ -50,6 +51,7 @@ static struct _elements_entry _elements[] = {
   { "fakesrc",             gst_fakesrc_get_type,       &gst_fakesrc_details,           NULL },
   { "fakesink",     gst_fakesink_get_type,     &gst_fakesink_details,          NULL },
   { "disksrc",             gst_disksrc_get_type,       &gst_disksrc_details,           NULL },
+  { "disksink",            gst_disksink_get_type,      &gst_disksink_details,          NULL },
   { "identity",     gst_identity_get_type,     &gst_identity_details,          NULL },
   { "fdsink",       gst_fdsink_get_type,       &gst_fdsink_details,            NULL },
   { "fdsrc",       gst_fdsrc_get_type,         &gst_fdsrc_details,             NULL },
@@ -65,15 +67,12 @@ static struct _elements_entry _elements[] = {
   { NULL, 0 },
 };
 
-GstPlugin *plugin_init (GModule *module)
+static gboolean
+plugin_init (GModule *module, GstPlugin *plugin)
 {
-  GstPlugin *plugin;
   GstElementFactory *factory;
   gint i = 0;
 
-  plugin = gst_plugin_new("gstelements");
-  g_return_val_if_fail(plugin != NULL,NULL);
-
   gst_plugin_set_longname (plugin, "Standard GST Elements");
 
   while (_elements[i].name) {
@@ -92,5 +91,13 @@ GstPlugin *plugin_init (GModule *module)
 
 //  INFO (GST_INFO_PLUGIN_LOAD,"gstelements: loaded %d standard elements", i);
 
-  return plugin;
+  return TRUE;
 }
+
+GstPluginDesc plugin_desc = {
+  GST_VERSION_MAJOR,
+  GST_VERSION_MINOR,
+  "gstelements",
+  plugin_init
+};
+
index 81709b764bb4dba8913c6fd4af7da989418ed922..11590c4bab13e0be62137e86638815ef4c947695 100644 (file)
@@ -44,6 +44,7 @@ enum {
 enum {
   ARG_0,
   ARG_NUM_SOURCES,
+  ARG_SILENT,
 };
 
 
@@ -90,6 +91,8 @@ gst_fakesink_class_init (GstFakeSinkClass *klass)
 
   gtk_object_add_arg_type ("GstFakeSink::num_sources", GTK_TYPE_INT,
                            GTK_ARG_READWRITE, ARG_NUM_SOURCES);
+  gtk_object_add_arg_type ("GstFakeSink::silent", GTK_TYPE_BOOL,
+                           GTK_ARG_READWRITE, ARG_SILENT);
 
   gst_fakesink_signals[SIGNAL_HANDOFF] =
     gtk_signal_new ("handoff", GTK_RUN_LAST, gtkobject_class->type,
@@ -112,6 +115,7 @@ gst_fakesink_init (GstFakeSink *fakesink)
   gst_pad_set_chain_function (pad, gst_fakesink_chain);
   fakesink->sinkpads = g_slist_prepend (NULL, pad);
   fakesink->numsinkpads = 1;
+  fakesink->silent = FALSE;
 
   // we're ready right away, since we don't have any args...
 //  gst_element_set_state(GST_ELEMENT(fakesink),GST_STATE_READY);
@@ -138,6 +142,9 @@ gst_fakesink_set_arg (GtkObject *object, GtkArg *arg, guint id)
         sink->numsinkpads++;
       }
       break;
+    case ARG_SILENT:
+      sink->silent = GTK_VALUE_BOOL (*arg);
+      break;
     default:
       break;
   }
@@ -157,6 +164,9 @@ gst_fakesink_get_arg (GtkObject *object, GtkArg *arg, guint id)
     case ARG_NUM_SOURCES:
       GTK_VALUE_INT (*arg) = sink->numsinkpads;
       break;
+    case ARG_SILENT:
+      GTK_VALUE_BOOL (*arg) = sink->silent;
+      break;
     default:
       arg->type = GTK_TYPE_INVALID;
       break;
@@ -181,7 +191,8 @@ gst_fakesink_chain (GstPad *pad, GstBuffer *buf)
   g_return_if_fail (buf != NULL);
 
   fakesink = GST_FAKESINK (gst_pad_get_parent (pad));
-  g_print("fakesink: ******* (%s:%s)< \n",GST_DEBUG_PAD_NAME(pad));
+  if (!fakesink->silent)
+    g_print("fakesink: ******* (%s:%s)< (%d bytes) \n",GST_DEBUG_PAD_NAME(pad),GST_BUFFER_SIZE(buf));
   
   gst_buffer_unref (buf);
 
index 74df38700d94c44e8080bccf91d14df0698d4443..573e8e512c5706e416ad59dbed8b952260f3f4b8 100644 (file)
@@ -56,6 +56,7 @@ struct _GstFakeSink {
 
   GSList *sinkpads;
   gint numsinkpads;
+  gboolean silent;
 };
 
 struct _GstFakeSinkClass {
index a9126b671d1c54f13517b5ce608170327e0c225b..1e92dc5094f1b4b7514377b77747a559b4c5d9da 100644 (file)
@@ -44,6 +44,7 @@ enum {
   ARG_0,
   ARG_LOOP_BASED,
   ARG_SLEEP_TIME,
+  ARG_SILENT,
 };
 
 
@@ -92,24 +93,59 @@ gst_identity_class_init (GstIdentityClass *klass)
                            GTK_ARG_READWRITE, ARG_LOOP_BASED);
   gtk_object_add_arg_type ("GstIdentity::sleep_time", GTK_TYPE_UINT,
                            GTK_ARG_READWRITE, ARG_SLEEP_TIME);
+  gtk_object_add_arg_type ("GstIdentity::silent", GTK_TYPE_BOOL,
+                           GTK_ARG_READWRITE, ARG_SILENT);
 
   gtkobject_class->set_arg = gst_identity_set_arg;  
   gtkobject_class->get_arg = gst_identity_get_arg;
 }
 
+static GstBufferPool*
+gst_identity_get_bufferpool (GstPad *pad)
+{
+  GstIdentity *identity;
+
+  identity = GST_IDENTITY (gst_pad_get_parent (pad));
+
+  return gst_pad_get_bufferpool (identity->srcpad);
+}
+
+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_chain_function (identity->sinkpad, gst_identity_chain);
+  gst_pad_set_bufferpool_function (identity->sinkpad, gst_identity_get_bufferpool);
+  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);
 
   identity->loop_based = FALSE;
-//  identity->sleep_time = 10000;
   identity->sleep_time = 0;
+  identity->silent = FALSE;
 }
 
 static void 
@@ -122,7 +158,9 @@ gst_identity_chain (GstPad *pad, GstBuffer *buf)
   g_return_if_fail (buf != NULL);
 
   identity = GST_IDENTITY (gst_pad_get_parent (pad));
-  g_print("identity: ******* (%s:%s)i \n",GST_DEBUG_PAD_NAME(pad));
+
+  if (!identity->silent)
+    g_print("identity: ******* (%s:%s)i \n",GST_DEBUG_PAD_NAME(pad));
   
   gst_pad_push (identity->srcpad, buf);
 
@@ -147,7 +185,8 @@ gst_identity_loop (GstElement *element)
 
     gst_pad_push (identity->srcpad, buf);
 
-    usleep (identity->sleep_time);
+    if (identity->sleep_time)
+      usleep (identity->sleep_time);
 
   } while (!GST_ELEMENT_IS_COTHREAD_STOPPING(element));
 }
@@ -177,6 +216,9 @@ gst_identity_set_arg (GtkObject *object, GtkArg *arg, guint id)
     case ARG_SLEEP_TIME:
       identity->sleep_time = GTK_VALUE_UINT (*arg);
       break;
+    case ARG_SILENT:
+      identity->silent = GTK_VALUE_BOOL (*arg);
+      break;
     default:
       break;
   }
@@ -197,6 +239,9 @@ static void gst_identity_get_arg(GtkObject *object,GtkArg *arg,guint id) {
     case ARG_SLEEP_TIME:
       GTK_VALUE_UINT (*arg) = identity->sleep_time;
       break;
+    case ARG_SILENT:
+      GTK_VALUE_BOOL (*arg) = identity->silent;
+      break;
     default:
       arg->type = GTK_TYPE_INVALID;
       break;
index 3c536484ecf16bcf7872425436b9452a652721bd..129c4922a6cfe9e599a5da4bf98d34a0b7871e47 100644 (file)
@@ -60,6 +60,7 @@ struct _GstIdentity {
   gboolean loop_based;
 
   guint sleep_time;
+  gboolean silent;
 };
 
 struct _GstIdentityClass {
index 7e8c92e56aa9144355ed5d31ddadcb8fe6b3126d..258eb928ed7906a4bfb6fddb9e07110d5889f3e2 100644 (file)
@@ -70,7 +70,8 @@ static GstPadNegotiateReturn  gst_queue_handle_negotiate_src (GstPad *pad, GstCa
 static GstPadNegotiateReturn   gst_queue_handle_negotiate_sink (GstPad *pad, GstCaps **caps, gpointer *data);
 static void                    gst_queue_chain         (GstPad *pad, GstBuffer *buf);
 static GstBuffer *             gst_queue_get           (GstPad *pad);
-
+static GstBufferPool*          gst_queue_get_bufferpool (GstPad *pad);
+       
 static void                    gst_queue_flush         (GstQueue *queue);
 
 static GstElementStateReturn   gst_queue_change_state  (GstElement *element);
@@ -134,6 +135,7 @@ gst_queue_init (GstQueue *queue)
   gst_element_add_pad (GST_ELEMENT (queue), queue->sinkpad);
   gst_pad_set_eos_function (queue->sinkpad, gst_queue_handle_eos);
   gst_pad_set_negotiate_function (queue->sinkpad, gst_queue_handle_negotiate_sink);
+  gst_pad_set_bufferpool_function (queue->sinkpad, gst_queue_get_bufferpool);
 
   queue->srcpad = gst_pad_new ("src", GST_PAD_SRC);
   gst_pad_set_get_function (queue->srcpad, GST_DEBUG_FUNCPTR(gst_queue_get));
@@ -152,6 +154,16 @@ gst_queue_init (GstQueue *queue)
   queue->fullcond = g_cond_new ();
 }
 
+static GstBufferPool*
+gst_queue_get_bufferpool (GstPad *pad)
+{
+  GstQueue *queue;
+
+  queue = GST_QUEUE (GST_OBJECT_PARENT (pad));
+
+  return gst_pad_get_bufferpool (queue->srcpad);
+}
+
 static GstPadNegotiateReturn
 gst_queue_handle_negotiate_src (GstPad *pad, GstCaps **caps, gpointer *data)
 {
index 86f0ab3ce40441bf72b52f3979848a725b73d150..fee68ef2959e784ce3996afaf8d5f3a671846207 100644 (file)
@@ -46,3 +46,9 @@ mp1tomp1
 pipetest
 mp3tovorbis
 xmmstest
+dv2mp1
+dvshow
+video2mp1
+mp3mad
+videotest2
+
index 5a56d5efd58bae9a739cfcc94853ec77467da1d2..7ee61b9831515d956f48c91e74df99fa0a43cf1a 100644 (file)
@@ -1,9 +1,17 @@
 # FIXME FIXME
 
-noinst_PROGRAMS = qtest spectrum record wave mp3 teardown buffer mp3parse \
-                 mpeg2parse mp1parse mp3play ac3parse ac3play dvdcat fake cobin videotest \
-                 aviparse vidcapture avi2mpg mp2tomp1 mp1tomp1 pipetest \
-                 vidcapture2 mp2toavi mp3tovorbis mpeg2parse2 xmmstest videotest2
+if HAVE_GNOME
+GNOME_PROGS = spectrum wave mpeg2parse mp1parse videotest aviparse \
+                  mpeg2parse2 videotest2 video2mp1 dvshow dv2mp1
+else
+GNOME_PROGS =
+endif
+
+noinst_PROGRAMS = qtest $(GNOME_PROGS) record mp3 teardown buffer mp3parse \
+                 mp3play ac3parse ac3play dvdcat fake cobin \
+                 vidcapture avi2mpg mp2tomp1 mp1tomp1 pipetest \
+                 vidcapture2 mp2toavi mp3tovorbis xmmstest \
+                 mp3mad
 
 SUBDIRS = xml bindings
 
@@ -19,7 +27,7 @@ else
 xvlibs=
 endif
 
-LDADD = ${xvlibs} -lXxf86vm
+LDADD = ${xvlibs} -lXxf86vm $(GNOME_LIBS) $(GST_LIBS)
 
 #LDADD = $(GLIB_LIBS) $(GTK_LIBS) $(top_builddir)/gst/libgst.la \
 #          $(top_builddir)/plugins/videosink/libvideosink.la -L/usr/X11/lib -lXxf86dga
diff --git a/test/dv2mp1.c b/test/dv2mp1.c
new file mode 100644 (file)
index 0000000..ff0dc49
--- /dev/null
@@ -0,0 +1,66 @@
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <string.h>
+#include <gst/gst.h>
+
+static gboolean
+idle_func (gpointer data) 
+{
+  gst_bin_iterate (GST_BIN (data));
+
+  return TRUE;
+}
+
+int 
+main (int argc,char *argv[]) 
+{
+  GstElement *bin;
+  GstElement *src;
+  GstElement *dvdec;
+  GstElement *cspace;
+  GstElement *videoscale;
+  GstElement *encoder;
+  GstElement *fdsink;
+
+  gint fd_video;
+
+  gst_init (&argc, &argv);
+
+  bin = gst_pipeline_new ("pipeline");
+
+  src = gst_elementfactory_make ("disksrc", "src");
+  gtk_object_set (GTK_OBJECT (src), "location", argv[1], "bytesperread", 480, NULL);
+
+  dvdec = gst_elementfactory_make ("dvdec", "decoder");
+  cspace = gst_elementfactory_make ("colorspace", "cspace");
+  //videoscale = gst_elementfactory_make ("videoscale", "videoscale");
+  //gtk_object_set (GTK_OBJECT (videoscale), "width", 352, "height",288, NULL);
+  encoder = gst_elementfactory_make ("mpeg2enc", "mpeg2enc");
+  fdsink = gst_elementfactory_make ("fdsink", "fdsink");
+
+  fd_video = open (argv[2], O_CREAT|O_RDWR|O_TRUNC);
+  gtk_object_set (GTK_OBJECT (fdsink), "fd", fd_video, NULL);
+
+  gst_bin_add (GST_BIN (bin), GST_ELEMENT (src));
+  gst_bin_add (GST_BIN (bin), GST_ELEMENT (dvdec));
+  gst_bin_add (GST_BIN (bin), GST_ELEMENT (cspace));
+  //gst_bin_add (GST_BIN (bin), GST_ELEMENT (videoscale));
+  gst_bin_add (GST_BIN (bin), GST_ELEMENT (encoder));
+  gst_bin_add (GST_BIN (bin), GST_ELEMENT (fdsink));
+
+  gst_element_connect (src, "src", dvdec, "sink");
+  gst_element_connect (cspace, "src", encoder, "sink");
+  //gst_element_connect (videoscale, "src", encoder, "sink");
+  gst_element_connect (encoder, "src", fdsink, "sink");
+  gst_element_connect (dvdec, "video", cspace, "sink");
+
+  gst_element_set_state (GST_ELEMENT (bin), GST_STATE_PLAYING);
+
+  g_idle_add (idle_func, bin);
+
+  gtk_main ();
+
+  exit (0);
+}
+
diff --git a/test/dvshow.c b/test/dvshow.c
new file mode 100644 (file)
index 0000000..0e3d2f7
--- /dev/null
@@ -0,0 +1,96 @@
+#include <gnome.h>
+#include <gst/gst.h>
+
+static gboolean
+idle_func (gpointer data) 
+{
+  gst_bin_iterate(GST_BIN(data));
+
+  return TRUE;
+}
+
+int 
+main (int argc,char *argv[]) 
+{
+  GstElement *bin;
+  GstElement *src;
+  GstElement *dvdec;
+  GstElement *cspace;
+  GstElement *videosink;
+
+  GtkWidget *appwindow;
+  GtkWidget *vbox1;
+  GtkWidget *button;
+  guint32 draw;
+  GtkWidget *gtk_socket;
+
+
+  gst_init(&argc,&argv);
+
+  gnome_init("Videotest","0.0.1",argc,argv);
+
+  bin = gst_bin_new("bin");
+
+  if (argc == 1) {
+    src = gst_elementfactory_make ("dv1394src", "src");
+  } else {
+    src = gst_elementfactory_make ("disksrc", "src");
+    gtk_object_set(GTK_OBJECT(src),"location",argv[1],"bytesperread",480,NULL);
+  }
+  dvdec = gst_elementfactory_make ("dvdec", "decoder");
+  if (!dvdec) fprintf(stderr,"no dvdec\n"),exit(1);
+//  cspace = gst_elementfactory_make ("colorspace", "cspace");
+  videosink = gst_elementfactory_make ("xvideosink", "videosink");
+  if (!videosink) fprintf(stderr,"no dvdec\n"),exit(1);
+  gtk_object_set(GTK_OBJECT(videosink),"width",720,"height",480,NULL);
+
+  gst_bin_add(GST_BIN(bin),GST_ELEMENT(src));
+  gst_bin_add(GST_BIN(bin),GST_ELEMENT(dvdec));
+//  gst_bin_add(GST_BIN(bin),GST_ELEMENT(cspace));
+  gst_bin_add(GST_BIN(bin),GST_ELEMENT(videosink));
+
+  gst_element_connect(src,"src",dvdec,"sink");
+//  gst_element_connect(cspace,"src",videosink,"sink");
+//  gst_element_connect(dvdec,"video",cspace,"sink");
+  gst_element_connect(dvdec,"video",videosink,"sink");
+
+  appwindow = gnome_app_new("Videotest","Videotest");
+
+  vbox1 = gtk_vbox_new (FALSE, 0);
+  gtk_widget_show (vbox1);
+
+  button = gtk_button_new_with_label(_("test"));//_with_label (_("chup"));
+  gtk_widget_show (button);
+  gtk_box_pack_start (GTK_BOX (vbox1), button, FALSE, FALSE, 0);
+
+  draw = gst_util_get_int_arg (GTK_OBJECT (videosink), "xid"),
+
+  gtk_socket = gtk_socket_new ();
+  gtk_widget_set_usize(gtk_socket,720,480);
+  gtk_widget_show (gtk_socket);
+
+  gnome_app_set_contents(GNOME_APP(appwindow), vbox1);
+
+  gtk_box_pack_start (GTK_BOX (vbox1),
+                      GTK_WIDGET(gtk_socket),
+                      TRUE, TRUE, 0);
+
+  gtk_widget_realize (gtk_socket);
+  gtk_socket_steal (GTK_SOCKET (gtk_socket), draw);
+                                                               
+  gtk_object_set(GTK_OBJECT(appwindow),"allow_grow",TRUE,NULL);
+  gtk_object_set(GTK_OBJECT(appwindow),"allow_shrink",TRUE,NULL);
+
+  gtk_widget_show_all(appwindow);
+
+  xmlSaveFile("dvshow.xml",gst_xml_write(GST_ELEMENT(bin)));
+
+  gst_element_set_state(GST_ELEMENT(bin),GST_STATE_PLAYING);
+
+  g_idle_add(idle_func,bin);
+
+  gtk_main();
+
+  exit (0);
+}
+
index 78d9550ec148cd6ac8daa2af967aef5549477a44..3a609f11622c15cee6299e4598ce8517efc19db8 100644 (file)
@@ -37,7 +37,7 @@ create_muxer (GstElement *pipeline, gchar *type, gchar *number)
 static void 
 mp2tomp1 (GstElement *parser, GstPad *pad, GstElement *pipeline) 
 {
-  GstElement *parse_audio, *parse_video, *decode, *decode_video, *play, *encode, *audio_resample;
+  GstElement *decode, *decode_video, *play, *encode, *audio_resample;
   GstElement *smooth, *median;
   GstElement *audio_queue, *video_queue;
   GstElement *audio_thread, *video_thread;
@@ -51,9 +51,6 @@ mp2tomp1 (GstElement *parser, GstPad *pad, GstElement *pipeline)
   //if (0) {
   if (strncmp(gst_pad_get_name(pad), "private_stream_1.0", 18) == 0) {
     // construct internal pipeline elements
-    parse_audio = gst_elementfactory_make("ac3parse","parse_audio");
-    g_return_if_fail(parse_audio != NULL);
-    gtk_object_set(GTK_OBJECT(parse_audio),"skip", 15, NULL);
     decode = gst_elementfactory_make("ac3dec","decode_audio");
     g_return_if_fail(decode != NULL);
     audio_resample = gst_elementfactory_make("audioscale","audioscale");
@@ -68,7 +65,6 @@ mp2tomp1 (GstElement *parser, GstPad *pad, GstElement *pipeline)
     // create the thread and pack stuff into it
     audio_thread = gst_thread_new("audio_thread");
     g_return_if_fail(audio_thread != NULL);
-    gst_bin_add(GST_BIN(audio_thread),GST_ELEMENT(parse_audio));
     gst_bin_add(GST_BIN(audio_thread),GST_ELEMENT(decode));
     gst_bin_add(GST_BIN(audio_thread),GST_ELEMENT(audio_resample));
     gst_bin_add(GST_BIN(audio_thread),GST_ELEMENT(audio_encode));
@@ -77,9 +73,7 @@ mp2tomp1 (GstElement *parser, GstPad *pad, GstElement *pipeline)
 
     // set up pad connections
     gst_element_add_ghost_pad(GST_ELEMENT(audio_thread),
-                              gst_element_get_pad(parse_audio,"sink"),"sink");
-    gst_pad_connect(gst_element_get_pad(parse_audio,"src"),
-                    gst_element_get_pad(decode,"sink"));
+                              gst_element_get_pad(decode,"sink"),"sink");
     gst_pad_connect(gst_element_get_pad(decode,"src"),
                     gst_element_get_pad(audio_resample,"sink"));
     gst_pad_connect(gst_element_get_pad(audio_resample,"src"),
@@ -106,9 +100,7 @@ mp2tomp1 (GstElement *parser, GstPad *pad, GstElement *pipeline)
     //                gst_element_get_pad(merge_subtitles,"subtitle"));
   } else if (strncmp(gst_pad_get_name(pad), "audio_", 6) == 0) {
     // construct internal pipeline elements
-    parse_audio = gst_elementfactory_make("mp3parse","parse_audio");
-    g_return_if_fail(parse_audio != NULL);
-    decode = gst_elementfactory_make("mpg123","decode_audio");
+    decode = gst_elementfactory_make("mad","decode_audio");
     g_return_if_fail(decode != NULL);
     play = gst_elementfactory_make("osssink","play_audio");
     g_return_if_fail(play != NULL);
@@ -116,16 +108,13 @@ mp2tomp1 (GstElement *parser, GstPad *pad, GstElement *pipeline)
     // create the thread and pack stuff into it
     audio_thread = gst_thread_new("audio_thread");
     g_return_if_fail(audio_thread != NULL);
-    gst_bin_add(GST_BIN(audio_thread),GST_ELEMENT(parse_audio));
     gst_bin_add(GST_BIN(audio_thread),GST_ELEMENT(decode));
     gst_bin_add(GST_BIN(audio_thread),GST_ELEMENT(play));
 
 
     // set up pad connections
     gst_element_add_ghost_pad(GST_ELEMENT(audio_thread),
-                              gst_element_get_pad(parse_audio,"sink"),"sink");
-    gst_pad_connect(gst_element_get_pad(parse_audio,"src"),
-                    gst_element_get_pad(decode,"sink"));
+                              gst_element_get_pad(decode,"sink"),"sink");
     gst_pad_connect(gst_element_get_pad(decode,"src"),
                     gst_element_get_pad(play,"sink"));
 
@@ -148,9 +137,7 @@ mp2tomp1 (GstElement *parser, GstPad *pad, GstElement *pipeline)
 
     //gst_plugin_load("mpeg1encoder");
     // construct internal pipeline elements
-    parse_video = gst_elementfactory_make("mp2videoparse","parse_video");
-    g_return_if_fail(parse_video != NULL);
-    decode_video = gst_elementfactory_make("mpeg2play","decode_video");
+    decode_video = gst_elementfactory_make("mpeg2dec","decode_video");
     g_return_if_fail(decode_video != NULL);
     //merge_subtitles = gst_elementfactory_make("mpeg2subt","merge_subtitles");
     //g_return_if_fail(merge_subtitles != NULL);
@@ -174,13 +161,14 @@ mp2tomp1 (GstElement *parser, GstPad *pad, GstElement *pipeline)
     //gtk_object_set(GTK_OBJECT(show),"width",640, "height", 480,NULL);
 
     muxerpad = create_muxer (pipeline, "video", "00");
+    g_return_if_fail(muxerpad != NULL);
+    
 
     // create the thread and pack stuff into it
     video_thread = gst_thread_new("video_thread");
     g_return_if_fail(video_thread != NULL);
-    gst_bin_add(GST_BIN(video_thread),GST_ELEMENT(parse_video));
     gst_bin_add(GST_BIN(video_thread),GST_ELEMENT(decode_video));
-    gst_bin_add(GST_BIN(video_thread),GST_ELEMENT(merge_subtitles));
+    //gst_bin_add(GST_BIN(video_thread),GST_ELEMENT(merge_subtitles));
     gst_bin_add(GST_BIN(video_thread),GST_ELEMENT(median));
     gst_bin_add(GST_BIN(video_thread),GST_ELEMENT(smooth));
     gst_bin_add(GST_BIN(video_thread),GST_ELEMENT(videoscale));
@@ -189,9 +177,7 @@ mp2tomp1 (GstElement *parser, GstPad *pad, GstElement *pipeline)
 
     // set up pad connections
     gst_element_add_ghost_pad(GST_ELEMENT(video_thread),
-                              gst_element_get_pad(parse_video,"sink"),"sink");
-    gst_pad_connect(gst_element_get_pad(parse_video,"src"),
-                    gst_element_get_pad(decode_video,"sink"));
+                              gst_element_get_pad(decode_video,"sink"),"sink");
     gst_pad_connect(gst_element_get_pad(decode_video,"src"),
                     gst_element_get_pad(median,"sink"));
     gst_pad_connect(gst_element_get_pad(median,"src"),
index 5f4ff6fba1cb5abfc3716c70c577fd7566c400e6..a92064c7901c1880ea08d311b7fa0706fdacaed9 100644 (file)
@@ -1,4 +1,3 @@
-#include <gnome.h>
 #include <gst/gst.h>
 
 extern gboolean _gst_plugin_spew;
diff --git a/test/mp3mad.c b/test/mp3mad.c
new file mode 100644 (file)
index 0000000..b154e60
--- /dev/null
@@ -0,0 +1,47 @@
+#include <gst/gst.h>
+
+
+int main(int argc,char *argv[]) {
+  GstElementFactory *srcfactory, *parsefactory, *decodefactory, *playfactory;
+  GstElement *pipeline, *src, *decode, *play;
+  GstPad *infopad;
+
+  g_print("have %d args\n",argc);
+
+  gst_init(&argc,&argv);
+
+  pipeline = gst_pipeline_new("pipeline");
+  g_return_if_fail(pipeline != NULL);
+
+  srcfactory = gst_elementfactory_find("disksrc");
+  g_return_if_fail(srcfactory != NULL);
+  decodefactory = gst_elementfactory_find("mad");
+  g_return_if_fail(decodefactory != NULL);
+  playfactory = gst_elementfactory_find("osssink");
+  g_return_if_fail(playfactory != NULL);
+
+  src = gst_elementfactory_create(srcfactory,"src");
+  g_return_if_fail(src != NULL);
+  gtk_object_set(GTK_OBJECT(src),"location",argv[1],NULL);
+  g_print("should be using file '%s'\n",argv[1]);
+  decode = gst_elementfactory_create(decodefactory,"decode");
+  g_return_if_fail(decode != NULL);
+  play = gst_elementfactory_create(playfactory,"play");
+  g_return_if_fail(play != NULL);
+
+  gst_bin_add(GST_BIN(pipeline),GST_ELEMENT(src));
+  gst_bin_add(GST_BIN(pipeline),GST_ELEMENT(decode));
+  gst_bin_add(GST_BIN(pipeline),GST_ELEMENT(play));
+
+  gst_pad_connect(gst_element_get_pad(src,"src"),
+                  gst_element_get_pad(decode,"sink"));
+  gst_pad_connect(gst_element_get_pad(decode,"src"),
+                  gst_element_get_pad(play,"sink"));
+
+  g_print("setting to READY state\n");
+  gst_element_set_state(GST_ELEMENT(pipeline),GST_STATE_READY);
+  gst_element_set_state(GST_ELEMENT(pipeline),GST_STATE_PLAYING);
+
+  g_print("about to enter loop\n");
+  while (gst_bin_iterate(GST_BIN(pipeline)));
+}
diff --git a/test/video2mp1.c b/test/video2mp1.c
new file mode 100644 (file)
index 0000000..79b3a50
--- /dev/null
@@ -0,0 +1,236 @@
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <string.h>
+#include <glib.h>
+#include <gst/gst.h>
+#include <gnome.h>
+
+static void
+gst_play_have_type (GstElement *sink, GstElement *sink2, gpointer data)
+{
+  GST_DEBUG (0,"GstPipeline: play have type %p\n", (gboolean *)data);
+
+  *(gboolean *)data = TRUE;
+}
+
+gboolean 
+idle_func (gpointer data)
+{
+  return gst_bin_iterate (GST_BIN (data));
+}
+
+static GstCaps*
+gst_play_typefind (GstBin *bin, GstElement *element)
+{
+  gboolean found = FALSE;
+  GstElement *typefind;
+  GstCaps *caps = NULL;
+
+  GST_DEBUG (0,"GstPipeline: typefind for element \"%s\" %p\n",
+             GST_ELEMENT_NAME(element), &found);
+
+  typefind = gst_elementfactory_make ("typefind", "typefind");
+  g_return_val_if_fail (typefind != NULL, FALSE);
+
+  gtk_signal_connect (GTK_OBJECT (typefind), "have_type",
+                      GTK_SIGNAL_FUNC (gst_play_have_type), &found);
+
+  gst_pad_connect (gst_element_get_pad (element, "src"),
+                   gst_element_get_pad (typefind, "sink"));
+
+  gst_bin_add (bin, typefind);
+
+  gst_element_set_state (GST_ELEMENT (bin), GST_STATE_PLAYING);
+
+  // push a buffer... the have_type signal handler will set the found flag
+  gst_bin_iterate (bin);
+
+  gst_element_set_state (GST_ELEMENT (bin), GST_STATE_NULL);
+
+  caps = gst_pad_get_caps (gst_element_get_pad (element, "src"));
+
+  gst_pad_disconnect (gst_element_get_pad (element, "src"),
+                      gst_element_get_pad (typefind, "sink"));
+  gst_bin_remove (bin, typefind);
+  gst_object_unref (GST_OBJECT (typefind));
+
+  return caps;
+}
+
+static GstElement*
+get_video_encoder_bin (void) 
+{
+  GstElement *bin;
+  GstElement *encoder, *queue, *colorspace, *videoscale;
+
+  bin = gst_bin_new ("video_encoder_bin");
+
+  colorspace = gst_elementfactory_make ("colorspace", "colorspace");
+  g_assert (colorspace != NULL);
+  videoscale = gst_elementfactory_make ("videoscale", "videoscale");
+  g_assert (videoscale != NULL);
+  gtk_object_set (GTK_OBJECT (videoscale), "width", 352, "height", 288, NULL);
+  encoder = gst_elementfactory_make ("mpeg2enc", "video_encoder");
+  g_assert (encoder != NULL);
+  queue = gst_elementfactory_make ("queue", "video_encoder_queue");
+  g_assert (queue != NULL);
+
+  gst_bin_add (GST_BIN (bin), colorspace);
+  gst_bin_add (GST_BIN (bin), videoscale);
+  gst_bin_add (GST_BIN (bin), encoder);
+  gst_bin_add (GST_BIN (bin), queue);
+
+  gst_element_connect (colorspace, "src", videoscale, "sink");
+  gst_element_connect (videoscale, "src", encoder, "sink");
+  gst_element_connect (encoder, "src", queue, "sink");
+
+  gst_element_add_ghost_pad (bin, gst_element_get_pad (colorspace, "sink"), "sink");
+  gst_element_add_ghost_pad (bin, gst_element_get_pad (queue, "src"), "src");
+
+  return bin;
+}
+
+static GstElement*
+get_audio_encoder_bin (void) 
+{
+  GstElement *bin;
+  GstElement *encoder, *queue;
+
+  bin = gst_bin_new ("audio_encoder_bin");
+
+  encoder = gst_elementfactory_make ("mpegaudio", "audio_encoder");
+  g_assert (encoder != NULL);
+  queue = gst_elementfactory_make ("queue", "audio_encoder_queue");
+  g_assert (queue != NULL);
+
+  gst_bin_add (GST_BIN (bin), encoder);
+  gst_bin_add (GST_BIN (bin), queue);
+
+  gst_element_connect (encoder, "src", queue, "sink");
+
+  gst_element_add_ghost_pad (bin, gst_element_get_pad (encoder, "sink"), "sink");
+  gst_element_add_ghost_pad (bin, gst_element_get_pad (queue, "src"), "src");
+
+  return bin;
+}
+
+int main(int argc,char *argv[]) 
+{
+  GstElement *disksrc, *audio_enc, *video_enc;
+  GstElement *muxthread_video, *muxer, *fdsink_video;
+  GstElement *muxthread_audio, *fdsink_audio;
+  GstElement *bin;
+  GtkWidget *appwindow;
+  GstCaps *srccaps;
+  GstElement *new_element;
+  GstAutoplug *autoplug;
+  GtkWidget *socket;
+  gint fd_video;
+  gint fd_audio;
+
+  g_thread_init(NULL);
+  gst_init(&argc,&argv);
+  gnome_init("autoplug","0.0.1", argc,argv);
+
+  if (argc != 4) {
+    g_print("usage: %s <in_filename> <out_video> <out_audio>\n", argv[0]);
+    exit(-1);
+  }
+
+  /* create a new bin to hold the elements */
+  bin = gst_pipeline_new("pipeline");
+  g_assert(bin != NULL);
+
+  /* create a disk reader */
+  disksrc = gst_elementfactory_make("disksrc", "disk_source");
+  g_assert(disksrc != NULL);
+  gtk_object_set(GTK_OBJECT(disksrc),"location", argv[1],NULL);
+
+  gst_bin_add (GST_BIN (bin), disksrc);
+
+  srccaps = gst_play_typefind (GST_BIN (bin), disksrc);
+
+  if (!srccaps) {
+    g_print ("could not autoplug, unknown media type...\n");
+    exit (-1);
+  }
+  
+  audio_enc = get_audio_encoder_bin();
+  video_enc = get_video_encoder_bin();
+
+  autoplug = gst_autoplugfactory_make ("staticrender");
+  g_assert (autoplug != NULL);
+
+  new_element = gst_autoplug_to_renderers (autoplug,
+           srccaps,
+           video_enc,
+           audio_enc,
+           NULL);
+
+  if (!new_element) {
+    g_print ("could not autoplug, no suitable codecs found...\n");
+    exit (-1);
+  }
+
+  gst_bin_remove (GST_BIN (bin), disksrc);
+  gst_object_destroy (GST_OBJECT (bin));
+
+  // FIXME hack, reparent the disksrc so the scheduler doesn't break
+  bin = gst_pipeline_new("pipeline");
+
+  gst_bin_add (GST_BIN (bin), disksrc);
+  gst_bin_add (GST_BIN (bin), new_element);
+
+  gst_element_connect (disksrc, "src", new_element, "sink");
+
+  muxer = gst_elementfactory_make ("system_encode", "muxer");
+  g_assert (muxer != NULL);
+
+  if (gst_bin_get_by_name (GST_BIN (new_element), "video_encoder_bin")) {
+    muxthread_video = gst_thread_new("thread_video");
+
+    fdsink_video = gst_elementfactory_make ("fdsink", "fdsink_video");
+    g_assert (fdsink_video != NULL);
+    fd_video = open (argv[2], O_CREAT|O_RDWR|O_TRUNC);
+    gtk_object_set (GTK_OBJECT (fdsink_video), "fd", fd_video, NULL);
+
+    gst_element_connect (video_enc, "src", fdsink_video, "sink");
+    gst_bin_add (GST_BIN (muxthread_video), fdsink_video);
+
+    gst_bin_add (GST_BIN (bin), muxthread_video);
+  }
+
+  if (gst_bin_get_by_name (GST_BIN (new_element), "audio_encoder_bin")) {
+    muxthread_audio = gst_thread_new("thread_audio");
+
+    fdsink_audio = gst_elementfactory_make ("fdsink", "fdsink_audio");
+    g_assert (fdsink_audio != NULL);
+    fd_audio = open (argv[3], O_CREAT|O_RDWR|O_TRUNC);
+    gtk_object_set (GTK_OBJECT (fdsink_audio), "fd", fd_audio, NULL);
+
+    gst_element_connect (audio_enc, "src", fdsink_audio, "sink");
+    gst_bin_add (GST_BIN (muxthread_audio), fdsink_audio);
+
+    gst_bin_add (GST_BIN (bin), muxthread_audio);
+  }
+
+  //gtk_object_set (GTK_OBJECT (muxer), "video", "00", NULL);
+  //gtk_object_set (GTK_OBJECT (muxer), "audio", "00", NULL);
+  
+  /* start playing */
+  gst_element_set_state(GST_ELEMENT(bin), GST_STATE_PLAYING);
+
+  gtk_idle_add(idle_func, bin);
+
+  gst_main();
+
+  /* stop the bin */
+  gst_element_set_state(GST_ELEMENT(bin), GST_STATE_NULL);
+
+  gst_pipeline_destroy(bin);
+
+  exit(0);
+}
+
index 59eb23d0ac78b3298ce26e303443e3f4a564c4ec..e88177b4e3af112c17c93c4335299d5dddd5d8b3 100644 (file)
@@ -1,4 +1,3 @@
-#include <gnome.h>
 #include <gst/gst.h>
 
 extern gboolean _gst_plugin_spew;
index d1ee8d983a3509110378ca25e0d25c6ec6a541b0..11ce4da685427514cccac19bcea58a3ca84ccd04 100644 (file)
@@ -2,7 +2,7 @@ SUBDIRS = sched eos
 
 noinst_PROGRAMS = init loadall simplefake states caps queue registry \
 paranoia rip mp3encode autoplug props case4 markup load tee autoplug2 autoplug3 \
-capsconnect incsched reaping threadlock mp1vid
+capsconnect padfactory autoplug4 incsched reaping threadlock mp1vid
 
 # we have nothing but apps here, we can do this safely
 LIBS += $(GST_LIBS)
index 34927edad287101974dbaed56e0e328bacc08580..479c415dc5158e9a86156e5fea6a8b4a0f9a4d18 100644 (file)
 int
 main (int argc, char *argv[])
 {
-  GstElement *element;
-  GstElement *sink1, *sink2;
   GstAutoplug *autoplug;
-  GstAutoplug *autoplug2;
+  GstElement *element;
+  GstElement *sink;
+  GstElement *pipeline;
+  GstElement *disksrc;
 
   gst_init(&argc,&argv);
 
-  sink1 = gst_elementfactory_make ("videosink", "videosink");
-  sink2 = gst_elementfactory_make ("osssink", "osssink");
+  sink = gst_elementfactory_make ("osssink", "osssink");
+  g_assert (sink != NULL);
 
   autoplug = gst_autoplugfactory_make ("staticrender");
-  autoplug2 = gst_autoplugfactory_make ("static");
+  g_assert (autoplug != NULL);
   
   element = gst_autoplug_to_renderers (autoplug, 
-                 gst_caps_new ("mp3caps", "audio/mp3", NULL), sink2, NULL);
-  xmlSaveFile ("autoplug3_1.gst", gst_xml_write (element));
+                                      gst_caps_new (
+                                        "mp3caps", 
+                                        "audio/mp3",
+                                        NULL
+                                      ), 
+                                      sink,
+                                      NULL);
+  g_assert (element != NULL);
 
-  element = gst_autoplug_to_renderers (autoplug, 
-                 gst_caps_new ("mpeg1caps", "video/mpeg", NULL), sink1, NULL);
-  if (element) {
-    xmlSaveFile ("autoplug3_2.gst", gst_xml_write (element));
-  }
+  pipeline = gst_pipeline_new ("main_pipeline");
+  g_assert (pipeline != NULL);
 
-  element = gst_autoplug_to_caps (autoplug2,
-                 gst_caps_new(
-                         "testcaps3",
-                         "video/mpeg",
-                         gst_props_new (
-                             "mpegversion",  GST_PROPS_INT (1),
-                             "systemstream", GST_PROPS_BOOLEAN (TRUE),
-                             NULL)),
-                 gst_caps_new("testcaps4","audio/raw", NULL),
-                 NULL);
-  if (element) {
-    xmlSaveFile ("autoplug3_3.gst", gst_xml_write (element));
-  }
+  disksrc = gst_elementfactory_make ("disksrc", "disk_reader");
+  g_assert (disksrc != NULL);
 
-  element = gst_autoplug_to_caps (autoplug2,
-                 gst_caps_new(
-                         "testcaps5",
-                         "video/mpeg",
-                         gst_props_new (
-                             "mpegversion",  GST_PROPS_INT (1),
-                             "systemstream", GST_PROPS_BOOLEAN (FALSE),
-                             NULL)),
-                 gst_caps_new("testcaps6", "video/raw", NULL),
-                 NULL);
-  if (element) {
-    xmlSaveFile ("autoplug3_4.gst", gst_xml_write (element));
-  }
+  gst_bin_add (GST_BIN (pipeline), disksrc);
+  gst_bin_add (GST_BIN (pipeline), element);
 
-  element = gst_autoplug_to_caps (autoplug2,
-                 gst_caps_new(
-                         "testcaps7",
-                         "video/avi", NULL),
-                 gst_caps_new("testcaps8", "video/raw", NULL),
-                 gst_caps_new("testcaps9", "audio/raw", NULL),
-                 NULL);
-  if (element) {
-    xmlSaveFile ("autoplug3_5.gst", gst_xml_write (element));
-  }
+  gst_element_connect (disksrc, "src", element, "sink");
 
-  element = gst_autoplug_to_caps (autoplug2,
-                 gst_caps_new(
-                         "testcaps10",
-                         "video/mpeg",
-                         gst_props_new (
-                             "mpegversion",  GST_PROPS_INT (1),
-                             "systemstream", GST_PROPS_BOOLEAN (TRUE),
-                             NULL)),
-                 gst_caps_new("testcaps10", "video/raw", NULL),
-                 gst_caps_new("testcaps11", "audio/raw", NULL),
-                 NULL);
-  if (element) {
-    xmlSaveFile ("autoplug3_6.gst", gst_xml_write (element));
-  }
+  gtk_object_set (GTK_OBJECT (disksrc), "location", argv[1], NULL);
 
-  sink1 = gst_elementfactory_make ("videosink", "videosink");
-  sink2 = gst_elementfactory_make ("osssink", "osssink");
-  
-  element = gst_autoplug_to_renderers (autoplug,
-                 gst_caps_new(
-                         "testcaps10",
-                         "video/mpeg",
-                         gst_props_new (
-                             "mpegversion",  GST_PROPS_INT (1),
-                             "systemstream", GST_PROPS_BOOLEAN (TRUE),
-                             NULL)),
-                 sink1,
-                 sink2,
-                 NULL);
-  if (element) {
-    xmlSaveFile ("autoplug3_7.gst", gst_xml_write (element));
-  }
+  gst_element_set_state (pipeline, GST_STATE_PLAYING);
+
+  while (gst_bin_iterate (GST_BIN (pipeline)));
+
+  gst_element_set_state (pipeline, GST_STATE_NULL);
 
   exit (0);
 }
diff --git a/tests/autoplug4.c b/tests/autoplug4.c
new file mode 100644 (file)
index 0000000..34927ed
--- /dev/null
@@ -0,0 +1,102 @@
+#include <gst/gst.h>
+
+int
+main (int argc, char *argv[])
+{
+  GstElement *element;
+  GstElement *sink1, *sink2;
+  GstAutoplug *autoplug;
+  GstAutoplug *autoplug2;
+
+  gst_init(&argc,&argv);
+
+  sink1 = gst_elementfactory_make ("videosink", "videosink");
+  sink2 = gst_elementfactory_make ("osssink", "osssink");
+
+  autoplug = gst_autoplugfactory_make ("staticrender");
+  autoplug2 = gst_autoplugfactory_make ("static");
+  
+  element = gst_autoplug_to_renderers (autoplug, 
+                 gst_caps_new ("mp3caps", "audio/mp3", NULL), sink2, NULL);
+  xmlSaveFile ("autoplug3_1.gst", gst_xml_write (element));
+
+  element = gst_autoplug_to_renderers (autoplug, 
+                 gst_caps_new ("mpeg1caps", "video/mpeg", NULL), sink1, NULL);
+  if (element) {
+    xmlSaveFile ("autoplug3_2.gst", gst_xml_write (element));
+  }
+
+  element = gst_autoplug_to_caps (autoplug2,
+                 gst_caps_new(
+                         "testcaps3",
+                         "video/mpeg",
+                         gst_props_new (
+                             "mpegversion",  GST_PROPS_INT (1),
+                             "systemstream", GST_PROPS_BOOLEAN (TRUE),
+                             NULL)),
+                 gst_caps_new("testcaps4","audio/raw", NULL),
+                 NULL);
+  if (element) {
+    xmlSaveFile ("autoplug3_3.gst", gst_xml_write (element));
+  }
+
+  element = gst_autoplug_to_caps (autoplug2,
+                 gst_caps_new(
+                         "testcaps5",
+                         "video/mpeg",
+                         gst_props_new (
+                             "mpegversion",  GST_PROPS_INT (1),
+                             "systemstream", GST_PROPS_BOOLEAN (FALSE),
+                             NULL)),
+                 gst_caps_new("testcaps6", "video/raw", NULL),
+                 NULL);
+  if (element) {
+    xmlSaveFile ("autoplug3_4.gst", gst_xml_write (element));
+  }
+
+  element = gst_autoplug_to_caps (autoplug2,
+                 gst_caps_new(
+                         "testcaps7",
+                         "video/avi", NULL),
+                 gst_caps_new("testcaps8", "video/raw", NULL),
+                 gst_caps_new("testcaps9", "audio/raw", NULL),
+                 NULL);
+  if (element) {
+    xmlSaveFile ("autoplug3_5.gst", gst_xml_write (element));
+  }
+
+  element = gst_autoplug_to_caps (autoplug2,
+                 gst_caps_new(
+                         "testcaps10",
+                         "video/mpeg",
+                         gst_props_new (
+                             "mpegversion",  GST_PROPS_INT (1),
+                             "systemstream", GST_PROPS_BOOLEAN (TRUE),
+                             NULL)),
+                 gst_caps_new("testcaps10", "video/raw", NULL),
+                 gst_caps_new("testcaps11", "audio/raw", NULL),
+                 NULL);
+  if (element) {
+    xmlSaveFile ("autoplug3_6.gst", gst_xml_write (element));
+  }
+
+  sink1 = gst_elementfactory_make ("videosink", "videosink");
+  sink2 = gst_elementfactory_make ("osssink", "osssink");
+  
+  element = gst_autoplug_to_renderers (autoplug,
+                 gst_caps_new(
+                         "testcaps10",
+                         "video/mpeg",
+                         gst_props_new (
+                             "mpegversion",  GST_PROPS_INT (1),
+                             "systemstream", GST_PROPS_BOOLEAN (TRUE),
+                             NULL)),
+                 sink1,
+                 sink2,
+                 NULL);
+  if (element) {
+    xmlSaveFile ("autoplug3_7.gst", gst_xml_write (element));
+  }
+
+  exit (0);
+}
index 17a14055c2d85c51c8bb056c5c352e068d8f8a83..c251eabb68f5fc73e52c33b88ff4ceb3026e0a94 100644 (file)
@@ -1,4 +1,11 @@
-SUBDIRS = autoplug \
+
+if HAVE_GNOME
+GNOME_SUBDS = autoplug
+else
+GNOME_SUBDS =
+endif
+
+SUBDIRS = $(GNOME_SUBDS) \
           helloworld helloworld2 \
           queue queue2 queue3 queue4 \
           launch thread xml plugins typefind
index 4a3453552cc83e2927768032614d4294ed28d4bc..e9135fb8d22479608811406ee0c7192d1bf378da 100644 (file)
@@ -1,26 +1,67 @@
 #include <gst/gst.h>
 #include <gnome.h>
 
-static gboolean playing;
-
-/* eos will be called when the src element has an end of stream */
-void eos(GstElement *element) 
+static void
+gst_play_have_type (GstElement *sink, GstElement *sink2, gpointer data)
 {
-  g_print("have eos, quitting\n");
+  GST_DEBUG (0,"GstPipeline: play have type %p\n", (gboolean *)data);
 
-  playing = FALSE;
+  *(gboolean *)data = TRUE;
 }
 
-gboolean idle_func(gpointer data) {
-  gst_bin_iterate(GST_BIN(data));
-  return TRUE;
+gboolean 
+idle_func (gpointer data)
+{
+  return gst_bin_iterate (GST_BIN (data));
+}
+
+static GstCaps*
+gst_play_typefind (GstBin *bin, GstElement *element)
+{
+  gboolean found = FALSE;
+  GstElement *typefind;
+  GstCaps *caps = NULL;
+
+  GST_DEBUG (0,"GstPipeline: typefind for element \"%s\" %p\n",
+             GST_ELEMENT_NAME(element), &found);
+
+  typefind = gst_elementfactory_make ("typefind", "typefind");
+  g_return_val_if_fail (typefind != NULL, FALSE);
+
+  gtk_signal_connect (GTK_OBJECT (typefind), "have_type",
+                      GTK_SIGNAL_FUNC (gst_play_have_type), &found);
+
+  gst_pad_connect (gst_element_get_pad (element, "src"),
+                   gst_element_get_pad (typefind, "sink"));
+
+  gst_bin_add (bin, typefind);
+
+  gst_element_set_state (GST_ELEMENT (bin), GST_STATE_PLAYING);
+
+  // push a buffer... the have_type signal handler will set the found flag
+  gst_bin_iterate (bin);
+
+  gst_element_set_state (GST_ELEMENT (bin), GST_STATE_NULL);
+
+  caps = gst_pad_get_caps (gst_element_get_pad (element, "src"));
+
+  gst_pad_disconnect (gst_element_get_pad (element, "src"),
+                      gst_element_get_pad (typefind, "sink"));
+  gst_bin_remove (bin, typefind);
+  gst_object_unref (GST_OBJECT (typefind));
+
+  return caps;
 }
 
 int main(int argc,char *argv[]) 
 {
-  GstElement *disksrc, *audiosink, *videosink;
-  GstElement *pipeline;
+  GstElement *disksrc, *osssink, *videosink;
+  GstElement *bin;
   GtkWidget *appwindow;
+  GstCaps *srccaps;
+  GstElement *new_element;
+  GstAutoplug *autoplug;
+  GtkWidget *socket;
 
   g_thread_init(NULL);
   gst_init(&argc,&argv);
@@ -31,58 +72,82 @@ int main(int argc,char *argv[])
     exit(-1);
   }
 
-
-
   /* create a new bin to hold the elements */
-  pipeline = gst_pipeline_new("pipeline");
-  g_assert(pipeline != NULL);
+  bin = gst_pipeline_new("pipeline");
+  g_assert(bin != NULL);
 
   /* create a disk reader */
   disksrc = gst_elementfactory_make("disksrc", "disk_source");
   g_assert(disksrc != NULL);
   gtk_object_set(GTK_OBJECT(disksrc),"location", argv[1],NULL);
-  gtk_signal_connect(GTK_OBJECT(disksrc),"eos",
-                     GTK_SIGNAL_FUNC(eos),NULL);
 
+  gst_bin_add (GST_BIN (bin), disksrc);
+
+  srccaps = gst_play_typefind (GST_BIN (bin), disksrc);
+
+  if (!srccaps) {
+    g_print ("could not autoplug, unknown media type...\n");
+    exit (-1);
+  }
+  
   /* and an audio sink */
-  audiosink = gst_elementfactory_make("audiosink", "play_audio");
-  g_assert(audiosink != NULL);
+  osssink = gst_elementfactory_make("osssink", "play_audio");
+  g_assert(osssink != NULL);
 
   /* and an video sink */
-  videosink = gst_elementfactory_make("videosink", "play_video");
+  videosink = gst_elementfactory_make("xvideosink", "play_video");
   g_assert(videosink != NULL);
-  gtk_object_set(GTK_OBJECT(videosink),"xv_enabled", FALSE,NULL);
+
+  autoplug = gst_autoplugfactory_make ("staticrender");
+  g_assert (autoplug != NULL);
+
+  new_element = gst_autoplug_to_renderers (autoplug,
+           srccaps,
+           videosink,
+           osssink,
+           NULL);
+
+  if (!new_element) {
+    g_print ("could not autoplug, no suitable codecs found...\n");
+    exit (-1);
+  }
+
+  gst_bin_remove (GST_BIN (bin), disksrc);
+  // FIXME hack, reparent the disksrc so the scheduler doesn't break
+  bin = gst_pipeline_new("pipeline");
+
+  gst_bin_add (GST_BIN (bin), disksrc);
+  gst_bin_add (GST_BIN (bin), new_element);
+
+  gst_element_connect (disksrc, "src", new_element, "sink");
 
   appwindow = gnome_app_new("autoplug demo","autoplug demo");
+
+  socket = gtk_socket_new ();
+  gtk_widget_show (socket);
+
   gnome_app_set_contents(GNOME_APP(appwindow),
-    gst_util_get_widget_arg(GTK_OBJECT(videosink),"widget"));
-  gtk_widget_show_all(appwindow);
+               GTK_WIDGET (socket));
 
-  /* add objects to the main pipeline */
-  gst_pipeline_add_src(GST_PIPELINE(pipeline), disksrc);
-  gst_pipeline_add_sink(GST_PIPELINE(pipeline), videosink);
-  gst_pipeline_add_sink(GST_PIPELINE(pipeline), audiosink);
+  gtk_widget_realize (socket);
+  gtk_socket_steal (GTK_SOCKET (socket), 
+                   gst_util_get_int_arg (GTK_OBJECT (videosink), "xid"));
 
-  if (!gst_pipeline_autoplug(GST_PIPELINE(pipeline))) {
-    g_print("unable to handle stream\n");
-    exit(-1);
-  }
+  gtk_widget_show_all(appwindow);
 
-  xmlSaveFile("xmlTest.gst", gst_xml_write(GST_ELEMENT(pipeline)));
+  xmlSaveFile("xmlTest.gst", gst_xml_write(GST_ELEMENT(bin)));
 
   /* start playing */
-  gst_element_set_state(GST_ELEMENT(pipeline), GST_STATE_PLAYING);
-
-  playing = TRUE;
+  gst_element_set_state(GST_ELEMENT(bin), GST_STATE_PLAYING);
 
-  gtk_idle_add(idle_func, pipeline);
+  gtk_idle_add(idle_func, bin);
 
   gst_main();
 
   /* stop the bin */
-  gst_element_set_state(GST_ELEMENT(pipeline), GST_STATE_NULL);
+  gst_element_set_state(GST_ELEMENT(bin), GST_STATE_NULL);
 
-  gst_pipeline_destroy(pipeline);
+  gst_pipeline_destroy(bin);
 
   exit(0);
 }
diff --git a/tests/old/examples/mixer/.gitignore b/tests/old/examples/mixer/.gitignore
new file mode 100644 (file)
index 0000000..31e0fce
--- /dev/null
@@ -0,0 +1 @@
+helloworld
diff --git a/tests/old/examples/mixer/Makefile.am b/tests/old/examples/mixer/Makefile.am
new file mode 100644 (file)
index 0000000..9c5573b
--- /dev/null
@@ -0,0 +1,4 @@
+noinst_PROGRAMS = mixer
+
+LIBS += $(GST_LIBS)
+CFLAGS += $(GST_CFLAGS)
diff --git a/tests/old/examples/mixer/mixer.c b/tests/old/examples/mixer/mixer.c
new file mode 100644 (file)
index 0000000..205d073
--- /dev/null
@@ -0,0 +1,360 @@
+/*
+ * mixer.c - stereo audio mixer - thomas@apestaart.org
+ * example based on helloworld
+ * demonstrates the adder plugin and the volume envelope plugin 
+ * work in progress but do try it out 
+ * 
+ * Latest change :     16/04/2001
+ *                                     multiple input channels allowed
+ *                                     volume envelope adapted 
+ * Version :           0.3
+ */
+
+#include <stdlib.h>
+#include <gst/gst.h>
+#include "mixer.h"
+#include <unistd.h>
+
+//#define DEBUG
+
+/* function prototypes */
+
+input_channel_t*       create_input_channel (int id, char* location);
+void                           destroy_input_channel (input_channel_t *pipe);
+void                           env_register_cp (GstElement *volenv, double cp_time, double cp_level);
+
+
+gboolean playing;
+
+
+/* eos will be called when the src element has an end of stream */
+void eos(GstElement *element) 
+{
+  g_print("have eos, quitting ?\n");
+
+//  playing = FALSE;
+}
+
+static void
+gst_play_have_type (GstElement *sink, GstElement *sink2, gpointer data)
+{
+  GST_DEBUG (0,"GstPipeline: play have type %p\n", (gboolean *)data);
+  *(gboolean *)data = TRUE;
+}
+
+static GstCaps*
+gst_play_typefind (GstBin *bin, GstElement *element)
+{
+  gboolean found = FALSE;
+  GstElement *typefind;
+  GstCaps *caps = NULL;
+
+  GST_DEBUG (0,"GstPipeline: typefind for element \"%s\" %p\n",
+             GST_ELEMENT_NAME(element), &found);
+  typefind = gst_elementfactory_make ("typefind", "typefind");
+  g_return_val_if_fail (typefind != NULL, FALSE);
+
+  gtk_signal_connect (GTK_OBJECT (typefind), "have_type",  
+                      GTK_SIGNAL_FUNC (gst_play_have_type), &found);
+  gst_pad_connect (gst_element_get_pad (element, "src"),
+                   gst_element_get_pad (typefind, "sink"));
+  gst_bin_add (bin, typefind);
+  
+  gst_element_set_state (GST_ELEMENT (bin), GST_STATE_PLAYING);
+  
+  // push a buffer... the have_type signal handler will set the found flag
+  gst_bin_iterate (bin);
+  
+  gst_element_set_state (GST_ELEMENT (bin), GST_STATE_NULL);
+
+  caps = gst_pad_get_caps (gst_element_get_pad (element, "src"));
+
+  gst_pad_disconnect (gst_element_get_pad (element, "src"),
+                      gst_element_get_pad (typefind, "sink"));
+  gst_bin_remove (bin, typefind);
+  gst_object_unref (GST_OBJECT (typefind));
+                   
+  return caps;
+}
+
+int main(int argc,char *argv[]) 
+{
+  int i;
+  int num_channels;
+  
+  char buffer[20];
+  
+  GList *input_channels;               /* structure holding all the input channels */
+  
+  input_channel_t *channel_in;
+  
+  GstElement *main_bin;
+  GstElement *adder;
+  GstElement *audiosink;
+
+  GstPad *pad; /* to request pads for the adder */
+
+  gst_init(&argc,&argv);
+
+  if (argc == 1) {
+    g_print("usage: %s <filename1> <filename2> <...>\n", argv[0]);
+    exit(-1);
+  }
+  num_channels = argc - 1;
+  
+  /* set up output channel and main bin */
+  
+  /* create adder */
+  adder = gst_elementfactory_make("adder", "adderel");
+
+  /* create an audio sink */
+  audiosink = gst_elementfactory_make("esdsink", "play_audio");
+
+  /* create main bin */
+  main_bin = gst_bin_new("bin");
+
+  /* connect adder and output to bin */
+
+  gst_bin_add(GST_BIN(main_bin), adder);
+  gst_bin_add(GST_BIN(main_bin), audiosink);
+
+  /* connect adder and audiosink */
+
+  gst_pad_connect(gst_element_get_pad(adder,"src"),
+                  gst_element_get_pad(audiosink,"sink"));
+  
+  /* create input channels, add to bin and connect */
+
+  input_channels = NULL;
+  
+  for (i = 1; i < argc; ++i)
+  {
+    printf ("Opening channel %d from file %s...\n", i, argv[i]);
+    channel_in = create_input_channel (i, argv[i]);
+    input_channels = g_list_append (input_channels, channel_in);  
+    gst_bin_add(GST_BIN(main_bin), channel_in->pipe);
+
+    /* request pads and connect to adder */
+    pad = gst_element_request_pad_by_name (adder, "sink%d");
+    g_print ("\tGot new adder sink pad %s\n", gst_pad_get_name (pad));
+    sprintf (buffer, "channel%d", i);
+    gst_pad_connect (gst_element_get_pad (channel_in->pipe, buffer), pad);
+
+    /* register a volume envelope */
+    printf ("\tregistering volume envelope...\n");
+
+    /* 
+     * this is the volenv :
+     * each song gets a slot of 5 seconds, with a 5 second fadeout
+     * at the end of that, all audio streams play simultaneously
+     * at a level ensuring no distortion
+     * example for three songs :
+     * song1 : starts at full level, plays 5 seconds, faded out at 10 seconds,
+     *                    sleep until 25, fade to end level at 30
+     * song2 : starts silent, fades in at 5 seconds, full blast at 10 seconds,
+     *            full level until 15, faded out at 20, sleep until 25, fade to end at 30
+     * song3 : starts muted, fades in from 15, full at 20, until 25, fade to end level
+     */
+
+    if (i == 1)
+    {
+      /* first song gets special treatment for end style */
+      env_register_cp (channel_in->volenv,  0.0, 1.0);
+    }
+    else
+    {
+      env_register_cp (channel_in->volenv,  0.0            , 0.0000001); /* start muted */
+      env_register_cp (channel_in->volenv,  i * 10.0 - 15.0, 0.0000001); /* start fade in */
+      env_register_cp (channel_in->volenv,  i * 10.0 - 10.0, 1.0);
+    }
+    env_register_cp (channel_in->volenv,  i * 10.0 -  5.0, 1.0); /* end of full level */
+
+    if (i != num_channels)
+    {
+      env_register_cp (channel_in->volenv,  i * 10.0         , 0.0000001); /* fade to black */
+      env_register_cp (channel_in->volenv,  num_channels * 10.0 - 5.0, 0.0000001); /* start fade in */
+    }   
+    env_register_cp (channel_in->volenv,  num_channels * 10.0      , 1.0 / num_channels); /* to end level */
+  }
+
+  /* sleep a few seconds doesn't seem to help anyway */
+
+  printf ("Sleeping a few seconds ...\n");
+  sleep (2);
+  printf ("Waking up ...\n");
+
+  
+  /* start playing */
+  gst_element_set_state(main_bin, GST_STATE_PLAYING);
+
+  playing = TRUE;
+
+  while (playing) {
+    gst_bin_iterate(GST_BIN(main_bin));
+  }
+
+  /* stop the bin */
+  gst_element_set_state(main_bin, GST_STATE_NULL);
+
+  while (input_channels)
+  {
+    destroy_input_channel (input_channels->data);
+    input_channels = g_list_next (input_channels);
+  }
+  g_list_free (input_channels);
+  
+  gst_object_destroy(GST_OBJECT(audiosink));
+
+  gst_object_destroy(GST_OBJECT(main_bin));
+
+  exit(0);
+}
+
+input_channel_t*
+create_input_channel (int id, char* location)
+{
+  /* create an input channel, reading from location
+   * return a pointer to the channel
+   * return NULL if failed
+   */
+
+  input_channel_t *channel;
+  
+  char buffer[20];             /* hold the names */
+
+  GstAutoplug *autoplug;
+  GstCaps *srccaps;
+  GstElement *new_element;  
+
+#ifdef DEBUG
+  printf ("DEBUG : c_i_p : creating channel with id %d for file %s\n",
+                 id, location);
+#endif
+  
+  /* allocate channel */
+
+  channel = (input_channel_t *) malloc (sizeof (input_channel_t));
+  if (channel == NULL)
+  {
+    printf ("create_input_channel : could not allocate memory for channel !\n");
+    return NULL;
+  }
+
+  /* create channel */
+
+#ifdef DEBUG
+  printf ("DEBUG : c_i_p : creating pipeline\n");
+#endif
+
+  channel->pipe = gst_bin_new ("pipeline");
+  g_assert(channel->pipe != NULL);    
+    
+  /* create elements */
+
+#ifdef DEBUG
+  printf ("DEBUG : c_i_p : creating disksrc\n");
+#endif
+
+  sprintf (buffer, "disksrc%d", id);
+  channel->disksrc = gst_elementfactory_make ("disksrc", buffer);
+  g_assert(channel->disksrc != NULL);    
+  
+  gtk_object_set(GTK_OBJECT(channel->disksrc),"location", location, NULL);
+
+  /* add disksrc to the bin before autoplug */
+  gst_bin_add(GST_BIN(channel->pipe), channel->disksrc);
+
+  /* connect signal to eos of disksrc */
+  gtk_signal_connect(GTK_OBJECT(channel->disksrc),"eos",
+                     GTK_SIGNAL_FUNC(eos),NULL);
+
+
+#ifdef DEBUG
+  printf ("DEBUG : c_i_p : creating volume envelope\n");
+#endif
+
+  sprintf (buffer, "volenv%d", id);
+  channel->volenv = gst_elementfactory_make ("volenv", buffer);
+  g_assert(channel->volenv != NULL);    
+
+  /* autoplug the pipe */
+
+#ifdef DEBUG
+  printf ("DEBUG : c_i_p : getting srccaps\n");
+#endif
+
+  srccaps = gst_play_typefind (GST_BIN (channel->pipe), channel->disksrc);
+
+  if (!srccaps) {
+    g_print ("could not autoplug, unknown media type...\n");
+    exit (-1);
+  }
+
+#ifdef DEBUG
+  printf ("DEBUG : c_i_p : creating autoplug\n");
+#endif
+
+  autoplug = gst_autoplugfactory_make ("static");
+  g_assert (autoplug != NULL);
+
+#ifdef DEBUG
+  printf ("DEBUG : c_i_p : autoplugging\n");
+#endif
+  new_element = gst_autoplug_to_caps (autoplug, srccaps, 
+                                       gst_caps_new ("audio", "audio/raw", NULL), NULL);
+  if (!new_element) {
+    g_print ("could not autoplug, no suitable codecs found...\n");
+    exit (-1);
+  }
+  
+  gst_bin_add (GST_BIN(channel->pipe), channel->volenv);
+  gst_bin_add (GST_BIN (channel->pipe), new_element);
+  
+  gst_element_connect (channel->disksrc, "src", new_element, "sink");
+  gst_element_connect (new_element, "src_00", channel->volenv, "sink");
+  
+  /* add a ghost pad */
+  sprintf (buffer, "channel%d", id);
+  gst_element_add_ghost_pad (channel->pipe,
+                             gst_element_get_pad (channel->volenv, "src"), buffer);
+
+   
+#ifdef DEBUG
+  printf ("DEBUG : c_i_p : end function\n");
+#endif
+
+  return channel;
+}
+
+void
+destroy_input_channel (input_channel_t *channel)
+{
+  /* 
+   * destroy an input channel
+   */
+   
+#ifdef DEBUG
+  printf ("DEBUG : d_i_p : start\n");
+#endif
+
+  /* destroy elements */
+
+  gst_object_destroy (GST_OBJECT (channel->pipe));
+
+  free (channel);
+}
+
+void env_register_cp (GstElement *volenv, double cp_time, double cp_level)
+{
+  char buffer[30];
+
+  sprintf (buffer, "%f:%f", cp_time, cp_level);
+  gtk_object_set(GTK_OBJECT(volenv), "controlpoint", buffer, NULL);
+
+}
+
diff --git a/tests/old/examples/mixer/mixer.h b/tests/old/examples/mixer/mixer.h
new file mode 100644 (file)
index 0000000..b967141
--- /dev/null
@@ -0,0 +1,12 @@
+/*
+ * mixer.h header file
+ * thomas@apestaart.org
+ */
+
+typedef struct 
+{
+  GstElement *pipe, *disksrc, *volenv;
+  
+  char *location;
+  int channel_id;
+} input_channel_t;
index 75e5c78ce65ffadd1cf4c39a09d7818e2c1c9f92..a2dad208cf5f302f3b4b404b5f034780e9de173d 100644 (file)
@@ -335,23 +335,17 @@ gst_example_get_arg (GtkObject *object,GtkArg *arg,guint id)
 /* This is the entry into the plugin itself.  When the plugin loads,
  * this function is called to register everything that the plugin provides.
  */
-GstPlugin*
-plugin_init (GModule *module)
+static gboolean
+plugin_init (GModule *module, GstPlugin *plugin)
 {
-  GstPlugin *plugin;
   GstElementFactory *factory;
 
-  /* First we try to create a new Plugin structure. */
-  plugin = gst_plugin_new("example");
-  /* If we get a NULL back, chances are we're already loaded. */
-  g_return_val_if_fail(plugin != NULL, NULL);
-
   /* We need to create an ElementFactory for each element we provide.
    * This consists of the name of the element, the GtkType identifier,
    * and a pointer to the details structure at the top of the file.
    */
   factory = gst_elementfactory_new("example", GST_TYPE_EXAMPLE, &example_details);
-  g_return_val_if_fail(factory != NULL, NULL);
+  g_return_val_if_fail(factory != NULL, FALSE);
 
   /* The pad templates can be easily generated from the factories above,
    * and then added to the list of padtemplates for the elementfactory.
@@ -367,10 +361,27 @@ plugin_init (GModule *module)
   /* The very last thing is to register the elementfactory with the plugin. */
   gst_plugin_add_factory (plugin, factory);
 
-  /* Now we can return the pointer to the newly created Plugin object. */
-  return plugin;
+  /* Now we can return successfully. */
+  return TRUE;
 
   /* At this point, the GStreamer core registers the plugin, its
    * elementfactories, padtemplates, etc., for use in you application.
    */
 }
+
+/* This structure describes the plugin to the system for dynamically loading
+ * plugins, so that the version number and name can be checked in a uniform
+ * way.
+ *
+ * The symbol pointing to this structure is the only symbol looked up when
+ * loading the plugin.
+ */
+GstPluginDesc plugin_desc = {
+  GST_VERSION_MAJOR, /* The major version of the core that this was built with */
+  GST_VERSION_MINOR, /* The minor version of the core that this was built with */
+  "example",         /* The name of the plugin.  This must be unique: plugins with
+                     * the same name will be assumed to be identical, and only
+                     * one will be loaded. */
+  plugin_init        /* Pointer to the initialisation function for the plugin. */
+};
+
index 086649111850ca2832a8f2acb942e9344f71392c..027440a9368916f066692f6333b288b2604dd149 100644 (file)
@@ -4,53 +4,87 @@
 GstPad *srcpad, *sinkpad;
 GstPad *srcpadtempl, *sinkpadtempl;
 
-static GstPadFactory src_factory = {
-  "src",
-  GST_PAD_FACTORY_SRC,
-  GST_PAD_FACTORY_ALWAYS,
-  GST_PAD_FACTORY_CAPS(
-  "test_src",
-    "video/raw",
-    "height",    GST_PROPS_INT_RANGE (16, 4096)
-  ),
-  NULL,
-};
-
-static GstPadFactory sink_factory = {
-  "sink",
-  GST_PAD_FACTORY_SINK,
-  GST_PAD_FACTORY_ALWAYS,
-  GST_PAD_FACTORY_CAPS(
-  "test_sink",
-    "video/raw",
-    "height",    GST_PROPS_INT_RANGE (16, 8192)
-  ),
-  NULL,
-};
-
-static GstCapsFactory sink_caps = {
-  "sink_caps",
-  "video/raw",
-  "height",     GST_PROPS_INT (3000),
-  NULL
-};
-
-static GstCapsFactory src_caps = {
-  "src_caps",
-  "video/raw",
-  "height",     GST_PROPS_INT (3000),
-  NULL
-};
+static GstPadTemplate*
+src_template_factory (void)
+{
+  static GstPadTemplate *templ = NULL;
+
+  if (!templ) {
+    templ = gst_padtemplate_new (
+      "src",
+      GST_PAD_SRC,
+      GST_PAD_ALWAYS,
+      gst_caps_new (
+        "test_src",
+        "video/raw",
+       gst_props_new (
+          "height",    GST_PROPS_INT_RANGE (16, 4096),
+         NULL)),
+      NULL);
+  }
+  return templ;
+}
 
-static GstPadTemplate *srctempl, *sinktempl;
-static GstCaps *srccaps, *sinkcaps;
+static GstPadTemplate*
+sink_template_factory (void)
+{
+  static GstPadTemplate *templ = NULL;
+
+  if (!templ) {
+    templ = gst_padtemplate_new (
+      "sink",
+      GST_PAD_SINK,
+      GST_PAD_ALWAYS,
+      gst_caps_new (
+        "test_sink",
+        "video/raw",
+       gst_props_new (
+           "height",    GST_PROPS_INT_RANGE (16, 8192),
+          NULL)),
+      NULL);
+  }
+  return templ;
+}
+
+static GstCaps*
+sink_caps_factory (void)
+{
+  static GstCaps *caps = NULL;
+
+  if (!caps) {
+    caps = gst_caps_new (
+      "sink_caps",
+      "video/raw",
+      gst_props_new (
+        "height",     GST_PROPS_INT (3000),
+        NULL));
+  }
+  return caps;
+}
+
+static GstCaps*
+src_caps_factory (void)
+{
+  static GstCaps *caps = NULL;
+
+  if (!caps) {
+    caps = gst_caps_new (
+      "src_caps",
+      "video/raw",
+      gst_props_new (
+        "height",     GST_PROPS_INT (3000),
+       NULL));
+  }
+  return caps;
+}
 
 static GstPadNegotiateReturn
-negotiate_src (GstPad *pad, GstCaps **caps, gint counter)
+negotiate_src (GstPad *pad, GstCaps **caps, gpointer *data)
 {
   g_print (">");
 
-  if (counter == 0) {
+  if (*data == NULL) {
+    *data = GINT_TO_POINTER (TRUE);
     *caps = NULL;
     return GST_PAD_NEGOTIATE_TRY;
   }
@@ -61,10 +95,11 @@ negotiate_src (GstPad *pad, GstCaps **caps, gint counter)
 }
 
 static GstPadNegotiateReturn
-negotiate_sink (GstPad *pad, GstCaps **caps, gint counter)
+negotiate_sink (GstPad *pad, GstCaps **caps, gpointer *data)
 {
   g_print ("<");
-  if (counter == 0) {
+  if (*data == NULL) {
+    *data = GINT_TO_POINTER (TRUE);
     *caps = NULL;
     return GST_PAD_NEGOTIATE_TRY;
   }
@@ -74,6 +109,9 @@ negotiate_sink (GstPad *pad, GstCaps **caps, gint counter)
   return GST_PAD_NEGOTIATE_FAIL;
 }
 
+static GstPadTemplate *srctempl, *sinktempl;
+static GstCaps *srccaps, *sinkcaps;
+
 static gboolean
 perform_check  (void)
 {
@@ -121,14 +159,14 @@ main (int argc, char *argv[])
   srcpad = gst_pad_new ("src", GST_PAD_SRC);
   sinkpad = gst_pad_new ("sink", GST_PAD_SINK);
 
-  srctempl = gst_padtemplate_new (&src_factory);
-  sinktempl = gst_padtemplate_new (&sink_factory);
+  srctempl = src_template_factory ();
+  sinktempl = sink_template_factory ();
 
-  srcpadtempl = gst_pad_new_from_template (srctempl, "src");
-  sinkpadtempl = gst_pad_new_from_template (sinktempl, "sink");
+  srcpadtempl = gst_pad_new_from_template (src_template_factory (), "src");
+  sinkpadtempl = gst_pad_new_from_template (sink_template_factory (), "sink");
 
-  sinkcaps  = gst_caps_register (&sink_caps);
-  srccaps  = gst_caps_register (&src_caps);
+  sinkcaps  = sink_caps_factory ();
+  srccaps  = src_caps_factory ();
 
   g_print ("*** compatible caps/templates ***\n");
 
index df26338d1fc300814d0eeaadb20b3ea1c727bf39..83dd8d4648032470fd3fce9853f04c7dafa5e3df 100644 (file)
 
 GstPad *srcpad, *sinkpad;
 GstPad *srcconvpad, *sinkconvpad;
-GstPad *srcpadtempl, *sinkpadtempl;
-GstPad *srcconvtempl, *sinkconvtempl;
+GstPadTemplate *srcpadtempl, *sinkpadtempl;
+GstPadTemplate *srcconvtempl, *sinkconvtempl;
 
 gint converter_in = -1, converter_out = -1;
 
-static GstPadFactory src_factory = {
-  "src",
-  GST_PAD_FACTORY_SRC,
-  GST_PAD_FACTORY_ALWAYS,
-  GST_PAD_FACTORY_CAPS(
-  "test_src",
-    "audio/raw",
-    "rate",    GST_PROPS_INT_RANGE (16, 20000)
-  ),
-  NULL,
-};
-
-static GstPadFactory src_conv_factory = {
-  "src",
-  GST_PAD_FACTORY_SRC,
-  GST_PAD_FACTORY_ALWAYS,
-  GST_PAD_FACTORY_CAPS(
-  "test_src",
-    "audio/raw",
-    "rate",    GST_PROPS_INT_RANGE (16, 20000)
-  ),
-  NULL,
-};
-
-static GstPadFactory sink_conv_factory = {
-  "src",
-  GST_PAD_FACTORY_SINK,
-  GST_PAD_FACTORY_ALWAYS,
-  GST_PAD_FACTORY_CAPS(
-  "test_src",
-    "audio/raw",
-    "rate",    GST_PROPS_INT_RANGE (16, 20000)
-  ),
-  NULL,
-};
-
-static GstPadFactory sink_factory = {
-  "sink",
-  GST_PAD_FACTORY_SINK,
-  GST_PAD_FACTORY_ALWAYS,
-  GST_PAD_FACTORY_CAPS(
-  "test_sink",
-    "audio/raw",
-    "rate",    GST_PROPS_INT_RANGE (16, 20000)
-  ),
-  NULL,
-};
-
-static GstCapsFactory sink_caps = {
-  "sink_caps",
-  "audio/raw",
-  "rate",     GST_PROPS_INT (6000),
-  NULL
-};
-
-static GstCapsFactory src_caps = {
-  "src_caps",
-  "audio/raw",
-  "rate",     GST_PROPS_INT (3000),
-  NULL
-};
+static GstPadTemplate*
+src_factory (void)
+{
+  return 
+    gst_padtemplate_new (
+      "src",
+      GST_PAD_SRC,
+      GST_PAD_ALWAYS,
+      gst_caps_new (
+        "test_src",
+        "audio/raw",
+       gst_props_new (
+          "rate",    GST_PROPS_INT_RANGE (16, 20000),
+         NULL)),
+      NULL);
+}
+
+static GstPadTemplate*
+src_conv_factory (void)
+{
+  return 
+    gst_padtemplate_new (
+      "src",
+      GST_PAD_SRC,
+      GST_PAD_ALWAYS,
+      gst_caps_new (
+        "test_src",
+        "audio/raw",
+       gst_props_new (
+          "rate",    GST_PROPS_INT_RANGE (16, 20000),
+         NULL)),
+      NULL);
+}
+
+static GstPadTemplate*
+sink_conv_factory (void)
+{
+  return 
+    gst_padtemplate_new (
+      "src",
+      GST_PAD_SINK,
+      GST_PAD_ALWAYS,
+      gst_caps_new (
+        "test_src",
+        "audio/raw",
+       gst_props_new (
+          "rate",    GST_PROPS_INT_RANGE (16, 20000),
+         NULL)),
+      NULL);
+}
+
+static GstPadTemplate*
+sink_factory (void)
+{
+  return 
+    gst_padtemplate_new (
+      "sink",
+      GST_PAD_SINK,
+      GST_PAD_ALWAYS,
+      gst_caps_new (
+        "test_sink",
+        "audio/raw",
+       gst_props_new (
+          "rate",    GST_PROPS_INT_RANGE (16, 20000),
+         NULL)),
+      NULL);
+}
+
+static GstCaps*
+sink_caps (void)
+{
+  return 
+    gst_caps_new (
+      "sink_caps",
+      "audio/raw",
+      gst_props_new (
+        "rate",     GST_PROPS_INT (6000),
+       NULL));
+}
+
+static GstCaps*
+src_caps (void)
+{
+  return 
+    gst_caps_new (
+      "src_caps",
+      "audio/raw",
+      gst_props_new (
+        "rate",     GST_PROPS_INT (3000),
+       NULL));
+}
 
 static GstPadTemplate *srctempl, *sinktempl;
 static GstCaps *srccaps, *sinkcaps;
 
 static GstPadNegotiateReturn
-negotiate_src (GstPad *pad, GstCaps **caps, gint counter)
+negotiate_src (GstPad *pad, GstCaps **caps, gpointer *data)
 {
   g_print (">");
 
-  if (counter == 0) {
+  if (data == NULL) {
     *caps = NULL;
     return GST_PAD_NEGOTIATE_TRY;
   }
@@ -91,10 +121,10 @@ negotiate_src (GstPad *pad, GstCaps **caps, gint counter)
 }
 
 static GstPadNegotiateReturn
-negotiate_sink (GstPad *pad, GstCaps **caps, gint counter)
+negotiate_sink (GstPad *pad, GstCaps **caps, gpointer *data)
 {
   g_print ("<");
-  if (counter == 0) {
+  if (data == NULL) {
     *caps = NULL;
     return GST_PAD_NEGOTIATE_TRY;
   }
@@ -114,21 +144,22 @@ main (int argc, char *argv[])
   
   gst_init (&argc, &argv);
 
-  srctempl = gst_padtemplate_new (&src_factory);
-  sinktempl = gst_padtemplate_new (&sink_factory);
+  srctempl = src_factory ();
+  sinktempl = sink_factory ();
   srcpad = gst_pad_new_from_template (srctempl, "src");
   sinkpad = gst_pad_new_from_template (sinktempl, "sink");
 
-  srcconvtempl = gst_padtemplate_new (&src_conv_factory);
-  sinkconvtempl = gst_padtemplate_new (&sink_conv_factory);
+  srcconvtempl = src_conv_factory ();
+  sinkconvtempl = sink_conv_factory ();
   srcconvpad = gst_pad_new_from_template (srcconvtempl, "src");
   sinkconvpad = gst_pad_new_from_template (sinkconvtempl, "sink");
 
   gst_pad_set_negotiate_function (srcconvpad, negotiate_src);
   gst_pad_set_negotiate_function (sinkconvpad, negotiate_sink);
 
-  sinkcaps  = gst_caps_register (&sink_caps);
-  srccaps  = gst_caps_register (&src_caps);
+  sinkcaps  = sink_caps ();
+  srccaps  = src_caps ();
+
   result = gst_pad_set_caps (srcpad, srccaps);
   g_print ("set caps on src: %d\n", result);
   g_print ("initial converter status: %d %d\n", converter_in, converter_out);
index 0532c76956ca4cd91d7589744eeba07fe1c0b30d..8b3ebb32ea66c53767a099ebc1b354f8262bda89 100644 (file)
 
 GstPad *srcpad, *sinkpad;
 GstPad *srcconvpad, *sinkconvpad;
-GstPad *srcpadtempl, *sinkpadtempl;
-GstPad *srcconvtempl, *sinkconvtempl;
+GstPadTemplate *srcpadtempl, *sinkpadtempl;
+GstPadTemplate *srcconvtempl, *sinkconvtempl;
 
 gint converter_in = -1, converter_out = -1;
 gint target_rate = 2000;
 
-static GstPadFactory src_factory = {
-  "src",
-  GST_PAD_FACTORY_SRC,
-  GST_PAD_FACTORY_ALWAYS,
-  GST_PAD_FACTORY_CAPS(
-  "test_src",
-    "audio/raw",
-    "rate",    GST_PROPS_INT_RANGE (16, 20000)
-  ),
-  NULL,
-};
-
-static GstPadFactory src_conv_factory = {
-  "src",
-  GST_PAD_FACTORY_SRC,
-  GST_PAD_FACTORY_ALWAYS,
-  GST_PAD_FACTORY_CAPS(
-  "test_src",
-    "audio/raw",
-    "rate",    GST_PROPS_INT_RANGE (16, 20000)
-  ),
-  NULL,
-};
-
-static GstPadFactory sink_conv_factory = {
-  "src",
-  GST_PAD_FACTORY_SINK,
-  GST_PAD_FACTORY_ALWAYS,
-  GST_PAD_FACTORY_CAPS(
-  "test_src",
-    "audio/raw",
-    "rate",    GST_PROPS_INT_RANGE (16, 20000)
-  ),
-  NULL,
-};
-
-static GstPadFactory sink_factory = {
-  "sink",
-  GST_PAD_FACTORY_SINK,
-  GST_PAD_FACTORY_ALWAYS,
-  GST_PAD_FACTORY_CAPS(
-  "test_sink",
-    "audio/raw",
-    "rate",    GST_PROPS_INT_RANGE (16, 20000)
-  ),
-  NULL,
-};
-
-static GstCapsFactory sink_caps = {
-  "sink_caps",
-  "audio/raw",
-  "rate",     GST_PROPS_INT (6000),
-  NULL
-};
-
-static GstCapsFactory src_caps = {
-  "src_caps",
-  "audio/raw",
-  "rate",     GST_PROPS_INT (3000),
-  NULL
-};
+static GstPadTemplate*
+src_factory (void)
+{
+  return 
+    gst_padtemplate_new (
+      "src",
+      GST_PAD_SRC,
+      GST_PAD_ALWAYS,
+      gst_caps_new (
+        "test_src",
+        "audio/raw",
+       gst_props_new (
+          "rate",    GST_PROPS_INT_RANGE (16, 20000),
+         NULL)),
+      NULL);
+}
+
+static GstPadTemplate*
+src_conv_factory (void)
+{
+  return 
+    gst_padtemplate_new (
+      "src",
+      GST_PAD_SRC,
+      GST_PAD_ALWAYS,
+      gst_caps_new (
+        "test_src",
+        "audio/raw",
+       gst_props_new (
+          "rate",    GST_PROPS_INT_RANGE (16, 20000),
+         NULL)),
+      NULL);
+}
+
+static GstPadTemplate*
+sink_conv_factory (void)
+{
+  return 
+    gst_padtemplate_new (
+      "src",
+      GST_PAD_SINK,
+      GST_PAD_ALWAYS,
+      gst_caps_new (
+        "test_src",
+        "audio/raw",
+       gst_props_new (
+          "rate",    GST_PROPS_INT_RANGE (16, 20000),
+         NULL)),
+      NULL);
+}
+
+static GstPadTemplate*
+sink_factory (void)
+{
+  return 
+    gst_padtemplate_new (
+      "sink",
+      GST_PAD_SINK,
+      GST_PAD_ALWAYS,
+      gst_caps_new (
+        "test_sink",
+        "audio/raw",
+       gst_props_new (
+          "rate",    GST_PROPS_INT_RANGE (16, 20000),
+         NULL)),
+      NULL);
+}
+
+static GstCaps*
+sink_caps (void)
+{
+  return 
+    gst_caps_new (
+      "sink_caps",
+      "audio/raw",
+      gst_props_new (
+        "rate",     GST_PROPS_INT (6000),
+       NULL));
+}
+
+static GstCaps*
+src_caps (void)
+{
+  return 
+    gst_caps_new (
+      "src_caps",
+      "audio/raw",
+      gst_props_new (
+        "rate",     GST_PROPS_INT (3000),
+       NULL));
+}
 
 static GstPadTemplate *srctempl, *sinktempl;
 static GstCaps *srccaps, *sinkcaps;
 
 static GstPadNegotiateReturn
-converter_negotiate_src (GstPad *pad, GstCaps **caps, gint counter)
+converter_negotiate_src (GstPad *pad, GstCaps **caps, gpointer *data)
 {
   g_print (">");
 
-  if (counter == 0) {
+  if (*data == NULL) {
     *caps = NULL;
     return GST_PAD_NEGOTIATE_TRY;
   }
@@ -92,19 +122,19 @@ converter_negotiate_src (GstPad *pad, GstCaps **caps, gint counter)
 }
 
 static GstPadNegotiateReturn
-converter_negotiate_sink (GstPad *pad, GstCaps **caps, gint counter)
+converter_negotiate_sink (GstPad *pad, GstCaps **caps, gpointer *data)
 {
   g_print ("<");
-  if (counter == 0) {
+  if (*data == NULL) {
     *caps = GST_PAD_CAPS (srcconvpad);
     return GST_PAD_NEGOTIATE_TRY;
   }
   if (*caps) {
     converter_in = gst_caps_get_int (*caps, "rate");
 
-    if (counter == 1) {
+    if (*data == 1) {
       converter_out = gst_caps_get_int (*caps, "rate");
-      return gst_pad_negotiate_proxy (pad, srcconvpad, caps, counter);
+      return gst_pad_negotiate_proxy (pad, srcconvpad, caps);
     }
     return GST_PAD_NEGOTIATE_AGREE;
   }
@@ -113,11 +143,11 @@ converter_negotiate_sink (GstPad *pad, GstCaps **caps, gint counter)
 }
 
 static GstPadNegotiateReturn
-target_negotiate_sink (GstPad *pad, GstCaps **caps, gint counter)
+target_negotiate_sink (GstPad *pad, GstCaps **caps, gpointer *data)
 {
   g_print ("{");
-  if (counter == 0) {
-    *caps = gst_caps_new_with_props (
+  if (*data == NULL) {
+    *caps = gst_caps_new (
                    "target_caps",
                    "audio/raw",
                    gst_props_new (
@@ -143,13 +173,13 @@ main (int argc, char *argv[])
   
   gst_init (&argc, &argv);
 
-  srctempl = gst_padtemplate_new (&src_factory);
-  sinktempl = gst_padtemplate_new (&sink_factory);
+  srctempl = src_factory ();
+  sinktempl = sink_factory ();
   srcpad = gst_pad_new_from_template (srctempl, "src");
   sinkpad = gst_pad_new_from_template (sinktempl, "sink");
 
-  srcconvtempl = gst_padtemplate_new (&src_conv_factory);
-  sinkconvtempl = gst_padtemplate_new (&sink_conv_factory);
+  srcconvtempl = src_conv_factory ();
+  sinkconvtempl = sink_conv_factory ();
   srcconvpad = gst_pad_new_from_template (srcconvtempl, "csrc");
   sinkconvpad = gst_pad_new_from_template (sinkconvtempl, "csink");
 
@@ -157,8 +187,8 @@ main (int argc, char *argv[])
   gst_pad_set_negotiate_function (sinkconvpad, converter_negotiate_sink);
   gst_pad_set_negotiate_function (sinkpad, target_negotiate_sink);
 
-  sinkcaps  = gst_caps_register (&sink_caps);
-  srccaps  = gst_caps_register (&src_caps);
+  sinkcaps  = sink_caps ();
+  srccaps  = src_caps ();
 
   g_print ("-------)      (-----------)       (-----   \n");
   g_print ("       !      ! converter !       !        \n");
index e3959309e92fc441e1586e723c9a031460a417b7..343e08c10d59a9c62f8963a627ec5885f328fe42 100644 (file)
@@ -4,36 +4,51 @@
 GstPad *srcconvpad, *sinkconvpad;
 GstPadTemplate *srcconvtempl, *sinkconvtempl;
 
-static GstPadFactory src_conv_factory = {
-  "src",
-  GST_PAD_FACTORY_SRC,
-  GST_PAD_FACTORY_ALWAYS,
-  GST_PAD_FACTORY_CAPS(
-  "test_src",
-    "audio/raw",
-    "rate",    GST_PROPS_INT_RANGE (16, 20000)
-  ),
-  NULL,
-};
-
-static GstPadFactory sink_conv_factory = {
-  "src",
-  GST_PAD_FACTORY_SINK,
-  GST_PAD_FACTORY_ALWAYS,
-  GST_PAD_FACTORY_CAPS(
-  "test_src",
-    "audio/raw",
-    "rate",    GST_PROPS_INT_RANGE (16, 20000)
-  ),
-  NULL,
-};
-
-static GstCapsFactory src_caps = {
-  "src_caps",
-  "audio/raw",
-  "rate",     GST_PROPS_INT (3000),
-  NULL
-};
+static GstPadTemplate*
+src_conv_factory (void)
+{
+  return 
+    gst_padtemplate_new (
+      "src",
+      GST_PAD_SRC,
+      GST_PAD_ALWAYS,
+      gst_caps_new (
+        "test_src",
+        "audio/raw",
+       gst_props_new (
+          "rate",    GST_PROPS_INT_RANGE (16, 20000),
+         NULL)),
+      NULL);
+}
+
+static GstPadTemplate*
+sink_conv_factory (void)
+{
+  return 
+    gst_padtemplate_new (
+      "sink",
+      GST_PAD_SINK,
+      GST_PAD_ALWAYS,
+      gst_caps_new (
+        "test_src",
+        "audio/raw",
+       gst_props_new (
+          "rate",    GST_PROPS_INT_RANGE (16, 20000),
+         NULL)),
+      NULL);
+}
+
+static GstCaps*
+src_caps (void)
+{
+  return
+    gst_caps_new (
+      "src_caps",
+      "audio/raw",
+      gst_props_new (
+        "rate",     GST_PROPS_INT (3000),
+       NULL));
+}
 
 static GstCaps *srccaps, *sinkcaps;
 
@@ -41,14 +56,14 @@ static gint src_rate = 140;
 static gint sink_rate = 100;
 
 static GstPadNegotiateReturn
-negotiate_src (GstPad *pad, GstCaps **caps, gint counter)
+negotiate_src (GstPad *pad, GstCaps **caps, gpointer *data)
 {
   g_print (">(%d:%d)", src_rate, (*caps)->refcount);
   src_rate++;
 
-  if (counter == 0 || caps == NULL) {
+  if (*data == NULL || caps == NULL) {
     g_print ("*");
-    *caps = gst_caps_new_with_props (
+    *caps = gst_caps_new (
                    "src_caps",
                    "audio/raw",
                    gst_props_new (
@@ -77,15 +92,15 @@ negotiate_src (GstPad *pad, GstCaps **caps, gint counter)
 }
 
 static GstPadNegotiateReturn
-negotiate_sink (GstPad *pad, GstCaps **caps, gint counter)
+negotiate_sink (GstPad *pad, GstCaps **caps, gpointer *data)
 {
 
   g_print ("<(%d:%d:%p)", sink_rate, (*caps)->refcount, *caps);
   sink_rate++;
 
-  if (counter == 0 || *caps == NULL) {
+  if (*data == NULL || *caps == NULL) {
     g_print ("*");
-    *caps = gst_caps_new_with_props (
+    *caps = gst_caps_new (
                    "sink_caps",
                    "audio/raw",
                    gst_props_new (
@@ -126,15 +141,15 @@ main (int argc, char *argv[])
 
   g_mem_chunk_info();
 
-  srcconvtempl = gst_padtemplate_new (&src_conv_factory);
-  sinkconvtempl = gst_padtemplate_new (&sink_conv_factory);
+  srcconvtempl = src_conv_factory ();
+  sinkconvtempl = sink_conv_factory ();
   srcconvpad = gst_pad_new_from_template (srcconvtempl, "src");
   sinkconvpad = gst_pad_new_from_template (sinkconvtempl, "sink");
 
   gst_pad_set_negotiate_function (srcconvpad, negotiate_src);
   gst_pad_set_negotiate_function (sinkconvpad, negotiate_sink);
 
-  srccaps  = gst_caps_register (&src_caps);
+  srccaps  = src_caps ();
   sinkcaps  = gst_caps_copy (srccaps);
 
   g_print ("The wild goose chase...\n");
index 3fcb2105567e9966c457c65dfae6f8fec6be1962..a95f465d0177d0ad117db538d575596300863b81 100644 (file)
@@ -1,55 +1,93 @@
 #include <gst/gst.h>
 
-static GstCapsFactory mpeg2dec_sink_caps = {
-  "mpeg2deccaps",
-  "video/mpeg",
-  "mpegtype", GST_PROPS_LIST (
-                     GST_PROPS_INT(1),
-                     GST_PROPS_INT(2)
-               ),
-  NULL
-};
-
-static GstCapsFactory mpeg2dec_src_caps = {
-  "name",
-  "video/raw",
-  "fourcc",    GST_PROPS_LIST (
-                        GST_PROPS_FOURCC ('Y','V','1','2'), 
-                       GST_PROPS_FOURCC_INT (0x56595559)
-                       ),
-  "width",     GST_PROPS_INT_RANGE (16, 4096),
-  "height",    GST_PROPS_INT_RANGE (16, 4096),
-  NULL
-};
+static GstCaps*
+mpeg2dec_sink_caps (void)
+{
+  static GstCaps *caps;
 
-static GstCapsFactory raw_sink_caps = {
-  NULL
-};
+  if (!caps) {
+    caps = gst_caps_new (
+      "mpeg2deccaps",
+      "video/mpeg",
+      gst_props_new (
+        "mpegtype", GST_PROPS_LIST (
+                      GST_PROPS_INT(1),
+                      GST_PROPS_INT(2)
+                   ),
+       NULL));
+  }
+  return caps;
+}
 
-static GstPadFactory pad_caps = {
-  "src",
-  GST_PAD_FACTORY_SRC,
-  GST_PAD_FACTORY_ALWAYS,
-  GST_PAD_FACTORY_CAPS (
-    "videocaps",
+GST_CAPS_FACTORY (mpeg2dec_src_caps,
+  GST_CAPS_NEW (
+    "mpeg2dec_src_caps",
     "video/raw",
-    "fourcc",  GST_PROPS_LIST (
-                        GST_PROPS_FOURCC_INT (0x32315659),
-                        GST_PROPS_FOURCC ('Y','U','Y','V') 
-                       ),
-    "height",  GST_PROPS_INT_RANGE (16, 4096)
+      "fourcc",   GST_PROPS_LIST (
+                    GST_PROPS_FOURCC ( GST_MAKE_FOURCC ('Y','V','1','2')), 
+                   GST_PROPS_FOURCC (0x56595559)
+                 ),
+      "width",   GST_PROPS_INT_RANGE (16, 4096),
+      "height",          GST_PROPS_INT_RANGE (16, 4096)
   ),
-  GST_PAD_FACTORY_CAPS (
-    "videocaps2",
+  GST_CAPS_NEW(
+    "mpeg2dec_src_caps",
     "video/raw",
-    "fourcc",  GST_PROPS_LIST (
-                        GST_PROPS_FOURCC_INT (0x32315659)
+      "foo",   GST_PROPS_BOOLEAN (TRUE)
+  )
+)
+
+static GstPadTemplate*
+pad_caps (void)
+{
+  static GstPadTemplate *template = NULL;
+
+  if (!template) {
+    template = gst_padtemplate_new (
+      "src",
+      GST_PAD_SRC,
+      GST_PAD_ALWAYS,
+      gst_caps_new (
+        "videocaps",
+        "video/raw",
+       gst_props_new (
+          "fourcc",    GST_PROPS_LIST (
+                          GST_PROPS_FOURCC (0x32315659),
+                          GST_PROPS_FOURCC (GST_MAKE_FOURCC ('Y','U','Y','V')) 
                        ),
-    "height",  GST_PROPS_INT_RANGE (16, 256)
-  ),
-  NULL
-};
+          "height",    GST_PROPS_INT_RANGE (16, 4096),
+         NULL)),
+      gst_caps_new (
+        "videocaps2",
+        "video/raw",
+       gst_props_new (
+          "fourcc",    GST_PROPS_LIST (
+                          GST_PROPS_FOURCC (0x32315659)
+                       ),
+          "height",    GST_PROPS_INT_RANGE (16, 256),
+         NULL)),
+      NULL);
+  }
+  return template;
+}
 
+GST_PADTEMPLATE_FACTORY (testtempl,
+  "src",
+  GST_PAD_SRC,
+  GST_PAD_ALWAYS,
+  GST_CAPS_NEW (
+    "mycaps",
+    "audio/raw",
+      "format", GST_PROPS_INT (55),
+      "foo",   GST_PROPS_STRING ("bar")
+  ),
+  GST_CAPS_NEW (
+    "mycaps2",
+    "audio/float",
+      "format", GST_PROPS_INT (7),
+      "baz",   GST_PROPS_STRING ("toe")
+  )
+)
 
 static GstCaps *sinkcaps = NULL, 
                *rawcaps = NULL;
@@ -58,27 +96,29 @@ static GstPadTemplate *temp;
 
 int main(int argc,char *argv[]) 
 {
-  gboolean testret;
   xmlDocPtr doc;
   xmlNodePtr parent;
 
   doc = xmlNewDoc ("1.0");
   doc->xmlRootNode = xmlNewDocNode (doc, NULL, "Capabilities", NULL);
 
-  _gst_type_initialize ();
+  gst_init (&argc, &argv);
 
-  sinkcaps = gst_caps_register (&mpeg2dec_sink_caps);
+  sinkcaps = mpeg2dec_sink_caps ();
   parent = xmlNewChild (doc->xmlRootNode, NULL, "Capabilities1", NULL);
   gst_caps_save_thyself (sinkcaps, parent);
 
-  rawcaps  = gst_caps_register (&mpeg2dec_src_caps);
+  rawcaps  = GST_CAPS_GET (mpeg2dec_src_caps);
   parent = xmlNewChild (doc->xmlRootNode, NULL, "Capabilities2", NULL);
   gst_caps_save_thyself (rawcaps, parent);
 
-  temp = gst_padtemplate_new (&pad_caps);
+  temp = pad_caps ();
   parent = xmlNewChild (doc->xmlRootNode, NULL, "Padtemplate", NULL);
   gst_padtemplate_save_thyself (temp, parent);
 
+  parent = xmlNewChild (doc->xmlRootNode, NULL, "Padtemplate2", NULL);
+  gst_padtemplate_save_thyself (GST_PADTEMPLATE_GET (testtempl), parent);
+
   xmlDocDump(stdout, doc);
 
   return 0;
index 086649111850ca2832a8f2acb942e9344f71392c..027440a9368916f066692f6333b288b2604dd149 100644 (file)
@@ -4,53 +4,87 @@
 GstPad *srcpad, *sinkpad;
 GstPad *srcpadtempl, *sinkpadtempl;
 
-static GstPadFactory src_factory = {
-  "src",
-  GST_PAD_FACTORY_SRC,
-  GST_PAD_FACTORY_ALWAYS,
-  GST_PAD_FACTORY_CAPS(
-  "test_src",
-    "video/raw",
-    "height",    GST_PROPS_INT_RANGE (16, 4096)
-  ),
-  NULL,
-};
-
-static GstPadFactory sink_factory = {
-  "sink",
-  GST_PAD_FACTORY_SINK,
-  GST_PAD_FACTORY_ALWAYS,
-  GST_PAD_FACTORY_CAPS(
-  "test_sink",
-    "video/raw",
-    "height",    GST_PROPS_INT_RANGE (16, 8192)
-  ),
-  NULL,
-};
-
-static GstCapsFactory sink_caps = {
-  "sink_caps",
-  "video/raw",
-  "height",     GST_PROPS_INT (3000),
-  NULL
-};
-
-static GstCapsFactory src_caps = {
-  "src_caps",
-  "video/raw",
-  "height",     GST_PROPS_INT (3000),
-  NULL
-};
+static GstPadTemplate*
+src_template_factory (void)
+{
+  static GstPadTemplate *templ = NULL;
+
+  if (!templ) {
+    templ = gst_padtemplate_new (
+      "src",
+      GST_PAD_SRC,
+      GST_PAD_ALWAYS,
+      gst_caps_new (
+        "test_src",
+        "video/raw",
+       gst_props_new (
+          "height",    GST_PROPS_INT_RANGE (16, 4096),
+         NULL)),
+      NULL);
+  }
+  return templ;
+}
 
-static GstPadTemplate *srctempl, *sinktempl;
-static GstCaps *srccaps, *sinkcaps;
+static GstPadTemplate*
+sink_template_factory (void)
+{
+  static GstPadTemplate *templ = NULL;
+
+  if (!templ) {
+    templ = gst_padtemplate_new (
+      "sink",
+      GST_PAD_SINK,
+      GST_PAD_ALWAYS,
+      gst_caps_new (
+        "test_sink",
+        "video/raw",
+       gst_props_new (
+           "height",    GST_PROPS_INT_RANGE (16, 8192),
+          NULL)),
+      NULL);
+  }
+  return templ;
+}
+
+static GstCaps*
+sink_caps_factory (void)
+{
+  static GstCaps *caps = NULL;
+
+  if (!caps) {
+    caps = gst_caps_new (
+      "sink_caps",
+      "video/raw",
+      gst_props_new (
+        "height",     GST_PROPS_INT (3000),
+        NULL));
+  }
+  return caps;
+}
+
+static GstCaps*
+src_caps_factory (void)
+{
+  static GstCaps *caps = NULL;
+
+  if (!caps) {
+    caps = gst_caps_new (
+      "src_caps",
+      "video/raw",
+      gst_props_new (
+        "height",     GST_PROPS_INT (3000),
+       NULL));
+  }
+  return caps;
+}
 
 static GstPadNegotiateReturn
-negotiate_src (GstPad *pad, GstCaps **caps, gint counter)
+negotiate_src (GstPad *pad, GstCaps **caps, gpointer *data)
 {
   g_print (">");
 
-  if (counter == 0) {
+  if (*data == NULL) {
+    *data = GINT_TO_POINTER (TRUE);
     *caps = NULL;
     return GST_PAD_NEGOTIATE_TRY;
   }
@@ -61,10 +95,11 @@ negotiate_src (GstPad *pad, GstCaps **caps, gint counter)
 }
 
 static GstPadNegotiateReturn
-negotiate_sink (GstPad *pad, GstCaps **caps, gint counter)
+negotiate_sink (GstPad *pad, GstCaps **caps, gpointer *data)
 {
   g_print ("<");
-  if (counter == 0) {
+  if (*data == NULL) {
+    *data = GINT_TO_POINTER (TRUE);
     *caps = NULL;
     return GST_PAD_NEGOTIATE_TRY;
   }
@@ -74,6 +109,9 @@ negotiate_sink (GstPad *pad, GstCaps **caps, gint counter)
   return GST_PAD_NEGOTIATE_FAIL;
 }
 
+static GstPadTemplate *srctempl, *sinktempl;
+static GstCaps *srccaps, *sinkcaps;
+
 static gboolean
 perform_check  (void)
 {
@@ -121,14 +159,14 @@ main (int argc, char *argv[])
   srcpad = gst_pad_new ("src", GST_PAD_SRC);
   sinkpad = gst_pad_new ("sink", GST_PAD_SINK);
 
-  srctempl = gst_padtemplate_new (&src_factory);
-  sinktempl = gst_padtemplate_new (&sink_factory);
+  srctempl = src_template_factory ();
+  sinktempl = sink_template_factory ();
 
-  srcpadtempl = gst_pad_new_from_template (srctempl, "src");
-  sinkpadtempl = gst_pad_new_from_template (sinktempl, "sink");
+  srcpadtempl = gst_pad_new_from_template (src_template_factory (), "src");
+  sinkpadtempl = gst_pad_new_from_template (sink_template_factory (), "sink");
 
-  sinkcaps  = gst_caps_register (&sink_caps);
-  srccaps  = gst_caps_register (&src_caps);
+  sinkcaps  = sink_caps_factory ();
+  srccaps  = src_caps_factory ();
 
   g_print ("*** compatible caps/templates ***\n");
 
index df26338d1fc300814d0eeaadb20b3ea1c727bf39..83dd8d4648032470fd3fce9853f04c7dafa5e3df 100644 (file)
 
 GstPad *srcpad, *sinkpad;
 GstPad *srcconvpad, *sinkconvpad;
-GstPad *srcpadtempl, *sinkpadtempl;
-GstPad *srcconvtempl, *sinkconvtempl;
+GstPadTemplate *srcpadtempl, *sinkpadtempl;
+GstPadTemplate *srcconvtempl, *sinkconvtempl;
 
 gint converter_in = -1, converter_out = -1;
 
-static GstPadFactory src_factory = {
-  "src",
-  GST_PAD_FACTORY_SRC,
-  GST_PAD_FACTORY_ALWAYS,
-  GST_PAD_FACTORY_CAPS(
-  "test_src",
-    "audio/raw",
-    "rate",    GST_PROPS_INT_RANGE (16, 20000)
-  ),
-  NULL,
-};
-
-static GstPadFactory src_conv_factory = {
-  "src",
-  GST_PAD_FACTORY_SRC,
-  GST_PAD_FACTORY_ALWAYS,
-  GST_PAD_FACTORY_CAPS(
-  "test_src",
-    "audio/raw",
-    "rate",    GST_PROPS_INT_RANGE (16, 20000)
-  ),
-  NULL,
-};
-
-static GstPadFactory sink_conv_factory = {
-  "src",
-  GST_PAD_FACTORY_SINK,
-  GST_PAD_FACTORY_ALWAYS,
-  GST_PAD_FACTORY_CAPS(
-  "test_src",
-    "audio/raw",
-    "rate",    GST_PROPS_INT_RANGE (16, 20000)
-  ),
-  NULL,
-};
-
-static GstPadFactory sink_factory = {
-  "sink",
-  GST_PAD_FACTORY_SINK,
-  GST_PAD_FACTORY_ALWAYS,
-  GST_PAD_FACTORY_CAPS(
-  "test_sink",
-    "audio/raw",
-    "rate",    GST_PROPS_INT_RANGE (16, 20000)
-  ),
-  NULL,
-};
-
-static GstCapsFactory sink_caps = {
-  "sink_caps",
-  "audio/raw",
-  "rate",     GST_PROPS_INT (6000),
-  NULL
-};
-
-static GstCapsFactory src_caps = {
-  "src_caps",
-  "audio/raw",
-  "rate",     GST_PROPS_INT (3000),
-  NULL
-};
+static GstPadTemplate*
+src_factory (void)
+{
+  return 
+    gst_padtemplate_new (
+      "src",
+      GST_PAD_SRC,
+      GST_PAD_ALWAYS,
+      gst_caps_new (
+        "test_src",
+        "audio/raw",
+       gst_props_new (
+          "rate",    GST_PROPS_INT_RANGE (16, 20000),
+         NULL)),
+      NULL);
+}
+
+static GstPadTemplate*
+src_conv_factory (void)
+{
+  return 
+    gst_padtemplate_new (
+      "src",
+      GST_PAD_SRC,
+      GST_PAD_ALWAYS,
+      gst_caps_new (
+        "test_src",
+        "audio/raw",
+       gst_props_new (
+          "rate",    GST_PROPS_INT_RANGE (16, 20000),
+         NULL)),
+      NULL);
+}
+
+static GstPadTemplate*
+sink_conv_factory (void)
+{
+  return 
+    gst_padtemplate_new (
+      "src",
+      GST_PAD_SINK,
+      GST_PAD_ALWAYS,
+      gst_caps_new (
+        "test_src",
+        "audio/raw",
+       gst_props_new (
+          "rate",    GST_PROPS_INT_RANGE (16, 20000),
+         NULL)),
+      NULL);
+}
+
+static GstPadTemplate*
+sink_factory (void)
+{
+  return 
+    gst_padtemplate_new (
+      "sink",
+      GST_PAD_SINK,
+      GST_PAD_ALWAYS,
+      gst_caps_new (
+        "test_sink",
+        "audio/raw",
+       gst_props_new (
+          "rate",    GST_PROPS_INT_RANGE (16, 20000),
+         NULL)),
+      NULL);
+}
+
+static GstCaps*
+sink_caps (void)
+{
+  return 
+    gst_caps_new (
+      "sink_caps",
+      "audio/raw",
+      gst_props_new (
+        "rate",     GST_PROPS_INT (6000),
+       NULL));
+}
+
+static GstCaps*
+src_caps (void)
+{
+  return 
+    gst_caps_new (
+      "src_caps",
+      "audio/raw",
+      gst_props_new (
+        "rate",     GST_PROPS_INT (3000),
+       NULL));
+}
 
 static GstPadTemplate *srctempl, *sinktempl;
 static GstCaps *srccaps, *sinkcaps;
 
 static GstPadNegotiateReturn
-negotiate_src (GstPad *pad, GstCaps **caps, gint counter)
+negotiate_src (GstPad *pad, GstCaps **caps, gpointer *data)
 {
   g_print (">");
 
-  if (counter == 0) {
+  if (data == NULL) {
     *caps = NULL;
     return GST_PAD_NEGOTIATE_TRY;
   }
@@ -91,10 +121,10 @@ negotiate_src (GstPad *pad, GstCaps **caps, gint counter)
 }
 
 static GstPadNegotiateReturn
-negotiate_sink (GstPad *pad, GstCaps **caps, gint counter)
+negotiate_sink (GstPad *pad, GstCaps **caps, gpointer *data)
 {
   g_print ("<");
-  if (counter == 0) {
+  if (data == NULL) {
     *caps = NULL;
     return GST_PAD_NEGOTIATE_TRY;
   }
@@ -114,21 +144,22 @@ main (int argc, char *argv[])
   
   gst_init (&argc, &argv);
 
-  srctempl = gst_padtemplate_new (&src_factory);
-  sinktempl = gst_padtemplate_new (&sink_factory);
+  srctempl = src_factory ();
+  sinktempl = sink_factory ();
   srcpad = gst_pad_new_from_template (srctempl, "src");
   sinkpad = gst_pad_new_from_template (sinktempl, "sink");
 
-  srcconvtempl = gst_padtemplate_new (&src_conv_factory);
-  sinkconvtempl = gst_padtemplate_new (&sink_conv_factory);
+  srcconvtempl = src_conv_factory ();
+  sinkconvtempl = sink_conv_factory ();
   srcconvpad = gst_pad_new_from_template (srcconvtempl, "src");
   sinkconvpad = gst_pad_new_from_template (sinkconvtempl, "sink");
 
   gst_pad_set_negotiate_function (srcconvpad, negotiate_src);
   gst_pad_set_negotiate_function (sinkconvpad, negotiate_sink);
 
-  sinkcaps  = gst_caps_register (&sink_caps);
-  srccaps  = gst_caps_register (&src_caps);
+  sinkcaps  = sink_caps ();
+  srccaps  = src_caps ();
+
   result = gst_pad_set_caps (srcpad, srccaps);
   g_print ("set caps on src: %d\n", result);
   g_print ("initial converter status: %d %d\n", converter_in, converter_out);
index 0532c76956ca4cd91d7589744eeba07fe1c0b30d..8b3ebb32ea66c53767a099ebc1b354f8262bda89 100644 (file)
 
 GstPad *srcpad, *sinkpad;
 GstPad *srcconvpad, *sinkconvpad;
-GstPad *srcpadtempl, *sinkpadtempl;
-GstPad *srcconvtempl, *sinkconvtempl;
+GstPadTemplate *srcpadtempl, *sinkpadtempl;
+GstPadTemplate *srcconvtempl, *sinkconvtempl;
 
 gint converter_in = -1, converter_out = -1;
 gint target_rate = 2000;
 
-static GstPadFactory src_factory = {
-  "src",
-  GST_PAD_FACTORY_SRC,
-  GST_PAD_FACTORY_ALWAYS,
-  GST_PAD_FACTORY_CAPS(
-  "test_src",
-    "audio/raw",
-    "rate",    GST_PROPS_INT_RANGE (16, 20000)
-  ),
-  NULL,
-};
-
-static GstPadFactory src_conv_factory = {
-  "src",
-  GST_PAD_FACTORY_SRC,
-  GST_PAD_FACTORY_ALWAYS,
-  GST_PAD_FACTORY_CAPS(
-  "test_src",
-    "audio/raw",
-    "rate",    GST_PROPS_INT_RANGE (16, 20000)
-  ),
-  NULL,
-};
-
-static GstPadFactory sink_conv_factory = {
-  "src",
-  GST_PAD_FACTORY_SINK,
-  GST_PAD_FACTORY_ALWAYS,
-  GST_PAD_FACTORY_CAPS(
-  "test_src",
-    "audio/raw",
-    "rate",    GST_PROPS_INT_RANGE (16, 20000)
-  ),
-  NULL,
-};
-
-static GstPadFactory sink_factory = {
-  "sink",
-  GST_PAD_FACTORY_SINK,
-  GST_PAD_FACTORY_ALWAYS,
-  GST_PAD_FACTORY_CAPS(
-  "test_sink",
-    "audio/raw",
-    "rate",    GST_PROPS_INT_RANGE (16, 20000)
-  ),
-  NULL,
-};
-
-static GstCapsFactory sink_caps = {
-  "sink_caps",
-  "audio/raw",
-  "rate",     GST_PROPS_INT (6000),
-  NULL
-};
-
-static GstCapsFactory src_caps = {
-  "src_caps",
-  "audio/raw",
-  "rate",     GST_PROPS_INT (3000),
-  NULL
-};
+static GstPadTemplate*
+src_factory (void)
+{
+  return 
+    gst_padtemplate_new (
+      "src",
+      GST_PAD_SRC,
+      GST_PAD_ALWAYS,
+      gst_caps_new (
+        "test_src",
+        "audio/raw",
+       gst_props_new (
+          "rate",    GST_PROPS_INT_RANGE (16, 20000),
+         NULL)),
+      NULL);
+}
+
+static GstPadTemplate*
+src_conv_factory (void)
+{
+  return 
+    gst_padtemplate_new (
+      "src",
+      GST_PAD_SRC,
+      GST_PAD_ALWAYS,
+      gst_caps_new (
+        "test_src",
+        "audio/raw",
+       gst_props_new (
+          "rate",    GST_PROPS_INT_RANGE (16, 20000),
+         NULL)),
+      NULL);
+}
+
+static GstPadTemplate*
+sink_conv_factory (void)
+{
+  return 
+    gst_padtemplate_new (
+      "src",
+      GST_PAD_SINK,
+      GST_PAD_ALWAYS,
+      gst_caps_new (
+        "test_src",
+        "audio/raw",
+       gst_props_new (
+          "rate",    GST_PROPS_INT_RANGE (16, 20000),
+         NULL)),
+      NULL);
+}
+
+static GstPadTemplate*
+sink_factory (void)
+{
+  return 
+    gst_padtemplate_new (
+      "sink",
+      GST_PAD_SINK,
+      GST_PAD_ALWAYS,
+      gst_caps_new (
+        "test_sink",
+        "audio/raw",
+       gst_props_new (
+          "rate",    GST_PROPS_INT_RANGE (16, 20000),
+         NULL)),
+      NULL);
+}
+
+static GstCaps*
+sink_caps (void)
+{
+  return 
+    gst_caps_new (
+      "sink_caps",
+      "audio/raw",
+      gst_props_new (
+        "rate",     GST_PROPS_INT (6000),
+       NULL));
+}
+
+static GstCaps*
+src_caps (void)
+{
+  return 
+    gst_caps_new (
+      "src_caps",
+      "audio/raw",
+      gst_props_new (
+        "rate",     GST_PROPS_INT (3000),
+       NULL));
+}
 
 static GstPadTemplate *srctempl, *sinktempl;
 static GstCaps *srccaps, *sinkcaps;
 
 static GstPadNegotiateReturn
-converter_negotiate_src (GstPad *pad, GstCaps **caps, gint counter)
+converter_negotiate_src (GstPad *pad, GstCaps **caps, gpointer *data)
 {
   g_print (">");
 
-  if (counter == 0) {
+  if (*data == NULL) {
     *caps = NULL;
     return GST_PAD_NEGOTIATE_TRY;
   }
@@ -92,19 +122,19 @@ converter_negotiate_src (GstPad *pad, GstCaps **caps, gint counter)
 }
 
 static GstPadNegotiateReturn
-converter_negotiate_sink (GstPad *pad, GstCaps **caps, gint counter)
+converter_negotiate_sink (GstPad *pad, GstCaps **caps, gpointer *data)
 {
   g_print ("<");
-  if (counter == 0) {
+  if (*data == NULL) {
     *caps = GST_PAD_CAPS (srcconvpad);
     return GST_PAD_NEGOTIATE_TRY;
   }
   if (*caps) {
     converter_in = gst_caps_get_int (*caps, "rate");
 
-    if (counter == 1) {
+    if (*data == 1) {
       converter_out = gst_caps_get_int (*caps, "rate");
-      return gst_pad_negotiate_proxy (pad, srcconvpad, caps, counter);
+      return gst_pad_negotiate_proxy (pad, srcconvpad, caps);
     }
     return GST_PAD_NEGOTIATE_AGREE;
   }
@@ -113,11 +143,11 @@ converter_negotiate_sink (GstPad *pad, GstCaps **caps, gint counter)
 }
 
 static GstPadNegotiateReturn
-target_negotiate_sink (GstPad *pad, GstCaps **caps, gint counter)
+target_negotiate_sink (GstPad *pad, GstCaps **caps, gpointer *data)
 {
   g_print ("{");
-  if (counter == 0) {
-    *caps = gst_caps_new_with_props (
+  if (*data == NULL) {
+    *caps = gst_caps_new (
                    "target_caps",
                    "audio/raw",
                    gst_props_new (
@@ -143,13 +173,13 @@ main (int argc, char *argv[])
   
   gst_init (&argc, &argv);
 
-  srctempl = gst_padtemplate_new (&src_factory);
-  sinktempl = gst_padtemplate_new (&sink_factory);
+  srctempl = src_factory ();
+  sinktempl = sink_factory ();
   srcpad = gst_pad_new_from_template (srctempl, "src");
   sinkpad = gst_pad_new_from_template (sinktempl, "sink");
 
-  srcconvtempl = gst_padtemplate_new (&src_conv_factory);
-  sinkconvtempl = gst_padtemplate_new (&sink_conv_factory);
+  srcconvtempl = src_conv_factory ();
+  sinkconvtempl = sink_conv_factory ();
   srcconvpad = gst_pad_new_from_template (srcconvtempl, "csrc");
   sinkconvpad = gst_pad_new_from_template (sinkconvtempl, "csink");
 
@@ -157,8 +187,8 @@ main (int argc, char *argv[])
   gst_pad_set_negotiate_function (sinkconvpad, converter_negotiate_sink);
   gst_pad_set_negotiate_function (sinkpad, target_negotiate_sink);
 
-  sinkcaps  = gst_caps_register (&sink_caps);
-  srccaps  = gst_caps_register (&src_caps);
+  sinkcaps  = sink_caps ();
+  srccaps  = src_caps ();
 
   g_print ("-------)      (-----------)       (-----   \n");
   g_print ("       !      ! converter !       !        \n");
index e3959309e92fc441e1586e723c9a031460a417b7..343e08c10d59a9c62f8963a627ec5885f328fe42 100644 (file)
@@ -4,36 +4,51 @@
 GstPad *srcconvpad, *sinkconvpad;
 GstPadTemplate *srcconvtempl, *sinkconvtempl;
 
-static GstPadFactory src_conv_factory = {
-  "src",
-  GST_PAD_FACTORY_SRC,
-  GST_PAD_FACTORY_ALWAYS,
-  GST_PAD_FACTORY_CAPS(
-  "test_src",
-    "audio/raw",
-    "rate",    GST_PROPS_INT_RANGE (16, 20000)
-  ),
-  NULL,
-};
-
-static GstPadFactory sink_conv_factory = {
-  "src",
-  GST_PAD_FACTORY_SINK,
-  GST_PAD_FACTORY_ALWAYS,
-  GST_PAD_FACTORY_CAPS(
-  "test_src",
-    "audio/raw",
-    "rate",    GST_PROPS_INT_RANGE (16, 20000)
-  ),
-  NULL,
-};
-
-static GstCapsFactory src_caps = {
-  "src_caps",
-  "audio/raw",
-  "rate",     GST_PROPS_INT (3000),
-  NULL
-};
+static GstPadTemplate*
+src_conv_factory (void)
+{
+  return 
+    gst_padtemplate_new (
+      "src",
+      GST_PAD_SRC,
+      GST_PAD_ALWAYS,
+      gst_caps_new (
+        "test_src",
+        "audio/raw",
+       gst_props_new (
+          "rate",    GST_PROPS_INT_RANGE (16, 20000),
+         NULL)),
+      NULL);
+}
+
+static GstPadTemplate*
+sink_conv_factory (void)
+{
+  return 
+    gst_padtemplate_new (
+      "sink",
+      GST_PAD_SINK,
+      GST_PAD_ALWAYS,
+      gst_caps_new (
+        "test_src",
+        "audio/raw",
+       gst_props_new (
+          "rate",    GST_PROPS_INT_RANGE (16, 20000),
+         NULL)),
+      NULL);
+}
+
+static GstCaps*
+src_caps (void)
+{
+  return
+    gst_caps_new (
+      "src_caps",
+      "audio/raw",
+      gst_props_new (
+        "rate",     GST_PROPS_INT (3000),
+       NULL));
+}
 
 static GstCaps *srccaps, *sinkcaps;
 
@@ -41,14 +56,14 @@ static gint src_rate = 140;
 static gint sink_rate = 100;
 
 static GstPadNegotiateReturn
-negotiate_src (GstPad *pad, GstCaps **caps, gint counter)
+negotiate_src (GstPad *pad, GstCaps **caps, gpointer *data)
 {
   g_print (">(%d:%d)", src_rate, (*caps)->refcount);
   src_rate++;
 
-  if (counter == 0 || caps == NULL) {
+  if (*data == NULL || caps == NULL) {
     g_print ("*");
-    *caps = gst_caps_new_with_props (
+    *caps = gst_caps_new (
                    "src_caps",
                    "audio/raw",
                    gst_props_new (
@@ -77,15 +92,15 @@ negotiate_src (GstPad *pad, GstCaps **caps, gint counter)
 }
 
 static GstPadNegotiateReturn
-negotiate_sink (GstPad *pad, GstCaps **caps, gint counter)
+negotiate_sink (GstPad *pad, GstCaps **caps, gpointer *data)
 {
 
   g_print ("<(%d:%d:%p)", sink_rate, (*caps)->refcount, *caps);
   sink_rate++;
 
-  if (counter == 0 || *caps == NULL) {
+  if (*data == NULL || *caps == NULL) {
     g_print ("*");
-    *caps = gst_caps_new_with_props (
+    *caps = gst_caps_new (
                    "sink_caps",
                    "audio/raw",
                    gst_props_new (
@@ -126,15 +141,15 @@ main (int argc, char *argv[])
 
   g_mem_chunk_info();
 
-  srcconvtempl = gst_padtemplate_new (&src_conv_factory);
-  sinkconvtempl = gst_padtemplate_new (&sink_conv_factory);
+  srcconvtempl = src_conv_factory ();
+  sinkconvtempl = sink_conv_factory ();
   srcconvpad = gst_pad_new_from_template (srcconvtempl, "src");
   sinkconvpad = gst_pad_new_from_template (sinkconvtempl, "sink");
 
   gst_pad_set_negotiate_function (srcconvpad, negotiate_src);
   gst_pad_set_negotiate_function (sinkconvpad, negotiate_sink);
 
-  srccaps  = gst_caps_register (&src_caps);
+  srccaps  = src_caps ();
   sinkcaps  = gst_caps_copy (srccaps);
 
   g_print ("The wild goose chase...\n");