diff --git a/AUTHORS b/AUTHORS index f5f401c9db..9b24ca11d4 100644 --- a/AUTHORS +++ b/AUTHORS @@ -1,5 +1,16 @@ Erik Walthinsen +Matt Howell +Brent Bradburn Wim Taymans Richard Boulton -Chris Emerson (PPC port) Zaheer Merali (thread synchronization rework) +David I. Lehn + - debian packaging + - various fixes +Chris Emerson + - PPC port + - small libxml patches +Jens Thiele + - color conversion patches +Thomas Nyberg + - gstreamer.m4 macros diff --git a/Makefile.am b/Makefile.am index 6d363ba57b..0315866f70 100644 --- a/Makefile.am +++ b/Makefile.am @@ -8,10 +8,17 @@ else SUBDIRS_LGG = endif -SUBDIRS = include gst libs plugins tools test tests examples $(SUBDIRS_LGG) docs +if BUILD_DOCS +SUBDIRS_DOCS = docs +else +SUBDIRS_DOCS = +endif + +SUBDIRS = include gst libs plugins tools test tests testsuite examples \ +$(SUBDIRS_LGG) $(SUBDIRS_DOCS) # These are all the possible subdirs -DIST_SUBDIRS = intl po include gst libs plugins tools test tests examples gstplay editor docs +DIST_SUBDIRS = include gst libs plugins tools test tests testsuite examples gstplay editor docs debian bin_SCRIPTS = gstreamer-config @@ -22,8 +29,10 @@ m4data_DATA = gstreamer.m4 pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = gstreamer.pc +man_MANS = gstreamer-config.1 + EXTRA_DIST = gstreamer.spec.in gstreamer-config.in gstreamer.m4 gstreamer.pc.in \ - LICENSE REQUIREMENTS ABOUT-NLS + LICENSE REQUIREMENTS ABOUT-NLS $(man_MANS) dist-hook: cp gstreamer.spec $(distdir) diff --git a/REQUIREMENTS b/REQUIREMENTS index e596e322e6..4af1a43b99 100644 --- a/REQUIREMENTS +++ b/REQUIREMENTS @@ -9,7 +9,10 @@ Required libraries: =================== glib v1.2.0 or better gtk+ v1.2.0 or better -libxml +libxml (also called gnome-xml, available from http://xmlsoft.org/) + +These libraries are all central parts of gnome, and are available from the +ftp.gnome.org or its mirrors, amongst other places. Optional libraries: =================== @@ -24,6 +27,8 @@ libvorbis (for vorbisenc, vorbisdec) libcdparanoia (for cdparanoia ripper) liblame (for lame mp3 encoder) libshout (for the shoutcast plugin) +libasound (for the alsa src/sink plugin) +librtp (for the rtp sink plugin) for AVI playback you might want to get the windows libraries from http://divx.euro.ru/ and put the .dll files in /usr/lib/win32/ diff --git a/acconfig.h b/acconfig.h index bee8dafad0..f2b788d361 100644 --- a/acconfig.h +++ b/acconfig.h @@ -19,16 +19,23 @@ #undef HAVE_CPU_PPC #undef HAVE_CPU_ALPHA #undef HAVE_CPU_ARM +#undef HAVE_CPU_SPARC #undef HAVE_GDK_PIXBUF #undef HAVE_LIBGHTTP #undef HAVE_LIBMMX #undef HAVE_LIBXV +#undef HAVE_OSS #undef HAVE_XAUDIO #undef HAVE_CSSAUTH #undef HAVE_VORBIS +#undef HAVE_LIBMAD #undef HAVE_LIBJPEG +#undef HAVE_LIBHERMES #undef HAVE_NASM +#undef HAVE_MPEG2DEC +#undef HAVE_LINUX_CDROM +#undef HAVE_LINUX_VIDEODEV #undef HAVE_ATOMIC_H diff --git a/components/bonobo-gstmediaplay/Makefile.am b/components/bonobo-gstmediaplay/Makefile.am index 86311bd24e..c026f43afb 100644 --- a/components/bonobo-gstmediaplay/Makefile.am +++ b/components/bonobo-gstmediaplay/Makefile.am @@ -7,6 +7,7 @@ INCLUDES = -I$(top_srcdir)/gst \ -DGNOMELOCALEDIR=\""$(datadir)/locale"\" \ -DDATADIR=\""$(datadir)"\" \ -I$(includedir) \ + $(shell gnome-config --cflags gnome gnomeui bonobo bonobox) \ $(BONOBOX_TEST_CFLAGS) -Wall -O2 bin_PROGRAMS = bonobo-gstmediaplay @@ -15,15 +16,16 @@ bonobo_gstmediaplay_SOURCES = \ bonobo-gstmediaplay.c bonobo_gstmediaplay_CFLAGS = -Wall -O2 \ - $(shell gnome-config --cflags gnomeui bonobo bonobox) $(shell libglade-config --cflags gnome) \ + $(shell gnome-config --cflags gnome gnomeui bonobo bonobox) $(shell libglade-config --cflags gnome) \ $(shell gstreamer-config --clfags ) bonobo_gstmediaplay_LDADD = \ - $(top_srcdir)/gstplay/libgstmediaplay.la + $(top_srcdir)/gstplay/libgstmediaplay.la \ + $(top_srcdir)/gst/libgst.la bonobo_gstmediaplay_LDFLAGS = \ - $(shell gnome-config --libs gnomeui bonobo bonobox) $(shell libglade-config --libs gnome) \ - $(shell gstreamer-config --libs ) + $(shell gnome-config --libs gnome gnomeui bonobo bonobox) $(shell libglade-config --libs gnome) \ + $(shell gstreamer-config --libs ) oafdir = $(datadir)/oaf OAF_FILES = gstmediaplay.oafinfo diff --git a/components/bonobo-gstmediaplay/bonobo-gstmediaplay.c b/components/bonobo-gstmediaplay/bonobo-gstmediaplay.c index ac6ee97d7e..4a6734eb3a 100644 --- a/components/bonobo-gstmediaplay/bonobo-gstmediaplay.c +++ b/components/bonobo-gstmediaplay/bonobo-gstmediaplay.c @@ -307,12 +307,16 @@ bonobo_gstmediaplay_factory (BonoboGenericFactory *this, void *data) control_data->play = gst_play_new (); + vbox = gtk_vbox_new (TRUE, 0); gtk_box_pack_start (GTK_BOX (vbox), GTK_WIDGET (control_data->play), TRUE, TRUE, 0); gtk_widget_show_all (vbox); + gst_play_set_uri (control_data->play, "/opt/data/armageddon1.mpg"); + gst_play_play (control_data->play); + /* * Create the BonoboControl object. */ @@ -403,6 +407,7 @@ init_server_factory (int argc, char **argv) int main (int argc, char **argv) { + //g_thread_init (NULL); /* * Setup the factory. */ diff --git a/configure.in b/configure.in index 01ef2d3c76..a35c501999 100644 --- a/configure.in +++ b/configure.in @@ -7,7 +7,7 @@ AM_CONFIG_HEADER(config.h) dnl FIXME this should be GSTREAMER_ now STREAMER_MAJOR_VERSION=0 STREAMER_MINOR_VERSION=1 -STREAMER_MICRO_VERSION=0 +STREAMER_MICRO_VERSION=1 STREAMER_VERSION=$STREAMER_MAJOR_VERSION.$STREAMER_MINOR_VERSION.$STREAMER_MICRO_VERSION PACKAGE=gstreamer @@ -41,20 +41,23 @@ AC_SUBST(GSTREAMER_LIBVERSION) AM_MAINTAINER_MODE -AC_ISC_POSIX AC_PROG_CC +AC_ISC_POSIX AC_STDC_HEADERS AC_ARG_PROGRAM +dnl We disable static building for development, for time savings +dnl *NOTE*: dnl this line before release, so release does static too AM_DISABLE_STATIC AC_LIBTOOL_DLOPEN AM_PROG_LIBTOOL -dnl ALL_LINGUAS="" -dnl AM_GNU_GETTEXT - CFLAGS="" +dnl This is used for the -config script... +builddir=`pwd` +AC_SUBST(builddir) + dnl ############################## dnl # Do automated configuration # dnl ############################## @@ -121,6 +124,8 @@ case "x${target_cpu}" in AC_DEFINE(HAVE_CPU_ALPHA) ;; xarm*) HAVE_CPU_ARM=yes ; AC_DEFINE(HAVE_CPU_ARM) ;; + xsparc*) HAVE_CPU_SPARC=yes ; + AC_DEFINE(HAVE_CPU_SPARC) ;; esac dnl Determine endianness @@ -156,16 +161,16 @@ AM_PATH_GLIB(1.2.0,, AC_MSG_ERROR(Cannot find glib: Is glib-config in path?), glib gmodule gthread) dnl Put the glib flags into $LIBS and $CFLAGS since we always use them -LIBS="$LIBS $GLIB_LIBS" -CFLAGS="$CFLAGS $GLIB_CFLAGS" +CORE_LIBS="$GLIB_LIBS" +CORE_CFLAGS="$GLIB_CFLAGS" dnl Check for gtk AM_PATH_GTK(1.2.0,, AC_MSG_ERROR(Cannot find gtk: Is gtk-config in path?)) dnl Put the gtk flags into $LIBS and $CFLAGS since we always use them -LIBS="$LIBS $GTK_LIBS" -CFLAGS="$CFLAGS $GTK_CFLAGS" +CORE_LIBS="$CORE_LIBS $GTK_LIBS" +CORE_CFLAGS="$CORE_CFLAGS $GTK_CFLAGS" dnl Check for libxml @@ -175,10 +180,13 @@ if test x$XML_CONFIG = xno; then fi XML_LIBS=`xml-config --libs` XML_CFLAGS=`xml-config --cflags` +AC_CHECK_LIB(xml, xmlDocGetRootElement, , + [ AC_MSG_ERROR(Need version 1.8.1 or better of libxml) ], + $XML_LIBS) AC_SUBST(XML_LIBS) AC_SUBST(XML_CFLAGS) -LIBS="$LIBS $XML_LIBS" -CFLAGS="$CFLAGS $XML_CFLAGS" +CORE_LIBS="$CORE_LIBS $XML_LIBS" +CORE_CFLAGS="$CORE_CFLAGS $XML_CFLAGS" dnl Next, check for the optional libraries: @@ -186,7 +194,44 @@ dnl ======================================= dnl Check for libesd +esd_save_LIBS=$LIBS +esd_save_CFLAGS=$CFLAGS AM_PATH_ESD(0.2.12, HAVE_LIBESD=yes, HAVE_LIBESD=no) +LIBS=$esd_save_LIBS +CFLAGS=$esd_save_CFLAGS +AC_ARG_ENABLE(esdsink, +[ --enable-esdsink enable the building of the esdsink], +[case "${enableval}" in + yes) : ;; + no) HAVE_LIBESD=no ;; + *) AC_MSG_ERROR(bad value ${enableval} for --enable-esdsink) ;; + esac], +[HAVE_LIBESD=$HAVE_LIBESD]) + +dnl Check for artsc +AC_PATH_PROG(ARTSC_CONFIG, artsc-config, no) +if test x$ARTSC_CONFIG = xno; then + AC_MSG_WARN(Couldn't find artsc-config) + ARTSC_LIBS= + ARTSC_CFLAGS= + HAVE_ARTSC=no +else + ARTSC_LIBS=`artsc-config --libs` + ARTSC_CFLAGS=`artsc-config --cflags` + HAVE_ARTSC=yes +fi +AC_SUBST(ARTSC_LIBS) +AC_SUBST(ARTSC_CFLAGS) +AC_ARG_ENABLE(artsd, +[ --enable-artsd enable the building of artsd plugins], +[case "${enableval}" in + yes) : ;; + no) HAVE_ARTSC=no ;; + *) AC_MSG_ERROR(bad value ${enableval} for --enable-artsd) ;; + esac], +[:]) + +dnl AM_PATH_XMMS(0.1.0, HAVE_LIBXMMS=yes, HAVE_LIBXMMS=no) dnl Check for libasound alsa_save_LIBS=$LIBS @@ -194,6 +239,14 @@ alsa_save_CFLAGS=$CFLAGS AM_PATH_ALSA(0.5.0, HAVE_LIBASOUND=yes, HAVE_LIBASOUND=no) LIBS=$alsa_save_LIBS CFLAGS=$alsa_save_CFLAGS +AC_ARG_ENABLE(alsasink, +[ --enable-alsasink enable the building of the alsasink], +[case "${enableval}" in + yes) HAVE_LIBASOUND=$HAVE_LIBASOUND ;; + no) HAVE_LIBASOUND=no ;; + *) AC_MSG_ERROR(bad value ${enableval} for --enable-alsasink) ;; +esac], +[HAVE_LIBASOUND=$HAVE_LIBASOUND]) dnl Check for libgdk-pixbuf AC_PATH_PROG(GDK_PIXBUF_CONFIG, gdk-pixbuf-config, no) @@ -211,6 +264,24 @@ AC_SUBST(GDK_PIXBUF_LIBS) AC_SUBST(GDK_PIXBUF_CFLAGS) +dnl Check for libgnome +AC_PATH_PROG(GNOME_CONFIG, gnome-config, no) +if test x$GNOME_CONFIG = xno; then + AC_MSG_WARN(Couldn't find gnome-config: can't build editor or gstplay) + GNOME_LIBS= + GNOME_CFLAGS= + HAVE_GNOME=no +else + GNOME_LIBS=`gnome-config --libs gnome gnomeui` + GNOME_CFLAGS=`gnome-config --cflags gnome gnomeui` + GHTTP_LIBS=`gnome-config --libs gnome gnomeui` + GHTTP_CFLAGS=`gnome-config --cflags gnome gnomeui` + HAVE_GNOME=yes +fi +AC_SUBST(GNOME_LIBS) +AC_SUBST(GNOME_CFLAGS) +AC_SUBST(GHTTP_LIBS) + dnl Check for libghttp dnl FIXME: need to check for header AC_CHECK_LIB(ghttp, ghttp_request_new, @@ -224,26 +295,8 @@ AC_CHECK_LIB(ghttp, ghttp_request_new, HAVE_LIBGHTTP=no ], $LIBS) -AC_SUBST(GHTTP_LIBS) AC_SUBST(GST_HTTPSRC_GET_TYPE) - -dnl Check for libgnome -AC_PATH_PROG(GNOME_CONFIG, gnome-config, no) -if test x$GNOME_CONFIG = xno; then - AC_MSG_WARN(Couldn't find gnome-config: can't build editor or gstplay) - GNOME_LIBS= - GNOME_CFLAGS= - HAVE_GNOME=no -else - GNOME_LIBS=`gnome-config --libs gnome gnomeui` - GNOME_CFLAGS=`gnome-config --cflags gnome gnomeui` - HAVE_GNOME=yes -fi -AC_SUBST(GNOME_LIBS) -AC_SUBST(GNOME_CFLAGS) - - dnl Check for libglade HAVE_LIBGLADE_GNOME="no" AC_PATH_PROG(LIBGLADE_CONFIG_PATH, libglade-config, no) @@ -251,19 +304,17 @@ if test x$LIBGLADE_CONFIG_PATH = xno; then AC_MSG_WARN(Couldn't find libglade-config - Can't build gstplay) LIBGLADE_GNOME_LIBS= LIBGLADE_GNOME_CFLAGS= - HAVE_LIBGLADE_GNOME=NO else LIBGLADE_GNOME_LIBS=`libglade-config --libs gnome` LIBGLADE_GNOME_CFLAGS=`libglade-config --cflags gnome` libglade_save_CFLAGS="$CFLAGS" libglade_save_LIBS="$LIBS" - CFLAGS="$CFLAGS $LIBGLADE_GNOME_CFLAGS" - LIBS="$LIBS $LIBGLADE_GNOME_LIBS" - HAVE_LIBGLADE_GNOME="no" + CFLAGS="$CFLAGS $LIBGLADE_GNOME_CFLAGS $GTK_CFLAGS" + LIBS="$LIBS $LIBGLADE_GNOME_LIBS $GTK_LIBS" AC_TRY_LINK([#include ],[glade_gnome_init();], HAVE_LIBGLADE_GNOME="yes", AC_MSG_WARN( - [Couldn't find gnome libraries for libglade - Can't build gstplay]) + [Couldn't find gnome libraries for libglade - Can't build gstmediaplay and gsteditor]) ) CFLAGS="$libglade_save_CFLAGS" LIBS="$libglade_save_LIBS" @@ -314,13 +365,24 @@ AC_DEFINE(HAVE_LIBXV), HAVE_LIBXV=no, $X_LIBS $X_PRE_LIBS -lXext -lX11 $X_EXTRA_LIBS) LIBS=${xvsave_LIBS} +dnl Check for OSS audio +AC_CHECK_HEADER(sys/soundcard.h, + AC_DEFINE(HAVE_OSS) + HAVE_OSS=yes, [] +) dnl Check for xaudio -AC_CHECK_HEADER(xaudio/decoder.h,[ +AC_CHECK_HEADER(xaudio/decoder.h, AC_DEFINE(HAVE_XAUDIO) HAVE_XAUDIO="yes", [] -]) +) +dnl Check for libvorbis +AC_MSG_CHECKING(MAD library) +AC_CHECK_LIB(mad, mad_decoder_finish, +HAVE_LIBMAD=yes +AC_DEFINE(HAVE_LIBMAD), +HAVE_LIBMAD=no, ) dnl Check for libvorbis AC_MSG_CHECKING(Vorbis library) @@ -336,6 +398,12 @@ HAVE_LIBJPEG=yes AC_DEFINE(HAVE_LIBJPEG), HAVE_LIBJPEG=no, ) +dnl Check for libvorbis +AC_MSG_CHECKING(Hermes library) +AC_CHECK_LIB(Hermes, Hermes_ConverterInstance, +HAVE_LIBHERMES=yes +AC_DEFINE(HAVE_LIBHERMES), +HAVE_LIBHERMES=no, ) dnl Check for cdparanoia AC_MSG_CHECKING(CDparanoia library) @@ -348,13 +416,22 @@ AC_CHECK_HEADER(cdda_paranoia.h, :, HAVE_CDPARANOIA=no) dnl Check for liblame AC_MSG_CHECKING(LAME library) AC_CHECK_LIB(mp3lame, lame_init, HAVE_LIBLAME=yes, HAVE_LIBLAME=no, ) -AC_CHECK_HEADER(lame.h, :, HAVE_LIBLAME=no) +AC_CHECK_HEADER(lame/lame.h, :, HAVE_LIBLAME=no) dnl Check for libshout AC_MSG_CHECKING(Shout library) AC_CHECK_LIB(shout, shout_init_connection, HAVE_LIBSHOUT=yes, HAVE_LIBSHOUT=no, ) AC_CHECK_HEADER(shout/shout.h, :, HAVE_LIBSHOUT=no) +dnl Check for mpeg2dec +AC_MSG_CHECKING(mpeg2dec library) +AC_CHECK_LIB(mpeg2, mpeg2_init, HAVE_MPEG2DEC=yes, HAVE_MPEG2DEC=no, ) +AC_CHECK_HEADER(mpeg2dec/mpeg2.h, :, HAVE_MPEG2DEC=no) + +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 if css-auth.c exists (FIXME) AC_MSG_CHECKING(DVD CSS code) @@ -368,6 +445,17 @@ else HAVE_CSSAUTH="no" fi +dnl Check for linux/cdrom.h +AC_CHECK_HEADER(linux/cdrom.h, + AC_DEFINE(HAVE_LINUX_CDROM) + HAVE_LINUX_CDROM=yes, [] +) + +dnl Check for linux/videodev.h +AC_CHECK_HEADER(linux/videodev.h, + AC_DEFINE(HAVE_LINUX_VIDEODEV) + HAVE_LINUX_VIDEODEV=yes, [] +) dnl ###################################################################### @@ -487,6 +575,27 @@ AC_ARG_WITH(win32_libdir, esac], [:]) dnl Default value +AC_ARG_ENABLE(docs-build, +[ --disable-docs-build disable all building of documentation], +[case "${enableval}" in + yes) BUILD_DOCS=yes ;; + no) BUILD_DOCS=no ;; + *) AC_MSG_ERROR(bad value ${enableval} for --enable-docs-build) ;; +esac], +[BUILD_DOCS=yes]) dnl Default value + +AC_ARG_ENABLE(plugin-docs, +[ --enable-plugin-docs enable the building of plugin documentation + (this is currently broken, so off by default)], +[case "${enableval}" in + yes) BUILD_PLUGIN_DOCS=yes ;; + no) BUILD_PLUGIN_DOCS=no ;; + *) AC_MSG_ERROR(bad value ${enableval} for --enable-plugin-docs) ;; +esac], +[BUILD_PLUGIN_DOCS=no]) dnl Default value + + + dnl ################################################ dnl # Set defines according to variables set above # @@ -551,19 +660,27 @@ AM_CONDITIONAL(HAVE_CPU_I386, test "x$HAVE_CPU_I386" = "xyes") AM_CONDITIONAL(HAVE_CPU_PPC, test "x$HAVE_CPU_PPC" = "xyes") AM_CONDITIONAL(HAVE_CPU_ALPHA, test "x$HAVE_CPU_ALPHA" = "xyes") AM_CONDITIONAL(HAVE_CPU_ARM, test "x$HAVE_CPU_ARM" = "xyes") +AM_CONDITIONAL(HAVE_CPU_SPARC, test "x$HAVE_CPU_SPARC" = "xyes") AM_CONDITIONAL(HAVE_GDK_PIXBUF, test "x$USE_GDK_PIXBUF" = "xyes") AM_CONDITIONAL(HAVE_LIBGHTTP, test "x$USE_LIBGHTTP" = "xyes") AM_CONDITIONAL(HAVE_LIBMMX, test "x$USE_LIBMMX" = "xyes") AM_CONDITIONAL(HAVE_ATOMIC_H, test "x$USE_ATOMIC_H" = "xyes") +AM_CONDITIONAL(HAVE_OSS, test "x$HAVE_OSS" = "xyes") AM_CONDITIONAL(HAVE_XAUDIO, test "x$HAVE_XAUDIO" = "xyes") +AM_CONDITIONAL(HAVE_LIBMAD, test "x$HAVE_LIBMAD" = "xyes") +AM_CONDITIONAL(HAVE_LINUX_CDROM, test "x$HAVE_LINUX_CDROM" = "xyes") +AM_CONDITIONAL(HAVE_LINUX_VIDEODEV, test "x$HAVE_LINUX_VIDEODEV" = "xyes") AM_CONDITIONAL(HAVE_CSSAUTH, test "x$HAVE_CSSAUTH" = "xyes") AM_CONDITIONAL(HAVE_VORBIS, test "x$HAVE_VORBIS" = "xyes") AM_CONDITIONAL(HAVE_LIBJPEG, test "x$HAVE_LIBJPEG" = "xyes") +AM_CONDITIONAL(HAVE_LIBHERMES, test "x$HAVE_LIBHERMES" = "xyes") AM_CONDITIONAL(HAVE_NASM, test "x$HAVE_NASM" = "xyes") AM_CONDITIONAL(HAVE_LIBGLADE_GNOME, test "x$HAVE_LIBGLADE_GNOME" = "xyes") AM_CONDITIONAL(HAVE_GNOME, test "x$HAVE_GNOME" = "xyes") AM_CONDITIONAL(HAVE_LIBXV, test "x$HAVE_LIBXV" = "xyes") AM_CONDITIONAL(HAVE_GTK_DOC, $HAVE_GTK_DOC) +AM_CONDITIONAL(BUILD_DOCS, test "x$BUILD_DOCS" = "xyes") +AM_CONDITIONAL(BUILD_PLUGIN_DOCS, test "x$BUILD_PLUGIN_DOCS" = "xyes") AM_CONDITIONAL(HAVE_DB2HTML, $HAVE_DB2HTML) AM_CONDITIONAL(HAVE_DB2PS, $HAVE_DB2PS) AM_CONDITIONAL(HAVE_PS2PDF, $HAVE_PS2PDF) @@ -573,7 +690,11 @@ AM_CONDITIONAL(HAVE_CDPARANOIA, test "x$HAVE_CDPARANOIA" = "xyes") AM_CONDITIONAL(HAVE_LIBLAME, test "x$HAVE_LIBLAME" = "xyes") AM_CONDITIONAL(HAVE_LIBSHOUT, test "x$HAVE_LIBSHOUT" = "xyes") AM_CONDITIONAL(HAVE_LIBESD, test "x$HAVE_LIBESD" = "xyes") +AM_CONDITIONAL(HAVE_ARTSC, test "x$HAVE_ARTSC" = "xyes") 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") @@ -609,7 +730,10 @@ dnl ############################## dnl # Set up the defaults cflags # dnl ############################## dnl CC="kgcc" -CFLAGS="$CFLAGS -O6 -Wall" +CFLAGS="$CORE_CFLAGS $CFLAGS -O6 -Wall" +LIBS="$CORE_LIBS $LIBS" +AC_SUBST(CORE_LIBS) +AC_SUBST(CORE_CFLAGS) dnl FIXME: having to AC_SUBST these is messy. Not sure if CPPFLAGS and LDFLAGS dnl need it, either. @@ -648,14 +772,13 @@ dnl # Make the output files # dnl ######################### AC_OUTPUT([Makefile -intl/Makefile -po/Makefile.in include/Makefile include/wine/Makefile gst/Makefile gst/types/Makefile gst/meta/Makefile gst/elements/Makefile +gst/autoplug/Makefile libs/Makefile libs/riff/Makefile libs/colorspace/Makefile @@ -665,15 +788,18 @@ libs/putbits/Makefile libs/winloader/Makefile libs/idct/Makefile plugins/Makefile +plugins/alsa/Makefile plugins/au/Makefile -plugins/wav/Makefile +plugins/audioscale/Makefile plugins/avi/Makefile plugins/avi/wincodec/Makefile +plugins/flx/Makefile plugins/jpeg/Makefile plugins/mp3decode/Makefile plugins/mp3decode/types/Makefile plugins/mp3decode/xa/Makefile plugins/mp3decode/mpg123/Makefile +plugins/mp3decode/mad/Makefile plugins/mp3decode/parse/Makefile plugins/mp3encode/Makefile plugins/mp3encode/lame/Makefile @@ -696,10 +822,19 @@ plugins/mpeg1/system_encode/Makefile plugins/mpeg1/mpeg1encoder/Makefile plugins/mpeg1video/Makefile plugins/mpeg1video/parse/Makefile +plugins/oss/Makefile +plugins/rtp/Makefile +plugins/rtp/rtpsend/Makefile +plugins/mulaw/Makefile +plugins/alaw/Makefile plugins/filters/Makefile plugins/filters/smooth/Makefile plugins/filters/median/Makefile plugins/filters/ladspa/Makefile +plugins/filters/stereo2mono/Makefile +plugins/filters/passthrough/Makefile +plugins/filters/colorspace/Makefile +plugins/filters/volenv/Makefile plugins/icecast/Makefile plugins/icecast/icecastsend/Makefile plugins/effects/Makefile @@ -712,7 +847,8 @@ plugins/visualization/synaesthesia/Makefile plugins/visualization/smoothwave/Makefile plugins/videosink/Makefile plugins/videoscale/Makefile -plugins/audioscale/Makefile +plugins/xvideosink/Makefile +plugins/wav/Makefile plugins/dvdsrc/Makefile plugins/vcdsrc/Makefile plugins/rtjpeg/Makefile @@ -722,6 +858,9 @@ plugins/capture/v4l/Makefile plugins/cdparanoia/Makefile plugins/esd/Makefile plugins/esd/esdsink/Makefile +plugins/artsd/Makefile +plugins/xmms/Makefile +plugins/mulaw/Makefile gstplay/Makefile dnl components/bonobo-gstmediaplay/Makefile test/Makefile @@ -730,6 +869,9 @@ test/bindings/Makefile tests/Makefile tests/sched/Makefile tests/eos/Makefile +testsuite/Makefile +testsuite/capsnego/Makefile +tests/nego/Makefile examples/Makefile examples/autoplug/Makefile examples/helloworld/Makefile @@ -755,6 +897,7 @@ docs/plugins/Makefile docs/plugins/gstreamer-plugins.types docs/manual/Makefile docs/fwg/Makefile +debian/Makefile stamp.h gstreamer-config gstreamer.spec diff --git a/debian/.gitignore b/debian/.gitignore new file mode 100644 index 0000000000..693edc0e5e --- /dev/null +++ b/debian/.gitignore @@ -0,0 +1,2 @@ +*.debhelper +*substvars diff --git a/debian/Makefile.am b/debian/Makefile.am new file mode 100644 index 0000000000..4b4b3fa91a --- /dev/null +++ b/debian/Makefile.am @@ -0,0 +1,40 @@ +EXTRA_DIST = \ + Makefile.am \ + README.Debian \ + changelog \ + control \ + copyright \ + gsteditor.files \ + gsteditor.manpages \ + gsteditor.menu \ + gstmediaplay.files \ + gstmediaplay.manpages \ + gstmediaplay.menu \ + gstreamer-alsa.files \ + gstreamer-cdparanoia.files \ + gstreamer-common.files \ + gstreamer-doc.files \ + gstreamer-elements.files \ + gstreamer-esd.files \ + gstreamer-lame.files \ + gstreamer-mpeg2dec.files \ + gstreamer-mpg123.files \ + gstreamer-plugin-template.postinst \ + gstreamer-plugin-template.prerm \ + gstreamer-runtime.files \ + gstreamer-runtime.manpages \ + gstreamer-runtime.postinst \ + gstreamer-tools.files \ + gstreamer-tools.manpages \ + gstreamer-vorbis.files \ + libgst-dev.files \ + libgst-dev.manpages \ + libgst0.files \ + libgst0.postinst \ + libgsteditor-dev.files \ + libgsteditor0.files \ + libgsteditor0.postinst \ + libgstmediaplay-dev.files \ + libgstmediaplay0.files \ + libgstmediaplay0.postinst \ + rules diff --git a/debian/README.Debian b/debian/README.Debian new file mode 100644 index 0000000000..72064b54c2 --- /dev/null +++ b/debian/README.Debian @@ -0,0 +1,38 @@ +GStreamer for Debian +---------------------- +This package contains the GStreamer distribution. + +More information can be found at http://gstreamer.net/ + +GStreamer is split into a number of base packages: + + libgst0 shared core libs + libgst-dev development libs and headers + libgst-runtime tools required by the libs (gstreamer-register) + gstreamer-doc documentation + gstreamer-tools useful tools + +recommended plugins: + + gstreamer-elements core plugins + gstreamer-common many independent plugins + +optional plugins: + + gstreamer-cdparanoia cdparanoia plugin + gstreamer-esd ESD plugin + gstreamer-lame LAME plugin + gstreamer-mpg123 mpg123 plugin + gstreamer-vorbis Vorbis plugin + +and applications and their supporting libs: + + libgstmediaplay0 media player libs + libgstmediaplay-dev media player dev support + gstmediaplay media player application + + libgsteditor0 stream pipeline visual editor libs + libgsteditor-dev stream pipeline visual editor dev support + gsteditor stream pipeline visual editor application + +David I. Lehn Fri, 19 Jan 2001 19:13:06 -0500 diff --git a/debian/changelog b/debian/changelog new file mode 100644 index 0000000000..bdba5fea24 --- /dev/null +++ b/debian/changelog @@ -0,0 +1,40 @@ +gstreamer (0.1.1.20010320-1) unstable; urgency=low + + * Latest CVS code + * enable main docs + * disable broken plugin docs with new option + + -- David I. Lehn Tue, 20 Mar 2001 18:15:19 -0500 + +gstreamer (0.1.1.20010315-1) unstable; urgency=low + + * Latest CVS code + * Added man pages + * Split mpeg2dec to seperate plugin + * libgst Architectures updated to cothread supported archs + + -- David I. Lehn Thu, 15 Mar 2001 20:17:19 -0500 + +gstreamer (0.1.1-1) unstable; urgency=low + + * New upstream release + * disable docs build, broken at the momemnt + + -- David I. Lehn Sun, 25 Feb 2001 17:58:25 -0500 + +gstreamer (0.1.0-2) unstable; urgency=low + + * debian/rules: call configure instead of autogen.sh + + -- David I. Lehn Sat, 24 Feb 2001 18:31:36 -0500 + +gstreamer (0.1.0-1) unstable; urgency=low + + * Initial Release. + + -- David I. Lehn Mon, 15 Jan 2001 18:25:18 -0500 + +Local variables: +mode: debian-changelog +add-log-mailing-address "dlehn@vt.edu" +End: diff --git a/debian/control b/debian/control new file mode 100644 index 0000000000..c04bc141b4 --- /dev/null +++ b/debian/control @@ -0,0 +1,157 @@ +Source: gstreamer +Section: x11 +Priority: optional +Maintainer: David I. Lehn +Build-Depends: debhelper (>= 3.0.0), libxml-dev (>= 1.8.10), zlib1g-dev (>= 1:1.1.3), libghttp-dev (>= 1.0.6), libglib-dev (>= 1.2.8), libgtk1.2-dev (>= 1.2.8), libglade0-dev (>= 0.14), libglade-gnome0-dev (>= 0.14), libesd0-dev (>= 0.2.22), libcdparanoia0-dev (>= 3a9.7), libvorbis-dev (>= 1.0beta3), libgnome-dev (>= 1.2.11), libasound1-dev (>= 0.5.10), libghttp-dev (>= 1.0.9), libjpeg62-dev (>= 6b) +Build-Depends-Indep: debhelper (>= 3.0.0), gtk-doc-tools (>= 0.4.0), jade (>= 1.2.1), transfig (>= 3.2.3.c) +Standards-Version: 3.5.2.0 + +Package: libgst0 +Architecture: [alpha arm i386 powerpc sparc] +Section: libs +Depends: ${shlibs:Depends} +Suggests: gstreamer-elements, gstreamer-common +Description: Core GStreamer shared library + Core GStreamer shared library + +Package: libgst-dev +Architecture: any +Section: devel +Depends: libgst0 (= ${Source-Version}), libc6-dev +Recommends: gstreamer-doc (= ${Source-Version}) +Description: GStreamer development libraries and headers + GStreamer development libraries and headers + +Package: gstreamer-runtime +Architecture: any +Section: libs +Depends: ${shlibs:Depends} +Description: gstreamer-register binary needed to manage plugin registry + gstreamer-register binary needed to manage plugin registry + +Package: gstreamer-doc +Architecture: all +Section: doc +Recommends: libgst-dev (= ${Source-Version}) +Description: Core GStreamer documentation + Core GStreamer documentation + +Package: gstreamer-tools +Architecture: any +Section: x11 +Depends: ${shlibs:Depends} +Suggests: gstreamer-common +Description: Tools for use with GStreamer + Tools for use with GStreamer + . + gstreamer-inspect: query details of installed plugins + gstreamer-launch: command line pipeline generator + +Package: libgstmediaplay0 +Architecture: any +Section: libs +Depends: ${shlibs:Depends} +Description: GStreamer media player library + GStreamer media player library + +Package: libgstmediaplay-dev +Architecture: any +Section: devel +Depends: libgstmediaplay0 (= ${Source-Version}), libc6-dev +Description: GStreamer media player development library and header + GStreamer media player development library and header + +Package: gstmediaplay +Architecture: any +Section: x11 +Depends: ${shlibs:Depends} +Suggests: gstreamer-common +Description: GStreamer media player + GStreamer media player + +Package: libgsteditor0 +Architecture: any +Section: libs +Depends: ${shlibs:Depends} +Description: GStreamer editor library + GStreamer editor library + +Package: libgsteditor-dev +Architecture: any +Section: devel +Depends: libgsteditor0 (= ${Source-Version}), libc6-dev +Description: GStreamer editor development library and header + GStreamer editor development library and header + +Package: gsteditor +Architecture: any +Section: x11 +Depends: ${shlibs:Depends} +Suggests: gstreamer-common +Description: GStreamer editor + GStreamer editor + +Package: gstreamer-alsa +Architecture: any +Section: libs +Depends: ${shlibs:Depends}, gstreamer-runtime +Description: ALSA plugin for GStreamer + ALSA plugin for GStreamer + +Package: gstreamer-cdparanoia +Architecture: any +Section: libs +Depends: ${shlibs:Depends}, gstreamer-runtime +Description: cdparanoia plugin for GStreamer + cdparanoia plugin for GStreamer + +Package: gstreamer-common +Architecture: any +Section: libs +Depends: ${shlibs:Depends}, gstreamer-runtime +Description: Collection of GStreamer plugins + Collection of GStreamer plugins + . + These plugins have no special dependencies. + +Package: gstreamer-elements +Architecture: any +Section: libs +Depends: ${shlibs:Depends}, gstreamer-runtime +Description: Core elements plugin for GStreamer + Core elements plugin for GStreamer + +Package: gstreamer-esd +Architecture: any +Section: libs +Depends: ${shlibs:Depends}, gstreamer-runtime +Description: Enlightened Sound Daemon plugin for GStreamer + Enlightened Sound Daemon plugin for GStreamer + +Package: gstreamer-lame +Architecture: any +Section: libs +Depends: ${shlibs:Depends}, gstreamer-runtime +Description: LAME plugin for GStreamer + LAME plugin for GStreamer + +Package: gstreamer-mpeg2dec +Architecture: any +Section: libs +Depends: ${shlibs:Depends}, gstreamer-runtime +Description: mpeg2dec plugin for GStreamer + mpeg2dec plugin for GStreamer + +Package: gstreamer-mpg123 +Architecture: any +Section: libs +Depends: ${shlibs:Depends}, gstreamer-runtime +Description: mpg123 plugin for GStreamer + mpg123 plugin for GStreamer + +Package: gstreamer-vorbis +Architecture: any +Section: libs +Depends: ${shlibs:Depends}, gstreamer-runtime +Description: Vorbis plugin for GStreamer + Vorbis plugin for GStreamer diff --git a/debian/copyright b/debian/copyright new file mode 100644 index 0000000000..fa8250bbe5 --- /dev/null +++ b/debian/copyright @@ -0,0 +1,29 @@ +This package was debianized by David I. Lehn on +Mon, 15 Jan 2001 18:21:37 -0500. + +It was downloaded from http://gstreamer.net/ + +Upstream Author(s): + Erik Walthinsen + Wim Taymans + Richard Boulton + +Copyright: + + This package is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This package 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 + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this package; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + +On Debian GNU/Linux systems, the complete text of the GNU Lesser General +Public License can be found in `/usr/share/common-licenses/LGPL'. + diff --git a/debian/gsteditor.files b/debian/gsteditor.files new file mode 100644 index 0000000000..22e2d6e96c --- /dev/null +++ b/debian/gsteditor.files @@ -0,0 +1,2 @@ +usr/bin/gsteditor +usr/share/gsteditor diff --git a/debian/gsteditor.manpages b/debian/gsteditor.manpages new file mode 100644 index 0000000000..a9813c2b1b --- /dev/null +++ b/debian/gsteditor.manpages @@ -0,0 +1 @@ +debian/gstreamer/usr/share/man/man1/gsteditor.1 diff --git a/debian/gsteditor.menu b/debian/gsteditor.menu new file mode 100644 index 0000000000..c78b4d2517 --- /dev/null +++ b/debian/gsteditor.menu @@ -0,0 +1,5 @@ +?package(gsteditor): \ + needs=X11 \ + section=Apps/Viewers \ + title="GStreamer Editor" \ + command="/usr/bin/gsteditor" diff --git a/debian/gstmediaplay.files b/debian/gstmediaplay.files new file mode 100644 index 0000000000..be0f4c8551 --- /dev/null +++ b/debian/gstmediaplay.files @@ -0,0 +1,2 @@ +usr/bin/gstmediaplay +usr/share/gstmediaplay diff --git a/debian/gstmediaplay.manpages b/debian/gstmediaplay.manpages new file mode 100644 index 0000000000..27951e8d4a --- /dev/null +++ b/debian/gstmediaplay.manpages @@ -0,0 +1 @@ +debian/gstreamer/usr/share/man/man1/gstmediaplay.1 diff --git a/debian/gstmediaplay.menu b/debian/gstmediaplay.menu new file mode 100644 index 0000000000..904038cde3 --- /dev/null +++ b/debian/gstmediaplay.menu @@ -0,0 +1,5 @@ +?package(gstmediaplay): \ + needs=X11 \ + section=Apps/Viewers \ + title="GStreamer Media Player" \ + command="/usr/bin/gstmediaplay" diff --git a/debian/gstreamer-alsa.files b/debian/gstreamer-alsa.files new file mode 100644 index 0000000000..969dc6efe5 --- /dev/null +++ b/debian/gstreamer-alsa.files @@ -0,0 +1,2 @@ +usr/lib/gst/libalsasrc.* +usr/lib/gst/libalsasink.* diff --git a/debian/gstreamer-cdparanoia.files b/debian/gstreamer-cdparanoia.files new file mode 100644 index 0000000000..b347fa11f8 --- /dev/null +++ b/debian/gstreamer-cdparanoia.files @@ -0,0 +1 @@ +usr/lib/gst/libcdparanoia.* diff --git a/debian/gstreamer-common.files b/debian/gstreamer-common.files new file mode 100644 index 0000000000..e1a8080f0c --- /dev/null +++ b/debian/gstreamer-common.files @@ -0,0 +1,47 @@ +usr/lib/gst/libgstriff.* +usr/lib/gst/libgstcolorspace.* +usr/lib/gst/libgstgetbits.* +usr/lib/gst/libgstparsewav.* +usr/lib/gst/libgstputbits.* +usr/lib/gst/libgstidct.* +usr/lib/gst/libgsttypes.* +usr/lib/gst/libgstvideoscale.* +usr/lib/gst/libwinloader.* +usr/lib/gst/libgstparseau.* +usr/lib/gst/libmp3parse.* +usr/lib/gst/libmp3types.* +usr/lib/gst/libstereo.* +usr/lib/gst/libvolume.* +usr/lib/gst/libgstspectrum.* +usr/lib/gst/libvumeter.* +usr/lib/gst/libsynaesthesia.* +usr/lib/gst/libsmoothwave.* +usr/lib/gst/libmpeg2parse.* +usr/lib/gst/libac3dec.* +usr/lib/gst/libac3parse.* +usr/lib/gst/libmpeg2play.* +usr/lib/gst/libmpeg2enc.* +usr/lib/gst/libmpeg2subt.* +usr/lib/gst/libmp2videoparse.* +usr/lib/gst/libmpeg2types.* +usr/lib/gst/libmpeg1parse.* +usr/lib/gst/libmpeg_play.* +usr/lib/gst/libmpeg1encoder.* +usr/lib/gst/libsystem_encode.* +usr/lib/gst/libmpegaudio.* +usr/lib/gst/libmpeg1types.* +usr/lib/gst/libvcdsrc.* +usr/lib/gst/librtjpeg.* +usr/lib/gst/libvideosink.* +usr/lib/gst/libv4lsrc.* +usr/lib/gst/libjpeg.* +usr/lib/gst/libmp1videoparse.* +usr/lib/gst/libvideoscale.* +usr/lib/gst/libsmooth.* +usr/lib/gst/libmedian.* +usr/lib/gst/libgstladspa.* +usr/lib/gst/libaudioscale.* +usr/lib/gst/libwincodec.* +usr/lib/gst/libaviencoder.* +usr/lib/gst/libavidecoder.* +usr/lib/gst/libdvdsrc.* diff --git a/debian/gstreamer-doc.files b/debian/gstreamer-doc.files new file mode 100644 index 0000000000..c6ff27539a --- /dev/null +++ b/debian/gstreamer-doc.files @@ -0,0 +1 @@ +usr/share/gstreamer diff --git a/debian/gstreamer-elements.files b/debian/gstreamer-elements.files new file mode 100644 index 0000000000..1941134be3 --- /dev/null +++ b/debian/gstreamer-elements.files @@ -0,0 +1,3 @@ +usr/lib/gst/libgstelements.* +usr/lib/gst/libgststaticautoplug.* +usr/lib/gst/libgststaticautoplugrender.* diff --git a/debian/gstreamer-esd.files b/debian/gstreamer-esd.files new file mode 100644 index 0000000000..dbfa96fc28 --- /dev/null +++ b/debian/gstreamer-esd.files @@ -0,0 +1 @@ +usr/lib/gst/libesdsink.* diff --git a/debian/gstreamer-lame.files b/debian/gstreamer-lame.files new file mode 100644 index 0000000000..ab21a06129 --- /dev/null +++ b/debian/gstreamer-lame.files @@ -0,0 +1 @@ +usr/lib/gst/libgstlame.* diff --git a/debian/gstreamer-mpeg2dec.files b/debian/gstreamer-mpeg2dec.files new file mode 100644 index 0000000000..22a51b6fd3 --- /dev/null +++ b/debian/gstreamer-mpeg2dec.files @@ -0,0 +1 @@ +usr/lib/gst/libmpeg2dec.* diff --git a/debian/gstreamer-mpg123.files b/debian/gstreamer-mpg123.files new file mode 100644 index 0000000000..f360298564 --- /dev/null +++ b/debian/gstreamer-mpg123.files @@ -0,0 +1 @@ +usr/lib/gst/libmpg123.* diff --git a/debian/gstreamer-plugin-template.postinst b/debian/gstreamer-plugin-template.postinst new file mode 100644 index 0000000000..b3a2e1807f --- /dev/null +++ b/debian/gstreamer-plugin-template.postinst @@ -0,0 +1,25 @@ +#! /bin/sh +# template plugin postinst script + +set -e + +case "$1" in + configure) + # Update shared lib deps + gstreamer-register + ;; + + abort-upgrade|abort-remove|abort-deconfigure) + + ;; + + *) + echo "postinst called with unknown argument \`$1'" >&2 + exit 0 + ;; +esac + +#DEBHELPER# + +exit 0 + diff --git a/debian/gstreamer-plugin-template.prerm b/debian/gstreamer-plugin-template.prerm new file mode 100644 index 0000000000..4a581177ed --- /dev/null +++ b/debian/gstreamer-plugin-template.prerm @@ -0,0 +1,23 @@ +#! /bin/sh +# template plugin prerm script + +set -e + +case "$1" in + remove|upgrade|deconfigure) + # update the shared libs + gstreamer-register + + ;; + failed-upgrade) + ;; + *) + echo "prerm called with unknown argument \`$1'" >&2 + exit 0 + ;; +esac + +#DEBHELPER# + +exit 0 + diff --git a/debian/gstreamer-runtime.files b/debian/gstreamer-runtime.files new file mode 100644 index 0000000000..4a423fb75a --- /dev/null +++ b/debian/gstreamer-runtime.files @@ -0,0 +1 @@ +usr/bin/gstreamer-register diff --git a/debian/gstreamer-runtime.manpages b/debian/gstreamer-runtime.manpages new file mode 100644 index 0000000000..e8f16e780d --- /dev/null +++ b/debian/gstreamer-runtime.manpages @@ -0,0 +1 @@ +debian/gstreamer/usr/share/man/man1/gstreamer-register.1 diff --git a/debian/gstreamer-runtime.postinst b/debian/gstreamer-runtime.postinst new file mode 100644 index 0000000000..8e649c5967 --- /dev/null +++ b/debian/gstreamer-runtime.postinst @@ -0,0 +1,47 @@ +#!/bin/sh +# postinst script for gstreamer +# +# see: dh_installdeb(1) + +set -e + +# summary of how this script can be called: +# * `configure' +# * `abort-upgrade' +# * `abort-remove' `in-favour' +# +# * `abort-deconfigure' `in-favour' +# `removing' +# +# for details, see /usr/share/doc/packaging-manual/ +# +# quoting from the policy: +# Any necessary prompting should almost always be confined to the +# post-installation script, and should be protected with a conditional +# so that unnecessary prompting doesn't happen if a package's +# installation fails and the `postinst' is called with `abort-upgrade', +# `abort-remove' or `abort-deconfigure'. + +case "$1" in + configure) + gstreamer-register + ;; + + abort-upgrade|abort-remove|abort-deconfigure) + + ;; + + *) + echo "postinst called with unknown argument \`$1'" >&2 + exit 0 + ;; +esac + +# dh_installdeb will replace this with shell code automatically +# generated by other debhelper scripts. + +#DEBHELPER# + +exit 0 + + diff --git a/debian/gstreamer-tools.files b/debian/gstreamer-tools.files new file mode 100644 index 0000000000..5e029a3348 --- /dev/null +++ b/debian/gstreamer-tools.files @@ -0,0 +1,2 @@ +usr/bin/gstreamer-inspect +usr/bin/gstreamer-launch diff --git a/debian/gstreamer-tools.manpages b/debian/gstreamer-tools.manpages new file mode 100644 index 0000000000..554de6cb37 --- /dev/null +++ b/debian/gstreamer-tools.manpages @@ -0,0 +1,2 @@ +debian/gstreamer/usr/share/man/man1/gstreamer-inspect.1 +debian/gstreamer/usr/share/man/man1/gstreamer-launch.1 diff --git a/debian/gstreamer-vorbis.files b/debian/gstreamer-vorbis.files new file mode 100644 index 0000000000..416b74183b --- /dev/null +++ b/debian/gstreamer-vorbis.files @@ -0,0 +1 @@ +usr/lib/gst/libgstvorbis.* diff --git a/debian/libgst-dev.files b/debian/libgst-dev.files new file mode 100644 index 0000000000..6d0eba8db5 --- /dev/null +++ b/debian/libgst-dev.files @@ -0,0 +1,6 @@ +usr/include +usr/share/aclocal +usr/bin/gstreamer-config +usr/lib/libgst.la +usr/lib/libgst.so +usr/lib/gst/libgstelements.la diff --git a/debian/libgst-dev.manpages b/debian/libgst-dev.manpages new file mode 100644 index 0000000000..f557ac564a --- /dev/null +++ b/debian/libgst-dev.manpages @@ -0,0 +1 @@ +debian/gstreamer/usr/share/man/man1/gstreamer-config.1 diff --git a/debian/libgst0.files b/debian/libgst0.files new file mode 100644 index 0000000000..1f4bb431e3 --- /dev/null +++ b/debian/libgst0.files @@ -0,0 +1 @@ +usr/lib/libgst.so.* diff --git a/debian/libgst0.postinst b/debian/libgst0.postinst new file mode 100644 index 0000000000..6a6aff91d1 --- /dev/null +++ b/debian/libgst0.postinst @@ -0,0 +1,47 @@ +#!/bin/sh +# postinst script for gstreamer +# +# see: dh_installdeb(1) + +set -e + +# summary of how this script can be called: +# * `configure' +# * `abort-upgrade' +# * `abort-remove' `in-favour' +# +# * `abort-deconfigure' `in-favour' +# `removing' +# +# for details, see /usr/share/doc/packaging-manual/ +# +# quoting from the policy: +# Any necessary prompting should almost always be confined to the +# post-installation script, and should be protected with a conditional +# so that unnecessary prompting doesn't happen if a package's +# installation fails and the `postinst' is called with `abort-upgrade', +# `abort-remove' or `abort-deconfigure'. + +case "$1" in + configure) + ldconfig + ;; + + abort-upgrade|abort-remove|abort-deconfigure) + + ;; + + *) + echo "postinst called with unknown argument \`$1'" >&2 + exit 0 + ;; +esac + +# dh_installdeb will replace this with shell code automatically +# generated by other debhelper scripts. + +#DEBHELPER# + +exit 0 + + diff --git a/debian/libgsteditor-dev.files b/debian/libgsteditor-dev.files new file mode 100644 index 0000000000..0e4c1bcdf7 --- /dev/null +++ b/debian/libgsteditor-dev.files @@ -0,0 +1,2 @@ +usr/lib/libgsteditor.la +usr/lib/libgsteditor.so diff --git a/debian/libgsteditor0.files b/debian/libgsteditor0.files new file mode 100644 index 0000000000..f220031216 --- /dev/null +++ b/debian/libgsteditor0.files @@ -0,0 +1 @@ +usr/lib/libgsteditor.so.* diff --git a/debian/libgsteditor0.postinst b/debian/libgsteditor0.postinst new file mode 100644 index 0000000000..6a6aff91d1 --- /dev/null +++ b/debian/libgsteditor0.postinst @@ -0,0 +1,47 @@ +#!/bin/sh +# postinst script for gstreamer +# +# see: dh_installdeb(1) + +set -e + +# summary of how this script can be called: +# * `configure' +# * `abort-upgrade' +# * `abort-remove' `in-favour' +# +# * `abort-deconfigure' `in-favour' +# `removing' +# +# for details, see /usr/share/doc/packaging-manual/ +# +# quoting from the policy: +# Any necessary prompting should almost always be confined to the +# post-installation script, and should be protected with a conditional +# so that unnecessary prompting doesn't happen if a package's +# installation fails and the `postinst' is called with `abort-upgrade', +# `abort-remove' or `abort-deconfigure'. + +case "$1" in + configure) + ldconfig + ;; + + abort-upgrade|abort-remove|abort-deconfigure) + + ;; + + *) + echo "postinst called with unknown argument \`$1'" >&2 + exit 0 + ;; +esac + +# dh_installdeb will replace this with shell code automatically +# generated by other debhelper scripts. + +#DEBHELPER# + +exit 0 + + diff --git a/debian/libgstmediaplay-dev.files b/debian/libgstmediaplay-dev.files new file mode 100644 index 0000000000..b6c11f62fb --- /dev/null +++ b/debian/libgstmediaplay-dev.files @@ -0,0 +1,2 @@ +usr/lib/libgstmediaplay.la +usr/lib/libgstmediaplay.so diff --git a/debian/libgstmediaplay0.files b/debian/libgstmediaplay0.files new file mode 100644 index 0000000000..763c8fc0c7 --- /dev/null +++ b/debian/libgstmediaplay0.files @@ -0,0 +1 @@ +usr/lib/libgstmediaplay.so.* diff --git a/debian/libgstmediaplay0.postinst b/debian/libgstmediaplay0.postinst new file mode 100644 index 0000000000..6a6aff91d1 --- /dev/null +++ b/debian/libgstmediaplay0.postinst @@ -0,0 +1,47 @@ +#!/bin/sh +# postinst script for gstreamer +# +# see: dh_installdeb(1) + +set -e + +# summary of how this script can be called: +# * `configure' +# * `abort-upgrade' +# * `abort-remove' `in-favour' +# +# * `abort-deconfigure' `in-favour' +# `removing' +# +# for details, see /usr/share/doc/packaging-manual/ +# +# quoting from the policy: +# Any necessary prompting should almost always be confined to the +# post-installation script, and should be protected with a conditional +# so that unnecessary prompting doesn't happen if a package's +# installation fails and the `postinst' is called with `abort-upgrade', +# `abort-remove' or `abort-deconfigure'. + +case "$1" in + configure) + ldconfig + ;; + + abort-upgrade|abort-remove|abort-deconfigure) + + ;; + + *) + echo "postinst called with unknown argument \`$1'" >&2 + exit 0 + ;; +esac + +# dh_installdeb will replace this with shell code automatically +# generated by other debhelper scripts. + +#DEBHELPER# + +exit 0 + + diff --git a/debian/rules b/debian/rules new file mode 100755 index 0000000000..feef988772 --- /dev/null +++ b/debian/rules @@ -0,0 +1,147 @@ +#!/usr/bin/make -f +# Sample debian/rules that uses debhelper. +# GNU copyright 1997 by Joey Hess. +# + +# Uncomment this to turn on verbose mode. +#export DH_VERBOSE=1 + +# This is the debhelper compatability version to use. +export DH_COMPAT=3 + +# This has to be exported to make some magic below work. +export DH_OPTIONS + +# The plugins are basically the same. +# Link special names to a template file. +# still need "*.files" to be done by hand + +PLUGINS=alsa cdparanoia common elements esd lame mpeg2dec mpg123 vorbis + +setup-links: + for i in $(PLUGINS); do \ + ln -fs debian/gstreamer-plugin-template.postinst \ + debian/gstreamer-$$i.postinst; \ + ln -fs debian/gstreamer-plugin-template.prerm \ + debian/gstreamer-$$i.prerm; \ + done + +configure: configure-stamp +configure-stamp: + dh_testdir + # Add here commands to configure the package. + ./configure \ + --prefix=/usr \ + --mandir=\$${prefix}/share/man \ + --infodir=\$${prefix}/share/info \ + --with-configdir=/etc/gstreamer \ + --disable-plugin-srcdir \ + --enable-docs-build \ + --disable-plugin-docs + + touch configure-stamp + +build: configure-stamp build-stamp +build-stamp: + dh_testdir + + # Add here commands to compile the package. + $(MAKE) + + touch build-stamp + +clean: + dh_testdir + dh_testroot + rm -f build-stamp configure-stamp + + # Add here commands to clean up after the build process. + -$(MAKE) distclean + + dh_clean + + for i in $(PLUGINS); do \ + rm -f debian/gstreamer-$$i.postinst; \ + rm -f debian/gstreamer-$$i.prerm; \ + done + +install: DH_OPTIONS= +install: build + dh_testdir + dh_testroot + dh_clean -k + dh_installdirs + + # Add here commands to install the package into debian/gstreamer. + $(MAKE) install prefix=$(CURDIR)/debian/gstreamer/usr + + dh_movefiles --sourcedir=debian/gstreamer + +# Build architecture-independent files here. +# Pass -i to all debhelper commands in this target to reduce clutter. +binary-indep: DH_OPTIONS=-i +binary-indep: build install +# Need this version of debhelper for DH_OPTIONS to work. + dh_testdir + dh_testroot +# dh_installdebconf + dh_installdocs + dh_installexamples + dh_installmenu +# dh_installemacsen +# dh_installpam +# dh_installinit +# dh_installcron + dh_installman +# dh_installinfo +# dh_undocumented + dh_installchangelogs ChangeLog + dh_strip +# dh_link + dh_compress + dh_fixperms +# You may want to make some executables suid here. +# dh_suidregister + dh_installdeb +# dh_makeshlibs +# dh_perl +# dh_shlibdeps + dh_gencontrol + dh_md5sums + dh_builddeb + +# Build architecture-dependent files here. +# Pass -a to all debhelper commands in this target to reduce clutter. +binary-arch: DH_OPTIONS=-a +binary-arch: build install setup-links +# Need this version of debhelper for DH_OPTIONS to work. + dh_testdir + dh_testroot +# dh_installdebconf + dh_installdocs + dh_installexamples + dh_installmenu +# dh_installemacsen +# dh_installpam +# dh_installinit +# dh_installcron + dh_installman +# dh_installinfo + dh_undocumented + dh_installchangelogs ChangeLog + dh_strip +# dh_link + dh_compress + dh_fixperms +# You may want to make some executables suid here. +# dh_suidregister + dh_installdeb + dh_makeshlibs +# dh_perl + dh_shlibdeps -l`pwd`/debian/libgst0/usr/lib:`pwd`/debian/libgstmediaplay0/usr/lib:`pwd`/debian/libgsteditor0/usr/lib + dh_gencontrol + dh_md5sums + dh_builddeb + +binary: binary-indep binary-arch +.PHONY: build clean binary-indep binary-arch binary install configure diff --git a/docs/Makefile.am b/docs/Makefile.am index f6fd3b4500..3b1e294008 100644 --- a/docs/Makefile.am +++ b/docs/Makefile.am @@ -1,4 +1,11 @@ -SUBDIRS = manual fwg gst libs + +if BUILD_PLUGIN_DOCS +SUBDIRS_PLUGINS = plugins +else +SUBDIRS_PLUGINS = +endif + +SUBDIRS = manual fwg gst libs $(SUBDIRS_PLUGINS) EXTRA_DIST = random slides manuals.mak diff --git a/docs/fwg/Makefile.am b/docs/fwg/Makefile.am index bd4be9b47e..6bd6a674af 100644 --- a/docs/fwg/Makefile.am +++ b/docs/fwg/Makefile.am @@ -4,11 +4,8 @@ htmlname = index.html sgml_files = gst-plugin-writers-guide.sgml \ titlepage.sgml \ intro.sgml \ - concepts.sgml \ - firstplugin.sgml \ testapp.sgml \ - loopbased.sgml \ - typesnprops.sgml + loopbased.sgml fig_files = eps_files = diff --git a/docs/fwg/concepts.sgml b/docs/fwg/concepts.sgml deleted file mode 100644 index b50e9e8b4f..0000000000 --- a/docs/fwg/concepts.sgml +++ /dev/null @@ -1,82 +0,0 @@ - - Plugins - - Extensions to GStreamer can be made using a plugin mechanism. This is - used extensively in GStreamer even if only the standard package is - being used: a few very basic functions reside in the core library, and - all others are in a standard set of plugins. - - - Plugins are only loaded when needed: a plugin registry is used to - store the details of the plugins so that it is not neccessary to load - all plugins to determine which are needed. - This registry needs to be updated when a new plugin is added to the - system: see the gstreamer-register utility and the - documentation in the GStreamer Application Development - Manual for more details. - - - User extensions to GStreamer can be installed in the main plugin - directory, and will immediately be available for use in applications. - gstreamer-register should be run to update - the repository: but the system will work correctly even if it hasn't - been - it will just load the correct plugin faster. - - - User specific plugin directories and registries will be available in future - versions of GStreamer. - - - - - Elements - - Elements are at the core of GStreamer. Without elements, GStreamer is just - a bunch of pipe fittings with nothing to connect. A large number of - elements (filters, sources and sinks) ship with GStreamer, but extra - elements can also be written. - - - An element may be constructed in several different ways, but all must - conform to the same basic rules. A simple filter may be built with the - FilterFactory, where the only code that need be written is the actual - filter code. A more complex filter, or a source or sink, will need to be - written out fully for complete access to the features and performance - possible with GStreamer. - - - The implementation of a new element will be contained in a plugin: - a single plugin may contain the implementation of several elements, or - just a single one. - - - - - Buffers - - - - - - Scheduling - - - - - - Chain vs Loop Elements - - - - - - Typing and Properties - - - - - - Metadata - - - diff --git a/docs/fwg/firstplugin.sgml b/docs/fwg/firstplugin.sgml deleted file mode 100644 index 2ada120a2a..0000000000 --- a/docs/fwg/firstplugin.sgml +++ /dev/null @@ -1,156 +0,0 @@ - - Constructing the boilerplate - - The first thing to do when making a new element is to specify some basic - details about it: what its name is, who wrote it, what version number it - is, etc. We also need to define an object to represent the element and to - store the data the element needs. I shall refer to these details - collectively as the boilerplate. - - - - Doing it the hard way with GstObject - - The standard way of defining the boilerplate is simply to write some - code, and fill in some structures. The easiest way to do this is to - copy an example and modify according to your needs. - - - First we will examine the code you would be likely to place in a header - file (although since the interface to the code is entirely defined - by the pluging system, and doesn't depend on reading a header file, - this is not crucial.) - - The code here can be found in - examples/plugins/example.h - - - - /* Definition of structure storing data for this element. */ - typedef struct _GstExample GstExample; - struct _GstExample { - GstElement element; - - GstPad *sinkpad,*srcpad; - - gint8 active; - }; - - /* Standard definition defining a class for this element. */ - typedef struct _GstExampleClass GstExampleClass; - struct _GstExampleClass { - GstElementClass parent_class; - }; - - /* Standard macros for defining types for this element. */ - #define GST_TYPE_EXAMPLE \ - (gst_example_get_type()) - #define GST_EXAMPLE(obj) \ - (GTK_CHECK_CAST((obj),GST_TYPE_EXAMPLE,GstExample)) - #define GST_EXAMPLE_CLASS(klass) \ - (GTK_CHECK_CLASS_CAST((klass),GST_TYPE_EXAMPLE,GstExample)) - #define GST_IS_EXAMPLE(obj) \ - (GTK_CHECK_TYPE((obj),GST_TYPE_EXAMPLE)) - #define GST_IS_EXAMPLE_CLASS(obj) \ - (GTK_CHECK_CLASS_TYPE((klass),GST_TYPE_EXAMPLE)) - - /* Standard function returning type information. */ - GtkType gst_example_get_type(void); - - - - - - Doing it the easy way with FilterFactory - - A plan for the future is to create a FilterFactory, to make the - process of making a new filter a simple process of specifying a few - details, and writing a small amount of code to perform the actual - data processing. - - - Unfortunately, this hasn't yet been implemented. It is also likely - that when it is, it will not be possible to cover all the possibilities - available by writing the boilerplate yourself, so some plugins will - always need to be manually registered. - - - As a rough outline of what is planned: the FilterFactory will take a - list of appropriate function pointers, and data structures to define - a filter. With a reasonable measure of preprocessor magic, the - plugin writer will then simply need to provide definitions of the - functions and data structures desired, and a name for the filter, and - then call a macro from within plugin_init() which will register the - new filter. All the fluff that goes into the definition of a filter - will thus be hidden from view. - - - Ideally, we will come up with a way for various FilterFactory-provided - functions to be overridden, to the point where you can construct - almost the most complex stuff with it, it just saves typing. - - - Of course, the filter factory can be used to create sources and sinks - too: simply create a filter with only source or sink pads. - - - You may be thinking that this should really be called an - ElementFactory. Well, we agree, but there is already something else - justifiably ealled an ElementFactory (this is the thing which actually - makes instances of elements). There is also already something called - a PluginFactory. We just have too many factories and not enough words. - And since this isn't yet written, it doesn't get priority for claiming - a name. - - - - - - An identity filter - - - - - Building an object with pads - - - - - - Attaching functions - - - - - - - The chain function - - - - - - - The plugin_init function - - - - - Registering the types - - - - - - Registering the filter - - - - - - - Having multiple filters in a single plugin - - - - diff --git a/docs/fwg/gst-plugin-writers-guide.sgml b/docs/fwg/gst-plugin-writers-guide.sgml index 9f5fdf0d1b..a6734bc225 100644 --- a/docs/fwg/gst-plugin-writers-guide.sgml +++ b/docs/fwg/gst-plugin-writers-guide.sgml @@ -3,16 +3,10 @@ - - - - - - @@ -20,6 +14,8 @@ + +GStreamer"> ]> @@ -30,22 +26,22 @@ Introduction - GStreamer is a framework for creating + &GStreamer; is a framework for creating streaming media applications. It is extremely powerful and versatile, and this versatility stems in part from its modularity, and its ability to incorporate new modules seamlessly into its framework. This document describes how to extend the capabilities of - GStreamer by creating new plugins. + &GStreamer; by creating new plugins. It first describes the concepts required and the ways in which - GStreamer can be extended. It then goes + &GStreamer; can be extended. It then goes through a worked example of how to write a simple filter (for data processing), and how to test and debug it. More advanced concepts are then introduced, with worked examples of each. Next, writing source and sink elements (for performing input and output) is discussed. Finally, checklists of things to be sure to do when extending - GStreamer are presented. + &GStreamer; are presented. @@ -59,12 +55,361 @@ This section introduces the basic concepts required to understand the - issues involved in extending GStreamer + issues involved in extending &GStreamer; + + + Many of these concepts are explained in greater detail in the + GStreamer Application Development Manual, and are merely mentioned + here to refresh your memory. - &CONCEPTS; + + + Plugins + + Extensions to &GStreamer; can be made using a plugin mechanism. This is + used extensively in &GStreamer; even if only the standard package is + being used: a few very basic functions reside in the core library, and + all others are implemented in plugins. + + + Plugins are only loaded when needed: a plugin registry is used to + store the details of the plugins so that it is not neccessary to load + all plugins to determine which are needed. + This registry needs to be updated whenever a new plugin is added to the + system: see the gstreamer-register utility and the + documentation in the GStreamer Application Development + Manual for more details. + + + User extensions to &GStreamer; can be installed in the main plugin + directory, and will immediately be available for use in applications. + gstreamer-register should be run to update + the repository: but the system should work correctly even if it hasn't + been - it will just take longer to load the correct plugin. + + + User specific plugin directories and registries will be available + in future versions of &GStreamer;. + + + + + Elements + + Elements are at the core of &GStreamer;. Without elements, &GStreamer; + is just + a bunch of pipe fittings with nothing to connect. A large number of + elements (filters, sources and sinks) ship with &GStreamer;, but extra + elements can also be written. + + + An element may be constructed in several different ways, but all must + conform to the same basic rules. A simple filter may be built with the + FilterFactory, where the only code that need be written is the actual + filter code. A more complex filter, or a source or sink, will need to + be written out fully for complete access to the features and + performance possible with &GStreamer;. + + + The implementation of a new element will be contained in a plugin: + a single plugin may contain the implementation of several elements, or + just a single one. + + + + + Buffers + + Buffers are structures used to pass data between elements. All streams + of data are chopped up into chunks which are stored in buffers. + Buffers can be of any size, and also contain metadata indicating the + type of data contained in them. Buffers can be allocated by various + different schemes, and may either be passed on by elements or + unreferenced (and the memory used by the buffer freed). + + + + + Typing and Properties + + A type system is used to ensure that the data passed between elements + is in a recognised format, and that the various parameters required + to fully specify that format match up correctly. Each connection + that is made between elements has a specified type. This is related, + but different, to the metadata in buffers which describes the type + of data in that particular buffer. See later in this document for + details of the available types. + + + + + Metadata + + + + + + Scheduling + + + + + + Chain vs Loop Elements + + + + + + Autopluggers + + &GStreamer; has an autoplugging mechanism, which enables application + writers to simply specify start and end elements for a path, and + the system will then create a path which links these elements, + in accordance with the type information provided by the elements. + + + It is possible to devise many different schemes for generating such + pathways, perhaps to optimise based on special criteria, or with + some specific constraints. It is thus possible to define new + autoplugging systems, using the plugin system. + + + + + + + + Types and Properties + + + There is a very large set of possible types that may be used to + pass data between elements. Indeed, each new element that is defined + may use a new data format (though unless at least one other element + recognises that format, it will be most likely be useless since + nothing will be able to link with it). + + + In order for types to be useful, and for systems like autopluggers to + work, it is neccessary that all elements + agree on the type definitions, and which properties are required + for each type. The &GStreamer; framework itself + simply provides the ability to define types and parameters, but does + not fix the meaning of types and parameters, and does not enforce + standards on the creation of new types. This is a matter for + a policy to decide, not technical systems to enforce. + + + For now, the policy is simple: + + + + Do not create a new type if you could use one which already + exists. + + + + + If creating a new type, discuss it first with the other + &GStreamer; developers, on at least one of: IRC, mailing lists, + the &GStreamer; wiki. + + + + + Try to ensure that the name for a new format is as unlikely to + conflict with anything else created already, and is not a more + generalised name than it should be. For example: + "audio/compressed" would be too generalised a name to represent + audio data compressed with an mp3 codec. Instead "audio/mp3" + might be an appropriate name, or "audio/compressed" could exist + and have a property indicating the type of compression used. + + + + + Ensure that, when you do create a new type, you specify it + clearly, and get it added to the list of known types so that + other developers can use the type correctly when writing their + elements. + + + + + + + + The basic types + + This is a list of the basic types used for buffers. For each type, we + give the name ("mime type") of the type, the list of properties which + are associated with the type, the meaning of each property, and the + purpose of the type. + + + + + audio/raw + - Unstructured and uncompressed raw audio data. + + law + - The law used to describe the data. This is an integer for which + there are three valid values: 0 for linear, 1 for + mu law, 2 for A law. + + endianness + - The order of bytes in a sample. This is a boolean: + 0 means little-endian (ie, bytes are least significant first), + 1 means big-endian (ie, most significant byte first). + + signed + - Whether the samples are signed or not. This is a boolean: + 0 means unsigned, 1 means signed. + + width + - The number of bits per sample. This is extremely likely to be + a multiple of 8, but as ever this is up to each element supporting + this format to specify. + + depth + - The number of bits used per sample. This must be less than or + equal to the width: if less than the width, the low bits are + assumed to be the ones used. For example, width=32, depth=24 + means that each sample is stored in a 32 bit word, but only the + low 24 bits are actually used. + + rate + - The sample rate of the data, in samples per second. + + channels + - The number of channels of audio data. + + + For example: 16 bit, unsigned, linear, monophonic, big-endian, + 44100KHz audio would be represented by + "law=0,endianness=1,signed=0,width=16,depth=16,rate=44100,channels=1" + + + + + + + audio/mp3 + - Audio data compressed using the mp3 encoding scheme. + + framed + - This is a boolean. If true (1), each buffer contains exactly + one frame. If false (0), frames and buffers do not (necessarily) + match up. If the data is not framed, the values of some of the + properties will not be available, but others will be assumed to + be constant throughout the file, or may be found in other ways. + + layer + - The compression scheme layer used to compress the data. + This is an integer, and can currently have the value 1, 2 + or 3. + + bitrate + - The bitrate, in kilobits per second. + For VBR (variable bitrate) mp3 data, this is the average bitrate. + + channels + - The number of channels of audio data present. This could + theoretically be any integer greater than 0, but in practice will + be either 1 or 2. + + joint-stereo + - Boolean. If true, channels must not be zero. If true, this + implies that stereo data is stored as a combined signal and + the difference between the signals, rather than as two entirely + separate signals. + + There are many other properties relevant for + audio/mp3 data: these may be added to this + specification at a later date. + + + + + + + audio/x-ogg + - Audio data compressed using the Ogg Vorbis encoding scheme. + There are currently no parameters defined for this type. FIXME. + + + + + + + video/raw + - Raw video data. + + fourcc + - A FOURCC code identifying the format in which this data is + stored. FOURCC (Four Character Code) is a simple system to + allow unambiguous identification of a video datastream format. + See http://www.webartz.com/fourcc/ + + width + - The number of pixels wide that each video frame is. + + height + - The number of pixels high that each video frame is. + + + + + + + video/mpeg + - Video data compressed using an mpeg encoding scheme. + + mpegversion + + systemstream + + + + + + + video/avi + - Video data compressed using the AVI encoding scheme. + There are currently no parameters defined for this type. FIXME. + + + + + + + Building a simple format for testing + + + + + + A simple MIME type + + + + + + Type properties + + + + + + Typefind functions and autoplugging + + + @@ -86,7 +431,296 @@ - &FIRSTPLUGIN; + + Constructing the boilerplate + + The first thing to do when making a new element is to specify some basic + details about it: what its name is, who wrote it, what version number it + is, etc. We also need to define an object to represent the element and to + store the data the element needs. I shall refer to these details + collectively as the boilerplate. + + + + Doing it the hard way with GstObject + + The standard way of defining the boilerplate is simply to write some + code, and fill in some structures. The easiest way to do this is to + copy an example and modify according to your needs. + + + First we will examine the code you would be likely to place in a header + file (although since the interface to the code is entirely defined + by the pluging system, and doesn't depend on reading a header file, + this is not crucial.) + + The code here can be found in + examples/plugins/example.h + + + + /* Definition of structure storing data for this element. */ + typedef struct _GstExample GstExample; + + struct _GstExample { + GstElement element; + + GstPad *sinkpad,*srcpad; + + gint8 active; + }; + + /* Standard definition defining a class for this element. */ + typedef struct _GstExampleClass GstExampleClass; + struct _GstExampleClass { + GstElementClass parent_class; + }; + + /* Standard macros for defining types for this element. */ + #define GST_TYPE_EXAMPLE \ + (gst_example_get_type()) + #define GST_EXAMPLE(obj) \ + (GTK_CHECK_CAST((obj),GST_TYPE_EXAMPLE,GstExample)) + #define GST_EXAMPLE_CLASS(klass) \ + (GTK_CHECK_CLASS_CAST((klass),GST_TYPE_EXAMPLE,GstExample)) + #define GST_IS_EXAMPLE(obj) \ + (GTK_CHECK_TYPE((obj),GST_TYPE_EXAMPLE)) + #define GST_IS_EXAMPLE_CLASS(obj) \ + (GTK_CHECK_CLASS_TYPE((klass),GST_TYPE_EXAMPLE)) + + /* Standard function returning type information. */ + GtkType gst_example_get_type(void); + + + + + + Doing it the easy way with FilterFactory + + A plan for the future is to create a FilterFactory, to make the + process of making a new filter a simple process of specifying a few + details, and writing a small amount of code to perform the actual + data processing. + + + Unfortunately, this hasn't yet been implemented. It is also likely + that when it is, it will not be possible to cover all the possibilities + available by writing the boilerplate yourself, so some plugins will + always need to be manually registered. + + + As a rough outline of what is planned: the FilterFactory will take a + list of appropriate function pointers, and data structures to define + a filter. With a reasonable measure of preprocessor magic, the + plugin writer will then simply need to provide definitions of the + functions and data structures desired, and a name for the filter, and + then call a macro from within plugin_init() which will register the + new filter. All the fluff that goes into the definition of a filter + will thus be hidden from view. + + + Ideally, we will come up with a way for various FilterFactory-provided + functions to be overridden, to the point where you can construct + almost the most complex stuff with it, it just saves typing. + + + Of course, the filter factory can be used to create sources and sinks + too: simply create a filter with only source or sink pads. + + + You may be thinking that this should really be called an + ElementFactory. Well, we agree, but there is already something else + justifiably ealled an ElementFactory (this is the thing which actually + makes instances of elements). There is also already something called + a PluginFactory. We just have too many factories and not enough words. + And since this isn't yet written, it doesn't get priority for claiming + a name. + + + + + + Defining an element + + A new element is defined by creating an element factory. This is a + structure containing all the information needed to create an instance + of the element. Creating a factory requires two things: a type for + the element to be created + (this was defined in the boilerplate above: FIXME - reorganise), + and a GstElementDetails structure, which contains some + general information about the element to be created. + + + + GstElementDetails + + The GstElementDetails structure gives a heirarchical type for + the element, a human-readable description of the element, as + well as author and version data. The entries are: + + + + A long, english, name for the element. + + The type of the element, as a heirarchy. The heirarchy is defined + by specifying the top level category, followed by a "/", followed + by the next level category, etc. The type should be defined + according to the guidelines elsewhere in this document. + (FIXME: write the guidelines, and give a better reference to them) + + A brief description of the purpose of the element. + + The version number of the element. For elements in the main + GStreamer source code, this will often simply be VERSION, which is + a macro defined to be the version number of the current GStreamer + version. The only requirement, however, is that the version + number should increase monotonically. + + Version numbers should be stored in major.minor.patch form: ie, 3 + (decimal) numbers, separated by ".". + + The name of the author of the element, optionally followed by + a contact email address in angle brackets. + + The copyright details for the element. + + + + For example: + + + static GstElementDetails example_details = { + "An example plugin", + "Example/FirstExample", + "Shows the basic structure of a plugin", + VERSION, + "your name <your.name@your.isp>", + "(C) 2001", + }; + + + + + Constructor functions + + Each element has two functions which are used for construction of + an element. These are the _class_init() function, which is used to + initialise the class (specifying what signals and arguments the class + has and setting up global state), and the _init() function, which + is used to initialise a specific instance of the class. + + + + + Specifying the pads + + + + + + Attaching functions + + + + + + The chain function + + + + + + Adding arguments + + Define arguments in enum. + + + + + + Signals + + Define signals in enum. + + + + + + + Defining a type + + A new type is defined by creating an type factory. This is a + structure containing all the information needed to create an instance + of the type. + + + + + The plugin_init function + + Once we have written code defining all the parts of the plugin, + we need to write the plugin_init() function. This is a special + function, which is called as soon as the plugin is loaded, and + must return a pointer to a newly allocated GstPlugin structure. + This structure contains the details of all the facilities provided + by the plugin, and is the mechanism by which the definitions are + made available to the rest of the &GStreamer; system. Helper + functions are provided to help fill the + structure: for future compatability it is recommended that these + functions are used, as documented below, rather than attempting to + access the structure directly. + + + Note that the information returned by the plugin_init() function + will be cached in a central registry. For this reason, it is + important that the same information is always returned by + the function: for example, it must not make element factories + available based on runtime conditions. If an element can only + work in certain conditions (for example, if the soundcard is not + being used by some other process) this must be reflected by the + element being unable to enter the READY state if unavailable, rather + than the plugin attempting to deny existence of the plugin. + + + + Registering new types + + + + + void gst_plugin_add_type(GstPlugin *plugin, + GstTypeFactory *factory); + + + + + + + Registering new element factories + + + + void gst_plugin_add_factory(GstPlugin *plugin, + GstElementFactory *factory); + + + Multiple element factories can be provided by a single plugin: + all it needs to do is call gst_plugin_add_factory() for each + element factory it wishes to provide. + + + + + Registering new autopluggers + + + + void gst_plugin_add_autoplugger(GstPlugin *plugin, + GstAutoplugFactory *factory); + + + + @@ -112,17 +746,6 @@ &LOOPBASED; - - - Types and Properties - - - - - - &TYPESNPROPS; - - Buffers and Metadata diff --git a/docs/fwg/testapp.sgml b/docs/fwg/testapp.sgml index be0807291f..bfbd66abdd 100644 --- a/docs/fwg/testapp.sgml +++ b/docs/fwg/testapp.sgml @@ -17,7 +17,7 @@ - + Running the pipeline diff --git a/docs/fwg/titlepage.sgml b/docs/fwg/titlepage.sgml index 6893a4b9f1..c7b46aca1b 100644 --- a/docs/fwg/titlepage.sgml +++ b/docs/fwg/titlepage.sgml @@ -23,7 +23,7 @@ - + This material may be distributed only subject to the terms and conditions set forth in the Open Publication License, v1.0 or diff --git a/docs/fwg/typesnprops.sgml b/docs/fwg/typesnprops.sgml deleted file mode 100644 index acb30ace5d..0000000000 --- a/docs/fwg/typesnprops.sgml +++ /dev/null @@ -1,24 +0,0 @@ - - Building a simple format for testing - - - - - - A simple MIME type - - - - - - Type properties - - - - - - Typefind functions and autoplugging - - - - diff --git a/docs/gst/Makefile.am b/docs/gst/Makefile.am index d964cfea83..2f3f4b77bc 100644 --- a/docs/gst/Makefile.am +++ b/docs/gst/Makefile.am @@ -19,17 +19,13 @@ GST_LIBS += ../../gst/elements/libgstelements.la TARGET_DIR=$(HTML_DIR)/$(DOC_MODULE) tmpl_sources = \ - tmpl/audioraw.sgml \ tmpl/cothreads.sgml \ tmpl/gst.sgml \ tmpl/gstinfo.sgml \ - tmpl/gstasyncdisksrc.sgml \ tmpl/gstautoplug.sgml \ tmpl/gstscheduler.sgml \ tmpl/gstprops.sgml \ tmpl/gstcaps.sgml \ - tmpl/gstaudiosink.sgml \ - tmpl/gstaudiosrc.sgml \ tmpl/gstbin.sgml \ tmpl/gstbuffer.sgml \ tmpl/gstbufferpool.sgml \ @@ -56,8 +52,7 @@ tmpl_sources = \ tmpl/gsttype.sgml \ tmpl/gstutils.sgml \ tmpl/gstxml.sgml \ - tmpl/spectrum.sgml \ - tmpl/videoraw.sgml + tmpl/spectrum.sgml gstreamer_docdir = $(HTML_DIR) gstreamer_doc_DATA = \ @@ -89,7 +84,7 @@ gstreamer-decl.txt: scanobj: $(srcdir)/$(DOC_MODULE).types rm gstreamer-scan.o; ln -s gstreamer-scan.lo gstreamer-scan.o - env CC="$(LIBTOOL) $(CC)" CFLAGS="$(GST_CFLAGS) $(GLIB_CFLAGS) $(XML_CFLAGS) -I../../" LDFLAGS="$(GST_LIBS)"\ + env CC="$(LIBTOOL) $(CC)" CFLAGS="$(LIBGST_CFLAGS) $(GLIB_CFLAGS) $(XML_CFLAGS) -I../../" LDFLAGS="$(GST_LIBS)"\ gtkdoc-scanobj --module=$(DOC_MODULE) gtkdoc-scan --module=$(DOC_MODULE) --source-dir=$(DOC_SOURCE_DIR) diff --git a/docs/gst/gstreamer-docs.sgml b/docs/gst/gstreamer-docs.sgml index 9f52596507..5d4f9574ed 100644 --- a/docs/gst/gstreamer-docs.sgml +++ b/docs/gst/gstreamer-docs.sgml @@ -27,23 +27,20 @@ + + - - - - - ]> @@ -125,12 +122,8 @@ with some more specialized elements. &GstFakeSink; &GstDiskSrc; - &GstAsyncDiskSrc; &GstHttpSrc; - &GstAudioSrc; - &GstAudioSink; - &GstSineSrc; &GstFdSrc; @@ -148,8 +141,16 @@ with some more specialized elements. MetaData is used to specify the content of buffers. See GstMeta. &spectrum; - &audioraw; - &videoraw; + + + + GStreamer Autoppluggers + + the autopluggers provide a way to automatically construct elements based on + sink and src capabilities + + &GstStaticAutoplug; + &GstStaticAutoplugRender; diff --git a/docs/gst/gstreamer-sections.txt b/docs/gst/gstreamer-sections.txt index bd23c82583..ca9923f14c 100644 --- a/docs/gst/gstreamer-sections.txt +++ b/docs/gst/gstreamer-sections.txt @@ -120,6 +120,7 @@ gst_parse_launch GST_ARCH_CALL GST_ARCH_SET_SP GST_ARCH_SETUP_STACK +GST_ARCH_PRESETJMP
@@ -191,6 +192,7 @@ GST_ELEMENT_IS_COTHREAD_STOPPING GST_ELEMENT_IS_EOS GST_ELEMENT_PARENT GST_ELEMENT_NAME +GST_ELEMENT_PADS GstElement GstElementDetails GstElementFactory @@ -227,8 +229,6 @@ gst_elementfactory_find gst_elementfactory_get_list gst_elementfactory_can_src_caps gst_elementfactory_can_sink_caps -gst_elementfactory_can_src_caps_list -gst_elementfactory_can_sink_caps_list gst_elementfactory_create gst_elementfactory_make gst_elementfactory_save_thyself @@ -243,6 +243,32 @@ GST_IS_ELEMENT_CLASS gst_element_get_type
+
+gstautoplug +GstAutoplug +GstAutoplug +GstAutoplugFlags +GstAutoplugFactory +gst_autoplug_signal_new_object +gst_autoplug_to_caps +gst_autoplug_to_renderers +gst_autoplugfactory_new +gst_autoplugfactory_destroy +gst_autoplugfactory_find +gst_autoplugfactory_get_list +gst_autoplugfactory_create +gst_autoplugfactory_make +gst_autoplugfactory_save_thyself +gst_autoplugfactory_load_thyself + +GST_AUTOPLUG +GST_IS_AUTOPLUG +GST_TYPE_AUTOPLUG +gst_autoplug_get_type +GST_AUTOPLUG_CLASS +GST_IS_AUTOPLUG_CLASS +
+
gstclock GstClockTime @@ -340,9 +366,16 @@ GstPadGetFunction GstPadGetRegionFunction GstPadQoSFunction GstPadEOSFunction +GstPadNewCapsFunction + + +GstPadNegotiateReturn +GstPadNegotiateFunction + GstPadPushFunction GstPadPullFunction +GstRegionType GstPadPullRegionFunction GstPadDirection @@ -354,11 +387,12 @@ gst_pad_get_direction gst_pad_set_chain_function gst_pad_set_get_function gst_pad_set_getregion_function +gst_pad_set_negotiate_function gst_pad_set_qos_function gst_pad_set_eos_function -gst_pad_set_caps_list -gst_pad_get_caps_list -gst_pad_get_caps_by_name +gst_pad_set_newcaps_function +gst_pad_set_caps +gst_pad_get_caps gst_pad_check_compatibility gst_pad_set_name gst_pad_get_name @@ -366,6 +400,7 @@ gst_pad_set_element_private gst_pad_get_element_private gst_pad_set_parent gst_pad_get_parent +gst_pad_get_real_parent gst_pad_add_ghost_pad gst_pad_remove_ghost_pad gst_pad_get_ghost_pad_list @@ -374,13 +409,20 @@ gst_pad_connect gst_pad_disconnect gst_pad_push gst_pad_pull -gst_pad_pull_region gst_pad_pullregion -gst_pad_select gst_pad_set_eos gst_pad_handle_qos gst_pad_eos gst_pad_load_and_connect +gst_pad_negotiate_proxy +gst_pad_renegotiate +gst_pad_get_padtemplate +gst_pad_get_padtemplate_caps + + +GST_RPAD_LEN +GST_RPAD_OFFSET +GST_RPAD_REGIONTYPE GstRealPad GST_RPAD_DIRECTION @@ -395,26 +437,24 @@ GST_RPAD_PULLFUNC GST_RPAD_PULLREGIONFUNC GST_RPAD_QOSFUNC GST_RPAD_EOSFUNC +GST_RPAD_NEGOTIATEFUNC +GST_RPAD_NEWCAPSFUNC GST_GPAD_REALPAD GstGhostPad gst_ghost_pad_new -GstPadFactoryEntry -GstPadFactory[] -GST_PAD_FACTORY_SOMETIMES -GST_PAD_FACTORY_ALWAYS -GST_PAD_FACTORY_REQUEST -GST_PAD_FACTORY_SINK -GST_PAD_FACTORY_SRC -GST_PAD_FACTORY_CAPS - GstPadPresence GstPadTemplate +GST_PADTEMPLATE_CAPS +GST_PADTEMPLATE_DIRECTION +GST_PADTEMPLATE_NAME_TEMPLATE +GST_PADTEMPLATE_PRESENCE gst_padtemplate_new -gst_padtemplate_create gst_padtemplate_load_thyself gst_padtemplate_save_thyself +gst_padtemplate_get_caps +gst_padtemplate_get_caps_by_name GstPadClass @@ -455,9 +495,6 @@ gst_padtemplate_get_type GstPipeline GstPipeline gst_pipeline_new -gst_pipeline_add_sink -gst_pipeline_add_src -gst_pipeline_autoplug gst_pipeline_destroy gst_pipeline_iterate @@ -471,25 +508,6 @@ GST_IS_PIPELINE_CLASS gst_pipeline_details
-
-gstautoplug -GstAutoplug -GST_AUTOPLUG_MAX_COST -GstAutoplugCostFunction -GstAutoplugListFunction -gst_autoplug_caps -gst_autoplug_pads -gst_autoplug_caps_list - -GstAutoplug -GST_AUTOPLUG -GST_IS_AUTOPLUG -GST_TYPE_AUTOPLUG -gst_autoplug_get_type -GST_AUTOPLUG_CLASS -GST_IS_AUTOPLUG_CLASS -
-
gstplugin GstPlugin @@ -506,16 +524,19 @@ gst_plugin_is_loaded gst_plugin_load_all gst_plugin_load gst_plugin_load_absolute +gst_plugin_add_path gst_library_load gst_plugin_add_factory gst_plugin_add_type +gst_plugin_add_autoplugger gst_plugin_find gst_plugin_get_list gst_plugin_get_factory_list gst_plugin_get_type_list -gst_plugin_find_elementfactory +gst_plugin_get_autoplug_list gst_plugin_load_elementfactory gst_plugin_load_typefactory +gst_plugin_load_autoplugfactory gst_plugin_load_thyself gst_plugin_save_thyself @@ -591,63 +612,79 @@ gst_typefactory_save_thyself
gstcaps GstCaps +GST_CAPS_LOCK +GST_CAPS_TRYLOCK +GST_CAPS_UNLOCK GstCaps -GstCapsFactoryEntry -GstCapsFactory[] gst_caps_new -gst_caps_new_with_props -gst_caps_register -gst_caps_register_count +gst_caps_destroy +gst_caps_ref +gst_caps_unref +gst_caps_copy +gst_caps_copy_on_write +gst_caps_append +gst_caps_prepend +gst_caps_set_name gst_caps_get_name -gst_caps_set_mime gst_caps_set_type_id gst_caps_get_type_id +gst_caps_set_mime gst_caps_get_mime -gst_caps_set_name gst_caps_set_props gst_caps_get_props gst_caps_check_compatibility -gst_caps_list_check_compatibility + +gst_caps_set +gst_caps_get_boolean +gst_caps_get_by_name +gst_caps_get_fourcc_int +gst_caps_get_int +gst_caps_get_string + gst_caps_save_thyself gst_caps_load_thyself +GST_CAPS
gstprops GstProps GstProps -GstPropsFactoryEntry -GstPropsFactory[] +GST_MAKE_FOURCC GST_PROPS_LIST GST_PROPS_INT GST_PROPS_INT_RANGE GST_PROPS_FOURCC -GST_PROPS_FOURCC_INT GST_PROPS_BOOLEAN -gst_props_register -gst_props_register_count +GST_PROPS_STRING +GST_PROPS_FLOAT +GST_PROPS_FLOAT_RANGE gst_props_new +gst_props_newv gst_props_merge +gst_props_copy +gst_props_copy_on_write +gst_props_destroy +gst_props_ref +gst_props_unref gst_props_check_compatibility +gst_props_set +gst_props_get_boolean +gst_props_get_fourcc_int +gst_props_get_int +gst_props_get_string gst_props_save_thyself gst_props_load_thyself GstPropsEntry -GstPropsListFactory[] GstPropsId -GST_PROPS_END_ID -GST_PROPS_LIST_ID -GST_PROPS_INT_ID -GST_PROPS_INT_RANGE_ID -GST_PROPS_FOURCC_ID -GST_PROPS_BOOL_ID -GST_PROPS_LAST_ID
gstutils GstUtils +gst_util_set_object_arg gst_util_get_int_arg gst_util_get_bool_arg gst_util_get_long_arg @@ -691,49 +728,29 @@ gst_cpu_get_flags
-gstasyncdisksrc -GstAsyncDiskSrc -GstAsyncDiskSrcFlags +gststaticautoplug +GstStaticAutoplug -GstAsyncDiskSrc -GstAsyncDiskSrcClass -gst_asyncdisksrc_get_type -GST_TYPE_ASYNCDISKSRC -GST_ASYNCDISKSRC -GST_ASYNCDISKSRC_CLASS -GST_IS_ASYNCDISKSRC -GST_IS_ASYNCDISKSRC_CLASS +GstStaticAutoplug +GST_STATIC_AUTOPLUG +GST_IS_STATIC_AUTOPLUG +GST_TYPE_STATIC_AUTOPLUG +gst_static_autoplug_get_type +GST_STATIC_AUTOPLUG_CLASS +GST_IS_STATIC_AUTOPLUG_CLASS
-gstaudiosink -GstAudioSink +gststaticautoplugrender +GstStaticAutoplugRender -GstAudioSink -GstAudioSinkClass -GstAudioSinkFlags -gst_audiosink_get_type -GST_TYPE_AUDIOSINK -GST_AUDIOSINK -GST_AUDIOSINK_CLASS -GST_IS_AUDIOSINK -GST_IS_AUDIOSINK_CLASS -gst_audiosink_factory_init -
- -
-gstaudiosrc -GstAudioSrc - -GstAudioSrc -GstAudioSrcClass -GstAudioSrcFlags -gst_audiosrc_get_type -GST_TYPE_AUDIOSRC -GST_AUDIOSRC -GST_AUDIOSRC_CLASS -GST_IS_AUDIOSRC -GST_IS_AUDIOSRC_CLASS +GstStaticAutoplugRender +GST_STATIC_AUTOPLUG_RENDER +GST_IS_STATIC_AUTOPLUG_RENDER +GST_TYPE_STATIC_AUTOPLUG_RENDER +gst_static_autoplug_render_get_type +GST_STATIC_AUTOPLUG_RENDER_CLASS +GST_IS_STATIC_AUTOPLUG_RENDER_CLASS
@@ -749,7 +766,6 @@ GST_DISKSRC GST_DISKSRC_CLASS GST_IS_DISKSRC GST_IS_DISKSRC_CLASS -gst_disksrc_details
@@ -896,9 +912,17 @@ GST_IS_TYPEFIND_CLASS
-gst/meta/audioraw.h -audioraw -MetaAudioRaw +gstmultidisksrc +GstMultiDiskSrc +GstMultiDiskSrcFlags + +GstMultiDiskSrc +GST_MULTIDISKSRC +GST_IS_MULTIDISKSRC +GST_TYPE_MULTIDISKSRC +gst_multidisksrc_get_type +GST_MULTIDISKSRC_CLASS +GST_IS_MULTIDISKSRC_CLASS
@@ -907,12 +931,3 @@ MetaAudioRaw MetaAudioSpectrum
-
-gst/meta/videoraw.h -videoraw -MetaVideoRaw -MetaDGA -MetaOverlay -OverlayClip -
- diff --git a/docs/gst/gstreamer.hierarchy b/docs/gst/gstreamer.hierarchy index 74b32e6c65..3fcebbbbf3 100644 --- a/docs/gst/gstreamer.hierarchy +++ b/docs/gst/gstreamer.hierarchy @@ -9,12 +9,9 @@ GtkObject GstFakeSrc GstFakeSink GstDiskSrc - GstAsyncDiskSrc GstHttpSrc GstFdSrc - GstAudioSrc GstSineSrc - GstAudioSink GstFdSink GstPipefilter GstIdentity diff --git a/docs/gst/gstreamer.types.in b/docs/gst/gstreamer.types.in index 075d597d04..e693472018 100644 --- a/docs/gst/gstreamer.types.in +++ b/docs/gst/gstreamer.types.in @@ -16,13 +16,10 @@ gst_fakesrc_get_type gst_fakesink_get_type gst_disksrc_get_type -gst_asyncdisksrc_get_type @GST_HTTPSRC_GET_TYPE@ gst_fdsrc_get_type -gst_audiosrc_get_type gst_sinesrc_get_type -gst_audiosink_get_type gst_fdsink_get_type gst_pipefilter_get_type diff --git a/docs/gst/tmpl/gstarch.sgml b/docs/gst/tmpl/gstarch.sgml index c4a89c31ab..c8cc02a96c 100644 --- a/docs/gst/tmpl/gstarch.sgml +++ b/docs/gst/tmpl/gstarch.sgml @@ -38,3 +38,10 @@ gstarch @sp: + + + + + + + diff --git a/docs/gst/tmpl/gstasyncdisksrc.sgml b/docs/gst/tmpl/gstasyncdisksrc.sgml deleted file mode 100644 index ca7479d480..0000000000 --- a/docs/gst/tmpl/gstasyncdisksrc.sgml +++ /dev/null @@ -1,54 +0,0 @@ - -GstAsyncDiskSrc - - -Asynchronous disk reader. (asyncdisksrc) - - - -Reads data from a file. You can seek to a specific location by setting -the offset. - - - - - - - - - - - - - -GST_ASYNCDISKSRC_OPEN -the asyncdisksrc is open for reading - - - - - - -@GST_ASYNCDISKSRC_OPEN: -@GST_ASYNCDISKSRC_FLAG_LAST: - - - -Specify the location of the file to read. - - - - -Specify how many bytes to read at a time. - - - - -Specify the current offset in the file. - - - - - - - diff --git a/docs/gst/tmpl/gstaudiosink.sgml b/docs/gst/tmpl/gstaudiosink.sgml deleted file mode 100644 index 87e51aa4d3..0000000000 --- a/docs/gst/tmpl/gstaudiosink.sgml +++ /dev/null @@ -1,45 +0,0 @@ - -GstAudioSink - - -Output to a sound card via OSS. (audiosink) - - - -Output to a sound card via OSS. - - - - - - - - - -The buffer is sent to the sound card. - - -@gstaudiosink: the object which received the signal. - -@arg1: the audiosink. - - - - - - - - - - - - - - - - - - - - - diff --git a/docs/gst/tmpl/gstaudiosrc.sgml b/docs/gst/tmpl/gstaudiosrc.sgml deleted file mode 100644 index 721a58f3e7..0000000000 --- a/docs/gst/tmpl/gstaudiosrc.sgml +++ /dev/null @@ -1,41 +0,0 @@ - -GstAudioSrc - - -Read from the sound card. (audiosrc) - - - -Create buffers from an OSS sound card. - - - - - - - - - -The number of bytes per read. - - - - -Get the current number of bytes read. - - - - -The audio format as defined in soundcard.h - - - - -The number of channels (mono, stereo, ...) - - - - -The frequency. - - diff --git a/docs/gst/tmpl/gstautoplug.sgml b/docs/gst/tmpl/gstautoplug.sgml index 2ea069b281..528b68724e 100644 --- a/docs/gst/tmpl/gstautoplug.sgml +++ b/docs/gst/tmpl/gstautoplug.sgml @@ -2,12 +2,12 @@ GstAutoplug -Provide automatic element selection. +Automatically create and connect elements -The autoplugger can select a list of elements that are needed -to convert a certain GstCaps to another one. +GstAutoplug is an abstract class that is used for constructing and +connecting elements. @@ -15,60 +15,134 @@ to convert a certain GstCaps to another one. - - -The maximum cost of a certain connection. - - - - - - -Calculate the cost between two elements. - - -@src: the source element -@dest: the destination element -@data: optional user data -@Returns: the cost for a connection between the two elements - - - - -Get a list of all elements. These elements will be used in autoplugging. - - -@data: user data -@Returns: a GList of elements - - - + +@object: + + + + + + +@GST_AUTOPLUG_TO_CAPS: +@GST_AUTOPLUG_TO_RENDERER: +@GST_AUTOPLUG_FLAG_LAST: + + + + + + +@name: +@longdesc: +@type: + + + + + + +@autoplug: +@object: + + + + + + + +@autoplug: @srccaps: @sinkcaps: +@Varargs: @Returns: - - - - - -@srcpad: -@sinkpad: -@Returns: - - - + +@autoplug: @srccaps: -@sinkcaps: +@target: +@Varargs: +@Returns: + + + + + + + +@name: +@longdesc: +@type: +@Returns: + + + + + + + +@factory: + + + + + + + +@name: +@Returns: + + + + + + + +@Returns: + + + + + + + +@factory: +@Returns: + + + + + + + +@name: +@Returns: + + + + + + + +@factory: +@parent: +@Returns: + + + + + + + +@parent: @Returns: diff --git a/docs/gst/tmpl/gstbuffer.sgml b/docs/gst/tmpl/gstbuffer.sgml index 5b670acb07..9e6f6a2913 100644 --- a/docs/gst/tmpl/gstbuffer.sgml +++ b/docs/gst/tmpl/gstbuffer.sgml @@ -134,39 +134,6 @@ This macro releases a lock on the object. -FIXME this is strange. - - - - - -GST_BUFFER_READONLY -the buffer is read only - - - -GST_BUFFER_EOS -this buffer is the last one in the stream - - - -GST_BUFFER_ORIGINAL -this buffer not a copy - - - -GST_BUFFER_DONTFREE -do not try to free the data when this buffer is unref-ed - - - -GST_BUFFER_FLUSH -this buffer is not related to previous buffers. This flag is mainly -used when data in a stream has been skipped - - - - @GST_BUFFER_READONLY: the buffer is read only @@ -175,7 +142,7 @@ used when data in a stream has been skipped @GST_BUFFER_FLUSH: this buffer is not related to previous buffers. This flag is mainly used when data in a stream has been skipped @GST_BUFFER_EOS: this buffer is the last one in the stream -@GST_BUFFER_DISCONTINUOUS: +@GST_BUFFER_DISCONTINUOUS: The buffer has a discontinuity diff --git a/docs/gst/tmpl/gstcaps.sgml b/docs/gst/tmpl/gstcaps.sgml index 0ba8ee300a..9f1e9f3fc4 100644 --- a/docs/gst/tmpl/gstcaps.sgml +++ b/docs/gst/tmpl/gstcaps.sgml @@ -15,6 +15,30 @@ a mime-type and a set of properties. + + +Lock the caps structure + + +@caps: The caps structure to lock + + + + +Try to lock the caps structure + + +@caps: The caps structure to try to lock + + + + +Unlock the caps structure + + +@caps: The caps structure to unlock + + @@ -22,60 +46,91 @@ a mime-type and a set of properties. @name: the name of the capability, for the application @id: the typeid of the capability +@refcount: a refcounter for this caps structure +@lock: the lock for this caps structure @properties: the properties of the capability - - - - - - - - - - - - +@next: a pointer to the next caps. -@name: -@mime: -@Returns: - - - - - - - @name: @mime: @props: @Returns: - + -@factory: -@Returns: +@caps: - + -@factory: -@counter: +@caps: + + + + + + + +@caps: + + + + + + + +@caps: @Returns: - -@count: + + + + + + + +@caps: +@Returns: + + + + + + + +@caps: +@capstoadd: +@Returns: + + + + + + + +@caps: +@capstoadd: +@Returns: + + + + + + + +@caps: +@name: @@ -87,6 +142,27 @@ a mime-type and a set of properties. @Returns: + + + + + +@caps: +@type_id: + +@Param2: +@typeid: + + + + + + + +@caps: +@Returns: + + @@ -96,24 +172,6 @@ a mime-type and a set of properties. @mime: - - - - - -@caps: -@typeid: - - - - - - - -@caps: -@Returns: - - @@ -123,15 +181,6 @@ a mime-type and a set of properties. @Returns: - - - - - -@caps: -@name: - - @@ -159,21 +208,64 @@ a mime-type and a set of properties. @fromcaps: @tocaps: @Returns: - -@caps1: -@caps2: - + -@fromcaps: -@tocaps: +@caps: +@name: +@args...: + + + + + + + +@caps: +@name: + + + + + + + +@caps: +@name: @Returns: + + + + + +@caps: +@name: + + + + + + + +@caps: +@name: + + + + + + + +@caps: +@name: + + diff --git a/docs/gst/tmpl/gstcpu.sgml b/docs/gst/tmpl/gstcpu.sgml index 265ecbb5bb..cbf398b4a3 100644 --- a/docs/gst/tmpl/gstcpu.sgml +++ b/docs/gst/tmpl/gstcpu.sgml @@ -25,6 +25,8 @@ features of the CPU. @GST_CPU_FLAG_MMX: @GST_CPU_FLAG_SSE: +@GST_CPU_FLAG_MMXEXT: +@GST_CPU_FLAG_3DNOW: diff --git a/docs/gst/tmpl/gstdisksrc.sgml b/docs/gst/tmpl/gstdisksrc.sgml index 67c4fd6366..a7d80b5896 100644 --- a/docs/gst/tmpl/gstdisksrc.sgml +++ b/docs/gst/tmpl/gstdisksrc.sgml @@ -2,12 +2,11 @@ GstDiskSrc -Synchronous read from a file (disksrc) +Asynchronous read from a file (disksrc) -Synchonously read buffers from a file. If you need asynchronous reading -with seeking capabilities use a GstAsynDiskSrc instead. +Asynchonously read buffers from a file. @@ -45,11 +44,11 @@ Specify how many bytes to read at a time. -Get the current offset in the file. +Get/set the current offset in the file. - +Get the size of the file. diff --git a/docs/gst/tmpl/gstelement.sgml b/docs/gst/tmpl/gstelement.sgml index 14542ac1f0..05b2defa61 100644 --- a/docs/gst/tmpl/gstelement.sgml +++ b/docs/gst/tmpl/gstelement.sgml @@ -174,6 +174,14 @@ Get the name of this element. @obj: The element to query + + +Get the pads of this elements. + + +@obj: The element to query + + @@ -519,26 +527,6 @@ circumstances. @Returns: - - - - - -@factory: -@caps: -@Returns: - - - - - - - -@factory: -@caps: -@Returns: - - diff --git a/docs/gst/tmpl/audioraw.sgml b/docs/gst/tmpl/gstmultidisksrc.sgml similarity index 56% rename from docs/gst/tmpl/audioraw.sgml rename to docs/gst/tmpl/gstmultidisksrc.sgml index df16e49c92..eb3000fd23 100644 --- a/docs/gst/tmpl/audioraw.sgml +++ b/docs/gst/tmpl/gstmultidisksrc.sgml @@ -1,12 +1,12 @@ -audioraw +GstMultiDiskSrc -Information about audio buffers. + -Information about audio buffers. + @@ -14,14 +14,11 @@ Information about audio buffers. - + -@meta: -@format: -@channels: -@frequency: -@bps: +@GST_MULTIDISKSRC_OPEN: +@GST_MULTIDISKSRC_FLAG_LAST: diff --git a/docs/gst/tmpl/gstobject.sgml b/docs/gst/tmpl/gstobject.sgml index 21cb532ae3..1abc9546de 100644 --- a/docs/gst/tmpl/gstobject.sgml +++ b/docs/gst/tmpl/gstobject.sgml @@ -101,26 +101,26 @@ This macro releases a lock on the object. - +Acquire a reference to the mutex of this object. -@obj: +@obj: Object to get the mutex of. - +Get the parent of this object -@obj: +@obj: Object to get the parent of. - +Get the name of this object -@obj: +@obj: Object to get the name of. diff --git a/docs/gst/tmpl/gstpad.sgml b/docs/gst/tmpl/gstpad.sgml index 06601cfd95..bc51b8eb22 100644 --- a/docs/gst/tmpl/gstpad.sgml +++ b/docs/gst/tmpl/gstpad.sgml @@ -124,12 +124,17 @@ The function that will be called when pulling a buffer. The function that will be called when pulling a region buffer. +You can specify which buffer to get using an offset/length pair or +a start/stop timecode pair. @pad: the pad to get a buffer from +@type: the type of region to get (time or offset based) @offset: the offset of the region to get -@size: the size of the region to get +@len: the length of the region to get @Returns: a #GstBuffer + +@size: the size of the region to get @@ -150,6 +155,37 @@ The function that will be called in an EOS case. @Returns: TRUE if EOS was successful, FALSE otherwise + + + + + +@pad: +@caps: + + + + +The possible results from padnegotiation. + + +@GST_PAD_NEGOTIATE_FAIL: The pads could not agree about the media type. +@GST_PAD_NEGOTIATE_AGREE: The pads agreed about the media type. +@GST_PAD_NEGOTIATE_TRY: The pad did not agree and suggests another media type. + + + +The function that will be called when negotiating. + + +@pad: The pad that is being negotiated +@caps: The current caps that are being negotiated +@data: +@Returns: The result of the negotiation process + +@count: A counter to keep track of the negotiation process + + @@ -169,15 +205,28 @@ The function that will be called when pulling buffers. @Returns: a GstBuffer + + +the region types for #gst_pad_pullregion. + + +@GST_REGION_NONE: no type specified +@GST_REGION_OFFSET_LEN: an offet/length pair +@GST_REGION_TIME_LEN: a time start/length pair + The function that will be called when pulling a region buffer. +You can specify which buffer to get using an offset/length pair or +a start/stop timecode pair. -@pad: the pad to pull -@offset: the offset of the region to pull -@size: the size of the region to pull -@Returns: a GstBuffer +@pad: the pad to get a buffer from +@type: the type of region to get (time or offset based) +@offset: the offset of the region to get +@len: the length of the region to get +@Returns: a #GstBuffer + @@ -264,6 +313,15 @@ Destroy the pad. @getregion: + + + + + +@pad: +@nego: + + @@ -282,31 +340,31 @@ Destroy the pad. @eos: - + + + + + +@pad: +@newcaps: + + + @pad: @caps: - - - - - - - -@pad: @Returns: - + @pad: -@name: @Returns: @@ -374,6 +432,15 @@ Destroy the pad. @Returns: + + + + + +@pad: +@Returns: + + @@ -417,6 +484,7 @@ Destroy the pad. @srcpad: @sinkpad: +@Returns: @@ -434,6 +502,8 @@ Destroy the pad. @pad: +@buf: + @buffer: @@ -446,37 +516,20 @@ Destroy the pad. @Returns: - + @pad: +@type: @offset: -@size: +@len: @Returns: - - - - - - - -@pad: -@offset: + @size: - - - - - -@nextpad: -@Varargs: -@Returns: - - @@ -515,6 +568,71 @@ Call the EOS function of the pad @elements: + + + + + +@srcpad: +@destpad: +@caps: +@Returns: + +@counter: +@count: + + + + + + + +@pad: +@Returns: + + + + + + + +@pad: +@Returns: + + + + + + + +@pad: +@Returns: + + + + + + + +@pad: + + + + + + + +@pad: + + + + + + + +@pad: + + @@ -526,6 +644,9 @@ Call the EOS function of the pad @threadstate: @peer: @bufpen: +@regiontype: +@offset: +@len: @chainfunc: @getfunc: @getregionfunc: @@ -534,6 +655,8 @@ Call the EOS function of the pad @pushfunc: @pullfunc: @pullregionfunc: +@negotiatefunc: +@newcapsfunc: @ghostpads: @@ -632,6 +755,22 @@ Get the EOS function of the real pad. @pad: the real pad to query. + + + + + +@pad: + + + + + + + +@pad: + + Get the real pad of this ghost pad. @@ -658,64 +797,6 @@ Get the real pad of this ghost pad. @Returns: - - -Defines an entry for a padfactory. - - - - - -The padfactory. - - - - - -Indicate that this pad will become available depending -on the media type. Use this in the factory definition. - - - - - - -Indicate that this pad will always be available. -Use this in the factory definition. - - - - - - -Indicates that this pad will be available on request. Use -this in the factory definition. - - - - - - -Indicates a sinkpad for the padfactory. - - - - - - -Indicates a srcpad for the padfactory. - - - - - - -Starts the declaration of a the capabilities for this padtemplate. - - -@a...: a capability factory - - Indicates when this pad will become available. @@ -736,16 +817,39 @@ Indicates when this pad will become available. @presence: @caps: - + -@factory: -@Returns: +@templ: - + + + + + +@templ: + + + + + + + +@templ: + + + + + + + +@templ: + + + @@ -754,7 +858,10 @@ Indicates when this pad will become available. @direction: @presence: @caps: +@Varargs: @Returns: + +@factory: @@ -778,3 +885,22 @@ Indicates when this pad will become available. @pad: + + + + + +@templ: +@Returns: + + + + + + + +@templ: +@name: +@Returns: + + diff --git a/docs/gst/tmpl/gstpipeline.sgml b/docs/gst/tmpl/gstpipeline.sgml index da53a47805..f486cfb193 100644 --- a/docs/gst/tmpl/gstpipeline.sgml +++ b/docs/gst/tmpl/gstpipeline.sgml @@ -38,33 +38,6 @@ pipeline figure out what plugins to use. @Returns: - - - - - -@pipeline: -@sink: - - - - - - - -@pipeline: -@src: - - - - - - - -@pipeline: -@Returns: - - Destroys the pipeline. diff --git a/docs/gst/tmpl/gstplugin.sgml b/docs/gst/tmpl/gstplugin.sgml index 802959e05a..ff213c9327 100644 --- a/docs/gst/tmpl/gstplugin.sgml +++ b/docs/gst/tmpl/gstplugin.sgml @@ -27,6 +27,8 @@ GStreamer is extensible so GstElements can be loaded at r @numtypes: @elements: @numelements: +@autopluggers: +@numautopluggers: @loaded: @@ -133,6 +135,14 @@ by the loader at statup. @Returns: + + + + + +@path: + + @@ -160,6 +170,15 @@ by the loader at statup. @factory: + + + + + +@plugin: +@factory: + + @@ -195,12 +214,12 @@ by the loader at statup. @Returns: - + -@name: +@plugin: @Returns: @@ -221,6 +240,15 @@ by the loader at statup. @mime: + + + + + +@name: +@Returns: + + diff --git a/docs/gst/tmpl/gstprops.sgml b/docs/gst/tmpl/gstprops.sgml index 39a17388b3..2c5f0eaf16 100644 --- a/docs/gst/tmpl/gstprops.sgml +++ b/docs/gst/tmpl/gstprops.sgml @@ -20,18 +20,19 @@ GstCaps +@refcount: +@lock: @properties: the properties - + - - - - - +@a: +@b: +@c: +@d: @@ -65,19 +66,12 @@ Construct a fourcc property out of four bytes. @a: first byte + @b: second byte @c: third byte @d: fourth byte - - -Create a fourcc property out of an integer value. - - -@a: the integer value - - Create a boolean property. @@ -86,23 +80,29 @@ Create a boolean property. @a: the boolean property - + -@factory: -@Returns: +@a: - + -@factory: -@counter: -@Returns: +@a: + + + + + + + +@a: +@b: @@ -110,9 +110,21 @@ Create a boolean property. -@entry: +@firstname: @Varargs: @Returns: + +@entry: + + + + + + + +@firstname: +@var_args: +@Returns: @@ -125,6 +137,48 @@ Create a boolean property. @Returns: + + + + + +@props: +@Returns: + + + + + + + +@props: +@Returns: + + + + + + + +@props: + + + + + + + +@props: + + + + + + + +@props: + + @@ -138,6 +192,60 @@ Create a boolean property. @props2: + + + + + +@props: +@name: +@Varargs: +@Returns: + +@entry: +@value: + + + + + + + +@props: +@name: +@Returns: + + + + + + + +@props: +@name: +@Returns: + + + + + + + +@props: +@name: +@Returns: + + + + + + + +@props: +@name: +@Returns: + + diff --git a/docs/gst/tmpl/gstreamer-unused.sgml b/docs/gst/tmpl/gstreamer-unused.sgml index a50a97934d..c750b5e1da 100644 --- a/docs/gst/tmpl/gstreamer-unused.sgml +++ b/docs/gst/tmpl/gstreamer-unused.sgml @@ -1,45 +1,29 @@ - + -@obj: +@pad: +@buf: - + + +Query the element for the current mime type + + + + - + - - - - - -@format: -@args...: - - - - - - -@id: -@sink: - - - - - - -@src: - @@ -47,14 +31,159 @@ @Returns: - + @obj: - + + + + + +@meta: + + + + + + +@fromcaps: +@tocaps: +@Returns: + + + + + + +@obj: + + + + + + + + + + + + +@pad: +@buf: + + + + + + +@pad: +@parent: + + + + + + +@pad: +@buf: + + + + + + +@pad: +@buf: + + + + + + +@Returns: + + + + + + +@klass: + + + + + + +@elementfactory: +@id: + + + + + + + + + +The number of channels. + + + + + +Use this macro to show debugging info. This is only usefull when developing new +plugin elements. +If you #define DEBUG_ENABLED before including gst/gst.h, this macro will produce +g_print messages. + + +@format: the format specification as in g_print +@args...: arguments + + +GstEsdSink + + + + + + + + + + + + + +@type: +@parent: +@Returns: + + + + + + +@src: + + + + + + +@obj: + + + + + + + + @@ -71,7 +200,70 @@ the stream. @gstsrc: the object which received the signal. @arg1: the object which received the signal - + + + + + +@Returns: + + + + + + + + + + + + +@obj: + + + + + + + + + + + + + + + + + + +@name_template: +@direction: +@presence: +@caps: +@Returns: + + + + + + +@obj: + + + + + + + + + + + + +@obj: + + @@ -79,104 +271,6 @@ the stream. @name: @Returns: - - - - - - - - - - - -@obj: - - - - - - - - - - - - - - - - - - - - - - - - -@obj: - - - - - - -@obj: - - - - - - -@name: -@Returns: - - - - - - -@obj: - - - - - - - - - - - - -@format: -@args...: - - - - - - -@obj: - - - - - - -@obj: - - - - - - - - - - - @@ -184,399 +278,28 @@ the stream. @klass: - + + + + + + + @klass: - - - - - -@obj: - - - - - - - - - - - - -@Returns: - - - - - - - - - - - - -@Returns: - - - - - - -@obj: - - - - - - - - - - - - -@klass: - - - - - - -@Returns: - - - -Use this macro to show debugging info. This is only usefull when developing new -plugin elements. -If you #define DEBUG_ENABLED before including gst/gst.h, this macro will produce -g_print messages. - - -@format: the format specification as in g_print -@args...: arguments - - - - - - - - - - - - - - - - - - -@obj: - - - -The sink is the end of the filter graph. A typical sink would be an audio -or a video card. - - - - - - - - - -@name: -@Returns: - - - - - - -@Returns: - - - - - - - - - - - - - - - - - - -@name: -@Returns: - - - - - - - - - - - - -@obj: - - - - - - -@connection: - - - -This macro checks to see if the GST_SRC_ASYNC flag is set. - - -@obj: GstSrc to check for flag in. - - - - - - - - - - - - - - - - - - -@klass: - - - - - - -@arg: - - -GstEsdSink - - - - - - - - - - - - - -@obj: - - - - - - - - - - - - - - - - - - -@name: -@Returns: - - - -A connection is a bas class for a generic connection between -elements. A connection is typically a bas class for queues. - - - - - - - - - -@Returns: - - - - - - - - - - - - - - + @pad: -@buf: - - - - - - -@id: -@src: - - - - - - +@parent: @Returns: - - - - - -@pad: -@buf: - - - - - - -@cat: -@format: -@args...: - - - - - - -@id: -@Returns: - - - - - - - - - - - - - - - - - - - - - - - - -@klass: - - - - - - -@klass: - - - - - - - - - - - - -@obj: - - - - - - -@obj: - - - - - - - - - - - - -@obj: - - -GstColorSpace - - - - - - - - - - - - - -@obj: - - - - - - - @@ -584,91 +307,24 @@ GstColorSpace @obj: - + - - - - - -@id: -@Returns: - - -Take data in and spit data out - - - - -Filters take data in and spit data out. They are the main Element in a filter graph. -Filters have zero or more inputs and zero or more outputs. Filters are connected -together to form filter graphs. A GstFilter is the base class and is not very usefull -on its own. - - - - - - - - -@name: -@Returns: - - - - - - -@name: -@Returns: - - - - - - - - - - - - -@name: -@Returns: - - - - - - -@format: -@args...: - - + @obj: - + - +Specify how many bytes to read at a time. -@obj: - - - - - - -@src: @@ -678,38 +334,61 @@ on its own. @name: @Returns: - + + + + + + + + + +@Returns: + + + + + + +@connection: + + + +subclass use this to start their flag enumeration + + + + + + + + +@audiosink: +@channels: + + - + +Generic connection between elements. + + + + + + + + + @obj: - - -Is trigered whenever the state of an element changes - - -@gstelement: the object which received the signal. -@arg1: the new state of the object - - -GstGetbits - - - - - - - -@klass: - @@ -719,89 +398,26 @@ GstGetbits @format: @args...: - + -@obj: +@meta: +@format: +@visual: +@width: +@height: +@overlay_info: +@dga_info: - - - - - -@src: -@offset: -@size: - - - - - - -@src: - - - - - - -@klass: - - - - - - -@obj: - - - - - - -@name: -@Returns: - - - - - - -@name: -@Returns: - - + - - - - - -@klass: - - - -A GstSrc is the start of a filter graph. It typically is a file or an -audio source. It provides data for the next element in the graph. - - - - - - - - - -@pad: -@buf: - - + @@ -816,476 +432,18 @@ audio source. It provides data for the next element in the graph. @esdsink: @channels: - - - - - -@klass: - - - - - - -@pad: -@parent: - - - - - - -@klass: - - - - - - - - -GstSrc - - - - - - - -@obj: - - - - - - -@obj: - - + +@autoplug: +@srcpad: +@sinkpad: +@Varargs: @Returns: - - - - - - -@obj: - - - - - - -@Returns: - - - -The frequency. - - - - - - - - - - - - - - - - - - - - -@obj: - - - -This macro unsets the given state on the element. - - -@obj: Element to unset state of. -@flag: State to unset, can be any number of bits in guint32. - - - - - - - - - -This macro returns the entire set of flags for the object. - - -@obj: GstSrc to return flags for. - - - - - - -@Returns: - - - - - - -@tee: -@Returns: - - - - - - - - - - - - -@klass: - - -The start point of a filter graph - - - - - - - -@klass: - - - - - - -@obj: - - - - - - - - - - - - -@obj: - - - - - - - - - - - - -@parent: -@Returns: - - - - - - - - - - - - - - - - -@format: -@args...: - - - - - - -@klass: - - - - - - -@klass: - - - - - - -@obj: - - - - - - -@Returns: - - - - - - - - - - - - -@obj: - - -GstConnection - - - - - - - - - - - - - - - - - - - - - - -This macro sets the given state on the element. - - -@obj: Element to set state of. -@flag: State to set, can be any number of bits in guint32. - - - - - - - - - - - - -@klass: - - - - - - -@GST_CAPS_ALWAYS: -@GST_CAPS_MAYBE: - - - - - - -@obj: - - -Generic connection between elements. - - - - - - - - - - - - - - - - - - - -@esdsink: - - - - - - -@obj: - - - - - - -@obj: - - - - - - -@obj: - - - - - - - - - - - - -@obj: - - - - - - -@obj: - - -plugin - - - - - - - - - - - - - -@pad: -@buf: - - - - - - - - - - - - -@name: -@Returns: - - - - - - -@obj: - - - - - - -@obj: - - - - - - - - - - - - - - - -This macro usets the given flags. - - -@src: -@flag: Flag to set, must be a single bit in guint32. -@obj: GstSrc to unset flag in. - - - - - - -@audiosink: - - - - - - -@name: -@Returns: - - - - - - -@obj: - - - - - - -@pad: -@Returns: - - - - - - -@obj: +@srccaps: +@sinkcaps: @@ -1294,34 +452,33 @@ This macro usets the given flags. @obj: - - -A flag indicating that SSE instructions are supported. - - - - + @pad: -@id: +@offset: +@size: +@Returns: - + +@name: +@fd: +@Returns: - + @obj: - + @@ -1333,49 +490,89 @@ A flag indicating that SSE instructions are supported. - - - - - -The end point of a filter graph - - - - - - - -@Returns: - - - - - - -@klass: - - + - + @obj: - + + + + + +@pad: +@pull: + + + + + + + + @Returns: - + + + + + +@obj: + + + + + + + + + + + + + + + + + + +@pad: +@caps: + + + +Create a fourcc property out of an integer value. + + +@a: the integer value + + + + + + + + + + + + +@format: +@args...: + + @@ -1389,149 +586,188 @@ The end point of a filter graph @Returns: - + + +Specify the current offset in the file. + + + + + + + + + + + + + + + + + + + + +@klass: + + + + + + +@nextpad: +@Varargs: +@Returns: + + + + + + +@Returns: + + + + + + + + + + + + + + + + + + + + + + + + +@base: +@swidth: +@sheight: +@bytes_per_line: + + + + + + + + + + + + + + + + + + +@obj: + + + + + + +@klass: + + + + + + + + + + + + +@name: +@Returns: + + + + + + + + + + + + + + + + + + +@id: +@sink: + + + + + + +@src: + + + + + + +@obj: + + +GstGetbits + + + +audioraw + + + + + + + +@klass: + + + + + + +@name: +@Returns: + + @element: -@templ: -@Returns: -@temp: - - - - - - -@pad: -@caps: - - - - - - -@obj: - - - -This macro checks to see if the given state is set. - - -@obj: Element to check for state. -@flag: State to check for, must be a single bit in guint32. - - - - - - -@type: @parent: @Returns: - + @obj: - - - - - -@Returns: - - - - - - -@obj: - - - - - - - - - - - - -@obj: - - - - - - -@Returns: - - - -This macro sets the given flags. - - -@src: -@flag: Flag to set, can by any number of bits in guint32. -@obj: GstSrc to set flag in. - - - -Query a GstSrc for the ASYNC flag - - -@obj: The GstSrc to query - - - - - - - - - - - -@argc: -@argv: -@Returns: - - - - - - - - - - - - - - - - - - -@pad: -@Returns: - - - - - - - - -GstSink - - @@ -1541,388 +777,7 @@ GstSink @srcid: @Returns: - - - - - - - - - - - - - - - - - -@Returns: - - - - - - - - - - - - -@connection: - - - - - - - - - - - - - - - - - - -@obj: - - - - - - -@buf: - - - - - - - - - -Query the element for the current mime type - - - - - - - - - - - - - - - - - - -@buffer: -@size: -@root: -@Returns: - - - - - - - - - - - - -@Returns: - - - - - - -@element: -@state: -@Returns: - - - - - - -@klass: - - - - - - - - - - - - - - - - - - -@klass: - - - - - - - - - - - - -@GST_PROPS_END_ID_NUM: -@GST_PROPS_LIST_ID_NUM: -@GST_PROPS_INT_ID_NUM: -@GST_PROPS_INT_RANGE_ID_NUM: -@GST_PROPS_FOURCC_ID_NUM: -@GST_PROPS_BOOL_ID_NUM: - - - - - - -@pad: -@Returns: - - - - - - - - - - - - -@esdsink: -@frequency: - - - -Get the size of the current file. - - - - - -subclass use this to start their flag enumeration - - - - - - - - -@element: -@object: -@format: -@args...: - - - -Flags for the GstSrc element - - -@GST_SRC_ASYNC: Indicates that this src is asynchronous -@GST_SRC_FLAG_LAST: subclasses can use this to number their flags - - - - - - - - - - - - - - - - - - -@name: -@Returns: - - - - - - -@audiosink: -@channels: - - - - - - - - - - - - -@thread: - - - - - - -@obj: - - - - - - - - - - - - -@obj: - - - - - - - - - - - - -@obj: - - - - - - -@elementfactory: -@id: - - - - - - -@Returns: - - - - - - -@pad: -@buf: - - - - - - - - - - - - -@pad: -@Returns: - - - - - - - - - - - - -@pad: -@buf: - - - - - - - - - - - - -@pad: -@buf: - - - -Indicates this pad is active - - - - - - - - -@klass: - - - - - - -@obj: - - - - - - -@obj: - - - - - - -@klass: - - + @@ -1934,266 +789,47 @@ Indicates this pad is active - - - - - -@element: -@parent: -@Returns: - - - - - - -@src: - - - - - - -@audiosink: -@frequency: - - - - - - - - - - - - -@elementfactory: - - - - - - -@Returns: - - - - - - -@meta: - - - - - - -@Returns: - - - - - - -@Returns: - - + @obj: - + +@id: @Returns: - - - - - -@obj: - - - - - - -@pad: -@parent: -@Returns: - - - - - - - - - - - - - - - - - - -@obj: - - - - - - -@obj: - - - - - - -@obj: - - - - - - - - - - - - -@pad: -@parent: - - -GstElement - - - - - - - -@obj: - - - - - - - - - - - - - - - - - - - - - - - - -@pad: -@pull: - - - - - - - - + @esdsink: -@format: +@frequency: - - -Query whether this object has multiple input pads. + - -@obj: Element to query for multiple input pads. - - - - - -@klass: - - + - - - - - - - + @obj: - - - - - - - - - -@src: - - - - - - -@klass: - - - - - - -@obj: - - - - - - -@obj: - - + @@ -2207,26 +843,31 @@ Query whether this object has multiple input pads. @obj: - + + +The audio format as defined in soundcard.h + + + + + + + + +@obj: + + +GstAsyncDiskSrc + + + +>>>>>>> 1.23.2.3 - - - - - -@name: -@fd: -@Returns: - - -GstFilter - - - + @@ -2234,14 +875,90 @@ GstFilter @elementfactory: @id: - + +@obj: + + + + + + + + + +The fequency. + + + + + + + + +@Returns: + + + + + + +@name: +@Returns: + + + + + + + + + + + + +@obj: + + + + + + + + + +The buffer is sent to the sound card. + + +@gstaudiosink: the object which received the signal. +@arg1: the audiosink. + + + + + + +@obj: + + + + + + +@obj: + + + + + + +@pad: @buf: - + @@ -2249,36 +966,59 @@ GstFilter @pad: @Returns: - + -@audiosink: -@format: +@factory: +@caps: +@Returns: - + -@klass: +@pad: +@buf: - + + + + + + + + + + + +@factory: +@counter: +@Returns: +@count: + + + + + + + + + + + + + + @obj: - - - - - -@Returns: - - + @@ -2295,7 +1035,959 @@ GstFilter @format: @args...: - + + + + + +@klass: + + + + + + + + + + + + +@id: +@src: + + + + + + + + + + + + +@obj: + + + + + + + + + + + + +@obj: + + + + + + +@klass: + + + + + + +@esdsink: + + + + + + +@connection: + + + + + + +@name: +@Returns: + + + + + + +@obj: + + + + + + + + +GstFilter + + + + + + + +@obj: + + + + + + +@Returns: + + + + + + +@obj: + + + + + + +@pad: +@Returns: + + + + + + +@x1: +@x2: +@y1: +@y2: + + + + + + +@thread: + + + +Flags for the GstSrc element + + +@GST_SRC_ASYNC: Indicates that this src is asynchronous +@GST_SRC_FLAG_LAST: subclasses can use this to number their flags + + + + + + +GstColorSpace + + + + +Defines an entry for a padfactory. + + + + + + + + + +GST_ASYNCDISKSRC_OPEN +the asyncdisksrc is open for reading + + + + + + +@GST_ASYNCDISKSRC_OPEN: +@GST_ASYNCDISKSRC_FLAG_LAST: + + + + + + + + + + + + +@element: +@state: +@Returns: + + + + + + +@pad: +@Returns: + + + + + + + + + + + + +@obj: + + + + + + +@klass: + + + + + + +@Returns: + + + +Indicates a sinkpad for the padfactory. + + + + + + + + +@klass: + + + + + + + + + + + + +@parent: +@Returns: + + + + + + +@pad: +@Returns: + + + + + + +@name: +@Returns: + + + + + + + + + + + + +@element: +@templ: +@Returns: +@temp: + + + + + + +@obj: + + +The end point of a filter graph + + + + + + + +@meta: +@format: +@channels: +@frequency: +@bps: + + + +The number of channels (mono, stereo, ...) + + + + + + + + + + + +This macro checks to see if the given state is set. + + +@obj: Element to check for state. +@flag: State to check for, must be a single bit in guint32. + + + + + + +@buffer: +@size: +@root: +@Returns: + + + + + + + + + + + + + + + + + + +@name: +@Returns: + + + + + + +@obj: + + +GstAudioSink + + + + + + + +@obj: + + + +This macro sets the given flags. + + +@src: +@flag: Flag to set, can by any number of bits in guint32. +@obj: GstSrc to set flag in. + + + + + + + + + + + + +@a: + + + + + + +@Returns: + + + + + + +@name: +@Returns: + + + + + + + + + +A flag indicating that MMX instructions are supported. + + + + +GstSink + + + + + + + +@Returns: + + + + + + + + + + + + +@factory: +@caps: +@Returns: + + + +This macro usets the given flags. + + +@src: +@flag: Flag to set, must be a single bit in guint32. +@obj: GstSrc to unset flag in. + + + +The frequency. + + + + + +Indicates a srcpad for the padfactory. + + + + + + + + +@obj: + + + + + + +@obj: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +@pad: +@name: +@Returns: + + + + + + + + + + + + +@esdsink: +@format: + + + + + + + + + + + + +@obj: + + + + + + + + + + + + +@Returns: + + + + + + +@obj: + + + + + + +@obj: + + + + + + +@name: +@Returns: + + + +Starts the declaration of a the capabilities for this padtemplate. + + +@a...: a capability factory + + +GstSrc + + + + + + + +@pad: +@Returns: + + + + + + +@pad: +@buf: + + + + + + +@name: +@mime: +@props: +@Returns: + + + + + + + + + + + + + + + + + + +@obj: + + + + + + +@arg: + + +GstConnection + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +@obj: + + +GstElement + + + + + + + +@id: +@Returns: + + + + + + +@buf: + + + + + + + + + + + + +@obj: + + + + + + + + + +The sink is the end of the filter graph. A typical sink would be an audio +or a video card. + + + + + + + + + +@Returns: + + + + + + +@obj: + + + + + + + + + + + + + + + +Query whether this object has multiple input pads. + + + +@obj: Element to query for multiple input pads. + + + + + + +@format: +@args...: + + + + + + + + + + + + + + + + + + + + + + + + +@factory: +@Returns: + + + + + + + + + + + + +@src: + + + + + + + + + + + + + + + +Information about video buffers. + + + + + + + + +@name: +@Returns: + + + + + + +@klass: + + + + + + + + + + + + +@obj: + + + + + + +@klass: + + + + + + + + + + + + +@name: +@Returns: + + + + + + +@obj: + + + + + + +@klass: + + + + + + + + + + + + + + + + +@Returns: + + + + + + + + + + + + +@obj: + + + +Filters take data in and spit data out. They are the main Element in a filter graph. +Filters have zero or more inputs and zero or more outputs. Filters are connected +together to form filter graphs. A GstFilter is the base class and is not very usefull +on its own. + + + + + + + + +@tee: +@Returns: + + + + + + +@obj: + + @@ -2309,7 +2001,56 @@ GstFilter @obj: - + + + + + +@klass: + + + + + + + + + + + + +videoraw + + + + + + + +@obj: + + + + + + +@wx: +@wy: +@overlay_element: +@clip_count: +@overlay_clip: +@width: +@height: +@did_overlay: +@fully_obscured: + + + + + + + + @@ -2317,15 +2058,772 @@ GstFilter @name: @Returns: + + + + + +@obj: + + + + + + + + + + + + +@obj: + + + + + + +@klass: + + + + + + + + + + + + +@obj: + + + +This macro returns the entire set of flags for the object. + + +@obj: GstSrc to return flags for. + + + + + + + + + +Get the size of the current file. + + + + + + + + +The start point of a filter graph + + + + + + + +@src: + + + + + + +@obj: + + + + + + +@src: + + + + + + +@factory: +@counter: +@Returns: + + + + + + +@a: +@b: + + + + + + +@klass: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +@Returns: + + + + + + +@Returns: + + + + + + +@klass: + + + + + + +@klass: <<<<<<< gstreamer-unused.sgml + + + +Indicates that this pad will be available on request. Use +this in the factory definition. + + + + + + + + +@audiosink: + + + +This macro unsets the given state on the element. + + +@obj: Element to unset state of. +@flag: State to unset, can be any number of bits in guint32. + + + + + + +@obj: + + + + + + +@klass: + + + + + + +@pad: +@id: + + + +Indicate that this pad will always be available. +Use this in the factory definition. + + + + + + + + +@pad: +@parent: + + + + + + +@audiosink: +@frequency: + + + + + + + + + + + + +@elementfactory: + + + +The number of bytes per read. + + + + + + + +@argc: +@argv: +@Returns: + + + + + + +@obj: + + + + + + +@Returns: + + + + + + +@element: +@object: +@format: +@args...: + + + + + + +@obj: + + + + + + +@obj: + - + -A flag indicating that MMX instructions are supported. + + + +@obj: + + + + + + + + + + + + +@Returns: + + + + + + +@klass: + + + +A connection is a bas class for a generic connection between +elements. A connection is typically a bas class for queues. + + + + + + + + + +@buf: + + + +Query a GstSrc for the ASYNC flag + + +@obj: The GstSrc to query + + + + + + +@obj: + + + +This macro sets the given state on the element. + + +@obj: Element to set state of. +@flag: State to set, can be any number of bits in guint32. + + + + + + +@Returns: + + + + + + + + + + + + +@obj: + + + + + + +@src: +@offset: +@size: + + + + + + +@Returns: + + +Information about video buffers. + + + + + + + + + + + + + +@format: +@args...: + + + +Is trigered whenever the state of an element changes + + +@gstelement: the object which received the signal. +@arg1: the new state of the object + + + + + + +@klass: + + + + + + +@name: +@Returns: + + + + + + +@Returns: + + +Information about audio buffers. + + + + + + + + + +Take data in and spit data out + + + + +The padfactory. + + + + + +This macro checks to see if the GST_SRC_ASYNC flag is set. + + +@obj: GstSrc to check for flag in. + + + + + + + + + + + + + + + + + + + + + +A flag indicating that SSE instructions are supported. + + + + + + + + +@obj: + + + + + + + + + + + + + + + + + + +@Returns: + + + + + + + + + + + + +@obj: + + + +Information about audio buffers. + + + + + + + + +@GST_PROPS_END_ID_NUM: +@GST_PROPS_LIST_ID_NUM: +@GST_PROPS_INT_ID_NUM: +@GST_PROPS_INT_RANGE_ID_NUM: +@GST_PROPS_FOURCC_ID_NUM: +@GST_PROPS_BOOL_ID_NUM: + + + + + + +@GST_CAPS_ALWAYS: +@GST_CAPS_MAYBE: + + + + + + + +<<<<<<< gstreamer-unused.sgml + + + + + + + + + +>>>>>>> 1.23.2.3 + + + + +@obj: + + + + + + + + + + + + +@factory: +@Returns: + + + + + + + + + +Specify the location of the file to read. + + + + + + + + +@klass: + + + + + + +@Returns: + + + + + + +@format: +@args...: + + + + + + +@audiosink: +@format: + + +GstAudioSrc + + + + +Indicate that this pad will become available depending +on the media type. Use this in the factory definition. + + + + + + + + +@cat: +@format: +@args...: + + + +Reads data from a file. You can seek to a specific location by setting +the offset. + + + + + + + + +@obj: + + + + + + +@name: +@Returns: + + + +Get the current number of bytes read. + + + + + + + + + + +plugin + + + + + + + +@obj: + + + + + + + + + + + + + + + + + + + + + + + + +@klass: + + + + + + +@obj: + + + + + + +@klass: + + + +Indicates this pad is active + + + + + + + + + + + +A GstSrc is the start of a filter graph. It typically is a file or an +audio source. It provides data for the next element in the graph. + diff --git a/docs/gst/tmpl/gstsinesrc.sgml b/docs/gst/tmpl/gstsinesrc.sgml index 7768424330..f9259760a1 100644 --- a/docs/gst/tmpl/gstsinesrc.sgml +++ b/docs/gst/tmpl/gstsinesrc.sgml @@ -24,13 +24,23 @@ The volume as a double 0.0 is silent, 1.0 is loudest. The format ad defined in soundcard.h - + -The number of channels. + - + -The fequency. + + + + + +The frequency. + + + + + diff --git a/docs/gst/tmpl/gststaticautoplug.sgml b/docs/gst/tmpl/gststaticautoplug.sgml new file mode 100644 index 0000000000..afe7abc44a --- /dev/null +++ b/docs/gst/tmpl/gststaticautoplug.sgml @@ -0,0 +1,17 @@ + +GstStaticAutoplug + + +A static autoplugger. + + + +This autoplugger will create a non threaded element before running the +pipeline. + + + + + + + diff --git a/docs/gst/tmpl/gststaticautoplugrender.sgml b/docs/gst/tmpl/gststaticautoplugrender.sgml new file mode 100644 index 0000000000..dde4315886 --- /dev/null +++ b/docs/gst/tmpl/gststaticautoplugrender.sgml @@ -0,0 +1,17 @@ + +GstStaticAutoplugRender + + +An autoplugger made for media playback + + + +this autoplugger will create a threaded element that can be used +in media players. + + + + + + + diff --git a/docs/gst/tmpl/gstutils.sgml b/docs/gst/tmpl/gstutils.sgml index 2550838846..f4bd0fe58b 100644 --- a/docs/gst/tmpl/gstutils.sgml +++ b/docs/gst/tmpl/gstutils.sgml @@ -14,6 +14,16 @@ Some convenience functions + + + + + +@object: +@name: +@value: + + diff --git a/docs/gst/tmpl/videoraw.sgml b/docs/gst/tmpl/videoraw.sgml deleted file mode 100644 index fda469c05b..0000000000 --- a/docs/gst/tmpl/videoraw.sgml +++ /dev/null @@ -1,64 +0,0 @@ - -videoraw - - -Information about video buffers. - - - -Information about video buffers. - - - - - - - - - - - - -@meta: -@format: -@visual: -@width: -@height: -@overlay_info: -@dga_info: - - - - - - -@base: -@swidth: -@sheight: -@bytes_per_line: - - - - - - -@wx: -@wy: -@overlay_element: -@clip_count: -@overlay_clip: -@width: -@height: -@did_overlay: -@fully_obscured: - - - - - - -@x1: -@x2: -@y1: -@y2: - diff --git a/docs/libs/.gitignore b/docs/libs/.gitignore index fce934253f..b5548ac928 100644 --- a/docs/libs/.gitignore +++ b/docs/libs/.gitignore @@ -1,6 +1,5 @@ Makefile Makefile.in -tmpl html sgml gstreamer-libs-unused.txt diff --git a/docs/manual/Makefile.am b/docs/manual/Makefile.am index 86452b25a6..9d9a225d29 100644 --- a/docs/manual/Makefile.am +++ b/docs/manual/Makefile.am @@ -1,5 +1,5 @@ manualname = gstreamer-manual -htmlname = gstreamer.html +htmlname = index.html sgml_files = gstreamer-manual.sgml \ advanced.sgml \ @@ -20,6 +20,7 @@ sgml_files = gstreamer-manual.sgml \ motivation.sgml \ plugins.sgml \ programs.sgml \ + debugging.sgml \ queues.sgml \ states.sgml \ threads.sgml \ diff --git a/docs/manual/bins.sgml b/docs/manual/bins.sgml index eb89b4c475..ec69b174cf 100644 --- a/docs/manual/bins.sgml +++ b/docs/manual/bins.sgml @@ -110,7 +110,7 @@ while (elements) { GstElement *element = GST_ELEMENT (elements->data); - g_print ("element in bin: %s\n", gst_element_get_name (element)); + g_print ("element in bin: %s\n", gst_element_get_name (element)); elements = g_list_next (elements); } diff --git a/docs/manual/debugging.sgml b/docs/manual/debugging.sgml new file mode 100644 index 0000000000..aae503c5ab --- /dev/null +++ b/docs/manual/debugging.sgml @@ -0,0 +1,89 @@ + + Debugging + + GStreamer has an extensive set of debugging tools for + plugin developers. + + + + Command line options + + Applications using the GStreamer libraries accept the following set + of command line argruments to enable the debugging system. + + + + + + + + Sets the mask for the debugging output. + + + + + + Sets the mask for the info output. + + + + + + Enable printout of errors while loading GST plugins. + + + + + + Add a directory to the plugin search path. + + + + Print the a short desciption of the + options and an overview of the current debugging/info masks + set. + + + + + + + The follwing table gives an overview of the mask values and + their meaning. (enabled) means that the corresponding flag + has been set. + + +Mask (to be OR'ed) info/debug FLAGS +-------------------------------------------------------- +0x00000001 (enabled)/ GST_INIT +0x00000002 / COTHREADS +0x00000004 / COTHREAD_SWITCH +0x00000008 / AUTOPLUG +0x00000010 / AUTOPLUG_ATTEMPT +0x00000020 / PARENTAGE +0x00000040 / STATES +0x00000080 / PLANING +0x00000100 / SCHEDULING +0x00000200 / OPERATION +0x00000400 / BUFFER +0x00000800 / CAPS +0x00001000 / CLOCK +0x00002000 / ELEMENT_PADS +0x00004000 / ELEMENTFACTORY +0x00008000 / PADS +0x00010000 / PIPELINE +0x00020000 / PLUGIN_LOADING +0x00040000 / PLUGIN_ERRORS +0x00080000 / PROPERTIES +0x00100000 / THREAD +0x00200000 / TYPES +0x00400000 / XML + + + + Adding a custom debug handler + + + + + diff --git a/docs/manual/dynamic.sgml b/docs/manual/dynamic.sgml index 4cfdcf6846..23a59263e7 100644 --- a/docs/manual/dynamic.sgml +++ b/docs/manual/dynamic.sgml @@ -102,7 +102,7 @@ new_pad_created (GstElement *parse, GstPad *pad, GstElement *pipeline) GtkWidget *appwindow; - g_print ("***** a new pad %s was created\n", gst_pad_get_name (pad)); + g_print ("***** a new pad %s was created\n", gst_pad_get_name (pad)); gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_PAUSED); diff --git a/docs/manual/gstreamer-manual.sgml b/docs/manual/gstreamer-manual.sgml index ee6ea71526..69871cfaa4 100644 --- a/docs/manual/gstreamer-manual.sgml +++ b/docs/manual/gstreamer-manual.sgml @@ -23,12 +23,13 @@ + ]> - + @@ -43,7 +44,7 @@ - + This material may be distributed only subject to the terms and conditions set forth in the Open Publication License, v1.0 or later (the @@ -183,9 +184,12 @@ GStreamer comes prepackaged with a few programs. + and some usefull debugging options. + &DEBUGGING; + &PROGRAMS; &COMPONENTS; diff --git a/docs/manual/helloworld.sgml b/docs/manual/helloworld.sgml index f9802e01c6..7eaa2450bc 100644 --- a/docs/manual/helloworld.sgml +++ b/docs/manual/helloworld.sgml @@ -38,7 +38,7 @@ main (int argc, char *argv[]) gst_init(&argc, &argv); if (argc != 2) { - g_print ("usage: %s <filename>n", argv[0]); + g_print ("usage: %s <filename>n", argv[0]); exit (-1); } diff --git a/docs/manual/helloworld2.sgml b/docs/manual/helloworld2.sgml index 98c2e96736..1a48f7f991 100644 --- a/docs/manual/helloworld2.sgml +++ b/docs/manual/helloworld2.sgml @@ -41,7 +41,7 @@ main (int argc, char *argv[]) GstElement *pipeline; if (argc != 2) { - g_print ("usage: %s <filename>\n", argv[0]); + g_print ("usage: %s <filename>\n", argv[0]); exit (-1); } diff --git a/docs/manual/pads.sgml b/docs/manual/pads.sgml index 8cfaf47f5d..1efd56dd0b 100644 --- a/docs/manual/pads.sgml +++ b/docs/manual/pads.sgml @@ -34,7 +34,7 @@ while (pads) { GstPad *pad = GST_PAD (pads->data); - g_print ("pad name %s\n", gst_pad_get_name (pad)); + g_print ("pad name %s\n", gst_pad_get_name (pad)); pads = g_list_next (pads); } @@ -57,7 +57,7 @@ GstObject. - + Dynamic pads Some elements might not have their pads when they are created. This can, for @@ -82,7 +82,7 @@ static void pad_connect_func (GstElement *parser, GstPad *pad, GstElement *pipeline) { - g_print("***** a new pad %s was created\n", gst_pad_get_name(pad)); + g_print("***** a new pad %s was created\n", gst_pad_get_name(pad)); gst_element_set_state (pipeline, GST_STATE_PAUSED); @@ -119,6 +119,58 @@ main(int argc, char *argv[]) + + Request pads + + An element can also have request pads. These pads are not created automatically + but are only created on demand. This is very usefull for muxers, aggregators + and tee elements. + + + The tee element, for example, has one input pad and a request padtemplate for the + output pads. Whenever an element wants to get an output pad from the tee element, it + has to request the pad. + + + The following piece of code can be used to get a pad from the tee element. After + the pad has been requested, it can be used to connect another element to it. + + + ... + GstPad *pad; + ... + element = gst_elementfactory_make ("tee", "element"); + + pad = gst_element_request_pad_by_name (element, "src%d"); + g_print ("new pad %s\n", gst_pad_get_name (pad)); + ... + + + The gst_element_request_pad_by_name method can be used to get a pad + from the element based on the name_template of the padtemplate. + + + It is also possible to request a pad that is compatible with another + padtemplate. This is very usefull if you want to connect an element to + a muxer element and you need to request a pad that is compatible. The + gst_element_request_compatible_pad is used to request a compatible pad, as + is shown in the next example. + + + ... + GstPadTemplate *templ; + GstPad *pad; + ... + element = gst_elementfactory_make ("tee", "element"); + mp3parse = gst_elementfactory_make ("mp3parse", "mp3parse"); + + templ = gst_element_get_padtemplate_by_name (mp3parse, "sink"); + + pad = gst_element_request_compatible_pad (element, templ); + g_print ("new pad %s\n", gst_pad_get_name (pad)); + ... + + Capabilities of a GstPad @@ -258,12 +310,12 @@ Pads: ... caps = gst_pad_get_caps_list (pad); - g_print ("pad name %s\n", gst_pad_get_name (pad)); + g_print ("pad name %s\n", gst_pad_get_name (pad)); while (caps) { GstCaps *cap = (GstCaps *) caps->data; - g_print (" Capability name %s, MIME type\n", gst_caps_get_name (cap), + g_print (" Capability name %s, MIME type\n", gst_caps_get_name (cap), gst_caps_get_mime (cap)); caps = g_list_next (caps); diff --git a/docs/manual/plugins.sgml b/docs/manual/plugins.sgml index 4f7c57cbed..a89d9cb908 100644 --- a/docs/manual/plugins.sgml +++ b/docs/manual/plugins.sgml @@ -15,6 +15,11 @@ one or more typedefinitions + + + one or more autopluggers + + The plugins have one simple method: plugin_init () where all the elementfactories are @@ -39,6 +44,8 @@ struct _GstPlugin { gint numtypes; GList *elements; /* list of elements provided */ gint numelements; + GList *autopluggers; /* list of autopluggers provided */ + gint numautopluggers; gboolean loaded; /* if the plugin is in memory */ }; @@ -55,7 +62,7 @@ struct _GstPlugin { while (plugins) { GstPlugin *plugin = (GstPlugin *)plugins->data; - g_print ("plugin: %s\n", gst_plugin_get_name (plugin)); + g_print ("plugin: %s\n", gst_plugin_get_name (plugin)); plugins = g_list_next (plugins); } diff --git a/docs/manual/queues.sgml b/docs/manual/queues.sgml index e057f2e8d7..2450e49961 100644 --- a/docs/manual/queues.sgml +++ b/docs/manual/queues.sgml @@ -66,7 +66,7 @@ main (int argc, char *argv[]) gst_init (&argc,&argv); if (argc != 2) { - g_print ("usage: %s <filename>\n", argv[0]); + g_print ("usage: %s <filename>\n", argv[0]); exit (-1); } diff --git a/docs/manual/quotes.sgml b/docs/manual/quotes.sgml index 78bff5dd0d..11cfc1f572 100644 --- a/docs/manual/quotes.sgml +++ b/docs/manual/quotes.sgml @@ -11,6 +11,26 @@ + + 16 Feb 2001 + + + wtay: + I shipped a few commerical products to >40000 people now but + GStreamer is way more exciting... + + + + + 16 Feb 2001 + + + * + tool-man + is a gstreamer groupie + + + 14 Jan 2001 diff --git a/docs/manual/threads.sgml b/docs/manual/threads.sgml index 29908ade29..b5f24f0bb6 100644 --- a/docs/manual/threads.sgml +++ b/docs/manual/threads.sgml @@ -77,7 +77,7 @@ main (int argc, char *argv[]) GstElement *thread; if (argc != 2) { - g_print ("usage: %s <filename>\n", argv[0]); + g_print ("usage: %s <filename>\n", argv[0]); exit (-1); } diff --git a/docs/manual/typedetection.sgml b/docs/manual/typedetection.sgml index cfbf97782b..e9bb972e10 100644 --- a/docs/manual/typedetection.sgml +++ b/docs/manual/typedetection.sgml @@ -3,7 +3,7 @@ Sometimes the capabilities of a pad are not specificied. The disksrc, for example, does not know what type of file it is reading. Before you can attach - and element to the pad of the disksrc, you need to determine the media type in + an element to the pad of the disksrc, you need to determine the media type in order to be able to choose a compatible element. @@ -64,7 +64,7 @@ main(int argc, char *argv[]) gst_init(&argc,&argv); if (argc != 2) { - g_print("usage: %s <filename>\n", argv[0]); + g_print("usage: %s <filename>\n", argv[0]); exit(-1); } diff --git a/docs/manual/xml.sgml b/docs/manual/xml.sgml index 399a90739a..7cc518205c 100644 --- a/docs/manual/xml.sgml +++ b/docs/manual/xml.sgml @@ -38,7 +38,7 @@ main (int argc, char *argv[]) gst_init (&argc,&argv); if (argc != 2) { - g_print ("usage: %s <filename>\n", argv[0]); + g_print ("usage: %s <filename>\n", argv[0]); exit (-1); } @@ -120,7 +120,9 @@ main (int argc, char *argv[]) Loading a GstElement from an XML file - A saved XML file can be loade with the gst_xml_new (filename, rootelement). + Before an XML file can be loaded, you must create a GstXML object. + A saved XML file can then be loaded with the + gst_xml_parse_file (xml, filename, rootelement) method. The root element can optionally left NULL. The following code example loads the previously created XML file and runs it. @@ -128,37 +130,28 @@ main (int argc, char *argv[]) #include <stdlib.h> #include <gst/gst.h> -gboolean playing; - -/* eos will be called when the src element has an end of stream */ -void -eos (GstElement *element, gpointer data) -{ - g_print ("have eos, quitting\n"); - - playing = FALSE; -} - int main(int argc, char *argv[]) { GstXML *xml; GstElement *bin; - GstElement *disk; + gboolean ret; gst_init (&argc, &argv); - xml = gst_xml_new ("xmlTest.gst", NULL); + xml = gst_xml_new (); + + ret = gst_xml_parse_file(xml, "xmlTest.gst", NULL); + g_assert (ret == TRUE); bin = gst_xml_get_element (xml, "bin"); + g_assert (bin != NULL); gst_element_set_state (bin, GST_STATE_PLAYING); playing = TRUE; - while (playing) { - gst_bin_iterate (GST_BIN (bin)); - } + while (gst_bin_iterate(GST_BIN(bin))); gst_element_set_state (bin, GST_STATE_NULL); @@ -173,6 +166,127 @@ main(int argc, char *argv[]) gst_xml_get_topelements (xml) can be used to get a list of all toplevel elements in the XML file. + + In addition to loading a file, you can also load a from a xmlDocPtr and + an in memory buffer using gst_xml_parse_doc and gst_xml_parse_memory + respectivily. both of these methods return a gboolean indicating success + or failure of the requested action. + + + + Adding custom XML tags into the core XML data + + + It is possible to add custom XML tags to the core XML created with + gst_xml_write. This feature can be used by an application to add more + information to the save plugins. the editor will for example insert + the position of the elements on the screen using the custom XML tags. + + + It is strongly suggested to save and load the custom XML tags using + a namespace. This will solve the problem of having your XML tags + interfere with the core XML tags. + + + To insert a hook into the element saving procedure you can connect + a signal to the GstElement using the following piece of code: + + +xmlNsPtr ns; + + ... + ns = xmlNewNs (NULL, "http://gstreamer.net/gst-test/1.0/", "test"); + ... + thread = gst_elementfactory_make("thread", "thread"); + gtk_signal_connect (GTK_OBJECT (thread), "object_saved", object_saved, g_strdup ("decoder thread")); + ... + + + When the thread is saved, the object_save method will be caled. Our example + will insert a comment tag: + + +static void +object_saved (GstObject *object, xmlNodePtr parent, gpointer data) +{ + xmlNodePtr child; + + child = xmlNewChild(parent, ns, "comment", NULL); + xmlNewChild(child, ns, "text", (gchar *)data); +} + + + Adding the custom tag code to the above example you will get an XML file + with the custom tags in it. Here's an excerpt: + + + ... + <gst:element> + <gst:name>thread</gst:name> + <gst:type>thread</gst:type> + <gst:version>0.1.0</gst:version> + ... + </gst:children> + <test:comment> + <test:text>decoder thread</test:text> + </test:comment> + </gst:element> + ... + + + To retrieve the custom XML again, you need to attach a signal to + the GstXML object used to load the XML data. You can then parse your + custom XML from the XML tree whenever an object is loaded. + + + + We can extend our previous example with the following piece of + code. + + + + xml = gst_xml_new (); + + gtk_signal_connect (GTK_OBJECT (xml), "object_loaded", xml_loaded, xml); + + ret = gst_xml_parse_file(xml, "xmlTest.gst", NULL); + g_assert (ret == TRUE); + + + + Whenever a new object has been loaded, the xml_loaded function will be + called. this function looks like: + + +static void +xml_loaded (GstXML *xml, GstObject *object, xmlNodePtr self, gpointer data) +{ + xmlNodePtr children = self->xmlChildrenNode; + + while (children) { + if (!strcmp (children->name, "comment")) { + xmlNodePtr nodes = children->xmlChildrenNode; + + while (nodes) { + if (!strcmp (nodes->name, "text")) { + gchar *name = g_strdup (xmlNodeGetContent (nodes)); + g_print ("object %s loaded with comment '%s'\n", + gst_object_get_name (object), name); + } + nodes = nodes->next; + } + } + children = children->next; + } +} + + + As you can see, you'll get a handle to the GstXML object, the + newly loaded GstObject and the xmlNodePtr that was used to create + this object. In the above example we look for our special tag inside + the XML tree that was used to load the object and we print our + comment to the console. + diff --git a/docs/plugins/Makefile.am b/docs/plugins/Makefile.am index 66492fdd42..c210ca1909 100644 --- a/docs/plugins/Makefile.am +++ b/docs/plugins/Makefile.am @@ -47,7 +47,9 @@ sgml/$(DOC_MODULE)-doc.bottom: $(tmpl_sources) $(MAKE) sgml scanobj: - CFLAGS="$(CFLAGS)" LDFLAGS="$(LDFLAGS)" ./gstdoc-scanobj --module=$(DOC_MODULE) + env CC="$(LIBTOOL) $(CC)" CFLAGS="$(LIBGST_CFLAGS) $(GLIB_CFLAGS) $(XML_CFLAGS) -I../../" LDFLAGS="$(GST_LIBS)"\ + ./gstdoc-scanobj --module=$(DOC_MODULE) + tmpl: scanobj ./gstdoc-mktmpl --module=$(DOC_MODULE) diff --git a/docs/plugins/gstdoc-scanobj b/docs/plugins/gstdoc-scanobj index 0faac08c69..a60e7c9ef2 100755 --- a/docs/plugins/gstdoc-scanobj +++ b/docs/plugins/gstdoc-scanobj @@ -839,7 +839,7 @@ output_widget_pads (FILE *fp, GstElement *element) type = gst_type_find_by_id(1); fprintf (fp, "\n%s::%s\n", - gtk_type_name(factory->type), pad->name); + gtk_type_name(factory->type), gst_object_get_name (GST_OBJECT (pad))); if (type) { fprintf(fp, "%s\n", type->mime); diff --git a/docs/plugins/tmpl/ac3parse.sgml b/docs/plugins/tmpl/ac3parse.sgml index 9c0b4eb817..6288ef2cc3 100644 --- a/docs/plugins/tmpl/ac3parse.sgml +++ b/docs/plugins/tmpl/ac3parse.sgml @@ -14,8 +14,3 @@ Ac3Parse - - - - - diff --git a/docs/plugins/tmpl/audioscale.sgml b/docs/plugins/tmpl/audioscale.sgml index 1bdd4a82e9..69bc3bb5d4 100644 --- a/docs/plugins/tmpl/audioscale.sgml +++ b/docs/plugins/tmpl/audioscale.sgml @@ -14,8 +14,3 @@ Audioscale - - - - - diff --git a/docs/plugins/tmpl/gstaviencoder.sgml b/docs/plugins/tmpl/gstaviencoder.sgml index 453ee2ed19..bdfaf6425b 100644 --- a/docs/plugins/tmpl/gstaviencoder.sgml +++ b/docs/plugins/tmpl/gstaviencoder.sgml @@ -14,13 +14,3 @@ GstAviEncoder - - - - - - - - - - diff --git a/docs/plugins/tmpl/gstmpeg2enc.sgml b/docs/plugins/tmpl/gstmpeg2enc.sgml index 2ce74351f0..0daebe9a25 100644 --- a/docs/plugins/tmpl/gstmpeg2enc.sgml +++ b/docs/plugins/tmpl/gstmpeg2enc.sgml @@ -14,8 +14,3 @@ GstMpeg2enc - - - - - diff --git a/docs/plugins/tmpl/gstmpeg2play.sgml b/docs/plugins/tmpl/gstmpeg2play.sgml index c279658d0a..bfc7025aa0 100644 --- a/docs/plugins/tmpl/gstmpeg2play.sgml +++ b/docs/plugins/tmpl/gstmpeg2play.sgml @@ -14,8 +14,3 @@ GstMpeg2play - - - - - diff --git a/docs/plugins/tmpl/gstmpeg_play.sgml b/docs/plugins/tmpl/gstmpeg_play.sgml index b3b9db6a53..5fb1038529 100644 --- a/docs/plugins/tmpl/gstmpeg_play.sgml +++ b/docs/plugins/tmpl/gstmpeg_play.sgml @@ -14,11 +14,3 @@ GstMpeg_play - - - - - -@gstmpeg_play: the object which received the signal. -@arg1: - diff --git a/docs/plugins/tmpl/gstreamer-plugins-unused.sgml b/docs/plugins/tmpl/gstreamer-plugins-unused.sgml index d59270a898..abaae708b1 100644 --- a/docs/plugins/tmpl/gstreamer-plugins-unused.sgml +++ b/docs/plugins/tmpl/gstreamer-plugins-unused.sgml @@ -1,1243 +1,4 @@ - - - - - -@packet_length: -@PES_scrambling_control: -@PES_priority: -@data_alignment_indicator: -@copyright: -@original_or_copy: -@PTS_DTS_flags: -@ESCR_flag: -@ES_rate_flag: -@DSM_trick_mode_flag: -@additional_copy_info_flag: -@CRC_flag: -@PES_extension_flag: -@PES_header_data_length: -@PTS: -@DTS: -@ESCR_base: -@ESCR_extension: -@ES_rate: -@trick_mode_control: - - - - - - -@sector: -@pack: -@sys_header: -@packet_size: -@inputbuffer: -@type: -@buffer_scale: -@buffer_size: -@buffers: -@PTS: -@DTS: -@timestamps: -@which_streams: - - - - - - - - - - -@x: -@y: -@mask: -@XIob: - - - - - - -@value: -@m1: - - - - - - - - - - - - - - - - - - -@vid_stream: - - - - - - -@name: -@Returns: - - - - - - - - - - - - -@cobin: - - - - - - -@matrix: - - -bit_allocate - - - - - - - -@pad: -@buf: - - - - - - - - - - - - -@matrix: -@qptr: -@qfact: - - - - - - - - - - - - - - - - - - -@mp: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -@Returns: - - - - - - - - - - - - -@sink: -@Returns: - - - - - - - - - - - - -@width: -@height: -@Returns: - - - - - - - - - - - - - - - - - - - - -@vid_stream: - - - - - - -@syncinfo: - - - - - - - - - - - - - - - - - - -@riff: -@Returns: - - - - - - -@obj: - - - - pads - - test - - - - - - - - - - - - - - - -@vs: - - - - - - -@s: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -@Returns: - - - - - - - - - - - - -@Returns: - - - - - - - - - - -@Returns: - - - - - - -@name: -@Returns: - - -globals - - - - - - - -@matrix: -@newmatrix: - - - - - - - - - - - - - - - - - - -@name: -@Returns: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -@vid_stream: -@Returns: - - - - - - -@vid_stream: -@filename: - - - - - - - - - - - - - - -csize - - - -mem - - - - - - - -@dt: -@out0: -@out1: -@samples: - - - - - - - - - - - - - - - - - - - - - - - - -@fd: -@Returns: - - - - - - - - - - - - -@mb: - - -RTjpeg - - - - - - - - - - - - - - - - - - - - - -mpeg2enc - - - - - - - - - - - - - -@val: -@Returns: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -@vid_stream: -@distance: - - - - - - - - - - - - - - - - - - - - - - -@audblk: -@coeffs: - - - - - - -@vid_stream: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -@Returns: - - - - - - -@vid_stream: -@index: -@matrix: - - - - - - - - - - - - - - - - - - -@bsi: -@audblk_t: -@coeffs: -@samples: - - - - - - - - - - - - - - - - - - - - - - -@matrix: -@qptr: -@qfact: - - - - - - -@info: - - - - - - - - - - - - - - - - - - - - - - - - -@vid_stream: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -@vid_stream: - - - - - - - - - - - - -@pad: -@buf: - - - - - - - - - - - - - - - - - - -@m1: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -@name: -@Returns: - - - - - - -@vid_stream: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -@Param1: -@Returns: - - - - - - - - - - - - - - - - - - - - - - - - -@fr: -@bandPtr: -@samples: -@pnt: -@Returns: - - - - - - - - - - - - - - - - - - - - - - - - -@mb: -@buf: - - - - - - - - - - - - - - - - -@type: -@id: -@Returns: - - - - - - - - - - - - -@vid_stream: -@index: -@matrix: - - - - - - - - - - - - -@matrix: - - - - - - -@window: -@gc: -@image: -@xsrc: -@ysrc: -@wsrc: -@hsrc: -@xdest: -@ydest: -@wdest: -@hdest: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -@name: -@Returns: - - - - - - - - - - - - -@vid_stream: - - - - - - - - - - - - - - - - -@codec: -@width: -@height: -@planes: -@bit_cnt: -@Returns: - - - - - - - - - - - - -@pad: -@buf: - - - - - - - - - - - - - - - - - - - - - - - - -@named_st: - - - - - - - - - - - - - - - - - - - - - - -@Returns: - - - - - - -@vid_stream: -@rx: -@ry: -@rm: -@cx: -@cy: -@cm: -@ox: -@oy: - - - - - - - - - - - - - - - - - - -@Returns: - - -l2tables - - - - - - - - - + @@ -1250,1881 +11,97 @@ l2tables @freq_limit: @Returns: - -grab - - - - - - - -@vid_stream: - - + - - - - - -@name: -@Returns: - - - - - - -@pad: -@buf: - - - - - - -@Q: - - - - - - - - -bitstream - - - - - - - - - -exponent - - - - - - - -@obj: - - - - - - - - - - - - - - - - - - -@widget: -@width: -@height: - - - - - - -@pb: -@len: - - - - - - -@obj: - - - - - - -@vid_stream: -@data: -@size: -@state: -@Returns: - - - - - - - - - - - - - - - - - - -@Returns: - - - - - - - - - - - - -@Param1: - - - - - - - - - - - - - - -encoder - - - - - - - -@Returns: - - - - - - -@vid_stream: - - - - - - -@de: -@inbuf: -@inlen: -@outbuf: -@outlen: -@Returns: - - - - - - - - - - - - - - - - - - -@obj: - - - - - - - - - - - - - - - - - - - - -mpeg2dec - - - - - - - -@buf: -@rgb: - - -param - - - - - - - - - - - - - -@parseavi: -@buf: - - - - - - - - - - - - -@widget: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -@pad: -@buf: - - -parse - - - - - - - - - - - - - - - - - - - - - - - -@name: -@Returns: - - - - - - - - - - - - -@vid_stream: - - - - - - - - - - - - -@pad: -@buf: - - - - - - - - + @gb: -@macro_val: +@runval: +@levelval: - + -@buf: -@rgb: - - - - - - - - -stats - - - - - - - - - - - - - -@gb: -@quant: -@motion_fwd: -@motion_bwd: -@pat: -@intra: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -@gb: -@quant: -@motion_fwd: -@motion_bwd: -@pat: -@intra: - - - - - - -@Returns: - - - - - - - - - - - - - - - - - - - - - - - - -@gb: -@quant: -@motion_fwd: -@motion_bwd: -@pat: -@intra: - - - - - - - - - - - - - - - - - - - - - - - - -@name: -@Returns: - - - - - - -@mp: - - - - - - - - - - - - - - - - - - -@bsi: -@audblk: -@gb: - - - - - - -@buf: -@rgb: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -@vid_stream: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -@vid_stream: -@fnum: -@Returns: - - - - - - -@Returns: - - - - - - -@vid_stream: -@val: -@huff: -@Returns: - - - - - - - - - - - - - - - - - - - - - - - - -@sp: -@bp: - - - - - - - - - - - - - - - - - - -@huff: - - - - - - - - - - - - -@matrix: - - - - - - - - - - - - - - - - - - - - - - - - -@obj: - - - - - - -@vid_stream: - - - - - - - - - - - - -@ptr: -@index: @value: +@flag: - - - - - - - - - -@Returns: - - - - - - + - + -@enc: -@inbuf: -@outbuf: -@outlen: -@Returns: - + + + + + + + + + + + +@vid_stream: + + + + + + + + @Param1: @Param2: - - - - - - @Returns: - - + - -@Varargs: - + @vid_stream: - - - - - - - - - - - - - - - - - - - - - - - - - -ac3 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -@bsi: -@samples: -@Returns: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -@filename: -@pwidth: -@pheight: -@width: -@height: -@omem: -@Returns: - - - - - - - - - - - - - - - - -@bs: -@Returns: - - -GtkOverlayImage - - - - - - - - - - - - - -@matrix: -@newmatrix: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -@vs: - - - - - - - - - - - - -@klass: - - - - - - -@pad: -@buf: - - - - - - -@pad: -@buf: - - - - - - - - - - - - -@Returns: - - - - - - - - - - - - -@fr: -@bits: - - - - - - -@var: -@lo: -@hi: -@str: - - - - - - -@de: -@scale: - - - - - - -@audblk: - - - - - - -@fr: -@Returns: - - - - - - -@buf: -@n: -@h: -@br: -@Returns: - - - - - - -@buf: -@n: -@h: -@br: -@searchForward: -@Returns: - - - - - - - - - - - - + +@index: @value: - - + - - - + +gdkxvimage - - - - - - - - - - - - - - - - - - - - - - - -@Returns: - - - - - - - - - - - - - - - - -@filename: -@mem: -@Returns: - - - - - - -@Returns: - - - - - - -@DVDSRC_OPEN: - - - - - - - - - - -@fmt: -@Varargs: - - - - - - - - - - -@Returns: - - - - - - - - - - - - -@huff: - - - - - - - - - - - - - - - - - - - - - - - - -@x: -@y: - - - - - - - - - - -@id: -@Returns: - - - - - - - - - - - - - - - - - - - - - - - - -@vid_stream: -@b: - - - - - - -@pad: -@buf: - - -decode - - - - - - - - - - - - - - - - - - - - - - - - - -common - - - - - - - - - - - - - - - - - - - - - - - - - -@vid_stream: - - - - - - - - - - - - - - - - - - - - - - - - -@vid_stream: -@n: -@b: - - - - - - - - -mhead - - - - - - - - - - - - - -@pb: -@Returns: - - -port - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -@pack: -@SCR: -@mux_rate: - - - - - - - - - - - - -@pad: -@Returns: - - - - - - -@mb: - - - - - - - - - - - - - - - - - - - - - - - - - - - - -@pad: -@buf: - - - - - - -@vid_stream: -@store: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -@vid_stream: - - - - - - -@Varargs: -@Param2: - - - - - - - - - - - - - - - - - - -@Returns: - - - - - - - - - - - - - - - - - - -@wFormatTag: -@wChannels: -@dwSamplesPerSec: -@dwAvgBytesPerSec: -@wBlockAlign: -@wBitsPerSample: - - - - - - - - - - - - - - -dvd_udf - - - - - - - -@gb: -@dct_coeff_tbl: -@run: -@level: - - - - - - - - - - - - - - - - - - -@vid_stream: - - - - - - - - - - - - - - - - - - -@vid_stream: -@matrix: -@XIob: -@YIob: - - - - - - - - -qtables - - - - - - - -@Returns: - - - - - - - - - - - - -@image: -@val: - - - - - - - - - - - - -@Returns: - - - - - - -@vid_stream: -@matrix: -@XIob: - - -musicin - - - - - - - -@filename: -@width: -@height: -@omem: -@Returns: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -@vid_stream: -@index: - - - - - - - - - - - - - - - - -@bsi: -@gb: - - - - - - - - - - - - -@x: -@y: - - - - - - - - - - - - -@info: - - - - - - -@matrix: -@qptr: -@qfact: - - - - - - - - - - - - - - - - - - - - - - - - -@fr: -@Param2: - - - - - - - - + @@ -3138,2846 +115,37 @@ musicin @gb: @val: - - - - - - - - - - - - - - - - - -@riff: -@buf: -@off: -@Returns: - - - - - - - - - - - - -@name: -@Returns: - - - - - - - - + @vid_stream: - - - - - - - - - - - - - - - - - - - - - - - - - - - - -@fr: -@header: -@Returns: - - - - - - - - - - - - -@Returns: - - - - - - - - - - - - -@vid_stream: -@distance: - - - - - - - - - - - - -@table: - - - - - - - - - - - - -@Returns: - - - - - - - - - - - - -@GST_V4LSRC_OPEN: - - - - - - -@Returns: - - - - - - - - - - - - -@vid_stream: - - - - - - - - - - - - -@image: -@x_shm_info: -@im_adaptor: -@im_port: -@im_format: - - - - - - - - - - - - - - - - - - - - - - - - - - - - -@pad: -@buf: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -@Varargs: -@Varargs: -@Returns: - - - - - - - - - - - - -@fr: -@bandPtr: -@channel: -@out: -@nb_blocks: -@Returns: - - - - - - -@vid_stream: -@inbuf: -@size: -@encoder_state: -@Returns: - - - - - - - - - - - - -@pad: -@buf: - - - - - - - - - - - - - - - - - - - - - - - - - - - - -@vs: -@o: -@i: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -@h: -@framebytes_arg: -@reduction_code: -@transform_code: -@convert_code: -@freq_limit: -@Returns: - - - - - - -@vid_stream: -@fs: -@index: - - - - - - -@imatrix: -@omatrix: - - - - - - - - - - - - - - - - - - - - - - - - -@vid_stream: - - - - - - - - - - - - -@VCDSRC_OPEN: - - - - - - -@vid_stream: -@store: - - - - - - - - - - - - -@bsi: - - - - - - - - - - - - - - - - - - - - - - - - -@name: -@Returns: - - - - - - - - - - - - -@bs: -@pcmbuf: -@Returns: - - - - - - -@vid_stream: -@Returns: - - - - - - - - - - - - -@vid_stream: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -@fr: -@Returns: - - - - - - - - - - - - -@fr: -@Returns: - - - - - - -@m1: -@m2: - - - - - - - - - - - - -@fr: -@Returns: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -@pad: -@buf: - - - - - - -@vid_stream: -@fs: - - - - - - -@Returns: - - - - - - - - - - - - -@bandPtr: -@channel: -@out: -@Returns: - - - - - - - - - - - - -@pb: -@val: -@n: - - - - - - -@Returns: - - - - - - - - - - - - -@sp: -@bp: -@Returns: - - - - - - -@vid_stream: -@inbuf: -@inlen: -@first: -@Returns: - - - - - - -@Returns: - - - - - - -@i: - - - - - - - - - - - - - - - - - - -@Param1: -@Param2: -@Returns: - - - - - - -@Returns: - - - - - - -@obj: - - - - - - - - - - - - - - - - - - -@name: -@Returns: - - - - - - -@Returns: - - - - - - -@bs: -@num_bits: -@Returns: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -@pad: -@buf: - - - - - - - - - - - - -vlc - - - - - - - -@vid_stream: -@Returns: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -@filename: -@extname: -@Returns: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -@Param1: -@Param2: - - - - - - - - - - - - -@fr: -@no: -@Returns: - - - - - - - - -putbits - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -@sp: -@bp: -@lmask: -@Returns: - - - - - - - - - - - - - - - - - - -@pb: - - - - - - - - -marker - - - - - - - - - - - - - - - - - - - - - - - - - -@image: - - - - - - - - - - - - -@vid_stream: -@hp: -@vp: -@h: -@v: -@Returns: - - - - - - - - - - - - -output - - - - - - - - - - - - - -@mb: -@scr: -@Returns: - - - - - - - - - - - - - - - - - - - - - - - - -@riff: -@Returns: - - - - - - - - -GtkXvImage - - - - - - - -@mb: - - - - - - - - -L3 - - - - - - - -@Returns: - - - - - - - - - - - - - - - - - - -@stream_id: -@STD_buffer_bound_scale: -@STD_buffer_size_bound: - - - - - - -@vid_stream: - - - - - - - - - - - - - - - - - - -@pad: -@buf: - - -dga - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -@vid_stream: - - - - - - - - - - - - -@Returns: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -@sys_header: -@rate_bound: -@audio_bound: -@fixed: -@CSPS: -@audio_lock: -@video_lock: -@video_bound: -@stream1: -@buffer1_scale: -@buffer1_size: -@stream2: -@buffer2_scale: -@buffer2_size: -@which_streams: - - - - - - - - - - - - -@Param1: - - - - - - - - - - - - - - - - - - - - - - - - -@pad: -@buf: - - - - - - -@Varargs: - - -dct - - - - - - - -@Returns: - - - - - - - - - - - - - - - - - - - - - - - - -@Param1: -@Param2: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -@index: -@value: - - - - - - - - - - - - - - -itype - - - -uncouple - - - - - - - - - - - - - -@vid_stream: -@index: - - - - - - -@name: -@Returns: - - - - - - - - - - - - - - - - - - - - - - - - - - - - -@parseavi: -@pad_nr: -@strf: -@Returns: - - - - - - - - - - - - -@Param1: -@Varargs: -@Varargs: -@Returns: - - - - - - -@length: -@original_length: -@frame_type: -@PTS: -@DTS: - - - - - - - - - - - - - - - - - - @matrix: -@qptr: -@qfact: +@XIob: +@YIob: - - - - - -@vid_stream: -@huff: -@Returns: - - - - - - - - - - - - - - -main - - - + @Returns: - - - - - - - - - - - - - - - - - -@bs: -@pcm: -@Returns: - - - - - - - - -video - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -@Param1: -@Param2: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -@vid_stream: -@flag: - - - - - - -@sp: -@bp: - - - - - - - - - - - - -@Param1: - - - - - - -@sp: -@bp: - - - - - - -@Returns: - - - - - - -@bs: - - - - - - - - - - - - -@syncinfo: -@gb: - - - - - - - - - - - - -@mb: - - - - - - - - - - - - - - - - - - -@Param1: - - - - - - - - - - - - -@pad: -@buf: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -ctables - - - - - - - -@obj: - - - - - - -@src: - - - - - - - - - - - - - - - - - - - - - - - - -@sp: -@bp: -@Returns: - - - - - - -@sp: -@bp: -@Returns: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -@Returns: - - - - - - -@pad: -@buf: - - -tables - - - - - - - -@fscod: -@bsi: -@audblk: - - - - - - -@vid_stream: - - - - - - - - - - - - - - - - - - - - - - -@vid_stream: - - -stream - - - - - - - - - - - -@fr: -@bandPtr: -@channel: -@out: -@pnt: -@Returns: - - - - - - - - - - - - - - - - - - - - - - -@mb: - - - - - - - - - - - - -@Param1: -@Param2: -@Param3: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -@Param1: -@Returns: - - - - - - - - - - - - -@vid_stream: - - - - - - - - - - - - - - - - - - -@vid_stream: - - - - - - -@name: -@Returns: - - - - - - - - - - - - - - - - - - -@txt: - - - - - - - - - - - - -@mb: -@size: - - - - - - -@file: -@Returns: - - -size - - - - - - - -@name: -@Returns: - - - - - - -@name: -@Returns: - - - - - - - - - - - - -@b: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -@mp: - - - - - - - - - - - - - - - - - - -@name: -@Returns: - - - - - - - - - - - - - - - - - - - - - - - - -@obj: - - - - - - -@obj: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -@vid_stream: -@Returns: - - - - - - - - - - - - -@var: -@lo: -@hi: -@str: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -@vid_stream: - - - - - - - - - - - - -@gb: -@value: - - - - - - -@imatrix: -@omatrix: - - - - - - -@bsi: -@audblk: -@gb: - - - - - - -@Varargs: -@Varargs: -@Returns: - - - - - - - - - - - - - - -tableawd - - - -debug - - - - - - - -@Param1: -@Returns: - - - - - - -@name: -@Returns: - - - - - - - - - - - - - - - - - - - - -proto - - - - - - - - - - - - - - - -acconfig - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -@Varargs: -@Param2: -@Returns: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -@vid_stream: -@tc: -@Returns: - - - - - - - - - - - - - - - - - - - - - - - - -@name: -@Returns: - - - - - - - - - - - - - - - - - - -@Param1: -@Returns: - - - - - - -@pad: -@buf: - - - - - - - - - - - - - - - - - - - - - - - - -@image: -@val: - - - - - - -@buf: -@rgb: - - - - - - -@info: - - - - - - -@pad: -@buf: - - - - - - -@vid_stream: - - - - - - - - - - - - - - - - - - -@vid_stream: -@Returns: - - - - - - -@vid_stream: -@Returns: - - - - - - - - - - - - -@vid_stream: -@filename: - - - - - - -@vid_stream: -@index: -@matrix: - - - - - - -@matrix: -@newmatrix: - - - - - - - - - - - - -@pad: -@buf: - - -htable - - - + + + + + +@pack: +@SCR: +@mux_rate: + + @@ -5994,782 +162,57 @@ htable @h: @v: - - - - - - - -gstriff - - - - - - - -@vid_stream: - - - - - - - - - - - - - - -crc - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -downmix - - - - - - - - - - - - - - - - - - - -@filename: -@Returns: - - - - - - - - - - - - - - - - - - - - - - - - - - -config - - - - - - - -@buf: -@rgb: - - - - - - -@pad: -@buf: - - - - - - - - - - - - - - - - - - - - - - - - -@blk: -@i_quant_mat: -@Returns: - - - - - - - - - - - - - - - - - - -gdkxvimage - - - - - - - - - - - - - -@offset: -@id: -@size: - - - - - - - - - - - - -@Returns: - - - - - - - - - - - - - - - - - - - - - - - - -@data: - - - - - - - - - - - - -@vid_stream: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -@vid_stream: -@index: -@matrix: - - - - - - - - - - - - -@Param1: -@Param2: -@Returns: - - - - - - -@pb: -@buffer: -@len: - - - - - - - - - - - - -@h: -@framebytes_arg: -@reduction_code: -@transform_code: -@convert_code: -@freq_limit: -@Returns: - - - - - - - - - - - - -@enc: -@Returns: - - - - - - - - - - - - -@Returns: - - - - - - -@vid_stream: -@coef: -@LocalEHuff: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -@value: -@flag: - - - - - - - - - - - - -@vid_stream: - - - - - - -@buf: -@n: -@h: -@Returns: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -@name: -@Returns: - - - - - - - - - - - - - - - - - - -@vid_stream: - - - - - - -@Varargs: -@Param2: - - - - - - - - - - - - -buffer - - - - - - - -@cobin: - - - - - - -@name: -@Returns: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -@type: -@width: -@height: -@Returns: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -@filename: -@pwidth: -@pheight: -@mem: -@Returns: - - - - - - - - - - -@bs: -@pcm: -@Returns: - - - - - - -@mem: - - - - - - -@vid_stream: -@matrix: -@XIob: -@YIob: - - - - - - -@vid_stream: -@RefFS: -@NewFS: - - - - - - -@vid_stream: -@LocalDHuff: -@Returns: - - - - - - -@riff: -@fourcc: -@Returns: - - - - - - - - - - - + +decoders - + -@buffer: -@length: -@base: -@scan_pos: -@last_pos: -@current_start: -@buffer_type: -@stream_id: -@new_frame: -@next_frame_time: - + - + -@syncinfo: -@bsi: - + - - - - - - - - - - - -@parseavi: -@pad_nr: -@strf: -@Returns: - - - - - - - - - + - - - - - - - - - - - - - - - - - - - -@matrix: - + -@fr: -@Returns: - + - + -@matrix: - + @@ -6781,118 +224,7 @@ buffer - - - - - - - - - - - - - - - - - -@pad: -@buf: - - - - - - - - -huffman - - - -system - - - -ring_buffer - - - - - - - - - - - - - -@vid_stream: -@Returns: - - - - - - - - - - - - - - - - - - - - - - - - -@vid_stream: -@matrix: -@XIob: - - - - - - - - - - -@pb: - - - - - - - - - - - - -@gb: -@runval: -@levelval: - - - - - - - - + @@ -6900,641 +232,6 @@ ring_buffer @buf: @rgb: - - - - - - - - - - - -@vid_stream: - - - - - - -@index: -@value: - - -util - - - - - - - -@vid_stream: - - - - - - -@name: -@Returns: - - - - - - - - -getvlc - - - - - - - - - - - - - -stamp - - - - - - - - - - - - - -@vid_stream: -@Returns: - - -prototypes - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -@pad: -@buf: - - - - - - -@name: -@Returns: - - - - - - - - -mpg123 - - - - - - - - - - - - - -@vid_stream: -@n: -@Returns: - - - - - - - - - - - - -@pad: -@buf: - - - - - - - - - - - - - - - - - - -@bsi: -@audblk: -@coeffs: - - -core - - - - - - - -@name: -@Returns: - - - - - - - - - - - - - - - - - - - - - - -@Param1: - - - - - - -@klass: - - - - - - - - - - - - -@Param1: -@Varargs: - - - - - - - - - - - - -@outbfr: -@outbase: -@temp: -@outcnt: -@bytecnt: -@len: -@newlen: - - - - - - - - - - -@Param1: -@Varargs: - - - - - - -@vid_stream: - - - - - - -@vid_stream: - - - - - - -@fourcc: -@Returns: - - - - - - -@Param1: -@Returns: - - - - - - -@name: - - -mantissa - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -imdct - - - - - - - - - - - - - - - - - - - -@pad: -@buf: - - - - - - - - - - - - - - - - - - - - - - - - -@vid_stream: -@fmcmatrix: -@bmcmatrix: -@imcmatrix: -@XIob: -@YIob: - - - - - - -@vid_stream: - - - - - - -@gb: -@runval: -@levelval: - - - - - - - - - - - - -@name: -@Returns: - - - - - - - - - - - - -@bsi: -@audblk: -@coeffs: - - - - - - - - - - - - -@vid_stream: - - - - - - -@Param1: -@Param2: -@Returns: - - - - - - - - - - - - - - - - - - - - - - -@sp: -@bp: -@lmask: -@cmask: -@Returns: - - - - - - - - - - - - -@name: -@Returns: - - - - - - -@Returns: - - - - - - - - - - - - -@Param1: -@Returns: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -7561,7 +258,32 @@ imdct @ES_rate: @trick_mode_control: - + + + + + + + + + + + + + + + + + +@h: +@framebytes_arg: +@reduction_code: +@transform_code: +@convert_code: +@freq_limit: +@Returns: + + @@ -7569,7 +291,2704 @@ imdct @pad: @buf: - + + + + + + + + + + + +@pad: +@buf: + + + + + + +@name: +@Returns: + + + + + + +@vid_stream: +@matrix: +@XIob: + + + + + + + + + + + + +@s: + + + + + + + + + + + + +@name: +@Returns: + + + + + + + + + + + + + + + + + + +@bsi: +@samples: +@Returns: + + + + + + + + + + + + + + + + + + +@buf: +@rgb: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +@Returns: + + + + + + + + + + + + +@Param1: + + + + + + + + + + + + + + +globals + + + + + + + + + +uncouple + + + + + + + + + + + + + + + + + + + + + + + + + +@buf: +@rgb: + + + + + + + + + + + + + + + + + + + + + + + + + + +@bs: + + + + + + + + + + + + + + + + + + +@Returns: + + + + + + + + + + + + + + + + + + + + +ac3 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +@pad: +@buf: + + + + + + + + + + + + + + + + + + +@type: +@id: +@Returns: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +@vid_stream: + + + + + + +@header: +@Returns: + + + + + + + + + + + + + + + + + + +@vid_stream: +@distance: + + +crc + + + + + + + +@vid_stream: +@inbuf: +@size: +@encoder_state: +@Returns: + + + + + + + + +imdct + + + + + + + +@pad: +@buf: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +@obj: + + + + + + + + + + + + +@name: +@Returns: + + + + + + +@name: +@Returns: + + + + + + +@vid_stream: +@Returns: + + + + + + + + + + + + + + + + +@vs: +@o: +@i: + + + + + + +@parseavi: +@pad_nr: +@strf: +@Returns: + + + + + + + + + + + + + + + + + + +@enc: +@Returns: + + + + + + + + + + + + + + + + + + +@vid_stream: +@Returns: + + + + + + +@Returns: + + + + + + + + + + + + + + + + + + +@b: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +@vid_stream: +@index: +@matrix: + + + + + + + + + + + + +@matrix: +@newmatrix: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +@name: +@Returns: + + + + + + + + + + + + +@Returns: + + + + + + + + +acconfig + + + + + + + + + + + + + +@fr: +@no: +@Returns: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +@txt: + + + + + + + + + + + + +@vid_stream: + + + + + + +@Returns: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +@matrix: +@qptr: +@qfact: + + + + + + +@vs: + + + + + + + + + + + + + + + + + + + + + + +@buf: +@n: +@h: +@Returns: + + + + + + + + + + + + + + + + + + + + + + +@matrix: +@qptr: +@qfact: + + + + + + + + + + + + + + + + + + + + +exponent + + + +getvlc + + + + + + + + + + + + + +@riff: +@buf: +@off: +@Returns: + + + + + + + + + + + + + + + + + + + + + + + + + + + + +@Param1: +@Returns: + + + + + + + + + + + + +@matrix: +@newmatrix: + + + + + + + + + + + + + + + + + + +@index: +@value: + + + + + + +@name: +@Returns: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +@vid_stream: +@b: + + + + + + + + + + + + +@length: +@original_length: +@frame_type: +@PTS: +@DTS: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +@vid_stream: +@coef: +@LocalEHuff: + + + + + + + + + + + + + + +config + + + + + + + +@sp: +@bp: +@Returns: + + + + + + +@vid_stream: +@n: +@b: + + + + + + + + + + + + + + + + +@image: + + + + + + + + + + + + + + + + + + + + + + + + +@gb: +@dct_coeff_tbl: +@run: +@level: + + + + + + + + + + + + +@vid_stream: + + + + + + +@name: +@Returns: + + + + + + +@name: +@Returns: + + + + + + +@bs: +@Returns: + + + + + + + + + + + + +@Returns: + + + + + + + + + + + + +@matrix: + + + + + + + + + + + + + + + + + + + + + + + + +@fmt: +@Varargs: + + + + + + + + + + + + + + + + + + +@Varargs: +@Varargs: +@Returns: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +@vid_stream: +@index: +@matrix: + + + + + + + + + + + + +@vid_stream: + + + + + + +@de: +@scale: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +system + + + + + + + + + + + + + +@packet_length: +@PES_scrambling_control: +@PES_priority: +@data_alignment_indicator: +@copyright: +@original_or_copy: +@PTS_DTS_flags: +@ESCR_flag: +@ES_rate_flag: +@DSM_trick_mode_flag: +@additional_copy_info_flag: +@CRC_flag: +@PES_extension_flag: +@PES_header_data_length: +@PTS: +@DTS: +@ESCR_base: +@ESCR_extension: +@ES_rate: +@trick_mode_control: + + + + + + +@mb: +@size: + + + + + + +@vid_stream: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +@name: +@Returns: + + + + + + +@Param1: +@Varargs: + + + + + + +@vid_stream: +@fnum: +@Returns: + + +debug + + + + + + + + + + + + + + + + + +@offset: +@id: +@size: + + + + + + + + + + + + +@obj: + + +htable + + + + + + + +@pb: +@len: + + + + + + + + + + + + +@sp: +@bp: + + + + + + +@Returns: + + + + + + + + + + + + + + + + + + + + + + + + + + + + +@vid_stream: +@Returns: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +@var: +@lo: +@hi: +@str: + + + + + + +@vid_stream: +@pmem: +@fmem: + + +musicin + + + + + + + + + + + + + +@Returns: + + + + + + +@gb: +@coded_bp: + + + + + + +@named_st: + + + + + + + + + + + + + + + + + + +@gstvideosink: the object which received the signal. +@arg1: + + + + + + +@pb: +@buffer: +@len: + + + + + + + + + + + + + + + + + + +@vid_stream: +@rx: +@ry: +@rm: +@cx: +@cy: +@cm: +@ox: +@oy: + + + + + + +@syncinfo: +@gb: + + + + + + +@vid_stream: +@huff: +@Returns: + + + + + + +@obj: + + + + + + + + + + + + + + + + +@bsi: +@gb: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +@sys_header: +@rate_bound: +@audio_bound: +@fixed: +@CSPS: +@audio_lock: +@video_lock: +@video_bound: +@stream1: +@buffer1_scale: +@buffer1_size: +@stream2: +@buffer2_scale: +@buffer2_size: +@which_streams: + + +mantissa + + + + + + + +@vid_stream: +@LocalDHuff: +@Returns: + + + + + + + + + + + + + + +video + + + + + + + +@matrix: +@newmatrix: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +@src: + + + + + + + + + + + + +@id: +@Returns: + + + + + + + + + + + + + + + + + + + + + + + + +@Returns: + + + + + + +@name: +@Returns: + + +dither + + + + + + + + + + + + + +@Returns: + + + + + + + + + + + + +@vid_stream: +@fs: +@index: + + + + + + + + + + + + +@value: + + + + + + +@pb: +@val: +@n: + + + + + + +@pad: +@buf: + + + + + + + + + + + + +@vid_stream: + + + + + + + + + + + + + + + + + + +@klass: + + + + + + +@mb: + + + + + + + + + + + + + + +mhead + + + + + + + + + + + + + + + + + + + +@gb: +@macro_val: + + + + + + + + + + + + +@fr: +@Param2: + + + + + + +@name: + + + + + + + + + + + + + + + + + + +@vs: +@o: +@i: + + + + + + + + + + + + +@huff: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +@sp: +@bp: +@lmask: +@Returns: + + + + + + +@audblk: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +@widget: + + + + + + + + + + + + + + + + + + +@Returns: + + + + + + + + + + + + +@vid_stream: +@Returns: + + + + + + +@imatrix: +@omatrix: + + + + + + + + + + + + + + +stream + + + + + + + + + + + + + +@vid_stream: +@Returns: + + + + + + +@vid_stream: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +bit_allocate + + + + + + + +@vid_stream: + + +ctables + + + + + + + +@mb: + + + + + + +@pad: +@buf: + + + + + + + + + + + + + + + + + + +@fr: +@Returns: + + + + + + +@name: +@Returns: + + + + + + +@fr: +@Returns: + + + + + + + + + + +@fr: +@Returns: + + +mpg123 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +@filename: +@Returns: + + + + + + + + + + + + +@fd: +@Returns: + + + + + + + + + + + + + + + + + + + + + + + + +@outbfr: +@outbase: +@temp: +@outcnt: +@bytecnt: +@len: +@newlen: + + + + + + +@blk: +@i_quant_mat: +@Returns: + + + + + + +dvd_udf + + + + + + + +@Param1: +@Returns: + + + + + + + + + + + + +@info: + + + + + + + + + + + + +@name: +@Returns: + + + + + + +@Returns: + + + + + + +@window: +@gc: +@image: +@xsrc: +@ysrc: +@wsrc: +@hsrc: +@xdest: +@ydest: +@wdest: +@hdest: + + + + + + + + + + + + +@gstwinenc: the object which received the signal. +@arg1: + + + + + + + + + + + + +@x: +@coef: + + + + + + + + @@ -7589,11 +3008,4404 @@ imdct @bpl: @mem: - + +ring_buffer + + + +@syncinfo: + + + + + + +@name: +@Returns: + + + + + + + + + + + + + + + + + + +@vid_stream: + + + + + + + + + + + + +@bsi: +@audblk: +@gb: + + + + + + + + + + + + +@vid_stream: + + + + + + +@pad: +@buf: + + + + + + + + + + + + +@mb: +@scr: +@Returns: + + +mpeg2enc + + + + + + + + + + + + + +@matrix: +@qptr: +@qfact: + + +port + + + + + + + +@vid_stream: +@RefFS: +@NewFS: + + + + + + + + + + + + + + + + + + + + + + + + + + +proto + + + + + + + + + + + + + + + +gstriff + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +@m1: +@m2: + + + + + + +@vid_stream: +@index: + + + + + + +@vid_stream: +@tc: +@Returns: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +@Param1: + + + + + + + + + + + + +@vid_stream: + + + + + + + + + + + + + + + + +@Param1: +@Returns: + + +marker + + + + + + + + + + + + + + + + + + + +@h: +@framebytes_arg: +@reduction_code: +@transform_code: +@convert_code: +@freq_limit: +@Returns: + + + + + + + + + + + + + + + + + + + + + + +@vid_stream: +@store: + + + + + + +@Returns: + + + + + + +@GST_V4LSRC_OPEN: + + + + + + +@Returns: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +@vid_stream: + + + + + + +@vid_stream: + + + + + + + + + + + + +@riff: +@fourcc: +@Returns: + + + + + + +@filename: +@mem: +@Returns: + + + + + + + + + + + + + + + + + + + + + + + + +@bs: +@num_bits: +@Returns: + + + + + + + + + + + + + + + + + + + + + + + + + + + + +@Param1: +@Param2: + + + + + + + + + + + + + + + + + + +@pad: +@buf: + + + + + + + + + + + + + + + + + + + + + + + + + + + + +@sp: +@bp: +@Returns: + + + + + + + + + + + + +@sp: +@bp: +@Returns: + + + + + + + + + + + + +@buf: +@n: +@h: +@br: +@Returns: + + + + + + +@buf: +@n: +@h: +@br: +@searchForward: +@Returns: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +tables + + + + + + + + + + + + + + + + + + + + + +output + + + + + + + +@bs: +@pcm: +@Returns: + + + + + + +@fr: +@bandPtr: +@channel: +@out: +@pnt: +@Returns: + + + + + + +@riff: +@Returns: + + + + + + +@Param1: + + + + + + +GtkOverlayImage + + + + + + + + + + + + + + + + + + + + + + + + + +@vid_stream: + + + + + + +@huff: + + + + + + + + + + + + +@name: +@Returns: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +@vid_stream: +@fmcmatrix: +@bmcmatrix: +@imcmatrix: +@XIob: +@YIob: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +csize + + + + + + + + + + + + + +@fscod: +@bsi: +@audblk: + + + + + + + + + + +@Varargs: +@Varargs: +@Returns: + + + + + + + + + + + + + + + + + + + + + + + + +@pad: +@buf: + + + + + + + + + + + + +stats + + + + + + + + + + + + + + + + + + + + + + + + + +@vid_stream: + + + + + + + + + + + + + + + + + + + + + + + + +@vid_stream: + + + + + + +@vid_stream: + + + + + + + + + + + + + + + + + + +@obj: + + + + + + + + + + + + +@x: +@y: + + + + + + +@filename: +@width: +@height: +@omem: +@Returns: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +@pad: +@buf: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +@Returns: + + + + + + + + +size + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +@pb: +@Returns: + + + + + + + + + + + + + + + + + + + + + + + + +@a: +@b: +@samples: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +@Param1: +@Param2: + + + + + + + + + + + + +@vid_stream: + + + + + + +@pad: +@buf: + + + + + + + + + + + + + + + + + + + + +putbits + + + + + + + +@name: +@Returns: + + + + + + + + + + + + +@fr: +@Returns: + + +itype + + + + + + + + + + + + + + + + + + + + + + + + + +@vid_stream: +@flag: + + +decode + + + + + + + + + + + + + + + + + + + +@pad: +@buf: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +@name: +@Returns: + + + + + + +@vid_stream: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +@mb: +@buf: + + + + + + + + +bitstream + + + + + + + + + + + + + + + + + + + +@vid_stream: + + + + + + + + + + + + +@pad: +@buf: + + + + + + + + + + + + +@Varargs: + + + + + + +@Returns: + + + + + + + + +prototypes + + + + + + + +@vid_stream: +@Returns: + + +L3 + + + + + + + +@data: + + + + + + + + + + + + + + + + + + +@pad: +@Returns: + + + + + + +@klass: + + + + + + + + + + + + + + + + + + +@name: +@Returns: + + + + + + + + + + + + + + +encoder + + + + + + + +@de: +@inbuf: +@inlen: +@outbuf: +@outlen: +@Returns: + + + + + + +@fr: +@bits: + + + + + + + + + + + + +@matrix: + + + + + + + + + + + + +@vid_stream: +@filename: + + + + + + +@vid_stream: +@n: +@Returns: + + + + + + + + + + + + + + + + + + +@vid_stream: + + + + + + + + + + + + + + + + + + + + +parse + + + + + + + +@pad: +@buf: + + + + + + + + + + + + +@bsi: + + + + + + + + + + + + + + +tableawd + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +@vid_stream: +@matrix: +@XIob: +@YIob: + + + + + + + + + + + + + + + + + + +@matrix: + + + + + + + + + + + + + + + + +@matrix: +@qptr: +@qfact: + + + + + + + + + + + + +@fr: +@bandPtr: +@channel: +@out: +@nb_blocks: +@Returns: + + + + + + + + + + + + + + + + + + + + + + + + +@mp: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +@pad: +@buf: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +@gstmpeg_play: the object which received the signal. +@arg1: + + + + + + + + + + + + + + + + pads + + test + + + + + + + + + +@Varargs: +@Param2: + + + + + + +@image: +@val: + + + + + + +@buf: +@rgb: + + + + + + +@vid_stream: + + + + + + + + + + + + + + + + + + + + + + + + +@name: +@Returns: + + + + + + + + + + + + +@name: +@Returns: + + + + + + + + + + + + + + + + + + +@DVDSRC_OPEN: + + + + + + + + + + +@vs: + + + + + + + + + + + + + + + + + + +@obj: + + + + + + +@mp: + + + + + + +@obj: + + + + + + +@vid_stream: + + + + + + + + + + + + +@pad: +@buf: + + + + + + + + + + + + +@vid_stream: +@Returns: + + + + + + +@enc: +@inbuf: +@outbuf: +@outlen: +@Returns: + + + + + + + + + + + + + + + + + + + + + + + + +@riff: +@Returns: + + + + + + +@x: +@y: +@mask: +@XIob: + + + + + + + + + + + + +@i: + + + + + + + + + + + + +@mb: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +@Varargs: +@Param2: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +@pad: +@buf: + + + + + + +@m1: + + + + + + + + + + + + + + + + + + +@riff: +@number: +@Returns: + + + + + + + + + + + + +@Returns: + + + + + + +@Param1: +@Returns: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +@fr: +@Returns: + + + + + + + + + + + + + + + + + + + + +common + + + + + + + + + + + + + + + + + + + + + + + +@file: +@Returns: + + + + + + +@vid_stream: + + + + + + +@vid_stream: +@index: +@matrix: + + + + + + +@mb: + + +rematrix + + + + + + + + + + + + + + + + + + + + + + + + + +@vid_stream: +@hp: +@vp: +@h: +@v: +@Returns: + + + + + + +@bsi: +@audblk_t: +@coeffs: +@samples: + + + + + + + + + + +@vid_stream: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +@Returns: + + + + + + +@name: +@Returns: + + + + + + +@vid_stream: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +buffer + + + + + + + + + + + + + + + + + + + + + + + + + +@sink: +@Returns: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +@width: +@height: +@Returns: + + + + + + + + + + + + + + + + + + +@var: +@lo: +@hi: +@str: + + + + + + +@parseavi: +@buf: + + + + + + +@Varargs: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +@gb: +@value: + + + + + + + + + + + + +@filename: +@pwidth: +@pheight: +@mem: +@Returns: + + +main + + + + + + + +@Returns: + + + + + + + + + + + + +@vid_stream: + + + + + + + + + + + + +@filename: +@pwidth: +@pheight: +@width: +@height: +@omem: +@Returns: + + + + + + +@vid_stream: +@Returns: + + + + + + + + +GtkXvImage + + + + + + + +@pad: +@buf: + + + + + + + + + + + + + + + + + + +@vid_stream: +@data: +@size: +@state: +@Returns: + + +jdw + + + + + + + + + + + + + + + + + + + +@vid_stream: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +@bsi: +@audblk: +@coeffs: + + + + + + +@sector: +@pack: +@sys_header: +@packet_size: +@inputbuffer: +@type: +@buffer_scale: +@buffer_size: +@buffers: +@PTS: +@DTS: +@timestamps: +@which_streams: + + + + + + +@Returns: + + + + + + + + + + + + + + + + + + +@bandPtr: +@channel: +@out: +@Returns: + + + + + + + + + + + + + + + + +@vid_stream: +@index: + + + + + + + + + + + + + + + + + + + + + + + + +@Returns: + + + + + + +@vid_stream: + + + + + + + + + + + + +@VCDSRC_OPEN: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +@image: +@x_shm_info: +@im_adaptor: +@im_port: +@im_format: + + + + + + + + + + + + + + + + +@mp: + + + + + + +@vid_stream: +@index: +@matrix: + + + + + + +@Returns: + + + + + + +@name: +@Returns: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +@Varargs: +@Param2: +@Returns: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +@ptr: +@index: +@value: + + + + + + + + + + + + +@syncinfo: +@gb: + + + + + + +@Param1: +@Varargs: +@Varargs: +@Returns: + + + + + + + + + + + + +@imatrix: +@omatrix: + + + + + + +@Returns: + + + + + + + + + + + + + + + + + + +@Returns: + + + + + + + + + + + + + + + + + + + + + + + + +@vid_stream: +@filename: + + + + + + + + + + + + + + + + + + +@pad: +@buf: + + + + + + + + + + + + + + + + + + + + + + + + +@Param1: +@Param2: + + + + + + + + + + + + + + + + + + + + + + + + + + + + +downmix + + + + + + + + + + + + + + + + + +@Returns: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +@bsi: +@audblk: +@coeffs: + + + + + + +@vid_stream: + + + + + + + + + + + + +@vid_stream: + + + + + + + + + + + + + + + + + + +@gb: +@runval: +@levelval: + + + + + + + + + + + + +@buf: +@rgb: + + + + + + + + + + +@Returns: + + + + + + + + + + + + + + + + + + +@sp: +@bp: +@lmask: +@cmask: +@Returns: + + + + + + + + + + + + + + +stamp + + + + + + + +@gb: +@quant: +@motion_fwd: +@motion_bwd: +@pat: +@intra: + + +dct + + + + + + + +@syncinfo: +@bsi: + + + + + + +@obj: + + + + + + + + + + + + +@gb: +@quant: +@motion_fwd: +@motion_bwd: +@pat: +@intra: + + + + + + +@obj: + + + + + + +@pad: +@buf: + + + + + + +@Returns: + + + + + + + + + + + + + + + + +@gb: +@quant: +@motion_fwd: +@motion_bwd: +@pat: +@intra: + + + + + + +@vid_stream: + + + + + + + + + + + + + + + + + + +@bsi: +@audblk: +@gb: + + + + + + + + + + + + + + +huffman + + + + + + + + + +param + + + + + + + + + + + + + + + + + + + +l2tables + + + + + + + + + + + + + +@value: +@m1: + + + + + + + + + + + + +@Returns: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +@Param1: + + + + + + +@Returns: + + + + + + +@Returns: + + + + + + +@Param1: +@Returns: + + + + + + +@mb: + + + + + + + + + + + + + + + + + + + + + + + + +@pad: +@buf: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +@matrix: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +@vid_stream: + + +mem + + + + + + + +@vid_stream: + + + + + + + + +grab + + + + + + + +@table: + + + + + + + + + + + + + + + + + + +@bs: +@pcm: +@Returns: + + + + + + +@pb: + + + + + + + + + + + + + + + + + + +@wFormatTag: +@wChannels: +@dwSamplesPerSec: +@dwAvgBytesPerSec: +@wBlockAlign: +@wBitsPerSample: + + + + + + +@gb: +@macro_val: + + + + + + + + + + + + +@Param1: +@Param2: +@Returns: + + + + + + + + + + + + + + + + + + + + + + +@val: +@Returns: + + + + + + + + + + + + + + + + + + +@Returns: + + + + + + + + + + + + + + + + + + +@name: +@Returns: + + + + + + + + + + + + + + + + + + + + + + + + +@Returns: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +@pad: +@buf: + + + + + + + + + + + + + + + + + + +@cobin: + + + + + + +@name: +@Returns: + + + + + + + + + + + + + + + + + + + + + + +@vid_stream: +@store: + + + + + + + + + + + + + + + + + + +@fr: +@header: +@Returns: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +@name: +@Returns: + + + + + + + + + + + + +@buf: +@rgb: + + + + + + +@ptr: +@index: +@value: + + + + + + + + +RTjpeg + + + + + + + + + + + + + +@filename: +@extname: +@Returns: + + + + + + + + + + + + +@fourcc: +@Returns: + + + + + + +@name: +@Returns: + + + + + + +@Returns: + + + + + + +@widget: +@width: +@height: + + + + + + + + + + + + + + + + +@bs: +@pcmbuf: +@Returns: + + + + + + + + + + + + +@matrix: + + + + + + +@vid_stream: + + + + + + + + + + + + + + + + + + +@pad: +@buf: + + + + + + +@pb: + + + + + + +@vid_stream: +@distance: + + + + + + + + + + + + + + + + + + + + +core + @@ -7603,11 +7415,304 @@ imdct @Param1: @Param2: - -rematrix + + + + + +@dt: +@out0: +@out1: +@samples: + + +vlc - + + + + + + + + + + + +@fr: +@bandPtr: +@samples: +@pnt: +@Returns: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +@vid_stream: +@val: +@huff: +@Returns: + + + + + + +@vid_stream: +@source: +@dest: + + + + + + +@name: +@Returns: + + + + + + +@cobin: + + + + + + + + + + + + + + + + + + + + + + + + +@Returns: + + +qtables + + + + + + + + + + + + + + + + + + + +@vid_stream: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +@vid_stream: + + + + + + + + + + + + + + +mpeg2dec + + + + + + + +@pad: +@buf: + + + + + + + + + + + + + + + + + + +@sp: +@bp: + + + + + + +@Param1: +@Param2: + + + + + + +@sp: +@bp: + + + + + + +@Returns: + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -7624,32 +7729,274 @@ rematrix @curoffset: @nextlikely: - + + + + + +@Param1: + + - - - - - -@ptr: -@index: -@value: - - + - + +@Param1: +@Varargs: + + + + + + +@mem: + + + + + + +@Q: + + + + + + + + + + + + + + +util + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +@Param1: +@Param2: +@Param3: + + + + + + + + + + + + + + + + +@stream_id: +@STD_buffer_bound_scale: +@STD_buffer_size_bound: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +@Returns: + + + + + + + + + + + + + + + + +@Param1: +@Returns: + + + + + + + + + + + + +@Returns: + + + + + + +@name: +@Returns: + + + + + + +@pad: +@buf: + + + + + + + + + + + + +@x: +@y: + + + + + + +@vid_stream: +@inbuf: +@inlen: +@first: +@Returns: + + + + + + + + + + + + +@info: @@ -7659,53 +8006,378 @@ rematrix @name: @Returns: - + - - - - - + - + - - - - - -@a: -@b: -@samples: - - - - - - -@vs: -@o: -@i: - - + - + + + + + +@obj: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +@parseavi: +@pad_nr: +@strf: +@Returns: + + + + + + + + + + + + + + + + + + + + + + +dga + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +@Param1: +@Param2: +@Returns: + + + + + + + + + + + + +@type: +@width: +@height: +@Returns: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +@info: + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +@buffer: +@length: +@base: +@scan_pos: +@last_pos: +@current_start: +@buffer_type: +@stream_id: +@new_frame: +@next_frame_time: + + + + + + +@pad: +@buf: + + + + + + + + + + + + + + + + + + +@image: +@val: + + + + + + + + + + + + +@vid_stream: +@matrix: +@XIob: + + + + + + + + + + + + +@audblk: +@coeffs: + + + + + + +@codec: +@width: +@height: +@planes: +@bit_cnt: +@Returns: + + + + + + + + + + + + +@Returns: + + + + + + + + + + + + + + + + + + + + + + + + +@pad: +@buf: + + @@ -7713,287 +8385,17 @@ rematrix @name: @Returns: - - - - - -@header: -@Returns: - - - - - - -decoders - - - - - - - -@x: -@coef: - - + - - - - - - - - - - - -@riff: -@number: -@Returns: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -@syncinfo: -@gb: - - -dither - - - - - - - -@Returns: - - - - - - -@Returns: - - - - - - - - - - - - - - - - - - - - - - - - -@gb: -@macro_val: - - - - - - - - - - - - - - - - - - - - - - -@name: -@Returns: - - + @vid_stream: -@source: -@dest: - - - - - - - - - - - - - - -jdw - - - - - - - -@vid_stream: - - - - - - -@name: -@Returns: - - - - - - - - - - - - - - - - - - - - - - - - - - -@vid_stream: -@pmem: -@fmem: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -@gb: -@coded_bp: - - - - - - - - - - - - +@fs: diff --git a/docs/plugins/tmpl/gstspectrum.sgml b/docs/plugins/tmpl/gstspectrum.sgml index feebe84b6e..a3dc5d38b3 100644 --- a/docs/plugins/tmpl/gstspectrum.sgml +++ b/docs/plugins/tmpl/gstspectrum.sgml @@ -14,8 +14,3 @@ GstSpectrum - - - - - diff --git a/docs/plugins/tmpl/gstv4lsrc.sgml b/docs/plugins/tmpl/gstv4lsrc.sgml index cece4f3cdb..ba14a4f02a 100644 --- a/docs/plugins/tmpl/gstv4lsrc.sgml +++ b/docs/plugins/tmpl/gstv4lsrc.sgml @@ -14,73 +14,3 @@ GstV4lSrc - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/docs/plugins/tmpl/gstwindec.sgml b/docs/plugins/tmpl/gstwindec.sgml index b3e9fc4613..e4f1e667f7 100644 --- a/docs/plugins/tmpl/gstwindec.sgml +++ b/docs/plugins/tmpl/gstwindec.sgml @@ -14,13 +14,3 @@ GstWinDec - - - - - - - - - - diff --git a/docs/plugins/tmpl/gstwinenc.sgml b/docs/plugins/tmpl/gstwinenc.sgml index 2a4997b045..8e8fe36422 100644 --- a/docs/plugins/tmpl/gstwinenc.sgml +++ b/docs/plugins/tmpl/gstwinenc.sgml @@ -14,36 +14,3 @@ GstWinEnc - - - - - -@gstwinenc: the object which received the signal. -@arg1: - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/docs/plugins/tmpl/median.sgml b/docs/plugins/tmpl/median.sgml index aa35882720..1408d68318 100644 --- a/docs/plugins/tmpl/median.sgml +++ b/docs/plugins/tmpl/median.sgml @@ -14,13 +14,3 @@ GstMedian - - - - - - - - - - diff --git a/docs/plugins/tmpl/mp3parse.sgml b/docs/plugins/tmpl/mp3parse.sgml index 6836a94154..07d6078e59 100644 --- a/docs/plugins/tmpl/mp3parse.sgml +++ b/docs/plugins/tmpl/mp3parse.sgml @@ -14,8 +14,3 @@ Mp3Parse - - - - - diff --git a/docs/plugins/tmpl/mpeg1parse.sgml b/docs/plugins/tmpl/mpeg1parse.sgml index a77682a3d2..de8497daff 100644 --- a/docs/plugins/tmpl/mpeg1parse.sgml +++ b/docs/plugins/tmpl/mpeg1parse.sgml @@ -14,8 +14,3 @@ Mpeg1Parse - - - - - diff --git a/docs/plugins/tmpl/mpeg2parse.sgml b/docs/plugins/tmpl/mpeg2parse.sgml index fafd52ecf5..a2533ccd79 100644 --- a/docs/plugins/tmpl/mpeg2parse.sgml +++ b/docs/plugins/tmpl/mpeg2parse.sgml @@ -14,8 +14,3 @@ Mpeg2Parse - - - - - diff --git a/docs/plugins/tmpl/mpeg2subt.sgml b/docs/plugins/tmpl/mpeg2subt.sgml index b70dee2bb3..1ce7894105 100644 --- a/docs/plugins/tmpl/mpeg2subt.sgml +++ b/docs/plugins/tmpl/mpeg2subt.sgml @@ -14,8 +14,3 @@ Mpeg2Subt - - - - - diff --git a/docs/plugins/tmpl/smooth.sgml b/docs/plugins/tmpl/smooth.sgml index f4ee1d3066..0828169db4 100644 --- a/docs/plugins/tmpl/smooth.sgml +++ b/docs/plugins/tmpl/smooth.sgml @@ -14,18 +14,3 @@ GstSmooth - - - - - - - - - - - - - - - diff --git a/docs/plugins/tmpl/smoothwave.sgml b/docs/plugins/tmpl/smoothwave.sgml index c9e149c7c5..be5c975f52 100644 --- a/docs/plugins/tmpl/smoothwave.sgml +++ b/docs/plugins/tmpl/smoothwave.sgml @@ -14,18 +14,3 @@ GstSmoothWave - - - - - - - - - - - - - - - diff --git a/docs/plugins/tmpl/stereo.sgml b/docs/plugins/tmpl/stereo.sgml index 09f343c3f8..9f1ed2f8f6 100644 --- a/docs/plugins/tmpl/stereo.sgml +++ b/docs/plugins/tmpl/stereo.sgml @@ -14,13 +14,3 @@ GstStereo - - - - - - - - - - diff --git a/docs/plugins/tmpl/synaesthesia.sgml b/docs/plugins/tmpl/synaesthesia.sgml index ac866565bc..40f34470c6 100644 --- a/docs/plugins/tmpl/synaesthesia.sgml +++ b/docs/plugins/tmpl/synaesthesia.sgml @@ -14,18 +14,3 @@ GstSynaesthesia - - - - - - - - - - - - - - - diff --git a/docs/plugins/tmpl/system_encode.sgml b/docs/plugins/tmpl/system_encode.sgml index 497a7934a8..e342229525 100644 --- a/docs/plugins/tmpl/system_encode.sgml +++ b/docs/plugins/tmpl/system_encode.sgml @@ -14,13 +14,3 @@ System_Encode - - - - - - - - - - diff --git a/docs/plugins/tmpl/videoscale.sgml b/docs/plugins/tmpl/videoscale.sgml index b3b8699d84..f7a0f27634 100644 --- a/docs/plugins/tmpl/videoscale.sgml +++ b/docs/plugins/tmpl/videoscale.sgml @@ -14,13 +14,3 @@ Videoscale - - - - - - - - - - diff --git a/docs/plugins/tmpl/videosink.sgml b/docs/plugins/tmpl/videosink.sgml index 0dfafbac05..010558b36a 100644 --- a/docs/plugins/tmpl/videosink.sgml +++ b/docs/plugins/tmpl/videosink.sgml @@ -14,42 +14,3 @@ GstVideoSink - - - - - -@gstvideosink: the object which received the signal. - -@arg1: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/docs/plugins/tmpl/volume.sgml b/docs/plugins/tmpl/volume.sgml index d285c5c442..cff4b422d8 100644 --- a/docs/plugins/tmpl/volume.sgml +++ b/docs/plugins/tmpl/volume.sgml @@ -14,13 +14,3 @@ GstVolume - - - - - - - - - - diff --git a/docs/plugins/tmpl/vumeter.sgml b/docs/plugins/tmpl/vumeter.sgml index 34abf7a5c8..3816526fa8 100644 --- a/docs/plugins/tmpl/vumeter.sgml +++ b/docs/plugins/tmpl/vumeter.sgml @@ -14,33 +14,3 @@ GstVuMeter - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/docs/random/NOTES-0.1.1 b/docs/random/NOTES-0.1.1 new file mode 100644 index 0000000000..348bb74a90 --- /dev/null +++ b/docs/random/NOTES-0.1.1 @@ -0,0 +1,36 @@ + +compile fixes: + + - BSD compatibility fixes (MAP_ANON) + - libxml compile problems fix + - compile fixes for non x86 architectures + (mpg123, mpeg_play, getbits, videoscale, ac3dec) + - mpeg2enc asm comment fixes + +bug fixes: + + - videoscaler/colorconversion fixes + - OSS audiosink bug fix + - reworked the queue threading code + - fixed the /etc/gstreamer permissions problem + - various minor bug fixes + +changes: + + - state change modifications + - _request pad implemented for muxer/mixer/aggregator + elements. also _request_compatible additions. + - massive ghostpad changes + - EOS handling (not for gstmediaplay) + - icecast send plugin using libshout + - lots of GstObject changes (XML save, name, parent + properties fixes) + - preliminary XML namespaces. + - added support for custom app tags in the XML save/load + routines (preliminary support) + - cothreads updates for ALPHA/ARM + - asyncdisksrc is gone in favor of a better disksrc + - getregion rework + - videoscaler/colorconversion updates + - manual/docs updates + diff --git a/docs/random/hierarchy b/docs/random/hierarchy new file mode 100644 index 0000000000..fc854aff72 --- /dev/null +++ b/docs/random/hierarchy @@ -0,0 +1,149 @@ +Face it, the plugins/ directory hierarchy is crap. We want to propose a +better layout for it now. Some things to consider: + + - Elements have a klass member in the factory that is used to + denote the functional type of the element. For example, the + mp3 encoder has a klass of Filter/Encoder/Audio + + - The plugins can be grouped together by the media type they + operate on or by the way they work (decoder/encoder) + +In GStreamer all plugins are techically filters, the only way they +can be considered sources or sinks (input/output) elements is +by the absence of src/sink pads. At first sight the source/filter/ +sink distinction is quite useless because most of the plugins +will go into the filters category anyway. + +We don't want to make the hierarchy too deep, yet provide a +clean way to ask for a mp3 decoder element.. + +Anyway this is a rough proposal to fire off the discussions... + +Wim + +Source + Disk + disksrc + fdsrc + multifilesrc + Network + HTTPsrc + RTPsrc + CDDA + cdparanoia + XMMS + .. + DVD + dvdsrc + Audio + ASLA + OSS + Capture + v4lsrc + firewire + +Demuxer + AVI + MPEG1 + MPEG2 + QT + +Muxer + AVI + MPEG1 + QT + +Aggregator + +Tee + gsttee + +Connection + queue + CORBA + +Parser + MPEG1 + MPEG2 + AC3 + +Mixer + Audio + Merge + Video + Subtitles + Merge + +Filters + Audio + ladspa + resample + Video + colorspace + +Effect + Audio + stereo + volume + delay + chorus + Video + median + smooth + XMMS + +Decoder + MPEG1 + MPEG2 + MP3 + mpg123 + xing + win32 + AU + WAV + JPEG + AC3 + ac3dec + RTJPEG + vorbis + +Encoder + MPEG1 + MPEG2 + MP3 + lame + mpegaudio + win32 + JPEG + AU + WAV + RTJPEG + Vorbis + +Visualisation + Video + histogram + Audio + smoothwave + spectrum + synaesthesia + vumeter + XMMS + +Sink + Disk + filesink + multifilesink + Network + ICECASTsink + FTPsink + RTPsink + XMMS + ESD + Video + videosink + SDLsink + Audio + OSSsink + ALSAsink + diff --git a/docs/random/omega/eos b/docs/random/omega/eos.old similarity index 100% rename from docs/random/omega/eos rename to docs/random/omega/eos.old diff --git a/docs/random/plugins.dia b/docs/random/plugins.dia index de76551a42..e7c42060b2 100644 Binary files a/docs/random/plugins.dia and b/docs/random/plugins.dia differ diff --git a/docs/random/wtay/autoplug2 b/docs/random/wtay/autoplug2 index 1c0f6f808c..c56f9b1f54 100644 --- a/docs/random/wtay/autoplug2 +++ b/docs/random/wtay/autoplug2 @@ -42,22 +42,26 @@ any intermediate steps to accomplish this conversion. The API for the user apps should be no more then this: - GstElement* gst_autoplug_construct (GstAutoplug *autoplug, - GstCaps *incaps, - GstCaps *outcaps, ...); + GstElement* gst_autoplug_caps_list (GstAutoplug *autoplug, + GList *incaps, + GList *outcaps, ...); autoplug is a reference to the autoplug implementation - incaps is a GstCaps handle for the source pad, the last set - of arguments is a va_list of destination caps. + incaps is a GList of GstCaps* for the source pad, the last set + of arguments is a va_list of destination caps lists. A handle to the autoplugger implementation can be obtained with - GList* gst_autoplug_get_list (void); + GList* gst_autoplugfactory_get_list (void); which will return a GList* of autopluggers. - GstAutoplug* gst_autoplug_get ("name"); + GstAutoplug* gst_autoplugfactory_make ("name"); + +or + + GstAutoplug* gst_autoplugfactory_create (GstAutoplugFactory *autoplug); is used to get an autoplugger. @@ -72,11 +76,12 @@ overriding various methods. the autoplugger can be registered with: gst_plugin_add_autoplugger (GstPlugin *plugin, - GstAutoplug *autoplug); + GstAutoplugFactory *autoplug); This will allow us to only load the autoplugger when needed. + 4) implementation ----------------- @@ -108,11 +113,9 @@ properties: - name, description, more text to identify the autoplugger. - - a class method autoplug_construct that has to be implemented by + - a class method autoplug_caps_list that has to be implemented by the real autoplugger. - - possible PadTemplates that this autoplugger can handle well? - optionally, the core autoplugger code can provide convenience functions to implement custom autopluggers. The shortest path algorithm with pluggable weighting and list functions come to @@ -124,8 +127,9 @@ A possible use case would be to let gstmediaplay perform an autoplug on the media stream and insert a custom sound/video effect in the pipeline when an appropriate element is created. +the "new_object" signal will be fired by the autoplugger whenever +a new object has been created. This signal can be caught by the +user app to perform an introspection on the newly created object. + -comments? -Wim - diff --git a/docs/random/wtay/caps-negociation b/docs/random/wtay/caps-negociation new file mode 100644 index 0000000000..ad72b9b3e4 --- /dev/null +++ b/docs/random/wtay/caps-negociation @@ -0,0 +1,345 @@ +caps negotiation +================ + +1) purpose +---------- + +The pads expose the media types they can handle using a mime +type and a set of properties. Before the pad is created or +used to pass buffers, we only know the global 'range' of media +data this pad can accept. When the element has had a chance to +look at the media data, only then it knows the exact values of the +properties. + +example1: +! +! The mp3 decoder exposes the capabilities of its src pad +! with the following caps: +! +! 'mpg123_src': +! MIME type: 'audio/raw': +! format: Integer: 16 +! depth: Integer: 16 +! rate: Integer range: 11025 - 48000 +! channels: Integer range: 1 - 2 + +as you can see in example1, the padtemplate has both a range +(for the audio rate) and a list (for the number of channels) +for its properties. + +only when the mpg123 element has decoded the first mpeg audio +header, it knows the exact values of the rate and channels +properties. + +suppose that we want to connect this src pad to the sink pad +of an audiosink with the properties given in example2: + +example2: +! +! 'audiosink_sink': +! MIME type: 'audio/raw': +! format: Integer: 16 +! depth: List: +! Integer: 8 +! Integer: 16 +! rate: Integer range: 8000 - 44000 +! channels: Integer range: 1 - 2 + +we can see that connecting the mpg123 src pad with the +audiosinks sink pad can cause a potential problem with the +rate property. + +When the mpg123 decoder decides to output raw audio with a +48000Hz samplerate, the audiosink will not be able to handle +it. The conservative approach would be to disallow the connection +between the two incompatible pads. This rules out any potential +problems but severely limits the amount of possible connections +between the elements. + +Another approach would be to allow the connection (and mark it +as dangerous) and let the two elements figure out a suitable +media type at runtime. This procedure is called caps negotiation. + + +2) a bit of history +------------------- + +The typing of the data that was attached to a buffer used to be +done using GstMeta* (and it still is as of 11 feb 2001). With +the new GstCaps and GstProps system this typing is gradually moved +to the pads and to the padtemplates. This has several advantages: + + - the typing of the data tends to be static. The type of media + doesn't change for every buffer. + + - Moving the typing up to the pad(templates) allows us to save + them into the registry and allows us to figure out what pads + are compatible. + + - the current metadata implementation needs header files. this may + change when we also use properties for metadata. + +example3: +! +! This is the current GstMeta structure that travels with audio buffers +! +! struct _MetaAudioRaw { +! GstMeta meta; +! +! /* formatting information */ +! gint format; +! gint channels; +! gint frequency; +! gint bps; +! }; + + +The question still remains what purpose the metadata will serve +now that we expose the media type in the pads. Some possibilities: + + - interesting information, not describing the data itself but the + context in which the data was generated (suggested buffer size, + timestamps, etc...) + + - user app metadata. + +In this proposal we also assume that the current use of metadata using +GstMeta is deprecated and that we move this information to the properties +of the pads. + + +3) the pad/padtemplates caps +---------------------------- + +All elements have to provide a padtemplate for their pads. + +The padtemplates provide a range of possible media types this pad can +src/sink. the main purpose for the padtemplates is to allow a +rough guess at which pads are compatible before even a single buffer +has been processed by the element. + +pads are usually created from the templates. When the pad is created +it has no GstCaps* attached to it yet. The possible caps this pad +can have is exposed in the padtemplate. The caps are filled in by +the element when it knows the values for the caps. + + +4) the connect function +----------------------- + +when two pads are connected the following steps will take +place (not sure, FIXME): + + - if both pads have caps, the caps are checked. If the caps + are incompatible, the padtemplates are checked, if they + are compatible, caps negotiation is performed. + + - if one of the pads has caps, the caps is checked against + the padtemplate of the peer pad. If they are incompatible, + the padtemplates are compared, if they are incompatible, + caps negotiation is performed. + + - if none of the pads have caps, the padtemplates are checked, + if they are incompatible, a warning is issued. + + +5) when the element knows the media type it is handling +------------------------------------------------------- + +When the element has received its first buffer it will know +the media type it is handling by inspecting the buffer. + +before pushing the data out to its peer element(s), the element +will set its src pad with the appropriate caps and properties. +These caps must follow the following rules: + + - the caps must be compatible with the padtemplates of this + pad. + + - the caps cannot contain ranges or lists. + +when the element wants to change the caps of a pad, it has to +perform gst_pad_renegotiate (GstPad *pad). this will trigger +the caps negotiation procedure. + +this will trigger the class method of the pad and calls the pads +gst_pad_negotiate function: + + GstCaps *gst_pad_negotiate (GstPad *pad, GstCaps *caps, guint count); + +This function takes a GstCaps *structure as an argument (typically the +current caps of the pad) and a negotiation counter. this counter can be +used to keep track of the negotiation process. + +The pad then creates a new caps structure with the desired caps. +If the caps are accepted, it just returns the provided input caps. the +_renegotiate function will set the caps of both pads whenever the +input caps are the same (pointer wise) as the input caps. + +the caps structure is checked against the padtemplate of the peer pad, +if it is incompatible the gst_pad_negotiate function is called again +and the element is supposed to create another caps structure. + +the gst_pad_renegotiate function then calls the gst_pad_negotiate +function of the peer pad with the new caps as the argument. The peer +pad can adjust or create a new caps if it doesn't accept it. + +the caps structure keeps on bouncing between the two pads until one +of the pads negotiation functions returns the caps unmodified. + +The element can also return a NULL pointer if it has run out of +options for the caps structure. When this happens, both pads are set +the the NULL caps again and the pad connnection is broken. + +The negotiation process is stopped after a fixed number of tries, +when the counter has reached some limit. This limit is typically +checked by the pads negotiate function. + + +6) caps negotiation function +---------------------------- + +the negotiate function of a pad is called whenever the pad or +peer pad has performed _renegotiate. + +example5: +! +! this is the caps negotiation function implemented by an element on +! one of its sink pads. +! +! static GstCaps* +! gst_pad_negotiate (GstPad *pad, GstCaps *caps, guint counter) +! { +! /* we don't accept anything else than audio/raw */ +! if (strcmp (gst_caps_get_mime (caps), "audio/raw")) +! return NULL; +! +! if (gst_caps_get_int_prop (caps, "format") != AFMT_S16_LE) +! return NULL; +! +! /* we accept everything else */ +! return caps; +! } + +When the negotiate function returns NULL (it does not accept the +specified caps of the peer pad), the negotiation process is stopped. + + + +APPENDIX A: use cases +===================== + +1) mpg123 src!sink audiosink +---------------------------- + +When the pads are connected the padtemplates are checked and it +turns out that the pads might be incompatible (mpg123 can do +48000Hz while audiosink can do 44000Hz). Nothing happens at +connect time except for the user app that can mark this connection +as possibly dangerous and keep some spare elements ready for when +the pads turn out to be incompatible. + +both elements start out with no caps at all (NULL). mpg123 wants +to output a buffer with specific properties. It calls +gst_pad_renegotiate (mpg123->srcpad). + +The _renegotiate functions calls the negotiate function of the +mpg123->srcpad. the negotiate function would look like this: + + +/* + * The mpg123 element cannot convert the decoded type into something + * else so it has to force the caps of the src pad into the specific + * type as defined by the mp3. + */ +static GstCaps* +gst_mpeg123_src_negotiate (GstPad *pad, GstCaps *caps, guint counter) +{ + GstMpg123 *mpg123; + + mpg123 = GST_MPG123 (gst_pad_get_parent (pad)); + + /* we got caps in, check them */ + if (caps != NULL) { + if (!strcmp (gst_caps_get_mime (caps), "audio/raw") && + (gst_caps_get_int_prop (caps, "format") == AFMT_S16_LE) && + (gst_caps_get_int_prop (caps, "depth") == 16) && + (gst_caps_get_int_prop (caps, "rate") == mpg123->rate) && + (gst_caps_get_int_prop (caps, "channels") == mpg123->channels)) { + return caps; + } + } + /* we didn't get caps, so we decide */ + else if (counter != 2) { + GstCaps *new; + + /* fill in our desired caps */ + new = gst_caps_new_with_props ( + "src_caps", /* name */ + "audio/raw", /* mime */ + gst_props_new ( + "format", GST_PROPS_INT (AFMT_S16_LE), + "depth", GST_PROPS_INT (16), + "rate", GST_PROPS_INT (mpg123->rate), + "channels", GST_PROPS_INT (mpg123->channels), + NULL + ) + ); + return caps; + } + /* too many attempts at nogotiation, bail out */ + return NULL; +} + + +The audiosink pad negotiate function would look like this: + +/* + * The audiosink has a wide range of possible parameters for + * its sink pad, based on the audio card capabilities and + * possibly the element configuration. + * we assume the audiosink element can be both the initiator of + * the negotiations and the negotiated one. + */ +static GstCaps* +gst_audiosink_sink_negotiate (GstPad *pad, GstCaps *caps, guint counter) +{ + GstAudiosink *audiosink; + gboolean accepted = TRUE; + + audiosink = GST_AUDIOSINK (gst_pad_get_parent (pad)); + + /* we got caps in, we know they will match the padtemplate */ + if (caps != NULL) { + return caps; + } + /* we didn't get caps, so we decide */ + else if (counter != 2) { + GstCaps *new; + + /* fill in our desired caps */ + new = gst_caps_new_with_props ( + "sink_caps", /* name */ + "audio/raw", /* mime */ + gst_props_new ( + "format", GST_PROPS_INT (audiosink->format), + "depth", GST_PROPS_INT (audiosink->depth), + "rate", GST_PROPS_INT (audiosink->rate), + "channels", GST_PROPS_INT (audiosink->channels), + NULL + ) + ); + return caps; + } + /* too many attempts at nogotiation, bail out */ + return NULL; +} + + + + + + + + + diff --git a/docs/random/wtay/capsnego-cases b/docs/random/wtay/capsnego-cases new file mode 100644 index 0000000000..18410f38ae --- /dev/null +++ b/docs/random/wtay/capsnego-cases @@ -0,0 +1,346 @@ + +pad has caps +| pad has template +|/ pad has negotiate function +||/ +--- -> --- + +always compatible + +--+ -> --- + +call negotiate function, set the resulting caps + +-+- -> --- + +always compatible + +-++ -> --- + +call negotiate function, set the resulting caps + ++-- -> --- + +always compatible, caps are those of the pad + ++-+ -> --- + +always compatible, caps are those of the pad + +++- -> --- + +always compatible, caps are those of the pad + ++++ -> --- + +always compatible, caps are those of the pad + +===================================== +pad has caps +| pad has template +|/ pad has negotiate function +||/ + +--- -> --+ + +call negotiate function, set the resulting caps + +--+ -> --+ + +negotiate until agreed + +-+- -> --+ + +call negotiate until caps match padtemplate + +-++ -> --+ + +negotiate until agreed, caps only got send to the +other pad if they match the padtemplate + ++-- -> --+ + +call negotiate function with src caps, set caps if ok + ++-+ -> --+ + +call negotiate function with src caps, negotiate until agreed + +++- -> --+ + +call negotiate function with src caps, set caps if ok + ++++ -> --+ + +call negotiate function with src caps, negotiate until agreed + +===================================== +pad has caps +| pad has template +|/ pad has negotiate function +||/ + +--- -> -+- + +always compatible + +--+ -> -+- + +call negotiate until caps match padtemplate + +-+- -> -+- + +check padtemplates, if compatible connect + +-++ -> -+- + +check templates, if compatible, +call negotiate, until it matches the padtemplate + ++-- -> -+- + +check caps against padtemplate, if compatible, connect + ++-+ -> -+- + +check caps against padtemplate, if compatible: connect +alse call negotiate until it matches template + +++- -> -+- + +check caps against padtemplate, if match, connect + ++++ -> -+- + +check caps against padtemplate, if match, connect +alse check padtemplates if compatible, +call negotiate until match template + + +===================================== + +pad has caps +| pad has template +|/ pad has negotiate function +||/ + +--- -> -++ + +call negotiate, set resulting caps + +--+ -> -++ + +call negotiate until agree, check src caps against +padtemplate before calling sink negotiate + +-+- -> -++ + +check padtemplates, if match call negotiate until +match src padtemplate. + +-++ -> -++ + +check padtemplates, if match call negotiate until +agree + ++-- -> -++ + +check caps against padtemplate +call negotiate with caps, if agree, set caps + ++-+ -> -++ + +check caps against padtemplate +call negotiate with caps, negotiate until agree + +++- -> -++ + +check caps against padtemplate +call negotiate with caps, call negotiate until +sink caps match src padtemplate + ++++ -> -++ + +check caps against padtemplate +call negotiate with caps, negotiate until agree + + +===================================== + + +pad has caps +| pad has template +|/ pad has negotiate function +||/ + +--- -> +-- + +connection fails + +--+ -> +-- + + + +-+- -> +-- + + +-++ -> +-- + + ++-- -> +-- + + ++-+ -> +-- + + +++- -> +-- + + ++++ -> +-- + +check caps, +call src negotiate with caps + + +===================================== + +pad has caps +| pad has template +|/ pad has negotiate function +||/ + +--- -> +-+ + + +--+ -> +-+ + + +-+- -> +-+ + + +-++ -> +-+ + + ++-- -> +-+ + + ++-+ -> +-+ + + +++- -> +-+ + + ++++ -> +-+ + + +===================================== + +pad has caps +| pad has template +|/ pad has negotiate function +||/ + +--- -> ++- + + +--+ -> ++- + + +-+- -> ++- + + +-++ -> ++- + + ++-- -> ++- + + ++-+ -> ++- + + +++- -> ++- + + ++++ -> ++- + + +===================================== + +pad has caps +| pad has template +|/ pad has negotiate function +||/ + +--- -> +++ + + +--+ -> +++ + + +-+- -> +++ + + +-++ -> +++ + + ++-- -> +++ + + ++-+ -> +++ + + +++- -> +++ + + ++++ -> +++ + + +===================================== + + srccaps = GST_PAD_CAPS (srcpad); + srctempl = FALSE; + + do { + + //no caps, get one + if (!srccaps) + { + if (srcpad->negotiatefunc && !srctempl) + { + srccaps = srcpad->negotiatefunc (srpad, srcaps, counter); + srctempl = FALSE; + } + else + { + srccaps = gst_pad_get_caps (srcpad); + srctempl = TRUE; + } + } + + /* check against other pad */ + + // the other pad doesn't want to negotiate + if (!sinkpad->negotiatefunc) + { + sinkcaps = gst_pad_get_caps (sinkpad); + + if (!sinkcaps) + break; + + if (gst_caps_check_compatibility (srccaps, sinkcaps)) + { + // cool + break; + } + } + else { + switch pads; + } + + } while (counter < 100); + + + + + + diff --git a/editor/Makefile.am b/editor/Makefile.am index a40beda3a4..0b426547b1 100644 --- a/editor/Makefile.am +++ b/editor/Makefile.am @@ -27,6 +27,8 @@ bin_PROGRAMS = gsteditor gsteditor_SOURCES = editor.c gsteditor_LDFLAGS = libgsteditor.la $(GST_LIBS) +man_MANS = gsteditor.1 + gladedir = $(datadir)/gsteditor glade_DATA = editor.glade editorelement.glade @@ -40,4 +42,4 @@ noinst_HEADERS = \ SUBDIRS = pixmaps -EXTRA_DIST = $(glade_DATA) +EXTRA_DIST = $(glade_DATA) $(man_MANS) diff --git a/editor/gsteditor.1 b/editor/gsteditor.1 new file mode 100644 index 0000000000..6667e6084a --- /dev/null +++ b/editor/gsteditor.1 @@ -0,0 +1,39 @@ +.TH GStreamer 1 "March 2001" +.SH NAME +gsteditor - a graphical GStreamer pipeline editor +.SH SYNOPSIS +.B gsteditor [OPTION...] [FILE] +.SH DESCRIPTION +.PP +\fIgsteditor\fP is a graphical \fIGStreamer\fP pipeline editor. It can +load, save, and run pipelines. +. +.SH OPTIONS +.l +\fIgsteditor\fP accepts the following options: +.TP 8 +.B FILE +Pipeline to load +.TP 8 +.B \-\-help +Print help synopsis and available FLAGS +.TP 8 +.B \-\-gst\-info\-mask=FLAGS +\fIGStreamer\fP info flags to set (list with \-\-help) +.TP 8 +.B \-\-gst\-debug\-mask=FLAGS +\fIGStreamer\fP debugging flags to set (list with \-\-help) +.TP 8 +.B \-\-gst\-plugin\-spew +\fIGStreamer\fP info flags to set +Enable printout of errors while loading \fIGStreamer\fP plugins +.TP 8 +.B \-\-gst\-plugin\-path=PATH +Add directories separated with ':' to the plugin search path +.SH SEE ALSO +.BR gstreamer\-register (1), +.BR gstreamer\-inspect (1), +.BR gstreamer\-launch (1), +.BR gstmediaplay (1) +.SH AUTHOR +The GStreamer team at http://gstreamer.net/ diff --git a/editor/gsteditor.h b/editor/gsteditor.h index 105e18087a..e67667e8a4 100644 --- a/editor/gsteditor.h +++ b/editor/gsteditor.h @@ -155,14 +155,14 @@ struct _GstEditorElement { struct _GstEditorElementClass { GnomeCanvasGroupClass parent_class; - void (*name_changed) (GstEditorElement *element); - void (*position_changed) (GstEditorElement *element); - void (*size_changed) (GstEditorElement *element); - void (*realize) (GstEditorElement *element); - gint (*event) (GnomeCanvasItem *item,GdkEvent *event, - GstEditorElement *element); - gint (*button_event) (GnomeCanvasItem *item,GdkEvent *event, - GstEditorElement *element); + void (*name_changed) (GstEditorElement *element); + void (*position_changed) (GstEditorElement *element); + void (*size_changed) (GstEditorElement *element); + void (*realize) (GstEditorElement *element); + gint (*event) (GnomeCanvasItem *item,GdkEvent *event, + GstEditorElement *element); + gint (*button_event) (GnomeCanvasItem *item,GdkEvent *event, + GstEditorElement *element); }; @@ -188,11 +188,11 @@ const gchar *gst_editor_element_get_name(GstEditorElement *element); (GTK_CHECK_TYPE((obj),GST_TYPE_EDITOR_BIN)) #define GST_IS_EDITOR_BIN_CLASS(obj) \ (GTK_CHECK_CLASS_TYPE((klass),GST_TYPE_EDITOR_BIN)) - + struct _GstEditorBin { GstEditorElement element; - /* lists of GUI elements and connections */ + /* lists of GUI elements and connections */ GList *elements, *connections; /* connection state */ @@ -213,11 +213,11 @@ struct _GstEditorBinClass { GtkType gst_editor_bin_get_type(); GstEditorBin* gst_editor_bin_new (GstBin *bin, const gchar *first_arg_name,...); -void gst_editor_bin_add (GstEditorBin *bin, GstEditorElement *element); - -void gst_editor_bin_connection_drag (GstEditorBin *bin, - gdouble wx,gdouble wy); -void gst_editor_bin_start_banding (GstEditorBin *bin,GstEditorPad *pad); +void gst_editor_bin_add (GstEditorBin *bin, GstEditorElement *element); + +void gst_editor_bin_connection_drag (GstEditorBin *bin, + gdouble wx,gdouble wy); +void gst_editor_bin_start_banding (GstEditorBin *bin,GstEditorPad *pad); #define GST_TYPE_EDITOR_CANVAS \ @@ -246,8 +246,8 @@ struct _GstEditorCanvasClass { GstEditorCanvas* gst_editor_canvas_new (void); GstEditorCanvas* gst_editor_canvas_new_with_bin (GstEditorBin *bin); -void gst_editor_canvas_set_bin (GstEditorCanvas *canvas, - GstEditorBin *element); +void gst_editor_canvas_set_bin (GstEditorCanvas *canvas, + GstEditorBin *element); GstEditorElement* gst_editor_canvas_get_bin (GstEditorCanvas *canvas); @@ -263,7 +263,7 @@ GstEditorElement* gst_editor_canvas_get_bin (GstEditorCanvas *canvas); (GTK_CHECK_CLASS_TYPE((klass),GST_TYPE_EDITOR_PAD)) struct _GstEditorPad { - GtkObject object; + GtkObject object; /* parent element */ GstEditorElement *parent; @@ -291,7 +291,7 @@ struct _GstEditorPad { gdouble width,height; // actual size gdouble boxwidth,boxheight; // size of pad box gboolean resize; // does it need resizing? - + /* interaction state */ gboolean dragging,resizing,moved; gdouble dragx,dragy; @@ -300,13 +300,13 @@ struct _GstEditorPad { // GnomeCanvasItem *connection; // can't use //GstEditorConnection }; - + struct _GstEditorPadClass { GtkObjectClass parent_class; void (*realize) (GstEditorPad *pad); }; - + GtkType gst_editor_pad_get_type(); GstEditorPad *gst_editor_pad_new(GstEditorElement *parent,GstPad *pad, const gchar *first_arg_name, ...); @@ -329,7 +329,7 @@ void gst_editor_pad_repack(GstEditorPad *pad); (GTK_CHECK_CLASS_TYPE((klass),GST_TYPE_EDITOR_PADTEMPLATE)) struct _GstEditorPadTemplate { - GtkObject object; + GtkObject object; /* parent element */ GstEditorElement *parent; @@ -361,7 +361,7 @@ struct _GstEditorPadTemplate { gdouble width,height; // actual size gdouble boxwidth,boxheight; // size of padtemplate box gboolean resize; // does it need resizing? - + /* interaction state */ gboolean dragging,resizing,moved; gdouble dragx,dragy; @@ -370,13 +370,13 @@ struct _GstEditorPadTemplate { // GnomeCanvasItem *connection; // can't use //GstEditorConnection }; - + struct _GstEditorPadTemplateClass { GtkObjectClass parent_class; void (*realize) (GstEditorPadTemplate *padtemplate); }; - + GtkType gst_editor_padtemplate_get_type(); GstEditorPadTemplate *gst_editor_padtemplate_new(GstEditorElement *parent,GstPadTemplate *padtemplate, const gchar *first_arg_name, ...); diff --git a/editor/gsteditorproperty.c b/editor/gsteditorproperty.c index 2e5e05ad23..9a787ce7e8 100644 --- a/editor/gsteditorproperty.c +++ b/editor/gsteditorproperty.c @@ -248,16 +248,16 @@ static gchar* gst_editor_props_show_func (GstPropsEntry *entry) { switch (entry->propstype) { - case GST_PROPS_INT_ID_NUM: + case GST_PROPS_INT_ID: return g_strdup_printf ("%d", entry->data.int_data); break; - case GST_PROPS_INT_RANGE_ID_NUM: + case GST_PROPS_INT_RANGE_ID: return g_strdup_printf ("%d-%d", entry->data.int_range_data.min, entry->data.int_range_data.max); break; - case GST_PROPS_FOURCC_ID_NUM: + case GST_PROPS_FOURCC_ID: return g_strdup_printf ("%4.4s", (gchar *)&entry->data.fourcc_data); break; - case GST_PROPS_BOOL_ID_NUM: + case GST_PROPS_BOOL_ID: return g_strdup_printf ("%s", (entry->data.bool_data ? "TRUE" : "FALSE")); break; default: @@ -272,7 +272,7 @@ gst_editor_add_caps_to_tree (GstCaps *caps, GtkWidget *tree, GtkCTreeNode *padno if (caps) { GstProps *props = gst_caps_get_props (caps); if (props) { - GSList *propslist = props->properties; + GList *propslist = props->properties; while (propslist) { gchar *data[2]; @@ -281,7 +281,7 @@ gst_editor_add_caps_to_tree (GstCaps *caps, GtkWidget *tree, GtkCTreeNode *padno data[0] = g_quark_to_string (entry->propid); switch (entry->propstype) { - case GST_PROPS_LIST_ID_NUM: + case GST_PROPS_LIST_ID: { GList *list; guint count = 0; @@ -303,7 +303,7 @@ gst_editor_add_caps_to_tree (GstCaps *caps, GtkWidget *tree, GtkCTreeNode *padno gtk_ctree_insert_node (GTK_CTREE (tree), padnode, NULL, data, 0, NULL, NULL, NULL, NULL, TRUE, TRUE); - propslist = g_slist_next (propslist); + propslist = g_list_next (propslist); } } } @@ -329,14 +329,14 @@ gst_editor_pads_create (GstEditorProperty *property, GstEditorElement *element) while (pads) { GstPad *pad = (GstPad *)pads->data; - GList *caps = gst_pad_get_caps_list (pad); + GstCaps *caps = gst_pad_get_caps (pad); gchar *mime; gchar *data[2]; GtkCTreeNode *padnode; if (caps) { GstType *type; - type = gst_type_find_by_id (((GstCaps *)caps->data)->id); + type = gst_type_find_by_id (caps->id); mime = type->mime; } else { @@ -348,13 +348,8 @@ gst_editor_pads_create (GstEditorProperty *property, GstEditorElement *element) padnode = gtk_ctree_insert_node (GTK_CTREE (tree), NULL, NULL, data, 0, NULL, NULL, NULL, NULL, FALSE, TRUE); - while (caps) { - GstCaps *cap = (GstCaps *)caps->data; - gst_editor_add_caps_to_tree (cap, tree, padnode); - - caps = g_list_next (caps); - } + gst_editor_add_caps_to_tree (caps, tree, padnode); pads = g_list_next (pads); } @@ -362,14 +357,14 @@ gst_editor_pads_create (GstEditorProperty *property, GstEditorElement *element) pads = gst_element_get_padtemplate_list(realelement); while (pads) { GstPadTemplate *templ = (GstPadTemplate *)pads->data; - GList *caps = templ->caps; + GstCaps *caps = templ->caps; gchar *mime; gchar *data[2]; GtkCTreeNode *padnode; if (caps) { GstType *type; - type = gst_type_find_by_id (((GstCaps *)caps->data)->id); + type = gst_type_find_by_id (((GstCaps *)caps)->id); mime = type->mime; } else { @@ -382,11 +377,11 @@ gst_editor_pads_create (GstEditorProperty *property, GstEditorElement *element) NULL, NULL, NULL, NULL, FALSE, TRUE); while (caps) { - GstCaps *cap = (GstCaps *)caps->data; + GstCaps *cap = (GstCaps *)caps; gst_editor_add_caps_to_tree (cap, tree, padnode); - caps = g_list_next (caps); + caps = (caps)->next; } pads = g_list_next (pads); diff --git a/examples/Makefile.am b/examples/Makefile.am index 1b5d86647b..17a14055c2 100644 --- a/examples/Makefile.am +++ b/examples/Makefile.am @@ -1,4 +1,4 @@ SUBDIRS = autoplug \ helloworld helloworld2 \ queue queue2 queue3 queue4 \ - launch thread xml plugins + launch thread xml plugins typefind diff --git a/examples/autoplug/.gitignore b/examples/autoplug/.gitignore index a2911a80f7..f76c31a123 100644 --- a/examples/autoplug/.gitignore +++ b/examples/autoplug/.gitignore @@ -1 +1,2 @@ autoplug +xmlTest.gst diff --git a/examples/helloworld/helloworld.c b/examples/helloworld/helloworld.c index eff130dd16..e01e1371d5 100644 --- a/examples/helloworld/helloworld.c +++ b/examples/helloworld/helloworld.c @@ -13,7 +13,7 @@ void eos(GstElement *element) int main(int argc,char *argv[]) { - GstElement *bin, *disksrc, *parse, *decoder, *audiosink; + GstElement *bin, *disksrc, *parse, *decoder, *downmix, *mulaw, *mulawdec, *osssink; gst_init(&argc,&argv); @@ -34,14 +34,20 @@ int main(int argc,char *argv[]) /* now it's time to get the parser */ parse = gst_elementfactory_make("mp3parse","parse"); decoder = gst_elementfactory_make("mpg123","decoder"); + downmix = gst_elementfactory_make("stereo2mono","stereo2mono"); + mulaw = gst_elementfactory_make("mulawencode","mulaw"); + mulawdec = gst_elementfactory_make("mulawdecode","mulawdec"); /* and an audio sink */ - audiosink = gst_elementfactory_make("audiosink", "play_audio"); + osssink = gst_elementfactory_make("osssink", "play_audio"); /* add objects to the main pipeline */ gst_bin_add(GST_BIN(bin), disksrc); gst_bin_add(GST_BIN(bin), parse); gst_bin_add(GST_BIN(bin), decoder); - gst_bin_add(GST_BIN(bin), audiosink); + gst_bin_add(GST_BIN(bin), downmix); + gst_bin_add(GST_BIN(bin), mulaw); + gst_bin_add(GST_BIN(bin), mulawdec); + gst_bin_add(GST_BIN(bin), osssink); /* connect src to sink */ gst_pad_connect(gst_element_get_pad(disksrc,"src"), @@ -49,10 +55,14 @@ int main(int argc,char *argv[]) gst_pad_connect(gst_element_get_pad(parse,"src"), gst_element_get_pad(decoder,"sink")); gst_pad_connect(gst_element_get_pad(decoder,"src"), - gst_element_get_pad(audiosink,"sink")); + gst_element_get_pad(downmix,"sink")); + gst_pad_connect(gst_element_get_pad(downmix,"src"), + gst_element_get_pad(mulaw,"sink")); + gst_pad_connect(gst_element_get_pad(mulaw,"src"), + gst_element_get_pad(mulawdec,"sink")); + gst_pad_connect(gst_element_get_pad(mulawdec,"src"), + gst_element_get_pad(osssink,"sink")); - /* make it ready */ - gst_element_set_state(bin, GST_STATE_READY); /* start playing */ gst_element_set_state(bin, GST_STATE_PLAYING); @@ -65,9 +75,12 @@ int main(int argc,char *argv[]) /* stop the bin */ gst_element_set_state(bin, GST_STATE_NULL); - gst_object_destroy(GST_OBJECT(audiosink)); + gst_object_destroy(GST_OBJECT(osssink)); gst_object_destroy(GST_OBJECT(parse)); gst_object_destroy(GST_OBJECT(decoder)); + gst_object_destroy(GST_OBJECT(downmix)); + gst_object_destroy(GST_OBJECT(mulaw)); + gst_object_destroy(GST_OBJECT(mulawdec)); gst_object_destroy(GST_OBJECT(disksrc)); gst_object_destroy(GST_OBJECT(bin)); diff --git a/examples/helloworld2/helloworld2.c b/examples/helloworld2/helloworld2.c index 64eed11d79..19e0b1e443 100644 --- a/examples/helloworld2/helloworld2.c +++ b/examples/helloworld2/helloworld2.c @@ -11,7 +11,7 @@ void eos(GstElement *element) int main(int argc,char *argv[]) { - GstElement *disksrc, *audiosink; + GstElement *disksrc, *osssink; GstElement *pipeline, *thread; gst_init(&argc,&argv); @@ -28,7 +28,6 @@ int main(int argc,char *argv[]) pipeline = gst_pipeline_new("pipeline"); g_assert(pipeline != NULL); - gst_bin_add(GST_BIN(thread), pipeline); /* create a disk reader */ disksrc = gst_elementfactory_make("disksrc", "disk_source"); @@ -38,20 +37,25 @@ int main(int argc,char *argv[]) GTK_SIGNAL_FUNC(eos),NULL); /* 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); /* add objects to the main pipeline */ + /* gst_pipeline_add_src(GST_PIPELINE(pipeline), disksrc); - gst_pipeline_add_sink(GST_PIPELINE(pipeline), audiosink); + gst_pipeline_add_sink(GST_PIPELINE(pipeline), osssink); if (!gst_pipeline_autoplug(GST_PIPELINE(pipeline))) { g_print("unable to handle stream\n"); exit(-1); } + */ + + // hmmmm hack? FIXME + GST_FLAG_UNSET (pipeline, GST_BIN_FLAG_MANAGER); + + gst_bin_add(GST_BIN(thread), pipeline); - /* make it ready */ - gst_element_set_state(GST_ELEMENT(thread), GST_STATE_READY); /* start playing */ gst_element_set_state(GST_ELEMENT(thread), GST_STATE_PLAYING); diff --git a/examples/launch/mp3play b/examples/launch/mp3play index b5fd5ac1ad..b09ccd3043 100755 --- a/examples/launch/mp3play +++ b/examples/launch/mp3play @@ -1,4 +1,4 @@ #! /bin/sh for loc in "$@"; do -gstreamer-launch disksrc "location=$loc" ! mp3parse ! mpg123 ! audiosink +../../tools/gstreamer-launch disksrc \""location=$loc"\" ! mp3parse ! mpg123 ! osssink done diff --git a/examples/plugins/example.c b/examples/plugins/example.c index b958272bb1..75e5c78ce6 100644 --- a/examples/plugins/example.c +++ b/examples/plugins/example.c @@ -17,67 +17,112 @@ * Boston, MA 02111-1307, USA. */ +/* First, include the header file for the plugin, to bring in the + * object definition and other useful things. + */ #include "example.h" -/* elementfactory information */ +/* The ElementDetails structure gives a human-readable description + * of the plugin, as well as author and version data. + */ static GstElementDetails example_details = { "An example plugin", - "Example", + "Example/FirstExample", "Shows the basic structure of a plugin", VERSION, "your name ", - "(C) 2000", + "(C) 2001", }; -/* Example signals and args */ +/* These are the signals that this element can fire. They are zero- + * based because the numbers themselves are private to the object. + * LAST_SIGNAL is used for initialization of the signal array. + */ enum { + ASDF, /* FILL ME */ LAST_SIGNAL }; +/* Arguments are identified the same way, but cannot be zero, so you + * must leave the ARG_0 entry in as a placeholder. + */ enum { ARG_0, - ARG_ACTIVE + ARG_ACTIVE, + /* FILL ME */ }; -static GstPadFactory sink_factory = { - "sink", /* the name of the pads */ - GST_PAD_FACTORY_SINK, /* type of the pad */ - GST_PAD_FACTORY_ALWAYS, /* ALWAYS/SOMETIMES */ - GST_PAD_FACTORY_CAPS( - "example_sink", /* the name of the caps */ - "unknown/unknown", /* the mime type of the caps */ - "something", GST_PROPS_INT (1), /* a property */ - "foo", GST_PROPS_BOOLEAN (TRUE) /* another property */ - ), - NULL -}; +/* The PadFactory structures describe what pads the element has or + * can have. They can be quite complex, but for this example plugin + * they are rather simple. + */ +static GstPadTemplate* +sink_factory (void) +{ + return + gst_padtemplate_new ( + "sink", /* The name of the pad */ + GST_PAD_SINK, /* Direction of the pad */ + GST_PAD_ALWAYS, /* The pad exists for every instance */ + gst_caps_new ( + "example_sink", /* The name of the caps */ + "unknown/unknown", /* The overall MIME/type */ + gst_props_new ( + "foo", GST_PROPS_INT (1), /* An integer property */ + "bar", GST_PROPS_BOOLEAN (TRUE), /* A boolean */ + "baz", GST_PROPS_LIST ( /* A list of values for */ + GST_PROPS_INT (1), + GST_PROPS_INT (3) + ), + NULL))); +} -static GstPadFactory src_factory = { - "src", - GST_PAD_FACTORY_SRC, - GST_PAD_FACTORY_ALWAYS, - GST_PAD_FACTORY_CAPS( - "example_src", - "unknown/unknown" - ), - NULL -}; +/* This factory is much simpler, and defines the source pad. */ +static GstPadTemplate* +src_factory (void) +{ + return + gst_padtemplate_new ( + "src", + GST_PAD_SRC, + GST_PAD_ALWAYS, + gst_caps_new ( + "example_src", + "unknown/unknown", + NULL)); +} -static void gst_example_class_init (GstExampleClass *klass); -static void gst_example_init (GstExample *example); +/* A number of functon prototypes are given so we can refer to them later. */ +static void gst_example_class_init (GstExampleClass *klass); +static void gst_example_init (GstExample *example); -static void gst_example_chain (GstPad *pad, GstBuffer *buf); +static void gst_example_chain (GstPad *pad, GstBuffer *buf); -static void gst_example_set_arg (GtkObject *object,GtkArg *arg,guint id); -static void gst_example_get_arg (GtkObject *object,GtkArg *arg,guint id); +static void gst_example_set_arg (GtkObject *object,GtkArg *arg,guint id); +static void gst_example_get_arg (GtkObject *object,GtkArg *arg,guint id); -GstPadTemplate *src_template, *sink_template; +/* These hold the constructed pad templates, which are created during + * plugin load, and used during element instantiation. + */ +static GstPadTemplate *src_template, *sink_template; +/* The parent class pointer needs to be kept around for some object + * operations. + */ static GstElementClass *parent_class = NULL; -//static guint gst_example_signals[LAST_SIGNAL] = { 0 }; +/* This array holds the ids of the signals registered for this object. + * The array indexes are based on the enum up above. + */ +static guint gst_example_signals[LAST_SIGNAL] = { 0 }; + +/* This function is used to register and subsequently return the type + * identifier for this object class. On first invocation, it will + * register the type, providing the name of the class, struct sizes, + * and pointers to the various functions that define the class. + */ GtkType gst_example_get_type(void) { @@ -90,8 +135,8 @@ gst_example_get_type(void) sizeof(GstExampleClass), (GtkClassInitFunc)gst_example_class_init, (GtkObjectInitFunc)gst_example_init, - (GtkArgSetFunc)gst_example_set_arg, - (GtkArgGetFunc)gst_example_get_arg, + (GtkArgSetFunc)NULL, /* These last three are depracated */ + (GtkArgGetFunc)NULL, (GtkClassInitFunc)NULL, }; example_type = gtk_type_unique(GST_TYPE_ELEMENT,&example_info); @@ -99,70 +144,166 @@ gst_example_get_type(void) return example_type; } +/* In order to create an instance of an object, the class must be + * initialized by this function. GtkObject will take care of running + * it, based on the pointer to the function provided above. + */ static void gst_example_class_init (GstExampleClass *klass) { + /* Class pointers are needed to supply pointers to the private + * implementations of parent class methods. + */ GtkObjectClass *gtkobject_class; GstElementClass *gstelement_class; + /* Since the example class contains the parent classes, you can simply + * cast the pointer to get access to the parent classes. + */ gtkobject_class = (GtkObjectClass*)klass; gstelement_class = (GstElementClass*)klass; + /* The parent class is needed for class method overrides. */ parent_class = gtk_type_class(GST_TYPE_ELEMENT); + /* Here we add an argument to the object. This argument is an integer, + * and can be both read and written. + */ gtk_object_add_arg_type("GstExample::active", GTK_TYPE_INT, GTK_ARG_READWRITE, ARG_ACTIVE); + /* Here we add a signal to the object. This is avery useless signal + * called asdf. The signal will also pass a pointer to the listeners + * which happens to be the example element itself */ + gst_example_signals[ASDF] = + gtk_signal_new("asdf", GTK_RUN_LAST, gtkobject_class->type, + GTK_SIGNAL_OFFSET (GstExampleClass, asdf), + gtk_marshal_NONE__POINTER, GTK_TYPE_NONE, 1, + GST_TYPE_EXAMPLE); + + gtk_object_class_add_signals (gtkobject_class, gst_example_signals, + LAST_SIGNAL); + + /* The last thing is to provide the functions that implement get and set + * of arguments. + */ gtkobject_class->set_arg = gst_example_set_arg; gtkobject_class->get_arg = gst_example_get_arg; } +/* This function is responsible for initializing a specific instance of + * the plugin. + */ static void gst_example_init(GstExample *example) { + /* First we create the sink pad, which is the input to the element. + * We will use the sink_template constructed in the plugin_init function + * (below) to quickly generate the pad we need. + */ example->sinkpad = gst_pad_new_from_template (sink_template, "sink"); - gst_element_add_pad(GST_ELEMENT(example),example->sinkpad); + /* Setting the chain function allows us to supply the function that will + * actually be performing the work. Without this, the element would do + * nothing, with undefined results (assertion failures and such). + */ gst_pad_set_chain_function(example->sinkpad,gst_example_chain); + /* We then must add this pad to the element's list of pads. The base + * element class manages the list of pads, and provides accessors to it. + */ + gst_element_add_pad(GST_ELEMENT(example),example->sinkpad); + /* The src pad, the output of the element, is created and registered + * in the same way, with the exception of the chain function. Source + * pads don't have chain functions, because they can't accept buffers, + * they only produce them. + */ example->srcpad = gst_pad_new_from_template (src_template, "src"); gst_element_add_pad(GST_ELEMENT(example),example->srcpad); + /* Initialization of element's private variables. */ example->active = FALSE; } +/* The chain function is the heart of the element. It's where all the + * work is done. It is passed a pointer to the pad in question, as well + * as the buffer provided by the peer element. + */ static void gst_example_chain (GstPad *pad, GstBuffer *buf) { GstExample *example; + GstBuffer *outbuf; + /* Some of these checks are of dubious value, since if there were not + * already true, the chain function would never be called. + */ g_return_if_fail(pad != NULL); g_return_if_fail(GST_IS_PAD(pad)); g_return_if_fail(buf != NULL); - //g_return_if_fail(GST_IS_BUFFER(buf)); + /* We need to get a pointer to the element this pad belogs to. */ example = GST_EXAMPLE(gst_pad_get_parent (pad)); + /* A few more sanity checks to make sure that the element that owns + * this pad is the right kind of element, in case something got confused. + */ g_return_if_fail(example != NULL); g_return_if_fail(GST_IS_EXAMPLE(example)); + /* If we are supposed to be doing something, here's where it happens. */ if (example->active) { - /* DO STUFF */ - } + /* In this example we're going to copy the buffer to another one, + * so we need to allocate a new buffer first. */ + outbuf = gst_buffer_new(); - gst_pad_push(example->srcpad,buf); + /* We need to copy the size and offset of the buffer at a minimum. */ + GST_BUFFER_SIZE (outbuf) = GST_BUFFER_SIZE (buf); + GST_BUFFER_OFFSET (outbuf) = GST_BUFFER_OFFSET (buf); + + /* Then allocate the memory for the new buffer */ + GST_BUFFER_DATA (outbuf) = (guchar *)g_malloc (GST_BUFFER_SIZE (outbuf)); + + /* Then copy the data in the incoming buffer into the new buffer. */ + memcpy (GST_BUFFER_DATA (outbuf), GST_BUFFER_DATA (buf), GST_BUFFER_SIZE (outbuf)); + + /* When we're done with the buffer, we push it on to the next element + * in the pipeline, through the element's source pad, which is stored + * in the element's structure. + */ + gst_pad_push(example->srcpad,outbuf); + + /* For fun we'll emit our useless signal here */ + gtk_signal_emit (GTK_OBJECT (example), gst_example_signals[ASDF], + example); + + /* If we're not doing something, just send the original incoming buffer. */ + } else { + gst_pad_push(example->srcpad,buf); + } } +/* Arguments are part of the Gtk+ object system, and these functions + * enable the element to respond to various arguments. + */ static void gst_example_set_arg (GtkObject *object,GtkArg *arg,guint id) { GstExample *example; - /* it's not null if we got it, but it might not be ours */ + /* It's not null if we got it, but it might not be ours */ g_return_if_fail(GST_IS_EXAMPLE(object)); + + /* Get a pointer of the right type. */ example = GST_EXAMPLE(object); - switch(id) { + /* Check the argument id to see which argument we're setting. */ + switch (id) { case ARG_ACTIVE: + /* Here we simply copy the value of the argument to our private + * storage. More complex operations can be done, but beware that + * they may occur at any time, possibly even while your chain function + * is running, if you are using threads. + */ example->active = GTK_VALUE_INT(*arg); g_print("example: set active to %d\n",example->active); break; @@ -171,12 +312,13 @@ gst_example_set_arg (GtkObject *object,GtkArg *arg,guint id) } } +/* The set function is simply the inverse of the get fuction. */ static void gst_example_get_arg (GtkObject *object,GtkArg *arg,guint id) { GstExample *example; - /* it's not null if we got it, but it might not be ours */ + /* It's not null if we got it, but it might not be ours */ g_return_if_fail(GST_IS_EXAMPLE(object)); example = GST_EXAMPLE(object); @@ -190,25 +332,45 @@ 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) { 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); - sink_template = gst_padtemplate_new (&sink_factory); + /* The pad templates can be easily generated from the factories above, + * and then added to the list of padtemplates for the elementfactory. + * Note that the generated padtemplates are stored in static global + * variables, for the gst_example_init function to use later on. + */ + sink_template = sink_factory (); gst_elementfactory_add_padtemplate (factory, sink_template); - src_template = gst_padtemplate_new (&src_factory); + src_template = src_factory (); gst_elementfactory_add_padtemplate (factory, src_template); + /* 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; + + /* At this point, the GStreamer core registers the plugin, its + * elementfactories, padtemplates, etc., for use in you application. + */ } diff --git a/examples/plugins/example.h b/examples/plugins/example.h index d7f19a3f99..840b8a3d18 100644 --- a/examples/plugins/example.h +++ b/examples/plugins/example.h @@ -28,36 +28,61 @@ extern "C" { #endif /* __cplusplus */ -/* Definition of structure storing data for this element. */ +/* This is the definition of the element's object structure. */ typedef struct _GstExample GstExample; +/* The structure itself is derived from GstElement, as can be seen by the + * fact that there's a complete instance of the GstElement structure at + * the beginning of the object. This allows the element to be cast to + * an Element or even an Object. + */ struct _GstExample { GstElement element; + /* We need to keep track of our pads, so we do so here. */ GstPad *sinkpad,*srcpad; - gint8 active; + /* We'll use this to decide whether to do anything to the data we get. */ + gboolean active; }; -/* Standard definition defining a class for this element. */ +/* The other half of the object is its class. The class also derives from + * the same parent, though it must be the class structure this time. + * Function pointers for polymophic methods and signals are placed in this + * structure. */ typedef struct _GstExampleClass GstExampleClass; + struct _GstExampleClass { GstElementClass parent_class; + + /* signals */ + void (*asdf) (GstElement *element, GstExample *example); }; -/* Standard macros for defining types for this element. */ +/* Five standard preprocessing macros are used in the Gtk+ object system. + * The first uses the object's _get_type function to return the GtkType + * of the object. + */ #define GST_TYPE_EXAMPLE \ (gst_example_get_type()) +/* The second is a checking cast to the correct type. If the object passed + * is not the right type, a warning will be generated on stderr. + */ #define GST_EXAMPLE(obj) \ (GTK_CHECK_CAST((obj),GST_TYPE_EXAMPLE,GstExample)) +/* The third is a checking cast of the class instead of the object. */ #define GST_EXAMPLE_CLASS(klass) \ (GTK_CHECK_CLASS_CAST((klass),GST_TYPE_EXAMPLE,GstExample)) +/* The last two simply check to see if the passed pointer is an object or + * class of the correct type. */ #define GST_IS_EXAMPLE(obj) \ (GTK_CHECK_TYPE((obj),GST_TYPE_EXAMPLE)) #define GST_IS_EXAMPLE_CLASS(obj) \ (GTK_CHECK_CLASS_TYPE((klass),GST_TYPE_EXAMPLE)) -/* Standard function returning type information. */ +/* This is the only prototype needed, because it is used in the above + * GST_TYPE_EXAMPLE macro. + */ GtkType gst_example_get_type(void); diff --git a/examples/queue/queue.c b/examples/queue/queue.c index 146c68912c..0d34a4bf96 100644 --- a/examples/queue/queue.c +++ b/examples/queue/queue.c @@ -1,19 +1,9 @@ #include #include -gboolean playing; - -/* eos will be called when the src element has an end of stream */ -void eos(GstElement *element, gpointer data) -{ - g_print("have eos, quitting\n"); - - playing = FALSE; -} - int main(int argc,char *argv[]) { - GstElement *disksrc, *audiosink, *parse, *decode, *queue; + GstElement *disksrc, *osssink, *parse, *decode, *queue; GstElement *bin; GstElement *thread; @@ -36,8 +26,6 @@ int main(int argc,char *argv[]) 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), thread); parse = gst_elementfactory_make("mp3parse", "parse"); decode = gst_elementfactory_make("mpg123", "decode"); @@ -45,8 +33,8 @@ int main(int argc,char *argv[]) queue = gst_elementfactory_make("queue", "queue"); /* 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); gst_bin_use_cothreads (GST_BIN (bin), TRUE); @@ -56,7 +44,7 @@ int main(int argc,char *argv[]) gst_bin_add(GST_BIN(bin), decode); gst_bin_add(GST_BIN(bin), queue); - gst_bin_add(GST_BIN(thread), audiosink); + gst_bin_add(GST_BIN(thread), osssink); gst_bin_add(GST_BIN(bin), thread); @@ -67,18 +55,12 @@ int main(int argc,char *argv[]) gst_pad_connect(gst_element_get_pad(decode,"src"), gst_element_get_pad(queue,"sink")); gst_pad_connect(gst_element_get_pad(queue,"src"), - gst_element_get_pad(audiosink,"sink")); + gst_element_get_pad(osssink,"sink")); - /* make it ready */ - gst_element_set_state(GST_ELEMENT(bin), GST_STATE_READY); /* start playing */ gst_element_set_state(GST_ELEMENT(bin), GST_STATE_PLAYING); - playing = TRUE; - - while (playing) { - gst_bin_iterate(GST_BIN(bin)); - } + while (gst_bin_iterate(GST_BIN(bin))); gst_element_set_state(GST_ELEMENT(bin), GST_STATE_NULL); diff --git a/examples/queue2/queue2.c b/examples/queue2/queue2.c index a3662b14e6..837732e4c9 100644 --- a/examples/queue2/queue2.c +++ b/examples/queue2/queue2.c @@ -13,7 +13,7 @@ void eos(GstElement *element, gpointer data) int main(int argc,char *argv[]) { - GstElement *disksrc, *audiosink, *queue; + GstElement *disksrc, *osssink, *queue; GstElement *pipeline; GstElement *thread; @@ -42,22 +42,24 @@ int main(int argc,char *argv[]) queue = gst_elementfactory_make("queue", "queue"); /* 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); /* add objects to the main pipeline */ + /* gst_pipeline_add_src(GST_PIPELINE(pipeline), disksrc); gst_pipeline_add_sink(GST_PIPELINE(pipeline), queue); - gst_bin_add(GST_BIN(thread), audiosink); - + gst_bin_add(GST_BIN(thread), osssink); + gst_pad_connect(gst_element_get_pad(queue,"src"), - gst_element_get_pad(audiosink,"sink")); + gst_element_get_pad(osssink,"sink")); if (!gst_pipeline_autoplug(GST_PIPELINE(pipeline))) { g_print("cannot autoplug pipeline\n"); exit(-1); } + */ gst_bin_add(GST_BIN(pipeline), thread); diff --git a/examples/queue3/queue3.c b/examples/queue3/queue3.c index 237b967dba..152cd1e30a 100644 --- a/examples/queue3/queue3.c +++ b/examples/queue3/queue3.c @@ -13,7 +13,7 @@ void eos(GstElement *element, gpointer data) int main(int argc,char *argv[]) { - GstElement *disksrc, *audiosink, *queue, *parse, *decode; + GstElement *disksrc, *osssink, *queue, *parse, *decode; GstElement *bin; GstElement *thread; @@ -42,8 +42,8 @@ int main(int argc,char *argv[]) queue = gst_elementfactory_make("queue", "queue"); /* 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); parse = gst_elementfactory_make("mp3parse", "parse"); decode = gst_elementfactory_make("mpg123", "decode"); @@ -54,7 +54,7 @@ int main(int argc,char *argv[]) gst_bin_add(GST_BIN(thread), parse); gst_bin_add(GST_BIN(thread), decode); - gst_bin_add(GST_BIN(thread), audiosink); + gst_bin_add(GST_BIN(thread), osssink); gst_pad_connect(gst_element_get_pad(disksrc,"src"), gst_element_get_pad(queue,"sink")); @@ -64,7 +64,7 @@ int main(int argc,char *argv[]) gst_pad_connect(gst_element_get_pad(parse,"src"), gst_element_get_pad(decode,"sink")); gst_pad_connect(gst_element_get_pad(decode,"src"), - gst_element_get_pad(audiosink,"sink")); + gst_element_get_pad(osssink,"sink")); gst_bin_add(GST_BIN(bin), thread); diff --git a/examples/queue4/queue4.c b/examples/queue4/queue4.c index a7e9d6d10d..cb984cc7bc 100644 --- a/examples/queue4/queue4.c +++ b/examples/queue4/queue4.c @@ -13,7 +13,7 @@ void eos(GstElement *element, gpointer data) int main(int argc,char *argv[]) { - GstElement *disksrc, *audiosink, *queue, *queue2, *parse, *decode; + GstElement *disksrc, *osssink, *queue, *queue2, *parse, *decode; GstElement *bin; GstElement *thread, *thread2; @@ -45,8 +45,8 @@ int main(int argc,char *argv[]) queue2 = gst_elementfactory_make("queue", "queue2"); /* 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); parse = gst_elementfactory_make("mp3parse", "parse"); decode = gst_elementfactory_make("mpg123", "decode"); @@ -59,7 +59,7 @@ int main(int argc,char *argv[]) gst_bin_add(GST_BIN(thread), decode); gst_bin_add(GST_BIN(thread), queue2); - gst_bin_add(GST_BIN(thread2), audiosink); + gst_bin_add(GST_BIN(thread2), osssink); gst_pad_connect(gst_element_get_pad(disksrc,"src"), gst_element_get_pad(queue,"sink")); @@ -72,7 +72,7 @@ int main(int argc,char *argv[]) gst_element_get_pad(queue2,"sink")); gst_pad_connect(gst_element_get_pad(queue2,"src"), - gst_element_get_pad(audiosink,"sink")); + gst_element_get_pad(osssink,"sink")); gst_bin_add(GST_BIN(bin), thread); gst_bin_add(GST_BIN(bin), thread2); diff --git a/examples/thread/thread.c b/examples/thread/thread.c index 533c38a6f7..5c691a0fa2 100644 --- a/examples/thread/thread.c +++ b/examples/thread/thread.c @@ -14,7 +14,7 @@ void eos(GstElement *element, gpointer data) int main(int argc,char *argv[]) { - GstElement *disksrc, *audiosink; + GstElement *disksrc, *osssink; GstElement *pipeline; GstElement *thread; @@ -41,17 +41,19 @@ int main(int argc,char *argv[]) GTK_SIGNAL_FUNC(eos), thread); /* 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); /* add objects to the main pipeline */ + /* gst_pipeline_add_src(GST_PIPELINE(pipeline), disksrc); - gst_pipeline_add_sink(GST_PIPELINE(pipeline), audiosink); + gst_pipeline_add_sink(GST_PIPELINE(pipeline), osssink); if (!gst_pipeline_autoplug(GST_PIPELINE(pipeline))) { g_print("unable to handle stream\n"); exit(-1); } + */ //gst_bin_remove(GST_BIN(pipeline), disksrc); diff --git a/examples/typefind/.gitignore b/examples/typefind/.gitignore new file mode 100644 index 0000000000..38bc2d7d1f --- /dev/null +++ b/examples/typefind/.gitignore @@ -0,0 +1 @@ +typefind diff --git a/examples/xml/createxml.c b/examples/xml/createxml.c index 154f943b9f..ce8b395495 100644 --- a/examples/xml/createxml.c +++ b/examples/xml/createxml.c @@ -15,7 +15,7 @@ object_saved (GstObject *object, xmlNodePtr parent, gpointer data) int main(int argc,char *argv[]) { - GstElement *disksrc, *audiosink, *queue, *queue2, *parse, *decode; + GstElement *disksrc, *osssink, *queue, *queue2, *parse, *decode; GstElement *bin; GstElement *thread, *thread2; @@ -52,8 +52,8 @@ int main(int argc,char *argv[]) queue2 = gst_elementfactory_make("queue", "queue2"); /* 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); parse = gst_elementfactory_make("mp3parse", "parse"); decode = gst_elementfactory_make("mpg123", "decode"); @@ -66,7 +66,7 @@ int main(int argc,char *argv[]) gst_bin_add(GST_BIN(thread), decode); gst_bin_add(GST_BIN(thread), queue2); - gst_bin_add(GST_BIN(thread2), audiosink); + gst_bin_add(GST_BIN(thread2), osssink); gst_pad_connect(gst_element_get_pad(disksrc,"src"), gst_element_get_pad(queue,"sink")); @@ -79,7 +79,7 @@ int main(int argc,char *argv[]) gst_element_get_pad(queue2,"sink")); gst_pad_connect(gst_element_get_pad(queue2,"src"), - gst_element_get_pad(audiosink,"sink")); + gst_element_get_pad(osssink,"sink")); gst_bin_add(GST_BIN(bin), thread); gst_bin_add(GST_BIN(bin), thread2); diff --git a/examples/xml/runxml.c b/examples/xml/runxml.c index 5594ec86b8..400e82559b 100644 --- a/examples/xml/runxml.c +++ b/examples/xml/runxml.c @@ -35,8 +35,6 @@ int main(int argc,char *argv[]) xml = gst_xml_new (); - //g_print ("%p\n", xml); - gtk_signal_connect (GTK_OBJECT (xml), "object_loaded", xml_loaded, xml); ret = gst_xml_parse_file(xml, "xmlTest.gst", NULL); @@ -47,8 +45,6 @@ int main(int argc,char *argv[]) gst_element_set_state(bin, GST_STATE_PLAYING); - playing = TRUE; - while (gst_bin_iterate(GST_BIN(bin))); gst_element_set_state(bin, GST_STATE_NULL); diff --git a/gst/Makefile.am b/gst/Makefile.am index 34e77090da..f4f8aada27 100644 --- a/gst/Makefile.am +++ b/gst/Makefile.am @@ -1,5 +1,5 @@ # cheap trick to build . first... -SUBDIRS = . types meta elements +SUBDIRS = . types elements autoplug lib_LTLIBRARIES = libgst.la @@ -43,29 +43,48 @@ libgst_la_SOURCES = \ gstparse.c \ $(GSTARCH_SRCS) + +##### Oh this sucks so badly. This isn't funny. ##### + # the compiler shoots cothreads.c in the head at -O6 # FIXME: these manual rules break the dependency generation, so we have a # nasty hack here. -LTCOMPILE2=$(LTCOMPILE) -O2 -COMPILE2=$(COMPILE) -O2 -cothreads.lo: cothreads.c - @echo '$(LTCOMPILE2) -c $<'; \ - $(LTCOMPILE2) -Wp,-MD,.deps/$(*F).pp -c $< - @-sed -e 's/^\([^:]*\)\.o[ ]*:/\1.lo \1.o :/' \ - < .deps/$(*F).pp > .deps/$(*F).P; \ - tr ' ' '\012' < .deps/$(*F).pp \ - | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \ - >> .deps/$(*F).P; \ - rm -f .deps/$(*F).pp -cothreads.o: cothreads.c - @echo '$(COMPILE2) -c $<'; \ - $(COMPILE2) -Wp,-MD,.deps/$(*F).pp -c $< - @-sed -e 's/^\([^:]*\)\.o[ ]*:/\1.lo \1.o :/' \ - < .deps/$(*F).pp > .deps/$(*F).P; \ - tr ' ' '\012' < .deps/$(*F).pp \ - | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \ - >> .deps/$(*F).P; \ - rm -f .deps/$(*F).pp +#LTCOMPILE2=$(LTCOMPILE) -O2 +#COMPILE2=$(COMPILE) -O2 + +cothreads.lo: cothreads.c cothreads.h gst_private.h ../config.h gstinfo.c \ +gstarch.h gsti386.h + $(LIBTOOL) --mode=compile $(COMPILE) -O2 -c $< +cothreads.o: cothreads.c cothreads.h gst_private.h ../config.h gstinfo.c \ +gstarch.h gsti386.h + $(COMPILE) -O2 -c $< + +# NOTDEPEND.cothreads.lo: cothreads.c +# NOTDEPEND $(LTCOMPILE2) -c $< +# NOTDEPEND.cothreads.o: cothreads.c +# NOTDEPEND $(COMPILE2) -c $< + +#cothreads.lo: cothreads.c +# @echo '$(LTCOMPILE2) -c $<'; \ +# $(LTCOMPILE2) -Wp,-MD,.deps/$(*F).pp -c $< +# @-sed -e 's/^\([^:]*\)\.o[ ]*:/\1.lo \1.o :/' \ +# < .deps/$(*F).pp > .deps/$(*F).P; \ +# tr ' ' '\012' < .deps/$(*F).pp \ +# | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \ +# >> .deps/$(*F).P; \ +# rm -f .deps/$(*F).pp +#cothreads.o: cothreads.c +# @echo '$(COMPILE2) -c $<'; \ +# $(COMPILE2) -Wp,-MD,.deps/$(*F).pp -c $< +# @-sed -e 's/^\([^:]*\)\.o[ ]*:/\1.lo \1.o :/' \ +# < .deps/$(*F).pp > .deps/$(*F).P; \ +# tr ' ' '\012' < .deps/$(*F).pp \ +# | sed -e 's/^\\$$//' -e '/^$$/ d' -e '/:$$/ d' -e 's/$$/ :/' \ +# >> .deps/$(*F).P; \ +# rm -f .deps/$(*F).pp + +##### end immense suckage ##### + libgstincludedir = $(includedir)/gst libgstinclude_HEADERS = \ @@ -106,6 +125,7 @@ noinst_HEADERS = \ gstppc.h \ gstalpha.h \ gstarm.h \ + gstsparc.h \ gstpropsprivate.h CFLAGS = $(LIBGST_CFLAGS) diff --git a/gst/Makefile.am.future b/gst/Makefile.am.future new file mode 100644 index 0000000000..8b7e666ced --- /dev/null +++ b/gst/Makefile.am.future @@ -0,0 +1,98 @@ +# This Makefile.am is a much neater Makefile.am for this directory, but +# depends on automake 1.4d or later. + +# cheap trick to build . first... +SUBDIRS = . types elements autoplug + +lib_LTLIBRARIES = libgst.la +noinst_LTLIBRARIES = libcothreads.la + +if HAVE_CPU_I386 +GSTARCH_SRCS = gstcpuid_i386.s +else +GSTARCH_SRCS = +endif + +EXTRA_libgst_la_SOURCES = gstcpuid_i386.s + + +libcothreads_la_CFLAGS = $(CFLAGS) $(LIBGST_CFLAGS) -O2 +libgst_la_CFLAGS = $(CFLAGS) $(LIBGST_CFLAGS) +CFLAGS = + +libcothreads_la_SOURCES = cothreads.c +libgst_la_SOURCES = \ + gst.c \ + gstautoplug.c \ + gstbin.c \ + gstbuffer.c \ + gstbufferpool.c \ + gstcaps.c \ + gstclock.c \ + gstcpu.c \ + gstelement.c \ + gstelementfactory.c \ + gstextratypes.c \ + gstinfo.c \ + gstmeta.c \ + gstobject.c \ + gstpad.c \ + gstpipeline.c \ + gstplugin.c \ + gstprops.c \ + gstqueue.c \ + gstscheduler.c \ + gstthread.c \ + gsttrace.c \ + gsttype.c \ + gsttypefind.c \ + gstutils.c \ + gstxml.c \ + gstparse.c \ + $(GSTARCH_SRCS) + +libgstincludedir = $(includedir)/gst +libgstinclude_HEADERS = \ + cothreads.h \ + gst.h \ + gstautoplug.h \ + gstbin.h \ + gstbuffer.h \ + gstbufferpool.h \ + gstcaps.h \ + gstclock.h \ + gstcpu.h \ + gstelement.h \ + gstextratypes.h \ + gstinfo.h \ + gstlog.h \ + gstmeta.h \ + gstobject.h \ + gstpad.h \ + gstpipeline.h \ + gstplugin.h \ + gstprops.h \ + gstqueue.h \ + gstscheduler.h \ + gstthread.h \ + gsttrace.h \ + gsttype.h \ + gsttypefind.h \ + gstutils.h \ + gstparse.h \ + gstxml.h + +noinst_HEADERS = \ + gst_private.h \ + gstarch.h \ + gsti386.h \ + gstppc.h \ + gstalpha.h \ + gstarm.h \ + gstsparc.h \ + gstpropsprivate.h + +libgst_la_LDFLAGS = -version-info $(GSTREAMER_LIBVERSION) $(LIBGST_LIBS) +libgst_la_LIBADD = libcothreads.la + +EXTRA_DIST = ROADMAP diff --git a/gst/cothreads.c b/gst/cothreads.c index 085759a27b..e9cd26184b 100644 --- a/gst/cothreads.c +++ b/gst/cothreads.c @@ -268,6 +268,9 @@ cothread_switch (cothread_state *thread) ctx->current = thread->threadnum; /* save the current stack pointer, frame pointer, and pc */ +#ifdef GST_ARCH_PRESETJMP + GST_ARCH_PRESETJMP(); +#endif enter = setjmp(current->jmp); if (enter != 0) { GST_DEBUG (0,"enter thread #%d %d %p<->%p (%d)\n",current->threadnum, enter, diff --git a/gst/elements/Makefile.am b/gst/elements/Makefile.am index 0c5b9e6810..e41a972f40 100644 --- a/gst/elements/Makefile.am +++ b/gst/elements/Makefile.am @@ -16,9 +16,8 @@ libgstelements_la_SOURCES = \ gstfakesink.c \ gstdisksrc.c \ gstfdsrc.c \ - gstaudiosink.c \ - gstaudiosrc.c \ gstfdsink.c \ + gstmultidisksrc.c \ gstpipefilter.c \ gsttee.c \ gstsinesrc.c \ @@ -30,9 +29,8 @@ noinst_HEADERS = \ gstfakesink.h \ gstdisksrc.h \ gstfdsrc.h \ + gstmultidisksrc.h \ gsthttpsrc.h \ - gstaudiosink.h \ - gstaudiosrc.h \ gstfdsink.h \ gstpipefilter.h \ gsttee.h \ diff --git a/gst/elements/gstaudiosink.c b/gst/elements/gstaudiosink.c deleted file mode 100644 index 10277290b9..0000000000 --- a/gst/elements/gstaudiosink.c +++ /dev/null @@ -1,438 +0,0 @@ -/* GStreamer - * Copyright (C) 1999,2000 Erik Walthinsen - * 2000 Wim Taymans - * - * gstaudiosink.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 -#include -#include -#include -#include -#include -#include - -//#define DEBUG_ENABLED - -#include -#include - - -GstElementDetails gst_audiosink_details = { - "Audio Sink (OSS)", - "Sink/Audio", - "Output to a sound card via OSS", - VERSION, - "Erik Walthinsen ", - "(C) 1999", -}; - -static void gst_audiosink_class_init (GstAudioSinkClass *klass); -static void gst_audiosink_init (GstAudioSink *audiosink); - -static gboolean gst_audiosink_open_audio (GstAudioSink *sink); -static void gst_audiosink_close_audio (GstAudioSink *sink); -static GstElementStateReturn gst_audiosink_change_state (GstElement *element); - -static void gst_audiosink_set_arg (GtkObject *object, GtkArg *arg, guint id); -static void gst_audiosink_get_arg (GtkObject *object, GtkArg *arg, guint id); - -static void gst_audiosink_chain (GstPad *pad,GstBuffer *buf); - -/* AudioSink signals and args */ -enum { - SIGNAL_HANDOFF, - LAST_SIGNAL -}; - -enum { - ARG_0, - ARG_MUTE, - ARG_FORMAT, - ARG_CHANNELS, - ARG_FREQUENCY, - /* FILL ME */ -}; - -static GstPadFactory audiosink_sink_factory = { - "sink", - GST_PAD_FACTORY_SINK, - GST_PAD_FACTORY_ALWAYS, - GST_PAD_FACTORY_CAPS ( - "audiosink_sink", - "audio/raw", - "format", GST_PROPS_INT (AFMT_S16_LE), - "depth", GST_PROPS_LIST ( - GST_PROPS_INT (8), - GST_PROPS_INT (16) - ), - "rate", GST_PROPS_INT_RANGE (8000, 48000), - "channels", GST_PROPS_INT_RANGE (1, 2) - ), - NULL -}; - -#define GST_TYPE_AUDIOSINK_FORMATS (gst_audiosink_formats_get_type()) - -static GtkType -gst_audiosink_formats_get_type(void) { - static GtkType audiosink_formats_type = 0; - static GtkEnumValue audiosink_formats[] = { - {8, "8", "8 Bits"}, - {16, "16", "16 Bits"}, - {0, NULL, NULL}, - }; - if (!audiosink_formats_type) { - audiosink_formats_type = gtk_type_register_enum("GstAudiosinkFormats", audiosink_formats); - } - return audiosink_formats_type; -} - -#define GST_TYPE_AUDIOSINK_CHANNELS (gst_audiosink_channels_get_type()) - -static GtkType -gst_audiosink_channels_get_type(void) { - static GtkType audiosink_channels_type = 0; - static GtkEnumValue audiosink_channels[] = { - {1, "1", "Mono"}, - {2, "2", "Stereo"}, - {0, NULL, NULL}, - }; - if (!audiosink_channels_type) { - audiosink_channels_type = gtk_type_register_enum("GstAudiosinkChannels", audiosink_channels); - } - return audiosink_channels_type; -} - - -static GstElementClass *parent_class = NULL; -static guint gst_audiosink_signals[LAST_SIGNAL] = { 0 }; - -static GstPadTemplate *gst_audiosink_sink_template; - -GtkType -gst_audiosink_get_type (void) -{ - static GtkType audiosink_type = 0; - - if (!audiosink_type) { - static const GtkTypeInfo audiosink_info = { - "GstAudioSink", - sizeof(GstAudioSink), - sizeof(GstAudioSinkClass), - (GtkClassInitFunc)gst_audiosink_class_init, - (GtkObjectInitFunc)gst_audiosink_init, - (GtkArgSetFunc)NULL, - (GtkArgGetFunc)NULL, - (GtkClassInitFunc)NULL, - }; - audiosink_type = gtk_type_unique (GST_TYPE_ELEMENT, &audiosink_info); - } - - return audiosink_type; -} - -static void -gst_audiosink_class_init (GstAudioSinkClass *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 ("GstAudioSink::mute", GTK_TYPE_BOOL, - GTK_ARG_READWRITE, ARG_MUTE); - gtk_object_add_arg_type ("GstAudioSink::format", GST_TYPE_AUDIOSINK_FORMATS, - GTK_ARG_READWRITE, ARG_FORMAT); - gtk_object_add_arg_type ("GstAudioSink::channels", GST_TYPE_AUDIOSINK_CHANNELS, - GTK_ARG_READWRITE, ARG_CHANNELS); - gtk_object_add_arg_type ("GstAudioSink::frequency", GTK_TYPE_INT, - GTK_ARG_READWRITE, ARG_FREQUENCY); - - gtkobject_class->set_arg = gst_audiosink_set_arg; - gtkobject_class->get_arg = gst_audiosink_get_arg; - - gst_audiosink_signals[SIGNAL_HANDOFF] = - gtk_signal_new("handoff",GTK_RUN_LAST,gtkobject_class->type, - GTK_SIGNAL_OFFSET(GstAudioSinkClass,handoff), - gtk_marshal_NONE__NONE,GTK_TYPE_NONE,0); - - gtk_object_class_add_signals(gtkobject_class,gst_audiosink_signals, - LAST_SIGNAL); - - gstelement_class->change_state = gst_audiosink_change_state; -} - -static void -gst_audiosink_init (GstAudioSink *audiosink) -{ - audiosink->sinkpad = gst_pad_new_from_template (gst_audiosink_sink_template, "sink"); - gst_element_add_pad (GST_ELEMENT (audiosink), audiosink->sinkpad); - - gst_pad_set_chain_function (audiosink->sinkpad, gst_audiosink_chain); - - audiosink->fd = -1; - audiosink->clock = gst_clock_get_system(); - audiosink->format = 16; - audiosink->channels = 2; - audiosink->frequency = 44100; - - gst_clock_register (audiosink->clock, GST_OBJECT (audiosink)); - - GST_FLAG_SET (audiosink, GST_ELEMENT_THREAD_SUGGESTED); -} - -static void -gst_audiosink_sync_parms (GstAudioSink *audiosink) -{ - audio_buf_info ospace; - int frag; - - g_return_if_fail (audiosink != NULL); - g_return_if_fail (GST_IS_AUDIOSINK (audiosink)); - - if (audiosink->fd == -1) return; - - ioctl (audiosink->fd, SNDCTL_DSP_RESET, 0); - - ioctl (audiosink->fd, SNDCTL_DSP_SETFMT, &audiosink->format); - ioctl (audiosink->fd, SNDCTL_DSP_CHANNELS, &audiosink->channels); - ioctl (audiosink->fd, SNDCTL_DSP_SPEED, &audiosink->frequency); - ioctl (audiosink->fd, SNDCTL_DSP_GETBLKSIZE, &frag); - - ioctl (audiosink->fd, SNDCTL_DSP_GETOSPACE, &ospace); - - g_print("audiosink: setting sound card to %dKHz %d bit %s (%d bytes buffer, %d fragment)\n", - audiosink->frequency, audiosink->format, - (audiosink->channels == 2) ? "stereo" : "mono", ospace.bytes, frag); - -} - -static void -gst_audiosink_chain (GstPad *pad, GstBuffer *buf) -{ - GstAudioSink *audiosink; - MetaAudioRaw *meta; - gboolean in_flush; - audio_buf_info ospace; - - g_return_if_fail (pad != NULL); - g_return_if_fail (GST_IS_PAD (pad)); - g_return_if_fail (buf != NULL); - - - /* this has to be an audio buffer */ -// g_return_if_fail(((GstMeta *)buf->meta)->type != -//gst_audiosink_type_audio); - audiosink = GST_AUDIOSINK (gst_pad_get_parent (pad)); -// g_return_if_fail(GST_FLAG_IS_SET(audiosink,GST_STATE_RUNNING)); - - if ((in_flush = GST_BUFFER_FLAG_IS_SET (buf, GST_BUFFER_FLUSH))) { - GST_DEBUG (0,"audiosink: flush\n"); - ioctl (audiosink->fd, SNDCTL_DSP_RESET, 0); - } - - - meta = (MetaAudioRaw *)gst_buffer_get_first_meta (buf); - if (meta != NULL) { - if ((meta->format != audiosink->format) || - (meta->channels != audiosink->channels) || - (meta->frequency != audiosink->frequency)) - { - audiosink->format = meta->format; - audiosink->channels = meta->channels; - audiosink->frequency = meta->frequency; - gst_audiosink_sync_parms (audiosink); - g_print("audiosink: sound device set to format %d, %d channels, %dHz\n", - audiosink->format, audiosink->channels, audiosink->frequency); - } - } - - gtk_signal_emit (GTK_OBJECT (audiosink), gst_audiosink_signals[SIGNAL_HANDOFF], - audiosink); - - if (GST_BUFFER_DATA (buf) != NULL) { - gst_trace_add_entry(NULL, 0, buf, "audiosink: writing to soundcard"); - //g_print("audiosink: writing to soundcard\n"); - if (audiosink->fd >= 0) { - if (!audiosink->mute) { - gst_clock_wait (audiosink->clock, GST_BUFFER_TIMESTAMP (buf), GST_OBJECT (audiosink)); - ioctl (audiosink->fd, SNDCTL_DSP_GETOSPACE, &ospace); - GST_DEBUG (0,"audiosink: (%d bytes buffer) %d %p %d\n", ospace.bytes, - audiosink->fd, GST_BUFFER_DATA (buf), GST_BUFFER_SIZE (buf)); - write (audiosink->fd, GST_BUFFER_DATA (buf), GST_BUFFER_SIZE (buf)); - //write(STDOUT_FILENO,GST_BUFFER_DATA(buf),GST_BUFFER_SIZE(buf)); - } - } - } - gst_buffer_unref (buf); -} - -static void -gst_audiosink_set_arg (GtkObject *object, GtkArg *arg, guint id) -{ - GstAudioSink *audiosink; - - /* it's not null if we got it, but it might not be ours */ - g_return_if_fail (GST_IS_AUDIOSINK (object)); - - audiosink = GST_AUDIOSINK (object); - - switch(id) { - case ARG_MUTE: - audiosink->mute = GTK_VALUE_BOOL (*arg); - break; - case ARG_FORMAT: - audiosink->format = GTK_VALUE_ENUM (*arg); - gst_audiosink_sync_parms (audiosink); - break; - case ARG_CHANNELS: - audiosink->channels = GTK_VALUE_ENUM (*arg); - gst_audiosink_sync_parms (audiosink); - break; - case ARG_FREQUENCY: - audiosink->frequency = GTK_VALUE_INT (*arg); - gst_audiosink_sync_parms (audiosink); - break; - default: - break; - } -} - -static void -gst_audiosink_get_arg (GtkObject *object, GtkArg *arg, guint id) -{ - GstAudioSink *audiosink; - - /* it's not null if we got it, but it might not be ours */ - g_return_if_fail (GST_IS_AUDIOSINK (object)); - - audiosink = GST_AUDIOSINK (object); - - switch(id) { - case ARG_MUTE: - GTK_VALUE_BOOL (*arg) = audiosink->mute; - break; - case ARG_FORMAT: - GTK_VALUE_ENUM (*arg) = audiosink->format; - break; - case ARG_CHANNELS: - GTK_VALUE_ENUM (*arg) = audiosink->channels; - break; - case ARG_FREQUENCY: - GTK_VALUE_INT (*arg) = audiosink->frequency; - break; - default: - break; - } -} - -static gboolean -gst_audiosink_open_audio (GstAudioSink *sink) -{ - g_return_val_if_fail (sink->fd == -1, FALSE); - - g_print ("audiosink: attempting to open sound device\n"); - - /* first try to open the sound card */ - sink->fd = open("/dev/dsp", O_WRONLY | O_NONBLOCK); - if (errno == EBUSY) { - g_print ("audiosink: unable to open the sound device (in use ?)\n"); - return FALSE; - } - - /* re-open the sound device in blocking mode */ - close(sink->fd); - sink->fd = open("/dev/dsp", O_WRONLY); - - /* if we have it, set the default parameters and go have fun */ - if (sink->fd >= 0) { - /* set card state */ - sink->format = AFMT_S16_LE; - sink->channels = 2; /* stereo */ - sink->frequency = 44100; - gst_audiosink_sync_parms (sink); - ioctl(sink->fd, SNDCTL_DSP_GETCAPS, &sink->caps); - - g_print("audiosink: Capabilities\n"); - - if (sink->caps & DSP_CAP_DUPLEX) g_print("audiosink: Full duplex\n"); - if (sink->caps & DSP_CAP_REALTIME) g_print("audiosink: Realtime\n"); - if (sink->caps & DSP_CAP_BATCH) g_print("audiosink: Batch\n"); - if (sink->caps & DSP_CAP_COPROC) g_print("audiosink: Has coprocessor\n"); - if (sink->caps & DSP_CAP_TRIGGER) g_print("audiosink: Trigger\n"); - if (sink->caps & DSP_CAP_MMAP) g_print("audiosink: Direct access\n"); - - g_print("audiosink: opened audio with fd=%d\n", sink->fd); - GST_FLAG_SET (sink, GST_AUDIOSINK_OPEN); - - return TRUE; - } - - return FALSE; -} - -static void -gst_audiosink_close_audio (GstAudioSink *sink) -{ - if (sink->fd < 0) return; - - close(sink->fd); - sink->fd = -1; - - GST_FLAG_UNSET (sink, GST_AUDIOSINK_OPEN); - - g_print("audiosink: closed sound device\n"); -} - -static GstElementStateReturn -gst_audiosink_change_state (GstElement *element) -{ - g_return_val_if_fail (GST_IS_AUDIOSINK (element), FALSE); - - /* if going down into NULL state, close the file if it's open */ - if (GST_STATE_PENDING (element) == GST_STATE_NULL) { - if (GST_FLAG_IS_SET (element, GST_AUDIOSINK_OPEN)) - gst_audiosink_close_audio (GST_AUDIOSINK (element)); - /* otherwise (READY or higher) we need to open the sound card */ - } else { - if (!GST_FLAG_IS_SET (element, GST_AUDIOSINK_OPEN)) { - if (!gst_audiosink_open_audio (GST_AUDIOSINK (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; -} - -gboolean -gst_audiosink_factory_init (GstElementFactory *factory) -{ - gst_audiosink_sink_template = gst_padtemplate_new (&audiosink_sink_factory); - gst_elementfactory_add_padtemplate (factory, gst_audiosink_sink_template); - - return TRUE; -} - diff --git a/gst/elements/gstaudiosink.h b/gst/elements/gstaudiosink.h deleted file mode 100644 index d5233922f1..0000000000 --- a/gst/elements/gstaudiosink.h +++ /dev/null @@ -1,92 +0,0 @@ -/* GStreamer - * Copyright (C) 1999,2000 Erik Walthinsen - * 2000 Wim Taymans - * - * gstaudiosink.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_AUDIOSINK_H__ -#define __GST_AUDIOSINK_H__ - - -#include -#include - - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - - -GstElementDetails gst_audiosink_details; - - -#define GST_TYPE_AUDIOSINK \ - (gst_audiosink_get_type()) -#define GST_AUDIOSINK(obj) \ - (GTK_CHECK_CAST((obj),GST_TYPE_AUDIOSINK,GstAudioSink)) -#define GST_AUDIOSINK_CLASS(klass) \ - (GTK_CHECK_CLASS_CAST((klass),GST_TYPE_AUDIOSINK,GstAudioSinkClass)) -#define GST_IS_AUDIOSINK(obj) \ - (GTK_CHECK_TYPE((obj),GST_TYPE_AUDIOSINK)) -#define GST_IS_AUDIOSINK_CLASS(obj) \ - (GTK_CHECK_CLASS_TYPE((klass),GST_TYPE_AUDIOSINK)) - -typedef enum { - GST_AUDIOSINK_OPEN = GST_ELEMENT_FLAG_LAST, - - GST_AUDIOSINK_FLAG_LAST = GST_ELEMENT_FLAG_LAST+2, -} GstAudioSinkFlags; - -typedef struct _GstAudioSink GstAudioSink; -typedef struct _GstAudioSinkClass GstAudioSinkClass; - -struct _GstAudioSink { - GstElement element; - - GstPad *sinkpad; - - //GstClockTime clocktime; - GstClock *clock; - /* soundcard state */ - int fd; - int caps; /* the capabilities */ - gint format; - gint channels; - gint frequency; - gboolean mute; -}; - -struct _GstAudioSinkClass { - GstElementClass parent_class; - - /* signals */ - void (*handoff) (GstElement *element,GstPad *pad); -}; - -GtkType gst_audiosink_get_type(void); - -gboolean gst_audiosink_factory_init(GstElementFactory *factory); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - - -#endif /* __GST_AUDIOSINK_H__ */ diff --git a/gst/elements/gstaudiosrc.c b/gst/elements/gstaudiosrc.c deleted file mode 100644 index b4645fdb9c..0000000000 --- a/gst/elements/gstaudiosrc.c +++ /dev/null @@ -1,321 +0,0 @@ -/* GStreamer - * Copyright (C) 1999,2000 Erik Walthinsen - * 2000 Wim Taymans - * - * gstaudiosrc.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 -#include -#include -#include -#include -#include - -#include - - -GstElementDetails gst_audiosrc_details = { - "Audio (OSS) Source", - "Source/Audio", - "Read from the sound card", - VERSION, - "Erik Walthinsen ", - "(C) 1999", -}; - - -/* AudioSrc signals and args */ -enum { - /* FILL ME */ - LAST_SIGNAL -}; - -enum { - ARG_0, - ARG_BYTESPERREAD, - ARG_CUROFFSET, - ARG_FORMAT, - ARG_CHANNELS, - ARG_FREQUENCY, -}; - - -static void gst_audiosrc_class_init (GstAudioSrcClass *klass); -static void gst_audiosrc_init (GstAudioSrc *audiosrc); - -static void gst_audiosrc_set_arg (GtkObject *object, GtkArg *arg, guint id); -static void gst_audiosrc_get_arg (GtkObject *object, GtkArg *arg, guint id); -static GstElementStateReturn gst_audiosrc_change_state (GstElement *element); - -static void gst_audiosrc_close_audio (GstAudioSrc *src); -static gboolean gst_audiosrc_open_audio (GstAudioSrc *src); -static void gst_audiosrc_sync_parms (GstAudioSrc *audiosrc); - -static GstBuffer * gst_audiosrc_get (GstPad *pad); - -static GstElementClass *parent_class = NULL; -//static guint gst_audiosrc_signals[LAST_SIGNAL] = { 0 }; - -GtkType -gst_audiosrc_get_type (void) -{ - static GtkType audiosrc_type = 0; - - if (!audiosrc_type) { - static const GtkTypeInfo audiosrc_info = { - "GstAudioSrc", - sizeof(GstAudioSrc), - sizeof(GstAudioSrcClass), - (GtkClassInitFunc)gst_audiosrc_class_init, - (GtkObjectInitFunc)gst_audiosrc_init, - (GtkArgSetFunc)gst_audiosrc_set_arg, - (GtkArgGetFunc)gst_audiosrc_get_arg, - (GtkClassInitFunc)NULL, - }; - audiosrc_type = gtk_type_unique (GST_TYPE_ELEMENT, &audiosrc_info); - } - return audiosrc_type; -} - -static void -gst_audiosrc_class_init (GstAudioSrcClass *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 ("GstAudioSrc::bytes_per_read", GTK_TYPE_ULONG, - GTK_ARG_READWRITE, ARG_BYTESPERREAD); - gtk_object_add_arg_type ("GstAudioSrc::curoffset", GTK_TYPE_ULONG, - GTK_ARG_READABLE, ARG_CUROFFSET); - gtk_object_add_arg_type ("GstAudioSrc::format", GTK_TYPE_INT, - GTK_ARG_READWRITE, ARG_FORMAT); - gtk_object_add_arg_type ("GstAudioSrc::channels", GTK_TYPE_INT, - GTK_ARG_READWRITE, ARG_CHANNELS); - gtk_object_add_arg_type ("GstAudioSrc::frequency", GTK_TYPE_INT, - GTK_ARG_READWRITE, ARG_FREQUENCY); - - gtkobject_class->set_arg = gst_audiosrc_set_arg; - gtkobject_class->get_arg = gst_audiosrc_get_arg; - - gstelement_class->change_state = gst_audiosrc_change_state; -} - -static void -gst_audiosrc_init (GstAudioSrc *audiosrc) -{ - audiosrc->srcpad = gst_pad_new ("src", GST_PAD_SRC); - gst_pad_set_get_function(audiosrc->srcpad,gst_audiosrc_get); - gst_element_add_pad (GST_ELEMENT (audiosrc), audiosrc->srcpad); - - audiosrc->fd = -1; - -// audiosrc->meta = (MetaAudioRaw *)gst_meta_new(); -// audiosrc->meta->format = AFMT_S16_LE; -// audiosrc->meta->channels = 2; -// audiosrc->meta->frequency = 44100; -// audiosrc->meta->bps = 4; - - audiosrc->bytes_per_read = 4096; - audiosrc->curoffset = 0; - audiosrc->seq = 0; -} - -static GstBuffer * -gst_audiosrc_get (GstPad *pad) -{ - GstAudioSrc *src; - GstBuffer *buf; - glong readbytes; - - g_return_val_if_fail (pad != NULL, NULL); - src = GST_AUDIOSRC(gst_pad_get_parent (pad)); - -// g_print("attempting to read something from soundcard\n"); - - buf = gst_buffer_new (); - g_return_val_if_fail (buf, NULL); - - GST_BUFFER_DATA (buf) = (gpointer)g_malloc (src->bytes_per_read); - - readbytes = read (src->fd,GST_BUFFER_DATA (buf), - src->bytes_per_read); - - if (readbytes == 0) { - gst_element_signal_eos (GST_ELEMENT (src)); - return NULL; - } - - GST_BUFFER_SIZE (buf) = readbytes; - GST_BUFFER_OFFSET (buf) = src->curoffset; - - src->curoffset += readbytes; - -// gst_buffer_add_meta(buf,GST_META(newmeta)); - -// g_print("pushed buffer from soundcard of %d bytes\n",readbytes); - return buf; -} - -static void -gst_audiosrc_set_arg (GtkObject *object, GtkArg *arg, guint id) -{ - GstAudioSrc *src; - - /* it's not null if we got it, but it might not be ours */ - g_return_if_fail (GST_IS_AUDIOSRC (object)); - - src = GST_AUDIOSRC (object); - - switch (id) { - case ARG_BYTESPERREAD: - src->bytes_per_read = GTK_VALUE_INT (*arg); - break; - case ARG_FORMAT: - src->format = GTK_VALUE_INT (*arg); - break; - case ARG_CHANNELS: - src->channels = GTK_VALUE_INT (*arg); - break; - case ARG_FREQUENCY: - src->frequency = GTK_VALUE_INT (*arg); - break; - default: - break; - } -} - -static void -gst_audiosrc_get_arg (GtkObject *object, GtkArg *arg, guint id) -{ - GstAudioSrc *src; - - /* it's not null if we got it, but it might not be ours */ - g_return_if_fail (GST_IS_AUDIOSRC (object)); - - src = GST_AUDIOSRC (object); - - switch (id) { - case ARG_BYTESPERREAD: - GTK_VALUE_INT (*arg) = src->bytes_per_read; - break; - case ARG_FORMAT: - GTK_VALUE_INT (*arg) = src->format; - break; - case ARG_CHANNELS: - GTK_VALUE_INT (*arg) = src->channels; - break; - case ARG_FREQUENCY: - GTK_VALUE_INT (*arg) = src->frequency; - break; - default: - arg->type = GTK_TYPE_INVALID; - break; - } -} - -static GstElementStateReturn -gst_audiosrc_change_state (GstElement *element) -{ - g_return_val_if_fail (GST_IS_AUDIOSRC (element), FALSE); - - /* if going down into NULL state, close the file if it's open */ - if (GST_STATE_PENDING (element) == GST_STATE_NULL) { - if (GST_FLAG_IS_SET (element, GST_AUDIOSRC_OPEN)) - gst_audiosrc_close_audio (GST_AUDIOSRC (element)); - /* otherwise (READY or higher) we need to open the sound card */ - } else { - if (!GST_FLAG_IS_SET (element, GST_AUDIOSRC_OPEN)) { - if (!gst_audiosrc_open_audio (GST_AUDIOSRC (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; -} - -static gboolean -gst_audiosrc_open_audio (GstAudioSrc *src) -{ - g_return_val_if_fail (!GST_FLAG_IS_SET (src, GST_AUDIOSRC_OPEN), FALSE); - - /* first try to open the sound card */ - src->fd = open("/dev/dsp", O_RDONLY); - - /* if we have it, set the default parameters and go have fun */ - if (src->fd > 0) { - int arg = 0x7fff0006; - - if (ioctl (src->fd, SNDCTL_DSP_SETFRAGMENT, &arg)) perror("uh"); - - /* set card state */ - gst_audiosrc_sync_parms (src); - GST_DEBUG (0,"opened audio\n"); - - GST_FLAG_SET (src, GST_AUDIOSRC_OPEN); - return TRUE; - } - - return FALSE; -} - -static void -gst_audiosrc_close_audio (GstAudioSrc *src) -{ - g_return_if_fail (GST_FLAG_IS_SET (src, GST_AUDIOSRC_OPEN)); - - close(src->fd); - src->fd = -1; - - GST_FLAG_UNSET (src, GST_AUDIOSRC_OPEN); -} - -static void -gst_audiosrc_sync_parms (GstAudioSrc *audiosrc) -{ - audio_buf_info ospace; - - g_return_if_fail (audiosrc != NULL); - g_return_if_fail (GST_IS_AUDIOSRC (audiosrc)); - g_return_if_fail (audiosrc->fd > 0); - - ioctl(audiosrc->fd, SNDCTL_DSP_RESET, 0); - - ioctl(audiosrc->fd, SNDCTL_DSP_SETFMT, &audiosrc->format); - ioctl(audiosrc->fd, SNDCTL_DSP_CHANNELS, &audiosrc->channels); - ioctl(audiosrc->fd, SNDCTL_DSP_SPEED, &audiosrc->frequency); - - ioctl(audiosrc->fd, SNDCTL_DSP_GETOSPACE, &ospace); - - g_print("setting sound card to %dKHz %d bit %s (%d bytes buffer)\n", - audiosrc->frequency,audiosrc->format, - (audiosrc->channels == 2) ? "stereo" : "mono",ospace.bytes); - -// audiosrc->meta.format = audiosrc->format; -// audiosrc->meta.channels = audiosrc->channels; -// audiosrc->meta.frequency = audiosrc->frequency; -// audiosrc->sentmeta = FALSE; -} diff --git a/gst/elements/gstaudiosrc.h b/gst/elements/gstaudiosrc.h deleted file mode 100644 index b4bbfc09ef..0000000000 --- a/gst/elements/gstaudiosrc.h +++ /dev/null @@ -1,95 +0,0 @@ -/* GStreamer - * Copyright (C) 1999,2000 Erik Walthinsen - * 2000 Wim Taymans - * - * gstaudiosrc.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_AUDIOSRC_H__ -#define __GST_AUDIOSRC_H__ - - -#include -#include -#include - - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - - -GstElementDetails gst_audiosrc_details; - - -#define GST_TYPE_AUDIOSRC \ - (gst_audiosrc_get_type()) -#define GST_AUDIOSRC(obj) \ - (GTK_CHECK_CAST((obj),GST_TYPE_AUDIOSRC,GstAudioSrc)) -#define GST_AUDIOSRC_CLASS(klass) \ - (GTK_CHECK_CLASS_CAST((klass),GST_TYPE_AUDIOSRC,GstAudioSrcClass)) -#define GST_IS_AUDIOSRC(obj) \ - (GTK_CHECK_TYPE((obj),GST_TYPE_AUDIOSRC)) -#define GST_IS_AUDIOSRC_CLASS(obj) \ - (GTK_CHECK_CLASS_TYPE((klass),GST_TYPE_AUDIOSRC)) - -typedef enum { - GST_AUDIOSRC_OPEN = GST_ELEMENT_FLAG_LAST, - - GST_AUDIOSRC_FLAG_LAST = GST_ELEMENT_FLAG_LAST+2, -} GstAudioSrcFlags; - -typedef struct _GstAudioSrc GstAudioSrc; -typedef struct _GstAudioSrcClass GstAudioSrcClass; - -struct _GstAudioSrc { - GstElement element; - - /* pads */ - GstPad *srcpad; - - /* sound card */ - gint fd; - - /* audio parameters */ - gint format; - gint channels; - gint frequency; - - /* blocking */ - gulong curoffset; - gulong bytes_per_read; - - gulong seq; - - MetaAudioRaw *meta; -}; - -struct _GstAudioSrcClass { - GstElementClass parent_class; -}; - -GtkType gst_audiosrc_get_type(void); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - - -#endif /* __GST_AUDIOSRC_H__ */ diff --git a/gst/elements/gstdisksrc.c b/gst/elements/gstdisksrc.c index 94f1a162a7..9e81eb9b73 100644 --- a/gst/elements/gstdisksrc.c +++ b/gst/elements/gstdisksrc.c @@ -2,7 +2,7 @@ * Copyright (C) 1999,2000 Erik Walthinsen * 2000 Wim Taymans * - * gstdisksrc.c: + * gstdisksrc.c: * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -32,7 +32,7 @@ GstElementDetails gst_disksrc_details = { - "hronous Disk Source", + "Disk Source", "Source/File", "Read from arbitrary point in a file", VERSION, @@ -56,23 +56,23 @@ enum { }; -static void gst_disksrc_class_init (GstDiskSrcClass *klass); -static void gst_disksrc_init (GstDiskSrc *disksrc); +static void gst_disksrc_class_init (GstDiskSrcClass *klass); +static void gst_disksrc_init (GstDiskSrc *disksrc); -static void gst_disksrc_set_arg (GtkObject *object, GtkArg *arg, guint id); -static void gst_disksrc_get_arg (GtkObject *object, GtkArg *arg, guint id); +static void gst_disksrc_set_arg (GtkObject *object, GtkArg *arg, guint id); +static void gst_disksrc_get_arg (GtkObject *object, GtkArg *arg, guint id); static GstBuffer * gst_disksrc_get (GstPad *pad); static GstBuffer * gst_disksrc_get_region (GstPad *pad,GstRegionType type,guint64 offset,guint64 len); -static GstElementStateReturn gst_disksrc_change_state (GstElement *element); +static GstElementStateReturn gst_disksrc_change_state (GstElement *element); static GstElementClass *parent_class = NULL; //static guint gst_disksrc_signals[LAST_SIGNAL] = { 0 }; GtkType -gst_disksrc_get_type(void) +gst_disksrc_get_type(void) { static GtkType disksrc_type = 0; @@ -93,7 +93,7 @@ gst_disksrc_get_type(void) } static void -gst_disksrc_class_init (GstDiskSrcClass *klass) +gst_disksrc_class_init (GstDiskSrcClass *klass) { GtkObjectClass *gtkobject_class; GstElementClass *gstelement_class; @@ -118,8 +118,8 @@ gst_disksrc_class_init (GstDiskSrcClass *klass) gstelement_class->change_state = gst_disksrc_change_state; } -static void -gst_disksrc_init (GstDiskSrc *disksrc) +static void +gst_disksrc_init (GstDiskSrc *disksrc) { // GST_FLAG_SET (disksrc, GST_SRC_); @@ -139,14 +139,14 @@ gst_disksrc_init (GstDiskSrc *disksrc) } -static void -gst_disksrc_set_arg (GtkObject *object, GtkArg *arg, guint id) +static void +gst_disksrc_set_arg (GtkObject *object, GtkArg *arg, guint id) { GstDiskSrc *src; /* it's not null if we got it, but it might not be ours */ g_return_if_fail (GST_IS_DISKSRC (object)); - + src = GST_DISKSRC (object); switch(id) { @@ -176,14 +176,14 @@ gst_disksrc_set_arg (GtkObject *object, GtkArg *arg, guint id) } } -static void -gst_disksrc_get_arg (GtkObject *object, GtkArg *arg, guint id) +static void +gst_disksrc_get_arg (GtkObject *object, GtkArg *arg, guint id) { GstDiskSrc *src; /* it's not null if we got it, but it might not be ours */ g_return_if_fail (GST_IS_DISKSRC (object)); - + src = GST_DISKSRC (object); switch (id) { @@ -212,7 +212,7 @@ gst_disksrc_get_arg (GtkObject *object, GtkArg *arg, guint id) * Push a new buffer from the disksrc at the current offset. */ static GstBuffer * -gst_disksrc_get (GstPad *pad) +gst_disksrc_get (GstPad *pad) { GstDiskSrc *src; GstBuffer *buf; @@ -223,7 +223,7 @@ gst_disksrc_get (GstPad *pad) /* deal with EOF state */ if (src->curoffset >= src->size) { - gst_element_signal_eos (GST_ELEMENT (src)); + gst_pad_set_eos (pad); return NULL; } @@ -269,7 +269,7 @@ gst_disksrc_get (GstPad *pad) * Push a new buffer from the disksrc of given size at given offset. */ static GstBuffer * -gst_disksrc_get_region (GstPad *pad, GstRegionType type,guint64 offset,guint64 len) +gst_disksrc_get_region (GstPad *pad, GstRegionType type,guint64 offset,guint64 len) { GstDiskSrc *src; GstBuffer *buf; @@ -281,10 +281,10 @@ gst_disksrc_get_region (GstPad *pad, GstRegionType type,guint64 offset,guint64 l g_return_val_if_fail (GST_IS_DISKSRC (src), NULL); g_return_val_if_fail (GST_FLAG_IS_SET (src, GST_DISKSRC_OPEN), NULL); - + /* deal with EOF state */ if (offset >= src->size) { - gst_element_signal_eos (GST_ELEMENT (src)); + gst_pad_set_eos (pad); return NULL; } @@ -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); @@ -343,8 +343,8 @@ gboolean gst_disksrc_open_file (GstDiskSrc *src) } /* unmap and close the file */ -static void -gst_disksrc_close_file (GstDiskSrc *src) +static void +gst_disksrc_close_file (GstDiskSrc *src) { g_return_if_fail (GST_FLAG_IS_SET (src, GST_DISKSRC_OPEN)); @@ -365,8 +365,8 @@ gst_disksrc_close_file (GstDiskSrc *src) } -static GstElementStateReturn -gst_disksrc_change_state (GstElement *element) +static GstElementStateReturn +gst_disksrc_change_state (GstElement *element) { g_return_val_if_fail (GST_IS_DISKSRC (element), GST_STATE_FAILURE); @@ -375,7 +375,7 @@ gst_disksrc_change_state (GstElement *element) gst_disksrc_close_file (GST_DISKSRC (element)); } else { if (!GST_FLAG_IS_SET (element, GST_DISKSRC_OPEN)) { - if (!gst_disksrc_open_file (GST_DISKSRC (element))) + if (!gst_disksrc_open_file (GST_DISKSRC (element))) return GST_STATE_FAILURE; } } diff --git a/gst/elements/gstelements.c b/gst/elements/gstelements.c index 294793df44..326d0e3aaf 100644 --- a/gst/elements/gstelements.c +++ b/gst/elements/gstelements.c @@ -2,7 +2,7 @@ * Copyright (C) 1999,2000 Erik Walthinsen * 2000 Wim Taymans * - * gstelements.c: + * gstelements.c: * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -23,14 +23,13 @@ #include -#include "gstaudiosink.h" -#include "gstaudiosrc.h" #include "gstdisksrc.h" #include "gstidentity.h" #include "gstfakesink.h" #include "gstfakesrc.h" #include "gstfdsink.h" #include "gstfdsrc.h" +#include "gstmultidisksrc.h" #include "gstpipefilter.h" #include "gstsinesrc.h" #include "gsttee.h" @@ -50,25 +49,23 @@ struct _elements_entry { static struct _elements_entry _elements[] = { { "fakesrc", gst_fakesrc_get_type, &gst_fakesrc_details, NULL }, { "fakesink", gst_fakesink_get_type, &gst_fakesink_details, NULL }, - { "asyncdisksrc", gst_disksrc_get_type, &gst_disksrc_details, NULL }, - { "audiosink", gst_audiosink_get_type, &gst_audiosink_details, gst_audiosink_factory_init }, - { "audiosrc", gst_audiosrc_get_type, &gst_audiosrc_details, NULL }, { "disksrc", gst_disksrc_get_type, &gst_disksrc_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 }, + { "multidisksrc", gst_multidisksrc_get_type, &gst_multidisksrc_details, NULL }, { "pipefilter", gst_pipefilter_get_type, &gst_pipefilter_details, NULL }, { "sinesrc", gst_sinesrc_get_type, &gst_sinesrc_details, NULL }, { "tee", gst_tee_get_type, &gst_tee_details, gst_tee_factory_init }, #if HAVE_LIBGHTTP - { "httpsrc", gst_httpsrc_get_type, &gst_httpsrc_details, NULL }, + { "httpsrc", gst_httpsrc_get_type, &gst_httpsrc_details, NULL }, #endif /* HAVE_LIBGHTTP */ - + { NULL, 0 }, }; -GstPlugin *plugin_init (GModule *module) +GstPlugin *plugin_init (GModule *module) { GstPlugin *plugin; GstElementFactory *factory; diff --git a/gst/elements/gstmultidisksrc.c b/gst/elements/gstmultidisksrc.c new file mode 100644 index 0000000000..726aed976f --- /dev/null +++ b/gst/elements/gstmultidisksrc.c @@ -0,0 +1,305 @@ +/* GStreamer + * Copyright (C) 1999,2000 Erik Walthinsen + * 2000 Wim Taymans + * 2001 Dominic Ludlam + * + * gstmultidisksrc.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 +#include +#include +#include +#include + +//#define GST_DEBUG_ENABLED + +#include "gstmultidisksrc.h" + +GstElementDetails gst_multidisksrc_details = { + "Multi Disk Source", + "Source/File", + "Read from multiple files in order", + VERSION, + "Dominic Ludlam ", + "(C) 2001", +}; + +/* DiskSrc signals and args */ +enum { + NEW_FILE, + LAST_SIGNAL +}; + +enum { + ARG_0, + ARG_LOCATIONS, +}; + +static void gst_multidisksrc_class_init (GstMultiDiskSrcClass *klass); +static void gst_multidisksrc_init (GstMultiDiskSrc *disksrc); + +static void gst_multidisksrc_set_arg (GtkObject *object, GtkArg *arg, guint id); +static void gst_multidisksrc_get_arg (GtkObject *object, GtkArg *arg, guint id); + +static GstBuffer * gst_multidisksrc_get (GstPad *pad); +//static GstBuffer * gst_multidisksrc_get_region (GstPad *pad,GstRegionType type,guint64 offset,guint64 len); + +static GstElementStateReturn gst_multidisksrc_change_state (GstElement *element); + +static gboolean gst_multidisksrc_open_file (GstMultiDiskSrc *src, GstPad *srcpad); +static void gst_multidisksrc_close_file (GstMultiDiskSrc *src); + +static GstElementClass *parent_class = NULL; +static guint gst_multidisksrc_signals[LAST_SIGNAL] = { 0 }; + +GtkType +gst_multidisksrc_get_type(void) +{ + static GtkType multidisksrc_type = 0; + + if (!multidisksrc_type) { + static const GtkTypeInfo multidisksrc_info = { + "GstMultiDiskSrc", + sizeof(GstMultiDiskSrc), + sizeof(GstMultiDiskSrcClass), + (GtkClassInitFunc)gst_multidisksrc_class_init, + (GtkObjectInitFunc)gst_multidisksrc_init, + (GtkArgSetFunc)gst_multidisksrc_set_arg, + (GtkArgGetFunc)gst_multidisksrc_get_arg, + (GtkClassInitFunc)NULL, + }; + multidisksrc_type = gtk_type_unique (GST_TYPE_ELEMENT, &multidisksrc_info); + } + return multidisksrc_type; +} + +static void +gst_multidisksrc_class_init (GstMultiDiskSrcClass *klass) +{ + GtkObjectClass *gtkobject_class; + GstElementClass *gstelement_class; + + gtkobject_class = (GtkObjectClass*)klass; + gstelement_class = (GstElementClass*)klass; + + parent_class = gtk_type_class (GST_TYPE_ELEMENT); + + gst_multidisksrc_signals[NEW_FILE] = + gtk_signal_new ("new_file", GTK_RUN_LAST, gtkobject_class->type, + GTK_SIGNAL_OFFSET (GstMultiDiskSrcClass, new_file), + gtk_marshal_NONE__POINTER, GTK_TYPE_NONE, 1, + GTK_TYPE_POINTER); + gtk_object_class_add_signals (gtkobject_class, gst_multidisksrc_signals, LAST_SIGNAL); + + gtk_object_add_arg_type ("GstMultiDiskSrc::locations", GTK_TYPE_POINTER, + GTK_ARG_READWRITE, ARG_LOCATIONS); + + gtkobject_class->set_arg = gst_multidisksrc_set_arg; + gtkobject_class->get_arg = gst_multidisksrc_get_arg; + + gstelement_class->change_state = gst_multidisksrc_change_state; +} + +static void +gst_multidisksrc_init (GstMultiDiskSrc *multidisksrc) +{ +// GST_FLAG_SET (disksrc, GST_SRC_); + + multidisksrc->srcpad = gst_pad_new ("src", GST_PAD_SRC); + gst_pad_set_get_function (multidisksrc->srcpad,gst_multidisksrc_get); +// gst_pad_set_getregion_function (multidisksrc->srcpad,gst_multidisksrc_get_region); + gst_element_add_pad (GST_ELEMENT (multidisksrc), multidisksrc->srcpad); + + multidisksrc->listptr = NULL; + multidisksrc->currentfilename = NULL; + multidisksrc->fd = 0; + multidisksrc->size = 0; + multidisksrc->map = NULL; + multidisksrc->new_seek = FALSE; +} + +static void +gst_multidisksrc_set_arg (GtkObject *object, GtkArg *arg, guint id) +{ + GstMultiDiskSrc *src; + + /* it's not null if we got it, but it might not be ours */ + g_return_if_fail (GST_IS_MULTIDISKSRC (object)); + + src = GST_MULTIDISKSRC (object); + + switch(id) { + case ARG_LOCATIONS: + /* the element must be stopped in order to do this */ + g_return_if_fail (GST_STATE (src) < GST_STATE_PLAYING); + + /* clear the filename if we get a NULL */ + if (GTK_VALUE_POINTER (*arg) == NULL) { + gst_element_set_state (GST_ELEMENT (object), GST_STATE_NULL); + src->listptr = NULL; + /* otherwise set the new filenames */ + } else { + src->listptr = GTK_VALUE_POINTER(*arg); + } + break; + default: + break; + } +} + +static void +gst_multidisksrc_get_arg (GtkObject *object, GtkArg *arg, guint id) +{ + GstMultiDiskSrc *src; + + /* it's not null if we got it, but it might not be ours */ + g_return_if_fail (GST_IS_MULTIDISKSRC (object)); + + src = GST_MULTIDISKSRC (object); + + switch (id) { + case ARG_LOCATIONS: + GTK_VALUE_POINTER (*arg) = src->listptr; + break; + default: + arg->type = GTK_TYPE_INVALID; + break; + } +} + +/** + * gst_disksrc_get: + * @pad: #GstPad to push a buffer from + * + * Push a new buffer from the disksrc at the current offset. + */ +static GstBuffer * +gst_multidisksrc_get (GstPad *pad) +{ + GstMultiDiskSrc *src; + GstBuffer *buf; + GSList *list; + + g_return_val_if_fail (pad != NULL, NULL); + src = GST_MULTIDISKSRC (gst_pad_get_parent (pad)); + + if (GST_FLAG_IS_SET (src, GST_MULTIDISKSRC_OPEN)) + gst_multidisksrc_close_file(src); + + if (!src->listptr) { + gst_pad_set_eos(pad); + return FALSE; + } + + list = src->listptr; + src->currentfilename = (gchar *) list->data; + src->listptr = src->listptr->next; + + if (!gst_multidisksrc_open_file(src, pad)) + return NULL; + + // emitted after the open, as the user may free the list and string from here + gtk_signal_emit(GTK_OBJECT(src), gst_multidisksrc_signals[NEW_FILE], list); + + /* create the buffer */ + // FIXME: should eventually use a bufferpool for this + buf = gst_buffer_new (); + + g_return_val_if_fail (buf != NULL, NULL); + + /* simply set the buffer to point to the correct region of the file */ + GST_BUFFER_DATA (buf) = src->map; + GST_BUFFER_OFFSET (buf) = 0; + GST_BUFFER_FLAG_SET (buf, GST_BUFFER_DONTFREE); + + if (src->new_seek) { + GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLUSH); + src->new_seek = FALSE; + } + + /* we're done, return the buffer */ + return buf; +} + +/* open the file and mmap it, necessary to go to READY state */ +static +gboolean gst_multidisksrc_open_file (GstMultiDiskSrc *src, GstPad *srcpad) +{ + g_return_val_if_fail (!GST_FLAG_IS_SET (src, GST_MULTIDISKSRC_OPEN), FALSE); + + /* open the file */ + src->fd = open ((const char *) src->currentfilename, O_RDONLY); + + if (src->fd < 0) { + perror ("open"); + gst_element_error (GST_ELEMENT (src), g_strconcat("opening file \"", src->currentfilename, "\"", NULL)); + return FALSE; + } else { + /* find the file length */ + src->size = lseek (src->fd, 0, SEEK_END); + lseek (src->fd, 0, SEEK_SET); + /* map the file into memory */ + src->map = mmap (NULL, src->size, PROT_READ, MAP_SHARED, src->fd, 0); + madvise (src->map,src->size, 2); + /* collapse state if that failed */ + if (src->map == NULL) { + close (src->fd); + gst_element_error (GST_ELEMENT (src),"mmapping file"); + return FALSE; + } + GST_FLAG_SET (src, GST_MULTIDISKSRC_OPEN); + src->new_seek = TRUE; + } + return TRUE; +} + +/* unmap and close the file */ +static void +gst_multidisksrc_close_file (GstMultiDiskSrc *src) +{ + g_return_if_fail (GST_FLAG_IS_SET (src, GST_MULTIDISKSRC_OPEN)); + + /* unmap the file from memory and close the file */ + munmap (src->map, src->size); + close (src->fd); + + /* zero out a lot of our state */ + src->fd = 0; + src->size = 0; + src->map = NULL; + src->new_seek = FALSE; + + GST_FLAG_UNSET (src, GST_MULTIDISKSRC_OPEN); +} + +static GstElementStateReturn +gst_multidisksrc_change_state (GstElement *element) +{ + g_return_val_if_fail (GST_IS_MULTIDISKSRC (element), GST_STATE_FAILURE); + + if (GST_STATE_PENDING (element) == GST_STATE_NULL) { + if (GST_FLAG_IS_SET (element, GST_MULTIDISKSRC_OPEN)) + gst_multidisksrc_close_file (GST_MULTIDISKSRC (element)); + } + + if (GST_ELEMENT_CLASS (parent_class)->change_state) + return GST_ELEMENT_CLASS (parent_class)->change_state (element); + + return GST_STATE_SUCCESS; +} diff --git a/gst/elements/gstmultidisksrc.h b/gst/elements/gstmultidisksrc.h new file mode 100644 index 0000000000..ed4a94c969 --- /dev/null +++ b/gst/elements/gstmultidisksrc.h @@ -0,0 +1,84 @@ +/* GStreamer + * Copyright (C) 1999,2000 Erik Walthinsen + * 2000 Wim Taymans + * 2001 Dominic Ludlam + * + * gstmultidisksrc.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_MULTIDISKSRC_H__ +#define __GST_MULTIDISKSRC_H__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +GstElementDetails gst_multidisksrc_details; + +#define GST_TYPE_MULTIDISKSRC \ + (gst_multidisksrc_get_type()) +#define GST_MULTIDISKSRC(obj) \ + (GTK_CHECK_CAST((obj),GST_TYPE_MULTIDISKSRC,GstMultiDiskSrc)) +#define GST_MULTIDISKSRC_CLASS(klass) \ + (GTK_CHECK_CLASS_CAST((klass),GST_TYPE_MULTIDISKSRC,GstMultiDiskSrcClass)) +#define GST_IS_MULTIDISKSRC(obj) \ + (GTK_CHECK_TYPE((obj),GST_TYPE_MULTIDISKSRC)) +#define GST_IS_MULTIDISKSRC_CLASS(obj) \ + (GTK_CHECK_CLASS_TYPE((klass),GST_TYPE_MULTIDISKSRC)) + +typedef enum { + GST_MULTIDISKSRC_OPEN = GST_ELEMENT_FLAG_LAST, + + GST_MULTIDISKSRC_FLAG_LAST = GST_ELEMENT_FLAG_LAST + 2, +} GstMultiDiskSrcFlags; + +typedef struct _GstMultiDiskSrc GstMultiDiskSrc; +typedef struct _GstMultiDiskSrcClass GstMultiDiskSrcClass; + +struct _GstMultiDiskSrc { + GstElement element; + /* pads */ + GstPad *srcpad; + + /* current file details */ + gchar *currentfilename; + GSList *listptr; + + /* mapping parameters */ + gint fd; + gulong size; /* how long is the file? */ + guchar *map; /* where the file is mapped to */ + + gboolean new_seek; +}; + +struct _GstMultiDiskSrcClass { + GstElementClass parent_class; + + void (*new_file) (GstMultiDiskSrc *multidisksrc, gchar *newfilename); +}; + +GtkType gst_multidisksrc_get_type(void); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* __GST_MULTIDISKSRC_H__ */ diff --git a/gst/elements/gstmultifilesrc.c b/gst/elements/gstmultifilesrc.c new file mode 100644 index 0000000000..726aed976f --- /dev/null +++ b/gst/elements/gstmultifilesrc.c @@ -0,0 +1,305 @@ +/* GStreamer + * Copyright (C) 1999,2000 Erik Walthinsen + * 2000 Wim Taymans + * 2001 Dominic Ludlam + * + * gstmultidisksrc.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 +#include +#include +#include +#include + +//#define GST_DEBUG_ENABLED + +#include "gstmultidisksrc.h" + +GstElementDetails gst_multidisksrc_details = { + "Multi Disk Source", + "Source/File", + "Read from multiple files in order", + VERSION, + "Dominic Ludlam ", + "(C) 2001", +}; + +/* DiskSrc signals and args */ +enum { + NEW_FILE, + LAST_SIGNAL +}; + +enum { + ARG_0, + ARG_LOCATIONS, +}; + +static void gst_multidisksrc_class_init (GstMultiDiskSrcClass *klass); +static void gst_multidisksrc_init (GstMultiDiskSrc *disksrc); + +static void gst_multidisksrc_set_arg (GtkObject *object, GtkArg *arg, guint id); +static void gst_multidisksrc_get_arg (GtkObject *object, GtkArg *arg, guint id); + +static GstBuffer * gst_multidisksrc_get (GstPad *pad); +//static GstBuffer * gst_multidisksrc_get_region (GstPad *pad,GstRegionType type,guint64 offset,guint64 len); + +static GstElementStateReturn gst_multidisksrc_change_state (GstElement *element); + +static gboolean gst_multidisksrc_open_file (GstMultiDiskSrc *src, GstPad *srcpad); +static void gst_multidisksrc_close_file (GstMultiDiskSrc *src); + +static GstElementClass *parent_class = NULL; +static guint gst_multidisksrc_signals[LAST_SIGNAL] = { 0 }; + +GtkType +gst_multidisksrc_get_type(void) +{ + static GtkType multidisksrc_type = 0; + + if (!multidisksrc_type) { + static const GtkTypeInfo multidisksrc_info = { + "GstMultiDiskSrc", + sizeof(GstMultiDiskSrc), + sizeof(GstMultiDiskSrcClass), + (GtkClassInitFunc)gst_multidisksrc_class_init, + (GtkObjectInitFunc)gst_multidisksrc_init, + (GtkArgSetFunc)gst_multidisksrc_set_arg, + (GtkArgGetFunc)gst_multidisksrc_get_arg, + (GtkClassInitFunc)NULL, + }; + multidisksrc_type = gtk_type_unique (GST_TYPE_ELEMENT, &multidisksrc_info); + } + return multidisksrc_type; +} + +static void +gst_multidisksrc_class_init (GstMultiDiskSrcClass *klass) +{ + GtkObjectClass *gtkobject_class; + GstElementClass *gstelement_class; + + gtkobject_class = (GtkObjectClass*)klass; + gstelement_class = (GstElementClass*)klass; + + parent_class = gtk_type_class (GST_TYPE_ELEMENT); + + gst_multidisksrc_signals[NEW_FILE] = + gtk_signal_new ("new_file", GTK_RUN_LAST, gtkobject_class->type, + GTK_SIGNAL_OFFSET (GstMultiDiskSrcClass, new_file), + gtk_marshal_NONE__POINTER, GTK_TYPE_NONE, 1, + GTK_TYPE_POINTER); + gtk_object_class_add_signals (gtkobject_class, gst_multidisksrc_signals, LAST_SIGNAL); + + gtk_object_add_arg_type ("GstMultiDiskSrc::locations", GTK_TYPE_POINTER, + GTK_ARG_READWRITE, ARG_LOCATIONS); + + gtkobject_class->set_arg = gst_multidisksrc_set_arg; + gtkobject_class->get_arg = gst_multidisksrc_get_arg; + + gstelement_class->change_state = gst_multidisksrc_change_state; +} + +static void +gst_multidisksrc_init (GstMultiDiskSrc *multidisksrc) +{ +// GST_FLAG_SET (disksrc, GST_SRC_); + + multidisksrc->srcpad = gst_pad_new ("src", GST_PAD_SRC); + gst_pad_set_get_function (multidisksrc->srcpad,gst_multidisksrc_get); +// gst_pad_set_getregion_function (multidisksrc->srcpad,gst_multidisksrc_get_region); + gst_element_add_pad (GST_ELEMENT (multidisksrc), multidisksrc->srcpad); + + multidisksrc->listptr = NULL; + multidisksrc->currentfilename = NULL; + multidisksrc->fd = 0; + multidisksrc->size = 0; + multidisksrc->map = NULL; + multidisksrc->new_seek = FALSE; +} + +static void +gst_multidisksrc_set_arg (GtkObject *object, GtkArg *arg, guint id) +{ + GstMultiDiskSrc *src; + + /* it's not null if we got it, but it might not be ours */ + g_return_if_fail (GST_IS_MULTIDISKSRC (object)); + + src = GST_MULTIDISKSRC (object); + + switch(id) { + case ARG_LOCATIONS: + /* the element must be stopped in order to do this */ + g_return_if_fail (GST_STATE (src) < GST_STATE_PLAYING); + + /* clear the filename if we get a NULL */ + if (GTK_VALUE_POINTER (*arg) == NULL) { + gst_element_set_state (GST_ELEMENT (object), GST_STATE_NULL); + src->listptr = NULL; + /* otherwise set the new filenames */ + } else { + src->listptr = GTK_VALUE_POINTER(*arg); + } + break; + default: + break; + } +} + +static void +gst_multidisksrc_get_arg (GtkObject *object, GtkArg *arg, guint id) +{ + GstMultiDiskSrc *src; + + /* it's not null if we got it, but it might not be ours */ + g_return_if_fail (GST_IS_MULTIDISKSRC (object)); + + src = GST_MULTIDISKSRC (object); + + switch (id) { + case ARG_LOCATIONS: + GTK_VALUE_POINTER (*arg) = src->listptr; + break; + default: + arg->type = GTK_TYPE_INVALID; + break; + } +} + +/** + * gst_disksrc_get: + * @pad: #GstPad to push a buffer from + * + * Push a new buffer from the disksrc at the current offset. + */ +static GstBuffer * +gst_multidisksrc_get (GstPad *pad) +{ + GstMultiDiskSrc *src; + GstBuffer *buf; + GSList *list; + + g_return_val_if_fail (pad != NULL, NULL); + src = GST_MULTIDISKSRC (gst_pad_get_parent (pad)); + + if (GST_FLAG_IS_SET (src, GST_MULTIDISKSRC_OPEN)) + gst_multidisksrc_close_file(src); + + if (!src->listptr) { + gst_pad_set_eos(pad); + return FALSE; + } + + list = src->listptr; + src->currentfilename = (gchar *) list->data; + src->listptr = src->listptr->next; + + if (!gst_multidisksrc_open_file(src, pad)) + return NULL; + + // emitted after the open, as the user may free the list and string from here + gtk_signal_emit(GTK_OBJECT(src), gst_multidisksrc_signals[NEW_FILE], list); + + /* create the buffer */ + // FIXME: should eventually use a bufferpool for this + buf = gst_buffer_new (); + + g_return_val_if_fail (buf != NULL, NULL); + + /* simply set the buffer to point to the correct region of the file */ + GST_BUFFER_DATA (buf) = src->map; + GST_BUFFER_OFFSET (buf) = 0; + GST_BUFFER_FLAG_SET (buf, GST_BUFFER_DONTFREE); + + if (src->new_seek) { + GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLUSH); + src->new_seek = FALSE; + } + + /* we're done, return the buffer */ + return buf; +} + +/* open the file and mmap it, necessary to go to READY state */ +static +gboolean gst_multidisksrc_open_file (GstMultiDiskSrc *src, GstPad *srcpad) +{ + g_return_val_if_fail (!GST_FLAG_IS_SET (src, GST_MULTIDISKSRC_OPEN), FALSE); + + /* open the file */ + src->fd = open ((const char *) src->currentfilename, O_RDONLY); + + if (src->fd < 0) { + perror ("open"); + gst_element_error (GST_ELEMENT (src), g_strconcat("opening file \"", src->currentfilename, "\"", NULL)); + return FALSE; + } else { + /* find the file length */ + src->size = lseek (src->fd, 0, SEEK_END); + lseek (src->fd, 0, SEEK_SET); + /* map the file into memory */ + src->map = mmap (NULL, src->size, PROT_READ, MAP_SHARED, src->fd, 0); + madvise (src->map,src->size, 2); + /* collapse state if that failed */ + if (src->map == NULL) { + close (src->fd); + gst_element_error (GST_ELEMENT (src),"mmapping file"); + return FALSE; + } + GST_FLAG_SET (src, GST_MULTIDISKSRC_OPEN); + src->new_seek = TRUE; + } + return TRUE; +} + +/* unmap and close the file */ +static void +gst_multidisksrc_close_file (GstMultiDiskSrc *src) +{ + g_return_if_fail (GST_FLAG_IS_SET (src, GST_MULTIDISKSRC_OPEN)); + + /* unmap the file from memory and close the file */ + munmap (src->map, src->size); + close (src->fd); + + /* zero out a lot of our state */ + src->fd = 0; + src->size = 0; + src->map = NULL; + src->new_seek = FALSE; + + GST_FLAG_UNSET (src, GST_MULTIDISKSRC_OPEN); +} + +static GstElementStateReturn +gst_multidisksrc_change_state (GstElement *element) +{ + g_return_val_if_fail (GST_IS_MULTIDISKSRC (element), GST_STATE_FAILURE); + + if (GST_STATE_PENDING (element) == GST_STATE_NULL) { + if (GST_FLAG_IS_SET (element, GST_MULTIDISKSRC_OPEN)) + gst_multidisksrc_close_file (GST_MULTIDISKSRC (element)); + } + + if (GST_ELEMENT_CLASS (parent_class)->change_state) + return GST_ELEMENT_CLASS (parent_class)->change_state (element); + + return GST_STATE_SUCCESS; +} diff --git a/gst/elements/gstmultifilesrc.h b/gst/elements/gstmultifilesrc.h new file mode 100644 index 0000000000..ed4a94c969 --- /dev/null +++ b/gst/elements/gstmultifilesrc.h @@ -0,0 +1,84 @@ +/* GStreamer + * Copyright (C) 1999,2000 Erik Walthinsen + * 2000 Wim Taymans + * 2001 Dominic Ludlam + * + * gstmultidisksrc.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_MULTIDISKSRC_H__ +#define __GST_MULTIDISKSRC_H__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +GstElementDetails gst_multidisksrc_details; + +#define GST_TYPE_MULTIDISKSRC \ + (gst_multidisksrc_get_type()) +#define GST_MULTIDISKSRC(obj) \ + (GTK_CHECK_CAST((obj),GST_TYPE_MULTIDISKSRC,GstMultiDiskSrc)) +#define GST_MULTIDISKSRC_CLASS(klass) \ + (GTK_CHECK_CLASS_CAST((klass),GST_TYPE_MULTIDISKSRC,GstMultiDiskSrcClass)) +#define GST_IS_MULTIDISKSRC(obj) \ + (GTK_CHECK_TYPE((obj),GST_TYPE_MULTIDISKSRC)) +#define GST_IS_MULTIDISKSRC_CLASS(obj) \ + (GTK_CHECK_CLASS_TYPE((klass),GST_TYPE_MULTIDISKSRC)) + +typedef enum { + GST_MULTIDISKSRC_OPEN = GST_ELEMENT_FLAG_LAST, + + GST_MULTIDISKSRC_FLAG_LAST = GST_ELEMENT_FLAG_LAST + 2, +} GstMultiDiskSrcFlags; + +typedef struct _GstMultiDiskSrc GstMultiDiskSrc; +typedef struct _GstMultiDiskSrcClass GstMultiDiskSrcClass; + +struct _GstMultiDiskSrc { + GstElement element; + /* pads */ + GstPad *srcpad; + + /* current file details */ + gchar *currentfilename; + GSList *listptr; + + /* mapping parameters */ + gint fd; + gulong size; /* how long is the file? */ + guchar *map; /* where the file is mapped to */ + + gboolean new_seek; +}; + +struct _GstMultiDiskSrcClass { + GstElementClass parent_class; + + void (*new_file) (GstMultiDiskSrc *multidisksrc, gchar *newfilename); +}; + +GtkType gst_multidisksrc_get_type(void); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* __GST_MULTIDISKSRC_H__ */ diff --git a/gst/elements/gstsinesrc.c b/gst/elements/gstsinesrc.c index 5e47d279c8..5a4e4abe57 100644 --- a/gst/elements/gstsinesrc.c +++ b/gst/elements/gstsinesrc.c @@ -1,6 +1,7 @@ /* GStreamer * Copyright (C) 1999,2000 Erik Walthinsen * 2000 Wim Taymans + * 2001 Steve Baker * * gstsinesrc.c: * @@ -20,10 +21,6 @@ * Boston, MA 02111-1307, USA. */ -#include -#include -#include -#include #include #include #include @@ -51,20 +48,25 @@ enum { ARG_0, ARG_VOLUME, ARG_FORMAT, - ARG_CHANNELS, - ARG_FREQUENCY, + ARG_SAMPLERATE, + ARG_FREQ, + ARG_TABLESIZE, + ARG_BUFFER_SIZE, }; static void gst_sinesrc_class_init(GstSineSrcClass *klass); -static void gst_sinesrc_init(GstSineSrc *sinesrc); +static void gst_sinesrc_init(GstSineSrc *src); static void gst_sinesrc_set_arg(GtkObject *object,GtkArg *arg,guint id); static void gst_sinesrc_get_arg(GtkObject *object,GtkArg *arg,guint id); //static gboolean gst_sinesrc_change_state(GstElement *element, // GstElementState state); //static void gst_sinesrc_close_audio(GstSineSrc *src); //static gboolean gst_sinesrc_open_audio(GstSineSrc *src); -void gst_sinesrc_sync_parms(GstSineSrc *sinesrc); +static void gst_sinesrc_populate_sinetable(GstSineSrc *src); +static inline void gst_sinesrc_update_table_inc(GstSineSrc *src); +static inline void gst_sinesrc_update_vol_scale(GstSineSrc *src); +void gst_sinesrc_sync_parms(GstSineSrc *src); static GstBuffer * gst_sinesrc_get(GstPad *pad); @@ -105,31 +107,44 @@ gst_sinesrc_class_init(GstSineSrcClass *klass) { GTK_ARG_READWRITE, ARG_VOLUME); gtk_object_add_arg_type("GstSineSrc::format", GTK_TYPE_INT, GTK_ARG_READWRITE, ARG_FORMAT); - gtk_object_add_arg_type("GstSineSrc::channels", GTK_TYPE_INT, - GTK_ARG_READWRITE, ARG_CHANNELS); - gtk_object_add_arg_type("GstSineSrc::frequency", GTK_TYPE_INT, - GTK_ARG_READWRITE, ARG_FREQUENCY); - + gtk_object_add_arg_type("GstSineSrc::samplerate", GTK_TYPE_INT, + GTK_ARG_READWRITE, ARG_SAMPLERATE); + gtk_object_add_arg_type("GstSineSrc::tablesize", GTK_TYPE_INT, + GTK_ARG_READWRITE, ARG_TABLESIZE); + gtk_object_add_arg_type("GstSineSrc::freq", GTK_TYPE_DOUBLE, + GTK_ARG_READWRITE, ARG_FREQ); + gtk_object_add_arg_type("GstSineSrc::buffersize", GTK_TYPE_INT, + GTK_ARG_READWRITE, ARG_BUFFER_SIZE); + gtkobject_class->set_arg = gst_sinesrc_set_arg; gtkobject_class->get_arg = gst_sinesrc_get_arg; // gstelement_class->change_state = gst_sinesrc_change_state; } -static void gst_sinesrc_init(GstSineSrc *sinesrc) { - sinesrc->srcpad = gst_pad_new("src",GST_PAD_SRC); - gst_pad_set_get_function(sinesrc->srcpad,gst_sinesrc_get); - gst_element_add_pad(GST_ELEMENT(sinesrc),sinesrc->srcpad); +static void gst_sinesrc_init(GstSineSrc *src) { + + src->srcpad = gst_pad_new("src",GST_PAD_SRC); + gst_pad_set_get_function(src->srcpad, gst_sinesrc_get); + gst_element_add_pad(GST_ELEMENT(src), src->srcpad); - sinesrc->volume = 1.0; + src->volume = 1.0; + gst_sinesrc_update_vol_scale(src); - sinesrc->format = AFMT_S16_LE; - sinesrc->channels = 2; - sinesrc->frequency = 44100; + src->format = 16; + src->samplerate = 44100; + src->freq = 100.0; + src->newcaps = FALSE; + + src->table_pos = 0.0; + src->table_size = 1024; + gst_sinesrc_populate_sinetable(src); + gst_sinesrc_update_table_inc(src); + gst_sinesrc_sync_parms(src); + src->buffer_size=1024; + + src->seq = 0; - sinesrc->seq = 0; - - sinesrc->sentmeta = FALSE; } static GstBuffer * @@ -139,33 +154,50 @@ gst_sinesrc_get(GstPad *pad) GstBuffer *buf; gint16 *samples; gint i; - gint volume; - gdouble val; - + g_return_val_if_fail (pad != NULL, NULL); src = GST_SINESRC(gst_pad_get_parent (pad)); buf = gst_buffer_new(); g_return_val_if_fail (buf, NULL); - GST_BUFFER_DATA(buf) = (gpointer)malloc(4096); - samples = (gint16*)GST_BUFFER_DATA(buf); - GST_BUFFER_SIZE(buf) = 4096; + samples = g_new(gint16, src->buffer_size); + GST_BUFFER_DATA(buf) = (gpointer) samples; + GST_BUFFER_SIZE(buf) = 2 * src->buffer_size; + + for (i=0 ; i < src->buffer_size; i++) { + src->table_lookup = (gint)(src->table_pos); + src->table_lookup_next = src->table_lookup + 1; + src->table_interp = src->table_pos - src->table_lookup; + + // wrap the array lookups if we're out of bounds + if (src->table_lookup_next >= src->table_size){ + src->table_lookup_next -= src->table_size; + if (src->table_lookup >= src->table_size){ + src->table_lookup -= src->table_size; + src->table_pos -= src->table_size; + } + } + + src->table_pos += src->table_inc; - volume = 65535 * src->volume; - for (i=0;i<1024;i++) { - val = sin((gdouble)i/src->frequency); - samples[i] = val * volume; - samples[i+1] = samples[i]; + //no interpolation + //samples[i] = src->table_data[src->table_lookup] + // * src->vol_scale; + + //linear interpolation + samples[i] = ((src->table_interp + *(src->table_data[src->table_lookup_next] + -src->table_data[src->table_lookup] + ) + )+src->table_data[src->table_lookup] + )* src->vol_scale; } - if (!src->sentmeta) { - MetaAudioRaw *newmeta = g_new(MetaAudioRaw,1); - memcpy(newmeta,&src->meta,sizeof(MetaAudioRaw)); - gst_buffer_add_meta(buf,GST_META(newmeta)); - src->sentmeta = TRUE; + if (src->newcaps) { + src->newcaps = FALSE; } - g_print(">"); + //g_print(">"); return buf; } @@ -178,17 +210,35 @@ static void gst_sinesrc_set_arg(GtkObject *object,GtkArg *arg,guint id) { switch (id) { case ARG_VOLUME: + if (GTK_VALUE_DOUBLE(*arg) < 0.0 || GTK_VALUE_DOUBLE(*arg) > 1.0) + break; src->volume = GTK_VALUE_DOUBLE(*arg); + gst_sinesrc_update_vol_scale(src); break; case ARG_FORMAT: src->format = GTK_VALUE_INT(*arg); + gst_sinesrc_sync_parms(src); break; - case ARG_CHANNELS: - src->channels = GTK_VALUE_INT(*arg); + case ARG_SAMPLERATE: + src->samplerate = GTK_VALUE_INT(*arg); + gst_sinesrc_sync_parms(src); + gst_sinesrc_update_table_inc(src); break; - case ARG_FREQUENCY: - src->frequency = GTK_VALUE_INT(*arg); + case ARG_FREQ: { + if (GTK_VALUE_DOUBLE(*arg) <= 0.0 || GTK_VALUE_DOUBLE(*arg) > src->samplerate/2) + break; + src->freq = GTK_VALUE_DOUBLE(*arg); + gst_sinesrc_update_table_inc(src); break; + case ARG_TABLESIZE: + src->table_size = GTK_VALUE_INT(*arg); + gst_sinesrc_populate_sinetable(src); + gst_sinesrc_update_table_inc(src); + break; + case ARG_BUFFER_SIZE: + src->buffer_size = GTK_VALUE_INT(*arg); + break; + } default: break; } @@ -208,11 +258,17 @@ static void gst_sinesrc_get_arg(GtkObject *object,GtkArg *arg,guint id) { case ARG_FORMAT: GTK_VALUE_INT(*arg) = src->format; break; - case ARG_CHANNELS: - GTK_VALUE_INT(*arg) = src->channels; + case ARG_SAMPLERATE: + GTK_VALUE_INT(*arg) = src->samplerate; break; - case ARG_FREQUENCY: - GTK_VALUE_INT(*arg) = src->frequency; + case ARG_FREQ: + GTK_VALUE_DOUBLE(*arg) = src->freq; + break; + case ARG_TABLESIZE: + GTK_VALUE_INT(*arg) = src->table_size; + break; + case ARG_BUFFER_SIZE: + GTK_VALUE_INT(*arg) = src->buffer_size; break; default: arg->type = GTK_TYPE_INVALID; @@ -243,9 +299,30 @@ static gboolean gst_sinesrc_change_state(GstElement *element, } */ -void gst_sinesrc_sync_parms(GstSineSrc *sinesrc) { - sinesrc->meta.format = sinesrc->format; - sinesrc->meta.channels = sinesrc->channels; - sinesrc->meta.frequency = sinesrc->frequency; - sinesrc->sentmeta = FALSE; +static void gst_sinesrc_populate_sinetable(GstSineSrc *src) +{ + gint i; + gdouble pi2scaled = M_PI * 2 / src->table_size; + gfloat *table = g_new(gfloat, src->table_size); + + for(i=0 ; i < src->table_size ; i++){ + table[i] = (gfloat)sin(i * pi2scaled); + } + + g_free(src->table_data); + src->table_data = table; +} + +static inline void gst_sinesrc_update_table_inc(GstSineSrc *src) +{ + src->table_inc = src->table_size * src->freq / src->samplerate; +} + +static inline void gst_sinesrc_update_vol_scale(GstSineSrc *src) +{ + src->vol_scale = 32767 * src->volume; +} + +void gst_sinesrc_sync_parms(GstSineSrc *src) { + src->newcaps = TRUE; } diff --git a/gst/elements/gstsinesrc.h b/gst/elements/gstsinesrc.h index b0c457a4e4..167a1ad098 100644 --- a/gst/elements/gstsinesrc.h +++ b/gst/elements/gstsinesrc.h @@ -27,8 +27,6 @@ #include #include -#include - #ifdef __cplusplus extern "C" { @@ -60,17 +58,27 @@ struct _GstSineSrc { /* parameters */ gdouble volume; - gint freq; - + gdouble vol_scale; + gdouble freq; + + /* lookup table data */ + gfloat *table_data; + gdouble table_pos; + gdouble table_inc; + gint table_size; + gdouble table_interp; + gint table_lookup; + gint table_lookup_next; + /* audio parameters */ gint format; - gint channels; - gint frequency; + gint samplerate; + gint buffer_size; gulong seq; - MetaAudioRaw meta; - gboolean sentmeta; + gboolean newcaps; + }; struct _GstSineSrcClass { diff --git a/gst/elements/gsttee.c b/gst/elements/gsttee.c index d444217367..67ab4b1541 100644 --- a/gst/elements/gsttee.c +++ b/gst/elements/gsttee.c @@ -45,13 +45,17 @@ enum { /* FILL ME */ }; -static GstPadFactory tee_src_factory = { - "src%d", - GST_PAD_FACTORY_SRC, - GST_PAD_FACTORY_REQUEST, - NULL, /* no caps */ - NULL, -}; +static GstPadTemplate* +tee_src_factory_create (void) +{ + return + gst_padtemplate_new ( + "src%d", + GST_PAD_SRC, + GST_PAD_REQUEST, + NULL /* no caps */ + ); +} static void gst_tee_class_init (GstTeeClass *klass); @@ -197,7 +201,7 @@ gst_tee_chain (GstPad *pad, GstBuffer *buf) gboolean gst_tee_factory_init (GstElementFactory *factory) { - gst_tee_src_template = gst_padtemplate_new (&tee_src_factory); + gst_tee_src_template = tee_src_factory_create (); gst_elementfactory_add_padtemplate (factory, gst_tee_src_template); return TRUE; diff --git a/gst/gst.c b/gst/gst.c index a8aa7958fd..0b0189b7f5 100644 --- a/gst/gst.c +++ b/gst/gst.c @@ -35,11 +35,13 @@ #include "gsttypefind.h" +#define MAX_PATH_SPLIT 16 gchar *_gst_progname; extern gint _gst_trace_on; +extern gboolean _gst_plugin_spew; static gboolean gst_init_check (int *argc, gchar ***argv); @@ -61,8 +63,6 @@ gst_init (int *argc, char **argv[]) if (!g_thread_supported ()) g_thread_init (NULL); - _gst_progname = g_strdup(*argv[0]); - gtk_init (argc,argv); if (!gst_init_check (argc,argv)) { @@ -71,6 +71,8 @@ gst_init (int *argc, char **argv[]) _gst_cpu_initialize (); _gst_type_initialize (); + _gst_props_initialize (); + _gst_caps_initialize (); _gst_plugin_initialize (); _gst_buffer_initialize (); @@ -88,6 +90,31 @@ gst_init (int *argc, char **argv[]) } } +static void +gst_add_paths_func (gchar *pathlist) +{ + gchar **paths; + gint j = 0; + gchar *lastpath = g_strdup (pathlist); + + while (lastpath) { + paths = g_strsplit (lastpath, G_SEARCHPATH_SEPARATOR_S, MAX_PATH_SPLIT); + g_free (lastpath); + lastpath = NULL; + + while (paths[j]) { + GST_INFO (GST_CAT_GST_INIT, "Adding plugin path: \"%s\"", paths[j]); + gst_plugin_add_path (paths[j]); + if (++j == MAX_PATH_SPLIT) { + lastpath = g_strdup (paths[j]); + g_strfreev (paths); + j=0; + break; + } + } + } +} + /* returns FALSE if the program can be aborted */ static gboolean gst_init_check (int *argc, @@ -96,9 +123,13 @@ gst_init_check (int *argc, gboolean ret = TRUE; gboolean showhelp = FALSE; + _gst_progname = NULL; + if (argc && argv) { gint i, j, k; + _gst_progname = g_strdup(*argv[0]); + for (i=1; i< *argc; i++) { if (!strncmp ("--gst-info-mask=", (*argv)[i], 16)) { guint32 val; @@ -128,6 +159,16 @@ gst_init_check (int *argc, (*argv)[i] = NULL; } + else if (!strncmp ("--gst-plugin-spew", (*argv)[i], 17)) { + _gst_plugin_spew = TRUE; + + (*argv)[i] = NULL; + } + else if (!strncmp ("--gst-plugin-path=", (*argv)[i], 17)) { + gst_add_paths_func ((*argv)[i]+18); + + (*argv)[i] = NULL; + } else if (!strncmp ("--help", (*argv)[i], 6)) { showhelp = TRUE; } @@ -147,20 +188,37 @@ gst_init_check (int *argc, } } + if (_gst_progname == NULL) { + _gst_progname = g_strdup("gstprog"); + } + + + /* check for ENV variables */ + { + gchar *plugin_path = g_getenv("GST_PLUGIN_PATH"); + + gst_add_paths_func (plugin_path); + } + if (showhelp) { guint i; - g_print ("usage %s [OPTION...]\n", (*argv)[0]); + g_print ("usage %s [OPTION...]\n", _gst_progname); g_print ("\nGStreamer options\n"); - g_print (" --gst-info-mask=FLAGS Gst info flags to set (current %08x)\n", gst_info_get_categories()); - g_print (" --gst-debug-mask=FLAGS Gst debugging flags to set\n"); + g_print (" --gst-info-mask=FLAGS GST info flags to set (current %08x)\n", gst_info_get_categories()); + g_print (" --gst-debug-mask=FLAGS GST debugging flags to set\n"); + g_print (" --gst-plugin-spew Enable printout of errors while loading GST plugins\n"); + g_print (" --gst-plugin-path=PATH Add directories separated with '%s' to the plugin search path\n", + G_SEARCHPATH_SEPARATOR_S); - g_print ("\nGStreamer info/debug FLAGS (to be OR'ed)\n"); + g_print ("\n Mask (to be OR'ed) info/debug FLAGS \n"); + g_print ("--------------------------------------------------------\n"); for (i = 0; i +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + /* initialize GST */ void gst_init(int *argc,char **argv[]); void gst_main (void); void gst_main_quit (void); +#ifdef __cplusplus +} +#endif /* __cplusplus */ + #include #endif /* __GST_H__ */ diff --git a/gst/gstarch.h b/gst/gstarch.h index d3b22161ba..d78e768cf7 100644 --- a/gst/gstarch.h +++ b/gst/gstarch.h @@ -35,6 +35,8 @@ #include "gstalpha.h" #elif defined(HAVE_CPU_ARM) #include "gstarm.h" +#elif defined(HAVE_CPU_SPARC) +#include "gstsparc.h" #else #error Need to know about this architecture, or have a generic implementation #endif diff --git a/gst/gstautoplug.c b/gst/gstautoplug.c index 4a088a5344..5294737b40 100644 --- a/gst/gstautoplug.c +++ b/gst/gstautoplug.c @@ -24,337 +24,337 @@ #include "gst_private.h" #include "gstautoplug.h" +#include "gstplugin.h" + +GList* _gst_autoplugfactories; + +enum { + NEW_OBJECT, + LAST_SIGNAL +}; + +enum { + ARG_0, + /* FILL ME */ +}; static void gst_autoplug_class_init (GstAutoplugClass *klass); static void gst_autoplug_init (GstAutoplug *autoplug); -static GList* gst_autoplug_func (gpointer src, gpointer sink, - GstAutoplugListFunction list_function, - GstAutoplugCostFunction cost_function, - gpointer data); - -struct _gst_autoplug_node -{ - gpointer iNode; - gpointer iPrev; - gint iDist; -}; - -typedef struct _gst_autoplug_node gst_autoplug_node; - static GstObjectClass *parent_class = NULL; +static guint gst_autoplug_signals[LAST_SIGNAL] = { 0 }; -GtkType gst_autoplug_get_type(void) { +GtkType gst_autoplug_get_type(void) +{ static GtkType autoplug_type = 0; if (!autoplug_type) { static const GtkTypeInfo autoplug_info = { "GstAutoplug", - sizeof(GstElement), - sizeof(GstElementClass), + sizeof(GstAutoplug), + sizeof(GstAutoplugClass), (GtkClassInitFunc)gst_autoplug_class_init, (GtkObjectInitFunc)gst_autoplug_init, (GtkArgSetFunc)NULL, (GtkArgGetFunc)NULL, (GtkClassInitFunc)NULL, }; - autoplug_type = gtk_type_unique(GST_TYPE_AUTOPLUG,&autoplug_info); + autoplug_type = gtk_type_unique (GST_TYPE_OBJECT, &autoplug_info); } return autoplug_type; } static void -gst_autoplug_class_init(GstAutoplugClass *klass) { +gst_autoplug_class_init(GstAutoplugClass *klass) +{ + GtkObjectClass *gtkobject_class; + GstObjectClass *gstobject_class; + + gtkobject_class = (GtkObjectClass*) klass; + gstobject_class = (GstObjectClass*) klass; + parent_class = gtk_type_class(GST_TYPE_OBJECT); + + gst_autoplug_signals[NEW_OBJECT] = + gtk_signal_new ("new_object", GTK_RUN_LAST, gtkobject_class->type, + GTK_SIGNAL_OFFSET (GstAutoplugClass, new_object), + gtk_marshal_NONE__POINTER, GTK_TYPE_NONE, 1, + GST_TYPE_OBJECT); + + gtk_object_class_add_signals (gtkobject_class, gst_autoplug_signals, LAST_SIGNAL); } -static void gst_autoplug_init(GstAutoplug *autoplug) { -} - -static gboolean -gst_autoplug_can_match (GstElementFactory *src, GstElementFactory *dest) +static void gst_autoplug_init(GstAutoplug *autoplug) { - GList *srctemps, *desttemps; - - srctemps = src->padtemplates; - - while (srctemps) { - GstPadTemplate *srctemp = (GstPadTemplate *)srctemps->data; - - desttemps = dest->padtemplates; - - while (desttemps) { - GstPadTemplate *desttemp = (GstPadTemplate *)desttemps->data; - - if (srctemp->direction == GST_PAD_SRC && - desttemp->direction == GST_PAD_SINK) { - if (gst_caps_list_check_compatibility (srctemp->caps, desttemp->caps)) { - GST_INFO (GST_CAT_AUTOPLUG_ATTEMPT,"factory \"%s\" can connect with factory \"%s\"", src->name, dest->name); - return TRUE; - } - } - - desttemps = g_list_next (desttemps); - } - srctemps = g_list_next (srctemps); - } - GST_INFO (GST_CAT_AUTOPLUG_ATTEMPT,"factory \"%s\" cannot connect with factory \"%s\"", src->name, dest->name); - return FALSE; } -static GList* -gst_autoplug_elementfactory_get_list (gpointer data) +void +_gst_autoplug_initialize (void) { - return gst_elementfactory_get_list (); -} - -typedef struct { - GList *src; - GList *sink; -} caps_struct; - -#define IS_CAPS(cap) (((cap) == caps->src) || (cap) == caps->sink) - -static guint -gst_autoplug_caps_find_cost (gpointer src, gpointer dest, gpointer data) -{ - caps_struct *caps = (caps_struct *)data; - gboolean res; - - if (IS_CAPS (src) && IS_CAPS (dest)) { - res = gst_caps_list_check_compatibility ((GList *)src, (GList *)dest); - //GST_INFO (GST_CAT_AUTOPLUG_ATTEMPT,"caps %d to caps %d %d", ((GstCaps *)src)->id, ((GstCaps *)dest)->id, res); - } - else if (IS_CAPS (src)) { - res = gst_elementfactory_can_sink_caps_list ((GstElementFactory *)dest, (GList *)src); - //GST_INFO (GST_CAT_AUTOPLUG_ATTEMPT,"factory %s to src caps %d %d", ((GstElementFactory *)dest)->name, ((GstCaps *)src)->id, res); - } - else if (IS_CAPS (dest)) { - res = gst_elementfactory_can_src_caps_list ((GstElementFactory *)src, (GList *)dest); - //GST_INFO (GST_CAT_AUTOPLUG_ATTEMPT,"factory %s to sink caps %d %d", ((GstElementFactory *)src)->name, ((GstCaps *)dest)->id, res); - } - else { - res = gst_autoplug_can_match ((GstElementFactory *)src, (GstElementFactory *)dest); - } - - if (res) - return 1; - else - return GST_AUTOPLUG_MAX_COST; + _gst_autoplugfactories = NULL; } /** - * gst_autoplug_caps: - * @srccaps: the source caps - * @sinkcaps: the sink caps + * gst_autoplug_signal_new_object: + * @autoplug: The autoplugger to emit the signal + * @object: The object that is passed to the signal * - * Perform autoplugging between the two given caps. - * - * Returns: a list of elementfactories that can connect - * the two caps + * Emit a new_object signal. autopluggers are supposed to + * emit this signal whenever a new object has been added to + * the autoplugged pipeline. + * */ -GList* -gst_autoplug_caps (GstCaps *srccaps, GstCaps *sinkcaps) +void +gst_autoplug_signal_new_object (GstAutoplug *autoplug, GstObject *object) { - caps_struct caps; + gtk_signal_emit (GTK_OBJECT (autoplug), gst_autoplug_signals[NEW_OBJECT], object); +} - caps.src = g_list_prepend (NULL,srccaps); - caps.sink = g_list_prepend (NULL,sinkcaps); - GST_INFO (GST_CAT_AUTOPLUG_ATTEMPT,"autoplugging two caps structures"); +/** + * gst_autoplug_to_caps: + * @autoplug: The autoplugger perform the autoplugging + * @srccaps: The source cpabilities + * @sinkcaps: The target capabilities + * @...: more target capabilities + * + * Perform the autoplugging procedure on the given autoplugger. + * The src caps will be connected to the sink caps. + * + * Returns: A new Element that connects the src caps to the sink caps. + */ +GstElement* +gst_autoplug_to_caps (GstAutoplug *autoplug, GstCaps *srccaps, GstCaps *sinkcaps, ...) +{ + GstAutoplugClass *oclass; + GstElement *element = NULL; + va_list args; - return gst_autoplug_func (caps.src, caps.sink, - gst_autoplug_elementfactory_get_list, - gst_autoplug_caps_find_cost, - &caps); + va_start (args, sinkcaps); + + oclass = GST_AUTOPLUG_CLASS (GTK_OBJECT (autoplug)->klass); + if (oclass->autoplug_to_caps) + element = (oclass->autoplug_to_caps) (autoplug, srccaps, sinkcaps, args); + + va_end (args); + + return element; } /** - * gst_autoplug_caps_list: - * @srccaps: the source caps list - * @sinkcaps: the sink caps list + * gst_autoplug_to_renderers: + * @autoplug: The autoplugger perform the autoplugging + * @srccaps: The source cpabilities + * @target: The target element + * @...: more target elements * - * Perform autoplugging between the two given caps lists. - * - * Returns: a list of elementfactories that can connect - * the two caps lists + * Perform the autoplugging procedure on the given autoplugger. + * The src caps will be connected to the target elements. + * + * Returns: A new Element that connects the src caps to the target elements. */ -GList* -gst_autoplug_caps_list (GList *srccaps, GList *sinkcaps) +GstElement* +gst_autoplug_to_renderers (GstAutoplug *autoplug, GstCaps *srccaps, GstElement *target, ...) { - caps_struct caps; + GstAutoplugClass *oclass; + GstElement *element = NULL; + va_list args; - caps.src = srccaps; - caps.sink = sinkcaps; + va_start (args, target); - GST_INFO (GST_CAT_AUTOPLUG_ATTEMPT,"autoplugging two caps list structures"); + oclass = GST_AUTOPLUG_CLASS (GTK_OBJECT (autoplug)->klass); + if (oclass->autoplug_to_renderers) + element = (oclass->autoplug_to_renderers) (autoplug, srccaps, target, args); - return gst_autoplug_func (caps.src, caps.sink, - gst_autoplug_elementfactory_get_list, - gst_autoplug_caps_find_cost, - &caps); + va_end (args); + + return element; +} + + +/** + * gst_autoplugfactory_new: + * @name: name of autoplugfactory to create + * @longdesc: long description of autoplugfactory to create + * @type: the gtk type of the GstAutoplug element of this factory + * + * Create a new autoplugfactory with the given parameters + * + * Returns: a new #GstAutoplugFactory. + */ +GstAutoplugFactory* +gst_autoplugfactory_new (const gchar *name, const gchar *longdesc, GtkType type) +{ + GstAutoplugFactory *factory; + + g_return_val_if_fail(name != NULL, NULL); + + factory = g_new0(GstAutoplugFactory, 1); + + factory->name = g_strdup(name); + factory->longdesc = g_strdup (longdesc); + factory->type = type; + + _gst_autoplugfactories = g_list_prepend (_gst_autoplugfactories, factory); + + return factory; } /** - * gst_autoplug_pads: - * @srcpad: the source pad - * @sinkpad: the sink pad + * gst_autoplugfactory_destroy: + * @factory: factory to destroy * - * Perform autoplugging between the two given pads. + * Removes the autoplug from the global list. + */ +void +gst_autoplugfactory_destroy (GstAutoplugFactory *factory) +{ + g_return_if_fail (factory != NULL); + + _gst_autoplugfactories = g_list_remove (_gst_autoplugfactories, factory); + + // we don't free the struct bacause someone might have a handle to it.. +} + +/** + * gst_autoplugfactory_find: + * @name: name of autoplugfactory to find * - * Returns: a list of elementfactories that can connect - * the two pads + * Search for an autoplugfactory of the given name. + * + * Returns: #GstAutoplugFactory if found, NULL otherwise + */ +GstAutoplugFactory* +gst_autoplugfactory_find (const gchar *name) +{ + GList *walk; + GstAutoplugFactory *factory; + + g_return_val_if_fail(name != NULL, NULL); + + GST_DEBUG (0,"gstautoplug: find \"%s\"\n", name); + + walk = _gst_autoplugfactories; + while (walk) { + factory = (GstAutoplugFactory *)(walk->data); + if (!strcmp (name, factory->name)) + return factory; + walk = g_list_next (walk); + } + + return NULL; +} + +/** + * gst_autoplugfactory_get_list: + * + * Get the global list of autoplugfactories. + * + * Returns: GList of type #GstAutoplugFactory */ GList* -gst_autoplug_pads (GstPad *srcpad, GstPad *sinkpad) +gst_autoplugfactory_get_list (void) { - caps_struct caps; - - caps.src = gst_pad_get_caps_list(srcpad); - caps.sink = gst_pad_get_caps_list(sinkpad); - - GST_INFO (GST_CAT_AUTOPLUG_ATTEMPT,"autoplugging two caps structures"); - - return gst_autoplug_func (caps.src, caps.sink, - gst_autoplug_elementfactory_get_list, - gst_autoplug_caps_find_cost, - &caps); + return _gst_autoplugfactories; } -static gint -find_factory (gst_autoplug_node *rgnNodes, gpointer factory) -{ - gint i=0; - while (rgnNodes[i].iNode) { - if (rgnNodes[i].iNode == factory) return i; - i++; +/** + * gst_autoplugfactory_create: + * @factory: the factory used to create the instance + * + * Create a new #GstAutoplug instance from the + * given autoplugfactory. + * + * Returns: A new #GstAutoplug instance. + */ +GstAutoplug* +gst_autoplugfactory_create (GstAutoplugFactory *factory) +{ + GstAutoplug *new = NULL; + + g_return_val_if_fail (factory != NULL, NULL); + + if (factory->type == 0){ + factory = gst_plugin_load_autoplugfactory (factory->name); } - return 0; + g_return_val_if_fail (factory != NULL, NULL); + g_return_val_if_fail (factory->type != 0, NULL); + + new = GST_AUTOPLUG (gtk_type_new (factory->type)); + + return new; } -static GList* -construct_path (gst_autoplug_node *rgnNodes, gpointer factory) +/** + * gst_autoplugfactory_make: + * @name: the name of the factory used to create the instance + * + * Create a new #GstAutoplug instance from the + * autoplugfactory with the given name. + * + * Returns: A new #GstAutoplug instance. + */ +GstAutoplug* +gst_autoplugfactory_make (const gchar *name) { - GstElementFactory *current; - GList *factories = NULL; + GstAutoplugFactory *factory; - current = rgnNodes[find_factory(rgnNodes, factory)].iPrev; + g_return_val_if_fail (name != NULL, NULL); - GST_INFO (GST_CAT_AUTOPLUG_ATTEMPT,"factories found in autoplugging (reversed order)"); + factory = gst_autoplugfactory_find (name); - while (current != NULL) - { - gpointer next = NULL; + if (factory == NULL) + return NULL; - next = rgnNodes[find_factory(rgnNodes, current)].iPrev; - if (next) { - factories = g_list_prepend (factories, current); - GST_INFO (GST_CAT_AUTOPLUG_ATTEMPT,"factory: \"%s\"", current->name); + return gst_autoplugfactory_create (factory);; +} + +/** + * gst_autoplugfactory_save_thyself: + * @factory: The facory to save + * @parent: the parent XML node pointer + * + * Save the autoplugfactory into an XML representation + * + * Returns: The new XML parent. + */ +xmlNodePtr +gst_autoplugfactory_save_thyself (GstAutoplugFactory *factory, xmlNodePtr parent) +{ + g_return_val_if_fail(factory != NULL, NULL); + + xmlNewChild(parent,NULL,"name",factory->name); + xmlNewChild(parent,NULL,"longdesc", factory->longdesc); + + return parent; +} + +/** + * gst_autoplugfactory_load_thyself: + * @parent: the parent XML node pointer + * + * Load an autoplugfactory from the given XML parent node. + * + * Returns: A new factory based on the XML node. + */ +GstAutoplugFactory* +gst_autoplugfactory_load_thyself (xmlNodePtr parent) +{ + GstAutoplugFactory *factory = g_new0(GstAutoplugFactory, 1); + xmlNodePtr children = parent->xmlChildrenNode; + + while (children) { + if (!strcmp(children->name, "name")) { + factory->name = xmlNodeGetContent(children); } - current = next; - } - return factories; -} - -static GList* -gst_autoplug_enqueue (GList *queue, gpointer iNode, gint iDist, gpointer iPrev) -{ - gst_autoplug_node *node = g_malloc (sizeof (gst_autoplug_node)); - - node->iNode = iNode; - node->iDist = iDist; - node->iPrev = iPrev; - - queue = g_list_append (queue, node); - - return queue; -} - -static GList* -gst_autoplug_dequeue (GList *queue, gpointer *iNode, gint *iDist, gpointer *iPrev) -{ - GList *head; - gst_autoplug_node *node; - - head = g_list_first (queue); - - if (head) { - node = (gst_autoplug_node *)head->data; - *iNode = node->iNode; - *iPrev = node->iPrev; - *iDist = node->iDist; - head = g_list_remove (queue, node); - } - - return head; -} - -static GList* -gst_autoplug_func (gpointer src, gpointer sink, - GstAutoplugListFunction list_function, - GstAutoplugCostFunction cost_function, - gpointer data) -{ - gst_autoplug_node *rgnNodes; - GList *queue = NULL; - gpointer iNode, iPrev; - gint iDist, i, iCost; - - GList *elements = g_list_copy (list_function(data)); - GList *factories; - guint num_factories; - - elements = g_list_append (elements, sink); - elements = g_list_append (elements, src); - - factories = elements; - - num_factories = g_list_length (factories); - - rgnNodes = g_new0 (gst_autoplug_node, num_factories+1); - - for (i=0; i< num_factories; i++) { - gpointer fact = factories->data; - - rgnNodes[i].iNode = fact; - rgnNodes[i].iPrev = NULL; - - if (fact == src) { - rgnNodes[i].iDist = 0; - } - else { - rgnNodes[i].iDist = GST_AUTOPLUG_MAX_COST; - } - - factories = g_list_next (factories); - } - rgnNodes[num_factories].iNode = NULL; - - queue = gst_autoplug_enqueue (queue, src, 0, NULL); - - while (g_list_length (queue) > 0) { - GList *factories2 = elements; - - queue = gst_autoplug_dequeue (queue, &iNode, &iDist, &iPrev); - - for (i=0; i< num_factories; i++) { - gpointer current = factories2->data; - - iCost = cost_function (iNode, current, data); - if (iCost != GST_AUTOPLUG_MAX_COST) { - if((GST_AUTOPLUG_MAX_COST == rgnNodes[i].iDist) || - (rgnNodes[i].iDist > (iCost + iDist))) { - rgnNodes[i].iDist = iDist + iCost; - rgnNodes[i].iPrev = iNode; - - queue = gst_autoplug_enqueue (queue, current, iDist + iCost, iNode); - } - } - - factories2 = g_list_next (factories2); + if (!strcmp(children->name, "longdesc")) { + factory->longdesc = xmlNodeGetContent(children); } + children = children->next; } - return construct_path (rgnNodes, sink); + _gst_autoplugfactories = g_list_prepend (_gst_autoplugfactories, factory); + + return factory; } diff --git a/gst/gstautoplug.h b/gst/gstautoplug.h index c646c24d61..6bb03c64c4 100644 --- a/gst/gstautoplug.h +++ b/gst/gstautoplug.h @@ -31,7 +31,7 @@ extern "C" { #endif /* __cplusplus */ #define GST_TYPE_AUTOPLUG \ - (gst_object_get_type()) + (gst_autoplug_get_type()) #define GST_AUTOPLUG(obj) \ (GTK_CHECK_CAST((obj),GST_TYPE_AUTOPLUG,GstAutoplug)) #define GST_AUTOPLUG_CLASS(klass) \ @@ -44,30 +44,66 @@ extern "C" { typedef struct _GstAutoplug GstAutoplug; typedef struct _GstAutoplugClass GstAutoplugClass; -#define GST_AUTOPLUG_MAX_COST 999999 +typedef enum { + GST_AUTOPLUG_TO_CAPS = GST_OBJECT_FLAG_LAST, + GST_AUTOPLUG_TO_RENDERER, -typedef guint (*GstAutoplugCostFunction) (gpointer src, gpointer dest, gpointer data); -typedef GList* (*GstAutoplugListFunction) (gpointer data); + GST_AUTOPLUG_FLAG_LAST = GST_OBJECT_FLAG_LAST + 8, +} GstAutoplugFlags; + struct _GstAutoplug { - GtkObject object; + GstObject object; }; struct _GstAutoplugClass { - GtkObjectClass parent_class; + GstObjectClass parent_class; + + /* signal callbacks */ + void (*new_object) (GstAutoplug *autoplug, GstObject *object); + + /* perform the autoplugging */ + GstElement* (*autoplug_to_caps) (GstAutoplug *autoplug, GstCaps *srccaps, GstCaps *sinkcaps, va_list args); + GstElement* (*autoplug_to_renderers) (GstAutoplug *autoplug, GstCaps *srccaps, GstElement *target, va_list args); }; -GtkType gst_autoplug_get_type (void); +typedef struct _GstAutoplugFactory GstAutoplugFactory; -GList* gst_autoplug_caps (GstCaps *srccaps, GstCaps *sinkcaps); -GList* gst_autoplug_caps_list (GList *srccaps, GList *sinkcaps); -GList* gst_autoplug_pads (GstPad *srcpad, GstPad *sinkpad); +struct _GstAutoplugFactory { + gchar *name; /* name of autoplugger */ + gchar *longdesc; /* long description of the autoplugger (well, don't overdo it..) */ + GtkType type; /* unique GtkType of the autoplugger */ +}; +GtkType gst_autoplug_get_type (void); + +void gst_autoplug_signal_new_object (GstAutoplug *autoplug, GstObject *object); + +GstElement* gst_autoplug_to_caps (GstAutoplug *autoplug, GstCaps *srccaps, GstCaps *sinkcaps, ...); +GstElement* gst_autoplug_to_renderers (GstAutoplug *autoplug, GstCaps *srccaps, + GstElement *target, ...); + + +/* + * creating autopluggers + * + */ +GstAutoplugFactory* gst_autoplugfactory_new (const gchar *name, const gchar *longdesc, GtkType type); +void gst_autoplugfactory_destroy (GstAutoplugFactory *factory); + +GstAutoplugFactory* gst_autoplugfactory_find (const gchar *name); +GList* gst_autoplugfactory_get_list (void); + +GstAutoplug* gst_autoplugfactory_create (GstAutoplugFactory *factory); +GstAutoplug* gst_autoplugfactory_make (const gchar *name); + +xmlNodePtr gst_autoplugfactory_save_thyself (GstAutoplugFactory *factory, xmlNodePtr parent); +GstAutoplugFactory* gst_autoplugfactory_load_thyself (xmlNodePtr parent); #ifdef __cplusplus } #endif /* __cplusplus */ -#endif /* __GST_AUTOPLUG_H__ */ +#endif /* __GST_AUTOPLUG_H__ */ diff --git a/gst/gstbin.c b/gst/gstbin.c index 33f9846c42..5f4cce2101 100644 --- a/gst/gstbin.c +++ b/gst/gstbin.c @@ -341,6 +341,7 @@ gst_bin_change_state (GstElement *element) GstBin *bin; GList *children; GstElement *child; + GstElementStateReturn ret; GST_DEBUG_ENTER("(\"%s\")",GST_ELEMENT_NAME (element)); @@ -368,9 +369,13 @@ gst_bin_change_state (GstElement *element) if (!parent || !GST_IS_BIN (parent)) gst_bin_create_plan (bin); + else + GST_DEBUG (0,"not creating plan for '%s'\n",GST_ELEMENT_NAME (bin)); break; } + case GST_STATE_READY_TO_NULL: + GST_FLAG_UNSET (bin, GST_BIN_FLAG_MANAGER); default: break; } @@ -397,7 +402,6 @@ gst_bin_change_state (GstElement *element) } // g_print("<-- \"%s\"\n",GST_OBJECT_NAME(bin)); - GST_INFO_ELEMENT (GST_CAT_STATES, element, "done changing bin's state from %s to %s", _gst_print_statename (GST_STATE (element)), _gst_print_statename (GST_STATE_PENDING (element))); @@ -698,7 +702,7 @@ gst_bin_create_plan (GstBin *bin) static void gst_bin_received_eos (GstElement *element, GstBin *bin) { - GST_INFO_ELEMENT (GST_CAT_PLANNING, bin, "child %s fired eos, pending %d\n", GST_ELEMENT_NAME (element), + GST_INFO_ELEMENT (GST_CAT_PLANNING, bin, "child %s fired eos, pending %d", GST_ELEMENT_NAME (element), bin->num_eos_providers); GST_LOCK (bin); @@ -875,7 +879,9 @@ gst_bin_create_plan_func (GstBin *bin) } // else it's not ours and we need to wait for EOS notifications else { - gtk_signal_connect (GTK_OBJECT (element), "eos", gst_bin_received_eos, bin); + GST_DEBUG (0,"setting up EOS signal from \"%s\" to \"%s\"\n", elementname, + gst_element_get_name (GST_ELEMENT(bin)->manager)); + gtk_signal_connect (GTK_OBJECT (element), "eos", gst_bin_received_eos, GST_ELEMENT(bin)->manager); bin->eos_providers = g_list_prepend (bin->eos_providers, element); bin->num_eos_providers++; } @@ -936,6 +942,8 @@ gst_bin_iterate_func (GstBin *bin) if (!chain->need_scheduling) continue; if (chain->need_cothreads) { + GList *entries; + // all we really have to do is switch to the first child // FIXME this should be lots more intelligent about where to start GST_DEBUG (0,"starting iteration via cothreads\n"); @@ -1001,7 +1009,7 @@ gst_bin_iterate_func (GstBin *bin) if (bin->num_eos_providers) { GST_LOCK (bin); GST_DEBUG (0,"waiting for eos providers\n"); - g_cond_wait (bin->eoscond, GST_OBJECT(bin)->lock); + g_cond_wait (bin->eoscond, GST_GET_LOCK(bin)); GST_DEBUG (0,"num eos providers %d\n", bin->num_eos_providers); GST_UNLOCK (bin); } diff --git a/gst/gstbuffer.c b/gst/gstbuffer.c index 465986a7ff..5f29ab84d1 100644 --- a/gst/gstbuffer.c +++ b/gst/gstbuffer.c @@ -27,8 +27,8 @@ #include "gstbuffer.h" -GMemChunk *_gst_buffer_chunk; -GMutex *chunck_lock; +static GMemChunk *_gst_buffer_chunk; +static GMutex *_gst_buffer_chunk_lock; void _gst_buffer_initialize (void) @@ -36,7 +36,7 @@ _gst_buffer_initialize (void) _gst_buffer_chunk = g_mem_chunk_new ("GstBuffer", sizeof(GstBuffer), sizeof(GstBuffer) * 16, G_ALLOC_AND_FREE); - chunck_lock = g_mutex_new (); + _gst_buffer_chunk_lock = g_mutex_new (); } /** @@ -51,9 +51,9 @@ gst_buffer_new(void) { GstBuffer *buffer; - g_mutex_lock (chunck_lock); + g_mutex_lock (_gst_buffer_chunk_lock); buffer = g_mem_chunk_alloc (_gst_buffer_chunk); - g_mutex_unlock (chunck_lock); + g_mutex_unlock (_gst_buffer_chunk_lock); GST_INFO (GST_CAT_BUFFER,"creating new buffer %p",buffer); // g_print("allocating new mutex\n"); @@ -112,9 +112,9 @@ gst_buffer_create_sub (GstBuffer *parent, g_return_val_if_fail (size > 0, NULL); g_return_val_if_fail ((offset+size) <= parent->size, NULL); - g_mutex_lock (chunck_lock); + g_mutex_lock (_gst_buffer_chunk_lock); buffer = g_mem_chunk_alloc (_gst_buffer_chunk); - g_mutex_unlock (chunck_lock); + g_mutex_unlock (_gst_buffer_chunk_lock); GST_INFO (GST_CAT_BUFFER,"creating new subbuffer %p from parent %p", buffer, parent); buffer->lock = g_mutex_new (); @@ -235,9 +235,9 @@ void gst_buffer_destroy (GstBuffer *buffer) //g_print("freed mutex\n"); // remove it entirely from memory - g_mutex_lock (chunck_lock); + g_mutex_lock (_gst_buffer_chunk_lock); g_mem_chunk_free (_gst_buffer_chunk,buffer); - g_mutex_unlock (chunck_lock); + g_mutex_unlock (_gst_buffer_chunk_lock); } /** diff --git a/gst/gstcaps.c b/gst/gstcaps.c index f8bfcb3e66..c77d9bdafb 100644 --- a/gst/gstcaps.c +++ b/gst/gstcaps.c @@ -28,10 +28,16 @@ #include "gstpropsprivate.h" +static GMemChunk *_gst_caps_chunk; +static GMutex *_gst_caps_chunk_lock; -void -_gst_caps_initialize (void) +void +_gst_caps_initialize (void) { + _gst_caps_chunk = g_mem_chunk_new ("GstCaps", + sizeof (GstCaps), sizeof (GstCaps) * 256, + G_ALLOC_AND_FREE); + _gst_caps_chunk_lock = g_mutex_new (); } static guint16 @@ -56,103 +62,153 @@ get_type_for_mime (const gchar *mime) * gst_caps_new: * @name: the name of this capability * @mime: the mime type to attach to the capability + * @props: the properties to add to this capability * - * Create a new capability with the given mime type. + * Create a new capability with the given mime typei and properties. * * Returns: a new capability */ GstCaps* -gst_caps_new (const gchar *name, const gchar *mime) +gst_caps_new (const gchar *name, const gchar *mime, GstProps *props) { GstCaps *caps; g_return_val_if_fail (mime != NULL, NULL); - - caps = g_new0 (GstCaps, 1); + + g_mutex_lock (_gst_caps_chunk_lock); + caps = g_mem_chunk_alloc (_gst_caps_chunk); + g_mutex_unlock (_gst_caps_chunk_lock); + caps->name = g_strdup (name); caps->id = get_type_for_mime (mime); - caps->properties = NULL; - - return caps; -} - -/** - * gst_caps_new_with_props: - * @name: the name of this capability - * @mime: the mime type to attach to the capability - * @props: the properties for this capability - * - * Create a new capability with the given mime type and the given properties. - * - * Returns: a new capability - */ -GstCaps* -gst_caps_new_with_props (const gchar *name, const gchar *mime, GstProps *props) -{ - GstCaps *caps; - - caps = gst_caps_new (name, mime); caps->properties = props; + caps->next = NULL; + caps->refcount = 1; + caps->lock = g_mutex_new (); return caps; } /** - * gst_caps_register: - * @factory: the factory to register + * gst_caps_destroy: + * @caps: the caps to destroy * - * Register the factory. - * - * Returns: the registered capability + * Frees the memory used by this caps structure and all + * the chained caps and properties. */ -GstCaps* -gst_caps_register (GstCapsFactory *factory) +void +gst_caps_destroy (GstCaps *caps) { - guint dummy; + GstCaps *next; - return gst_caps_register_count (factory, &dummy); + g_return_if_fail (caps != NULL); + + GST_CAPS_LOCK (caps); + next = caps->next; + g_free (caps->name); + g_free (caps); + GST_CAPS_UNLOCK (caps); + + if (next) + gst_caps_unref (next); } /** - * gst_caps_register_count: - * @factory: the factory to register - * @counter: count how many entries were consumed + * gst_caps_unref: + * @caps: the caps to unref * - * Register the factory. + * Decrease the refcount of this caps structure, + * destroying it when the refcount is 0 + */ +void +gst_caps_unref (GstCaps *caps) +{ + gboolean zero; + GstCaps *next; + + g_return_if_fail (caps != NULL); + + GST_CAPS_LOCK (caps); + caps->refcount--; + zero = (caps->refcount == 0); + next = caps->next; + GST_CAPS_UNLOCK (caps); + + if (next) + gst_caps_unref (next); + + if (zero) + gst_caps_destroy (caps); +} + +/** + * gst_caps_ref: + * @caps: the caps to ref * - * Returns: the registered capability + * Increase the refcount of this caps structure + */ +void +gst_caps_ref (GstCaps *caps) +{ + g_return_if_fail (caps != NULL); + + GST_CAPS_LOCK (caps); + caps->refcount++; + GST_CAPS_UNLOCK (caps); +} + +/** + * gst_caps_copy: + * @caps: the caps to copy + * + * Copies the caps. + * + * Returns: a copy of the GstCaps structure. */ GstCaps* -gst_caps_register_count (GstCapsFactory *factory, guint *counter) +gst_caps_copy (GstCaps *caps) { - GstCapsFactoryEntry tag; - gint i = 0; - guint16 typeid; - gchar *name; - GstCaps *caps; + GstCaps *new = caps;; - g_return_val_if_fail (factory != NULL, NULL); - - tag = (*factory)[i++]; - g_return_val_if_fail (tag != NULL, NULL); - - name = tag; - - tag = (*factory)[i++]; - g_return_val_if_fail (tag != NULL, NULL); - - typeid = get_type_for_mime ((gchar *)tag); - - caps = g_new0 (GstCaps, 1); g_return_val_if_fail (caps != NULL, NULL); - caps->name = g_strdup (name); - caps->id = typeid; - caps->properties = gst_props_register_count (&(*factory)[i], counter); + GST_CAPS_LOCK (caps); + new = gst_caps_new ( + caps->name, + (gst_type_find_by_id (caps->id))->mime, + gst_props_copy (caps->properties)); + GST_CAPS_UNLOCK (caps); - *counter += 2; + return new; +} - return caps; +/** + * gst_caps_copy_on_write: + * @caps: the caps to copy + * + * Copies the caps if the refcount is greater than 1 + * + * Returns: a pointer to a GstCaps strcuture that can + * be safely written to + */ +GstCaps* +gst_caps_copy_on_write (GstCaps *caps) +{ + GstCaps *new = caps; + gboolean needcopy; + + g_return_val_if_fail (caps != NULL, NULL); + + GST_CAPS_LOCK (caps); + needcopy = (caps->refcount > 1); + GST_CAPS_UNLOCK (caps); + + if (needcopy) { + new = gst_caps_copy (caps); + gst_caps_unref (caps); + } + + return new; } /** @@ -163,7 +219,7 @@ gst_caps_register_count (GstCapsFactory *factory, guint *counter) * * Returns: the name of the caps */ -const gchar* +const gchar* gst_caps_get_name (GstCaps *caps) { g_return_val_if_fail (caps != NULL, NULL); @@ -173,7 +229,7 @@ gst_caps_get_name (GstCaps *caps) /** * gst_caps_set_name: - * @caps: the caps to set the name to + * @caps: the caps to set the name to * @name: the name to set * * Set the name of a caps. @@ -182,7 +238,7 @@ void gst_caps_set_name (GstCaps *caps, const gchar *name) { g_return_if_fail (caps != NULL); - + if (caps->name) g_free (caps->name); @@ -197,7 +253,7 @@ gst_caps_set_name (GstCaps *caps, const gchar *name) * * Returns: the mime type of the caps */ -const gchar* +const gchar* gst_caps_get_mime (GstCaps *caps) { GstType *type; @@ -206,9 +262,9 @@ gst_caps_get_mime (GstCaps *caps) type = gst_type_find_by_id (caps->id); - if (type) + if (type) return type->mime; - else + else return "unknown/unknown"; } @@ -236,7 +292,7 @@ gst_caps_set_mime (GstCaps *caps, const gchar *mime) * * Returns: the type id of the caps */ -guint16 +guint16 gst_caps_get_type_id (GstCaps *caps) { g_return_val_if_fail (caps != NULL, 0); @@ -247,16 +303,16 @@ gst_caps_get_type_id (GstCaps *caps) /** * gst_caps_set_type_id: * @caps: the caps to set the type id to - * @typeid: the type id to set + * @type_id: the type id to set * * Set the type id of the caps. */ void -gst_caps_set_type_id (GstCaps *caps, guint16 typeid) +gst_caps_set_type_id (GstCaps *caps, guint16 type_id) { g_return_if_fail (caps != NULL); - caps->id = typeid; + caps->id = type_id; } /** @@ -276,7 +332,7 @@ gst_caps_set_props (GstCaps *caps, GstProps *props) g_return_val_if_fail (caps->properties == NULL, caps); caps->properties = props; - + return caps; } @@ -297,23 +353,92 @@ gst_caps_get_props (GstCaps *caps) } /** - * gst_caps_check_compatibility: - * @fromcaps: a capabilty - * @tocaps: a capabilty + * gst_caps_append: + * @caps: a capabilty + * @capstoadd: the capability to append * - * Checks whether two capabilities are compatible. + * Appends a capability to the existing capability. * - * Returns: TRUE if compatible, FALSE otherwise + * Returns: the new capability */ -gboolean -gst_caps_check_compatibility (GstCaps *fromcaps, GstCaps *tocaps) +GstCaps* +gst_caps_append (GstCaps *caps, GstCaps *capstoadd) +{ + GstCaps *orig = caps; + + g_return_val_if_fail (caps != capstoadd, caps); + + if (caps == NULL) + return capstoadd; + + while (caps->next) { + caps = caps->next; + } + caps->next = capstoadd; + + return orig; +} + +/** + * gst_caps_prepend: + * @caps: a capabilty + * @capstoadd: a capabilty to prepend + * + * prepend the capability to the list of capabilities + * + * Returns: the new capability + */ +GstCaps* +gst_caps_prepend (GstCaps *caps, GstCaps *capstoadd) +{ + GstCaps *orig = capstoadd; + + g_return_val_if_fail (caps != capstoadd, caps); + + if (capstoadd == NULL) + return caps; + + while (capstoadd->next) { + capstoadd = capstoadd->next; + } + capstoadd->next = caps; + + return orig; +} + +/** + * gst_caps_get_by_name: + * @caps: a capabilty + * @name: the name of the capability to get + * + * Get the capability with the given name from this + * chain of capabilities. + * + * Returns: the first capability in the chain with the + * given name + */ +GstCaps* +gst_caps_get_by_name (GstCaps *caps, const gchar *name) +{ + g_return_val_if_fail (caps != NULL, NULL); + g_return_val_if_fail (name != NULL, NULL); + + while (caps) { + if (!strcmp (caps->name, name)) + return caps; + caps = caps->next; + } + + return NULL; +} + +static gboolean +gst_caps_check_compatibility_func (GstCaps *fromcaps, GstCaps *tocaps) { - g_return_val_if_fail (fromcaps != NULL, FALSE); - g_return_val_if_fail (tocaps != NULL, FALSE); - if (fromcaps->id != tocaps->id) { - GST_DEBUG (0,"gstcaps: mime types differ (%d to %d)\n", - fromcaps->id, tocaps->id); + GST_DEBUG (0,"gstcaps: mime types differ (%s to %s)\n", + gst_type_find_by_id (fromcaps->id)->mime, + gst_type_find_by_id (tocaps->id)->mime); return FALSE; } @@ -334,30 +459,44 @@ gst_caps_check_compatibility (GstCaps *fromcaps, GstCaps *tocaps) } /** - * gst_caps_list_check_compatibility: + * gst_caps_check_compatibility: * @fromcaps: a capabilty * @tocaps: a capabilty * - * Checks whether two capability lists are compatible. + * Checks whether two capabilities are compatible. * * Returns: TRUE if compatible, FALSE otherwise */ gboolean -gst_caps_list_check_compatibility (GList *fromcaps, GList *tocaps) +gst_caps_check_compatibility (GstCaps *fromcaps, GstCaps *tocaps) { + if (fromcaps == NULL) { + if (tocaps == NULL) { + GST_DEBUG (0,"gstcaps: no caps\n"); + return TRUE; + } + else { + GST_DEBUG (0,"gstcaps: no src but destination caps\n"); + return FALSE; + } + } + else { + if (tocaps == NULL) { + GST_DEBUG (0,"gstcaps: src caps and no dest caps\n"); + return TRUE; + } + } + while (fromcaps) { - GstCaps *fromcap = (GstCaps *)fromcaps->data; - GList *destcaps = tocaps; + GstCaps *destcaps = tocaps; while (destcaps) { - GstCaps *destcap = (GstCaps *)destcaps->data; - - if (gst_caps_check_compatibility (fromcap, destcap)) + if (gst_caps_check_compatibility_func (fromcaps, destcaps)) return TRUE; - destcaps = g_list_next (destcaps); + destcaps = destcaps->next; } - fromcaps = g_list_next (fromcaps); + fromcaps = fromcaps->next; } return FALSE; } @@ -371,19 +510,24 @@ gst_caps_list_check_compatibility (GList *fromcaps, GList *tocaps) * * Returns: a new XML node pointer */ -xmlNodePtr +xmlNodePtr gst_caps_save_thyself (GstCaps *caps, xmlNodePtr parent) { xmlNodePtr subtree; + xmlNodePtr subsubtree; - g_return_val_if_fail (caps != NULL, NULL); + while (caps) { + subtree = xmlNewChild (parent, NULL, "capscomp", NULL); - xmlNewChild (parent, NULL, "name", caps->name); - xmlNewChild (parent, NULL, "type", gst_type_find_by_id (caps->id)->mime); - if (caps->properties) { - subtree = xmlNewChild (parent, NULL, "properties", NULL); + xmlNewChild (subtree, NULL, "name", caps->name); + xmlNewChild (subtree, NULL, "type", gst_type_find_by_id (caps->id)->mime); + if (caps->properties) { + subsubtree = xmlNewChild (subtree, NULL, "properties", NULL); - gst_props_save_thyself (caps->properties, subtree); + gst_props_save_thyself (caps->properties, subsubtree); + } + + caps = caps->next; } return parent; @@ -397,29 +541,47 @@ gst_caps_save_thyself (GstCaps *caps, xmlNodePtr parent) * * Returns: a new capability */ -GstCaps* +GstCaps* gst_caps_load_thyself (xmlNodePtr parent) { - GstCaps *caps = g_new0 (GstCaps, 1); + GstCaps *result = NULL; xmlNodePtr field = parent->xmlChildrenNode; - gchar *content; while (field) { - if (!strcmp (field->name, "name")) { - caps->name = xmlNodeGetContent (field); - } - if (!strcmp (field->name, "type")) { - content = xmlNodeGetContent (field); - caps->id = get_type_for_mime (content); - g_free (content); - } - else if (!strcmp (field->name, "properties")) { - caps->properties = gst_props_load_thyself (field); + if (!strcmp (field->name, "capscomp")) { + xmlNodePtr subfield = field->xmlChildrenNode; + GstCaps *caps; + gchar *content; + + g_mutex_lock (_gst_caps_chunk_lock); + caps = g_mem_chunk_alloc0 (_gst_caps_chunk); + g_mutex_unlock (_gst_caps_chunk_lock); + + caps->refcount = 1; + caps->lock = g_mutex_new (); + caps->next = NULL; + + while (subfield) { + if (!strcmp (subfield->name, "name")) { + caps->name = xmlNodeGetContent (subfield); + } + if (!strcmp (subfield->name, "type")) { + content = xmlNodeGetContent (subfield); + caps->id = get_type_for_mime (content); + g_free (content); + } + else if (!strcmp (subfield->name, "properties")) { + caps->properties = gst_props_load_thyself (subfield); + } + + subfield = subfield->next; + } + result = gst_caps_append (result, caps); } field = field->next; } - return caps; + return result; } diff --git a/gst/gstcaps.h b/gst/gstcaps.h index 0150b0ffd9..c3c619ec9d 100644 --- a/gst/gstcaps.h +++ b/gst/gstcaps.h @@ -36,41 +36,65 @@ #include typedef struct _GstCaps GstCaps; -typedef gpointer GstCapsFactoryEntry; -typedef GstCapsFactoryEntry GstCapsFactory[]; + +#define GST_CAPS(caps) \ + ((GstCaps *)(caps)) + +#define GST_CAPS_LOCK(caps) (g_mutex_lock(GST_CAPS(caps)->lock)) +#define GST_CAPS_TRYLOCK(caps) (g_mutex_trylock(GST_CAPS(caps)->lock)) +#define GST_CAPS_UNLOCK(caps) (g_mutex_unlock(GST_CAPS(caps)->lock)) struct _GstCaps { gchar *name; /* the name of this caps */ - guint16 id; /* type id (major type) */ + guint refcount; + GMutex *lock; /* global lock for this capability */ + GstProps *properties; /* properties for this capability */ + + GstCaps *next; }; /* initialize the subsystem */ -void _gst_caps_initialize (void); +void _gst_caps_initialize (void); -GstCaps* gst_caps_new (const gchar *name, const gchar *mime); -GstCaps* gst_caps_new_with_props (const gchar *name, const gchar *mime, GstProps *props); -GstCaps* gst_caps_register (GstCapsFactory *factory); -GstCaps* gst_caps_register_count (GstCapsFactory *factory, guint *counter); +GstCaps* gst_caps_new (const gchar *name, const gchar *mime, GstProps *props); + +void gst_caps_unref (GstCaps *caps); +void gst_caps_ref (GstCaps *caps); +void gst_caps_destroy (GstCaps *caps); + +GstCaps* gst_caps_copy (GstCaps *caps); +GstCaps* gst_caps_copy_on_write (GstCaps *caps); const gchar* gst_caps_get_name (GstCaps *caps); -void gst_caps_set_name (GstCaps *caps, const gchar *name); +void gst_caps_set_name (GstCaps *caps, const gchar *name); const gchar* gst_caps_get_mime (GstCaps *caps); -void gst_caps_set_mime (GstCaps *caps, const gchar *mime); +void gst_caps_set_mime (GstCaps *caps, const gchar *mime); -guint16 gst_caps_get_type_id (GstCaps *caps); -void gst_caps_set_type_id (GstCaps *caps, guint16 typeid); +guint16 gst_caps_get_type_id (GstCaps *caps); +void gst_caps_set_type_id (GstCaps *caps, guint16 type_id); GstCaps* gst_caps_set_props (GstCaps *caps, GstProps *props); GstProps* gst_caps_get_props (GstCaps *caps); -gboolean gst_caps_check_compatibility (GstCaps *fromcaps, GstCaps *tocaps); -gboolean gst_caps_list_check_compatibility (GList *fromcaps, GList *tocaps); +#define gst_caps_set(caps, name, args...) gst_props_set ((caps)->properties, name, args) -xmlNodePtr gst_caps_save_thyself (GstCaps *caps, xmlNodePtr parent); -GstCaps* gst_caps_load_thyself (xmlNodePtr parent); +#define gst_caps_get_int(caps, name) gst_props_get_int ((caps)->properties, name) +#define gst_caps_get_fourcc_int(caps, name) gst_props_get_fourcc_int ((caps)->properties, name) +#define gst_caps_get_boolean(caps, name) gst_props_get_boolean ((caps)->properties, name) +#define gst_caps_get_string(caps, name) gst_props_get_string ((caps)->properties, name) + +GstCaps* gst_caps_get_by_name (GstCaps *caps, const gchar *name); + +GstCaps* gst_caps_append (GstCaps *caps, GstCaps *capstoadd); +GstCaps* gst_caps_prepend (GstCaps *caps, GstCaps *capstoadd); + +gboolean gst_caps_check_compatibility (GstCaps *fromcaps, GstCaps *tocaps); + +xmlNodePtr gst_caps_save_thyself (GstCaps *caps, xmlNodePtr parent); +GstCaps* gst_caps_load_thyself (xmlNodePtr parent); #endif /* __GST_CAPS_H__ */ diff --git a/gst/gstcpu.c b/gst/gstcpu.c index 22a77d0897..582bcc43fd 100644 --- a/gst/gstcpu.c +++ b/gst/gstcpu.c @@ -48,29 +48,53 @@ static gchar *stringcat (gchar *a,gchar *b) { return c; } + void _gst_cpu_initialize (void) { gchar *featurelist = NULL; + gboolean AMD; long eax=0, ebx=0, ecx=0, edx=0; + gst_cpuid(0, &eax, &ebx, &ecx, &edx); + + AMD = (ebx == 0x68747541) && (ecx == 0x444d4163) && (edx == 0x69746e65); + gst_cpuid(1, &eax, &ebx, &ecx, &edx); if (edx & (1<<23)) { _gst_cpu_flags |= GST_CPU_FLAG_MMX; featurelist = stringcat(featurelist,"MMX "); - } - if (edx & (1<<25)) { - _gst_cpu_flags |= GST_CPU_FLAG_SSE; - featurelist = stringcat(featurelist,"SSE "); + + if (edx & (1<<25)) { + _gst_cpu_flags |= GST_CPU_FLAG_SSE; + _gst_cpu_flags |= GST_CPU_FLAG_MMXEXT; + featurelist = stringcat(featurelist,"SSE "); + } + + gst_cpuid(0x80000000, &eax, &ebx, &ecx, &edx); + + if (eax >= 0x80000001) { + + gst_cpuid(0x80000001, &eax, &ebx, &ecx, &edx); + + if (edx & (1<<31)) { + _gst_cpu_flags |= GST_CPU_FLAG_3DNOW; + featurelist = stringcat(featurelist,"3DNOW "); + } + if (AMD && (edx & (1<<22))) { + _gst_cpu_flags |= GST_CPU_FLAG_MMXEXT; + featurelist = stringcat(featurelist,"MMXEXT "); + } + } } if (!_gst_cpu_flags) { featurelist = stringcat(featurelist,"NONE"); } - GST_INFO (GST_CAT_GST_INIT, "CPU features: %s",featurelist); + GST_INFO (GST_CAT_GST_INIT, "CPU features: (%08lx) %s",edx, featurelist); g_free(featurelist); } diff --git a/gst/gstcpu.h b/gst/gstcpu.h index f31e709256..e79b9c916a 100644 --- a/gst/gstcpu.h +++ b/gst/gstcpu.h @@ -27,6 +27,8 @@ typedef enum { GST_CPU_FLAG_MMX = (1<<0), GST_CPU_FLAG_SSE = (1<<1), + GST_CPU_FLAG_MMXEXT = (1<<2), + GST_CPU_FLAG_3DNOW = (1<<3), } GstCPUFlags; void _gst_cpu_initialize (void); diff --git a/gst/gstelement.c b/gst/gstelement.c index 77b68ec46d..ccb843e591 100644 --- a/gst/gstelement.c +++ b/gst/gstelement.c @@ -27,6 +27,7 @@ #include "gstextratypes.h" #include "gstbin.h" #include "gstscheduler.h" +#include "gstutils.h" /* Element signals and args */ @@ -471,14 +472,14 @@ gst_element_get_padtemplate_by_compatible (GstElement *element, GstPadTemplate * if (padtempl->direction == GST_PAD_SRC && compattempl->direction == GST_PAD_SINK) { GST_DEBUG(0,"compatible direction: found src pad template\n"); - compat = gst_caps_list_check_compatibility(padtempl->caps, - compattempl->caps); + compat = gst_caps_check_compatibility(GST_PADTEMPLATE_CAPS (padtempl), + GST_PADTEMPLATE_CAPS (compattempl)); GST_DEBUG(0,"caps are %scompatible\n", (compat?"":"not ")); } else if (padtempl->direction == GST_PAD_SINK && compattempl->direction == GST_PAD_SRC) { GST_DEBUG(0,"compatible direction: found sink pad template\n"); - compat = gst_caps_list_check_compatibility(compattempl->caps, - padtempl->caps); + compat = gst_caps_check_compatibility(GST_PADTEMPLATE_CAPS (compattempl), + GST_PADTEMPLATE_CAPS (padtempl)); GST_DEBUG(0,"caps are %scompatible\n", (compat?"":"not ")); } @@ -529,7 +530,7 @@ gst_element_request_compatible_pad (GstElement *element, GstPadTemplate *templ) g_return_val_if_fail (templ != NULL, NULL); templ_new = gst_element_get_padtemplate_by_compatible (element, templ); - if (templ_new != NULL) + if (templ_new != NULL) pad = gst_element_request_pad (element, templ_new); return pad; @@ -775,8 +776,12 @@ gst_element_change_state (GstElement *element) GST_DEBUG (GST_CAT_STATES, "default handler sets '%s' state to %s\n", GST_ELEMENT_NAME (element), _gst_print_statename(GST_STATE_PENDING(element))); - if (GST_STATE_TRANSITION(element) == GST_STATE_READY_TO_PLAYING) + if (GST_STATE_TRANSITION(element) == GST_STATE_READY_TO_PLAYING) { + if (GST_ELEMENT_PARENT(element)) + fprintf(stderr,"READY->PLAYING: element \"%s\" has parent \"%s\" and sched %p\n", +GST_ELEMENT_NAME(element),GST_ELEMENT_NAME(GST_ELEMENT_PARENT(element)),GST_ELEMENT_SCHED(element)); GST_SCHEDULE_ENABLE_ELEMENT (element->sched,element); + } else if (GST_STATE_TRANSITION(element) == GST_STATE_PLAYING_TO_READY) GST_SCHEDULE_DISABLE_ELEMENT (element->sched,element); @@ -925,13 +930,15 @@ gst_element_save_thyself (GstObject *object, type = gtk_type_parent (type); } - pads = element->pads; + pads = GST_ELEMENT_PADS (element); + while (pads) { GstPad *pad = GST_PAD (pads->data); - xmlNodePtr padtag = xmlNewChild (parent, NULL, "pad", NULL); // figure out if it's a direct pad or a ghostpad - if (GST_ELEMENT (GST_OBJECT_PARENT (pad)) == element) + if (GST_ELEMENT (GST_OBJECT_PARENT (pad)) == element) { + xmlNodePtr padtag = xmlNewChild (parent, NULL, "pad", NULL); gst_object_save_thyself (GST_OBJECT (pad), padtag); + } pads = g_list_next (pads); } @@ -996,78 +1003,7 @@ gst_element_load_thyself (xmlNodePtr self, GstObject *parent) } child = child->next; } - if (name && value) { - GtkType type = GTK_OBJECT_TYPE (element); - GtkArgInfo *info; - gchar *result; - - result = gtk_object_arg_get_info (type, name, &info); - - if (result) { - g_print("gstelement: %s\n", result); - } - else if (info->arg_flags & GTK_ARG_WRITABLE) { - switch (info->type) { - case GTK_TYPE_STRING: - gtk_object_set (GTK_OBJECT (element), name, value, NULL); - break; - case GTK_TYPE_INT: { - gint i; - sscanf (value, "%d", &i); - gtk_object_set (GTK_OBJECT (element), name, i, NULL); - break; - } - case GTK_TYPE_LONG: { - glong i; - sscanf (value, "%ld", &i); - gtk_object_set (GTK_OBJECT (element), name, i, NULL); - break; - } - case GTK_TYPE_ULONG: { - gulong i; - sscanf (value, "%lu", &i); - gtk_object_set (GTK_OBJECT (element), name, i, NULL); - break; - } - case GTK_TYPE_BOOL: { - gboolean i = FALSE; - if (!strcmp ("true", value)) i = TRUE; - gtk_object_set (GTK_OBJECT (element), name, i, NULL); - break; - } - case GTK_TYPE_CHAR: { - gchar i; - sscanf (value, "%c", &i); - gtk_object_set (GTK_OBJECT (element), name, i, NULL); - break; - } - case GTK_TYPE_UCHAR: { - guchar i; - sscanf (value, "%c", &i); - gtk_object_set (GTK_OBJECT (element), name, i, NULL); - break; - } - case GTK_TYPE_FLOAT: { - gfloat i; - sscanf (value, "%f", &i); - gtk_object_set (GTK_OBJECT (element), name, i, NULL); - break; - } - case GTK_TYPE_DOUBLE: { - gdouble i; - sscanf (value, "%g", (float *)&i); - gtk_object_set (GTK_OBJECT (element), name, i, NULL); - break; - } - default: - if (info->type == GST_TYPE_FILENAME) { - gtk_object_set (GTK_OBJECT (element), name, value, NULL); - } - break; - } - - } - } + gst_util_set_object_arg (GTK_OBJECT (element), name, value); } children = children->next; } diff --git a/gst/gstelement.h b/gst/gstelement.h index 69583866be..bc91ab2686 100644 --- a/gst/gstelement.h +++ b/gst/gstelement.h @@ -58,7 +58,7 @@ typedef enum { static inline char *_gst_print_statename(int state) { switch (state) { - case GST_STATE_NONE_PENDING: return "NONE PENDING";break; + case GST_STATE_NONE_PENDING: return "NONE_PENDING";break; case GST_STATE_NULL: return "NULL";break; case GST_STATE_READY: return "READY";break; case GST_STATE_PLAYING: return "PLAYING";break; @@ -102,6 +102,9 @@ typedef enum { /* this element is incable of seeking (FIXME: does this apply to filters?) */ GST_ELEMENT_NO_SEEK, + /***** !!!!! need to have a flag that says that an element must + *not* be an entry into a scheduling chain !!!!! *****/ + /* there is a new loopfunction ready for placement */ GST_ELEMENT_NEW_LOOPFUNC, /* the cothread holding this element needs to be stopped */ @@ -124,6 +127,7 @@ typedef enum { #define GST_ELEMENT_PARENT(obj) (GST_OBJECT_PARENT(obj)) #define GST_ELEMENT_MANAGER(obj) (((GstElement*)(obj))->manager) #define GST_ELEMENT_SCHED(obj) (((GstElement*)(obj))->sched) +#define GST_ELEMENT_PADS(obj) ((obj)->pads) //typedef struct _GstElement GstElement; //typedef struct _GstElementClass GstElementClass; @@ -253,10 +257,10 @@ gboolean gst_elementfactory_can_src_caps (GstElementFactory *factory, GstCaps *caps); gboolean gst_elementfactory_can_sink_caps (GstElementFactory *factory, GstCaps *caps); -gboolean gst_elementfactory_can_src_caps_list (GstElementFactory *factory, - GList *caps); -gboolean gst_elementfactory_can_sink_caps_list (GstElementFactory *factory, - GList *caps); +gboolean gst_elementfactory_can_src_caps (GstElementFactory *factory, + GstCaps *caps); +gboolean gst_elementfactory_can_sink_caps (GstElementFactory *factory, + GstCaps *caps); GstElement* gst_elementfactory_create (GstElementFactory *factory, const gchar *name); diff --git a/gst/gstelementfactory.c b/gst/gstelementfactory.c index 6e31a0d6e2..997cb20553 100644 --- a/gst/gstelementfactory.c +++ b/gst/gstelementfactory.c @@ -30,8 +30,8 @@ /* global list of registered elementfactories */ GList* _gst_elementfactories; -void -_gst_elementfactory_initialize (void) +void +_gst_elementfactory_initialize (void) { _gst_elementfactories = NULL; } @@ -42,8 +42,8 @@ _gst_elementfactory_initialize (void) * * Removes the elementfactory from the global list. */ -void -gst_elementfactory_destroy (GstElementFactory *elementfactory) +void +gst_elementfactory_destroy (GstElementFactory *elementfactory) { g_return_if_fail (elementfactory != NULL); @@ -61,7 +61,7 @@ gst_elementfactory_destroy (GstElementFactory *elementfactory) * Returns: #GstElementFactory if found, NULL otherwise */ GstElementFactory* -gst_elementfactory_find (const gchar *name) +gst_elementfactory_find (const gchar *name) { GList *walk; GstElementFactory *factory; @@ -89,7 +89,7 @@ gst_elementfactory_find (const gchar *name) * Returns: GList of type #GstElementFactory */ GList* -gst_elementfactory_get_list (void) +gst_elementfactory_get_list (void) { return _gst_elementfactories; } @@ -108,12 +108,14 @@ gst_elementfactory_get_list (void) */ GstElementFactory* gst_elementfactory_new (const gchar *name, GtkType type, - GstElementDetails *details) + GstElementDetails *details) { - GstElementFactory *factory = g_new0(GstElementFactory, 1); + GstElementFactory *factory; g_return_val_if_fail(name != NULL, NULL); + factory = g_new0(GstElementFactory, 1); + factory->name = g_strdup(name); factory->type = type; factory->details = details; @@ -138,7 +140,7 @@ gst_elementfactory_new (const gchar *name, GtkType type, */ GstElement * gst_elementfactory_create (GstElementFactory *factory, - const gchar *name) + const gchar *name) { GstElement *element; GstElementClass *oclass; @@ -184,7 +186,7 @@ gst_elementfactory_create (GstElementFactory *factory, * Returns: new #GstElement */ GstElement* -gst_elementfactory_make (const gchar *factoryname, const gchar *name) +gst_elementfactory_make (const gchar *factoryname, const gchar *name) { GstElementFactory *factory; GstElement *element; @@ -220,17 +222,17 @@ gst_elementfactory_add_padtemplate (GstElementFactory *factory, } /** - * gst_elementfactory_can_src_caps_list : + * gst_elementfactory_can_src_caps : * @factory: factory to query - * @caps: the caps list to check + * @caps: the caps to check * - * Checks if the factory can source the given capability list. + * Checks if the factory can source the given capability. * * Returns: true if it can src the capabilities */ gboolean -gst_elementfactory_can_src_caps_list (GstElementFactory *factory, - GList *caps) +gst_elementfactory_can_src_caps (GstElementFactory *factory, + GstCaps *caps) { GList *templates; @@ -243,7 +245,7 @@ gst_elementfactory_can_src_caps_list (GstElementFactory *factory, GstPadTemplate *template = (GstPadTemplate *)templates->data; if (template->direction == GST_PAD_SRC) { - if (gst_caps_list_check_compatibility (template->caps, caps)) + if (gst_caps_check_compatibility (GST_PADTEMPLATE_CAPS (template), caps)) return TRUE; } templates = g_list_next (templates); @@ -253,17 +255,17 @@ gst_elementfactory_can_src_caps_list (GstElementFactory *factory, } /** - * gst_elementfactory_can_sink_caps_list : + * gst_elementfactory_can_sink_caps : * @factory: factory to query - * @caps: the caps list to check + * @caps: the caps to check * - * Checks if the factory can sink the given capability list. + * Checks if the factory can sink the given capability. * * Returns: true if it can sink the capabilities */ gboolean -gst_elementfactory_can_sink_caps_list (GstElementFactory *factory, - GList *caps) +gst_elementfactory_can_sink_caps (GstElementFactory *factory, + GstCaps *caps) { GList *templates; @@ -276,7 +278,7 @@ gst_elementfactory_can_sink_caps_list (GstElementFactory *factory, GstPadTemplate *template = (GstPadTemplate *)templates->data; if (template->direction == GST_PAD_SINK) { - if (gst_caps_list_check_compatibility (caps, template->caps)) + if (gst_caps_check_compatibility (caps, GST_PADTEMPLATE_CAPS (template))) return TRUE; } templates = g_list_next (templates); @@ -285,68 +287,18 @@ gst_elementfactory_can_sink_caps_list (GstElementFactory *factory, return FALSE; } -/** - * gst_elementfactory_can_src_caps : - * @factory: factory to query - * @caps: the caps to check - * - * Checks if the factory can src the given capability. - * - * Returns: true if it can sink the capability - */ -gboolean -gst_elementfactory_can_src_caps (GstElementFactory *factory, - GstCaps *caps) -{ - GList *dummy; - gboolean ret; - - dummy = g_list_prepend (NULL, caps); - - ret = gst_elementfactory_can_src_caps_list (factory, dummy); - - g_list_free (dummy); - - return ret; -} - -/** - * gst_elementfactory_can_sink_caps : - * @factory: factory to query - * @caps: the caps to check - * - * Checks if the factory can sink the given capability. - * - * Returns: true if it can sink the capability - */ -gboolean -gst_elementfactory_can_sink_caps (GstElementFactory *factory, - GstCaps *caps) -{ - GList *dummy; - gboolean ret; - - dummy = g_list_prepend (NULL, caps); - - ret = gst_elementfactory_can_sink_caps_list (factory, dummy); - - g_list_free (dummy); - - return ret; -} - /** * gst_elementfactory_save_thyself: * @factory: factory to save - * @parent: the parent xmlNodePtr + * @parent: the parent xmlNodePtr * * Saves the factory into an XML tree. - * + * * Returns: the new xmlNodePtr */ -xmlNodePtr -gst_elementfactory_save_thyself (GstElementFactory *factory, - xmlNodePtr parent) +xmlNodePtr +gst_elementfactory_save_thyself (GstElementFactory *factory, + xmlNodePtr parent) { GList *pads; @@ -377,14 +329,14 @@ gst_elementfactory_save_thyself (GstElementFactory *factory, /** * gst_elementfactory_load_thyself: - * @parent: the parent xmlNodePtr + * @parent: the parent xmlNodePtr * * Creates a new factory from an xmlNodePtr. - * + * * Returns: the new factory */ GstElementFactory * -gst_elementfactory_load_thyself (xmlNodePtr parent) +gst_elementfactory_load_thyself (xmlNodePtr parent) { GstElementFactory *factory = g_new0(GstElementFactory, 1); xmlNodePtr children = parent->xmlChildrenNode; @@ -415,7 +367,7 @@ gst_elementfactory_load_thyself (xmlNodePtr parent) } if (!strcmp(children->name, "padtemplate")) { GstPadTemplate *template; - + template = gst_padtemplate_load_thyself (children); gst_elementfactory_add_padtemplate (factory, template); diff --git a/gst/gstinfo.c b/gst/gstinfo.c index 3e2994abc7..41c9d9a5ee 100644 --- a/gst/gstinfo.c +++ b/gst/gstinfo.c @@ -60,10 +60,12 @@ static gchar *_gst_info_category_strings[] = { "PIPELINE", "PLUGIN_LOADING", "PLUGIN_ERRORS", + "PLUGIN_INFO", "PROPERTIES", "THREAD", "TYPES", "XML", + "NEGOTIATION", }; /** @@ -94,7 +96,11 @@ gst_default_info_handler (gint category, gchar *file, gchar *function, if (element && GST_IS_ELEMENT (element)) elementname = g_strdup_printf (" [%s]", GST_OBJECT_NAME (element)); +#ifdef GST_DEBUG_ENABLED + fprintf(stderr,"INFO(%d:%d):%s%s %s\n",getpid(),cothread_getcurrent(),location,elementname,string); +#else fprintf(stderr,"INFO:%s%s %s\n",location,elementname,string); +#endif if (location != empty) g_free(location); if (elementname != empty) g_free(elementname); diff --git a/gst/gstinfo.h b/gst/gstinfo.h index cb11ca1ead..aae18933f3 100644 --- a/gst/gstinfo.h +++ b/gst/gstinfo.h @@ -139,7 +139,7 @@ _gst_debug_register_funcptr (void *ptr, gchar *ptrname) static inline gchar * _gst_debug_nameof_funcptr (void *ptr) { - gchar *ptrname = __gst_function_pointers ? g_hash_table_lookup(__gst_function_pointers,ptr) : NULL; + gchar *ptrname = (gchar*)( __gst_function_pointers ? g_hash_table_lookup(__gst_function_pointers,ptr) : NULL ); // FIXME this must go away, it's a major leak if (!ptrname) return g_strdup_printf("%p",ptr); else return ptrname; @@ -271,10 +271,12 @@ enum { GST_CAT_PIPELINE, // Pipeline stuff GST_CAT_PLUGIN_LOADING, // Plugin loading GST_CAT_PLUGIN_ERRORS, // Errors during plugin loading + GST_CAT_PLUGIN_INFO, // Plugin state information GST_CAT_PROPERTIES, // Properties GST_CAT_THREAD, // Thread creation/management GST_CAT_TYPES, // Typing GST_CAT_XML, // XML load/save of everything + GST_CAT_NEGOTIATION, // Caps Negotiation stuff GST_CAT_MAX_CATEGORY, }; diff --git a/gst/gstobject.c b/gst/gstobject.c index 5600037e7f..e7fa7ce21d 100644 --- a/gst/gstobject.c +++ b/gst/gstobject.c @@ -397,13 +397,15 @@ gst_object_get_path_string (GstObject *object) GSList *parentage = NULL; GSList *parents; void *parent; - gchar *prevpath, *path = ""; + gchar *prevpath, *path; const char *component; gchar *separator = ""; gboolean free_component; parentage = g_slist_prepend (NULL, object); + path = g_strdup (""); + // first walk the object hierarchy to build a list of the parents do { if (GST_IS_OBJECT (object)) { @@ -424,9 +426,9 @@ gst_object_get_path_string (GstObject *object) parents = parentage; while (parents) { if (GST_IS_OBJECT (parents->data)) { - GstObjectClass *oclass = GST_OBJECT_CLASS (GTK_OBJECT (parents->data)); + GstObjectClass *oclass = GST_OBJECT_CLASS (GTK_OBJECT (parents->data)->klass); - component = GST_OBJECT_NAME (parents->data); + component = gst_object_get_name (parents->data); separator = oclass->path_string_separator; free_component = FALSE; } else { diff --git a/gst/gstpad.c b/gst/gstpad.c index fc8078e924..154e0e595c 100644 --- a/gst/gstpad.c +++ b/gst/gstpad.c @@ -36,7 +36,6 @@ static void gst_pad_init (GstPad *pad); static xmlNodePtr gst_pad_save_thyself (GstObject *object, xmlNodePtr parent); - static GstObject *pad_parent_class = NULL; GtkType @@ -273,7 +272,6 @@ gst_pad_new_from_template (GstPadTemplate *templ, g_return_val_if_fail (templ != NULL, NULL); pad = gst_pad_new (name, templ->direction); - GST_PAD_CAPS(pad) = templ->caps; GST_PAD_PADTEMPLATE(pad) = templ; return pad; @@ -423,6 +421,45 @@ gst_pad_set_eos_function (GstPad *pad, GST_DEBUG_PAD_NAME(pad),pad,&GST_RPAD_EOSFUNC(pad),eos); } +/** + * gst_pad_set_negotiate_function: + * @pad: the pad to set the negotiate function for + * @nego: the negotiate function + * + * Set the given negotiate function for the pad. + */ +void +gst_pad_set_negotiate_function (GstPad *pad, + GstPadNegotiateFunction nego) +{ + g_return_if_fail (pad != NULL); + g_return_if_fail (GST_IS_REAL_PAD (pad)); + + GST_RPAD_NEGOTIATEFUNC(pad) = nego; + GST_DEBUG (0,"negotiatefunc for %s:%s(@%p) at %p is set to %p\n", + GST_DEBUG_PAD_NAME(pad),pad,&GST_RPAD_NEGOTIATEFUNC(pad),nego); +} + + +/** + * gst_pad_set_newcaps_function: + * @pad: the pad to set the newcaps function for + * @newcaps: the newcaps function + * + * Set the given newcaps function for the pad. + */ +void +gst_pad_set_newcaps_function (GstPad *pad, + GstPadNewCapsFunction newcaps) +{ + g_return_if_fail (pad != NULL); + g_return_if_fail (GST_IS_REAL_PAD (pad)); + + GST_RPAD_NEWCAPSFUNC (pad) = newcaps; + GST_DEBUG (0,"newcapsfunc for %s:%s(@%p) at %p is set to %p\n", + GST_DEBUG_PAD_NAME(pad),pad,&GST_RPAD_NEWCAPSFUNC(pad),newcaps); +} + static void @@ -523,26 +560,32 @@ gst_pad_disconnect (GstPad *srcpad, * @sinkpad: the sink pad to connect * * Connects the source pad to the sink pad. + * + * Returns: TRUE if the pad could be connected */ -void +gboolean gst_pad_connect (GstPad *srcpad, GstPad *sinkpad) { GstRealPad *realsrc, *realsink; GstRealPad *temppad; + gboolean negotiated = FALSE; /* generic checks */ - g_return_if_fail(srcpad != NULL); - g_return_if_fail(GST_IS_PAD(srcpad)); - g_return_if_fail(sinkpad != NULL); - g_return_if_fail(GST_IS_PAD(sinkpad)); + g_return_val_if_fail(srcpad != NULL, FALSE); + g_return_val_if_fail(GST_IS_PAD(srcpad), FALSE); + g_return_val_if_fail(sinkpad != NULL, FALSE); + g_return_val_if_fail(GST_IS_PAD(sinkpad), FALSE); + + GST_INFO (GST_CAT_ELEMENT_PADS, "about to connect %s:%s and %s:%s", + GST_DEBUG_PAD_NAME(srcpad), GST_DEBUG_PAD_NAME(sinkpad)); // now we need to deal with the real/ghost stuff realsrc = GST_PAD_REALIZE(srcpad); realsink = GST_PAD_REALIZE(sinkpad); - g_return_if_fail(GST_RPAD_PEER(realsrc) == NULL); - g_return_if_fail(GST_RPAD_PEER(realsink) == NULL); + g_return_val_if_fail(GST_RPAD_PEER(realsrc) == NULL, FALSE); + g_return_val_if_fail(GST_RPAD_PEER(realsink) == NULL, FALSE); /* check for reversed directions and swap if necessary */ if ((GST_RPAD_DIRECTION(realsrc) == GST_PAD_SINK) && @@ -551,23 +594,14 @@ gst_pad_connect (GstPad *srcpad, realsrc = realsink; realsink = temppad; } - g_return_if_fail((GST_RPAD_DIRECTION(realsrc) == GST_PAD_SRC) && - (GST_RPAD_DIRECTION(realsink) == GST_PAD_SINK)); + g_return_val_if_fail((GST_RPAD_DIRECTION(realsrc) == GST_PAD_SRC) && + (GST_RPAD_DIRECTION(realsink) == GST_PAD_SINK), FALSE); - if (!gst_pad_check_compatibility (srcpad, sinkpad)) { - g_warning ("gstpad: connecting incompatible pads (%s:%s) and (%s:%s)\n", - GST_DEBUG_PAD_NAME (srcpad), GST_DEBUG_PAD_NAME (sinkpad)); - } - else { - GST_DEBUG (0,"gstpad: connecting compatible pads (%s:%s) and (%s:%s)\n", - GST_DEBUG_PAD_NAME (srcpad), GST_DEBUG_PAD_NAME (sinkpad)); - } /* first set peers */ GST_RPAD_PEER(realsrc) = realsink; GST_RPAD_PEER(realsink) = realsrc; - /* set the connected flag */ /* FIXME: set connected flag */ /* fire off a signal to each of the pads telling them that they've been connected */ @@ -582,6 +616,21 @@ gst_pad_connect (GstPad *srcpad, GST_INFO (GST_CAT_ELEMENT_PADS, "connected %s:%s and %s:%s", GST_DEBUG_PAD_NAME(srcpad), GST_DEBUG_PAD_NAME(sinkpad)); + + if (GST_PAD_CAPS (srcpad)) { + negotiated = gst_pad_renegotiate (srcpad); + } + else if (GST_PAD_CAPS (sinkpad)) { + negotiated = gst_pad_renegotiate (sinkpad); + } + else + negotiated = TRUE; + + if (!negotiated) { + gst_pad_disconnect (GST_PAD (realsrc), GST_PAD (realsink)); + return FALSE; + } + return TRUE; } /** @@ -605,6 +654,23 @@ gst_pad_set_parent (GstPad *pad, gst_object_set_parent (GST_OBJECT (pad), parent); } +/** + * gst_pad_get_padtemplate: + * @pad: the pad to get the padtemplate from + * + * Get the padtemplate object of this pad. + * + * Returns: the padtemplate object + */ +GstPadTemplate* +gst_pad_get_padtemplate (GstPad *pad) +{ + g_return_val_if_fail (pad != NULL, NULL); + g_return_val_if_fail (GST_IS_PAD (pad), NULL); + + return GST_PAD_PADTEMPLATE (pad); +} + /** * gst_pad_get_parent: * @pad: the pad to get the parent from @@ -640,6 +706,25 @@ gst_pad_get_sched (GstPad *pad) return GST_RPAD_SCHED(pad); } +/** + * gst_pad_get_real_parent: + * @pad: the pad to get the parent from + * + * Get the real parent object of this pad. If the pad + * is a ghostpad, the actual owner of the real pad is + * returned, as opposed to the gst_pad_get_parent. + * + * Returns: the parent object + */ +GstObject* +gst_pad_get_real_parent (GstPad *pad) +{ + g_return_val_if_fail (pad != NULL, NULL); + g_return_val_if_fail (GST_IS_PAD (pad), NULL); + + return GST_PAD_PARENT (GST_PAD (GST_PAD_REALIZE (pad))); +} + /** * gst_pad_add_ghost_pad: * @pad: the pad to set the ghost parent @@ -705,68 +790,101 @@ gst_pad_get_ghost_pad_list (GstPad *pad) } /** - * gst_pad_set_caps_list: + * gst_pad_set_caps: * @pad: the pad to set the caps to - * @caps: a GList of the capabilities to attach to this pad + * @caps: the capabilities to attach to this pad * * Set the capabilities of this pad. + * + * Returns: a boolean indicating the caps could be set on the pad */ -void -gst_pad_set_caps_list (GstPad *pad, - GList *caps) +gboolean +gst_pad_set_caps (GstPad *pad, + GstCaps *caps) { - g_return_if_fail (pad != NULL); - g_return_if_fail (GST_IS_REAL_PAD (pad)); // NOTE this restriction + g_return_val_if_fail (pad != NULL, FALSE); + g_return_val_if_fail (GST_IS_REAL_PAD (pad), FALSE); // NOTE this restriction + 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)); + + if (caps) + gst_caps_ref (caps); GST_PAD_CAPS(pad) = caps; + + return gst_pad_renegotiate (pad); } /** - * gst_pad_get_caps_list: + * gst_pad_get_caps: + * @pad: the pad to get the capabilities from + * + * Get the capabilities of this pad. + * + * Returns: the capabilities of this pad + */ +GstCaps* +gst_pad_get_caps (GstPad *pad) +{ + g_return_val_if_fail (pad != NULL, NULL); + g_return_val_if_fail (GST_IS_PAD (pad), NULL); + + if (GST_PAD_CAPS (pad)) + return GST_PAD_CAPS (pad); + else if (GST_PAD_PADTEMPLATE (pad)) + return GST_PADTEMPLATE_CAPS (GST_PAD_PADTEMPLATE (pad)); + + return NULL; +} + +/** + * gst_pad_get_padtemplate_caps: * @pad: the pad to get the capabilities from * * Get the capabilities of this pad. * * Returns: a list of the capabilities of this pad */ -GList * -gst_pad_get_caps_list (GstPad *pad) +GstCaps* +gst_pad_get_padtemplate_caps (GstPad *pad) { g_return_val_if_fail (pad != NULL, NULL); g_return_val_if_fail (GST_IS_PAD (pad), NULL); - return GST_PAD_CAPS(pad); + if (GST_PAD_PADTEMPLATE (pad)) + return GST_PADTEMPLATE_CAPS (GST_PAD_PADTEMPLATE (pad)); + + return NULL; } + /** - * gst_pad_get_caps_by_name: - * @pad: the pad to get the capabilities from + * gst_padtemplate_get_caps_by_name: + * @templ: the padtemplate to get the capabilities from * @name: the name of the capability to get * - * Get the capabilities with the given name from this pad. + * Get the capability with the given name from this padtemplate. * * Returns: a capability or NULL if not found */ -GstCaps * -gst_pad_get_caps_by_name (GstPad *pad, gchar *name) +GstCaps* +gst_padtemplate_get_caps_by_name (GstPadTemplate *templ, const gchar *name) { - GList *caps; + GstCaps *caps; - g_return_val_if_fail (pad != NULL, NULL); - g_return_val_if_fail (GST_IS_PAD (pad), NULL); + g_return_val_if_fail (templ != NULL, NULL); - caps = GST_PAD_CAPS(pad); + caps = GST_PADTEMPLATE_CAPS (templ); + if (!caps) + return NULL; - while (caps) { - GstCaps *cap = (GstCaps *)caps->data; - - if (!strcmp (cap->name, name)) - return cap; - - caps = g_list_next (caps); - } - - return NULL; + return gst_caps_get_by_name (caps, name); } /** @@ -782,18 +900,13 @@ gst_pad_get_caps_by_name (GstPad *pad, gchar *name) gboolean gst_pad_check_compatibility (GstPad *srcpad, GstPad *sinkpad) { - GstRealPad *realsrc, *realsink; - g_return_val_if_fail (srcpad != NULL, FALSE); g_return_val_if_fail (GST_IS_PAD (srcpad), FALSE); g_return_val_if_fail (sinkpad != NULL, FALSE); g_return_val_if_fail (GST_IS_PAD (sinkpad), FALSE); - realsrc = GST_PAD_REALIZE(srcpad); - realsink = GST_PAD_REALIZE(sinkpad); - - if (GST_RPAD_CAPS(realsrc) && GST_RPAD_CAPS(realsink)) { - if (!gst_caps_list_check_compatibility (GST_RPAD_CAPS(realsrc), GST_RPAD_CAPS(realsink))) { + if (GST_PAD_CAPS(srcpad) && GST_PAD_CAPS(sinkpad)) { + if (!gst_caps_check_compatibility (GST_PAD_CAPS(srcpad), GST_PAD_CAPS(sinkpad))) { return FALSE; } else { @@ -801,8 +914,9 @@ gst_pad_check_compatibility (GstPad *srcpad, GstPad *sinkpad) } } else { - GST_DEBUG (0,"gstpad: could not check capabilities of pads (%s:%s) and (%s:%s)\n", - GST_DEBUG_PAD_NAME (srcpad), GST_DEBUG_PAD_NAME (sinkpad)); + GST_DEBUG (0,"gstpad: could not check capabilities of pads (%s:%s) and (%s:%s) %p %p\n", + GST_DEBUG_PAD_NAME (srcpad), GST_DEBUG_PAD_NAME (sinkpad), + GST_PAD_CAPS (srcpad), GST_PAD_CAPS (sinkpad)); return TRUE; } } @@ -848,7 +962,7 @@ void gst_pad_load_and_connect (xmlNodePtr self, GstObject *parent) { - xmlNodePtr field = self->childs; + xmlNodePtr field = self->xmlChildrenNode; GstPad *pad = NULL, *targetpad; guchar *peer = NULL; gchar **split; @@ -893,6 +1007,225 @@ cleanup: g_strfreev (split); } +static gboolean +gst_pad_renegotiate_func (GstPad *pad, gpointer *data1, GstPad *peerpad, gpointer *data2, GstCaps **newcaps) +{ + GstRealPad *currentpad, *otherpad; + gpointer *currentdata, *otherdata; + GstPadNegotiateReturn result; + gint counter = 0; + + g_return_val_if_fail (pad != NULL, FALSE); + + currentpad = GST_PAD_REALIZE (pad); + otherpad = GST_REAL_PAD (peerpad); + currentdata = data1; + otherdata = data2; + + GST_DEBUG (GST_CAT_NEGOTIATION, "negotiating pad %s:%s and %s:%s data:%p\n", + GST_DEBUG_PAD_NAME(currentpad), GST_DEBUG_PAD_NAME(otherpad), currentdata); + + do { + gboolean matchtempl; + + if (!*newcaps) { + if (otherpad->negotiatefunc) { + GstRealPad *temp; + gpointer *tempdata; + + GST_DEBUG (GST_CAT_NEGOTIATION, "requesting other caps from pad %s:%s data:%p\n", + GST_DEBUG_PAD_NAME(otherpad), otherdata); + otherpad->negotiatefunc (GST_PAD (otherpad), newcaps, otherdata); + + temp = otherpad; + otherpad = currentpad; + currentpad = temp; + + tempdata = otherdata; + otherdata = currentdata; + currentdata = tempdata; + } + } + + GST_DEBUG (GST_CAT_NEGOTIATION, "checking compatibility with pad %s:%s\n", + GST_DEBUG_PAD_NAME(otherpad)); + matchtempl = gst_caps_check_compatibility (*newcaps, gst_pad_get_padtemplate_caps (GST_PAD (otherpad))); + + GST_DEBUG (GST_CAT_NEGOTIATION, "caps compatibility check %s\n", (matchtempl?"ok":"fail")); + + if (matchtempl) { + GST_DEBUG (GST_CAT_NEGOTIATION, "checking if other pad %s:%s can negotiate data:%p\n", + GST_DEBUG_PAD_NAME(otherpad), otherdata); + if (otherpad->negotiatefunc) { + GstRealPad *temp; + gpointer *tempdata; + + GST_DEBUG (GST_CAT_NEGOTIATION, "switching pad for next phase\n"); + + temp = currentpad; + currentpad = otherpad; + otherpad = temp; + + tempdata = otherdata; + otherdata = currentdata; + currentdata = tempdata; + } + else if (gst_caps_check_compatibility (*newcaps, GST_PAD_CAPS (otherpad))) { + GST_DEBUG (GST_CAT_NEGOTIATION, "negotiation succeeded\n"); + return TRUE; + } + else { + *newcaps = GST_PAD_CAPS (otherpad); + if (*newcaps) gst_caps_ref(*newcaps); + } + } + else { + *newcaps = GST_PAD_CAPS (otherpad); + if (*newcaps) gst_caps_ref(*newcaps); + } + + counter++; + + if (currentpad->negotiatefunc) { + GST_DEBUG (GST_CAT_NEGOTIATION, "calling negotiate function on pad %s:%s data: %p\n", + GST_DEBUG_PAD_NAME (currentpad), currentdata); + result = currentpad->negotiatefunc (GST_PAD (currentpad), newcaps, currentdata); + + switch (result) { + case GST_PAD_NEGOTIATE_FAIL: + GST_DEBUG (GST_CAT_NEGOTIATION, "negotiation failed\n"); + return FALSE; + case GST_PAD_NEGOTIATE_AGREE: + GST_DEBUG (GST_CAT_NEGOTIATION, "negotiation succeeded\n"); + return TRUE; + case GST_PAD_NEGOTIATE_TRY: + GST_DEBUG (GST_CAT_NEGOTIATION, "try another option\n"); + break; + default: + GST_DEBUG (GST_CAT_NEGOTIATION, "invalid return\n"); + break; + } + } + else { + GST_DEBUG (GST_CAT_NEGOTIATION, "negotiation failed, no more options\n"); + return FALSE; + } + + } while (counter < 100); + + g_warning ("negotiation between (%s:%s) and (%s:%s) failed: too many attempts (%d)\n", + GST_DEBUG_PAD_NAME(pad), GST_DEBUG_PAD_NAME(peerpad), counter); + + GST_DEBUG (GST_CAT_NEGOTIATION, "negotiation failed, too many attempts\n"); + + return FALSE; +} + +/** + * gst_pad_renegotiate: + * @pad: the pad to perform the negotiation on + * + * Perform the negotiation process with the peer pad. + * + * Returns: TRUE if the negotiation process succeded + */ +gboolean +gst_pad_renegotiate (GstPad *pad) +{ + GstCaps *newcaps = NULL; + GstRealPad *peerpad, *currentpad, *otherpad; + gboolean result; + gpointer data1 = NULL, data2 = NULL; + + g_return_val_if_fail (pad != NULL, FALSE); + + peerpad = GST_PAD_PEER (pad); + + currentpad = GST_PAD_REALIZE (pad); + + if (!peerpad) { + GST_DEBUG (GST_CAT_NEGOTIATION, "no peer pad for pad %s:%s\n", + GST_DEBUG_PAD_NAME(currentpad)); + return TRUE; + } + + otherpad = GST_REAL_PAD (peerpad); + + GST_INFO (GST_CAT_NEGOTIATION, "negotiating pad %s:%s and %s:%s", + GST_DEBUG_PAD_NAME(pad), GST_DEBUG_PAD_NAME(peerpad)); + + newcaps = GST_PAD_CAPS (pad); + + result = gst_pad_renegotiate_func (GST_PAD (currentpad), &data1, GST_PAD (otherpad), &data2, &newcaps); + + if (result) { + 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; + if (GST_RPAD_NEWCAPSFUNC (currentpad)) + GST_RPAD_NEWCAPSFUNC (currentpad) (GST_PAD (currentpad), newcaps); + + GST_PAD_CAPS (otherpad) = newcaps; + if (GST_RPAD_NEWCAPSFUNC (otherpad)) + GST_RPAD_NEWCAPSFUNC (otherpad) (GST_PAD (otherpad), newcaps); + } + + return result; +} + +/** + * gst_pad_negotiate_proxy: + * @srcpad: the pad that proxies + * @destpad: the pad to proxy the negotiation to + * @caps: the current caps + * + * Proxies the negotiation pad from srcpad to destpad. Further + * negotiation is done on the peers of both pad instead. + * + * Returns: the result of the negotiation preocess. + */ +GstPadNegotiateReturn +gst_pad_negotiate_proxy (GstPad *srcpad, GstPad *destpad, GstCaps **caps) +{ + GstRealPad *srcpeer; + GstRealPad *destpeer; + gboolean result; + gpointer data1 = NULL, data2 = NULL; + + g_return_val_if_fail (srcpad != NULL, GST_PAD_NEGOTIATE_FAIL); + g_return_val_if_fail (destpad != NULL, GST_PAD_NEGOTIATE_FAIL); + + GST_DEBUG (GST_CAT_NEGOTIATION, "negotiation proxied from pad (%s:%s) to pad (%s:%s)\n", + GST_DEBUG_PAD_NAME (srcpad), GST_DEBUG_PAD_NAME (destpad)); + + srcpeer = GST_RPAD_PEER (srcpad); + destpeer = GST_RPAD_PEER (destpad); + + if (srcpeer && destpeer) { + result = gst_pad_renegotiate_func (GST_PAD (srcpeer), &data1, GST_PAD (destpeer), &data2, caps); + + if (result) { + GST_DEBUG (GST_CAT_NEGOTIATION, "pads (%s:%s) and (%s:%s) aggreed on caps :)\n", + GST_DEBUG_PAD_NAME (srcpad), GST_DEBUG_PAD_NAME (destpad)); + + /* here we have some sort of aggreement of the caps */ + GST_PAD_CAPS (destpeer) = *caps; + if (GST_RPAD_NEWCAPSFUNC (destpeer)) + GST_RPAD_NEWCAPSFUNC (destpeer) (GST_PAD (destpeer), *caps); + + GST_PAD_CAPS (destpad) = *caps; + if (GST_RPAD_NEWCAPSFUNC (destpad)) + GST_RPAD_NEWCAPSFUNC (destpad) (GST_PAD (destpad), *caps); + } + else { + GST_DEBUG (GST_CAT_NEGOTIATION, "pads did not aggree on caps :(\n"); + return GST_PAD_NEGOTIATE_FAIL; + } + } + + return GST_PAD_NEGOTIATE_AGREE; +} /** * gst_pad_save_thyself: @@ -956,22 +1289,49 @@ gst_pad_ghost_save_thyself (GstPad *pad, } #ifndef gst_pad_push -void gst_pad_push(GstPad *pad,GstBuffer *buf) { - GstRealPad *peer = GST_RPAD_PEER(pad); - GST_DEBUG_ENTER("(%s:%s)",GST_DEBUG_PAD_NAME(pad)); +/** + * gst_pad_push: + * @pad: the pad to push + * @buf: the buffer to push + * + * Push a buffer to the peer of the pad. + */ +void +gst_pad_push (GstPad *pad, GstBuffer *buf) +{ + GstRealPad *peer = GST_RPAD_PEER (pad); + + g_return_if_fail (peer != NULL); + + GST_DEBUG_ENTER ("(%s:%s)", GST_DEBUG_PAD_NAME (pad)); + if (peer->pushfunc) { - GST_DEBUG (0,"calling pushfunc &%s of peer pad %s:%s\n", - GST_DEBUG_FUNCPTR_NAME(peer->pushfunc),GST_DEBUG_PAD_NAME(((GstPad*)peer))); - (peer->pushfunc)(((GstPad*)peer),buf); + GST_DEBUG (0, "calling pushfunc &%s of peer pad %s:%s\n", + GST_DEBUG_FUNCPTR_NAME (peer->pushfunc), GST_DEBUG_PAD_NAME (((GstPad*)peer))); + (peer->pushfunc) (((GstPad*)peer), buf); } else - GST_DEBUG (0,"no pushfunc\n"); + GST_DEBUG (0, "no pushfunc\n"); } #endif #ifndef gst_pad_pull -GstBuffer *gst_pad_pull(GstPad *pad) { +/** + * gst_pad_pull: + * @pad: the pad to pull + * + * Pull a buffer from the peer pad. + * + * Returns: a new buffer from the peer pad. + */ +GstBuffer* +gst_pad_pull (GstPad *pad) +{ GstRealPad *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->pullfunc) { GST_DEBUG (0,"calling pullfunc &%s (@%p) of peer pad %s:%s\n", GST_DEBUG_FUNCPTR_NAME(peer->pullfunc),&peer->pullfunc,GST_DEBUG_PAD_NAME(((GstPad*)peer))); @@ -984,9 +1344,29 @@ GstBuffer *gst_pad_pull(GstPad *pad) { #endif #ifndef gst_pad_pullregion -GstBuffer *gst_pad_pullregion(GstPad *pad,GstRegionType type,guint64 offset,guint64 len) { +/** + * gst_pad_pullregion: + * @pad: the pad to pull the region from + * @type: the regiontype + * @offset: the offset/start of the buffer to pull + * @len: the length of the buffer to pull + * + * Pull a buffer region from the peer pad. The region to pull can be + * specified with a offset/lenght pair or with a start/legnth time + * indicator as specified by the type parameter. + * + * Returns: a new buffer from the peer pad with data in the specified + * region. + */ +GstBuffer* +gst_pad_pullregion (GstPad *pad, GstRegionType type, guint64 offset, guint64 len) +{ GstRealPad *peer = GST_RPAD_PEER(pad); + + g_return_val_if_fail (peer != NULL, NULL); + GST_DEBUG_ENTER("(%s:%s,%d,%lld,%lld)",GST_DEBUG_PAD_NAME(pad),type,offset,len); + if (peer->pullregionfunc) { GST_DEBUG (0,"calling pullregionfunc &%s of peer pad %s:%s\n", GST_DEBUG_FUNCPTR_NAME(peer->pullregionfunc),GST_DEBUG_PAD_NAME(((GstPad*)peer))); @@ -1003,46 +1383,64 @@ GstBuffer *gst_pad_pullregion(GstPad *pad,GstRegionType type,guint64 offset,guin * templates * */ +static void gst_padtemplate_class_init (GstPadTemplateClass *klass); +static void gst_padtemplate_init (GstPadTemplate *templ); -/** - * gst_padtemplate_new: - * @factory: the padfactory to use - * - * Creates a new padtemplate from the factory. - * - * Returns: the new padtemplate - */ -GstPadTemplate* -gst_padtemplate_new (GstPadFactory *factory) +enum { + TEMPL_PAD_CREATED, + /* FILL ME */ + TEMPL_LAST_SIGNAL +}; + +static GstObject *padtemplate_parent_class = NULL; +static guint gst_padtemplate_signals[TEMPL_LAST_SIGNAL] = { 0 }; + +GtkType +gst_padtemplate_get_type (void) { - GstPadTemplate *new; - GstPadFactoryEntry tag; - gint i = 0; - guint counter = 0; + static GtkType padtemplate_type = 0; - g_return_val_if_fail (factory != NULL, NULL); - - new = g_new0 (GstPadTemplate, 1); - - tag = (*factory)[i++]; - g_return_val_if_fail (tag != NULL, new); - new->name_template = g_strdup ((gchar *)tag); - - tag = (*factory)[i++]; - new->direction = GPOINTER_TO_UINT (tag); - - tag = (*factory)[i++]; - new->presence = GPOINTER_TO_UINT (tag); - - tag = (*factory)[i++]; - - while (GPOINTER_TO_INT (tag) == 1) { - new->caps = g_list_append (new->caps, gst_caps_register_count ((GstCapsFactory *)&(*factory)[i], &counter)); - i+=counter; - tag = (*factory)[i++]; + if (!padtemplate_type) { + static const GtkTypeInfo padtemplate_info = { + "GstPadTemplate", + sizeof(GstPadTemplate), + sizeof(GstPadTemplateClass), + (GtkClassInitFunc)gst_padtemplate_class_init, + (GtkObjectInitFunc)gst_padtemplate_init, + (GtkArgSetFunc)NULL, + (GtkArgGetFunc)NULL, + (GtkClassInitFunc)NULL, + }; + padtemplate_type = gtk_type_unique(GST_TYPE_OBJECT,&padtemplate_info); } + return padtemplate_type; +} - return new; +static void +gst_padtemplate_class_init (GstPadTemplateClass *klass) +{ + GtkObjectClass *gtkobject_class; + GstObjectClass *gstobject_class; + + gtkobject_class = (GtkObjectClass*)klass; + gstobject_class = (GstObjectClass*)klass; + + padtemplate_parent_class = gtk_type_class(GST_TYPE_OBJECT); + + gst_padtemplate_signals[TEMPL_PAD_CREATED] = + gtk_signal_new ("pad_created", GTK_RUN_LAST, gtkobject_class->type, + GTK_SIGNAL_OFFSET (GstPadTemplateClass, pad_created), + gtk_marshal_NONE__POINTER, GTK_TYPE_NONE, 1, + GST_TYPE_PAD); + + gtk_object_class_add_signals (gtkobject_class, gst_padtemplate_signals, TEMPL_LAST_SIGNAL); + + gstobject_class->path_string_separator = "*"; +} + +static void +gst_padtemplate_init (GstPadTemplate *templ) +{ } /** @@ -1057,22 +1455,50 @@ gst_padtemplate_new (GstPadFactory *factory) * Returns: the new padtemplate */ GstPadTemplate* -gst_padtemplate_create (gchar *name_template, - GstPadDirection direction, GstPadPresence presence, - GList *caps) +gst_padtemplate_new (gchar *name_template, + GstPadDirection direction, GstPadPresence presence, + GstCaps *caps, ...) { GstPadTemplate *new; + va_list var_args; + GstCaps *thecaps = NULL; - new = g_new0 (GstPadTemplate, 1); + g_return_val_if_fail (name_template != NULL, NULL); - new->name_template = name_template; - new->direction = direction; - new->presence = presence; - new->caps = caps; + new = gtk_type_new (gst_padtemplate_get_type ()); + + GST_PADTEMPLATE_NAME_TEMPLATE (new) = name_template; + GST_PADTEMPLATE_DIRECTION (new) = direction; + GST_PADTEMPLATE_PRESENCE (new) = presence; + + va_start (var_args, caps); + + while (caps) { + thecaps = gst_caps_append (thecaps, caps); + caps = va_arg (var_args, GstCaps*); + } + va_end (var_args); + + GST_PADTEMPLATE_CAPS (new) = thecaps; return new; } +/** + * gst_padtemplate_get_caps: + * @templ: the padtemplate to use + * + * Get the capabilities of the padtemplate + * + * Returns: a GstCaps* + */ +GstCaps* +gst_padtemplate_get_caps (GstPadTemplate *templ) +{ + g_return_val_if_fail (templ != NULL, NULL); + + return GST_PADTEMPLATE_CAPS (templ); +} /** * gst_padtemplate_save_thyself: @@ -1087,9 +1513,10 @@ xmlNodePtr gst_padtemplate_save_thyself (GstPadTemplate *templ, xmlNodePtr parent) { xmlNodePtr subtree; - GList *caps; guchar *presence; + GST_DEBUG (0,"saving padtemplate %s\n", templ->name_template); + xmlNewChild(parent,NULL,"nametemplate", templ->name_template); xmlNewChild(parent,NULL,"direction", (templ->direction == GST_PAD_SINK? "sink":"src")); @@ -1109,14 +1536,9 @@ gst_padtemplate_save_thyself (GstPadTemplate *templ, xmlNodePtr parent) } xmlNewChild(parent,NULL,"presence", presence); - caps = templ->caps; - while (caps) { - GstCaps *cap = (GstCaps *)caps->data; - + if (GST_PADTEMPLATE_CAPS (templ)) { subtree = xmlNewChild (parent, NULL, "caps", NULL); - gst_caps_save_thyself (cap, subtree); - - caps = g_list_next (caps); + gst_caps_save_thyself (GST_PADTEMPLATE_CAPS (templ), subtree); } return parent; @@ -1133,22 +1555,25 @@ gst_padtemplate_save_thyself (GstPadTemplate *templ, xmlNodePtr parent) GstPadTemplate* gst_padtemplate_load_thyself (xmlNodePtr parent) { - xmlNodePtr field = parent->childs; - GstPadTemplate *factory = g_new0 (GstPadTemplate, 1); + xmlNodePtr field = parent->xmlChildrenNode; + GstPadTemplate *factory; + gchar *name_template = NULL; + GstPadDirection direction = GST_PAD_UNKNOWN; + GstPadPresence presence = GST_PAD_ALWAYS; + GstCaps *caps = NULL; while (field) { if (!strcmp(field->name, "nametemplate")) { - factory->name_template = xmlNodeGetContent(field); + name_template = xmlNodeGetContent(field); } if (!strcmp(field->name, "direction")) { gchar *value = xmlNodeGetContent(field); - factory->direction = GST_PAD_UNKNOWN; if (!strcmp(value, "sink")) { - factory->direction = GST_PAD_SINK; + direction = GST_PAD_SINK; } else if (!strcmp(value, "src")) { - factory->direction = GST_PAD_SRC; + direction = GST_PAD_SRC; } g_free (value); } @@ -1156,21 +1581,24 @@ gst_padtemplate_load_thyself (xmlNodePtr parent) gchar *value = xmlNodeGetContent(field); if (!strcmp(value, "always")) { - factory->presence = GST_PAD_ALWAYS; + presence = GST_PAD_ALWAYS; } else if (!strcmp(value, "sometimes")) { - factory->presence = GST_PAD_SOMETIMES; + presence = GST_PAD_SOMETIMES; } else if (!strcmp(value, "request")) { - factory->presence = GST_PAD_REQUEST; + presence = GST_PAD_REQUEST; } g_free (value); } else if (!strcmp(field->name, "caps")) { - factory->caps = g_list_append(factory->caps, gst_caps_load_thyself (field)); + caps = gst_caps_load_thyself (field); } field = field->next; } + + factory = gst_padtemplate_new (name_template, direction, presence, caps, NULL); + return factory; } @@ -1244,23 +1672,6 @@ gst_pad_set_eos(GstPad *pad) return TRUE; } -/* -GstPad * -gst_pad_select(GstPad *nextpad, ...) { - va_list args; - GstPad *pad; - GSList *pads = NULL; - - // construct the list of pads - va_start (args, nextpad); - while ((pad = va_arg (args, GstPad*))) - pads = g_slist_prepend (pads, pad); - va_end (args); - - // now switch to the nextpad -*/ - - /** * gst_pad_set_element_private: * @pad: the pad to set the private data to @@ -1292,13 +1703,6 @@ gst_pad_get_element_private (GstPad *pad) } - - - - - - - /***** ghost pads *****/ static void gst_ghost_pad_class_init (GstGhostPadClass *klass); diff --git a/gst/gstpad.h b/gst/gstpad.h index ca09ff879b..aa253112ba 100644 --- a/gst/gstpad.h +++ b/gst/gstpad.h @@ -26,6 +26,13 @@ #include // NOTE: This is xml-config's fault +// Include compatability defines: if libxml hasn't already defined these, +// we have an old version 1.x +#ifndef xmlChildrenNode +#define xmlChildrenNode childs +#define xmlRootNode root +#endif + #include #include #include @@ -72,19 +79,27 @@ typedef enum { GST_REGION_TIME_LEN, } GstRegionType; +typedef enum { + GST_PAD_NEGOTIATE_FAIL, + GST_PAD_NEGOTIATE_AGREE, + GST_PAD_NEGOTIATE_TRY, +} GstPadNegotiateReturn; + /* this defines the functions used to chain buffers * pad is the sink pad (so the same chain function can be used for N pads) * buf is the buffer being passed */ -typedef void (*GstPadChainFunction) (GstPad *pad,GstBuffer *buf); -typedef GstBuffer *(*GstPadGetFunction) (GstPad *pad); -typedef GstBuffer *(*GstPadGetRegionFunction) (GstPad *pad, GstRegionType type, guint64 offset, guint64 len); -typedef void (*GstPadQoSFunction) (GstPad *pad, glong qos_message); +typedef void (*GstPadChainFunction) (GstPad *pad,GstBuffer *buf); +typedef GstBuffer* (*GstPadGetFunction) (GstPad *pad); +typedef GstBuffer* (*GstPadGetRegionFunction) (GstPad *pad, GstRegionType type, guint64 offset, guint64 len); +typedef void (*GstPadQoSFunction) (GstPad *pad, glong qos_message); -typedef void (*GstPadPushFunction) (GstPad *pad, GstBuffer *buf); -typedef GstBuffer *(*GstPadPullFunction) (GstPad *pad); -typedef GstBuffer *(*GstPadPullRegionFunction) (GstPad *pad, GstRegionType type, guint64 offset, guint64 len); -typedef gboolean (*GstPadEOSFunction) (GstPad *pad); +typedef void (*GstPadPushFunction) (GstPad *pad, GstBuffer *buf); +typedef GstBuffer* (*GstPadPullFunction) (GstPad *pad); +typedef GstBuffer* (*GstPadPullRegionFunction) (GstPad *pad, GstRegionType type, guint64 offset, guint64 len); +typedef gboolean (*GstPadEOSFunction) (GstPad *pad); +typedef GstPadNegotiateReturn (*GstPadNegotiateFunction) (GstPad *pad, GstCaps **caps, gpointer *data); +typedef void (*GstPadNewCapsFunction) (GstPad *pad, GstCaps *caps); typedef enum { GST_PAD_UNKNOWN, @@ -100,11 +115,11 @@ typedef enum { } GstPadFlags; struct _GstPad { - GstObject object; + GstObject object; - gpointer element_private; + gpointer element_private; - GstPadTemplate *padtemplate; /* the template for this pad */ + GstPadTemplate *padtemplate; /* the template for this pad */ }; struct _GstPadClass { @@ -112,33 +127,36 @@ struct _GstPadClass { }; struct _GstRealPad { - GstPad pad; + GstPad pad; - GList *caps; - GstPadDirection direction; + GstCaps *caps; + GstPadDirection direction; - cothread_state *threadstate; + cothread_state *threadstate; - GstRealPad *peer; + GstRealPad *peer; - GstBuffer *bufpen; - GstRegionType regiontype; - guint64 offset; - guint64 len; + GstBuffer *bufpen; + GstRegionType regiontype; + guint64 offset; + guint64 len; - GstPadChainFunction chainfunc; - GstPadGetFunction getfunc; - GstPadGetRegionFunction getregionfunc; - GstPadQoSFunction qosfunc; - GstPadEOSFunction eosfunc; + GstSchedule *sched; - GstPadPushFunction pushfunc; - GstPadPullFunction pullfunc; - GstPadPullRegionFunction pullregionfunc; + GstPadChainFunction chainfunc; + GstPadGetFunction getfunc; + GstPadGetRegionFunction getregionfunc; + GstPadQoSFunction qosfunc; + GstPadEOSFunction eosfunc; + + GstPadPushFunction pushfunc; + GstPadPullFunction pullfunc; + GstPadPullRegionFunction pullregionfunc; + + GstPadNegotiateFunction negotiatefunc; + GstPadNewCapsFunction newcapsfunc; GList *ghostpads; - - GstSchedule *sched; }; struct _GstRealPadClass { @@ -185,6 +203,8 @@ struct _GstGhostPadClass { #define GST_RPAD_PULLREGIONFUNC(pad) (((GstRealPad *)(pad))->pullregionfunc) #define GST_RPAD_QOSFUNC(pad) (((GstRealPad *)(pad))->qosfunc) #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_REGIONTYPE(pad) (((GstRealPad *)(pad))->regiontype) #define GST_RPAD_OFFSET(pad) (((GstRealPad *)(pad))->offset) @@ -200,7 +220,7 @@ struct _GstGhostPadClass { #define GST_PAD_PEER(pad) GST_RPAD_PEER(GST_PAD_REALIZE(pad)) /* Some check functions (unused?) */ -#define GST_PAD_CONNECTED(pad) (GST_IS_REAL_PAD(pad) && GST_REAL_PAD(pad)->peer != NULL) +#define GST_PAD_CONNECTED(pad) (GST_PAD_PEER(pad) != NULL) #define GST_PAD_CAN_PULL(pad) (GST_IS_REAL_PAD(pad) && GST_REAL_PAD(pad)->pullfunc != NULL) @@ -217,13 +237,18 @@ typedef enum { GST_PAD_REQUEST, } GstPadPresence; +#define GST_PADTEMPLATE_NAME_TEMPLATE(templ) (((GstPadTemplate *)(templ))->name_template) +#define GST_PADTEMPLATE_DIRECTION(templ) (((GstPadTemplate *)(templ))->direction) +#define GST_PADTEMPLATE_PRESENCE(templ) (((GstPadTemplate *)(templ))->presence) +#define GST_PADTEMPLATE_CAPS(templ) (((GstPadTemplate *)(templ))->caps) + struct _GstPadTemplate { GstObject object; gchar *name_template; GstPadDirection direction; GstPadPresence presence; - GList *caps; + GstCaps *caps; }; struct _GstPadTemplateClass { @@ -234,20 +259,6 @@ struct _GstPadTemplateClass { }; -/* factory */ -typedef gpointer GstPadFactoryEntry; -typedef GstPadFactoryEntry GstPadFactory[]; - -#define GST_PAD_FACTORY_ALWAYS GINT_TO_POINTER(GST_PAD_ALWAYS) -#define GST_PAD_FACTORY_SOMETIMES GINT_TO_POINTER(GST_PAD_SOMETIMES) -#define GST_PAD_FACTORY_REQUEST GINT_TO_POINTER(GST_PAD_REQUEST) - -#define GST_PAD_FACTORY_SRC GINT_TO_POINTER(GST_PAD_SRC) -#define GST_PAD_FACTORY_SINK GINT_TO_POINTER(GST_PAD_SINK) - -#define GST_PAD_FACTORY_CAPS(a...) GINT_TO_POINTER(1),##a,NULL - - GtkType gst_pad_get_type (void); GtkType gst_real_pad_get_type (void); GtkType gst_ghost_pad_get_type (void); @@ -263,10 +274,12 @@ void gst_pad_set_get_function (GstPad *pad, GstPadGetFunction get); void gst_pad_set_getregion_function (GstPad *pad, GstPadGetRegionFunction getregion); 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_caps_list (GstPad *pad, GList *caps); -GList* gst_pad_get_caps_list (GstPad *pad); -GstCaps* gst_pad_get_caps_by_name (GstPad *pad, gchar *name); +gboolean gst_pad_set_caps (GstPad *pad, GstCaps *caps); +GstCaps* gst_pad_get_caps (GstPad *pad); +GstCaps* gst_pad_get_padtemplate_caps (GstPad *pad); gboolean gst_pad_check_compatibility (GstPad *srcpad, GstPad *sinkpad); void gst_pad_set_element_private (GstPad *pad, gpointer priv); @@ -277,6 +290,7 @@ const gchar* gst_pad_get_name (GstPad *pad); void gst_pad_set_parent (GstPad *pad, GstObject *parent); GstObject* gst_pad_get_parent (GstPad *pad); +GstObject* gst_pad_get_real_parent (GstPad *pad); void gst_pad_set_sched (GstPad *pad, GstSchedule *sched); GstSchedule* gst_pad_get_sched (GstPad *pad); @@ -285,13 +299,18 @@ void gst_pad_add_ghost_pad (GstPad *pad, GstPad *ghostpad); void gst_pad_remove_ghost_pad (GstPad *pad, GstPad *ghostpad); GList* gst_pad_get_ghost_pad_list (GstPad *pad); +GstPadTemplate* gst_pad_get_padtemplate (GstPad *pad); + GstPad* gst_pad_get_peer (GstPad *pad); -void gst_pad_connect (GstPad *srcpad, GstPad *sinkpad); +gboolean gst_pad_connect (GstPad *srcpad, GstPad *sinkpad); void gst_pad_disconnect (GstPad *srcpad, GstPad *sinkpad); +gboolean gst_pad_renegotiate (GstPad *pad); +GstPadNegotiateReturn gst_pad_negotiate_proxy (GstPad *srcpad, GstPad *destpad, GstCaps **caps); + #if 1 -void gst_pad_push (GstPad *pad, GstBuffer *buffer); +void gst_pad_push (GstPad *pad, GstBuffer *buf); #else #define gst_pad_push(pad,buf) G_STMT_START{ \ if ((pad)->peer->pushfunc) ((pad)->peer->pushfunc)((pad)->peer,(buf)); \ @@ -307,8 +326,6 @@ GstBuffer* gst_pad_pullregion (GstPad *pad, GstRegionType type, guint64 offset (((pad)->peer->pullregionfunc) ? ((pad)->peer->pullregionfunc)((pad)->peer,(type),(offset),(len)) : NULL) #endif -GstPad * gst_pad_select (GstPad *nextpad, ...); - #define gst_pad_eos(pad) (GST_RPAD_EOSFUNC(GST_RPAD_PEER(pad))(GST_PAD(GST_RPAD_PEER(pad)))) gboolean gst_pad_set_eos (GstPad *pad); @@ -325,10 +342,12 @@ GstPad * gst_ghost_pad_new (gchar *name,GstPad *pad); /* templates and factories */ GtkType gst_padtemplate_get_type (void); -GstPadTemplate* gst_padtemplate_new (GstPadFactory *factory); -GstPadTemplate* gst_padtemplate_create (gchar *name_template, +GstPadTemplate* gst_padtemplate_new (gchar *name_template, GstPadDirection direction, GstPadPresence presence, - GList *caps); + GstCaps *caps, ...); + +GstCaps* gst_padtemplate_get_caps (GstPadTemplate *templ); +GstCaps* gst_padtemplate_get_caps_by_name (GstPadTemplate *templ, const gchar *name); xmlNodePtr gst_padtemplate_save_thyself (GstPadTemplate *templ, xmlNodePtr parent); GstPadTemplate* gst_padtemplate_load_thyself (xmlNodePtr parent); diff --git a/gst/gstparse.c b/gst/gstparse.c index 11c51a2360..03e8bf9a43 100644 --- a/gst/gstparse.c +++ b/gst/gstparse.c @@ -30,6 +30,7 @@ #include "gstparse.h" #include "gstpipeline.h" #include "gstthread.h" +#include "gstutils.h" typedef struct _gst_parse_priv gst_parse_priv; struct _gst_parse_priv { @@ -180,7 +181,8 @@ if (GST_IS_GHOST_PAD(srcpad)) GST_DEBUG(0,"it's a ghost pad\n"); argval = pos+1; DEBUG("attempting to set argument '%s' to '%s' on element '%s'\n", argname,argval,GST_ELEMENT_NAME(previous)); - gtk_object_set(GTK_OBJECT(previous),argname,argval,NULL); + //gtk_object_set(GTK_OBJECT(previous),argname,argval,NULL); + gst_util_set_object_arg (GTK_OBJECT(previous), argname, argval); g_free(argname); // element or argument, or beginning of bin or thread @@ -321,8 +323,9 @@ gst_parse_launch(const gchar *cmdline,GstBin *parent) gst_parse_priv priv; gchar **argvn; gint newargc; - gint len; - int i,j,k; + gint i; + const gchar *cp, *start, *end; + GSList *string_list = NULL, *slist; priv.bincount = 0; priv.threadcount = 0; @@ -331,46 +334,64 @@ gst_parse_launch(const gchar *cmdline,GstBin *parent) priv.verbose = FALSE; priv.debug = FALSE; - // first walk through quickly and see how many more slots we need - len = strlen(cmdline); - newargc = 1; - for (i=0;i 0) { + // normal argument - copy and add to the list + string_list = g_slist_prepend(string_list, g_strndup(cp, i)); + newargc++; + cp += i; + } + + // skip spaces + while (cp < end && *cp == ' ') + cp++; + + // handle quoted arguments + if (*cp == '"') { + start = ++cp; + + // find matching quote + while (cp < end && *cp != '"') + cp++; + + // make sure we got it + if (cp == end) { + g_warning("gst_parse_launch: Unbalanced quote in command line"); + // FIXME: The list leaks here + return 0; + } + + // copy the string sans quotes + string_list = g_slist_prepend(string_list, g_strndup(start, cp - start)); + newargc++; + cp += 2; // skip the quote aswell + } + + // brackets exist in a separate argument slot + if (*cp && strchr("([{}])", *cp)) { + string_list = g_slist_prepend(string_list, g_strndup(cp, 1)); + newargc++; + cp++; } } // now allocate the new argv array - argvn = g_new0(char *,newargc+1); - GST_DEBUG(0,"supposed to have %d args\n",newargc); + argvn = g_new0(char *,newargc); + GST_DEBUG(0,"got %d args\n",newargc); - // now attempt to construct the new arg list - j = 0;k = 0; - for (i=0;i 0) { - if (cmdline[k] == ' ') k++; - argvn[j] = g_new0(char,(i-k)+1); - memcpy(argvn[j],&cmdline[k],i-k); + // reverse the list and put the strings in the new array + i = newargc; - // catch misparses - if (strlen(argvn[j]) > 0) j++; - } - k = i; + for (slist = string_list; slist; slist = slist->next) + argvn[--i] = slist->data; - // if this is a bracket, construct a word - if ((cmdline[i] != ' ') && (cmdline[i] != '\0')) { - argvn[j++] = g_strdup_printf("%c",cmdline[i]); - k++; - } - } - } + g_slist_free(string_list); // print them out for (i=0;isrc = NULL; - pipeline->sinks = NULL; - GST_ELEMENT_SCHED(pipeline) = gst_schedule_new(GST_ELEMENT(pipeline)); g_print("pipeline's scheduler is %p\n",GST_ELEMENT_SCHED(pipeline)); // gst_element_set_manager(GST_ELEMENT(pipeline),GST_ELEMENT(pipeline)); @@ -120,7 +115,7 @@ gst_pipeline_init (GstPipeline *pipeline) * Returns: newly created GstPipeline */ GstElement* -gst_pipeline_new (guchar *name) +gst_pipeline_new (const guchar *name) { return gst_elementfactory_make ("pipeline", name); } @@ -132,375 +127,6 @@ gst_pipeline_prepare (GstPipeline *pipeline) GST_ELEMENT_NAME(GST_ELEMENT(pipeline))); } -static void -gst_pipeline_have_type (GstElement *sink, GstElement *sink2, gpointer data) -{ - GST_DEBUG (0,"GstPipeline: pipeline have type %p\n", (gboolean *)data); - - *(gboolean *)data = TRUE; -} - -static GstCaps* -gst_pipeline_typefind (GstPipeline *pipeline, 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_pipeline_have_type), &found); - - gst_pad_connect (gst_element_get_pad (element, "src"), - gst_element_get_pad (typefind, "sink")); - - gst_bin_add (GST_BIN (pipeline), typefind); - - //gst_bin_create_plan (GST_BIN (pipeline)); - gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_READY); - gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_PLAYING); - - // keep pushing buffers... the have_type signal handler will set the found flag - while (!found) { - gst_bin_iterate (GST_BIN (pipeline)); - } - - gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_NULL); - - if (found) { - caps = gst_util_get_pointer_arg (GTK_OBJECT (typefind), "caps"); - - gst_pad_set_caps_list (gst_element_get_pad (element, "src"), g_list_prepend (NULL, caps)); - } - - gst_pad_disconnect (gst_element_get_pad (element, "src"), - gst_element_get_pad (typefind, "sink")); - gst_bin_remove (GST_BIN (pipeline), typefind); - gst_object_unref (GST_OBJECT (typefind)); - - return caps; -} - -static gboolean -gst_pipeline_pads_autoplug_func (GstElement *src, GstPad *pad, GstElement *sink) -{ - GList *sinkpads; - gboolean connected = FALSE; - - GST_DEBUG (0,"gstpipeline: autoplug pad connect function for \"%s\" to \"%s\"\n", - GST_ELEMENT_NAME(src), GST_ELEMENT_NAME(sink)); - - sinkpads = gst_element_get_pad_list(sink); - while (sinkpads) { - GstPad *sinkpad = (GstPad *)sinkpads->data; - - // if we have a match, connect the pads - if (gst_pad_get_direction(sinkpad) == GST_PAD_SINK && - !GST_PAD_CONNECTED(sinkpad)) - { - if (gst_caps_list_check_compatibility (gst_pad_get_caps_list(pad), gst_pad_get_caps_list(sinkpad))) { - gst_pad_connect(pad, sinkpad); - GST_DEBUG (0,"gstpipeline: autoconnect pad \"%s\" in element %s <-> ", GST_PAD_NAME (pad), - GST_ELEMENT_NAME(src)); - GST_DEBUG (0,"pad \"%s\" in element %s\n", GST_PAD_NAME (sinkpad), - GST_ELEMENT_NAME(sink)); - connected = TRUE; - break; - } - else { - GST_DEBUG (0,"pads incompatible %s, %s\n", GST_PAD_NAME (pad), GST_PAD_NAME (sinkpad)); - } - } - sinkpads = g_list_next(sinkpads); - } - - if (!connected) { - GST_DEBUG (0,"gstpipeline: no path to sinks for type\n"); - } - return connected; -} - -static void -gst_pipeline_pads_autoplug (GstElement *src, GstElement *sink) -{ - GList *srcpads; - gboolean connected = FALSE; - - srcpads = gst_element_get_pad_list(src); - - while (srcpads && !connected) { - GstPad *srcpad = (GstPad *)srcpads->data; - - if (gst_pad_get_direction(srcpad) == GST_PAD_SRC) - connected = gst_pipeline_pads_autoplug_func (src, srcpad, sink); - - srcpads = g_list_next(srcpads); - } - - if (!connected) { - GST_DEBUG (0,"gstpipeline: delaying pad connections for \"%s\" to \"%s\"\n", - GST_ELEMENT_NAME(src), GST_ELEMENT_NAME(sink)); - gtk_signal_connect(GTK_OBJECT(src),"new_pad", - GTK_SIGNAL_FUNC(gst_pipeline_pads_autoplug_func), sink); - } -} - -/** - * gst_pipeline_add_src: - * @pipeline: the pipeline to add the src to - * @src: the src to add to the pipeline - * - * Adds a src element to the pipeline. This element - * will be used as a src for autoplugging. If you add more - * than one src element, the previously added element will - * be removed. - */ -void -gst_pipeline_add_src (GstPipeline *pipeline, GstElement *src) -{ - g_return_if_fail (pipeline != NULL); - g_return_if_fail (GST_IS_PIPELINE (pipeline)); - g_return_if_fail (src != NULL); - g_return_if_fail (GST_IS_ELEMENT (src)); - - if (pipeline->src) { - printf("gstpipeline: *WARNING* removing previously added element \"%s\"\n", - GST_ELEMENT_NAME(pipeline->src)); - gst_bin_remove(GST_BIN(pipeline), pipeline->src); - } - pipeline->src = src; - gst_bin_add(GST_BIN(pipeline), src); -} - -/** - * gst_pipeline_add_sink: - * @pipeline: the pipeline to add the sink to - * @sink: the sink to add to the pipeline - * - * Adds a sink element to the pipeline. This element - * will be used as a sink for autoplugging. - */ -void -gst_pipeline_add_sink (GstPipeline *pipeline, GstElement *sink) -{ - g_return_if_fail (pipeline != NULL); - g_return_if_fail (GST_IS_PIPELINE (pipeline)); - g_return_if_fail (sink != NULL); - g_return_if_fail (GST_IS_ELEMENT (sink)); - - pipeline->sinks = g_list_prepend (pipeline->sinks, sink); - //gst_bin_add(GST_BIN(pipeline), sink); -} - -/** - * gst_pipeline_autoplug: - * @pipeline: the pipeline to autoplug - * - * Constructs a complete pipeline by automatically - * detecting the plugins needed. - * - * Returns: a gboolean indicating success or failure. - */ -gboolean -gst_pipeline_autoplug (GstPipeline *pipeline) -{ - GList *elements; - GstElement *element, *srcelement = NULL, *sinkelement= NULL; - GList **factories; - GList **base_factories; - GstElementFactory *factory; - GstCaps *src_caps = 0; - guint i, numsinks; - gboolean use_thread = FALSE, have_common = FALSE; - GList *sinkstart; - - g_return_val_if_fail(pipeline != NULL, FALSE); - g_return_val_if_fail(GST_IS_PIPELINE(pipeline), FALSE); - - GST_DEBUG (0,"GstPipeline: autopluging pipeline \"%s\"\n", - GST_ELEMENT_NAME(GST_ELEMENT(pipeline))); - - - // fase 1, run typedetect on the source if needed... - if (!pipeline->src) { - GST_DEBUG (0,"GstPipeline: no source detected, can't autoplug pipeline \"%s\"\n", - GST_ELEMENT_NAME(GST_ELEMENT(pipeline))); - return FALSE; - } - - GST_DEBUG (0,"GstPipeline: source \"%s\" has no MIME type, running typefind...\n", - GST_ELEMENT_NAME(pipeline->src)); - - src_caps = gst_pipeline_typefind(pipeline, pipeline->src); - - if (src_caps) { - GST_DEBUG (0,"GstPipeline: source \"%s\" type found %d\n", GST_ELEMENT_NAME(pipeline->src), - src_caps->id); - } - else { - GST_DEBUG (0,"GstPipeline: source \"%s\" has no type\n", GST_ELEMENT_NAME(pipeline->src)); - return FALSE; - } - - srcelement = pipeline->src; - - elements = pipeline->sinks; - - sinkstart = g_list_copy (elements); - - numsinks = g_list_length(elements); - factories = g_new0(GList *, numsinks); - base_factories = g_new0(GList *, numsinks); - - i = 0; - // fase 2, loop over all the sinks.. - while (elements) { - GstPad *pad; - - element = GST_ELEMENT(elements->data); - - pad = (GstPad *)gst_element_get_pad_list (element)->data; - - base_factories[i] = factories[i] = gst_autoplug_caps_list (g_list_append(NULL,src_caps), -gst_pad_get_caps_list(pad)); - // if we have a succesfull connection, proceed - if (factories[i] != NULL) { - i++; - } - else { - sinkstart = g_list_remove (sinkstart, element); - } - - elements = g_list_next(elements); - } - - while (factories[0]) { - // fase 3: add common elements - factory = (GstElementFactory *)(factories[0]->data); - - // check to other paths for mathing elements (factories) - for (i=1; idata))) { - goto differ; - } - factories[i] = g_list_next(factories[i]); - } - factory = (GstElementFactory *)(factories[0]->data); - - GST_DEBUG (0,"common factory \"%s\"\n", factory->name); - - element = gst_elementfactory_create(factory, factory->name); - gst_bin_add(GST_BIN(pipeline), element); - - gst_pipeline_pads_autoplug(srcelement, element); - - srcelement = element; - - factories[0] = g_list_next(factories[0]); - - have_common = TRUE; - } - -differ: - // loop over all the sink elements - elements = sinkstart; - - i = 0; - while (elements) { - GstElement *thesrcelement = srcelement; - GstElement *thebin = GST_ELEMENT(pipeline); - - if (g_list_length(base_factories[i]) == 0) goto next; - - sinkelement = (GstElement *)elements->data; - - use_thread = have_common; - - while (factories[i] || sinkelement) { - // fase 4: add other elements... - - if (factories[i]) { - factory = (GstElementFactory *)(factories[i]->data); - GST_DEBUG (0,"factory \"%s\"\n", factory->name); - element = gst_elementfactory_create(factory, factory->name); - factories[i] = g_list_next(factories[i]); - } - // we have arived to the final sink element - else { - element = sinkelement; - sinkelement = NULL; - } - - // this element suggests the use of a thread, so we set one up... - if (GST_ELEMENT_IS_THREAD_SUGGESTED(element) || use_thread) { - GstElement *queue; - GList *sinkpads; - GstPad *srcpad, *sinkpad; - - use_thread = FALSE; - - GST_DEBUG (0,"sugest new thread for \"%s\" %08x\n", GST_ELEMENT_NAME (element), GST_FLAGS(element)); - - // create a new queue and add to the previous bin - queue = gst_elementfactory_make("queue", g_strconcat("queue_", GST_ELEMENT_NAME(element), NULL)); - GST_DEBUG (0,"adding element \"%s\"\n", GST_ELEMENT_NAME (element)); - gst_bin_add(GST_BIN(thebin), queue); - - // this will be the new bin for all following elements - thebin = gst_elementfactory_make("thread", g_strconcat("thread_", GST_ELEMENT_NAME(element), NULL)); - - srcpad = gst_element_get_pad(queue, "src"); - - sinkpads = gst_element_get_pad_list(element); - while (sinkpads) { - sinkpad = (GstPad *)sinkpads->data; - - // FIXME connect matching pads, not just the first one... - if (gst_pad_get_direction(sinkpad) == GST_PAD_SINK && - !GST_PAD_CONNECTED(sinkpad)) { - GList *caps = gst_pad_get_caps_list (sinkpad); - - // the queue has the type of the elements it connects - gst_pad_set_caps_list (srcpad, caps); - gst_pad_set_caps_list (gst_element_get_pad(queue, "sink"), caps); - break; - } - sinkpads = g_list_next(sinkpads); - } - gst_pipeline_pads_autoplug(thesrcelement, queue); - - GST_DEBUG (0,"adding element %s\n", GST_ELEMENT_NAME (element)); - gst_bin_add(GST_BIN(thebin), element); - GST_DEBUG (0,"adding element %s\n", GST_ELEMENT_NAME (thebin)); - gst_bin_add(GST_BIN(pipeline), thebin); - thesrcelement = queue; - } - // no thread needed, easy case - else { - GST_DEBUG (0,"adding element %s\n", GST_ELEMENT_NAME (element)); - gst_bin_add(GST_BIN(thebin), element); - } - gst_pipeline_pads_autoplug(thesrcelement, element); - - // this element is now the new source element - thesrcelement = element; - } -next: - elements = g_list_next(elements); - i++; - } - return TRUE; - - GST_DEBUG (0,"GstPipeline: unable to autoplug pipeline \"%s\"\n", - GST_ELEMENT_NAME(GST_ELEMENT(pipeline))); - return FALSE; -} - static GstElementStateReturn gst_pipeline_change_state (GstElement *element) { diff --git a/gst/gstpipeline.h b/gst/gstpipeline.h index 5ab0afe101..27f14e4526 100644 --- a/gst/gstpipeline.h +++ b/gst/gstpipeline.h @@ -50,30 +50,22 @@ typedef struct _GstPipelineClass GstPipelineClass; struct _GstPipeline { GstBin bin; - - GstElement *src; /* we only allow one src element */ - GList *sinks; /* and multiple sinks */ }; struct _GstPipelineClass { GstBinClass parent_class; }; -GtkType gst_pipeline_get_type (void); -GstElement* gst_pipeline_new (guchar *name); -#define gst_pipeline_destroy(pipeline) gst_object_destroy(GST_OBJECT(pipeline)) +GtkType gst_pipeline_get_type (void); +GstElement* gst_pipeline_new (const guchar *name); +#define gst_pipeline_destroy(pipeline) gst_object_destroy(GST_OBJECT(pipeline)) -void gst_pipeline_add_src (GstPipeline *pipeline, GstElement *src); -void gst_pipeline_add_sink (GstPipeline *pipeline, GstElement *sink); - -gboolean gst_pipeline_autoplug (GstPipeline *pipeline); - -void gst_pipeline_iterate (GstPipeline *pipeline); +void gst_pipeline_iterate (GstPipeline *pipeline); #ifdef __cplusplus } #endif /* __cplusplus */ -#endif /* __GST_PIPELINE_H__ */ +#endif /* __GST_PIPELINE_H__ */ diff --git a/gst/gstplugin.c b/gst/gstplugin.c index f6a5d73ad2..2e5362a2ae 100644 --- a/gst/gstplugin.c +++ b/gst/gstplugin.c @@ -66,6 +66,8 @@ _gst_plugin_initialize (void) _gst_libraries = NULL; _gst_libraries_seqno = 0; + /* add the main (installed) library path */ + _gst_plugin_paths = g_list_prepend (_gst_plugin_paths, PLUGINS_DIR); /* if this is set, we add build-directory paths to the list */ #ifdef PLUGINS_USE_SRCDIR @@ -80,17 +82,19 @@ _gst_plugin_initialize (void) PLUGINS_SRCDIR "/gst/elements"); _gst_plugin_paths = g_list_prepend (_gst_plugin_paths, PLUGINS_SRCDIR "/gst/types"); -#else /* PLUGINS_USE_SRCDIR */ - /* add the main (installed) library path */ - _gst_plugin_paths = g_list_prepend (_gst_plugin_paths, PLUGINS_DIR); + _gst_plugin_paths = g_list_prepend (_gst_plugin_paths, + PLUGINS_SRCDIR "/gst/autoplug"); #endif /* PLUGINS_USE_SRCDIR */ doc = xmlParseFile (GST_CONFIG_DIR"/reg.xml"); - if (!doc || strcmp (doc->xmlRootNode->name, "GST-PluginRegistry") || + if (!doc || + !doc->xmlRootNode || + doc->xmlRootNode->name == 0 || + strcmp (doc->xmlRootNode->name, "GST-PluginRegistry") || !plugin_times_older_than(get_time(GST_CONFIG_DIR"/reg.xml"))) { if (_gst_warn_old_registry) - g_warning ("gstplugin: registry needs rebuild\n"); + g_warning ("gstplugin: registry needs rebuild: run gstreamer-register\n"); gst_plugin_load_all (); return; } @@ -99,6 +103,18 @@ _gst_plugin_initialize (void) xmlFreeDoc (doc); } +/** + * gst_plugin_add_path: + * @path: the directory to add to the search path + * + * Add a directory to the path searched for plugins. + */ +void +gst_plugin_add_path (const gchar *path) +{ + _gst_plugin_paths = g_list_prepend (_gst_plugin_paths,g_strdup(path)); +} + static time_t get_time(const char * path) { @@ -214,7 +230,7 @@ gst_plugin_load_all(void) path = _gst_plugin_paths; while (path != NULL) { - GST_DEBUG (GST_CAT_PLUGIN_LOADING,"loading plugins from %s\n",(gchar *)path->data); + GST_INFO (GST_CAT_PLUGIN_LOADING,"loading plugins from %s",(gchar *)path->data); gst_plugin_load_recurse(path->data,NULL); path = g_list_next(path); } @@ -348,6 +364,8 @@ 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))) { GST_INFO (GST_CAT_PLUGIN_LOADING,"plugin \"%s\" loaded: %d elements, %d types", plugin->name,plugin->numelements,plugin->numtypes); @@ -364,7 +382,8 @@ gst_plugin_load_absolute (const gchar *name) } return TRUE; } else if (_gst_plugin_spew) { - gst_info("error loading plugin: %s, reason: %s\n", name, g_module_error()); + // FIXME this should be some standard gst mechanism!!! + g_printerr ("error loading plugin %s, reason: %s\n", name, g_module_error()); } return FALSE; @@ -395,6 +414,8 @@ gst_plugin_new (const gchar *name) plugin->numelements = 0; plugin->types = NULL; plugin->numtypes = 0; + plugin->autopluggers = NULL; + plugin->numautopluggers = 0; plugin->loaded = TRUE; return plugin; @@ -529,15 +550,7 @@ gst_plugin_find (const gchar *name) return NULL; } -/** - * gst_plugin_find_elementfactory: - * @name: name of elementfactory to find - * - * Find a registered elementfactory by name. - * - * Returns: @GstElementFactory if found, NULL if not - */ -GstElementFactory* +static GstElementFactory* gst_plugin_find_elementfactory (const gchar *name) { GList *plugins, *factories; @@ -609,6 +622,77 @@ gst_plugin_load_elementfactory (const gchar *name) return factory; } +static GstAutoplugFactory* +gst_plugin_find_autoplugfactory (const gchar *name) +{ + GList *plugins, *factories; + GstAutoplugFactory *factory; + + g_return_val_if_fail(name != NULL, NULL); + + plugins = _gst_plugins; + while (plugins) { + factories = ((GstPlugin *)(plugins->data))->autopluggers; + while (factories) { + factory = (GstAutoplugFactory*)(factories->data); + if (!strcmp(factory->name, name)) + return (GstAutoplugFactory*)(factory); + factories = g_list_next(factories); + } + plugins = g_list_next(plugins); + } + + return NULL; +} +/** + * gst_plugin_load_autoplugfactory: + * @name: name of autoplugfactory to load + * + * Load a registered autoplugfactory by name. + * + * Returns: @GstAutoplugFactory if loaded, NULL if not + */ +GstAutoplugFactory* +gst_plugin_load_autoplugfactory (const gchar *name) +{ + GList *plugins, *factories; + GstAutoplugFactory *factory = NULL; + GstPlugin *plugin; + + g_return_val_if_fail(name != NULL, NULL); + + plugins = _gst_plugins; + while (plugins) { + plugin = (GstPlugin *)plugins->data; + factories = plugin->autopluggers; + + while (factories) { + factory = (GstAutoplugFactory*)(factories->data); + + if (!strcmp(factory->name,name)) { + if (!plugin->loaded) { + gchar *filename = g_strdup (plugin->filename); + gchar *pluginname = g_strdup (plugin->name); + + GST_INFO (GST_CAT_PLUGIN_LOADING,"loaded autoplugfactory %s from plugin %s",name,plugin->name); + gst_plugin_remove(plugin); + if (!gst_plugin_load_absolute(filename)) { + GST_DEBUG (0,"gstplugin: error loading autoplug factory %s from plugin %s\n", name, pluginname); + } + g_free (pluginname); + g_free (filename); + } + factory = gst_plugin_find_autoplugfactory(name); + return factory; + } + factories = g_list_next(factories); + } + plugins = g_list_next(plugins); + } + + return factory; +} + /** * gst_plugin_load_typefactory: * @mime: name of typefactory to load @@ -696,6 +780,24 @@ gst_plugin_add_type (GstPlugin *plugin, GstTypeFactory *factory) gst_type_register (factory); } +/** + * gst_plugin_add_autoplugger: + * @plugin: plugin to add the autoplugger to + * @factory: the autoplugfactory to add + * + * Add an autoplugfactory to the list of those provided by the plugin. + */ +void +gst_plugin_add_autoplugger (GstPlugin *plugin, GstAutoplugFactory *factory) +{ + g_return_if_fail (plugin != NULL); + g_return_if_fail (factory != NULL); + +// g_print("adding factory to plugin\n"); + plugin->autopluggers = g_list_prepend (plugin->autopluggers, factory); + plugin->numautopluggers++; +} + /** * gst_plugin_get_list: * @@ -704,7 +806,7 @@ gst_plugin_add_type (GstPlugin *plugin, GstTypeFactory *factory) * Returns; a GList of GstPlugin elements */ GList* -gst_plugin_get_list(void) +gst_plugin_get_list (void) { return _gst_plugins; } @@ -721,34 +823,45 @@ xmlNodePtr gst_plugin_save_thyself (xmlNodePtr parent) { xmlNodePtr tree, subtree; - GList *plugins = NULL, *elements = NULL, *types = NULL; + GList *plugins = NULL, *elements = NULL, *types = NULL, *autopluggers = NULL; - plugins = gst_plugin_get_list(); + plugins = gst_plugin_get_list (); while (plugins) { GstPlugin *plugin = (GstPlugin *)plugins->data; - tree = xmlNewChild(parent,NULL,"plugin",NULL); - xmlNewChild(tree,NULL,"name",plugin->name); - xmlNewChild(tree,NULL,"longname",plugin->longname); - xmlNewChild(tree,NULL,"filename",plugin->filename); + + tree = xmlNewChild (parent, NULL, "plugin", NULL); + xmlNewChild (tree, NULL, "name", plugin->name); + xmlNewChild (tree, NULL, "longname", plugin->longname); + xmlNewChild (tree, NULL, "filename", plugin->filename); + types = plugin->types; while (types) { GstTypeFactory *factory = (GstTypeFactory *)types->data; - subtree = xmlNewChild(tree,NULL,"typefactory",NULL); + subtree = xmlNewChild(tree, NULL, "typefactory", NULL); - gst_typefactory_save_thyself(factory, subtree); + gst_typefactory_save_thyself (factory, subtree); - types = g_list_next(types); + types = g_list_next (types); } elements = plugin->elements; while (elements) { GstElementFactory *factory = (GstElementFactory *)elements->data; - subtree = xmlNewChild(tree,NULL,"elementfactory",NULL); + subtree = xmlNewChild (tree, NULL, "elementfactory", NULL); - gst_elementfactory_save_thyself(factory, subtree); + gst_elementfactory_save_thyself (factory, subtree); - elements = g_list_next(elements); + elements = g_list_next (elements); } - plugins = g_list_next(plugins); + autopluggers = plugin->autopluggers; + while (autopluggers) { + GstAutoplugFactory *factory = (GstAutoplugFactory *)autopluggers->data; + subtree = xmlNewChild (tree, NULL, "autoplugfactory", NULL); + + gst_autoplugfactory_save_thyself (factory, subtree); + + autopluggers = g_list_next (autopluggers); + } + plugins = g_list_next (plugins); } return parent; } @@ -764,43 +877,50 @@ gst_plugin_load_thyself (xmlNodePtr parent) { xmlNodePtr kinderen; gint elementcount = 0; + gint autoplugcount = 0; gint typecount = 0; gchar *pluginname; kinderen = parent->xmlChildrenNode; // Dutch invasion :-) while (kinderen) { - if (!strcmp(kinderen->name, "plugin")) { + if (!strcmp (kinderen->name, "plugin")) { xmlNodePtr field = kinderen->xmlChildrenNode; GstPlugin *plugin = g_new0 (GstPlugin, 1); + plugin->elements = NULL; plugin->types = NULL; plugin->loaded = FALSE; while (field) { - if (!strcmp(field->name, "name")) { - pluginname = xmlNodeGetContent(field); - if (gst_plugin_find(pluginname)) { - g_free(pluginname); - g_free(plugin); + if (!strcmp (field->name, "name")) { + pluginname = xmlNodeGetContent (field); + if (gst_plugin_find (pluginname)) { + g_free (pluginname); + g_free (plugin); plugin = NULL; break; } else { plugin->name = pluginname; } } - else if (!strcmp(field->name, "longname")) { - plugin->longname = xmlNodeGetContent(field); + else if (!strcmp (field->name, "longname")) { + plugin->longname = xmlNodeGetContent (field); } - else if (!strcmp(field->name, "filename")) { - plugin->filename = xmlNodeGetContent(field); + else if (!strcmp (field->name, "filename")) { + plugin->filename = xmlNodeGetContent (field); } - else if (!strcmp(field->name, "elementfactory")) { - GstElementFactory *factory = gst_elementfactory_load_thyself(field); + else if (!strcmp (field->name, "elementfactory")) { + GstElementFactory *factory = gst_elementfactory_load_thyself (field); gst_plugin_add_factory (plugin, factory); elementcount++; } - else if (!strcmp(field->name, "typefactory")) { - GstTypeFactory *factory = gst_typefactory_load_thyself(field); + else if (!strcmp (field->name, "autoplugfactory")) { + GstAutoplugFactory *factory = gst_autoplugfactory_load_thyself (field); + gst_plugin_add_autoplugger (plugin, factory); + autoplugcount++; + } + else if (!strcmp (field->name, "typefactory")) { + GstTypeFactory *factory = gst_typefactory_load_thyself (field); gst_plugin_add_type (plugin, factory); elementcount++; typecount++; @@ -810,13 +930,14 @@ gst_plugin_load_thyself (xmlNodePtr parent) } if (plugin) { - _gst_plugins = g_list_prepend(_gst_plugins, plugin); + _gst_plugins = g_list_prepend (_gst_plugins, plugin); } } kinderen = kinderen->next; } - GST_INFO (GST_CAT_PLUGIN_LOADING,"added %d registered factories and %d types",elementcount,typecount); + GST_INFO (GST_CAT_PLUGIN_LOADING, "added %d registered factories, %d autopluggers and %d types", + elementcount, autoplugcount, typecount); } @@ -851,3 +972,19 @@ gst_plugin_get_type_list (GstPlugin *plugin) return plugin->types; } + +/** + * gst_plugin_get_autoplug_list: + * @plugin: the plugin to get the autoplugfactories from + * + * get a list of all the autoplugfactories that this plugin provides + * + * Returns: a GList of factories + */ +GList* +gst_plugin_get_autoplug_list (GstPlugin *plugin) +{ + g_return_val_if_fail (plugin != NULL, NULL); + + return plugin->autopluggers; +} diff --git a/gst/gstplugin.h b/gst/gstplugin.h index 6a53dcd686..299d10edc1 100644 --- a/gst/gstplugin.h +++ b/gst/gstplugin.h @@ -36,10 +36,11 @@ #include #include +#include -typedef struct _GstPlugin GstPlugin; -typedef struct _GstPluginElement GstPluginElement; +typedef struct _GstPlugin GstPlugin; +typedef struct _GstPluginElement GstPluginElement; struct _GstPlugin { gchar *name; /* name of the plugin */ @@ -50,6 +51,8 @@ struct _GstPlugin { gint numtypes; GList *elements; /* list of elements provided */ gint numelements; + GList *autopluggers; /* list of autopluggers provided */ + gint numautopluggers; gboolean loaded; /* if the plugin is in memory */ }; @@ -57,38 +60,41 @@ struct _GstPlugin { typedef GstPlugin* (*GstPluginInitFunc) (GModule *module); -void _gst_plugin_initialize (void); +void _gst_plugin_initialize (void); GstPlugin* gst_plugin_new (const gchar *name); +void gst_plugin_add_path (const gchar *path); + const gchar* gst_plugin_get_name (GstPlugin *plugin); -void gst_plugin_set_name (GstPlugin *plugin, const gchar *name); +void gst_plugin_set_name (GstPlugin *plugin, const gchar *name); const gchar* gst_plugin_get_longname (GstPlugin *plugin); -void gst_plugin_set_longname (GstPlugin *plugin, const gchar *longname); +void gst_plugin_set_longname (GstPlugin *plugin, const gchar *longname); const gchar* gst_plugin_get_filename (GstPlugin *plugin); -gboolean gst_plugin_is_loaded (GstPlugin *plugin); +gboolean gst_plugin_is_loaded (GstPlugin *plugin); GList* gst_plugin_get_type_list (GstPlugin *plugin); GList* gst_plugin_get_factory_list (GstPlugin *plugin); +GList* gst_plugin_get_autoplug_list (GstPlugin *plugin); void gst_plugin_load_all (void); gboolean gst_plugin_load (const gchar *name); gboolean gst_plugin_load_absolute (const gchar *name); gboolean gst_library_load (const gchar *name); -void gst_plugin_add_factory (GstPlugin *plugin, GstElementFactory *factory); -void gst_plugin_add_type (GstPlugin *plugin, GstTypeFactory *factory); +void gst_plugin_add_factory (GstPlugin *plugin, GstElementFactory *factory); +void gst_plugin_add_type (GstPlugin *plugin, GstTypeFactory *factory); +void gst_plugin_add_autoplugger (GstPlugin *plugin, GstAutoplugFactory *factory); GstPlugin* gst_plugin_find (const gchar *name); GList* gst_plugin_get_list (void); -GstElementFactory* gst_plugin_find_elementfactory (const gchar *name); - GstElementFactory* gst_plugin_load_elementfactory (const gchar *name); -void gst_plugin_load_typefactory (const gchar *mime); +void gst_plugin_load_typefactory (const gchar *mime); +GstAutoplugFactory* gst_plugin_load_autoplugfactory (const gchar *name); -xmlNodePtr gst_plugin_save_thyself (xmlNodePtr parent); -void gst_plugin_load_thyself (xmlNodePtr parent); +xmlNodePtr gst_plugin_save_thyself (xmlNodePtr parent); +void gst_plugin_load_thyself (xmlNodePtr parent); #endif /* __GST_PLUGIN_H__ */ diff --git a/gst/gstprops.c b/gst/gstprops.c index 11a5a523ae..0ba00e2b48 100644 --- a/gst/gstprops.c +++ b/gst/gstprops.c @@ -26,70 +26,56 @@ #include "gstprops.h" #include "gstpropsprivate.h" +static GMemChunk *_gst_props_entries_chunk; +static GMutex *_gst_props_entries_chunk_lock; + +static GMemChunk *_gst_props_chunk; +static GMutex *_gst_props_chunk_lock; static gboolean gst_props_entry_check_compatibility (GstPropsEntry *entry1, GstPropsEntry *entry2); -static guint _arg_len[] = { - 0, // GST_PROPS_END_ID_NUM = 0, - 0, // GST_PROPS_LIST_ID_NUM, - 1, // GST_PROPS_INT_ID_NUM, - 2, // GST_PROPS_INT_RANGE_ID_NUM, - 1, // GST_PROPS_FOURCC_ID_NUM, - 1, // GST_PROPS_BOOL_ID_NUM, -}; - void _gst_props_initialize (void) { + _gst_props_entries_chunk = g_mem_chunk_new ("GstPropsEntries", + sizeof (GstPropsEntry), sizeof (GstPropsEntry) * 256, + G_ALLOC_AND_FREE); + _gst_props_entries_chunk_lock = g_mutex_new (); + + _gst_props_chunk = g_mem_chunk_new ("GstProps", + sizeof (GstProps), sizeof (GstProps) * 256, + G_ALLOC_AND_FREE); + _gst_props_chunk_lock = g_mutex_new (); } -static GstPropsEntry * -gst_props_create_entry (GstPropsFactory factory, gint *skipped) +static void +gst_props_debug_entry (GstPropsEntry *entry) { - GstPropsFactoryEntry tag; - GstPropsEntry *entry; - guint i=0; - - entry = g_new0 (GstPropsEntry, 1); - - tag = factory[i++]; - switch (GPOINTER_TO_INT (tag)) { + switch (entry->propstype) { case GST_PROPS_INT_ID: - entry->propstype = GST_PROPS_INT_ID_NUM; - entry->data.int_data = GPOINTER_TO_INT (factory[i++]); - break; - case GST_PROPS_INT_RANGE_ID: - entry->propstype = GST_PROPS_INT_RANGE_ID_NUM; - entry->data.int_range_data.min = GPOINTER_TO_INT (factory[i++]); - entry->data.int_range_data.max = GPOINTER_TO_INT (factory[i++]); + GST_DEBUG (0, "%d\n", entry->data.int_data); break; case GST_PROPS_FOURCC_ID: - entry->propstype = GST_PROPS_FOURCC_ID_NUM; - entry->data.fourcc_data = GPOINTER_TO_INT (factory[i++]); - break; - case GST_PROPS_LIST_ID: - g_print("gstprops: list not allowed in list\n"); + GST_DEBUG (0, "%4.4s\n", (gchar*)&entry->data.fourcc_data); break; case GST_PROPS_BOOL_ID: - entry->propstype = GST_PROPS_BOOL_ID_NUM; - entry->data.bool_data = GPOINTER_TO_INT (factory[i++]); + GST_DEBUG (0, "%d\n", entry->data.bool_data); + break; + case GST_PROPS_STRING_ID: + GST_DEBUG (0, "%s\n", entry->data.string_data.string); + break; + case GST_PROPS_INT_RANGE_ID: + GST_DEBUG (0, "%d-%d\n", entry->data.int_range_data.min, + entry->data.int_range_data.max); break; default: - g_print("gstprops: unknown props id found\n"); - g_free (entry); - entry = NULL; break; } - - *skipped = i; - - return entry; } - static gint props_compare_func (gconstpointer a, - gconstpointer b) + gconstpointer b) { GstPropsEntry *entry1 = (GstPropsEntry *)a; GstPropsEntry *entry2 = (GstPropsEntry *)b; @@ -97,181 +83,454 @@ props_compare_func (gconstpointer a, return (entry1->propid - entry2->propid); } -/** - * gst_props_register: - * @factory: the factory to register - * - * Register the factory. - * - * Returns: the new property created from the factory - */ -GstProps * -gst_props_register (GstPropsFactory factory) +static gint +props_find_func (gconstpointer a, + gconstpointer b) { - guint dummy; + GstPropsEntry *entry2 = (GstPropsEntry *)a; + GQuark entry1 = (GQuark) GPOINTER_TO_INT (b); - return gst_props_register_count (factory, &dummy); + return (entry1 - entry2->propid); } -/** - * gst_props_register_count: - * @factory: the factory to register - * @counter: count how many fields were consumed - * - * Register the factory. - * - * Returns: the new property created from the factory - */ -GstProps * -gst_props_register_count (GstPropsFactory factory, guint *counter) +static void +gst_props_entry_fill (GstPropsEntry *entry, va_list *var_args) { - GstPropsFactoryEntry tag; - gint i = 0; - GstProps *props = NULL; - gint skipped; - - g_return_val_if_fail (factory != NULL, NULL); + entry->propstype = va_arg (*var_args, GstPropsId); - tag = factory[i++]; - - if (!tag) goto end; - - props = g_new0 (GstProps, 1); - g_return_val_if_fail (props != NULL, NULL); - - props->properties = NULL; - - while (tag) { - GQuark quark; - GstPropsEntry *entry; - - if (tag < GST_PROPS_LAST_ID) { - g_warning ("properties seem to be wrong\n"); - return NULL; - } - - quark = g_quark_from_string ((gchar *)tag); - - tag = factory[i]; - switch (GPOINTER_TO_INT (tag)) { - case GST_PROPS_LIST_ID: - { - GstPropsEntry *list_entry; - - entry = g_new0 (GstPropsEntry, 1); - entry->propid = quark; - entry->propstype = GST_PROPS_LIST_ID_NUM; - entry->data.list_data.entries = NULL; - - i++; // skip list tag - tag = factory[i]; - while (tag) { - list_entry = gst_props_create_entry (&factory[i], &skipped); - list_entry->propid = quark; - i += skipped; - tag = factory[i]; - entry->data.list_data.entries = g_list_prepend (entry->data.list_data.entries, list_entry); - } - entry->data.list_data.entries = g_list_reverse (entry->data.list_data.entries); - i++; //skip NULL (list end) - break; - } - default: - { - entry = gst_props_create_entry (&factory[i], &skipped); - entry->propid = quark; - i += skipped; - break; - } - } - props->properties = g_list_insert_sorted (props->properties, entry, props_compare_func); - - tag = factory[i++]; + switch (entry->propstype) { + case GST_PROPS_INT_ID: + entry->data.int_data = va_arg (*var_args, gint); + break; + case GST_PROPS_INT_RANGE_ID: + entry->data.int_range_data.min = va_arg (*var_args, gint); + entry->data.int_range_data.max = va_arg (*var_args, gint); + break; + case GST_PROPS_FLOAT_ID: + entry->data.float_data = va_arg (*var_args, gdouble); + break; + case GST_PROPS_FLOAT_RANGE_ID: + entry->data.float_range_data.min = va_arg (*var_args, gdouble); + entry->data.float_range_data.max = va_arg (*var_args, gdouble); + break; + case GST_PROPS_FOURCC_ID: + entry->data.fourcc_data = va_arg (*var_args, gulong); + break; + case GST_PROPS_BOOL_ID: + entry->data.bool_data = va_arg (*var_args, gboolean); + break; + case GST_PROPS_STRING_ID: + entry->data.string_data.string = g_strdup (va_arg (*var_args, gchar*)); + break; + default: + break; } - -end: - *counter = i; - - return props; } /** * gst_props_new: - * @entry: the property entries for the property - * @...: the property entries for the property + * @firstname: the first property name + * @...: the property values + * + * Create a new property from the given key/value pairs + * + * Returns: the new property + */ +GstProps* +gst_props_new (const gchar *firstname, ...) +{ + GstProps *props; + va_list var_args; + + va_start (var_args, firstname); + + props = gst_props_newv (firstname, var_args); + + va_end (var_args); + + return props; +} + +/** + * gst_props_newv: + * @firstname: the first property name + * @var_args: the property values * * Create a new property from the list of entries. * * Returns: the new property created from the list of entries */ -GstProps * -gst_props_new (GstPropsFactoryEntry entry, ...) +GstProps* +gst_props_newv (const gchar *firstname, va_list var_args) { - va_list var_args; - GstPropsFactoryEntry value; - gint i = 0; - gint size, skip; - GstPropsFactoryEntry *factory; - gboolean inlist = FALSE; GstProps *props; + gboolean inlist = FALSE; + const gchar *prop_name; + GstPropsEntry *list_entry = NULL; -#define add_value(value) {\ - GST_DEBUG (0,"%d %p\n", i, value);\ - factory[i++] = value; \ - if (i >= size) { \ - size += 16; \ - factory = (GstPropsFactoryEntry *) g_realloc (factory, size*sizeof(GstPropsFactoryEntry));\ - }\ -} + g_mutex_lock (_gst_props_chunk_lock); + props = g_mem_chunk_alloc (_gst_props_chunk); + g_mutex_unlock (_gst_props_chunk_lock); - size = 16; - factory = (GstPropsFactoryEntry *) g_malloc (size*sizeof(GstPropsFactoryEntry)); + props->properties = NULL; + props->refcount = 1; + + prop_name = firstname; - va_start (var_args, entry); - // property name - value = (GstPropsFactoryEntry) entry; - // properties - while (value) { - if (!inlist) { - // add name - add_value (value); + while (prop_name) { + GstPropsEntry *entry; + + g_mutex_lock (_gst_props_entries_chunk_lock); + entry = g_mem_chunk_alloc (_gst_props_entries_chunk); + g_mutex_unlock (_gst_props_entries_chunk_lock); - // get value - value = va_arg (var_args, GstPropsFactoryEntry); - } - switch (GPOINTER_TO_INT (value)) { - case GST_PROPS_END_ID: - g_assert (inlist == TRUE); + entry->propid = g_quark_from_string (prop_name); + gst_props_entry_fill (entry, &var_args); - inlist = FALSE; - skip = 0; + switch (entry->propstype) { + case GST_PROPS_INT_ID: + case GST_PROPS_INT_RANGE_ID: + case GST_PROPS_FLOAT_ID: + case GST_PROPS_FLOAT_RANGE_ID: + case GST_PROPS_FOURCC_ID: + case GST_PROPS_BOOL_ID: + case GST_PROPS_STRING_ID: break; - case GST_PROPS_LIST_ID: - { - g_assert (inlist == FALSE); - - skip = 0; + case GST_PROPS_LIST_ID: + g_return_val_if_fail (inlist == FALSE, NULL); inlist = TRUE; + list_entry = entry; + list_entry->data.list_data.entries = NULL; break; - } + case GST_PROPS_END_ID: + g_return_val_if_fail (inlist == TRUE, NULL); + inlist = FALSE; + list_entry = NULL; + prop_name = va_arg (var_args, gchar*); + continue; default: - skip = _arg_len[GPOINTER_TO_INT (value)]; - break; + g_mutex_lock (_gst_props_entries_chunk_lock); + g_mem_chunk_free (_gst_props_entries_chunk, entry); + g_mutex_unlock (_gst_props_entries_chunk_lock); + g_assert_not_reached (); + break; } - do { - add_value (value); - value = va_arg (var_args, GstPropsFactoryEntry); - } - while (skip--); - } - factory[i++] = NULL; - props = gst_props_register (factory); + if (inlist && (list_entry != entry)) { + list_entry->data.list_data.entries = g_list_prepend (list_entry->data.list_data.entries, entry); + } + else { + props->properties = g_list_insert_sorted (props->properties, entry, props_compare_func); + } + if (!inlist) + prop_name = va_arg (var_args, gchar*); + } return props; } +/** + * gst_props_set: + * @props: the props to modify + * @name: the name of the entry to modify + * @...: More property entries. + * + * Modifies the value of the given entry in the props struct. + * + * Returns: the new modified property structure. + */ +GstProps* +gst_props_set (GstProps *props, const gchar *name, ...) +{ + GQuark quark; + GList *lentry; + va_list var_args; + + quark = g_quark_from_string (name); + + lentry = g_list_find_custom (props->properties, GINT_TO_POINTER (quark), props_find_func); + + if (lentry) { + GstPropsEntry *entry; + + entry = (GstPropsEntry *)lentry->data; + + va_start (var_args, name); + + gst_props_entry_fill (entry, &var_args); + + va_end (var_args); + } + else { + g_print("gstprops: no property '%s' to change\n", name); + } + + return props; +} + +/** + * gst_props_unref: + * @props: the props to unref + * + * Decrease the refcount of the property structure, destroying + * the property if the refcount is 0. + */ +void +gst_props_unref (GstProps *props) +{ + g_return_if_fail (props != NULL); + + props->refcount--; + + if (props->refcount == 0) + gst_props_destroy (props); +} + +/** + * gst_props_ref: + * @props: the props to ref + * + * Increase the refcount of the property structure. + */ +void +gst_props_ref (GstProps *props) +{ + g_return_if_fail (props != NULL); + + props->refcount++; +} + +/** + * gst_props_destroy: + * @props: the props to destroy + * + * Destroy the property, freeing all the memory that + * was allocated. + */ +void +gst_props_destroy (GstProps *props) +{ + GList *entries; + + g_return_if_fail (props != NULL); + + entries = props->properties; + + while (entries) { + GstPropsEntry *entry = (GstPropsEntry *)entries->data; + + // FIXME also free the lists + g_mutex_lock (_gst_props_entries_chunk_lock); + g_mem_chunk_free (_gst_props_entries_chunk, entry); + g_mutex_unlock (_gst_props_entries_chunk_lock); + + entries = g_list_next (entries); + } + + g_list_free (props->properties); +} + +/** + * gst_props_copy: + * @props: the props to copy + * + * Copy the property structure. + * + * Returns: the new property that is a copy of the original + * one. + */ +GstProps* +gst_props_copy (GstProps *props) +{ + GstProps *new; + GList *properties; + + g_return_val_if_fail (props != NULL, NULL); + + g_mutex_lock (_gst_props_chunk_lock); + new = g_mem_chunk_alloc (_gst_props_chunk); + g_mutex_unlock (_gst_props_chunk_lock); + + new->properties = NULL; + + properties = props->properties; + + while (properties) { + GstPropsEntry *entry = (GstPropsEntry *)properties->data; + GstPropsEntry *newentry; + + g_mutex_lock (_gst_props_entries_chunk_lock); + newentry = g_mem_chunk_alloc (_gst_props_entries_chunk); + g_mutex_unlock (_gst_props_entries_chunk_lock); + + // FIXME copy lists too + memcpy (newentry, entry, sizeof (GstPropsEntry)); + + new->properties = g_list_prepend (new->properties, newentry); + + properties = g_list_next (properties); + } + new->properties = g_list_reverse (new->properties); + + return new; +} + +/** + * gst_props_copy_on_write: + * @props: the props to copy on write + * + * Copy the property structure if the refcount is >1. + * + * Returns: A new props that can be safely written to. + */ +GstProps* +gst_props_copy_on_write (GstProps *props) +{ + GstProps *new = props;; + + g_return_val_if_fail (props != NULL, NULL); + + if (props->refcount > 1) { + new = gst_props_copy (props); + gst_props_unref (props); + } + + return props; +} + +/** + * gst_props_get_int: + * @props: the props to get the int value from + * @name: the name of the props entry to get. + * + * Get the named entry as an integer. + * + * Returns: the integer value of the named entry, 0 if not found. + */ +gint +gst_props_get_int (GstProps *props, const gchar *name) +{ + GList *lentry; + GQuark quark; + + g_return_val_if_fail (props != NULL, 0); + g_return_val_if_fail (name != NULL, 0); + + quark = g_quark_from_string (name); + + lentry = g_list_find_custom (props->properties, GINT_TO_POINTER (quark), props_find_func); + + if (lentry) { + GstPropsEntry *thisentry; + + thisentry = (GstPropsEntry *)lentry->data; + + return thisentry->data.int_data; + } + + return 0; +} + +/** + * gst_props_get_fourcc_int: + * @props: the props to get the fourcc value from + * @name: the name of the props entry to get. + * + * Get the named entry as a gulong fourcc. + * + * Returns: the fourcc value of the named entry, 0 if not found. + */ +gulong +gst_props_get_fourcc_int (GstProps *props, const gchar *name) +{ + GList *lentry; + GQuark quark; + + g_return_val_if_fail (props != NULL, 0); + g_return_val_if_fail (name != NULL, 0); + + quark = g_quark_from_string (name); + + lentry = g_list_find_custom (props->properties, GINT_TO_POINTER (quark), props_find_func); + + if (lentry) { + GstPropsEntry *thisentry; + + thisentry = (GstPropsEntry *)lentry->data; + + return thisentry->data.fourcc_data; + } + + return 0; +} + +/** + * gst_props_get_boolean: + * @props: the props to get the fourcc value from + * @name: the name of the props entry to get. + * + * Get the named entry as a boolean value. + * + * Returns: the boolean value of the named entry, 0 if not found. + */ +gboolean +gst_props_get_boolean (GstProps *props, const gchar *name) +{ + GList *lentry; + GQuark quark; + + g_return_val_if_fail (props != NULL, FALSE); + g_return_val_if_fail (name != NULL, FALSE); + + quark = g_quark_from_string (name); + + lentry = g_list_find_custom (props->properties, GINT_TO_POINTER (quark), props_find_func); + + if (lentry) { + GstPropsEntry *thisentry; + + thisentry = (GstPropsEntry *)lentry->data; + + return thisentry->data.bool_data; + } + + return 0; +} + +/** + * gst_props_get_string: + * @props: the props to get the fourcc value from + * @name: the name of the props entry to get. + * + * Get the named entry as a string value. + * + * Returns: the string value of the named entry, NULL if not found. + */ +const gchar* +gst_props_get_string (GstProps *props, const gchar *name) +{ + GList *lentry; + GQuark quark; + + g_return_val_if_fail (props != NULL, NULL); + g_return_val_if_fail (name != NULL, NULL); + + quark = g_quark_from_string (name); + + lentry = g_list_find_custom (props->properties, GINT_TO_POINTER (quark), props_find_func); + + if (lentry) { + GstPropsEntry *thisentry; + + thisentry = (GstPropsEntry *)lentry->data; + + return thisentry->data.string_data.string; + } + + return NULL; +} + /** * gst_props_merge: * @props: the property to merge into @@ -328,7 +587,7 @@ gst_props_entry_check_compatibility (GstPropsEntry *entry1, GstPropsEntry *entry GST_DEBUG (0,"compare: %s %s\n", g_quark_to_string (entry1->propid), g_quark_to_string (entry2->propid)); switch (entry1->propstype) { - case GST_PROPS_LIST_ID_NUM: + case GST_PROPS_LIST_ID: { GList *entrylist = entry1->data.list_data.entries; gboolean valid = TRUE; // innocent until proven guilty @@ -343,52 +602,90 @@ gst_props_entry_check_compatibility (GstPropsEntry *entry1, GstPropsEntry *entry return valid; } - case GST_PROPS_INT_RANGE_ID_NUM: + case GST_PROPS_INT_RANGE_ID: switch (entry2->propstype) { // a - b <---> a - c - case GST_PROPS_INT_RANGE_ID_NUM: + case GST_PROPS_INT_RANGE_ID: return (entry2->data.int_range_data.min <= entry1->data.int_range_data.min && entry2->data.int_range_data.max >= entry1->data.int_range_data.max); - case GST_PROPS_LIST_ID_NUM: + case GST_PROPS_LIST_ID: return gst_props_entry_check_list_compatibility (entry1, entry2); default: return FALSE; } break; - case GST_PROPS_FOURCC_ID_NUM: + case GST_PROPS_FLOAT_RANGE_ID: + switch (entry2->propstype) { + // a - b <---> a - c + case GST_PROPS_FLOAT_RANGE_ID: + return (entry2->data.float_range_data.min <= entry1->data.float_range_data.min && + entry2->data.float_range_data.max >= entry1->data.float_range_data.max); + case GST_PROPS_LIST_ID: + return gst_props_entry_check_list_compatibility (entry1, entry2); + default: + return FALSE; + } + break; + case GST_PROPS_FOURCC_ID: switch (entry2->propstype) { // b <---> a - case GST_PROPS_FOURCC_ID_NUM: + case GST_PROPS_FOURCC_ID: return (entry2->data.fourcc_data == entry1->data.fourcc_data); // b <---> a,b,c - case GST_PROPS_LIST_ID_NUM: + case GST_PROPS_LIST_ID: return gst_props_entry_check_list_compatibility (entry1, entry2); default: return FALSE; } break; - case GST_PROPS_INT_ID_NUM: + case GST_PROPS_INT_ID: switch (entry2->propstype) { // b <---> a - d - case GST_PROPS_INT_RANGE_ID_NUM: + case GST_PROPS_INT_RANGE_ID: return (entry2->data.int_range_data.min <= entry1->data.int_data && entry2->data.int_range_data.max >= entry1->data.int_data); // b <---> a - case GST_PROPS_INT_ID_NUM: + case GST_PROPS_INT_ID: return (entry2->data.int_data == entry1->data.int_data); // b <---> a,b,c - case GST_PROPS_LIST_ID_NUM: + case GST_PROPS_LIST_ID: return gst_props_entry_check_list_compatibility (entry1, entry2); default: return FALSE; } break; - case GST_PROPS_BOOL_ID_NUM: + case GST_PROPS_FLOAT_ID: + switch (entry2->propstype) { + // b <---> a - d + case GST_PROPS_FLOAT_RANGE_ID: + return (entry2->data.float_range_data.min <= entry1->data.float_data && + entry2->data.float_range_data.max >= entry1->data.float_data); + // b <---> a + case GST_PROPS_FLOAT_ID: + return (entry2->data.float_data == entry1->data.float_data); + // b <---> a,b,c + case GST_PROPS_LIST_ID: + return gst_props_entry_check_list_compatibility (entry1, entry2); + default: + return FALSE; + } + break; + case GST_PROPS_BOOL_ID: switch (entry2->propstype) { // t <---> t - case GST_PROPS_BOOL_ID_NUM: + case GST_PROPS_BOOL_ID: return (entry2->data.bool_data == entry1->data.bool_data); - case GST_PROPS_LIST_ID_NUM: + case GST_PROPS_LIST_ID: + return gst_props_entry_check_list_compatibility (entry1, entry2); + default: + return FALSE; + } + case GST_PROPS_STRING_ID: + switch (entry2->propstype) { + // t <---> t + case GST_PROPS_STRING_ID: + return (!strcmp (entry2->data.string_data.string, entry1->data.string_data.string)); + case GST_PROPS_LIST_ID: return gst_props_entry_check_list_compatibility (entry1, entry2); default: return FALSE; @@ -448,9 +745,10 @@ gst_props_check_compatibility (GstProps *fromprops, GstProps *toprops) if (!gst_props_entry_check_compatibility (entry1, entry2)) { compatible = FALSE; - GST_DEBUG (0, "%s and %s are not compatible\n", - g_quark_to_string (entry1->propid), - g_quark_to_string (entry2->propid)); + GST_DEBUG (0, "%s are not compatible\n:", + g_quark_to_string (entry1->propid)); + gst_props_debug_entry (entry1); + gst_props_debug_entry (entry2); } sourcelist = g_list_next (sourcelist); @@ -477,14 +775,14 @@ gst_props_save_thyself_func (GstPropsEntry *entry, xmlNodePtr parent) gchar *str; switch (entry->propstype) { - case GST_PROPS_INT_ID_NUM: + case GST_PROPS_INT_ID: subtree = xmlNewChild (parent, NULL, "int", NULL); xmlNewProp (subtree, "name", g_quark_to_string (entry->propid)); str = g_strdup_printf ("%d", entry->data.int_data); xmlNewProp (subtree, "value", str); g_free(str); break; - case GST_PROPS_INT_RANGE_ID_NUM: + case GST_PROPS_INT_RANGE_ID: subtree = xmlNewChild (parent, NULL, "range", NULL); xmlNewProp (subtree, "name", g_quark_to_string (entry->propid)); str = g_strdup_printf ("%d", entry->data.int_range_data.min); @@ -494,7 +792,24 @@ gst_props_save_thyself_func (GstPropsEntry *entry, xmlNodePtr parent) xmlNewProp (subtree, "max", str); g_free(str); break; - case GST_PROPS_FOURCC_ID_NUM: + case GST_PROPS_FLOAT_ID: + subtree = xmlNewChild (parent, NULL, "float", NULL); + xmlNewProp (subtree, "name", g_quark_to_string (entry->propid)); + str = g_strdup_printf ("%f", entry->data.float_data); + xmlNewProp (subtree, "value", str); + g_free(str); + break; + case GST_PROPS_FLOAT_RANGE_ID: + subtree = xmlNewChild (parent, NULL, "floatrange", NULL); + xmlNewProp (subtree, "name", g_quark_to_string (entry->propid)); + str = g_strdup_printf ("%f", entry->data.float_range_data.min); + xmlNewProp (subtree, "min", str); + g_free(str); + str = g_strdup_printf ("%f", entry->data.float_range_data.max); + xmlNewProp (subtree, "max", str); + g_free(str); + break; + case GST_PROPS_FOURCC_ID: str = g_strdup_printf ("%4.4s", (gchar *)&entry->data.fourcc_data); xmlAddChild (parent, xmlNewComment (str)); g_free(str); @@ -504,11 +819,16 @@ gst_props_save_thyself_func (GstPropsEntry *entry, xmlNodePtr parent) xmlNewProp (subtree, "hexvalue", str); g_free(str); break; - case GST_PROPS_BOOL_ID_NUM: + case GST_PROPS_BOOL_ID: subtree = xmlNewChild (parent, NULL, "boolean", NULL); xmlNewProp (subtree, "name", g_quark_to_string (entry->propid)); xmlNewProp (subtree, "value", (entry->data.bool_data ? "true" : "false")); break; + case GST_PROPS_STRING_ID: + subtree = xmlNewChild (parent, NULL, "string", NULL); + xmlNewProp (subtree, "name", g_quark_to_string (entry->propid)); + xmlNewProp (subtree, "value", entry->data.string_data.string); + break; default: break; } @@ -539,7 +859,7 @@ gst_props_save_thyself (GstProps *props, xmlNodePtr parent) GstPropsEntry *entry = (GstPropsEntry *) proplist->data; switch (entry->propstype) { - case GST_PROPS_LIST_ID_NUM: + case GST_PROPS_LIST_ID: subtree = xmlNewChild (parent, NULL, "list", NULL); xmlNewProp (subtree, "name", g_quark_to_string (entry->propid)); g_list_foreach (entry->data.list_data.entries, (GFunc) gst_props_save_thyself_func, subtree); @@ -559,10 +879,12 @@ gst_props_load_thyself_func (xmlNodePtr field) GstPropsEntry *entry; gchar *prop; - entry = g_new0 (GstPropsEntry, 1); + g_mutex_lock (_gst_props_entries_chunk_lock); + entry = g_mem_chunk_alloc (_gst_props_entries_chunk); + g_mutex_unlock (_gst_props_entries_chunk_lock); if (!strcmp(field->name, "int")) { - entry->propstype = GST_PROPS_INT_ID_NUM; + entry->propstype = GST_PROPS_INT_ID; prop = xmlGetProp(field, "name"); entry->propid = g_quark_from_string (prop); g_free (prop); @@ -571,19 +893,40 @@ gst_props_load_thyself_func (xmlNodePtr field) g_free (prop); } else if (!strcmp(field->name, "range")) { - entry->propstype = GST_PROPS_INT_RANGE_ID_NUM; + entry->propstype = GST_PROPS_INT_RANGE_ID; prop = xmlGetProp(field, "name"); entry->propid = g_quark_from_string (prop); g_free (prop); prop = xmlGetProp (field, "min"); sscanf (prop, "%d", &entry->data.int_range_data.min); g_free (prop); - prop = xmlGetProp (field, "min"); + prop = xmlGetProp (field, "max"); sscanf (prop, "%d", &entry->data.int_range_data.max); g_free (prop); } + else if (!strcmp(field->name, "float")) { + entry->propstype = GST_PROPS_FLOAT_ID; + prop = xmlGetProp(field, "name"); + entry->propid = g_quark_from_string (prop); + g_free (prop); + prop = xmlGetProp(field, "value"); + sscanf (prop, "%f", &entry->data.float_data); + g_free (prop); + } + else if (!strcmp(field->name, "floatrange")) { + entry->propstype = GST_PROPS_FLOAT_RANGE_ID; + prop = xmlGetProp(field, "name"); + entry->propid = g_quark_from_string (prop); + g_free (prop); + prop = xmlGetProp (field, "min"); + sscanf (prop, "%f", &entry->data.float_range_data.min); + g_free (prop); + prop = xmlGetProp (field, "max"); + sscanf (prop, "%f", &entry->data.float_range_data.max); + g_free (prop); + } else if (!strcmp(field->name, "boolean")) { - entry->propstype = GST_PROPS_BOOL_ID_NUM; + entry->propstype = GST_PROPS_BOOL_ID; prop = xmlGetProp(field, "name"); entry->propid = g_quark_from_string (prop); g_free (prop); @@ -593,7 +936,7 @@ gst_props_load_thyself_func (xmlNodePtr field) g_free (prop); } else if (!strcmp(field->name, "fourcc")) { - entry->propstype = GST_PROPS_FOURCC_ID_NUM; + entry->propstype = GST_PROPS_FOURCC_ID; prop = xmlGetProp(field, "name"); entry->propid = g_quark_from_string (prop); g_free (prop); @@ -601,6 +944,19 @@ gst_props_load_thyself_func (xmlNodePtr field) sscanf (prop, "%08x", &entry->data.fourcc_data); g_free (prop); } + else if (!strcmp(field->name, "string")) { + entry->propstype = GST_PROPS_STRING_ID; + prop = xmlGetProp(field, "name"); + entry->propid = g_quark_from_string (prop); + g_free (prop); + entry->data.string_data.string = xmlGetProp (field, "value"); + } + else { + g_mutex_lock (_gst_props_entries_chunk_lock); + g_mem_chunk_free (_gst_props_entries_chunk, entry); + g_mutex_unlock (_gst_props_entries_chunk_lock); + entry = NULL; + } return entry; } @@ -616,17 +972,28 @@ gst_props_load_thyself_func (xmlNodePtr field) GstProps* gst_props_load_thyself (xmlNodePtr parent) { - GstProps *props = g_new0 (GstProps, 1); + GstProps *props; xmlNodePtr field = parent->xmlChildrenNode; gchar *prop; + g_mutex_lock (_gst_props_chunk_lock); + props = g_mem_chunk_alloc (_gst_props_chunk); + g_mutex_unlock (_gst_props_chunk_lock); + + props->properties = NULL; + props->refcount = 1; + while (field) { if (!strcmp (field->name, "list")) { GstPropsEntry *entry; xmlNodePtr subfield = field->xmlChildrenNode; - entry = g_new0 (GstPropsEntry, 1); - entry->propstype = GST_PROPS_LIST_ID_NUM; + g_mutex_lock (_gst_props_entries_chunk_lock); + entry = g_mem_chunk_alloc (_gst_props_entries_chunk); + g_mutex_unlock (_gst_props_entries_chunk_lock); + + entry->propstype = GST_PROPS_LIST_ID; + entry->data.list_data.entries = NULL; prop = xmlGetProp (field, "name"); entry->propid = g_quark_from_string (prop); g_free (prop); @@ -634,7 +1001,8 @@ gst_props_load_thyself (xmlNodePtr parent) while (subfield) { GstPropsEntry *subentry = gst_props_load_thyself_func (subfield); - entry->data.list_data.entries = g_list_prepend (entry->data.list_data.entries, subentry); + if (subentry) + entry->data.list_data.entries = g_list_prepend (entry->data.list_data.entries, subentry); subfield = subfield->next; } @@ -646,11 +1014,11 @@ gst_props_load_thyself (xmlNodePtr parent) entry = gst_props_load_thyself_func (field); - props->properties = g_list_insert_sorted (props->properties, entry, props_compare_func); + if (entry) + props->properties = g_list_insert_sorted (props->properties, entry, props_compare_func); } field = field->next; } return props; } - diff --git a/gst/gstprops.h b/gst/gstprops.h index fe12355a62..a67acf8aea 100644 --- a/gst/gstprops.h +++ b/gst/gstprops.h @@ -36,52 +36,63 @@ typedef struct _GstProps GstProps; -typedef gpointer GstPropsFactoryEntry; -typedef GstPropsFactoryEntry GstPropsFactory[]; -typedef GstPropsFactory *GstPropsListFactory[]; typedef enum { - GST_PROPS_END_ID_NUM = 0, - GST_PROPS_LIST_ID_NUM, - GST_PROPS_INT_ID_NUM, - GST_PROPS_INT_RANGE_ID_NUM, - GST_PROPS_FOURCC_ID_NUM, - GST_PROPS_BOOL_ID_NUM, - GST_PROPS_LAST_ID_NUM = GST_PROPS_END_ID_NUM + 16, + GST_PROPS_END_ID = 0, + GST_PROPS_LIST_ID, + GST_PROPS_INT_ID, + GST_PROPS_INT_RANGE_ID, + GST_PROPS_FLOAT_ID, + GST_PROPS_FLOAT_RANGE_ID, + GST_PROPS_FOURCC_ID, + GST_PROPS_BOOL_ID, + GST_PROPS_STRING_ID, + GST_PROPS_LAST_ID = GST_PROPS_END_ID + 16, } GstPropsId; -#define GST_PROPS_END_ID GINT_TO_POINTER(GST_PROPS_END_ID_NUM) -#define GST_PROPS_LIST_ID GINT_TO_POINTER(GST_PROPS_LIST_ID_NUM) -#define GST_PROPS_INT_ID GINT_TO_POINTER(GST_PROPS_INT_ID_NUM) -#define GST_PROPS_INT_RANGE_ID GINT_TO_POINTER(GST_PROPS_INT_RANGE_ID_NUM) -#define GST_PROPS_FOURCC_ID GINT_TO_POINTER(GST_PROPS_FOURCC_ID_NUM) -#define GST_PROPS_BOOL_ID GINT_TO_POINTER(GST_PROPS_BOOL_ID_NUM) -#define GST_PROPS_LAST_ID GINT_TO_POINTER(GST_PROPS_LAST_ID_NUM) +#define GST_MAKE_FOURCC(a,b,c,d) ((a)|(b)<<8|(c)<<16|(d)<<24) -#define GST_PROPS_LIST(a...) GST_PROPS_LIST_ID,##a,NULL -#define GST_PROPS_INT(a) GST_PROPS_INT_ID,(GINT_TO_POINTER(a)) -#define GST_PROPS_INT_RANGE(a,b) GST_PROPS_INT_RANGE_ID,(GINT_TO_POINTER(a)),(GINT_TO_POINTER(b)) -#define GST_PROPS_FOURCC(a,b,c,d) GST_PROPS_FOURCC_ID,(GINT_TO_POINTER((a)|(b)<<8|(c)<<16|(d)<<24)) -#define GST_PROPS_FOURCC_INT(a) GST_PROPS_FOURCC_ID,(GINT_TO_POINTER(a)) -#define GST_PROPS_BOOLEAN(a) GST_PROPS_BOOL_ID,(GINT_TO_POINTER(a)) +#define GST_PROPS_LIST(a...) GST_PROPS_LIST_ID,##a,NULL +#define GST_PROPS_INT(a) GST_PROPS_INT_ID,(a) +#define GST_PROPS_INT_RANGE(a,b) GST_PROPS_INT_RANGE_ID,(a),(b) +#define GST_PROPS_FLOAT(a) GST_PROPS_FLOAT_ID,(a) +#define GST_PROPS_FLOAT_RANGE(a,b) GST_PROPS_FLOAT_RANGE_ID,(a),(b) +#define GST_PROPS_FOURCC(a) GST_PROPS_FOURCC_ID,(a) +#define GST_PROPS_BOOLEAN(a) GST_PROPS_BOOL_ID,(a) +#define GST_PROPS_STRING(a) GST_PROPS_STRING_ID,(a) struct _GstProps { + gint refcount; + GMutex *lock; + GList *properties; /* real properties for this property */ }; /* initialize the subsystem */ void _gst_props_initialize (void); -GstProps* gst_props_register (GstPropsFactory factory); -GstProps* gst_props_register_count (GstPropsFactory factory, guint *counter); +GstProps* gst_props_new (const gchar *firstname, ...); +GstProps* gst_props_newv (const gchar *firstname, va_list var_args); -GstProps* gst_props_new (GstPropsFactoryEntry entry, ...); +void gst_props_unref (GstProps *props); +void gst_props_ref (GstProps *props); +void gst_props_destroy (GstProps *props); + +GstProps* gst_props_copy (GstProps *props); +GstProps* gst_props_copy_on_write (GstProps *props); GstProps* gst_props_merge (GstProps *props, GstProps *tomerge); gboolean gst_props_check_compatibility (GstProps *fromprops, GstProps *toprops); +GstProps* gst_props_set (GstProps *props, const gchar *name, ...); + +gint gst_props_get_int (GstProps *props, const gchar *name); +gulong gst_props_get_fourcc_int (GstProps *props, const gchar *name); +gboolean gst_props_get_boolean (GstProps *props, const gchar *name); +const gchar* gst_props_get_string (GstProps *props, const gchar *name); + xmlNodePtr gst_props_save_thyself (GstProps *props, xmlNodePtr parent); GstProps* gst_props_load_thyself (xmlNodePtr parent); diff --git a/gst/gstpropsprivate.h b/gst/gstpropsprivate.h index 8a5fb057fa..8a1f0e3ac7 100644 --- a/gst/gstpropsprivate.h +++ b/gst/gstpropsprivate.h @@ -37,15 +37,23 @@ struct _GstPropsEntry { gboolean bool_data; guint32 fourcc_data; gint int_data; + gfloat float_data; /* structured values */ struct { GList *entries; } list_data; + struct { + gchar *string; + } string_data; struct { gint min; gint max; } int_range_data; + struct { + gfloat min; + gfloat max; + } float_range_data; } data; }; diff --git a/gst/gstqueue.c b/gst/gstqueue.c index 79865c3f06..7e8c92e56a 100644 --- a/gst/gstqueue.c +++ b/gst/gstqueue.c @@ -66,6 +66,8 @@ static void gst_queue_set_arg (GtkObject *object, GtkArg *arg, guint id); static void gst_queue_get_arg (GtkObject *object, GtkArg *arg, guint id); static gboolean gst_queue_handle_eos (GstPad *pad); +static GstPadNegotiateReturn gst_queue_handle_negotiate_src (GstPad *pad, GstCaps **caps, gpointer *data); +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); @@ -131,10 +133,12 @@ gst_queue_init (GstQueue *queue) gst_pad_set_chain_function (queue->sinkpad, GST_DEBUG_FUNCPTR(gst_queue_chain)); 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); queue->srcpad = gst_pad_new ("src", GST_PAD_SRC); gst_pad_set_get_function (queue->srcpad, GST_DEBUG_FUNCPTR(gst_queue_get)); gst_element_add_pad (GST_ELEMENT (queue), queue->srcpad); + gst_pad_set_negotiate_function (queue->srcpad, gst_queue_handle_negotiate_src); queue->queue = NULL; queue->level_buffers = 0; @@ -148,6 +152,41 @@ gst_queue_init (GstQueue *queue) queue->fullcond = g_cond_new (); } +static GstPadNegotiateReturn +gst_queue_handle_negotiate_src (GstPad *pad, GstCaps **caps, gpointer *data) +{ + GstQueue *queue; + + queue = GST_QUEUE (GST_OBJECT_PARENT (pad)); + + return gst_pad_negotiate_proxy (pad, queue->sinkpad, caps); + + + //return GST_PAD_NEGOTIATE_FAIL; +} + +static GstPadNegotiateReturn +gst_queue_handle_negotiate_sink (GstPad *pad, GstCaps **caps, gpointer *data) +{ + GstQueue *queue; + + queue = GST_QUEUE (GST_OBJECT_PARENT (pad)); + + /* + if (counter == 0) { + *caps = NULL; + return GST_PAD_NEGOTIATE_TRY; + } + if (*caps) { + */ + return gst_pad_negotiate_proxy (pad, queue->srcpad, caps); + /* + } + + return GST_PAD_NEGOTIATE_FAIL; + */ +} + static gboolean gst_queue_handle_eos (GstPad *pad) { @@ -251,11 +290,15 @@ gst_queue_chain (GstPad *pad, GstBuffer *buf) static GstBuffer * gst_queue_get (GstPad *pad) { - GstQueue *queue = GST_QUEUE (GST_OBJECT_PARENT (pad)); + GstQueue *queue; GstBuffer *buf = NULL; GSList *front; const guchar *name; + g_return_val_if_fail (pad != NULL, NULL); + g_return_val_if_fail (GST_IS_PAD (pad), NULL); + + queue = GST_QUEUE (GST_OBJECT_PARENT (pad)); name = GST_ELEMENT_NAME (queue); /* have to lock for thread-safety */ diff --git a/gst/gstscheduler.c b/gst/gstscheduler.c index efd2a94942..2b8372e860 100644 --- a/gst/gstscheduler.c +++ b/gst/gstscheduler.c @@ -105,6 +105,7 @@ gst_bin_src_wrapper (int argc,char *argv[]) // fprintf(stderr,"error, no getregionfunc in \"%s\"\n", name); // else buf = (GST_RPAD_GETREGIONFUNC(realpad))((GstPad*)realpad,realpad->regiontype,realpad->offset,realpad->len); + realpad->regiontype = GST_REGION_NONE; } else { g_return_val_if_fail (GST_RPAD_GETFUNC(realpad) != NULL, 0); // if (GST_RPAD_GETFUNC(realpad) == NULL) diff --git a/gst/meta/audioraw.h b/gst/gstsparc.h similarity index 51% rename from gst/meta/audioraw.h rename to gst/gstsparc.h index 7c8d52d237..8dca391cc9 100644 --- a/gst/meta/audioraw.h +++ b/gst/gstsparc.h @@ -1,5 +1,8 @@ -/* Gnome-Streamer - * Copyright (C) <1999> Erik Walthinsen +/* GStreamer + * Copyright (C) 1999,2000 Erik Walthinsen + * 2000 Wim Taymans + * + * gstsparc.h: Header for Sparc-specific architecture issues * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -17,24 +20,23 @@ * Boston, MA 02111-1307, USA. */ +#ifndef __GST_GSTSPARC_H__ +#define __GST_GSTSPARC_H__ -#ifndef __GST_META_AUDIORAW_H__ -#define __GST_META_AUDIORAW_H__ +#define GST_ARCH_SET_SP(stackpointer) \ + __asm__( "ta 3\n\t" + "mov %0, %%sp" : : "r"(stackpointer)); -#include -#include +#define GST_ARCH_CALL(target) \ + __asm__( "call %0,0\n\t" + "nop" : : "r"(target) ); -typedef struct _MetaAudioRaw MetaAudioRaw; +#define GST_ARCH_PRESETJMP() \ + __asm__( "ta 3" ); -struct _MetaAudioRaw { - GstMeta meta; +// Need to get more information about the stackframe format +// and get the fields more correct. Check GDB sources maybe? - /* formatting information */ - gint format; - gint channels; - gint frequency; - gint bps; -}; - -#endif /* __GST_META_AUDIORAW_H__ */ +#define GST_ARCH_SETUP_STACK(sp) sp -= 4 +#endif /* __GST_GSTSPARC_H__ */ diff --git a/gst/gstthread.c b/gst/gstthread.c index 7d2c541eaa..10515d770e 100644 --- a/gst/gstthread.c +++ b/gst/gstthread.c @@ -69,8 +69,6 @@ static xmlNodePtr gst_thread_save_thyself (GstObject *object, xmlNodePtr paren static void gst_thread_restore_thyself (GstObject *object, xmlNodePtr self); static void gst_thread_signal_thread (GstThread *thread, gboolean spinning); -static void -gst_thread_wait_two_thread (GstThread *thread, guint syncflag, gboolean set,guint syncflag2, gboolean set2); static void gst_thread_schedule_dummy (GstBin *bin); static void* gst_thread_main_loop (void *arg); @@ -256,6 +254,7 @@ gst_thread_change_state (GstElement *element) g_mutex_lock(thread->lock); + g_mutex_lock (thread->lock); // create the thread pthread_create (&thread->thread_id, NULL, gst_thread_main_loop, thread); diff --git a/gst/gsttype.c b/gst/gsttype.c index 84090e74d3..437da194df 100644 --- a/gst/gsttype.c +++ b/gst/gsttype.c @@ -43,10 +43,10 @@ struct _GstTypeFindInfo { GstPlugin *plugin; /* the plugin with this typefind function */ }; -static GstCaps* gst_type_typefind_dummy (GstBuffer *buffer, gpointer priv); +static GstCaps* gst_type_typefind_dummy (GstBuffer *buffer, gpointer priv); -void -_gst_type_initialize (void) +void +_gst_type_initialize (void) { _gst_types = NULL; _gst_maxtype = 1; /* type 0 is undefined */ @@ -60,8 +60,8 @@ _gst_type_initialize (void) * * Returns: the new type id */ -guint16 -gst_type_register (GstTypeFactory *factory) +guint16 +gst_type_register (GstTypeFactory *factory) { guint16 id; GstType *type; @@ -70,16 +70,17 @@ gst_type_register (GstTypeFactory *factory) // GST_INFO (GST_CAT_TYPES,"type register %s", factory->mime); id = gst_type_find_by_mime (factory->mime); - + if (!id) { type = g_new0 (GstType, 1); - type->id = _gst_maxtype++; - type->mime = factory->mime; - type->exts = factory->exts; - _gst_types = g_list_prepend (_gst_types, type); + type->id = _gst_maxtype++; + type->mime = factory->mime; + type->exts = factory->exts; + _gst_types = g_list_prepend (_gst_types, type); id = type->id; + GST_DEBUG (0,"gsttype: new mime type '%s', id %d\n", type->mime, type->id); } else { type = gst_type_find_by_id (id); @@ -96,8 +97,8 @@ gst_type_register (GstTypeFactory *factory) return id; } -static -guint16 gst_type_find_by_mime_func (const gchar *mime) +static +guint16 gst_type_find_by_mime_func (const gchar *mime) { GList *walk; GstType *type; @@ -142,8 +143,8 @@ guint16 gst_type_find_by_mime_func (const gchar *mime) * * Returns: the type id */ -guint16 -gst_type_find_by_mime (const gchar *mime) +guint16 +gst_type_find_by_mime (const gchar *mime) { return gst_type_find_by_mime_func (mime); } @@ -156,8 +157,8 @@ gst_type_find_by_mime (const gchar *mime) * * Returns: the type id */ -guint16 -gst_type_find_by_ext (const gchar *ext) +guint16 +gst_type_find_by_ext (const gchar *ext) { //FIXME g_warning ("gsttype: find_by_ext not implemented"); @@ -173,7 +174,7 @@ gst_type_find_by_ext (const gchar *ext) * Returns: the type */ GstType* -gst_type_find_by_id (guint16 id) +gst_type_find_by_id (guint16 id) { GList *walk = _gst_types; GstType *type; @@ -196,7 +197,7 @@ gst_type_find_by_id (guint16 id) * Returns: a list of GstTypes */ GList* -gst_type_get_list (void) +gst_type_get_list (void) { return _gst_types; } @@ -210,8 +211,8 @@ gst_type_get_list (void) * * Returns: the new xmlNodePtr */ -xmlNodePtr -gst_typefactory_save_thyself (GstTypeFactory *factory, xmlNodePtr parent) +xmlNodePtr +gst_typefactory_save_thyself (GstTypeFactory *factory, xmlNodePtr parent) { xmlNewChild (parent, NULL, "mime", factory->mime); if (factory->exts) { @@ -220,11 +221,11 @@ gst_typefactory_save_thyself (GstTypeFactory *factory, xmlNodePtr parent) if (factory->typefindfunc) { xmlNewChild (parent, NULL, "typefind", NULL); } - + return parent; } -static GstCaps * +static GstCaps * gst_type_typefind_dummy (GstBuffer *buffer, gpointer priv) { GstType *type = (GstType *)priv; @@ -263,7 +264,7 @@ gst_type_typefind_dummy (GstBuffer *buffer, gpointer priv) * Returns: the new typefactory */ GstTypeFactory* -gst_typefactory_load_thyself (xmlNodePtr parent) +gst_typefactory_load_thyself (xmlNodePtr parent) { GstTypeFactory *factory = g_new0 (GstTypeFactory, 1); diff --git a/gst/gsttype.h b/gst/gsttype.h index 2e2ef0a129..68ab8ce686 100644 --- a/gst/gsttype.h +++ b/gst/gsttype.h @@ -52,14 +52,14 @@ struct _GstTypeFactory { /* initialize the subsystem */ -void _gst_type_initialize (void); +void _gst_type_initialize (void); /* create a new type, or find/merge an existing one */ -guint16 gst_type_register (GstTypeFactory *factory); +guint16 gst_type_register (GstTypeFactory *factory); /* look up a type by mime or extension */ -guint16 gst_type_find_by_mime (const gchar *mime); -guint16 gst_type_find_by_ext (const gchar *ext); +guint16 gst_type_find_by_mime (const gchar *mime); +guint16 gst_type_find_by_ext (const gchar *ext); /* get GstType by id */ GstType* gst_type_find_by_id (guint16 id); @@ -67,7 +67,7 @@ GstType* gst_type_find_by_id (guint16 id); /* get the list of registered types (returns list of GstType!) */ GList* gst_type_get_list (void); -xmlNodePtr gst_typefactory_save_thyself (GstTypeFactory *factory, xmlNodePtr parent); +xmlNodePtr gst_typefactory_save_thyself (GstTypeFactory *factory, xmlNodePtr parent); GstTypeFactory* gst_typefactory_load_thyself (xmlNodePtr parent); #endif /* __GST_TYPE_H__ */ diff --git a/gst/gsttypefind.c b/gst/gsttypefind.c index 8f8489d681..78ac04c818 100644 --- a/gst/gsttypefind.c +++ b/gst/gsttypefind.c @@ -52,19 +52,20 @@ enum { }; -static void gst_typefind_class_init (GstTypeFindClass *klass); -static void gst_typefind_init (GstTypeFind *typefind); +static void gst_typefind_class_init (GstTypeFindClass *klass); +static void gst_typefind_init (GstTypeFind *typefind); -static void gst_typefind_set_arg (GtkObject *object, GtkArg *arg, guint id); -static void gst_typefind_get_arg (GtkObject *object, GtkArg *arg, guint id); +static void gst_typefind_set_arg (GtkObject *object, GtkArg *arg, guint id); +static void gst_typefind_get_arg (GtkObject *object, GtkArg *arg, guint id); -static void gst_typefind_chain (GstPad *pad, GstBuffer *buf); +static void gst_typefind_chain (GstPad *pad, GstBuffer *buf); static GstElementClass *parent_class = NULL; static guint gst_typefind_signals[LAST_SIGNAL] = { 0 }; GtkType -gst_typefind_get_type(void) { +gst_typefind_get_type (void) +{ static GtkType typefind_type = 0; if (!typefind_type) { @@ -78,13 +79,13 @@ gst_typefind_get_type(void) { (GtkArgGetFunc)gst_typefind_get_arg, (GtkClassInitFunc)NULL, }; - typefind_type = gtk_type_unique(GST_TYPE_ELEMENT,&typefind_info); + typefind_type = gtk_type_unique (GST_TYPE_ELEMENT, &typefind_info); } return typefind_type; } static void -gst_typefind_class_init (GstTypeFindClass *klass) +gst_typefind_class_init (GstTypeFindClass *klass) { GtkObjectClass *gtkobject_class; @@ -107,22 +108,22 @@ gst_typefind_class_init (GstTypeFindClass *klass) gtkobject_class->get_arg = gst_typefind_get_arg; } -static void -gst_typefind_init (GstTypeFind *typefind) +static void +gst_typefind_init (GstTypeFind *typefind) { typefind->sinkpad = gst_pad_new ("sink", GST_PAD_SINK); gst_element_add_pad (GST_ELEMENT (typefind), typefind->sinkpad); gst_pad_set_chain_function (typefind->sinkpad, gst_typefind_chain); } -static void -gst_typefind_set_arg (GtkObject *object, GtkArg *arg, guint id) +static void +gst_typefind_set_arg (GtkObject *object, GtkArg *arg, guint id) { GstTypeFind *typefind; /* it's not null if we got it, but it might not be ours */ g_return_if_fail (GST_IS_TYPEFIND (object)); - + typefind = GST_TYPEFIND (object); switch(id) { @@ -131,14 +132,14 @@ gst_typefind_set_arg (GtkObject *object, GtkArg *arg, guint id) } } -static void -gst_typefind_get_arg (GtkObject *object, GtkArg *arg, guint id) +static void +gst_typefind_get_arg (GtkObject *object, GtkArg *arg, guint id) { GstTypeFind *typefind; /* it's not null if we got it, but it might not be ours */ g_return_if_fail (GST_IS_TYPEFIND (object)); - + typefind = GST_TYPEFIND (object); switch(id) { @@ -150,8 +151,8 @@ gst_typefind_get_arg (GtkObject *object, GtkArg *arg, guint id) } } -static void -gst_typefind_chain (GstPad *pad, GstBuffer *buf) +static void +gst_typefind_chain (GstPad *pad, GstBuffer *buf) { GstTypeFind *typefind; GList *type_list; @@ -183,6 +184,7 @@ gst_typefind_chain (GstPad *pad, GstBuffer *buf) typefind->caps = caps; gtk_signal_emit (GTK_OBJECT (typefind), gst_typefind_signals[HAVE_TYPE], typefind->caps); + gst_pad_set_caps (pad, caps); goto end; } funcs = g_slist_next (funcs); diff --git a/gst/gstutils.c b/gst/gstutils.c index 9ea074a7b0..2ade4a5053 100644 --- a/gst/gstutils.c +++ b/gst/gstutils.c @@ -20,6 +20,9 @@ * Boston, MA 02111-1307, USA. */ +#include + +#include "gstextratypes.h" #include "gstutils.h" @@ -32,7 +35,9 @@ * * Returns: the property of the object */ -gint gst_util_get_int_arg(GtkObject *object,guchar *argname) { +gint +gst_util_get_int_arg (GtkObject *object,guchar *argname) +{ GtkArg arg; arg.name = argname; @@ -49,7 +54,9 @@ gint gst_util_get_int_arg(GtkObject *object,guchar *argname) { * * Returns: the property of the object */ -gint gst_util_get_bool_arg(GtkObject *object,guchar *argname) { +gint +gst_util_get_bool_arg (GtkObject *object,guchar *argname) +{ GtkArg arg; arg.name = argname; @@ -66,7 +73,9 @@ gint gst_util_get_bool_arg(GtkObject *object,guchar *argname) { * * Returns: the property of the object */ -glong gst_util_get_long_arg(GtkObject *object,guchar *argname) { +glong +gst_util_get_long_arg (GtkObject *object,guchar *argname) +{ GtkArg arg; arg.name = argname; @@ -83,7 +92,9 @@ glong gst_util_get_long_arg(GtkObject *object,guchar *argname) { * * Returns: the property of the object */ -gfloat gst_util_get_float_arg(GtkObject *object,guchar *argname) { +gfloat +gst_util_get_float_arg (GtkObject *object,guchar *argname) +{ GtkArg arg; arg.name = argname; @@ -100,7 +111,9 @@ gfloat gst_util_get_float_arg(GtkObject *object,guchar *argname) { * * Returns: the property of the object */ -gdouble gst_util_get_double_arg(GtkObject *object,guchar *argname) { +gdouble +gst_util_get_double_arg (GtkObject *object,guchar *argname) +{ GtkArg arg; arg.name = argname; @@ -117,7 +130,9 @@ gdouble gst_util_get_double_arg(GtkObject *object,guchar *argname) { * * Returns: the property of the object */ -guchar *gst_util_get_string_arg(GtkObject *object,guchar *argname) { +guchar* +gst_util_get_string_arg (GtkObject *object,guchar *argname) +{ GtkArg arg; arg.name = argname; @@ -134,11 +149,14 @@ guchar *gst_util_get_string_arg(GtkObject *object,guchar *argname) { * * Returns: the property of the object */ -gpointer gst_util_get_pointer_arg(GtkObject *object,guchar *argname) { +gpointer +gst_util_get_pointer_arg (GtkObject *object,guchar *argname) +{ GtkArg arg; arg.name = argname; gtk_object_getv(GTK_OBJECT(object),1,&arg); + return GTK_VALUE_POINTER(arg); } @@ -151,11 +169,14 @@ gpointer gst_util_get_pointer_arg(GtkObject *object,guchar *argname) { * * Returns: the property of the object */ -GtkWidget *gst_util_get_widget_arg(GtkObject *object,guchar *argname) { +GtkWidget* +gst_util_get_widget_arg (GtkObject *object,guchar *argname) +{ GtkArg arg; arg.name = argname; gtk_object_getv(GTK_OBJECT(object),1,&arg); + return GTK_WIDGET(GTK_VALUE_OBJECT(arg)); } @@ -166,7 +187,9 @@ GtkWidget *gst_util_get_widget_arg(GtkObject *object,guchar *argname) { * * Dumps the memory block into a hex representation. Useful for debugging. */ -void gst_util_dump_mem(guchar *mem, guint size) { +void +gst_util_dump_mem (guchar *mem, guint size) +{ guint i, j; i = j =0; @@ -183,3 +206,88 @@ void gst_util_dump_mem(guchar *mem, guint size) { } g_print("\n"); } + +/** + * gst_util_set_object_arg: + * @object: the object to set the argument of + * @name: the name of the argument to set + * @value: the string value to set + * + * Convertes the string value to the type of the objects argument and + * sets the argument with it. + */ +void +gst_util_set_object_arg (GtkObject *object, guchar *name, gchar *value) +{ + if (name && value) { + GtkType type = GTK_OBJECT_TYPE (object); + GtkArgInfo *info; + gchar *result; + + result = gtk_object_arg_get_info (type, name, &info); + + if (result) { + g_print("gstutil: %s\n", result); + } + else if (info->arg_flags & GTK_ARG_WRITABLE) { + switch (info->type) { + case GTK_TYPE_STRING: + gtk_object_set (GTK_OBJECT (object), name, value, NULL); + break; + case GTK_TYPE_INT: { + gint i; + sscanf (value, "%d", &i); + gtk_object_set (GTK_OBJECT (object), name, i, NULL); + break; + } + case GTK_TYPE_LONG: { + glong i; + sscanf (value, "%ld", &i); + gtk_object_set (GTK_OBJECT (object), name, i, NULL); + break; + } + case GTK_TYPE_ULONG: { + gulong i; + sscanf (value, "%lu", &i); + gtk_object_set (GTK_OBJECT (object), name, i, NULL); + break; + } + case GTK_TYPE_BOOL: { + gboolean i = FALSE; + if (!strcmp ("true", value)) i = TRUE; + gtk_object_set (GTK_OBJECT (object), name, i, NULL); + break; + } + case GTK_TYPE_CHAR: { + gchar i; + sscanf (value, "%c", &i); + gtk_object_set (GTK_OBJECT (object), name, i, NULL); + break; + } + case GTK_TYPE_UCHAR: { + guchar i; + sscanf (value, "%c", &i); + gtk_object_set (GTK_OBJECT (object), name, i, NULL); + break; + } + case GTK_TYPE_FLOAT: { + gfloat i; + sscanf (value, "%f", &i); + gtk_object_set (GTK_OBJECT (object), name, i, NULL); + break; + } + case GTK_TYPE_DOUBLE: { + gfloat i; + sscanf (value, "%g", &i); + gtk_object_set (GTK_OBJECT (object), name, (gdouble)i, NULL); + break; + } + default: + if (info->type == GST_TYPE_FILENAME) { + gtk_object_set (GTK_OBJECT (object), name, value, NULL); + } + break; + } + } + } +} diff --git a/gst/gstutils.h b/gst/gstutils.h index a6465fee08..b57f86613b 100644 --- a/gst/gstutils.h +++ b/gst/gstutils.h @@ -26,6 +26,10 @@ #include +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + gint gst_util_get_int_arg (GtkObject *object, guchar *argname); gboolean gst_util_get_bool_arg (GtkObject *object, guchar *argname); glong gst_util_get_long_arg (GtkObject *object, guchar *argname); @@ -35,6 +39,12 @@ guchar* gst_util_get_string_arg (GtkObject *object, guchar *argname); gpointer gst_util_get_pointer_arg (GtkObject *object, guchar *argname); GtkWidget* gst_util_get_widget_arg (GtkObject *object, guchar *argname); +void gst_util_set_object_arg (GtkObject *object, guchar *name, gchar *value); + void gst_util_dump_mem (guchar *mem, guint size); +#ifdef __cplusplus +} +#endif /* __cplusplus */ + #endif /* __GST_UTILS_H__ */ diff --git a/gst/meta/Makefile.am b/gst/meta/Makefile.am index 59107c0de5..388fd45da0 100644 --- a/gst/meta/Makefile.am +++ b/gst/meta/Makefile.am @@ -1,4 +1,3 @@ metaincludedir = $(includedir)/gst/meta metainclude_HEADERS = \ - audioraw.h \ - videoraw.h + spectrum.h diff --git a/gst/meta/videoraw.h b/gst/meta/videoraw.h deleted file mode 100644 index 8452eaad08..0000000000 --- a/gst/meta/videoraw.h +++ /dev/null @@ -1,80 +0,0 @@ -/* Gnome-Streamer - * Copyright (C) <1999> Erik Walthinsen - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - - -#ifndef __GST_META_VIDEORAW_H__ -#define __GST_META_VIDEORAW_H__ - -#include -#include -#include -#include - -typedef struct _MetaVideoRaw MetaVideoRaw; -typedef struct _MetaDGA MetaDGA; -typedef struct _MetaOverlay MetaOverlay; -typedef struct _OverlayClip OverlayClip; - -struct _OverlayClip { - int x1, x2, y1, y2; -}; - -struct _MetaDGA { - /* the base address of the screen */ - void *base; - /* the dimensions of the screen */ - int swidth, sheight; - /* the number of bytes in a line */ - int bytes_per_line; -}; - -struct _MetaOverlay { - /* the position of the window */ - int wx, wy; - /* a reference to the object sending overlay change events */ - GtkWidget *overlay_element; - /* the number of overlay regions */ - int clip_count; - /* the overlay regions of the display window */ - struct _OverlayClip overlay_clip[32]; - - gint width; - gint height; - - gboolean did_overlay; - gboolean fully_obscured; -}; - -struct _MetaVideoRaw { - GstMeta meta; - - /* formatting information */ - GstColorSpaceType format; - GdkVisual *visual; - /* dimensions of the video buffer */ - gint width; - gint height; - /* a pointer to the overlay info if the sink supports this */ - MetaOverlay *overlay_info; - /* a pointer to the DGA info if the sink supports this */ - MetaDGA *dga_info; -}; - -#endif /* __GST_META_VIDEORAW_H__ */ - diff --git a/gst/types/gsttypes.c b/gst/types/gsttypes.c index 6165455d6d..9fe885b644 100644 --- a/gst/types/gsttypes.c +++ b/gst/types/gsttypes.c @@ -40,11 +40,11 @@ plugin_init (GModule *module) while (_factories[i].mime) { gst_type_register (&_factories[i]); gst_plugin_add_type (plugin, &_factories[i]); -// DEBUG("added factory #%d '%s'\n",i,_factories[i].mime); + GST_DEBUG(0, "added factory #%d '%s'\n",i,_factories[i].mime); i++; } -// gst_info ("gsttypes: loaded %d standard types\n",i); + //gst_info ("gsttypes: loaded %d standard types\n",i); return plugin; } diff --git a/gstplay/Makefile.am b/gstplay/Makefile.am index eb4a726d86..943960095b 100644 --- a/gstplay/Makefile.am +++ b/gstplay/Makefile.am @@ -9,10 +9,12 @@ bin_PROGRAMS = gstmediaplay lib_LTLIBRARIES = libgstmediaplay.la +man_MANS = gstmediaplay.1 + gladedir = $(datadir)/gstmediaplay glade_DATA = gstmediaplay.glade play.xpm stop.xpm pause.xpm -EXTRA_DIST = $(glade_DATA) +EXTRA_DIST = $(glade_DATA) $(man_MANS) libgstmediaplay_la_SOURCES = \ gstplay.c \ @@ -23,13 +25,18 @@ libgstmediaplay_la_SOURCES = \ gstmediaplay_SOURCES = \ main.c +libgstmediaplayincludedir = $(includedir)/gstplay +libgstmediaplayinclude_HEADERS = \ + gstplay.h + noinst_HEADERS = \ gstmediaplay.h \ gststatusarea.h \ callbacks.h \ - gstplay.h \ gstplayprivate.h +libgstmediaplay_la_LDFLAGS = -rdynamic + gstmediaplay_CFLAGS = $(LIBGLADE_GNOME_CFLAGS) gstmediaplay_LDADD = $(GST_LIBS) $(LIBGLADE_GNOME_LIBS) libgstmediaplay.la diff --git a/gstplay/callbacks.c b/gstplay/callbacks.c index 3e35234d9b..781173f894 100644 --- a/gstplay/callbacks.c +++ b/gstplay/callbacks.c @@ -6,6 +6,9 @@ #include #include +#include +#include + #include "gstplay.h" #include "callbacks.h" @@ -45,7 +48,15 @@ on_preferences1_activate (GtkMenuItem *menuitem, void on_about_activate(GtkWidget *widget, gpointer data) { GladeXML *xml; - xml = glade_xml_new(DATADIR "gstmediaplay.glade", "about"); + struct stat statbuf; + + if (stat(DATADIR"gstmediaplay.glade", &statbuf) == 0) { + xml = glade_xml_new (DATADIR"gstmediaplay.glade", "about"); + } + else { + xml = glade_xml_new ("gstmediaplay.glade", "about"); + } + /* connect the signals in the interface */ glade_xml_signal_autoconnect(xml); } diff --git a/gstplay/gstmediaplay.1 b/gstplay/gstmediaplay.1 new file mode 100644 index 0000000000..b88c097886 --- /dev/null +++ b/gstplay/gstmediaplay.1 @@ -0,0 +1,39 @@ +.TH GStreamer 1 "March 2001" +.SH NAME +gstmediaplay - a GStreamer media player +.SH SYNOPSIS +.B gstmediaplay [OPTION...] [FILE] +.SH DESCRIPTION +.PP +\fIgstmediaplay\fP is a media player based on the \fIGStreamer\fP +framework. +. +.SH OPTIONS +.l +\fIgstmediaplay\fP accepts the following options: +.TP 8 +.B FILE +File to play on startup +.TP 8 +.B \-\-help +Print help synopsis and available FLAGS +.TP 8 +.B \-\-gst\-info\-mask=FLAGS +\fIGStreamer\fP info flags to set (list with \-\-help) +.TP 8 +.B \-\-gst\-debug\-mask=FLAGS +\fIGStreamer\fP debugging flags to set (list with \-\-help) +.TP 8 +.B \-\-gst\-plugin\-spew +\fIGStreamer\fP info flags to set +Enable printout of errors while loading \fIGStreamer\fP plugins +.TP 8 +.B \-\-gst\-plugin\-path=PATH +Add directories separated with ':' to the plugin search path +.SH SEE ALSO +.BR gstreamer\-register (1), +.BR gstreamer\-inspect (1), +.BR gstreamer\-launch (1), +.BR gsteditor (1) +.SH AUTHOR +The GStreamer team at http://gstreamer.net/ diff --git a/gstplay/gstmediaplay.c b/gstplay/gstmediaplay.c index 49276c6af1..24be408f5e 100644 --- a/gstplay/gstmediaplay.c +++ b/gstplay/gstmediaplay.c @@ -412,6 +412,8 @@ gst_media_play_frame_displayed (GstPlay *play, size = gst_play_get_media_size (play); current_offset = gst_play_get_media_offset (play); + //g_print ("%lu %lu %lu %lu\n", current_time, total_time, size, current_offset); + if (current_time != mplay->last_time) { gdk_threads_enter (); gst_media_play_update_status_area (mplay, current_time, total_time); diff --git a/gstplay/gstmediaplay.glade b/gstplay/gstmediaplay.glade index c24f68918b..448409d2e0 100644 --- a/gstplay/gstmediaplay.glade +++ b/gstplay/gstmediaplay.glade @@ -148,7 +148,7 @@ False - False + True @@ -405,7 +405,8 @@ Erik Walthinsen <omega@cse.ogi.edu>, Wim Taymans <wim.taymans@tvd.be>, Richard Boulton <richard@tartarus.org>, -Chris Emerson (PPC port) +Chris Emerson (PPC port), +Ronald Bultje <rbultje@ronald.bitfreak.net> A generic media player for the gstreamer streaming media framework. @@ -442,6 +443,7 @@ Chris Emerson (PPC port) Sun, 06 Aug 2000 15:55:52 GMT GNOME_STOCK_BUTTON_OK + GTK_RELIEF_NORMAL @@ -457,6 +459,7 @@ Chris Emerson (PPC port) Sun, 06 Aug 2000 15:53:48 GMT GNOME_STOCK_BUTTON_CANCEL + GTK_RELIEF_NORMAL diff --git a/gstplay/gstplay.c b/gstplay/gstplay.c index 86aa6261b5..e8898ef32d 100644 --- a/gstplay/gstplay.c +++ b/gstplay/gstplay.c @@ -17,6 +17,7 @@ static void gst_play_get_arg (GtkObject *object,GtkArg *arg,guint id); static void gst_play_realize (GtkWidget *play); static void gst_play_frame_displayed (GstElement *element, GstPlay *play); +static void gst_play_have_size (GstElement *element, guint width, guint height, GstPlay *play); static void gst_play_audio_handoff (GstElement *element, GstPlay *play); /* signals and args */ @@ -41,8 +42,8 @@ enum { static GtkObject *parent_class = NULL; static guint gst_play_signals[LAST_SIGNAL] = { 0 }; -GtkType -gst_play_get_type (void) +GtkType +gst_play_get_type (void) { static GtkType play_type = 0; @@ -62,8 +63,8 @@ gst_play_get_type (void) return play_type; } -static void -gst_play_class_init (GstPlayClass *klass) +static void +gst_play_class_init (GstPlayClass *klass) { GtkObjectClass *object_class; GtkWidgetClass *widget_class; @@ -108,39 +109,47 @@ gst_play_class_init (GstPlayClass *klass) object_class->set_arg = gst_play_set_arg; object_class->get_arg = gst_play_get_arg; - widget_class->realize = gst_play_realize; + widget_class->realize = gst_play_realize; } -static void -gst_play_init (GstPlay *play) +static void +gst_play_init (GstPlay *play) { - GstPlayPrivate *priv = g_new0 (GstPlayPrivate, 1); + GstElement *colorspace; play->priv = priv; /* create a new bin to hold the elements */ priv->thread = gst_thread_new ("main_thread"); g_assert (priv->thread != NULL); - priv->pipeline = gst_pipeline_new ("main_pipeline"); - g_assert (priv->pipeline != NULL); + priv->bin = gst_bin_new ("main_bin"); + g_assert (priv->bin != NULL); - /* and an audio sink */ - priv->audio_play = gst_elementfactory_make ("audiosink","play_audio"); - g_return_if_fail (priv->audio_play != NULL); - gtk_signal_connect (GTK_OBJECT (priv->audio_play), "handoff", + priv->audio_element = gst_elementfactory_make ("osssink", "play_audio"); + g_return_if_fail (priv->audio_element != NULL); + gtk_signal_connect (GTK_OBJECT (priv->audio_element), "handoff", GTK_SIGNAL_FUNC (gst_play_audio_handoff), play); - /* and a video sink */ - priv->video_show = gst_elementfactory_make ("videosink","show"); + priv->video_element = gst_elementfactory_make ("bin", "video_bin"); + + priv->video_show = gst_elementfactory_make ("xvideosink", "show"); g_return_if_fail (priv->video_show != NULL); - gtk_object_set (GTK_OBJECT (priv->video_show),"xv_enabled",FALSE,NULL); - gtk_signal_connect (GTK_OBJECT (priv->video_show), "frame_displayed", + //gtk_object_set (GTK_OBJECT (priv->video_element), "xv_enabled", FALSE, NULL); + gtk_signal_connect (GTK_OBJECT (priv->video_show), "frame_displayed", GTK_SIGNAL_FUNC (gst_play_frame_displayed), play); + gtk_signal_connect (GTK_OBJECT (priv->video_show), "have_size", + GTK_SIGNAL_FUNC (gst_play_have_size), play); - gst_pipeline_add_sink (GST_PIPELINE (priv->pipeline), priv->audio_play); - gst_pipeline_add_sink (GST_PIPELINE (priv->pipeline), priv->video_show); + colorspace = gst_elementfactory_make ("colorspace", "colorspace"); + gst_bin_add (GST_BIN (priv->video_element), colorspace); + gst_bin_add (GST_BIN (priv->video_element), priv->video_show); + + gst_element_connect (colorspace, "src", priv->video_show, "sink"); + gst_element_add_ghost_pad (priv->video_element, + gst_element_get_pad (colorspace, "sink"), + "sink"); play->state = GST_PLAY_STOPPED; play->flags = 0; @@ -155,164 +164,288 @@ gst_play_init (GstPlay *play) } GstPlay * -gst_play_new () +gst_play_new () { return GST_PLAY (gtk_type_new (GST_TYPE_PLAY)); } -static void -gst_play_eos (GstElement *element, - GstPlay *play) +static void +gst_play_eos (GstElement *element, + GstPlay *play) { - g_print("gstplay: eos reached\n"); + GST_DEBUG(0, "gstplay: eos reached\n"); gst_play_stop(play); } -static void -gst_play_frame_displayed (GstElement *element, - GstPlay *play) +static void +gst_play_have_size (GstElement *element, guint width, guint height, + GstPlay *play) { + GstPlayPrivate *priv; + + priv = (GstPlayPrivate *)play->priv; + + gtk_widget_set_usize (priv->video_widget, width, height); +} + +static void +gst_play_frame_displayed (GstElement *element, + GstPlay *play) +{ + GstPlayPrivate *priv; + static int stolen = FALSE; + + priv = (GstPlayPrivate *)play->priv; + + gdk_threads_enter (); + if (!stolen) { + gtk_widget_realize (priv->video_widget); + gtk_socket_steal (GTK_SOCKET (priv->video_widget), + gst_util_get_int_arg (GTK_OBJECT(priv->video_show), "xid")); + gtk_widget_show (priv->video_widget); + stolen = TRUE; + } + gdk_threads_leave (); + gtk_signal_emit (GTK_OBJECT (play), gst_play_signals[SIGNAL_FRAME_DISPLAYED], NULL); } -static void -gst_play_audio_handoff (GstElement *element, - GstPlay *play) +static void +gst_play_audio_handoff (GstElement *element, + GstPlay *play) { gtk_signal_emit (GTK_OBJECT (play), gst_play_signals[SIGNAL_AUDIO_PLAYED], NULL); } -static void -gst_play_object_introspect (GstElement *element, +static void +gst_play_object_introspect (GstObject *object, const gchar *property, GstElement **target) { gchar *info; GtkArgInfo *arg; + GstElement *element; - info = gtk_object_arg_get_info( GTK_OBJECT_TYPE(element), property, &arg); + if (!GST_IS_ELEMENT (object)) + return; + + element = GST_ELEMENT (object); + + info = gtk_object_arg_get_info (GTK_OBJECT_TYPE (element), property, &arg); if (info) { g_free(info); } else { *target = element; - g_print("gstplay: using element \"%s\" for %s property\n", + GST_DEBUG(0, "gstplay: using element \"%s\" for %s property\n", gst_element_get_name(element), property); } } /* Dumb introspection of the interface... - * this will change with glib 1.4 + * this will change with glib 1.4 * */ -static void -gst_play_object_added (GstElement *pipeline, - GstElement *element, - GstPlay *play) +static void +gst_play_object_added (GstAutoplug* autoplug, + GstObject *object, + GstPlay *play) { GstPlayPrivate *priv; - + g_return_if_fail (play != NULL); priv = (GstPlayPrivate *)play->priv; - if (GST_FLAG_IS_SET (element, GST_ELEMENT_NO_SEEK)) { + if (GST_FLAG_IS_SET (object, GST_ELEMENT_NO_SEEK)) { priv->can_seek = FALSE; } - if (GST_IS_BIN (element)) { - gtk_signal_connect (GTK_OBJECT (element), "object_added", gst_play_object_added, play); + if (GST_IS_BIN (object)) { + //gtk_signal_connect (GTK_OBJECT (object), "object_added", gst_play_object_added, play); } else { // first come first serve here... - if (!priv->offset_element) - gst_play_object_introspect (element, "offset", &priv->offset_element); - if (!priv->bit_rate_element) - gst_play_object_introspect (element, "bit_rate", &priv->bit_rate_element); + if (!priv->offset_element) + gst_play_object_introspect (object, "offset", &priv->offset_element); + if (!priv->bit_rate_element) + gst_play_object_introspect (object, "bit_rate", &priv->bit_rate_element); if (!priv->media_time_element) - gst_play_object_introspect (element, "media_time", &priv->media_time_element); + gst_play_object_introspect (object, "media_time", &priv->media_time_element); if (!priv->current_time_element) - gst_play_object_introspect (element, "current_time", &priv->current_time_element); + gst_play_object_introspect (object, "current_time", &priv->current_time_element); } } -GstPlayReturn -gst_play_set_uri (GstPlay *play, - const guchar *uri) +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); + + if (found) { + caps = gst_util_get_pointer_arg (GTK_OBJECT (typefind), "caps"); + + gst_pad_set_caps (gst_element_get_pad (element, "src"), caps); + } + + 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 gboolean +connect_pads (GstElement *new_element, GstElement *target, gboolean add) +{ + GList *pads = gst_element_get_pad_list (new_element); + GstPad *targetpad = gst_element_get_pad (target, "sink"); + + while (pads) { + GstPad *pad = GST_PAD (pads->data); + + if (gst_pad_check_compatibility (pad, targetpad)) { + if (add) { + gst_bin_add (GST_BIN (gst_element_get_parent ( + GST_ELEMENT (gst_pad_get_real_parent (pad)))), + target); + } + gst_pad_connect (pad, targetpad); + return TRUE; + } + pads = g_list_next (pads); + } + return FALSE; +} + +GstPlayReturn +gst_play_set_uri (GstPlay *play, + const guchar *uri) { GstPlayPrivate *priv; + GstCaps *src_caps; + GstElement *new_element; + GstAutoplug *autoplug; g_return_val_if_fail (play != NULL, GST_PLAY_ERROR); g_return_val_if_fail (GST_IS_PLAY (play), GST_PLAY_ERROR); g_return_val_if_fail (uri != NULL, GST_PLAY_ERROR); - + priv = (GstPlayPrivate *)play->priv; - if (priv->src) { - } - - if (priv->uri) g_free (priv->uri); + if (priv->uri) + g_free (priv->uri); priv->uri = g_strdup (uri); - //priv->src = gst_elementfactory_make ("disksrc", "disk_src"); priv->src = gst_elementfactory_make ("disksrc", "disk_src"); //priv->src = gst_elementfactory_make ("dvdsrc", "disk_src"); + priv->offset_element = priv->src; + g_return_val_if_fail (priv->src != NULL, -1); - gtk_object_set (GTK_OBJECT (priv->src),"location",uri,NULL); - gtk_signal_connect (GTK_OBJECT (priv->src), "eos", GTK_SIGNAL_FUNC (gst_play_eos), play); + gtk_object_set (GTK_OBJECT (priv->src), "location", uri, NULL); - gtk_signal_connect (GTK_OBJECT (priv->pipeline), "object_added", gst_play_object_added, play); + gst_bin_add (GST_BIN (priv->bin), priv->src); - gst_pipeline_add_src (GST_PIPELINE (priv->pipeline),GST_ELEMENT (priv->src)); + src_caps = gst_play_typefind (GST_BIN (priv->bin), priv->src); - if (!gst_pipeline_autoplug (GST_PIPELINE (priv->pipeline))) { + if (!src_caps) { return GST_PLAY_UNKNOWN_MEDIA; } - if (GST_PAD_CONNECTED (gst_element_get_pad (priv->video_show, "sink"))) { - play->flags |= GST_PLAY_TYPE_VIDEO; - } - if (GST_PAD_CONNECTED (gst_element_get_pad (priv->audio_play, "sink"))) { - play->flags |= GST_PLAY_TYPE_AUDIO; + autoplug = gst_autoplugfactory_make ("staticrender"); + g_assert (autoplug != NULL); + + gtk_signal_connect (GTK_OBJECT (autoplug), "new_object", gst_play_object_added, play); + + new_element = gst_autoplug_to_renderers (autoplug, + gst_pad_get_caps (gst_element_get_pad (priv->src, "src")), + priv->video_element, + priv->audio_element, + NULL); + + if (!new_element) { + return GST_PLAY_CANNOT_PLAY; } - // hmmmm hack? FIXME - GST_FLAG_UNSET (priv->pipeline, GST_BIN_FLAG_MANAGER); + gst_bin_remove (GST_BIN (priv->bin), priv->src); + gst_bin_add (GST_BIN (priv->thread), priv->src); - gst_bin_add (GST_BIN (priv->thread), priv->pipeline); + gst_bin_add (GST_BIN (priv->bin), new_element); + + gst_element_connect (priv->src, "src", new_element, "sink"); + + gst_bin_add (GST_BIN (priv->thread), priv->bin); + gtk_signal_connect (GTK_OBJECT (priv->thread), "eos", GTK_SIGNAL_FUNC (gst_play_eos), play); return GST_PLAY_OK; } -static void -gst_play_realize (GtkWidget *widget) +static void +gst_play_realize (GtkWidget *widget) { GstPlay *play; - GtkWidget *video_widget; GstPlayPrivate *priv; - + g_return_if_fail (GST_IS_PLAY (widget)); + //g_print ("realize\n"); + play = GST_PLAY (widget); priv = (GstPlayPrivate *)play->priv; - video_widget = gst_util_get_widget_arg (GTK_OBJECT (priv->video_show),"widget"); + priv->video_widget = gtk_socket_new (); - if (video_widget) { - gtk_container_add (GTK_CONTAINER (widget), video_widget); - gtk_widget_show (video_widget); - } + gtk_container_add (GTK_CONTAINER (widget), priv->video_widget); if (GTK_WIDGET_CLASS (parent_class)->realize) { GTK_WIDGET_CLASS (parent_class)->realize (widget); } + + //gtk_socket_steal (GTK_SOCKET (priv->video_widget), + // gst_util_get_int_arg (GTK_OBJECT(priv->video_element), "xid")); + + //gtk_widget_realize (priv->video_widget); + //gtk_socket_steal (GTK_SOCKET (priv->video_widget), + // gst_util_get_int_arg (GTK_OBJECT(priv->video_element), "xid")); } -void -gst_play_play (GstPlay *play) +void +gst_play_play (GstPlay *play) { GstPlayPrivate *priv; @@ -333,8 +466,8 @@ gst_play_play (GstPlay *play) play->state); } -void -gst_play_pause (GstPlay *play) +void +gst_play_pause (GstPlay *play) { GstPlayPrivate *priv; @@ -353,8 +486,8 @@ gst_play_pause (GstPlay *play) play->state); } -void -gst_play_stop (GstPlay *play) +void +gst_play_stop (GstPlay *play) { GstPlayPrivate *priv; @@ -365,8 +498,10 @@ gst_play_stop (GstPlay *play) priv = (GstPlayPrivate *)play->priv; - gst_element_set_state (GST_ELEMENT (priv->thread),GST_STATE_NULL); + // FIXME until state changes are handled properly + gst_element_set_state (GST_ELEMENT (priv->thread),GST_STATE_READY); gtk_object_set (GTK_OBJECT (priv->src),"offset",0,NULL); + //gst_element_set_state (GST_ELEMENT (priv->thread),GST_STATE_NULL); play->state = GST_PLAY_STOPPED; @@ -374,8 +509,8 @@ gst_play_stop (GstPlay *play) play->state); } -gulong -gst_play_get_media_size (GstPlay *play) +gulong +gst_play_get_media_size (GstPlay *play) { GstPlayPrivate *priv; @@ -387,7 +522,7 @@ gst_play_get_media_size (GstPlay *play) return gst_util_get_long_arg (GTK_OBJECT (priv->src), "size"); } -gulong +gulong gst_play_get_media_offset (GstPlay *play) { GstPlayPrivate *priv; @@ -397,15 +532,18 @@ gst_play_get_media_offset (GstPlay *play) priv = (GstPlayPrivate *)play->priv; - return gst_util_get_long_arg (GTK_OBJECT (priv->offset_element), "offset"); + if (priv->offset_element) + return gst_util_get_long_arg (GTK_OBJECT (priv->offset_element), "offset"); + else + return 0; } -gulong +gulong gst_play_get_media_total_time (GstPlay *play) { gulong total_time, bit_rate; GstPlayPrivate *priv; - + g_return_val_if_fail (play != NULL, 0); g_return_val_if_fail (GST_IS_PLAY (play), 0); @@ -419,7 +557,7 @@ gst_play_get_media_total_time (GstPlay *play) bit_rate = gst_util_get_long_arg (GTK_OBJECT (priv->bit_rate_element), "bit_rate"); - if (bit_rate) + if (bit_rate) total_time = (gst_play_get_media_size (play) * 8) / bit_rate; else total_time = 0; @@ -427,12 +565,12 @@ gst_play_get_media_total_time (GstPlay *play) return total_time; } -gulong +gulong gst_play_get_media_current_time (GstPlay *play) { gulong current_time, bit_rate; GstPlayPrivate *priv; - + g_return_val_if_fail (play != NULL, 0); g_return_val_if_fail (GST_IS_PLAY (play), 0); @@ -446,7 +584,7 @@ gst_play_get_media_current_time (GstPlay *play) bit_rate = gst_util_get_long_arg (GTK_OBJECT (priv->bit_rate_element), "bit_rate"); - if (bit_rate) + if (bit_rate) current_time = (gst_play_get_media_offset (play) * 8) / bit_rate; else current_time = 0; @@ -454,7 +592,7 @@ gst_play_get_media_current_time (GstPlay *play) return current_time; } -gboolean +gboolean gst_play_media_can_seek (GstPlay *play) { GstPlayPrivate *priv; @@ -467,8 +605,8 @@ gst_play_media_can_seek (GstPlay *play) return priv->can_seek; } -void -gst_play_media_seek (GstPlay *play, +void +gst_play_media_seek (GstPlay *play, gulong offset) { GstPlayPrivate *priv; @@ -482,10 +620,10 @@ gst_play_media_seek (GstPlay *play, } -static void +static void gst_play_set_arg (GtkObject *object, GtkArg *arg, - guint id) + guint id) { GstPlay *play; @@ -503,10 +641,10 @@ gst_play_set_arg (GtkObject *object, } } -static void +static void gst_play_get_arg (GtkObject *object, GtkArg *arg, - guint id) + guint id) { GstPlay *play; GstPlayPrivate *priv; diff --git a/gstplay/gstplay.h b/gstplay/gstplay.h index 7452a78826..fcaebf2f18 100644 --- a/gstplay/gstplay.h +++ b/gstplay/gstplay.h @@ -31,6 +31,7 @@ typedef enum { typedef enum { GST_PLAY_OK, GST_PLAY_UNKNOWN_MEDIA, + GST_PLAY_CANNOT_PLAY, GST_PLAY_ERROR, } GstPlayReturn; diff --git a/gstplay/gstplayprivate.h b/gstplay/gstplayprivate.h index 66b7b4dd9c..6c51479f03 100644 --- a/gstplay/gstplayprivate.h +++ b/gstplay/gstplayprivate.h @@ -12,9 +12,10 @@ typedef struct _GstPlayPrivate GstPlayPrivate; struct _GstPlayPrivate { GstElement *thread; - GstElement *pipeline; - GstElement *audio_play; + GstElement *bin; + GstElement *video_element, *audio_element; GstElement *video_show; + GtkWidget *video_widget; GstElement *src; guchar *uri; diff --git a/gstreamer-config.1 b/gstreamer-config.1 new file mode 100644 index 0000000000..254ae3129f --- /dev/null +++ b/gstreamer-config.1 @@ -0,0 +1,43 @@ +.TH GStreamer 1 "March 2001" +.SH NAME +gstreamer\-config - script to get information about the installed version of GStreamer +.SH SYNOPSIS +.B gstreamer\-config [\-\-prefix\fI[=DIR]\fP] [\-\-exec\-prefix\fI[=DIR]\fP] [\-\-version] [\-\-libs] [\-\-cflags] +.SH DESCRIPTION +.PP +\fIgstreamer\-config\fP is a tool that is used to configure to determine +the compiler and linker flags that should be used to compile +and link programs that use \fIGStreamer\fP. It is also used internally +to the .m4 macros for GNU autoconf that are included with \fIGStreamer\fP. +. +.SH OPTIONS +.l +\fIgstreamer\-config\fP accepts the following options: +.TP 8 +.B \-\-version +Print the currently installed version of \fIGStreamer\fP on the standard output. +.TP 8 +.B \-\-libs +Print the linker flags that are necessary to link a \fIGStreamer\fP program. +.TP 8 +.B \-\-cflags +Print the compiler flags that are necessary to compile a \fIGStreamer\fP program. +.TP 8 +.B \-\-prefix=PREFIX +If specified, use PREFIX instead of the installation prefix that \fIGStreamer\fP +was built with when computing the output for the \-\-cflags and +\-\-libs options. This option is also used for the exec prefix +if \-\-exec\-prefix was not specified. This option must be specified +before any \-\-libs or \-\-cflags options. +.TP 8 +.B \-\-exec\-prefix=PREFIX +If specified, use PREFIX instead of the installation exec prefix that +\fIGStreamer\fP was built with when computing the output for the \-\-cflags +and \-\-libs options. This option must be specified before any +\-\-libs or \-\-cflags options. +.SH SEE ALSO +.BR gstreamer\-register (1), +.BR gstreamer\-inspect (1), +.BR gstreamer\-launch (1) +.SH AUTHOR +The GStreamer team at http://gstreamer.net/ diff --git a/gstreamer-config.in b/gstreamer-config.in index 6811a7feee..8cd2df8e76 100644 --- a/gstreamer-config.in +++ b/gstreamer-config.in @@ -47,14 +47,14 @@ while test $# -gt 0; do elif test @includedir@ != /usr/include ; then includes=-I@includedir@ fi - echo $includes `gtk-config --cflags gtk gthread` + echo $includes @CORE_CFLAGS@ ;; --libs) if test $prefix -ef @builddir@ ; then - echo @builddir@/libgst.la `gtk-config --libs gtk gthread` + echo @builddir@/libgst.la @CORE_LIBS@ else libdirs=-L@libdir@ - echo $libdirs -lgst `gtk-config --libs gtk gthread` + echo $libdirs -lgst @CORE_LIBS@ fi ;; *) diff --git a/gstreamer.m4 b/gstreamer.m4 index 2497de709b..59f63d9d69 100644 --- a/gstreamer.m4 +++ b/gstreamer.m4 @@ -1,21 +1,169 @@ -# a macro to get the libs/cflags for gscope -# serial 1 +dnl Configure paths for GStreamer +dnl This was based upon the glib.m4 created by Owen Taylor 97-11-3 +dnl Changes mostly involve replacing GLIB with GStreamer +dnl +dnl Written by Thomas Nyberg 2001-03-01 -dnl AM_PATH_GSTREAMER([ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]) -dnl Test to see if timestamp is installed, and define GSTREAMER_CFLAGS, LIBS +dnl AM_PATH_GSTREAMER([MINIMUM-VERSION, [ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]]]) +dnl Test for GStreamer, and define GSTREAMER_CFLAGS and GSTREAMER_LIBS dnl AC_DEFUN(AM_PATH_GSTREAMER, -[dnl -dnl Get the cflags and libraries for the GtkScope widget +[ dnl -AC_ARG_WITH(gscope-prefix, -[ --with-gscope-prefix=PFX Prefix where GtkScope is installed], -GSTREAMER_PREFIX="$withval") +dnl Get command-line stuff +dnl + AC_ARG_WITH(gstreamer-prefix,[ --with-gstreamer-prefix=PFX Prefix where GStreamer is installed (optional)], + gstreamer_config_prefix="$withval", gstreamer_config_prefix="") + AC_ARG_WITH(gstreamer-exec-prefix,[ --with-gstreamer-exec-prefix=PFX Exec prefix where GStreamer is installed (optional)], + gstreamer_config_exec_prefix="$withval", gstreamer_config_exec_prefix="") + AC_ARG_ENABLE(gstreamer-test, [ --disable-gstreamer-test Do not try and run a test GStreamer-program], + , enable_gstreamer_test=yes) -AC_CHECK_LIB(gscope,gtk_scope_new, - AC_MSG_RESULT(yes), - AC_MSG_RESULT(no),"$GSTREAMER_PREFIX $LIBS") -AC_SUBST(GSTREAMER_CFLAGS) -AC_SUBST(GSTREAMER_LIBS) -AC_SUBST(HAVE_GSTREAMER) + if test "x$gstreamer_config_prefix" != "x"; then + gstreamer_config_args="$gstreamer_config_args --prefix=$gstreamer_config_prefix" ; + + if test "x${GSTREAMER_CONFIG+set}" != "xset" ; then + GSTREAMER_CONFIG="$gstreamer_config_prefix/bin/gstreamer-config" + fi + fi + if test "x$gstreamer_config_exec_prefix" != "x"; then + gstreamer_config_args="$gstreamer_config_args --exec-prefix=$gstreamer_config_exec_prefix" ; + + if test "x${GSTREAMER_CONFIG+set}" != "xset" ; then + GSTREAMER_CONFIG="$gstreamer_config_exec_prefix/bin/gstreamer-config" + fi + fi + + AC_PATH_PROG(GSTREAMER_CONFIG, gstreamer-config, no) + + if test "x$1" == "x" ; then + min_gstreamer_version="0.0.1" + else + min_gstreamer_version="$1" + fi + +dnl +dnl Check to make sure version wanted is better than the existing version +dnl + AC_MSG_CHECKING(for GStreamer-version >= $min_gstreamer_version) + no_gstreamer="" + + if test "x$GSTREAMER_CONFIG" = "xno" ; then + no_gstreamer=yes + else + GSTREAMER_CFLAGS=`$GSTREAMER_CONFIG $gstreamer_config_args --cflags` + GSTREAMER_LIBS=`$GSTREAMER_CONFIG $gstreamer_config_args --libs` + + gstreamer_config_major_version=`$GSTREAMER_CONFIG $gstreamer_config_args --version | \ + sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\1/'` + gstreamer_config_minor_version=`$GSTREAMER_CONFIG $gstreamer_config_args --version | \ + sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\2/'` + gstreamer_config_micro_version=`$GSTREAMER_CONFIG $gstreamer_config_args --version | \ + sed 's/\([[0-9]]*\).\([[0-9]]*\).\([[0-9]]*\)/\3/'` + + if test "x$enable_gstreamer_test" = "xyes" ; then + ac_save_CFLAGS="$CFLAGS" + ac_save_LIBS="$LIBS" + CFLAGS="$CFLAGS $GSTREAMER_CFLAGS" + LIBS="$GSTREAMER_LIBS $LIBS" +dnl +dnl Try and run a program linked with libs +dnl +AC_TRY_RUN([ +#include +#include +#include +#include +int +main () +{ + int major, minor, micro; + char *tmp_version; + + system("touch conf.gstreamertest"); + + tmp_version = strdup("$min_gstreamer_version"); + if (sscanf(tmp_version, "%d.%d.%d", &major, &minor, µ) != 3) { + printf("%s, bad version string\n", "$min_gstreamer_version"); + return 1; + } + + if (($gstreamer_config_major_version > major) || + (($gstreamer_config_major_version == major) && ($gstreamer_config_minor_version > minor)) || + (($gstreamer_config_major_version == major) && ($gstreamer_config_minor_version == minor) && + ($gstreamer_config_micro_version >= micro))) { + return 0; + } else { + printf("\n*** An old version of GStreamer(%d.%d.%d) was found.\n", + $gstreamer_config_major_version, $gstreamer_config_minor_version, + $gstreamer_config_micro_version); + + printf("*** You need a version of GStreamer newer than %d.%d.%d.\n", major, minor, micro); + + } + + return 1; + +} +],, no_gstreamer=yes, [echo $ac_n "cross compiling; assuming OK... $ac_c"]) + CFLAGS="$ac_save_CFLAGS" + LIBS="$ac_save_LIBS" + fi + fi + if test "x$no_gstreamer" = "x" ; then + AC_MSG_RESULT(yes) + ifelse([$2], , :, [$2]) + else +dnl +dnl Something went wrong, looks like GStreamer was not found +dnl + if test "$GSTREAMER_CONFIG" = "no" ; then + echo "*** The gstreamer-config script installed by GStreamer could not be found" + echo "*** If GStreamer was installed in PREFIX, make sure PREFIX/bin is in" + echo "*** your path, or set the GSTREAMER_CONFIG environment variable to the" + echo "*** full path to gstreamer-config." + else + if test -f conf.gstreamertest ; then + : + else + echo "*** Could not run GStreamer test program, checking why..." + CFLAGS="$CFLAGS $GSTREAMER_CFLAGS" + LIBS="$LIBS $GSTREAMER_LIBS" +AC_TRY_LINK([ +#include +#include +], +[ +gst_init(NULL, NULL); +return 0; +], + [ echo "*** The test program compiled, but did not run. This usually means" + echo "*** that the run-time linker is not finding GStreamer or finding the wrong" + echo "*** version of GStreamer. If it is not finding GStreamer, you'll need to set your" + echo "*** LD_LIBRARY_PATH environment variable, or edit /etc/ld.so.conf to point" + echo "*** to the installed location Also, make sure you have run ldconfig if that" + echo "*** is required on your system" + echo "***" + echo "*** If you have an old version installed, it is best to remove it, although" + echo "*** you may also be able to get things to work by modifying LD_LIBRARY_PATH" ], + [ echo "*** The test program failed to compile or link. See the file config.log for the" + echo "*** exact error that occured. This usually means GStreamer was incorrectly installed" + echo "*** or that you have moved GStreamer since it was installed. In the latter case, you" + echo "*** may want to edit the gstremaer-config script: $GSTREAMER_CONFIG" ]) + CFLAGS="$ac_save_CFLAGS" + LIBS="$ac_save_LIBS" + fi + fi + GSTREAMER_CFLAGS="" + GSTREAMER_LIBS="" + ifelse([$3], , :, [$3]) + fi + +dnl +dnl Define our flags and libs +dnl + AC_SUBST(GSTREAMER_CFLAGS) + AC_SUBST(GSTREAMER_LIBS) + rm -f conf.gstreamertest ]) + diff --git a/gstreamer.spec.in b/gstreamer.spec.in index caa0444785..6ccff3ea72 100644 --- a/gstreamer.spec.in +++ b/gstreamer.spec.in @@ -68,6 +68,7 @@ make prefix=$RPM_BUILD_ROOT%{prefix} install %post /sbin/ldconfig +%{prefix}/bin/gstreamer-register %postun /sbin/ldconfig diff --git a/include/Makefile.am b/include/Makefile.am index 0039492811..6414a20d39 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -1,8 +1,5 @@ SUBDIRS = wine noinst_HEADERS = \ - avifmt.h \ - default.h \ mmx.h \ - registry.h \ sse.h diff --git a/include/default.h b/include/default.h deleted file mode 100644 index b12e9c1fb0..0000000000 --- a/include/default.h +++ /dev/null @@ -1,15 +0,0 @@ -#ifndef _DEFAULT_H -#define _DEFAULT_H - -typedef long HRESULT; -typedef unsigned int offset_t; -#define E_NOTIMPL -158 -#define E_FAIL -1 -#define E_ERROR -2 - -#define fccDIV3 mmioFOURCC('D', 'I', 'V', '3') -#define fccDIV4 mmioFOURCC('D', 'I', 'V', '4') -#define fccIV50 mmioFOURCC('I', 'V', '5', '0') - -#endif - diff --git a/include/wine/msacm.h b/include/wine/msacm.h index 18f1d855c7..b76c1095a8 100644 --- a/include/wine/msacm.h +++ b/include/wine/msacm.h @@ -13,7 +13,7 @@ extern "C" { #endif /* defined(__cplusplus) */ -typedef WORD VERSION; /* major (high byte), minor (low byte) */ +//typedef WORD VERSION; /* major (high byte), minor (low byte) */ typedef UINT16 MMVERSION16; typedef UINT MMVERSION; diff --git a/libs/Makefile.am b/libs/Makefile.am index b77eea6fc8..7b895f0bc5 100644 --- a/libs/Makefile.am +++ b/libs/Makefile.am @@ -1,9 +1,9 @@ if HAVE_CPU_I386 -GSTARCH_SUBDS = videoscale winloader +GSTARCH_SUBDS = winloader else GSTARCH_SUBDS = endif -SUBDIRS = riff colorspace getbits putbits idct $(GSTARCH_SUBDS) +SUBDIRS = riff colorspace getbits putbits idct videoscale $(GSTARCH_SUBDS) DIST_SUBDIRS = riff colorspace getbits putbits videoscale winloader idct diff --git a/libs/colorspace/rgb2rgb.c b/libs/colorspace/rgb2rgb.c index 43f06ce943..09f7f8aff5 100644 --- a/libs/colorspace/rgb2rgb.c +++ b/libs/colorspace/rgb2rgb.c @@ -24,8 +24,12 @@ static void gst_colorspace_rgb_to_rgb_identity(GstColorSpaceConverter *space, unsigned char *src, unsigned char *dest); static void gst_colorspace_rgb24_to_bgr24(GstColorSpaceConverter *space, unsigned char *src, unsigned char *dest); +static void gst_colorspace_rgb24_to_rgb32(GstColorSpaceConverter *space, unsigned char *src, unsigned char *dest); static void gst_colorspace_rgb32_to_bgr32(GstColorSpaceConverter *space, unsigned char *src, unsigned char *dest); static void gst_colorspace_rgb555_to_rgb565(GstColorSpaceConverter *space, unsigned char *src, unsigned char *dest); +static void gst_colorspace_bgr565_to_rgb32(GstColorSpaceConverter *space, unsigned char *src, unsigned char *dest); +static void gst_colorspace_bgr24_to_bgr565(GstColorSpaceConverter *space, unsigned char *src, unsigned char *dest); +static void gst_colorspace_bgr32_to_bgr565(GstColorSpaceConverter *space, unsigned char *src, unsigned char *dest); GstColorSpaceConvertFunction gst_colorspace_rgb2rgb_get_converter(GstColorSpaceConverter *space, GstColorSpaceType src, GstColorSpaceType dest) { switch(src) { @@ -38,6 +42,9 @@ GstColorSpaceConvertFunction gst_colorspace_rgb2rgb_get_converter(GstColorSpaceC case GST_COLORSPACE_BGR24: space->outsize = space->width*space->height*3; return gst_colorspace_rgb24_to_bgr24; + case GST_COLORSPACE_RGB32: + space->outsize = space->width*space->height*4; + return gst_colorspace_rgb24_to_rgb32; default: break; } @@ -51,6 +58,9 @@ GstColorSpaceConvertFunction gst_colorspace_rgb2rgb_get_converter(GstColorSpaceC case GST_COLORSPACE_BGR24: space->outsize = space->width*space->height*3; return gst_colorspace_rgb_to_rgb_identity; + case GST_COLORSPACE_BGR565: + space->outsize = space->width*space->height*2; + return gst_colorspace_bgr24_to_bgr565; default: break; } @@ -77,6 +87,12 @@ GstColorSpaceConvertFunction gst_colorspace_rgb2rgb_get_converter(GstColorSpaceC case GST_COLORSPACE_BGR32: space->outsize = space->width*space->height*4; return gst_colorspace_rgb_to_rgb_identity; + case GST_COLORSPACE_BGR565: + space->outsize = space->width*space->height*2; + return gst_colorspace_bgr32_to_bgr565; + case GST_COLORSPACE_RGB565: + space->outsize = space->width*space->height*2; + return gst_colorspace_bgr32_to_bgr565; default: break; } @@ -93,6 +109,17 @@ GstColorSpaceConvertFunction gst_colorspace_rgb2rgb_get_converter(GstColorSpaceC default: break; } + break; + case GST_COLORSPACE_BGR565: + space->insize = space->width*space->height*2; + switch(dest) { + case GST_COLORSPACE_RGB32 : + space->outsize = space->width*space->height*4; + return gst_colorspace_bgr565_to_rgb32; + default: + break; + }; + break; default: break; } @@ -110,7 +137,7 @@ static void gst_colorspace_rgb24_to_bgr24(GstColorSpaceConverter *space, unsigne gint size; gchar temp; - GST_DEBUG (0,"gst_colorspace_rgb24_to_bgr24 %p %p %d\n", src, dest, space->outsize); + GST_DEBUG (0,"gst_colorspace_rgb24_to_bgr24 %p %p %d %d %d\n", src, dest, space->outsize, space->width, space->height); size = space->outsize/3; @@ -133,6 +160,54 @@ static void gst_colorspace_rgb24_to_bgr24(GstColorSpaceConverter *space, unsigne GST_DEBUG (0,"gst_colorspace_rgb24_to_bgr24 end\n"); } +static void gst_colorspace_bgr24_to_bgr565(GstColorSpaceConverter *space, unsigned char *src, unsigned char *dest) +{ + gint size; + guint16 *destptr = (guint16 *)dest; + + GST_DEBUG (0,"gst_colorspace_bgr24_to_bgr565 %p %p %d %d %d\n", src, dest, space->outsize, space->width, space->height); + + size = space->outsize/2; + + while (size--) { + *destptr++ = ((src[2]&0xF8)<<8)|((src[1]&0xFC)<<3)|((src[0]&0xF8)>>3); + src+=3; + } + GST_DEBUG (0,"gst_colorspace_bgr24_to_bgr565 end\n"); +} + +static void gst_colorspace_bgr32_to_bgr565(GstColorSpaceConverter *space, unsigned char *src, unsigned char *dest) +{ + gint size; + guint16 *destptr = (guint16 *)dest; + + GST_DEBUG (0,"gst_colorspace_bgr32_to_bgr565 %p %p %d %d %d\n", src, dest, space->outsize, space->width, space->height); + + size = space->outsize/2; + + while (size--) { + *destptr++ = ((src[2]&0xF8)<<8)|((src[1]&0xFC)<<3)|((src[0]&0xF8)>>3); + src+=4; + } + GST_DEBUG (0,"gst_colorspace_bgr32_to_bgr565 end\n"); +} + +static void gst_colorspace_rgb24_to_rgb32(GstColorSpaceConverter *space, unsigned char *src, unsigned char *dest) +{ + gint size; + guint32 *destptr = (guint32 *)dest; + + GST_DEBUG (0,"gst_colorspace_rgb24_to_rgb32 %p %p %d\n", src, dest, space->outsize); + + size = space->outsize/4; + + while (size--) { + *destptr++ = (src[0]<<16)|(src[1]<<8)|src[2]; + src+=3; + } + GST_DEBUG (0,"gst_colorspace_rgb24_to_rgb32 end\n"); +} + static void gst_colorspace_rgb32_to_bgr32(GstColorSpaceConverter *space, unsigned char *src, unsigned char *dest) { gint size; @@ -183,3 +258,27 @@ static void gst_colorspace_rgb555_to_rgb565(GstColorSpaceConverter *space, unsig } } } + +static void gst_colorspace_bgr565_to_rgb32(GstColorSpaceConverter *space, unsigned char *src, unsigned char *dest) +{ + gint size; + guint16 *srcptr = (guint16 *)src; + guint32 *destptr = (guint32 *)dest; + size = space->outsize >> 2; + + g_assert (src != dest); /* todo */ + while (size--) { + /* in detail I do this + red=(unsigned char)(*srcptr)&0x1f; + green=(unsigned char)(((*srcptr)&0x07E0)>>5); + blue=(unsigned char)(((*srcptr)&0xf800)>>11); + *destptr++ = (((guint32)blue) << 3) + | (((guint32)green) << (8+2)) + | (((guint32)red) << (16+3)); + */ + *destptr++ = (((*srcptr)&0xf800)>>8)|(((*srcptr)&0x07E0)<<5)|(((*srcptr)&0x1f)<<19); + srcptr++; + } +} + + diff --git a/libs/getbits/gstgetbits.c b/libs/getbits/gstgetbits.c index 5ebb042621..1a04acb52b 100644 --- a/libs/getbits/gstgetbits.c +++ b/libs/getbits/gstgetbits.c @@ -166,7 +166,7 @@ void gst_getbits_init(gst_getbits_t *gb, GstGetbitsCallback callback, void *data gb->getbits = _gst_getbits_mmx; // gb->backbits = _gst_getbits_back_mmx; // gb->backbytes = _gst_getbits_byteback_mmx; - printf("gstgetbits: using MMX optimized versions\n"); +// printf("gstgetbits: using MMX optimized versions\n"); } else #endif /* HAVE_LIBMMX */ { @@ -175,7 +175,7 @@ void gst_getbits_init(gst_getbits_t *gb, GstGetbitsCallback callback, void *data gb->showbits = _gst_showbits_int; gb->flushbits = _gst_flushbits_int; gb->backbits = _gst_getbits_back_int; - printf("gstgetbits: using callback versions\n"); +// printf("gstgetbits: using callback versions\n"); } else { #ifdef HAVE_CPU_I386 @@ -187,7 +187,7 @@ void gst_getbits_init(gst_getbits_t *gb, GstGetbitsCallback callback, void *data gb->showbits = _gst_showbits_i386; gb->flushbits = _gst_flushbits_i386; gb->backbits = _gst_getbits_back_i386; - printf("gstgetbits: using i386 optimized versions\n"); +// printf("gstgetbits: using i386 optimized versions\n"); #else gb->get1bit = _gst_get1bit_int; gb->getbits = _gst_getbits_int; @@ -197,7 +197,7 @@ void gst_getbits_init(gst_getbits_t *gb, GstGetbitsCallback callback, void *data gb->showbits = _gst_showbits_int; gb->flushbits = _gst_flushbits_int; gb->backbits = _gst_getbits_back_int; - printf("gstgetbits: using normal versions\n"); +// printf("gstgetbits: using normal versions\n"); #endif } } diff --git a/libs/getbits/gstgetbits.h b/libs/getbits/gstgetbits.h index 7e56796c39..79b29f3de0 100644 --- a/libs/getbits/gstgetbits.h +++ b/libs/getbits/gstgetbits.h @@ -17,22 +17,7 @@ #include #endif /* HAVE_LIBSSE */ -#ifdef WORDS_BIGENDIAN -# define swab32(x) (x) -#else -# if defined (__i386__) -# define swab32(x) __i386_swab32(x) - static inline const unsigned long __i386_swab32(unsigned long x) - { - __asm__("bswap %0" : "=r" (x) : "0" (x)); - return x; - } -# else -# define swab32(x)\ - ((((guint8*)&x)[0] << 24) | (((guint8*)&x)[1] << 16) | \ - (((guint8*)&x)[2] << 8) | (((guint8*)&x)[3])) -# endif -#endif +#define swab32(x) GUINT32_FROM_BE(x) typedef struct _gst_getbits_t gst_getbits_t; typedef void (*GstGetbitsCallback) (gst_getbits_t *gb, void *data); diff --git a/libs/getbits/gstgetbits_inl.h b/libs/getbits/gstgetbits_inl.h index 2e025c7aaa..0fcbc3b590 100644 --- a/libs/getbits/gstgetbits_inl.h +++ b/libs/getbits/gstgetbits_inl.h @@ -73,22 +73,7 @@ #define checklength2(src, dst) #endif -#ifdef WORDS_BIGENDIAN -# define swab32(x) (x) -#else -# if defined (__i386__) -# define swab32(x) __i386_swab32(x) - static inline const guint32 __i386_swab32(guint32 x) - { - __asm__("bswap %0" : "=r" (x) : "0" (x)); - return x; - } -# else -# define swab32(x)\ - ((((guint8*)&x)[0] << 24) | (((guint8*)&x)[1] << 16) | \ - (((guint8*)&x)[2] << 8) | (((guint8*)&x)[3])) -# endif -#endif +#define swab32(x) GUINT32_FROM_BE(x) /* External declarations for bitstream i/o operations. */ extern unsigned long gst_getbits_nBitMask[]; diff --git a/libs/idct/gstidct.c b/libs/idct/gstidct.c index 6eae831cef..39b3cfcf99 100644 --- a/libs/idct/gstidct.c +++ b/libs/idct/gstidct.c @@ -20,7 +20,7 @@ #include -#include +#include #include "gstidct.h" #include "dct.h" @@ -53,38 +53,38 @@ GstIDCT *gst_idct_new(GstIDCTMethod method) switch (method) { case GST_IDCT_FAST_INT: - g_print("GstIDCT: using fast_int_idct\n"); + GST_INFO (GST_CAT_PLUGIN_INFO, "GstIDCT: using fast_int_idct\n"); gst_idct_init_fast_int_idct(); new->convert = gst_idct_fast_int_idct; break; case GST_IDCT_INT: - g_print("GstIDCT: using int_idct\n"); + GST_INFO (GST_CAT_PLUGIN_INFO, "GstIDCT: using int_idct\n"); new->convert = gst_idct_int_idct; break; case GST_IDCT_FLOAT: - g_print("GstIDCT: using float_idct\n"); + GST_INFO (GST_CAT_PLUGIN_INFO, "GstIDCT: using float_idct\n"); gst_idct_init_float_idct(); new->convert = gst_idct_float_idct; break; #ifdef HAVE_LIBMMX case GST_IDCT_MMX: - g_print("GstIDCT: using MMX_idct\n"); + GST_INFO (GST_CAT_PLUGIN_INFO, "GstIDCT: using MMX_idct\n"); new->convert = gst_idct_mmx_idct; new->need_transpose = TRUE; break; case GST_IDCT_MMX32: - g_print("GstIDCT: using MMX32_idct\n"); + GST_INFO (GST_CAT_PLUGIN_INFO, "GstIDCT: using MMX32_idct\n"); new->convert = gst_idct_mmx32_idct; new->need_transpose = TRUE; break; case GST_IDCT_SSE: - g_print("GstIDCT: using SSE_idct\n"); + GST_INFO (GST_CAT_PLUGIN_INFO, "GstIDCT: using SSE_idct\n"); new->convert = gst_idct_sse_idct; new->need_transpose = TRUE; break; #endif /* HAVE_LIBMMX */ default: - g_print("GstIDCT: method not supported\n"); + GST_INFO (GST_CAT_PLUGIN_INFO, "GstIDCT: method not supported\n"); g_free(new); return NULL; } diff --git a/libs/videoscale/gstvideoscale.c b/libs/videoscale/gstvideoscale.c index 9565198e8b..43cb9912d2 100644 --- a/libs/videoscale/gstvideoscale.c +++ b/libs/videoscale/gstvideoscale.c @@ -26,8 +26,6 @@ #ifdef HAVE_CPU_I386 #include "gstscale_x86.h" #endif -//FIXME -#include static void gst_videoscale_scale_yuv (GstVideoScale *scale, unsigned char *src, unsigned char *dest); static void gst_videoscale_scale_rgb (GstVideoScale *scale, unsigned char *src, unsigned char *dest); diff --git a/libs/winloader/Makefile.am b/libs/winloader/Makefile.am index 75d0f2b16f..ececec29c8 100644 --- a/libs/winloader/Makefile.am +++ b/libs/winloader/Makefile.am @@ -3,12 +3,12 @@ filterdir = $(libdir)/gst filter_LTLIBRARIES = libwinloader.la # compiler manages to screw something up here... must reduce optimizations -CFLAGS += -O2 +CFLAGS += -O0 -funroll-loops -libwinloader_la_SOURCES = driver.c elfdll.c ext.c externals.c module.c \ +libwinloader_la_SOURCES = win32.c driver.c elfdll.c ext.c module.c \ pe_image.c pe_resource.c registry.c resource.c stubs.s vfl.c afl.c -noinst_HEADERS = externals.h wineacm.h +noinst_HEADERS = wineacm.h win32.h registry.h avifmt.h DEFINES=-rdynamic -fPIC -D__WINE__ -Ddbg_printf=__vprintf -DTRACE=__vprintf CFLAGS += $(DEFINES) diff --git a/libs/winloader/afl.c b/libs/winloader/afl.c index 72546f3b49..df4187f6d8 100644 --- a/libs/winloader/afl.c +++ b/libs/winloader/afl.c @@ -304,6 +304,7 @@ void MSACM_RegisterAllDrivers(void) MSACM_RegisterDriver("divxa32", (LPSTR)0x161, 0); MSACM_RegisterDriver("msadp32", (LPSTR)0x2, 0); + MSACM_RegisterDriver("l3codeca", (LPSTR)0x55, 0); } /*********************************************************************** diff --git a/include/avifmt.h b/libs/winloader/avifmt.h similarity index 100% rename from include/avifmt.h rename to libs/winloader/avifmt.h diff --git a/libs/winloader/driver.c b/libs/winloader/driver.c index 8fdb435e42..3dfd0ffa8e 100644 --- a/libs/winloader/driver.c +++ b/libs/winloader/driver.c @@ -6,7 +6,7 @@ #include #include -#include +#include "config.h" #define STORE_ALL \ __asm__ ( \ @@ -25,6 +25,7 @@ "pop %%ebx\n\t"::) +#define WIN32_PATH GST_WIN32_LIBDIR typedef struct { UINT uDriverSignature; @@ -86,18 +87,21 @@ typedef struct int usage; }codec_t; -//#define Win32Path "/usr/lib/win32/" -#define Win32Path GST_WIN32_LIBDIR static codec_t avi_codecs[]={ - {0, Win32Path"/divxc32.dll", 0}, //0 - {0, Win32Path"/ir50_32.dll", 0}, - {0, Win32Path"/ir41_32.dll", 0}, - {0, Win32Path"/ir32_32.dll", 0}, - {0, Win32Path"/mpg4c32.dll", 0}, - {0, Win32Path"/iccvid.dll", 0}, //5 - {0, Win32Path"/libvideodll.so", 0}, - {0, Win32Path"/divxa32.acm", 0}, //7 - {0, Win32Path"/msadp32.acm", 0}, + {0, WIN32_PATH"/divxc32.dll", 0}, //0 + {0, WIN32_PATH"/ir50_32.dll", 0}, + {0, WIN32_PATH"/ir41_32.dll", 0}, + {0, WIN32_PATH"/ir32_32.dll", 0}, + {0, WIN32_PATH"/mpg4c32.dll", 0}, + {0, WIN32_PATH"/iccvid.dll", 0}, //5 + {0, WIN32_PATH"/libvideodll.so", 0}, + {0, WIN32_PATH"/divxa32.acm", 0}, + {0, WIN32_PATH"/msadp32.acm", 0}, + {0, WIN32_PATH"/ativcr1.dll", 0}, + {0, WIN32_PATH"/ativcr2.dll", 0}, //10 + {0, WIN32_PATH"/i263_32.drv", 0}, + {0, WIN32_PATH"/l3codeca.acm", 0}, +// {0, WIN32_PATH"/atiyvu9.dll", 0}, }; @@ -155,6 +159,9 @@ DrvOpen(LPARAM lParam2) case mmioFOURCC('D', 'I', 'V', '4'): case mmioFOURCC('d', 'i', 'v', '3'): case mmioFOURCC('d', 'i', 'v', '4'): + case mmioFOURCC('M', 'P', '4', '1'): + case mmioFOURCC('M', 'P', '4', '2'): + case mmioFOURCC('M', 'P', '4', '3'): printf("Video in DivX ;-) format\n"); drv_id=0; break; @@ -178,9 +185,6 @@ DrvOpen(LPARAM lParam2) case mmioFOURCC('m', 'p', '4', '2'): case mmioFOURCC('m', 'p', '4', '3'): case mmioFOURCC('M', 'P', 'G', '4'): - case mmioFOURCC('M', 'P', '4', '1'): - case mmioFOURCC('M', 'P', '4', '2'): - case mmioFOURCC('M', 'P', '4', '3'): printf("Video in Microsoft MPEG-4 format\n"); drv_id=4; break; @@ -188,6 +192,19 @@ DrvOpen(LPARAM lParam2) printf("Video in Cinepak format\n"); drv_id=5; break; + case mmioFOURCC('V', 'C', 'R', '1'): + drv_id=9; + break; + case mmioFOURCC('V', 'C', 'R', '2'): + drv_id=10; + break; + case mmioFOURCC('i', '2', '6', '3'): + case mmioFOURCC('I', '2', '6', '3'): + drv_id=11; + break; +// case mmioFOURCC('Y', 'V', 'U', '9'): +// drv_id=12; +// break; default: printf("Unknown codec %X='%c%c%c%c'\n", fccHandler, fccHandler&0xFF, (fccHandler&0xFF00)>>8, @@ -204,6 +221,10 @@ DrvOpen(LPARAM lParam2) case 0x2://MS ADPCM drv_id=8; break; + case 0x55://MPEG Layer 3 + printf("MPEG Layer 3 ( 0x55 )\n"); + drv_id=12; + break; default: printf("Unknown ACM codec 0x%X\n", fccHandler); return (HDRVR)0; diff --git a/libs/winloader/elfdll.c b/libs/winloader/elfdll.c index f78ad8ca36..b65e2287c2 100644 --- a/libs/winloader/elfdll.c +++ b/libs/winloader/elfdll.c @@ -45,8 +45,7 @@ extern DWORD fixup_imports(WINE_MODREF *wm); extern void dump_exports(HMODULE hModule); /*---------------- END HACKS ---------------*/ -//char *extra_ld_library_path = "/usr/lib/win32"; -char *extra_ld_library_path = GST_WIN32_LIBDIR; +char *extra_ld_library_path = "/usr/lib/win32"; struct elfdll_image { diff --git a/libs/winloader/module.c b/libs/winloader/module.c index eda45d13ea..945c5b5083 100644 --- a/libs/winloader/module.c +++ b/libs/winloader/module.c @@ -14,7 +14,7 @@ #include #include - +/* #ifdef __linux__ #include #include @@ -40,7 +40,7 @@ struct modify_ldt_ldt_s { #define __NR_modify_ldt 123 #endif - +*/ #include #include #include @@ -64,7 +64,7 @@ modref_list; * * Convert an ldt_entry structure to the raw bytes of the descriptor. */ -static void LDT_EntryToBytes( unsigned long *buffer, const struct modify_ldt_ldt_s *content ) +/*static void LDT_EntryToBytes( unsigned long *buffer, const struct modify_ldt_ldt_s *content ) { *buffer++ = ((content->base_addr & 0x0000ffff) << 16) | (content->limit & 0x0ffff); @@ -77,7 +77,7 @@ static void LDT_EntryToBytes( unsigned long *buffer, const struct modify_ldt_ldt ((content->limit_in_pages != 0) << 23) | 0xf000; } - +*/ // // funcs: @@ -86,6 +86,7 @@ static void LDT_EntryToBytes( unsigned long *buffer, const struct modify_ldt_ldt // 1 write old mode // 0x11 write // +/* static int modify_ldt( int func, struct modify_ldt_ldt_s *ptr, unsigned long count ) { @@ -107,7 +108,7 @@ static int modify_ldt( int func, struct modify_ldt_ldt_s *ptr, "b" (func), "c" (ptr), "d" (sizeof(struct modify_ldt_ldt_s)*count) ); -#endif /* __PIC__ */ +#endif if (res >= 0) return res; errno = -res; return -1; @@ -147,7 +148,7 @@ static int install_fs() perror("install_fs"); MESSAGE("Couldn't install fs segment, expect segfault\n"); } -#endif /*linux*/ +#endif #if defined(__NetBSD__) || defined(__FreeBSD__) || defined(__OpenBSD__) { @@ -161,11 +162,11 @@ static int install_fs() MESSAGE("Did you reconfigure the kernel with \"options USER_LDT\"?\n"); } } -#endif /* __NetBSD__ || __FreeBSD__ || __OpenBSD__ */ +#endif __asm__ ( "movl $0xf,%eax\n\t" - "pushw %ax\n\t" +// "pushw %ax\n\t" "movw %ax, %fs\n\t" ); prev_struct=malloc(8); @@ -178,13 +179,15 @@ static int install_fs() }; static int uninstall_fs() { + printf("Uninstalling FS segment\n"); if(fs_seg==0) return -1; munmap(fs_seg, 0x30000); + fs_installed=0; return 0; } - +*/ //WINE_MODREF *local_wm=NULL; modref_list* local_wm=NULL; @@ -216,7 +219,7 @@ void MODULE_RemoveFromList(WINE_MODREF *mod) { free(list); local_wm=NULL; - uninstall_fs(); +// uninstall_fs(); return; } for(;list;list=list->prev) @@ -412,8 +415,8 @@ HMODULE WINAPI LoadLibraryExA(LPCSTR libname, HANDLE hfile, DWORD flags) SetLastError(ERROR_INVALID_PARAMETER); return 0; } - if(fs_installed==0) - install_fs(); +// if(fs_installed==0) +// install_fs(); wm = MODULE_LoadLibraryExA( libname, hfile, flags ); diff --git a/libs/winloader/pe_image.c b/libs/winloader/pe_image.c index a98529a2cc..6342d1f15e 100644 --- a/libs/winloader/pe_image.c +++ b/libs/winloader/pe_image.c @@ -55,7 +55,7 @@ #include #include -#include "externals.h" +#include "win32.h" #define RVA(x) ((void *)((char *)load_addr+(unsigned int)(x))) diff --git a/include/registry.h b/libs/winloader/registry.h similarity index 99% rename from include/registry.h rename to libs/winloader/registry.h index 44026e93b7..94f45fc64a 100644 --- a/include/registry.h +++ b/libs/winloader/registry.h @@ -15,11 +15,11 @@ extern "C" { long RegOpenKeyExA(long key, const char* subkey, long reserved, long access, int* newkey); long RegCloseKey(long key); long RegQueryValueExA(long key, const char* value, int* reserved, int* type, int* data, int* count); -long RegCreateKeyExA(long key, const char* name, long reserved, - void* classs, long options, long security, +long RegCreateKeyExA(long key, const char* name, long reserved, + void* classs, long options, long security, void* sec_attr, int* newkey, int* status) ; long RegSetValueExA(long key, const char* name, long v1, long v2, void* data, long size); #ifdef __cplusplus }; #endif -#endif +#endif \ No newline at end of file diff --git a/libs/winloader/vfl.c b/libs/winloader/vfl.c index b6e26a4d8b..c0b17d107a 100644 --- a/libs/winloader/vfl.c +++ b/libs/winloader/vfl.c @@ -338,6 +338,13 @@ ICSendMessage(HIC hic,unsigned int msg,long lParam1,long lParam2) { // printf("private=%x\n", whic->private); __asm__ __volatile__ ("fsave (%0)\n\t": :"r"(&qw)); STORE_ALL; + /*__asm__ + ( + "pushl %eax\n\t" + "movl $0xf,%eax\n\t" + "movw %ax, %fs\n\t" + "popl %eax\n\t" + );*/ ret = whic->driverproc(whic->private,1,msg,lParam1,lParam2); REST_ALL; __asm__ __volatile__ ("frstor (%0)\n\t": :"r"(&qw)); diff --git a/libs/winloader/externals.c b/libs/winloader/win32.c similarity index 93% rename from libs/winloader/externals.c rename to libs/winloader/win32.c index 00b8c60a31..0c23b932c9 100644 --- a/libs/winloader/externals.c +++ b/libs/winloader/win32.c @@ -1,4 +1,14 @@ -#include "externals.h" +/*********************************************************** + + Win32 emulation code. Functions that emulate + responses from corresponding Win32 API calls. + Since we are not going to be able to load + virtually any DLL, we can only implement this + much, adding needed functions with each new codec. + +************************************************************/ + +#include "win32.h" #include #include #include @@ -120,16 +130,24 @@ int my_release(char* memory) #else void* my_mreq(int size, int to_zero) { + void* answer; if(to_zero) - return calloc(size, 1); - else - return malloc(size); + answer=calloc(size+4, 1); + else + answer=malloc(size+4); + *(int*)answer=size; + return (int*)answer+1; } int my_release(char* memory) { - free(memory); + if(memory==0)return 0; + free(memory-4); return 0; } +int my_size(char* memory) +{ + return *(int*)(memory-4); +} #endif extern int unk_exp1; @@ -526,7 +544,14 @@ long WINAPI expHeapFree(int arg1, int arg2, void* ptr) my_release(ptr); return 1; } - +long WINAPI expHeapSize(int heap, int flags, void* pointer) +{ + return my_size(pointer); +} +long WINAPI expGetProcessHeap(void) +{ + return 1; +} void* WINAPI expVirtualAlloc(void* v1, long v2, long v3, long v4) { void* z; @@ -972,8 +997,11 @@ LPCSTR WINAPI expGetEnvironmentStrings() int WINAPI expGetStartupInfoA(STARTUPINFOA *s) { + int i; dbgprintf("GetStartupInfoA\n"); - return 1; + for(i=0; i - * 2000 Wim Taymans - * - * gstaudiosink.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 -#include -#include -#include -#include -#include -#include - -//#define DEBUG_ENABLED - -#include -#include - - -GstElementDetails gst_audiosink_details = { - "Audio Sink (OSS)", - "Sink/Audio", - "Output to a sound card via OSS", - VERSION, - "Erik Walthinsen ", - "(C) 1999", -}; - -static void gst_audiosink_class_init (GstAudioSinkClass *klass); -static void gst_audiosink_init (GstAudioSink *audiosink); - -static gboolean gst_audiosink_open_audio (GstAudioSink *sink); -static void gst_audiosink_close_audio (GstAudioSink *sink); -static GstElementStateReturn gst_audiosink_change_state (GstElement *element); - -static void gst_audiosink_set_arg (GtkObject *object, GtkArg *arg, guint id); -static void gst_audiosink_get_arg (GtkObject *object, GtkArg *arg, guint id); - -static void gst_audiosink_chain (GstPad *pad,GstBuffer *buf); - -/* AudioSink signals and args */ -enum { - SIGNAL_HANDOFF, - LAST_SIGNAL -}; - -enum { - ARG_0, - ARG_MUTE, - ARG_FORMAT, - ARG_CHANNELS, - ARG_FREQUENCY, - /* FILL ME */ -}; - -static GstPadFactory audiosink_sink_factory = { - "sink", - GST_PAD_FACTORY_SINK, - GST_PAD_FACTORY_ALWAYS, - GST_PAD_FACTORY_CAPS ( - "audiosink_sink", - "audio/raw", - "format", GST_PROPS_INT (AFMT_S16_LE), - "depth", GST_PROPS_LIST ( - GST_PROPS_INT (8), - GST_PROPS_INT (16) - ), - "rate", GST_PROPS_INT_RANGE (8000, 48000), - "channels", GST_PROPS_INT_RANGE (1, 2) - ), - NULL -}; - -#define GST_TYPE_AUDIOSINK_FORMATS (gst_audiosink_formats_get_type()) - -static GtkType -gst_audiosink_formats_get_type(void) { - static GtkType audiosink_formats_type = 0; - static GtkEnumValue audiosink_formats[] = { - {8, "8", "8 Bits"}, - {16, "16", "16 Bits"}, - {0, NULL, NULL}, - }; - if (!audiosink_formats_type) { - audiosink_formats_type = gtk_type_register_enum("GstAudiosinkFormats", audiosink_formats); - } - return audiosink_formats_type; -} - -#define GST_TYPE_AUDIOSINK_CHANNELS (gst_audiosink_channels_get_type()) - -static GtkType -gst_audiosink_channels_get_type(void) { - static GtkType audiosink_channels_type = 0; - static GtkEnumValue audiosink_channels[] = { - {1, "1", "Mono"}, - {2, "2", "Stereo"}, - {0, NULL, NULL}, - }; - if (!audiosink_channels_type) { - audiosink_channels_type = gtk_type_register_enum("GstAudiosinkChannels", audiosink_channels); - } - return audiosink_channels_type; -} - - -static GstElementClass *parent_class = NULL; -static guint gst_audiosink_signals[LAST_SIGNAL] = { 0 }; - -static GstPadTemplate *gst_audiosink_sink_template; - -GtkType -gst_audiosink_get_type (void) -{ - static GtkType audiosink_type = 0; - - if (!audiosink_type) { - static const GtkTypeInfo audiosink_info = { - "GstAudioSink", - sizeof(GstAudioSink), - sizeof(GstAudioSinkClass), - (GtkClassInitFunc)gst_audiosink_class_init, - (GtkObjectInitFunc)gst_audiosink_init, - (GtkArgSetFunc)NULL, - (GtkArgGetFunc)NULL, - (GtkClassInitFunc)NULL, - }; - audiosink_type = gtk_type_unique (GST_TYPE_ELEMENT, &audiosink_info); - } - - return audiosink_type; -} - -static void -gst_audiosink_class_init (GstAudioSinkClass *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 ("GstAudioSink::mute", GTK_TYPE_BOOL, - GTK_ARG_READWRITE, ARG_MUTE); - gtk_object_add_arg_type ("GstAudioSink::format", GST_TYPE_AUDIOSINK_FORMATS, - GTK_ARG_READWRITE, ARG_FORMAT); - gtk_object_add_arg_type ("GstAudioSink::channels", GST_TYPE_AUDIOSINK_CHANNELS, - GTK_ARG_READWRITE, ARG_CHANNELS); - gtk_object_add_arg_type ("GstAudioSink::frequency", GTK_TYPE_INT, - GTK_ARG_READWRITE, ARG_FREQUENCY); - - gtkobject_class->set_arg = gst_audiosink_set_arg; - gtkobject_class->get_arg = gst_audiosink_get_arg; - - gst_audiosink_signals[SIGNAL_HANDOFF] = - gtk_signal_new("handoff",GTK_RUN_LAST,gtkobject_class->type, - GTK_SIGNAL_OFFSET(GstAudioSinkClass,handoff), - gtk_marshal_NONE__NONE,GTK_TYPE_NONE,0); - - gtk_object_class_add_signals(gtkobject_class,gst_audiosink_signals, - LAST_SIGNAL); - - gstelement_class->change_state = gst_audiosink_change_state; -} - -static void -gst_audiosink_init (GstAudioSink *audiosink) -{ - audiosink->sinkpad = gst_pad_new_from_template (gst_audiosink_sink_template, "sink"); - gst_element_add_pad (GST_ELEMENT (audiosink), audiosink->sinkpad); - - gst_pad_set_chain_function (audiosink->sinkpad, gst_audiosink_chain); - - audiosink->fd = -1; - audiosink->clock = gst_clock_get_system(); - audiosink->format = 16; - audiosink->channels = 2; - audiosink->frequency = 44100; - - gst_clock_register (audiosink->clock, GST_OBJECT (audiosink)); - - GST_FLAG_SET (audiosink, GST_ELEMENT_THREAD_SUGGESTED); -} - -static void -gst_audiosink_sync_parms (GstAudioSink *audiosink) -{ - audio_buf_info ospace; - int frag; - - g_return_if_fail (audiosink != NULL); - g_return_if_fail (GST_IS_AUDIOSINK (audiosink)); - - if (audiosink->fd == -1) return; - - ioctl (audiosink->fd, SNDCTL_DSP_RESET, 0); - - ioctl (audiosink->fd, SNDCTL_DSP_SETFMT, &audiosink->format); - ioctl (audiosink->fd, SNDCTL_DSP_CHANNELS, &audiosink->channels); - ioctl (audiosink->fd, SNDCTL_DSP_SPEED, &audiosink->frequency); - ioctl (audiosink->fd, SNDCTL_DSP_GETBLKSIZE, &frag); - - ioctl (audiosink->fd, SNDCTL_DSP_GETOSPACE, &ospace); - - g_print("audiosink: setting sound card to %dKHz %d bit %s (%d bytes buffer, %d fragment)\n", - audiosink->frequency, audiosink->format, - (audiosink->channels == 2) ? "stereo" : "mono", ospace.bytes, frag); - -} - -static void -gst_audiosink_chain (GstPad *pad, GstBuffer *buf) -{ - GstAudioSink *audiosink; - MetaAudioRaw *meta; - gboolean in_flush; - audio_buf_info ospace; - - g_return_if_fail (pad != NULL); - g_return_if_fail (GST_IS_PAD (pad)); - g_return_if_fail (buf != NULL); - - - /* this has to be an audio buffer */ -// g_return_if_fail(((GstMeta *)buf->meta)->type != -//gst_audiosink_type_audio); - audiosink = GST_AUDIOSINK (gst_pad_get_parent (pad)); -// g_return_if_fail(GST_FLAG_IS_SET(audiosink,GST_STATE_RUNNING)); - - if ((in_flush = GST_BUFFER_FLAG_IS_SET (buf, GST_BUFFER_FLUSH))) { - GST_DEBUG (0,"audiosink: flush\n"); - ioctl (audiosink->fd, SNDCTL_DSP_RESET, 0); - } - - - meta = (MetaAudioRaw *)gst_buffer_get_first_meta (buf); - if (meta != NULL) { - if ((meta->format != audiosink->format) || - (meta->channels != audiosink->channels) || - (meta->frequency != audiosink->frequency)) - { - audiosink->format = meta->format; - audiosink->channels = meta->channels; - audiosink->frequency = meta->frequency; - gst_audiosink_sync_parms (audiosink); - g_print("audiosink: sound device set to format %d, %d channels, %dHz\n", - audiosink->format, audiosink->channels, audiosink->frequency); - } - } - - gtk_signal_emit (GTK_OBJECT (audiosink), gst_audiosink_signals[SIGNAL_HANDOFF], - audiosink); - - if (GST_BUFFER_DATA (buf) != NULL) { - gst_trace_add_entry(NULL, 0, buf, "audiosink: writing to soundcard"); - //g_print("audiosink: writing to soundcard\n"); - if (audiosink->fd >= 0) { - if (!audiosink->mute) { - gst_clock_wait (audiosink->clock, GST_BUFFER_TIMESTAMP (buf), GST_OBJECT (audiosink)); - ioctl (audiosink->fd, SNDCTL_DSP_GETOSPACE, &ospace); - GST_DEBUG (0,"audiosink: (%d bytes buffer) %d %p %d\n", ospace.bytes, - audiosink->fd, GST_BUFFER_DATA (buf), GST_BUFFER_SIZE (buf)); - write (audiosink->fd, GST_BUFFER_DATA (buf), GST_BUFFER_SIZE (buf)); - //write(STDOUT_FILENO,GST_BUFFER_DATA(buf),GST_BUFFER_SIZE(buf)); - } - } - } - gst_buffer_unref (buf); -} - -static void -gst_audiosink_set_arg (GtkObject *object, GtkArg *arg, guint id) -{ - GstAudioSink *audiosink; - - /* it's not null if we got it, but it might not be ours */ - g_return_if_fail (GST_IS_AUDIOSINK (object)); - - audiosink = GST_AUDIOSINK (object); - - switch(id) { - case ARG_MUTE: - audiosink->mute = GTK_VALUE_BOOL (*arg); - break; - case ARG_FORMAT: - audiosink->format = GTK_VALUE_ENUM (*arg); - gst_audiosink_sync_parms (audiosink); - break; - case ARG_CHANNELS: - audiosink->channels = GTK_VALUE_ENUM (*arg); - gst_audiosink_sync_parms (audiosink); - break; - case ARG_FREQUENCY: - audiosink->frequency = GTK_VALUE_INT (*arg); - gst_audiosink_sync_parms (audiosink); - break; - default: - break; - } -} - -static void -gst_audiosink_get_arg (GtkObject *object, GtkArg *arg, guint id) -{ - GstAudioSink *audiosink; - - /* it's not null if we got it, but it might not be ours */ - g_return_if_fail (GST_IS_AUDIOSINK (object)); - - audiosink = GST_AUDIOSINK (object); - - switch(id) { - case ARG_MUTE: - GTK_VALUE_BOOL (*arg) = audiosink->mute; - break; - case ARG_FORMAT: - GTK_VALUE_ENUM (*arg) = audiosink->format; - break; - case ARG_CHANNELS: - GTK_VALUE_ENUM (*arg) = audiosink->channels; - break; - case ARG_FREQUENCY: - GTK_VALUE_INT (*arg) = audiosink->frequency; - break; - default: - break; - } -} - -static gboolean -gst_audiosink_open_audio (GstAudioSink *sink) -{ - g_return_val_if_fail (sink->fd == -1, FALSE); - - g_print ("audiosink: attempting to open sound device\n"); - - /* first try to open the sound card */ - sink->fd = open("/dev/dsp", O_WRONLY | O_NONBLOCK); - if (errno == EBUSY) { - g_print ("audiosink: unable to open the sound device (in use ?)\n"); - return FALSE; - } - - /* re-open the sound device in blocking mode */ - close(sink->fd); - sink->fd = open("/dev/dsp", O_WRONLY); - - /* if we have it, set the default parameters and go have fun */ - if (sink->fd >= 0) { - /* set card state */ - sink->format = AFMT_S16_LE; - sink->channels = 2; /* stereo */ - sink->frequency = 44100; - gst_audiosink_sync_parms (sink); - ioctl(sink->fd, SNDCTL_DSP_GETCAPS, &sink->caps); - - g_print("audiosink: Capabilities\n"); - - if (sink->caps & DSP_CAP_DUPLEX) g_print("audiosink: Full duplex\n"); - if (sink->caps & DSP_CAP_REALTIME) g_print("audiosink: Realtime\n"); - if (sink->caps & DSP_CAP_BATCH) g_print("audiosink: Batch\n"); - if (sink->caps & DSP_CAP_COPROC) g_print("audiosink: Has coprocessor\n"); - if (sink->caps & DSP_CAP_TRIGGER) g_print("audiosink: Trigger\n"); - if (sink->caps & DSP_CAP_MMAP) g_print("audiosink: Direct access\n"); - - g_print("audiosink: opened audio with fd=%d\n", sink->fd); - GST_FLAG_SET (sink, GST_AUDIOSINK_OPEN); - - return TRUE; - } - - return FALSE; -} - -static void -gst_audiosink_close_audio (GstAudioSink *sink) -{ - if (sink->fd < 0) return; - - close(sink->fd); - sink->fd = -1; - - GST_FLAG_UNSET (sink, GST_AUDIOSINK_OPEN); - - g_print("audiosink: closed sound device\n"); -} - -static GstElementStateReturn -gst_audiosink_change_state (GstElement *element) -{ - g_return_val_if_fail (GST_IS_AUDIOSINK (element), FALSE); - - /* if going down into NULL state, close the file if it's open */ - if (GST_STATE_PENDING (element) == GST_STATE_NULL) { - if (GST_FLAG_IS_SET (element, GST_AUDIOSINK_OPEN)) - gst_audiosink_close_audio (GST_AUDIOSINK (element)); - /* otherwise (READY or higher) we need to open the sound card */ - } else { - if (!GST_FLAG_IS_SET (element, GST_AUDIOSINK_OPEN)) { - if (!gst_audiosink_open_audio (GST_AUDIOSINK (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; -} - -gboolean -gst_audiosink_factory_init (GstElementFactory *factory) -{ - gst_audiosink_sink_template = gst_padtemplate_new (&audiosink_sink_factory); - gst_elementfactory_add_padtemplate (factory, gst_audiosink_sink_template); - - return TRUE; -} - diff --git a/plugins/elements/gstaudiosink.h b/plugins/elements/gstaudiosink.h deleted file mode 100644 index d5233922f1..0000000000 --- a/plugins/elements/gstaudiosink.h +++ /dev/null @@ -1,92 +0,0 @@ -/* GStreamer - * Copyright (C) 1999,2000 Erik Walthinsen - * 2000 Wim Taymans - * - * gstaudiosink.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_AUDIOSINK_H__ -#define __GST_AUDIOSINK_H__ - - -#include -#include - - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - - -GstElementDetails gst_audiosink_details; - - -#define GST_TYPE_AUDIOSINK \ - (gst_audiosink_get_type()) -#define GST_AUDIOSINK(obj) \ - (GTK_CHECK_CAST((obj),GST_TYPE_AUDIOSINK,GstAudioSink)) -#define GST_AUDIOSINK_CLASS(klass) \ - (GTK_CHECK_CLASS_CAST((klass),GST_TYPE_AUDIOSINK,GstAudioSinkClass)) -#define GST_IS_AUDIOSINK(obj) \ - (GTK_CHECK_TYPE((obj),GST_TYPE_AUDIOSINK)) -#define GST_IS_AUDIOSINK_CLASS(obj) \ - (GTK_CHECK_CLASS_TYPE((klass),GST_TYPE_AUDIOSINK)) - -typedef enum { - GST_AUDIOSINK_OPEN = GST_ELEMENT_FLAG_LAST, - - GST_AUDIOSINK_FLAG_LAST = GST_ELEMENT_FLAG_LAST+2, -} GstAudioSinkFlags; - -typedef struct _GstAudioSink GstAudioSink; -typedef struct _GstAudioSinkClass GstAudioSinkClass; - -struct _GstAudioSink { - GstElement element; - - GstPad *sinkpad; - - //GstClockTime clocktime; - GstClock *clock; - /* soundcard state */ - int fd; - int caps; /* the capabilities */ - gint format; - gint channels; - gint frequency; - gboolean mute; -}; - -struct _GstAudioSinkClass { - GstElementClass parent_class; - - /* signals */ - void (*handoff) (GstElement *element,GstPad *pad); -}; - -GtkType gst_audiosink_get_type(void); - -gboolean gst_audiosink_factory_init(GstElementFactory *factory); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - - -#endif /* __GST_AUDIOSINK_H__ */ diff --git a/plugins/elements/gstaudiosrc.c b/plugins/elements/gstaudiosrc.c deleted file mode 100644 index b4645fdb9c..0000000000 --- a/plugins/elements/gstaudiosrc.c +++ /dev/null @@ -1,321 +0,0 @@ -/* GStreamer - * Copyright (C) 1999,2000 Erik Walthinsen - * 2000 Wim Taymans - * - * gstaudiosrc.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 -#include -#include -#include -#include -#include - -#include - - -GstElementDetails gst_audiosrc_details = { - "Audio (OSS) Source", - "Source/Audio", - "Read from the sound card", - VERSION, - "Erik Walthinsen ", - "(C) 1999", -}; - - -/* AudioSrc signals and args */ -enum { - /* FILL ME */ - LAST_SIGNAL -}; - -enum { - ARG_0, - ARG_BYTESPERREAD, - ARG_CUROFFSET, - ARG_FORMAT, - ARG_CHANNELS, - ARG_FREQUENCY, -}; - - -static void gst_audiosrc_class_init (GstAudioSrcClass *klass); -static void gst_audiosrc_init (GstAudioSrc *audiosrc); - -static void gst_audiosrc_set_arg (GtkObject *object, GtkArg *arg, guint id); -static void gst_audiosrc_get_arg (GtkObject *object, GtkArg *arg, guint id); -static GstElementStateReturn gst_audiosrc_change_state (GstElement *element); - -static void gst_audiosrc_close_audio (GstAudioSrc *src); -static gboolean gst_audiosrc_open_audio (GstAudioSrc *src); -static void gst_audiosrc_sync_parms (GstAudioSrc *audiosrc); - -static GstBuffer * gst_audiosrc_get (GstPad *pad); - -static GstElementClass *parent_class = NULL; -//static guint gst_audiosrc_signals[LAST_SIGNAL] = { 0 }; - -GtkType -gst_audiosrc_get_type (void) -{ - static GtkType audiosrc_type = 0; - - if (!audiosrc_type) { - static const GtkTypeInfo audiosrc_info = { - "GstAudioSrc", - sizeof(GstAudioSrc), - sizeof(GstAudioSrcClass), - (GtkClassInitFunc)gst_audiosrc_class_init, - (GtkObjectInitFunc)gst_audiosrc_init, - (GtkArgSetFunc)gst_audiosrc_set_arg, - (GtkArgGetFunc)gst_audiosrc_get_arg, - (GtkClassInitFunc)NULL, - }; - audiosrc_type = gtk_type_unique (GST_TYPE_ELEMENT, &audiosrc_info); - } - return audiosrc_type; -} - -static void -gst_audiosrc_class_init (GstAudioSrcClass *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 ("GstAudioSrc::bytes_per_read", GTK_TYPE_ULONG, - GTK_ARG_READWRITE, ARG_BYTESPERREAD); - gtk_object_add_arg_type ("GstAudioSrc::curoffset", GTK_TYPE_ULONG, - GTK_ARG_READABLE, ARG_CUROFFSET); - gtk_object_add_arg_type ("GstAudioSrc::format", GTK_TYPE_INT, - GTK_ARG_READWRITE, ARG_FORMAT); - gtk_object_add_arg_type ("GstAudioSrc::channels", GTK_TYPE_INT, - GTK_ARG_READWRITE, ARG_CHANNELS); - gtk_object_add_arg_type ("GstAudioSrc::frequency", GTK_TYPE_INT, - GTK_ARG_READWRITE, ARG_FREQUENCY); - - gtkobject_class->set_arg = gst_audiosrc_set_arg; - gtkobject_class->get_arg = gst_audiosrc_get_arg; - - gstelement_class->change_state = gst_audiosrc_change_state; -} - -static void -gst_audiosrc_init (GstAudioSrc *audiosrc) -{ - audiosrc->srcpad = gst_pad_new ("src", GST_PAD_SRC); - gst_pad_set_get_function(audiosrc->srcpad,gst_audiosrc_get); - gst_element_add_pad (GST_ELEMENT (audiosrc), audiosrc->srcpad); - - audiosrc->fd = -1; - -// audiosrc->meta = (MetaAudioRaw *)gst_meta_new(); -// audiosrc->meta->format = AFMT_S16_LE; -// audiosrc->meta->channels = 2; -// audiosrc->meta->frequency = 44100; -// audiosrc->meta->bps = 4; - - audiosrc->bytes_per_read = 4096; - audiosrc->curoffset = 0; - audiosrc->seq = 0; -} - -static GstBuffer * -gst_audiosrc_get (GstPad *pad) -{ - GstAudioSrc *src; - GstBuffer *buf; - glong readbytes; - - g_return_val_if_fail (pad != NULL, NULL); - src = GST_AUDIOSRC(gst_pad_get_parent (pad)); - -// g_print("attempting to read something from soundcard\n"); - - buf = gst_buffer_new (); - g_return_val_if_fail (buf, NULL); - - GST_BUFFER_DATA (buf) = (gpointer)g_malloc (src->bytes_per_read); - - readbytes = read (src->fd,GST_BUFFER_DATA (buf), - src->bytes_per_read); - - if (readbytes == 0) { - gst_element_signal_eos (GST_ELEMENT (src)); - return NULL; - } - - GST_BUFFER_SIZE (buf) = readbytes; - GST_BUFFER_OFFSET (buf) = src->curoffset; - - src->curoffset += readbytes; - -// gst_buffer_add_meta(buf,GST_META(newmeta)); - -// g_print("pushed buffer from soundcard of %d bytes\n",readbytes); - return buf; -} - -static void -gst_audiosrc_set_arg (GtkObject *object, GtkArg *arg, guint id) -{ - GstAudioSrc *src; - - /* it's not null if we got it, but it might not be ours */ - g_return_if_fail (GST_IS_AUDIOSRC (object)); - - src = GST_AUDIOSRC (object); - - switch (id) { - case ARG_BYTESPERREAD: - src->bytes_per_read = GTK_VALUE_INT (*arg); - break; - case ARG_FORMAT: - src->format = GTK_VALUE_INT (*arg); - break; - case ARG_CHANNELS: - src->channels = GTK_VALUE_INT (*arg); - break; - case ARG_FREQUENCY: - src->frequency = GTK_VALUE_INT (*arg); - break; - default: - break; - } -} - -static void -gst_audiosrc_get_arg (GtkObject *object, GtkArg *arg, guint id) -{ - GstAudioSrc *src; - - /* it's not null if we got it, but it might not be ours */ - g_return_if_fail (GST_IS_AUDIOSRC (object)); - - src = GST_AUDIOSRC (object); - - switch (id) { - case ARG_BYTESPERREAD: - GTK_VALUE_INT (*arg) = src->bytes_per_read; - break; - case ARG_FORMAT: - GTK_VALUE_INT (*arg) = src->format; - break; - case ARG_CHANNELS: - GTK_VALUE_INT (*arg) = src->channels; - break; - case ARG_FREQUENCY: - GTK_VALUE_INT (*arg) = src->frequency; - break; - default: - arg->type = GTK_TYPE_INVALID; - break; - } -} - -static GstElementStateReturn -gst_audiosrc_change_state (GstElement *element) -{ - g_return_val_if_fail (GST_IS_AUDIOSRC (element), FALSE); - - /* if going down into NULL state, close the file if it's open */ - if (GST_STATE_PENDING (element) == GST_STATE_NULL) { - if (GST_FLAG_IS_SET (element, GST_AUDIOSRC_OPEN)) - gst_audiosrc_close_audio (GST_AUDIOSRC (element)); - /* otherwise (READY or higher) we need to open the sound card */ - } else { - if (!GST_FLAG_IS_SET (element, GST_AUDIOSRC_OPEN)) { - if (!gst_audiosrc_open_audio (GST_AUDIOSRC (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; -} - -static gboolean -gst_audiosrc_open_audio (GstAudioSrc *src) -{ - g_return_val_if_fail (!GST_FLAG_IS_SET (src, GST_AUDIOSRC_OPEN), FALSE); - - /* first try to open the sound card */ - src->fd = open("/dev/dsp", O_RDONLY); - - /* if we have it, set the default parameters and go have fun */ - if (src->fd > 0) { - int arg = 0x7fff0006; - - if (ioctl (src->fd, SNDCTL_DSP_SETFRAGMENT, &arg)) perror("uh"); - - /* set card state */ - gst_audiosrc_sync_parms (src); - GST_DEBUG (0,"opened audio\n"); - - GST_FLAG_SET (src, GST_AUDIOSRC_OPEN); - return TRUE; - } - - return FALSE; -} - -static void -gst_audiosrc_close_audio (GstAudioSrc *src) -{ - g_return_if_fail (GST_FLAG_IS_SET (src, GST_AUDIOSRC_OPEN)); - - close(src->fd); - src->fd = -1; - - GST_FLAG_UNSET (src, GST_AUDIOSRC_OPEN); -} - -static void -gst_audiosrc_sync_parms (GstAudioSrc *audiosrc) -{ - audio_buf_info ospace; - - g_return_if_fail (audiosrc != NULL); - g_return_if_fail (GST_IS_AUDIOSRC (audiosrc)); - g_return_if_fail (audiosrc->fd > 0); - - ioctl(audiosrc->fd, SNDCTL_DSP_RESET, 0); - - ioctl(audiosrc->fd, SNDCTL_DSP_SETFMT, &audiosrc->format); - ioctl(audiosrc->fd, SNDCTL_DSP_CHANNELS, &audiosrc->channels); - ioctl(audiosrc->fd, SNDCTL_DSP_SPEED, &audiosrc->frequency); - - ioctl(audiosrc->fd, SNDCTL_DSP_GETOSPACE, &ospace); - - g_print("setting sound card to %dKHz %d bit %s (%d bytes buffer)\n", - audiosrc->frequency,audiosrc->format, - (audiosrc->channels == 2) ? "stereo" : "mono",ospace.bytes); - -// audiosrc->meta.format = audiosrc->format; -// audiosrc->meta.channels = audiosrc->channels; -// audiosrc->meta.frequency = audiosrc->frequency; -// audiosrc->sentmeta = FALSE; -} diff --git a/plugins/elements/gstaudiosrc.h b/plugins/elements/gstaudiosrc.h deleted file mode 100644 index b4bbfc09ef..0000000000 --- a/plugins/elements/gstaudiosrc.h +++ /dev/null @@ -1,95 +0,0 @@ -/* GStreamer - * Copyright (C) 1999,2000 Erik Walthinsen - * 2000 Wim Taymans - * - * gstaudiosrc.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_AUDIOSRC_H__ -#define __GST_AUDIOSRC_H__ - - -#include -#include -#include - - -#ifdef __cplusplus -extern "C" { -#endif /* __cplusplus */ - - -GstElementDetails gst_audiosrc_details; - - -#define GST_TYPE_AUDIOSRC \ - (gst_audiosrc_get_type()) -#define GST_AUDIOSRC(obj) \ - (GTK_CHECK_CAST((obj),GST_TYPE_AUDIOSRC,GstAudioSrc)) -#define GST_AUDIOSRC_CLASS(klass) \ - (GTK_CHECK_CLASS_CAST((klass),GST_TYPE_AUDIOSRC,GstAudioSrcClass)) -#define GST_IS_AUDIOSRC(obj) \ - (GTK_CHECK_TYPE((obj),GST_TYPE_AUDIOSRC)) -#define GST_IS_AUDIOSRC_CLASS(obj) \ - (GTK_CHECK_CLASS_TYPE((klass),GST_TYPE_AUDIOSRC)) - -typedef enum { - GST_AUDIOSRC_OPEN = GST_ELEMENT_FLAG_LAST, - - GST_AUDIOSRC_FLAG_LAST = GST_ELEMENT_FLAG_LAST+2, -} GstAudioSrcFlags; - -typedef struct _GstAudioSrc GstAudioSrc; -typedef struct _GstAudioSrcClass GstAudioSrcClass; - -struct _GstAudioSrc { - GstElement element; - - /* pads */ - GstPad *srcpad; - - /* sound card */ - gint fd; - - /* audio parameters */ - gint format; - gint channels; - gint frequency; - - /* blocking */ - gulong curoffset; - gulong bytes_per_read; - - gulong seq; - - MetaAudioRaw *meta; -}; - -struct _GstAudioSrcClass { - GstElementClass parent_class; -}; - -GtkType gst_audiosrc_get_type(void); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ - - -#endif /* __GST_AUDIOSRC_H__ */ diff --git a/plugins/elements/gstdisksrc.c b/plugins/elements/gstdisksrc.c index 94f1a162a7..9e81eb9b73 100644 --- a/plugins/elements/gstdisksrc.c +++ b/plugins/elements/gstdisksrc.c @@ -2,7 +2,7 @@ * Copyright (C) 1999,2000 Erik Walthinsen * 2000 Wim Taymans * - * gstdisksrc.c: + * gstdisksrc.c: * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -32,7 +32,7 @@ GstElementDetails gst_disksrc_details = { - "hronous Disk Source", + "Disk Source", "Source/File", "Read from arbitrary point in a file", VERSION, @@ -56,23 +56,23 @@ enum { }; -static void gst_disksrc_class_init (GstDiskSrcClass *klass); -static void gst_disksrc_init (GstDiskSrc *disksrc); +static void gst_disksrc_class_init (GstDiskSrcClass *klass); +static void gst_disksrc_init (GstDiskSrc *disksrc); -static void gst_disksrc_set_arg (GtkObject *object, GtkArg *arg, guint id); -static void gst_disksrc_get_arg (GtkObject *object, GtkArg *arg, guint id); +static void gst_disksrc_set_arg (GtkObject *object, GtkArg *arg, guint id); +static void gst_disksrc_get_arg (GtkObject *object, GtkArg *arg, guint id); static GstBuffer * gst_disksrc_get (GstPad *pad); static GstBuffer * gst_disksrc_get_region (GstPad *pad,GstRegionType type,guint64 offset,guint64 len); -static GstElementStateReturn gst_disksrc_change_state (GstElement *element); +static GstElementStateReturn gst_disksrc_change_state (GstElement *element); static GstElementClass *parent_class = NULL; //static guint gst_disksrc_signals[LAST_SIGNAL] = { 0 }; GtkType -gst_disksrc_get_type(void) +gst_disksrc_get_type(void) { static GtkType disksrc_type = 0; @@ -93,7 +93,7 @@ gst_disksrc_get_type(void) } static void -gst_disksrc_class_init (GstDiskSrcClass *klass) +gst_disksrc_class_init (GstDiskSrcClass *klass) { GtkObjectClass *gtkobject_class; GstElementClass *gstelement_class; @@ -118,8 +118,8 @@ gst_disksrc_class_init (GstDiskSrcClass *klass) gstelement_class->change_state = gst_disksrc_change_state; } -static void -gst_disksrc_init (GstDiskSrc *disksrc) +static void +gst_disksrc_init (GstDiskSrc *disksrc) { // GST_FLAG_SET (disksrc, GST_SRC_); @@ -139,14 +139,14 @@ gst_disksrc_init (GstDiskSrc *disksrc) } -static void -gst_disksrc_set_arg (GtkObject *object, GtkArg *arg, guint id) +static void +gst_disksrc_set_arg (GtkObject *object, GtkArg *arg, guint id) { GstDiskSrc *src; /* it's not null if we got it, but it might not be ours */ g_return_if_fail (GST_IS_DISKSRC (object)); - + src = GST_DISKSRC (object); switch(id) { @@ -176,14 +176,14 @@ gst_disksrc_set_arg (GtkObject *object, GtkArg *arg, guint id) } } -static void -gst_disksrc_get_arg (GtkObject *object, GtkArg *arg, guint id) +static void +gst_disksrc_get_arg (GtkObject *object, GtkArg *arg, guint id) { GstDiskSrc *src; /* it's not null if we got it, but it might not be ours */ g_return_if_fail (GST_IS_DISKSRC (object)); - + src = GST_DISKSRC (object); switch (id) { @@ -212,7 +212,7 @@ gst_disksrc_get_arg (GtkObject *object, GtkArg *arg, guint id) * Push a new buffer from the disksrc at the current offset. */ static GstBuffer * -gst_disksrc_get (GstPad *pad) +gst_disksrc_get (GstPad *pad) { GstDiskSrc *src; GstBuffer *buf; @@ -223,7 +223,7 @@ gst_disksrc_get (GstPad *pad) /* deal with EOF state */ if (src->curoffset >= src->size) { - gst_element_signal_eos (GST_ELEMENT (src)); + gst_pad_set_eos (pad); return NULL; } @@ -269,7 +269,7 @@ gst_disksrc_get (GstPad *pad) * Push a new buffer from the disksrc of given size at given offset. */ static GstBuffer * -gst_disksrc_get_region (GstPad *pad, GstRegionType type,guint64 offset,guint64 len) +gst_disksrc_get_region (GstPad *pad, GstRegionType type,guint64 offset,guint64 len) { GstDiskSrc *src; GstBuffer *buf; @@ -281,10 +281,10 @@ gst_disksrc_get_region (GstPad *pad, GstRegionType type,guint64 offset,guint64 l g_return_val_if_fail (GST_IS_DISKSRC (src), NULL); g_return_val_if_fail (GST_FLAG_IS_SET (src, GST_DISKSRC_OPEN), NULL); - + /* deal with EOF state */ if (offset >= src->size) { - gst_element_signal_eos (GST_ELEMENT (src)); + gst_pad_set_eos (pad); return NULL; } @@ -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); @@ -343,8 +343,8 @@ gboolean gst_disksrc_open_file (GstDiskSrc *src) } /* unmap and close the file */ -static void -gst_disksrc_close_file (GstDiskSrc *src) +static void +gst_disksrc_close_file (GstDiskSrc *src) { g_return_if_fail (GST_FLAG_IS_SET (src, GST_DISKSRC_OPEN)); @@ -365,8 +365,8 @@ gst_disksrc_close_file (GstDiskSrc *src) } -static GstElementStateReturn -gst_disksrc_change_state (GstElement *element) +static GstElementStateReturn +gst_disksrc_change_state (GstElement *element) { g_return_val_if_fail (GST_IS_DISKSRC (element), GST_STATE_FAILURE); @@ -375,7 +375,7 @@ gst_disksrc_change_state (GstElement *element) gst_disksrc_close_file (GST_DISKSRC (element)); } else { if (!GST_FLAG_IS_SET (element, GST_DISKSRC_OPEN)) { - if (!gst_disksrc_open_file (GST_DISKSRC (element))) + if (!gst_disksrc_open_file (GST_DISKSRC (element))) return GST_STATE_FAILURE; } } diff --git a/plugins/elements/gstelements.c b/plugins/elements/gstelements.c index 294793df44..326d0e3aaf 100644 --- a/plugins/elements/gstelements.c +++ b/plugins/elements/gstelements.c @@ -2,7 +2,7 @@ * Copyright (C) 1999,2000 Erik Walthinsen * 2000 Wim Taymans * - * gstelements.c: + * gstelements.c: * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public @@ -23,14 +23,13 @@ #include -#include "gstaudiosink.h" -#include "gstaudiosrc.h" #include "gstdisksrc.h" #include "gstidentity.h" #include "gstfakesink.h" #include "gstfakesrc.h" #include "gstfdsink.h" #include "gstfdsrc.h" +#include "gstmultidisksrc.h" #include "gstpipefilter.h" #include "gstsinesrc.h" #include "gsttee.h" @@ -50,25 +49,23 @@ struct _elements_entry { static struct _elements_entry _elements[] = { { "fakesrc", gst_fakesrc_get_type, &gst_fakesrc_details, NULL }, { "fakesink", gst_fakesink_get_type, &gst_fakesink_details, NULL }, - { "asyncdisksrc", gst_disksrc_get_type, &gst_disksrc_details, NULL }, - { "audiosink", gst_audiosink_get_type, &gst_audiosink_details, gst_audiosink_factory_init }, - { "audiosrc", gst_audiosrc_get_type, &gst_audiosrc_details, NULL }, { "disksrc", gst_disksrc_get_type, &gst_disksrc_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 }, + { "multidisksrc", gst_multidisksrc_get_type, &gst_multidisksrc_details, NULL }, { "pipefilter", gst_pipefilter_get_type, &gst_pipefilter_details, NULL }, { "sinesrc", gst_sinesrc_get_type, &gst_sinesrc_details, NULL }, { "tee", gst_tee_get_type, &gst_tee_details, gst_tee_factory_init }, #if HAVE_LIBGHTTP - { "httpsrc", gst_httpsrc_get_type, &gst_httpsrc_details, NULL }, + { "httpsrc", gst_httpsrc_get_type, &gst_httpsrc_details, NULL }, #endif /* HAVE_LIBGHTTP */ - + { NULL, 0 }, }; -GstPlugin *plugin_init (GModule *module) +GstPlugin *plugin_init (GModule *module) { GstPlugin *plugin; GstElementFactory *factory; diff --git a/plugins/elements/gstmultidisksrc.c b/plugins/elements/gstmultidisksrc.c new file mode 100644 index 0000000000..726aed976f --- /dev/null +++ b/plugins/elements/gstmultidisksrc.c @@ -0,0 +1,305 @@ +/* GStreamer + * Copyright (C) 1999,2000 Erik Walthinsen + * 2000 Wim Taymans + * 2001 Dominic Ludlam + * + * gstmultidisksrc.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 +#include +#include +#include +#include + +//#define GST_DEBUG_ENABLED + +#include "gstmultidisksrc.h" + +GstElementDetails gst_multidisksrc_details = { + "Multi Disk Source", + "Source/File", + "Read from multiple files in order", + VERSION, + "Dominic Ludlam ", + "(C) 2001", +}; + +/* DiskSrc signals and args */ +enum { + NEW_FILE, + LAST_SIGNAL +}; + +enum { + ARG_0, + ARG_LOCATIONS, +}; + +static void gst_multidisksrc_class_init (GstMultiDiskSrcClass *klass); +static void gst_multidisksrc_init (GstMultiDiskSrc *disksrc); + +static void gst_multidisksrc_set_arg (GtkObject *object, GtkArg *arg, guint id); +static void gst_multidisksrc_get_arg (GtkObject *object, GtkArg *arg, guint id); + +static GstBuffer * gst_multidisksrc_get (GstPad *pad); +//static GstBuffer * gst_multidisksrc_get_region (GstPad *pad,GstRegionType type,guint64 offset,guint64 len); + +static GstElementStateReturn gst_multidisksrc_change_state (GstElement *element); + +static gboolean gst_multidisksrc_open_file (GstMultiDiskSrc *src, GstPad *srcpad); +static void gst_multidisksrc_close_file (GstMultiDiskSrc *src); + +static GstElementClass *parent_class = NULL; +static guint gst_multidisksrc_signals[LAST_SIGNAL] = { 0 }; + +GtkType +gst_multidisksrc_get_type(void) +{ + static GtkType multidisksrc_type = 0; + + if (!multidisksrc_type) { + static const GtkTypeInfo multidisksrc_info = { + "GstMultiDiskSrc", + sizeof(GstMultiDiskSrc), + sizeof(GstMultiDiskSrcClass), + (GtkClassInitFunc)gst_multidisksrc_class_init, + (GtkObjectInitFunc)gst_multidisksrc_init, + (GtkArgSetFunc)gst_multidisksrc_set_arg, + (GtkArgGetFunc)gst_multidisksrc_get_arg, + (GtkClassInitFunc)NULL, + }; + multidisksrc_type = gtk_type_unique (GST_TYPE_ELEMENT, &multidisksrc_info); + } + return multidisksrc_type; +} + +static void +gst_multidisksrc_class_init (GstMultiDiskSrcClass *klass) +{ + GtkObjectClass *gtkobject_class; + GstElementClass *gstelement_class; + + gtkobject_class = (GtkObjectClass*)klass; + gstelement_class = (GstElementClass*)klass; + + parent_class = gtk_type_class (GST_TYPE_ELEMENT); + + gst_multidisksrc_signals[NEW_FILE] = + gtk_signal_new ("new_file", GTK_RUN_LAST, gtkobject_class->type, + GTK_SIGNAL_OFFSET (GstMultiDiskSrcClass, new_file), + gtk_marshal_NONE__POINTER, GTK_TYPE_NONE, 1, + GTK_TYPE_POINTER); + gtk_object_class_add_signals (gtkobject_class, gst_multidisksrc_signals, LAST_SIGNAL); + + gtk_object_add_arg_type ("GstMultiDiskSrc::locations", GTK_TYPE_POINTER, + GTK_ARG_READWRITE, ARG_LOCATIONS); + + gtkobject_class->set_arg = gst_multidisksrc_set_arg; + gtkobject_class->get_arg = gst_multidisksrc_get_arg; + + gstelement_class->change_state = gst_multidisksrc_change_state; +} + +static void +gst_multidisksrc_init (GstMultiDiskSrc *multidisksrc) +{ +// GST_FLAG_SET (disksrc, GST_SRC_); + + multidisksrc->srcpad = gst_pad_new ("src", GST_PAD_SRC); + gst_pad_set_get_function (multidisksrc->srcpad,gst_multidisksrc_get); +// gst_pad_set_getregion_function (multidisksrc->srcpad,gst_multidisksrc_get_region); + gst_element_add_pad (GST_ELEMENT (multidisksrc), multidisksrc->srcpad); + + multidisksrc->listptr = NULL; + multidisksrc->currentfilename = NULL; + multidisksrc->fd = 0; + multidisksrc->size = 0; + multidisksrc->map = NULL; + multidisksrc->new_seek = FALSE; +} + +static void +gst_multidisksrc_set_arg (GtkObject *object, GtkArg *arg, guint id) +{ + GstMultiDiskSrc *src; + + /* it's not null if we got it, but it might not be ours */ + g_return_if_fail (GST_IS_MULTIDISKSRC (object)); + + src = GST_MULTIDISKSRC (object); + + switch(id) { + case ARG_LOCATIONS: + /* the element must be stopped in order to do this */ + g_return_if_fail (GST_STATE (src) < GST_STATE_PLAYING); + + /* clear the filename if we get a NULL */ + if (GTK_VALUE_POINTER (*arg) == NULL) { + gst_element_set_state (GST_ELEMENT (object), GST_STATE_NULL); + src->listptr = NULL; + /* otherwise set the new filenames */ + } else { + src->listptr = GTK_VALUE_POINTER(*arg); + } + break; + default: + break; + } +} + +static void +gst_multidisksrc_get_arg (GtkObject *object, GtkArg *arg, guint id) +{ + GstMultiDiskSrc *src; + + /* it's not null if we got it, but it might not be ours */ + g_return_if_fail (GST_IS_MULTIDISKSRC (object)); + + src = GST_MULTIDISKSRC (object); + + switch (id) { + case ARG_LOCATIONS: + GTK_VALUE_POINTER (*arg) = src->listptr; + break; + default: + arg->type = GTK_TYPE_INVALID; + break; + } +} + +/** + * gst_disksrc_get: + * @pad: #GstPad to push a buffer from + * + * Push a new buffer from the disksrc at the current offset. + */ +static GstBuffer * +gst_multidisksrc_get (GstPad *pad) +{ + GstMultiDiskSrc *src; + GstBuffer *buf; + GSList *list; + + g_return_val_if_fail (pad != NULL, NULL); + src = GST_MULTIDISKSRC (gst_pad_get_parent (pad)); + + if (GST_FLAG_IS_SET (src, GST_MULTIDISKSRC_OPEN)) + gst_multidisksrc_close_file(src); + + if (!src->listptr) { + gst_pad_set_eos(pad); + return FALSE; + } + + list = src->listptr; + src->currentfilename = (gchar *) list->data; + src->listptr = src->listptr->next; + + if (!gst_multidisksrc_open_file(src, pad)) + return NULL; + + // emitted after the open, as the user may free the list and string from here + gtk_signal_emit(GTK_OBJECT(src), gst_multidisksrc_signals[NEW_FILE], list); + + /* create the buffer */ + // FIXME: should eventually use a bufferpool for this + buf = gst_buffer_new (); + + g_return_val_if_fail (buf != NULL, NULL); + + /* simply set the buffer to point to the correct region of the file */ + GST_BUFFER_DATA (buf) = src->map; + GST_BUFFER_OFFSET (buf) = 0; + GST_BUFFER_FLAG_SET (buf, GST_BUFFER_DONTFREE); + + if (src->new_seek) { + GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLUSH); + src->new_seek = FALSE; + } + + /* we're done, return the buffer */ + return buf; +} + +/* open the file and mmap it, necessary to go to READY state */ +static +gboolean gst_multidisksrc_open_file (GstMultiDiskSrc *src, GstPad *srcpad) +{ + g_return_val_if_fail (!GST_FLAG_IS_SET (src, GST_MULTIDISKSRC_OPEN), FALSE); + + /* open the file */ + src->fd = open ((const char *) src->currentfilename, O_RDONLY); + + if (src->fd < 0) { + perror ("open"); + gst_element_error (GST_ELEMENT (src), g_strconcat("opening file \"", src->currentfilename, "\"", NULL)); + return FALSE; + } else { + /* find the file length */ + src->size = lseek (src->fd, 0, SEEK_END); + lseek (src->fd, 0, SEEK_SET); + /* map the file into memory */ + src->map = mmap (NULL, src->size, PROT_READ, MAP_SHARED, src->fd, 0); + madvise (src->map,src->size, 2); + /* collapse state if that failed */ + if (src->map == NULL) { + close (src->fd); + gst_element_error (GST_ELEMENT (src),"mmapping file"); + return FALSE; + } + GST_FLAG_SET (src, GST_MULTIDISKSRC_OPEN); + src->new_seek = TRUE; + } + return TRUE; +} + +/* unmap and close the file */ +static void +gst_multidisksrc_close_file (GstMultiDiskSrc *src) +{ + g_return_if_fail (GST_FLAG_IS_SET (src, GST_MULTIDISKSRC_OPEN)); + + /* unmap the file from memory and close the file */ + munmap (src->map, src->size); + close (src->fd); + + /* zero out a lot of our state */ + src->fd = 0; + src->size = 0; + src->map = NULL; + src->new_seek = FALSE; + + GST_FLAG_UNSET (src, GST_MULTIDISKSRC_OPEN); +} + +static GstElementStateReturn +gst_multidisksrc_change_state (GstElement *element) +{ + g_return_val_if_fail (GST_IS_MULTIDISKSRC (element), GST_STATE_FAILURE); + + if (GST_STATE_PENDING (element) == GST_STATE_NULL) { + if (GST_FLAG_IS_SET (element, GST_MULTIDISKSRC_OPEN)) + gst_multidisksrc_close_file (GST_MULTIDISKSRC (element)); + } + + if (GST_ELEMENT_CLASS (parent_class)->change_state) + return GST_ELEMENT_CLASS (parent_class)->change_state (element); + + return GST_STATE_SUCCESS; +} diff --git a/plugins/elements/gstmultidisksrc.h b/plugins/elements/gstmultidisksrc.h new file mode 100644 index 0000000000..ed4a94c969 --- /dev/null +++ b/plugins/elements/gstmultidisksrc.h @@ -0,0 +1,84 @@ +/* GStreamer + * Copyright (C) 1999,2000 Erik Walthinsen + * 2000 Wim Taymans + * 2001 Dominic Ludlam + * + * gstmultidisksrc.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_MULTIDISKSRC_H__ +#define __GST_MULTIDISKSRC_H__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +GstElementDetails gst_multidisksrc_details; + +#define GST_TYPE_MULTIDISKSRC \ + (gst_multidisksrc_get_type()) +#define GST_MULTIDISKSRC(obj) \ + (GTK_CHECK_CAST((obj),GST_TYPE_MULTIDISKSRC,GstMultiDiskSrc)) +#define GST_MULTIDISKSRC_CLASS(klass) \ + (GTK_CHECK_CLASS_CAST((klass),GST_TYPE_MULTIDISKSRC,GstMultiDiskSrcClass)) +#define GST_IS_MULTIDISKSRC(obj) \ + (GTK_CHECK_TYPE((obj),GST_TYPE_MULTIDISKSRC)) +#define GST_IS_MULTIDISKSRC_CLASS(obj) \ + (GTK_CHECK_CLASS_TYPE((klass),GST_TYPE_MULTIDISKSRC)) + +typedef enum { + GST_MULTIDISKSRC_OPEN = GST_ELEMENT_FLAG_LAST, + + GST_MULTIDISKSRC_FLAG_LAST = GST_ELEMENT_FLAG_LAST + 2, +} GstMultiDiskSrcFlags; + +typedef struct _GstMultiDiskSrc GstMultiDiskSrc; +typedef struct _GstMultiDiskSrcClass GstMultiDiskSrcClass; + +struct _GstMultiDiskSrc { + GstElement element; + /* pads */ + GstPad *srcpad; + + /* current file details */ + gchar *currentfilename; + GSList *listptr; + + /* mapping parameters */ + gint fd; + gulong size; /* how long is the file? */ + guchar *map; /* where the file is mapped to */ + + gboolean new_seek; +}; + +struct _GstMultiDiskSrcClass { + GstElementClass parent_class; + + void (*new_file) (GstMultiDiskSrc *multidisksrc, gchar *newfilename); +}; + +GtkType gst_multidisksrc_get_type(void); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* __GST_MULTIDISKSRC_H__ */ diff --git a/plugins/elements/gstmultifilesrc.c b/plugins/elements/gstmultifilesrc.c new file mode 100644 index 0000000000..726aed976f --- /dev/null +++ b/plugins/elements/gstmultifilesrc.c @@ -0,0 +1,305 @@ +/* GStreamer + * Copyright (C) 1999,2000 Erik Walthinsen + * 2000 Wim Taymans + * 2001 Dominic Ludlam + * + * gstmultidisksrc.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 +#include +#include +#include +#include + +//#define GST_DEBUG_ENABLED + +#include "gstmultidisksrc.h" + +GstElementDetails gst_multidisksrc_details = { + "Multi Disk Source", + "Source/File", + "Read from multiple files in order", + VERSION, + "Dominic Ludlam ", + "(C) 2001", +}; + +/* DiskSrc signals and args */ +enum { + NEW_FILE, + LAST_SIGNAL +}; + +enum { + ARG_0, + ARG_LOCATIONS, +}; + +static void gst_multidisksrc_class_init (GstMultiDiskSrcClass *klass); +static void gst_multidisksrc_init (GstMultiDiskSrc *disksrc); + +static void gst_multidisksrc_set_arg (GtkObject *object, GtkArg *arg, guint id); +static void gst_multidisksrc_get_arg (GtkObject *object, GtkArg *arg, guint id); + +static GstBuffer * gst_multidisksrc_get (GstPad *pad); +//static GstBuffer * gst_multidisksrc_get_region (GstPad *pad,GstRegionType type,guint64 offset,guint64 len); + +static GstElementStateReturn gst_multidisksrc_change_state (GstElement *element); + +static gboolean gst_multidisksrc_open_file (GstMultiDiskSrc *src, GstPad *srcpad); +static void gst_multidisksrc_close_file (GstMultiDiskSrc *src); + +static GstElementClass *parent_class = NULL; +static guint gst_multidisksrc_signals[LAST_SIGNAL] = { 0 }; + +GtkType +gst_multidisksrc_get_type(void) +{ + static GtkType multidisksrc_type = 0; + + if (!multidisksrc_type) { + static const GtkTypeInfo multidisksrc_info = { + "GstMultiDiskSrc", + sizeof(GstMultiDiskSrc), + sizeof(GstMultiDiskSrcClass), + (GtkClassInitFunc)gst_multidisksrc_class_init, + (GtkObjectInitFunc)gst_multidisksrc_init, + (GtkArgSetFunc)gst_multidisksrc_set_arg, + (GtkArgGetFunc)gst_multidisksrc_get_arg, + (GtkClassInitFunc)NULL, + }; + multidisksrc_type = gtk_type_unique (GST_TYPE_ELEMENT, &multidisksrc_info); + } + return multidisksrc_type; +} + +static void +gst_multidisksrc_class_init (GstMultiDiskSrcClass *klass) +{ + GtkObjectClass *gtkobject_class; + GstElementClass *gstelement_class; + + gtkobject_class = (GtkObjectClass*)klass; + gstelement_class = (GstElementClass*)klass; + + parent_class = gtk_type_class (GST_TYPE_ELEMENT); + + gst_multidisksrc_signals[NEW_FILE] = + gtk_signal_new ("new_file", GTK_RUN_LAST, gtkobject_class->type, + GTK_SIGNAL_OFFSET (GstMultiDiskSrcClass, new_file), + gtk_marshal_NONE__POINTER, GTK_TYPE_NONE, 1, + GTK_TYPE_POINTER); + gtk_object_class_add_signals (gtkobject_class, gst_multidisksrc_signals, LAST_SIGNAL); + + gtk_object_add_arg_type ("GstMultiDiskSrc::locations", GTK_TYPE_POINTER, + GTK_ARG_READWRITE, ARG_LOCATIONS); + + gtkobject_class->set_arg = gst_multidisksrc_set_arg; + gtkobject_class->get_arg = gst_multidisksrc_get_arg; + + gstelement_class->change_state = gst_multidisksrc_change_state; +} + +static void +gst_multidisksrc_init (GstMultiDiskSrc *multidisksrc) +{ +// GST_FLAG_SET (disksrc, GST_SRC_); + + multidisksrc->srcpad = gst_pad_new ("src", GST_PAD_SRC); + gst_pad_set_get_function (multidisksrc->srcpad,gst_multidisksrc_get); +// gst_pad_set_getregion_function (multidisksrc->srcpad,gst_multidisksrc_get_region); + gst_element_add_pad (GST_ELEMENT (multidisksrc), multidisksrc->srcpad); + + multidisksrc->listptr = NULL; + multidisksrc->currentfilename = NULL; + multidisksrc->fd = 0; + multidisksrc->size = 0; + multidisksrc->map = NULL; + multidisksrc->new_seek = FALSE; +} + +static void +gst_multidisksrc_set_arg (GtkObject *object, GtkArg *arg, guint id) +{ + GstMultiDiskSrc *src; + + /* it's not null if we got it, but it might not be ours */ + g_return_if_fail (GST_IS_MULTIDISKSRC (object)); + + src = GST_MULTIDISKSRC (object); + + switch(id) { + case ARG_LOCATIONS: + /* the element must be stopped in order to do this */ + g_return_if_fail (GST_STATE (src) < GST_STATE_PLAYING); + + /* clear the filename if we get a NULL */ + if (GTK_VALUE_POINTER (*arg) == NULL) { + gst_element_set_state (GST_ELEMENT (object), GST_STATE_NULL); + src->listptr = NULL; + /* otherwise set the new filenames */ + } else { + src->listptr = GTK_VALUE_POINTER(*arg); + } + break; + default: + break; + } +} + +static void +gst_multidisksrc_get_arg (GtkObject *object, GtkArg *arg, guint id) +{ + GstMultiDiskSrc *src; + + /* it's not null if we got it, but it might not be ours */ + g_return_if_fail (GST_IS_MULTIDISKSRC (object)); + + src = GST_MULTIDISKSRC (object); + + switch (id) { + case ARG_LOCATIONS: + GTK_VALUE_POINTER (*arg) = src->listptr; + break; + default: + arg->type = GTK_TYPE_INVALID; + break; + } +} + +/** + * gst_disksrc_get: + * @pad: #GstPad to push a buffer from + * + * Push a new buffer from the disksrc at the current offset. + */ +static GstBuffer * +gst_multidisksrc_get (GstPad *pad) +{ + GstMultiDiskSrc *src; + GstBuffer *buf; + GSList *list; + + g_return_val_if_fail (pad != NULL, NULL); + src = GST_MULTIDISKSRC (gst_pad_get_parent (pad)); + + if (GST_FLAG_IS_SET (src, GST_MULTIDISKSRC_OPEN)) + gst_multidisksrc_close_file(src); + + if (!src->listptr) { + gst_pad_set_eos(pad); + return FALSE; + } + + list = src->listptr; + src->currentfilename = (gchar *) list->data; + src->listptr = src->listptr->next; + + if (!gst_multidisksrc_open_file(src, pad)) + return NULL; + + // emitted after the open, as the user may free the list and string from here + gtk_signal_emit(GTK_OBJECT(src), gst_multidisksrc_signals[NEW_FILE], list); + + /* create the buffer */ + // FIXME: should eventually use a bufferpool for this + buf = gst_buffer_new (); + + g_return_val_if_fail (buf != NULL, NULL); + + /* simply set the buffer to point to the correct region of the file */ + GST_BUFFER_DATA (buf) = src->map; + GST_BUFFER_OFFSET (buf) = 0; + GST_BUFFER_FLAG_SET (buf, GST_BUFFER_DONTFREE); + + if (src->new_seek) { + GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLUSH); + src->new_seek = FALSE; + } + + /* we're done, return the buffer */ + return buf; +} + +/* open the file and mmap it, necessary to go to READY state */ +static +gboolean gst_multidisksrc_open_file (GstMultiDiskSrc *src, GstPad *srcpad) +{ + g_return_val_if_fail (!GST_FLAG_IS_SET (src, GST_MULTIDISKSRC_OPEN), FALSE); + + /* open the file */ + src->fd = open ((const char *) src->currentfilename, O_RDONLY); + + if (src->fd < 0) { + perror ("open"); + gst_element_error (GST_ELEMENT (src), g_strconcat("opening file \"", src->currentfilename, "\"", NULL)); + return FALSE; + } else { + /* find the file length */ + src->size = lseek (src->fd, 0, SEEK_END); + lseek (src->fd, 0, SEEK_SET); + /* map the file into memory */ + src->map = mmap (NULL, src->size, PROT_READ, MAP_SHARED, src->fd, 0); + madvise (src->map,src->size, 2); + /* collapse state if that failed */ + if (src->map == NULL) { + close (src->fd); + gst_element_error (GST_ELEMENT (src),"mmapping file"); + return FALSE; + } + GST_FLAG_SET (src, GST_MULTIDISKSRC_OPEN); + src->new_seek = TRUE; + } + return TRUE; +} + +/* unmap and close the file */ +static void +gst_multidisksrc_close_file (GstMultiDiskSrc *src) +{ + g_return_if_fail (GST_FLAG_IS_SET (src, GST_MULTIDISKSRC_OPEN)); + + /* unmap the file from memory and close the file */ + munmap (src->map, src->size); + close (src->fd); + + /* zero out a lot of our state */ + src->fd = 0; + src->size = 0; + src->map = NULL; + src->new_seek = FALSE; + + GST_FLAG_UNSET (src, GST_MULTIDISKSRC_OPEN); +} + +static GstElementStateReturn +gst_multidisksrc_change_state (GstElement *element) +{ + g_return_val_if_fail (GST_IS_MULTIDISKSRC (element), GST_STATE_FAILURE); + + if (GST_STATE_PENDING (element) == GST_STATE_NULL) { + if (GST_FLAG_IS_SET (element, GST_MULTIDISKSRC_OPEN)) + gst_multidisksrc_close_file (GST_MULTIDISKSRC (element)); + } + + if (GST_ELEMENT_CLASS (parent_class)->change_state) + return GST_ELEMENT_CLASS (parent_class)->change_state (element); + + return GST_STATE_SUCCESS; +} diff --git a/plugins/elements/gstmultifilesrc.h b/plugins/elements/gstmultifilesrc.h new file mode 100644 index 0000000000..ed4a94c969 --- /dev/null +++ b/plugins/elements/gstmultifilesrc.h @@ -0,0 +1,84 @@ +/* GStreamer + * Copyright (C) 1999,2000 Erik Walthinsen + * 2000 Wim Taymans + * 2001 Dominic Ludlam + * + * gstmultidisksrc.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_MULTIDISKSRC_H__ +#define __GST_MULTIDISKSRC_H__ + +#include + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +GstElementDetails gst_multidisksrc_details; + +#define GST_TYPE_MULTIDISKSRC \ + (gst_multidisksrc_get_type()) +#define GST_MULTIDISKSRC(obj) \ + (GTK_CHECK_CAST((obj),GST_TYPE_MULTIDISKSRC,GstMultiDiskSrc)) +#define GST_MULTIDISKSRC_CLASS(klass) \ + (GTK_CHECK_CLASS_CAST((klass),GST_TYPE_MULTIDISKSRC,GstMultiDiskSrcClass)) +#define GST_IS_MULTIDISKSRC(obj) \ + (GTK_CHECK_TYPE((obj),GST_TYPE_MULTIDISKSRC)) +#define GST_IS_MULTIDISKSRC_CLASS(obj) \ + (GTK_CHECK_CLASS_TYPE((klass),GST_TYPE_MULTIDISKSRC)) + +typedef enum { + GST_MULTIDISKSRC_OPEN = GST_ELEMENT_FLAG_LAST, + + GST_MULTIDISKSRC_FLAG_LAST = GST_ELEMENT_FLAG_LAST + 2, +} GstMultiDiskSrcFlags; + +typedef struct _GstMultiDiskSrc GstMultiDiskSrc; +typedef struct _GstMultiDiskSrcClass GstMultiDiskSrcClass; + +struct _GstMultiDiskSrc { + GstElement element; + /* pads */ + GstPad *srcpad; + + /* current file details */ + gchar *currentfilename; + GSList *listptr; + + /* mapping parameters */ + gint fd; + gulong size; /* how long is the file? */ + guchar *map; /* where the file is mapped to */ + + gboolean new_seek; +}; + +struct _GstMultiDiskSrcClass { + GstElementClass parent_class; + + void (*new_file) (GstMultiDiskSrc *multidisksrc, gchar *newfilename); +}; + +GtkType gst_multidisksrc_get_type(void); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* __GST_MULTIDISKSRC_H__ */ diff --git a/plugins/elements/gstqueue.c b/plugins/elements/gstqueue.c index 79865c3f06..7e8c92e56a 100644 --- a/plugins/elements/gstqueue.c +++ b/plugins/elements/gstqueue.c @@ -66,6 +66,8 @@ static void gst_queue_set_arg (GtkObject *object, GtkArg *arg, guint id); static void gst_queue_get_arg (GtkObject *object, GtkArg *arg, guint id); static gboolean gst_queue_handle_eos (GstPad *pad); +static GstPadNegotiateReturn gst_queue_handle_negotiate_src (GstPad *pad, GstCaps **caps, gpointer *data); +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); @@ -131,10 +133,12 @@ gst_queue_init (GstQueue *queue) gst_pad_set_chain_function (queue->sinkpad, GST_DEBUG_FUNCPTR(gst_queue_chain)); 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); queue->srcpad = gst_pad_new ("src", GST_PAD_SRC); gst_pad_set_get_function (queue->srcpad, GST_DEBUG_FUNCPTR(gst_queue_get)); gst_element_add_pad (GST_ELEMENT (queue), queue->srcpad); + gst_pad_set_negotiate_function (queue->srcpad, gst_queue_handle_negotiate_src); queue->queue = NULL; queue->level_buffers = 0; @@ -148,6 +152,41 @@ gst_queue_init (GstQueue *queue) queue->fullcond = g_cond_new (); } +static GstPadNegotiateReturn +gst_queue_handle_negotiate_src (GstPad *pad, GstCaps **caps, gpointer *data) +{ + GstQueue *queue; + + queue = GST_QUEUE (GST_OBJECT_PARENT (pad)); + + return gst_pad_negotiate_proxy (pad, queue->sinkpad, caps); + + + //return GST_PAD_NEGOTIATE_FAIL; +} + +static GstPadNegotiateReturn +gst_queue_handle_negotiate_sink (GstPad *pad, GstCaps **caps, gpointer *data) +{ + GstQueue *queue; + + queue = GST_QUEUE (GST_OBJECT_PARENT (pad)); + + /* + if (counter == 0) { + *caps = NULL; + return GST_PAD_NEGOTIATE_TRY; + } + if (*caps) { + */ + return gst_pad_negotiate_proxy (pad, queue->srcpad, caps); + /* + } + + return GST_PAD_NEGOTIATE_FAIL; + */ +} + static gboolean gst_queue_handle_eos (GstPad *pad) { @@ -251,11 +290,15 @@ gst_queue_chain (GstPad *pad, GstBuffer *buf) static GstBuffer * gst_queue_get (GstPad *pad) { - GstQueue *queue = GST_QUEUE (GST_OBJECT_PARENT (pad)); + GstQueue *queue; GstBuffer *buf = NULL; GSList *front; const guchar *name; + g_return_val_if_fail (pad != NULL, NULL); + g_return_val_if_fail (GST_IS_PAD (pad), NULL); + + queue = GST_QUEUE (GST_OBJECT_PARENT (pad)); name = GST_ELEMENT_NAME (queue); /* have to lock for thread-safety */ diff --git a/plugins/elements/gstsinesrc.c b/plugins/elements/gstsinesrc.c index 5e47d279c8..5a4e4abe57 100644 --- a/plugins/elements/gstsinesrc.c +++ b/plugins/elements/gstsinesrc.c @@ -1,6 +1,7 @@ /* GStreamer * Copyright (C) 1999,2000 Erik Walthinsen * 2000 Wim Taymans + * 2001 Steve Baker * * gstsinesrc.c: * @@ -20,10 +21,6 @@ * Boston, MA 02111-1307, USA. */ -#include -#include -#include -#include #include #include #include @@ -51,20 +48,25 @@ enum { ARG_0, ARG_VOLUME, ARG_FORMAT, - ARG_CHANNELS, - ARG_FREQUENCY, + ARG_SAMPLERATE, + ARG_FREQ, + ARG_TABLESIZE, + ARG_BUFFER_SIZE, }; static void gst_sinesrc_class_init(GstSineSrcClass *klass); -static void gst_sinesrc_init(GstSineSrc *sinesrc); +static void gst_sinesrc_init(GstSineSrc *src); static void gst_sinesrc_set_arg(GtkObject *object,GtkArg *arg,guint id); static void gst_sinesrc_get_arg(GtkObject *object,GtkArg *arg,guint id); //static gboolean gst_sinesrc_change_state(GstElement *element, // GstElementState state); //static void gst_sinesrc_close_audio(GstSineSrc *src); //static gboolean gst_sinesrc_open_audio(GstSineSrc *src); -void gst_sinesrc_sync_parms(GstSineSrc *sinesrc); +static void gst_sinesrc_populate_sinetable(GstSineSrc *src); +static inline void gst_sinesrc_update_table_inc(GstSineSrc *src); +static inline void gst_sinesrc_update_vol_scale(GstSineSrc *src); +void gst_sinesrc_sync_parms(GstSineSrc *src); static GstBuffer * gst_sinesrc_get(GstPad *pad); @@ -105,31 +107,44 @@ gst_sinesrc_class_init(GstSineSrcClass *klass) { GTK_ARG_READWRITE, ARG_VOLUME); gtk_object_add_arg_type("GstSineSrc::format", GTK_TYPE_INT, GTK_ARG_READWRITE, ARG_FORMAT); - gtk_object_add_arg_type("GstSineSrc::channels", GTK_TYPE_INT, - GTK_ARG_READWRITE, ARG_CHANNELS); - gtk_object_add_arg_type("GstSineSrc::frequency", GTK_TYPE_INT, - GTK_ARG_READWRITE, ARG_FREQUENCY); - + gtk_object_add_arg_type("GstSineSrc::samplerate", GTK_TYPE_INT, + GTK_ARG_READWRITE, ARG_SAMPLERATE); + gtk_object_add_arg_type("GstSineSrc::tablesize", GTK_TYPE_INT, + GTK_ARG_READWRITE, ARG_TABLESIZE); + gtk_object_add_arg_type("GstSineSrc::freq", GTK_TYPE_DOUBLE, + GTK_ARG_READWRITE, ARG_FREQ); + gtk_object_add_arg_type("GstSineSrc::buffersize", GTK_TYPE_INT, + GTK_ARG_READWRITE, ARG_BUFFER_SIZE); + gtkobject_class->set_arg = gst_sinesrc_set_arg; gtkobject_class->get_arg = gst_sinesrc_get_arg; // gstelement_class->change_state = gst_sinesrc_change_state; } -static void gst_sinesrc_init(GstSineSrc *sinesrc) { - sinesrc->srcpad = gst_pad_new("src",GST_PAD_SRC); - gst_pad_set_get_function(sinesrc->srcpad,gst_sinesrc_get); - gst_element_add_pad(GST_ELEMENT(sinesrc),sinesrc->srcpad); +static void gst_sinesrc_init(GstSineSrc *src) { + + src->srcpad = gst_pad_new("src",GST_PAD_SRC); + gst_pad_set_get_function(src->srcpad, gst_sinesrc_get); + gst_element_add_pad(GST_ELEMENT(src), src->srcpad); - sinesrc->volume = 1.0; + src->volume = 1.0; + gst_sinesrc_update_vol_scale(src); - sinesrc->format = AFMT_S16_LE; - sinesrc->channels = 2; - sinesrc->frequency = 44100; + src->format = 16; + src->samplerate = 44100; + src->freq = 100.0; + src->newcaps = FALSE; + + src->table_pos = 0.0; + src->table_size = 1024; + gst_sinesrc_populate_sinetable(src); + gst_sinesrc_update_table_inc(src); + gst_sinesrc_sync_parms(src); + src->buffer_size=1024; + + src->seq = 0; - sinesrc->seq = 0; - - sinesrc->sentmeta = FALSE; } static GstBuffer * @@ -139,33 +154,50 @@ gst_sinesrc_get(GstPad *pad) GstBuffer *buf; gint16 *samples; gint i; - gint volume; - gdouble val; - + g_return_val_if_fail (pad != NULL, NULL); src = GST_SINESRC(gst_pad_get_parent (pad)); buf = gst_buffer_new(); g_return_val_if_fail (buf, NULL); - GST_BUFFER_DATA(buf) = (gpointer)malloc(4096); - samples = (gint16*)GST_BUFFER_DATA(buf); - GST_BUFFER_SIZE(buf) = 4096; + samples = g_new(gint16, src->buffer_size); + GST_BUFFER_DATA(buf) = (gpointer) samples; + GST_BUFFER_SIZE(buf) = 2 * src->buffer_size; + + for (i=0 ; i < src->buffer_size; i++) { + src->table_lookup = (gint)(src->table_pos); + src->table_lookup_next = src->table_lookup + 1; + src->table_interp = src->table_pos - src->table_lookup; + + // wrap the array lookups if we're out of bounds + if (src->table_lookup_next >= src->table_size){ + src->table_lookup_next -= src->table_size; + if (src->table_lookup >= src->table_size){ + src->table_lookup -= src->table_size; + src->table_pos -= src->table_size; + } + } + + src->table_pos += src->table_inc; - volume = 65535 * src->volume; - for (i=0;i<1024;i++) { - val = sin((gdouble)i/src->frequency); - samples[i] = val * volume; - samples[i+1] = samples[i]; + //no interpolation + //samples[i] = src->table_data[src->table_lookup] + // * src->vol_scale; + + //linear interpolation + samples[i] = ((src->table_interp + *(src->table_data[src->table_lookup_next] + -src->table_data[src->table_lookup] + ) + )+src->table_data[src->table_lookup] + )* src->vol_scale; } - if (!src->sentmeta) { - MetaAudioRaw *newmeta = g_new(MetaAudioRaw,1); - memcpy(newmeta,&src->meta,sizeof(MetaAudioRaw)); - gst_buffer_add_meta(buf,GST_META(newmeta)); - src->sentmeta = TRUE; + if (src->newcaps) { + src->newcaps = FALSE; } - g_print(">"); + //g_print(">"); return buf; } @@ -178,17 +210,35 @@ static void gst_sinesrc_set_arg(GtkObject *object,GtkArg *arg,guint id) { switch (id) { case ARG_VOLUME: + if (GTK_VALUE_DOUBLE(*arg) < 0.0 || GTK_VALUE_DOUBLE(*arg) > 1.0) + break; src->volume = GTK_VALUE_DOUBLE(*arg); + gst_sinesrc_update_vol_scale(src); break; case ARG_FORMAT: src->format = GTK_VALUE_INT(*arg); + gst_sinesrc_sync_parms(src); break; - case ARG_CHANNELS: - src->channels = GTK_VALUE_INT(*arg); + case ARG_SAMPLERATE: + src->samplerate = GTK_VALUE_INT(*arg); + gst_sinesrc_sync_parms(src); + gst_sinesrc_update_table_inc(src); break; - case ARG_FREQUENCY: - src->frequency = GTK_VALUE_INT(*arg); + case ARG_FREQ: { + if (GTK_VALUE_DOUBLE(*arg) <= 0.0 || GTK_VALUE_DOUBLE(*arg) > src->samplerate/2) + break; + src->freq = GTK_VALUE_DOUBLE(*arg); + gst_sinesrc_update_table_inc(src); break; + case ARG_TABLESIZE: + src->table_size = GTK_VALUE_INT(*arg); + gst_sinesrc_populate_sinetable(src); + gst_sinesrc_update_table_inc(src); + break; + case ARG_BUFFER_SIZE: + src->buffer_size = GTK_VALUE_INT(*arg); + break; + } default: break; } @@ -208,11 +258,17 @@ static void gst_sinesrc_get_arg(GtkObject *object,GtkArg *arg,guint id) { case ARG_FORMAT: GTK_VALUE_INT(*arg) = src->format; break; - case ARG_CHANNELS: - GTK_VALUE_INT(*arg) = src->channels; + case ARG_SAMPLERATE: + GTK_VALUE_INT(*arg) = src->samplerate; break; - case ARG_FREQUENCY: - GTK_VALUE_INT(*arg) = src->frequency; + case ARG_FREQ: + GTK_VALUE_DOUBLE(*arg) = src->freq; + break; + case ARG_TABLESIZE: + GTK_VALUE_INT(*arg) = src->table_size; + break; + case ARG_BUFFER_SIZE: + GTK_VALUE_INT(*arg) = src->buffer_size; break; default: arg->type = GTK_TYPE_INVALID; @@ -243,9 +299,30 @@ static gboolean gst_sinesrc_change_state(GstElement *element, } */ -void gst_sinesrc_sync_parms(GstSineSrc *sinesrc) { - sinesrc->meta.format = sinesrc->format; - sinesrc->meta.channels = sinesrc->channels; - sinesrc->meta.frequency = sinesrc->frequency; - sinesrc->sentmeta = FALSE; +static void gst_sinesrc_populate_sinetable(GstSineSrc *src) +{ + gint i; + gdouble pi2scaled = M_PI * 2 / src->table_size; + gfloat *table = g_new(gfloat, src->table_size); + + for(i=0 ; i < src->table_size ; i++){ + table[i] = (gfloat)sin(i * pi2scaled); + } + + g_free(src->table_data); + src->table_data = table; +} + +static inline void gst_sinesrc_update_table_inc(GstSineSrc *src) +{ + src->table_inc = src->table_size * src->freq / src->samplerate; +} + +static inline void gst_sinesrc_update_vol_scale(GstSineSrc *src) +{ + src->vol_scale = 32767 * src->volume; +} + +void gst_sinesrc_sync_parms(GstSineSrc *src) { + src->newcaps = TRUE; } diff --git a/plugins/elements/gstsinesrc.h b/plugins/elements/gstsinesrc.h index b0c457a4e4..167a1ad098 100644 --- a/plugins/elements/gstsinesrc.h +++ b/plugins/elements/gstsinesrc.h @@ -27,8 +27,6 @@ #include #include -#include - #ifdef __cplusplus extern "C" { @@ -60,17 +58,27 @@ struct _GstSineSrc { /* parameters */ gdouble volume; - gint freq; - + gdouble vol_scale; + gdouble freq; + + /* lookup table data */ + gfloat *table_data; + gdouble table_pos; + gdouble table_inc; + gint table_size; + gdouble table_interp; + gint table_lookup; + gint table_lookup_next; + /* audio parameters */ gint format; - gint channels; - gint frequency; + gint samplerate; + gint buffer_size; gulong seq; - MetaAudioRaw meta; - gboolean sentmeta; + gboolean newcaps; + }; struct _GstSineSrcClass { diff --git a/plugins/elements/gsttee.c b/plugins/elements/gsttee.c index d444217367..67ab4b1541 100644 --- a/plugins/elements/gsttee.c +++ b/plugins/elements/gsttee.c @@ -45,13 +45,17 @@ enum { /* FILL ME */ }; -static GstPadFactory tee_src_factory = { - "src%d", - GST_PAD_FACTORY_SRC, - GST_PAD_FACTORY_REQUEST, - NULL, /* no caps */ - NULL, -}; +static GstPadTemplate* +tee_src_factory_create (void) +{ + return + gst_padtemplate_new ( + "src%d", + GST_PAD_SRC, + GST_PAD_REQUEST, + NULL /* no caps */ + ); +} static void gst_tee_class_init (GstTeeClass *klass); @@ -197,7 +201,7 @@ gst_tee_chain (GstPad *pad, GstBuffer *buf) gboolean gst_tee_factory_init (GstElementFactory *factory) { - gst_tee_src_template = gst_padtemplate_new (&tee_src_factory); + gst_tee_src_template = tee_src_factory_create (); gst_elementfactory_add_padtemplate (factory, gst_tee_src_template); return TRUE; diff --git a/test/.gitignore b/test/.gitignore index 40244b01f8..86f0ab3ce4 100644 --- a/test/.gitignore +++ b/test/.gitignore @@ -27,6 +27,7 @@ teardown buffer mp3parse mpeg2parse +mpeg2parse2 mp3play ac3parse ac3play @@ -44,3 +45,4 @@ mp2toavi mp1tomp1 pipetest mp3tovorbis +xmmstest diff --git a/test/Makefile.am b/test/Makefile.am index 6b8e7e6c70..5a56d5efd5 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -3,7 +3,7 @@ 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 + vidcapture2 mp2toavi mp3tovorbis mpeg2parse2 xmmstest videotest2 SUBDIRS = xml bindings @@ -19,7 +19,7 @@ else xvlibs= endif -LDADD = $(top_builddir)/plugins/videosink/gdkxvimage.lo ${xvlibs} -lXxf86vm +LDADD = ${xvlibs} -lXxf86vm #LDADD = $(GLIB_LIBS) $(GTK_LIBS) $(top_builddir)/gst/libgst.la \ # $(top_builddir)/plugins/videosink/libvideosink.la -L/usr/X11/lib -lXxf86dga diff --git a/test/a.c b/test/a.c index 6efa57dae4..03dd680152 100644 --- a/test/a.c +++ b/test/a.c @@ -9,7 +9,7 @@ int main(int argc,char *argv[]) { GstType *autype; GList *factories; GstElementFactory *parsefactory; - GstElement *bin, *disksrc, *parse, *audiosink; + GstElement *bin, *disksrc, *parse, *osssink; GList *padlist; gst_init(&argc,&argv); @@ -42,7 +42,7 @@ int main(int argc,char *argv[]) { } - audiosink = gst_audiosink_new("audiosink"); + osssink = gst_osssink_new("osssink"); gtk_signal_connect(GTK_OBJECT(disksrc),"eos", GTK_SIGNAL_FUNC(eof),NULL); @@ -50,18 +50,18 @@ int main(int argc,char *argv[]) { /* add objects to the main pipeline */ gst_bin_add(GST_BIN(bin),GST_OBJECT(disksrc)); gst_bin_add(GST_BIN(bin),GST_OBJECT(parse)); - gst_bin_add(GST_BIN(bin),GST_OBJECT(audiosink)); + gst_bin_add(GST_BIN(bin),GST_OBJECT(osssink)); /* connect src to sink */ gst_pad_connect(gst_element_get_pad(disksrc,"src"), gst_element_get_pad(parse,"sink")); gst_pad_connect(gst_element_get_pad(parse,"src"), - gst_element_get_pad(audiosink,"sink")); + gst_element_get_pad(osssink,"sink")); while(1) gst_disksrc_push(GST_SRC(disksrc)); - gst_object_destroy(GST_OBJECT(audiosink)); + gst_object_destroy(GST_OBJECT(osssink)); gst_object_destroy(GST_OBJECT(parse)); gst_object_destroy(GST_OBJECT(disksrc)); gst_object_destroy(GST_OBJECT(bin)); diff --git a/test/ac3play.c b/test/ac3play.c index 9967a1aada..9154793865 100644 --- a/test/ac3play.c +++ b/test/ac3play.c @@ -30,7 +30,7 @@ int main(int argc,char *argv[]) { g_return_if_fail(parse != NULL); decode = gst_elementfactory_make("ac3dec","decode"); g_return_if_fail(decode != NULL); - play = gst_elementfactory_make("audiosink","play"); + play = gst_elementfactory_make("osssink","play"); g_return_if_fail(play != NULL); // construct the decode thread diff --git a/test/aviparse.c b/test/aviparse.c index 1721930796..7e3882e59a 100644 --- a/test/aviparse.c +++ b/test/aviparse.c @@ -23,7 +23,7 @@ void new_pad_created(GstElement *parse,GstPad *pad,GstElement *pipeline) { //if (0) { if (strncmp(gst_pad_get_name(pad), "audio_", 6) == 0) { // construct internal pipeline elements - play = gst_elementfactory_make("audiosink","play_audio"); + play = gst_elementfactory_make("osssink","play_audio"); g_return_if_fail(play != NULL); // create the thread and pack stuff into it diff --git a/test/m.c b/test/m.c index f210e068ed..6b3607ad8e 100644 --- a/test/m.c +++ b/test/m.c @@ -47,7 +47,7 @@ int main(int argc,char *argv[]) { } - sink = gst_audiosink_new("audiosink"); + sink = gst_osssink_new("osssink"); gtk_signal_connect(GTK_OBJECT(src),"eof", GTK_SIGNAL_FUNC(eof),NULL); diff --git a/test/mcut.c b/test/mcut.c index 95f1969e4a..a75d109c79 100644 --- a/test/mcut.c +++ b/test/mcut.c @@ -48,7 +48,7 @@ int main(int argc,char *argv[]) { } - sink = gst_audiosink_new("audiosink"); + sink = gst_osssink_new("osssink"); gtk_signal_connect(GTK_OBJECT(src),"eof", GTK_SIGNAL_FUNC(eof),NULL); diff --git a/test/mp1parse.c b/test/mp1parse.c index d49bdad0eb..4db677dab1 100644 --- a/test/mp1parse.c +++ b/test/mp1parse.c @@ -31,7 +31,7 @@ void new_pad_created(GstElement *parse,GstPad *pad,GstElement *pipeline) { g_return_if_fail(parse_audio != NULL); decode = gst_elementfactory_make("mpg123","decode_audio"); g_return_if_fail(decode != NULL); - play = gst_elementfactory_make("audiosink","play_audio"); + play = gst_elementfactory_make("osssink","play_audio"); g_return_if_fail(play != NULL); // create the thread and pack stuff into it @@ -62,7 +62,6 @@ void new_pad_created(GstElement *parse,GstPad *pad,GstElement *pipeline) { // set up thread state and kick things off gtk_object_set(GTK_OBJECT(audio_thread),"create_thread",TRUE,NULL); g_print("setting to READY state\n"); - gst_element_set_state(GST_ELEMENT(audio_thread),GST_STATE_READY); } else if (strncmp(gst_pad_get_name(pad), "video_", 6) == 0) { //} else if (0) { @@ -116,7 +115,6 @@ void new_pad_created(GstElement *parse,GstPad *pad,GstElement *pipeline) { // set up thread state and kick things off gtk_object_set(GTK_OBJECT(video_thread),"create_thread",TRUE,NULL); g_print("setting to READY state\n"); - gst_element_set_state(GST_ELEMENT(video_thread),GST_STATE_READY); } g_print("\n"); gst_element_set_state(GST_ELEMENT(pipeline),GST_STATE_PLAYING); diff --git a/test/mp1tomp1.c b/test/mp1tomp1.c index f047886b02..ebe298e817 100644 --- a/test/mp1tomp1.c +++ b/test/mp1tomp1.c @@ -33,7 +33,7 @@ void mp2tomp1(GstElement *parser,GstPad *pad, GstElement *pipeline) { g_return_if_fail(parse_audio != NULL); decode = gst_elementfactory_make("ac3dec","decode_audio"); g_return_if_fail(decode != NULL); - play = gst_elementfactory_make("audiosink","play_audio"); + play = gst_elementfactory_make("osssink","play_audio"); g_return_if_fail(play != NULL); // create the thread and pack stuff into it @@ -75,7 +75,7 @@ void mp2tomp1(GstElement *parser,GstPad *pad, GstElement *pipeline) { g_return_if_fail(parse_audio != NULL); decode = gst_elementfactory_make("mpg123","decode_audio"); g_return_if_fail(decode != NULL); - play = gst_elementfactory_make("audiosink","play_audio"); + play = gst_elementfactory_make("osssink","play_audio"); g_return_if_fail(play != NULL); // create the thread and pack stuff into it diff --git a/test/mp2toavi.c b/test/mp2toavi.c index 4dd7e3cae9..fd5a7b7e82 100644 --- a/test/mp2toavi.c +++ b/test/mp2toavi.c @@ -104,7 +104,7 @@ void mp2tomp1(GstElement *parser,GstPad *pad, GstElement *pipeline) { g_return_if_fail(parse_audio != NULL); decode = gst_elementfactory_make("mpg123","decode_audio"); g_return_if_fail(decode != NULL); - play = gst_elementfactory_make("audiosink","play_audio"); + play = gst_elementfactory_make("osssink","play_audio"); g_return_if_fail(play != NULL); // create the thread and pack stuff into it diff --git a/test/mp2tomp1.c b/test/mp2tomp1.c index 9265930d2f..78d9550ec1 100644 --- a/test/mp2tomp1.c +++ b/test/mp2tomp1.c @@ -110,7 +110,7 @@ mp2tomp1 (GstElement *parser, GstPad *pad, GstElement *pipeline) g_return_if_fail(parse_audio != NULL); decode = gst_elementfactory_make("mpg123","decode_audio"); g_return_if_fail(decode != NULL); - play = gst_elementfactory_make("audiosink","play_audio"); + play = gst_elementfactory_make("osssink","play_audio"); g_return_if_fail(play != NULL); // create the thread and pack stuff into it diff --git a/test/mp3.c b/test/mp3.c index 88b8a7ad1e..5f4ff6fba1 100644 --- a/test/mp3.c +++ b/test/mp3.c @@ -31,7 +31,7 @@ int main(int argc,char *argv[]) { mp3factory = gst_elementfactory_find(argv[2]); else mp3factory = gst_elementfactory_find("xa"); - sinkfactory = gst_elementfactory_find("audiosink"); + sinkfactory = gst_elementfactory_find("osssink"); src = gst_elementfactory_create(srcfactory,"src"); g_return_val_if_fail(src != NULL, -1); diff --git a/test/mp3play.c b/test/mp3play.c index 8401798357..0f57fcf5fa 100644 --- a/test/mp3play.c +++ b/test/mp3play.c @@ -24,7 +24,7 @@ int main(int argc,char *argv[]) { g_return_if_fail(parsefactory != NULL); decodefactory = gst_elementfactory_find("mpg123"); g_return_if_fail(decodefactory != NULL); - playfactory = gst_elementfactory_find("audiosink"); + playfactory = gst_elementfactory_find("osssink"); g_return_if_fail(playfactory != NULL); src = gst_elementfactory_create(srcfactory,"src"); diff --git a/test/mpeg2parse.c b/test/mpeg2parse.c index bdae3ca371..50aeb0162c 100644 --- a/test/mpeg2parse.c +++ b/test/mpeg2parse.c @@ -34,7 +34,7 @@ void mpeg2parse_newpad(GstElement *parser,GstPad *pad, GstElement *pipeline) { g_return_if_fail(parse_audio != NULL); decode = gst_elementfactory_make("ac3dec","decode_audio"); g_return_if_fail(decode != NULL); - play = gst_elementfactory_make("audiosink","play_audio"); + play = gst_elementfactory_make("osssink","play_audio"); g_return_if_fail(play != NULL); // create the thread and pack stuff into it @@ -78,7 +78,7 @@ void mpeg2parse_newpad(GstElement *parser,GstPad *pad, GstElement *pipeline) { g_return_if_fail(parse_audio != NULL); decode = gst_elementfactory_make("mpg123","decode_audio"); g_return_if_fail(decode != NULL); - play = gst_elementfactory_make("audiosink","play_audio"); + play = gst_elementfactory_make("osssink","play_audio"); g_return_if_fail(play != NULL); // create the thread and pack stuff into it diff --git a/test/mpeg2parse2.c b/test/mpeg2parse2.c new file mode 100644 index 0000000000..176eed35d2 --- /dev/null +++ b/test/mpeg2parse2.c @@ -0,0 +1,136 @@ +#include +#include + +GstElement *parse2, *queue; +GtkWidget *appwindow; + +void eof(GstElement *src) { + g_print("have eos, quitting\n"); + exit(0); +} + +gboolean idle_func(gpointer data) { + gst_bin_iterate(GST_BIN(data)); + return TRUE; +} + +void mpeg2parse_newpad(GstElement *parser,GstPad *pad, GstElement *pipeline) { + + g_print("***** a new pad %s was created\n", gst_pad_get_name(pad)); + gst_element_set_state(GST_ELEMENT(pipeline),GST_STATE_PAUSED); + + if (strncmp(gst_pad_get_name(pad), "video_", 6) == 0) { + + gst_pad_connect(pad, gst_element_get_pad(queue,"sink")); + } + gst_element_set_state(GST_ELEMENT(pipeline),GST_STATE_PLAYING); +} + +int main(int argc,char *argv[]) { + GstPipeline *pipeline; + GstElement *src, *parse; + GstElement *decode, *show, *thread, *color; + GtkWidget *gtk_socket; + + g_print("have %d args\n",argc); + + gst_init(&argc,&argv); + gnome_init("MPEG2 Video player","0.0.1",argc,argv); + //gst_plugin_load("mpeg1parse"); + + pipeline = GST_PIPELINE(gst_pipeline_new("pipeline")); + g_return_val_if_fail(pipeline != NULL, -1); + thread = GST_ELEMENT(gst_thread_new("thread")); + g_return_val_if_fail(thread != NULL, -1); + + if (strstr(argv[1],"video_ts")) { + src = gst_elementfactory_make("dvdsrc","src"); + g_print("using DVD source\n"); + } else + src = gst_elementfactory_make("disksrc","src"); + + g_return_val_if_fail(src != NULL, -1); + gtk_object_set(GTK_OBJECT(src),"location",argv[1],NULL); + if (argc >= 3) { + gtk_object_set(GTK_OBJECT(src),"bytesperread",atoi(argv[2]),NULL); + g_print("block size is %d\n",atoi(argv[2])); + } + g_print("should be using file '%s'\n",argv[1]); + + parse = gst_elementfactory_make("mpeg2parse","parse"); + //parse = gst_elementfactory_make("mpeg1parse","parse"); + g_return_val_if_fail(parse != NULL, -1); + + queue = gst_elementfactory_make("queue","queue"); + g_return_val_if_fail(queue != NULL, -1); + + /**** + * you can substitute mpeg2play with you own player here + * optionally you can remove the parse2 element. make + * sure to remove the pad connections too and don't add the + * mp2videoparse element to the bin. + **/ + //parse2 = gst_elementfactory_make("mp2videoparse","parse"); + //g_return_val_if_fail(parse2 != NULL, -1); + decode = gst_elementfactory_make("mpeg2dec","decode_video"); + g_return_val_if_fail(decode != NULL, -1); + + color = gst_elementfactory_make("colorspace","color"); + g_return_val_if_fail(color != NULL, -1); + + show = gst_elementfactory_make("xvideosink","show"); + //gtk_object_set(GTK_OBJECT(show),"xv_enabled",FALSE,NULL); + g_return_val_if_fail(show != NULL, -1); + + appwindow = gnome_app_new("MPEG player","MPEG player"); + + gtk_socket = gtk_socket_new (); + gtk_widget_show (gtk_socket); + + gnome_app_set_contents(GNOME_APP(appwindow), + GTK_WIDGET(gtk_socket)); + + gtk_widget_realize (gtk_socket); + gtk_socket_steal (GTK_SOCKET (gtk_socket), + gst_util_get_int_arg (GTK_OBJECT(show), "xid")); + + gst_bin_add(GST_BIN(pipeline),GST_ELEMENT(src)); + gst_bin_add(GST_BIN(pipeline),GST_ELEMENT(parse)); + gst_bin_add(GST_BIN(pipeline),GST_ELEMENT(queue)); + + //gst_bin_add(GST_BIN(thread),GST_ELEMENT(parse2)); + gst_bin_add(GST_BIN(thread),GST_ELEMENT(decode)); + gst_bin_add(GST_BIN(thread),GST_ELEMENT(color)); + gst_bin_add(GST_BIN(thread),GST_ELEMENT(show)); + + gst_bin_add(GST_BIN(pipeline),GST_ELEMENT(thread)); + + gtk_signal_connect(GTK_OBJECT(parse),"new_pad",mpeg2parse_newpad, pipeline); + + gtk_signal_connect(GTK_OBJECT(src),"eos",GTK_SIGNAL_FUNC(eof),NULL); + + gst_pad_connect(gst_element_get_pad(src,"src"), + gst_element_get_pad(parse,"sink")); + + gst_pad_connect(gst_element_get_pad(queue,"src"), + // gst_element_get_pad(parse2,"sink")); + //gst_pad_connect(gst_element_get_pad(parse2,"src"), + gst_element_get_pad(decode,"sink")); + gst_pad_connect(gst_element_get_pad(decode,"src"), + gst_element_get_pad(color,"sink")); + gst_pad_connect(gst_element_get_pad(color,"src"), + gst_element_get_pad(show,"sink")); + + gtk_widget_show_all(appwindow); + + g_print("setting to PLAYING state\n"); + gst_element_set_state(GST_ELEMENT(pipeline),GST_STATE_PLAYING); + + gtk_idle_add(idle_func,pipeline); + + gdk_threads_enter(); + gtk_main(); + gdk_threads_leave(); + + return 0; +} diff --git a/test/mpg123.c b/test/mpg123.c index e242b9c8ed..6c3d17dc77 100644 --- a/test/mpg123.c +++ b/test/mpg123.c @@ -8,7 +8,7 @@ void eof(GstSrc *src) { int main(int argc,char *argv[]) { GList *factories; GstElementFactory *parsefactory; - GstElement *bin, *disksrc, *parse, *audiosink; + GstElement *bin, *disksrc, *parse, *osssink; GList *padlist; guchar *filename; int i; @@ -38,7 +38,7 @@ int main(int argc,char *argv[]) { } - audiosink = gst_audiosink_new("audiosink"); + osssink = gst_osssink_new("osssink"); gtk_signal_connect(GTK_OBJECT(disksrc),"eof", GTK_SIGNAL_FUNC(eof),NULL); @@ -46,20 +46,20 @@ int main(int argc,char *argv[]) { /* add objects to the main pipeline */ gst_bin_add(GST_BIN(bin),GST_OBJECT(disksrc)); gst_bin_add(GST_BIN(bin),GST_OBJECT(parse)); - gst_bin_add(GST_BIN(bin),GST_OBJECT(audiosink)); + gst_bin_add(GST_BIN(bin),GST_OBJECT(osssink)); /* connect src to sink */ gst_pad_connect(gst_element_get_pad(disksrc,"src"), gst_element_get_pad(parse,"sink")); gst_pad_connect(gst_element_get_pad(parse,"src"), - gst_element_get_pad(audiosink,"sink")); + gst_element_get_pad(osssink,"sink")); for (i=0;i<4;i++) { g_print("\n"); gst_disksrc_push(GST_SRC(disksrc)); } - gst_object_destroy(GST_OBJECT(audiosink)); + gst_object_destroy(GST_OBJECT(osssink)); gst_object_destroy(GST_OBJECT(parse)); gst_object_destroy(GST_OBJECT(disksrc)); gst_object_destroy(GST_OBJECT(bin)); diff --git a/test/p.c b/test/p.c index 457e4b374b..6ec69825d1 100644 --- a/test/p.c +++ b/test/p.c @@ -7,7 +7,7 @@ void eof(GstSrc *src) { } int main(int argc,char *argv[]) { - GstElement *bin, *disksrc, *p, *audiosink; + GstElement *bin, *disksrc, *p, *osssink; GList *padlist; gst_init(&argc,&argv); @@ -24,7 +24,7 @@ int main(int argc,char *argv[]) { g_print("loaded file '%s'\n",gst_disksrc_get_filename(disksrc)); p = gst_plugin_find_elementfactory("pipe"); - audiosink = gst_audiosink_new("audiosink"); + osssink = gst_osssink_new("osssink"); gtk_signal_connect(GTK_OBJECT(disksrc),"eof", GTK_SIGNAL_FUNC(eof),NULL); @@ -32,23 +32,23 @@ int main(int argc,char *argv[]) { /* add objects to the main pipeline */ gst_bin_add(GST_BIN(bin),GST_OBJECT(disksrc)); gst_bin_add(GST_BIN(bin),GST_OBJECT(p)); - gst_bin_add(GST_BIN(bin),GST_OBJECT(audiosink)); + gst_bin_add(GST_BIN(bin),GST_OBJECT(osssink)); /* connect src to sink */ gst_pad_connect(gst_element_get_pad(disksrc,"src"), gst_element_get_pad(p,"sink")); gst_pad_connect(gst_element_get_pad(p,"src"), - gst_element_get_pad(audiosink,"sink")); + gst_element_get_pad(osssink,"sink")); /* set soundcard properties */ - gst_audiosink_set_format(GST_AUDIOSINK(audiosink),AFMT_S16_BE); - gst_audiosink_set_channels(GST_AUDIOSINK(audiosink),2); - gst_audiosink_set_frequency(GST_AUDIOSINK(audiosink),44100); + gst_osssink_set_format(GST_AUDIOSINK(osssink),AFMT_S16_BE); + gst_osssink_set_channels(GST_AUDIOSINK(osssink),2); + gst_osssink_set_frequency(GST_AUDIOSINK(osssink),44100); while(1) gst_disksrc_push(GST_SRC(disksrc)); - gst_object_destroy(GST_OBJECT(audiosink)); + gst_object_destroy(GST_OBJECT(osssink)); gst_object_destroy(GST_OBJECT(disksrc)); gst_object_destroy(GST_OBJECT(bin)); } diff --git a/test/qtest.c b/test/qtest.c index cc32715f6e..262f0499dd 100644 --- a/test/qtest.c +++ b/test/qtest.c @@ -57,7 +57,7 @@ int main(int argc,char *argv[]) { /* then the play thread and sink */ playthread = gst_thread_new("playthread"); - sinkfactory = gst_elementfactory_find("audiosink"); + sinkfactory = gst_elementfactory_find("osssink"); sink = gst_elementfactory_create(sinkfactory,"sink"); gst_bin_add(GST_BIN(playthread),GST_ELEMENT(sink)); gst_element_add_ghost_pad(GST_ELEMENT(playthread), diff --git a/test/r.c b/test/r.c index 5acc6225f4..a389f68056 100644 --- a/test/r.c +++ b/test/r.c @@ -7,7 +7,7 @@ void eof(GstSrc *src) { } int main(int argc,char *argv[]) { - GstElement *bin, *disksrc, *audiosink; + GstElement *bin, *disksrc, *osssink; GList *padlist; gst_init(&argc,&argv); @@ -23,28 +23,28 @@ int main(int argc,char *argv[]) { gtk_object_set(GTK_OBJECT(disksrc),"bytesperread",32768,NULL); g_print("loaded file '%s'\n",gst_disksrc_get_filename(disksrc)); - audiosink = gst_audiosink_new("audiosink"); + osssink = gst_osssink_new("osssink"); gtk_signal_connect(GTK_OBJECT(disksrc),"eof", GTK_SIGNAL_FUNC(eof),NULL); /* add objects to the main pipeline */ gst_bin_add(GST_BIN(bin),GST_OBJECT(disksrc)); - gst_bin_add(GST_BIN(bin),GST_OBJECT(audiosink)); + gst_bin_add(GST_BIN(bin),GST_OBJECT(osssink)); /* connect src to sink */ gst_pad_connect(gst_element_get_pad(disksrc,"src"), - gst_element_get_pad(audiosink,"sink")); + gst_element_get_pad(osssink,"sink")); /* set soundcard properties */ - gst_audiosink_set_format(GST_AUDIOSINK(audiosink),AFMT_S16_BE); - gst_audiosink_set_channels(GST_AUDIOSINK(audiosink),2); - gst_audiosink_set_frequency(GST_AUDIOSINK(audiosink),44100); + gst_osssink_set_format(GST_AUDIOSINK(osssink),AFMT_S16_BE); + gst_osssink_set_channels(GST_AUDIOSINK(osssink),2); + gst_osssink_set_frequency(GST_AUDIOSINK(osssink),44100); while(1) gst_disksrc_push(GST_SRC(disksrc)); - gst_object_destroy(GST_OBJECT(audiosink)); + gst_object_destroy(GST_OBJECT(osssink)); gst_object_destroy(GST_OBJECT(disksrc)); gst_object_destroy(GST_OBJECT(bin)); } diff --git a/test/record.c b/test/record.c index b297969842..12b3a2783d 100644 --- a/test/record.c +++ b/test/record.c @@ -6,16 +6,16 @@ int main(int argc,char *argv[]) { int fd; - GstElement *pipeline, *audiosrc, *fdsink; - GstElementFactory *audiosrcfactory, *fdsinkfactory; + GstElement *pipeline, *osssrc, *fdsink; + GstElementFactory *osssrcfactory, *fdsinkfactory; GList *padlist; gst_init(&argc,&argv); pipeline = GST_ELEMENT(gst_pipeline_new("pipeline")); - audiosrcfactory = gst_elementfactory_find("audiosrc"); - audiosrc = gst_elementfactory_create(audiosrcfactory,"audiosrc"); + osssrcfactory = gst_elementfactory_find("osssrc"); + osssrc = gst_elementfactory_create(osssrcfactory,"osssrc"); fd = open(argv[1],O_CREAT|O_RDWR); @@ -24,11 +24,11 @@ int main(int argc,char *argv[]) { gtk_object_set(GTK_OBJECT(fdsink),"fd",fd,NULL); /* add objects to the main pipeline */ - gst_bin_add(GST_BIN(pipeline),GST_ELEMENT(audiosrc)); + gst_bin_add(GST_BIN(pipeline),GST_ELEMENT(osssrc)); gst_bin_add(GST_BIN(pipeline),GST_ELEMENT(fdsink)); /* connect src to sink */ - gst_pad_connect(gst_element_get_pad(audiosrc,"src"), + gst_pad_connect(gst_element_get_pad(osssrc,"src"), gst_element_get_pad(fdsink,"sink")); g_print("\nok, runnable, hitting 'play'...\n"); diff --git a/test/s.c b/test/s.c index cefab58e49..1d2f6b6b37 100644 --- a/test/s.c +++ b/test/s.c @@ -11,7 +11,7 @@ int main(int argc,char *argv[]) { guint16 mp3type; GList *factories; GstElementFactory *parsefactory; - GstElement *bin, *src, *parse, *audiosink; + GstElement *bin, *src, *parse, *osssink; GList *padlist; ghttp_request *pls; guchar *plsbuf; @@ -85,7 +85,7 @@ int main(int argc,char *argv[]) { } - audiosink = gst_audiosink_new("audiosink"); + osssink = gst_osssink_new("osssink"); gtk_signal_connect(GTK_OBJECT(src),"eof", GTK_SIGNAL_FUNC(eof),NULL); @@ -93,13 +93,13 @@ int main(int argc,char *argv[]) { /* add objects to the main pipeline */ gst_bin_add(GST_BIN(bin),GST_OBJECT(src)); gst_bin_add(GST_BIN(bin),GST_OBJECT(parse)); - gst_bin_add(GST_BIN(bin),GST_OBJECT(audiosink)); + gst_bin_add(GST_BIN(bin),GST_OBJECT(osssink)); /* connect src to sink */ gst_pad_connect(gst_element_get_pad(src,"src"), gst_element_get_pad(parse,"sink")); gst_pad_connect(gst_element_get_pad(parse,"src"), - gst_element_get_pad(audiosink,"sink")); + gst_element_get_pad(osssink,"sink")); sleep(5); /* to let the network buffer fill a bit */ @@ -108,7 +108,7 @@ int main(int argc,char *argv[]) { gst_httpsrc_push(GST_SRC(src)); } - gst_object_destroy(GST_OBJECT(audiosink)); + gst_object_destroy(GST_OBJECT(osssink)); gst_object_destroy(GST_OBJECT(parse)); gst_object_destroy(GST_OBJECT(src)); gst_object_destroy(GST_OBJECT(bin)); diff --git a/test/spectrum.c b/test/spectrum.c index 767deabf0b..826613ed1b 100644 --- a/test/spectrum.c +++ b/test/spectrum.c @@ -26,7 +26,7 @@ int main(int argc,char *argv[]) { bin = gst_bin_new("bin"); - srcfactory = gst_elementfactory_find("audiosrc"); + srcfactory = gst_elementfactory_find("osssrc"); spectrumfactory = gst_elementfactory_find("gstspectrum"); src = gst_elementfactory_create(srcfactory,"src"); diff --git a/test/typefind.c b/test/typefind.c index a9867c6b0f..639aa14c15 100644 --- a/test/typefind.c +++ b/test/typefind.c @@ -36,7 +36,7 @@ int main(int argc,char *argv[]) { } - audiosink = gst_audiosink_new("audiosink"); + osssink = gst_osssink_new("osssink"); gtk_signal_connect(GTK_OBJECT(disksrc),"eof", GTK_SIGNAL_FUNC(eof),NULL); @@ -44,18 +44,18 @@ int main(int argc,char *argv[]) { /* add objects to the main pipeline */ gst_bin_add(GST_BIN(bin),GST_OBJECT(disksrc)); gst_bin_add(GST_BIN(bin),GST_OBJECT(parse)); - gst_bin_add(GST_BIN(bin),GST_OBJECT(audiosink)); + gst_bin_add(GST_BIN(bin),GST_OBJECT(osssink)); /* connect src to sink */ gst_pad_connect(gst_element_get_pad(disksrc,"src"), gst_element_get_pad(parse,"sink")); gst_pad_connect(gst_element_get_pad(parse,"src"), - gst_element_get_pad(audiosink,"sink")); + gst_element_get_pad(osssink,"sink")); while(1) gst_disksrc_push(GST_SRC(disksrc)); - gst_object_destroy(GST_OBJECT(audiosink)); + gst_object_destroy(GST_OBJECT(osssink)); gst_object_destroy(GST_OBJECT(parse)); gst_object_destroy(GST_OBJECT(disksrc)); gst_object_destroy(GST_OBJECT(bin)); diff --git a/test/vidcapture.c b/test/vidcapture.c index 136d627253..6d3bd2bdc2 100644 --- a/test/vidcapture.c +++ b/test/vidcapture.c @@ -7,8 +7,8 @@ int main(int argc,char *argv[]) { int fd; GstPipeline *pipeline; - GstElement *audiosrc, *videosrc, *fdsink, *encoder, *compress, *video_queue, *video_thread; - GstElementFactory *audiosrcfactory, *fdsinkfactory, *encoderfactory, *compressfactory; + GstElement *osssrc, *videosrc, *fdsink, *encoder, *compress, *video_queue, *video_thread; + GstElementFactory *osssrcfactory, *fdsinkfactory, *encoderfactory, *compressfactory; GstElementFactory *videosrcfactory; GList *padlist; @@ -20,8 +20,8 @@ int main(int argc,char *argv[]) { pipeline = gst_pipeline_new("pipeline"); - audiosrcfactory = gst_elementfactory_find("audiosrc"); - audiosrc = gst_elementfactory_create(audiosrcfactory,"audiosrc"); + osssrcfactory = gst_elementfactory_find("osssrc"); + osssrc = gst_elementfactory_create(osssrcfactory,"osssrc"); videosrcfactory = gst_elementfactory_find("v4lsrc"); videosrc = gst_elementfactory_create(videosrcfactory,"videosrc"); diff --git a/test/vidcapture2.c b/test/vidcapture2.c index d3d247528c..af4ad4145a 100644 --- a/test/vidcapture2.c +++ b/test/vidcapture2.c @@ -7,8 +7,8 @@ int main(int argc,char *argv[]) { int fd; GstPipeline *pipeline; - GstElement *audiosrc, *videosrc, *fdsink, *encoder, *compress, *video_queue, *video_thread; - GstElementFactory *audiosrcfactory, *fdsinkfactory, *encoderfactory, *compressfactory; + GstElement *osssrc, *videosrc, *fdsink, *encoder, *compress, *video_queue, *video_thread; + GstElementFactory *osssrcfactory, *fdsinkfactory, *encoderfactory, *compressfactory; GstElementFactory *videosrcfactory; GList *padlist; @@ -20,8 +20,8 @@ int main(int argc,char *argv[]) { pipeline = gst_pipeline_new("pipeline"); - audiosrcfactory = gst_elementfactory_find("audiosrc"); - audiosrc = gst_elementfactory_create(audiosrcfactory,"audiosrc"); + osssrcfactory = gst_elementfactory_find("osssrc"); + osssrc = gst_elementfactory_create(osssrcfactory,"osssrc"); videosrcfactory = gst_elementfactory_find("v4lsrc"); videosrc = gst_elementfactory_create(videosrcfactory,"videosrc"); diff --git a/test/videotest.c b/test/videotest.c index 2012e3c66b..9c08566460 100644 --- a/test/videotest.c +++ b/test/videotest.c @@ -6,23 +6,25 @@ extern gboolean _gst_plugin_spew; gboolean idle_func(gpointer data); GstElement *videosink; +GstElement *videosink2; GstElement *src; int main(int argc,char *argv[]) { GstElement *bin; + GstElement *tee; GstElementFactory *srcfactory; GstElementFactory *videosinkfactory; GtkWidget *appwindow; + GtkWidget *appwindow2; GtkWidget *vbox1; GtkWidget *button; GtkWidget *draw; + GtkWidget *draw2; //_gst_plugin_spew = TRUE; gst_init(&argc,&argv); - gst_plugin_load("v4lsrc"); - gst_plugin_load("videosink"); gnome_init("Videotest","0.0.1",argc,argv); @@ -34,17 +36,33 @@ int main(int argc,char *argv[]) { g_return_if_fail(videosinkfactory != NULL); src = gst_elementfactory_create(srcfactory,"src"); + gtk_object_set(GTK_OBJECT(src),"format",3,NULL); + gtk_object_set(GTK_OBJECT(src),"width",320,"height",240,NULL); + videosink = gst_elementfactory_create(videosinkfactory,"videosink"); + gtk_object_set(GTK_OBJECT(videosink),"xv_enabled",FALSE,NULL); gtk_object_set(GTK_OBJECT(videosink),"width",320,"height",240,NULL); + videosink2 = gst_elementfactory_create(videosinkfactory,"videosink2"); + gtk_object_set(GTK_OBJECT(videosink2),"xv_enabled",FALSE,NULL); + gtk_object_set(GTK_OBJECT(videosink2),"width",320,"height",240,NULL); + + tee = gst_elementfactory_make ("tee", "tee"); gst_bin_add(GST_BIN(bin),GST_ELEMENT(src)); + gst_bin_add(GST_BIN(bin),GST_ELEMENT(tee)); gst_bin_add(GST_BIN(bin),GST_ELEMENT(videosink)); + gst_bin_add(GST_BIN(bin),GST_ELEMENT(videosink2)); gst_pad_connect(gst_element_get_pad(src,"src"), + gst_element_get_pad(tee,"sink")); + gst_pad_connect(gst_element_request_pad_by_name (tee,"src%d"), gst_element_get_pad(videosink,"sink")); + gst_pad_connect(gst_element_request_pad_by_name (tee,"src%d"), + gst_element_get_pad(videosink2,"sink")); appwindow = gnome_app_new("Videotest","Videotest"); + appwindow2 = gnome_app_new("Videotest2","Videotest2"); vbox1 = gtk_vbox_new (FALSE, 0); gtk_widget_show (vbox1); @@ -60,17 +78,24 @@ int main(int argc,char *argv[]) { draw, TRUE, TRUE, 0); gtk_widget_show (draw); + + draw2 = gst_util_get_widget_arg(GTK_OBJECT(videosink2),"widget"), + gtk_widget_show (draw2); gnome_app_set_contents(GNOME_APP(appwindow), vbox1); + gnome_app_set_contents(GNOME_APP(appwindow2), draw2); + 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); + gtk_widget_show_all(appwindow2); - gst_element_set_state(GST_ELEMENT(bin),GST_STATE_READY); gst_element_set_state(GST_ELEMENT(bin),GST_STATE_PLAYING); + gtk_object_set(GTK_OBJECT(src),"bright",32000,"contrast", 32000,NULL); + //gtk_object_set(GTK_OBJECT(src),"tune",133250,NULL); g_idle_add(idle_func,bin); diff --git a/test/videotest2.c b/test/videotest2.c new file mode 100644 index 0000000000..c830cc8ff2 --- /dev/null +++ b/test/videotest2.c @@ -0,0 +1,85 @@ +#include +#include + +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 *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"); + + src = gst_elementfactory_make ("v4lsrc", "src"); + gtk_object_set(GTK_OBJECT(src),"format",9,NULL); + gtk_object_set(GTK_OBJECT(src),"width",320,"height",240,NULL); + //gtk_object_set(GTK_OBJECT(src),"width",100,"height",100,NULL); + + videosink = gst_elementfactory_make ("xvideosink", "videosink"); + gtk_object_set(GTK_OBJECT(videosink),"width",320,"height",240,NULL); + + gst_bin_add(GST_BIN(bin),GST_ELEMENT(src)); + gst_bin_add(GST_BIN(bin),GST_ELEMENT(videosink)); + + gst_pad_connect(gst_element_get_pad(src,"src"), + gst_element_get_pad(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_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); + + gst_element_set_state(GST_ELEMENT(bin),GST_STATE_PLAYING); + + gtk_object_set(GTK_OBJECT(src),"bright",32000,"contrast", 32000,NULL); + + //gtk_object_set(GTK_OBJECT(src),"tune",133250,NULL); + g_idle_add(idle_func,bin); + + gtk_main(); + + exit (0); +} + diff --git a/test/w.c b/test/w.c index 1173e9e958..b65171b383 100644 --- a/test/w.c +++ b/test/w.c @@ -9,7 +9,7 @@ int main(int argc,char *argv[]) { GstType *autype; GList *factories; GstElementFactory *parsefactory; - GstElement *bin, *disksrc, *parse, *audiosink; + GstElement *bin, *disksrc, *parse, *osssink; GList *padlist; gst_init(&argc,&argv); @@ -43,7 +43,7 @@ int main(int argc,char *argv[]) { } - audiosink = gst_audiosink_new("audiosink"); + osssink = gst_osssink_new("osssink"); gtk_signal_connect(GTK_OBJECT(disksrc),"eof", GTK_SIGNAL_FUNC(eof),NULL); @@ -51,20 +51,20 @@ int main(int argc,char *argv[]) { /* add objects to the main pipeline */ gst_bin_add(GST_BIN(bin),GST_OBJECT(disksrc)); gst_bin_add(GST_BIN(bin),GST_OBJECT(parse)); - gst_bin_add(GST_BIN(bin),GST_OBJECT(audiosink)); + gst_bin_add(GST_BIN(bin),GST_OBJECT(osssink)); /* connect src to sink */ gst_pad_connect(gst_element_get_pad(disksrc,"src"), gst_element_get_pad(parse,"sink")); gst_pad_connect(gst_element_get_pad(parse,"src"), - gst_element_get_pad(audiosink,"sink")); + gst_element_get_pad(osssink,"sink")); while(1) { g_print("\n"); gst_disksrc_push(GST_SRC(disksrc)); } - gst_object_destroy(GST_OBJECT(audiosink)); + gst_object_destroy(GST_OBJECT(osssink)); gst_object_destroy(GST_OBJECT(parse)); gst_object_destroy(GST_OBJECT(disksrc)); gst_object_destroy(GST_OBJECT(bin)); diff --git a/test/xml/readreg.c b/test/xml/readreg.c index 8db054b32e..300a07ce6c 100644 --- a/test/xml/readreg.c +++ b/test/xml/readreg.c @@ -2,6 +2,13 @@ #include #include +// Include compatability defines: if libxml hasn't already defined these, +// we have an old version 1.x +#ifndef xmlChildrenNode +#define xmlChildrenNode childs +#define xmlRootNode root +#endif + typedef struct _GstRegistryPlugin GstRegistryPlugin; typedef struct _GstRegistryElement GstRegistryElement; @@ -17,7 +24,7 @@ struct _GstRegistryElement { }; gchar *getcontents(xmlDocPtr doc,xmlNodePtr cur) { - return g_strdup(xmlNodeListGetString(doc,cur->childs,1)); + return g_strdup(xmlNodeListGetString(doc,cur->xmlChildrenNode,1)); } int main(int argc,char *argv[]) { @@ -51,10 +58,10 @@ int main(int argc,char *argv[]) { exit(1); } - cur = cur->childs; /* 'childs'??? He (Daniel) is Dutch, so... */ + cur = cur->xmlChildrenNode; while (cur != NULL) { if (!strcmp(cur->name,"plugin")) { - xmlNodePtr field = cur->childs; + xmlNodePtr field = cur->xmlChildrenNode; GstRegistryPlugin *plugin = g_new0(GstRegistryPlugin,1); while (field) { @@ -67,7 +74,7 @@ int main(int argc,char *argv[]) { g_print("new plugin '%s' at '%s'\n",plugin->name,plugin->filename); plugins = g_slist_prepend(plugins,plugin); } else if (!strcmp(cur->name,"element")) { - xmlNodePtr field = cur->childs; + xmlNodePtr field = cur->xmlChildrenNode; GstRegistryElement *element = g_new0(GstRegistryElement,1); while (field) { diff --git a/test/xmmstest.c b/test/xmmstest.c new file mode 100644 index 0000000000..59eb23d0ac --- /dev/null +++ b/test/xmmstest.c @@ -0,0 +1,67 @@ +#include +#include + +extern gboolean _gst_plugin_spew; + +gboolean idle_func(gpointer data); + +GstElement *src; + +int +main (int argc,char *argv[]) +{ + GstElement *bin; + GstElement *effect; + GstElement *osssink; + + gst_init(&argc,&argv); + + bin = gst_bin_new("bin"); + + src = gst_elementfactory_make("XMMS_INPUT_mpeg_layer_1/2/3_player_1.2.4", "xmms_plugin"); + //src = gst_elementfactory_make("XMMS_INPUT_oggvorbis_player_0.1", "xmms_plugin"); + //src = gst_elementfactory_make("XMMS_INPUT_mikmod_player_1.2.4", "xmms_plugin"); + //src = gst_elementfactory_make("XMMS_INPUT_tone_generator_1.2.4", "xmms_plugin"); + g_return_val_if_fail(src != NULL, -1); + + //effect = gst_elementfactory_make("XMMS_EFFECT_voice_removal_plugin_1.2.4", "xmms_effect"); + effect = gst_elementfactory_make("XMMS_EFFECT_extra_stereo_plugin_1.2.4", "xmms_effect"); + //effect = gst_elementfactory_make("XMMS_EFFECT_echo_plugin_1.2.4", "xmms_effect"); + g_return_val_if_fail(effect != NULL, -1); + + gtk_object_set (GTK_OBJECT (src), "location", argv[1], NULL); + //gtk_object_set (GTK_OBJECT (src), "filename", "tone://1000", NULL); + + g_print ("Song Info (text:length): %s\n",gst_util_get_string_arg (GTK_OBJECT (src), "song_info")); + //gtk_object_set (GTK_OBJECT (src), "show_about", TRUE, NULL); + //gtk_object_set (GTK_OBJECT (src), "configure", TRUE, NULL); + //gtk_object_set (GTK_OBJECT (src), "show_file_info", TRUE, NULL); + + osssink = gst_elementfactory_make("osssink", "osssink"); + g_return_val_if_fail(osssink != NULL, -1); + + gst_bin_add(GST_BIN(bin),GST_ELEMENT(src)); + gst_bin_add(GST_BIN(bin),GST_ELEMENT(effect)); + gst_bin_add(GST_BIN(bin),GST_ELEMENT(osssink)); + + gst_pad_connect(gst_element_get_pad(src,"src"), + gst_element_get_pad(effect,"sink")); + gst_pad_connect(gst_element_get_pad(effect,"src"), + gst_element_get_pad(osssink,"sink")); + + gst_element_set_state(GST_ELEMENT(bin),GST_STATE_PLAYING); + + g_idle_add(idle_func, bin); + + gtk_main(); + + return 0; +} + +gboolean +idle_func (gpointer data) +{ + gst_bin_iterate(GST_BIN(data)); + + return TRUE; +} diff --git a/tests/.gitignore b/tests/.gitignore index 8d0cd0b737..2c686c0470 100644 --- a/tests/.gitignore +++ b/tests/.gitignore @@ -6,7 +6,7 @@ Makefile.in .deps .libs *.xml - +*.gst init loadall simplefake @@ -24,3 +24,6 @@ markup load padfactory tee +autoplug2 +autoplug3 +capsconnect diff --git a/tests/Makefile.am b/tests/Makefile.am index cda97e2123..d1ee8d983a 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -1,8 +1,8 @@ SUBDIRS = sched eos noinst_PROGRAMS = init loadall simplefake states caps queue registry \ -paranoia rip mp3encode autoplug props case4 markup load tee incsched \ -reaping threadlock +paranoia rip mp3encode autoplug props case4 markup load tee autoplug2 autoplug3 \ +capsconnect incsched reaping threadlock mp1vid # we have nothing but apps here, we can do this safely LIBS += $(GST_LIBS) diff --git a/tests/autoplug.c b/tests/autoplug.c index f6dcb1be39..2898e64828 100644 --- a/tests/autoplug.c +++ b/tests/autoplug.c @@ -1,63 +1,45 @@ #include -static GList* -autoplug_caps (gchar *mime1, gchar *mime2) -{ - GstCaps *caps1, *caps2; - - caps1 = gst_caps_new ("tescaps1", mime1); - caps2 = gst_caps_new ("tescaps2", mime2); - - return gst_autoplug_caps (caps1, caps2); -} - static void -dump_factories (GList *factories) +new_object_added (GstAutoplug *autoplug, GstObject *object) { - g_print ("dumping factories\n"); - - while (factories) { - GstElementFactory *factory = (GstElementFactory *)factories->data; - - g_print ("factory: \"%s\"\n", factory->name); - - factories = g_list_next (factories); - } + g_print ("added new object \"%s\"\n", gst_object_get_name (object)); } -int main(int argc,char *argv[]) +int +main (int argc, char *argv[]) { - GList *factories; + GstElement *element; + GstElement *videosink, *osssink; + GstAutoplug *autoplugger; + GList *testcaps; gst_init(&argc,&argv); - factories = autoplug_caps ("audio/mp3", "audio/raw"); - dump_factories (factories); + osssink = gst_elementfactory_make ("osssink", "osssink"); + g_assert (osssink != NULL); + videosink = gst_elementfactory_make ("videosink", "videosink"); + g_assert (videosink != NULL); - factories = autoplug_caps ("video/mpeg", "audio/raw"); - dump_factories (factories); + testcaps = g_list_append (NULL, + gst_caps_new ("test_caps", + "video/mpeg", + gst_props_new ( + "mpegversion", GST_PROPS_INT (1), + "systemstream", GST_PROPS_BOOLEAN (TRUE), + NULL))); - factories = gst_autoplug_caps ( - gst_caps_new_with_props( - "testcaps3", - "video/mpeg", - gst_props_new ( - "mpegversion", GST_PROPS_INT (1), - "systemstream", GST_PROPS_BOOLEAN (TRUE), - NULL)), - gst_caps_new("testcaps4","audio/raw")); - dump_factories (factories); + autoplugger = gst_autoplugfactory_make ("static"); - factories = gst_autoplug_caps ( - gst_caps_new_with_props( - "testcaps5", - "video/mpeg", - gst_props_new ( - "mpegversion", GST_PROPS_INT (1), - "systemstream", GST_PROPS_BOOLEAN (FALSE), - NULL)), - gst_caps_new("testcaps6", "video/raw")); - dump_factories (factories); + gtk_signal_connect (GTK_OBJECT (autoplugger), "new_object", new_object_added, NULL); + + element = gst_autoplug_to_caps (autoplugger, testcaps, + gst_pad_get_caps (gst_element_get_pad (osssink, "sink")), + gst_pad_get_caps (gst_element_get_pad (videosink, "sink")), + NULL); + g_assert (element != NULL); + + xmlDocDump (stdout, gst_xml_write (element)); exit (0); } diff --git a/tests/autoplug2.c b/tests/autoplug2.c new file mode 100644 index 0000000000..8076fa2dea --- /dev/null +++ b/tests/autoplug2.c @@ -0,0 +1,78 @@ +#include + +static GstElement* +autoplug_caps (GstAutoplug *autoplug, gchar *mime1, gchar *mime2) +{ + GstCaps *caps1, *caps2; + + caps1 = gst_caps_new ("tescaps1", mime1, NULL); + caps2 = gst_caps_new ("tescaps2", mime2, NULL); + + return gst_autoplug_to_caps (autoplug, caps1, caps2, NULL); +} + +int +main (int argc, char *argv[]) +{ + GstElement *element; + GstAutoplug *autoplug; + + gst_init(&argc,&argv); + + autoplug = gst_autoplugfactory_make ("static"); + + element = autoplug_caps (autoplug, "audio/mp3", "audio/raw"); + xmlSaveFile ("autoplug2_1.gst", gst_xml_write (element)); + + element = autoplug_caps (autoplug, "video/mpeg", "audio/raw"); + xmlSaveFile ("autoplug2_2.gst", gst_xml_write (element)); + + element = gst_autoplug_to_caps (autoplug, + 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); + xmlSaveFile ("autoplug2_3.gst", gst_xml_write (element)); + + element = gst_autoplug_to_caps (autoplug, + 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); + xmlSaveFile ("autoplug2_4.gst", gst_xml_write (element)); + + element = gst_autoplug_to_caps (autoplug, + gst_caps_new( + "testcaps7", + "video/avi", NULL), + gst_caps_new("testcaps8", "video/raw", NULL), + gst_caps_new("testcaps9", "audio/raw", NULL), + NULL); + xmlSaveFile ("autoplug2_5.gst", gst_xml_write (element)); + + element = gst_autoplug_to_caps (autoplug, + 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); + xmlSaveFile ("autoplug2_6.gst", gst_xml_write (element)); + + exit (0); + exit (0); +} diff --git a/tests/autoplug3.c b/tests/autoplug3.c new file mode 100644 index 0000000000..34927edad2 --- /dev/null +++ b/tests/autoplug3.c @@ -0,0 +1,102 @@ +#include + +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); +} diff --git a/tests/caps.c b/tests/caps.c index df8147eeed..97dc963817 100644 --- a/tests/caps.c +++ b/tests/caps.c @@ -1,57 +1,110 @@ #include -static GstCapsFactory mpeg2dec_sink_caps = { - "mpeg2dec_sink", - "video/mpeg", - "mpegtype", GST_PROPS_LIST ( - GST_PROPS_INT(1), - GST_PROPS_INT(2) - ), - NULL -}; +static GstCaps* +mpeg2dec_sink_caps (void) +{ + return + gst_caps_new ( + "mpeg2dec_sink", + "video/mpeg", + gst_props_new ( + "mpegtype", GST_PROPS_LIST ( + GST_PROPS_INT(1), + GST_PROPS_INT(2) + ), + NULL + ) + ); +} -static GstCapsFactory mp1parse_src_caps = { - "mp1parse_src", - "video/mpeg", - "mpegtype", GST_PROPS_LIST ( - GST_PROPS_INT(1) - ), - NULL -}; +static GstCaps* +mp1parse_src_caps (void) +{ + return + gst_caps_new ( + "mp1parse_src", + "video/mpeg", + gst_props_new ( + "mpegtype", GST_PROPS_LIST ( + GST_PROPS_INT(1) + ), + NULL + ) + ); +} -static GstCapsFactory mpeg2dec_src_caps = { - "mpeg2dec_src", - "video/raw", - "fourcc", GST_PROPS_LIST ( - GST_PROPS_FOURCC ('Y','V','1','2'), - GST_PROPS_FOURCC_INT (0x56595559) +static GstCaps* +mpeg2dec_src_caps (void) +{ + return + gst_caps_new ( + "mpeg2dec_src", + "video/raw", + gst_props_new ( + "fourcc", GST_PROPS_LIST ( + GST_PROPS_FOURCC (GST_MAKE_FOURCC ('Y','V','1','2')), + GST_PROPS_FOURCC (GST_MAKE_FOURCC ('Y','U','Y','2')) ), - "width", GST_PROPS_INT_RANGE (16, 4096), - "height", GST_PROPS_INT_RANGE (16, 4096), - NULL -}; + "width", GST_PROPS_INT_RANGE (16, 4096), + "height", GST_PROPS_INT_RANGE (16, 4096), + NULL + ) + ); +} -static GstCapsFactory raw_sink_caps = { - "raw_sink_caps", - "video/raw", - "fourcc", GST_PROPS_LIST ( - GST_PROPS_FOURCC_INT (0x32315659) +static GstCaps* +raw_sink_caps (void) +{ + return + gst_caps_new ( + "raw_sink_caps", + "video/raw", + gst_props_new ( + "fourcc", GST_PROPS_LIST ( + GST_PROPS_FOURCC (GST_MAKE_FOURCC ('Y','V','1','2')) + ), + "height", GST_PROPS_INT_RANGE (16, 256), + NULL + ) + ); +} + +static GstCaps* +raw2_sink_caps (void) +{ + return + gst_caps_new ( + "raw2_sink_caps", + "video/raw", + gst_props_new ( + "fourcc", GST_PROPS_LIST ( + GST_PROPS_FOURCC (GST_MAKE_FOURCC ('Y','V','1','2')), + GST_PROPS_FOURCC (GST_MAKE_FOURCC ('Y','U','Y','2')) + ), + "height", GST_PROPS_INT_RANGE (16, 4096), + NULL + ) + ); +} + + +static GstCaps* +get_testcaps (void) +{ + return + gst_caps_new ( + "raw2_sink_caps", + "video/raw", + gst_props_new ( + "fourcc", GST_PROPS_LIST ( + GST_PROPS_FOURCC (GST_MAKE_FOURCC ('Y','V','1','2')), + GST_PROPS_FOURCC (GST_MAKE_FOURCC ('Y','U','Y','V')) ), - "height", GST_PROPS_INT_RANGE (16, 256), - NULL -}; - -static GstCapsFactory raw2_sink_caps = { - "raw2_sink_caps", - "video/raw", - "fourcc", GST_PROPS_LIST ( - GST_PROPS_FOURCC_INT (0x32315659), - GST_PROPS_FOURCC ('Y','U','Y','V') - ), - "height", GST_PROPS_INT_RANGE (16, 4096), - NULL -}; - + "height", GST_PROPS_INT_RANGE (16, 4096), + NULL + ) + ); +} static GstCaps *sinkcaps = NULL, *rawcaps = NULL, @@ -59,7 +112,8 @@ static GstCaps *sinkcaps = NULL, *rawcaps3 = NULL, *mp1parsecaps = NULL; -int main(int argc,char *argv[]) +int +main (int argc, char *argv[]) { gboolean testret; xmlDocPtr doc; @@ -68,25 +122,28 @@ int main(int argc,char *argv[]) doc = xmlNewDoc ("1.0"); doc->xmlRootNode = xmlNewDocNode (doc, NULL, "Capabilities", NULL); + g_thread_init (NULL); _gst_type_initialize (); + _gst_props_initialize (); + _gst_caps_initialize (); - 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 = mpeg2dec_src_caps (); parent = xmlNewChild (doc->xmlRootNode, NULL, "Capabilities2", NULL); gst_caps_save_thyself (rawcaps, parent); - rawcaps2 = gst_caps_register (&raw_sink_caps); + rawcaps2 = raw_sink_caps (); parent = xmlNewChild (doc->xmlRootNode, NULL, "Capabilities3", NULL); gst_caps_save_thyself (rawcaps2, parent); - mp1parsecaps = gst_caps_register (&mp1parse_src_caps); + mp1parsecaps = mp1parse_src_caps (); parent = xmlNewChild (doc->xmlRootNode, NULL, "Capabilities4", NULL); gst_caps_save_thyself (mp1parsecaps, parent); - rawcaps3 = gst_caps_register (&raw2_sink_caps); + rawcaps3 = raw2_sink_caps (); parent = xmlNewChild (doc->xmlRootNode, NULL, "Capabilities5", NULL); gst_caps_save_thyself (rawcaps3, parent); diff --git a/tests/capsconnect.c b/tests/capsconnect.c new file mode 100644 index 0000000000..01e8e7b9a5 --- /dev/null +++ b/tests/capsconnect.c @@ -0,0 +1,62 @@ +#include + +int main(int argc,char *argv[]) +{ + gboolean testret; + xmlDocPtr doc; + xmlNodePtr parent; + GstElement *mpg123; + GstElement *mp3parse; + GstElement *queue; + GstPad *sinkpad; + GstPad *srcpad; + GstPad *qsinkpad; + + doc = xmlNewDoc ("1.0"); + doc->xmlRootNode = xmlNewDocNode (doc, NULL, "Capabilities", NULL); + + gst_init (&argc, &argv); + + mpg123 = gst_elementfactory_make ("mpg123", "mpg123"); + g_assert (mpg123 != NULL); + + sinkpad = gst_element_get_pad (mpg123, "sink"); + g_assert (sinkpad != NULL); + + queue = gst_elementfactory_make ("queue", "queue"); + g_assert (queue != NULL); + + srcpad = gst_element_get_pad (queue, "src"); + g_assert (srcpad != NULL); + qsinkpad = gst_element_get_pad (queue, "sink"); + g_assert (qsinkpad != NULL); + + parent = xmlNewChild (doc->xmlRootNode, NULL, "mpg123 caps", NULL); + gst_caps_save_thyself (gst_pad_get_caps (sinkpad), parent); + + parent = xmlNewChild (doc->xmlRootNode, NULL, "queue caps", NULL); + gst_caps_save_thyself (gst_pad_get_caps (srcpad), parent); + + gst_pad_connect (srcpad, sinkpad); + + parent = xmlNewChild (doc->xmlRootNode, NULL, "queue caps after connect src", NULL); + gst_caps_save_thyself (gst_pad_get_caps (srcpad), parent); + + parent = xmlNewChild (doc->xmlRootNode, NULL, "queue caps after connect sink", NULL); + gst_caps_save_thyself (gst_pad_get_caps (qsinkpad), parent); + + mp3parse = gst_elementfactory_make ("mp3parse", "mp3parse"); + g_assert (mp3parse != NULL); + + gst_pad_connect (gst_element_get_pad (mp3parse, "src"), qsinkpad); + + parent = xmlNewChild (doc->xmlRootNode, NULL, "queue caps after connect sink", NULL); + gst_caps_save_thyself (gst_pad_get_caps (qsinkpad), parent); + + parent = xmlNewChild (doc->xmlRootNode, NULL, "mpg123 caps after connect sink", NULL); + gst_caps_save_thyself (gst_pad_get_caps (sinkpad), parent); + + xmlDocDump(stdout, doc); + + return 0; +} diff --git a/tests/nego/.gitignore b/tests/nego/.gitignore new file mode 100644 index 0000000000..3224b98fe1 --- /dev/null +++ b/tests/nego/.gitignore @@ -0,0 +1,9 @@ +Makefile +Makefile.in +*.o +*.lo +*.la +.deps +.libs +*.xml +nego1 diff --git a/tests/nego/Makefile.am b/tests/nego/Makefile.am new file mode 100644 index 0000000000..4260472389 --- /dev/null +++ b/tests/nego/Makefile.am @@ -0,0 +1,5 @@ +noinst_PROGRAMS = nego1 + +# jsut apps here, this is safe +LIBS += $(GST_LIBS) +CFLAGS += $(GST_CFLAGS) diff --git a/tests/nego/nego1.c b/tests/nego/nego1.c new file mode 100644 index 0000000000..23848bc87a --- /dev/null +++ b/tests/nego/nego1.c @@ -0,0 +1,59 @@ +#include + +/* this is an example of the src pad dictating the caps + * the sink pad only accepts audio/raw */ + +static GstCaps* +negotiate (GstPad *pad, GstCaps *caps, gint count) +{ + g_print ("negotiation entered\n"); + + if (!strcmp (gst_caps_get_mime (caps), "audio/raw")) + return caps; + + return NULL; +} + +int +main(int argc,char *argv[]) +{ + GstPad *srcpad, *sinkpad; + GstCaps *new; + + gst_init(&argc,&argv); + + srcpad = gst_pad_new ("src", GST_PAD_SRC); + sinkpad = gst_pad_new ("sink", GST_PAD_SINK); + + gst_pad_connect (srcpad, sinkpad); + + gst_pad_set_negotiate_function (sinkpad, negotiate); + + /* fill in our desired caps */ + new = gst_caps_new_with_props ( + "src_caps", /* name */ + "audio/raw", /* mime */ + gst_props_new ( + "format", GST_PROPS_INT (16), + "depth", GST_PROPS_INT (16), + "rate", GST_PROPS_INT (48000), + "channels", GST_PROPS_INT (2), + NULL + ) + ); + + gst_pad_set_caps (srcpad, new); + + new = gst_caps_new_with_props ( + "src_caps", /* name */ + "video/raw", /* mime */ + gst_props_new ( + "format", GST_PROPS_FOURCC ('Y','U','Y','V'), + NULL + ) + ); + + gst_pad_set_caps (srcpad, new); + + exit (0); +} diff --git a/tests/old/examples/Makefile.am b/tests/old/examples/Makefile.am index 1b5d86647b..17a14055c2 100644 --- a/tests/old/examples/Makefile.am +++ b/tests/old/examples/Makefile.am @@ -1,4 +1,4 @@ SUBDIRS = autoplug \ helloworld helloworld2 \ queue queue2 queue3 queue4 \ - launch thread xml plugins + launch thread xml plugins typefind diff --git a/tests/old/examples/autoplug/.gitignore b/tests/old/examples/autoplug/.gitignore index a2911a80f7..f76c31a123 100644 --- a/tests/old/examples/autoplug/.gitignore +++ b/tests/old/examples/autoplug/.gitignore @@ -1 +1,2 @@ autoplug +xmlTest.gst diff --git a/tests/old/examples/helloworld/helloworld.c b/tests/old/examples/helloworld/helloworld.c index eff130dd16..e01e1371d5 100644 --- a/tests/old/examples/helloworld/helloworld.c +++ b/tests/old/examples/helloworld/helloworld.c @@ -13,7 +13,7 @@ void eos(GstElement *element) int main(int argc,char *argv[]) { - GstElement *bin, *disksrc, *parse, *decoder, *audiosink; + GstElement *bin, *disksrc, *parse, *decoder, *downmix, *mulaw, *mulawdec, *osssink; gst_init(&argc,&argv); @@ -34,14 +34,20 @@ int main(int argc,char *argv[]) /* now it's time to get the parser */ parse = gst_elementfactory_make("mp3parse","parse"); decoder = gst_elementfactory_make("mpg123","decoder"); + downmix = gst_elementfactory_make("stereo2mono","stereo2mono"); + mulaw = gst_elementfactory_make("mulawencode","mulaw"); + mulawdec = gst_elementfactory_make("mulawdecode","mulawdec"); /* and an audio sink */ - audiosink = gst_elementfactory_make("audiosink", "play_audio"); + osssink = gst_elementfactory_make("osssink", "play_audio"); /* add objects to the main pipeline */ gst_bin_add(GST_BIN(bin), disksrc); gst_bin_add(GST_BIN(bin), parse); gst_bin_add(GST_BIN(bin), decoder); - gst_bin_add(GST_BIN(bin), audiosink); + gst_bin_add(GST_BIN(bin), downmix); + gst_bin_add(GST_BIN(bin), mulaw); + gst_bin_add(GST_BIN(bin), mulawdec); + gst_bin_add(GST_BIN(bin), osssink); /* connect src to sink */ gst_pad_connect(gst_element_get_pad(disksrc,"src"), @@ -49,10 +55,14 @@ int main(int argc,char *argv[]) gst_pad_connect(gst_element_get_pad(parse,"src"), gst_element_get_pad(decoder,"sink")); gst_pad_connect(gst_element_get_pad(decoder,"src"), - gst_element_get_pad(audiosink,"sink")); + gst_element_get_pad(downmix,"sink")); + gst_pad_connect(gst_element_get_pad(downmix,"src"), + gst_element_get_pad(mulaw,"sink")); + gst_pad_connect(gst_element_get_pad(mulaw,"src"), + gst_element_get_pad(mulawdec,"sink")); + gst_pad_connect(gst_element_get_pad(mulawdec,"src"), + gst_element_get_pad(osssink,"sink")); - /* make it ready */ - gst_element_set_state(bin, GST_STATE_READY); /* start playing */ gst_element_set_state(bin, GST_STATE_PLAYING); @@ -65,9 +75,12 @@ int main(int argc,char *argv[]) /* stop the bin */ gst_element_set_state(bin, GST_STATE_NULL); - gst_object_destroy(GST_OBJECT(audiosink)); + gst_object_destroy(GST_OBJECT(osssink)); gst_object_destroy(GST_OBJECT(parse)); gst_object_destroy(GST_OBJECT(decoder)); + gst_object_destroy(GST_OBJECT(downmix)); + gst_object_destroy(GST_OBJECT(mulaw)); + gst_object_destroy(GST_OBJECT(mulawdec)); gst_object_destroy(GST_OBJECT(disksrc)); gst_object_destroy(GST_OBJECT(bin)); diff --git a/tests/old/examples/helloworld2/helloworld2.c b/tests/old/examples/helloworld2/helloworld2.c index 64eed11d79..19e0b1e443 100644 --- a/tests/old/examples/helloworld2/helloworld2.c +++ b/tests/old/examples/helloworld2/helloworld2.c @@ -11,7 +11,7 @@ void eos(GstElement *element) int main(int argc,char *argv[]) { - GstElement *disksrc, *audiosink; + GstElement *disksrc, *osssink; GstElement *pipeline, *thread; gst_init(&argc,&argv); @@ -28,7 +28,6 @@ int main(int argc,char *argv[]) pipeline = gst_pipeline_new("pipeline"); g_assert(pipeline != NULL); - gst_bin_add(GST_BIN(thread), pipeline); /* create a disk reader */ disksrc = gst_elementfactory_make("disksrc", "disk_source"); @@ -38,20 +37,25 @@ int main(int argc,char *argv[]) GTK_SIGNAL_FUNC(eos),NULL); /* 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); /* add objects to the main pipeline */ + /* gst_pipeline_add_src(GST_PIPELINE(pipeline), disksrc); - gst_pipeline_add_sink(GST_PIPELINE(pipeline), audiosink); + gst_pipeline_add_sink(GST_PIPELINE(pipeline), osssink); if (!gst_pipeline_autoplug(GST_PIPELINE(pipeline))) { g_print("unable to handle stream\n"); exit(-1); } + */ + + // hmmmm hack? FIXME + GST_FLAG_UNSET (pipeline, GST_BIN_FLAG_MANAGER); + + gst_bin_add(GST_BIN(thread), pipeline); - /* make it ready */ - gst_element_set_state(GST_ELEMENT(thread), GST_STATE_READY); /* start playing */ gst_element_set_state(GST_ELEMENT(thread), GST_STATE_PLAYING); diff --git a/tests/old/examples/launch/mp3play b/tests/old/examples/launch/mp3play index b5fd5ac1ad..b09ccd3043 100755 --- a/tests/old/examples/launch/mp3play +++ b/tests/old/examples/launch/mp3play @@ -1,4 +1,4 @@ #! /bin/sh for loc in "$@"; do -gstreamer-launch disksrc "location=$loc" ! mp3parse ! mpg123 ! audiosink +../../tools/gstreamer-launch disksrc \""location=$loc"\" ! mp3parse ! mpg123 ! osssink done diff --git a/tests/old/examples/plugins/example.c b/tests/old/examples/plugins/example.c index b958272bb1..75e5c78ce6 100644 --- a/tests/old/examples/plugins/example.c +++ b/tests/old/examples/plugins/example.c @@ -17,67 +17,112 @@ * Boston, MA 02111-1307, USA. */ +/* First, include the header file for the plugin, to bring in the + * object definition and other useful things. + */ #include "example.h" -/* elementfactory information */ +/* The ElementDetails structure gives a human-readable description + * of the plugin, as well as author and version data. + */ static GstElementDetails example_details = { "An example plugin", - "Example", + "Example/FirstExample", "Shows the basic structure of a plugin", VERSION, "your name ", - "(C) 2000", + "(C) 2001", }; -/* Example signals and args */ +/* These are the signals that this element can fire. They are zero- + * based because the numbers themselves are private to the object. + * LAST_SIGNAL is used for initialization of the signal array. + */ enum { + ASDF, /* FILL ME */ LAST_SIGNAL }; +/* Arguments are identified the same way, but cannot be zero, so you + * must leave the ARG_0 entry in as a placeholder. + */ enum { ARG_0, - ARG_ACTIVE + ARG_ACTIVE, + /* FILL ME */ }; -static GstPadFactory sink_factory = { - "sink", /* the name of the pads */ - GST_PAD_FACTORY_SINK, /* type of the pad */ - GST_PAD_FACTORY_ALWAYS, /* ALWAYS/SOMETIMES */ - GST_PAD_FACTORY_CAPS( - "example_sink", /* the name of the caps */ - "unknown/unknown", /* the mime type of the caps */ - "something", GST_PROPS_INT (1), /* a property */ - "foo", GST_PROPS_BOOLEAN (TRUE) /* another property */ - ), - NULL -}; +/* The PadFactory structures describe what pads the element has or + * can have. They can be quite complex, but for this example plugin + * they are rather simple. + */ +static GstPadTemplate* +sink_factory (void) +{ + return + gst_padtemplate_new ( + "sink", /* The name of the pad */ + GST_PAD_SINK, /* Direction of the pad */ + GST_PAD_ALWAYS, /* The pad exists for every instance */ + gst_caps_new ( + "example_sink", /* The name of the caps */ + "unknown/unknown", /* The overall MIME/type */ + gst_props_new ( + "foo", GST_PROPS_INT (1), /* An integer property */ + "bar", GST_PROPS_BOOLEAN (TRUE), /* A boolean */ + "baz", GST_PROPS_LIST ( /* A list of values for */ + GST_PROPS_INT (1), + GST_PROPS_INT (3) + ), + NULL))); +} -static GstPadFactory src_factory = { - "src", - GST_PAD_FACTORY_SRC, - GST_PAD_FACTORY_ALWAYS, - GST_PAD_FACTORY_CAPS( - "example_src", - "unknown/unknown" - ), - NULL -}; +/* This factory is much simpler, and defines the source pad. */ +static GstPadTemplate* +src_factory (void) +{ + return + gst_padtemplate_new ( + "src", + GST_PAD_SRC, + GST_PAD_ALWAYS, + gst_caps_new ( + "example_src", + "unknown/unknown", + NULL)); +} -static void gst_example_class_init (GstExampleClass *klass); -static void gst_example_init (GstExample *example); +/* A number of functon prototypes are given so we can refer to them later. */ +static void gst_example_class_init (GstExampleClass *klass); +static void gst_example_init (GstExample *example); -static void gst_example_chain (GstPad *pad, GstBuffer *buf); +static void gst_example_chain (GstPad *pad, GstBuffer *buf); -static void gst_example_set_arg (GtkObject *object,GtkArg *arg,guint id); -static void gst_example_get_arg (GtkObject *object,GtkArg *arg,guint id); +static void gst_example_set_arg (GtkObject *object,GtkArg *arg,guint id); +static void gst_example_get_arg (GtkObject *object,GtkArg *arg,guint id); -GstPadTemplate *src_template, *sink_template; +/* These hold the constructed pad templates, which are created during + * plugin load, and used during element instantiation. + */ +static GstPadTemplate *src_template, *sink_template; +/* The parent class pointer needs to be kept around for some object + * operations. + */ static GstElementClass *parent_class = NULL; -//static guint gst_example_signals[LAST_SIGNAL] = { 0 }; +/* This array holds the ids of the signals registered for this object. + * The array indexes are based on the enum up above. + */ +static guint gst_example_signals[LAST_SIGNAL] = { 0 }; + +/* This function is used to register and subsequently return the type + * identifier for this object class. On first invocation, it will + * register the type, providing the name of the class, struct sizes, + * and pointers to the various functions that define the class. + */ GtkType gst_example_get_type(void) { @@ -90,8 +135,8 @@ gst_example_get_type(void) sizeof(GstExampleClass), (GtkClassInitFunc)gst_example_class_init, (GtkObjectInitFunc)gst_example_init, - (GtkArgSetFunc)gst_example_set_arg, - (GtkArgGetFunc)gst_example_get_arg, + (GtkArgSetFunc)NULL, /* These last three are depracated */ + (GtkArgGetFunc)NULL, (GtkClassInitFunc)NULL, }; example_type = gtk_type_unique(GST_TYPE_ELEMENT,&example_info); @@ -99,70 +144,166 @@ gst_example_get_type(void) return example_type; } +/* In order to create an instance of an object, the class must be + * initialized by this function. GtkObject will take care of running + * it, based on the pointer to the function provided above. + */ static void gst_example_class_init (GstExampleClass *klass) { + /* Class pointers are needed to supply pointers to the private + * implementations of parent class methods. + */ GtkObjectClass *gtkobject_class; GstElementClass *gstelement_class; + /* Since the example class contains the parent classes, you can simply + * cast the pointer to get access to the parent classes. + */ gtkobject_class = (GtkObjectClass*)klass; gstelement_class = (GstElementClass*)klass; + /* The parent class is needed for class method overrides. */ parent_class = gtk_type_class(GST_TYPE_ELEMENT); + /* Here we add an argument to the object. This argument is an integer, + * and can be both read and written. + */ gtk_object_add_arg_type("GstExample::active", GTK_TYPE_INT, GTK_ARG_READWRITE, ARG_ACTIVE); + /* Here we add a signal to the object. This is avery useless signal + * called asdf. The signal will also pass a pointer to the listeners + * which happens to be the example element itself */ + gst_example_signals[ASDF] = + gtk_signal_new("asdf", GTK_RUN_LAST, gtkobject_class->type, + GTK_SIGNAL_OFFSET (GstExampleClass, asdf), + gtk_marshal_NONE__POINTER, GTK_TYPE_NONE, 1, + GST_TYPE_EXAMPLE); + + gtk_object_class_add_signals (gtkobject_class, gst_example_signals, + LAST_SIGNAL); + + /* The last thing is to provide the functions that implement get and set + * of arguments. + */ gtkobject_class->set_arg = gst_example_set_arg; gtkobject_class->get_arg = gst_example_get_arg; } +/* This function is responsible for initializing a specific instance of + * the plugin. + */ static void gst_example_init(GstExample *example) { + /* First we create the sink pad, which is the input to the element. + * We will use the sink_template constructed in the plugin_init function + * (below) to quickly generate the pad we need. + */ example->sinkpad = gst_pad_new_from_template (sink_template, "sink"); - gst_element_add_pad(GST_ELEMENT(example),example->sinkpad); + /* Setting the chain function allows us to supply the function that will + * actually be performing the work. Without this, the element would do + * nothing, with undefined results (assertion failures and such). + */ gst_pad_set_chain_function(example->sinkpad,gst_example_chain); + /* We then must add this pad to the element's list of pads. The base + * element class manages the list of pads, and provides accessors to it. + */ + gst_element_add_pad(GST_ELEMENT(example),example->sinkpad); + /* The src pad, the output of the element, is created and registered + * in the same way, with the exception of the chain function. Source + * pads don't have chain functions, because they can't accept buffers, + * they only produce them. + */ example->srcpad = gst_pad_new_from_template (src_template, "src"); gst_element_add_pad(GST_ELEMENT(example),example->srcpad); + /* Initialization of element's private variables. */ example->active = FALSE; } +/* The chain function is the heart of the element. It's where all the + * work is done. It is passed a pointer to the pad in question, as well + * as the buffer provided by the peer element. + */ static void gst_example_chain (GstPad *pad, GstBuffer *buf) { GstExample *example; + GstBuffer *outbuf; + /* Some of these checks are of dubious value, since if there were not + * already true, the chain function would never be called. + */ g_return_if_fail(pad != NULL); g_return_if_fail(GST_IS_PAD(pad)); g_return_if_fail(buf != NULL); - //g_return_if_fail(GST_IS_BUFFER(buf)); + /* We need to get a pointer to the element this pad belogs to. */ example = GST_EXAMPLE(gst_pad_get_parent (pad)); + /* A few more sanity checks to make sure that the element that owns + * this pad is the right kind of element, in case something got confused. + */ g_return_if_fail(example != NULL); g_return_if_fail(GST_IS_EXAMPLE(example)); + /* If we are supposed to be doing something, here's where it happens. */ if (example->active) { - /* DO STUFF */ - } + /* In this example we're going to copy the buffer to another one, + * so we need to allocate a new buffer first. */ + outbuf = gst_buffer_new(); - gst_pad_push(example->srcpad,buf); + /* We need to copy the size and offset of the buffer at a minimum. */ + GST_BUFFER_SIZE (outbuf) = GST_BUFFER_SIZE (buf); + GST_BUFFER_OFFSET (outbuf) = GST_BUFFER_OFFSET (buf); + + /* Then allocate the memory for the new buffer */ + GST_BUFFER_DATA (outbuf) = (guchar *)g_malloc (GST_BUFFER_SIZE (outbuf)); + + /* Then copy the data in the incoming buffer into the new buffer. */ + memcpy (GST_BUFFER_DATA (outbuf), GST_BUFFER_DATA (buf), GST_BUFFER_SIZE (outbuf)); + + /* When we're done with the buffer, we push it on to the next element + * in the pipeline, through the element's source pad, which is stored + * in the element's structure. + */ + gst_pad_push(example->srcpad,outbuf); + + /* For fun we'll emit our useless signal here */ + gtk_signal_emit (GTK_OBJECT (example), gst_example_signals[ASDF], + example); + + /* If we're not doing something, just send the original incoming buffer. */ + } else { + gst_pad_push(example->srcpad,buf); + } } +/* Arguments are part of the Gtk+ object system, and these functions + * enable the element to respond to various arguments. + */ static void gst_example_set_arg (GtkObject *object,GtkArg *arg,guint id) { GstExample *example; - /* it's not null if we got it, but it might not be ours */ + /* It's not null if we got it, but it might not be ours */ g_return_if_fail(GST_IS_EXAMPLE(object)); + + /* Get a pointer of the right type. */ example = GST_EXAMPLE(object); - switch(id) { + /* Check the argument id to see which argument we're setting. */ + switch (id) { case ARG_ACTIVE: + /* Here we simply copy the value of the argument to our private + * storage. More complex operations can be done, but beware that + * they may occur at any time, possibly even while your chain function + * is running, if you are using threads. + */ example->active = GTK_VALUE_INT(*arg); g_print("example: set active to %d\n",example->active); break; @@ -171,12 +312,13 @@ gst_example_set_arg (GtkObject *object,GtkArg *arg,guint id) } } +/* The set function is simply the inverse of the get fuction. */ static void gst_example_get_arg (GtkObject *object,GtkArg *arg,guint id) { GstExample *example; - /* it's not null if we got it, but it might not be ours */ + /* It's not null if we got it, but it might not be ours */ g_return_if_fail(GST_IS_EXAMPLE(object)); example = GST_EXAMPLE(object); @@ -190,25 +332,45 @@ 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) { 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); - sink_template = gst_padtemplate_new (&sink_factory); + /* The pad templates can be easily generated from the factories above, + * and then added to the list of padtemplates for the elementfactory. + * Note that the generated padtemplates are stored in static global + * variables, for the gst_example_init function to use later on. + */ + sink_template = sink_factory (); gst_elementfactory_add_padtemplate (factory, sink_template); - src_template = gst_padtemplate_new (&src_factory); + src_template = src_factory (); gst_elementfactory_add_padtemplate (factory, src_template); + /* 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; + + /* At this point, the GStreamer core registers the plugin, its + * elementfactories, padtemplates, etc., for use in you application. + */ } diff --git a/tests/old/examples/plugins/example.h b/tests/old/examples/plugins/example.h index d7f19a3f99..840b8a3d18 100644 --- a/tests/old/examples/plugins/example.h +++ b/tests/old/examples/plugins/example.h @@ -28,36 +28,61 @@ extern "C" { #endif /* __cplusplus */ -/* Definition of structure storing data for this element. */ +/* This is the definition of the element's object structure. */ typedef struct _GstExample GstExample; +/* The structure itself is derived from GstElement, as can be seen by the + * fact that there's a complete instance of the GstElement structure at + * the beginning of the object. This allows the element to be cast to + * an Element or even an Object. + */ struct _GstExample { GstElement element; + /* We need to keep track of our pads, so we do so here. */ GstPad *sinkpad,*srcpad; - gint8 active; + /* We'll use this to decide whether to do anything to the data we get. */ + gboolean active; }; -/* Standard definition defining a class for this element. */ +/* The other half of the object is its class. The class also derives from + * the same parent, though it must be the class structure this time. + * Function pointers for polymophic methods and signals are placed in this + * structure. */ typedef struct _GstExampleClass GstExampleClass; + struct _GstExampleClass { GstElementClass parent_class; + + /* signals */ + void (*asdf) (GstElement *element, GstExample *example); }; -/* Standard macros for defining types for this element. */ +/* Five standard preprocessing macros are used in the Gtk+ object system. + * The first uses the object's _get_type function to return the GtkType + * of the object. + */ #define GST_TYPE_EXAMPLE \ (gst_example_get_type()) +/* The second is a checking cast to the correct type. If the object passed + * is not the right type, a warning will be generated on stderr. + */ #define GST_EXAMPLE(obj) \ (GTK_CHECK_CAST((obj),GST_TYPE_EXAMPLE,GstExample)) +/* The third is a checking cast of the class instead of the object. */ #define GST_EXAMPLE_CLASS(klass) \ (GTK_CHECK_CLASS_CAST((klass),GST_TYPE_EXAMPLE,GstExample)) +/* The last two simply check to see if the passed pointer is an object or + * class of the correct type. */ #define GST_IS_EXAMPLE(obj) \ (GTK_CHECK_TYPE((obj),GST_TYPE_EXAMPLE)) #define GST_IS_EXAMPLE_CLASS(obj) \ (GTK_CHECK_CLASS_TYPE((klass),GST_TYPE_EXAMPLE)) -/* Standard function returning type information. */ +/* This is the only prototype needed, because it is used in the above + * GST_TYPE_EXAMPLE macro. + */ GtkType gst_example_get_type(void); diff --git a/tests/old/examples/queue/queue.c b/tests/old/examples/queue/queue.c index 146c68912c..0d34a4bf96 100644 --- a/tests/old/examples/queue/queue.c +++ b/tests/old/examples/queue/queue.c @@ -1,19 +1,9 @@ #include #include -gboolean playing; - -/* eos will be called when the src element has an end of stream */ -void eos(GstElement *element, gpointer data) -{ - g_print("have eos, quitting\n"); - - playing = FALSE; -} - int main(int argc,char *argv[]) { - GstElement *disksrc, *audiosink, *parse, *decode, *queue; + GstElement *disksrc, *osssink, *parse, *decode, *queue; GstElement *bin; GstElement *thread; @@ -36,8 +26,6 @@ int main(int argc,char *argv[]) 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), thread); parse = gst_elementfactory_make("mp3parse", "parse"); decode = gst_elementfactory_make("mpg123", "decode"); @@ -45,8 +33,8 @@ int main(int argc,char *argv[]) queue = gst_elementfactory_make("queue", "queue"); /* 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); gst_bin_use_cothreads (GST_BIN (bin), TRUE); @@ -56,7 +44,7 @@ int main(int argc,char *argv[]) gst_bin_add(GST_BIN(bin), decode); gst_bin_add(GST_BIN(bin), queue); - gst_bin_add(GST_BIN(thread), audiosink); + gst_bin_add(GST_BIN(thread), osssink); gst_bin_add(GST_BIN(bin), thread); @@ -67,18 +55,12 @@ int main(int argc,char *argv[]) gst_pad_connect(gst_element_get_pad(decode,"src"), gst_element_get_pad(queue,"sink")); gst_pad_connect(gst_element_get_pad(queue,"src"), - gst_element_get_pad(audiosink,"sink")); + gst_element_get_pad(osssink,"sink")); - /* make it ready */ - gst_element_set_state(GST_ELEMENT(bin), GST_STATE_READY); /* start playing */ gst_element_set_state(GST_ELEMENT(bin), GST_STATE_PLAYING); - playing = TRUE; - - while (playing) { - gst_bin_iterate(GST_BIN(bin)); - } + while (gst_bin_iterate(GST_BIN(bin))); gst_element_set_state(GST_ELEMENT(bin), GST_STATE_NULL); diff --git a/tests/old/examples/queue2/queue2.c b/tests/old/examples/queue2/queue2.c index a3662b14e6..837732e4c9 100644 --- a/tests/old/examples/queue2/queue2.c +++ b/tests/old/examples/queue2/queue2.c @@ -13,7 +13,7 @@ void eos(GstElement *element, gpointer data) int main(int argc,char *argv[]) { - GstElement *disksrc, *audiosink, *queue; + GstElement *disksrc, *osssink, *queue; GstElement *pipeline; GstElement *thread; @@ -42,22 +42,24 @@ int main(int argc,char *argv[]) queue = gst_elementfactory_make("queue", "queue"); /* 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); /* add objects to the main pipeline */ + /* gst_pipeline_add_src(GST_PIPELINE(pipeline), disksrc); gst_pipeline_add_sink(GST_PIPELINE(pipeline), queue); - gst_bin_add(GST_BIN(thread), audiosink); - + gst_bin_add(GST_BIN(thread), osssink); + gst_pad_connect(gst_element_get_pad(queue,"src"), - gst_element_get_pad(audiosink,"sink")); + gst_element_get_pad(osssink,"sink")); if (!gst_pipeline_autoplug(GST_PIPELINE(pipeline))) { g_print("cannot autoplug pipeline\n"); exit(-1); } + */ gst_bin_add(GST_BIN(pipeline), thread); diff --git a/tests/old/examples/queue3/queue3.c b/tests/old/examples/queue3/queue3.c index 237b967dba..152cd1e30a 100644 --- a/tests/old/examples/queue3/queue3.c +++ b/tests/old/examples/queue3/queue3.c @@ -13,7 +13,7 @@ void eos(GstElement *element, gpointer data) int main(int argc,char *argv[]) { - GstElement *disksrc, *audiosink, *queue, *parse, *decode; + GstElement *disksrc, *osssink, *queue, *parse, *decode; GstElement *bin; GstElement *thread; @@ -42,8 +42,8 @@ int main(int argc,char *argv[]) queue = gst_elementfactory_make("queue", "queue"); /* 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); parse = gst_elementfactory_make("mp3parse", "parse"); decode = gst_elementfactory_make("mpg123", "decode"); @@ -54,7 +54,7 @@ int main(int argc,char *argv[]) gst_bin_add(GST_BIN(thread), parse); gst_bin_add(GST_BIN(thread), decode); - gst_bin_add(GST_BIN(thread), audiosink); + gst_bin_add(GST_BIN(thread), osssink); gst_pad_connect(gst_element_get_pad(disksrc,"src"), gst_element_get_pad(queue,"sink")); @@ -64,7 +64,7 @@ int main(int argc,char *argv[]) gst_pad_connect(gst_element_get_pad(parse,"src"), gst_element_get_pad(decode,"sink")); gst_pad_connect(gst_element_get_pad(decode,"src"), - gst_element_get_pad(audiosink,"sink")); + gst_element_get_pad(osssink,"sink")); gst_bin_add(GST_BIN(bin), thread); diff --git a/tests/old/examples/queue4/queue4.c b/tests/old/examples/queue4/queue4.c index a7e9d6d10d..cb984cc7bc 100644 --- a/tests/old/examples/queue4/queue4.c +++ b/tests/old/examples/queue4/queue4.c @@ -13,7 +13,7 @@ void eos(GstElement *element, gpointer data) int main(int argc,char *argv[]) { - GstElement *disksrc, *audiosink, *queue, *queue2, *parse, *decode; + GstElement *disksrc, *osssink, *queue, *queue2, *parse, *decode; GstElement *bin; GstElement *thread, *thread2; @@ -45,8 +45,8 @@ int main(int argc,char *argv[]) queue2 = gst_elementfactory_make("queue", "queue2"); /* 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); parse = gst_elementfactory_make("mp3parse", "parse"); decode = gst_elementfactory_make("mpg123", "decode"); @@ -59,7 +59,7 @@ int main(int argc,char *argv[]) gst_bin_add(GST_BIN(thread), decode); gst_bin_add(GST_BIN(thread), queue2); - gst_bin_add(GST_BIN(thread2), audiosink); + gst_bin_add(GST_BIN(thread2), osssink); gst_pad_connect(gst_element_get_pad(disksrc,"src"), gst_element_get_pad(queue,"sink")); @@ -72,7 +72,7 @@ int main(int argc,char *argv[]) gst_element_get_pad(queue2,"sink")); gst_pad_connect(gst_element_get_pad(queue2,"src"), - gst_element_get_pad(audiosink,"sink")); + gst_element_get_pad(osssink,"sink")); gst_bin_add(GST_BIN(bin), thread); gst_bin_add(GST_BIN(bin), thread2); diff --git a/tests/old/examples/thread/thread.c b/tests/old/examples/thread/thread.c index 533c38a6f7..5c691a0fa2 100644 --- a/tests/old/examples/thread/thread.c +++ b/tests/old/examples/thread/thread.c @@ -14,7 +14,7 @@ void eos(GstElement *element, gpointer data) int main(int argc,char *argv[]) { - GstElement *disksrc, *audiosink; + GstElement *disksrc, *osssink; GstElement *pipeline; GstElement *thread; @@ -41,17 +41,19 @@ int main(int argc,char *argv[]) GTK_SIGNAL_FUNC(eos), thread); /* 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); /* add objects to the main pipeline */ + /* gst_pipeline_add_src(GST_PIPELINE(pipeline), disksrc); - gst_pipeline_add_sink(GST_PIPELINE(pipeline), audiosink); + gst_pipeline_add_sink(GST_PIPELINE(pipeline), osssink); if (!gst_pipeline_autoplug(GST_PIPELINE(pipeline))) { g_print("unable to handle stream\n"); exit(-1); } + */ //gst_bin_remove(GST_BIN(pipeline), disksrc); diff --git a/tests/old/examples/typefind/.gitignore b/tests/old/examples/typefind/.gitignore new file mode 100644 index 0000000000..38bc2d7d1f --- /dev/null +++ b/tests/old/examples/typefind/.gitignore @@ -0,0 +1 @@ +typefind diff --git a/tests/old/examples/xml/createxml.c b/tests/old/examples/xml/createxml.c index 154f943b9f..ce8b395495 100644 --- a/tests/old/examples/xml/createxml.c +++ b/tests/old/examples/xml/createxml.c @@ -15,7 +15,7 @@ object_saved (GstObject *object, xmlNodePtr parent, gpointer data) int main(int argc,char *argv[]) { - GstElement *disksrc, *audiosink, *queue, *queue2, *parse, *decode; + GstElement *disksrc, *osssink, *queue, *queue2, *parse, *decode; GstElement *bin; GstElement *thread, *thread2; @@ -52,8 +52,8 @@ int main(int argc,char *argv[]) queue2 = gst_elementfactory_make("queue", "queue2"); /* 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); parse = gst_elementfactory_make("mp3parse", "parse"); decode = gst_elementfactory_make("mpg123", "decode"); @@ -66,7 +66,7 @@ int main(int argc,char *argv[]) gst_bin_add(GST_BIN(thread), decode); gst_bin_add(GST_BIN(thread), queue2); - gst_bin_add(GST_BIN(thread2), audiosink); + gst_bin_add(GST_BIN(thread2), osssink); gst_pad_connect(gst_element_get_pad(disksrc,"src"), gst_element_get_pad(queue,"sink")); @@ -79,7 +79,7 @@ int main(int argc,char *argv[]) gst_element_get_pad(queue2,"sink")); gst_pad_connect(gst_element_get_pad(queue2,"src"), - gst_element_get_pad(audiosink,"sink")); + gst_element_get_pad(osssink,"sink")); gst_bin_add(GST_BIN(bin), thread); gst_bin_add(GST_BIN(bin), thread2); diff --git a/tests/old/examples/xml/runxml.c b/tests/old/examples/xml/runxml.c index 5594ec86b8..400e82559b 100644 --- a/tests/old/examples/xml/runxml.c +++ b/tests/old/examples/xml/runxml.c @@ -35,8 +35,6 @@ int main(int argc,char *argv[]) xml = gst_xml_new (); - //g_print ("%p\n", xml); - gtk_signal_connect (GTK_OBJECT (xml), "object_loaded", xml_loaded, xml); ret = gst_xml_parse_file(xml, "xmlTest.gst", NULL); @@ -47,8 +45,6 @@ int main(int argc,char *argv[]) gst_element_set_state(bin, GST_STATE_PLAYING); - playing = TRUE; - while (gst_bin_iterate(GST_BIN(bin))); gst_element_set_state(bin, GST_STATE_NULL); diff --git a/tests/old/testsuite/Makefile.am b/tests/old/testsuite/Makefile.am new file mode 100644 index 0000000000..9e32fd0ae2 --- /dev/null +++ b/tests/old/testsuite/Makefile.am @@ -0,0 +1,11 @@ +SUBDIRS = + +testprogs = test_gst_init + +TESTS = $(testprogs) + +check_PROGRAMS = $(testprogs) + +# we have nothing but apps here, we can do this safely +LIBS += $(GST_LIBS) +CFLAGS += $(GST_CFLAGS) diff --git a/tests/old/testsuite/capsnego/.gitignore b/tests/old/testsuite/capsnego/.gitignore new file mode 100644 index 0000000000..9e3be9fc86 --- /dev/null +++ b/tests/old/testsuite/capsnego/.gitignore @@ -0,0 +1,11 @@ +Makefile +Makefile.in +*.o +*.lo +*.la +.deps +.libs +capsnego +converter +converter2 +enum diff --git a/tests/old/testsuite/capsnego/Makefile.am b/tests/old/testsuite/capsnego/Makefile.am new file mode 100644 index 0000000000..c2ac4395e7 --- /dev/null +++ b/tests/old/testsuite/capsnego/Makefile.am @@ -0,0 +1,11 @@ +SUBDIRS = + +testprogs = capsnego converter converter2 enum + +TESTS = $(testprogs) + +check_PROGRAMS = $(testprogs) + +# we have nothing but apps here, we can do this safely +LIBS += $(GST_LIBS) +CFLAGS += $(GST_CFLAGS) diff --git a/tests/old/testsuite/capsnego/capsnego.c b/tests/old/testsuite/capsnego/capsnego.c new file mode 100644 index 0000000000..0866491118 --- /dev/null +++ b/tests/old/testsuite/capsnego/capsnego.c @@ -0,0 +1,143 @@ + +#include + +GstPad *srcpad, *sinkpad; +GstPad *srcpadtempl, *sinkpadtempl; + +static GstPadFactory src_factory = { + "src", + GST_PAD_FACTORY_SRC, + GST_PAD_FACTORY_ALWAYS, + GST_PAD_FACTORY_CAPS( + "test_src", + "video/raw", + "height", GST_PROPS_INT_RANGE (16, 4096) + ), + NULL, +}; + +static GstPadFactory sink_factory = { + "sink", + GST_PAD_FACTORY_SINK, + GST_PAD_FACTORY_ALWAYS, + GST_PAD_FACTORY_CAPS( + "test_sink", + "video/raw", + "height", GST_PROPS_INT_RANGE (16, 8192) + ), + NULL, +}; + +static GstCapsFactory sink_caps = { + "sink_caps", + "video/raw", + "height", GST_PROPS_INT (3000), + NULL +}; + +static GstCapsFactory src_caps = { + "src_caps", + "video/raw", + "height", GST_PROPS_INT (3000), + NULL +}; + +static GstPadTemplate *srctempl, *sinktempl; +static GstCaps *srccaps, *sinkcaps; + +static GstPadNegotiateReturn +negotiate_src (GstPad *pad, GstCaps **caps, gint counter) +{ + g_print (">"); + + if (counter == 0) { + *caps = NULL; + return GST_PAD_NEGOTIATE_TRY; + } + if (*caps) + return GST_PAD_NEGOTIATE_AGREE; + + return GST_PAD_NEGOTIATE_FAIL; +} + +static GstPadNegotiateReturn +negotiate_sink (GstPad *pad, GstCaps **caps, gint counter) +{ + g_print ("<"); + if (counter == 0) { + *caps = NULL; + return GST_PAD_NEGOTIATE_TRY; + } + if (*caps) + return GST_PAD_NEGOTIATE_AGREE; + + return GST_PAD_NEGOTIATE_FAIL; +} + +static gboolean +perform_check (void) +{ + gboolean result, overall = TRUE; + + gint i, j; + + g_print ("ABC: A=pad caps, B=pad template, C=negotiate function\n"); + + for (j=0; j<8; j++) { + GstPad *srctest, *sinktest; + + for (i=0; i<8; i++) { + + (j & 0x2 ? (sinktest = sinkpadtempl) : (sinktest = sinkpad)); + (j & 0x4 ? (gst_pad_set_caps (sinktest, sinkcaps)) : (gst_pad_set_caps (sinktest, NULL))); + (j & 0x1 ? (gst_pad_set_negotiate_function (sinktest, negotiate_sink)) : + gst_pad_set_negotiate_function (sinktest, NULL)); + + (i & 0x2 ? (srctest = srcpadtempl) : (srctest = srcpad)); + (i & 0x4 ? (gst_pad_set_caps (srctest, srccaps)) : (gst_pad_set_caps (srctest, NULL))); + (i & 0x1 ? (gst_pad_set_negotiate_function (srctest, negotiate_src)) : + gst_pad_set_negotiate_function (srctest, NULL)); + + + g_print ("%d%d%d -> %d%d%d ..", (i&4)>>2, (i&2)>>1, i&1, (j&4)>>2, (j&2)>>1, j&1); + result = gst_pad_connect (srctest, sinktest); + + g_print (".. %s\n", (result? "ok":"fail")); + if (result) gst_pad_disconnect (srctest, sinktest); + + overall &= result; + } + } + return overall; +} + +int +main (int argc, char *argv[]) +{ + gboolean overall = TRUE; + + gst_init (&argc, &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); + + srcpadtempl = gst_pad_new_from_template (srctempl, "src"); + sinkpadtempl = gst_pad_new_from_template (sinktempl, "sink"); + + sinkcaps = gst_caps_register (&sink_caps); + srccaps = gst_caps_register (&src_caps); + + g_print ("*** compatible caps/templates ***\n"); + + overall &= perform_check (); + + gst_caps_set (srccaps, "height", GST_PROPS_INT (9000)); + + g_print ("*** incompatible caps ***\n"); + overall &= perform_check (); + + exit (!overall); +} diff --git a/tests/old/testsuite/capsnego/converter.c b/tests/old/testsuite/capsnego/converter.c new file mode 100644 index 0000000000..df26338d1f --- /dev/null +++ b/tests/old/testsuite/capsnego/converter.c @@ -0,0 +1,168 @@ + +#include + +GstPad *srcpad, *sinkpad; +GstPad *srcconvpad, *sinkconvpad; +GstPad *srcpadtempl, *sinkpadtempl; +GstPad *srcconvtempl, *sinkconvtempl; + +gint converter_in = -1, converter_out = -1; + +static GstPadFactory src_factory = { + "src", + GST_PAD_FACTORY_SRC, + GST_PAD_FACTORY_ALWAYS, + GST_PAD_FACTORY_CAPS( + "test_src", + "audio/raw", + "rate", GST_PROPS_INT_RANGE (16, 20000) + ), + NULL, +}; + +static GstPadFactory src_conv_factory = { + "src", + GST_PAD_FACTORY_SRC, + GST_PAD_FACTORY_ALWAYS, + GST_PAD_FACTORY_CAPS( + "test_src", + "audio/raw", + "rate", GST_PROPS_INT_RANGE (16, 20000) + ), + NULL, +}; + +static GstPadFactory sink_conv_factory = { + "src", + GST_PAD_FACTORY_SINK, + GST_PAD_FACTORY_ALWAYS, + GST_PAD_FACTORY_CAPS( + "test_src", + "audio/raw", + "rate", GST_PROPS_INT_RANGE (16, 20000) + ), + NULL, +}; + +static GstPadFactory sink_factory = { + "sink", + GST_PAD_FACTORY_SINK, + GST_PAD_FACTORY_ALWAYS, + GST_PAD_FACTORY_CAPS( + "test_sink", + "audio/raw", + "rate", GST_PROPS_INT_RANGE (16, 20000) + ), + NULL, +}; + +static GstCapsFactory sink_caps = { + "sink_caps", + "audio/raw", + "rate", GST_PROPS_INT (6000), + NULL +}; + +static GstCapsFactory src_caps = { + "src_caps", + "audio/raw", + "rate", GST_PROPS_INT (3000), + NULL +}; + +static GstPadTemplate *srctempl, *sinktempl; +static GstCaps *srccaps, *sinkcaps; + +static GstPadNegotiateReturn +negotiate_src (GstPad *pad, GstCaps **caps, gint counter) +{ + g_print (">"); + + if (counter == 0) { + *caps = NULL; + return GST_PAD_NEGOTIATE_TRY; + } + if (*caps) { + converter_out = gst_caps_get_int (*caps, "rate"); + return GST_PAD_NEGOTIATE_AGREE; + } + + return GST_PAD_NEGOTIATE_FAIL; +} + +static GstPadNegotiateReturn +negotiate_sink (GstPad *pad, GstCaps **caps, gint counter) +{ + g_print ("<"); + if (counter == 0) { + *caps = NULL; + return GST_PAD_NEGOTIATE_TRY; + } + if (*caps) { + converter_in = gst_caps_get_int (*caps, "rate"); + return GST_PAD_NEGOTIATE_AGREE; + } + + return GST_PAD_NEGOTIATE_FAIL; +} + +int +main (int argc, char *argv[]) +{ + gboolean overall = TRUE; + gboolean result; + + gst_init (&argc, &argv); + + srctempl = gst_padtemplate_new (&src_factory); + sinktempl = gst_padtemplate_new (&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); + 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); + 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); + + result = gst_pad_connect (srcpad, sinkconvpad); + g_print ("pad connect 1: %d\n", result); + overall &= (result == TRUE); + result = gst_pad_connect (srcconvpad, sinkpad); + g_print ("pad connect 2: %d\n", result); + overall &= (result == TRUE); + + g_print ("after connect, converter status: %d %d\n", converter_in, converter_out); + + result = gst_pad_set_caps (srcpad, srccaps); + g_print ("src pad set caps %d, converter status: %d %d\n", result, converter_in, converter_out); + + result = gst_pad_set_caps (sinkpad, sinkcaps); + g_print ("sink pad set caps %d, converter status: %d %d\n", result, converter_in, converter_out); + + gst_caps_set (srccaps, "rate", GST_PROPS_INT (4000)); + result = gst_pad_renegotiate (srcpad); + g_print ("sink pad renegotiate caps %d, converter status: %d %d\n", result, converter_in, converter_out); + + gst_caps_set (srccaps, "rate", GST_PROPS_INT (40000)); + result = gst_pad_set_caps (srcpad, srccaps); + g_print ("sink pad set caps %d, converter status: %d %d\n", result, converter_in, converter_out); + + gst_caps_set (sinkcaps, "rate", GST_PROPS_INT (40000)); + result = gst_pad_set_caps (sinkpad, sinkcaps); + g_print ("sink pad set caps %d, converter status: %d %d\n", result, converter_in, converter_out); + + gst_caps_set (sinkcaps, "rate", GST_PROPS_INT (9000)); + result = gst_pad_set_caps (sinkpad, sinkcaps); + g_print ("sink pad set caps %d, converter status: %d %d\n", result, converter_in, converter_out); + + exit (!overall); +} diff --git a/tests/old/testsuite/capsnego/converter2.c b/tests/old/testsuite/capsnego/converter2.c new file mode 100644 index 0000000000..0532c76956 --- /dev/null +++ b/tests/old/testsuite/capsnego/converter2.c @@ -0,0 +1,224 @@ + +#include + +GstPad *srcpad, *sinkpad; +GstPad *srcconvpad, *sinkconvpad; +GstPad *srcpadtempl, *sinkpadtempl; +GstPad *srcconvtempl, *sinkconvtempl; + +gint converter_in = -1, converter_out = -1; +gint target_rate = 2000; + +static GstPadFactory src_factory = { + "src", + GST_PAD_FACTORY_SRC, + GST_PAD_FACTORY_ALWAYS, + GST_PAD_FACTORY_CAPS( + "test_src", + "audio/raw", + "rate", GST_PROPS_INT_RANGE (16, 20000) + ), + NULL, +}; + +static GstPadFactory src_conv_factory = { + "src", + GST_PAD_FACTORY_SRC, + GST_PAD_FACTORY_ALWAYS, + GST_PAD_FACTORY_CAPS( + "test_src", + "audio/raw", + "rate", GST_PROPS_INT_RANGE (16, 20000) + ), + NULL, +}; + +static GstPadFactory sink_conv_factory = { + "src", + GST_PAD_FACTORY_SINK, + GST_PAD_FACTORY_ALWAYS, + GST_PAD_FACTORY_CAPS( + "test_src", + "audio/raw", + "rate", GST_PROPS_INT_RANGE (16, 20000) + ), + NULL, +}; + +static GstPadFactory sink_factory = { + "sink", + GST_PAD_FACTORY_SINK, + GST_PAD_FACTORY_ALWAYS, + GST_PAD_FACTORY_CAPS( + "test_sink", + "audio/raw", + "rate", GST_PROPS_INT_RANGE (16, 20000) + ), + NULL, +}; + +static GstCapsFactory sink_caps = { + "sink_caps", + "audio/raw", + "rate", GST_PROPS_INT (6000), + NULL +}; + +static GstCapsFactory src_caps = { + "src_caps", + "audio/raw", + "rate", GST_PROPS_INT (3000), + NULL +}; + +static GstPadTemplate *srctempl, *sinktempl; +static GstCaps *srccaps, *sinkcaps; + +static GstPadNegotiateReturn +converter_negotiate_src (GstPad *pad, GstCaps **caps, gint counter) +{ + g_print (">"); + + if (counter == 0) { + *caps = NULL; + return GST_PAD_NEGOTIATE_TRY; + } + if (*caps) { + converter_out = gst_caps_get_int (*caps, "rate"); + return GST_PAD_NEGOTIATE_AGREE; + } + + return GST_PAD_NEGOTIATE_FAIL; +} + +static GstPadNegotiateReturn +converter_negotiate_sink (GstPad *pad, GstCaps **caps, gint counter) +{ + g_print ("<"); + if (counter == 0) { + *caps = GST_PAD_CAPS (srcconvpad); + return GST_PAD_NEGOTIATE_TRY; + } + if (*caps) { + converter_in = gst_caps_get_int (*caps, "rate"); + + if (counter == 1) { + converter_out = gst_caps_get_int (*caps, "rate"); + return gst_pad_negotiate_proxy (pad, srcconvpad, caps, counter); + } + return GST_PAD_NEGOTIATE_AGREE; + } + + return GST_PAD_NEGOTIATE_FAIL; +} + +static GstPadNegotiateReturn +target_negotiate_sink (GstPad *pad, GstCaps **caps, gint counter) +{ + g_print ("{"); + if (counter == 0) { + *caps = gst_caps_new_with_props ( + "target_caps", + "audio/raw", + gst_props_new ( + "rate", GST_PROPS_INT (target_rate), + NULL) + ); + return GST_PAD_NEGOTIATE_TRY; + } + if (*caps) { + target_rate = gst_caps_get_int (*caps, "rate"); + g_print ("target set %d\n", target_rate); + return GST_PAD_NEGOTIATE_AGREE; + } + + return GST_PAD_NEGOTIATE_FAIL; +} + +int +main (int argc, char *argv[]) +{ + gboolean overall = TRUE; + gboolean result; + + gst_init (&argc, &argv); + + srctempl = gst_padtemplate_new (&src_factory); + sinktempl = gst_padtemplate_new (&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); + srcconvpad = gst_pad_new_from_template (srcconvtempl, "csrc"); + sinkconvpad = gst_pad_new_from_template (sinkconvtempl, "csink"); + + gst_pad_set_negotiate_function (srcconvpad, converter_negotiate_src); + 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); + + g_print ("-------) (-----------) (----- \n"); + g_print (" ! ! converter ! ! \n"); + g_print (" src -- csink csrc -- sink \n"); + g_print ("-------) (-----------) (----- \n\n"); + g_print ("The convertor first tries to proxy the caps received\n"); + g_print ("on its csink pad to its csrc pad, when that fails, it\n"); + g_print ("sets up the conversion.\n\n"); + + + g_print ("sink pad set caps (rate=%d), converter status: %d %d\n", target_rate, + converter_in, converter_out); + gst_caps_set (sinkcaps, "rate", GST_PROPS_INT (target_rate)); + result = gst_pad_set_caps (sinkpad, sinkcaps); + g_print ("result: %d, converter status: %d %d, target: %d\n\n", result, + converter_in, converter_out, target_rate); + + result = gst_pad_connect (srcpad, sinkconvpad); + g_print ("pad connect 1: %d\n", result); + overall &= (result == TRUE); + result = gst_pad_connect (srcconvpad, sinkpad); + g_print ("pad connect 2: %d\n", result); + overall &= (result == TRUE); + + g_print ("after connect, converter status: %d %d, target %d\n\n", converter_in, converter_out, target_rate); + + g_print ("src pad set caps (rate=%d), converter status: %d %d, target %d \n", gst_caps_get_int (srccaps, "rate"), + converter_in, converter_out, target_rate); + result = gst_pad_set_caps (srcpad, srccaps); + g_print ("result %d, converter status: %d %d, target %d\n\n", result, + converter_in, converter_out, target_rate); + + g_print ("sink pad set caps (rate=2000), converter status: %d %d, target %d \n", + converter_in, converter_out, target_rate); + target_rate = 2000; + gst_caps_set (sinkcaps, "rate", GST_PROPS_INT (target_rate)); + result = gst_pad_set_caps (sinkpad, sinkcaps); + g_print ("result %d, converter status: %d %d, target: %d\n\n", result, + converter_in, converter_out, target_rate); + + gst_caps_set (srccaps, "rate", GST_PROPS_INT (4000)); + result = gst_pad_renegotiate (srcpad); + g_print ("sink pad renegotiate caps %d, converter status: %d %d, target: %d\n", result, + converter_in, converter_out, target_rate); + + gst_caps_set (srccaps, "rate", GST_PROPS_INT (40000)); + result = gst_pad_set_caps (srcpad, srccaps); + g_print ("sink pad set caps %d, converter status: %d %d, target: %d\n", result, + converter_in, converter_out, target_rate); + + gst_caps_set (sinkcaps, "rate", GST_PROPS_INT (40000)); + result = gst_pad_set_caps (sinkpad, sinkcaps); + g_print ("sink pad set caps %d, converter status: %d %d, target: %d\n", result, + converter_in, converter_out, target_rate); + + target_rate = 9000; + gst_caps_set (sinkcaps, "rate", GST_PROPS_INT (target_rate)); + result = gst_pad_set_caps (sinkpad, sinkcaps); + g_print ("sink pad set caps %d, converter status: %d %d, target: %d\n", result, + converter_in, converter_out, target_rate); + + exit (!overall); +} diff --git a/tests/old/testsuite/capsnego/enum.c b/tests/old/testsuite/capsnego/enum.c new file mode 100644 index 0000000000..e3959309e9 --- /dev/null +++ b/tests/old/testsuite/capsnego/enum.c @@ -0,0 +1,227 @@ + +#include + +GstPad *srcconvpad, *sinkconvpad; +GstPadTemplate *srcconvtempl, *sinkconvtempl; + +static GstPadFactory src_conv_factory = { + "src", + GST_PAD_FACTORY_SRC, + GST_PAD_FACTORY_ALWAYS, + GST_PAD_FACTORY_CAPS( + "test_src", + "audio/raw", + "rate", GST_PROPS_INT_RANGE (16, 20000) + ), + NULL, +}; + +static GstPadFactory sink_conv_factory = { + "src", + GST_PAD_FACTORY_SINK, + GST_PAD_FACTORY_ALWAYS, + GST_PAD_FACTORY_CAPS( + "test_src", + "audio/raw", + "rate", GST_PROPS_INT_RANGE (16, 20000) + ), + NULL, +}; + +static GstCapsFactory src_caps = { + "src_caps", + "audio/raw", + "rate", GST_PROPS_INT (3000), + NULL +}; + +static GstCaps *srccaps, *sinkcaps; + +static gint src_rate = 140; +static gint sink_rate = 100; + +static GstPadNegotiateReturn +negotiate_src (GstPad *pad, GstCaps **caps, gint counter) +{ + g_print (">(%d:%d)", src_rate, (*caps)->refcount); + src_rate++; + + if (counter == 0 || caps == NULL) { + g_print ("*"); + *caps = gst_caps_new_with_props ( + "src_caps", + "audio/raw", + gst_props_new ( + "rate", GST_PROPS_INT (src_rate), + NULL) + ); + return GST_PAD_NEGOTIATE_TRY; + } + if (*caps) { + gint in_rate = gst_caps_get_int (*caps, "rate"); + g_print ("(%d)", in_rate); + + if (in_rate > 140 && in_rate < 300) { + g_print ("A"); + return GST_PAD_NEGOTIATE_AGREE; + } + + *caps = gst_caps_copy_on_write (*caps); + gst_caps_set (*caps, "rate", GST_PROPS_INT (src_rate)); + g_print ("T"); + return GST_PAD_NEGOTIATE_TRY; + } + + g_print ("F"); + return GST_PAD_NEGOTIATE_FAIL; +} + +static GstPadNegotiateReturn +negotiate_sink (GstPad *pad, GstCaps **caps, gint counter) +{ + + g_print ("<(%d:%d:%p)", sink_rate, (*caps)->refcount, *caps); + sink_rate++; + + if (counter == 0 || *caps == NULL) { + g_print ("*"); + *caps = gst_caps_new_with_props ( + "sink_caps", + "audio/raw", + gst_props_new ( + "rate", GST_PROPS_INT (sink_rate), + NULL) + ); + return GST_PAD_NEGOTIATE_TRY; + } + if (*caps) { + gint in_rate = gst_caps_get_int (*caps, "rate"); + g_print ("(%d)", in_rate); + + if (in_rate >= 100 && in_rate < 140) { + g_print ("A"); + return GST_PAD_NEGOTIATE_AGREE; + } + + *caps = gst_caps_copy_on_write (*caps); + g_print ("%p", *caps); + gst_caps_set (*caps, "rate", GST_PROPS_INT (sink_rate)); + + g_print ("T"); + return GST_PAD_NEGOTIATE_TRY; + } + + g_print ("F"); + return GST_PAD_NEGOTIATE_FAIL; +} + +int +main (int argc, char *argv[]) +{ + gboolean overall = TRUE; + gboolean result; + GstElement *queue; + + gst_init (&argc, &argv); + + g_mem_chunk_info(); + + srcconvtempl = gst_padtemplate_new (&src_conv_factory); + sinkconvtempl = gst_padtemplate_new (&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); + sinkcaps = gst_caps_copy (srccaps); + + g_print ("The wild goose chase...\n"); + + result = gst_pad_connect (srcconvpad, sinkconvpad); + g_print ("pad connect 1: %d\n", result); + overall &= (result == TRUE); + + result = gst_pad_set_caps (srcconvpad, srccaps); + g_print ("\nset caps on src: %d, final rate: %d\n", result, + gst_caps_get_int (gst_pad_get_caps (srcconvpad), "rate")); + + g_print ("with the src negotiate function disabled...\n"); + + GST_PAD_CAPS (srcconvpad) = NULL; + GST_PAD_CAPS (sinkconvpad) = NULL; + src_rate = 140; + sink_rate = 100; + + gst_pad_set_negotiate_function (srcconvpad, NULL); + + gst_caps_set (srccaps, "rate", GST_PROPS_INT (120)); + result = gst_pad_set_caps (srcconvpad, srccaps); + g_print ("\nset caps on src: %d, final rate: %d\n", result, + gst_caps_get_int (gst_pad_get_caps (srcconvpad), "rate")); + + + g_print ("with the sink negotiate function disabled...\n"); + + GST_PAD_CAPS (srcconvpad) = NULL; + GST_PAD_CAPS (sinkconvpad) = NULL; + src_rate = 140; + sink_rate = 100; + + gst_pad_set_negotiate_function (srcconvpad, negotiate_src); + gst_pad_set_negotiate_function (sinkconvpad, NULL); + + gst_caps_set (sinkcaps, "rate", GST_PROPS_INT (170)); + result = gst_pad_set_caps (sinkconvpad, sinkcaps); + g_print ("\nset caps on src: %d, final rate: %d\n", result, + gst_caps_get_int (gst_pad_get_caps (srcconvpad), "rate")); + + g_print ("without negotiate functions...\n"); + + GST_PAD_CAPS (srcconvpad) = NULL; + GST_PAD_CAPS (sinkconvpad) = NULL; + src_rate = 140; + sink_rate = 100; + + gst_pad_set_negotiate_function (srcconvpad, NULL); + gst_pad_set_negotiate_function (sinkconvpad, NULL); + + sinkcaps = gst_caps_copy (sinkcaps); + gst_caps_set (sinkcaps, "rate", GST_PROPS_INT (150)); + result = gst_pad_set_caps (sinkconvpad, sinkcaps); + g_print ("\nset caps on src: %d, final rate: %d\n", result, + gst_caps_get_int (gst_pad_get_caps (srcconvpad), "rate")); + + + sinkcaps = gst_caps_copy (sinkcaps); + gst_caps_set (sinkcaps, "rate", GST_PROPS_INT (160)); + result = gst_pad_set_caps (sinkconvpad, sinkcaps); + g_print ("\nset caps on src: %d, final rate: %d\n", result, + gst_caps_get_int (gst_pad_get_caps (srcconvpad), "rate")); + + g_print ("with a proxy element in between...\n"); + + gst_pad_disconnect (srcconvpad, sinkconvpad); + + queue = gst_elementfactory_make ("queue", "queue"); + + GST_PAD_CAPS (srcconvpad) = NULL; + GST_PAD_CAPS (sinkconvpad) = NULL; + src_rate = 140; + sink_rate = 100; + + gst_pad_set_negotiate_function (srcconvpad, negotiate_src); + gst_pad_set_negotiate_function (sinkconvpad, negotiate_sink); + + gst_pad_connect (srcconvpad, gst_element_get_pad (queue, "sink")); + gst_pad_connect (gst_element_get_pad (queue, "src"), sinkconvpad); + + gst_caps_set (srccaps, "rate", GST_PROPS_INT (50)); + result = gst_pad_set_caps (srcconvpad, srccaps); + g_print ("\nset caps on src: %d, final rate: %d\n", result, + gst_caps_get_int (gst_pad_get_caps (srcconvpad), "rate")); + + + exit (!overall); +} diff --git a/tests/old/testsuite/test_gst_init.c b/tests/old/testsuite/test_gst_init.c new file mode 100644 index 0000000000..1749328509 --- /dev/null +++ b/tests/old/testsuite/test_gst_init.c @@ -0,0 +1,13 @@ +#include + +/* This tests that gst_init() doesn't segfault when passed two NULLs as + * parameters, and that it doesn't fail if gst_init() happens to get called + * a second time. */ +int +main (int argc, char *argv[]) +{ + gst_init(NULL, NULL); + gst_init(&argc, &argv); + + return 0; +} diff --git a/tests/paranoia.c b/tests/paranoia.c index 418bfebf52..94f86c9c0a 100644 --- a/tests/paranoia.c +++ b/tests/paranoia.c @@ -7,7 +7,7 @@ void paranoia_eos(GstPad *pad) { int main(int argc,char *argv[]) { GstPipeline *pipeline; - GstElement *paranoia,*queue,*audio_thread,*audiosink; + GstElement *paranoia,*queue,*audio_thread,*osssink; int i; int track = (argc == 2) ? atoi(argv[1]) : 1; @@ -29,14 +29,14 @@ int main(int argc,char *argv[]) { gtk_object_set(GTK_OBJECT(queue),"max_level",750,NULL); g_return_val_if_fail(queue != NULL,4); - audiosink = gst_elementfactory_make("fakesink","audiosink"); - g_return_val_if_fail(audiosink != NULL,4); + osssink = gst_elementfactory_make("fakesink","osssink"); + g_return_val_if_fail(osssink != NULL,4); gst_bin_add(GST_BIN(pipeline),paranoia); gst_bin_add(GST_BIN(pipeline),queue); - gst_bin_add(GST_BIN(audio_thread),audiosink); + gst_bin_add(GST_BIN(audio_thread),osssink); gst_bin_add(GST_BIN(pipeline),audio_thread); - gst_element_add_ghost_pad(GST_ELEMENT(audio_thread),gst_element_get_pad(audiosink,"sink"),"sink"); + gst_element_add_ghost_pad(GST_ELEMENT(audio_thread),gst_element_get_pad(osssink,"sink"),"sink"); gst_element_connect(paranoia,"src",queue,"sink"); gst_element_connect(queue,"src",audio_thread,"sink"); diff --git a/tests/props.c b/tests/props.c index 9203b13579..572af7a7be 100644 --- a/tests/props.c +++ b/tests/props.c @@ -1,22 +1,24 @@ #include -static GstPropsFactory mpeg2dec_sink_props = { - "mpegtype", GST_PROPS_LIST ( +static GstProps* mpeg2dec_sink_props_register (void) { + return gst_props_new ( + "mpegtype", GST_PROPS_LIST ( GST_PROPS_INT(1), GST_PROPS_INT(2) ), - NULL -}; + NULL); +} -static GstPropsFactory mpeg2dec_src_props = { - "fourcc", GST_PROPS_LIST ( - GST_PROPS_FOURCC ('Y','V','1','2'), - GST_PROPS_FOURCC_INT (0x56595559) +static GstProps* mpeg2dec_src_props_register (void) { + return gst_props_new ( + "fourcc", GST_PROPS_LIST ( + GST_PROPS_FOURCC (GST_MAKE_FOURCC ('Y','V','1','2')), + GST_PROPS_FOURCC (GST_MAKE_FOURCC ('Y','U','Y','2')) ), - "width", GST_PROPS_INT_RANGE (16, 4096), - "height", GST_PROPS_INT_RANGE (16, 4096), - NULL -}; + "width", GST_PROPS_INT_RANGE (16, 4096), + "height", GST_PROPS_INT_RANGE (16, 4096), + NULL); +} static GstProps *sinkprops = NULL, *rawprops = NULL, @@ -31,13 +33,14 @@ int main(int argc,char *argv[]) doc = xmlNewDoc ("1.0"); doc->xmlRootNode = xmlNewDocNode (doc, NULL, "Properties", NULL); - _gst_type_initialize (); + g_thread_init (NULL); + _gst_props_initialize (); - sinkprops = gst_props_register (mpeg2dec_sink_props); + sinkprops = mpeg2dec_sink_props_register (); parent = xmlNewChild (doc->xmlRootNode, NULL, "Props1", NULL); gst_props_save_thyself (sinkprops, parent); - rawprops = gst_props_register (mpeg2dec_src_props); + rawprops = mpeg2dec_src_props_register (); parent = xmlNewChild (doc->xmlRootNode, NULL, "Props2", NULL); gst_props_save_thyself (rawprops, parent); @@ -51,8 +54,8 @@ int main(int argc,char *argv[]) gst_props_new ("framed", GST_PROPS_BOOLEAN (TRUE), "mpegtest", GST_PROPS_BOOLEAN (FALSE), "hello", GST_PROPS_LIST ( - GST_PROPS_FOURCC_INT (0X5555), - GST_PROPS_FOURCC_INT (0X6666) + GST_PROPS_FOURCC (GST_MAKE_FOURCC (0,0,0x55,0x55)), + GST_PROPS_FOURCC (GST_MAKE_FOURCC (0,0,0x66,0x66)) ), NULL)); } @@ -60,6 +63,15 @@ int main(int argc,char *argv[]) parent = xmlNewChild (doc->xmlRootNode, NULL, "Props3", NULL); gst_props_save_thyself (testprops, parent); + sinkprops = gst_props_set (sinkprops, "mpegtype", GST_PROPS_INT (1)); + sinkprops = gst_props_set (sinkprops, "foobar", GST_PROPS_FOURCC (GST_MAKE_FOURCC (0x56, 0x56,0x56,0x56))); + + g_print ("%08lx\n", gst_props_get_fourcc_int (sinkprops, "foobar")); + g_print ("%d\n", gst_props_get_int (sinkprops, "mpegtype")); + + parent = xmlNewChild (doc->xmlRootNode, NULL, "Props4", NULL); + gst_props_save_thyself (sinkprops, parent); + xmlDocDump(stdout, doc); return 0; diff --git a/testsuite/Makefile.am b/testsuite/Makefile.am new file mode 100644 index 0000000000..9e32fd0ae2 --- /dev/null +++ b/testsuite/Makefile.am @@ -0,0 +1,11 @@ +SUBDIRS = + +testprogs = test_gst_init + +TESTS = $(testprogs) + +check_PROGRAMS = $(testprogs) + +# we have nothing but apps here, we can do this safely +LIBS += $(GST_LIBS) +CFLAGS += $(GST_CFLAGS) diff --git a/testsuite/capsnego/.gitignore b/testsuite/capsnego/.gitignore new file mode 100644 index 0000000000..9e3be9fc86 --- /dev/null +++ b/testsuite/capsnego/.gitignore @@ -0,0 +1,11 @@ +Makefile +Makefile.in +*.o +*.lo +*.la +.deps +.libs +capsnego +converter +converter2 +enum diff --git a/testsuite/capsnego/Makefile.am b/testsuite/capsnego/Makefile.am new file mode 100644 index 0000000000..c2ac4395e7 --- /dev/null +++ b/testsuite/capsnego/Makefile.am @@ -0,0 +1,11 @@ +SUBDIRS = + +testprogs = capsnego converter converter2 enum + +TESTS = $(testprogs) + +check_PROGRAMS = $(testprogs) + +# we have nothing but apps here, we can do this safely +LIBS += $(GST_LIBS) +CFLAGS += $(GST_CFLAGS) diff --git a/testsuite/capsnego/capsnego.c b/testsuite/capsnego/capsnego.c new file mode 100644 index 0000000000..0866491118 --- /dev/null +++ b/testsuite/capsnego/capsnego.c @@ -0,0 +1,143 @@ + +#include + +GstPad *srcpad, *sinkpad; +GstPad *srcpadtempl, *sinkpadtempl; + +static GstPadFactory src_factory = { + "src", + GST_PAD_FACTORY_SRC, + GST_PAD_FACTORY_ALWAYS, + GST_PAD_FACTORY_CAPS( + "test_src", + "video/raw", + "height", GST_PROPS_INT_RANGE (16, 4096) + ), + NULL, +}; + +static GstPadFactory sink_factory = { + "sink", + GST_PAD_FACTORY_SINK, + GST_PAD_FACTORY_ALWAYS, + GST_PAD_FACTORY_CAPS( + "test_sink", + "video/raw", + "height", GST_PROPS_INT_RANGE (16, 8192) + ), + NULL, +}; + +static GstCapsFactory sink_caps = { + "sink_caps", + "video/raw", + "height", GST_PROPS_INT (3000), + NULL +}; + +static GstCapsFactory src_caps = { + "src_caps", + "video/raw", + "height", GST_PROPS_INT (3000), + NULL +}; + +static GstPadTemplate *srctempl, *sinktempl; +static GstCaps *srccaps, *sinkcaps; + +static GstPadNegotiateReturn +negotiate_src (GstPad *pad, GstCaps **caps, gint counter) +{ + g_print (">"); + + if (counter == 0) { + *caps = NULL; + return GST_PAD_NEGOTIATE_TRY; + } + if (*caps) + return GST_PAD_NEGOTIATE_AGREE; + + return GST_PAD_NEGOTIATE_FAIL; +} + +static GstPadNegotiateReturn +negotiate_sink (GstPad *pad, GstCaps **caps, gint counter) +{ + g_print ("<"); + if (counter == 0) { + *caps = NULL; + return GST_PAD_NEGOTIATE_TRY; + } + if (*caps) + return GST_PAD_NEGOTIATE_AGREE; + + return GST_PAD_NEGOTIATE_FAIL; +} + +static gboolean +perform_check (void) +{ + gboolean result, overall = TRUE; + + gint i, j; + + g_print ("ABC: A=pad caps, B=pad template, C=negotiate function\n"); + + for (j=0; j<8; j++) { + GstPad *srctest, *sinktest; + + for (i=0; i<8; i++) { + + (j & 0x2 ? (sinktest = sinkpadtempl) : (sinktest = sinkpad)); + (j & 0x4 ? (gst_pad_set_caps (sinktest, sinkcaps)) : (gst_pad_set_caps (sinktest, NULL))); + (j & 0x1 ? (gst_pad_set_negotiate_function (sinktest, negotiate_sink)) : + gst_pad_set_negotiate_function (sinktest, NULL)); + + (i & 0x2 ? (srctest = srcpadtempl) : (srctest = srcpad)); + (i & 0x4 ? (gst_pad_set_caps (srctest, srccaps)) : (gst_pad_set_caps (srctest, NULL))); + (i & 0x1 ? (gst_pad_set_negotiate_function (srctest, negotiate_src)) : + gst_pad_set_negotiate_function (srctest, NULL)); + + + g_print ("%d%d%d -> %d%d%d ..", (i&4)>>2, (i&2)>>1, i&1, (j&4)>>2, (j&2)>>1, j&1); + result = gst_pad_connect (srctest, sinktest); + + g_print (".. %s\n", (result? "ok":"fail")); + if (result) gst_pad_disconnect (srctest, sinktest); + + overall &= result; + } + } + return overall; +} + +int +main (int argc, char *argv[]) +{ + gboolean overall = TRUE; + + gst_init (&argc, &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); + + srcpadtempl = gst_pad_new_from_template (srctempl, "src"); + sinkpadtempl = gst_pad_new_from_template (sinktempl, "sink"); + + sinkcaps = gst_caps_register (&sink_caps); + srccaps = gst_caps_register (&src_caps); + + g_print ("*** compatible caps/templates ***\n"); + + overall &= perform_check (); + + gst_caps_set (srccaps, "height", GST_PROPS_INT (9000)); + + g_print ("*** incompatible caps ***\n"); + overall &= perform_check (); + + exit (!overall); +} diff --git a/testsuite/capsnego/converter.c b/testsuite/capsnego/converter.c new file mode 100644 index 0000000000..df26338d1f --- /dev/null +++ b/testsuite/capsnego/converter.c @@ -0,0 +1,168 @@ + +#include + +GstPad *srcpad, *sinkpad; +GstPad *srcconvpad, *sinkconvpad; +GstPad *srcpadtempl, *sinkpadtempl; +GstPad *srcconvtempl, *sinkconvtempl; + +gint converter_in = -1, converter_out = -1; + +static GstPadFactory src_factory = { + "src", + GST_PAD_FACTORY_SRC, + GST_PAD_FACTORY_ALWAYS, + GST_PAD_FACTORY_CAPS( + "test_src", + "audio/raw", + "rate", GST_PROPS_INT_RANGE (16, 20000) + ), + NULL, +}; + +static GstPadFactory src_conv_factory = { + "src", + GST_PAD_FACTORY_SRC, + GST_PAD_FACTORY_ALWAYS, + GST_PAD_FACTORY_CAPS( + "test_src", + "audio/raw", + "rate", GST_PROPS_INT_RANGE (16, 20000) + ), + NULL, +}; + +static GstPadFactory sink_conv_factory = { + "src", + GST_PAD_FACTORY_SINK, + GST_PAD_FACTORY_ALWAYS, + GST_PAD_FACTORY_CAPS( + "test_src", + "audio/raw", + "rate", GST_PROPS_INT_RANGE (16, 20000) + ), + NULL, +}; + +static GstPadFactory sink_factory = { + "sink", + GST_PAD_FACTORY_SINK, + GST_PAD_FACTORY_ALWAYS, + GST_PAD_FACTORY_CAPS( + "test_sink", + "audio/raw", + "rate", GST_PROPS_INT_RANGE (16, 20000) + ), + NULL, +}; + +static GstCapsFactory sink_caps = { + "sink_caps", + "audio/raw", + "rate", GST_PROPS_INT (6000), + NULL +}; + +static GstCapsFactory src_caps = { + "src_caps", + "audio/raw", + "rate", GST_PROPS_INT (3000), + NULL +}; + +static GstPadTemplate *srctempl, *sinktempl; +static GstCaps *srccaps, *sinkcaps; + +static GstPadNegotiateReturn +negotiate_src (GstPad *pad, GstCaps **caps, gint counter) +{ + g_print (">"); + + if (counter == 0) { + *caps = NULL; + return GST_PAD_NEGOTIATE_TRY; + } + if (*caps) { + converter_out = gst_caps_get_int (*caps, "rate"); + return GST_PAD_NEGOTIATE_AGREE; + } + + return GST_PAD_NEGOTIATE_FAIL; +} + +static GstPadNegotiateReturn +negotiate_sink (GstPad *pad, GstCaps **caps, gint counter) +{ + g_print ("<"); + if (counter == 0) { + *caps = NULL; + return GST_PAD_NEGOTIATE_TRY; + } + if (*caps) { + converter_in = gst_caps_get_int (*caps, "rate"); + return GST_PAD_NEGOTIATE_AGREE; + } + + return GST_PAD_NEGOTIATE_FAIL; +} + +int +main (int argc, char *argv[]) +{ + gboolean overall = TRUE; + gboolean result; + + gst_init (&argc, &argv); + + srctempl = gst_padtemplate_new (&src_factory); + sinktempl = gst_padtemplate_new (&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); + 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); + 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); + + result = gst_pad_connect (srcpad, sinkconvpad); + g_print ("pad connect 1: %d\n", result); + overall &= (result == TRUE); + result = gst_pad_connect (srcconvpad, sinkpad); + g_print ("pad connect 2: %d\n", result); + overall &= (result == TRUE); + + g_print ("after connect, converter status: %d %d\n", converter_in, converter_out); + + result = gst_pad_set_caps (srcpad, srccaps); + g_print ("src pad set caps %d, converter status: %d %d\n", result, converter_in, converter_out); + + result = gst_pad_set_caps (sinkpad, sinkcaps); + g_print ("sink pad set caps %d, converter status: %d %d\n", result, converter_in, converter_out); + + gst_caps_set (srccaps, "rate", GST_PROPS_INT (4000)); + result = gst_pad_renegotiate (srcpad); + g_print ("sink pad renegotiate caps %d, converter status: %d %d\n", result, converter_in, converter_out); + + gst_caps_set (srccaps, "rate", GST_PROPS_INT (40000)); + result = gst_pad_set_caps (srcpad, srccaps); + g_print ("sink pad set caps %d, converter status: %d %d\n", result, converter_in, converter_out); + + gst_caps_set (sinkcaps, "rate", GST_PROPS_INT (40000)); + result = gst_pad_set_caps (sinkpad, sinkcaps); + g_print ("sink pad set caps %d, converter status: %d %d\n", result, converter_in, converter_out); + + gst_caps_set (sinkcaps, "rate", GST_PROPS_INT (9000)); + result = gst_pad_set_caps (sinkpad, sinkcaps); + g_print ("sink pad set caps %d, converter status: %d %d\n", result, converter_in, converter_out); + + exit (!overall); +} diff --git a/testsuite/capsnego/converter2.c b/testsuite/capsnego/converter2.c new file mode 100644 index 0000000000..0532c76956 --- /dev/null +++ b/testsuite/capsnego/converter2.c @@ -0,0 +1,224 @@ + +#include + +GstPad *srcpad, *sinkpad; +GstPad *srcconvpad, *sinkconvpad; +GstPad *srcpadtempl, *sinkpadtempl; +GstPad *srcconvtempl, *sinkconvtempl; + +gint converter_in = -1, converter_out = -1; +gint target_rate = 2000; + +static GstPadFactory src_factory = { + "src", + GST_PAD_FACTORY_SRC, + GST_PAD_FACTORY_ALWAYS, + GST_PAD_FACTORY_CAPS( + "test_src", + "audio/raw", + "rate", GST_PROPS_INT_RANGE (16, 20000) + ), + NULL, +}; + +static GstPadFactory src_conv_factory = { + "src", + GST_PAD_FACTORY_SRC, + GST_PAD_FACTORY_ALWAYS, + GST_PAD_FACTORY_CAPS( + "test_src", + "audio/raw", + "rate", GST_PROPS_INT_RANGE (16, 20000) + ), + NULL, +}; + +static GstPadFactory sink_conv_factory = { + "src", + GST_PAD_FACTORY_SINK, + GST_PAD_FACTORY_ALWAYS, + GST_PAD_FACTORY_CAPS( + "test_src", + "audio/raw", + "rate", GST_PROPS_INT_RANGE (16, 20000) + ), + NULL, +}; + +static GstPadFactory sink_factory = { + "sink", + GST_PAD_FACTORY_SINK, + GST_PAD_FACTORY_ALWAYS, + GST_PAD_FACTORY_CAPS( + "test_sink", + "audio/raw", + "rate", GST_PROPS_INT_RANGE (16, 20000) + ), + NULL, +}; + +static GstCapsFactory sink_caps = { + "sink_caps", + "audio/raw", + "rate", GST_PROPS_INT (6000), + NULL +}; + +static GstCapsFactory src_caps = { + "src_caps", + "audio/raw", + "rate", GST_PROPS_INT (3000), + NULL +}; + +static GstPadTemplate *srctempl, *sinktempl; +static GstCaps *srccaps, *sinkcaps; + +static GstPadNegotiateReturn +converter_negotiate_src (GstPad *pad, GstCaps **caps, gint counter) +{ + g_print (">"); + + if (counter == 0) { + *caps = NULL; + return GST_PAD_NEGOTIATE_TRY; + } + if (*caps) { + converter_out = gst_caps_get_int (*caps, "rate"); + return GST_PAD_NEGOTIATE_AGREE; + } + + return GST_PAD_NEGOTIATE_FAIL; +} + +static GstPadNegotiateReturn +converter_negotiate_sink (GstPad *pad, GstCaps **caps, gint counter) +{ + g_print ("<"); + if (counter == 0) { + *caps = GST_PAD_CAPS (srcconvpad); + return GST_PAD_NEGOTIATE_TRY; + } + if (*caps) { + converter_in = gst_caps_get_int (*caps, "rate"); + + if (counter == 1) { + converter_out = gst_caps_get_int (*caps, "rate"); + return gst_pad_negotiate_proxy (pad, srcconvpad, caps, counter); + } + return GST_PAD_NEGOTIATE_AGREE; + } + + return GST_PAD_NEGOTIATE_FAIL; +} + +static GstPadNegotiateReturn +target_negotiate_sink (GstPad *pad, GstCaps **caps, gint counter) +{ + g_print ("{"); + if (counter == 0) { + *caps = gst_caps_new_with_props ( + "target_caps", + "audio/raw", + gst_props_new ( + "rate", GST_PROPS_INT (target_rate), + NULL) + ); + return GST_PAD_NEGOTIATE_TRY; + } + if (*caps) { + target_rate = gst_caps_get_int (*caps, "rate"); + g_print ("target set %d\n", target_rate); + return GST_PAD_NEGOTIATE_AGREE; + } + + return GST_PAD_NEGOTIATE_FAIL; +} + +int +main (int argc, char *argv[]) +{ + gboolean overall = TRUE; + gboolean result; + + gst_init (&argc, &argv); + + srctempl = gst_padtemplate_new (&src_factory); + sinktempl = gst_padtemplate_new (&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); + srcconvpad = gst_pad_new_from_template (srcconvtempl, "csrc"); + sinkconvpad = gst_pad_new_from_template (sinkconvtempl, "csink"); + + gst_pad_set_negotiate_function (srcconvpad, converter_negotiate_src); + 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); + + g_print ("-------) (-----------) (----- \n"); + g_print (" ! ! converter ! ! \n"); + g_print (" src -- csink csrc -- sink \n"); + g_print ("-------) (-----------) (----- \n\n"); + g_print ("The convertor first tries to proxy the caps received\n"); + g_print ("on its csink pad to its csrc pad, when that fails, it\n"); + g_print ("sets up the conversion.\n\n"); + + + g_print ("sink pad set caps (rate=%d), converter status: %d %d\n", target_rate, + converter_in, converter_out); + gst_caps_set (sinkcaps, "rate", GST_PROPS_INT (target_rate)); + result = gst_pad_set_caps (sinkpad, sinkcaps); + g_print ("result: %d, converter status: %d %d, target: %d\n\n", result, + converter_in, converter_out, target_rate); + + result = gst_pad_connect (srcpad, sinkconvpad); + g_print ("pad connect 1: %d\n", result); + overall &= (result == TRUE); + result = gst_pad_connect (srcconvpad, sinkpad); + g_print ("pad connect 2: %d\n", result); + overall &= (result == TRUE); + + g_print ("after connect, converter status: %d %d, target %d\n\n", converter_in, converter_out, target_rate); + + g_print ("src pad set caps (rate=%d), converter status: %d %d, target %d \n", gst_caps_get_int (srccaps, "rate"), + converter_in, converter_out, target_rate); + result = gst_pad_set_caps (srcpad, srccaps); + g_print ("result %d, converter status: %d %d, target %d\n\n", result, + converter_in, converter_out, target_rate); + + g_print ("sink pad set caps (rate=2000), converter status: %d %d, target %d \n", + converter_in, converter_out, target_rate); + target_rate = 2000; + gst_caps_set (sinkcaps, "rate", GST_PROPS_INT (target_rate)); + result = gst_pad_set_caps (sinkpad, sinkcaps); + g_print ("result %d, converter status: %d %d, target: %d\n\n", result, + converter_in, converter_out, target_rate); + + gst_caps_set (srccaps, "rate", GST_PROPS_INT (4000)); + result = gst_pad_renegotiate (srcpad); + g_print ("sink pad renegotiate caps %d, converter status: %d %d, target: %d\n", result, + converter_in, converter_out, target_rate); + + gst_caps_set (srccaps, "rate", GST_PROPS_INT (40000)); + result = gst_pad_set_caps (srcpad, srccaps); + g_print ("sink pad set caps %d, converter status: %d %d, target: %d\n", result, + converter_in, converter_out, target_rate); + + gst_caps_set (sinkcaps, "rate", GST_PROPS_INT (40000)); + result = gst_pad_set_caps (sinkpad, sinkcaps); + g_print ("sink pad set caps %d, converter status: %d %d, target: %d\n", result, + converter_in, converter_out, target_rate); + + target_rate = 9000; + gst_caps_set (sinkcaps, "rate", GST_PROPS_INT (target_rate)); + result = gst_pad_set_caps (sinkpad, sinkcaps); + g_print ("sink pad set caps %d, converter status: %d %d, target: %d\n", result, + converter_in, converter_out, target_rate); + + exit (!overall); +} diff --git a/testsuite/capsnego/enum.c b/testsuite/capsnego/enum.c new file mode 100644 index 0000000000..e3959309e9 --- /dev/null +++ b/testsuite/capsnego/enum.c @@ -0,0 +1,227 @@ + +#include + +GstPad *srcconvpad, *sinkconvpad; +GstPadTemplate *srcconvtempl, *sinkconvtempl; + +static GstPadFactory src_conv_factory = { + "src", + GST_PAD_FACTORY_SRC, + GST_PAD_FACTORY_ALWAYS, + GST_PAD_FACTORY_CAPS( + "test_src", + "audio/raw", + "rate", GST_PROPS_INT_RANGE (16, 20000) + ), + NULL, +}; + +static GstPadFactory sink_conv_factory = { + "src", + GST_PAD_FACTORY_SINK, + GST_PAD_FACTORY_ALWAYS, + GST_PAD_FACTORY_CAPS( + "test_src", + "audio/raw", + "rate", GST_PROPS_INT_RANGE (16, 20000) + ), + NULL, +}; + +static GstCapsFactory src_caps = { + "src_caps", + "audio/raw", + "rate", GST_PROPS_INT (3000), + NULL +}; + +static GstCaps *srccaps, *sinkcaps; + +static gint src_rate = 140; +static gint sink_rate = 100; + +static GstPadNegotiateReturn +negotiate_src (GstPad *pad, GstCaps **caps, gint counter) +{ + g_print (">(%d:%d)", src_rate, (*caps)->refcount); + src_rate++; + + if (counter == 0 || caps == NULL) { + g_print ("*"); + *caps = gst_caps_new_with_props ( + "src_caps", + "audio/raw", + gst_props_new ( + "rate", GST_PROPS_INT (src_rate), + NULL) + ); + return GST_PAD_NEGOTIATE_TRY; + } + if (*caps) { + gint in_rate = gst_caps_get_int (*caps, "rate"); + g_print ("(%d)", in_rate); + + if (in_rate > 140 && in_rate < 300) { + g_print ("A"); + return GST_PAD_NEGOTIATE_AGREE; + } + + *caps = gst_caps_copy_on_write (*caps); + gst_caps_set (*caps, "rate", GST_PROPS_INT (src_rate)); + g_print ("T"); + return GST_PAD_NEGOTIATE_TRY; + } + + g_print ("F"); + return GST_PAD_NEGOTIATE_FAIL; +} + +static GstPadNegotiateReturn +negotiate_sink (GstPad *pad, GstCaps **caps, gint counter) +{ + + g_print ("<(%d:%d:%p)", sink_rate, (*caps)->refcount, *caps); + sink_rate++; + + if (counter == 0 || *caps == NULL) { + g_print ("*"); + *caps = gst_caps_new_with_props ( + "sink_caps", + "audio/raw", + gst_props_new ( + "rate", GST_PROPS_INT (sink_rate), + NULL) + ); + return GST_PAD_NEGOTIATE_TRY; + } + if (*caps) { + gint in_rate = gst_caps_get_int (*caps, "rate"); + g_print ("(%d)", in_rate); + + if (in_rate >= 100 && in_rate < 140) { + g_print ("A"); + return GST_PAD_NEGOTIATE_AGREE; + } + + *caps = gst_caps_copy_on_write (*caps); + g_print ("%p", *caps); + gst_caps_set (*caps, "rate", GST_PROPS_INT (sink_rate)); + + g_print ("T"); + return GST_PAD_NEGOTIATE_TRY; + } + + g_print ("F"); + return GST_PAD_NEGOTIATE_FAIL; +} + +int +main (int argc, char *argv[]) +{ + gboolean overall = TRUE; + gboolean result; + GstElement *queue; + + gst_init (&argc, &argv); + + g_mem_chunk_info(); + + srcconvtempl = gst_padtemplate_new (&src_conv_factory); + sinkconvtempl = gst_padtemplate_new (&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); + sinkcaps = gst_caps_copy (srccaps); + + g_print ("The wild goose chase...\n"); + + result = gst_pad_connect (srcconvpad, sinkconvpad); + g_print ("pad connect 1: %d\n", result); + overall &= (result == TRUE); + + result = gst_pad_set_caps (srcconvpad, srccaps); + g_print ("\nset caps on src: %d, final rate: %d\n", result, + gst_caps_get_int (gst_pad_get_caps (srcconvpad), "rate")); + + g_print ("with the src negotiate function disabled...\n"); + + GST_PAD_CAPS (srcconvpad) = NULL; + GST_PAD_CAPS (sinkconvpad) = NULL; + src_rate = 140; + sink_rate = 100; + + gst_pad_set_negotiate_function (srcconvpad, NULL); + + gst_caps_set (srccaps, "rate", GST_PROPS_INT (120)); + result = gst_pad_set_caps (srcconvpad, srccaps); + g_print ("\nset caps on src: %d, final rate: %d\n", result, + gst_caps_get_int (gst_pad_get_caps (srcconvpad), "rate")); + + + g_print ("with the sink negotiate function disabled...\n"); + + GST_PAD_CAPS (srcconvpad) = NULL; + GST_PAD_CAPS (sinkconvpad) = NULL; + src_rate = 140; + sink_rate = 100; + + gst_pad_set_negotiate_function (srcconvpad, negotiate_src); + gst_pad_set_negotiate_function (sinkconvpad, NULL); + + gst_caps_set (sinkcaps, "rate", GST_PROPS_INT (170)); + result = gst_pad_set_caps (sinkconvpad, sinkcaps); + g_print ("\nset caps on src: %d, final rate: %d\n", result, + gst_caps_get_int (gst_pad_get_caps (srcconvpad), "rate")); + + g_print ("without negotiate functions...\n"); + + GST_PAD_CAPS (srcconvpad) = NULL; + GST_PAD_CAPS (sinkconvpad) = NULL; + src_rate = 140; + sink_rate = 100; + + gst_pad_set_negotiate_function (srcconvpad, NULL); + gst_pad_set_negotiate_function (sinkconvpad, NULL); + + sinkcaps = gst_caps_copy (sinkcaps); + gst_caps_set (sinkcaps, "rate", GST_PROPS_INT (150)); + result = gst_pad_set_caps (sinkconvpad, sinkcaps); + g_print ("\nset caps on src: %d, final rate: %d\n", result, + gst_caps_get_int (gst_pad_get_caps (srcconvpad), "rate")); + + + sinkcaps = gst_caps_copy (sinkcaps); + gst_caps_set (sinkcaps, "rate", GST_PROPS_INT (160)); + result = gst_pad_set_caps (sinkconvpad, sinkcaps); + g_print ("\nset caps on src: %d, final rate: %d\n", result, + gst_caps_get_int (gst_pad_get_caps (srcconvpad), "rate")); + + g_print ("with a proxy element in between...\n"); + + gst_pad_disconnect (srcconvpad, sinkconvpad); + + queue = gst_elementfactory_make ("queue", "queue"); + + GST_PAD_CAPS (srcconvpad) = NULL; + GST_PAD_CAPS (sinkconvpad) = NULL; + src_rate = 140; + sink_rate = 100; + + gst_pad_set_negotiate_function (srcconvpad, negotiate_src); + gst_pad_set_negotiate_function (sinkconvpad, negotiate_sink); + + gst_pad_connect (srcconvpad, gst_element_get_pad (queue, "sink")); + gst_pad_connect (gst_element_get_pad (queue, "src"), sinkconvpad); + + gst_caps_set (srccaps, "rate", GST_PROPS_INT (50)); + result = gst_pad_set_caps (srcconvpad, srccaps); + g_print ("\nset caps on src: %d, final rate: %d\n", result, + gst_caps_get_int (gst_pad_get_caps (srcconvpad), "rate")); + + + exit (!overall); +} diff --git a/testsuite/test_gst_init.c b/testsuite/test_gst_init.c new file mode 100644 index 0000000000..1749328509 --- /dev/null +++ b/testsuite/test_gst_init.c @@ -0,0 +1,13 @@ +#include + +/* This tests that gst_init() doesn't segfault when passed two NULLs as + * parameters, and that it doesn't fail if gst_init() happens to get called + * a second time. */ +int +main (int argc, char *argv[]) +{ + gst_init(NULL, NULL); + gst_init(&argc, &argv); + + return 0; +} diff --git a/tools/Makefile.am b/tools/Makefile.am index d203155426..f723d5d02d 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -1,4 +1,7 @@ bin_PROGRAMS = gstreamer-launch gstreamer-register gstreamer-inspect +man_MANS = gstreamer-launch.1 gstreamer-register.1 gstreamer-inspect.1 + LDADD = $(GST_LIBS) +EXTRA_DIST = $(man_MANS) diff --git a/tools/README b/tools/README index 5d9ffe8fae..29f7f44767 100644 --- a/tools/README +++ b/tools/README @@ -1,5 +1,5 @@ -launch -====== +gstreamer-launch +================ This is a tool that will construct pipelines based on a command-line syntax. The syntax is rather complex to enable all the features I want it @@ -8,7 +8,7 @@ feedback pipelines are the most complex. A simple commandline looks like: -./launch disksrc demo.mp3 | mp3parse | mpg123 | audiosink-oss +./launch disksrc demo.mp3 | mp3parse | mpg123 | osssink A more complex pipeline looks like: diff --git a/tools/gstreamer-inspect.1 b/tools/gstreamer-inspect.1 new file mode 100644 index 0000000000..ec7fcd8e80 --- /dev/null +++ b/tools/gstreamer-inspect.1 @@ -0,0 +1,43 @@ +.TH GStreamer 1 "March 2001" +.SH NAME +gstreamer\-inspect - print info about a GStreamer plugin or element +.SH SYNOPSIS +.B gstreamer\-register [OPTION...] [PLUGIN|ELEMENT] +.SH DESCRIPTION +.PP +\fIgstreamer\-inspect\fP is a tool to print out information on the +available \fIGStreamer\fP plugins, information on a plugin, or +information on an element. With no PLUGIN or ELEMENT option it +will list all plugins and elements. +. +.SH OPTIONS +.l +\fIgstreamer\-inspect\fP accepts the following options: +.TP 8 +.B PLUGIN +Name of a plugin +.TP 8 +.B ELEMENT +Name of an element +.TP 8 +.B \-\-help +Print help synopsis and available FLAGS +.TP 8 +.B \-\-gst\-info\-mask=FLAGS +\fIGStreamer\fP info flags to set (list with \-\-help) +.TP 8 +.B \-\-gst\-debug\-mask=FLAGS +\fIGStreamer\fP debugging flags to set (list with \-\-help) +.TP 8 +.B \-\-gst\-plugin\-spew +\fIGStreamer\fP info flags to set +Enable printout of errors while loading \fIGStreamer\fP plugins +.TP 8 +.B \-\-gst\-plugin\-path=PATH +Add directories separated with ':' to the plugin search path +.SH SEE ALSO +.BR gstreamer\-config (1), +.BR gstreamer\-register (1), +.BR gstreamer\-launch (1) +.SH AUTHOR +The GStreamer team at http://gstreamer.net/ diff --git a/tools/gstreamer-inspect.c b/tools/gstreamer-inspect.c index a95392e9cb..e18c5f4dcb 100644 --- a/tools/gstreamer-inspect.c +++ b/tools/gstreamer-inspect.c @@ -15,22 +15,25 @@ void print_prop(GstPropsEntry *prop,gboolean showname,gchar *pfx) { printf(pfx); switch (prop->propstype) { - case GST_PROPS_INT_ID_NUM: + case GST_PROPS_INT_ID: printf("Integer: %d\n",prop->data.int_data); break; - case GST_PROPS_INT_RANGE_ID_NUM: + case GST_PROPS_INT_RANGE_ID: printf("Integer range: %d - %d\n",prop->data.int_range_data.min, prop->data.int_range_data.max); break; - case GST_PROPS_BOOL_ID_NUM: + case GST_PROPS_BOOL_ID: printf("Boolean: %s\n",prop->data.bool_data ? "TRUE" : "FALSE"); break; - case GST_PROPS_FOURCC_ID_NUM: + case GST_PROPS_STRING_ID: + printf("String: %s\n",prop->data.string_data.string); + break; + case GST_PROPS_FOURCC_ID: printf("FourCC: %c%c%c%c\n", prop->data.fourcc_data & 0xff,prop->data.fourcc_data>>8 & 0xff, prop->data.fourcc_data>>16 & 0xff,prop->data.fourcc_data>>24 & 0xff); break; - case GST_PROPS_LIST_ID_NUM: + case GST_PROPS_LIST_ID: printf("List:\n"); longprefix = g_strdup_printf("%s ",pfx); list = prop->data.list_data.entries; @@ -42,7 +45,7 @@ void print_prop(GstPropsEntry *prop,gboolean showname,gchar *pfx) { g_free(longprefix); break; default: - printf("\n"); + printf("unknown props %d\n", prop->propstype); } } @@ -59,38 +62,17 @@ void print_props(GstProps *properties,gchar *pfx) { } } -/* -struct _GstPropsEntry { - GQuark propid; - GstPropsId propstype; - - union { - // flat values - gboolean bool_data; - guint32 fourcc_data; - gint int_data; - - // structured values - struct { - GList *entries; - } list_data; - struct { - gint min; - gint max; - } int_range_data; - } data; -}; -*/ - -gint print_element_info(GstElementFactory *factory) { +gint +print_element_info (GstElementFactory *factory) +{ GstElement *element; GstObjectClass *gstobject_class; GstElementClass *gstelement_class; - GList *pads, *caps; + GList *pads; + GstCaps *caps; GstPad *pad; GstRealPad *realpad; GstPadTemplate *padtemplate; - GstCaps *cap; GtkArg *args; guint32 *flags; gint num_args,i; @@ -142,19 +124,18 @@ gint print_element_info(GstElementFactory *factory) { while (caps) { GstType *type; - cap = (GstCaps*)(caps->data); - caps = g_list_next(caps); + printf(" '%s':\n",caps->name); - printf(" '%s':\n",cap->name); - - type = gst_type_find_by_id (cap->id); + type = gst_type_find_by_id (caps->id); if (type) printf(" MIME type: '%s':\n",type->mime); else printf(" MIME type: 'unknown/unknown':\n"); - if (cap->properties) - print_props(cap->properties," "); + if (caps->properties) + print_props(caps->properties," "); + + caps = caps->next; } } @@ -231,19 +212,18 @@ gint print_element_info(GstElementFactory *factory) { while (caps) { GstType *type; - cap = (GstCaps*)(caps->data); - caps = g_list_next(caps); + printf(" '%s':\n",caps->name); - printf(" '%s':\n",cap->name); - - type = gst_type_find_by_id (cap->id); + type = gst_type_find_by_id (caps->id); if (type) printf(" MIME type: '%s':\n",type->mime); else printf(" MIME type: 'unknown/unknown':\n"); - if (cap->properties) - print_props(cap->properties," "); + if (caps->properties) + print_props(caps->properties," "); + + caps = caps->next; } } @@ -322,11 +302,9 @@ void print_element_list() { } } - -void print_plugin_info(GstPlugin *plugin) { - GList *factories; - GstElementFactory *factory; - +void +print_plugin_info (GstPlugin *plugin) +{ printf("Plugin Details:\n"); printf(" Name:\t\t%s\n",plugin->name); printf(" Long Name:\t%s\n",plugin->longname); @@ -334,6 +312,9 @@ void print_plugin_info(GstPlugin *plugin) { printf("\n"); if (plugin->numelements) { + GList *factories; + GstElementFactory *factory; + printf("Element Factories:\n"); factories = gst_plugin_get_factory_list(plugin); @@ -344,6 +325,36 @@ void print_plugin_info(GstPlugin *plugin) { printf(" %s: %s\n",factory->name,factory->details->longname); } } + if (plugin->numautopluggers) { + GList *factories; + GstAutoplugFactory *factory; + + printf("Autpluggers:\n"); + + factories = gst_plugin_get_autoplug_list(plugin); + while (factories) { + factory = (GstAutoplugFactory*)(factories->data); + factories = g_list_next(factories); + + printf(" %s: %s\n", factory->name, factory->longdesc); + } + } + if (plugin->numtypes) { + GList *factories; + GstTypeFactory *factory; + + printf("Types:\n"); + + factories = gst_plugin_get_type_list(plugin); + while (factories) { + factory = (GstTypeFactory*)(factories->data); + factories = g_list_next(factories); + + printf(" %s: %s\n", factory->mime, factory->exts); + if (factory->typefindfunc) + printf(" Has typefind function: %s\n",GST_DEBUG_FUNCPTR_NAME(factory->typefindfunc)); + } + } printf("\n"); } @@ -357,7 +368,7 @@ int main(int argc,char *argv[]) { // if no arguments, print out list of elements if (argc == 1) { - print_element_list(); + print_element_list(); // else we try to get a factory } else { diff --git a/tools/gstreamer-launch.1 b/tools/gstreamer-launch.1 new file mode 100644 index 0000000000..6d370687d0 --- /dev/null +++ b/tools/gstreamer-launch.1 @@ -0,0 +1,38 @@ +.TH GStreamer 1 "March 2001" +.SH NAME +gstreamer\-launch - build and run a GStreamer pipeline +.SH SYNOPSIS +.B gstreamer\-launch [OPTION...] PIPELINE\-DESCRIPTION +.SH DESCRIPTION +.PP +\fIgstreamer\-launch\fP is a tool that is used to build and run a basic +\fIGStreamer\fP pipeline. +. +See other docs, examples, and the source for description on how to +create a PIPELINE\-DESCRIPTION. +. +.SH OPTIONS +.l +\fIgstreamer\-launch\fP accepts the following options: +.TP 8 +.B \-\-help +Print help synopsis and available FLAGS +.TP 8 +.B \-\-gst\-info\-mask=FLAGS +\fIGStreamer\fP info flags to set (list with \-\-help) +.TP 8 +.B \-\-gst\-debug\-mask=FLAGS +\fIGStreamer\fP debugging flags to set (list with \-\-help) +.TP 8 +.B \-\-gst\-plugin\-spew +\fIGStreamer\fP info flags to set +Enable printout of errors while loading \fIGStreamer\fP plugins +.TP 8 +.B \-\-gst\-plugin\-path=PATH +Add directories separated with ':' to the plugin search path +.SH SEE ALSO +.BR gstreamer\-register (1), +.BR gstreamer\-inspect (1), +.BR gstreamer\-config (1) +.SH AUTHOR +The GStreamer team at http://gstreamer.net/ diff --git a/tools/gstreamer-launch.c b/tools/gstreamer-launch.c index 1938f2bfe5..0b6cfa955b 100644 --- a/tools/gstreamer-launch.c +++ b/tools/gstreamer-launch.c @@ -25,10 +25,7 @@ main(int argc, char *argv[]) gst_parse_launch (cmdline, GST_BIN (pipeline)); - xmlSaveFile("launch.gst", gst_xml_write(GST_ELEMENT(pipeline))); - - gst_schedule_show(GST_ELEMENT_SCHED(pipeline)); - gst_schedule_show(GST_ELEMENT_SCHED(gst_bin_get_by_name(pipeline,"thread0"))); + xmlSaveFile("gstreamer-launch.gst",gst_xml_write(pipeline)); fprintf(stderr,"RUNNING pipeline\n"); gst_element_set_state (pipeline, GST_STATE_PLAYING); diff --git a/tools/gstreamer-register.1 b/tools/gstreamer-register.1 new file mode 100644 index 0000000000..d0fe5a49d1 --- /dev/null +++ b/tools/gstreamer-register.1 @@ -0,0 +1,37 @@ +.TH GStreamer 1 "March 2001" +.SH NAME +gstreamer\-register - register GStreamer plugins +.SH SYNOPSIS +.B gstreamer\-register [OPTION...] +.SH DESCRIPTION +.PP +\fIgstreamer\-register\fP is a tool that is used to register all +the \fIGStreamer\fP plugins on your system. It creates a listing of their +properties such that on startup of \fIGStreamer\fP based application do not +need to load plugins until they need them. +. +.SH OPTIONS +.l +\fIgstreamer\-register\fP accepts the following options: +.TP 8 +.B \-\-help +Print help synopsis and available FLAGS +.TP 8 +.B \-\-gst\-info\-mask=FLAGS +\fIGStreamer\fP info flags to set (list with \-\-help) +.TP 8 +.B \-\-gst\-debug\-mask=FLAGS +\fIGStreamer\fP debugging flags to set (list with \-\-help) +.TP 8 +.B \-\-gst\-plugin\-spew +\fIGStreamer\fP info flags to set +Enable printout of errors while loading \fIGStreamer\fP plugins +.TP 8 +.B \-\-gst\-plugin\-path=PATH +Add directories separated with ':' to the plugin search path +.SH SEE ALSO +.BR gstreamer\-config (1), +.BR gstreamer\-inspect (1), +.BR gstreamer\-launch (1) +.SH AUTHOR +The GStreamer team at http://gstreamer.net/