summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: d0cfa2d)
raw | patch | inline | side by side (parent: d0cfa2d)
author | wrobell <wrobell@ite.pl> | |
Tue, 4 Dec 2001 22:12:50 +0000 (22:12 +0000) | ||
committer | Wim Taymans <wim.taymans@gmail.com> | |
Tue, 4 Dec 2001 22:12:50 +0000 (22:12 +0000) |
Original commit message from CVS:
- added playondemand plugin by Leif Morgan Johnson <lmjohns3@eos.ncsu.edu>
- some fixes to int2float
- aplied a patch from wrobell <wrobell@ite.pl> that is a first attempt at
making automake 1.5 happy (gst now requires automake1.5). It's still not
perfect but it builds.
- Made the schedulers plugable. The default scheduler now lives inside a
plugin.
- Added a new mpeg1/2 parser/demuxer.
- Fixed some compiler warnings in the core libs.
- substantial work to GstThread (hopefully less race conditions). simplified
the code in GstThread a bit. A state change can now also happen in the
thread context.
- reworked the state semantics of a bin. it'll now automatically get the
highest state of its children.
- the autoplugger now nests the threads so that a state change failure of
one thread doesn't make its upstream thread lock.
- GstQueue refuses to go to PLAYING if the sinkpad is not connected. This
way the queue will not wedge in the _get lock.
- GstQueue unlocks its mutexes when going to PAUSED.
- make sure that when all elements in a bin/thread go to PAUSED, the bin
is set to PAUSED too.
- make a parent bin wait for its children to PAUSE before ending the
iteration with FALSE (EOS)
- Some changes to GstPlay to deal with EOS.
- aplied the latest patch from Zeenix to gstrtp.
end result: GstPlay doesn't crash on EOS and the pipeline is now shut down
properly.
- added playondemand plugin by Leif Morgan Johnson <lmjohns3@eos.ncsu.edu>
- some fixes to int2float
- aplied a patch from wrobell <wrobell@ite.pl> that is a first attempt at
making automake 1.5 happy (gst now requires automake1.5). It's still not
perfect but it builds.
- Made the schedulers plugable. The default scheduler now lives inside a
plugin.
- Added a new mpeg1/2 parser/demuxer.
- Fixed some compiler warnings in the core libs.
- substantial work to GstThread (hopefully less race conditions). simplified
the code in GstThread a bit. A state change can now also happen in the
thread context.
- reworked the state semantics of a bin. it'll now automatically get the
highest state of its children.
- the autoplugger now nests the threads so that a state change failure of
one thread doesn't make its upstream thread lock.
- GstQueue refuses to go to PLAYING if the sinkpad is not connected. This
way the queue will not wedge in the _get lock.
- GstQueue unlocks its mutexes when going to PAUSED.
- make sure that when all elements in a bin/thread go to PAUSED, the bin
is set to PAUSED too.
- make a parent bin wait for its children to PAUSE before ending the
iteration with FALSE (EOS)
- Some changes to GstPlay to deal with EOS.
- aplied the latest patch from Zeenix to gstrtp.
end result: GstPlay doesn't crash on EOS and the pipeline is now shut down
properly.
111 files changed:
diff --git a/configure.base b/configure.base
index fc284c0740d37da23fe2de50f2130b34bb38ff09..d944188d68b1f479d284695beab324e9f51f82c1 100644 (file)
--- a/configure.base
+++ b/configure.base
AC_SUBST(GST_AGE)
AC_SUBST(GST_LIBVERSION)
-
AM_MAINTAINER_MODE
AC_PROG_CC
+AM_PROG_CC_STDC
+AM_PROG_AS
AC_PROG_CXX
AC_PROG_CXXCPP
AC_ISC_POSIX
-SUBSTFOR configure.ac:AC_HEADER_STDC([])
-SUBSTFOR configure.in: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
AC_LIBTOOL_DLOPEN
AM_PROG_LIBTOOL
-CFLAGS=""
+SUBSTFOR configure.ac:AC_HEADER_STDC([])
+SUBSTFOR configure.in:AC_STDC_HEADERS
dnl This is used for the -config script...
builddir=`pwd`
],
[
AC_MSG_RESULT(yes)
-CORE_CFLAGS="$CORE_CFLAGS -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64"
-GST_DEFINE_CFLAGS="$GST_DEFINE_CFLAGS -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64"
+GST_CFLAGS="$GST_CFLAGS -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64"
],
[
AC_MSG_RESULT(no)
GST_CHECK_FEATURE(GLIB2, [use of glib-2.0 and GObject], , [
PKG_CHECK_MODULES(GLIB2, glib-2.0 gobject-2.0 gthread-2.0 gmodule-2.0,
HAVE_GLIB2=yes,HAVE_GLIB2=no)
- AC_SUBST(GLIB2_LIBS)
- AC_SUBST(GLIB2_CFLAGS)
+ GLIB_LIBS=$GLIB2_LIBS
+ GLIB_CFLAGS=$GLIB2_CFLAGS
+ AC_SUBST(GLIB_LIBS)
+ AC_SUBST(GLIB_CFLAGS)
], disabled, [
- CORE_LIBS="$CORE_LIBS $GLIB2_LIBS"
- CORE_CFLAGS="$CORE_CFLAGS $GLIB2_CFLAGS"
-
AC_DEFINE(USE_GLIB2)
- GST_DEFINE_CFLAGS="$GST_DEFINE_CFLAGS -DUSE_GLIB2"
+ GST_CFLAGS="$GST_CFLAGS -DUSE_GLIB2"
])
AC_SUBST(USE_GLIB2)
AC_MSG_ERROR(Cannot find gtk: Is gtk-config in path?))
HAVE_GTK=yes
- CORE_LIBS="$CORE_LIBS $GLIB_LIBS $GTK_LIBS"
- CORE_CFLAGS="$CORE_CFLAGS $GLIB_CFLAGS $GTK_CFLAGS"
+ GLIB_LIBS="$GLIB_LIBS $GTK_LIBS"
+ GLIB_CFLAGS="$GLIB_CFLAGS $GTK_CFLAGS"
else
GST_PKG_DEPS="glib-2.0 gobject-2.0 gmodule-2.0 gthread-2.0"
if test x$XML_CONFIG = xno; then
AC_MSG_ERROR(Couldn't find xml-config)
fi
-xml_save_LIBS=$LIBS
-xml_save_CFLAGS=$CFLAGS
-XML_LIBS=`xml-config --libs`
-XML_CFLAGS=`xml-config --cflags`
-LIBS=$XML_LIBS
-CFLAGS=$XML_CFLAGS
-AC_CHECK_LIB(xml, xmlDocGetRootElement, ,
+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)
-LIBS=$xml_save_LIBS
-CFLAGS=$xml_save_CFLAGS
AC_SUBST(XML_LIBS)
AC_SUBST(XML_CFLAGS)
-CORE_LIBS="$CORE_LIBS $XML_LIBS"
-CORE_CFLAGS="$CORE_CFLAGS $XML_CFLAGS"
dnl ==========================================================================
dnl AC_CHECK_HEADER uses CPPFLAGS, but not CFLAGS.
dnl FIXME: ensure only suitable flags result from artsc-config --cflags
-CPPFLAGS="$CPPFLAGS $ARTS_CFLAGS"
AC_CHECK_HEADER(artsflow.h, :, HAVE_ARTS=no)
SUBSTFOR configure.ac:AC_LANG_POP(C++)
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 $GTK_CFLAGS"
- LIBS="$LIBS $LIBGLADE_GNOME_LIBS $GTK_LIBS"
AC_TRY_LINK([#include <glade/glade.h>],[glade_gnome_init();],
HAVE_LIBGLADE_GNOME="yes",
AC_MSG_WARN(
[Couldn't find gnome libraries for libglade - Can't build gstmediaplay and gsteditor])
)
- CFLAGS="$libglade_save_CFLAGS"
- LIBS="$libglade_save_LIBS"
fi
fi
AC_SUBST(LIBGLADE_GNOME_LIBS)
AC_CHECK_HEADER(dvdread/dvd_reader.h, :, HAVE_LIBDVDREAD=no)
dnl Check for SDL library
-AC_MSG_CHECKING(SDL library)
-HAVE_LIBSDL=yes
-if sdl-config --libs > /dev/null 2>&1; then
- SDL_VERSION=`sdl-config --version`
- AC_MSG_RESULT([found (version $SDL_VERSION)])
- SDL_LIBS="`sdl-config --libs`"
- SDL_CFLAGS="`sdl-config --cflags`"
- AC_CHECK_LIB(SDL, SDL_Init, :, HAVE_LIBSDL=no, $SDL_LIBS)
- dnl AC_CHECK_HEADER uses CPPFLAGS, but not CFLAGS.
- dnl Assume only suitable flags result from artsc-config --cflags
- sdlcheck_save_CPPFLAGS="$CPPFLAGS"
- CPPFLAGS="$CPPFLAGS $SDL_CFLAGS"
- AC_CHECK_HEADER(SDL.h, :, HAVE_LIBSDL=no)
- CPPFLAGS="$sdlcheck_save_CPPFLAGS"
- AC_CHECK_LIB(SDL, SDL_CreateYUVOverlay, :, HAVE_LIBSDL=no, $SDL_LIBS)
-else
- AC_MSG_RESULT(not found)
- HAVE_LIBSDL=no
- SDL_LIBS=
- SDL_CFLAGS=
-fi
-AC_SUBST(SDL_LIBS)
-AC_SUBST(SDL_CFLAGS)
+AM_PATH_SDL( , , HAVE_LIBSDL=no)
if test "x$HAVE_LIBSDL" = "xno"; then
AC_MSG_WARN(
GST_SUBSYSTEM_DISABLE(TRACE,[tracing subsystem])
GST_SUBSYSTEM_DISABLE(REGISTRY,[plugin registry])
-GST_DEFINE_CFLAGS="$GST_DEFINE_CFLAGS $GST_SUBSYSTEM_DISABLE_DEFINES"
+GST_CFLAGS="$GST_CFLAGS $GST_SUBSYSTEM_DISABLE_DEFINES"
dnl ################################################
AC_DEFINE(PLUGINS_USE_BUILDDIR, 1, [Define if plugins should be loaded from the build tree - only developers should use this])
fi
-if test "x$USE_DEBUG" = xyes; then
- CFLAGS="$CFLAGS -g"
-fi
+dnl if test "x$USE_DEBUG" = xyes; then
+dnl CFLAGS="$CFLAGS -g"
+dnl fi
if test "x$USE_PROFILING" = xyes; then
- CFLAGS="$CFLAGS -pg -fprofile-arcs"
+dnl CFLAGS="$CFLAGS -pg -fprofile-arcs"
FOMIT_FRAME_POINTER=""
else
FOMIT_FRAME_POINTER="-fomit-frame-pointer"
AC_DEFINE_UNQUOTED(PLUGINS_BUILDDIR,"$PLUGINS_BUILDDIR")
AC_SUBST(PLUGINS_BUILDDIR)
-dnl ##############################
-dnl # Set up the defaults cflags #
-dnl ##############################
-dnl CC="kgcc"
-if test "x$USE_PROFILING" = xyes; then
- CFLAGS="$CORE_CFLAGS $CFLAGS -Wall"
-else
- CFLAGS="$CORE_CFLAGS $CFLAGS -O6 -Wall"
-fi
-LIBS="$CORE_LIBS $LIBS"
-AC_SUBST(CORE_LIBS)
-AC_SUBST(CORE_CFLAGS)
-
dnl Vars for everyone else
GST_LIBS="\$(top_builddir)/gst/libgst.la"
GST_CFLAGS="-I\$(top_srcdir) -I\$(top_srcdir)/include"
AC_SUBST(GST_CFLAGS)
dnl Private vars for libgst only
-LIBGST_LIBS="$LIBS"
-LIBGST_CFLAGS="$CFLAGS $GST_CFLAGS"
+LIBGST_CFLAGS="$GST_CFLAGS"
AC_SUBST(LIBGST_LIBS)
AC_SUBST(LIBGST_CFLAGS)
-dnl CFLAGS for everyone else
-CFLAGS="$GST_CFLAGS $CFLAGS"
-LDFLAGS="$GST_LIBS $LDFLAGS"
-
-dnl Needed to make automake 1.4g happy.
-dnl FIXME: find as properly, rather than just using CC
-AS="\$(CC)"
-
-dnl Having to AC_SUBST these is messy, but doesn't seem to do any harm.
-dnl I'm not sure whether it's really necessary, but it removes some warnings
-dnl when automake 1.4g runs, and may be beneficial elsewhere.
-AC_SUBST(LIBS)
-AC_SUBST(CFLAGS)
-AC_SUBST(CPPFLAGS)
-AC_SUBST(LDFLAGS)
-AC_SUBST(AS)
-AC_SUBST(ASFLAGS)
-
-AC_SUBST(GST_DEFINE_CFLAGS)
+AC_SUBST(GST_CFLAGS)
dnl #############################
dnl # Configure the subpackages #
dnl # Make the output files #
dnl #########################
+dnl until ffmpeg is handled by configure plugins/ffmpeg/Makefile
+dnl components/bonobo-gstmediaplay/Makefile
+dnl someone should fix this test/misc/Makefile
SUBSTFOR configure.ac:AC_OUTPUT(
SUBSTFOR configure.ac:Makefile
SUBSTFOR configure.in:AC_OUTPUT([Makefile
gst/types/Makefile
gst/elements/Makefile
gst/autoplug/Makefile
+gst/schedulers/Makefile
libs/Makefile
libs/riff/Makefile
libs/getbits/Makefile
plugins/rtp/Makefile
plugins/mulaw/Makefile
plugins/alaw/Makefile
-dnl until ffmpeg is handled by configure plugins/ffmpeg/Makefile
plugins/filters/Makefile
plugins/filters/smooth/Makefile
plugins/filters/median/Makefile
plugins/filters/deinterlace/Makefile
plugins/filters/volume/Makefile
plugins/filters/speed/Makefile
+plugins/filters/playondemand/Makefile
plugins/gnomevfs/Makefile
plugins/icecast/Makefile
plugins/icecast/icecastsend/Makefile
plugins/synthesis/sinesrc/Makefile
plugins/silence/Makefile
gstplay/Makefile
-dnl components/bonobo-gstmediaplay/Makefile
test/Makefile
test/xml/Makefile
test/bindings/Makefile
-dnl someone should fix this test/misc/Makefile
test/memchunk/Makefile
test/events/Makefile
tests/Makefile
testsuite/capsnego/Makefile
testsuite/refcounting/Makefile
testsuite/plugin/Makefile
+testsuite/threads/Makefile
tests/nego/Makefile
examples/Makefile
examples/autoplug/Makefile
diff --git a/docs/gst/.gitignore b/docs/gst/.gitignore
index 80491c9cb6134ae7d97ac303355660da38999342..099652a98638f863cce243b0bb4edf6d2eb47bce 100644 (file)
--- a/docs/gst/.gitignore
+++ b/docs/gst/.gitignore
gstreamer.types
gstreamer.html
gstreamer-unused.txt
+gstreamer-undocumented.txt
gstreamer-decl-list.txt
gstreamer-decl.txt
gstreamer-scan.c
index 263ec6d5d873d4d974c5f2a7c40588cafacc1539..f8eb9e35ad03ec85bca0855d0d46ed9a9ff64413 100644 (file)
unlock (release lock) !
! status = iterate() (*)
lock mutex
+ signal TH
if (!status) // EOS
unset SPINNING flag
}
diff --git a/editor/Makefile.am b/editor/Makefile.am
index 0b426547b157e01a82c7ea9bcbd3a04b35458151..9be4d57d51a56dba93a4ef6a8568e174b7644507 100644 (file)
--- a/editor/Makefile.am
+++ b/editor/Makefile.am
-CFLAGS += -DDATADIR="\"$(gladedir)/\"" $(GNOME_CFLAGS) $(LIBGLADE_GNOME_CFLAGS)
-LDFLAGS += $(GNOME_LIBS) $(LIBGLADE_GNOME_LIBS)
lib_LTLIBRARIES = libgsteditor.la
gstelementselect.c \
gsteditorcreate.c
+libgsteditor_la_CFLAGS = -DDATADIR="\"$(gladedir)/\"" $(GNOME_CFLAGS) $(LIBGLADE_GNOME_CFLAGS)
+libgsteditor_la_LDFLAGS = $(GNOME_LIBS) $(LIBGLADE_GNOME_LIBS)
+
libgsteditorincludedir = $(includedir)/gst
libgsteditorinclude_HEADERS = \
gsteditor.h
index f263f271004f234616b1e949275c975441125ebc..8f8cdd41531777c5c99886c18b77dbbd60d30813 100644 (file)
noinst_PROGRAMS = autoplug
# just an app here, we're safe
-LIBS += $(GNOME_LIBS) $(GST_LIBS)
-CFLAGS += $(GNOME_CFLAGS) $(GST_CFLAGS)
+autoplug_LDADD = $(GNOME_LIBS) $(GST_LIBS) $(GLIB_LIBS)
+autoplug_CFLAGS = $(GNOME_CFLAGS) $(GLIB_CFLAGS) $(XML_CFLAGS) $(GST_CFLAGS)
index c1fca3f985f21a65de6d092be6d8872b8b57c71e..29da841f05595e515613cbe4147138bc67a8e4de 100644 (file)
noinst_PROGRAMS = cutter
noinst_HEADERS = cutter.h
-LIBS += $(GST_LIBS)
-CFLAGS += $(GST_CFLAGS)
+cutter_LDADD = $(GST_LIBS)
+cutter_CFLAGS = $(GLIB_CFLAGS) $(XML_CFLAGS) $(GST_CFLAGS)
index 77e8ef336ae80c85053dcbbcbe65ce252a8888f1..5821f461f27e7dc4fb22cb916c775562bc8dc9b6 100644 (file)
noinst_PROGRAMS = helloworld
-LIBS += $(GST_LIBS)
-CFLAGS += $(GST_CFLAGS)
+helloworld_LDADD = $(GST_LIBS)
+helloworld_CFLAGS = $(GLIB_CFLAGS) $(XML_CFLAGS) $(GST_CFLAGS)
index 6d686a40923c7c3a5af205ef5e5f21e906be931b..1daf5c0da1e16297a4bed9412b80fb143becd991 100644 (file)
noinst_PROGRAMS = helloworld2
-LIBS += $(GST_LIBS)
-CFLAGS += $(GST_CFLAGS)
+helloworld2_LDADD = $(GST_LIBS)
+helloworld2_CFLAGS = $(GLIB_CFLAGS) $(XML_CFLAGS) $(GST_CFLAGS)
index 11c2e57cfc692a4af35abe460c73be9949f54562..c1d844569c77595b722114cdac3bed93193d576f 100644 (file)
noinst_PROGRAMS = mp3parselaunch
# just an app here, we're safe
-LIBS += $(GST_LIBS)
-CFLAGS += $(GST_CFLAGS)
+mp3parselaunch_LDADD = $(GST_LIBS)
+mp3parselaunch_CFLAGS = $(GLIB_CFLAGS) $(XML_CFLAGS) $(GST_CFLAGS)
noinst_SCRIPTS = mp3play
EXTRA_DIST = mp3play
index d15b425208014d2c3ea189338c46ab090ee4110d..8d993da8c70593144397cd23b712eb42b5888732 100644 (file)
noinst_PROGRAMS = mixer
noinst_HEADERS = mixer.h
-LIBS += $(GST_LIBS)
-CFLAGS += $(GST_CFLAGS)
+mixer_LDADD = $(GST_LIBS)
+mixer_CFLAGS = $(GLIB_CFLAGS) $(XML_CFLAGS) $(GST_CFLAGS)
diff --git a/examples/mixer/mixer.c b/examples/mixer/mixer.c
index 7a02eddcb44aa55011cb01f04ff86c721e2b3e60..ec492cad34f7989deddb071a5229cb8bfed2dd09 100644 (file)
--- a/examples/mixer/mixer.c
+++ b/examples/mixer/mixer.c
gst_element_set_state(main_bin, GST_STATE_PLAYING);
// write out the schedule
- gst_schedule_show(GST_ELEMENT_SCHED(main_bin));
+ gst_scheduler_show(GST_ELEMENT_SCHED(main_bin));
playing = TRUE;
j = 0;
index 5e0b9fca0fa9fe418989b221d0eeb4a96a06456d..11c631711ddb4dbfcc60e2c5bfc86e3abcc1ec68 100644 (file)
noinst_LTLIBRARIES = libexample.la
libexample_la_SOURCES = example.c
+libexample_la_CFLAGS = $(GLIB_CFLAGS) $(XML_CFLAGS) $(GST_CFLAGS)
noinst_HEADERS = example.h
index e4ef4c7ce8ed3f4fd1a8b1e0ecab9700b85e7471..7b67eeabd69e1b3e3684ba177787d914a72eb5ae 100644 (file)
noinst_PROGRAMS = queue
-LIBS += $(GST_LIBS)
-CFLAGS += $(GST_CFLAGS)
+queue_LDADD = $(GST_LIBS)
+queue_CFLAGS = $(GLIB_CFLAGS) $(XML_CFLAGS) $(GST_CFLAGS)
index fd4f914bbd3e47fec62007b600bc12e96abf9355..5bd7542f1c16f13de10e7fe91228ca20503c1cf0 100644 (file)
noinst_PROGRAMS = queue2
-LIBS += $(GST_LIBS)
-CFLAGS += $(GST_CFLAGS)
+queue2_LDADD = $(GST_LIBS)
+queue2_CFLAGS = $(GLIB_CFLAGS) $(XML_CFLAGS) $(GST_CFLAGS)
index be6313ce6d5b8d1810c375769a44a76cb4dfbd21..de2d00faabca5c573927edf0b2635eebbc471e66 100644 (file)
noinst_PROGRAMS = queue3
-LIBS += $(GST_LIBS)
-CFLAGS += $(GST_CFLAGS)
+queue3_LDADD = $(GST_LIBS)
+queue3_CFLAGS = $(GLIB_CFLAGS) $(XML_CFLAGS) $(GST_CFLAGS)
index 0b1a4857b8244e0a1f6c06ef6e9eeae5b71ddad5..8d6e2eec9550a951e33045aee4b7b6b1e1d86ef7 100644 (file)
noinst_PROGRAMS = queue4
-LIBS += $(GST_LIBS)
-CFLAGS += $(GST_CFLAGS)
+queue4_LDADD = $(GST_LIBS)
+queue4_CFLAGS = $(GLIB_CFLAGS) $(XML_CFLAGS) $(GST_CFLAGS)
index 4e019cb7316c1778f12455d202a864cfd2f4aec7..ae9f9ac7594d168c1953e27f42948b884ae960ca 100644 (file)
noinst_PROGRAMS = thread
-LIBS += $(GST_LIBS)
-CFLAGS += $(GST_CFLAGS)
+thread_LDADD = $(GST_LIBS)
+thread_CFLAGS = $(GLIB_CFLAGS) $(XML_CFLAGS) $(GST_CFLAGS)
index 57669bdcc06fb3e9baca1673faa1a966068c5a79..e8a9b4f1c805da96c5a6e08c4ae20f0d66b6c9a3 100644 (file)
noinst_PROGRAMS = typefind
-LIBS += $(GST_LIBS)
-CFLAGS += $(GST_CFLAGS)
+typefind_LDADD = $(GST_LIBS)
+typefind_CFLAGS = $(GLIB_CFLAGS) $(XML_CFLAGS) $(GST_CFLAGS)
index 24b890fd84d245aca9f44c0ad5fde26b60c01ce0..7b8e2f4745ad7ca470bbaec183edd2ec9b4f38a7 100644 (file)
--- a/examples/xml/Makefile.am
+++ b/examples/xml/Makefile.am
noinst_PROGRAMS = createxml runxml
-LIBS += $(GST_LIBS)
-CFLAGS += $(GST_CFLAGS)
+createxml_LDADD = $(GST_LIBS)
+createxml_CFLAGS = $(GLIB_CFLAGS) $(XML_CFLAGS) $(GST_CFLAGS)
+runxml_LDADD = $(GST_LIBS)
+runxml_CFLAGS = $(GLIB_CFLAGS) $(XML_CFLAGS) $(GST_CFLAGS)
diff --git a/gst/Makefile.am b/gst/Makefile.am
index f881cafd30b1d28c9d3cb2bd20035f55fc00b2be..4d09d49fa3030d0bc23bcc4dd261892a307e991f 100644 (file)
--- a/gst/Makefile.am
+++ b/gst/Makefile.am
EXTRA_libgst_la_SOURCES = gstcpuid_i386.s gstmarshal.list gobject2gtk.c gobject2gtk.h gstxml.c gsttypefind.c gstparse.c gstautoplug.c gsttrace.c
-SUBDIRS = . types elements $(GST_AUTOPLUG_DIRS)
-DIST_SUBDIRS = types elements autoplug
+SUBDIRS = . types elements $(GST_AUTOPLUG_DIRS) schedulers
+DIST_SUBDIRS = types elements autoplug schedulers
libgst_la_SOURCES = \
cothreads.c \
gstarch.h \
gstpropsprivate.h
-CFLAGS = \
- $(LIBGST_CFLAGS) \
+libgst_la_CFLAGS = -D_GNU_SOURCE -DGST_CONFIG_DIR=\""$(GST_CONFIG_DIR)"\" \
+ $(LIBGST_CFLAGS) $(XML_CFLAGS) $(GLIB_CFLAGS) \
-D_GNU_SOURCE \
-DG_LOG_DOMAIN=g_log_domain_gstreamer \
-DGST_CONFIG_DIR=\""$(GST_CONFIG_DIR)"\" \
- \
-W -Wpointer-arith -Wbad-function-cast \
-Wcast-align -Wsign-compare \
-Wmissing-prototypes -Wmissing-declarations \
-Wnested-externs \
-Winline -Wno-unused
-CFLAGS = $(LIBGST_CFLAGS) -D_GNU_SOURCE -DGST_CONFIG_DIR=\""$(GST_CONFIG_DIR)"\" -Wall
-LIBS = $(LIBGST_LIBS)
-LDFLAGS = ""
+libgst_la_LIBADD = $(XML_LIBS) $(GLIB_LIBS)
+
libgst_la_LDFLAGS = -version-info $(GST_LIBVERSION)
EXTRA_DIST = ROADMAP
index 9c84f3384ac31f20a0c2efbe958bfcd271528817..56211a67b331b9be11d8a388b4aeba78b6257a59 100644 (file)
--- a/gst/autoplug/Makefile.am
+++ b/gst/autoplug/Makefile.am
libgstautoplugcache_la_LDFLAGS = -version-info $(GST_LIBVERSION)
libgstautoplugger_la_LDFLAGS = -version-info $(GST_LIBVERSION)
+libgststaticautoplug_la_CFLAGS = $(GLIB_CFLAGS) $(XML_CFLAGS)
+libgststaticautoplugrender_la_CFLAGS = $(GLIB_CFLAGS) $(XML_CFLAGS)
+libgstautoplugcache_la_CFLAGS = $(GLIB_CFLAGS) $(XML_CFLAGS)
+libgstautoplugger_la_CFLAGS = $(GLIB_CFLAGS) $(XML_CFLAGS)
+
noinst_HEADERS = gststaticautoplug.h gststaticautoplugrender.h
noinst_PROGRAMS = autoplugtest
-autoplugtest_LDADD = $(GST_LIBS)
+
+autoplugtest_CFLAGS = $(GST_CFLAGS) $(GLIB_CFLAGS) $(XML_CFLAGS)
+autoplugtest_LDADD = $(GST_LIBS) $(GLIB_LIBS) $(XML_LIBS)
index 638528678857d87447e736423651065c1a31874e..bb8895f5c50954b860a7185b252cb7429f719c00 100644 (file)
gst_element_set_state (pipeline, GST_STATE_PAUSED);
gst_element_disconnect(src,"src",cache,"sink");
- gst_schedule_show (GST_ELEMENT_SCHED(pipeline));
+ gst_scheduler_show (GST_ELEMENT_SCHED(pipeline));
gst_element_disconnect(cache,"src",decoder,"sink");
- gst_schedule_show (GST_ELEMENT_SCHED(pipeline));
+ gst_scheduler_show (GST_ELEMENT_SCHED(pipeline));
gst_bin_remove (GST_BIN(autobin), cache);
- gst_schedule_show (GST_ELEMENT_SCHED(pipeline));
+ gst_scheduler_show (GST_ELEMENT_SCHED(pipeline));
gst_element_connect(src,"src",decoder,"sink");
- gst_schedule_show (GST_ELEMENT_SCHED(pipeline));
+ gst_scheduler_show (GST_ELEMENT_SCHED(pipeline));
gst_element_set_state (pipeline, GST_STATE_PLAYING);
- gst_schedule_show (GST_ELEMENT_SCHED(pipeline));
+ gst_scheduler_show (GST_ELEMENT_SCHED(pipeline));
fprintf(stderr,"done with cache_empty\n");
}
gst_element_disconnect(cache,"src",typefind,"sink");
gst_bin_remove(GST_BIN(autobin),typefind);
- gst_schedule_show (GST_ELEMENT_SCHED(pipeline));
+ gst_scheduler_show (GST_ELEMENT_SCHED(pipeline));
if (strstr(gst_caps_get_mime(caps),"mp3")) {
decoder = gst_elementfactory_make ("mad","decoder");
index 2306080b1c320ff1d373b1d14fed5e8a24010691..2530ad204998869d84b36e5776f3af11869de38c 100644 (file)
GST_DEBUG (0,"delaying the creation of a ghostpad for %s\n", GST_ELEMENT_NAME (thesrcelement));
g_signal_connect (G_OBJECT (thesrcelement), "new_pad",
G_CALLBACK (autoplug_dynamic_pad), data);
- g_signal_connect (G_OBJECT (thesrcelement), "new_ghost_pad",
- G_CALLBACK (autoplug_dynamic_pad), data);
}
}
}
index 0c71fffc0852c8407d59e59ced2717380051eb08..d4c9ad1a545655e455162c85cd982a16533fccca 100644 (file)
if (factory != NULL) {
gst_plugin_add_feature (plugin, GST_PLUGIN_FEATURE (factory));
}
+ else {
+ g_warning ("could not register autoplugger: staticrender");
+ }
return TRUE;
}
GST_ELEMENT_NAME(src), GST_ELEMENT_NAME(sink));
g_signal_connect (G_OBJECT(src),"new_pad",
G_CALLBACK (gst_autoplug_pads_autoplug_func), sink);
- g_signal_connect (G_OBJECT(src),"new_ghost_pad",
- G_CALLBACK (gst_autoplug_pads_autoplug_func), sink);
}
}
GST_DEBUG (0,"common factory \"%s\"\n", GST_OBJECT_NAME (factory));
- element = gst_elementfactory_create (factory, GST_OBJECT_NAME (factory));
+ element = gst_elementfactory_create (factory, g_strdup (GST_OBJECT_NAME (factory)));
gst_bin_add (GST_BIN(result), element);
if (srcelement != NULL) {
factory = (GstElementFactory *)(factories[i]->data);
GST_DEBUG (0,"factory \"%s\"\n", GST_OBJECT_NAME (factory));
- element = gst_elementfactory_create(factory, GST_OBJECT_NAME (factory));
+ element = gst_elementfactory_create(factory, g_strdup (GST_OBJECT_NAME (factory)));
}
else {
element = sinkelement;
if (GST_ELEMENT_IS_THREAD_SUGGESTED(element) || use_thread) {
GstElement *queue;
GstPad *srcpad;
+ GstElement *current_bin = thebin;
use_thread = FALSE;
gst_bin_add(GST_BIN(thebin), element);
gst_autoplug_signal_new_object (GST_AUTOPLUG (autoplug), GST_OBJECT (element));
GST_DEBUG (0,"adding element %s\n", GST_ELEMENT_NAME (thebin));
- gst_bin_add(GST_BIN(result), thebin);
+ gst_bin_add(GST_BIN(current_bin), thebin);
gst_autoplug_signal_new_object (GST_AUTOPLUG (autoplug), GST_OBJECT (thebin));
thesrcelement = queue;
}
index 64b75fce5a3b1fc07e6937fcc54226bdefb8b909..d9caf8310d18f88ebca2ebb066e81721e57372d9 100644 (file)
--- a/gst/elements/Makefile.am
+++ b/gst/elements/Makefile.am
GSTHTTPSRC=
endif
-#CFLAGS += -O2 -Wall -finstrument-functions -DGST_ENABLE_FUNC_INSTRUMENTATION
-
libgstelements_la_DEPENDENCIES = ../libgst.la
libgstelements_la_SOURCES = \
gstelements.c \
gstaggregator.h \
gststatistics.h
-CFLAGS += -O2 -Wall
-LDFLAGS += -lm
-
-libgstelements_la_LIBADD = $(GHTTP_LIBS)
+libgstelements_la_CFLAGS = $(GHTTP_CFLAGS) $(GLIB_CFLAGS) $(XML_CFLAGS)
+libgstelements_la_LIBADD = $(GHTTP_LIBS) $(GLIB_LIBS) $(XML_LIBS)
libgstelements_la_LDFLAGS = -version-info $(GST_LIBVERSION)
index 02eb921fa3ed07366a14675f254a66175357af7e..69b8740525c677686c3a96ad1f6c166bfb155e01 100644 (file)
@@ -213,14 +213,6 @@ gst_fakesink_get_property (GObject *object, guint prop_id, GValue *value, GParam
}
}
-/**
- * gst_fakesink_chain:
- * @pad: the pad this faksink is connected to
- * @buffer: the buffer or event that has to be absorbed
- *
- * Take the buffer or event from the pad and unref it without doing
- * anything with it.
- */
static void
gst_fakesink_chain (GstPad *pad, GstBuffer *buf)
{
fakesink = GST_FAKESINK (gst_pad_get_parent (pad));
- if (GST_IS_EVENT(buf)) {
- GstEvent *event = GST_EVENT (buf);
-
- switch (GST_EVENT_TYPE (event)) {
- case GST_EVENT_EOS:
- g_print("fakesink: have EOS event!\n");
- gst_element_set_state (GST_ELEMENT (fakesink), GST_STATE_PAUSED);
- break;
- default:
- g_print("fakesink: have unhandled event!\n");
- break;
- }
- gst_event_free (event);
+ /*
+ if (GST_IS_EVENT (buf)) {
+ gst_pad_event_default (pad, GST_EVENT (buf));
return;
}
+ */
if (!fakesink->silent)
g_print("fakesink: chain ******* (%s:%s)< (%d bytes, %lld) %p\n",
diff --git a/gst/gobject2gtk.h b/gst/gobject2gtk.h
index a14203a2630820eb362ef1e7f3993a630fc35f56..03bd676077753c7f0e377a1efa876a2d4328dd5b 100644 (file)
--- a/gst/gobject2gtk.h
+++ b/gst/gobject2gtk.h
g_signal_connect(object,name,func,func_data) \
gtk_signal_connect((GtkObject *)object,name,func,func_data)
+#define \
+g_signal_handlers_disconnect_by_func(object,func,func_data) \
+gtk_signal_disconnect_by_func((GtkObject *)object,func,func_data)
+
+#define \
+g_signal_connect_object(object,name,func,func_data) \
+gtk_signal_connect_object((GtkObject *)object,name,func,(GtkObject*)func_data)
+
#define \
g_signal_emit_by_name(object,name,data,self) \
gtk_signal_emit_by_name ((GtkObject *)object,name,data,self)
typedef struct _GParamSpec GParamSpec;
struct _GParamSpec {
gchar *name;
- gint value_type;
- gint flags;
+ GType value_type;
+ GParamFlags flags;
};
#define g_value_init(value,t) ((value)->type = (t))
diff --git a/gst/gst.c b/gst/gst.c
index c6afbb12d5da2da8cdbf7a7e297fe478a13b40d0..6b47f66aa85747145903cbff4daa8636e832bc95 100644 (file)
--- a/gst/gst.c
+++ b/gst/gst.c
#include "gst_private.h"
-#include "gstversion.h"
-#include "gstcpu.h"
-#include "gsttype.h"
-#include "gstplugin.h"
-#include "gstbuffer.h"
-#include "gstbin.h"
-#include "gstpipeline.h"
-#include "gstthread.h"
+#include "gst.h"
#include "gstqueue.h"
-#include "gstautoplug.h"
-#include "gstscheduler.h"
#ifndef GST_DISABLE_TYPEFIND
#include "gsttypefind.h"
#endif
gst_elementfactory_get_type ();
gst_element_get_type ();
gst_typefactory_get_type ();
- gst_schedule_get_type ();
+ gst_schedulerfactory_get_type ();
gst_bin_get_type ();
#ifndef GST_DISABLE_AUTOPLUG
gst_autoplugfactory_get_type ();
while (lastlist) {
strings = g_strsplit (lastlist, separator, MAX_PATH_SPLIT);
- //strings = g_strsplit (lastlist, G_SEARCHPATH_SEPARATOR_S, MAX_PATH_SPLIT);
g_free (lastlist);
lastlist = NULL;
diff --git a/gst/gst.h b/gst/gst.h
index 032d5d2c57fc24d4b6d0871b265f82c3b16cf917..5fed0630f8e02be1458d7faa4cd4f8e3fc9cac21 100644 (file)
--- a/gst/gst.h
+++ b/gst/gst.h
#endif /* __cplusplus */
/* initialize GST */
-void gst_init(int *argc,char **argv[]);
+void gst_init (int *argc, char **argv[]);
void gst_main (void);
void gst_main_quit (void);
diff --git a/gst/gstautoplug.c b/gst/gstautoplug.c
index c1c813e65e3b006ce91f42aa0f5320ca7860b31d..10e6df1b5471f6ae0d7604c445ba7f98c9ab9b0b 100644 (file)
--- a/gst/gstautoplug.c
+++ b/gst/gstautoplug.c
if (factory == NULL)
return NULL;
- return gst_autoplugfactory_create (factory);;
+ return gst_autoplugfactory_create (factory);
}
#ifndef GST_DISABLE_REGISTRY
diff --git a/gst/gstbin.c b/gst/gstbin.c
index 9a149d2b5ff8fb89ce938ba9bed1457076680097..579fce9a9a5d8c32e93d58a1706b24079c5de63d 100644 (file)
--- a/gst/gstbin.c
+++ b/gst/gstbin.c
static gboolean gst_bin_change_state_type (GstBin *bin,
GstElementState state,
GType type);
+static void gst_bin_child_state_change (GstBin *bin, GstElementState old,
+ GstElementState new, GstElement *child);
static gboolean gst_bin_iterate_func (GstBin *bin);
bin->children = NULL;
bin->eos_providers = NULL;
bin->num_eos_providers = 0;
- bin->chains = NULL;
bin->eoscond = g_cond_new ();
}
}
static inline void
-gst_bin_reset_element_sched (GstElement *element, GstSchedule *sched)
+gst_bin_reset_element_sched (GstElement *element, GstScheduler *sched)
{
GST_INFO_ELEMENT (GST_CAT_PARENTAGE, element, "resetting element's scheduler");
- // first remove the element from its current schedule, if any
-// if (GST_ELEMENT_SCHED(element))
-// GST_SCHEDULE_REMOVE_ELEMENT (GST_ELEMENT_SCHED(element), element);
- // then set the new manager
gst_element_set_sched (element,sched);
-
- // and add it to the new scheduler
-// if (sched)
-// GST_SCHEDULE_ADD_ELEMENT (sched, element);
}
static void
-gst_bin_set_element_sched (GstElement *element,GstSchedule *sched)
+gst_bin_set_element_sched (GstElement *element,GstScheduler *sched)
{
GList *children;
GstElement *child;
g_return_if_fail (element != NULL);
g_return_if_fail (GST_IS_ELEMENT(element));
g_return_if_fail (sched != NULL);
- g_return_if_fail (GST_IS_SCHEDULE(sched));
+ g_return_if_fail (GST_IS_SCHEDULER(sched));
GST_INFO (GST_CAT_SCHEDULING, "setting element \"%s\" sched to %p",GST_ELEMENT_NAME(element),
sched);
// if it's actually a Bin
if (GST_IS_BIN(element)) {
-
- if (GST_FLAG_IS_SET(element,GST_BIN_FLAG_MANAGER)) {
+ if (GST_FLAG_IS_SET (element, GST_BIN_FLAG_MANAGER)) {
GST_INFO_ELEMENT (GST_CAT_PARENTAGE, element, "child is already a manager, not resetting");
return;
}
GST_INFO_ELEMENT (GST_CAT_PARENTAGE, element, "setting children's schedule to parent's");
- GST_SCHEDULE_ADD_ELEMENT (sched, element);
+ gst_scheduler_add_element (sched, element);
// set the children's schedule
children = GST_BIN(element)->children;
// otherwise, if it's just a regular old element
} else {
- GST_SCHEDULE_ADD_ELEMENT (sched, element);
+ gst_scheduler_add_element (sched, element);
}
}
// FIXME this check should be irrelevant
if (GST_ELEMENT_SCHED (element))
- GST_SCHEDULE_REMOVE_ELEMENT (GST_ELEMENT_SCHED(element), element);
+ gst_scheduler_remove_element (GST_ELEMENT_SCHED(element), element);
// for each child, remove them from their schedule
children = GST_BIN(element)->children;
} else {
// FIXME this check should be irrelevant
if (GST_ELEMENT_SCHED (element))
- GST_SCHEDULE_REMOVE_ELEMENT (GST_ELEMENT_SCHED(element), element);
+ gst_scheduler_remove_element (GST_ELEMENT_SCHED(element), element);
}
}
g_return_if_fail (GST_IS_ELEMENT (element));
GST_DEBUG (GST_CAT_PARENTAGE, "adding element \"%s\" to bin \"%s\"\n",
- GST_ELEMENT_NAME(element),GST_ELEMENT_NAME(bin));
+ GST_ELEMENT_NAME (element), GST_ELEMENT_NAME (bin));
// must be not be in PLAYING state in order to modify bin
-// g_return_if_fail (GST_STATE (bin) != GST_STATE_PLAYING);
+ g_return_if_fail (GST_STATE (bin) != GST_STATE_PLAYING);
// the element must not already have a parent
- g_return_if_fail (GST_ELEMENT_PARENT(element) == NULL);
+ g_return_if_fail (GST_ELEMENT_PARENT (element) == NULL);
// then check to see if the element's name is already taken in the bin
- g_return_if_fail (gst_object_check_uniqueness (bin->children, GST_ELEMENT_NAME(element)) == TRUE);
+ g_return_if_fail (gst_object_check_uniqueness (bin->children, GST_ELEMENT_NAME (element)) == TRUE);
// set the element's parent and add the element to the bin's list of children
gst_object_set_parent (GST_OBJECT (element), GST_OBJECT (bin));
+ g_signal_connect_object (G_OBJECT (element), "state_change", gst_bin_child_state_change, G_OBJECT (bin));
+
bin->children = g_list_append (bin->children, element);
bin->numchildren++;
///// now we have to deal with manager stuff
// we can only do this if there's a scheduler:
// if we're not a manager, and aren't attached to anything, we have no sched (yet)
- if (GST_ELEMENT_SCHED(bin) != NULL)
- gst_bin_set_element_sched (element, GST_ELEMENT_SCHED(bin));
+ if (GST_IS_BIN(element) && GST_FLAG_IS_SET (element, GST_BIN_FLAG_MANAGER)) {
+ GST_INFO_ELEMENT (GST_CAT_PARENTAGE, element, "child is a manager");
+ }
+ else if (GST_ELEMENT_SCHED (bin) != NULL) {
+ gst_bin_set_element_sched (element, GST_ELEMENT_SCHED (bin));
+ }
GST_INFO_ELEMENT (GST_CAT_PARENTAGE, bin, "added child \"%s\"", GST_ELEMENT_NAME (element));
gst_element_set_state (GST_ELEMENT (bin), GST_STATE_NULL);
}
+static void
+gst_bin_child_state_change (GstBin *bin, GstElementState old, GstElementState new, GstElement *child)
+{
+ gint old_idx = 0, new_idx = 0, i;
+
+ GST_INFO (GST_CAT_STATES, "child %s changed state in bin %s from %s to %s",
+ GST_ELEMENT_NAME (child), GST_ELEMENT_NAME (bin),
+ gst_element_statename (old), gst_element_statename (new));
+
+ while (old>>=1) old_idx++;
+ while (new>>=1) new_idx++;
+
+ GST_LOCK (bin);
+ bin->child_states[old_idx]--;
+ bin->child_states[new_idx]++;
+
+ for (i = GST_NUM_STATES-1; i >= 0; i--) {
+ if (bin->child_states[i] != 0) {
+ if (GST_STATE (bin) != (1 << i)) {
+ GST_INFO (GST_CAT_STATES, "bin %s need state change to %s",
+ GST_ELEMENT_NAME (bin), gst_element_statename (1<<i));
+ GST_STATE_PENDING (bin) = (1<<i);
+ gst_bin_change_state_norecurse (bin);
+ }
+ break;
+ }
+ }
+ // FIXME, need to setup this array at add/remove time
+ if (i<0) {
+ GST_STATE_PENDING (bin) = GST_STATE_NULL;
+ gst_bin_change_state_norecurse (bin);
+ }
+
+ GST_UNLOCK (bin);
+}
static GstElementStateReturn
gst_bin_change_state (GstElement *element)
GList *children;
GstElement *child;
GstElementStateReturn ret;
-
-// GST_DEBUG_ENTER("(\"%s\")",GST_ELEMENT_NAME (element));
+ GstElementState old_state, pending;
+ gboolean have_async = FALSE;
g_return_val_if_fail (GST_IS_BIN (element), GST_STATE_FAILURE);
bin = GST_BIN (element);
-// GST_DEBUG (GST_CAT_STATES,"currently %d(%s), %d(%s) pending\n",GST_STATE (element),
-// gst_element_statename (GST_STATE (element)), GST_STATE_PENDING (element),
-// gst_element_statename (GST_STATE_PENDING (element)));
+ old_state = GST_STATE (element);
+ pending = GST_STATE_PENDING (element);
GST_INFO_ELEMENT (GST_CAT_STATES, element, "changing childrens' state from %s to %s",
- gst_element_statename (GST_STATE (element)),
- gst_element_statename (GST_STATE_PENDING (element)));
-
-// g_return_val_if_fail(bin->numchildren != 0, GST_STATE_FAILURE);
+ gst_element_statename (old_state),
+ gst_element_statename (pending));
-
-// g_print("-->\n");
children = bin->children;
while (children) {
child = GST_ELEMENT (children->data);
-// GST_DEBUG (GST_CAT_STATES,"setting state on '%s'\n",GST_ELEMENT_NAME (child));
- switch (gst_element_set_state (child, GST_STATE_PENDING (element))) {
+ children = g_list_next (children);
+
+ switch (gst_element_set_state (child, pending)) {
case GST_STATE_FAILURE:
GST_STATE_PENDING (element) = GST_STATE_VOID_PENDING;
GST_DEBUG (GST_CAT_STATES,"child '%s' failed to go to state %d(%s)\n", GST_ELEMENT_NAME (child),
- GST_STATE_PENDING (element), gst_element_statename (GST_STATE_PENDING (element)));
- return GST_STATE_FAILURE;
+ pending, gst_element_statename (pending));
+
+ gst_element_set_state (child, old_state);
+ if (GST_ELEMENT_SCHED (child) == GST_ELEMENT_SCHED (element)) {
+ return GST_STATE_FAILURE;
+ }
break;
case GST_STATE_ASYNC:
GST_DEBUG (GST_CAT_STATES,"child '%s' is changing state asynchronously\n", GST_ELEMENT_NAME (child));
+ have_async = TRUE;
break;
}
-// g_print("\n");
- children = g_list_next (children);
}
-// 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_element_statename (GST_STATE (element)),
- gst_element_statename (GST_STATE_PENDING (element)));
- ret = gst_bin_change_state_norecurse (bin);
+ gst_element_statename (old_state),
+ gst_element_statename (pending));
+
+ if (have_async)
+ ret = GST_STATE_ASYNC;
+ else
+ ret = GST_STATE_SUCCESS;
return ret;
}
}
static gboolean
-gst_bin_change_state_type(GstBin *bin,
- GstElementState state,
- GType type)
+gst_bin_change_state_type (GstBin *bin,
+ GstElementState state,
+ GType type)
{
GList *children;
GstElement *child;
-// g_print("gst_bin_change_state_type(\"%s\",%d,%d);\n",
-// GST_OBJECT_NAME(bin))),state,type);
-
g_return_val_if_fail (GST_IS_BIN (bin), FALSE);
g_return_val_if_fail (bin->numchildren != 0, FALSE);
-// g_print("-->\n");
children = bin->children;
while (children) {
child = GST_ELEMENT (children->data);
if (!gst_element_set_state (child,state))
return FALSE;
}
-// g_print("\n");
children = g_list_next (children);
}
if (type == GST_TYPE_BIN)
- gst_element_set_state (GST_ELEMENT (bin),state);
+ gst_element_set_state (GST_ELEMENT (bin), state);
return TRUE;
}
}
#endif /* GST_DISABLE_LOADSAVE */
+static gboolean
+gst_bin_iterate_func (GstBin *bin)
+{
+ // only iterate if this is the manager bin
+ if (GST_ELEMENT_SCHED(bin)->parent == GST_ELEMENT (bin)) {
+ return gst_scheduler_iterate (GST_ELEMENT_SCHED(bin));
+ } else {
+ g_warning ("bin \"%d\" can't be iterated on!\n", GST_ELEMENT_NAME (bin));
+ }
+
+ return FALSE;
+}
/**
* gst_bin_iterate:
GST_DEBUG_LEAVE("(\"%s\")",GST_ELEMENT_NAME (bin));
-// if (!running)
- // gst_element_set_state (GST_ELEMENT (bin), GST_STATE_PAUSED);
+ if (!running) {
+ if (GST_STATE (bin) == GST_STATE_PLAYING && GST_STATE_PENDING (bin) == GST_STATE_VOID_PENDING) {
+ GST_DEBUG_ELEMENT (GST_CAT_DATAFLOW, bin, "waiting for child shutdown after useless iteration\n");
+ //gst_element_set_state (GST_ELEMENT (bin), GST_STATE_PAUSED);
+ gst_element_wait_state_change (GST_ELEMENT (bin));
+ GST_DEBUG_ELEMENT (GST_CAT_DATAFLOW, bin, "child shutdown\n");
+ }
+ }
return running;
}
GST_UNLOCK (bin);
}
-typedef struct {
- gulong offset;
- gulong size;
-} region_struct;
-
-
-static gboolean
-gst_bin_iterate_func (GstBin *bin)
-{
- // only iterate if this is the manager bin
- if (GST_ELEMENT_SCHED(bin)->parent == GST_ELEMENT (bin)) {
- return GST_SCHEDULE_ITERATE(GST_ELEMENT_SCHED(bin));
- } else {
- GST_DEBUG (GST_CAT_SCHEDULING, "this bin can't be iterated on!\n");
- }
-
- return FALSE;
-}
-
diff --git a/gst/gstbin.h b/gst/gstbin.h
index f8e2c6d7cace30b0462acadb31deea18676eb752..2a9c22cf9fe42e11c548c01c79d1b26f09e13d04 100644 (file)
--- a/gst/gstbin.h
+++ b/gst/gstbin.h
//typedef struct _GstBin GstBin;
//typedef struct _GstBinClass GstBinClass;
-typedef struct __GstBinChain _GstBinChain;
struct _GstBin {
GstElement element;
GList *eos_providers;
GCond *eoscond;
- /* iteration state */
- gboolean need_cothreads;
- GList *managed_elements;
- gint num_managed_elements;
-
- GList *chains;
- gint num_chains;
- GList *entries;
- gint num_entries;
-
+ GstElementState child_states[GST_NUM_STATES];
+
cothread_context *threadcontext;
};
gboolean (*iterate) (GstBin *bin);
};
-struct __GstBinChain {
- GList *elements;
- gint num_elements;
-
- GList *entries;
-
- gboolean need_cothreads;
- gboolean need_scheduling;
-};
-
-
GType gst_bin_get_type (void);
GstElement* gst_bin_new (const gchar *name);
#define gst_bin_destroy(bin) gst_object_destroy(GST_OBJECT(bin))
/* add and remove elements from the bin */
-void gst_bin_add (GstBin *bin,
- GstElement *element);
-void gst_bin_remove (GstBin *bin,
- GstElement *element);
+void gst_bin_add (GstBin *bin, GstElement *element);
+void gst_bin_remove (GstBin *bin, GstElement *element);
/* retrieve a single element or the list of children */
-GstElement* gst_bin_get_by_name (GstBin *bin,
- const gchar *name);
-GstElement* gst_bin_get_by_name_recurse_up (GstBin *bin,
- const gchar *name);
+GstElement* gst_bin_get_by_name (GstBin *bin, const gchar *name);
+GstElement* gst_bin_get_by_name_recurse_up (GstBin *bin, const gchar *name);
GList* gst_bin_get_list (GstBin *bin);
-gboolean gst_bin_set_state_type (GstBin *bin,
- GstElementState state,
- GType type);
+gboolean gst_bin_set_state_type (GstBin *bin, GstElementState state, GType type);
gboolean gst_bin_iterate (GstBin *bin);
diff --git a/gst/gstbuffer.c b/gst/gstbuffer.c
index 1a45f4f83bcab0d97f9ae1500e8b2a62c600eb85..eedf8fd9f1b1dea0a52b1b38b92847e0e7b8e0ed 100644 (file)
--- a/gst/gstbuffer.c
+++ b/gst/gstbuffer.c
0, // sizeof(object),
0,
NULL,
+ NULL,
};
// round up to the nearest 32 bytes for cache-line and other efficiencies
buffer->maxsize = parent->size - offset;
// deal with bogus/unknown offsets
- if (parent->offset != -1)
+ if (parent->offset != (guint32)-1)
buffer->offset = parent->offset + offset;
else
- buffer->offset = -1;
+ buffer->offset = (guint32)-1;
// again, for lack of better, copy parent's timestamp
buffer->timestamp = parent->timestamp;
newbuf->data = g_malloc (newbuf->size);
memcpy (newbuf->data, buffer->data, buffer->size);
memcpy (newbuf->data+buffer->size, append->data, append->size);
+ GST_BUFFER_TIMESTAMP (newbuf) = GST_BUFFER_TIMESTAMP (buffer);
GST_BUFFER_UNLOCK (buffer);
gst_buffer_unref (buffer);
buffer = newbuf;
// copy the second buffer's data across
memcpy(newbuf->data + (buf1->size - offset), buf2->data, len - (buf1->size - offset));
- if (newbuf->offset != -1)
+ if (newbuf->offset != (guint32)-1)
newbuf->offset = buf1->offset + offset;
newbuf->timestamp = buf1->timestamp;
if (buf2->maxage > buf1->maxage) newbuf->maxage = buf2->maxage;
@@ -518,6 +520,11 @@ gst_buffer_span (GstBuffer *buf1, guint32 offset, GstBuffer *buf2, guint32 len)
GstBuffer *
gst_buffer_merge (GstBuffer *buf1, GstBuffer *buf2)
{
+ GstBuffer *result;
// we're just a specific case of the more general gst_buffer_span()
- return gst_buffer_span (buf1, 0, buf2, buf1->size + buf2->size);
+ result = gst_buffer_span (buf1, 0, buf2, buf1->size + buf2->size);
+
+ GST_BUFFER_TIMESTAMP (result) = GST_BUFFER_TIMESTAMP (buf1);
+
+ return result;
}
diff --git a/gst/gstelement.c b/gst/gstelement.c
index e7597af6a66d5c7bb3bb1000623669653646aa23..bcf8d50f3c4d2b31976991d74a349d075e480e9c 100644 (file)
--- a/gst/gstelement.c
+++ b/gst/gstelement.c
*/
//#define GST_DEBUG_ENABLED
+#include <glib.h>
#include "gst_private.h"
#include "gstelement.h"
STATE_CHANGE,
NEW_PAD,
PAD_REMOVED,
- NEW_GHOST_PAD,
- GHOST_PAD_REMOVED,
ERROR,
EOS,
LAST_SIGNAL
gst_element_signals[STATE_CHANGE] =
g_signal_new ("state_change", G_TYPE_FROM_CLASS(klass), G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (GstElementClass, state_change), NULL, NULL,
- gst_marshal_VOID__INT, G_TYPE_NONE, 1,
- G_TYPE_INT);
+ G_STRUCT_OFFSET (GstElementClass, state_change), NULL, NULL,
+ gst_marshal_VOID__INT_INT, G_TYPE_NONE, 2,
+ G_TYPE_INT, G_TYPE_INT);
gst_element_signals[NEW_PAD] =
g_signal_new ("new_pad", G_TYPE_FROM_CLASS(klass), G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (GstElementClass, new_pad), NULL, NULL,
- gst_marshal_VOID__OBJECT, G_TYPE_NONE, 1,
- GST_TYPE_PAD);
+ G_STRUCT_OFFSET (GstElementClass, new_pad), NULL, NULL,
+ gst_marshal_VOID__OBJECT, G_TYPE_NONE, 1,
+ GST_TYPE_PAD);
gst_element_signals[PAD_REMOVED] =
g_signal_new ("pad_removed", G_TYPE_FROM_CLASS(klass), G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (GstElementClass, pad_removed), NULL, NULL,
- gst_marshal_VOID__OBJECT, G_TYPE_NONE, 1,
- GST_TYPE_PAD);
- gst_element_signals[NEW_GHOST_PAD] =
- g_signal_new ("new_ghost_pad", G_TYPE_FROM_CLASS(klass), G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (GstElementClass, new_ghost_pad), NULL, NULL,
- gst_marshal_VOID__OBJECT, G_TYPE_NONE, 1,
- GST_TYPE_PAD);
- gst_element_signals[GHOST_PAD_REMOVED] =
- g_signal_new ("ghost_pad_removed", G_TYPE_FROM_CLASS(klass), G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (GstElementClass, ghost_pad_removed), NULL, NULL,
- gst_marshal_VOID__OBJECT, G_TYPE_NONE, 1,
- GST_TYPE_PAD);
+ G_STRUCT_OFFSET (GstElementClass, pad_removed), NULL, NULL,
+ gst_marshal_VOID__OBJECT, G_TYPE_NONE, 1,
+ GST_TYPE_PAD);
gst_element_signals[ERROR] =
g_signal_new ("error", G_TYPE_FROM_CLASS(klass), G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (GstElementClass, error), NULL, NULL,
- gst_marshal_VOID__STRING, G_TYPE_NONE,1,
- G_TYPE_STRING);
+ G_STRUCT_OFFSET (GstElementClass, error), NULL, NULL,
+ gst_marshal_VOID__STRING, G_TYPE_NONE,1,
+ G_TYPE_STRING);
gst_element_signals[EOS] =
g_signal_new ("eos", G_TYPE_FROM_CLASS(klass), G_SIGNAL_RUN_LAST,
- G_STRUCT_OFFSET (GstElementClass,eos), NULL, NULL,
- gst_marshal_VOID__VOID, G_TYPE_NONE, 0);
+ G_STRUCT_OFFSET (GstElementClass,eos), NULL, NULL,
+ gst_marshal_VOID__VOID, G_TYPE_NONE, 0);
- gobject_class->set_property = GST_DEBUG_FUNCPTR(gst_element_set_property);
- gobject_class->get_property = GST_DEBUG_FUNCPTR(gst_element_get_property);
- gobject_class->dispose = GST_DEBUG_FUNCPTR(gst_element_dispose);
+ gobject_class->set_property = GST_DEBUG_FUNCPTR (gst_element_set_property);
+ gobject_class->get_property = GST_DEBUG_FUNCPTR (gst_element_get_property);
+ gobject_class->dispose = GST_DEBUG_FUNCPTR (gst_element_dispose);
#ifndef GST_DISABLE_LOADSAVE
- gstobject_class->save_thyself = GST_DEBUG_FUNCPTR(gst_element_save_thyself);
- gstobject_class->restore_thyself = GST_DEBUG_FUNCPTR(gst_element_restore_thyself);
+ gstobject_class->save_thyself = GST_DEBUG_FUNCPTR (gst_element_save_thyself);
+ gstobject_class->restore_thyself = GST_DEBUG_FUNCPTR (gst_element_restore_thyself);
#endif
- klass->change_state = GST_DEBUG_FUNCPTR(gst_element_change_state);
- klass->elementfactory = NULL;
- klass->padtemplates = NULL;
- klass->numpadtemplates = 0;
+ klass->change_state = GST_DEBUG_FUNCPTR (gst_element_change_state);
+ klass->elementfactory = NULL;
+ klass->padtemplates = NULL;
+ klass->numpadtemplates = 0;
}
static void
@@ -184,12 +173,8 @@ gst_element_set_property (GObject *object, guint prop_id, const GValue *value, G
{
GstElementClass *oclass = (GstElementClass *)G_OBJECT_GET_CLASS(object);
- GST_SCHEDULE_LOCK_ELEMENT ( GST_ELEMENT_SCHED(object), GST_ELEMENT(object) );
-
if (oclass->set_property)
(oclass->set_property)(object,prop_id,value,pspec);
-
- GST_SCHEDULE_UNLOCK_ELEMENT ( GST_ELEMENT_SCHED(object), GST_ELEMENT(object) );
}
@@ -198,12 +183,8 @@ gst_element_get_property (GObject *object, guint prop_id, GValue *value, GParamS
{
GstElementClass *oclass = (GstElementClass *)G_OBJECT_GET_CLASS(object);
- GST_SCHEDULE_LOCK_ELEMENT (GST_ELEMENT_SCHED(object), GST_ELEMENT(object) );
-
if (oclass->get_property)
(oclass->get_property)(object,prop_id,value,pspec);
-
- GST_SCHEDULE_UNLOCK_ELEMENT (GST_ELEMENT_SCHED(object), GST_ELEMENT(object) );
}
GST_DEBUG(GST_CAT_ELEMENT_PADS,"added ghostpad %s:%s\n",GST_DEBUG_PAD_NAME(ghostpad));
/* emit the NEW_GHOST_PAD signal */
- g_signal_emit (G_OBJECT (element), gst_element_signals[NEW_GHOST_PAD], 0, ghostpad);
+ g_signal_emit (G_OBJECT (element), gst_element_signals[NEW_PAD], 0, ghostpad);
}
/**
return GST_STATE (element);
}
+static void
+gst_element_wait_done (GstElement *element, GstElementState old, GstElementState new, GCond *cond)
+{
+ g_signal_handlers_disconnect_by_func (G_OBJECT (element), gst_element_wait_done, cond);
+ g_cond_signal (cond);
+}
+
+void
+gst_element_wait_state_change (GstElement *element)
+{
+ GCond *cond = g_cond_new ();
+ GMutex *mutex = g_mutex_new ();
+
+ g_mutex_lock (mutex);
+ g_signal_connect (G_OBJECT (element), "state_change", gst_element_wait_done, cond);
+ g_cond_wait (cond, mutex);
+ g_mutex_unlock (mutex);
+
+ g_mutex_free (mutex);
+ g_cond_free (cond);
+}
/**
* gst_element_set_state:
* @element: element to change state of
curpending = GST_STATE(element);
/* loop until the final requested state is set */
- while (GST_STATE(element) != state) {
+ while (GST_STATE(element) != state && GST_STATE (element) != GST_STATE_VOID_PENDING) {
/* move the curpending state in the correct direction */
if (curpending < state) curpending<<=1;
else curpending>>=1;
if (oclass->change_state)
return_val = (oclass->change_state)(element);
- /* if that outright didn't work, we need to bail right away */
- /* NOTE: this will bail on ASYNC as well! */
- if (return_val == GST_STATE_FAILURE) {
- GST_DEBUG_ELEMENT (GST_CAT_STATES,element,"have failed change_state return\n");
- return return_val;
+ switch (return_val) {
+ case GST_STATE_FAILURE:
+ GST_DEBUG_ELEMENT (GST_CAT_STATES,element,"have failed change_state return\n");
+ return return_val;
+ case GST_STATE_ASYNC:
+ GST_DEBUG_ELEMENT (GST_CAT_STATES,element,"element will change state async\n");
+ return return_val;
+ default:
+ /* Last thing we do is verify that a successful state change really
+ * did change the state... */
+ if (GST_STATE(element) != curpending) {
+ GST_DEBUG_ELEMENT (GST_CAT_STATES, element, "element claimed state-change success, but state didn't change\n");
+ return GST_STATE_FAILURE;
+ }
+ break;
}
+ }
- /* Last thing we do is verify that a successful state change really
- * did change the state... */
- if (GST_STATE(element) != curpending) {
- GST_DEBUG_ELEMENT (GST_CAT_STATES, element, "element claimed state-change success, but state didn't change\n");
- return GST_STATE_FAILURE;
+ return return_val;
+}
+
+static GstElementStateReturn
+gst_element_change_state (GstElement *element)
+{
+ GstElementState old_state;
+
+ g_return_val_if_fail (element != NULL, GST_STATE_FAILURE);
+ g_return_val_if_fail (GST_IS_ELEMENT (element), GST_STATE_FAILURE);
+
+ old_state = GST_STATE (element);
+
+ if (GST_STATE_PENDING (element) == GST_STATE_VOID_PENDING || old_state == GST_STATE_PENDING (element)) {
+ g_warning ("no state change needed for element %s (VOID_PENDING)\n", GST_ELEMENT_NAME (element));
+ return GST_STATE_SUCCESS;
+ }
+
+ GST_INFO (GST_CAT_STATES, "%s default handler sets state from %s to %s %d", GST_ELEMENT_NAME (element),
+ gst_element_statename (old_state),
+ gst_element_statename (GST_STATE_PENDING (element)),
+ GST_STATE_TRANSITION (element));
+
+ if (GST_STATE_TRANSITION (element) == GST_STATE_PAUSED_TO_PLAYING) {
+ g_return_val_if_fail (GST_ELEMENT_SCHED (element), GST_STATE_FAILURE);
+
+ if (GST_ELEMENT_PARENT (element)) {
+ GST_DEBUG (GST_CAT_STATES, "PAUSED->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_scheduler_enable_element (element->sched, element);
+ }
+ else if (GST_STATE_TRANSITION (element) == GST_STATE_PLAYING_TO_PAUSED) {
+ if (GST_ELEMENT_PARENT (element)) {
+ GST_DEBUG (GST_CAT_STATES, "PLAYING->PAUSED: 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_scheduler_disable_element (element->sched, element);
}
- return return_val;
+ GST_STATE (element) = GST_STATE_PENDING (element);
+ GST_STATE_PENDING (element) = GST_STATE_VOID_PENDING;
+
+ // note: queues' state_change is a special case because it needs to lock
+ // for synchronization (from another thread). since this signal may block
+ // or (worse) make another state change, the queue needs to unlock before
+ // calling. thus, gstqueue.c::gst_queue_state_change() blocks, unblocks,
+ // unlocks, then emits this.
+ g_signal_emit (G_OBJECT (element), gst_element_signals[STATE_CHANGE], 0,
+ old_state, GST_STATE (element));
+
+ return GST_STATE_SUCCESS;
}
/**
return oclass->elementfactory;
}
-
-/**
- * gst_element_change_state:
- * @element: element to change state of
- *
- * Changes the state of the element, but more importantly fires off a signal
- * indicating the new state.
- * The element will have no pending states anymore.
- *
- * Returns: whether or not the state change was successfully set.
- */
-GstElementStateReturn
-gst_element_change_state (GstElement *element)
-{
- g_return_val_if_fail (element != NULL, GST_STATE_FAILURE);
- g_return_val_if_fail (GST_IS_ELEMENT (element), GST_STATE_FAILURE);
-
-// GST_DEBUG_ELEMENT (GST_CAT_STATES, element, "default handler sets state to %s\n",
-// gst_element_statename(GST_STATE_PENDING(element)));
-
- if (GST_STATE_TRANSITION(element) == GST_STATE_PAUSED_TO_PLAYING) {
- g_return_val_if_fail(GST_ELEMENT_SCHED(element), GST_STATE_FAILURE);
- if (GST_ELEMENT_PARENT(element))
- GST_DEBUG(GST_CAT_STATES,"PAUSED->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_PAUSED) {
- if (GST_ELEMENT_PARENT(element))
- GST_DEBUG(GST_CAT_STATES,"PLAYING->PAUSED: 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_DISABLE_ELEMENT (element->sched,element);
- }
-
- GST_STATE (element) = GST_STATE_PENDING (element);
- GST_STATE_PENDING (element) = GST_STATE_VOID_PENDING;
-
- // note: queues' state_change is a special case because it needs to lock
- // for synchronization (from another thread). since this signal may block
- // or (worse) make another state change, the queue needs to unlock before
- // calling. thus, gstqueue.c::gst_queue_state_change() blocks, unblocks,
- // unlocks, then emits this.
- g_signal_emit (G_OBJECT (element), gst_element_signals[STATE_CHANGE], 0,
- GST_STATE (element));
- return GST_STATE_SUCCESS;
-}
-
static void
gst_element_dispose (GObject *object)
{
/**
* gst_element_set_sched:
* @element: Element to set manager of.
- * @sched: @GstSchedule to set.
+ * @sched: @GstScheduler to set.
*
* Sets the scheduler of the element. For internal use only, unless you're
* writing a new bin subclass.
*/
void
gst_element_set_sched (GstElement *element,
- GstSchedule *sched)
+ GstScheduler *sched)
{
GST_INFO_ELEMENT (GST_CAT_PARENTAGE, element, "setting scheduler to %p",sched);
element->sched = sched;
*
* Returns: Element's scheduler
*/
-GstSchedule*
+GstScheduler*
gst_element_get_sched (GstElement *element)
{
return element->sched;
case GST_STATE_READY: return "\033[01;31mREADY\033[00m";break;
case GST_STATE_PLAYING: return "\033[01;32mPLAYING\033[00m";break;
case GST_STATE_PAUSED: return "\033[01;33mPAUSED\033[00m";break;
- default: return "\033[01;37;41mUNKNOWN!\033[00m";
+ default: return g_strdup_printf ("\033[01;37;41mUNKNOWN!\033[00m(%d)", state);
#else
case GST_STATE_VOID_PENDING: return "NONE_PENDING";break;
case GST_STATE_NULL: return "NULL";break;
diff --git a/gst/gstelement.h b/gst/gstelement.h
index 9748e9b6d450c2e65925d2533c6de2ba8a6ece9e..41197eb302802ddfcb7071482f1896151dffb014 100644 (file)
--- a/gst/gstelement.h
+++ b/gst/gstelement.h
extern "C" {
#endif /* __cplusplus */
+#define GST_NUM_STATES 4
typedef enum {
GST_STATE_VOID_PENDING = 0,
/* the element has to be scheduled as a cothread for any sanity */
GST_ELEMENT_USE_COTHREAD,
- /* if this element is in EOS */
- GST_ELEMENT_EOS,
-
/* if this element can handle events */
GST_ELEMENT_EVENT_AWARE,
guint8 current_state;
guint8 pending_state;
GstElement *manager;
- GstSchedule *sched;
+ GstScheduler *sched;
GstElementLoopFunction loopfunc;
cothread_state *threadstate;
gint numpadtemplates;
/* signal callbacks */
- void (*state_change) (GstElement *element,GstElementState state);
- void (*new_pad) (GstElement *element,GstPad *pad);
- void (*pad_removed) (GstElement *element,GstPad *pad);
- void (*new_ghost_pad) (GstElement *element,GstPad *pad);
- void (*ghost_pad_removed) (GstElement *element,GstPad *pad);
- void (*error) (GstElement *element,gchar *error);
+ void (*state_change) (GstElement *element, GstElementState old, GstElementState state);
+ void (*new_pad) (GstElement *element, GstPad *pad);
+ void (*pad_removed) (GstElement *element, GstPad *pad);
+ void (*error) (GstElement *element, gchar *error);
void (*eos) (GstElement *element);
/* local pointers for get/set */
void gst_element_set_parent (GstElement *element, GstObject *parent);
GstObject* gst_element_get_parent (GstElement *element);
-void gst_element_set_sched (GstElement *element, GstSchedule *sched);
-GstSchedule* gst_element_get_sched (GstElement *element);
+void gst_element_set_sched (GstElement *element, GstScheduler *sched);
+GstScheduler* gst_element_get_sched (GstElement *element);
void gst_element_add_pad (GstElement *element, GstPad *pad);
void gst_element_remove_pad (GstElement *element, GstPad *pad);
GstElementState gst_element_get_state (GstElement *element);
-/* called by the app to set the state of the element */
gint gst_element_set_state (GstElement *element, GstElementState state);
-const gchar * gst_element_statename (GstElementState state);
+
+void gst_element_wait_state_change (GstElement *element);
+
+const gchar* gst_element_statename (GstElementState state);
void gst_element_error (GstElement *element, const gchar *error);
index b2079f9589ad3a44f0940fc585731d1fe37b369a..4fcb8864c0b10f371df0edd4395b58f0af1790ee 100644 (file)
--- a/gst/gstelementfactory.c
+++ b/gst/gstelementfactory.c
#include "gstelement.h"
-static void gst_elementfactory_class_init (GstElementFactoryClass *klass);
-static void gst_elementfactory_init (GstElementFactory *factory);
+static void gst_elementfactory_class_init (GstElementFactoryClass *klass);
+static void gst_elementfactory_init (GstElementFactory *factory);
#ifndef GST_DISABLE_REGISTRY
-static void gst_elementfactory_restore_thyself (GstObject *object, xmlNodePtr parent);
-static xmlNodePtr gst_elementfactory_save_thyself (GstObject *object, xmlNodePtr parent);
+static void gst_elementfactory_restore_thyself (GstObject *object, xmlNodePtr parent);
+static xmlNodePtr gst_elementfactory_save_thyself (GstObject *object, xmlNodePtr parent);
#endif
-static void gst_elementfactory_unload_thyself (GstPluginFeature *feature);
+static void gst_elementfactory_unload_thyself (GstPluginFeature *feature);
/* global list of registered elementfactories */
static GList* _gst_elementfactories;
diff --git a/gst/gstevent.c b/gst/gstevent.c
index e06ed50ccaa0210dcb7d0f5c29a2dac69d630e4d..f4f289cfc1353fbce215734f253700bdc0745c88 100644 (file)
--- a/gst/gstevent.c
+++ b/gst/gstevent.c
0,
0,
NULL,
+ NULL,
};
// round up to the nearest 32 bytes for cache-line and other efficiencies
diff --git a/gst/gstpad.c b/gst/gstpad.c
index c753d01b83ecb2f3e02e71f702558952145d9b86..a0d6558aca9db5a7ce3e82ead4e6ad6929020546 100644 (file)
--- a/gst/gstpad.c
+++ b/gst/gstpad.c
// now tell the scheduler
if (realsrc->sched)
- GST_SCHEDULE_PAD_DISCONNECT (realsrc->sched, (GstPad *)realsrc, (GstPad *)realsink);
-// if (realsink->sched)
-// GST_SCHEDULE_PAD_DISCONNECT (realsink->sched, (GstPad *)realsrc, (GstPad *)realsink);
+ gst_scheduler_pad_connect (realsrc->sched, (GstPad *)realsrc, (GstPad *)realsink);
GST_INFO (GST_CAT_ELEMENT_PADS, "disconnected %s:%s and %s:%s",
GST_DEBUG_PAD_NAME(srcpad), GST_DEBUG_PAD_NAME(sinkpad));
// now tell the scheduler(s)
if (realsrc->sched)
- GST_SCHEDULE_PAD_CONNECT (realsrc->sched, (GstPad *)realsrc, (GstPad *)realsink);
+ gst_scheduler_pad_connect (realsrc->sched, (GstPad *)realsrc, (GstPad *)realsink);
else if (realsink->sched)
- GST_SCHEDULE_PAD_CONNECT (realsink->sched, (GstPad *)realsrc, (GstPad *)realsink);
+ gst_scheduler_pad_connect (realsink->sched, (GstPad *)realsrc, (GstPad *)realsink);
GST_INFO (GST_CAT_PADS, "connected %s:%s and %s:%s",
GST_DEBUG_PAD_NAME(srcpad), GST_DEBUG_PAD_NAME(sinkpad));
* Set the sceduler for the pad
*/
void
-gst_pad_set_sched (GstPad *pad, GstSchedule *sched)
+gst_pad_set_sched (GstPad *pad, GstScheduler *sched)
{
g_return_if_fail (pad != NULL);
g_return_if_fail (GST_IS_PAD (pad));
*
* Returns: the scheduler of the pad.
*/
-GstSchedule*
+GstScheduler*
gst_pad_get_sched (GstPad *pad)
{
g_return_val_if_fail (pad != NULL, NULL);
{
GstPad *pad;
- pad = gst_schedule_pad_select (gst_pad_get_sched (GST_PAD (padlist->data)), padlist);
+ pad = gst_scheduler_pad_select (gst_pad_get_sched (GST_PAD (padlist->data)), padlist);
return pad;
}
GList *pads = element->pads;
while (pads) {
- if (GST_PAD_DIRECTION (pads->data) == GST_PAD_SRC) {
+ if (GST_PAD_DIRECTION (pads->data) == GST_PAD_SRC && GST_PAD_CONNECTED (pads->data)) {
gst_pad_push (GST_PAD (pads->data), GST_BUFFER (gst_event_new (GST_EVENT_TYPE (event))));
}
pads = g_list_next (pads);
diff --git a/gst/gstpad.h b/gst/gstpad.h
index 7eb962afc496d6e752010a01d5de510049daf3c1..c73ecf740baa7512b20c4f707043a902fc11ca8c 100644 (file)
--- a/gst/gstpad.h
+++ b/gst/gstpad.h
guint64 offset;
guint64 len;
- GstSchedule *sched;
+ GstScheduler *sched;
GstPadChainFunction chainfunc;
GstPadChainFunction chainhandler;
GstElement* gst_pad_get_parent (GstPad *pad);
GstElement* gst_pad_get_real_parent (GstPad *pad);
-void gst_pad_set_sched (GstPad *pad, GstSchedule *sched);
-GstSchedule* gst_pad_get_sched (GstPad *pad);
+void gst_pad_set_sched (GstPad *pad, GstScheduler *sched);
+GstScheduler* gst_pad_get_sched (GstPad *pad);
void gst_pad_add_ghost_pad (GstPad *pad, GstPad *ghostpad);
void gst_pad_remove_ghost_pad (GstPad *pad, GstPad *ghostpad);
diff --git a/gst/gstparse.c b/gst/gstparse.c
index 533d0cfc5a5c4e1135f8f1fbbcf1ae5e2e59aa30..bf8ffd7ea693aa57c4ecfb857a2c4eae5451f76a 100644 (file)
--- a/gst/gstparse.c
+++ b/gst/gstparse.c
@@ -383,8 +383,6 @@ gst_parse_launch_cmdline(int argc,char *argv[],GstBin *parent,gst_parse_priv *pr
g_signal_connect (G_OBJECT (previous), "new_pad",
G_CALLBACK (dynamic_connect), connect);
- g_signal_connect (G_OBJECT (previous), "new_ghost_pad",
- G_CALLBACK (dynamic_connect), connect);
}
else {
for (j=0; (j<numsrcpads) && (j<numsinkpads); j++){
diff --git a/gst/gstpipeline.c b/gst/gstpipeline.c
index b215697248fb45c6b0988e5a73cb3a4bc87fe0cc..0279b4092fca5fbfc66f667325850093760f916c 100644 (file)
--- a/gst/gstpipeline.c
+++ b/gst/gstpipeline.c
gstelement_class = (GstElementClass*)klass;
- parent_class = g_type_class_ref(gst_bin_get_type());
+ parent_class = g_type_class_ref (gst_bin_get_type ());
gstelement_class->change_state = gst_pipeline_change_state;
}
// we're a manager by default
GST_FLAG_SET (pipeline, GST_BIN_FLAG_MANAGER);
- GST_ELEMENT_SCHED(pipeline) = gst_schedule_new(GST_ELEMENT(pipeline));
- GST_DEBUG(GST_CAT_PIPELINE, "pipeline's scheduler is %p\n",GST_ELEMENT_SCHED(pipeline));
+ GST_ELEMENT_SCHED (pipeline) = gst_schedulerfactory_make ("basic", GST_ELEMENT (pipeline));
+ GST_DEBUG (GST_CAT_PIPELINE, "pipeline's scheduler is %p\n", GST_ELEMENT_SCHED (pipeline));
}
diff --git a/gst/gstplugin.c b/gst/gstplugin.c
index 753c6666da77ccc0029448a18d9c3da8b28b3c43..38c3b5607f7841e8388dba0e97a78929c5beb3fe 100644 (file)
--- a/gst/gstplugin.c
+++ b/gst/gstplugin.c
PLUGINS_BUILDDIR "/gst/types");
_gst_plugin_paths = g_list_prepend (_gst_plugin_paths,
PLUGINS_BUILDDIR "/gst/autoplug");
+ _gst_plugin_paths = g_list_prepend (_gst_plugin_paths,
+ PLUGINS_BUILDDIR "/gst/schedulers");
#endif /* PLUGINS_USE_BUILDDIR */
#ifndef GST_DISABLE_REGISTRY
diff --git a/gst/gstqueue.c b/gst/gstqueue.c
index f78792d69a91516d3c54647cce7cfcc3ebe04614..cdad2e7aafbef9cc77f0ed5c17647600751272c7 100644 (file)
--- a/gst/gstqueue.c
+++ b/gst/gstqueue.c
reader = FALSE;
+restart:
/* we have to lock the queue since we span threads */
GST_DEBUG_ELEMENT (GST_CAT_DATAFLOW, queue, "locking t:%ld\n", pthread_self ());
g_mutex_lock (queue->qlock);
gst_queue_locked_flush (queue);
break;
case GST_EVENT_EOS:
+ GST_DEBUG_ELEMENT (GST_CAT_DATAFLOW, queue, "eos in on %s %d\n",
+ GST_ELEMENT_NAME (queue), queue->level_buffers);
break;
default:
gst_pad_event_default (pad, GST_EVENT (buf));
while (queue->level_buffers == queue->size_buffers) {
// if there's a pending state change for this queue or its manager, switch
// back to iterator so bottom half of state change executes
- if (GST_STATE_PENDING(queue) != GST_STATE_VOID_PENDING ||
-// GST_STATE_PENDING(GST_SCHEDULE(GST_ELEMENT(queue)->sched)->parent) != GST_STATE_VOID_PENDING)
-GST_STATE_PENDING(GST_SCHED_PARENT(GST_ELEMENT_SCHED(GST_PAD_PARENT(GST_PAD_PEER(queue->sinkpad))))) !=
-GST_STATE_VOID_PENDING)
- {
+ while (GST_STATE (queue) != GST_STATE_PLAYING) {
GST_DEBUG_ELEMENT (GST_CAT_DATAFLOW, queue, "interrupted!!\n");
- if (GST_STATE_PENDING(queue) != GST_STATE_VOID_PENDING)
- GST_DEBUG_ELEMENT (GST_CAT_DATAFLOW, queue, "GST_STATE_PENDING(queue) != GST_STATE_VOID_PENDING)\n");
- if (GST_STATE_PENDING(GST_SCHEDULE(GST_ELEMENT(queue)->sched)->parent) != GST_STATE_VOID_PENDING)
- GST_DEBUG_ELEMENT (GST_CAT_DATAFLOW, queue, "GST_STATE_PENDING(GST_SCHEDULE(GST_ELEMENT(queue)->sched)->parent) != GST_STATE_VOID_PENDING\n");
g_mutex_unlock (queue->qlock);
cothread_switch(cothread_current_main());
+ goto restart;
}
+ g_assert (GST_STATE (queue) == GST_STATE_PLAYING);
GST_DEBUG_ELEMENT (GST_CAT_DATAFLOW, queue, "waiting for not_full, level:%d/%d\n", queue->level_buffers, queue->size_buffers);
if (queue->writer)
writer = FALSE;
+restart:
/* have to lock for thread-safety */
GST_DEBUG_ELEMENT (GST_CAT_DATAFLOW, queue, "locking t:%ld\n", pthread_self ());
g_mutex_lock (queue->qlock);
while (queue->level_buffers == 0) {
// if there's a pending state change for this queue or its manager, switch
// back to iterator so bottom half of state change executes
- if (GST_STATE_PENDING(queue) != GST_STATE_VOID_PENDING ||
-// GST_STATE_PENDING(GST_SCHEDULE(GST_ELEMENT(queue)->sched)->parent) != GST_STATE_VOID_PENDING)
-GST_STATE_PENDING(GST_SCHED_PARENT(GST_ELEMENT_SCHED(GST_PAD_PARENT(GST_PAD_PEER(queue->srcpad))))) !=
-GST_STATE_VOID_PENDING)
- {
+ while (GST_STATE (queue) != GST_STATE_PLAYING) {
GST_DEBUG_ELEMENT (GST_CAT_DATAFLOW, queue, "interrupted!!\n");
- if (GST_STATE_PENDING(queue) != GST_STATE_VOID_PENDING)
- GST_DEBUG_ELEMENT (GST_CAT_DATAFLOW, queue, "GST_STATE_PENDING(queue) != GST_STATE_VOID_PENDING)\n");
- if (GST_STATE_PENDING(GST_SCHEDULE(GST_ELEMENT(queue)->sched)->parent) != GST_STATE_VOID_PENDING)
- GST_DEBUG_ELEMENT (GST_CAT_DATAFLOW, queue, "GST_STATE_PENDING(GST_SCHEDULE(GST_ELEMENT(queue)->sched)->parent) != GST_STATE_VOID_PENDING\n");
g_mutex_unlock (queue->qlock);
cothread_switch(cothread_current_main());
+ goto restart;
}
+ g_assert (GST_STATE (queue) == GST_STATE_PLAYING);
GST_DEBUG_ELEMENT (GST_CAT_DATAFLOW, queue, "waiting for not_empty, level:%d/%d\n", queue->level_buffers, queue->size_buffers);
if (queue->reader)
GstEvent *event = GST_EVENT(buf);
switch (GST_EVENT_TYPE(event)) {
case GST_EVENT_EOS:
- GST_DEBUG_ELEMENT (GST_CAT_DATAFLOW, queue, "queue eos\n");
+ GST_DEBUG_ELEMENT (GST_CAT_DATAFLOW, queue, "queue \"%s\" eos\n", GST_ELEMENT_NAME (queue));
gst_element_set_state (GST_ELEMENT (queue), GST_STATE_PAUSED);
break;
default:
{
GstQueue *queue;
GstElementStateReturn ret;
+ GstElementState new_state;
g_return_val_if_fail (GST_IS_QUEUE (element), GST_STATE_FAILURE);
queue = GST_QUEUE (element);
+ GST_DEBUG_ENTER("('%s')", GST_ELEMENT_NAME (element));
+
// lock the queue so another thread (not in sync with this thread's state)
// can't call this queue's _get (or whatever)
- GST_LOCK (queue);
+ g_mutex_lock (queue->qlock);
- /* if going down into NULL state, clear out buffers*/
- if (GST_STATE_PENDING (element) == GST_STATE_READY) {
- /* otherwise (READY or higher) we need to open the file */
- gst_queue_flush (queue);
- }
+ new_state = GST_STATE_PENDING (element);
- // if we haven't failed already, give the parent class a chance to ;-)
- if (GST_ELEMENT_CLASS (parent_class)->change_state)
- {
- gboolean valid_handler = FALSE;
- guint state_change_id = g_signal_lookup("state_change", G_OBJECT_TYPE(element));
-
- // determine whether we need to block the parent (element) class'
- // STATE_CHANGE signal so we can UNLOCK before returning. we block
- // it if we could find the state_change signal AND there's a signal
- // handler attached to it.
- //
- // note: this assumes that change_state() *only* emits state_change signal.
- // if element change_state() emits other signals, they need to be blocked
- // as well.
- if (state_change_id &&
- g_signal_has_handler_pending(G_OBJECT(element), state_change_id, 0, FALSE))
- valid_handler = TRUE;
- if (valid_handler)
- g_signal_handler_block(G_OBJECT(element), state_change_id);
-
- ret = GST_ELEMENT_CLASS (parent_class)->change_state (element);
-
- if (valid_handler)
- g_signal_handler_unblock(G_OBJECT(element), state_change_id);
-
- // UNLOCK, *then* emit signal (if there's one there)
- GST_UNLOCK(queue);
- if (valid_handler)
- g_signal_emit(G_OBJECT (element), state_change_id, 0, GST_STATE(element));
+ if (new_state == GST_STATE_PAUSED) {
+ g_cond_signal (queue->not_full);
+ g_cond_signal (queue->not_empty);
}
- else
- {
- ret = GST_STATE_SUCCESS;
- GST_UNLOCK(queue);
+ else if (new_state == GST_STATE_READY) {
+ gst_queue_locked_flush (queue);
}
+ else if (new_state == GST_STATE_PLAYING) {
+ if (!GST_PAD_CONNECTED (queue->sinkpad)) {
+ // FIXME can this be?
+ if (queue->reader)
+ g_cond_signal (queue->not_empty);
+ g_mutex_unlock (queue->qlock);
+
+ return GST_STATE_FAILURE;
+ }
+ }
+
+ ret = GST_ELEMENT_CLASS (parent_class)->change_state (element);
+ g_mutex_unlock (queue->qlock);
+ GST_DEBUG_LEAVE("('%s')", GST_ELEMENT_NAME (element));
return ret;
}
diff --git a/gst/gstscheduler.c b/gst/gstscheduler.c
index ccef994f6aba561db689346731548114b957a125..d11c93410c1d1edcbb8067e7a809c5c8aebe645b 100644 (file)
--- a/gst/gstscheduler.c
+++ b/gst/gstscheduler.c
/* GStreamer
* Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
- * 2000 Wim Taymans <wtay@chello.be>
+ * 2000 Wim Taymans <wim.taymans@chello.be>
*
* gstscheduler.c: Default scheduling code for most cases
*
* Boston, MA 02111-1307, USA.
*/
-//#define GST_DEBUG_ENABLED
+#define CLASS(obj) GST_SCHEDULER_CLASS (G_OBJECT_GET_CLASS (obj))
+
#include "gst_private.h"
#include "gstscheduler.h"
-GType _gst_schedule_type = 0;
-
-static int
-gst_schedule_loopfunc_wrapper (int argc,char *argv[])
-{
- GstElement *element = GST_ELEMENT (argv);
- G_GNUC_UNUSED const gchar *name = GST_ELEMENT_NAME (element);
-
- GST_DEBUG_ENTER("(%d,'%s')",argc,name);
-
- do {
- GST_DEBUG (GST_CAT_DATAFLOW,"calling loopfunc %s for element %s\n",
- GST_DEBUG_FUNCPTR_NAME (element->loopfunc),name);
- (element->loopfunc) (element);
- GST_DEBUG (GST_CAT_DATAFLOW,"element %s ended loop function\n", name);
- } while (!GST_ELEMENT_IS_COTHREAD_STOPPING(element));
- GST_FLAG_UNSET(element,GST_ELEMENT_COTHREAD_STOPPING);
+static void gst_scheduler_class_init (GstSchedulerClass *klass);
+static void gst_scheduler_init (GstScheduler *sched);
- GST_DEBUG_LEAVE("(%d,'%s')",argc,name);
- return 0;
-}
+static GstObjectClass *parent_class = NULL;
-static int
-gst_schedule_chain_wrapper (int argc,char *argv[])
+GType
+gst_scheduler_get_type (void)
{
- GstElement *element = GST_ELEMENT (argv);
- G_GNUC_UNUSED const gchar *name = GST_ELEMENT_NAME (element);
-
- GST_DEBUG_ENTER("(\"%s\")",name);
-
- GST_DEBUG (GST_CAT_DATAFLOW,"stepping through pads\n");
-
- do {
- GList *pads = element->pads;
-
- while (pads) {
- GstPad *pad = GST_PAD (pads->data);
- GstRealPad *realpad;
-
- pads = g_list_next (pads);
- if (!GST_IS_REAL_PAD(pad))
- continue;
- realpad = GST_REAL_PAD(pad);
- if (GST_RPAD_DIRECTION (realpad) == GST_PAD_SINK) {
- GstBuffer *buf;
-
- GST_DEBUG (GST_CAT_DATAFLOW,"pulling data from %s:%s\n", name, GST_PAD_NAME (pad));
- buf = gst_pad_pull (pad);
- if (buf) {
- if (GST_IS_EVENT (buf) && !GST_ELEMENT_IS_EVENT_AWARE (element)) {
- //gst_pad_event_default (pad, GST_EVENT (buf));
- gst_pad_send_event (pad, GST_EVENT (buf));
- }
- else {
- GST_DEBUG (GST_CAT_DATAFLOW,"calling chain function of %s:%s\n", name, GST_PAD_NAME (pad));
- GST_RPAD_CHAINFUNC(realpad) (pad, buf);
- }
- }
- GST_DEBUG (GST_CAT_DATAFLOW,"calling chain function of %s:%s done\n", name, GST_PAD_NAME (pad));
- }
- }
- } while (!GST_ELEMENT_IS_COTHREAD_STOPPING(element));
- GST_FLAG_UNSET(element,GST_ELEMENT_COTHREAD_STOPPING);
-
- GST_DEBUG_LEAVE("(%d,'%s')",argc,name);
- return 0;
-}
+ static GType _gst_scheduler_type = 0;
-static int
-gst_schedule_src_wrapper (int argc,char *argv[])
-{
- GstElement *element = GST_ELEMENT (argv);
- GList *pads;
- GstRealPad *realpad;
- GstBuffer *buf = NULL;
- G_GNUC_UNUSED const gchar *name = GST_ELEMENT_NAME (element);
-
- GST_DEBUG_ENTER("(%d,\"%s\")",argc,name);
-
- do {
- pads = element->pads;
- while (pads) {
- if (!GST_IS_REAL_PAD(pads->data)) continue;
- realpad = (GstRealPad*)(pads->data);
- pads = g_list_next(pads);
- if (GST_RPAD_DIRECTION(realpad) == GST_PAD_SRC) {
- GST_DEBUG (GST_CAT_DATAFLOW,"calling _getfunc for %s:%s\n",GST_DEBUG_PAD_NAME(realpad));
- if (realpad->regiontype != GST_REGION_VOID) {
- g_return_val_if_fail (GST_RPAD_GETREGIONFUNC(realpad) != NULL, 0);
-// if (GST_RPAD_GETREGIONFUNC(realpad) == NULL)
-// 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_VOID;
- } else {
- g_return_val_if_fail (GST_RPAD_GETFUNC(realpad) != NULL, 0);
-// if (GST_RPAD_GETFUNC(realpad) == NULL)
-// fprintf(stderr,"error, no getfunc in \"%s\"\n", name);
-// else
- buf = GST_RPAD_GETFUNC(realpad) ((GstPad*)realpad);
- }
-
- GST_DEBUG (GST_CAT_DATAFLOW,"calling gst_pad_push on pad %s:%s\n",GST_DEBUG_PAD_NAME(realpad));
- gst_pad_push ((GstPad*)realpad, buf);
- }
- }
- } while (!GST_ELEMENT_IS_COTHREAD_STOPPING(element));
- GST_FLAG_UNSET(element,GST_ELEMENT_COTHREAD_STOPPING);
+ if (!_gst_scheduler_type) {
+ static const GTypeInfo scheduler_info = {
+ sizeof (GstSchedulerClass),
+ NULL,
+ NULL,
+ (GClassInitFunc) gst_scheduler_class_init,
+ NULL,
+ NULL,
+ sizeof (GstScheduler),
+ 0,
+ (GInstanceInitFunc) gst_scheduler_init,
+ NULL
+ };
- GST_DEBUG_LEAVE("");
- return 0;
+ _gst_scheduler_type = g_type_register_static (GST_TYPE_OBJECT, "GstScheduler",
+ &scheduler_info, G_TYPE_FLAG_ABSTRACT);
+ }
+ return _gst_scheduler_type;
}
static void
-gst_schedule_chainhandler_proxy (GstPad *pad, GstBuffer *buf)
+gst_scheduler_class_init (GstSchedulerClass *klass)
{
- GstRealPad *peer = GST_RPAD_PEER(pad);
-
- GST_DEBUG_ENTER("(%s:%s)",GST_DEBUG_PAD_NAME(pad));
- GST_DEBUG (GST_CAT_DATAFLOW,"putting buffer %p in peer \"%s:%s\"'s pen\n",buf,GST_DEBUG_PAD_NAME(peer));
-
- // FIXME this should be bounded
- // loop until the bufferpen is empty so we can fill it up again
- while (GST_RPAD_BUFPEN(pad) != NULL) {
- GST_DEBUG (GST_CAT_DATAFLOW, "switching to %p to empty bufpen\n",
- GST_ELEMENT (GST_PAD_PARENT (pad))->threadstate);
- cothread_switch (GST_ELEMENT (GST_PAD_PARENT (pad))->threadstate);
-
- // we may no longer be the same pad, check.
- if (GST_RPAD_PEER(peer) != (GstRealPad *)pad) {
- GST_DEBUG (GST_CAT_DATAFLOW, "new pad in mid-switch!\n");
- pad = (GstPad *)GST_RPAD_PEER(peer);
- }
- }
-
- g_assert (GST_RPAD_BUFPEN(GST_RPAD_PEER(pad)) == NULL);
- // now fill the bufferpen and switch so it can be consumed
- GST_RPAD_BUFPEN(GST_RPAD_PEER(pad)) = buf;
- GST_DEBUG (GST_CAT_DATAFLOW,"switching to %p\n",GST_ELEMENT (GST_PAD_PARENT (pad))->threadstate);
- cothread_switch (GST_ELEMENT (GST_PAD_PARENT (pad))->threadstate);
-
- GST_DEBUG (GST_CAT_DATAFLOW,"done switching\n");
+ parent_class = g_type_class_ref (GST_TYPE_OBJECT);
}
static void
-gst_schedule_select_proxy (GstPad *pad, GstBuffer *buf)
+gst_scheduler_init (GstScheduler *sched)
{
- GstRealPad *peer = GST_RPAD_PEER(pad);
-
- g_print ("select proxy (%s:%s)\n",GST_DEBUG_PAD_NAME(pad));
-
- GST_DEBUG_ENTER("(%s:%s)",GST_DEBUG_PAD_NAME(pad));
-
- GST_DEBUG (GST_CAT_DATAFLOW,"putting buffer %p in peer's pen\n",buf);
-
- g_assert (GST_RPAD_BUFPEN(GST_RPAD_PEER(pad)) == NULL);
- // now fill the bufferpen and switch so it can be consumed
- GST_RPAD_BUFPEN(GST_RPAD_PEER(pad)) = buf;
- GST_DEBUG (GST_CAT_DATAFLOW,"switching to %p\n",GST_ELEMENT (GST_PAD_PARENT (pad))->threadstate);
- g_print ("%p %s\n", GST_ELEMENT (GST_PAD_PARENT (pad)), gst_element_get_name (GST_ELEMENT (GST_PAD_PARENT (pad))));
- GST_ELEMENT (GST_PAD_PARENT (pad))->select_pad = pad;
- GST_FLAG_UNSET(GST_PAD_PARENT (pad), GST_ELEMENT_COTHREAD_STOPPING);
- cothread_switch (GST_ELEMENT (GST_PAD_PARENT (pad))->threadstate);
-
- g_print ("done switching\n");
- GST_DEBUG (GST_CAT_DATAFLOW,"done switching\n");
}
-
-static GstBuffer*
-gst_schedule_gethandler_proxy (GstPad *pad)
+/**
+ * gst_scheduler_pad_connect:
+ * @sched: the schedulerr
+ * @srcpad: the srcpad to connect
+ * @sinkpad: the sinkpad to connect to
+ *
+ * Connect the srcpad to the given sinkpad.
+ */
+void
+gst_scheduler_pad_connect (GstScheduler *sched, GstPad *srcpad, GstPad *sinkpad)
{
- GstBuffer *buf;
- GstRealPad *peer = GST_RPAD_PEER(pad);
-
- GST_DEBUG_ENTER("(%s:%s)",GST_DEBUG_PAD_NAME(pad));
-
- // FIXME this should be bounded
- // we will loop switching to the peer until it's filled up the bufferpen
- while (GST_RPAD_BUFPEN(pad) == NULL) {
- GST_DEBUG (GST_CAT_DATAFLOW, "switching to \"%s\": %p to fill bufpen\n",
- GST_ELEMENT_NAME(GST_ELEMENT(GST_PAD_PARENT(pad))),
- GST_ELEMENT(GST_PAD_PARENT(pad))->threadstate);
- cothread_switch (GST_ELEMENT(GST_PAD_PARENT(pad))->threadstate);
-
- // we may no longer be the same pad, check.
- if (GST_RPAD_PEER(peer) != (GstRealPad *)pad) {
- GST_DEBUG (GST_CAT_DATAFLOW, "new pad in mid-switch!\n");
- pad = (GstPad *)GST_RPAD_PEER(peer);
- }
- }
- GST_DEBUG (GST_CAT_DATAFLOW,"done switching\n");
-
- // now grab the buffer from the pen, clear the pen, and return the buffer
- buf = GST_RPAD_BUFPEN(pad);
- GST_RPAD_BUFPEN(pad) = NULL;
-
- return buf;
+ if (CLASS (sched)->pad_connect)
+ CLASS (sched)->pad_connect (sched, srcpad, sinkpad);
}
-static GstBuffer*
-gst_schedule_pullregionfunc_proxy (GstPad *pad,GstRegionType type,guint64 offset,guint64 len)
+/**
+ * gst_scheduler_pad_disconnect:
+ * @sched: the schedulerr
+ * @srcpad: the srcpad to disconnect
+ * @sinkpad: the sinkpad to disconnect from
+ *
+ * Disconnect the srcpad to the given sinkpad.
+ */
+void
+gst_scheduler_pad_disconnect (GstScheduler *sched, GstPad *srcpad, GstPad *sinkpad)
{
- GstBuffer *buf;
- GstRealPad *peer = GST_RPAD_PEER(pad);
-
- GST_DEBUG_ENTER("%s:%s,%d,%lld,%lld",GST_DEBUG_PAD_NAME(pad),type,offset,len);
-
- // put the region info into the pad
- GST_RPAD_REGIONTYPE(pad) = type;
- GST_RPAD_OFFSET(pad) = offset;
- GST_RPAD_LEN(pad) = len;
-
- // FIXME this should be bounded
- // we will loop switching to the peer until it's filled up the bufferpen
- while (GST_RPAD_BUFPEN(pad) == NULL) {
- GST_DEBUG (GST_CAT_DATAFLOW, "switching to %p to fill bufpen\n",
- GST_ELEMENT(GST_PAD_PARENT(pad))->threadstate);
- cothread_switch (GST_ELEMENT(GST_PAD_PARENT(pad))->threadstate);
-
- // we may no longer be the same pad, check.
- if (GST_RPAD_PEER(peer) != (GstRealPad *)pad) {
- GST_DEBUG (GST_CAT_DATAFLOW, "new pad in mid-switch!\n");
- pad = (GstPad *)GST_RPAD_PEER(peer);
- }
- }
- GST_DEBUG (GST_CAT_DATAFLOW,"done switching\n");
-
- // now grab the buffer from the pen, clear the pen, and return the buffer
- buf = GST_RPAD_BUFPEN(pad);
- GST_RPAD_BUFPEN(pad) = NULL;
- return buf;
-}
-
-
-static void
-gst_schedule_cothreaded_chain (GstBin *bin, GstScheduleChain *chain) {
- GList *elements;
- GstElement *element;
- cothread_func wrapper_function;
- GList *pads;
- GstPad *pad;
-
- GST_DEBUG (GST_CAT_SCHEDULING,"chain is using COTHREADS\n");
-
- // first create thread context
- if (bin->threadcontext == NULL) {
- GST_DEBUG (GST_CAT_SCHEDULING,"initializing cothread context\n");
- bin->threadcontext = cothread_init ();
- }
-
- // walk through all the chain's elements
- elements = chain->elements;
- while (elements) {
- element = GST_ELEMENT (elements->data);
- elements = g_list_next (elements);
-
- // start out without a wrapper function, we select it later
- wrapper_function = NULL;
-
- // if the element has a loopfunc...
- if (element->loopfunc != NULL) {
- wrapper_function = GST_DEBUG_FUNCPTR(gst_schedule_loopfunc_wrapper);
- GST_DEBUG (GST_CAT_SCHEDULING,"element '%s' is a loop-based\n",GST_ELEMENT_NAME(element));
- } else {
- // otherwise we need to decide what kind of cothread
- // if it's not DECOUPLED, we decide based on whether it's a source or not
- if (!GST_FLAG_IS_SET (element, GST_ELEMENT_DECOUPLED)) {
- // if it doesn't have any sinks, it must be a source (duh)
- if (element->numsinkpads == 0) {
- wrapper_function = GST_DEBUG_FUNCPTR(gst_schedule_src_wrapper);
- GST_DEBUG (GST_CAT_SCHEDULING,"element '%s' is a source, using _src_wrapper\n",GST_ELEMENT_NAME(element));
- } else {
- wrapper_function = GST_DEBUG_FUNCPTR(gst_schedule_chain_wrapper);
- GST_DEBUG (GST_CAT_SCHEDULING,"element '%s' is a filter, using _chain_wrapper\n",GST_ELEMENT_NAME(element));
- }
- }
- }
-
- // now we have to walk through the pads to set up their state
- pads = gst_element_get_pad_list (element);
- while (pads) {
- pad = GST_PAD (pads->data);
- pads = g_list_next (pads);
- if (!GST_IS_REAL_PAD(pad)) continue;
-
- // if the element is DECOUPLED or outside the manager, we have to chain
- if ((wrapper_function == NULL) ||
- (GST_RPAD_PEER(pad) &&
- (GST_ELEMENT (GST_PAD_PARENT (GST_PAD (GST_RPAD_PEER (pad))))->sched != chain->sched))
- ) {
- // set the chain proxies
- if (GST_RPAD_DIRECTION(pad) == GST_PAD_SINK) {
- GST_DEBUG (GST_CAT_SCHEDULING,"copying chain function into push proxy for %s:%s\n",GST_DEBUG_PAD_NAME(pad));
- GST_RPAD_CHAINHANDLER(pad) = GST_RPAD_CHAINFUNC(pad);
- } else {
- GST_DEBUG (GST_CAT_SCHEDULING,"copying get function into pull proxy for %s:%s\n",GST_DEBUG_PAD_NAME(pad));
- GST_RPAD_GETHANDLER(pad) = GST_RPAD_GETFUNC(pad);
- GST_RPAD_PULLREGIONFUNC(pad) = GST_RPAD_GETREGIONFUNC(pad);
- }
-
- // otherwise we really are a cothread
- } else {
- if (gst_pad_get_direction (pad) == GST_PAD_SINK) {
- GST_DEBUG (GST_CAT_SCHEDULING,"setting cothreaded push proxy for sinkpad %s:%s\n",GST_DEBUG_PAD_NAME(pad));
- GST_RPAD_CHAINHANDLER(pad) = GST_DEBUG_FUNCPTR(gst_schedule_chainhandler_proxy);
- } else {
- GST_DEBUG (GST_CAT_SCHEDULING,"setting cothreaded pull proxy for srcpad %s:%s\n",GST_DEBUG_PAD_NAME(pad));
- GST_RPAD_GETHANDLER(pad) = GST_DEBUG_FUNCPTR(gst_schedule_gethandler_proxy);
- GST_RPAD_PULLREGIONFUNC(pad) = GST_DEBUG_FUNCPTR(gst_schedule_pullregionfunc_proxy);
- }
- }
- }
-
- // need to set up the cothread now
- if (wrapper_function != NULL) {
- if (element->threadstate == NULL) {
- // FIXME handle cothread_create returning NULL
- element->threadstate = cothread_create (bin->threadcontext);
- GST_DEBUG (GST_CAT_SCHEDULING,"created cothread %p for '%s'\n",element->threadstate,GST_ELEMENT_NAME(element));
- }
- cothread_setfunc (element->threadstate, wrapper_function, 0, (char **)element);
- GST_DEBUG (GST_CAT_SCHEDULING,"set wrapper function for '%s' to &%s\n",GST_ELEMENT_NAME(element),
- GST_DEBUG_FUNCPTR_NAME(wrapper_function));
- }
- }
+ if (CLASS (sched)->pad_disconnect)
+ CLASS (sched)->pad_disconnect (sched, srcpad, sinkpad);
}
-G_GNUC_UNUSED static void
-gst_schedule_chained_chain (GstBin *bin, _GstBinChain *chain) {
- GList *elements;
- GstElement *element;
- GList *pads;
- GstPad *pad;
-
- GST_DEBUG (GST_CAT_SCHEDULING,"chain entered\n");
- // walk through all the elements
- elements = chain->elements;
- while (elements) {
- element = GST_ELEMENT (elements->data);
- elements = g_list_next (elements);
-
- // walk through all the pads
- pads = gst_element_get_pad_list (element);
- while (pads) {
- pad = GST_PAD (pads->data);
- pads = g_list_next (pads);
- if (!GST_IS_REAL_PAD(pad)) continue;
-
- if (GST_RPAD_DIRECTION(pad) == GST_PAD_SINK) {
- GST_DEBUG (GST_CAT_SCHEDULING,"copying chain function into push proxy for %s:%s\n",GST_DEBUG_PAD_NAME(pad));
- GST_RPAD_CHAINHANDLER(pad) = GST_RPAD_CHAINFUNC(pad);
- } else {
- GST_DEBUG (GST_CAT_SCHEDULING,"copying get function into pull proxy for %s:%s\n",GST_DEBUG_PAD_NAME(pad));
- GST_RPAD_GETHANDLER(pad) = GST_RPAD_GETFUNC(pad);
- GST_RPAD_PULLREGIONFUNC(pad) = GST_RPAD_GETREGIONFUNC(pad);
- }
- }
- }
-}
-
-/* depracated!! */
-static void
-gst_bin_schedule_cleanup (GstBin *bin)
+/**
+ * gst_scheduler_pad_select:
+ * @sched: the schedulerr
+ * @padlist: the padlist to select on
+ *
+ * register the given padlist for a select operation.
+ *
+ * Returns: the pad which received a buffer.
+ */
+GstPad *
+gst_scheduler_pad_select (GstScheduler *sched, GList *padlist)
{
- GList *chains;
- _GstBinChain *chain;
-
- chains = bin->chains;
- while (chains) {
- chain = (_GstBinChain *)(chains->data);
- chains = g_list_next(chains);
-
-// g_list_free(chain->disabled);
- g_list_free(chain->elements);
- g_list_free(chain->entries);
-
- g_free(chain);
- }
- g_list_free(bin->chains);
-
- bin->chains = NULL;
+ if (CLASS (sched)->pad_select)
+ CLASS (sched)->pad_select (sched, padlist);
}
-static void
-gst_scheduler_handle_eos (GstElement *element, _GstBinChain *chain)
+/**
+ * gst_scheduler_add_element:
+ * @sched: the schedulerr
+ * @element: the element to add to the schedulerr
+ *
+ * Add an element to the schedulerr.
+ */
+void
+gst_scheduler_add_element (GstScheduler *sched, GstElement *element)
{
- GST_DEBUG (GST_CAT_SCHEDULING,"chain removed from scheduler, EOS from element \"%s\"\n", GST_ELEMENT_NAME (element));
- chain->need_scheduling = FALSE;
+ if (CLASS (sched)->add_element)
+ CLASS (sched)->add_element (sched, element);
}
-/*
-void gst_bin_schedule_func(GstBin *bin) {
- GList *elements;
- GstElement *element;
- GSList *pending = NULL;
- GList *pads;
- GstPad *pad;
- GstElement *peerparent;
- GList *chains;
- GstScheduleChain *chain;
-
- GST_DEBUG_ENTER("(\"%s\")",GST_ELEMENT_NAME (GST_ELEMENT (bin)));
-
- gst_bin_schedule_cleanup(bin);
-
- // next we have to find all the separate scheduling chains
- GST_DEBUG (GST_CAT_SCHEDULING,"attempting to find scheduling chains...\n");
- // first make a copy of the managed_elements we can mess with
- elements = g_list_copy (bin->managed_elements);
- // we have to repeat until the list is empty to get all chains
- while (elements) {
- element = GST_ELEMENT (elements->data);
-
- // if this is a DECOUPLED element
- if (GST_FLAG_IS_SET (element, GST_ELEMENT_DECOUPLED)) {
- // skip this element entirely
- GST_DEBUG (GST_CAT_SCHEDULING,"skipping '%s' because it's decoupled\n",GST_ELEMENT_NAME(element));
- elements = g_list_next (elements);
- continue;
- }
-
- GST_DEBUG (GST_CAT_SCHEDULING,"starting with element '%s'\n",GST_ELEMENT_NAME(element));
-
- // prime the pending list with the first element off the top
- pending = g_slist_prepend (NULL, element);
- // and remove that one from the main list
- elements = g_list_remove (elements, element);
-
- // create a chain structure
- chain = g_new0 (_GstBinChain, 1);
- chain->need_scheduling = TRUE;
-
- // for each pending element, walk the pipeline
- do {
- // retrieve the top of the stack and pop it
- element = GST_ELEMENT (pending->data);
- pending = g_slist_remove (pending, element);
-
- // add ourselves to the chain's list of elements
- GST_DEBUG (GST_CAT_SCHEDULING,"adding '%s' to chain\n",GST_ELEMENT_NAME(element));
- chain->elements = g_list_prepend (chain->elements, element);
- chain->num_elements++;
- gtk_signal_connect (G_OBJECT (element), "eos", gst_scheduler_handle_eos, chain);
- // set the cothreads flag as appropriate
- if (GST_FLAG_IS_SET (element, GST_ELEMENT_USE_COTHREAD))
- chain->need_cothreads = TRUE;
- if (bin->use_cothreads == TRUE)
- chain->need_cothreads = TRUE;
-
- // if we're managed by the current bin, and we're not decoupled,
- // go find all the peers and add them to the list of elements to check
- if ((element->manager == GST_ELEMENT(bin)) &&
- !GST_FLAG_IS_SET (element, GST_ELEMENT_DECOUPLED)) {
- // remove ourselves from the outer list of all managed elements
-// GST_DEBUG (GST_CAT_SCHEDULING,"removing '%s' from list of possible elements\n",GST_ELEMENT_NAME(element));
- elements = g_list_remove (elements, element);
-
- // if this element is a source, add it as an entry
- if (element->numsinkpads == 0) {
- chain->entries = g_list_prepend (chain->entries, element);
- GST_DEBUG (GST_CAT_SCHEDULING,"added '%s' as SRC entry into the chain\n",GST_ELEMENT_NAME(element));
- }
-
- // now we have to walk the pads to find peers
- pads = gst_element_get_pad_list (element);
- while (pads) {
- pad = GST_PAD (pads->data);
- pads = g_list_next (pads);
- if (!GST_IS_REAL_PAD(pad)) continue;
- GST_DEBUG (GST_CAT_SCHEDULING,"have pad %s:%s\n",GST_DEBUG_PAD_NAME(pad));
-
- if (GST_RPAD_PEER(pad) == NULL) continue;
- if (GST_RPAD_PEER(pad) == NULL) GST_ERROR(pad,"peer is null!");
- g_assert(GST_RPAD_PEER(pad) != NULL);
- g_assert(GST_PAD_PARENT (GST_PAD(GST_RPAD_PEER(pad))) != NULL);
-
- peerparent = GST_ELEMENT(GST_PAD_PARENT (GST_PAD(GST_RPAD_PEER(pad))));
-
- GST_DEBUG (GST_CAT_SCHEDULING,"peer pad %p\n", GST_RPAD_PEER(pad));
- // only bother with if the pad's peer's parent is this bin or it's DECOUPLED
- // only add it if it's in the list of un-visited elements still
- if ((g_list_find (elements, peerparent) != NULL) ||
- GST_FLAG_IS_SET (peerparent, GST_ELEMENT_DECOUPLED)) {
- // add the peer element to the pending list
- GST_DEBUG (GST_CAT_SCHEDULING,"adding '%s' to list of pending elements\n",
- GST_ELEMENT_NAME(peerparent));
- pending = g_slist_prepend (pending, peerparent);
-
- // if this is a sink pad, then the element on the other side is an entry
- if ((GST_RPAD_DIRECTION(pad) == GST_PAD_SINK) &&
- (GST_FLAG_IS_SET (peerparent, GST_ELEMENT_DECOUPLED))) {
- chain->entries = g_list_prepend (chain->entries, peerparent);
- gtk_signal_connect (G_OBJECT (peerparent), "eos", gst_scheduler_handle_eos, chain);
- GST_DEBUG (GST_CAT_SCHEDULING,"added '%s' as DECOUPLED entry into the chain\n",GST_ELEMENT_NAME(peerparent));
- }
- } else
- GST_DEBUG (GST_CAT_SCHEDULING,"element '%s' has already been dealt with\n",GST_ELEMENT_NAME(peerparent));
- }
- }
- } while (pending);
-
- // add the chain to the bin
- GST_DEBUG (GST_CAT_SCHEDULING,"have chain with %d elements: ",chain->num_elements);
- { GList *elements = chain->elements;
- while (elements) {
- element = GST_ELEMENT (elements->data);
- elements = g_list_next(elements);
- GST_DEBUG_NOPREFIX(GST_CAT_SCHEDULING,"%s, ",GST_ELEMENT_NAME(element));
- }
- }
- GST_DEBUG_NOPREFIX(GST_CAT_DATAFLOW,"\n");
- bin->chains = g_list_prepend (bin->chains, chain);
- bin->num_chains++;
- }
- // free up the list in case it's full of DECOUPLED elements
- g_list_free (elements);
-
- GST_DEBUG (GST_CAT_SCHEDULING,"\nwe have %d chains to schedule\n",bin->num_chains);
-
- // now we have to go through all the chains and schedule them
- chains = bin->chains;
- while (chains) {
- chain = (GstScheduleChain *)(chains->data);
- chains = g_list_next (chains);
-
- // schedule as appropriate
- if (chain->need_cothreads) {
- gst_schedule_cothreaded_chain (bin,chain);
- } else {
- gst_schedule_chained_chain (bin,chain);
- }
- }
-
- GST_DEBUG_LEAVE("(\"%s\")",GST_ELEMENT_NAME(GST_ELEMENT(bin)));
-}
-*/
-
-
-/*
- // ***** check for possible connections outside
- // get the pad's peer
- peer = gst_pad_get_peer (pad);
- // FIXME this should be an error condition, if not disabled
- if (!peer) break;
- // get the parent of the peer of the pad
- outside = GST_ELEMENT (gst_pad_get_parent (peer));
- // FIXME this should *really* be an error condition
- if (!outside) break;
- // if it's a source or connection and it's not ours...
- if ((GST_IS_SRC (outside) || GST_IS_CONNECTION (outside)) &&
- (gst_object_get_parent (GST_OBJECT (outside)) != GST_OBJECT (bin))) {
- if (gst_pad_get_direction (pad) == GST_PAD_SINK) {
- GST_DEBUG (0,"dealing with outside source element %s\n",GST_ELEMENT_NAME(outside));
-// GST_DEBUG (0,"PUNT: copying gethandler ptr from %s:%s to %s:%s (@ %p)\n",
-//GST_DEBUG_PAD_NAME(pad->peer),GST_DEBUG_PAD_NAME(pad),&pad->gethandler);
-// pad->gethandler = pad->peer->gethandler;
-// GST_DEBUG (0,"PUNT: setting chainhandler proxy to fake proxy on %s:%s\n",GST_DEBUG_PAD_NAME(pad->peer));
-// pad->peer->chainhandler = GST_DEBUG_FUNCPTR(gst_bin_chainhandler_fake_proxy);
- GST_RPAD_GETHANDLER(pad) = GST_DEBUG_FUNCPTR(gst_bin_gethandler_proxy);
- GST_RPAD_PULLREGIONFUNC(pad) = GST_DEBUG_FUNCPTR(gst_bin_pullregionfunc_proxy);
- }
- } else {
-*/
-
-
-
-
-
-/*
- } else if (GST_IS_SRC (element)) {
- GST_DEBUG (0,"adding '%s' as entry point, because it's a source\n",GST_ELEMENT_NAME (element));
- bin->entries = g_list_prepend (bin->entries,element);
- bin->num_entries++;
- cothread_setfunc(element->threadstate,gst_bin_src_wrapper,0,(char **)element);
- }
-
- pads = gst_element_get_pad_list (element);
- while (pads) {
- pad = GST_PAD(pads->data);
-
- if (gst_pad_get_direction (pad) == GST_PAD_SINK) {
- GST_DEBUG (0,"setting push proxy for sinkpad %s:%s\n",GST_DEBUG_PAD_NAME(pad));
- // set the proxy functions
- pad->chainhandler = GST_DEBUG_FUNCPTR(gst_bin_chainhandler_proxy);
- GST_DEBUG (0,"chainhandler %p = gst_bin_chainhandler_proxy %p\n",&pad->chainhandler,gst_bin_chainhandler_proxy);
- } else if (gst_pad_get_direction (pad) == GST_PAD_SRC) {
- GST_DEBUG (0,"setting pull proxies for srcpad %s:%s\n",GST_DEBUG_PAD_NAME(pad));
- // set the proxy functions
- GST_RPAD_GETHANDLER(pad) = GST_DEBUG_FUNCPTR(gst_bin_gethandler_proxy);
- GST_RPAD_PULLREGIONFUNC(pad) = GST_DEBUG_FUNCPTR(gst_bin_pullregionfunc_proxy);
- GST_DEBUG (0,"pad->gethandler(@%p) = gst_bin_gethandler_proxy(@%p)\n",
- &pad->gethandler,gst_bin_gethandler_proxy);
- pad->pullregionfunc = GST_DEBUG_FUNCPTR(gst_bin_pullregionfunc_proxy);
- }
- pads = g_list_next (pads);
- }
- elements = g_list_next (elements);
-
- // if there are no entries, we have to pick one at random
- if (bin->num_entries == 0)
- bin->entries = g_list_prepend (bin->entries, GST_ELEMENT(bin->children->data));
- }
- } else {
- GST_DEBUG (0,"don't need cothreads, looking for entry points\n");
- // we have to find which elements will drive an iteration
- elements = bin->children;
- while (elements) {
- element = GST_ELEMENT (elements->data);
- GST_DEBUG (0,"found element \"%s\"\n", GST_ELEMENT_NAME (element));
- if (GST_IS_BIN (element)) {
- gst_bin_create_plan (GST_BIN (element));
- }
- if (GST_IS_SRC (element)) {
- GST_DEBUG (0,"adding '%s' as entry point, because it's a source\n",GST_ELEMENT_NAME (element));
- bin->entries = g_list_prepend (bin->entries, element);
- bin->num_entries++;
- }
-
- // go through all the pads, set pointers, and check for connections
- pads = gst_element_get_pad_list (element);
- while (pads) {
- pad = GST_PAD (pads->data);
-
- if (gst_pad_get_direction (pad) == GST_PAD_SINK) {
- GST_DEBUG (0,"found SINK pad %s:%s\n", GST_DEBUG_PAD_NAME(pad));
-
- // copy the peer's chain function, easy enough
- GST_DEBUG (0,"copying peer's chainfunc to %s:%s's chainhandler\n",GST_DEBUG_PAD_NAME(pad));
- GST_RPAD_CHAINHANDLER(pad) = GST_DEBUG_FUNCPTR(GST_RPAD_CHAINFUNC(GST_RPAD_PEER(pad)));
-
- // need to walk through and check for outside connections
-//FIXME need to do this for all pads
- // get the pad's peer
- peer = GST_RPAD_PEER(pad);
- if (!peer) {
- GST_DEBUG (0,"found SINK pad %s has no peer\n", GST_ELEMENT_NAME (pad));
- break;
- }
- // get the parent of the peer of the pad
- outside = GST_ELEMENT (GST_PAD_PARENT(peer));
- if (!outside) break;
- // if it's a connection and it's not ours...
- if (GST_IS_CONNECTION (outside) &&
- (gst_object_get_parent (GST_OBJECT (outside)) != GST_OBJECT (bin))) {
- gst_info("gstbin: element \"%s\" is the external source Connection "
- "for internal element \"%s\"\n",
- GST_ELEMENT_NAME (GST_ELEMENT (outside)),
- GST_ELEMENT_NAME (GST_ELEMENT (element)));
- bin->entries = g_list_prepend (bin->entries, outside);
- bin->num_entries++;
- }
- }
- else {
- GST_DEBUG (0,"found pad %s\n", GST_ELEMENT_NAME (pad));
- }
- pads = g_list_next (pads);
-
- }
- elements = g_list_next (elements);
- }
-*/
-
-
-
-
-/*
- // If cothreads are needed, we need to not only find elements but
- // set up cothread states and various proxy functions.
- if (bin->need_cothreads) {
- GST_DEBUG (0,"bin is using cothreads\n");
-
- // first create thread context
- if (bin->threadcontext == NULL) {
- GST_DEBUG (0,"initializing cothread context\n");
- bin->threadcontext = cothread_init ();
- }
-
- // walk through all the children
- elements = bin->managed_elements;
- while (elements) {
- element = GST_ELEMENT (elements->data);
- elements = g_list_next (elements);
-
- // start out with a NULL warpper function, we'll set it if we want a cothread
- wrapper_function = NULL;
-
- // have to decide if we need to or can use a cothreads, and if so which wrapper
- // first of all, if there's a loopfunc, the decision's already made
- if (element->loopfunc != NULL) {
- wrapper_function = GST_DEBUG_FUNCPTR(gst_bin_loopfunc_wrapper);
- GST_DEBUG (0,"element %s is a loopfunc, must use a cothread\n",GST_ELEMENT_NAME (element));
- } else {
- // otherwise we need to decide if it needs a cothread
- // if it's complex, or cothreads are preferred and it's *not* decoupled, cothread it
- if (GST_FLAG_IS_SET (element,GST_ELEMENT_COMPLEX) ||
- (GST_FLAG_IS_SET (bin,GST_BIN_FLAG_PREFER_COTHREADS) &&
- !GST_FLAG_IS_SET (element,GST_ELEMENT_DECOUPLED))) {
- // base it on whether we're going to loop through source or sink pads
- if (element->numsinkpads == 0)
- wrapper_function = GST_DEBUG_FUNCPTR(gst_bin_src_wrapper);
- else
- wrapper_function = GST_DEBUG_FUNCPTR(gst_bin_chain_wrapper);
- }
- }
-
- // walk through the all the pads for this element, setting proxy functions
- // the selection of proxy functions depends on whether we're in a cothread or not
- pads = gst_element_get_pad_list (element);
- while (pads) {
- pad = GST_PAD (pads->data);
- pads = g_list_next (pads);
-
- // check to see if someone else gets to set up the element
- peer_manager = GST_ELEMENT((pad)->peer->parent)->manager;
- if (peer_manager != GST_ELEMENT(bin)) {
- GST_DEBUG (0,"WARNING: pad %s:%s is connected outside of bin\n",GST_DEBUG_PAD_NAME(pad));
- }
-
- // if the wrapper_function is set, we need to use the proxy functions
- if (wrapper_function != NULL) {
- // set up proxy functions
- if (gst_pad_get_direction (pad) == GST_PAD_SINK) {
- GST_DEBUG (0,"setting push proxy for sinkpad %s:%s\n",GST_DEBUG_PAD_NAME(pad));
- pad->chainhandler = GST_DEBUG_FUNCPTR(gst_bin_chainhandler_proxy);
- } else if (gst_pad_get_direction (pad) == GST_PAD_SRC) {
- GST_DEBUG (0,"setting pull proxy for srcpad %s:%s\n",GST_DEBUG_PAD_NAME(pad));
- GST_RPAD_GETHANDLER(pad) = GST_DEBUG_FUNCPTR(gst_bin_gethandler_proxy);
- GST_RPAD_PULLREGIONFUNC(pad) = GST_DEBUG_FUNCPTR(gst_bin_pullregionfunc_proxy);
- }
- } else {
- // otherwise we need to set up for 'traditional' chaining
- if (gst_pad_get_direction (pad) == GST_PAD_SINK) {
- // we can just copy the chain function, since it shares the prototype
- GST_DEBUG (0,"copying chain function into push proxy for %s:%s\n",
- GST_DEBUG_PAD_NAME(pad));
- pad->chainhandler = pad->chainfunc;
- } else if (gst_pad_get_direction (pad) == GST_PAD_SRC) {
- // we can just copy the get function, since it shares the prototype
- GST_DEBUG (0,"copying get function into pull proxy for %s:%s\n",
- GST_DEBUG_PAD_NAME(pad));
- pad->gethandler = pad->getfunc;
- }
- }
- }
-
- // if a loopfunc has been specified, create and set up a cothread
- if (wrapper_function != NULL) {
- if (element->threadstate == NULL) {
- element->threadstate = cothread_create (bin->threadcontext);
- GST_DEBUG (0,"created cothread %p (@%p) for \"%s\"\n",element->threadstate,
- &element->threadstate,GST_ELEMENT_NAME (element));
- }
- cothread_setfunc (element->threadstate, wrapper_function, 0, (char **)element);
- GST_DEBUG (0,"set wrapper function for \"%s\" to &%s\n",GST_ELEMENT_NAME (element),
- GST_DEBUG_FUNCPTR_NAME(wrapper_function));
- }
-
-// // HACK: if the element isn't decoupled, it's an entry
-// if (!GST_FLAG_IS_SET(element,GST_ELEMENT_DECOUPLED))
-// bin->entries = g_list_append(bin->entries, element);
- }
-
- // otherwise, cothreads are not needed
- } else {
- GST_DEBUG (0,"bin is chained, no cothreads needed\n");
-
- elements = bin->managed_elements;
- while (elements) {
- element = GST_ELEMENT (elements->data);
- elements = g_list_next (elements);
-
- pads = gst_element_get_pad_list (element);
- while (pads) {
- pad = GST_PAD (pads->data);
- pads = g_list_next (pads);
-
- if (gst_pad_get_direction (pad) == GST_PAD_SINK) {
- GST_DEBUG (0,"copying chain function into push proxy for %s:%s\n",GST_DEBUG_PAD_NAME(pad));
- pad->chainhandler = pad->chainfunc;
- } else {
- GST_DEBUG (0,"copying get function into pull proxy for %s:%s\n",GST_DEBUG_PAD_NAME(pad));
- pad->gethandler = pad->getfunc;
- }
- }
- }
- }
-*/
-
-static void
-gst_schedule_lock_element (GstSchedule *sched,GstElement *element)
+/**
+ * gst_scheduler_enable_element:
+ * @sched: the schedulerr
+ * @element: the element to enable
+ *
+ * Enable an element for scheduling.
+ */
+void
+gst_scheduler_enable_element (GstScheduler *sched, GstElement *element)
{
- if (element->threadstate)
- cothread_lock(element->threadstate);
+ if (CLASS (sched)->enable_element)
+ CLASS (sched)->enable_element (sched, element);
}
-static void
-gst_schedule_unlock_element (GstSchedule *sched,GstElement *element)
+/**
+ * gst_scheduler_disable_element:
+ * @sched: the schedulerr
+ * @element: the element to disable
+ *
+ * Disable an element for scheduling.
+ */
+void
+gst_scheduler_disable_element (GstScheduler *sched, GstElement *element)
{
- if (element->threadstate)
- cothread_unlock(element->threadstate);
+ if (CLASS (sched)->disable_element)
+ CLASS (sched)->disable_element (sched, element);
}
-
-/*************** INCREMENTAL SCHEDULING CODE STARTS HERE ***************/
-
-
-static void gst_schedule_class_init (GstScheduleClass *klass);
-static void gst_schedule_init (GstSchedule *schedule);
-
-static GstObjectClass *parent_class = NULL;
-
-GType
-gst_schedule_get_type (void)
+/**
+ * gst_scheduler_remove_element:
+ * @sched: the schedulerr
+ * @element: the element to remove
+ *
+ * Remove an element from the schedulerr.
+ */
+void
+gst_scheduler_remove_element (GstScheduler *sched, GstElement *element)
{
- if (!_gst_schedule_type) {
- static const GTypeInfo schedule_info = {
- sizeof(GstScheduleClass),
- NULL,
- NULL,
- (GClassInitFunc)gst_schedule_class_init,
- NULL,
- NULL,
- sizeof(GstSchedule),
- 0,
- (GInstanceInitFunc)gst_schedule_init,
- NULL
- };
- _gst_schedule_type = g_type_register_static(GST_TYPE_OBJECT, "GstSchedule", &schedule_info, 0);
- }
- return _gst_schedule_type;
+ if (CLASS (sched)->remove_element)
+ CLASS (sched)->remove_element (sched, element);
}
-static void
-gst_schedule_class_init (GstScheduleClass *klass)
+void
+gst_scheduler_lock_element (GstScheduler *sched, GstElement *element)
{
- parent_class = g_type_class_ref(GST_TYPE_OBJECT);
+ if (CLASS (sched)->lock_element)
+ CLASS (sched)->lock_element (sched, element);
}
-static void
-gst_schedule_init (GstSchedule *schedule)
+void
+gst_scheduler_unlock_element (GstScheduler *sched, GstElement *element)
{
- schedule->add_element = GST_DEBUG_FUNCPTR(gst_schedule_add_element);
- schedule->remove_element = GST_DEBUG_FUNCPTR(gst_schedule_remove_element);
- schedule->enable_element = GST_DEBUG_FUNCPTR(gst_schedule_enable_element);
- schedule->disable_element = GST_DEBUG_FUNCPTR(gst_schedule_disable_element);
- schedule->lock_element = GST_DEBUG_FUNCPTR(gst_schedule_lock_element);
- schedule->unlock_element = GST_DEBUG_FUNCPTR(gst_schedule_unlock_element);
- schedule->pad_connect = GST_DEBUG_FUNCPTR(gst_schedule_pad_connect);
- schedule->pad_disconnect = GST_DEBUG_FUNCPTR(gst_schedule_pad_disconnect);
- schedule->pad_select = GST_DEBUG_FUNCPTR(gst_schedule_pad_select);
- schedule->iterate = GST_DEBUG_FUNCPTR(gst_schedule_iterate);
+ if (CLASS (sched)->unlock_element)
+ CLASS (sched)->unlock_element (sched, element);
}
/**
- * gst_schedule_new:
- * @parent: the parent of the new scheduler
+ * gst_scheduler_iterate:
+ * @sched: the schedulerr
*
- * Create a new scheduler for the given parent.
+ * Perform one iteration on the schedulerr.
*
- * Returns: the new scheduler.
+ * Returns: a boolean indicating something usefull has happened.
*/
-GstSchedule*
-gst_schedule_new(GstElement *parent)
+gboolean
+gst_scheduler_iterate (GstScheduler *sched)
{
- GstSchedule *sched = GST_SCHEDULE (g_object_new(GST_TYPE_SCHEDULE,NULL));
-
- sched->parent = parent;
-
- return sched;
+ if (CLASS (sched)->iterate)
+ CLASS (sched)->iterate (sched);
}
-/* this function will look at a pad and determine if the peer parent is
- * a possible candidate for connecting up in the same chain. */
-/* DEPRACATED !!!!
-GstElement *gst_schedule_check_pad (GstSchedule *sched, GstPad *pad) {
- GstRealPad *peer;
- GstElement *element, *peerelement;
-
- GST_INFO (GST_CAT_SCHEDULING, "checking pad %s:%s for peer in scheduler",
- GST_DEBUG_PAD_NAME(pad));
-
- element = GST_ELEMENT(GST_PAD_PARENT(peer));
- GST_DEBUG(GST_CAT_SCHEDULING, "element is \"%s\"\n",GST_ELEMENT_NAME(element));
-
- peer = GST_PAD_PEER (pad);
- if (peer == NULL) return NULL;
- peerelement = GST_ELEMENT(GST_PAD_PARENT (peer));
- if (peerelement == NULL) return NULL;
- GST_DEBUG(GST_CAT_SCHEDULING, "peer element is \"%s\"\n",GST_ELEMENT_NAME(peerelement));
-
- // now check to see if it's in the same schedule
- if (GST_ELEMENT_SCHED(element) == GST_ELEMENT_SCHED(peerelement)) {
- GST_DEBUG(GST_CAT_SCHEDULING, "peer is in same schedule\n");
- return peerelement;
- }
-
- // otherwise it's not a candidate
- return NULL;
-}
-*/
-
-static GstScheduleChain *
-gst_schedule_chain_new (GstSchedule *sched)
-{
- GstScheduleChain *chain = g_new (GstScheduleChain, 1);
-
- // initialize the chain with sane values
- chain->sched = sched;
- chain->disabled = NULL;
- chain->elements = NULL;
- chain->num_elements = 0;
- chain->entry = NULL;
- chain->cothreaded_elements = 0;
- chain->schedule = FALSE;
-
- // add the chain to the schedules' list of chains
- sched->chains = g_list_prepend (sched->chains, chain);
- sched->num_chains++;
-
- GST_INFO (GST_CAT_SCHEDULING, "created new chain %p, now are %d chains in sched %p",
- chain,sched->num_chains,sched);
-
- return chain;
-}
-
-static void
-gst_schedule_chain_destroy (GstScheduleChain *chain)
+/**
+ * gst_scheduler_show:
+ * @sched: the schedulerr
+ *
+ * Dump the state of the schedulerr
+ */
+void
+gst_scheduler_show (GstScheduler *sched)
{
- GstSchedule *sched = chain->sched;
-
- // remove the chain from the schedules' list of chains
- chain->sched->chains = g_list_remove (chain->sched->chains, chain);
- chain->sched->num_chains--;
-
- // destroy the chain
- g_list_free (chain->disabled); // should be empty...
- g_list_free (chain->elements); // ditto
- g_free (chain);
-
- GST_INFO (GST_CAT_SCHEDULING, "destroyed chain %p, now are %d chains in sched %p",chain,sched->num_chains,sched);
+ if (CLASS (sched)->show)
+ CLASS (sched)->show (sched);
}
-static void
-gst_schedule_chain_add_element (GstScheduleChain *chain, GstElement *element)
-{
- GST_INFO (GST_CAT_SCHEDULING, "adding element \"%s\" to chain %p", GST_ELEMENT_NAME (element),chain);
-
- // set the sched pointer for the element
- element->sched = chain->sched;
-
- // add the element to the list of 'disabled' elements
- chain->disabled = g_list_prepend (chain->disabled, element);
- chain->num_elements++;
-}
+/*
+ * Factory stuff starts here
+ *
+ */
-static void
-gst_schedule_chain_enable_element (GstScheduleChain *chain, GstElement *element)
-{
- GST_INFO (GST_CAT_SCHEDULING, "enabling element \"%s\" in chain %p", GST_ELEMENT_NAME (element),chain);
+static GList* _gst_schedulerfactories;
- // remove from disabled list
- chain->disabled = g_list_remove (chain->disabled, element);
+static void gst_schedulerfactory_class_init (GstSchedulerFactoryClass *klass);
+static void gst_schedulerfactory_init (GstSchedulerFactory *factory);
- // add to elements list
- chain->elements = g_list_prepend (chain->elements, element);
+#ifndef GST_DISABLE_REGISTRY
+static xmlNodePtr gst_schedulerfactory_save_thyself (GstObject *object, xmlNodePtr parent);
+static void gst_schedulerfactory_restore_thyself (GstObject *object, xmlNodePtr parent);
+#endif
- // reschedule the chain
- gst_schedule_cothreaded_chain(GST_BIN(chain->sched->parent),chain);
-}
+static GstPluginFeatureClass *factory_parent_class = NULL;
+//static guint gst_schedulerfactory_signals[LAST_SIGNAL] = { 0 };
-static void
-gst_schedule_chain_disable_element (GstScheduleChain *chain, GstElement *element)
+GType
+gst_schedulerfactory_get_type (void)
{
- GST_INFO (GST_CAT_SCHEDULING, "disabling element \"%s\" in chain %p", GST_ELEMENT_NAME (element),chain);
+ static GType schedulerfactory_type = 0;
- // remove from elements list
- chain->elements = g_list_remove (chain->elements, element);
-
- // add to disabled list
- chain->disabled = g_list_prepend (chain->disabled, element);
-
- // reschedule the chain
-// FIXME this should be done only if manager state != NULL
-// gst_schedule_cothreaded_chain(GST_BIN(chain->sched->parent),chain);
+ if (!schedulerfactory_type) {
+ static const GTypeInfo schedulerfactory_info = {
+ sizeof (GstSchedulerFactoryClass),
+ NULL,
+ NULL,
+ (GClassInitFunc) gst_schedulerfactory_class_init,
+ NULL,
+ NULL,
+ sizeof(GstSchedulerFactory),
+ 0,
+ (GInstanceInitFunc) gst_schedulerfactory_init,
+ NULL
+ };
+ schedulerfactory_type = g_type_register_static (GST_TYPE_PLUGIN_FEATURE,
+ "GstSchedulerFactory", &schedulerfactory_info, 0);
+ }
+ return schedulerfactory_type;
}
static void
-gst_schedule_chain_remove_element (GstScheduleChain *chain, GstElement *element)
+gst_schedulerfactory_class_init (GstSchedulerFactoryClass *klass)
{
- GST_INFO (GST_CAT_SCHEDULING, "removing element \"%s\" from chain %p", GST_ELEMENT_NAME (element),chain);
+ GObjectClass *gobject_class;
+ GstObjectClass *gstobject_class;
+ GstPluginFeatureClass *gstpluginfeature_class;
- // if it's active, deactivate it
- if (g_list_find (chain->elements, element)) {
- gst_schedule_chain_disable_element (chain, element);
- }
+ gobject_class = (GObjectClass*)klass;
+ gstobject_class = (GstObjectClass*)klass;
+ gstpluginfeature_class = (GstPluginFeatureClass*) klass;
- // remove the element from the list of elements
- chain->disabled = g_list_remove (chain->disabled, element);
- chain->num_elements--;
+ factory_parent_class = g_type_class_ref (GST_TYPE_PLUGIN_FEATURE);
- // if there are no more elements in the chain, destroy the chain
- if (chain->num_elements == 0)
- gst_schedule_chain_destroy(chain);
+#ifndef GST_DISABLE_REGISTRY
+ gstobject_class->save_thyself = GST_DEBUG_FUNCPTR (gst_schedulerfactory_save_thyself);
+ gstobject_class->restore_thyself = GST_DEBUG_FUNCPTR (gst_schedulerfactory_restore_thyself);
+#endif
- // unset the sched pointer for the element
- element->sched = NULL;
+ _gst_schedulerfactories = NULL;
}
static void
-gst_schedule_chain_elements (GstSchedule *sched, GstElement *element1, GstElement *element2)
+gst_schedulerfactory_init (GstSchedulerFactory *factory)
{
- GList *chains;
- GstScheduleChain *chain;
- GstScheduleChain *chain1 = NULL, *chain2 = NULL;
- GstElement *element;
-
- // first find the chains that hold the two
- chains = sched->chains;
- while (chains) {
- chain = (GstScheduleChain *)(chains->data);
- chains = g_list_next(chains);
-
- if (g_list_find (chain->disabled,element1))
- chain1 = chain;
- else if (g_list_find (chain->elements,element1))
- chain1 = chain;
-
- if (g_list_find (chain->disabled,element2))
- chain2 = chain;
- else if (g_list_find (chain->elements,element2))
- chain2 = chain;
- }
-
- // first check to see if they're in the same chain, we're done if that's the case
- if ((chain1 != NULL) && (chain1 == chain2)) {
- GST_INFO (GST_CAT_SCHEDULING, "elements are already in the same chain");
- return;
- }
-
- // now, if neither element has a chain, create one
- if ((chain1 == NULL) && (chain2 == NULL)) {
- GST_INFO (GST_CAT_SCHEDULING, "creating new chain to hold two new elements");
- chain = gst_schedule_chain_new (sched);
- gst_schedule_chain_add_element (chain, element1);
- gst_schedule_chain_add_element (chain, element2);
- // FIXME chain changed here
-// gst_schedule_cothreaded_chain(chain->sched->parent,chain);
-
- // otherwise if both have chains already, join them
- } else if ((chain1 != NULL) && (chain2 != NULL)) {
- GST_INFO (GST_CAT_SCHEDULING, "merging chain %p into chain %p",chain2,chain1);
- // take the contents of chain2 and merge them into chain1
- chain1->disabled = g_list_concat (chain1->disabled, g_list_copy(chain2->disabled));
- chain1->elements = g_list_concat (chain1->elements, g_list_copy(chain2->elements));
- chain1->num_elements += chain2->num_elements;
- // FIXME chain changed here
-// gst_schedule_cothreaded_chain(chain->sched->parent,chain);
-
- gst_schedule_chain_destroy(chain2);
-
- // otherwise one has a chain already, the other doesn't
- } else {
- // pick out which one has the chain, and which doesn't
- if (chain1 != NULL) chain = chain1, element = element2;
- else chain = chain2, element = element1;
-
- GST_INFO (GST_CAT_SCHEDULING, "adding element to existing chain");
- gst_schedule_chain_add_element (chain, element);
- // FIXME chain changed here
-// gst_schedule_cothreaded_chain(chain->sched->parent,chain);
- }
+ _gst_schedulerfactories = g_list_prepend (_gst_schedulerfactories, factory);
}
+
/**
- * gst_schedule_pad_connect:
- * @sched: the scheduler
- * @srcpad: the srcpad to connect
- * @sinkpad: the sinkpad to connect to
+ * gst_schedulerfactory_new:
+ * @name: name of schedulerfactory to create
+ * @longdesc: long description of schedulerfactory to create
+ * @type: the gtk type of the GstScheduler element of this factory
*
- * Connect the srcpad to the given sinkpad.
+ * Create a new schedulerfactory with the given parameters
+ *
+ * Returns: a new #GstSchedulerFactory.
*/
-void
-gst_schedule_pad_connect (GstSchedule *sched, GstPad *srcpad, GstPad *sinkpad)
+GstSchedulerFactory*
+gst_schedulerfactory_new (const gchar *name, const gchar *longdesc, GType type)
{
- GstElement *srcelement,*sinkelement;
-
- srcelement = GST_PAD_PARENT(srcpad);
- g_return_if_fail(srcelement != NULL);
- sinkelement = GST_PAD_PARENT(sinkpad);
- g_return_if_fail(sinkelement != NULL);
+ GstSchedulerFactory *factory;
- GST_INFO (GST_CAT_SCHEDULING, "have pad connected callback on %s:%s to %s:%s",GST_DEBUG_PAD_NAME(srcpad),GST_DEBUG_PAD_NAME(sinkpad));
- GST_DEBUG(GST_CAT_SCHEDULING, "srcpad sched is %p, sinkpad sched is %p\n",
-GST_ELEMENT_SCHED(srcelement),GST_ELEMENT_SCHED(sinkelement));
-
- if (GST_ELEMENT_SCHED(srcelement) == GST_ELEMENT_SCHED(sinkelement)) {
- GST_INFO (GST_CAT_SCHEDULING, "peer %s:%s is in same schedule, chaining together",GST_DEBUG_PAD_NAME(sinkpad));
- gst_schedule_chain_elements (sched, srcelement, sinkelement);
+ g_return_val_if_fail(name != NULL, NULL);
+ factory = gst_schedulerfactory_find (name);
+ if (!factory) {
+ factory = GST_SCHEDULERFACTORY (g_object_new (GST_TYPE_SCHEDULERFACTORY, NULL));
}
-}
-// find the chain within the schedule that holds the element, if any
-static GstScheduleChain *
-gst_schedule_find_chain (GstSchedule *sched, GstElement *element)
-{
- GList *chains;
- GstScheduleChain *chain;
-
- GST_INFO (GST_CAT_SCHEDULING, "searching for element \"%s\" in chains",GST_ELEMENT_NAME(element));
-
- chains = sched->chains;
- while (chains) {
- chain = (GstScheduleChain *)(chains->data);
- chains = g_list_next (chains);
-
- if (g_list_find (chain->elements, element))
- return chain;
- if (g_list_find (chain->disabled, element))
- return chain;
- }
+ gst_object_set_name (GST_OBJECT (factory), name);
+ if (factory->longdesc)
+ g_free (factory->longdesc);
+ factory->longdesc = g_strdup (longdesc);
+ factory->type = type;
- return NULL;
-}
-
-static void
-gst_schedule_chain_recursive_add (GstScheduleChain *chain, GstElement *element)
-{
- GList *pads;
- GstPad *pad;
- GstElement *peerelement;
-
- // add the element to the chain
- gst_schedule_chain_add_element (chain, element);
-
- GST_DEBUG(GST_CAT_SCHEDULING, "recursing on element \"%s\"\n",GST_ELEMENT_NAME(element));
- // now go through all the pads and see which peers can be added
- pads = element->pads;
- while (pads) {
- pad = GST_PAD(pads->data);
- pads = g_list_next (pads);
-
- GST_DEBUG(GST_CAT_SCHEDULING, "have pad %s:%s, checking for valid peer\n",GST_DEBUG_PAD_NAME(pad));
- // if the peer exists and could be in the same chain
- if (GST_PAD_PEER(pad)) {
- GST_DEBUG(GST_CAT_SCHEDULING, "has peer %s:%s\n",GST_DEBUG_PAD_NAME(GST_PAD_PEER(pad)));
- peerelement = GST_PAD_PARENT(GST_PAD_PEER(pad));
- if (GST_ELEMENT_SCHED(GST_PAD_PARENT(pad)) == GST_ELEMENT_SCHED(peerelement)) {
- GST_DEBUG(GST_CAT_SCHEDULING, "peer \"%s\" is valid for same chain\n",GST_ELEMENT_NAME(peerelement));
- // if it's not already in a chain, add it to this one
- if (gst_schedule_find_chain (chain->sched, peerelement) == NULL) {
- gst_schedule_chain_recursive_add (chain, peerelement);
- }
- }
- }
- }
+ return factory;
}
/**
- * gst_schedule_pad_disconnect:
- * @sched: the scheduler
- * @srcpad: the srcpad to disconnect
- * @sinkpad: the sinkpad to disconnect from
+ * gst_schedulerfactory_destroy:
+ * @factory: factory to destroy
*
- * Disconnect the srcpad to the given sinkpad.
+ * Removes the scheduler from the global list.
*/
void
-gst_schedule_pad_disconnect (GstSchedule *sched, GstPad *srcpad, GstPad *sinkpad)
+gst_schedulerfactory_destroy (GstSchedulerFactory *factory)
{
- GstScheduleChain *chain;
- GstElement *element1, *element2;
- GstScheduleChain *chain1, *chain2;
-
- GST_INFO (GST_CAT_SCHEDULING, "disconnecting pads %s:%s and %s:%s",
- GST_DEBUG_PAD_NAME(srcpad), GST_DEBUG_PAD_NAME(sinkpad));
-
- // we need to have the parent elements of each pad
- element1 = GST_ELEMENT(GST_PAD_PARENT(srcpad));
- element2 = GST_ELEMENT(GST_PAD_PARENT(sinkpad));
-
- // first task is to remove the old chain they belonged to.
- // this can be accomplished by taking either of the elements,
- // since they are guaranteed to be in the same chain
- // FIXME is it potentially better to make an attempt at splitting cleaner??
- chain = gst_schedule_find_chain (sched, element1);
- if (chain) {
- GST_INFO (GST_CAT_SCHEDULING, "destroying chain");
- gst_schedule_chain_destroy (chain);
- }
+ g_return_if_fail (factory != NULL);
- // now create a new chain to hold element1 and build it from scratch
- chain1 = gst_schedule_chain_new (sched);
- gst_schedule_chain_recursive_add (chain1, element1);
+ _gst_schedulerfactories = g_list_remove (_gst_schedulerfactories, factory);
- // check the other element to see if it landed in the newly created chain
- if (gst_schedule_find_chain (sched, element2) == NULL) {
- // if not in chain, create chain and build from scratch
- chain2 = gst_schedule_chain_new (sched);
- gst_schedule_chain_recursive_add (chain2, element2);
- }
+ // we don't free the struct bacause someone might have a handle to it..
}
/**
- * gst_schedule_pad_select:
- * @sched: the scheduler
- * @padlist: the padlist to select on
+ * gst_schedulerfactory_find:
+ * @name: name of schedulerfactory to find
*
- * register the given padlist for a select operation.
+ * Search for an schedulerfactory of the given name.
*
- * Returns: the pad which received a buffer.
+ * Returns: #GstSchedulerFactory if found, NULL otherwise
*/
-GstPad*
-gst_schedule_pad_select (GstSchedule *sched, GList *padlist)
+GstSchedulerFactory*
+gst_schedulerfactory_find (const gchar *name)
{
- GstPad *pad = NULL;
- GList *padlist2 = padlist;
- GST_INFO (GST_CAT_SCHEDULING, "performing select");
-
- while (padlist2) {
- pad = GST_PAD (padlist2->data);
-
- if (gst_pad_peek (pad)) {
- g_print ("found something in pad %s:%s\n", GST_DEBUG_PAD_NAME (pad));
- return pad;
- }
-
- padlist2 = g_list_next (padlist2);
- }
+ GList *walk;
+ GstSchedulerFactory *factory;
- /* else there is nothing ready to consume, set up the select functions */
- while (padlist) {
- pad = GST_PAD (padlist->data);
+ g_return_val_if_fail(name != NULL, NULL);
- GST_RPAD_CHAINHANDLER(pad) = GST_DEBUG_FUNCPTR(gst_schedule_select_proxy);
+ GST_DEBUG (0,"gstscheduler: find \"%s\"\n", name);
- padlist = g_list_next (padlist);
+ walk = _gst_schedulerfactories;
+ while (walk) {
+ factory = (GstSchedulerFactory *)(walk->data);
+ if (!strcmp (name, GST_OBJECT_NAME (factory)))
+ return factory;
+ walk = g_list_next (walk);
}
- if (pad != NULL) {
- GstRealPad *peer = GST_RPAD_PEER(pad);
-
- cothread_switch (GST_ELEMENT (GST_PAD_PARENT (peer))->threadstate);
- g_print ("%p %s\n", GST_ELEMENT (GST_PAD_PARENT (pad)), gst_element_get_name (GST_ELEMENT (GST_PAD_PARENT (pad))));
- pad = GST_ELEMENT (GST_PAD_PARENT (pad))->select_pad;
-
- g_assert (pad != NULL);
- g_print ("back from select (%s:%s)\n", GST_DEBUG_PAD_NAME (pad));
- }
- return pad;
+ return NULL;
}
/**
- * gst_schedule_add_element:
- * @sched: the scheduler
- * @element: the element to add to the scheduler
+ * gst_schedulerfactory_get_list:
*
- * Add an element to the scheduler.
- */
-void
-gst_schedule_add_element (GstSchedule *sched, GstElement *element)
-{
- GList *pads;
- GstPad *pad;
- GstElement *peerelement;
- GstScheduleChain *chain;
-
- g_return_if_fail (element != NULL);
- g_return_if_fail (GST_IS_ELEMENT(element));
-
- // if it's already in this schedule, don't bother doing anything
- if (GST_ELEMENT_SCHED(element) == sched) return;
-
- GST_INFO (GST_CAT_SCHEDULING, "adding element \"%s\" to schedule",
- GST_ELEMENT_NAME(element));
-
- // if the element already has a different scheduler, remove the element from it
- if (GST_ELEMENT_SCHED(element)) {
- gst_schedule_remove_element(GST_ELEMENT_SCHED(element),element);
- }
-
- // set the sched pointer in the element itself
- GST_ELEMENT_SCHED(element) = sched;
-
- // only deal with elements after this point, not bins
- // exception is made for Bin's that are schedulable, like the autoplugger
- if (GST_IS_BIN (element) && !GST_FLAG_IS_SET(element, GST_BIN_SELF_SCHEDULABLE)) return;
-
- // first add it to the list of elements that are to be scheduled
- sched->elements = g_list_prepend (sched->elements, element);
- sched->num_elements++;
-
- // create a chain to hold it, and add
- chain = gst_schedule_chain_new (sched);
- gst_schedule_chain_add_element (chain, element);
-
- // set the sched pointer in all the pads
- pads = element->pads;
- while (pads) {
- pad = GST_PAD(pads->data);
- pads = g_list_next(pads);
-
- // we only operate on real pads
- if (!GST_IS_REAL_PAD(pad)) continue;
-
- // set the pad's sched pointer
- gst_pad_set_sched (pad, sched);
-
- // if the peer element exists and is a candidate
- if (GST_PAD_PEER(pad)) {
- peerelement = GST_PAD_PARENT( GST_PAD_PEER (pad) );
- if (GST_ELEMENT_SCHED(element) == GST_ELEMENT_SCHED(peerelement)) {
- GST_INFO (GST_CAT_SCHEDULING, "peer is in same schedule, chaining together");
- // make sure that the two elements are in the same chain
- gst_schedule_chain_elements (sched,element,peerelement);
- }
- }
- }
-}
-
-/**
- * gst_schedule_enable_element:
- * @sched: the scheduler
- * @element: the element to enable
+ * Get the global list of schedulerfactories.
*
- * Enable an element for scheduling.
+ * Returns: GList of type #GstSchedulerFactory
*/
-void
-gst_schedule_enable_element (GstSchedule *sched, GstElement *element)
+GList*
+gst_schedulerfactory_get_list (void)
{
- GstScheduleChain *chain;
-
- // find the chain the element's in
- chain = gst_schedule_find_chain (sched, element);
-
- if (chain)
- gst_schedule_chain_enable_element (chain, element);
- else
- GST_INFO (GST_CAT_SCHEDULING, "element not found in any chain, not enabling");
+ return _gst_schedulerfactories;
}
/**
- * gst_schedule_disable_element:
- * @sched: the scheduler
- * @element: the element to disable
+ * gst_schedulerfactory_create:
+ * @factory: the factory used to create the instance
*
- * Disable an element for scheduling.
+ * Create a new #GstScheduler instance from the
+ * given schedulerfactory.
+ *
+ * Returns: A new #GstScheduler instance.
*/
-void
-gst_schedule_disable_element (GstSchedule *sched, GstElement *element)
+GstScheduler*
+gst_schedulerfactory_create (GstSchedulerFactory *factory, GstElement *parent)
{
- GstScheduleChain *chain;
+ GstScheduler *new = NULL;
- // find the chain the element is in
- chain = gst_schedule_find_chain (sched, element);
+ g_return_val_if_fail (factory != NULL, NULL);
- // remove it from the chain
- if (chain) {
- gst_schedule_chain_disable_element(chain,element);
+ if (gst_plugin_feature_ensure_loaded (GST_PLUGIN_FEATURE (factory))) {
+ g_return_val_if_fail (factory->type != 0, NULL);
+
+ new = GST_SCHEDULER (g_object_new (factory->type, NULL));
+ new->parent = parent;
}
+
+ return new;
}
/**
- * gst_schedule_remove_element:
- * @sched: the scheduler
- * @element: the element to remove
+ * gst_schedulerfactory_make:
+ * @name: the name of the factory used to create the instance
+ *
+ * Create a new #GstScheduler instance from the
+ * schedulerfactory with the given name.
*
- * Remove an element from the scheduler.
+ * Returns: A new #GstScheduler instance.
*/
-void
-gst_schedule_remove_element (GstSchedule *sched, GstElement *element)
+GstScheduler*
+gst_schedulerfactory_make (const gchar *name, GstElement *parent)
{
- GstScheduleChain *chain;
-
- g_return_if_fail (element != NULL);
- g_return_if_fail (GST_IS_ELEMENT(element));
-
- if (g_list_find (sched->elements, element)) {
- GST_INFO (GST_CAT_SCHEDULING, "removing element \"%s\" from schedule",
- GST_ELEMENT_NAME(element));
+ GstSchedulerFactory *factory;
- // find what chain the element is in
- chain = gst_schedule_find_chain(sched, element);
+ g_return_val_if_fail (name != NULL, NULL);
- // remove it from its chain
- gst_schedule_chain_remove_element (chain, element);
+ factory = gst_schedulerfactory_find (name);
- // remove it from the list of elements
- sched->elements = g_list_remove (sched->elements, element);
- sched->num_elements--;
+ if (factory == NULL)
+ return NULL;
- // unset the scheduler pointer in the element
- GST_ELEMENT_SCHED(element) = NULL;
- }
+ return gst_schedulerfactory_create (factory, parent);
}
-/**
- * gst_schedule_iterate:
- * @sched: the scheduler
- *
- * Perform one iteration on the scheduler.
- *
- * Returns: a boolean indicating something usefull has happened.
- */
-gboolean
-gst_schedule_iterate (GstSchedule *sched)
+#ifndef GST_DISABLE_REGISTRY
+static xmlNodePtr
+gst_schedulerfactory_save_thyself (GstObject *object, xmlNodePtr parent)
{
- GstBin *bin = GST_BIN(sched->parent);
- GList *chains;
- GstScheduleChain *chain;
- GstElement *entry;
- gint num_scheduled = 0;
- gboolean eos = FALSE;
- GList *elements;
-
- GST_DEBUG_ENTER("(\"%s\")", GST_ELEMENT_NAME (bin));
-
- g_return_val_if_fail (bin != NULL, TRUE);
- g_return_val_if_fail (GST_IS_BIN (bin), TRUE);
-// g_return_val_if_fail (GST_STATE (bin) == GST_STATE_PLAYING, TRUE);
-
- // step through all the chains
- chains = sched->chains;
-// if (chains == NULL) return FALSE;
-g_return_val_if_fail (chains != NULL, FALSE);
- while (chains) {
- chain = (GstScheduleChain *)(chains->data);
- chains = g_list_next (chains);
-
-// if (!chain->need_scheduling) continue;
-
-// if (chain->need_cothreads) {
- // 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 (GST_CAT_DATAFLOW,"starting iteration via cothreads\n");
-
- if (chain->elements) {
- entry = NULL; //MattH ADDED?
-GST_DEBUG(GST_CAT_SCHEDULING,"there are %d elements in this chain\n",chain->num_elements);
- elements = chain->elements;
- while (elements) {
- entry = GST_ELEMENT(elements->data);
- elements = g_list_next(elements);
- if (GST_FLAG_IS_SET(entry,GST_ELEMENT_DECOUPLED)) {
- GST_DEBUG(GST_CAT_SCHEDULING,"entry \"%s\" is DECOUPLED, skipping\n",GST_ELEMENT_NAME(entry));
- entry = NULL;
- } else if (GST_FLAG_IS_SET(entry,GST_ELEMENT_NO_ENTRY)) {
- GST_DEBUG(GST_CAT_SCHEDULING,"entry \"%s\" is not valid, skipping\n",GST_ELEMENT_NAME(entry));
- entry = NULL;
- } else
- break;
- }
- if (entry) {
- GST_FLAG_SET (entry, GST_ELEMENT_COTHREAD_STOPPING);
- GST_DEBUG (GST_CAT_DATAFLOW,"set COTHREAD_STOPPING flag on \"%s\"(@%p)\n",
- GST_ELEMENT_NAME (entry),entry);
- cothread_switch (entry->threadstate);
-
- // following is a check to see if the chain was interrupted due to a
- // top-half state_change(). (i.e., if there's a pending state.)
- //
- // if it was, return to gstthread.c::gst_thread_main_loop() to
- // execute the state change.
- GST_DEBUG (GST_CAT_DATAFLOW,"cothread switch ended or interrupted\n");
- if (GST_STATE_PENDING(GST_SCHEDULE(sched)->parent) != GST_STATE_VOID_PENDING)
- {
- GST_DEBUG (GST_CAT_DATAFLOW,"handle pending state %d\n",
- GST_STATE_PENDING(GST_SCHEDULE(sched)->parent));
- return 0;
- }
-
- } else {
- GST_INFO (GST_CAT_DATAFLOW,"NO ENTRY INTO CHAIN!");
-gst_schedule_show(sched);
- //eos = TRUE;
- //gst_element_set_state (GST_ELEMENT (bin), GST_STATE_PAUSED);
- }
- } else {
- GST_INFO (GST_CAT_DATAFLOW,"NO ENABLED ELEMENTS IN CHAIN!!");
- eos = TRUE;
- }
-
-/*
- } else {
- GST_DEBUG (GST_CAT_DATAFLOW,"starting iteration via chain-functions\n");
-
- entries = chain->entries;
-
- g_assert (entries != NULL);
-
- while (entries) {
- entry = GST_ELEMENT (entries->data);
- entries = g_list_next (entries);
-
- GST_DEBUG (GST_CAT_DATAFLOW,"have entry \"%s\"\n",GST_ELEMENT_NAME (entry));
-
- if (GST_IS_BIN (entry)) {
- gst_bin_iterate (GST_BIN (entry));
- } else {
- pads = entry->pads;
- while (pads) {
- pad = GST_PAD (pads->data);
- GST_DEBUG (GST_CAT_DATAFLOW,"calling getfunc of %s:%s\n",GST_DEBUG_PAD_NAME(pad));
- if (GST_REAL_PAD(pad)->getfunc == NULL)
- fprintf(stderr, "error, no getfunc in \"%s\"\n", GST_ELEMENT_NAME (entry));
- else
- buf = (GST_REAL_PAD(pad)->getfunc)(pad);
- if (buf) gst_pad_push(pad,buf);
- }
- pads = g_list_next (pads);
- }
- }
- }
- }*/
- num_scheduled++;
- }
+ GstSchedulerFactory *factory;
-/*
- // check if nothing was scheduled that was ours..
- if (!num_scheduled) {
- // are there any other elements that are still busy?
- if (bin->num_eos_providers) {
- GST_LOCK (bin);
- GST_DEBUG (GST_CATA_DATAFLOW,"waiting for eos providers\n");
- g_cond_wait (bin->eoscond, GST_OBJECT(bin)->lock);
- GST_DEBUG (GST_CAT_DATAFLOW,"num eos providers %d\n", bin->num_eos_providers);
- GST_UNLOCK (bin);
- }
- else {
- gst_element_signal_eos (GST_ELEMENT (bin));
- eos = TRUE;
- }
+ g_return_val_if_fail (GST_IS_SCHEDULERFACTORY (object), parent);
+
+ factory = GST_SCHEDULERFACTORY (object);
+
+ if (GST_OBJECT_CLASS (factory_parent_class)->save_thyself) {
+ GST_OBJECT_CLASS (factory_parent_class)->save_thyself (object, parent);
}
-*/
- GST_DEBUG (GST_CAT_DATAFLOW, "leaving (%s)\n", GST_ELEMENT_NAME (bin));
- return !eos;
-}
+ xmlNewChild (parent, NULL, "longdesc", factory->longdesc);
+ return parent;
+}
/**
- * gst_schedule_show:
- * @sched: the scheduler
+ * gst_schedulerfactory_load_thyself:
+ * @parent: the parent XML node pointer
*
- * Dump the state of the scheduler
+ * Load an schedulerfactory from the given XML parent node.
+ *
+ * Returns: A new factory based on the XML node.
*/
-void
-gst_schedule_show (GstSchedule *sched)
+static void
+gst_schedulerfactory_restore_thyself (GstObject *object, xmlNodePtr parent)
{
- GList *chains, *elements;
- GstElement *element;
- GstScheduleChain *chain;
-
- if (sched == NULL) {
- g_print("schedule doesn't exist for this element\n");
- return;
- }
-
- g_return_if_fail(GST_IS_SCHEDULE(sched));
-
- g_print("SCHEDULE DUMP FOR MANAGING BIN \"%s\"\n",GST_ELEMENT_NAME(sched->parent));
+ GstSchedulerFactory *factory = GST_SCHEDULERFACTORY (object);
+ xmlNodePtr children = parent->xmlChildrenNode;
- g_print("schedule has %d elements in it: ",sched->num_elements);
- elements = sched->elements;
- while (elements) {
- element = GST_ELEMENT(elements->data);
- elements = g_list_next(elements);
-
- g_print("%s, ",GST_ELEMENT_NAME(element));
+ if (GST_OBJECT_CLASS (factory_parent_class)->restore_thyself) {
+ GST_OBJECT_CLASS (factory_parent_class)->restore_thyself (object, parent);
}
- g_print("\n");
-
- g_print("schedule has %d chains in it\n",sched->num_chains);
- chains = sched->chains;
- while (chains) {
- chain = (GstScheduleChain *)(chains->data);
- chains = g_list_next(chains);
- g_print("%p: ",chain);
-
- elements = chain->disabled;
- while (elements) {
- element = GST_ELEMENT(elements->data);
- elements = g_list_next(elements);
-
- g_print("!%s, ",GST_ELEMENT_NAME(element));
+ while (children) {
+ if (!strcmp(children->name, "name")) {
+ gst_object_set_name (GST_OBJECT (factory), xmlNodeGetContent (children));
}
-
- elements = chain->elements;
- while (elements) {
- element = GST_ELEMENT(elements->data);
- elements = g_list_next(elements);
-
- g_print("%s, ",GST_ELEMENT_NAME(element));
+ if (!strcmp(children->name, "longdesc")) {
+ factory->longdesc = xmlNodeGetContent (children);
}
- g_print("\n");
+ children = children->next;
}
}
+#endif /* GST_DISABLE_REGISTRY */
diff --git a/gst/gstscheduler.h b/gst/gstscheduler.h
index b65c5ed2d88e7fd5652a886239d8adc354fd1a0d..042664d7b9278808c97f25eb0de4a4c291e5d407 100644 (file)
--- a/gst/gstscheduler.h
+++ b/gst/gstscheduler.h
* Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
* 2000 Wim Taymans <wtay@chello.be>
*
- * gstscheduler.h: Header for default scheduler code
+ * gstschedulerr.h: Header for default schedulerr code
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
#ifndef __GST_SCHEDULER_H__
#define __GST_SCHEDULER_H__
+#include <glib.h>
#include <gst/gstelement.h>
#include <gst/gstbin.h>
-
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
-extern GType _gst_schedule_type;
-
-#define GST_TYPE_SCHEDULE (_gst_schedule_type)
-# define GST_IS_SCHEDULE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_SCHEDULE))
-# define GST_IS_SCHEDULE_CLASS(obj) (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_SCHEDULE))
-
-#define GST_SCHEDULE_FAST(obj) ((GstSchedule*)(obj))
-#define GST_SCHEDULE_CLASS_FAST(klass) ((GstScheduleClass*)(klass))
-
-#ifdef GST_TYPE_PARANOID
-# define GST_SCHEDULE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_SCHEDULE, GstSchedule))
-# define GST_SCHEDULE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_SCHEDULE, GstScheduleClass))
-#else
-# define GST_SCHEDULE GST_SCHEDULE_FAST
-# define GST_SCHEDULE_CLASS GST_SCHEDULE_CLASS_FAST
-#endif
+#define GST_TYPE_SCHEDULER \
+ (gst_scheduler_get_type())
+#define GST_SCHEDULER(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_SCHEDULER,GstScheduler))
+#define GST_SCHEDULER_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_SCHEDULER,GstSchedulerClass))
+#define GST_IS_SCHEDULER(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_SCHEDULER))
+#define GST_IS_SCHEDULER_CLASS(obj) \
+ (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_SCHEDULER))
#define GST_SCHED_PARENT(sched) ((sched)->parent)
-//typedef struct _GstSchedule GstSchedule;
-//typedef struct _GstScheduleClass GstScheduleClass;
-typedef struct _GstScheduleChain GstScheduleChain;
+//typedef struct _GstScheduler GstScheduler;
+//typedef struct _GstSchedulerClass GstSchedulerClass;
-struct _GstSchedule {
+struct _GstScheduler {
GstObject object;
GstElement *parent;
GList *chains;
gint num_chains;
-
- void (*add_element) (GstSchedule *sched, GstElement *element);
- void (*remove_element) (GstSchedule *sched, GstElement *element);
- void (*enable_element) (GstSchedule *sched, GstElement *element);
- void (*disable_element) (GstSchedule *sched, GstElement *element);
- void (*lock_element) (GstSchedule *sched, GstElement *element);
- void (*unlock_element) (GstSchedule *sched, GstElement *element);
- void (*pad_connect) (GstSchedule *sched, GstPad *srcpad, GstPad *sinkpad);
- void (*pad_disconnect) (GstSchedule *sched, GstPad *srcpad, GstPad *sinkpad);
- void (*pad_select) (GstSchedule *sched, GList *padlist);
- gboolean (*iterate) (GstSchedule *sched);
};
-struct _GstScheduleClass {
+struct _GstSchedulerClass {
GstObjectClass parent_class;
+
+ void (*add_element) (GstScheduler *sched, GstElement *element);
+ void (*remove_element) (GstScheduler *sched, GstElement *element);
+ void (*enable_element) (GstScheduler *sched, GstElement *element);
+ void (*disable_element) (GstScheduler *sched, GstElement *element);
+ void (*lock_element) (GstScheduler *sched, GstElement *element);
+ void (*unlock_element) (GstScheduler *sched, GstElement *element);
+ void (*pad_connect) (GstScheduler *sched, GstPad *srcpad, GstPad *sinkpad);
+ void (*pad_disconnect) (GstScheduler *sched, GstPad *srcpad, GstPad *sinkpad);
+ void (*pad_select) (GstScheduler *sched, GList *padlist);
+ gboolean (*iterate) (GstScheduler *sched);
+
+ /* for debugging */
+ void (*show) (GstScheduler *sched);
};
-#define GST_SCHEDULE_SAFETY(sched) if (sched)
-//#define GST_SCHEDULE_SAFETY(sched)
-
-#define GST_SCHEDULE_ADD_ELEMENT(sched,element) G_STMT_START{ \
- GST_SCHEDULE_SAFETY(sched) { ((sched)->add_element((sched),(element))); } \
-}G_STMT_END
-#define GST_SCHEDULE_REMOVE_ELEMENT(sched,element) G_STMT_START{ \
- GST_SCHEDULE_SAFETY(sched) { ((sched)->remove_element((sched),(element))); } \
-}G_STMT_END
-#define GST_SCHEDULE_ENABLE_ELEMENT(sched,element) G_STMT_START{ \
- GST_SCHEDULE_SAFETY(sched) { ((sched)->enable_element((sched),(element))); } \
-}G_STMT_END
-#define GST_SCHEDULE_DISABLE_ELEMENT(sched,element) G_STMT_START{ \
- GST_SCHEDULE_SAFETY(sched) { ((sched)->disable_element((sched),(element))); } \
-}G_STMT_END
-#define GST_SCHEDULE_LOCK_ELEMENT(sched,element) G_STMT_START{ \
- GST_SCHEDULE_SAFETY(sched) { if ((sched)->lock_element != NULL) \
- ((sched)->lock_element((sched),(element))); } \
-}G_STMT_END
-#define GST_SCHEDULE_UNLOCK_ELEMENT(sched,element) G_STMT_START{ \
- GST_SCHEDULE_SAFETY(sched) { if ((sched)->unlock_element != NULL) \
- ((sched)->unlock_element((sched),(element))); } \
-}G_STMT_END
-#define GST_SCHEDULE_PAD_CONNECT(sched,srcpad,sinkpad) G_STMT_START{ \
- GST_SCHEDULE_SAFETY(sched) { ((sched)->pad_connect((sched),(srcpad),(sinkpad))); } \
-}G_STMT_END
-#define GST_SCHEDULE_PAD_DISCONNECT(sched,srcpad,sinkpad) G_STMT_START{ \
- GST_SCHEDULE_SAFETY(sched) { ((sched)->pad_disconnect((sched),(srcpad),(sinkpad))); } \
-}G_STMT_END
-#define GST_SCHEDULE_ITERATE(sched) \
- ((sched)->iterate((sched)))
-
-
-
-struct _GstScheduleChain {
- GstSchedule *sched;
-
- GList *disabled;
+GType gst_scheduler_get_type (void);
- GList *elements;
- gint num_elements;
+void gst_scheduler_add_element (GstScheduler *sched, GstElement *element);
+void gst_scheduler_remove_element (GstScheduler *sched, GstElement *element);
+void gst_scheduler_enable_element (GstScheduler *sched, GstElement *element);
+void gst_scheduler_disable_element (GstScheduler *sched, GstElement *element);
+void gst_scheduler_lock_element (GstScheduler *sched, GstElement *element);
+void gst_scheduler_unlock_element (GstScheduler *sched, GstElement *element);
+void gst_scheduler_pad_connect (GstScheduler *sched, GstPad *srcpad, GstPad *sinkpad);
+void gst_scheduler_pad_disconnect (GstScheduler *sched, GstPad *srcpad, GstPad *sinkpad);
+GstPad* gst_scheduler_pad_select (GstScheduler *sched, GList *padlist);
+gboolean gst_scheduler_iterate (GstScheduler *sched);
+
+void gst_scheduler_show (GstScheduler *sched);
- GstElement *entry;
+/*
+ * creating schedulers
+ *
+ */
+#define GST_TYPE_SCHEDULERFACTORY \
+ (gst_schedulerfactory_get_type ())
+#define GST_SCHEDULERFACTORY(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_SCHEDULERFACTORY, GstSchedulerFactory))
+#define GST_SCHEDULERFACTORY_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_SCHEDULERFACTORY, GstSchedulerFactoryClass))
+#define GST_IS_SCHEDULERFACTORY(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_SCHEDULERFACTORY))
+#define GST_IS_SCHEDULERFACTORY_CLASS(obj) \
+ (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_SCHEDULERFACTORY))
+
+typedef struct _GstSchedulerFactory GstSchedulerFactory;
+typedef struct _GstSchedulerFactoryClass GstSchedulerFactoryClass;
+
+struct _GstSchedulerFactory {
+ GstPluginFeature feature;
+
+ gchar *longdesc; /* long description of the scheduler (well, don't overdo it..) */
+ GType type; /* unique GType of the scheduler */
+};
- gint cothreaded_elements;
- gboolean schedule;
+struct _GstSchedulerFactoryClass {
+ GstPluginFeatureClass parent;
};
+GType gst_schedulerfactory_get_type (void);
-GType gst_schedule_get_type (void);
-GstSchedule* gst_schedule_new (GstElement *parent);
+GstSchedulerFactory* gst_schedulerfactory_new (const gchar *name, const gchar *longdesc, GType type);
+void gst_schedulerfactory_destroy (GstSchedulerFactory *factory);
-void gst_schedule_add_element (GstSchedule *sched, GstElement *element);
-void gst_schedule_remove_element (GstSchedule *sched, GstElement *element);
-void gst_schedule_enable_element (GstSchedule *sched, GstElement *element);
-void gst_schedule_disable_element (GstSchedule *sched, GstElement *element);
-void gst_schedule_pad_connect (GstSchedule *sched, GstPad *srcpad, GstPad *sinkpad);
-void gst_schedule_pad_disconnect (GstSchedule *sched, GstPad *srcpad, GstPad *sinkpad);
-GstPad* gst_schedule_pad_select (GstSchedule *sched, GList *padlist);
-gboolean gst_schedule_iterate (GstSchedule *sched);
+GstSchedulerFactory* gst_schedulerfactory_find (const gchar *name);
+GList* gst_schedulerfactory_get_list (void);
-void gst_schedule_show (GstSchedule *sched);
+GstScheduler* gst_schedulerfactory_create (GstSchedulerFactory *factory, GstElement *parent);
+GstScheduler* gst_schedulerfactory_make (const gchar *name, GstElement *parent);
#ifdef __cplusplus
diff --git a/gst/gstthread.c b/gst/gstthread.c
index 65a3793f2d1bd571c3b2c8ec7d015867b41bbd89..269203bed9d7b7475aaa9f2fde3630d33a47105d 100644 (file)
--- a/gst/gstthread.c
+++ b/gst/gstthread.c
enum {
ARG_0,
- ARG_CREATE_THREAD,
};
static void gst_thread_restore_thyself (GstObject *object, xmlNodePtr self);
#endif
-static void gst_thread_signal_thread (GstThread *thread, gboolean spinning);
-
static void* gst_thread_main_loop (void *arg);
static GstBinClass *parent_class = NULL;
parent_class = g_type_class_ref (GST_TYPE_BIN);
- g_object_class_install_property(G_OBJECT_CLASS(klass), ARG_CREATE_THREAD,
- g_param_spec_boolean("create_thread", "Create Thread", "Whether to create a thread.",
- TRUE,G_PARAM_READWRITE));
-
gobject_class->dispose = gst_thread_dispose;
#ifndef GST_DISABLE_LOADSAVE
// we're a manager by default
GST_FLAG_SET (thread, GST_BIN_FLAG_MANAGER);
- // default is to create a thread
- GST_FLAG_SET (thread, GST_THREAD_CREATE);
-
thread->lock = g_mutex_new();
thread->cond = g_cond_new();
- GST_ELEMENT_SCHED(thread) = gst_schedule_new(GST_ELEMENT(thread));
+ GST_ELEMENT_SCHED(thread) = gst_schedulerfactory_make ("basic", GST_ELEMENT(thread));
GST_DEBUG(GST_CAT_THREAD, "thread's scheduler is %p\n",GST_ELEMENT_SCHED(thread));
thread->ppid = getpid();
+ thread->thread_id = -1;
// gst_element_set_manager(GST_ELEMENT(thread),GST_ELEMENT(thread));
}
@@ -184,17 +175,6 @@ gst_thread_set_property (GObject *object, guint prop_id, const GValue *value, GP
g_return_if_fail (GST_IS_THREAD (object));
switch (prop_id) {
- case ARG_CREATE_THREAD:
- if (g_value_get_boolean(value)) {
- GST_INFO (GST_CAT_THREAD,"turning ON the creation of the thread");
- GST_FLAG_SET (object, GST_THREAD_CREATE);
-// GST_DEBUG (GST_CAT_THREAD,"flags are 0x%08x\n", GST_FLAGS (object));
- } else {
- GST_INFO (GST_CAT_THREAD,"gstthread: turning OFF the creation of the thread");
- GST_FLAG_UNSET (object, GST_THREAD_CREATE);
-// GST_DEBUG (GST_CAT_THREAD,"gstthread: flags are 0x%08x\n", GST_FLAGS (object));
- }
- break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@@ -208,9 +188,6 @@ gst_thread_get_property (GObject *object, guint prop_id, GValue *value, GParamSp
g_return_if_fail (GST_IS_THREAD (object));
switch (prop_id) {
- case ARG_CREATE_THREAD:
- g_value_set_boolean(value, GST_FLAG_IS_SET (object, GST_THREAD_CREATE));
- break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
GST_DEBUG_ELEMENT(GST_CAT_THREAD, thread, "sync-main(" GST_DEBUG_THREAD_FORMAT "): " format , \
GST_DEBUG_THREAD_ARGS(thread->ppid) , ## args )
+static GstElementStateReturn
+gst_thread_update_state (GstThread *thread)
+{
+ // check for state change
+ if (GST_STATE_PENDING(thread) != GST_STATE_VOID_PENDING) {
+ // punt and change state on all the children
+ if (GST_ELEMENT_CLASS (parent_class)->change_state)
+ return GST_ELEMENT_CLASS (parent_class)->change_state (GST_ELEMENT(thread));
+ }
+
+ return GST_STATE_SUCCESS;
+}
+
static GstElementStateReturn
-gst_thread_change_state (GstElement *element)
+gst_thread_change_state (GstElement * element)
{
GstThread *thread;
gboolean stateset = GST_STATE_SUCCESS;
gint transition;
- pthread_t self = pthread_self();
+ pthread_t self = pthread_self ();
- g_return_val_if_fail (GST_IS_THREAD(element), FALSE);
-// GST_DEBUG_ENTER("(\"%s\")",GST_ELEMENT_NAME(element));
+ g_return_val_if_fail (GST_IS_THREAD (element), FALSE);
thread = GST_THREAD (element);
-// GST_DEBUG (GST_CAT_THREAD, "**** THREAD %ld changing THREAD %ld ****\n",self,thread->thread_id);
-// GST_DEBUG (GST_CAT_THREAD, "**** current pid=%d\n",getpid());
transition = GST_STATE_TRANSITION (element);
- THR_INFO("changing state from %s to %s",
- gst_element_statename(GST_STATE (element)),
- gst_element_statename(GST_STATE_PENDING (element)));
+ THR_INFO ("changing state from %s to %s",
+ gst_element_statename (GST_STATE (element)),
+ gst_element_statename (GST_STATE_PENDING (element)));
- //GST_FLAG_UNSET (thread, GST_THREAD_STATE_SPINNING);
+ if (pthread_equal (self, thread->thread_id)) {
+ GST_DEBUG (GST_CAT_THREAD,
+ "no sync(" GST_DEBUG_THREAD_FORMAT "): setting own thread's state to spinning\n",
+ GST_DEBUG_THREAD_ARGS (thread->pid));
+ return gst_thread_update_state (thread);
+ }
switch (transition) {
case GST_STATE_NULL_TO_READY:
// set the state to idle
GST_FLAG_UNSET (thread, GST_THREAD_STATE_SPINNING);
- GST_FLAG_UNSET (thread, GST_THREAD_STATE_REAPING);
- // create the thread if that's what we're supposed to do
- if (GST_FLAG_IS_SET (thread, GST_THREAD_CREATE)) {
- THR_DEBUG ("creating thread \"%s\"\n",
- GST_ELEMENT_NAME (element));
-
- g_mutex_lock (thread->lock);
-
- // create the thread
- pthread_create (&thread->thread_id, NULL,
- gst_thread_main_loop, thread);
-
- // wait for it to 'spin up'
- THR_DEBUG("waiting for child thread spinup\n");
- g_cond_wait(thread->cond,thread->lock);
- THR_DEBUG("thread claims to be up\n");
- g_mutex_unlock(thread->lock);
- } else {
- GST_INFO (GST_CAT_THREAD, "NOT creating thread \"%s\"",
- GST_ELEMENT_NAME (GST_ELEMENT (element)));
-
- // punt and change state on all the children
- if (GST_ELEMENT_CLASS (parent_class)->change_state)
- stateset = GST_ELEMENT_CLASS (parent_class)->change_state (element);
- }
+ THR_DEBUG ("creating thread \"%s\"\n", GST_ELEMENT_NAME (element));
+
+ g_mutex_lock (thread->lock);
+
+ // create the thread
+ pthread_create (&thread->thread_id, NULL, gst_thread_main_loop, thread);
+
+ // wait for it to 'spin up'
+ THR_DEBUG ("waiting for child thread spinup\n");
+ g_cond_wait (thread->cond, thread->lock);
+ THR_DEBUG ("thread claims to be up\n");
+ g_mutex_unlock (thread->lock);
break;
case GST_STATE_READY_TO_PAUSED:
- THR_INFO("readying thread");
-
- // check to see if the thread is somehow changing its own state.
- // FIXME this is currently illegal, but must somehow be made legal at some point.
- if (pthread_equal(self, thread->thread_id))
- {
- //FIXME this should not happen
- g_assert(!pthread_equal(self, thread->thread_id));
- GST_FLAG_SET(thread, GST_THREAD_STATE_SPINNING);
- GST_DEBUG(GST_CAT_THREAD,"no sync(" GST_DEBUG_THREAD_FORMAT "): setting own thread's state to spinning\n",
- GST_DEBUG_THREAD_ARGS(thread->pid));
- }
- else
- {
- g_mutex_lock(thread->lock);
- gst_thread_signal_thread(thread,FALSE);
- }
+ THR_INFO ("readying thread");
+ g_mutex_lock (thread->lock);
+ THR_DEBUG ("signaling\n");
+ g_cond_signal (thread->cond);
+ THR_DEBUG ("waiting for ack\n");
+ g_cond_wait (thread->cond, thread->lock);
+ THR_DEBUG ("got ack\n");
+ g_mutex_unlock (thread->lock);
break;
case GST_STATE_PAUSED_TO_PLAYING:
- THR_INFO("starting thread");
-
- // check to see if the thread is somehow changing its own state.
- // FIXME this is currently illegal, but must somehow be made legal at some point.
- if (pthread_equal(self, thread->thread_id))
- {
- //FIXME this should not happen
- g_assert(!pthread_equal(self, thread->thread_id));
- GST_FLAG_SET(thread, GST_THREAD_STATE_SPINNING);
- GST_DEBUG(GST_CAT_THREAD,"no sync(" GST_DEBUG_THREAD_FORMAT "): setting own thread's state to spinning\n",
- GST_DEBUG_THREAD_ARGS(thread->pid));
- }
- else
- {
- THR_DEBUG("telling thread to start spinning\n");
- g_mutex_lock(thread->lock);
- gst_thread_signal_thread(thread,TRUE);
- }
+ THR_DEBUG ("telling thread to start spinning\n");
+ g_mutex_lock (thread->lock);
+ THR_DEBUG ("signaling\n");
+ g_cond_signal (thread->cond);
+ THR_DEBUG ("waiting for ack\n");
+ g_cond_wait (thread->cond, thread->lock);
+ THR_DEBUG ("got ack\n");
+ g_mutex_unlock (thread->lock);
break;
case GST_STATE_PLAYING_TO_PAUSED:
- THR_INFO("pausing thread");
-
- // check to see if the thread is somehow changing its own state.
- // FIXME this is currently illegal, but must somehow be made legal at some point.
- if (pthread_equal(self, thread->thread_id))
- {
- //FIXME this should not happen
- GST_DEBUG(GST_CAT_THREAD,"no sync(" GST_DEBUG_THREAD_FORMAT "): setting own thread's state to paused\n",
- GST_DEBUG_THREAD_ARGS(thread->pid));
- GST_FLAG_UNSET (thread, GST_THREAD_STATE_SPINNING);
- g_assert(!pthread_equal(self, thread->thread_id));
- }
- else
- {
- GList *elements = (element->sched)->elements;
-
- // the following code ensures that the bottom half of thread will run
- // to perform each elements' change_state() (by calling gstbin.c::
- // change_state()).
- // + the pending state was already set by gstelement.c::set_state()
- // + find every queue we manage, and signal its empty and full conditions
-
- g_mutex_lock(thread->lock);
-
- GST_FLAG_UNSET (thread, GST_THREAD_STATE_SPINNING);
-
- while (elements)
- {
- GstElement *e = GST_ELEMENT(elements->data);
- g_assert(e);
- THR_DEBUG(" element \"%s\"\n",GST_ELEMENT_NAME(e));
- elements = g_list_next(elements);
- if (GST_IS_QUEUE(e))
- {
- //FIXME make this more efficient by only waking queues that are asleep
- //FIXME and only waking the appropriate condition (depending on if it's
- //FIXME on up- or down-stream side)
- //
- //FIXME also make this more efficient by keeping list of managed queues
- THR_DEBUG("waking queue \"%s\"\n",GST_ELEMENT_NAME(e));
- //GST_LOCK(e);
- g_cond_signal((GST_QUEUE(e)->not_empty));
- g_cond_signal((GST_QUEUE(e)->not_full));
- //GST_UNLOCK(e);
- }
- else
- {
- GList *pads = GST_ELEMENT_PADS(e);
- while (pads)
- {
- GstRealPad *peer;
- GstElement *peerelement;
- GstPad *p = GST_PAD(pads->data);
- pads = g_list_next(pads);
-
- peer = GST_PAD_PEER(p);
- if (!peer) continue;
-
- peerelement = GST_PAD_PARENT(peer);
- if (!peerelement) continue; // deal with case where there's no peer
-
- if (!GST_FLAG_IS_SET(peerelement,GST_ELEMENT_DECOUPLED)) {
- GST_DEBUG(GST_CAT_THREAD,"peer element isn't DECOUPLED\n");
- continue;
- }
-
- // FIXME this needs to go away eventually
- if (!GST_IS_QUEUE(peerelement)) {
- GST_DEBUG(GST_CAT_THREAD,"peer element isn't a Queue\n");
- continue;
- }
-
- if (GST_ELEMENT_SCHED(peerelement) != GST_ELEMENT_SCHED(thread))
- {
- THR_DEBUG(" element \"%s\" has pad cross sched boundary\n",GST_ELEMENT_NAME(e));
- //GST_LOCK(peerelement);
- g_cond_signal(GST_QUEUE(peerelement)->not_empty);
- g_cond_signal(GST_QUEUE(peerelement)->not_full);
- //GST_UNLOCK(peerelement);
- }
- }
- }
- }
- THR_DEBUG("waiting for thread to stop spinning\n");
- g_cond_wait (thread->cond, thread->lock);
- THR_DEBUG("telling thread to pause\n");
- gst_thread_signal_thread(thread,FALSE);
+ {
+ GList *elements = (element->sched)->elements;
+
+ THR_INFO ("pausing thread");
+
+ // the following code ensures that the bottom half of thread will run
+ // to perform each elements' change_state() (by calling gstbin.c::
+ // change_state()).
+ // + the pending state was already set by gstelement.c::set_state()
+ // + find every queue we manage, and signal its empty and full conditions
+ g_mutex_lock (thread->lock);
+
+ GST_FLAG_UNSET (thread, GST_THREAD_STATE_SPINNING);
+
+ while (elements) {
+ GstElement *e = GST_ELEMENT (elements->data);
+
+ g_assert (e);
+ THR_DEBUG (" element \"%s\"\n", GST_ELEMENT_NAME (e));
+ elements = g_list_next (elements);
+ if (GST_IS_QUEUE (e)) {
+ //FIXME make this more efficient by only waking queues that are asleep
+ //FIXME and only waking the appropriate condition (depending on if it's
+ //FIXME on up- or down-stream side)
+ //
+ //FIXME also make this more efficient by keeping list of managed queues
+ THR_DEBUG ("waking queue \"%s\"\n", GST_ELEMENT_NAME (e));
+ gst_element_set_state (e, GST_STATE_PAUSED);
+ }
+ else {
+ GList *pads = GST_ELEMENT_PADS (e);
+
+ while (pads) {
+ GstRealPad *peer;
+ GstElement *peerelement;
+ GstPad *p = GST_PAD (pads->data);
+
+ pads = g_list_next (pads);
+
+ peer = GST_PAD_PEER (p);
+ if (!peer)
+ continue;
+
+ peerelement = GST_PAD_PARENT (peer);
+ if (!peerelement)
+ continue; // deal with case where there's no peer
+
+ if (!GST_FLAG_IS_SET (peerelement, GST_ELEMENT_DECOUPLED)) {
+ GST_DEBUG (GST_CAT_THREAD, "peer element isn't DECOUPLED\n");
+ continue;
+ }
+
+ // FIXME this needs to go away eventually
+ if (!GST_IS_QUEUE (peerelement)) {
+ GST_DEBUG (GST_CAT_THREAD, "peer element isn't a Queue\n");
+ continue;
+ }
+
+ if (GST_ELEMENT_SCHED (peerelement) != GST_ELEMENT_SCHED (thread)) {
+ GstQueue *queue = GST_QUEUE (peerelement);
+
+ THR_DEBUG (" element \"%s\" has pad cross sched boundary\n", GST_ELEMENT_NAME (e));
+ // FIXME!!
+ g_mutex_lock (queue->qlock);
+ g_cond_signal (queue->not_full);
+ g_cond_signal (queue->not_empty);
+ g_mutex_unlock (queue->qlock);
+ }
+ }
+ }
}
+ THR_DEBUG ("telling thread to pause, signaling\n");
+ g_cond_signal (thread->cond);
+ THR_DEBUG ("waiting for ack\n");
+ g_cond_wait (thread->cond, thread->lock);
+ THR_DEBUG ("got ack\n");
+ g_mutex_unlock (thread->lock);
break;
+ }
case GST_STATE_READY_TO_NULL:
- THR_INFO("stopping thread");
-
- GST_FLAG_SET (thread, GST_THREAD_STATE_REAPING);
-
- // check to see if the thread is somehow changing its own state.
- // FIXME this is currently illegal, but must somehow be made legal at some point.
- if (pthread_equal(self, thread->thread_id))
- {
- //FIXME this should not happen
- g_assert(!pthread_equal(self, thread->thread_id));
- THR_DEBUG("setting own thread's state to NULL (paused)\n");
- GST_FLAG_UNSET (thread, GST_THREAD_STATE_SPINNING);
- }
- else
- {
- THR_DEBUG("telling thread to pause (null) - and joining\n");
- //MattH FIXME revisit
- g_mutex_lock(thread->lock);
- gst_thread_signal_thread(thread,FALSE);
- pthread_join(thread->thread_id,NULL);
- }
+ THR_DEBUG ("telling thread to pause (null) - and joining\n");
+ //MattH FIXME revisit
+ g_mutex_lock (thread->lock);
+ THR_DEBUG ("signaling\n");
+ g_cond_signal (thread->cond);
+ THR_DEBUG ("waiting for ack\n");
+ g_cond_wait (thread->cond, thread->lock);
+ THR_DEBUG ("got ack\n");
+ pthread_join (thread->thread_id, NULL);
+ thread->thread_id = -1;
+ g_mutex_unlock (thread->lock);
- GST_FLAG_UNSET(thread,GST_THREAD_STATE_REAPING);
- GST_FLAG_UNSET(thread,GST_THREAD_STATE_STARTED);
- GST_FLAG_UNSET(thread,GST_THREAD_STATE_SPINNING);
- GST_FLAG_UNSET(thread,GST_THREAD_STATE_ELEMENT_CHANGED);
+ GST_FLAG_UNSET (thread, GST_THREAD_STATE_REAPING);
+ GST_FLAG_UNSET (thread, GST_THREAD_STATE_STARTED);
+ GST_FLAG_UNSET (thread, GST_THREAD_STATE_SPINNING);
break;
case GST_STATE_PAUSED_TO_READY:
- THR_INFO("stopping thread");
-
- // check to see if the thread is somehow changing its own state.
- // FIXME this is currently illegal, but must somehow be made legal at some point.
- if (pthread_equal(self, thread->thread_id))
- {
- //FIXME this should not happen
- g_assert(!pthread_equal(self, thread->thread_id));
- GST_FLAG_SET(thread, GST_THREAD_STATE_SPINNING);
- GST_DEBUG(GST_CAT_THREAD,"no sync(" GST_DEBUG_THREAD_FORMAT "): setting own thread's state to spinning\n",
- GST_DEBUG_THREAD_ARGS(thread->pid));
- }
- else
- {
- THR_DEBUG("telling thread to stop spinning\n");
- g_mutex_lock(thread->lock);
- gst_thread_signal_thread(thread,FALSE);
- }
-
+ THR_DEBUG ("telling thread to stop spinning\n");
+ g_mutex_lock (thread->lock);
+ THR_DEBUG ("signaling\n");
+ g_cond_signal (thread->cond);
+ THR_DEBUG ("waiting for ack\n");
+ g_cond_wait (thread->cond, thread->lock);
+ THR_DEBUG ("got ack\n");
+ g_mutex_unlock (thread->lock);
+
break;
default:
- GST_DEBUG_ELEMENT(GST_CAT_THREAD, element, "UNHANDLED STATE CHANGE! %x\n",transition);
+ GST_DEBUG_ELEMENT (GST_CAT_THREAD, element, "UNHANDLED STATE CHANGE! %x\n", transition);
break;
}
return stateset;
}
-static void gst_thread_update_state (GstThread *thread)
-{
- // check for state change
- if (GST_STATE_PENDING(thread) != GST_STATE_VOID_PENDING) {
- // punt and change state on all the children
- if (GST_ELEMENT_CLASS (parent_class)->change_state)
- GST_ELEMENT_CLASS (parent_class)->change_state (GST_ELEMENT(thread));
- }
-}
-
/**
* gst_thread_main_loop:
* @arg: the thread to start
GstThread *thread = GST_THREAD (arg);
gint stateset;
+ g_mutex_lock (thread->lock);
+
+ GST_FLAG_UNSET (thread, GST_THREAD_STATE_REAPING);
+
thread->pid = getpid();
THR_INFO_MAIN("thread is running");
// first we need to change the state of all the children
- if (GST_ELEMENT_CLASS (parent_class)->change_state)
+ if (GST_ELEMENT_CLASS (parent_class)->change_state) {
stateset = GST_ELEMENT_CLASS (parent_class)->change_state (GST_ELEMENT(thread));
- // construct the plan and signal back
-/* DEPRACATED for INCSCHED1
- THR_DEBUG_MAIN("creating plan for thread\n");
- if (GST_BIN_CLASS (parent_class)->schedule)
- GST_BIN_CLASS (parent_class)->schedule (GST_BIN (thread));
-*/
+ if (stateset != GST_STATE_SUCCESS) {
+ THR_DEBUG_MAIN ("state change of children failed\n");
+ }
+ }
+
-// THR_DEBUG_MAIN("indicating spinup\n");
- g_mutex_lock (thread->lock);
+ THR_DEBUG_MAIN ("indicating spinup\n");
g_cond_signal (thread->cond);
// don't unlock the mutex because we hold it into the top of the while loop
- THR_DEBUG_MAIN("thread has indicated spinup to parent process\n");
+ THR_DEBUG_MAIN ("thread has indicated spinup to parent process\n");
/***** THREAD IS NOW IN READY STATE *****/
while (!GST_FLAG_IS_SET (thread, GST_THREAD_STATE_REAPING)) {
// NOTE we hold the thread lock at this point
// what we do depends on what state we're in
- switch (GST_STATE(thread)) {
+ switch (GST_STATE (thread)) {
// NOTE: cannot be in NULL, we're not running in that state at all
case GST_STATE_READY:
// wait to be set to either the NULL or PAUSED states
- THR_DEBUG_MAIN("thread in %s state, waiting for either %s or %s\n",
- gst_element_statename(GST_STATE_READY),
- gst_element_statename(GST_STATE_NULL),
- gst_element_statename(GST_STATE_PAUSED));
- g_cond_wait(thread->cond,thread->lock);
+ THR_DEBUG_MAIN ("thread in %s state, waiting for either %s or %s\n",
+ gst_element_statename (GST_STATE_READY),
+ gst_element_statename (GST_STATE_NULL),
+ gst_element_statename (GST_STATE_PAUSED));
+ g_cond_wait (thread->cond,thread->lock);
+
+ g_assert (GST_STATE_PENDING (thread) == GST_STATE_NULL ||
+ GST_STATE_PENDING (thread) == GST_STATE_PAUSED);
+
// been signaled, we need to state transition now and signal back
- gst_thread_update_state(thread);
- THR_DEBUG_MAIN("done with state transition, signaling back to parent process\n");
- g_cond_signal(thread->cond);
-// g_mutex_unlock(thread->lock);
- // now we decide what to do next (FIXME can be collapsed to a continue)
- if (GST_STATE(thread) == GST_STATE_NULL) {
+ gst_thread_update_state (thread);
+ THR_DEBUG_MAIN ("done with state transition, signaling back to parent process\n");
+ g_cond_signal (thread->cond);
+ // now we decide what to do next
+ if (GST_STATE (thread) == GST_STATE_NULL) {
// REAPING must be set, we can simply break this iteration
- continue;
- } else {
- // PAUSED is the next state, we can wait for that next
- continue;
- }
- break;
+ GST_FLAG_SET (thread, GST_THREAD_STATE_REAPING);
+ }
+ continue;
case GST_STATE_PAUSED:
// wait to be set to either the READY or PLAYING states
THR_DEBUG_MAIN("thread in %s state, waiting for either %s or %s\n",
- gst_element_statename(GST_STATE_PAUSED),
- gst_element_statename(GST_STATE_READY),
- gst_element_statename(GST_STATE_PLAYING));
- g_cond_wait(thread->cond,thread->lock);
+ gst_element_statename (GST_STATE_PAUSED),
+ gst_element_statename (GST_STATE_READY),
+ gst_element_statename (GST_STATE_PLAYING));
+ g_cond_wait (thread->cond,thread->lock);
+
+ g_assert (GST_STATE_PENDING (thread) == GST_STATE_READY ||
+ GST_STATE_PENDING (thread) == GST_STATE_PLAYING);
+
// been signaled, we need to state transition now and signal back
- gst_thread_update_state(thread);
- g_cond_signal(thread->cond);
-// g_mutex_unlock(thread->lock);
+ gst_thread_update_state (thread);
// now we decide what to do next
- if (GST_STATE(thread) == GST_STATE_READY) {
- // READY is the next state, we can wait for that next
+ if (GST_STATE (thread) != GST_STATE_PLAYING) {
+ // either READY or the state change failed for some reason
+ g_cond_signal (thread->cond);
continue;
- } else {
- g_mutex_unlock(thread->lock);
+ }
+ else {
+ GST_FLAG_SET (thread, GST_THREAD_STATE_SPINNING);
// PLAYING is coming up, so we can now start spinning
while (GST_FLAG_IS_SET (thread, GST_THREAD_STATE_SPINNING)) {
- if (!gst_bin_iterate (GST_BIN (thread))) {
-// GST_FLAG_UNSET (thread, GST_THREAD_STATE_SPINNING);
-// THR_DEBUG_MAIN("removed spinning state due to failed iteration!\n");
- // FIXME FIXME FIXME this is ugly!
- THR_DEBUG_MAIN("iteration failed, something very wrong, spinning to let parent sync\n");
- while (GST_FLAG_IS_SET(thread, GST_THREAD_STATE_SPINNING)) ;
- }
+ gboolean status;
+
+ g_cond_signal (thread->cond);
+ g_mutex_unlock (thread->lock);
+ status = gst_bin_iterate (GST_BIN (thread));
+ g_mutex_lock (thread->lock);
+ //g_cond_signal(thread->cond);
+
+ if (!status || GST_STATE_PENDING (thread) != GST_STATE_VOID_PENDING)
+ GST_FLAG_UNSET (thread, GST_THREAD_STATE_SPINNING);
}
- g_mutex_lock(thread->lock);
+ // looks like we were stopped because of a statechange
+ if (GST_STATE_PENDING (thread)) {
+ gst_thread_update_state (thread);
+ }
// once we're here, SPINNING has stopped, we should signal that we're done
- THR_DEBUG_MAIN("SPINNING stopped, signaling back to parent process\n");
+ THR_DEBUG_MAIN ("SPINNING stopped, signaling back to parent process\n");
g_cond_signal (thread->cond);
// now we can wait for PAUSED
continue;
}
- break;
case GST_STATE_PLAYING:
// wait to be set to PAUSED
- THR_DEBUG_MAIN("thread in %s state, waiting for %s\n",
- gst_element_statename(GST_STATE_PLAYING),
- gst_element_statename(GST_STATE_PAUSED));
- g_cond_wait(thread->cond,thread->lock);
+ THR_DEBUG_MAIN ("thread in %s state, waiting for %s\n",
+ gst_element_statename(GST_STATE_PLAYING),
+ gst_element_statename(GST_STATE_PAUSED));
+ g_cond_wait (thread->cond,thread->lock);
+
// been signaled, we need to state transition now and signal back
- gst_thread_update_state(thread);
- g_cond_signal(thread->cond);
-// g_mutex_unlock(thread->lock);
+ gst_thread_update_state (thread);
+ g_cond_signal (thread->cond);
// now we decide what to do next
// there's only PAUSED, we we just wait for it
continue;
+ case GST_STATE_NULL:
+ THR_DEBUG_MAIN ("thread in %s state, preparing to die\n",
+ gst_element_statename(GST_STATE_NULL));
+ GST_FLAG_SET (thread, GST_THREAD_STATE_REAPING);
+ break;
+ default:
+ g_assert_not_reached ();
break;
}
-
- // need to grab the lock so we're ready for the top of the loop
-// g_mutex_lock(thread->lock);
- }
-
-/*
- while (!GST_FLAG_IS_SET (thread, GST_THREAD_STATE_REAPING)) {
- // start out by waiting for a state change into spinning
- THR_DEBUG_MAIN("waiting for signal from parent process (at top of while())\n");
- g_cond_wait (thread->cond,thread->lock);
- THR_DEBUG_MAIN("woken up with %s pending\n",gst_element_statename(GST_STATE(thread)));
- // now is a good time to change the state of the children and the thread itself
- gst_thread_update_state (thread);
- THR_DEBUG_MAIN("done changing state, signaling back\n");
- g_cond_signal (thread->cond);
- g_mutex_unlock (thread->lock);
- THR_DEBUG_MAIN("finished sycnronizing with main process\n");
-
- while (GST_FLAG_IS_SET (thread, GST_THREAD_STATE_SPINNING)) {
- if (!gst_bin_iterate (GST_BIN (thread))) {
- GST_FLAG_UNSET (thread, GST_THREAD_STATE_SPINNING);
- THR_DEBUG_MAIN("removed spinning state due to failed iteration!\n");
- }
- }
-
- g_mutex_lock (thread->lock);
-
- if (GST_STATE_PENDING(thread) == GST_STATE_PAUSED) {
- // we've stopped spinning, because of PLAYING->PAUSED
- THR_DEBUG_MAIN("SPINNING flag unset, signaling parent process we're stopped\n");
- // we need to signal back that we've stopped spinning
- g_cond_signal (thread->cond);
- }
-
-// THR_DEBUG_MAIN("signaling that the thread is out of the SPINNING loop\n");
-// g_cond_signal (thread->cond);
-// g_cond_wait (thread->cond, thread->lock);
-// THR_DEBUG_MAIN("parent process has signaled at bottom of while\n");
-// // now change the children's and thread's state
-// gst_thread_update_state (thread);
-// THR_DEBUG_MAIN("done changing state, signaling back to parent process\n");
-// g_cond_signal (thread->cond);
-// // don't release the mutex, we hold that into the top of the loop
-// THR_DEBUG_MAIN("done syncing with parent process at bottom of while\n");
}
-*/
-
// since we don't unlock at the end of the while loop, do it here
g_mutex_unlock (thread->lock);
return NULL;
}
-// the set flag is to say whether it should set TRUE or FALSE
-//
-// WARNING: this has synchronization built in! if you remove or add any
-// locks, waits, signals, or unlocks you need to be sure they match the
-// code above (in gst_thread_main_loop()). basically, don't change anything.
-static void
-gst_thread_signal_thread (GstThread *thread, gboolean spinning)
-{
- // set the spinning state
- if (spinning) GST_FLAG_SET(thread,GST_THREAD_STATE_SPINNING);
- else GST_FLAG_UNSET (thread, GST_THREAD_STATE_SPINNING);
-
- THR_DEBUG("thread locked\n");
-// g_mutex_lock(thread->lock);
-
-// if (!spinning) {
-// THR_DEBUG("waiting for spindown\n");
-// g_cond_wait (thread->cond, thread->lock);
-// }
- THR_DEBUG("signaling\n");
- g_cond_signal (thread->cond);
- THR_DEBUG("waiting for ack\n");
- g_cond_wait (thread->cond,thread->lock);
- THR_DEBUG("got ack\n");
-
- THR_DEBUG("unlocking\n");
- g_mutex_unlock(thread->lock);
- THR_DEBUG("unlocked\n");
-}
-
-
#ifndef GST_DISABLE_LOADSAVE
static xmlNodePtr
gst_thread_save_thyself (GstObject *object,
diff --git a/gst/gstthread.h b/gst/gstthread.h
index 961457679c8fa7ca2928b582541b403b594a52b1..def68e325742237aeda0ab92ac5e9c48a6c021d1 100644 (file)
--- a/gst/gstthread.h
+++ b/gst/gstthread.h
typedef enum {
- GST_THREAD_CREATE = GST_BIN_FLAG_LAST,
-
- GST_THREAD_STATE_STARTED,
+ GST_THREAD_STATE_STARTED = GST_BIN_FLAG_LAST,
GST_THREAD_STATE_SPINNING,
GST_THREAD_STATE_REAPING,
- GST_THREAD_STATE_ELEMENT_CHANGED,
/* padding */
GST_THREAD_FLAG_LAST = GST_BIN_FLAG_LAST + 4,
diff --git a/gst/gsttrace.c b/gst/gsttrace.c
index 6aad09125366cf3acbe5963d9bb480b2e52849c1..b792169cc4e2de8f3ab922172650f382b7b1aa0f 100644 (file)
--- a/gst/gsttrace.c
+++ b/gst/gsttrace.c
#include "gstlog.h"
#include "gsttrace.h"
-
-__inline__ void read_tsc(guint64 *dst) {
+static __inline__ void
+read_tsc (guint64 * dst)
+{
#ifdef HAVE_RDTSC
guint64 tsc;
- __asm__ __volatile__ ("rdtsc" : "=A" (tsc));
+ __asm__ __volatile__ ("rdtsc":"=A" (tsc));
+
*dst = tsc;
#else
*dst = 0;
#endif
}
-void gst_trace_read_tsc(guint64 *dst) {
- read_tsc(dst);
+void
+gst_trace_read_tsc (guint64 * dst)
+{
+ read_tsc (dst);
}
GstTrace *_gst_trace_default = NULL;
gint _gst_trace_on = 1;
-GstTrace *gst_trace_new(guchar *filename,gint size) {
- GstTrace *trace = g_malloc(sizeof(GstTrace));
-
- g_return_val_if_fail(trace != NULL,NULL);
- trace->filename = g_strdup(filename);
- g_print("opening '%s'\n",trace->filename);
- trace->fd = open(trace->filename,O_RDWR|O_CREAT|O_TRUNC,S_IRUSR|S_IWUSR);
- perror("opening trace file");
- g_return_val_if_fail(trace->fd > 0,NULL);
- trace->buf = g_malloc(size * sizeof(GstTraceEntry));
- g_return_val_if_fail(trace->buf != NULL,NULL);
+GstTrace *
+gst_trace_new (guchar * filename, gint size)
+{
+ GstTrace *trace = g_malloc (sizeof (GstTrace));
+
+ g_return_val_if_fail (trace != NULL, NULL);
+ trace->filename = g_strdup (filename);
+ g_print ("opening '%s'\n", trace->filename);
+ trace->fd = open (trace->filename, O_RDWR | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR);
+ perror ("opening trace file");
+ g_return_val_if_fail (trace->fd > 0, NULL);
+ trace->buf = g_malloc (size * sizeof (GstTraceEntry));
+ g_return_val_if_fail (trace->buf != NULL, NULL);
trace->bufsize = size;
trace->bufoffset = 0;
return trace;
}
-void gst_trace_destroy(GstTrace *trace) {
- g_return_if_fail(trace != NULL);
- g_return_if_fail(trace->buf != NULL);
-
- if (gst_trace_get_remaining(trace) > 0)
- gst_trace_flush(trace);
- close(trace->fd);
- g_free(trace->buf);
- g_free(trace);
+void
+gst_trace_destroy (GstTrace * trace)
+{
+ g_return_if_fail (trace != NULL);
+ g_return_if_fail (trace->buf != NULL);
+
+ if (gst_trace_get_remaining (trace) > 0)
+ gst_trace_flush (trace);
+ close (trace->fd);
+ g_free (trace->buf);
+ g_free (trace);
}
-void gst_trace_flush(GstTrace *trace) {
+void
+gst_trace_flush (GstTrace * trace)
+{
if (!trace) {
trace = _gst_trace_default;
- if (!trace ) return;
+ if (!trace)
+ return;
}
- write(trace->fd,trace->buf,trace->bufoffset * sizeof(GstTraceEntry));
+ write (trace->fd, trace->buf, trace->bufoffset * sizeof (GstTraceEntry));
trace->bufoffset = 0;
}
-void gst_trace_text_flush(GstTrace *trace) {
+void
+gst_trace_text_flush (GstTrace * trace)
+{
int i;
- const int strsize = 20+1 + 10+1 + 10+1 + 112+1 + 1;
+ const int strsize = 20 + 1 + 10 + 1 + 10 + 1 + 112 + 1 + 1;
char str[strsize];
if (!trace) {
trace = _gst_trace_default;
- if (!trace ) return;
+ if (!trace)
+ return;
}
- for (i=0; i<trace->bufoffset; i++) {
- snprintf(str, strsize, "%20lld %10d %10d %s\n",
- trace->buf[i].timestamp,
- trace->buf[i].sequence,
- trace->buf[i].data,
- trace->buf[i].message);
- write(trace->fd,str,strlen(str));
+ for (i = 0; i < trace->bufoffset; i++) {
+ snprintf (str, strsize, "%20lld %10d %10d %s\n",
+ trace->buf[i].timestamp,
+ trace->buf[i].sequence, trace->buf[i].data, trace->buf[i].message);
+ write (trace->fd, str, strlen (str));
}
trace->bufoffset = 0;
}
-void gst_trace_set_default(GstTrace *trace) {
- g_return_if_fail(trace != NULL);
+void
+gst_trace_set_default (GstTrace * trace)
+{
+ g_return_if_fail (trace != NULL);
_gst_trace_default = trace;
}
-void _gst_trace_add_entry(GstTrace *trace,guint32 seq,guint32 data,gchar *msg) {
+void
+_gst_trace_add_entry (GstTrace * trace, guint32 seq, guint32 data, gchar * msg)
+{
GstTraceEntry *entry;
+
if (!trace) {
trace = _gst_trace_default;
- if (!trace ) return;
+ if (!trace)
+ return;
}
entry = trace->buf + trace->bufoffset;
- read_tsc(&(entry->timestamp));
+ read_tsc (&(entry->timestamp));
entry->sequence = seq;
entry->data = data;
- strncpy(entry->message,msg,112);
+ strncpy (entry->message, msg, 112);
trace->bufoffset++;
- gst_trace_flush(trace);
+ gst_trace_flush (trace);
}
diff --git a/gst/gsttypes.h b/gst/gsttypes.h
index a7c07ed8fb0d983b1e6face4b0ed72501d585556..e6f0335b41e36ea4e6139c3b008ad71411b86508 100644 (file)
--- a/gst/gsttypes.h
+++ b/gst/gsttypes.h
typedef struct _GstElementClass GstElementClass;
typedef struct _GstBin GstBin;
typedef struct _GstBinClass GstBinClass;
-typedef struct _GstSchedule GstSchedule;
-typedef struct _GstScheduleClass GstScheduleClass;
+typedef struct _GstScheduler GstScheduler;
+typedef struct _GstSchedulerClass GstSchedulerClass;
#endif
diff --git a/gst/gstutils.c b/gst/gstutils.c
index b119a868a49a1e8c4e1adddcf6af85cdd0d945ce..5e9c55f295a987c87fe37de0ecc64862f280a4a6 100644 (file)
--- a/gst/gstutils.c
+++ b/gst/gstutils.c
g_string_append_c (buf, '\n');
- if (G_VALUE_TYPE (&value))
+ if (G_VALUE_TYPE (&value)) {
g_value_unset (&value);
+ }
}
g_free (property_specs);
}
diff --git a/gst/schedulers/Makefile.am b/gst/schedulers/Makefile.am
--- /dev/null
@@ -0,0 +1,9 @@
+filterdir = $(libdir)/gst
+
+filter_LTLIBRARIES = libgstbasicscheduler.la
+
+libgstbasicscheduler_la_SOURCES = gstbasicscheduler.c
+
+libgstbasicscheduler_la_LDFLAGS = -version-info $(GST_LIBVERSION)
+
+libgstbasicscheduler_la_CFLAGS = $(GLIB_CFLAGS) $(XML_CFLAGS)
diff --git a/gst/schedulers/gstbasicscheduler.c b/gst/schedulers/gstbasicscheduler.c
--- /dev/null
@@ -0,0 +1,1142 @@
+/* GStreamer
+ * Copyright (C) 1999,2000 Erik Walthinsen <omega@cse.ogi.edu>
+ * 2000 Wim Taymans <wtay@chello.be>
+ *
+ * gstscheduler.c: Default scheduling code for most cases
+ *
+ * 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.
+ */
+
+//#define GST_DEBUG_ENABLED
+#include <gst/gst.h>
+
+typedef struct _GstSchedulerChain GstSchedulerChain;
+
+struct _GstSchedulerChain {
+ GstScheduler *sched;
+
+ GList *disabled;
+
+ GList *elements;
+ gint num_elements;
+
+ GstElement *entry;
+
+ gint cothreaded_elements;
+ gboolean schedule;
+};
+
+static GType _gst_basic_scheduler_type = 0;
+
+static void gst_basic_scheduler_class_init (GstSchedulerClass * klass);
+static void gst_basic_scheduler_init (GstScheduler * scheduler);
+
+static void gst_basic_scheduler_add_element (GstScheduler *sched, GstElement *element);
+static void gst_basic_scheduler_remove_element (GstScheduler *sched, GstElement *element);
+static void gst_basic_scheduler_enable_element (GstScheduler *sched, GstElement *element);
+static void gst_basic_scheduler_disable_element (GstScheduler *sched, GstElement *element);
+static void gst_basic_scheduler_lock_element (GstScheduler *sched, GstElement *element);
+static void gst_basic_scheduler_unlock_element (GstScheduler *sched, GstElement *element);
+static void gst_basic_scheduler_pad_connect (GstScheduler *sched, GstPad *srcpad, GstPad *sinkpad);
+static void gst_basic_scheduler_pad_disconnect (GstScheduler *sched, GstPad *srcpad, GstPad *sinkpad);
+static GstPad* gst_basic_scheduler_pad_select (GstScheduler *sched, GList *padlist);
+static gboolean gst_basic_scheduler_iterate (GstScheduler *sched);
+
+static void gst_basic_scheduler_show (GstScheduler *sched);
+
+static GstSchedulerClass *parent_class = NULL;
+
+static GType
+gst_basic_scheduler_get_type (void)
+{
+ if (!_gst_basic_scheduler_type) {
+ static const GTypeInfo scheduler_info = {
+ sizeof (GstSchedulerClass),
+ NULL,
+ NULL,
+ (GClassInitFunc) gst_basic_scheduler_class_init,
+ NULL,
+ NULL,
+ sizeof (GstScheduler),
+ 0,
+ (GInstanceInitFunc) gst_basic_scheduler_init,
+ NULL
+ };
+
+ _gst_basic_scheduler_type = g_type_register_static (GST_TYPE_SCHEDULER, "GstBasicScheduler", &scheduler_info, 0);
+ }
+ return _gst_basic_scheduler_type;
+}
+
+static void
+gst_basic_scheduler_class_init (GstSchedulerClass * klass)
+{
+ GObjectClass *gobject_class;
+ GstObjectClass *gstobject_class;
+
+ gobject_class = (GObjectClass*)klass;
+ gstobject_class = (GstObjectClass*)klass;
+
+ parent_class = g_type_class_ref (GST_TYPE_SCHEDULER);
+
+ klass->add_element = GST_DEBUG_FUNCPTR (gst_basic_scheduler_add_element);
+ klass->remove_element = GST_DEBUG_FUNCPTR (gst_basic_scheduler_remove_element);
+ klass->enable_element = GST_DEBUG_FUNCPTR (gst_basic_scheduler_enable_element);
+ klass->disable_element = GST_DEBUG_FUNCPTR (gst_basic_scheduler_disable_element);
+ klass->lock_element = GST_DEBUG_FUNCPTR (gst_basic_scheduler_lock_element);
+ klass->unlock_element = GST_DEBUG_FUNCPTR (gst_basic_scheduler_unlock_element);
+ klass->pad_connect = GST_DEBUG_FUNCPTR (gst_basic_scheduler_pad_connect);
+ klass->pad_disconnect = GST_DEBUG_FUNCPTR (gst_basic_scheduler_pad_disconnect);
+ klass->pad_select = GST_DEBUG_FUNCPTR (gst_basic_scheduler_pad_select);
+ klass->iterate = GST_DEBUG_FUNCPTR (gst_basic_scheduler_iterate);
+}
+
+static void
+gst_basic_scheduler_init (GstScheduler *scheduler)
+{
+}
+
+static gboolean
+plugin_init (GModule *module, GstPlugin *plugin)
+{
+ GstSchedulerFactory *factory;
+
+ gst_plugin_set_longname (plugin, "A basic scheduler");
+
+ factory = gst_schedulerfactory_new ("basic",
+ "A basic scheduler, it uses cothreads",
+ gst_basic_scheduler_get_type());
+
+ if (factory != NULL) {
+ gst_plugin_add_feature (plugin, GST_PLUGIN_FEATURE (factory));
+ }
+ else {
+ g_warning ("could not register scheduler: basic");
+ }
+ return TRUE;
+}
+
+GstPluginDesc plugin_desc = {
+ GST_VERSION_MAJOR,
+ GST_VERSION_MINOR,
+ "gstbasicscheduler",
+ plugin_init
+};
+
+static int
+gst_basic_scheduler_loopfunc_wrapper (int argc, char *argv[])
+{
+ GstElement *element = GST_ELEMENT (argv);
+ G_GNUC_UNUSED const gchar *name = GST_ELEMENT_NAME (element);
+
+ GST_DEBUG_ENTER ("(%d,'%s')", argc, name);
+
+ do {
+ GST_DEBUG (GST_CAT_DATAFLOW, "calling loopfunc %s for element %s\n",
+ GST_DEBUG_FUNCPTR_NAME (element->loopfunc), name);
+ (element->loopfunc) (element);
+ GST_DEBUG (GST_CAT_DATAFLOW, "element %s ended loop function\n", name);
+ } while (!GST_ELEMENT_IS_COTHREAD_STOPPING (element));
+ GST_FLAG_UNSET (element, GST_ELEMENT_COTHREAD_STOPPING);
+
+ GST_DEBUG_LEAVE ("(%d,'%s')", argc, name);
+ return 0;
+}
+
+static int
+gst_basic_scheduler_chain_wrapper (int argc, char *argv[])
+{
+ GstElement *element = GST_ELEMENT (argv);
+ G_GNUC_UNUSED const gchar *name = GST_ELEMENT_NAME (element);
+
+ GST_DEBUG_ENTER ("(\"%s\")", name);
+
+ GST_DEBUG (GST_CAT_DATAFLOW, "stepping through pads\n");
+
+ do {
+ GList *pads = element->pads;
+
+ while (pads) {
+ GstPad *pad = GST_PAD (pads->data);
+ GstRealPad *realpad;
+
+ pads = g_list_next (pads);
+ if (!GST_IS_REAL_PAD (pad))
+ continue;
+ realpad = GST_REAL_PAD (pad);
+ if (GST_RPAD_DIRECTION (realpad) == GST_PAD_SINK) {
+ GstBuffer *buf;
+
+ GST_DEBUG (GST_CAT_DATAFLOW, "pulling data from %s:%s\n", name, GST_PAD_NAME (pad));
+ buf = gst_pad_pull (pad);
+ if (buf) {
+ if (GST_IS_EVENT (buf) && !GST_ELEMENT_IS_EVENT_AWARE (element)) {
+ //gst_pad_event_default (pad, GST_EVENT (buf));
+ gst_pad_send_event (pad, GST_EVENT (buf));
+ }
+ else {
+ GST_DEBUG (GST_CAT_DATAFLOW, "calling chain function of %s:%s\n", name,
+ GST_PAD_NAME (pad));
+ GST_RPAD_CHAINFUNC (realpad) (pad, buf);
+ }
+ }
+ GST_DEBUG (GST_CAT_DATAFLOW, "calling chain function of %s:%s done\n", name,
+ GST_PAD_NAME (pad));
+ }
+ }
+ } while (!GST_ELEMENT_IS_COTHREAD_STOPPING (element));
+ GST_FLAG_UNSET (element, GST_ELEMENT_COTHREAD_STOPPING);
+
+ GST_DEBUG_LEAVE ("(%d,'%s')", argc, name);
+ return 0;
+}
+
+static int
+gst_basic_scheduler_src_wrapper (int argc, char *argv[])
+{
+ GstElement *element = GST_ELEMENT (argv);
+ GList *pads;
+ GstRealPad *realpad;
+ GstBuffer *buf = NULL;
+ G_GNUC_UNUSED const gchar *name = GST_ELEMENT_NAME (element);
+
+ GST_DEBUG_ENTER ("(%d,\"%s\")", argc, name);
+
+ do {
+ pads = element->pads;
+ while (pads) {
+ if (!GST_IS_REAL_PAD (pads->data))
+ continue;
+ realpad = (GstRealPad *) (pads->data);
+ pads = g_list_next (pads);
+ if (GST_RPAD_DIRECTION (realpad) == GST_PAD_SRC) {
+ GST_DEBUG (GST_CAT_DATAFLOW, "calling _getfunc for %s:%s\n", GST_DEBUG_PAD_NAME (realpad));
+ if (realpad->regiontype != GST_REGION_VOID) {
+ g_return_val_if_fail (GST_RPAD_GETREGIONFUNC (realpad) != NULL, 0);
+// if (GST_RPAD_GETREGIONFUNC(realpad) == NULL)
+// 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_VOID;
+ }
+ else {
+ g_return_val_if_fail (GST_RPAD_GETFUNC (realpad) != NULL, 0);
+// if (GST_RPAD_GETFUNC(realpad) == NULL)
+// fprintf(stderr,"error, no getfunc in \"%s\"\n", name);
+// else
+ buf = GST_RPAD_GETFUNC (realpad) ((GstPad *) realpad);
+ }
+
+ GST_DEBUG (GST_CAT_DATAFLOW, "calling gst_pad_push on pad %s:%s\n",
+ GST_DEBUG_PAD_NAME (realpad));
+ gst_pad_push ((GstPad *) realpad, buf);
+ }
+ }
+ } while (!GST_ELEMENT_IS_COTHREAD_STOPPING (element));
+ GST_FLAG_UNSET (element, GST_ELEMENT_COTHREAD_STOPPING);
+
+ GST_DEBUG_LEAVE ("");
+ return 0;
+}
+
+static void
+gst_basic_scheduler_chainhandler_proxy (GstPad * pad, GstBuffer * buf)
+{
+ GstRealPad *peer = GST_RPAD_PEER (pad);
+
+ GST_DEBUG_ENTER ("(%s:%s)", GST_DEBUG_PAD_NAME (pad));
+ GST_DEBUG (GST_CAT_DATAFLOW, "putting buffer %p in peer \"%s:%s\"'s pen\n", buf,
+ GST_DEBUG_PAD_NAME (peer));
+
+ // FIXME this should be bounded
+ // loop until the bufferpen is empty so we can fill it up again
+ while (GST_RPAD_BUFPEN (pad) != NULL) {
+ GST_DEBUG (GST_CAT_DATAFLOW, "switching to %p to empty bufpen\n",
+ GST_ELEMENT (GST_PAD_PARENT (pad))->threadstate);
+ cothread_switch (GST_ELEMENT (GST_PAD_PARENT (pad))->threadstate);
+
+ // we may no longer be the same pad, check.
+ if (GST_RPAD_PEER (peer) != (GstRealPad *) pad) {
+ GST_DEBUG (GST_CAT_DATAFLOW, "new pad in mid-switch!\n");
+ pad = (GstPad *) GST_RPAD_PEER (peer);
+ }
+ }
+
+ g_assert (GST_RPAD_BUFPEN (GST_RPAD_PEER (pad)) == NULL);
+ // now fill the bufferpen and switch so it can be consumed
+ GST_RPAD_BUFPEN (GST_RPAD_PEER (pad)) = buf;
+ GST_DEBUG (GST_CAT_DATAFLOW, "switching to %p\n",
+ GST_ELEMENT (GST_PAD_PARENT (pad))->threadstate);
+ cothread_switch (GST_ELEMENT (GST_PAD_PARENT (pad))->threadstate);
+
+ GST_DEBUG (GST_CAT_DATAFLOW, "done switching\n");
+}
+
+static void
+gst_basic_scheduler_select_proxy (GstPad * pad, GstBuffer * buf)
+{
+ GstRealPad *peer = GST_RPAD_PEER (pad);
+
+ g_print ("select proxy (%s:%s)\n", GST_DEBUG_PAD_NAME (pad));
+
+ GST_DEBUG_ENTER ("(%s:%s)", GST_DEBUG_PAD_NAME (pad));
+
+ GST_DEBUG (GST_CAT_DATAFLOW, "putting buffer %p in peer's pen\n", buf);
+
+ g_assert (GST_RPAD_BUFPEN (GST_RPAD_PEER (pad)) == NULL);
+ // now fill the bufferpen and switch so it can be consumed
+ GST_RPAD_BUFPEN (GST_RPAD_PEER (pad)) = buf;
+ GST_DEBUG (GST_CAT_DATAFLOW, "switching to %p\n",
+ GST_ELEMENT (GST_PAD_PARENT (pad))->threadstate);
+ g_print ("%p %s\n", GST_ELEMENT (GST_PAD_PARENT (pad)),
+ gst_element_get_name (GST_ELEMENT (GST_PAD_PARENT (pad))));
+ GST_ELEMENT (GST_PAD_PARENT (pad))->select_pad = pad;
+ GST_FLAG_UNSET (GST_PAD_PARENT (pad), GST_ELEMENT_COTHREAD_STOPPING);
+ cothread_switch (GST_ELEMENT (GST_PAD_PARENT (pad))->threadstate);
+
+ g_print ("done switching\n");
+ GST_DEBUG (GST_CAT_DATAFLOW, "done switching\n");
+}
+
+
+static GstBuffer *
+gst_basic_scheduler_gethandler_proxy (GstPad * pad)
+{
+ GstBuffer *buf;
+ GstRealPad *peer = GST_RPAD_PEER (pad);
+
+ GST_DEBUG_ENTER ("(%s:%s)", GST_DEBUG_PAD_NAME (pad));
+
+ // FIXME this should be bounded
+ // we will loop switching to the peer until it's filled up the bufferpen
+ while (GST_RPAD_BUFPEN (pad) == NULL) {
+ GST_DEBUG (GST_CAT_DATAFLOW, "switching to \"%s\": %p to fill bufpen\n",
+ GST_ELEMENT_NAME (GST_ELEMENT (GST_PAD_PARENT (pad))),
+ GST_ELEMENT (GST_PAD_PARENT (pad))->threadstate);
+ cothread_switch (GST_ELEMENT (GST_PAD_PARENT (pad))->threadstate);
+
+ // we may no longer be the same pad, check.
+ if (GST_RPAD_PEER (peer) != (GstRealPad *) pad) {
+ GST_DEBUG (GST_CAT_DATAFLOW, "new pad in mid-switch!\n");
+ pad = (GstPad *) GST_RPAD_PEER (peer);
+ }
+ }
+ GST_DEBUG (GST_CAT_DATAFLOW, "done switching\n");
+
+ // now grab the buffer from the pen, clear the pen, and return the buffer
+ buf = GST_RPAD_BUFPEN (pad);
+ GST_RPAD_BUFPEN (pad) = NULL;
+
+ return buf;
+}
+
+static GstBuffer *
+gst_basic_scheduler_pullregionfunc_proxy (GstPad * pad, GstRegionType type, guint64 offset, guint64 len)
+{
+ GstBuffer *buf;
+ GstRealPad *peer = GST_RPAD_PEER (pad);
+
+ GST_DEBUG_ENTER ("%s:%s,%d,%lld,%lld", GST_DEBUG_PAD_NAME (pad), type, offset, len);
+
+ // put the region info into the pad
+ GST_RPAD_REGIONTYPE (pad) = type;
+ GST_RPAD_OFFSET (pad) = offset;
+ GST_RPAD_LEN (pad) = len;
+
+ // FIXME this should be bounded
+ // we will loop switching to the peer until it's filled up the bufferpen
+ while (GST_RPAD_BUFPEN (pad) == NULL) {
+ GST_DEBUG (GST_CAT_DATAFLOW, "switching to %p to fill bufpen\n",
+ GST_ELEMENT (GST_PAD_PARENT (pad))->threadstate);
+ cothread_switch (GST_ELEMENT (GST_PAD_PARENT (pad))->threadstate);
+
+ // we may no longer be the same pad, check.
+ if (GST_RPAD_PEER (peer) != (GstRealPad *) pad) {
+ GST_DEBUG (GST_CAT_DATAFLOW, "new pad in mid-switch!\n");
+ pad = (GstPad *) GST_RPAD_PEER (peer);
+ }
+ }
+ GST_DEBUG (GST_CAT_DATAFLOW, "done switching\n");
+
+ // now grab the buffer from the pen, clear the pen, and return the buffer
+ buf = GST_RPAD_BUFPEN (pad);
+ GST_RPAD_BUFPEN (pad) = NULL;
+ return buf;
+}
+
+
+static void
+gst_basic_scheduler_cothreaded_chain (GstBin * bin, GstSchedulerChain * chain)
+{
+ GList *elements;
+ GstElement *element;
+ cothread_func wrapper_function;
+ GList *pads;
+ GstPad *pad;
+
+ GST_DEBUG (GST_CAT_SCHEDULING, "chain is using COTHREADS\n");
+
+ // first create thread context
+ if (bin->threadcontext == NULL) {
+ GST_DEBUG (GST_CAT_SCHEDULING, "initializing cothread context\n");
+ bin->threadcontext = cothread_init ();
+ }
+
+ // walk through all the chain's elements
+ elements = chain->elements;
+ while (elements) {
+ element = GST_ELEMENT (elements->data);
+ elements = g_list_next (elements);
+
+ // start out without a wrapper function, we select it later
+ wrapper_function = NULL;
+
+ // if the element has a loopfunc...
+ if (element->loopfunc != NULL) {
+ wrapper_function = GST_DEBUG_FUNCPTR (gst_basic_scheduler_loopfunc_wrapper);
+ GST_DEBUG (GST_CAT_SCHEDULING, "element '%s' is a loop-based\n", GST_ELEMENT_NAME (element));
+ }
+ else {
+ // otherwise we need to decide what kind of cothread
+ // if it's not DECOUPLED, we decide based on whether it's a source or not
+ if (!GST_FLAG_IS_SET (element, GST_ELEMENT_DECOUPLED)) {
+ // if it doesn't have any sinks, it must be a source (duh)
+ if (element->numsinkpads == 0) {
+ wrapper_function = GST_DEBUG_FUNCPTR (gst_basic_scheduler_src_wrapper);
+ GST_DEBUG (GST_CAT_SCHEDULING, "element '%s' is a source, using _src_wrapper\n",
+ GST_ELEMENT_NAME (element));
+ }
+ else {
+ wrapper_function = GST_DEBUG_FUNCPTR (gst_basic_scheduler_chain_wrapper);
+ GST_DEBUG (GST_CAT_SCHEDULING, "element '%s' is a filter, using _chain_wrapper\n",
+ GST_ELEMENT_NAME (element));
+ }
+ }
+ }
+
+ // now we have to walk through the pads to set up their state
+ pads = gst_element_get_pad_list (element);
+ while (pads) {
+ pad = GST_PAD (pads->data);
+ pads = g_list_next (pads);
+ if (!GST_IS_REAL_PAD (pad))
+ continue;
+
+ // if the element is DECOUPLED or outside the manager, we have to chain
+ if ((wrapper_function == NULL) ||
+ (GST_RPAD_PEER (pad) &&
+ (GST_ELEMENT (GST_PAD_PARENT (GST_PAD (GST_RPAD_PEER (pad))))->sched != chain->sched))
+ ) {
+ // set the chain proxies
+ if (GST_RPAD_DIRECTION (pad) == GST_PAD_SINK) {
+ GST_DEBUG (GST_CAT_SCHEDULING, "copying chain function into push proxy for %s:%s\n",
+ GST_DEBUG_PAD_NAME (pad));
+ GST_RPAD_CHAINHANDLER (pad) = GST_RPAD_CHAINFUNC (pad);
+ }
+ else {
+ GST_DEBUG (GST_CAT_SCHEDULING, "copying get function into pull proxy for %s:%s\n",
+ GST_DEBUG_PAD_NAME (pad));
+ GST_RPAD_GETHANDLER (pad) = GST_RPAD_GETFUNC (pad);
+ GST_RPAD_PULLREGIONFUNC (pad) = GST_RPAD_GETREGIONFUNC (pad);
+ }
+
+ // otherwise we really are a cothread
+ }
+ else {
+ if (gst_pad_get_direction (pad) == GST_PAD_SINK) {
+ GST_DEBUG (GST_CAT_SCHEDULING, "setting cothreaded push proxy for sinkpad %s:%s\n",
+ GST_DEBUG_PAD_NAME (pad));
+ GST_RPAD_CHAINHANDLER (pad) = GST_DEBUG_FUNCPTR (gst_basic_scheduler_chainhandler_proxy);
+ }
+ else {
+ GST_DEBUG (GST_CAT_SCHEDULING, "setting cothreaded pull proxy for srcpad %s:%s\n",
+ GST_DEBUG_PAD_NAME (pad));
+ GST_RPAD_GETHANDLER (pad) = GST_DEBUG_FUNCPTR (gst_basic_scheduler_gethandler_proxy);
+ GST_RPAD_PULLREGIONFUNC (pad) = GST_DEBUG_FUNCPTR (gst_basic_scheduler_pullregionfunc_proxy);
+ }
+ }
+ }
+
+ // need to set up the cothread now
+ if (wrapper_function != NULL) {
+ if (element->threadstate == NULL) {
+ // FIXME handle cothread_create returning NULL
+ element->threadstate = cothread_create (bin->threadcontext);
+ GST_DEBUG (GST_CAT_SCHEDULING, "created cothread %p for '%s'\n", element->threadstate,
+ GST_ELEMENT_NAME (element));
+ }
+ cothread_setfunc (element->threadstate, wrapper_function, 0, (char **) element);
+ GST_DEBUG (GST_CAT_SCHEDULING, "set wrapper function for '%s' to &%s\n",
+ GST_ELEMENT_NAME (element), GST_DEBUG_FUNCPTR_NAME (wrapper_function));
+ }
+ }
+}
+
+/*
+G_GNUC_UNUSED static void
+gst_basic_scheduler_chained_chain (GstBin *bin, _GstBinChain *chain) {
+ GList *elements;
+ GstElement *element;
+ GList *pads;
+ GstPad *pad;
+
+ GST_DEBUG (GST_CAT_SCHEDULING,"chain entered\n");
+ // walk through all the elements
+ elements = chain->elements;
+ while (elements) {
+ element = GST_ELEMENT (elements->data);
+ elements = g_list_next (elements);
+
+ // walk through all the pads
+ pads = gst_element_get_pad_list (element);
+ while (pads) {
+ pad = GST_PAD (pads->data);
+ pads = g_list_next (pads);
+ if (!GST_IS_REAL_PAD(pad)) continue;
+
+ if (GST_RPAD_DIRECTION(pad) == GST_PAD_SINK) {
+ GST_DEBUG (GST_CAT_SCHEDULING,"copying chain function into push proxy for %s:%s\n",GST_DEBUG_PAD_NAME(pad));
+ GST_RPAD_CHAINHANDLER(pad) = GST_RPAD_CHAINFUNC(pad);
+ } else {
+ GST_DEBUG (GST_CAT_SCHEDULING,"copying get function into pull proxy for %s:%s\n",GST_DEBUG_PAD_NAME(pad));
+ GST_RPAD_GETHANDLER(pad) = GST_RPAD_GETFUNC(pad);
+ GST_RPAD_PULLREGIONFUNC(pad) = GST_RPAD_GETREGIONFUNC(pad);
+ }
+ }
+ }
+}
+*/
+
+
+static GstSchedulerChain *
+gst_basic_scheduler_chain_new (GstScheduler * sched)
+{
+ GstSchedulerChain *chain = g_new (GstSchedulerChain, 1);
+
+ // initialize the chain with sane values
+ chain->sched = sched;
+ chain->disabled = NULL;
+ chain->elements = NULL;
+ chain->num_elements = 0;
+ chain->entry = NULL;
+ chain->cothreaded_elements = 0;
+ chain->schedule = FALSE;
+
+ // add the chain to the schedulers' list of chains
+ sched->chains = g_list_prepend (sched->chains, chain);
+ sched->num_chains++;
+
+ GST_INFO (GST_CAT_SCHEDULING, "created new chain %p, now are %d chains in sched %p",
+ chain, sched->num_chains, sched);
+
+ return chain;
+}
+
+static void
+gst_basic_scheduler_chain_destroy (GstSchedulerChain * chain)
+{
+ GstScheduler *sched = chain->sched;
+
+ // remove the chain from the schedulers' list of chains
+ chain->sched->chains = g_list_remove (chain->sched->chains, chain);
+ chain->sched->num_chains--;
+
+ // destroy the chain
+ g_list_free (chain->disabled); // should be empty...
+ g_list_free (chain->elements); // ditto
+ g_free (chain);
+
+ GST_INFO (GST_CAT_SCHEDULING, "destroyed chain %p, now are %d chains in sched %p", chain,
+ sched->num_chains, sched);
+}
+
+static void
+gst_basic_scheduler_chain_add_element (GstSchedulerChain * chain, GstElement * element)
+{
+ GST_INFO (GST_CAT_SCHEDULING, "adding element \"%s\" to chain %p", GST_ELEMENT_NAME (element),
+ chain);
+
+ // set the sched pointer for the element
+ element->sched = chain->sched;
+
+ // add the element to the list of 'disabled' elements
+ chain->disabled = g_list_prepend (chain->disabled, element);
+ chain->num_elements++;
+}
+
+static void
+gst_basic_scheduler_chain_enable_element (GstSchedulerChain * chain, GstElement * element)
+{
+ GST_INFO (GST_CAT_SCHEDULING, "enabling element \"%s\" in chain %p", GST_ELEMENT_NAME (element),
+ chain);
+
+ // remove from disabled list
+ chain->disabled = g_list_remove (chain->disabled, element);
+
+ // add to elements list
+ chain->elements = g_list_prepend (chain->elements, element);
+
+ // reschedule the chain
+ gst_basic_scheduler_cothreaded_chain (GST_BIN (chain->sched->parent), chain);
+}
+
+static void
+gst_basic_scheduler_chain_disable_element (GstSchedulerChain * chain, GstElement * element)
+{
+ GST_INFO (GST_CAT_SCHEDULING, "disabling element \"%s\" in chain %p", GST_ELEMENT_NAME (element),
+ chain);
+
+ // remove from elements list
+ chain->elements = g_list_remove (chain->elements, element);
+
+ // add to disabled list
+ chain->disabled = g_list_prepend (chain->disabled, element);
+
+ // reschedule the chain
+// FIXME this should be done only if manager state != NULL
+// gst_basic_scheduler_cothreaded_chain(GST_BIN(chain->sched->parent),chain);
+}
+
+static void
+gst_basic_scheduler_chain_remove_element (GstSchedulerChain * chain, GstElement * element)
+{
+ GST_INFO (GST_CAT_SCHEDULING, "removing element \"%s\" from chain %p", GST_ELEMENT_NAME (element),
+ chain);
+
+ // if it's active, deactivate it
+ if (g_list_find (chain->elements, element)) {
+ gst_basic_scheduler_chain_disable_element (chain, element);
+ }
+
+ // remove the element from the list of elements
+ chain->disabled = g_list_remove (chain->disabled, element);
+ chain->num_elements--;
+
+ // if there are no more elements in the chain, destroy the chain
+ if (chain->num_elements == 0)
+ gst_basic_scheduler_chain_destroy (chain);
+
+ // unset the sched pointer for the element
+ element->sched = NULL;
+}
+
+static void
+gst_basic_scheduler_chain_elements (GstScheduler * sched, GstElement * element1, GstElement * element2)
+{
+ GList *chains;
+ GstSchedulerChain *chain;
+ GstSchedulerChain *chain1 = NULL, *chain2 = NULL;
+ GstElement *element;
+
+ // first find the chains that hold the two
+ chains = sched->chains;
+ while (chains) {
+ chain = (GstSchedulerChain *) (chains->data);
+ chains = g_list_next (chains);
+
+ if (g_list_find (chain->disabled, element1))
+ chain1 = chain;
+ else if (g_list_find (chain->elements, element1))
+ chain1 = chain;
+
+ if (g_list_find (chain->disabled, element2))
+ chain2 = chain;
+ else if (g_list_find (chain->elements, element2))
+ chain2 = chain;
+ }
+
+ // first check to see if they're in the same chain, we're done if that's the case
+ if ((chain1 != NULL) && (chain1 == chain2)) {
+ GST_INFO (GST_CAT_SCHEDULING, "elements are already in the same chain");
+ return;
+ }
+
+ // now, if neither element has a chain, create one
+ if ((chain1 == NULL) && (chain2 == NULL)) {
+ GST_INFO (GST_CAT_SCHEDULING, "creating new chain to hold two new elements");
+ chain = gst_basic_scheduler_chain_new (sched);
+ gst_basic_scheduler_chain_add_element (chain, element1);
+ gst_basic_scheduler_chain_add_element (chain, element2);
+ // FIXME chain changed here
+// gst_basic_scheduler_cothreaded_chain(chain->sched->parent,chain);
+
+ // otherwise if both have chains already, join them
+ }
+ else if ((chain1 != NULL) && (chain2 != NULL)) {
+ GST_INFO (GST_CAT_SCHEDULING, "merging chain %p into chain %p", chain2, chain1);
+ // take the contents of chain2 and merge them into chain1
+ chain1->disabled = g_list_concat (chain1->disabled, g_list_copy (chain2->disabled));
+ chain1->elements = g_list_concat (chain1->elements, g_list_copy (chain2->elements));
+ chain1->num_elements += chain2->num_elements;
+ // FIXME chain changed here
+// gst_basic_scheduler_cothreaded_chain(chain->sched->parent,chain);
+
+ gst_basic_scheduler_chain_destroy (chain2);
+
+ // otherwise one has a chain already, the other doesn't
+ }
+ else {
+ // pick out which one has the chain, and which doesn't
+ if (chain1 != NULL)
+ chain = chain1, element = element2;
+ else
+ chain = chain2, element = element1;
+
+ GST_INFO (GST_CAT_SCHEDULING, "adding element to existing chain");
+ gst_basic_scheduler_chain_add_element (chain, element);
+ // FIXME chain changed here
+// gst_basic_scheduler_cothreaded_chain(chain->sched->parent,chain);
+ }
+}
+
+
+// find the chain within the scheduler that holds the element, if any
+static GstSchedulerChain *
+gst_basic_scheduler_find_chain (GstScheduler * sched, GstElement * element)
+{
+ GList *chains;
+ GstSchedulerChain *chain;
+
+ GST_INFO (GST_CAT_SCHEDULING, "searching for element \"%s\" in chains",
+ GST_ELEMENT_NAME (element));
+
+ chains = sched->chains;
+ while (chains) {
+ chain = (GstSchedulerChain *) (chains->data);
+ chains = g_list_next (chains);
+
+ if (g_list_find (chain->elements, element))
+ return chain;
+ if (g_list_find (chain->disabled, element))
+ return chain;
+ }
+
+ return NULL;
+}
+
+static void
+gst_basic_scheduler_chain_recursive_add (GstSchedulerChain * chain, GstElement * element)
+{
+ GList *pads;
+ GstPad *pad;
+ GstElement *peerelement;
+
+ // add the element to the chain
+ gst_basic_scheduler_chain_add_element (chain, element);
+
+ GST_DEBUG (GST_CAT_SCHEDULING, "recursing on element \"%s\"\n", GST_ELEMENT_NAME (element));
+ // now go through all the pads and see which peers can be added
+ pads = element->pads;
+ while (pads) {
+ pad = GST_PAD (pads->data);
+ pads = g_list_next (pads);
+
+ GST_DEBUG (GST_CAT_SCHEDULING, "have pad %s:%s, checking for valid peer\n",
+ GST_DEBUG_PAD_NAME (pad));
+ // if the peer exists and could be in the same chain
+ if (GST_PAD_PEER (pad)) {
+ GST_DEBUG (GST_CAT_SCHEDULING, "has peer %s:%s\n", GST_DEBUG_PAD_NAME (GST_PAD_PEER (pad)));
+ peerelement = GST_PAD_PARENT (GST_PAD_PEER (pad));
+ if (GST_ELEMENT_SCHED (GST_PAD_PARENT (pad)) == GST_ELEMENT_SCHED (peerelement)) {
+ GST_DEBUG (GST_CAT_SCHEDULING, "peer \"%s\" is valid for same chain\n",
+ GST_ELEMENT_NAME (peerelement));
+ // if it's not already in a chain, add it to this one
+ if (gst_basic_scheduler_find_chain (chain->sched, peerelement) == NULL) {
+ gst_basic_scheduler_chain_recursive_add (chain, peerelement);
+ }
+ }
+ }
+ }
+}
+
+/*
+ * Entry points for this scheduler.
+ */
+static void
+gst_basic_scheduler_add_element (GstScheduler * sched, GstElement * element)
+{
+ GList *pads;
+ GstPad *pad;
+ GstElement *peerelement;
+ GstSchedulerChain *chain;
+
+ g_return_if_fail (element != NULL);
+ g_return_if_fail (GST_IS_ELEMENT (element));
+
+ // if it's already in this scheduler, don't bother doing anything
+ if (GST_ELEMENT_SCHED (element) == sched)
+ return;
+
+ GST_INFO (GST_CAT_SCHEDULING, "adding element \"%s\" to scheduler", GST_ELEMENT_NAME (element));
+
+ // if the element already has a different scheduler, remove the element from it
+ if (GST_ELEMENT_SCHED (element)) {
+ gst_basic_scheduler_remove_element (GST_ELEMENT_SCHED (element), element);
+ }
+
+ // set the sched pointer in the element itself
+ GST_ELEMENT_SCHED (element) = sched;
+
+ // only deal with elements after this point, not bins
+ // exception is made for Bin's that are schedulable, like the autoplugger
+ if (GST_IS_BIN (element) && !GST_FLAG_IS_SET (element, GST_BIN_SELF_SCHEDULABLE))
+ return;
+
+ // first add it to the list of elements that are to be scheduled
+ sched->elements = g_list_prepend (sched->elements, element);
+ sched->num_elements++;
+
+ // create a chain to hold it, and add
+ chain = gst_basic_scheduler_chain_new (sched);
+ gst_basic_scheduler_chain_add_element (chain, element);
+
+ // set the sched pointer in all the pads
+ pads = element->pads;
+ while (pads) {
+ pad = GST_PAD (pads->data);
+ pads = g_list_next (pads);
+
+ // we only operate on real pads
+ if (!GST_IS_REAL_PAD (pad))
+ continue;
+
+ // set the pad's sched pointer
+ gst_pad_set_sched (pad, sched);
+
+ // if the peer element exists and is a candidate
+ if (GST_PAD_PEER (pad)) {
+ peerelement = GST_PAD_PARENT (GST_PAD_PEER (pad));
+ if (GST_ELEMENT_SCHED (element) == GST_ELEMENT_SCHED (peerelement)) {
+ GST_INFO (GST_CAT_SCHEDULING, "peer is in same scheduler, chaining together");
+ // make sure that the two elements are in the same chain
+ gst_basic_scheduler_chain_elements (sched, element, peerelement);
+ }
+ }
+ }
+}
+
+static void
+gst_basic_scheduler_remove_element (GstScheduler * sched, GstElement * element)
+{
+ GstSchedulerChain *chain;
+
+ g_return_if_fail (element != NULL);
+ g_return_if_fail (GST_IS_ELEMENT (element));
+
+ if (g_list_find (sched->elements, element)) {
+ GST_INFO (GST_CAT_SCHEDULING, "removing element \"%s\" from scheduler",
+ GST_ELEMENT_NAME (element));
+
+ // find what chain the element is in
+ chain = gst_basic_scheduler_find_chain (sched, element);
+
+ // remove it from its chain
+ gst_basic_scheduler_chain_remove_element (chain, element);
+
+ // remove it from the list of elements
+ sched->elements = g_list_remove (sched->elements, element);
+ sched->num_elements--;
+
+ // unset the scheduler pointer in the element
+ GST_ELEMENT_SCHED (element) = NULL;
+ }
+}
+
+static void
+gst_basic_scheduler_enable_element (GstScheduler *sched, GstElement *element)
+{
+ GstSchedulerChain *chain;
+
+ // find the chain the element's in
+ chain = gst_basic_scheduler_find_chain (sched, element);
+
+ if (chain) {
+ gst_basic_scheduler_chain_enable_element (chain, element);
+ }
+ else {
+ GST_INFO (GST_CAT_SCHEDULING, "element \"%s\" not found in any chain, not enabling", GST_ELEMENT_NAME (element));
+ }
+}
+
+static void
+gst_basic_scheduler_disable_element (GstScheduler *sched, GstElement *element)
+{
+ GstSchedulerChain *chain;
+
+ // find the chain the element is in
+ chain = gst_basic_scheduler_find_chain (sched, element);
+
+ // remove it from the chain
+ if (chain) {
+ gst_basic_scheduler_chain_disable_element (chain, element);
+ }
+ else {
+ GST_INFO (GST_CAT_SCHEDULING, "element \"%s\" not found in any chain, not disabling", GST_ELEMENT_NAME (element));
+ }
+}
+
+static void
+gst_basic_scheduler_lock_element (GstScheduler * sched, GstElement * element)
+{
+ if (element->threadstate)
+ cothread_lock (element->threadstate);
+}
+
+static void
+gst_basic_scheduler_unlock_element (GstScheduler * sched, GstElement * element)
+{
+ if (element->threadstate)
+ cothread_unlock (element->threadstate);
+}
+
+static void
+gst_basic_scheduler_pad_connect (GstScheduler * sched, GstPad * srcpad, GstPad * sinkpad)
+{
+ GstElement *srcelement, *sinkelement;
+
+ srcelement = GST_PAD_PARENT (srcpad);
+ g_return_if_fail (srcelement != NULL);
+ sinkelement = GST_PAD_PARENT (sinkpad);
+ g_return_if_fail (sinkelement != NULL);
+
+ GST_INFO (GST_CAT_SCHEDULING, "have pad connected callback on %s:%s to %s:%s",
+ GST_DEBUG_PAD_NAME (srcpad), GST_DEBUG_PAD_NAME (sinkpad));
+ GST_DEBUG (GST_CAT_SCHEDULING, "srcpad sched is %p, sinkpad sched is %p\n",
+ GST_ELEMENT_SCHED (srcelement), GST_ELEMENT_SCHED (sinkelement));
+
+ if (GST_ELEMENT_SCHED (srcelement) == GST_ELEMENT_SCHED (sinkelement)) {
+ GST_INFO (GST_CAT_SCHEDULING, "peer %s:%s is in same scheduler, chaining together",
+ GST_DEBUG_PAD_NAME (sinkpad));
+ gst_basic_scheduler_chain_elements (sched, srcelement, sinkelement);
+ }
+}
+
+static void
+gst_basic_scheduler_pad_disconnect (GstScheduler * sched, GstPad * srcpad, GstPad * sinkpad)
+{
+ GstSchedulerChain *chain;
+ GstElement *element1, *element2;
+ GstSchedulerChain *chain1, *chain2;
+
+ GST_INFO (GST_CAT_SCHEDULING, "disconnecting pads %s:%s and %s:%s",
+ GST_DEBUG_PAD_NAME (srcpad), GST_DEBUG_PAD_NAME (sinkpad));
+
+ // we need to have the parent elements of each pad
+ element1 = GST_ELEMENT (GST_PAD_PARENT (srcpad));
+ element2 = GST_ELEMENT (GST_PAD_PARENT (sinkpad));
+
+ // first task is to remove the old chain they belonged to.
+ // this can be accomplished by taking either of the elements,
+ // since they are guaranteed to be in the same chain
+ // FIXME is it potentially better to make an attempt at splitting cleaner??
+ chain = gst_basic_scheduler_find_chain (sched, element1);
+ if (chain) {
+ GST_INFO (GST_CAT_SCHEDULING, "destroying chain");
+ gst_basic_scheduler_chain_destroy (chain);
+ }
+
+ // now create a new chain to hold element1 and build it from scratch
+ chain1 = gst_basic_scheduler_chain_new (sched);
+ gst_basic_scheduler_chain_recursive_add (chain1, element1);
+
+ // check the other element to see if it landed in the newly created chain
+ if (gst_basic_scheduler_find_chain (sched, element2) == NULL) {
+ // if not in chain, create chain and build from scratch
+ chain2 = gst_basic_scheduler_chain_new (sched);
+ gst_basic_scheduler_chain_recursive_add (chain2, element2);
+ }
+}
+
+static GstPad *
+gst_basic_scheduler_pad_select (GstScheduler * sched, GList * padlist)
+{
+ GstPad *pad = NULL;
+ GList *padlist2 = padlist;
+
+ GST_INFO (GST_CAT_SCHEDULING, "performing select");
+
+ while (padlist2) {
+ pad = GST_PAD (padlist2->data);
+
+ if (gst_pad_peek (pad)) {
+ g_print ("found something in pad %s:%s\n", GST_DEBUG_PAD_NAME (pad));
+ return pad;
+ }
+
+ padlist2 = g_list_next (padlist2);
+ }
+
+ /* else there is nothing ready to consume, set up the select functions */
+ while (padlist) {
+ pad = GST_PAD (padlist->data);
+
+ GST_RPAD_CHAINHANDLER (pad) = GST_DEBUG_FUNCPTR (gst_basic_scheduler_select_proxy);
+
+ padlist = g_list_next (padlist);
+ }
+ if (pad != NULL) {
+ GstRealPad *peer = GST_RPAD_PEER (pad);
+
+ cothread_switch (GST_ELEMENT (GST_PAD_PARENT (peer))->threadstate);
+
+ g_print ("%p %s\n", GST_ELEMENT (GST_PAD_PARENT (pad)),
+ gst_element_get_name (GST_ELEMENT (GST_PAD_PARENT (pad))));
+ pad = GST_ELEMENT (GST_PAD_PARENT (pad))->select_pad;
+
+ g_assert (pad != NULL);
+ g_print ("back from select (%s:%s)\n", GST_DEBUG_PAD_NAME (pad));
+ }
+ return pad;
+}
+
+static gboolean
+gst_basic_scheduler_iterate (GstScheduler * sched)
+{
+ GstBin *bin = GST_BIN (sched->parent);
+ GList *chains;
+ GstSchedulerChain *chain;
+ GstElement *entry;
+ gint num_basic_schedulerd = 0;
+ gboolean eos = FALSE;
+ GList *elements;
+
+ GST_DEBUG_ENTER ("(\"%s\")", GST_ELEMENT_NAME (bin));
+
+ g_return_val_if_fail (bin != NULL, TRUE);
+ g_return_val_if_fail (GST_IS_BIN (bin), TRUE);
+
+ // step through all the chains
+ chains = sched->chains;
+
+ g_return_val_if_fail (chains != NULL, FALSE);
+
+ while (chains) {
+ chain = (GstSchedulerChain *) (chains->data);
+ chains = g_list_next (chains);
+
+ // 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 (GST_CAT_DATAFLOW, "starting iteration via cothreads\n");
+
+ if (chain->elements) {
+ entry = NULL; //MattH ADDED?
+ GST_DEBUG (GST_CAT_SCHEDULING, "there are %d elements in this chain\n", chain->num_elements);
+ elements = chain->elements;
+ while (elements) {
+ entry = GST_ELEMENT (elements->data);
+ elements = g_list_next (elements);
+ if (GST_FLAG_IS_SET (entry, GST_ELEMENT_DECOUPLED)) {
+ GST_DEBUG (GST_CAT_SCHEDULING, "entry \"%s\" is DECOUPLED, skipping\n",
+ GST_ELEMENT_NAME (entry));
+ entry = NULL;
+ }
+ else if (GST_FLAG_IS_SET (entry, GST_ELEMENT_NO_ENTRY)) {
+ GST_DEBUG (GST_CAT_SCHEDULING, "entry \"%s\" is not valid, skipping\n",
+ GST_ELEMENT_NAME (entry));
+ entry = NULL;
+ }
+ else
+ break;
+ }
+ if (entry) {
+ GST_FLAG_SET (entry, GST_ELEMENT_COTHREAD_STOPPING);
+ GST_DEBUG (GST_CAT_DATAFLOW, "set COTHREAD_STOPPING flag on \"%s\"(@%p)\n",
+ GST_ELEMENT_NAME (entry), entry);
+ cothread_switch (entry->threadstate);
+
+ // following is a check to see if the chain was interrupted due to a
+ // top-half state_change(). (i.e., if there's a pending state.)
+ //
+ // if it was, return to gstthread.c::gst_thread_main_loop() to
+ // execute the state change.
+ GST_DEBUG (GST_CAT_DATAFLOW, "cothread switch ended or interrupted\n");
+ if (GST_STATE_PENDING (GST_SCHEDULER (sched)->parent) != GST_STATE_VOID_PENDING) {
+ GST_DEBUG (GST_CAT_DATAFLOW, "handle pending state %d\n",
+ GST_STATE_PENDING (GST_SCHEDULER (sched)->parent));
+ return FALSE;
+ }
+
+ }
+ else {
+ GST_INFO (GST_CAT_DATAFLOW, "NO ENTRY INTO CHAIN!");
+ eos = TRUE;
+ }
+ }
+ else {
+ GST_INFO (GST_CAT_DATAFLOW, "NO ENABLED ELEMENTS IN CHAIN!!");
+ eos = TRUE;
+ }
+ }
+
+ GST_DEBUG (GST_CAT_DATAFLOW, "leaving (%s)\n", GST_ELEMENT_NAME (bin));
+ return !eos;
+}
+
+
+static void
+gst_basic_scheduler_show (GstScheduler * sched)
+{
+ GList *chains, *elements;
+ GstElement *element;
+ GstSchedulerChain *chain;
+
+ if (sched == NULL) {
+ g_print ("scheduler doesn't exist for this element\n");
+ return;
+ }
+
+ g_return_if_fail (GST_IS_SCHEDULER (sched));
+
+ g_print ("SCHEDULER DUMP FOR MANAGING BIN \"%s\"\n", GST_ELEMENT_NAME (sched->parent));
+
+ g_print ("scheduler has %d elements in it: ", sched->num_elements);
+ elements = sched->elements;
+ while (elements) {
+ element = GST_ELEMENT (elements->data);
+ elements = g_list_next (elements);
+
+ g_print ("%s, ", GST_ELEMENT_NAME (element));
+ }
+ g_print ("\n");
+
+ g_print ("scheduler has %d chains in it\n", sched->num_chains);
+ chains = sched->chains;
+ while (chains) {
+ chain = (GstSchedulerChain *) (chains->data);
+ chains = g_list_next (chains);
+
+ g_print ("%p: ", chain);
+
+ elements = chain->disabled;
+ while (elements) {
+ element = GST_ELEMENT (elements->data);
+ elements = g_list_next (elements);
+
+ g_print ("!%s, ", GST_ELEMENT_NAME (element));
+ }
+
+ elements = chain->elements;
+ while (elements) {
+ element = GST_ELEMENT (elements->data);
+ elements = g_list_next (elements);
+
+ g_print ("%s, ", GST_ELEMENT_NAME (element));
+ }
+ g_print ("\n");
+ }
+}
diff --git a/gst/types/Makefile.am b/gst/types/Makefile.am
index 7de9743a3ba67bfae2b4232011f5146c5c9d09cd..4fb622b33d2227e6ebc7a56c8b120e3fd950d140 100644 (file)
--- a/gst/types/Makefile.am
+++ b/gst/types/Makefile.am
filter_LTLIBRARIES = libgsttypes.la
-libgsttypes_la_SOURCES = \
- gsttypes.c
+libgsttypes_la_SOURCES = gsttypes.c
+
+libgsttypes_la_CFLAGS = $(XML_CFLAGS) $(XML_CFLAGS) $(GLIB_CFLAGS)
+
+libgsttypes_la_LIBADD = $(XML_LIBS) $(GLIB_LIBS)
libgsttypes_la_LDFLAGS = -version-info $(GST_LIBVERSION)
diff --git a/gstplay/Makefile.am b/gstplay/Makefile.am
index b30d421cabeeaa4a74db540fdc806f34ffec1460..5efea227c07bc756191e41f41258732cedafd4d4 100644 (file)
--- a/gstplay/Makefile.am
+++ b/gstplay/Makefile.am
# FIXME FIXME
-LIBADD += $(GNOME_LIBS) $(GST_LIBS)
-CFLAGS += $(GNOME_CFLAGS) $(LIBGLADE_GNOME_CFLAGS) $(GST_CFLAGS) -DDATADIR=\""$(gladedir)/"\"
bin_PROGRAMS = gstmediaplay
gstplayprivate.h
libgstmediaplay_la_LDFLAGS = -rdynamic
-
-gstmediaplay_CFLAGS = $(LIBGLADE_GNOME_CFLAGS)
+libgstmediaplay_la_CFLAGS = $(GNOME_CFLAGS) $(LIBGLADE_GNOME_CFLAGS) $(GST_CFLAGS) -DDATADIR=\""$(gladedir)/"\"
+gstmediaplay_CFLAGS = $(LIBGLADE_GNOME_CFLAGS) $(GNOME_CFLAGS) $(LIBGLADE_GNOME_CFLAGS) $(GST_CFLAGS) -DDATADIR=\""$(gladedir)/"\"
gstmediaplay_LDADD = $(GST_LIBS) $(LIBGLADE_GNOME_LIBS) libgstmediaplay.la
diff --git a/gstplay/gstplay.c b/gstplay/gstplay.c
index 42071c33f6cfe0bfa8c5599abc056d21ca5e7c78..22d84cd9ccc1c508e028ccd0b76198b964700e4e 100644 (file)
--- a/gstplay/gstplay.c
+++ b/gstplay/gstplay.c
"sink");
}
else {
+ GST_FLAG_SET (priv->video_element, GST_ELEMENT_THREAD_SUGGESTED);
gst_bin_add (GST_BIN (priv->video_element), colorspace);
gst_element_connect (colorspace, "src", priv->video_show, "sink");
gst_element_add_ghost_pad (priv->video_element,
static gboolean
gst_play_idle_func (gpointer data)
{
- return gst_bin_iterate (GST_BIN (data));
+ gboolean busy;
+
+ busy = gst_bin_iterate (GST_BIN (data));
+
+ return busy;
}
static void
diff --git a/libs/audio/Makefile.am b/libs/audio/Makefile.am
index 355f3f5225608ff682f429e05e22c45228bcd801..d9c76e22f85f13fa7d93c5dde37f88adee19a18b 100644 (file)
--- a/libs/audio/Makefile.am
+++ b/libs/audio/Makefile.am
libgstaudioinclude_HEADERS = gstaudio.h
# FIXME is this needed?
-CFLAGS += -O2 $(FOMIT_FRAME_POINTER) -finline-functions -ffast-math
+libgstaudio_la_CFLAGS = -O2 $(FOMIT_FRAME_POINTER) -finline-functions -ffast-math $(GLIB_CFLAGS) $(XML_CFLAGS)
index 0a6e8ee9cf666cd979351586d639feaedf2d4080..a9156401490c0574d19fd67751c609f552cc8b30 100644 (file)
filter_LTLIBRARIES = libgstbytestream.la libgstbstest.la
libgstbytestream_la_SOURCES = gstbytestream.c
+libgstbytestream_la_CFLAGS = $(GLIB_CFLAGS) $(XML_CFLAGS) $(GST_CFLAGS)
libgstbstest_la_SOURCES = gstbstest.c
+libgstbstest_la_CFLAGS = $(GLIB_CFLAGS) $(XML_CFLAGS) $(GST_CFLAGS)
libgstbytestreamincludedir = $(includedir)/gst/libs/bytestream
libgstbytestreaminclude_HEADERS = gstbytestream.h
-# CFLAGS += -O2 $(FOMIT_FRAME_POINTER) -funroll-all-loops -finline-functions -ffast-math
index 2c948cc199ddf461bfe73f0ef75840853a4267d6..c63537d85edfd57fbe3f982dd8760d69af61e753 100644 (file)
--- a/libs/control/Makefile.am
+++ b/libs/control/Makefile.am
gstdplinearinterp.h
libgstcontrol_la_LIBADD = -lm
-
-CFLAGS += -O2 $(FOMIT_FRAME_POINTER) -finline-functions -ffast-math
+libgstcontrol_la_CFLAGS = -O2 $(FOMIT_FRAME_POINTER) -finline-functions -ffast-math $(GLIB_CFLAGS) $(XML_CFLAGS)
index f9f4699549822a93922f06ac443be49c31ecd076..c96a6f45e9d4ea6021395ecc1b19b499b27ea1e1 100644 (file)
--- a/libs/getbits/Makefile.am
+++ b/libs/getbits/Makefile.am
gbtest_SOURCES = gbtest.c
gbtest_LDADD = libgstgetbits.la $(GST_LIBS)
-CFLAGS += -O2 $(FOMIT_FRAME_POINTER) -funroll-all-loops -finline-functions -ffast-math
+libgstgetbits_la_CFLAGS = -O2 $(FOMIT_FRAME_POINTER) -funroll-all-loops -finline-functions -ffast-math $(GLIB_CFLAGS) $(XML_CFLAGS)
diff --git a/libs/idct/Makefile.am b/libs/idct/Makefile.am
index ba53d490801d0cd9fac10c709dc17c50047378a6..44b476ae01a56463991ff468bd86754fa191662f 100644 (file)
--- a/libs/idct/Makefile.am
+++ b/libs/idct/Makefile.am
noinst_HEADERS = dct.h
-CFLAGS += -O2 $(FOMIT_FRAME_POINTER) -finline-functions -ffast-math
+libgstidct_la_CFLAGS = -O2 $(FOMIT_FRAME_POINTER) -finline-functions -ffast-math $(GLIB_CFLAGS) $(XML_CFLAGS) $(GST_CFLAGS)
index 727a1764bba1df8e611bbd438261a55ed2d2259a..7bff65a60208931e913a70e6e037e175807e22b8 100644 (file)
--- a/libs/putbits/Makefile.am
+++ b/libs/putbits/Makefile.am
noinst_HEADERS = gstputbits.h
-CFLAGS += -O2 $(FOMIT_FRAME_POINTER) -funroll-all-loops -finline-functions -ffast-math
+libgstputbits_la_CFLAGS = -O2 $(FOMIT_FRAME_POINTER) -funroll-all-loops -finline-functions -ffast-math
index 504e9680d631ad6b56948d1e84fc70916a858f09..79893d080af70f9573918494dd6049dc6d4031a0 100644 (file)
endif
endif
-CFLAGS += -O2 -ffast-math $(ARCHCFLAGS)
+libresample_la_CFLAGS = -O2 -ffast-math $(ARCHCFLAGS)
diff --git a/libs/riff/Makefile.am b/libs/riff/Makefile.am
index 6307536dba0d1824a898002c501b39567d4dd6b6..493cd8381d715238f12c71cc3aaae08e53fd52ea 100644 (file)
--- a/libs/riff/Makefile.am
+++ b/libs/riff/Makefile.am
libgstriffincludedir = $(includedir)/gst/libs/gstriff
libgstriffinclude_HEADERS = gstriff.h
-CFLAGS += -O2 $(FOMIT_FRAME_POINTER) -funroll-all-loops -finline-functions -ffast-math
+libgstriff_la_CFLAGS = -O2 $(FOMIT_FRAME_POINTER) -funroll-all-loops -finline-functions -ffast-math $(GLIB_CFLAGS) $(XML_CFLAGS) $(GST_CFLAGS)
index 64b75fce5a3b1fc07e6937fcc54226bdefb8b909..d9caf8310d18f88ebca2ebb066e81721e57372d9 100644 (file)
GSTHTTPSRC=
endif
-#CFLAGS += -O2 -Wall -finstrument-functions -DGST_ENABLE_FUNC_INSTRUMENTATION
-
libgstelements_la_DEPENDENCIES = ../libgst.la
libgstelements_la_SOURCES = \
gstelements.c \
gstaggregator.h \
gststatistics.h
-CFLAGS += -O2 -Wall
-LDFLAGS += -lm
-
-libgstelements_la_LIBADD = $(GHTTP_LIBS)
+libgstelements_la_CFLAGS = $(GHTTP_CFLAGS) $(GLIB_CFLAGS) $(XML_CFLAGS)
+libgstelements_la_LIBADD = $(GHTTP_LIBS) $(GLIB_LIBS) $(XML_LIBS)
libgstelements_la_LDFLAGS = -version-info $(GST_LIBVERSION)
index 02eb921fa3ed07366a14675f254a66175357af7e..69b8740525c677686c3a96ad1f6c166bfb155e01 100644 (file)
@@ -213,14 +213,6 @@ gst_fakesink_get_property (GObject *object, guint prop_id, GValue *value, GParam
}
}
-/**
- * gst_fakesink_chain:
- * @pad: the pad this faksink is connected to
- * @buffer: the buffer or event that has to be absorbed
- *
- * Take the buffer or event from the pad and unref it without doing
- * anything with it.
- */
static void
gst_fakesink_chain (GstPad *pad, GstBuffer *buf)
{
fakesink = GST_FAKESINK (gst_pad_get_parent (pad));
- if (GST_IS_EVENT(buf)) {
- GstEvent *event = GST_EVENT (buf);
-
- switch (GST_EVENT_TYPE (event)) {
- case GST_EVENT_EOS:
- g_print("fakesink: have EOS event!\n");
- gst_element_set_state (GST_ELEMENT (fakesink), GST_STATE_PAUSED);
- break;
- default:
- g_print("fakesink: have unhandled event!\n");
- break;
- }
- gst_event_free (event);
+ /*
+ if (GST_IS_EVENT (buf)) {
+ gst_pad_event_default (pad, GST_EVENT (buf));
return;
}
+ */
if (!fakesink->silent)
g_print("fakesink: chain ******* (%s:%s)< (%d bytes, %lld) %p\n",
index f78792d69a91516d3c54647cce7cfcc3ebe04614..cdad2e7aafbef9cc77f0ed5c17647600751272c7 100644 (file)
reader = FALSE;
+restart:
/* we have to lock the queue since we span threads */
GST_DEBUG_ELEMENT (GST_CAT_DATAFLOW, queue, "locking t:%ld\n", pthread_self ());
g_mutex_lock (queue->qlock);
gst_queue_locked_flush (queue);
break;
case GST_EVENT_EOS:
+ GST_DEBUG_ELEMENT (GST_CAT_DATAFLOW, queue, "eos in on %s %d\n",
+ GST_ELEMENT_NAME (queue), queue->level_buffers);
break;
default:
gst_pad_event_default (pad, GST_EVENT (buf));
while (queue->level_buffers == queue->size_buffers) {
// if there's a pending state change for this queue or its manager, switch
// back to iterator so bottom half of state change executes
- if (GST_STATE_PENDING(queue) != GST_STATE_VOID_PENDING ||
-// GST_STATE_PENDING(GST_SCHEDULE(GST_ELEMENT(queue)->sched)->parent) != GST_STATE_VOID_PENDING)
-GST_STATE_PENDING(GST_SCHED_PARENT(GST_ELEMENT_SCHED(GST_PAD_PARENT(GST_PAD_PEER(queue->sinkpad))))) !=
-GST_STATE_VOID_PENDING)
- {
+ while (GST_STATE (queue) != GST_STATE_PLAYING) {
GST_DEBUG_ELEMENT (GST_CAT_DATAFLOW, queue, "interrupted!!\n");
- if (GST_STATE_PENDING(queue) != GST_STATE_VOID_PENDING)
- GST_DEBUG_ELEMENT (GST_CAT_DATAFLOW, queue, "GST_STATE_PENDING(queue) != GST_STATE_VOID_PENDING)\n");
- if (GST_STATE_PENDING(GST_SCHEDULE(GST_ELEMENT(queue)->sched)->parent) != GST_STATE_VOID_PENDING)
- GST_DEBUG_ELEMENT (GST_CAT_DATAFLOW, queue, "GST_STATE_PENDING(GST_SCHEDULE(GST_ELEMENT(queue)->sched)->parent) != GST_STATE_VOID_PENDING\n");
g_mutex_unlock (queue->qlock);
cothread_switch(cothread_current_main());
+ goto restart;
}
+ g_assert (GST_STATE (queue) == GST_STATE_PLAYING);
GST_DEBUG_ELEMENT (GST_CAT_DATAFLOW, queue, "waiting for not_full, level:%d/%d\n", queue->level_buffers, queue->size_buffers);
if (queue->writer)
writer = FALSE;
+restart:
/* have to lock for thread-safety */
GST_DEBUG_ELEMENT (GST_CAT_DATAFLOW, queue, "locking t:%ld\n", pthread_self ());
g_mutex_lock (queue->qlock);
while (queue->level_buffers == 0) {
// if there's a pending state change for this queue or its manager, switch
// back to iterator so bottom half of state change executes
- if (GST_STATE_PENDING(queue) != GST_STATE_VOID_PENDING ||
-// GST_STATE_PENDING(GST_SCHEDULE(GST_ELEMENT(queue)->sched)->parent) != GST_STATE_VOID_PENDING)
-GST_STATE_PENDING(GST_SCHED_PARENT(GST_ELEMENT_SCHED(GST_PAD_PARENT(GST_PAD_PEER(queue->srcpad))))) !=
-GST_STATE_VOID_PENDING)
- {
+ while (GST_STATE (queue) != GST_STATE_PLAYING) {
GST_DEBUG_ELEMENT (GST_CAT_DATAFLOW, queue, "interrupted!!\n");
- if (GST_STATE_PENDING(queue) != GST_STATE_VOID_PENDING)
- GST_DEBUG_ELEMENT (GST_CAT_DATAFLOW, queue, "GST_STATE_PENDING(queue) != GST_STATE_VOID_PENDING)\n");
- if (GST_STATE_PENDING(GST_SCHEDULE(GST_ELEMENT(queue)->sched)->parent) != GST_STATE_VOID_PENDING)
- GST_DEBUG_ELEMENT (GST_CAT_DATAFLOW, queue, "GST_STATE_PENDING(GST_SCHEDULE(GST_ELEMENT(queue)->sched)->parent) != GST_STATE_VOID_PENDING\n");
g_mutex_unlock (queue->qlock);
cothread_switch(cothread_current_main());
+ goto restart;
}
+ g_assert (GST_STATE (queue) == GST_STATE_PLAYING);
GST_DEBUG_ELEMENT (GST_CAT_DATAFLOW, queue, "waiting for not_empty, level:%d/%d\n", queue->level_buffers, queue->size_buffers);
if (queue->reader)
GstEvent *event = GST_EVENT(buf);
switch (GST_EVENT_TYPE(event)) {
case GST_EVENT_EOS:
- GST_DEBUG_ELEMENT (GST_CAT_DATAFLOW, queue, "queue eos\n");
+ GST_DEBUG_ELEMENT (GST_CAT_DATAFLOW, queue, "queue \"%s\" eos\n", GST_ELEMENT_NAME (queue));
gst_element_set_state (GST_ELEMENT (queue), GST_STATE_PAUSED);
break;
default:
{
GstQueue *queue;
GstElementStateReturn ret;
+ GstElementState new_state;
g_return_val_if_fail (GST_IS_QUEUE (element), GST_STATE_FAILURE);
queue = GST_QUEUE (element);
+ GST_DEBUG_ENTER("('%s')", GST_ELEMENT_NAME (element));
+
// lock the queue so another thread (not in sync with this thread's state)
// can't call this queue's _get (or whatever)
- GST_LOCK (queue);
+ g_mutex_lock (queue->qlock);
- /* if going down into NULL state, clear out buffers*/
- if (GST_STATE_PENDING (element) == GST_STATE_READY) {
- /* otherwise (READY or higher) we need to open the file */
- gst_queue_flush (queue);
- }
+ new_state = GST_STATE_PENDING (element);
- // if we haven't failed already, give the parent class a chance to ;-)
- if (GST_ELEMENT_CLASS (parent_class)->change_state)
- {
- gboolean valid_handler = FALSE;
- guint state_change_id = g_signal_lookup("state_change", G_OBJECT_TYPE(element));
-
- // determine whether we need to block the parent (element) class'
- // STATE_CHANGE signal so we can UNLOCK before returning. we block
- // it if we could find the state_change signal AND there's a signal
- // handler attached to it.
- //
- // note: this assumes that change_state() *only* emits state_change signal.
- // if element change_state() emits other signals, they need to be blocked
- // as well.
- if (state_change_id &&
- g_signal_has_handler_pending(G_OBJECT(element), state_change_id, 0, FALSE))
- valid_handler = TRUE;
- if (valid_handler)
- g_signal_handler_block(G_OBJECT(element), state_change_id);
-
- ret = GST_ELEMENT_CLASS (parent_class)->change_state (element);
-
- if (valid_handler)
- g_signal_handler_unblock(G_OBJECT(element), state_change_id);
-
- // UNLOCK, *then* emit signal (if there's one there)
- GST_UNLOCK(queue);
- if (valid_handler)
- g_signal_emit(G_OBJECT (element), state_change_id, 0, GST_STATE(element));
+ if (new_state == GST_STATE_PAUSED) {
+ g_cond_signal (queue->not_full);
+ g_cond_signal (queue->not_empty);
}
- else
- {
- ret = GST_STATE_SUCCESS;
- GST_UNLOCK(queue);
+ else if (new_state == GST_STATE_READY) {
+ gst_queue_locked_flush (queue);
}
+ else if (new_state == GST_STATE_PLAYING) {
+ if (!GST_PAD_CONNECTED (queue->sinkpad)) {
+ // FIXME can this be?
+ if (queue->reader)
+ g_cond_signal (queue->not_empty);
+ g_mutex_unlock (queue->qlock);
+
+ return GST_STATE_FAILURE;
+ }
+ }
+
+ ret = GST_ELEMENT_CLASS (parent_class)->change_state (element);
+ g_mutex_unlock (queue->qlock);
+ GST_DEBUG_LEAVE("('%s')", GST_ELEMENT_NAME (element));
return ret;
}
diff --git a/test/Makefile.am b/test/Makefile.am
index 88ca16a9e96b664d5dc49ee37bf7ede51e997392..5f062b4e0acb390da763ba1ed30992122ecebf54 100644 (file)
--- a/test/Makefile.am
+++ b/test/Makefile.am
GNOME_PROGS = spectrum wave mp1parse videotest aviparse \
videotest2 video2mp1 dvshow dv2mp1 \
mpeg2parse2 mpeg2parse3 \
- mp2tomp1v2 main sinesliders testspeed dvdplay
+ mp2tomp1v2 main sinesliders testspeed dvdplay testpod
sinesliders_LDADD = ../libs/control/libgstcontrol.la
else
GNOME_PROGS =
mp3play ac3parse ac3play dvdcat fake cobin \
vidcapture avi2mpg mp2tomp1 mp1tomp1 pipetest \
vidcapture2 mp2toavi mp3tovorbis xmmstest \
- mp3mad lat
+ mp3mad lat
SUBDIRS = xml bindings events memchunk
noinst_HEADERS = mem.h
-LIBS += $(GNOME_LIBS) $(GST_LIBS)
-CFLAGS += $(GNOME_CFLAGS) $(GST_CFLAGS)
+LIBS = $(GNOME_LIBS) $(GST_LIBS)
+CFLAGS = $(GNOME_CFLAGS) $(GST_CFLAGS) $(XML_CFLAGS) $(GST_CFLAGS)
EXTRA_DIST = README
index 27542ace21718159a0b20533c769a7e107ab1d10..fdc7dc05f8f3de2d1326818d7ceb07e6a78da31f 100644 (file)
noinst_LTLIBRARIES = libcrashtest.la
-libcrashtest_la_SOURCES = \
- dummy.c
+libcrashtest_la_SOURCES = dummy.c
+libcrashtest_la_CFLAGS = $(GLIB_CFLAGS) $(XML_CFLAGS) $(GST_CFLAGS)
-noinst_HEADERS = \
- dummy.h
+noinst_HEADERS = dummy.h
noinst_PROGRAMS = test
-test_LDADD = libcrashtest.la
+test_LDADD = libcrashtest.la $(GLIB_LIBS)
+test_CFLAGS = $(GLIB_CFLAGS) $(XML_CFLAGS) $(GST_CFLAGS)
index f2300be1ac61d729ac6c57fab90ab54a6761e83b..82d65e2f4695a3cc101a36a20b7b4f61f6696885 100644 (file)
--- a/test/events/Makefile.am
+++ b/test/events/Makefile.am
noinst_PROGRAMS = seek
-LIBS += $(GST_LIBS)
-CFLAGS += $(GST_CFLAGS)
+LIBS = $(GLIB_LIBS) $(GST_LIBS)
+CFLAGS = $(GLIB_CFLAGS) $(XML_CFLAGS) $(GST_CFLAGS)
index e3198c289eb5c2292539393183336a3e432d4cb7..fdc2c409251cd82ecfda42997ad09681d593e1df 100644 (file)
gmemchunktest_SOURCES = gmemchunktest.c
gstmemchunktest_SOURCES = gstmemchunktest.c gstmemchunk.c gstmemchunk.h
-LIBS += $(GST_LIBS)
-CFLAGS += $(GST_CFLAGS)
+LIBS = $(GST_LIBS)
+CFLAGS = $(GLIB_CFLAGS) $(XML_CFLAGS) $(GST_CFLAGS)
diff --git a/test/mpeg2parse2.c b/test/mpeg2parse2.c
index 29f2d98d3990d758d199afef7938bd2d0fe052bc..ae66fdf92408cc14003efd5e5d4bad585889ddd6 100644 (file)
--- a/test/mpeg2parse2.c
+++ b/test/mpeg2parse2.c
return TRUE;
}
-void mpeg2parse_newpad(GstElement *parser,GstPad *pad, GstElement *pipeline) {
+void mpegdemux_newpad(GstElement *parser,GstPad *pad, GstElement *pipeline) {
g_print("***** a new pad %s was created %p\n", gst_pad_get_name(pad), pipeline);
gst_element_set_state(GST_ELEMENT(pipeline),GST_STATE_PAUSED);
}
g_print("should be using file '%s'\n",argv[1]);
- parse = gst_elementfactory_make("mpeg2parse","parse");
+ parse = gst_elementfactory_make("mpegdemux","parse");
//parse = gst_elementfactory_make("mpeg1parse","parse");
g_return_val_if_fail(parse != NULL, -1);
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(parse),"new_pad",mpegdemux_newpad, pipeline);
gtk_signal_connect(GTK_OBJECT(src),"eos",GTK_SIGNAL_FUNC(eof),NULL);
diff --git a/test/mpeg2parse3.c b/test/mpeg2parse3.c
index 75bf72736e55c9f7f21fcf3d0868fe601bacf21c..88d4f84d92e8779fbbd0d096a76511c77128d9ae 100644 (file)
--- a/test/mpeg2parse3.c
+++ b/test/mpeg2parse3.c
}
gboolean idle_func(gpointer data) {
- gst_bin_iterate(GST_BIN(data));
- return TRUE;
+ return gst_bin_iterate(GST_BIN(data));
}
-void mpeg2parse_newpad(GstElement *parser,GstPad *pad, GstElement *pipeline) {
+void mpegdemux_newpad(GstElement *parser,GstPad *pad, GstElement *pipeline) {
g_print("***** a new pad %s was created\n", gst_pad_get_name(pad));
}
}
-void mpeg2parse_have_size(GstElement *videosink,gint width,gint height) {
+void mpegdemux_have_size(GstElement *videosink,gint width,gint height) {
gtk_widget_set_usize(gtk_socket,width,height);
gtk_widget_show_all(appwindow);
}
src = gst_elementfactory_make("dvdsrc","src");
g_print("using DVD source\n");
} else {
- src = gst_elementfactory_make("disksrc","src");
+ src = gst_elementfactory_make("filesrc","src");
}
g_return_val_if_fail(src != NULL, -1);
}
g_print("should be using file '%s'\n",argv[1]);
- parse = gst_elementfactory_make("mpeg2parse","parse");
+ parse = gst_elementfactory_make("mpegdemux","parse");
//parse = gst_elementfactory_make("mpeg1parse","parse");
g_return_val_if_fail(parse != NULL, -1);
gtk_socket_steal (GTK_SOCKET (gtk_socket),
gst_util_get_int_arg (GTK_OBJECT(show), "xid"));
- gtk_signal_connect(GTK_OBJECT(parse),"new_pad",mpeg2parse_newpad, pipeline);
+ gtk_signal_connect(GTK_OBJECT(parse),"new_pad",mpegdemux_newpad, pipeline);
gtk_signal_connect(GTK_OBJECT(src),"eos",GTK_SIGNAL_FUNC(eof),NULL);
- gtk_signal_connect(GTK_OBJECT(show),"have_size",mpeg2parse_have_size, pipeline);
+ gtk_signal_connect(GTK_OBJECT(show),"have_size",mpegdemux_have_size, pipeline);
g_print("setting to PLAYING state\n");
gst_element_set_state(GST_ELEMENT(pipeline),GST_STATE_PLAYING);
diff --git a/test/testpod.c b/test/testpod.c
--- /dev/null
+++ b/test/testpod.c
@@ -0,0 +1,86 @@
+#include <gtk/gtk.h>
+#include <gst/gst.h>
+
+void play (GtkButton *button, gpointer data)
+{
+ gtk_signal_emit_by_name(GTK_OBJECT(data), "play");
+}
+
+void reset (GtkButton *button, gpointer data)
+{
+ gtk_signal_emit_by_name(GTK_OBJECT(data), "reset");
+}
+
+int main(int argc, char **argv)
+{
+ guint channels;
+ GtkWidget *window, *vbox, *play_button, *reset_button, *quit_button;
+ GstElement *disksrc, *mad, *stereo2mono, *pod, *osssink, *pipeline;
+
+ gst_init (&argc, &argv);
+ gtk_init (&argc, &argv);
+
+ if (argc!=2) {
+ g_print("usage: %s <mp3-filename>\n", argv[0]);
+ exit(-1);
+ }
+
+ disksrc = gst_elementfactory_make("disksrc", "disksrc");
+ mad = gst_elementfactory_make("mad", "mad");
+ pod = gst_elementfactory_make("playondemand", "playondemand");
+ osssink = gst_elementfactory_make("osssink", "osssink");
+
+ gtk_object_set(GTK_OBJECT(disksrc), "location", argv[1], NULL);
+ gtk_object_set(GTK_OBJECT(osssink), "fragment", 0x00180008, NULL);
+ gtk_object_get(GTK_OBJECT(disksrc), "channels", &channels, NULL);
+
+ pipeline = gst_pipeline_new("app");
+
+ gst_bin_add(GST_BIN(pipeline), disksrc);
+ gst_bin_add(GST_BIN(pipeline), mad);
+ gst_bin_add(GST_BIN(pipeline), pod);
+ gst_bin_add(GST_BIN(pipeline), osssink);
+
+ gst_element_connect(disksrc, "src", mad, "sink");
+ gst_element_connect(pod, "src", osssink, "sink");
+
+ if (channels != 2) {
+ gst_element_connect(mad, "src", pod, "sink");
+ } else {
+ stereo2mono = gst_elementfactory_make("stereo2mono", "stereo2mono");
+ gst_bin_add(GST_BIN(pipeline), stereo2mono);
+ gst_element_connect(mad, "src", stereo2mono, "sink");
+ gst_element_connect(stereo2mono, "src", pod, "sink");
+ }
+
+ gst_element_set_state(pipeline, GST_STATE_PLAYING);
+
+ /* initialize gui elements ... */
+ window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
+ vbox = gtk_vbox_new(FALSE, 0);
+ play_button = gtk_button_new_with_label("play");
+ reset_button = gtk_button_new_with_label("reset");
+ quit_button = gtk_button_new_with_label("quit");
+
+ /* do the packing stuff ... */
+ gtk_window_set_default_size(GTK_WINDOW(window), 96, 96);
+ gtk_container_add(GTK_CONTAINER(window), vbox);
+ gtk_box_pack_start(GTK_BOX(vbox), play_button, FALSE, FALSE, 2);
+ gtk_box_pack_start(GTK_BOX(vbox), reset_button, FALSE, FALSE, 2);
+ gtk_box_pack_start(GTK_BOX(vbox), quit_button, FALSE, FALSE, 2);
+
+ /* connect things ... */
+ gtk_signal_connect(GTK_OBJECT(play_button), "clicked", play, pod);
+ gtk_signal_connect(GTK_OBJECT(reset_button), "clicked", reset, pod);
+ gtk_signal_connect(GTK_OBJECT(quit_button), "clicked", gtk_main_quit, NULL);
+
+ /* show the gui. */
+ gtk_widget_show(play_button);
+ gtk_widget_show(reset_button);
+ gtk_widget_show(quit_button);
+ gtk_widget_show(vbox);
+ gtk_widget_show(window);
+ gtk_idle_add((GtkFunction)gst_bin_iterate, pipeline);
+
+ gtk_main();
+}
diff --git a/test/xml/Makefile.am b/test/xml/Makefile.am
index 045355ec2e557024ac173c2cdc65fc1c847ab8e7..2f9ac71747b1b3e55cff9475a8404dad3eeee5eb 100644 (file)
--- a/test/xml/Makefile.am
+++ b/test/xml/Makefile.am
noinst_PROGRAMS = readreg createreg
LDADD = $(GST_LIBS)
+CFLAGS = $(GLIB_CFLAGS) $(XML_CFLAGS) $(GST_CFLAGS)
EXTRA_DIST = README
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 43ac3402a0e088361490494f56622afacc7e2f62..9eeeb6f2237158d990b8b7aa49e14a68137ee809 100644 (file)
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
faketest events timecache
# we have nothing but apps here, we can do this safely
-LIBS += $(GST_LIBS)
-CFLAGS += $(GST_CFLAGS)
+LIBS = $(GST_LIBS)
+CFLAGS = $(GLIB_CFLAGS) $(XML_CFLAGS) $(GST_CFLAGS)
EXTRA_DIST = README
diff --git a/tests/eos/Makefile.am b/tests/eos/Makefile.am
index 55839b9e5ab499eb658afbe6aaa90f9ab38b1ffc..aa55a8fcd5f35d6cbe2147393fb5572aa2e975da 100644 (file)
--- a/tests/eos/Makefile.am
+++ b/tests/eos/Makefile.am
noinst_PROGRAMS = case1 case2 case3 case4 case5 case6 case7
# jsut apps here, this is safe
-LIBS += $(GST_LIBS)
-CFLAGS += $(GST_CFLAGS)
+LIBS = $(GST_LIBS)
+CFLAGS = $(GLIB_CFLAGS) $(XML_CFLAGS) $(GST_CFLAGS)
diff --git a/tests/incsched.c b/tests/incsched.c
index 1e63534ad3bc7e8c19d19f9deb3d19eed6f10851..edb73f88a47adfa45b6f003f3246e80934f9dd44 100644 (file)
--- a/tests/incsched.c
+++ b/tests/incsched.c
g_print("\nAdding src to thread:\n");
gst_bin_add(thread,src);
- gst_schedule_show(GST_ELEMENT_SCHED(thread));
+ gst_scheduler_show(GST_ELEMENT_SCHED(thread));
g_print("\nAdding identity to thread:\n");
gst_bin_add(thread,identity);
- gst_schedule_show(GST_ELEMENT_SCHED(thread));
+ gst_scheduler_show(GST_ELEMENT_SCHED(thread));
g_print("\nRemoving identity from thread:\n");
gst_bin_remove(thread, identity);
- gst_schedule_show(GST_ELEMENT_SCHED(thread));
+ gst_scheduler_show(GST_ELEMENT_SCHED(thread));
g_print("\nAdding identity to thread:\n");
gst_bin_add(thread,identity);
- gst_schedule_show(GST_ELEMENT_SCHED(thread));
+ gst_scheduler_show(GST_ELEMENT_SCHED(thread));
g_print("\nConnecting src to identity:\n");
gst_element_connect(src,"src",identity,"sink");
- gst_schedule_show(GST_ELEMENT_SCHED(thread));
+ gst_scheduler_show(GST_ELEMENT_SCHED(thread));
g_print("\nDisconnecting src from identity:\n");
gst_element_disconnect(src,"src",identity,"sink");
- gst_schedule_show(GST_ELEMENT_SCHED(thread));
+ gst_scheduler_show(GST_ELEMENT_SCHED(thread));
g_print("\nConnecting src to identity:\n");
gst_element_connect(src,"src",identity,"sink");
- gst_schedule_show(GST_ELEMENT_SCHED(thread));
+ gst_scheduler_show(GST_ELEMENT_SCHED(thread));
g_print("\nAdding sink to bin:\n");
gst_bin_add(bin,sink);
- gst_schedule_show(GST_ELEMENT_SCHED(thread));
+ gst_scheduler_show(GST_ELEMENT_SCHED(thread));
g_print("\nAdding bin to thread:\n");
gst_bin_add(thread, GST_ELEMENT(bin));
- gst_schedule_show(GST_ELEMENT_SCHED(thread));
+ gst_scheduler_show(GST_ELEMENT_SCHED(thread));
g_print("\nConnecting identity to sink:\n");
gst_element_connect(identity,"src",sink,"sink");
- gst_schedule_show(GST_ELEMENT_SCHED(thread));
+ gst_scheduler_show(GST_ELEMENT_SCHED(thread));
g_print("\nDisconnecting sink:\n");
gst_element_disconnect(identity,"src",sink,"sink");
- gst_schedule_show(GST_ELEMENT_SCHED(thread));
+ gst_scheduler_show(GST_ELEMENT_SCHED(thread));
g_print("\nAdding identity2 to bin:\n");
gst_bin_add(bin, identity2);
- gst_schedule_show(GST_ELEMENT_SCHED(thread));
+ gst_scheduler_show(GST_ELEMENT_SCHED(thread));
g_print("\nConnecting identity2 to sink\n");
gst_element_connect(identity2,"src",sink,"sink");
- gst_schedule_show(GST_ELEMENT_SCHED(thread));
+ gst_scheduler_show(GST_ELEMENT_SCHED(thread));
g_print("\nConnecting identity to identity2\n");
gst_element_connect(identity,"src",identity2,"sink");
- gst_schedule_show(GST_ELEMENT_SCHED(thread));
+ gst_scheduler_show(GST_ELEMENT_SCHED(thread));
g_print("\n\nNow setting state from NULL to READY:\n");
gst_element_set_state(GST_ELEMENT(thread),GST_STATE_READY);
- gst_schedule_show(GST_ELEMENT_SCHED(thread));
+ gst_scheduler_show(GST_ELEMENT_SCHED(thread));
g_print("\n\nNow setting state from READY to PLAYING:\n");
gst_element_set_state(GST_ELEMENT(thread),GST_STATE_PLAYING);
- gst_schedule_show(GST_ELEMENT_SCHED(thread));
+ gst_scheduler_show(GST_ELEMENT_SCHED(thread));
g_print("\n\nIterating:\n");
gst_bin_iterate(thread);
g_print("\n\nNow setting state from PLAYING to READY:\n");
gst_element_set_state(GST_ELEMENT(thread),GST_STATE_READY);
- gst_schedule_show(GST_ELEMENT_SCHED(thread));
+ gst_scheduler_show(GST_ELEMENT_SCHED(thread));
g_print("\n\nNow setting state from READY to PLAYING:\n");
gst_element_set_state(GST_ELEMENT(thread),GST_STATE_PLAYING);
- gst_schedule_show(GST_ELEMENT_SCHED(thread));
+ gst_scheduler_show(GST_ELEMENT_SCHED(thread));
g_print("\n\nIterating:\n");
gst_bin_iterate(thread);
g_print("\n\nNow setting state from PLAYING to READY:\n");
gst_element_set_state(GST_ELEMENT(thread),GST_STATE_READY);
- gst_schedule_show(GST_ELEMENT_SCHED(thread));
+ gst_scheduler_show(GST_ELEMENT_SCHED(thread));
g_print("\nDisconnecting identity from identity2:\n");
gst_element_disconnect(identity,"src",identity2,"sink");
- gst_schedule_show(GST_ELEMENT_SCHED(thread));
+ gst_scheduler_show(GST_ELEMENT_SCHED(thread));
g_print("\nDisconnecting identity2 from sink:\n");
gst_element_disconnect(identity2,"src",sink,"sink");
- gst_schedule_show(GST_ELEMENT_SCHED(thread));
+ gst_scheduler_show(GST_ELEMENT_SCHED(thread));
g_print("\nConnecting identity to sink:\n");
gst_element_connect(identity,"src",sink,"sink");
- gst_schedule_show(GST_ELEMENT_SCHED(thread));
+ gst_scheduler_show(GST_ELEMENT_SCHED(thread));
g_print("\n\nNow setting identity2 to NULL:\n");
gst_element_set_state(identity2,GST_STATE_NULL);
g_print("\nRemoving identity2 from bin:\n");
gst_bin_remove(bin, identity2);
- gst_schedule_show(GST_ELEMENT_SCHED(thread));
+ gst_scheduler_show(GST_ELEMENT_SCHED(thread));
g_print("\n\nNow setting state from READY to PLAYING:\n");
gst_element_set_state(GST_ELEMENT(thread),GST_STATE_PLAYING);
- gst_schedule_show(GST_ELEMENT_SCHED(thread));
+ gst_scheduler_show(GST_ELEMENT_SCHED(thread));
g_print("\n\nIterating:\n");
gst_bin_iterate(thread);
diff --git a/tests/mp1vid.c b/tests/mp1vid.c
index 678f2f31f9997ee666cb3d46e3e57fe72856ae31..c502b1bc29b89ca5a38f1a346e01d46d7e17a69c 100644 (file)
--- a/tests/mp1vid.c
+++ b/tests/mp1vid.c
gst_bin_add(GST_BIN(pipeline),sourcethread);
- gst_schedule_show(GST_ELEMENT_SCHED(pipeline));
+ gst_scheduler_show(GST_ELEMENT_SCHED(pipeline));
gst_element_set_state(pipeline,GST_STATE_PLAYING);
sleep(1);
index 5b25390e24384b041562a5bf39d23ae87dab8f16..447ed2f940c8d8aaae70017d7a1fc22efd605b60 100644 (file)
--- a/tests/muxing/Makefile.am
+++ b/tests/muxing/Makefile.am
noinst_PROGRAMS = case1
# jsut apps here, this is safe
-LIBS += $(GST_LIBS)
-CFLAGS += $(GST_CFLAGS)
+LIBS = $(GST_LIBS)
+CFLAGS = $(GLIB_CFLAGS) $(XML_CFLAGS) $(GST_CFLAGS)
diff --git a/tests/nego/Makefile.am b/tests/nego/Makefile.am
index 42604723892dc3aec6a1181688a3f00d98467f7c..7e47fff9b64154408182cac43380088da6850f0b 100644 (file)
--- a/tests/nego/Makefile.am
+++ b/tests/nego/Makefile.am
noinst_PROGRAMS = nego1
# jsut apps here, this is safe
-LIBS += $(GST_LIBS)
-CFLAGS += $(GST_CFLAGS)
+LIBS = $(GST_LIBS)
+CFLAGS = $(GLIB_CFLAGS) $(XML_CFLAGS) $(GST_CFLAGS)
index f263f271004f234616b1e949275c975441125ebc..8f8cdd41531777c5c99886c18b77dbbd60d30813 100644 (file)
noinst_PROGRAMS = autoplug
# just an app here, we're safe
-LIBS += $(GNOME_LIBS) $(GST_LIBS)
-CFLAGS += $(GNOME_CFLAGS) $(GST_CFLAGS)
+autoplug_LDADD = $(GNOME_LIBS) $(GST_LIBS) $(GLIB_LIBS)
+autoplug_CFLAGS = $(GNOME_CFLAGS) $(GLIB_CFLAGS) $(XML_CFLAGS) $(GST_CFLAGS)
index c1fca3f985f21a65de6d092be6d8872b8b57c71e..29da841f05595e515613cbe4147138bc67a8e4de 100644 (file)
noinst_PROGRAMS = cutter
noinst_HEADERS = cutter.h
-LIBS += $(GST_LIBS)
-CFLAGS += $(GST_CFLAGS)
+cutter_LDADD = $(GST_LIBS)
+cutter_CFLAGS = $(GLIB_CFLAGS) $(XML_CFLAGS) $(GST_CFLAGS)
index 77e8ef336ae80c85053dcbbcbe65ce252a8888f1..5821f461f27e7dc4fb22cb916c775562bc8dc9b6 100644 (file)
noinst_PROGRAMS = helloworld
-LIBS += $(GST_LIBS)
-CFLAGS += $(GST_CFLAGS)
+helloworld_LDADD = $(GST_LIBS)
+helloworld_CFLAGS = $(GLIB_CFLAGS) $(XML_CFLAGS) $(GST_CFLAGS)
diff --git a/tests/old/examples/helloworld2/Makefile.am b/tests/old/examples/helloworld2/Makefile.am
index 6d686a40923c7c3a5af205ef5e5f21e906be931b..1daf5c0da1e16297a4bed9412b80fb143becd991 100644 (file)
noinst_PROGRAMS = helloworld2
-LIBS += $(GST_LIBS)
-CFLAGS += $(GST_CFLAGS)
+helloworld2_LDADD = $(GST_LIBS)
+helloworld2_CFLAGS = $(GLIB_CFLAGS) $(XML_CFLAGS) $(GST_CFLAGS)
index 11c2e57cfc692a4af35abe460c73be9949f54562..c1d844569c77595b722114cdac3bed93193d576f 100644 (file)
noinst_PROGRAMS = mp3parselaunch
# just an app here, we're safe
-LIBS += $(GST_LIBS)
-CFLAGS += $(GST_CFLAGS)
+mp3parselaunch_LDADD = $(GST_LIBS)
+mp3parselaunch_CFLAGS = $(GLIB_CFLAGS) $(XML_CFLAGS) $(GST_CFLAGS)
noinst_SCRIPTS = mp3play
EXTRA_DIST = mp3play
index d15b425208014d2c3ea189338c46ab090ee4110d..8d993da8c70593144397cd23b712eb42b5888732 100644 (file)
noinst_PROGRAMS = mixer
noinst_HEADERS = mixer.h
-LIBS += $(GST_LIBS)
-CFLAGS += $(GST_CFLAGS)
+mixer_LDADD = $(GST_LIBS)
+mixer_CFLAGS = $(GLIB_CFLAGS) $(XML_CFLAGS) $(GST_CFLAGS)
index 7a02eddcb44aa55011cb01f04ff86c721e2b3e60..ec492cad34f7989deddb071a5229cb8bfed2dd09 100644 (file)
gst_element_set_state(main_bin, GST_STATE_PLAYING);
// write out the schedule
- gst_schedule_show(GST_ELEMENT_SCHED(main_bin));
+ gst_scheduler_show(GST_ELEMENT_SCHED(main_bin));
playing = TRUE;
j = 0;
index 5e0b9fca0fa9fe418989b221d0eeb4a96a06456d..11c631711ddb4dbfcc60e2c5bfc86e3abcc1ec68 100644 (file)
noinst_LTLIBRARIES = libexample.la
libexample_la_SOURCES = example.c
+libexample_la_CFLAGS = $(GLIB_CFLAGS) $(XML_CFLAGS) $(GST_CFLAGS)
noinst_HEADERS = example.h
index e4ef4c7ce8ed3f4fd1a8b1e0ecab9700b85e7471..7b67eeabd69e1b3e3684ba177787d914a72eb5ae 100644 (file)
noinst_PROGRAMS = queue
-LIBS += $(GST_LIBS)
-CFLAGS += $(GST_CFLAGS)
+queue_LDADD = $(GST_LIBS)
+queue_CFLAGS = $(GLIB_CFLAGS) $(XML_CFLAGS) $(GST_CFLAGS)
index fd4f914bbd3e47fec62007b600bc12e96abf9355..5bd7542f1c16f13de10e7fe91228ca20503c1cf0 100644 (file)
noinst_PROGRAMS = queue2
-LIBS += $(GST_LIBS)
-CFLAGS += $(GST_CFLAGS)
+queue2_LDADD = $(GST_LIBS)
+queue2_CFLAGS = $(GLIB_CFLAGS) $(XML_CFLAGS) $(GST_CFLAGS)
index be6313ce6d5b8d1810c375769a44a76cb4dfbd21..de2d00faabca5c573927edf0b2635eebbc471e66 100644 (file)
noinst_PROGRAMS = queue3
-LIBS += $(GST_LIBS)
-CFLAGS += $(GST_CFLAGS)
+queue3_LDADD = $(GST_LIBS)
+queue3_CFLAGS = $(GLIB_CFLAGS) $(XML_CFLAGS) $(GST_CFLAGS)
index 0b1a4857b8244e0a1f6c06ef6e9eeae5b71ddad5..8d6e2eec9550a951e33045aee4b7b6b1e1d86ef7 100644 (file)
noinst_PROGRAMS = queue4
-LIBS += $(GST_LIBS)
-CFLAGS += $(GST_CFLAGS)
+queue4_LDADD = $(GST_LIBS)
+queue4_CFLAGS = $(GLIB_CFLAGS) $(XML_CFLAGS) $(GST_CFLAGS)
index 4e019cb7316c1778f12455d202a864cfd2f4aec7..ae9f9ac7594d168c1953e27f42948b884ae960ca 100644 (file)
noinst_PROGRAMS = thread
-LIBS += $(GST_LIBS)
-CFLAGS += $(GST_CFLAGS)
+thread_LDADD = $(GST_LIBS)
+thread_CFLAGS = $(GLIB_CFLAGS) $(XML_CFLAGS) $(GST_CFLAGS)
index 57669bdcc06fb3e9baca1673faa1a966068c5a79..e8a9b4f1c805da96c5a6e08c4ae20f0d66b6c9a3 100644 (file)
noinst_PROGRAMS = typefind
-LIBS += $(GST_LIBS)
-CFLAGS += $(GST_CFLAGS)
+typefind_LDADD = $(GST_LIBS)
+typefind_CFLAGS = $(GLIB_CFLAGS) $(XML_CFLAGS) $(GST_CFLAGS)
index 24b890fd84d245aca9f44c0ad5fde26b60c01ce0..7b8e2f4745ad7ca470bbaec183edd2ec9b4f38a7 100644 (file)
noinst_PROGRAMS = createxml runxml
-LIBS += $(GST_LIBS)
-CFLAGS += $(GST_CFLAGS)
+createxml_LDADD = $(GST_LIBS)
+createxml_CFLAGS = $(GLIB_CFLAGS) $(XML_CFLAGS) $(GST_CFLAGS)
+runxml_LDADD = $(GST_LIBS)
+runxml_CFLAGS = $(GLIB_CFLAGS) $(XML_CFLAGS) $(GST_CFLAGS)
index 74d5101862e44738e384f4d7db419f757d380c0e..e5d82ee00a5926b6075bd38821513e80d10f8763 100644 (file)
check_PROGRAMS = $(testprogs)
# we have nothing but apps here, we can do this safely
-LIBS += $(GST_LIBS)
-CFLAGS += $(GST_CFLAGS)
+LIBS = $(GST_LIBS)
+CFLAGS = $(GLIB_CFLAGS) $(XML_CFLAGS) $(GST_CFLAGS)
DIST_SUBDIRS = refcounting capsnego plugin bytestream
diff --git a/tests/old/testsuite/bytestream/Makefile.am b/tests/old/testsuite/bytestream/Makefile.am
index 75aeed7915fcf7b97401dee94ab04bedbde53b93..1f617b231fd3f537c1cd11715c6d28d6b94ecc36 100644 (file)
# we have nothing but apps here, we can do this safely
-LIBS += $(GST_LIBS)
-CFLAGS += $(GST_CFLAGS)
+LIBS = $(GST_LIBS)
+CFLAGS = $(GLIB_CFLAGS) $(XML_CFLAGS) $(GST_CFLAGS)
index 6b1c466c7c858781d1ad138c5bd44de66e664da2..8dc74bb8c07862a1e69f9864a0d5a98f91321d98 100644 (file)
check_PROGRAMS = $(testprogs)
# we have nothing but apps here, we can do this safely
-LIBS += $(GST_LIBS)
-CFLAGS += $(GST_CFLAGS)
+LIBS = $(GST_LIBS)
+CFLAGS = $(GLIB_CFLAGS) $(XML_CFLAGS) $(GST_CFLAGS)
index f56298f1cc5c8d4b68fc7aada63c5478369bc0ce..bc7386fe1c8478516cfd6bdb7668f07b48b91f30 100644 (file)
dparamstest_LDFLAGS = -L$(top_builddir)/libs/control/ -lgstcontrol
# we have nothing but apps here, we can do this safely
LIBS = $(GST_LIBS)
-CFLAGS += $(GST_CFLAGS)
+CFLAGS = $(GLIB_CFLAGS) $(XML_CFLAGS) $(GST_CFLAGS)
index 9acef8767d4803544ec24396f4d777113486e987..4cadb77724968b2365cdda559e45408d3398c3ad 100644 (file)
check_PROGRAMS = $(testprogs)
# we have nothing but apps here, we can do this safely
-LIBS += $(GST_LIBS)
-CFLAGS += $(GST_CFLAGS)
+LIBS = $(GST_LIBS)
+CFLAGS = $(GLIB_CFLAGS) $(XML_CFLAGS) $(GST_CFLAGS)
diff --git a/tests/old/testsuite/refcounting/Makefile.am b/tests/old/testsuite/refcounting/Makefile.am
index 06319a7597ba93ac5f5359b8e7ebc4a4a34d2d6d..3d98225aa864432f015ae72aff17b67acc6aabca 100644 (file)
noinst_HEADERS = mem.h
# we have nothing but apps here, we can do this safely
-LIBS += $(GST_LIBS)
-CFLAGS += $(GST_CFLAGS)
+LIBS = $(GST_LIBS)
+CFLAGS = $(GLIB_CFLAGS) $(XML_CFLAGS) $(GST_CFLAGS)
index 2bcb8cee3992c50de11ef4c1aabae289cb7e1a5e..8f1fa53d6a5a30286a188ad29c4bb569e685bf24 100644 (file)
--- a/tests/sched/Makefile.am
+++ b/tests/sched/Makefile.am
dynamic_pipeline_SOURCES = dynamic-pipeline.c
# nothing but apps here, this is safe
-LIBS += $(GST_LIBS)
-CFLAGS += $(GST_CFLAGS)
+LIBS = $(GST_LIBS)
+CFLAGS = $(GLIB_CFLAGS) $(XML_CFLAGS) $(GST_CFLAGS)
diff --git a/testsuite/Makefile.am b/testsuite/Makefile.am
index 74d5101862e44738e384f4d7db419f757d380c0e..e5d82ee00a5926b6075bd38821513e80d10f8763 100644 (file)
--- a/testsuite/Makefile.am
+++ b/testsuite/Makefile.am
check_PROGRAMS = $(testprogs)
# we have nothing but apps here, we can do this safely
-LIBS += $(GST_LIBS)
-CFLAGS += $(GST_CFLAGS)
+LIBS = $(GST_LIBS)
+CFLAGS = $(GLIB_CFLAGS) $(XML_CFLAGS) $(GST_CFLAGS)
DIST_SUBDIRS = refcounting capsnego plugin bytestream
index 75aeed7915fcf7b97401dee94ab04bedbde53b93..1f617b231fd3f537c1cd11715c6d28d6b94ecc36 100644 (file)
# we have nothing but apps here, we can do this safely
-LIBS += $(GST_LIBS)
-CFLAGS += $(GST_CFLAGS)
+LIBS = $(GST_LIBS)
+CFLAGS = $(GLIB_CFLAGS) $(XML_CFLAGS) $(GST_CFLAGS)
index 6b1c466c7c858781d1ad138c5bd44de66e664da2..8dc74bb8c07862a1e69f9864a0d5a98f91321d98 100644 (file)
check_PROGRAMS = $(testprogs)
# we have nothing but apps here, we can do this safely
-LIBS += $(GST_LIBS)
-CFLAGS += $(GST_CFLAGS)
+LIBS = $(GST_LIBS)
+CFLAGS = $(GLIB_CFLAGS) $(XML_CFLAGS) $(GST_CFLAGS)
index f56298f1cc5c8d4b68fc7aada63c5478369bc0ce..bc7386fe1c8478516cfd6bdb7668f07b48b91f30 100644 (file)
dparamstest_LDFLAGS = -L$(top_builddir)/libs/control/ -lgstcontrol
# we have nothing but apps here, we can do this safely
LIBS = $(GST_LIBS)
-CFLAGS += $(GST_CFLAGS)
+CFLAGS = $(GLIB_CFLAGS) $(XML_CFLAGS) $(GST_CFLAGS)
index 9acef8767d4803544ec24396f4d777113486e987..4cadb77724968b2365cdda559e45408d3398c3ad 100644 (file)
check_PROGRAMS = $(testprogs)
# we have nothing but apps here, we can do this safely
-LIBS += $(GST_LIBS)
-CFLAGS += $(GST_CFLAGS)
+LIBS = $(GST_LIBS)
+CFLAGS = $(GLIB_CFLAGS) $(XML_CFLAGS) $(GST_CFLAGS)
index 06319a7597ba93ac5f5359b8e7ebc4a4a34d2d6d..3d98225aa864432f015ae72aff17b67acc6aabca 100644 (file)
noinst_HEADERS = mem.h
# we have nothing but apps here, we can do this safely
-LIBS += $(GST_LIBS)
-CFLAGS += $(GST_CFLAGS)
+LIBS = $(GST_LIBS)
+CFLAGS = $(GLIB_CFLAGS) $(XML_CFLAGS) $(GST_CFLAGS)
diff --git a/tools/Makefile.am b/tools/Makefile.am
index bef06f9476b18439a57ec03cb31cdafe24cea8be..a761fd77dc4d316f20424a3bd1857cd43ce08037 100644 (file)
--- a/tools/Makefile.am
+++ b/tools/Makefile.am
gstreamer-complete.1 gstreamer-compprep.1
LDADD = $(GST_LIBS)
-CFLAGS = $(LIBGST_CFLAGS) -DGST_CONFIG_DIR=\"$(GST_CONFIG_DIR)\"
+CFLAGS = $(GST_CFLAGS) -DGST_CONFIG_DIR=\"$(GST_CONFIG_DIR)\" $(GLIB_CFLAGS) $(XML_CFLAGS)
EXTRA_DIST = $(man_MANS)
index 6ac84be18af7ffee7c37e3cc11e204fa60a72801..423516a698179ba841cf2f935b26f1fa6ae74733 100644 (file)
if (factory->typefindfunc)
printf(" Has typefind function: %s\n",GST_DEBUG_FUNCPTR_NAME(factory->typefindfunc));
}
+ else if (GST_IS_SCHEDULERFACTORY (feature)) {
+ GstSchedulerFactory *factory;
+
+ factory = GST_SCHEDULERFACTORY (feature);
+ printf("%s: %s: %s\n", plugin->name, GST_OBJECT_NAME (factory), factory->longdesc);
+ }
else {
printf("%s: %s (%s)\n", plugin->name, gst_object_get_name (GST_OBJECT (feature)),
g_type_name (G_OBJECT_TYPE (feature)));
if (factory->typefindfunc)
printf(" Has typefind function: %s\n",GST_DEBUG_FUNCPTR_NAME(factory->typefindfunc));
}
+ else if (GST_IS_SCHEDULERFACTORY (feature)) {
+ GstSchedulerFactory *factory;
+
+ factory = GST_SCHEDULERFACTORY (feature);
+ printf(" %s: %s\n", GST_OBJECT_NAME (factory), factory->longdesc);
+ }
else {
printf(" %s (%s)\n", gst_object_get_name (GST_OBJECT (feature)),
g_type_name (G_OBJECT_TYPE (feature)));
index 8e91fc05ceb26d725b873827225bd08ea2b20dec..e50db14cbd74f69d3f6ba7bede5b080c9b8317c2 100644 (file)
--- a/tools/gstreamer-launch.c
+++ b/tools/gstreamer-launch.c
#ifndef USE_GLIB2
gtk_main_quit ();
#endif
+ g_print ("iteration ended\n");
return FALSE;
}
return TRUE;