mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-13 03:46:34 +00:00
Merged from HEAD to INCSCHED1 on 200104251
Original commit message from CVS: Merged from HEAD to INCSCHED1 on 200104251
This commit is contained in:
parent
99aa793b1c
commit
583f6660fa
99 changed files with 4437 additions and 946 deletions
|
@ -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
|
||||
|
|
71
configure.in
71
configure.in
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -9,6 +9,7 @@ GtkObject
|
|||
GstFakeSrc
|
||||
GstFakeSink
|
||||
GstDiskSrc
|
||||
GstDiskSink
|
||||
GstHttpSrc
|
||||
GstFdSrc
|
||||
GstSineSrc
|
||||
|
|
|
@ -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>
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -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>
|
||||
|
||||
<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:
|
||||
|
|
|
@ -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 ##### -->
|
||||
|
|
|
@ -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>
|
||||
|
||||
|
|
|
@ -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 ##### -->
|
||||
|
|
|
@ -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:
|
||||
|
||||
<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 >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 ##### -->
|
||||
|
|
|
@ -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 ##### -->
|
||||
|
|
36
docs/gst/tmpl/gstdisksink.sgml
Normal file
36
docs/gst/tmpl/gstdisksink.sgml
Normal file
|
@ -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>
|
||||
|
|
@ -28,3 +28,8 @@ with the buffer. (fakesink)
|
|||
|
||||
</para>
|
||||
|
||||
<!-- ##### ARG GstFakeSink:silent ##### -->
|
||||
<para>
|
||||
|
||||
</para>
|
||||
|
||||
|
|
|
@ -24,3 +24,8 @@ Pass data without modification.
|
|||
|
||||
</para>
|
||||
|
||||
<!-- ##### ARG GstIdentity:silent ##### -->
|
||||
<para>
|
||||
|
||||
</para>
|
||||
|
||||
|
|
|
@ -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:
|
||||
@caps:
|
||||
@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: 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:
|
||||
@pad: the real pad to query.
|
||||
|
||||
|
||||
<!-- ##### MACRO GST_RPAD_BUFFERPOOLFUNC ##### -->
|
||||
<para>
|
||||
Get the bufferpoolfunction from the real pad.
|
||||
</para>
|
||||
|
||||
@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:
|
||||
@templ: the template to query
|
||||
|
||||
|
||||
<!-- ##### MACRO GST_PADTEMPLATE_NEW ##### -->
|
||||
<para>
|
||||
Create a new padtemplate.
|
||||
</para>
|
||||
|
||||
@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 ##### -->
|
||||
|
|
|
@ -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 ##### -->
|
||||
|
|
|
@ -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>
|
||||
|
||||
|
|
|
@ -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:
|
||||
|
||||
|
||||
|
|
|
@ -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:
|
||||
@b:
|
||||
@c:
|
||||
@d:
|
||||
@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>
|
||||
|
||||
@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 ##### -->
|
||||
|
|
|
@ -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>
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
||||
appwindow = gnome_app_new("autoplug demo","autoplug demo");
|
||||
gnome_app_set_contents(GNOME_APP(appwindow),
|
||||
gst_util_get_widget_arg(GTK_OBJECT(videosink),"widget"));
|
||||
gtk_widget_show_all(appwindow);
|
||||
autoplug = gst_autoplugfactory_make ("staticrender");
|
||||
g_assert (autoplug != NULL);
|
||||
|
||||
/* 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);
|
||||
new_element = gst_autoplug_to_renderers (autoplug,
|
||||
srccaps,
|
||||
videosink,
|
||||
osssink,
|
||||
NULL);
|
||||
|
||||
if (!gst_pipeline_autoplug(GST_PIPELINE(pipeline))) {
|
||||
g_print("unable to handle stream\n");
|
||||
exit(-1);
|
||||
if (!new_element) {
|
||||
g_print ("could not autoplug, no suitable codecs found...\n");
|
||||
exit (-1);
|
||||
}
|
||||
|
||||
xmlSaveFile("xmlTest.gst", gst_xml_write(GST_ELEMENT(pipeline)));
|
||||
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),
|
||||
GTK_WIDGET (socket));
|
||||
|
||||
gtk_widget_realize (socket);
|
||||
gtk_socket_steal (GTK_SOCKET (socket),
|
||||
gst_util_get_int_arg (GTK_OBJECT (videosink), "xid"));
|
||||
|
||||
gtk_widget_show_all(appwindow);
|
||||
|
||||
xmlSaveFile("xmlTest.gst", gst_xml_write(GST_ELEMENT(bin)));
|
||||
|
||||
/* start playing */
|
||||
gst_element_set_state(GST_ELEMENT(pipeline), GST_STATE_PLAYING);
|
||||
gst_element_set_state(GST_ELEMENT(bin), GST_STATE_PLAYING);
|
||||
|
||||
playing = TRUE;
|
||||
|
||||
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);
|
||||
}
|
||||
|
|
1
examples/mixer/.gitignore
vendored
Normal file
1
examples/mixer/.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
helloworld
|
4
examples/mixer/Makefile.am
Normal file
4
examples/mixer/Makefile.am
Normal file
|
@ -0,0 +1,4 @@
|
|||
noinst_PROGRAMS = mixer
|
||||
|
||||
LIBS += $(GST_LIBS)
|
||||
CFLAGS += $(GST_CFLAGS)
|
360
examples/mixer/mixer.c
Normal file
360
examples/mixer/mixer.c
Normal file
|
@ -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);
|
||||
|
||||
}
|
||||
|
12
examples/mixer/mixer.h
Normal file
12
examples/mixer/mixer.h
Normal file
|
@ -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;
|
|
@ -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. */
|
||||
};
|
||||
|
||||
|
|
1
gst/.gitignore
vendored
1
gst/.gitignore
vendored
|
@ -5,3 +5,4 @@ Makefile.in
|
|||
*.la
|
||||
.deps
|
||||
.libs
|
||||
gstversion.h
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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 *);
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
254
gst/elements/gstdisksink.c
Normal file
254
gst/elements/gstdisksink.c
Normal file
|
@ -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;
|
||||
}
|
||||
|
82
gst/elements/gstdisksink.h
Normal file
82
gst/elements/gstdisksink.h
Normal file
|
@ -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__ */
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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
|
||||
};
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -56,6 +56,7 @@ struct _GstFakeSink {
|
|||
|
||||
GSList *sinkpads;
|
||||
gint numsinkpads;
|
||||
gboolean silent;
|
||||
};
|
||||
|
||||
struct _GstFakeSinkClass {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -60,6 +60,7 @@ struct _GstIdentity {
|
|||
gboolean loop_based;
|
||||
|
||||
guint sleep_time;
|
||||
gboolean silent;
|
||||
};
|
||||
|
||||
struct _GstIdentityClass {
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
70
gst/gstpad.c
70
gst/gstpad.c
|
@ -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.
|
||||
*
|
||||
|
|
31
gst/gstpad.h
31
gst/gstpad.h
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
31
gst/gstversion.h.in
Normal file
31
gst/gstversion.h.in
Normal file
|
@ -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__ */
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
};
|
||||
|
|
|
@ -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++)
|
||||
|
|
|
@ -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)
|
||||
|
|
254
plugins/elements/gstdisksink.c
Normal file
254
plugins/elements/gstdisksink.c
Normal file
|
@ -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;
|
||||
}
|
||||
|
82
plugins/elements/gstdisksink.h
Normal file
82
plugins/elements/gstdisksink.h
Normal file
|
@ -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__ */
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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
|
||||
};
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -56,6 +56,7 @@ struct _GstFakeSink {
|
|||
|
||||
GSList *sinkpads;
|
||||
gint numsinkpads;
|
||||
gboolean silent;
|
||||
};
|
||||
|
||||
struct _GstFakeSinkClass {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -60,6 +60,7 @@ struct _GstIdentity {
|
|||
gboolean loop_based;
|
||||
|
||||
guint sleep_time;
|
||||
gboolean silent;
|
||||
};
|
||||
|
||||
struct _GstIdentityClass {
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
6
test/.gitignore
vendored
6
test/.gitignore
vendored
|
@ -46,3 +46,9 @@ mp1tomp1
|
|||
pipetest
|
||||
mp3tovorbis
|
||||
xmmstest
|
||||
dv2mp1
|
||||
dvshow
|
||||
video2mp1
|
||||
mp3mad
|
||||
videotest2
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
66
test/dv2mp1.c
Normal file
66
test/dv2mp1.c
Normal file
|
@ -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);
|
||||
}
|
||||
|
96
test/dvshow.c
Normal file
96
test/dvshow.c
Normal file
|
@ -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);
|
||||
}
|
||||
|
|
@ -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"),
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
#include <gnome.h>
|
||||
#include <gst/gst.h>
|
||||
|
||||
extern gboolean _gst_plugin_spew;
|
||||
|
|
47
test/mp3mad.c
Normal file
47
test/mp3mad.c
Normal file
|
@ -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)));
|
||||
}
|
236
test/video2mp1.c
Normal file
236
test/video2mp1.c
Normal file
|
@ -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);
|
||||
}
|
||||
|
|
@ -1,4 +1,3 @@
|
|||
#include <gnome.h>
|
||||
#include <gst/gst.h>
|
||||
|
||||
extern gboolean _gst_plugin_spew;
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -3,100 +3,48 @@
|
|||
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);
|
||||
}
|
||||
|
|
102
tests/autoplug4.c
Normal file
102
tests/autoplug4.c
Normal file
|
@ -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);
|
||||
}
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
||||
appwindow = gnome_app_new("autoplug demo","autoplug demo");
|
||||
gnome_app_set_contents(GNOME_APP(appwindow),
|
||||
gst_util_get_widget_arg(GTK_OBJECT(videosink),"widget"));
|
||||
gtk_widget_show_all(appwindow);
|
||||
autoplug = gst_autoplugfactory_make ("staticrender");
|
||||
g_assert (autoplug != NULL);
|
||||
|
||||
/* 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);
|
||||
new_element = gst_autoplug_to_renderers (autoplug,
|
||||
srccaps,
|
||||
videosink,
|
||||
osssink,
|
||||
NULL);
|
||||
|
||||
if (!gst_pipeline_autoplug(GST_PIPELINE(pipeline))) {
|
||||
g_print("unable to handle stream\n");
|
||||
exit(-1);
|
||||
if (!new_element) {
|
||||
g_print ("could not autoplug, no suitable codecs found...\n");
|
||||
exit (-1);
|
||||
}
|
||||
|
||||
xmlSaveFile("xmlTest.gst", gst_xml_write(GST_ELEMENT(pipeline)));
|
||||
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),
|
||||
GTK_WIDGET (socket));
|
||||
|
||||
gtk_widget_realize (socket);
|
||||
gtk_socket_steal (GTK_SOCKET (socket),
|
||||
gst_util_get_int_arg (GTK_OBJECT (videosink), "xid"));
|
||||
|
||||
gtk_widget_show_all(appwindow);
|
||||
|
||||
xmlSaveFile("xmlTest.gst", gst_xml_write(GST_ELEMENT(bin)));
|
||||
|
||||
/* start playing */
|
||||
gst_element_set_state(GST_ELEMENT(pipeline), GST_STATE_PLAYING);
|
||||
gst_element_set_state(GST_ELEMENT(bin), GST_STATE_PLAYING);
|
||||
|
||||
playing = TRUE;
|
||||
|
||||
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);
|
||||
}
|
||||
|
|
1
tests/old/examples/mixer/.gitignore
vendored
Normal file
1
tests/old/examples/mixer/.gitignore
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
helloworld
|
4
tests/old/examples/mixer/Makefile.am
Normal file
4
tests/old/examples/mixer/Makefile.am
Normal file
|
@ -0,0 +1,4 @@
|
|||
noinst_PROGRAMS = mixer
|
||||
|
||||
LIBS += $(GST_LIBS)
|
||||
CFLAGS += $(GST_CFLAGS)
|
360
tests/old/examples/mixer/mixer.c
Normal file
360
tests/old/examples/mixer/mixer.c
Normal file
|
@ -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);
|
||||
|
||||
}
|
||||
|
12
tests/old/examples/mixer/mixer.h
Normal file
12
tests/old/examples/mixer/mixer.h
Normal file
|
@ -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;
|
|
@ -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. */
|
||||
};
|
||||
|
||||
|
|
|
@ -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 GstPadTemplate*
|
||||
src_template_factory (void)
|
||||
{
|
||||
static GstPadTemplate *templ = 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,
|
||||
};
|
||||
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 GstCapsFactory sink_caps = {
|
||||
"sink_caps",
|
||||
"video/raw",
|
||||
"height", GST_PROPS_INT (3000),
|
||||
NULL
|
||||
};
|
||||
static GstPadTemplate*
|
||||
sink_template_factory (void)
|
||||
{
|
||||
static GstPadTemplate *templ = NULL;
|
||||
|
||||
static GstCapsFactory src_caps = {
|
||||
"src_caps",
|
||||
"video/raw",
|
||||
"height", GST_PROPS_INT (3000),
|
||||
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 GstPadTemplate *srctempl, *sinktempl;
|
||||
static GstCaps *srccaps, *sinkcaps;
|
||||
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");
|
||||
|
||||
|
|
|
@ -3,82 +3,112 @@
|
|||
|
||||
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 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 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 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 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 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 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 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 GstCapsFactory sink_caps = {
|
||||
"sink_caps",
|
||||
"audio/raw",
|
||||
"rate", GST_PROPS_INT (6000),
|
||||
NULL
|
||||
};
|
||||
static GstCaps*
|
||||
sink_caps (void)
|
||||
{
|
||||
return
|
||||
gst_caps_new (
|
||||
"sink_caps",
|
||||
"audio/raw",
|
||||
gst_props_new (
|
||||
"rate", GST_PROPS_INT (6000),
|
||||
NULL));
|
||||
}
|
||||
|
||||
static GstCapsFactory src_caps = {
|
||||
"src_caps",
|
||||
"audio/raw",
|
||||
"rate", GST_PROPS_INT (3000),
|
||||
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);
|
||||
|
|
|
@ -3,83 +3,113 @@
|
|||
|
||||
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 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 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 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 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 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 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 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 GstCapsFactory sink_caps = {
|
||||
"sink_caps",
|
||||
"audio/raw",
|
||||
"rate", GST_PROPS_INT (6000),
|
||||
NULL
|
||||
};
|
||||
static GstCaps*
|
||||
sink_caps (void)
|
||||
{
|
||||
return
|
||||
gst_caps_new (
|
||||
"sink_caps",
|
||||
"audio/raw",
|
||||
gst_props_new (
|
||||
"rate", GST_PROPS_INT (6000),
|
||||
NULL));
|
||||
}
|
||||
|
||||
static GstCapsFactory src_caps = {
|
||||
"src_caps",
|
||||
"audio/raw",
|
||||
"rate", GST_PROPS_INT (3000),
|
||||
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");
|
||||
|
|
|
@ -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 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 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 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 GstCapsFactory src_caps = {
|
||||
"src_caps",
|
||||
"audio/raw",
|
||||
"rate", GST_PROPS_INT (3000),
|
||||
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");
|
||||
|
|
|
@ -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 GstCaps*
|
||||
mpeg2dec_sink_caps (void)
|
||||
{
|
||||
static GstCaps *caps;
|
||||
|
||||
static GstCapsFactory mpeg2dec_src_caps = {
|
||||
"name",
|
||||
"video/raw",
|
||||
"fourcc", GST_PROPS_LIST (
|
||||
GST_PROPS_FOURCC ('Y','V','1','2'),
|
||||
GST_PROPS_FOURCC_INT (0x56595559)
|
||||
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;
|
||||
}
|
||||
|
||||
GST_CAPS_FACTORY (mpeg2dec_src_caps,
|
||||
GST_CAPS_NEW (
|
||||
"mpeg2dec_src_caps",
|
||||
"video/raw",
|
||||
"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_CAPS_NEW(
|
||||
"mpeg2dec_src_caps",
|
||||
"video/raw",
|
||||
"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'))
|
||||
),
|
||||
"width", GST_PROPS_INT_RANGE (16, 4096),
|
||||
"height", GST_PROPS_INT_RANGE (16, 4096),
|
||||
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;
|
||||
}
|
||||
|
||||
static GstCapsFactory raw_sink_caps = {
|
||||
NULL
|
||||
};
|
||||
|
||||
static GstPadFactory pad_caps = {
|
||||
GST_PADTEMPLATE_FACTORY (testtempl,
|
||||
"src",
|
||||
GST_PAD_FACTORY_SRC,
|
||||
GST_PAD_FACTORY_ALWAYS,
|
||||
GST_PAD_FACTORY_CAPS (
|
||||
"videocaps",
|
||||
"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)
|
||||
GST_PAD_SRC,
|
||||
GST_PAD_ALWAYS,
|
||||
GST_CAPS_NEW (
|
||||
"mycaps",
|
||||
"audio/raw",
|
||||
"format", GST_PROPS_INT (55),
|
||||
"foo", GST_PROPS_STRING ("bar")
|
||||
),
|
||||
GST_PAD_FACTORY_CAPS (
|
||||
"videocaps2",
|
||||
"video/raw",
|
||||
"fourcc", GST_PROPS_LIST (
|
||||
GST_PROPS_FOURCC_INT (0x32315659)
|
||||
),
|
||||
"height", GST_PROPS_INT_RANGE (16, 256)
|
||||
),
|
||||
NULL
|
||||
};
|
||||
|
||||
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;
|
||||
|
|
|
@ -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 GstPadTemplate*
|
||||
src_template_factory (void)
|
||||
{
|
||||
static GstPadTemplate *templ = 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,
|
||||
};
|
||||
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 GstCapsFactory sink_caps = {
|
||||
"sink_caps",
|
||||
"video/raw",
|
||||
"height", GST_PROPS_INT (3000),
|
||||
NULL
|
||||
};
|
||||
static GstPadTemplate*
|
||||
sink_template_factory (void)
|
||||
{
|
||||
static GstPadTemplate *templ = NULL;
|
||||
|
||||
static GstCapsFactory src_caps = {
|
||||
"src_caps",
|
||||
"video/raw",
|
||||
"height", GST_PROPS_INT (3000),
|
||||
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 GstPadTemplate *srctempl, *sinktempl;
|
||||
static GstCaps *srccaps, *sinkcaps;
|
||||
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");
|
||||
|
||||
|
|
|
@ -3,82 +3,112 @@
|
|||
|
||||
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 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 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 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 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 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 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 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 GstCapsFactory sink_caps = {
|
||||
"sink_caps",
|
||||
"audio/raw",
|
||||
"rate", GST_PROPS_INT (6000),
|
||||
NULL
|
||||
};
|
||||
static GstCaps*
|
||||
sink_caps (void)
|
||||
{
|
||||
return
|
||||
gst_caps_new (
|
||||
"sink_caps",
|
||||
"audio/raw",
|
||||
gst_props_new (
|
||||
"rate", GST_PROPS_INT (6000),
|
||||
NULL));
|
||||
}
|
||||
|
||||
static GstCapsFactory src_caps = {
|
||||
"src_caps",
|
||||
"audio/raw",
|
||||
"rate", GST_PROPS_INT (3000),
|
||||
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);
|
||||
|
|
|
@ -3,83 +3,113 @@
|
|||
|
||||
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 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 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 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 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 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 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 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 GstCapsFactory sink_caps = {
|
||||
"sink_caps",
|
||||
"audio/raw",
|
||||
"rate", GST_PROPS_INT (6000),
|
||||
NULL
|
||||
};
|
||||
static GstCaps*
|
||||
sink_caps (void)
|
||||
{
|
||||
return
|
||||
gst_caps_new (
|
||||
"sink_caps",
|
||||
"audio/raw",
|
||||
gst_props_new (
|
||||
"rate", GST_PROPS_INT (6000),
|
||||
NULL));
|
||||
}
|
||||
|
||||
static GstCapsFactory src_caps = {
|
||||
"src_caps",
|
||||
"audio/raw",
|
||||
"rate", GST_PROPS_INT (3000),
|
||||
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");
|
||||
|
|
|
@ -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 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 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 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 GstCapsFactory src_caps = {
|
||||
"src_caps",
|
||||
"audio/raw",
|
||||
"rate", GST_PROPS_INT (3000),
|
||||
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");
|
||||
|
|
Loading…
Reference in a new issue