diff --git a/ChangeLog b/ChangeLog index d27e8a6fe6..f5f8801b24 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,23 @@ +2003-12-16 Thomas Vander Stichele + + * gst/gst.c: + * gst/gstplugin.c: + rename --enable-segfault to --disable-segtrap + +2003-12-15 Thomas Vander Stichele + + * gst/gst.c: (init_popt_callback): + * gst/gstplugin.c: (_gst_plugin_fault_handler_restore), + (_gst_plugin_fault_handler_sighandler), + (_gst_plugin_fault_handler_setup), (gst_plugin_load_file): + Implemented fault handlers for catching SIGSEGV while loading + plug-ins + +2003-12-02 Thomas Vander Stichele + + * fix documentation build using docbook2..., works on fc1 and rh9 + * fix distcheck on fc1 + 2003-11-14 Thomas Vander Stichele * put GST_CACHE_DIR in config.h, as ordered by iain diff --git a/Makefile.am b/Makefile.am index c6d6c5e0f9..c3c43e53d6 100644 --- a/Makefile.am +++ b/Makefile.am @@ -24,6 +24,8 @@ all-local: gst-element-check-@GST_MAJORMINOR@.m4 gst-element-check-@GST_MAJORMINOR@.m4: gst-element-check.m4 cp $(srcdir)/gst-element-check.m4 gst-element-check-@GST_MAJORMINOR@.m4 +ACLOCAL_AMFLAGS = -I common/m4 + aclocaldir = $(datadir)/aclocal aclocal_DATA = gst-element-check-@GST_MAJORMINOR@.m4 diff --git a/configure.ac b/configure.ac index 8ac15132dd..16b21e271d 100644 --- a/configure.ac +++ b/configure.ac @@ -470,7 +470,6 @@ dnl ############################ dnl set license and copyright notice AC_DEFINE(GST_LICENSE, "LGPL", [GStreamer license]) -AC_DEFINE(GST_COPYRIGHT, "(c) 1999-2003 The GStreamer Team", [copyright message in plugins]) dnl package name in plugins AC_ARG_WITH(package-name, AC_HELP_STRING([--with-package-name],[specify package name to use in plugins]), @@ -479,7 +478,7 @@ AC_HELP_STRING([--with-package-name],[specify package name to use in plugins]), no) AC_MSG_ERROR(bad value ${withval} for --with-package-name) ;; *) GST_PACKAGE="${withval}" ;; esac], -[GST_PACKAGE="Gstreamer"]) dnl Default value +[GST_PACKAGE="GStreamer"]) dnl Default value AC_MSG_NOTICE(Using $GST_PACKAGE as package name) AC_DEFINE_UNQUOTED(GST_PACKAGE, "$GST_PACKAGE", [package name in plugins]) dnl package origin URL @@ -602,6 +601,7 @@ tests/seeking/Makefile tests/sched/Makefile tests/threadstate/Makefile testsuite/Makefile +testsuite/bins/Makefile testsuite/bytestream/Makefile testsuite/caps/Makefile testsuite/caps2/Makefile @@ -617,10 +617,8 @@ testsuite/refcounting/Makefile testsuite/tags/Makefile testsuite/threads/Makefile examples/Makefile -examples/autoplug/Makefile examples/cutter/Makefile examples/helloworld/Makefile -examples/helloworld2/Makefile examples/launch/Makefile examples/manual/Makefile examples/mixer/Makefile diff --git a/debian/control b/debian/control index 718ce22d8e..b856344e47 100644 --- a/debian/control +++ b/debian/control @@ -38,8 +38,8 @@ Recommends: libgstreamer-dev (= ${Source-Version}) Description: Core GStreamer documentation Core GStreamer documentation . - Gstreamer Manual - Gstreamer Plugin Writers Guide + GStreamer Manual + GStreamer Plugin Writers Guide Various API docs Package: gstreamer-tools diff --git a/debian/control.in b/debian/control.in index b92f24bf73..68a380ef69 100644 --- a/debian/control.in +++ b/debian/control.in @@ -38,8 +38,8 @@ Recommends: libgstreamer-dev (= ${Source-Version}) Description: Core GStreamer documentation Core GStreamer documentation . - Gstreamer Manual - Gstreamer Plugin Writers Guide + GStreamer Manual + GStreamer Plugin Writers Guide Various API docs Package: gstreamer-tools diff --git a/docs/faq/faq.xml b/docs/faq/faq.xml index 23bae58289..0fee3531a6 100644 --- a/docs/faq/faq.xml +++ b/docs/faq/faq.xml @@ -17,10 +17,9 @@ - ]> -
+
GStreamer FAQ diff --git a/docs/gst/Makefile.am b/docs/gst/Makefile.am index b631a84222..3fd49543b3 100644 --- a/docs/gst/Makefile.am +++ b/docs/gst/Makefile.am @@ -258,7 +258,7 @@ uninstall-local: echo '-- Uninstalling $(DESTDIR)$(TARGET_DIR)/index.sgml' ; \ rm -f $(DESTDIR)$(TARGET_DIR)/index.sgml; \ fi) - rmdir -p --ignore-fail-on-non-empty $(DESTDIR)$(TARGET_DIR) + if test -d $(DESTDIR)$(TARGET_DIR); then rmdir -p --ignore-fail-on-non-empty $(DESTDIR)$(TARGET_DIR); fi else install-data-local: uninstall-local: diff --git a/docs/gst/gstreamer-docs.sgml b/docs/gst/gstreamer-docs.sgml index 1344062b0f..6b667c5c39 100644 --- a/docs/gst/gstreamer-docs.sgml +++ b/docs/gst/gstreamer-docs.sgml @@ -83,7 +83,6 @@ well as the object hierarchy that defines elements and bins, along with some more specialized elements. &Gst; - &GstAutoplug; &GstBin; &GstBuffer; &GstConfig; diff --git a/docs/gst/tmpl/gst.sgml b/docs/gst/tmpl/gst.sgml index 0aa658138f..6a518c69e6 100644 --- a/docs/gst/tmpl/gst.sgml +++ b/docs/gst/tmpl/gst.sgml @@ -1,5 +1,5 @@ -Gstreamer +GStreamer Media library supporting arbitrary formats and filter graphs. @@ -112,14 +112,6 @@ pipeline and Microsoft's DirectShow for some background. @Returns: - - - - - -@Returns: - - diff --git a/docs/gst/tmpl/gstbuffer.sgml b/docs/gst/tmpl/gstbuffer.sgml index c9474ec5a5..38ced90965 100644 --- a/docs/gst/tmpl/gstbuffer.sgml +++ b/docs/gst/tmpl/gstbuffer.sgml @@ -265,6 +265,7 @@ The basic structure of a buffer. @offset_end: @pool: @pool_private: +@_gst_reserved: diff --git a/docs/gst/tmpl/gstbufferpool.sgml b/docs/gst/tmpl/gstbufferpool.sgml index 53a0ce99f5..197cf5e90e 100644 --- a/docs/gst/tmpl/gstbufferpool.sgml +++ b/docs/gst/tmpl/gstbufferpool.sgml @@ -92,6 +92,7 @@ The bufferpool structure @buffer_copy: @buffer_free: @user_data: +@_gst_reserved: diff --git a/docs/gst/tmpl/gstconfig.sgml b/docs/gst/tmpl/gstconfig.sgml index 99b80335de..650cc595a8 100644 --- a/docs/gst/tmpl/gstconfig.sgml +++ b/docs/gst/tmpl/gstconfig.sgml @@ -44,13 +44,6 @@ If a subsystem is disabled in GStreamer, a value is defined in - - - - - - - diff --git a/docs/gst/tmpl/gstdata.sgml b/docs/gst/tmpl/gstdata.sgml index 16aced475e..3705ec4c28 100644 --- a/docs/gst/tmpl/gstdata.sgml +++ b/docs/gst/tmpl/gstdata.sgml @@ -85,6 +85,7 @@ The base structure @flags: The flags of this GstData @free: A pointer to a custom free function @copy: A pointer to a custom copy function +@_gst_reserved: diff --git a/docs/gst/tmpl/gstelementfactory.sgml b/docs/gst/tmpl/gstelementfactory.sgml index 6e6cfe15c2..b9b83ff3f5 100644 --- a/docs/gst/tmpl/gstelementfactory.sgml +++ b/docs/gst/tmpl/gstelementfactory.sgml @@ -64,6 +64,7 @@ describes the element, mostly for the benefit of editors. @klass: @description: @author: +@_gst_reserved: diff --git a/docs/gst/tmpl/gstpad.sgml b/docs/gst/tmpl/gstpad.sgml index 49342f1b1b..82c34f49c7 100644 --- a/docs/gst/tmpl/gstpad.sgml +++ b/docs/gst/tmpl/gstpad.sgml @@ -785,8 +785,11 @@ Flags for the pad. -@padlist: +@pad: +@Varargs: @Returns: + +@padlist: @@ -794,9 +797,11 @@ Flags for the pad. +@padlist: +@Returns: + @pad: @Varargs: -@Returns: @@ -1090,6 +1095,7 @@ The realpad object @intlinkfunc: @bufferpoolfunc: @probedisp: +@_gst_reserved: diff --git a/docs/gst/tmpl/gstplugin.sgml b/docs/gst/tmpl/gstplugin.sgml index 30dc50fc7f..c418c8a990 100644 --- a/docs/gst/tmpl/gstplugin.sgml +++ b/docs/gst/tmpl/gstplugin.sgml @@ -69,6 +69,7 @@ The plugin object @numfeatures: @manager: @module: +@_gst_reserved: @@ -96,9 +97,9 @@ loaded will use this variable to initialize the plugin. @plugin_exit: @version: @license: -@copyright: @package: @origin: +@_gst_reserved: diff --git a/docs/gst/tmpl/gstreamer-unused.sgml b/docs/gst/tmpl/gstreamer-unused.sgml index ecad921fed..c40f9e3a8e 100644 --- a/docs/gst/tmpl/gstreamer-unused.sgml +++ b/docs/gst/tmpl/gstreamer-unused.sgml @@ -1992,6 +1992,12 @@ to the current function, i.e. "('element')" @format: printf-style format string @args...: printf arguments + + + + + + @@ -8950,6 +8956,13 @@ of an element he doesn't need anymore. @format: @args...: + + + + + +@Returns: + ======= diff --git a/docs/gst/tmpl/gstregistry.sgml b/docs/gst/tmpl/gstregistry.sgml index 4a600589eb..af8c1a1b6b 100644 --- a/docs/gst/tmpl/gstregistry.sgml +++ b/docs/gst/tmpl/gstregistry.sgml @@ -49,6 +49,7 @@ The registry object @loaded: @plugins: @paths: +@_gst_reserved: diff --git a/docs/htmlinstall.mak b/docs/htmlinstall.mak index 0d2d6ecff2..a3765fd175 100644 --- a/docs/htmlinstall.mak +++ b/docs/htmlinstall.mak @@ -4,12 +4,12 @@ if DOC_HTML install-data-local: html - mkdir -p $(docdir) - cp -pr $(HTML_DAT) $(docdir) + $(mkinstalldirs) $(DESTDIR)$(docdir) + cp -pr $(HTML_DAT) $(DESTDIR)$(docdir) uninstall-local: - for part in $(HTML_DAT); do rm -rf $(docdir)/$$part; done - rmdir $(docdir) + for part in $(HTML_DAT); do rm -rf $(DESTDIR)$(docdir)/$$part; done + if test -d $(DESTDIR)$(docdir); then rmdir $(DESTDIR)$(docdir); fi else install-data-local: uninstall-local: diff --git a/docs/libs/Makefile.am b/docs/libs/Makefile.am index e2101b6ef8..f3ef7f7355 100644 --- a/docs/libs/Makefile.am +++ b/docs/libs/Makefile.am @@ -257,7 +257,7 @@ uninstall-local: echo '-- Uninstalling $(DESTDIR)$(TARGET_DIR)/index.sgml' ; \ rm -f $(DESTDIR)$(TARGET_DIR)/index.sgml; \ fi) - rmdir -p --ignore-fail-on-non-empty $(DESTDIR)$(TARGET_DIR) + if test -d $(DESTDIR)$(TARGET_DIR); then rmdir -p --ignore-fail-on-non-empty $(DESTDIR)$(TARGET_DIR); fi else install-data-local: uninstall-local: diff --git a/docs/manuals.mak b/docs/manuals.mak index 5693a117da..dd272d1707 100644 --- a/docs/manuals.mak +++ b/docs/manuals.mak @@ -95,7 +95,7 @@ html/index.html: $(BUILDDIR)/$(MAIN) $(PNG_BUILT) $(FIG_SRC) @echo "*** Generating HTML output ***" @-mkdir -p html @cp -f $(srcdir)/../image-png $(BUILDDIR)/image.entities - @cd $(BUILDDIR) && xmlto html -o ../html $(MAIN) + @cd $(BUILDDIR) && docbook2html -o ../html -V '%use-id-as-filename%' $(MAIN) @test "x$(CSS)" != "x" && \ echo "Copying .css files: $(CSS)" && \ cp $(srcdir)/$(CSS) html @@ -165,8 +165,9 @@ $(BUILDIMAGESDIR)/%.ps: %.png @cat $< | pngtopnm | pnmtops -noturn > $@ 2> /dev/null # make sure xml validates properly -#check-local: -# xmllint -noout -valid $(srcdir)/$(MAIN) +check-local: $(BUILDDIR)/$(MAIN) + @cp -f $(srcdir)/../image-png $(BUILDDIR)/image.entities + cd $(BUILDDIR) && xmllint -noout -valid $(MAIN) ### this is a website upload target diff --git a/docs/pwg/building-boiler.xml b/docs/pwg/building-boiler.xml index 7347ab9d46..2e7e8c1ccf 100644 --- a/docs/pwg/building-boiler.xml +++ b/docs/pwg/building-boiler.xml @@ -14,8 +14,8 @@ - - Getting the Gstreamer Plugin Templates + + Getting the GStreamer Plugin Templates There are currently two ways to develop a new plugin for &GStreamer;: You can write the entire plugin by hand, or you can copy an existing plugin diff --git a/docs/pwg/pwg.xml b/docs/pwg/pwg.xml index c60f1d824c..be67573c6c 100644 --- a/docs/pwg/pwg.xml +++ b/docs/pwg/pwg.xml @@ -38,7 +38,7 @@ GStreamer Library Reference"> ]> - + &TITLEPAGE; diff --git a/examples/Makefile.am b/examples/Makefile.am index c7d650c31b..ed48293d69 100644 --- a/examples/Makefile.am +++ b/examples/Makefile.am @@ -4,7 +4,7 @@ else GST_LOADSAVE_DIRS = xml typefind endif -SUBDIRS = \ +dirs = \ helloworld \ queue \ queue2 \ @@ -17,22 +17,9 @@ SUBDIRS = \ cutter \ pingpong \ manual \ - retag \ - $(GST_LOADSAVE_DIRS) - -DIST_SUBDIRS = helloworld \ - queue \ - queue2 \ - queue3 \ - queue4 \ - launch \ - thread \ - plugins \ - mixer \ - cutter \ - pingpong \ - manual \ - xml \ - typefind \ retag +SUBDIRS = $(dirs) \ + $(GST_LOADSAVE_DIRS) + +DIST_SUBDIRS = $(dirs) xml typefind diff --git a/examples/autoplug/.gitignore b/examples/autoplug/.gitignore deleted file mode 100644 index f76c31a123..0000000000 --- a/examples/autoplug/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -autoplug -xmlTest.gst diff --git a/examples/autoplug/Makefile.am b/examples/autoplug/Makefile.am deleted file mode 100644 index efba8b2c41..0000000000 --- a/examples/autoplug/Makefile.am +++ /dev/null @@ -1,4 +0,0 @@ -noinst_PROGRAMS = autoplug - -autoplug_LDADD = $(GST_LIBS) -autoplug_CFLAGS = $(GST_CFLAGS) diff --git a/examples/autoplug/autoplug.c b/examples/autoplug/autoplug.c deleted file mode 100644 index dc9296d986..0000000000 --- a/examples/autoplug/autoplug.c +++ /dev/null @@ -1,152 +0,0 @@ -#include - -static void -gst_play_have_type (GstElement *typefind, GstCaps *caps, GstElement *pipeline) -{ - GstElement *osssink, *videosink, *videoelement, *colorspace; - GstElement *new_element; - GstAutoplug *autoplug; - GstElement *autobin; - GstElement *filesrc; - GstElement *cache; - - GST_DEBUG ("GstPipeline: play have type"); - - gst_element_set_state (pipeline, GST_STATE_PAUSED); - - filesrc = gst_bin_get_by_name (GST_BIN (pipeline), "disk_source"); - autobin = gst_bin_get_by_name (GST_BIN (pipeline), "autobin"); - cache = gst_bin_get_by_name (GST_BIN (autobin), "cache"); - - /* unlink the typefind from the pipeline and remove it */ - gst_element_unlink_pads (cache, "src", typefind, "sink"); - gst_bin_remove (GST_BIN (autobin), typefind); - - /* and an audio sink */ - osssink = gst_element_factory_make ("osssink", "play_audio"); - g_assert (osssink != NULL); - - videosink = gst_bin_new ("videosink"); - /* and an video sink */ - videoelement = gst_element_factory_make ("xvideosink", "play_video"); - g_assert (videosink != NULL); - - colorspace = gst_element_factory_make ("colorspace", "colorspace"); - g_assert (colorspace != NULL); - - gst_element_link_pads (colorspace, "src", videoelement, "sink"); - gst_bin_add (GST_BIN (videosink), colorspace); - gst_bin_add (GST_BIN (videosink), videoelement); - - gst_element_add_ghost_pad (videosink, - gst_element_get_pad (colorspace, "sink"), "sink"); - - autoplug = gst_autoplug_factory_make ("staticrender"); - g_assert (autoplug != NULL); - - new_element = gst_autoplug_to_renderers (autoplug, - caps, - videosink, - osssink, - NULL); - - if (!new_element) { - g_print ("could not autoplug, no suitable codecs found...\n"); - exit (-1); - } - - gst_element_set_name (new_element, "new_element"); - - gst_bin_add (GST_BIN (autobin), new_element); - - g_object_set (G_OBJECT (cache), "reset", TRUE, NULL); - - gst_element_link_pads (cache, "src", new_element, "sink"); - - gst_element_set_state (pipeline, GST_STATE_PLAYING); - -#ifndef GST_DISABLE_LOADSAVE - gst_xml_write_file (GST_ELEMENT (pipeline), fopen ("xmlTest.gst", "w")); -#endif -} - -static void -gst_play_cache_empty (GstElement *element, GstElement *pipeline) -{ - GstElement *autobin; - GstElement *filesrc; - GstElement *cache; - GstElement *new_element; - - fprintf (stderr, "have cache empty\n"); - - gst_element_set_state (pipeline, GST_STATE_PAUSED); - - filesrc = gst_bin_get_by_name (GST_BIN (pipeline), "disk_source"); - autobin = gst_bin_get_by_name (GST_BIN (pipeline), "autobin"); - cache = gst_bin_get_by_name (GST_BIN (autobin), "cache"); - new_element = gst_bin_get_by_name (GST_BIN (autobin), "new_element"); - - gst_element_unlink_many (filesrc, cache, new_element, NULL); - gst_bin_remove (GST_BIN (autobin), cache); - gst_element_link_pads (filesrc, "src", new_element, "sink"); - - gst_element_set_state (pipeline, GST_STATE_PLAYING); - - fprintf (stderr, "done with cache_empty\n"); -} - -int main(int argc,char *argv[]) -{ - GstElement *filesrc; - GstElement *pipeline; - GstElement *autobin; - GstElement *typefind; - GstElement *cache; - - g_thread_init(NULL); - gst_init(&argc,&argv); - - if (argc != 2) { - g_print("usage: %s \n", argv[0]); - exit(-1); - } - - /* create a new pipeline to hold the elements */ - pipeline = gst_pipeline_new("pipeline"); - g_assert(pipeline != NULL); - - /* create a disk reader */ - filesrc = gst_element_factory_make("filesrc", "disk_source"); - g_assert(filesrc != NULL); - g_object_set(G_OBJECT(filesrc),"location", argv[1],NULL); - gst_bin_add (GST_BIN (pipeline), filesrc); - - autobin = gst_bin_new ("autobin"); - cache = gst_element_factory_make ("autoplugcache", "cache"); - g_signal_connect (G_OBJECT (cache), "cache_empty", G_CALLBACK (gst_play_cache_empty), pipeline); - - typefind = gst_element_factory_make ("typefind", "typefind"); - g_signal_connect (G_OBJECT (typefind), "have_type", G_CALLBACK (gst_play_have_type), pipeline); - gst_bin_add (GST_BIN (autobin), cache); - gst_bin_add (GST_BIN (autobin), typefind); - - gst_element_link_pads (cache, "src", typefind, "sink"); - gst_element_add_ghost_pad (autobin, gst_element_get_pad (cache, "sink"), "sink"); - - gst_bin_add (GST_BIN( pipeline), autobin); - gst_element_link_pads (filesrc, "src", autobin, "sink"); - - /* start playing */ - gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_PLAYING); - - while (gst_bin_iterate (GST_BIN (pipeline))); - - /* stop the pipeline */ - gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_NULL); - - gst_object_unref (GST_OBJECT (pipeline)); - - exit(0); -} - diff --git a/examples/plugins/example.c b/examples/plugins/example.c index ec1ee1c158..ad47dcdc9a 100644 --- a/examples/plugins/example.c +++ b/examples/plugins/example.c @@ -422,11 +422,6 @@ GST_PLUGIN_DEFINE ( "0.1", /* The version number of the plugin */ "LGPL", /* ieffective license the plugin can be shipped with. Must be * valid for all libraries it links to, too. */ - "(c) 2003 E. Xamplewriter", - /* Copyright holder for this plugin. This does not include - * the libraries it links to, contrary to the license. This - * field should be considered informational and not legally - * binding */ "my nifty plugin package", /* package this plugin belongs to. */ "http://www.mydomain.com" diff --git a/gst/autoplug/Makefile.am b/gst/autoplug/Makefile.am index 5d65e44036..118ef8c3a1 100644 --- a/gst/autoplug/Makefile.am +++ b/gst/autoplug/Makefile.am @@ -10,7 +10,7 @@ libgstspider_la_CFLAGS = $(GST_CFLAGS) libgstspider_la_LIBADD = libgstspider_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) -noinst_HEADERS = gstspider.h gstsearchfuncs.h +noinst_HEADERS = gstspider.h gstspideridentity.h gstsearchfuncs.h noinst_PROGRAMS = spidertest diff --git a/gst/autoplug/gstspider.c b/gst/autoplug/gstspider.c index e6dac4ed84..458a8d18c3 100644 --- a/gst/autoplug/gstspider.c +++ b/gst/autoplug/gstspider.c @@ -593,6 +593,15 @@ gst_spider_plug_from_srcpad (GstSpiderConnection *conn, GstPad *srcpad) GST_DEBUG ("trying to plug from %s:%s to %s", GST_DEBUG_PAD_NAME (srcpad), GST_ELEMENT_NAME (conn->src)); + /* see if they match already */ + if (gst_pad_link (srcpad, conn->src->sink)) { + GST_DEBUG ("%s:%s and %s:%s can link directly", + GST_DEBUG_PAD_NAME (srcpad), GST_DEBUG_PAD_NAME (conn->src->sink)); + gst_pad_unlink (srcpad, conn->src->sink); + gst_spider_create_and_plug (conn, NULL); + return GST_PAD_LINK_OK; + } + /* find a path from src to sink */ plugpath = gst_autoplug_sp (gst_pad_get_caps (srcpad), gst_pad_get_caps (conn->src->sink), spider->factories); @@ -664,7 +673,6 @@ GST_PLUGIN_DEFINE ( plugin_init, VERSION, GST_LICENSE, - GST_COPYRIGHT, GST_PACKAGE, GST_ORIGIN ) diff --git a/gst/elements/gstaggregator.c b/gst/elements/gstaggregator.c index b15eaffd2f..2c30e62c66 100644 --- a/gst/elements/gstaggregator.c +++ b/gst/elements/gstaggregator.c @@ -335,7 +335,7 @@ gst_aggregator_loop (GstElement *element) debug = "loop_select"; - pad = gst_pad_select (aggregator->sinkpads); + pad = gst_pad_selectv (aggregator->sinkpads); buf = GST_BUFFER (gst_pad_pull (pad)); gst_aggregator_push (aggregator, pad, buf, debug); diff --git a/gst/elements/gstelements.c b/gst/elements/gstelements.c index 909b88392c..3b30483535 100644 --- a/gst/elements/gstelements.c +++ b/gst/elements/gstelements.c @@ -95,7 +95,6 @@ GST_PLUGIN_DEFINE ( plugin_init, VERSION, GST_LICENSE, - GST_COPYRIGHT, GST_PACKAGE, GST_ORIGIN ) diff --git a/gst/elements/gsttee.c b/gst/elements/gsttee.c index 533a907281..c5d03cb21a 100644 --- a/gst/elements/gsttee.c +++ b/gst/elements/gsttee.c @@ -195,7 +195,7 @@ gst_tee_getcaps (GstPad *pad) pads = gst_element_get_pad_list (GST_ELEMENT (tee)); while (pads) { - GstPad *srcpad = GST_PAD_CAST (pads->data); + GstPad *srcpad = GST_PAD (pads->data); GstPad *peer; const GstCaps2 *peercaps; GstCaps2 *newcaps; diff --git a/gst/elements/gsttypefind.c b/gst/elements/gsttypefind.c index 066ecf19dd..565758d09c 100644 --- a/gst/elements/gsttypefind.c +++ b/gst/elements/gsttypefind.c @@ -367,16 +367,17 @@ stop_typefinding (GstTypeFindElement *typefind) if (push_cached_buffers) { GstBuffer *buffer; guint size = gst_buffer_store_get_size (typefind->store, 0); - if (size && (buffer = gst_buffer_store_get_buffer (typefind->store, 0, size))) { - gst_pad_push (typefind->src, GST_DATA (buffer)); - } else { - size = 0; - } + GST_LOG_OBJECT (typefind, "seeking back to current position %u", size); if (!gst_pad_send_event (GST_PAD_PEER (typefind->sink), gst_event_new_seek (GST_SEEK_METHOD_SET | GST_FORMAT_BYTES, size))) { GST_WARNING_OBJECT (typefind, "could not seek to required position %u, hope for the best", size); } + if (size && (buffer = gst_buffer_store_get_buffer (typefind->store, 0, size))) { + gst_pad_push (typefind->src, GST_DATA (buffer)); + } else { + size = 0; + } } gst_buffer_store_clear (typefind->store); } diff --git a/gst/elements/gsttypefindelement.c b/gst/elements/gsttypefindelement.c index 066ecf19dd..565758d09c 100644 --- a/gst/elements/gsttypefindelement.c +++ b/gst/elements/gsttypefindelement.c @@ -367,16 +367,17 @@ stop_typefinding (GstTypeFindElement *typefind) if (push_cached_buffers) { GstBuffer *buffer; guint size = gst_buffer_store_get_size (typefind->store, 0); - if (size && (buffer = gst_buffer_store_get_buffer (typefind->store, 0, size))) { - gst_pad_push (typefind->src, GST_DATA (buffer)); - } else { - size = 0; - } + GST_LOG_OBJECT (typefind, "seeking back to current position %u", size); if (!gst_pad_send_event (GST_PAD_PEER (typefind->sink), gst_event_new_seek (GST_SEEK_METHOD_SET | GST_FORMAT_BYTES, size))) { GST_WARNING_OBJECT (typefind, "could not seek to required position %u, hope for the best", size); } + if (size && (buffer = gst_buffer_store_get_buffer (typefind->store, 0, size))) { + gst_pad_push (typefind->src, GST_DATA (buffer)); + } else { + size = 0; + } } gst_buffer_store_clear (typefind->store); } diff --git a/gst/gst.c b/gst/gst.c index a5dff6b697..834edead60 100644 --- a/gst/gst.c +++ b/gst/gst.c @@ -55,6 +55,9 @@ static gboolean gst_initialized = FALSE; static gboolean _gst_initialization_failure = FALSE; extern gint _gst_trace_on; +/* set to TRUE when segfaults need to be left as is */ +gboolean _gst_disable_segtrap = FALSE; + extern GThreadFunctions gst_thread_dummy_functions; @@ -96,6 +99,7 @@ enum { ARG_PLUGIN_SPEW, ARG_PLUGIN_PATH, ARG_PLUGIN_LOAD, + ARG_SEGTRAP_DISABLE, ARG_SCHEDULER, ARG_REGISTRY }; @@ -122,6 +126,7 @@ static const struct poptOption gstreamer_options[] = { {"gst-plugin-spew", NUL, POPT_ARG_NONE|POPT_ARGFLAG_STRIP, NULL, ARG_PLUGIN_SPEW, N_("enable verbose plugin loading diagnostics"), NULL}, {"gst-plugin-path", NUL, POPT_ARG_STRING|POPT_ARGFLAG_STRIP, NULL, ARG_PLUGIN_PATH, N_("'" G_SEARCHPATH_SEPARATOR_S "'--separated path list for loading plugins"), "PATHS"}, {"gst-plugin-load", NUL, POPT_ARG_STRING|POPT_ARGFLAG_STRIP, NULL, ARG_PLUGIN_LOAD, N_("comma-separated list of plugins to preload in addition to the list stored in env variable GST_PLUGIN_PATH"), "PLUGINS"}, + {"gst-disable-segtrap",NUL, POPT_ARG_NONE|POPT_ARGFLAG_STRIP, NULL, ARG_SEGTRAP_DISABLE,N_("disable trapping of segmentation faults during plugin loading"), NULL}, {"gst-scheduler", NUL, POPT_ARG_STRING|POPT_ARGFLAG_STRIP, NULL, ARG_SCHEDULER, N_("scheduler to use ('"GST_SCHEDULER_DEFAULT_NAME"' is the default)"), "SCHEDULER"}, {"gst-registry", NUL, POPT_ARG_STRING|POPT_ARGFLAG_STRIP, NULL, ARG_REGISTRY, N_("registry to use") , "REGISTRY"}, POPT_TABLEEND @@ -467,11 +472,10 @@ static GstPluginDesc plugin_desc = { NULL, VERSION, GST_LICENSE, - GST_COPYRIGHT, GST_PACKAGE, GST_ORIGIN, - GST_STRUCT_PADDING_INIT + GST_PADDING_INIT }; /* @@ -700,6 +704,9 @@ init_popt_callback (poptContext context, enum poptCallbackReason reason, case ARG_PLUGIN_LOAD: split_and_iterate (arg, ",", prepare_for_load_plugin_func, NULL); break; + case ARG_SEGTRAP_DISABLE: + _gst_disable_segtrap = TRUE; + break; case ARG_SCHEDULER: gst_scheduler_factory_set_default_name (arg); break; diff --git a/gst/gstbin.c b/gst/gstbin.c index bec55ec430..6ae0242cea 100644 --- a/gst/gstbin.c +++ b/gst/gstbin.c @@ -891,6 +891,77 @@ gst_bin_get_list (GstBin * bin) return bin->children; } +/** + * gst_bin_get_by_interface: + * @bin: bin to find element in + * @interface: interface to be implemented by interface + * + * Looks for the first element inside the bin that implements the given + * interface. If such an element is found, it returns the element. You can + * cast this element to the given interface afterwards. + * If you want all elements that implement the interface, use + * gst_bin_get_all_by_interface(). The function recurses bins inside bins. + * + * Returns: An element inside the bin implementing the interface. + */ +GstElement * +gst_bin_get_by_interface (GstBin *bin, const GType interface) +{ + GList *walk; + + g_return_val_if_fail (GST_IS_BIN (bin), NULL); + g_return_val_if_fail (G_TYPE_IS_INTERFACE (interface), NULL); + + walk = bin->children; + while (walk) { + if (G_TYPE_CHECK_INSTANCE_TYPE (walk->data, interface)) + return GST_ELEMENT (walk->data); + if (GST_IS_BIN (walk->data)) { + GstElement *ret; + ret = gst_bin_get_by_interface (GST_BIN (walk->data), interface); + if (ret) + return ret; + } + walk = g_list_next (walk); + } + + return NULL; +} + +/** + * gst_bin_get_all_by_interface: + * @bin: bin to find elements in + * @interface: interface to be implemented by interface + * + * Looks for all element inside the bin that implements the given + * interface. You can safely cast all returned elements to the given interface. + * The function recurses bins inside bins. You need to free the list using + * g_list_free() after use. + * + * Returns: An element inside the bin implementing the interface. + */ +GList * +gst_bin_get_all_by_interface (GstBin *bin, const GType interface) +{ + GList *walk, *ret = NULL; + + g_return_val_if_fail (GST_IS_BIN (bin), NULL); + g_return_val_if_fail (G_TYPE_IS_INTERFACE (interface), NULL); + + walk = bin->children; + while (walk) { + if (G_TYPE_CHECK_INSTANCE_TYPE (walk->data, interface)) + ret = g_list_prepend (ret, walk->data); + if (GST_IS_BIN (walk->data)) { + ret = g_list_concat (ret, + gst_bin_get_all_by_interface (GST_BIN (walk->data), interface)); + } + walk = g_list_next (walk); + } + + return ret; +} + /** * gst_bin_sync_children_state: * @bin: #Gstbin to sync state diff --git a/gst/gstbin.h b/gst/gstbin.h index 92af83b4ee..2e08b75985 100644 --- a/gst/gstbin.h +++ b/gst/gstbin.h @@ -34,17 +34,8 @@ extern GType _gst_bin_type; #define GST_IS_BIN(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_BIN)) #define GST_IS_BIN_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_BIN)) #define GST_BIN_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_BIN, GstBinClass)) - -#define GST_BIN_CAST(obj) ((GstBin*)(obj)) -#define GST_BIN_CLASS_CAST(klass) ((GstBinClass*)(klass)) - -#ifdef GST_TYPE_PARANOID -# define GST_BIN(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_BIN, GstBin)) -# define GST_BIN_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_BIN, GstBinClass)) -#else -# define GST_BIN GST_BIN_CAST -# define GST_BIN_CLASS GST_BIN_CLASS_CAST -#endif +#define GST_BIN(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_BIN, GstBin)) +#define GST_BIN_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_BIN, GstBinClass)) typedef void (*GstBinPrePostIterateFunction) (GstBin *bin, gpointer user_data); @@ -76,7 +67,7 @@ struct _GstBin { GstElementState child_states[GST_NUM_STATES]; - GST_OBJECT_PADDING + gpointer _gst_reserved[GST_PADDING]; }; struct _GstBinClass { @@ -95,7 +86,7 @@ struct _GstBinClass { void (*element_added) (GstBin *bin, GstElement *child); void (*element_removed) (GstBin *bin, GstElement *child); - GST_CLASS_PADDING + gpointer _gst_reserved[GST_PADDING]; }; GType gst_bin_get_type (void); @@ -112,6 +103,8 @@ GstElement* gst_bin_get_by_name (GstBin *bin, const gchar *name); GstElement* gst_bin_get_by_name_recurse_up (GstBin *bin, const gchar *name); G_CONST_RETURN GList* gst_bin_get_list (GstBin *bin); +GstElement* gst_bin_get_by_interface (GstBin *bin, const GType interface); +GList * gst_bin_get_all_by_interface (GstBin *bin, const GType interface); gboolean gst_bin_iterate (GstBin *bin); diff --git a/gst/gstbuffer.h b/gst/gstbuffer.h index ab7fe7a6d5..3840b82218 100644 --- a/gst/gstbuffer.h +++ b/gst/gstbuffer.h @@ -114,7 +114,7 @@ struct _GstBuffer { /* pointer to pool private data of parent buffer in case of a subbuffer */ gpointer pool_private; - GST_STRUCT_PADDING + gpointer _gst_reserved[GST_PADDING]; }; /* bufferpools */ @@ -139,7 +139,7 @@ struct _GstBufferPool { gpointer user_data; - GST_STRUCT_PADDING + gpointer _gst_reserved[GST_PADDING]; }; /* allocation */ diff --git a/gst/gstcaps2.c b/gst/gstcaps2.c index 3c4ec71ead..be1e4cfc3e 100644 --- a/gst/gstcaps2.c +++ b/gst/gstcaps2.c @@ -213,7 +213,7 @@ void gst_caps2_append (GstCaps2 *caps1, GstCaps2 *caps2) } g_ptr_array_free(caps2->structs, TRUE); #ifdef USE_POISONING - memset (caps, 0xff, sizeof(GstCaps2)); + memset (caps2, 0xff, sizeof(GstCaps2)); #endif g_free(caps2); } diff --git a/gst/gstclock.c b/gst/gstclock.c index 20b6daf194..180c7526d3 100644 --- a/gst/gstclock.c +++ b/gst/gstclock.c @@ -600,6 +600,7 @@ gboolean gst_clock_handle_discont (GstClock *clock, guint64 time) { GstClockTime itime = G_GINT64_CONSTANT (0); + GstClockClass *cclass = GST_CLOCK_GET_CLASS (clock);; GST_CAT_DEBUG (GST_CAT_CLOCK, "clock discont %" G_GUINT64_FORMAT " %" G_GUINT64_FORMAT " %d", @@ -609,21 +610,8 @@ gst_clock_handle_discont (GstClock *clock, guint64 time) return TRUE; GST_LOCK (clock); - if (clock->accept_discont) { - GstClockClass *cclass; - - cclass = GST_CLOCK_GET_CLASS (clock); - - if (cclass->get_internal_time) { - itime = cclass->get_internal_time (clock); - } - } - else { - GST_UNLOCK (clock); - GST_CAT_DEBUG (GST_CAT_CLOCK, "clock discont refused %" G_GUINT64_FORMAT - " %" G_GUINT64_FORMAT, - time, clock->start_time); - return FALSE; + if (cclass->get_internal_time) { + itime = cclass->get_internal_time (clock); } clock->start_time = itime - time; diff --git a/gst/gstclock.h b/gst/gstclock.h index 1e17ceb539..37d7e2871f 100644 --- a/gst/gstclock.h +++ b/gst/gstclock.h @@ -137,7 +137,7 @@ struct _GstClock { GCond *active_cond; gboolean stats; - GST_OBJECT_PADDING + gpointer _gst_reserved[GST_PADDING]; }; struct _GstClockClass { @@ -159,7 +159,7 @@ struct _GstClockClass { void (*unschedule) (GstClock *clock, GstClockEntry *entry); void (*unlock) (GstClock *clock, GstClockEntry *entry); - GST_CLASS_PADDING + gpointer _gst_reserved[GST_PADDING]; }; GType gst_clock_get_type (void); diff --git a/gst/gstdata.h b/gst/gstdata.h index c329ec92ae..14d4b75a5d 100644 --- a/gst/gstdata.h +++ b/gst/gstdata.h @@ -75,7 +75,7 @@ struct _GstData { GstDataFreeFunction free; /* free the data */ GstDataCopyFunction copy; /* copy the data */ - GST_STRUCT_PADDING + gpointer _gst_reserved[GST_PADDING]; }; /* function used by subclasses only */ diff --git a/gst/gstelement.c b/gst/gstelement.c index 1821a481fd..f15efc8943 100644 --- a/gst/gstelement.c +++ b/gst/gstelement.c @@ -1867,7 +1867,7 @@ gst_element_unlink (GstElement *src, GstElement *dest) srcpads = gst_element_get_pad_list (src); while (srcpads) { - pad = GST_PAD_CAST (srcpads->data); + pad = GST_PAD (srcpads->data); /* we only care about real src pads */ if (GST_IS_REAL_PAD (pad) && GST_PAD_IS_SRC (pad)) { @@ -1909,7 +1909,7 @@ gst_element_get_random_pad (GstElement *element, GstPadDirection dir) GList *pads = element->pads; GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "getting a random pad"); while (pads) { - GstPad *pad = GST_PAD_CAST (pads->data); + GstPad *pad = GST_PAD (pads->data); GST_CAT_DEBUG (GST_CAT_ELEMENT_PADS, "checking pad %s:%s", GST_DEBUG_PAD_NAME (pad)); @@ -2522,7 +2522,7 @@ gst_element_pads_activate (GstElement *element, gboolean active) GList *pads = element->pads; while (pads) { - GstPad *pad = GST_PAD_CAST (pads->data); + GstPad *pad = GST_PAD (pads->data); pads = g_list_next (pads); if (!GST_IS_REAL_PAD (pad)) @@ -3228,10 +3228,10 @@ gst_element_get_managing_bin (GstElement *element) g_return_val_if_fail (element != NULL, NULL); - bin = GST_BIN (gst_object_get_parent (GST_OBJECT_CAST (element))); + bin = GST_BIN (gst_object_get_parent (GST_OBJECT (element))); - while (bin && !GST_FLAG_IS_SET (GST_OBJECT_CAST (bin), GST_BIN_FLAG_MANAGER)) - bin = GST_BIN (gst_object_get_parent (GST_OBJECT_CAST (bin))); + while (bin && !GST_FLAG_IS_SET (GST_OBJECT (bin), GST_BIN_FLAG_MANAGER)) + bin = GST_BIN (gst_object_get_parent (GST_OBJECT (bin))); return bin; } diff --git a/gst/gstelement.h b/gst/gstelement.h index e290fab0d1..a0019917d8 100644 --- a/gst/gstelement.h +++ b/gst/gstelement.h @@ -45,10 +45,10 @@ struct _GstElementDetails { gchar *description; /* insights of one form or another */ gchar *author; /* who wrote this thing? */ - GST_STRUCT_PADDING + gpointer _gst_reserved[GST_PADDING]; }; #define GST_ELEMENT_DETAILS(longname,klass,description,author) \ - { longname, klass, description, author, GST_STRUCT_PADDING_INIT } + { longname, klass, description, author, GST_PADDING_INIT } #define GST_IS_ELEMENT_DETAILS(details) ( \ (details) && ((details)->longname != NULL) && ((details)->klass != NULL) \ && ((details)->description != NULL) && ((details)->author != NULL)) @@ -73,20 +73,11 @@ struct _GstElementDetails { extern GType _gst_element_type; #define GST_TYPE_ELEMENT (_gst_element_type) - -#define GST_ELEMENT_CAST(obj) ((GstElement*)(obj)) -#define GST_ELEMENT_CLASS_CAST(klass) ((GstElementClass*)(klass)) #define GST_IS_ELEMENT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_ELEMENT)) #define GST_IS_ELEMENT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_ELEMENT)) #define GST_ELEMENT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_ELEMENT, GstElementClass)) - -#ifdef GST_TYPE_PARANOID -# define GST_ELEMENT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_ELEMENT, GstElement)) -# define GST_ELEMENT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_ELEMENT, GstElementClass)) -#else -# define GST_ELEMENT GST_ELEMENT_CAST -# define GST_ELEMENT_CLASS GST_ELEMENT_CLASS_CAST -#endif +#define GST_ELEMENT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_ELEMENT, GstElement)) +#define GST_ELEMENT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_ELEMENT, GstElementClass)) /* convenience functions */ #ifdef G_HAVE_ISO_VARARGS @@ -184,7 +175,7 @@ struct _GstElement { GAsyncQueue *prop_value_queue; GMutex *property_mutex; - GST_OBJECT_PADDING + gpointer _gst_reserved[GST_PADDING]; }; struct _GstElementClass { @@ -241,7 +232,7 @@ struct _GstElementClass { GstIndex* (*get_index) (GstElement *element); void (*set_index) (GstElement *element, GstIndex *index); - GST_CLASS_PADDING + gpointer _gst_reserved[GST_PADDING]; }; void gst_element_class_add_pad_template (GstElementClass *klass, GstPadTemplate *templ); @@ -408,13 +399,13 @@ struct _GstElementFactory { GList * interfaces; /* interfaces this element implements */ - GST_OBJECT_PADDING + gpointer _gst_reserved[GST_PADDING]; }; struct _GstElementFactoryClass { GstPluginFeatureClass parent_class; - GST_CLASS_PADDING + gpointer _gst_reserved[GST_PADDING]; }; GType gst_element_factory_get_type (void); @@ -431,8 +422,8 @@ G_CONST_RETURN gchar * gst_element_factory_get_klass (GstElementFactory *factor G_CONST_RETURN gchar * gst_element_factory_get_description (GstElementFactory *factory); G_CONST_RETURN gchar * gst_element_factory_get_version (GstElementFactory *factory); G_CONST_RETURN gchar * gst_element_factory_get_author (GstElementFactory *factory); -guint gst_element_factory_get_num_padtemplates (GstElementFactory *factory); -G_CONST_RETURN GList * gst_element_factory_get_padtemplates (GstElementFactory *factory); +guint gst_element_factory_get_num_pad_templates (GstElementFactory *factory); +G_CONST_RETURN GList * gst_element_factory_get_pad_templates (GstElementFactory *factory); guint gst_element_factory_get_uri_type (GstElementFactory *factory); gchar ** gst_element_factory_get_uri_protocols (GstElementFactory *factory); diff --git a/gst/gstevent.c b/gst/gstevent.c index ad63b78148..56e8a15edf 100644 --- a/gst/gstevent.c +++ b/gst/gstevent.c @@ -194,7 +194,7 @@ gst_event_new_seek (GstSeekType type, gint64 offset) } /** - * gst_event_new_discontinuousv: + * gst_event_new_discontinuous_valist: * @new_media: A flag indicating a new media type starts * @format1: The format of the discont value * @var_args: more discont values and formats @@ -207,7 +207,7 @@ gst_event_new_seek (GstSeekType type, gint64 offset) * Returns: A new discontinuous event. */ GstEvent* -gst_event_new_discontinuousv (gboolean new_media, GstFormat format1, va_list var_args) +gst_event_new_discontinuous_valist (gboolean new_media, GstFormat format1, va_list var_args) { GstEvent *event; gint count = 0; @@ -251,7 +251,7 @@ gst_event_new_discontinuous (gboolean new_media, GstFormat format1, ...) va_start (var_args, format1); - event = gst_event_new_discontinuousv (new_media, format1, var_args); + event = gst_event_new_discontinuous_valist (new_media, format1, var_args); va_end (var_args); diff --git a/gst/gstevent.h b/gst/gstevent.h index a060dc9dca..e6db59679d 100644 --- a/gst/gstevent.h +++ b/gst/gstevent.h @@ -186,7 +186,7 @@ struct _GstEvent { } structure; } event_data; - GST_STRUCT_PADDING + gpointer _gst_reserved[GST_PADDING]; }; void _gst_event_initialize (void); @@ -215,7 +215,7 @@ GstEvent* gst_event_new_size (GstFormat format, gint64 value); /* discontinous event */ GstEvent* gst_event_new_discontinuous (gboolean new_media, GstFormat format1, ...); -GstEvent* gst_event_new_discontinuousv (gboolean new_media, +GstEvent* gst_event_new_discontinuous_valist (gboolean new_media, GstFormat format1, va_list var_args); gboolean gst_event_discont_get_value (GstEvent *event, GstFormat format, gint64 *value); diff --git a/gst/gstindex.h b/gst/gstindex.h index fa6231b50b..80a71c038b 100644 --- a/gst/gstindex.h +++ b/gst/gstindex.h @@ -168,7 +168,7 @@ struct _GstIndex { GHashTable *writers; gint last_id; - GST_OBJECT_PADDING + gpointer _gst_reserved[GST_PADDING]; }; struct _GstIndexClass { @@ -189,7 +189,7 @@ struct _GstIndexClass { /* signals */ void (*entry_added) (GstIndex *index, GstIndexEntry *entry); - GST_CLASS_PADDING; + gpointer _gst_reserved[GST_PADDING]; }; GType gst_index_get_type (void); @@ -253,13 +253,13 @@ struct _GstIndexFactory { gchar *longdesc; /* long description of the index (well, don't overdo it..) */ GType type; /* unique GType of the index */ - GST_OBJECT_PADDING + gpointer _gst_reserved[GST_PADDING]; }; struct _GstIndexFactoryClass { GstPluginFeatureClass parent; - GST_CLASS_PADDING + gpointer _gst_reserved[GST_PADDING]; }; GType gst_index_factory_get_type (void); diff --git a/gst/gstinfo.h b/gst/gstinfo.h index 6a16c83a7f..bf2abca39b 100644 --- a/gst/gstinfo.h +++ b/gst/gstinfo.h @@ -353,7 +353,7 @@ extern gboolean __gst_debug_enabled; #endif /* G_HAVE_ISO_VARARGS */ #else /* GST_DEBUG_ENABLE_DEPRECATED */ -/* This is a workaround so the old debugging stuff of Gstreamer 0.6 works. +/* This is a workaround so the old debugging stuff of GStreamer 0.6 works. This is undocumented and will go when 0.8 comes out. */ #ifdef G_HAVE_ISO_VARARGS diff --git a/gst/gstinterface.c b/gst/gstinterface.c index fe099e9a7d..a6bb684c90 100644 --- a/gst/gstinterface.c +++ b/gst/gstinterface.c @@ -28,19 +28,21 @@ #include "gstinterface.h" #include "gstlog.h" -static void gst_interface_class_init (GstInterfaceClass *ifklass); -static gboolean gst_interface_supported_default (GstInterface *iface, - GType iface_type); +static void +gst_implements_interface_class_init (GstImplementsInterfaceClass *ifklass); +static gboolean +gst_implements_interface_supported_default (GstImplementsInterface *iface, + GType iface_type); GType -gst_interface_get_type (void) +gst_implements_interface_get_type (void) { static GType gst_interface_type = 0; if (!gst_interface_type) { static const GTypeInfo gst_interface_info = { - sizeof (GstInterfaceClass), - (GBaseInitFunc) gst_interface_class_init, + sizeof (GstImplementsInterfaceClass), + (GBaseInitFunc) gst_implements_interface_class_init, NULL, NULL, NULL, @@ -52,7 +54,7 @@ gst_interface_get_type (void) }; gst_interface_type = g_type_register_static (G_TYPE_INTERFACE, - "GstInterface", + "GstImplementsInterface", &gst_interface_info, 0); g_type_interface_add_prerequisite (gst_interface_type, @@ -63,14 +65,14 @@ gst_interface_get_type (void) } static void -gst_interface_class_init (GstInterfaceClass *klass) +gst_implements_interface_class_init (GstImplementsInterfaceClass *klass) { - klass->supported = gst_interface_supported_default; + klass->supported = gst_implements_interface_supported_default; } static gboolean -gst_interface_supported_default (GstInterface *interface, - GType iface_type) +gst_implements_interface_supported_default (GstImplementsInterface *interface, + GType iface_type) { /* Well, if someone didn't set the virtual function, * then something is clearly wrong. So big no-no here */ @@ -93,12 +95,12 @@ gst_element_implements_interface (GstElement *element, { if (G_TYPE_CHECK_INSTANCE_TYPE (G_OBJECT (element), iface_type)) { - GstInterface *iface; - GstInterfaceClass *ifclass; + GstImplementsInterface *iface; + GstImplementsInterfaceClass *ifclass; iface = G_TYPE_CHECK_INSTANCE_CAST (G_OBJECT (element), - iface_type, GstInterface); - ifclass = GST_INTERFACE_GET_CLASS (iface); + iface_type, GstImplementsInterface); + ifclass = GST_IMPLEMENTS_INTERFACE_GET_CLASS (iface); if (ifclass->supported != NULL && ifclass->supported (iface, iface_type) == TRUE) { @@ -110,7 +112,7 @@ gst_element_implements_interface (GstElement *element, } /** - * gst_interface_cast: + * gst_implements_interface_cast: * @from: the object (any sort) from which to cast to the interface * @type: the interface type to cast to * @@ -118,15 +120,15 @@ gst_element_implements_interface (GstElement *element, * interface is supported for this specific instance. */ -GstInterface * -gst_interface_cast (gpointer from, - GType iface_type) +gpointer +gst_implements_interface_cast (gpointer from, + GType iface_type) { - GstInterface *iface; + GstImplementsInterface *iface; /* check cast, give warning+fail if it's invalid */ if (!(iface = G_TYPE_CHECK_INSTANCE_CAST (from, iface_type, - GstInterface))) { + GstImplementsInterface))) { return NULL; } @@ -142,7 +144,7 @@ gst_interface_cast (gpointer from, } /** - * gst_interface_cast: + * gst_implements_interface_cast: * @from: the object (any sort) from which to check from for the interface * @type: the interface type to check for * @@ -151,17 +153,17 @@ gst_interface_cast (gpointer from, */ gboolean -gst_interface_check (gpointer from, - GType type) +gst_implements_interface_check (gpointer from, + GType type) { - GstInterface *iface; + GstImplementsInterface *iface; /* check cast, return FALSE if it fails, don't give a warning... */ if (!G_TYPE_CHECK_INSTANCE_TYPE (from, type)) { return FALSE; } - iface = G_TYPE_CHECK_INSTANCE_CAST (from, type, GstInterface); + iface = G_TYPE_CHECK_INSTANCE_CAST (from, type, GstImplementsInterface); /* now, if we're an element (or derivative), is this thing * actually implemented for real? */ diff --git a/gst/gstinterface.h b/gst/gstinterface.h index bd11637668..8cd5ba3b14 100644 --- a/gst/gstinterface.h +++ b/gst/gstinterface.h @@ -20,57 +20,60 @@ * Boston, MA 02111-1307, USA. */ -#ifndef __GST_INTERFACE_H__ -#define __GST_INTERFACE_H__ +#ifndef __GST_IMPLEMENTS_INTERFACE_H__ +#define __GST_IMPLEMENTS_INTERFACE_H__ #include G_BEGIN_DECLS -#define GST_TYPE_INTERFACE \ - (gst_interface_get_type ()) -#define GST_INTERFACE(obj) \ - (GST_INTERFACE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_INTERFACE, GstInterface)) -#define GST_INTERFACE_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_INTERFACE, GstInterfaceClass)) -#define GST_IS_INTERFACE(obj) \ - (GST_INTERFACE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_INTERFACE)) -#define GST_IS_INTERFACE_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_INTERFACE)) -#define GST_INTERFACE_GET_CLASS(inst) \ - (G_TYPE_INSTANCE_GET_INTERFACE ((inst), GST_TYPE_INTERFACE, GstInterfaceClass)) +#define GST_TYPE_IMPLEMENTS_INTERFACE \ + (gst_implements_interface_get_type ()) +#define GST_IMPLEMENTS_INTERFACE(obj) \ + (GST_INTERFACE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_IMPLEMENTS_INTERFACE, \ + GstImplementsInterface)) +#define GST_IMPLEMENTS_INTERFACE_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_IMPLEMENTS_INTERFACE, \ + GstImplementsInterfaceClass)) +#define GST_IS_IMPLEMENTS_INTERFACE(obj) \ + (GST_INTERFACE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_IMPLEMENTS_INTERFACE)) +#define GST_IS_IMPLEMENTS_INTERFACE_CLASS(klass) \ + (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_IMPLEMENTS_INTERFACE)) +#define GST_IMPLEMENTS_INTERFACE_GET_CLASS(inst) \ + (G_TYPE_INSTANCE_GET_INTERFACE ((inst), GST_TYPE_IMPLEMENTS_INTERFACE, \ + GstImplementsInterfaceClass)) -typedef struct _GstInterface GstInterface; +typedef struct _GstImplementsInterface GstImplementsInterface; /* This small extra virtual function is here to provide an * interface functionality on a per-instance basis rather * than a per-class basis, which is the case for glib. */ -typedef struct _GstInterfaceClass { +typedef struct _GstImplementsInterfaceClass { GTypeInterface parent; /* virtual functions */ - gboolean (* supported) (GstInterface *iface, - GType iface_type); + gboolean (* supported) (GstImplementsInterface *iface, + GType iface_type); - GST_CLASS_PADDING -} GstInterfaceClass; + gpointer _gst_reserved[GST_PADDING]; +} GstImplementsInterfaceClass; -#define GST_INTERFACE_CHECK_INSTANCE_CAST(obj, type, cast_t) \ - ((cast_t *) gst_interface_cast ((obj), (type))) -#define GST_INTERFACE_CHECK_INSTANCE_TYPE(obj, type) \ - (gst_interface_check ((obj), (type))) +#define GST_IMPLEMENTS_INTERFACE_CHECK_INSTANCE_CAST(obj, type, cast_t) \ + ((cast_t *) gst_implements_interface_cast ((obj), (type))) +#define GST_IMPLEMENTS_INTERFACE_CHECK_INSTANCE_TYPE(obj, type) \ + (gst_implements_interface_check ((obj), (type))) -GType gst_interface_get_type (void); +GType gst_implements_interface_get_type (void); /* wrapper functions to check for functionality implementation */ -gboolean gst_element_implements_interface(GstElement *element, - GType iface_type); -GstInterface * gst_interface_cast (gpointer from, - GType type); -gboolean gst_interface_check (gpointer from, - GType type); +gboolean gst_element_implements_interface (GstElement *element, + GType iface_type); +gpointer gst_implements_interface_cast (gpointer from, + GType type); +gboolean gst_implements_interface_check (gpointer from, + GType type); G_END_DECLS -#endif /* __GST_INTERFACE_H__ */ +#endif /* __GST_IMPLEMENTS_INTERFACE_H__ */ diff --git a/gst/gstobject.h b/gst/gstobject.h index 741d320e55..5f62d8bb47 100644 --- a/gst/gstobject.h +++ b/gst/gstobject.h @@ -35,21 +35,12 @@ G_BEGIN_DECLS extern GType _gst_object_type; -#define GST_TYPE_OBJECT (_gst_object_type) -#define GST_IS_OBJECT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_OBJECT)) -#define GST_IS_OBJECT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_OBJECT)) -#define GST_OBJECT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_OBJECT, GstObjectClass)) - -#define GST_OBJECT_CAST(obj) ((GstObject*)(obj)) -#define GST_OBJECT_CLASS_CAST(klass) ((GstObjectClass*)(klass)) - -#ifdef GST_TYPE_PARANOID -# define GST_OBJECT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_OBJECT, GstObject)) -# define GST_OBJECT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_OBJECT, GstObjectClass)) -#else -# define GST_OBJECT GST_OBJECT_CAST -# define GST_OBJECT_CLASS GST_OBJECT_CLASS_CAST -#endif +#define GST_TYPE_OBJECT (_gst_object_type) +#define GST_IS_OBJECT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_OBJECT)) +#define GST_IS_OBJECT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_OBJECT)) +#define GST_OBJECT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_OBJECT, GstObjectClass)) +#define GST_OBJECT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_OBJECT, GstObject)) +#define GST_OBJECT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_OBJECT, GstObjectClass)) /* make sure we don't change the object size but stil make it compile * without libxml */ @@ -77,7 +68,7 @@ struct _GstObject { guint32 flags; - GST_OBJECT_PADDING + gpointer _gst_reserved[GST_PADDING]; }; /* signal_object is used to signal to the whole class */ @@ -99,10 +90,10 @@ struct _GstObjectClass { xmlNodePtr (*save_thyself) (GstObject *object, xmlNodePtr parent); void (*restore_thyself) (GstObject *object, xmlNodePtr self); - GST_CLASS_PADDING + gpointer _gst_reserved[GST_PADDING]; }; -#define GST_FLAGS(obj) (GST_OBJECT_CAST (obj)->flags) +#define GST_FLAGS(obj) (GST_OBJECT (obj)->flags) #define GST_FLAG_IS_SET(obj,flag) (GST_FLAGS (obj) & (1<<(flag))) #define GST_FLAG_SET(obj,flag) G_STMT_START{ (GST_FLAGS (obj) |= (1<<(flag))); }G_STMT_END #define GST_FLAG_UNSET(obj,flag) G_STMT_START{ (GST_FLAGS (obj) &= ~(1<<(flag))); }G_STMT_END @@ -114,10 +105,10 @@ struct _GstObjectClass { #define GST_OBJECT_FLOATING(obj) (GST_FLAG_IS_SET (obj, GST_FLOATING)) /* CR1: object locking - GObject 2.0 doesn't have threadsafe locking */ -#define GST_LOCK(obj) (g_mutex_lock(GST_OBJECT_CAST(obj)->lock)) -#define GST_TRYLOCK(obj) (g_mutex_trylock(GST_OBJECT_CAST(obj)->lock)) -#define GST_UNLOCK(obj) (g_mutex_unlock(GST_OBJECT_CAST(obj)->lock)) -#define GST_GET_LOCK(obj) (GST_OBJECT_CAST(obj)->lock) +#define GST_LOCK(obj) (g_mutex_lock(GST_OBJECT(obj)->lock)) +#define GST_TRYLOCK(obj) (g_mutex_trylock(GST_OBJECT(obj)->lock)) +#define GST_UNLOCK(obj) (g_mutex_unlock(GST_OBJECT(obj)->lock)) +#define GST_GET_LOCK(obj) (GST_OBJECT(obj)->lock) /* normal GObject stuff */ diff --git a/gst/gstpad.c b/gst/gstpad.c index 6cac3d5712..df4b3fce7f 100644 --- a/gst/gstpad.c +++ b/gst/gstpad.c @@ -565,7 +565,7 @@ gst_pad_get_event_masks (GstPad *pad) g_return_val_if_fail (rpad, FALSE); if (GST_RPAD_EVENTMASKFUNC (rpad)) - return GST_RPAD_EVENTMASKFUNC (rpad) (GST_PAD_CAST (pad)); + return GST_RPAD_EVENTMASKFUNC (rpad) (GST_PAD (pad)); return NULL; } @@ -678,7 +678,7 @@ gst_pad_get_query_types (GstPad *pad) g_return_val_if_fail (rpad, FALSE); if (GST_RPAD_QUERYTYPEFUNC (rpad)) - return GST_RPAD_QUERYTYPEFUNC (rpad) (GST_PAD_CAST (pad)); + return GST_RPAD_QUERYTYPEFUNC (rpad) (GST_PAD (pad)); return NULL; } @@ -888,15 +888,15 @@ gst_pad_unlink (GstPad *srcpad, (GST_RPAD_DIRECTION (realsink) == GST_PAD_SINK)); if (GST_RPAD_UNLINKFUNC (realsrc)) { - GST_RPAD_UNLINKFUNC (realsrc) (GST_PAD_CAST (realsrc)); + GST_RPAD_UNLINKFUNC (realsrc) (GST_PAD (realsrc)); } if (GST_RPAD_UNLINKFUNC (realsink)) { - GST_RPAD_UNLINKFUNC (realsink) (GST_PAD_CAST (realsink)); + GST_RPAD_UNLINKFUNC (realsink) (GST_PAD (realsink)); } /* get the schedulers before we unlink */ - src_sched = gst_pad_get_scheduler (GST_PAD_CAST (realsrc)); - sink_sched = gst_pad_get_scheduler (GST_PAD_CAST (realsink)); + src_sched = gst_pad_get_scheduler (GST_PAD (realsrc)); + sink_sched = gst_pad_get_scheduler (GST_PAD (realsink)); /* first clear peers */ GST_RPAD_PEER (realsrc) = NULL; @@ -905,8 +905,8 @@ gst_pad_unlink (GstPad *srcpad, /* now tell the scheduler */ if (src_sched && src_sched == sink_sched) { gst_scheduler_pad_unlink (src_sched, - GST_PAD_CAST (realsrc), - GST_PAD_CAST (realsink)); + GST_PAD (realsrc), + GST_PAD (realsink)); } /* hold a reference, as they can go away in the signal handlers */ @@ -933,8 +933,8 @@ gst_pad_check_schedulers (GstRealPad *realsrc, GstRealPad *realsink) GstScheduler *src_sched, *sink_sched; gint num_decoupled = 0; - src_sched = gst_pad_get_scheduler (GST_PAD_CAST (realsrc)); - sink_sched = gst_pad_get_scheduler (GST_PAD_CAST (realsink)); + src_sched = gst_pad_get_scheduler (GST_PAD (realsrc)); + sink_sched = gst_pad_get_scheduler (GST_PAD (realsink)); if (src_sched && sink_sched) { if (GST_FLAG_IS_SET (GST_PAD_PARENT (realsrc), GST_ELEMENT_DECOUPLED)) @@ -1115,13 +1115,13 @@ gst_pad_link_filtered (GstPad *srcpad, GstPad *sinkpad, g_signal_emit (G_OBJECT (realsink), gst_real_pad_signals[REAL_LINKED], 0, realsrc); - src_sched = gst_pad_get_scheduler (GST_PAD_CAST (realsrc)); - sink_sched = gst_pad_get_scheduler (GST_PAD_CAST (realsink)); + src_sched = gst_pad_get_scheduler (GST_PAD (realsrc)); + sink_sched = gst_pad_get_scheduler (GST_PAD (realsink)); /* now tell the scheduler */ if (src_sched && src_sched == sink_sched) { gst_scheduler_pad_link (src_sched, - GST_PAD_CAST (realsrc), GST_PAD_CAST (realsink)); + GST_PAD (realsrc), GST_PAD (realsink)); } else { GST_CAT_INFO (GST_CAT_PADS, "not telling link to scheduler %s:%s and %s:%s, %p %p", @@ -1239,7 +1239,7 @@ gst_pad_get_scheduler (GstPad *pad) GstRealPad *peer = GST_RPAD_PEER (pad); if (peer) { - scheduler = gst_element_get_scheduler (gst_pad_get_parent (GST_PAD_CAST (peer))); + scheduler = gst_element_get_scheduler (gst_pad_get_parent (GST_PAD (peer))); } } else { @@ -1984,11 +1984,11 @@ gst_pad_get_caps (GstPad *pad) GstCaps2 *caps; GST_CAT_DEBUG (GST_CAT_CAPS, "using pad get function"); - caps = GST_RPAD_GETCAPSFUNC (realpad) (GST_PAD_CAST (realpad)); + caps = GST_RPAD_GETCAPSFUNC (realpad) (GST_PAD (realpad)); if (caps == NULL) { g_critical ("pad %s:%s returned NULL caps from getcaps function\n", - GST_ELEMENT_NAME(GST_PAD_PARENT(GST_PAD_CAST(realpad))), + GST_ELEMENT_NAME(GST_PAD_PARENT(GST_PAD (realpad))), GST_PAD_NAME(realpad)); caps = gst_caps2_new_any (); } @@ -2477,7 +2477,7 @@ gst_pad_push (GstPad *pad, GstData *data) if (!gst_probe_dispatcher_dispatch (&peer->probedisp, &data)) return; - (peer->chainhandler) (GST_PAD_CAST (peer), data); + (peer->chainhandler) (GST_PAD (peer), data); return; } else { @@ -2531,7 +2531,7 @@ restart: GST_DEBUG_FUNCPTR_NAME (peer->gethandler), GST_DEBUG_PAD_NAME (peer)); - data = (peer->gethandler) (GST_PAD_CAST (peer)); + data = (peer->gethandler) (GST_PAD (peer)); if (data) { if (!gst_probe_dispatcher_dispatch (&peer->probedisp, &data)) @@ -2555,7 +2555,7 @@ restart: } /** - * gst_pad_select: + * gst_pad_selectv: * @padlist: a #GList of pads. * * Waits for a buffer on any of the list of pads. @@ -2564,7 +2564,7 @@ restart: * Use #gst_pad_pull() to get the buffer. */ GstPad* -gst_pad_select (GList *padlist) +gst_pad_selectv (GList *padlist) { GstPad *pad; @@ -2574,7 +2574,7 @@ gst_pad_select (GList *padlist) } /** - * gst_pad_selectv: + * gst_pad_select: * @pad: a first #GstPad to perform the select on. * @...: A NULL-terminated list of more pads to select on. * @@ -2584,10 +2584,9 @@ gst_pad_select (GList *padlist) * Use #gst_pad_pull() to get the buffer. */ GstPad* -gst_pad_selectv (GstPad *pad, ...) +gst_pad_select (GstPad *pad, ...) { GstPad *result; - GList *padlist = NULL; va_list var_args; if (pad == NULL) @@ -2595,15 +2594,39 @@ gst_pad_selectv (GstPad *pad, ...) va_start (var_args, pad); + result = gst_pad_select_valist (pad, var_args); + + va_end (var_args); + + return result; +} + +/** + * gst_pad_select_valist: + * @pad: a first #GstPad to perform the select on. + * @varargs: A va_list of more pads to select on. + * + * Waits for a buffer on the given set of pads. + * + * Returns: the #GstPad that has a buffer available. + * Use #gst_pad_pull() to get the buffer. + */ +GstPad* +gst_pad_select_valist (GstPad *pad, va_list var_args) +{ + GstPad *result; + GList *padlist = NULL; + + if (pad == NULL) + return NULL; + while (pad) { padlist = g_list_prepend (padlist, pad); pad = va_arg (var_args, GstPad *); } - result = gst_pad_select (padlist); + result = gst_pad_selectv (padlist); g_list_free (padlist); - va_end (var_args); - return result; } @@ -2990,7 +3013,7 @@ gst_pad_get_internal_links (GstPad *pad) rpad = GST_PAD_REALIZE (pad); if (GST_RPAD_INTLINKFUNC (rpad)) - res = GST_RPAD_INTLINKFUNC (rpad) (GST_PAD_CAST (rpad)); + res = GST_RPAD_INTLINKFUNC (rpad) (GST_PAD (rpad)); return res; } @@ -3016,7 +3039,7 @@ gst_pad_event_default_dispatch (GstPad *pad, GstElement *element, gst_pad_push (eventpad, GST_DATA (event)); } else { - GstPad *peerpad = GST_PAD_CAST (GST_RPAD_PEER (eventpad)); + GstPad *peerpad = GST_PAD (GST_RPAD_PEER (eventpad)); /* we only send the event on one pad, multi-sinkpad elements * should implement a handler */ @@ -3101,7 +3124,7 @@ gst_pad_dispatcher (GstPad *pad, GstPadDispatcherFunction dispatch, GstRealPad *int_peer = GST_RPAD_PEER (int_rpad); if (int_peer) { - res = dispatch (GST_PAD_CAST (int_peer), data); + res = dispatch (GST_PAD (int_peer), data); if (res) break; } @@ -3140,7 +3163,7 @@ gst_pad_send_event (GstPad *pad, GstEvent *event) GST_EVENT_TYPE (event), GST_DEBUG_PAD_NAME (rpad)); if (GST_RPAD_EVENTHANDLER (rpad)) - success = GST_RPAD_EVENTHANDLER (rpad) (GST_PAD_CAST (rpad), event); + success = GST_RPAD_EVENTHANDLER (rpad) (GST_PAD (rpad), event); else { g_warning ("pad %s:%s has no event handler", GST_DEBUG_PAD_NAME (rpad)); gst_event_unref (event); @@ -3230,7 +3253,7 @@ gst_pad_convert (GstPad *pad, rpad = GST_PAD_REALIZE (pad); if (GST_RPAD_CONVERTFUNC (rpad)) { - return GST_RPAD_CONVERTFUNC (rpad) (GST_PAD_CAST (rpad), src_format, + return GST_RPAD_CONVERTFUNC (rpad) (GST_PAD (rpad), src_format, src_value, dest_format, dest_value); } @@ -3309,7 +3332,7 @@ gst_pad_query (GstPad *pad, GstQueryType type, g_return_val_if_fail (rpad, FALSE); if (GST_RPAD_QUERYFUNC (rpad)) - return GST_RPAD_QUERYFUNC (rpad) (GST_PAD_CAST (pad), type, format, value); + return GST_RPAD_QUERYFUNC (rpad) (GST_PAD (pad), type, format, value); return FALSE; } @@ -3359,7 +3382,7 @@ gst_pad_get_formats (GstPad *pad) rpad = GST_PAD_REALIZE (pad); if (GST_RPAD_FORMATSFUNC (rpad)) - return GST_RPAD_FORMATSFUNC (rpad) (GST_PAD_CAST (pad)); + return GST_RPAD_FORMATSFUNC (rpad) (GST_PAD (pad)); return NULL; } diff --git a/gst/gstpad.h b/gst/gstpad.h index c56f7d917c..7fb3cb85be 100644 --- a/gst/gstpad.h +++ b/gst/gstpad.h @@ -40,65 +40,36 @@ extern GType _gst_pad_type; extern GType _gst_real_pad_type; extern GType _gst_ghost_pad_type; -#define GST_TYPE_PARANOID - /* * Pad base class */ #define GST_TYPE_PAD (_gst_pad_type) - -#define GST_PAD_CAST(obj) ((GstPad*)(obj)) -#define GST_PAD_CLASS_CAST(klass) ((GstPadClass*)(klass)) #define GST_IS_PAD(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_PAD)) #define GST_IS_PAD_FAST(obj) (G_OBJECT_TYPE(obj) == GST_TYPE_REAL_PAD || \ G_OBJECT_TYPE(obj) == GST_TYPE_GHOST_PAD) #define GST_IS_PAD_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_PAD)) - -#ifdef GST_TYPE_PARANOID -# define GST_PAD(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_PAD, GstPad)) -# define GST_PAD_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_PAD, GstPadClass)) -#else -# define GST_PAD GST_PAD_CAST -# define GST_PAD_CLASS GST_PAD_CLASS_CAST -#endif +#define GST_PAD(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_PAD, GstPad)) +#define GST_PAD_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_PAD, GstPadClass)) /* * Real Pads */ #define GST_TYPE_REAL_PAD (_gst_real_pad_type) - -#define GST_REAL_PAD_CAST(obj) ((GstRealPad*)(obj)) -#define GST_REAL_PAD_CLASS_CAST(klass) ((GstRealPadClass*)(klass)) #define GST_IS_REAL_PAD(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_REAL_PAD)) #define GST_IS_REAL_PAD_FAST(obj) (G_OBJECT_TYPE(obj) == GST_TYPE_REAL_PAD) #define GST_IS_REAL_PAD_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_REAL_PAD)) - -#ifdef GST_TYPE_PARANOID -# define GST_REAL_PAD(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_REAL_PAD, GstRealPad)) -# define GST_REAL_PAD_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_REAL_PAD, GstRealPadClass)) -#else -# define GST_REAL_PAD GST_REAL_PAD_CAST -# define GST_REAL_PAD_CLASS GST_REAL_PAD_CLASS_CAST -#endif +#define GST_REAL_PAD(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_REAL_PAD, GstRealPad)) +#define GST_REAL_PAD_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_REAL_PAD, GstRealPadClass)) /* * Ghost Pads */ #define GST_TYPE_GHOST_PAD (_gst_ghost_pad_type) - -#define GST_GHOST_PAD_CAST(obj) ((GstGhostPad*)(obj)) -#define GST_GHOST_PAD_CLASS_CAST(klass) ((GstGhostPadClass*)(klass)) #define GST_IS_GHOST_PAD(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_GHOST_PAD)) #define GST_IS_GHOST_PAD_FAST(obj) (G_OBJECT_TYPE(obj) == GST_TYPE_GHOST_PAD) #define GST_IS_GHOST_PAD_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_GHOST_PAD)) - -#ifdef GST_TYPE_PARANOID -# define GST_GHOST_PAD(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_GHOST_PAD, GstGhostPad)) -# define GST_GHOST_PAD_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_GHOST_PAD, GstGhostPadClass)) -#else -# define GST_GHOST_PAD GST_GHOST_PAD_CAST -# define GST_GHOST_PAD_CLASS GST_GHOST_PAD_CLASS_CAST -#endif +#define GST_GHOST_PAD(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_GHOST_PAD, GstGhostPad)) +#define GST_GHOST_PAD_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_GHOST_PAD, GstGhostPadClass)) /*typedef struct _GstPad GstPad; */ @@ -175,13 +146,13 @@ struct _GstPad { GstPadTemplate *padtemplate; /* the template for this pad */ - GST_OBJECT_PADDING + gpointer _gst_reserved[GST_PADDING]; }; struct _GstPadClass { GstObjectClass parent_class; - GST_CLASS_PADDING + gpointer _gst_reserved[GST_PADDING]; }; struct _GstRealPad { @@ -224,7 +195,7 @@ struct _GstRealPad { GstProbeDispatcher probedisp; - GST_OBJECT_PADDING + gpointer _gst_reserved[GST_PADDING]; }; struct _GstRealPadClass { @@ -236,7 +207,7 @@ struct _GstRealPadClass { void (*linked) (GstPad *pad, GstPad *peer); void (*unlinked) (GstPad *pad, GstPad *peer); - GST_CLASS_PADDING + gpointer _gst_reserved[GST_PADDING]; }; struct _GstGhostPad { @@ -244,13 +215,13 @@ struct _GstGhostPad { GstRealPad *realpad; - GST_OBJECT_PADDING + gpointer _gst_reserved[GST_PADDING]; }; struct _GstGhostPadClass { GstPadClass parent_class; - GST_CLASS_PADDING + gpointer _gst_reserved[GST_PADDING]; }; @@ -292,7 +263,7 @@ struct _GstGhostPadClass { #define GST_PAD_REALIZE(pad) (GST_IS_REAL_PAD(pad) ? ((GstRealPad *)(pad)) : GST_GPAD_REALPAD(pad)) #define GST_PAD_DIRECTION(pad) GST_RPAD_DIRECTION(GST_PAD_REALIZE(pad)) #define GST_PAD_CAPS(pad) GST_RPAD_CAPS(GST_PAD_REALIZE(pad)) -#define GST_PAD_PEER(pad) GST_PAD_CAST(GST_RPAD_PEER(GST_PAD_REALIZE(pad))) +#define GST_PAD_PEER(pad) GST_PAD(GST_RPAD_PEER(GST_PAD_REALIZE(pad))) /* Some check functions (unused?) */ #define GST_PAD_IS_LINKED(pad) (GST_PAD_PEER(pad) != NULL) @@ -337,7 +308,7 @@ struct _GstPadTemplate { GstPadPresence presence; GstCaps2 *caps; - GST_OBJECT_PADDING + gpointer _gst_reserved[GST_PADDING]; }; struct _GstPadTemplateClass { @@ -346,7 +317,7 @@ struct _GstPadTemplateClass { /* signal callbacks */ void (*pad_created) (GstPadTemplate *templ, GstPad *pad); - GST_CLASS_PADDING + gpointer _gst_reserved[GST_PADDING]; }; struct _GstStaticPadTemplate { @@ -445,8 +416,9 @@ void gst_pad_push (GstPad *pad, GstData *data); GstData* gst_pad_pull (GstPad *pad); gboolean gst_pad_send_event (GstPad *pad, GstEvent *event); gboolean gst_pad_event_default (GstPad *pad, GstEvent *event); -GstPad* gst_pad_select (GList *padlist); -GstPad* gst_pad_selectv (GstPad *pad, ...); +GstPad* gst_pad_selectv (GList *padlist); +GstPad* gst_pad_select (GstPad *pad, ...); +GstPad* gst_pad_select_valist (GstPad *pad, va_list varargs); /* convert/query/format functions */ diff --git a/gst/gstpipeline.h b/gst/gstpipeline.h index b63419558c..5dd5b11c06 100644 --- a/gst/gstpipeline.h +++ b/gst/gstpipeline.h @@ -41,13 +41,13 @@ typedef struct _GstPipelineClass GstPipelineClass; struct _GstPipeline { GstBin bin; - GST_OBJECT_PADDING + gpointer _gst_reserved[GST_PADDING]; }; struct _GstPipelineClass { GstBinClass parent_class; - GST_CLASS_PADDING + gpointer _gst_reserved[GST_PADDING]; }; GType gst_pipeline_get_type (void); diff --git a/gst/gstplugin.c b/gst/gstplugin.c index 597cf34d11..ac6ffb3ec4 100644 --- a/gst/gstplugin.c +++ b/gst/gstplugin.c @@ -24,6 +24,7 @@ #include #include #include +#include #include "gst_private.h" @@ -39,6 +40,11 @@ static GModule *main_module = NULL; static GList *_gst_plugin_static = NULL; +/* static variables for segfault handling of plugin loading */ +static char *_gst_plugin_fault_handler_filename = NULL; +extern gboolean *_gst_disable_segtrap; /* see gst.c */ +static gboolean *_gst_plugin_fault_handler_is_setup = FALSE; + /* list of valid licenses. * One of these must be specified or the plugin won't be loaded * Contact gstreamer-devel@lists.sourceforge.net if your license should be @@ -168,7 +174,7 @@ gst_plugin_register_func (GstPlugin *plugin, GModule *module, GstPluginDesc *des } if (!desc->license || !desc->description || !desc->package || - !desc->copyright || !desc->origin) { + !desc->origin) { if (GST_CAT_DEFAULT) GST_INFO ("plugin \"%s\" has incorrect GstPluginDesc, not loading", plugin->filename); return FALSE; @@ -194,6 +200,71 @@ gst_plugin_register_func (GstPlugin *plugin, GModule *module, GstPluginDesc *des return plugin; } +/** + * _gst_plugin_fault_handler_restore: + * segfault handler restorer + */ +static void +_gst_plugin_fault_handler_restore (void) +{ + struct sigaction action; + + memset (&action, 0, sizeof (action)); + action.sa_handler = SIG_DFL; + + sigaction (SIGSEGV, &action, NULL); +} + +/** + * _gst_plugin_fault_handler_sighandler: + * segfault handler implementation + */ +static void +_gst_plugin_fault_handler_sighandler (int signum) +{ + /* We need to restore the fault handler or we'll keep getting it */ + _gst_plugin_fault_handler_restore (); + + switch (signum) + { + case SIGSEGV: + g_print ("\nERROR: "); + g_print ("Caught a segmentation fault while loading plugin file:\n"); + g_print ("%s\n\n", _gst_plugin_fault_handler_filename); + g_print ("Please either:\n"); + g_print ("- remove it and restart.\n"); + g_print ("- run with --gst-disable-segtrap and debug.\n"); + exit (-1); + break; + default: + g_print ("Caught unhandled signal on plugin loading\n"); + break; + } +} + +/** + * _gst_plugin_fault_handler_setup: + * sets up the segfault handler + */ +static void +_gst_plugin_fault_handler_setup (void) +{ + struct sigaction action; + + /* if asked to leave segfaults alone, just return */ + if (_gst_disable_segtrap) return; + + if (_gst_plugin_fault_handler_is_setup) return; + + memset (&action, 0, sizeof (action)); + action.sa_handler = _gst_plugin_fault_handler_sighandler; + + sigaction (SIGSEGV, &action, NULL); +} + +static void +_gst_plugin_fault_handler_setup (); + /** * gst_plugin_load_file: * @plugin: The plugin to load @@ -201,7 +272,7 @@ gst_plugin_register_func (GstPlugin *plugin, GModule *module, GstPluginDesc *des * * Load the given plugin. * - * Returns: a new GstPlugin or NULL, if an error occured + * Returns: a new GstPlugin or NULL, if an error occurred. */ GstPlugin * gst_plugin_load_file (const gchar *filename, GError **error) @@ -229,8 +300,8 @@ gst_plugin_load_file (const gchar *filename, GError **error) GST_PLUGIN_ERROR, GST_PLUGIN_ERROR_MODULE, "Problem opening file %s\n", - filename); - return FALSE; + filename); + return NULL; } module = g_module_open (filename, G_MODULE_BIND_LAZY); @@ -278,10 +349,19 @@ gst_plugin_load_file (const gchar *filename, GError **error) desc->name); } + /* this is where we load the actual .so, so let's trap SIGSEGV */ + _gst_plugin_fault_handler_setup (); + _gst_plugin_fault_handler_filename = plugin->filename; + if (gst_plugin_register_func (plugin, module, desc)) { + /* remove signal handler */ + _gst_plugin_fault_handler_restore (); + _gst_plugin_fault_handler_filename = NULL; GST_INFO ("plugin \"%s\" loaded", plugin->filename); return plugin; } else { + /* remove signal handler */ + _gst_plugin_fault_handler_restore (); GST_DEBUG ("gst_plugin_register_func failed for plugin \"%s\"", filename); /* plugin == NULL */ g_set_error (error, @@ -327,8 +407,6 @@ gst_plugin_desc_copy (GstPluginDesc *dest, const GstPluginDesc *src) dest->version = g_strdup (src->version); g_free (dest->license); dest->license = g_strdup (src->license); - g_free (dest->copyright); - dest->copyright = g_strdup (src->copyright); g_free (dest->package); dest->package = g_strdup (src->package); g_free (dest->origin); @@ -343,7 +421,6 @@ gst_plugin_desc_free (GstPluginDesc *desc) g_free (desc->description); g_free (desc->version); g_free (desc->license); - g_free (desc->copyright); g_free (desc->package); g_free (desc->origin); @@ -439,21 +516,6 @@ gst_plugin_get_license (GstPlugin *plugin) return plugin->desc.license; } -/** - * gst_plugin_get_copyright: - * @plugin: plugin to get the copyright of - * - * get the informal copyright notice of the plugin - * - * Returns: the copyright of the plugin - */ -G_CONST_RETURN gchar* -gst_plugin_get_copyright (GstPlugin *plugin) -{ - g_return_val_if_fail (plugin != NULL, NULL); - - return plugin->desc.copyright; -} /** * gst_plugin_get_package: * @plugin: plugin to get the package of diff --git a/gst/gstplugin.h b/gst/gstplugin.h index d976783964..8d31d29b01 100644 --- a/gst/gstplugin.h +++ b/gst/gstplugin.h @@ -61,11 +61,10 @@ struct _GstPluginDesc { GstPluginExitFunc plugin_exit; /* pointer to exiting function */ gchar *version; /* version of the plugin */ gchar *license; /* effective license of plugin */ - gchar *copyright; /* informal copyright notice */ gchar *package; /* package plugin belongs to */ gchar *origin; /* URL to provider of plugin */ - GST_STRUCT_PADDING + gpointer _gst_reserved[GST_PADDING]; }; struct _GstPlugin { @@ -78,10 +77,10 @@ struct _GstPlugin { gpointer manager; /* managing registry */ GModule * module; /* contains the module if the plugin is loaded */ - GST_STRUCT_PADDING + gpointer _gst_reserved[GST_PADDING]; }; -#define GST_PLUGIN_DEFINE(major,minor,name,description,init,version,license,copyright,package,origin) \ +#define GST_PLUGIN_DEFINE(major,minor,name,description,init,version,license,package,origin) \ GstPluginDesc gst_plugin_desc = { \ major, \ minor, \ @@ -91,13 +90,12 @@ GstPluginDesc gst_plugin_desc = { \ NULL, \ version, \ license, \ - copyright, \ package, \ origin, \ - GST_STRUCT_PADDING_INIT \ + GST_PADDING_INIT \ }; -#define GST_PLUGIN_DEFINE_STATIC(major,minor,name,description,init,version,license,copyright,package,origin) \ +#define GST_PLUGIN_DEFINE_STATIC(major,minor,name,description,init,version,license,package,origin) \ static void GST_GNUC_CONSTRUCTOR \ _gst_plugin_static_init__ ##init (void) \ { \ @@ -110,10 +108,9 @@ _gst_plugin_static_init__ ##init (void) \ NULL, \ version, \ license, \ - copyright, \ package, \ origin, \ - GST_STRUCT_PADDING_INIT \ + GST_PADDING_INIT \ }; \ _gst_plugin_register_static (&plugin_desc_); \ } @@ -135,7 +132,6 @@ void gst_plugin_set_name (GstPlugin *plugin, const gchar *name); G_CONST_RETURN gchar* gst_plugin_get_longname (GstPlugin *plugin); G_CONST_RETURN gchar* gst_plugin_get_filename (GstPlugin *plugin); G_CONST_RETURN gchar* gst_plugin_get_license (GstPlugin *plugin); -G_CONST_RETURN gchar* gst_plugin_get_copyright (GstPlugin *plugin); G_CONST_RETURN gchar* gst_plugin_get_package (GstPlugin *plugin); G_CONST_RETURN gchar* gst_plugin_get_origin (GstPlugin *plugin); GModule * gst_plugin_get_module (GstPlugin *plugin); diff --git a/gst/gstpluginfeature.h b/gst/gstpluginfeature.h index 760214ccc3..66994070a0 100644 --- a/gst/gstpluginfeature.h +++ b/gst/gstpluginfeature.h @@ -50,7 +50,7 @@ struct _GstPluginFeature { gpointer manager; - GST_OBJECT_PADDING + gpointer _gst_reserved[GST_PADDING]; }; struct _GstPluginFeatureClass { @@ -58,7 +58,7 @@ struct _GstPluginFeatureClass { void (*unload_thyself) (GstPluginFeature *feature); - GST_CLASS_PADDING + gpointer _gst_reserved[GST_PADDING]; }; typedef struct { diff --git a/gst/gstqueue.c b/gst/gstqueue.c index 76a93b09d6..e62c413a7f 100644 --- a/gst/gstqueue.c +++ b/gst/gstqueue.c @@ -39,54 +39,75 @@ static GstElementDetails gst_queue_details = GST_ELEMENT_DETAILS ( /* Queue signals and args */ enum { - FULL, + SIGNAL_UNDERRUN, + SIGNAL_RUNNING, + SIGNAL_OVERRUN, LAST_SIGNAL }; enum { ARG_0, - ARG_LEVEL_BUFFERS, - ARG_LEVEL_BYTES, - ARG_LEVEL_TIME, - ARG_SIZE_BUFFERS, - ARG_SIZE_BYTES, - ARG_SIZE_TIME, + /* FIXME: don't we have another way of doing this + * "Gstreamer format" (frame/byte/time) queries? */ + ARG_CUR_LEVEL_BUFFERS, + ARG_CUR_LEVEL_BYTES, + ARG_CUR_LEVEL_TIME, + ARG_MAX_SIZE_BUFFERS, + ARG_MAX_SIZE_BYTES, + ARG_MAX_SIZE_TIME, + ARG_MIN_TRESHOLD_BUFFERS, + ARG_MIN_TRESHOLD_BYTES, + ARG_MIN_TRESHOLD_TIME, ARG_LEAKY, - ARG_LEVEL, - ARG_MAX_LEVEL, - ARG_MIN_THRESHOLD_BYTES, ARG_MAY_DEADLOCK, - ARG_BLOCK_TIMEOUT, + ARG_BLOCK_TIMEOUT + /* FILL ME */ }; -static void gst_queue_base_init (gpointer g_class); -static void gst_queue_class_init (gpointer g_class, - gpointer class_data); -static void gst_queue_init (GTypeInstance *instance, - gpointer g_class); -static void gst_queue_dispose (GObject *object); +typedef struct _GstQueueEventResponse { + GstEvent *event; + gboolean ret, handled; +} GstQueueEventResponse; -static void gst_queue_set_property (GObject *object, guint prop_id, - const GValue *value, GParamSpec *pspec); -static void gst_queue_get_property (GObject *object, guint prop_id, - GValue *value, GParamSpec *pspec); +static void gst_queue_base_init (GstQueueClass *klass); +static void gst_queue_class_init (GstQueueClass *klass); +static void gst_queue_init (GstQueue *queue); +static void gst_queue_dispose (GObject *object); -static void gst_queue_chain (GstPad *pad, GstData *data); -static GstData * gst_queue_get (GstPad *pad); -static GstBufferPool* gst_queue_get_bufferpool (GstPad *pad); +static void gst_queue_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec); +static void gst_queue_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec); + +static GstCaps2 *gst_queue_getcaps (GstPad *pad); +static GstPadLinkReturn + gst_queue_link (GstPad *pad, + const GstCaps2 *caps); +static void gst_queue_chain (GstPad *pad, + GstData *data); +static GstData *gst_queue_get (GstPad *pad); +static GstBufferPool * + gst_queue_get_bufferpool (GstPad *pad); -static gboolean gst_queue_handle_src_event (GstPad *pad, GstEvent *event); +static gboolean gst_queue_handle_src_event (GstPad *pad, + GstEvent *event); +static void gst_queue_locked_flush (GstQueue *queue); -static void gst_queue_locked_flush (GstQueue *queue); - -static GstElementStateReturn gst_queue_change_state (GstElement *element); -static gboolean gst_queue_release_locks (GstElement *element); +static GstElementStateReturn + gst_queue_change_state (GstElement *element); +static gboolean gst_queue_release_locks (GstElement *element); -#define GST_TYPE_QUEUE_LEAKY (queue_leaky_get_type()) +#define GST_TYPE_QUEUE_LEAKY (queue_leaky_get_type ()) + static GType -queue_leaky_get_type(void) { +queue_leaky_get_type (void) +{ static GType queue_leaky_type = 0; static GEnumValue queue_leaky[] = { { GST_QUEUE_NO_LEAK, "0", "Not Leaky" }, @@ -104,115 +125,127 @@ static GstElementClass *parent_class = NULL; static guint gst_queue_signals[LAST_SIGNAL] = { 0 }; GType -gst_queue_get_type(void) +gst_queue_get_type (void) { static GType queue_type = 0; if (!queue_type) { static const GTypeInfo queue_info = { - sizeof(GstQueueClass), - gst_queue_base_init, + sizeof (GstQueueClass), + (GBaseInitFunc) gst_queue_base_init, NULL, - gst_queue_class_init, + (GClassInitFunc) gst_queue_class_init, NULL, NULL, - sizeof(GstQueue), + sizeof (GstQueue), 4, - gst_queue_init, + (GInstanceInitFunc) gst_queue_init, NULL }; - queue_type = g_type_register_static (GST_TYPE_ELEMENT, "GstQueue", &queue_info, 0); + + queue_type = g_type_register_static (GST_TYPE_ELEMENT, + "GstQueue", &queue_info, 0); } + return queue_type; } static void -gst_queue_base_init (gpointer g_class) +gst_queue_base_init (GstQueueClass *klass) { - GstElementClass *gstelement_class = GST_ELEMENT_CLASS (g_class); + GstElementClass *gstelement_class = GST_ELEMENT_CLASS (klass); gst_element_class_set_details (gstelement_class, &gst_queue_details); } static void -gst_queue_class_init (gpointer g_class, gpointer class_data) +gst_queue_class_init (GstQueueClass *klass) { - GObjectClass *gobject_class = G_OBJECT_CLASS (g_class); - GstElementClass *gstelement_class = GST_ELEMENT_CLASS (g_class); - GstQueueClass *gstqueue_class = GST_QUEUE_CLASS (g_class); + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + GstElementClass *gstelement_class = GST_ELEMENT_CLASS (klass); - parent_class = g_type_class_peek_parent (g_class); + parent_class = g_type_class_peek_parent (klass); - gst_queue_signals[FULL] = - g_signal_new ("full", G_TYPE_FROM_CLASS (gstqueue_class), G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (GstQueueClass, full), NULL, NULL, + /* signals */ + gst_queue_signals[SIGNAL_UNDERRUN] = + g_signal_new ("underrun", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (GstQueueClass, underrun), NULL, NULL, + g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); + gst_queue_signals[SIGNAL_RUNNING] = + g_signal_new ("running", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (GstQueueClass, running), NULL, NULL, + g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); + gst_queue_signals[SIGNAL_OVERRUN] = + g_signal_new ("overrun", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (GstQueueClass, overrun), NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); - g_object_class_install_property (G_OBJECT_CLASS (gstqueue_class), ARG_LEAKY, - g_param_spec_enum ("leaky", "Leaky", "Where the queue leaks, if at all.", - GST_TYPE_QUEUE_LEAKY, GST_QUEUE_NO_LEAK, G_PARAM_READWRITE)); - g_object_class_install_property (G_OBJECT_CLASS (gstqueue_class), ARG_LEVEL, - g_param_spec_int ("level", "Level", "How many buffers are in the queue.", - 0, G_MAXINT, 0, G_PARAM_READABLE)); - g_object_class_install_property (G_OBJECT_CLASS (gstqueue_class), ARG_MAX_LEVEL, - g_param_spec_int ("max_level", "Maximum Level", "How many buffers the queue holds.", - 0, G_MAXINT, 100, G_PARAM_READWRITE)); - g_object_class_install_property (G_OBJECT_CLASS (gstqueue_class), ARG_MIN_THRESHOLD_BYTES, - g_param_spec_int ("min_threshold_bytes", "Minimum Threshold", - "Minimum bytes required before signalling not_empty to reader.", - 0, G_MAXINT, 0, G_PARAM_READWRITE)); - g_object_class_install_property (G_OBJECT_CLASS (gstqueue_class), ARG_MAY_DEADLOCK, - g_param_spec_boolean ("may_deadlock", "May Deadlock", "The queue may deadlock if it's full and not PLAYING", - TRUE, G_PARAM_READWRITE)); - g_object_class_install_property (G_OBJECT_CLASS (gstqueue_class), ARG_BLOCK_TIMEOUT, - g_param_spec_int ("block_timeout", "Timeout for Block", - "Microseconds until blocked queue times out and returns filler event. " - "Value of -1 disables timeout", - -1, G_MAXINT, -1, G_PARAM_READWRITE)); - gobject_class->dispose = GST_DEBUG_FUNCPTR (gst_queue_dispose); - gobject_class->set_property = GST_DEBUG_FUNCPTR (gst_queue_set_property); - gobject_class->get_property = GST_DEBUG_FUNCPTR (gst_queue_get_property); + /* properties */ + g_object_class_install_property (gobject_class, ARG_CUR_LEVEL_BYTES, + g_param_spec_uint ("current-level-bytes", "Current level (kB)", + "Current amount of data in the queue (bytes)", + 0, G_MAXUINT, 0, G_PARAM_READABLE)); + g_object_class_install_property (gobject_class, ARG_CUR_LEVEL_BUFFERS, + g_param_spec_uint ("current-level-buffers", "Current level (buffers)", + "Current number of buffers in the queue", + 0, G_MAXUINT, 0, G_PARAM_READABLE)); + g_object_class_install_property (gobject_class, ARG_CUR_LEVEL_TIME, + g_param_spec_uint64 ("current-level-time", "Current level (ns)", + "Current amount of data in the queue (in ns)", + 0, G_MAXUINT64, 0, G_PARAM_READABLE)); - gstelement_class->change_state = GST_DEBUG_FUNCPTR(gst_queue_change_state); - gstelement_class->release_locks = GST_DEBUG_FUNCPTR(gst_queue_release_locks); -} + g_object_class_install_property (gobject_class, ARG_MAX_SIZE_BYTES, + g_param_spec_uint ("max-size-bytes", "Max. size (kB)", + "Max. amount of data in the queue (bytes, 0=disable)", + 0, G_MAXUINT, 0, G_PARAM_READWRITE)); + g_object_class_install_property (gobject_class, ARG_MAX_SIZE_BUFFERS, + g_param_spec_uint ("max-size-buffers", "Max. size (buffers)", + "Max. number of buffers in the queue (0=disable)", + 0, G_MAXUINT, 0, G_PARAM_READWRITE)); + g_object_class_install_property (gobject_class, ARG_MAX_SIZE_TIME, + g_param_spec_uint64 ("max-size-time", "Max. size (ns)", + "Max. amount of data in the queue (in ns, 0=disable)", + 0, G_MAXUINT64, 0, G_PARAM_READWRITE)); -static GstPadLinkReturn -gst_queue_link (GstPad *pad, const GstCaps2 *caps) -{ - GstQueue *queue = GST_QUEUE (gst_pad_get_parent (pad)); - GstPad *otherpad; + g_object_class_install_property (gobject_class, ARG_MIN_TRESHOLD_BYTES, + g_param_spec_uint ("min-treshold-bytes", "Min. treshold (kB)", + "Min. amount of data in the queue to allow reading (bytes, 0=disable)", + 0, G_MAXUINT, 0, G_PARAM_READWRITE)); + g_object_class_install_property (gobject_class, ARG_MIN_TRESHOLD_BUFFERS, + g_param_spec_uint ("min-treshold-buffers", "Min. treshold (buffers)", + "Min. number of buffers in the queue to allow reading (0=disable)", + 0, G_MAXUINT, 0, G_PARAM_READWRITE)); + g_object_class_install_property (gobject_class, ARG_MIN_TRESHOLD_TIME, + g_param_spec_uint64 ("min-treshold-time", "Min. treshold (ns)", + "Min. amount of data in the queue to allow reading (in ns, 0=disable)", + 0, G_MAXUINT64, 0, G_PARAM_READWRITE)); - if (pad == queue->srcpad) - otherpad = queue->sinkpad; - else - otherpad = queue->srcpad; + g_object_class_install_property (gobject_class, ARG_LEAKY, + g_param_spec_enum ("leaky", "Leaky", + "Where the queue leaks, if at all", + GST_TYPE_QUEUE_LEAKY, GST_QUEUE_NO_LEAK, G_PARAM_READWRITE)); + g_object_class_install_property (gobject_class, ARG_MAY_DEADLOCK, + g_param_spec_boolean ("may_deadlock", "May Deadlock", + "The queue may deadlock if it's full and not PLAYING", + TRUE, G_PARAM_READWRITE)); + g_object_class_install_property (gobject_class, ARG_BLOCK_TIMEOUT, + g_param_spec_uint64 ("block_timeout", "Timeout for Block", + "Nanoseconds until blocked queue times out and returns filler event. " + "Value of -1 disables timeout", + 0, G_MAXUINT64, -1, G_PARAM_READWRITE)); - return gst_pad_proxy_link (otherpad, caps); -} + /* set several parent class virtual functions */ + gobject_class->dispose = GST_DEBUG_FUNCPTR (gst_queue_dispose); + gobject_class->set_property = GST_DEBUG_FUNCPTR (gst_queue_set_property); + gobject_class->get_property = GST_DEBUG_FUNCPTR (gst_queue_get_property); -static GstCaps2 * -gst_queue_getcaps (GstPad *pad) -{ - GstQueue *queue = GST_QUEUE (gst_pad_get_parent (pad)); - GstPad *otherpad; - - if (pad == queue->srcpad) - otherpad = GST_PAD_PEER (queue->sinkpad); - else - otherpad = GST_PAD_PEER (queue->srcpad); - - if (otherpad) - return gst_pad_get_allowed_caps (otherpad); - - return gst_caps2_new_any (); + gstelement_class->change_state = GST_DEBUG_FUNCPTR (gst_queue_change_state); + gstelement_class->release_locks = GST_DEBUG_FUNCPTR (gst_queue_release_locks); } static void -gst_queue_init (GTypeInstance *instance, gpointer g_class) +gst_queue_init (GstQueue *queue) { - GstQueue *queue = GST_QUEUE (instance); - /* scheduling on this kind of element is, well, interesting */ GST_FLAG_SET (queue, GST_ELEMENT_DECOUPLED); GST_FLAG_SET (queue, GST_ELEMENT_EVENT_AWARE); @@ -233,26 +266,31 @@ gst_queue_init (GTypeInstance *instance, gpointer g_class) gst_pad_set_event_function (queue->srcpad, GST_DEBUG_FUNCPTR (gst_queue_handle_src_event)); gst_pad_set_active (queue->srcpad, TRUE); + queue->cur_level.buffers = 0; /* no content */ + queue->cur_level.bytes = 0; /* no content */ + queue->cur_level.time = 0; /* no content */ + queue->max_size.buffers = 100; /* max. 100 buffers */ + queue->max_size.bytes = 1024 * 1024; /* max. 1 MB */ + queue->max_size.time = GST_SECOND; /* max. 1 sec. */ + queue->min_treshold.buffers = 0; /* no treshold */ + queue->min_treshold.bytes = 0; /* no treshold */ + queue->min_treshold.time = 0; /* no treshold */ + queue->leaky = GST_QUEUE_NO_LEAK; - queue->queue = NULL; - queue->level_buffers = 0; - queue->level_bytes = 0; - queue->level_time = G_GINT64_CONSTANT (0); - queue->size_buffers = 100; /* 100 buffers */ - queue->size_bytes = 100 * 1024; /* 100KB */ - queue->size_time = GST_SECOND; /* 1sec */ - queue->min_threshold_bytes = 0; queue->may_deadlock = TRUE; - queue->block_timeout = -1; + queue->block_timeout = GST_CLOCK_TIME_NONE; queue->interrupt = FALSE; queue->flush = FALSE; queue->qlock = g_mutex_new (); - queue->not_empty = g_cond_new (); - queue->not_full = g_cond_new (); - queue->events = g_async_queue_new(); + queue->item_add = g_cond_new (); + queue->item_del = g_cond_new (); + queue->event_done = g_cond_new (); + queue->events = g_queue_new (); queue->queue = g_queue_new (); - GST_CAT_DEBUG_OBJECT (GST_CAT_THREAD, queue, "initialized queue's not_empty & not_full conditions"); + + GST_CAT_DEBUG_OBJECT (GST_CAT_THREAD, queue, + "initialized queue's not_empty & not_full conditions"); } static void @@ -262,54 +300,114 @@ gst_queue_dispose (GObject *object) gst_element_set_state (GST_ELEMENT (queue), GST_STATE_NULL); - g_mutex_free (queue->qlock); - g_cond_free (queue->not_empty); - g_cond_free (queue->not_full); + while (!g_queue_is_empty (queue->queue)) { + GstData *data = g_queue_pop_head (queue->queue); + gst_data_unref (data); + } g_queue_free (queue->queue); + g_mutex_free (queue->qlock); + g_cond_free (queue->item_add); + g_cond_free (queue->item_del); + g_cond_free (queue->event_done); + while (!g_queue_is_empty (queue->events)) { + GstEvent *event = g_queue_pop_head (queue->events); + gst_event_unref (event); + } - g_async_queue_unref(queue->events); - - G_OBJECT_CLASS (parent_class)->dispose (object); + if (G_OBJECT_CLASS (parent_class)->dispose) + G_OBJECT_CLASS (parent_class)->dispose (object); } -static GstBufferPool* +static GstPad * +gst_queue_otherpad (GstPad *pad) +{ + GstQueue *queue = GST_QUEUE (gst_pad_get_parent (pad)); + GstPad *otherpad; + + if (pad == queue->srcpad) + otherpad = queue->sinkpad; + else + otherpad = queue->srcpad; + + return otherpad; +} + +static GstPadLinkReturn +gst_queue_link (GstPad *pad, const GstCaps2 *caps) +{ + return gst_pad_proxy_link (gst_queue_otherpad (pad), caps); +} + +static GstCaps2 * +gst_queue_getcaps (GstPad *pad) +{ + GstPad *otherpad = GST_PAD_PEER (gst_queue_otherpad (pad)); + + if (otherpad) + return gst_pad_get_caps (otherpad); + + return gst_caps2_new_any (); +} + +static GstBufferPool * gst_queue_get_bufferpool (GstPad *pad) { - GstQueue *queue; - - queue = GST_QUEUE (GST_OBJECT_PARENT (pad)); - - return gst_pad_get_bufferpool (queue->srcpad); -} - -static void -gst_queue_cleanup_data (gpointer data, const gpointer user_data) -{ - GST_CAT_DEBUG_OBJECT (GST_CAT_DATAFLOW, user_data, "cleaning buffer %p", data); - - gst_data_unref (GST_DATA (data)); + return gst_pad_get_bufferpool (gst_queue_otherpad (pad)); } static void gst_queue_locked_flush (GstQueue *queue) { - gpointer data; - - while ((data = g_queue_pop_head (queue->queue))) { - gst_queue_cleanup_data (data, (gpointer) queue); + while (!g_queue_is_empty (queue->queue)) { + GstData *data = g_queue_pop_head (queue->queue); + gst_data_unref (data); } queue->timeval = NULL; - queue->level_buffers = 0; - queue->level_bytes = 0; - queue->level_time = G_GINT64_CONSTANT (0); + queue->cur_level.buffers = 0; + queue->cur_level.bytes = 0; + queue->cur_level.time = 0; + /* make sure any pending buffers to be added are flushed too */ queue->flush = TRUE; - /* signal not_full, since we apparently aren't full anymore */ - g_cond_signal (queue->not_full); + + /* we deleted something... */ + g_cond_signal (queue->item_del); } static void -gst_queue_chain (GstPad *pad, GstData *data) +gst_queue_handle_pending_events (GstQueue *queue) +{ + /* check for events to send upstream */ + while (!g_queue_is_empty (queue->events)){ + GstQueueEventResponse *er = g_queue_pop_head (queue->events); + GST_CAT_DEBUG_OBJECT (GST_CAT_DATAFLOW, queue, "sending event upstream"); + er->ret = gst_pad_event_default (GST_PAD_PEER (queue->sinkpad), er->event); + er->handled = TRUE; + g_cond_signal (queue->event_done); + GST_CAT_DEBUG_OBJECT (GST_CAT_DATAFLOW, queue, "event sent"); + } +} + +#define STATUS(queue, msg) \ + GST_CAT_LOG_OBJECT (GST_CAT_DATAFLOW, queue, \ + "(%s:%s) " msg ": %u of %u-%u buffers, %u of %u-%u " \ + "bytes, %" G_GUINT64_FORMAT " of %" G_GUINT64_FORMAT \ + "-%" G_GUINT64_FORMAT " ns, %u elements", \ + GST_DEBUG_PAD_NAME (pad), \ + queue->cur_level.buffers, \ + queue->min_treshold.buffers, \ + queue->max_size.buffers, \ + queue->cur_level.bytes, \ + queue->min_treshold.bytes, \ + queue->max_size.bytes, \ + queue->cur_level.time, \ + queue->min_treshold.time, \ + queue->max_size.time, \ + queue->queue->length) + +static void +gst_queue_chain (GstPad *pad, + GstData *data) { GstQueue *queue; @@ -319,147 +417,201 @@ gst_queue_chain (GstPad *pad, GstData *data) queue = GST_QUEUE (GST_OBJECT_PARENT (pad)); - /* check for events to send upstream */ - g_async_queue_lock(queue->events); - while (g_async_queue_length_unlocked(queue->events) > 0){ - GstEvent *event = (GstEvent*)g_async_queue_pop_unlocked(queue->events); - GST_CAT_DEBUG_OBJECT (GST_CAT_DATAFLOW, queue, "sending event upstream\n"); - gst_pad_event_default (pad, event); - GST_CAT_DEBUG_OBJECT (GST_CAT_DATAFLOW, queue, "event sent\n"); - } - g_async_queue_unlock(queue->events); - restart: /* we have to lock the queue since we span threads */ GST_CAT_LOG_OBJECT (GST_CAT_DATAFLOW, queue, "locking t:%p", g_thread_self ()); g_mutex_lock (queue->qlock); GST_CAT_LOG_OBJECT (GST_CAT_DATAFLOW, queue, "locked t:%p", g_thread_self ()); - + + gst_queue_handle_pending_events (queue); + /* assume don't need to flush this buffer when the queue is filled */ queue->flush = FALSE; if (GST_IS_EVENT (data)) { switch (GST_EVENT_TYPE (data)) { case GST_EVENT_FLUSH: - GST_CAT_DEBUG_OBJECT (GST_CAT_DATAFLOW, queue, "FLUSH event, flushing queue\n"); + STATUS (queue, "received flush event"); gst_queue_locked_flush (queue); break; case GST_EVENT_EOS: - GST_CAT_DEBUG_OBJECT (GST_CAT_DATAFLOW, queue, "eos in on %s %d\n", - GST_ELEMENT_NAME (queue), queue->level_buffers); + STATUS (queue, "received EOS"); break; default: /* we put the event in the queue, we don't have to act ourselves */ + GST_CAT_LOG_OBJECT (GST_CAT_DATAFLOW, queue, + "adding event %p of type %d", + data, GST_EVENT_TYPE (data)); break; } } if (GST_IS_BUFFER (data)) GST_CAT_LOG_OBJECT (GST_CAT_DATAFLOW, queue, - "adding buffer %p of size %d", data, GST_BUFFER_SIZE (data)); + "adding buffer %p of size %d", + data, GST_BUFFER_SIZE (data)); - if (queue->level_buffers == queue->size_buffers) { + /* We make space available if we're "full" according to whatever + * the user defined as "full". Note that this only applies to buffers. + * We always handle events and they don't count in our statistics. */ + if (GST_IS_BUFFER (data) && + ((queue->max_size.buffers > 0 && + queue->cur_level.buffers >= queue->max_size.buffers) || + (queue->max_size.bytes > 0 && + queue->cur_level.bytes >= queue->max_size.bytes) || + (queue->max_size.time > 0 && + queue->cur_level.time >= queue->max_size.time))) { g_mutex_unlock (queue->qlock); - g_signal_emit (G_OBJECT (queue), gst_queue_signals[FULL], 0); + g_signal_emit (G_OBJECT (queue), gst_queue_signals[SIGNAL_OVERRUN], 0); g_mutex_lock (queue->qlock); - /* if this is a leaky queue... */ - if (queue->leaky) { - /* FIXME don't want to leak events! */ - /* if we leak on the upstream side, drop the current buffer */ - if (queue->leaky == GST_QUEUE_LEAK_UPSTREAM) { - GST_CAT_DEBUG_OBJECT (GST_CAT_DATAFLOW, queue, "queue is full, leaking buffer on upstream end"); - if (GST_IS_EVENT (data)) - fprintf(stderr, "Error: queue [%s] leaked an event, type:%d\n", - GST_ELEMENT_NAME(GST_ELEMENT(queue)), - GST_EVENT_TYPE(GST_EVENT(data))); - /* now we have to clean up and exit right away */ + /* how are we going to make space for this buffer? */ + switch (queue->leaky) { + /* leak current buffer */ + case GST_QUEUE_LEAK_UPSTREAM: + GST_CAT_DEBUG_OBJECT (GST_CAT_DATAFLOW, queue, + "queue is full, leaking buffer on upstream end"); + /* now we can clean up and exit right away */ g_mutex_unlock (queue->qlock); goto out_unref; - } - /* otherwise we have to push a buffer off the other end */ - else { - gpointer front; - GstData *leak; - GST_CAT_DEBUG_OBJECT (GST_CAT_DATAFLOW, queue, "queue is full, leaking buffer on downstream end"); + /* leak first buffer in the queue */ + case GST_QUEUE_LEAK_DOWNSTREAM: { + /* this is a bit hacky. We'll manually iterate the list + * and find the first buffer from the head on. We'll + * unref that and "fix up" the GQueue object... */ + GList *item; + GstData *leak = NULL; - front = g_queue_pop_head (queue->queue); - leak = GST_DATA (front); + GST_CAT_DEBUG_OBJECT (GST_CAT_DATAFLOW, queue, + "queue is full, leaking buffer on downstream end"); - queue->level_buffers--; - if (GST_IS_EVENT (leak)) { - fprintf(stderr, "Error: queue [%s] leaked an event, type:%d\n", - GST_ELEMENT_NAME(GST_ELEMENT(queue)), - GST_EVENT_TYPE(GST_EVENT(leak))); - } else { - queue->level_bytes -= GST_BUFFER_SIZE(leak); + for (item = queue->queue->head; item != NULL; item = item->next) { + if (GST_IS_BUFFER (item->data)) { + leak = item->data; + break; + } } - gst_data_unref (leak); + /* if we didn't find anything, it means we have no buffers + * in here. That cannot happen, since we had >= 1 bufs */ + g_assert (leak); + + /* Now remove it from the list, fixing up the GQueue + * CHECKME: is a queue->head the first or the last item? */ + item = g_list_delete_link (queue->queue->head, item); + queue->queue->head = g_list_first (item); + queue->queue->tail = g_list_last (item); + queue->queue->length--; + + /* and unref the data at the end. Twice, because we keep a ref + * to make things read-only. Also keep our list uptodate. */ + queue->cur_level.bytes -= GST_BUFFER_SIZE (data); + queue->cur_level.buffers --; + if (GST_BUFFER_DURATION (data) != GST_CLOCK_TIME_NONE) + queue->cur_level.time -= GST_BUFFER_DURATION (data); + + gst_data_unref (data); + gst_data_unref (data); + break; } - } - GST_CAT_LOG_OBJECT (GST_CAT_DATAFLOW, queue, "pre full wait, level:%d/%d buffers, %d bytes", - queue->level_buffers, queue->size_buffers, queue->level_bytes); + default: + g_warning ("Unknown leaky type, using default"); + /* fall-through */ - 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 (queue->interrupt) { - GST_CAT_DEBUG_OBJECT (GST_CAT_DATAFLOW, queue, "interrupted!!"); + /* don't leak. Instead, wait for space to be available */ + case GST_QUEUE_NO_LEAK: + STATUS (queue, "pre-full wait"); + + while ((queue->max_size.buffers > 0 && + queue->cur_level.buffers >= queue->max_size.buffers) || + (queue->max_size.bytes > 0 && + queue->cur_level.bytes >= queue->max_size.bytes) || + (queue->max_size.time > 0 && + queue->cur_level.time >= queue->max_size.time)) { + /* 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 (queue->interrupt) { + GST_CAT_DEBUG_OBJECT (GST_CAT_DATAFLOW, queue, "interrupted"); + g_mutex_unlock (queue->qlock); + if (gst_scheduler_interrupt (gst_pad_get_scheduler (queue->sinkpad), + GST_ELEMENT (queue))) { + goto out_unref; + } + /* if we got here because we were unlocked after a + * flush, we don't need to add the buffer to the + * queue again */ + if (queue->flush) { + GST_CAT_DEBUG_OBJECT (GST_CAT_DATAFLOW, queue, + "not adding pending buffer after flush"); + goto out_unref; + } + GST_CAT_DEBUG_OBJECT (GST_CAT_DATAFLOW, queue, + "adding pending buffer after interrupt"); + goto restart; + } + + if (GST_STATE (queue) != GST_STATE_PLAYING) { + /* this means the other end is shut down. Try to + * signal to resolve the error */ + if (!queue->may_deadlock) { + g_mutex_unlock (queue->qlock); + gst_data_unref (data); + gst_element_error (GST_ELEMENT (queue), + "deadlock found, source pad elements are shut down"); + /* we don't go to out_unref here, since we want to + * unref the buffer *before* calling gst_element_error */ + return; + } else { + GST_CAT_WARNING_OBJECT (GST_CAT_DATAFLOW, queue, + "%s: waiting for the app to restart " + "source pad elements", + GST_ELEMENT_NAME (queue)); + } + } + + /* OK, we've got a serious issue here. Imagine the situation + * where the puller (next element) is sending an event here, + * so it cannot pull events from the queue, and we cannot + * push data further because the queue is 'full' and therefore, + * we wait here (and do not handle events): deadlock! to solve + * that, we handle pending upstream events here, too. */ + gst_queue_handle_pending_events (queue); + + STATUS (queue, "waiting for item_del signal"); + g_cond_wait (queue->item_del, queue->qlock); + STATUS (queue, "received item_del signal"); + } + + STATUS (queue, "post-full wait"); g_mutex_unlock (queue->qlock); - if (gst_scheduler_interrupt (gst_pad_get_scheduler (queue->sinkpad), GST_ELEMENT (queue))) - goto out_unref; - /* if we got here because we were unlocked after a flush, we don't need - * to add the buffer to the queue again */ - if (queue->flush) { - GST_CAT_DEBUG_OBJECT (GST_CAT_DATAFLOW, queue, "not adding pending buffer after flush"); - goto out_unref; - } - GST_CAT_DEBUG_OBJECT (GST_CAT_DATAFLOW, queue, "adding pending buffer after interrupt"); - goto restart; - } - if (GST_STATE (queue) != GST_STATE_PLAYING) { - /* this means the other end is shut down */ - /* try to signal to resolve the error */ - if (!queue->may_deadlock) { - g_mutex_unlock (queue->qlock); - gst_data_unref (data); - gst_element_error (GST_ELEMENT (queue), "deadlock found, source pad elements are shut down"); - /* we don't want to goto out_unref here, since we want to clean up before calling gst_element_error */ - return; - } - else { - g_print ("%s: waiting for the app to restart source pad elements\n", GST_ELEMENT_NAME (queue)); - } - } - - GST_CAT_DEBUG_OBJECT (GST_CAT_DATAFLOW, queue, "waiting for not_full, level:%d/%d buffers, %d bytes", - queue->level_buffers, queue->size_buffers, queue->level_bytes); - g_cond_wait (queue->not_full, queue->qlock); - GST_CAT_DEBUG_OBJECT (GST_CAT_DATAFLOW, queue, "got not_full signal"); + g_signal_emit (G_OBJECT (queue), gst_queue_signals[SIGNAL_RUNNING], 0); + g_mutex_lock (queue->qlock); + break; } - GST_CAT_LOG_OBJECT (GST_CAT_DATAFLOW, queue, "post full wait, level:%d/%d buffers, %d bytes", - queue->level_buffers, queue->size_buffers, queue->level_bytes); } - /* put the buffer on the tail of the list */ + /* put the buffer on the tail of the list. We keep a reference, + * so that the data is read-only while in here. There's a good + * reason to do so: we have a size and time counter, and any + * modification to the content could change any of the two. */ + gst_data_ref (data); g_queue_push_tail (queue->queue, data); - queue->level_buffers++; - if (GST_IS_BUFFER (data)) - queue->level_bytes += GST_BUFFER_SIZE (data); + /* Note that we only add buffers (not events) to the statistics */ + if (GST_IS_BUFFER (data)) { + queue->cur_level.buffers++; + queue->cur_level.bytes += GST_BUFFER_SIZE (data); + if (GST_BUFFER_DURATION (data) != GST_CLOCK_TIME_NONE) + queue->cur_level.time += GST_BUFFER_DURATION (data); + } - /* this assertion _has_ to hold */ - g_assert (queue->queue->length == queue->level_buffers); + STATUS (queue, "+ level"); - GST_CAT_LOG_OBJECT (GST_CAT_DATAFLOW, queue, "(%s:%s)+ level:%d/%d buffers, %d bytes", - GST_DEBUG_PAD_NAME(pad), - queue->level_buffers, queue->size_buffers, queue->level_bytes); - - GST_CAT_LOG_OBJECT (GST_CAT_DATAFLOW, queue, "signalling not_empty"); - g_cond_signal (queue->not_empty); + GST_CAT_LOG_OBJECT (GST_CAT_DATAFLOW, queue, "signalling item_add"); + g_cond_signal (queue->item_add); g_mutex_unlock (queue->qlock); return; @@ -473,96 +625,123 @@ static GstData * gst_queue_get (GstPad *pad) { GstQueue *queue; - GstData *data = NULL; - gpointer front; + GstData *data; - g_assert(pad != NULL); - g_assert(GST_IS_PAD(pad)); g_return_val_if_fail (pad != NULL, NULL); g_return_val_if_fail (GST_IS_PAD (pad), NULL); - queue = GST_QUEUE (GST_OBJECT_PARENT (pad)); + queue = GST_QUEUE (gst_pad_get_parent (pad)); restart: /* have to lock for thread-safety */ - GST_CAT_LOG_OBJECT (GST_CAT_DATAFLOW, queue, "locking t:%p", g_thread_self ()); + GST_CAT_LOG_OBJECT (GST_CAT_DATAFLOW, queue, + "locking t:%p", g_thread_self ()); g_mutex_lock (queue->qlock); - GST_CAT_LOG_OBJECT (GST_CAT_DATAFLOW, queue, "locked t:%p %p", g_thread_self (), queue->not_empty); + GST_CAT_LOG_OBJECT (GST_CAT_DATAFLOW, queue, + "locked t:%p", g_thread_self ()); - GST_CAT_LOG_OBJECT (GST_CAT_DATAFLOW, queue, "pre empty wait, level:%d/%d buffers, %d bytes", - queue->level_buffers, queue->size_buffers, queue->level_bytes); - 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 - */ - //while (GST_STATE_PENDING (queue) != GST_STATE_VOID_PENDING) { - if (queue->interrupt) { - GST_CAT_DEBUG_OBJECT (GST_CAT_DATAFLOW, queue, "interrupted!!"); - g_mutex_unlock (queue->qlock); - if (gst_scheduler_interrupt (gst_pad_get_scheduler (queue->srcpad), GST_ELEMENT (queue))) - return GST_DATA (gst_event_new (GST_EVENT_INTERRUPT)); - goto restart; - } - if (GST_STATE (queue) != GST_STATE_PLAYING) { - /* this means the other end is shut down */ - if (!queue->may_deadlock) { + if (queue->queue->length == 0 || + (queue->min_treshold.buffers > 0 && + queue->cur_level.buffers < queue->min_treshold.buffers) || + (queue->min_treshold.bytes > 0 && + queue->cur_level.bytes < queue->min_treshold.bytes) || + (queue->min_treshold.time > 0 && + queue->cur_level.time < queue->min_treshold.time)) { + g_mutex_unlock (queue->qlock); + g_signal_emit (G_OBJECT (queue), gst_queue_signals[SIGNAL_UNDERRUN], 0); + g_mutex_lock (queue->qlock); + + STATUS (queue, "pre-empty wait"); + while (queue->queue->length == 0 || + (queue->min_treshold.buffers > 0 && + queue->cur_level.buffers < queue->min_treshold.buffers) || + (queue->min_treshold.bytes > 0 && + queue->cur_level.bytes < queue->min_treshold.bytes) || + (queue->min_treshold.time > 0 && + queue->cur_level.time < queue->min_treshold.time)) { + /* 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 (queue->interrupt) { + GST_CAT_DEBUG_OBJECT (GST_CAT_DATAFLOW, queue, "interrupted"); g_mutex_unlock (queue->qlock); - gst_element_error (GST_ELEMENT (queue), "deadlock found, sink pad elements are shut down"); + if (gst_scheduler_interrupt (gst_pad_get_scheduler (queue->srcpad), + GST_ELEMENT (queue))) + return GST_DATA (gst_event_new (GST_EVENT_INTERRUPT)); goto restart; } - else { - g_print ("%s: waiting for the app to restart source pad elements\n", GST_ELEMENT_NAME (queue)); + if (GST_STATE (queue) != GST_STATE_PLAYING) { + /* this means the other end is shut down */ + if (!queue->may_deadlock) { + g_mutex_unlock (queue->qlock); + gst_element_error (GST_ELEMENT (queue), + "deadlock found, sink pad elements are shut down"); + goto restart; + } else { + GST_CAT_WARNING_OBJECT (GST_CAT_DATAFLOW, queue, + "%s: waiting for the app to restart " + "source pad elements", + GST_ELEMENT_NAME (queue)); + } } - } - GST_CAT_DEBUG_OBJECT (GST_CAT_DATAFLOW, queue, "waiting for not_empty, level:%d/%d buffers, %d bytes", - queue->level_buffers, queue->size_buffers, queue->level_bytes); + STATUS (queue, "waiting for item_add"); - /* if (queue->block_timeout > -1){ */ - if (FALSE) { - GTimeVal timeout; - g_get_current_time(&timeout); - g_time_val_add(&timeout, queue->block_timeout); - if (!g_cond_timed_wait (queue->not_empty, queue->qlock, &timeout)){ - g_mutex_unlock (queue->qlock); - g_warning ("filler"); - return GST_DATA (gst_event_new_filler()); + if (queue->block_timeout != GST_CLOCK_TIME_NONE) { + GTimeVal timeout; + g_get_current_time (&timeout); + g_time_val_add (&timeout, queue->block_timeout / 1000); + if (!g_cond_timed_wait (queue->item_add, queue->qlock, &timeout)){ + g_mutex_unlock (queue->qlock); + GST_CAT_WARNING_OBJECT (GST_CAT_DATAFLOW, queue, + "Sending filler event"); + return GST_DATA (gst_event_new_filler ()); + } + } else { + g_cond_wait (queue->item_add, queue->qlock); } + STATUS (queue, "got item_add signal"); } - else { - g_cond_wait (queue->not_empty, queue->qlock); - } - GST_CAT_DEBUG_OBJECT (GST_CAT_DATAFLOW, queue, "got not_empty signal"); + + STATUS (queue, "post-empty wait"); + g_mutex_unlock (queue->qlock); + g_signal_emit (G_OBJECT (queue), gst_queue_signals[SIGNAL_RUNNING], 0); + g_mutex_lock (queue->qlock); } - GST_CAT_LOG_OBJECT (GST_CAT_DATAFLOW, queue, "post empty wait, level:%d/%d buffers, %d bytes", - queue->level_buffers, queue->size_buffers, queue->level_bytes); - front = g_queue_pop_head (queue->queue); - data = GST_DATA (front); - GST_CAT_LOG_OBJECT (GST_CAT_DATAFLOW, queue, "retrieved data %p from queue", data); + /* There's something in the list now, whatever it is */ + data = g_queue_pop_head (queue->queue); + GST_CAT_LOG_OBJECT (GST_CAT_DATAFLOW, queue, + "retrieved data %p from queue", data); - queue->level_buffers--; - if (GST_IS_BUFFER (data)) - queue->level_bytes -= GST_BUFFER_SIZE (data); + if (GST_IS_BUFFER (data)) { + /* Update statistics */ + queue->cur_level.buffers--; + queue->cur_level.bytes -= GST_BUFFER_SIZE (data); + if (GST_BUFFER_DURATION (data) != GST_CLOCK_TIME_NONE) + queue->cur_level.time -= GST_BUFFER_DURATION (data); + } - GST_CAT_LOG_OBJECT (GST_CAT_DATAFLOW, queue, "(%s:%s)- level:%d/%d buffers, %d bytes", - GST_DEBUG_PAD_NAME(pad), - queue->level_buffers, queue->size_buffers, queue->level_bytes); + /* Now that we're done, we can lose our own reference to + * the item, since we're no longer in danger. */ + gst_data_unref (data); - /* this assertion _has_ to hold */ - g_assert (queue->queue->length == queue->level_buffers); - - GST_CAT_LOG_OBJECT (GST_CAT_DATAFLOW, queue, "signalling not_full"); - g_cond_signal (queue->not_full); + STATUS (queue, "after _get()"); + GST_CAT_LOG_OBJECT (GST_CAT_DATAFLOW, queue, "signalling item_del"); + g_cond_signal (queue->item_del); g_mutex_unlock (queue->qlock); - /* FIXME where should this be? locked? */ + /* FIXME: I suppose this needs to be locked, since the EOS + * bit affects the pipeline state. However, that bit is + * locked too so it'd cause a deadlock. */ if (GST_IS_EVENT (data)) { GstEvent *event = GST_EVENT (data); - switch (GST_EVENT_TYPE(event)) { + switch (GST_EVENT_TYPE (event)) { case GST_EVENT_EOS: - GST_CAT_DEBUG_OBJECT (GST_CAT_DATAFLOW, queue, "queue \"%s\" eos", GST_ELEMENT_NAME (queue)); + GST_CAT_DEBUG_OBJECT (GST_CAT_DATAFLOW, queue, + "queue \"%s\" eos", + GST_ELEMENT_NAME (queue)); gst_element_set_eos (GST_ELEMENT (queue)); break; default: @@ -575,47 +754,49 @@ restart: static gboolean -gst_queue_handle_src_event (GstPad *pad, GstEvent *event) +gst_queue_handle_src_event (GstPad *pad, + GstEvent *event) { - GstQueue *queue; + GstQueue *queue = GST_QUEUE (gst_pad_get_parent (pad)); gboolean res; - gint event_type; - gint flag_flush = 0; - - queue = GST_QUEUE (GST_OBJECT_PARENT (pad)); g_mutex_lock (queue->qlock); if (gst_element_get_state (GST_ELEMENT (queue)) == GST_STATE_PLAYING) { - /* push the event to the queue for upstream consumption */ - g_async_queue_push(queue->events, event); - g_warning ("FIXME: sending event in a running queue"); - /* FIXME wait for delivery of the event here, then return the result - * instead of FALSE */ - res = FALSE; - goto done; - } + GstQueueEventResponse er; - event_type = GST_EVENT_TYPE (event); - if (event_type == GST_EVENT_SEEK) - flag_flush = GST_EVENT_SEEK_FLAGS (event) & GST_SEEK_FLAG_FLUSH; + /* push the event to the queue and wait for upstream consumption */ + er.event = event; + er.handled = FALSE; + g_queue_push_tail (queue->events, &er); + GST_CAT_WARNING_OBJECT (GST_CAT_DATAFLOW, queue, + "Preparing for loop for event handler"); + /* see the chain function on why this is here - it prevents a deadlock */ + g_cond_signal (queue->item_del); + while (!er.handled) { + g_cond_wait (queue->event_done, queue->qlock); + } + GST_CAT_WARNING_OBJECT (GST_CAT_DATAFLOW, queue, + "Event handled"); + res = er.ret; + } else { + res = gst_pad_event_default (pad, event); - res = gst_pad_event_default (pad, event); - - switch (event_type) { - case GST_EVENT_FLUSH: - GST_CAT_DEBUG_OBJECT (GST_CAT_DATAFLOW, queue, "FLUSH event, flushing queue\n"); - gst_queue_locked_flush (queue); - break; - case GST_EVENT_SEEK: - if (flag_flush) { + switch (GST_EVENT_TYPE (event)) { + case GST_EVENT_FLUSH: + GST_CAT_DEBUG_OBJECT (GST_CAT_DATAFLOW, queue, + "FLUSH event, flushing queue\n"); gst_queue_locked_flush (queue); - } - default: - break; + break; + case GST_EVENT_SEEK: + if (GST_EVENT_SEEK_FLAGS (event) & GST_SEEK_FLAG_FLUSH) { + gst_queue_locked_flush (queue); + } + default: + break; + } } -done: g_mutex_unlock (queue->qlock); /* we have to claim success, but we don't really know */ @@ -631,8 +812,8 @@ gst_queue_release_locks (GstElement *element) g_mutex_lock (queue->qlock); queue->interrupt = TRUE; - g_cond_signal (queue->not_full); - g_cond_signal (queue->not_empty); + g_cond_signal (queue->item_add); + g_cond_signal (queue->item_del); g_mutex_unlock (queue->qlock); return TRUE; @@ -642,7 +823,7 @@ static GstElementStateReturn gst_queue_change_state (GstElement *element) { GstQueue *queue; - GstElementStateReturn ret; + GstElementStateReturn ret = GST_STATE_SUCCESS; queue = GST_QUEUE (element); @@ -657,29 +838,29 @@ gst_queue_change_state (GstElement *element) case GST_STATE_NULL_TO_READY: gst_queue_locked_flush (queue); break; - case GST_STATE_READY_TO_PAUSED: - break; case GST_STATE_PAUSED_TO_PLAYING: if (!GST_PAD_IS_LINKED (queue->sinkpad)) { - GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, queue, "queue %s is not linked", GST_ELEMENT_NAME (queue)); + GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, queue, + "queue %s is not linked", + GST_ELEMENT_NAME (queue)); /* FIXME can this be? */ - g_cond_signal (queue->not_empty); + g_cond_signal (queue->item_add); ret = GST_STATE_FAILURE; goto error; - } - else { + } else { GstScheduler *src_sched, *sink_sched; - src_sched = gst_pad_get_scheduler (GST_PAD_CAST (queue->srcpad)); - sink_sched = gst_pad_get_scheduler (GST_PAD_CAST (queue->sinkpad)); + src_sched = gst_pad_get_scheduler (GST_PAD (queue->srcpad)); + sink_sched = gst_pad_get_scheduler (GST_PAD (queue->sinkpad)); if (src_sched == sink_sched) { - GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, queue, "queue %s does not connect different schedulers", - GST_ELEMENT_NAME (queue)); + GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, queue, + "queue %s does not connect different schedulers", + GST_ELEMENT_NAME (queue)); g_warning ("queue %s does not connect different schedulers", - GST_ELEMENT_NAME (queue)); + GST_ELEMENT_NAME (queue)); ret = GST_STATE_FAILURE; goto error; @@ -687,18 +868,19 @@ gst_queue_change_state (GstElement *element) } queue->interrupt = FALSE; break; - case GST_STATE_PLAYING_TO_PAUSED: - break; case GST_STATE_PAUSED_TO_READY: gst_queue_locked_flush (queue); break; - case GST_STATE_READY_TO_NULL: + default: break; } - ret = GST_ELEMENT_CLASS (parent_class)->change_state (element); - /* this is an ugly hack to make sure our pads are always active. Reason for this is that - * pad activation for the queue element depends on 2 schedulers (ugh) */ + if (GST_ELEMENT_CLASS (parent_class)->change_state) + ret = GST_ELEMENT_CLASS (parent_class)->change_state (element); + + /* this is an ugly hack to make sure our pads are always active. + * Reason for this is that pad activation for the queue element + * depends on 2 schedulers (ugh) */ gst_pad_set_active (queue->sinkpad, TRUE); gst_pad_set_active (queue->srcpad, TRUE); @@ -706,70 +888,103 @@ error: g_mutex_unlock (queue->qlock); GST_CAT_LOG_OBJECT (GST_CAT_STATES, element, "done with state change"); + return ret; } static void -gst_queue_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) +gst_queue_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) { - GstQueue *queue; + GstQueue *queue = GST_QUEUE (object); - /* it's not null if we got it, but it might not be ours */ - g_return_if_fail (GST_IS_QUEUE (object)); - - queue = GST_QUEUE (object); + /* someone could change levels here, and since this + * affects the get/put funcs, we need to lock for safety. */ + g_mutex_lock (queue->qlock); switch (prop_id) { + case ARG_MAX_SIZE_BYTES: + queue->max_size.bytes = g_value_get_uint (value); + break; + case ARG_MAX_SIZE_BUFFERS: + queue->max_size.buffers = g_value_get_uint (value); + break; + case ARG_MAX_SIZE_TIME: + queue->max_size.time = g_value_get_uint64 (value); + break; + case ARG_MIN_TRESHOLD_BYTES: + queue->max_size.bytes = g_value_get_uint (value); + break; + case ARG_MIN_TRESHOLD_BUFFERS: + queue->max_size.buffers = g_value_get_uint (value); + break; + case ARG_MIN_TRESHOLD_TIME: + queue->max_size.time = g_value_get_uint64 (value); + break; case ARG_LEAKY: queue->leaky = g_value_get_enum (value); break; - case ARG_MAX_LEVEL: - queue->size_buffers = g_value_get_int (value); - break; - case ARG_MIN_THRESHOLD_BYTES: - queue->min_threshold_bytes = g_value_get_int (value); - break; case ARG_MAY_DEADLOCK: queue->may_deadlock = g_value_get_boolean (value); break; case ARG_BLOCK_TIMEOUT: - queue->block_timeout = g_value_get_int (value); + queue->block_timeout = g_value_get_uint64 (value); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } + + g_mutex_unlock (queue->qlock); } static void -gst_queue_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) +gst_queue_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) { - GstQueue *queue; - - /* it's not null if we got it, but it might not be ours */ - g_return_if_fail (GST_IS_QUEUE (object)); - - queue = GST_QUEUE (object); + GstQueue *queue = GST_QUEUE (object); switch (prop_id) { + case ARG_CUR_LEVEL_BYTES: + g_value_set_uint (value, queue->cur_level.bytes); + break; + case ARG_CUR_LEVEL_BUFFERS: + g_value_set_uint (value, queue->cur_level.buffers); + break; + case ARG_CUR_LEVEL_TIME: + g_value_set_uint64 (value, queue->cur_level.time); + break; + case ARG_MAX_SIZE_BYTES: + g_value_set_uint (value, queue->max_size.bytes); + break; + case ARG_MAX_SIZE_BUFFERS: + g_value_set_uint (value, queue->max_size.buffers); + break; + case ARG_MAX_SIZE_TIME: + g_value_set_uint64 (value, queue->max_size.time); + break; + case ARG_MIN_TRESHOLD_BYTES: + g_value_set_uint (value, queue->min_treshold.bytes); + break; + case ARG_MIN_TRESHOLD_BUFFERS: + g_value_set_uint (value, queue->min_treshold.buffers); + break; + case ARG_MIN_TRESHOLD_TIME: + g_value_set_uint64 (value, queue->min_treshold.time); + break; case ARG_LEAKY: g_value_set_enum (value, queue->leaky); break; - case ARG_LEVEL: - g_value_set_int (value, queue->level_buffers); - break; - case ARG_MAX_LEVEL: - g_value_set_int (value, queue->size_buffers); - break; - case ARG_MIN_THRESHOLD_BYTES: - g_value_set_int (value, queue->min_threshold_bytes); - break; case ARG_MAY_DEADLOCK: g_value_set_boolean (value, queue->may_deadlock); break; case ARG_BLOCK_TIMEOUT: - g_value_set_int (value, queue->block_timeout); + g_value_set_uint64 (value, queue->block_timeout); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); diff --git a/gst/gstqueue.h b/gst/gstqueue.h index c52d637730..5e87b899e5 100644 --- a/gst/gstqueue.h +++ b/gst/gstqueue.h @@ -56,43 +56,51 @@ struct _GstQueue { GstPad *sinkpad; GstPad *srcpad; - /* the queue of buffers we're keeping our grubby hands on */ + /* the queue of data we're keeping our grubby hands on */ GQueue *queue; - guint level_buffers; /* number of buffers queued here */ - guint level_bytes; /* number of bytes queued here */ - guint64 level_time; /* amount of time queued here */ + struct { + guint buffers; /* no. of buffers */ + guint bytes; /* no. of bytes */ + guint64 time; /* amount of time */ + } cur_level, /* currently in the queue */ + max_size, /* max. amount of data allowed in the queue */ + min_treshold; /* min. amount of data required to wake reader */ - guint size_buffers; /* size of queue in buffers */ - guint size_bytes; /* size of queue in bytes */ - guint64 size_time; /* size of queue in time */ + /* whether we leak data, and at which end */ + gint leaky; + + /* number of nanoseconds until a blocked queue 'times out' + * to receive data and returns a filler event. -1 = disable */ + guint64 block_timeout; + + /* it the queue should fail on possible deadlocks */ + gboolean may_deadlock; - gint leaky; /* whether the queue is leaky, and if so at which end */ - gint block_timeout; /* microseconds until a blocked queue times out and returns GST_EVENT_FILLER. - * A value of -1 will block forever. */ - guint min_threshold_bytes; /* the minimum number of bytes required before - * waking up the reader thread */ - gboolean may_deadlock; /* it the queue should fail on possible deadlocks */ gboolean interrupt; gboolean flush; GMutex *qlock; /* lock for queue (vs object lock) */ - GCond *not_empty; /* signals buffers now available for reading */ - GCond *not_full; /* signals space now available for writing */ + GCond *item_add; /* signals buffers now available for reading */ + GCond *item_del; /* signals space now available for writing */ + GCond *event_done; /* upstream event signaller */ GTimeVal *timeval; /* the timeout for the queue locking */ - GAsyncQueue *events; /* upstream events get decoupled here */ + GQueue *events; /* upstream events get decoupled here */ - GST_OBJECT_PADDING + gpointer _gst_reserved[GST_PADDING]; }; struct _GstQueueClass { GstElementClass parent_class; - /* signal callbacks */ - void (*full) (GstQueue *queue); + /* signals - 'running' is called from both sides + * which might make it sort of non-useful... */ + void (*underrun) (GstQueue *queue); + void (*running) (GstQueue *queue); + void (*overrun) (GstQueue *queue); - GST_CLASS_PADDING + gpointer _gst_reserved[GST_PADDING]; }; GType gst_queue_get_type (void); diff --git a/gst/gstregistry.h b/gst/gstregistry.h index 7889ef34a7..ed10727216 100644 --- a/gst/gstregistry.h +++ b/gst/gstregistry.h @@ -86,7 +86,7 @@ struct _GstRegistry { GList *paths; - GST_OBJECT_PADDING + gpointer _gst_reserved[GST_PADDING]; }; struct _GstRegistryClass { @@ -105,7 +105,7 @@ struct _GstRegistryClass { /* signals */ void (*plugin_added) (GstRegistry *registry, GstPlugin *plugin); - GST_CLASS_PADDING + gpointer _gst_reserved[GST_PADDING]; }; diff --git a/gst/gstscheduler.c b/gst/gstscheduler.c index c829fab915..d194b67cb8 100644 --- a/gst/gstscheduler.c +++ b/gst/gstscheduler.c @@ -799,8 +799,14 @@ gst_scheduler_factory_class_init (GstSchedulerFactoryClass *klass) factory_parent_class = g_type_class_ref (GST_TYPE_PLUGIN_FEATURE); - if (!_default_name) - _default_name = g_strdup (GST_SCHEDULER_DEFAULT_NAME); + if (!_default_name) { + if (g_getenv ("GST_SCHEDULER")) { + _default_name = g_strdup (g_getenv ("GST_SCHEDULER")); + } else { + _default_name = g_strdup (GST_SCHEDULER_DEFAULT_NAME); + } + } + g_assert (_default_name); } static void diff --git a/gst/gstscheduler.h b/gst/gstscheduler.h index 22cbf76187..9233c526cb 100644 --- a/gst/gstscheduler.h +++ b/gst/gstscheduler.h @@ -72,7 +72,7 @@ struct _GstScheduler { GList *schedulers; - GST_OBJECT_PADDING + gpointer _gst_reserved[GST_PADDING]; }; struct _GstSchedulerClass { @@ -105,7 +105,7 @@ struct _GstSchedulerClass { void (*object_sync) (GstScheduler *sched, GstClock *clock, GstObject *object, GstClockID id); - GST_CLASS_PADDING + gpointer _gst_reserved[GST_PADDING]; }; GType gst_scheduler_get_type (void); @@ -161,13 +161,13 @@ struct _GstSchedulerFactory { gchar *longdesc; /* long description of the scheduler (well, don't overdo it..) */ GType type; /* unique GType of the scheduler */ - GST_OBJECT_PADDING + gpointer _gst_reserved[GST_PADDING]; }; struct _GstSchedulerFactoryClass { GstPluginFeatureClass parent; - GST_CLASS_PADDING + gpointer _gst_reserved[GST_PADDING]; }; GType gst_scheduler_factory_get_type (void); diff --git a/gst/gstsystemclock.h b/gst/gstsystemclock.h index 5f4170be76..33c03533bd 100644 --- a/gst/gstsystemclock.h +++ b/gst/gstsystemclock.h @@ -45,13 +45,13 @@ struct _GstSystemClock { GMutex * mutex; GCond * cond; - GST_OBJECT_PADDING + gpointer _gst_reserved[GST_PADDING]; }; struct _GstSystemClockClass { GstClockClass parent_class; - GST_CLASS_PADDING + gpointer _gst_reserved[GST_PADDING]; }; GType gst_system_clock_get_type (void); diff --git a/gst/gstthread.h b/gst/gstthread.h index 3d554e2915..62142bce0e 100644 --- a/gst/gstthread.h +++ b/gst/gstthread.h @@ -63,7 +63,7 @@ struct _GstThread { GMutex *lock; /* thread lock/condititon pairs */ GCond *cond; /* used to control the thread */ - GST_OBJECT_PADDING + gpointer _gst_reserved[GST_PADDING]; }; struct _GstThreadClass { @@ -72,7 +72,7 @@ struct _GstThreadClass { /* signals */ void (*shutdown) (GstThread *thread); - GST_CLASS_PADDING + gpointer _gst_reserved[GST_PADDING]; }; GType gst_thread_get_type (void); diff --git a/gst/gsttypefind.h b/gst/gsttypefind.h index 333d33362a..0008c3beb6 100644 --- a/gst/gsttypefind.h +++ b/gst/gsttypefind.h @@ -67,7 +67,7 @@ struct _GstTypeFind { guint64 (* get_length) (gpointer data); /* */ - GST_STRUCT_PADDING + gpointer _gst_reserved[GST_PADDING]; }; struct _GstTypeFindFactory { @@ -80,14 +80,14 @@ struct _GstTypeFindFactory { gpointer user_data; - GST_OBJECT_PADDING + gpointer _gst_reserved[GST_PADDING]; }; struct _GstTypeFindFactoryClass { GstPluginFeatureClass parent; /* */ - GST_CLASS_PADDING + gpointer _gst_reserved[GST_PADDING]; }; /* typefind function interface */ diff --git a/gst/gsttypes.h b/gst/gsttypes.h index ad4f029211..b9e8fb1961 100644 --- a/gst/gsttypes.h +++ b/gst/gsttypes.h @@ -63,11 +63,8 @@ typedef enum { #define GST_RANK_MARGINAL 64 #define GST_RANK_NONE 0 -#define GST_STRUCT_PADDING gpointer _gst_reserved[4]; -#define GST_CLASS_PADDING gpointer _gst_reserved[4]; -#define GST_OBJECT_PADDING gpointer _gst_reserved[4]; - -#define GST_STRUCT_PADDING_INIT {NULL, NULL, NULL, NULL} +#define GST_PADDING 4 +#define GST_PADDING_INIT { 0 } G_END_DECLS diff --git a/gst/gsturi.h b/gst/gsturi.h index 0d0a1093f6..20118abbb9 100644 --- a/gst/gsturi.h +++ b/gst/gsturi.h @@ -73,7 +73,7 @@ struct _GstURIHandlerInterface { /* we might want to add functions here to query features, someone with gnome-vfs knowledge go ahead */ - GST_CLASS_PADDING + gpointer _gst_reserved[GST_PADDING]; }; /* general URI functions */ diff --git a/gst/gstxml.h b/gst/gstxml.h index 25bb32e2b0..6c12c3e181 100644 --- a/gst/gstxml.h +++ b/gst/gstxml.h @@ -49,7 +49,7 @@ struct _GstXML { xmlNsPtr ns; - GST_OBJECT_PADDING + gpointer _gst_reserved[GST_PADDING]; }; typedef struct _GstXMLNs GstXMLNs; @@ -61,7 +61,7 @@ struct _GstXMLClass { void (*object_loaded) (GstXML *xml, GstObject *object, xmlNodePtr self); void (*object_saved) (GstXML *xml, GstObject *object, xmlNodePtr self); - GST_CLASS_PADDING + gpointer _gst_reserved[GST_PADDING]; }; GType gst_xml_get_type (void); diff --git a/gst/indexers/gstindexers.c b/gst/indexers/gstindexers.c index 6894202a4d..5d4c4afff7 100644 --- a/gst/indexers/gstindexers.c +++ b/gst/indexers/gstindexers.c @@ -39,11 +39,10 @@ GST_PLUGIN_DEFINE ( GST_VERSION_MAJOR, GST_VERSION_MINOR, "gstindexers", - "Gstremaer core indexers", + "GStreamer core indexers", plugin_init, VERSION, GST_LICENSE, - GST_COPYRIGHT, GST_PACKAGE, GST_ORIGIN ) diff --git a/gst/parse/parse.l b/gst/parse/parse.l index 95fb0c5ff8..761f2ee80b 100644 --- a/gst/parse/parse.l +++ b/gst/parse/parse.l @@ -42,9 +42,10 @@ _ref {_identifier}"."{_identifier}? _binref {_identifier}[[:space:]]*"."[[:space:]]*"(" /* links */ -_capschar ("\\".)|([^[:space:]\;!\.\,\(\)\]\[]) +_mimechar ([[:alnum:]-]) +_mimetype ({_mimechar}+"/"{_mimechar}+)|("\""([^\"]|"\\\"")*"\"")|("'"([^']|"\\\"")*"'") +_capschar ("\\".)|([^[:space:]\;!\,\(\)\]\[]) _capsstring {_capschar}+|("\""([^\"]|"\\\"")*"\"")|("'"([^']|"\\\"")*"'") -_mimetype ({_capschar}+"/"{_capschar}+)|("\""([^\"]|"\\\"")*"\"")|("'"([^']|"\\\"")*"'") _caps {_mimetype}(","[^!]|{_capsstring})* _link ("!"[[:space:]]*{_caps}([[:space:]]*";"[[:space:]]*{_caps})*[[:space:]]*"!")|("!") diff --git a/gst/registries/gstxmlregistry.c b/gst/registries/gstxmlregistry.c index 4d0c0c0a1a..f6239a6e38 100644 --- a/gst/registries/gstxmlregistry.c +++ b/gst/registries/gstxmlregistry.c @@ -663,9 +663,6 @@ gst_xml_registry_parse_plugin (GMarkupParseContext *context, const gchar *tag, c else if (!strcmp (tag, "version")) { plugin->desc.version = g_strndup (text, text_len); } - else if (!strcmp (tag, "copyright")) { - plugin->desc.copyright = g_strndup (text, text_len); - } else if (!strcmp (tag, "license")) { plugin->desc.license = g_strndup (text, text_len); } @@ -1220,7 +1217,6 @@ gst_xml_registry_save_plugin (GstXMLRegistry *xmlregistry, GstPlugin *plugin) PUT_ESCAPED ("filename", plugin->filename); PUT_ESCAPED ("version", plugin->desc.version); PUT_ESCAPED ("license", plugin->desc.license); - PUT_ESCAPED ("copyright", plugin->desc.copyright); PUT_ESCAPED ("package", plugin->desc.package); PUT_ESCAPED ("origin", plugin->desc.origin); diff --git a/gst/schedulers/gstbasicscheduler.c b/gst/schedulers/gstbasicscheduler.c index fba3fb8401..574c5ac02e 100644 --- a/gst/schedulers/gstbasicscheduler.c +++ b/gst/schedulers/gstbasicscheduler.c @@ -34,8 +34,8 @@ GST_DEBUG_CATEGORY_STATIC(debug_scheduler); typedef struct _GstSchedulerChain GstSchedulerChain; -#define GST_ELEMENT_THREADSTATE(elem) (cothread*) (GST_ELEMENT_CAST (elem)->sched_private) -#define GST_RPAD_BUFPEN(pad) (GstData*) (GST_REAL_PAD_CAST(pad)->sched_private) +#define GST_ELEMENT_THREADSTATE(elem) (cothread*) (GST_ELEMENT (elem)->sched_private) +#define GST_RPAD_BUFPEN(pad) (GstData*) (GST_REAL_PAD(pad)->sched_private) #define GST_ELEMENT_COTHREAD_STOPPING GST_ELEMENT_SCHEDULER_PRIVATE1 #define GST_ELEMENT_IS_COTHREAD_STOPPING(element) GST_FLAG_IS_SET((element), GST_ELEMENT_COTHREAD_STOPPING) @@ -74,8 +74,7 @@ struct _GstSchedulerChain { #define GST_IS_BASIC_SCHEDULER_CLASS(obj) \ (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_BASIC_SCHEDULER)) -#define GST_BASIC_SCHEDULER_CAST(sched) ((GstBasicScheduler *)(sched)) -#define SCHED(element) GST_BASIC_SCHEDULER_CAST (GST_ELEMENT_SCHED (element)) +#define SCHED(element) GST_BASIC_SCHEDULER (GST_ELEMENT_SCHED (element)) typedef enum { GST_BASIC_SCHEDULER_STATE_NONE, @@ -273,7 +272,6 @@ GST_PLUGIN_DEFINE ( plugin_init, VERSION, GST_LICENSE, - GST_COPYRIGHT, GST_PACKAGE, GST_ORIGIN ) @@ -281,7 +279,7 @@ GST_PLUGIN_DEFINE ( static int gst_basic_scheduler_loopfunc_wrapper (int argc, char **argv) { - GstElement *element = GST_ELEMENT_CAST (argv); + GstElement *element = GST_ELEMENT (argv); G_GNUC_UNUSED const gchar *name = GST_ELEMENT_NAME (element); GST_DEBUG("entering loopfunc wrapper of %s", name); @@ -315,7 +313,7 @@ static int gst_basic_scheduler_chain_wrapper (int argc, char **argv) { GSList *already_iterated = NULL; - GstElement *element = GST_ELEMENT_CAST (argv); + GstElement *element = GST_ELEMENT (argv); G_GNUC_UNUSED const gchar *name = GST_ELEMENT_NAME (element); GST_DEBUG ("entered chain wrapper of element %s", name); @@ -387,7 +385,7 @@ gst_basic_scheduler_chain_wrapper (int argc, char **argv) static int gst_basic_scheduler_src_wrapper (int argc, char **argv) { - GstElement *element = GST_ELEMENT_CAST (argv); + GstElement *element = GST_ELEMENT (argv); GList *pads; GstRealPad *realpad; GstData *data = NULL; @@ -402,17 +400,17 @@ gst_basic_scheduler_src_wrapper (int argc, char **argv) if (!GST_IS_REAL_PAD (pads->data)) continue; - realpad = GST_REAL_PAD_CAST (pads->data); + realpad = GST_REAL_PAD (pads->data); pads = g_list_next (pads); if (GST_RPAD_DIRECTION (realpad) == GST_PAD_SRC && GST_PAD_IS_USABLE (realpad)) { GST_CAT_DEBUG (debug_dataflow, "calling _getfunc for %s:%s", GST_DEBUG_PAD_NAME (realpad)); g_return_val_if_fail (GST_RPAD_GETFUNC (realpad) != NULL, 0); - data = GST_RPAD_GETFUNC (realpad) (GST_PAD_CAST (realpad)); + data = GST_RPAD_GETFUNC (realpad) (GST_PAD (realpad)); if (data) { GST_CAT_DEBUG (debug_dataflow, "calling gst_pad_push on pad %s:%s %p", GST_DEBUG_PAD_NAME (realpad), data); - gst_pad_push (GST_PAD_CAST (realpad), data); + gst_pad_push (GST_PAD (realpad), data); } } } @@ -604,7 +602,7 @@ gst_basic_scheduler_cothreaded_chain (GstBin * bin, GstSchedulerChain * chain) while (elements) { gboolean decoupled; - element = GST_ELEMENT_CAST (elements->data); + element = GST_ELEMENT (elements->data); elements = g_list_next (elements); decoupled = GST_FLAG_IS_SET (element, GST_ELEMENT_DECOUPLED); @@ -650,7 +648,7 @@ gst_basic_scheduler_cothreaded_chain (GstBin * bin, GstSchedulerChain * chain) peerpad = GST_PAD_PEER (pad); if (peerpad) { - GstElement *peerelement = GST_ELEMENT_CAST (GST_PAD_PARENT (peerpad)); + GstElement *peerelement = GST_ELEMENT (GST_PAD_PARENT (peerpad)); gboolean different_sched = (peerelement->sched != GST_SCHEDULER (chain->sched)); gboolean peer_decoupled = GST_FLAG_IS_SET (peerelement, GST_ELEMENT_DECOUPLED); @@ -1043,9 +1041,9 @@ static void gst_basic_scheduler_setup (GstScheduler *sched) { /* first create thread context */ - if (GST_BASIC_SCHEDULER_CAST (sched)->context == NULL) { + if (GST_BASIC_SCHEDULER (sched)->context == NULL) { GST_DEBUG ("initializing cothread context"); - GST_BASIC_SCHEDULER_CAST (sched)->context = do_cothread_context_init (); + GST_BASIC_SCHEDULER (sched)->context = do_cothread_context_init (); } } @@ -1053,7 +1051,7 @@ static void gst_basic_scheduler_reset (GstScheduler *sched) { cothread_context *ctx; - GList *elements = GST_BASIC_SCHEDULER_CAST (sched)->elements; + GList *elements = GST_BASIC_SCHEDULER (sched)->elements; while (elements) { GstElement *element = GST_ELEMENT (elements->data); @@ -1064,11 +1062,11 @@ gst_basic_scheduler_reset (GstScheduler *sched) elements = g_list_next (elements); } - ctx = GST_BASIC_SCHEDULER_CAST (sched)->context; + ctx = GST_BASIC_SCHEDULER (sched)->context; do_cothread_context_destroy (ctx); - GST_BASIC_SCHEDULER_CAST (sched)->context = NULL; + GST_BASIC_SCHEDULER (sched)->context = NULL; } static void @@ -1262,8 +1260,8 @@ gst_basic_scheduler_pad_unlink (GstScheduler * sched, GstPad * srcpad, GstPad * GST_DEBUG_PAD_NAME (srcpad), GST_DEBUG_PAD_NAME (sinkpad)); /* we need to have the parent elements of each pad */ - element1 = GST_ELEMENT_CAST (GST_PAD_PARENT (srcpad)); - element2 = GST_ELEMENT_CAST (GST_PAD_PARENT (sinkpad)); + 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, @@ -1391,7 +1389,7 @@ gst_basic_scheduler_iterate (GstScheduler * sched) GST_DEBUG ("there are %d elements in this chain", chain->num_elements); elements = chain->elements; while (elements) { - entry = GST_ELEMENT_CAST (elements->data); + entry = GST_ELEMENT (elements->data); elements = g_list_next (elements); if (GST_FLAG_IS_SET (entry, GST_ELEMENT_DECOUPLED)) { GST_DEBUG ("entry \"%s\" is DECOUPLED, skipping", diff --git a/gst/schedulers/gstoptimalscheduler.c b/gst/schedulers/gstoptimalscheduler.c index 4826f27736..ab6d4e98d8 100644 --- a/gst/schedulers/gstoptimalscheduler.c +++ b/gst/schedulers/gstoptimalscheduler.c @@ -36,9 +36,9 @@ GST_DEBUG_CATEGORY_STATIC(debug_scheduler); # define COTHREADS_NAME "" #endif -#define GST_ELEMENT_SCHED_CONTEXT(elem) ((GstOptSchedulerCtx*) (GST_ELEMENT_CAST (elem)->sched_private)) +#define GST_ELEMENT_SCHED_CONTEXT(elem) ((GstOptSchedulerCtx*) (GST_ELEMENT (elem)->sched_private)) #define GST_ELEMENT_SCHED_GROUP(elem) (GST_ELEMENT_SCHED_CONTEXT (elem)->group) -#define GST_PAD_BUFLIST(pad) ((GList*) (GST_REAL_PAD_CAST(pad)->sched_private)) +#define GST_PAD_BUFLIST(pad) ((GList*) (GST_REAL_PAD(pad)->sched_private)) #define GST_ELEMENT_COTHREAD_STOPPING GST_ELEMENT_SCHEDULER_PRIVATE1 #define GST_ELEMENT_IS_COTHREAD_STOPPING(element) GST_FLAG_IS_SET((element), GST_ELEMENT_COTHREAD_STOPPING) @@ -59,8 +59,6 @@ typedef struct _GstOptSchedulerClass GstOptSchedulerClass; #define GST_IS_OPT_SCHEDULER_CLASS(obj) \ (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_OPT_SCHEDULER)) -#define GST_OPT_SCHEDULER_CAST(sched) ((GstOptScheduler *)(sched)) - typedef enum { GST_OPT_SCHEDULER_STATE_NONE, GST_OPT_SCHEDULER_STATE_STOPPED, @@ -378,7 +376,6 @@ GST_PLUGIN_DEFINE ( plugin_init, VERSION, GST_LICENSE, - GST_VERSION, GST_PACKAGE, GST_ORIGIN ); @@ -954,7 +951,7 @@ get_group_schedule_function (int argc, char *argv[]) while (pads) { GstData *data; - GstPad *pad = GST_PAD_CAST (pads->data); + GstPad *pad = GST_PAD (pads->data); pads = g_list_next (pads); /* skip sinks and ghostpads */ @@ -1247,7 +1244,7 @@ setup_group_scheduler (GstOptScheduler *osched, GstOptSchedulerGroup *group) static GstElementStateReturn gst_opt_scheduler_state_transition (GstScheduler *sched, GstElement *element, gint transition) { - GstOptScheduler *osched = GST_OPT_SCHEDULER_CAST (sched); + GstOptScheduler *osched = GST_OPT_SCHEDULER (sched); GstOptSchedulerGroup *group; GstElementStateReturn res = GST_STATE_SUCCESS; @@ -1477,7 +1474,7 @@ static void gst_opt_scheduler_setup (GstScheduler *sched) { #ifdef USE_COTHREADS - GstOptScheduler *osched = GST_OPT_SCHEDULER_CAST (sched); + GstOptScheduler *osched = GST_OPT_SCHEDULER (sched); /* first create thread context */ if (osched->context == NULL) { @@ -1491,7 +1488,7 @@ static void gst_opt_scheduler_reset (GstScheduler *sched) { #ifdef USE_COTHREADS - GstOptScheduler *osched = GST_OPT_SCHEDULER_CAST (sched); + GstOptScheduler *osched = GST_OPT_SCHEDULER (sched); GSList *chains = osched->chains; while (chains) { @@ -1516,7 +1513,7 @@ gst_opt_scheduler_reset (GstScheduler *sched) static void gst_opt_scheduler_add_element (GstScheduler *sched, GstElement *element) { - GstOptScheduler *osched = GST_OPT_SCHEDULER_CAST (sched); + GstOptScheduler *osched = GST_OPT_SCHEDULER (sched); GstOptSchedulerCtx *ctx; const GList *pads; @@ -1584,14 +1581,14 @@ gst_opt_scheduler_remove_element (GstScheduler *sched, GstElement *element) static void gst_opt_scheduler_lock_element (GstScheduler *sched, GstElement *element) { - //GstOptScheduler *osched = GST_OPT_SCHEDULER_CAST (sched); + //GstOptScheduler *osched = GST_OPT_SCHEDULER (sched); g_warning ("lock element, implement me"); } static void gst_opt_scheduler_unlock_element (GstScheduler *sched, GstElement *element) { - //GstOptScheduler *osched = GST_OPT_SCHEDULER_CAST (sched); + //GstOptScheduler *osched = GST_OPT_SCHEDULER (sched); g_warning ("unlock element, implement me"); } @@ -1625,7 +1622,7 @@ gst_opt_scheduler_interrupt (GstScheduler *sched, GstElement *element) return FALSE; #else { - GstOptScheduler *osched = GST_OPT_SCHEDULER_CAST (sched); + GstOptScheduler *osched = GST_OPT_SCHEDULER (sched); GST_INFO ( "scheduler set interrupted state"); osched->state = GST_OPT_SCHEDULER_STATE_INTERRUPTED; @@ -1637,7 +1634,7 @@ gst_opt_scheduler_interrupt (GstScheduler *sched, GstElement *element) static void gst_opt_scheduler_error (GstScheduler *sched, GstElement *element) { - GstOptScheduler *osched = GST_OPT_SCHEDULER_CAST (sched); + GstOptScheduler *osched = GST_OPT_SCHEDULER (sched); GstOptSchedulerGroup *group; get_group (element, &group); if (group) @@ -1650,7 +1647,7 @@ gst_opt_scheduler_error (GstScheduler *sched, GstElement *element) static void gst_opt_scheduler_pad_link (GstScheduler *sched, GstPad *srcpad, GstPad *sinkpad) { - GstOptScheduler *osched = GST_OPT_SCHEDULER_CAST (sched); + GstOptScheduler *osched = GST_OPT_SCHEDULER (sched); LinkType type = GST_OPT_INVALID; GstElement *element1, *element2; @@ -1828,7 +1825,7 @@ element_has_link_with_group (GstElement *element, GstOptSchedulerGroup *group, G /* see if the element has no more links to the peer group */ pads = gst_element_get_pad_list (element); while (pads && !linked) { - GstPad *pad = GST_PAD_CAST (pads->data); + GstPad *pad = GST_PAD (pads->data); pads = g_list_next (pads); /* we only operate on real pads and on the pad that is not broken */ @@ -1916,7 +1913,7 @@ group_can_reach_group (GstOptSchedulerGroup *group, GstOptSchedulerGroup *target static void gst_opt_scheduler_pad_unlink (GstScheduler *sched, GstPad *srcpad, GstPad *sinkpad) { - GstOptScheduler *osched = GST_OPT_SCHEDULER_CAST (sched); + GstOptScheduler *osched = GST_OPT_SCHEDULER (sched); GstElement *element1, *element2; GstOptSchedulerGroup *group1, *group2; @@ -2040,7 +2037,7 @@ gst_opt_scheduler_pad_unlink (GstScheduler *sched, GstPad *srcpad, GstPad *sinkp static void gst_opt_scheduler_pad_select (GstScheduler *sched, GList *padlist) { - //GstOptScheduler *osched = GST_OPT_SCHEDULER_CAST (sched); + //GstOptScheduler *osched = GST_OPT_SCHEDULER (sched); g_warning ("pad select, implement me"); } @@ -2057,7 +2054,7 @@ static GstSchedulerState gst_opt_scheduler_iterate (GstScheduler *sched) { GstSchedulerState state = GST_SCHEDULER_STATE_STOPPED; - GstOptScheduler *osched = GST_OPT_SCHEDULER_CAST (sched); + GstOptScheduler *osched = GST_OPT_SCHEDULER (sched); gint iterations = osched->iterations; osched->state = GST_OPT_SCHEDULER_STATE_RUNNING; @@ -2121,7 +2118,7 @@ gst_opt_scheduler_iterate (GstScheduler *sched) static void gst_opt_scheduler_show (GstScheduler *sched) { - GstOptScheduler *osched = GST_OPT_SCHEDULER_CAST (sched); + GstOptScheduler *osched = GST_OPT_SCHEDULER (sched); GSList *chains; g_print ("iterations: %d\n", osched->iterations); @@ -2164,7 +2161,7 @@ gst_opt_scheduler_get_property (GObject *object, guint prop_id, g_return_if_fail (GST_IS_OPT_SCHEDULER (object)); - osched = GST_OPT_SCHEDULER_CAST (object); + osched = GST_OPT_SCHEDULER (object); switch (prop_id) { case ARG_ITERATIONS: @@ -2187,7 +2184,7 @@ gst_opt_scheduler_set_property (GObject *object, guint prop_id, g_return_if_fail (GST_IS_OPT_SCHEDULER (object)); - osched = GST_OPT_SCHEDULER_CAST (object); + osched = GST_OPT_SCHEDULER (object); switch (prop_id) { case ARG_ITERATIONS: diff --git a/gstreamer.spec.in b/gstreamer.spec.in index 0f5320bc32..406efd53d1 100644 --- a/gstreamer.spec.in +++ b/gstreamer.spec.in @@ -31,8 +31,10 @@ Prereq: /sbin/ldconfig ### documentation requirements BuildRequires: openjade BuildRequires: python2 -BuildRequires: docbook-style-dsssl docbook-dtd31-sgml -BuildRequires: transfig xfig +BuildRequires: docbook-style-dsssl +BuildRequires: docbook-utils +BuildRequires: transfig +BuildRequires: xfig %description GStreamer is a streaming-media framework, based on graphs of filters which @@ -139,15 +141,12 @@ rm -f $RPM_BUILD_ROOT%{_libdir}/*.la %{_libdir}/libgstcontrol-%{majorminor}.so.* %dir %{_libdir}/gstreamer-%{majorminor} %dir %{_localstatedir}/cache/gstreamer-%{majorminor} -%{_libdir}/gstreamer-%{majorminor}/libgstautoplugcache*.so* -%{_libdir}/gstreamer-%{majorminor}/libgstautoplugger*.so* %{_libdir}/gstreamer-%{majorminor}/libgstbasicomega*.so* %{_libdir}/gstreamer-%{majorminor}/libgstoptscheduler.so* %{_libdir}/gstreamer-%{majorminor}/libgstoptomega*.so* %{_libdir}/gstreamer-%{majorminor}/libgstbasicgthreadscheduler*.so %{_libdir}/gstreamer-%{majorminor}/libgstoptgthreadscheduler*.so %{_libdir}/gstreamer-%{majorminor}/libgstelements*.so* -%{_libdir}/gstreamer-%{majorminor}/libgststaticautoplug*.so* %{_libdir}/gstreamer-%{majorminor}/libgstgetbits*.so* %{_libdir}/gstreamer-%{majorminor}/libgstspider*.so* %{_libdir}/gstreamer-%{majorminor}/libgstindexers.so* @@ -208,6 +207,9 @@ rm -f $RPM_BUILD_ROOT%{_libdir}/*.la %changelog +* Mon Dec 01 2003 Thomas Vander Stichele +- changed documentation buildrequires + * Sun Nov 09 2003 Christian Schaller - Fix spec to handle new bytestream library diff --git a/libs/gst/bytestream/bytestream.c b/libs/gst/bytestream/bytestream.c index 352551a1b3..b0a2b72c46 100644 --- a/libs/gst/bytestream/bytestream.c +++ b/libs/gst/bytestream/bytestream.c @@ -252,6 +252,7 @@ gst_bytestream_peek (GstByteStream *bs, GstBuffer **buf, guint32 len) GstBuffer *headbuf, *retbuf = NULL; g_return_val_if_fail (bs != NULL, 0); + g_return_val_if_fail (buf != NULL, 0); g_return_val_if_fail (len > 0, 0); GST_DEBUG ("peek: asking for %d bytes", len); @@ -323,6 +324,7 @@ gst_bytestream_peek_bytes (GstByteStream *bs, guint8** data, guint32 len) GstBuffer *headbuf; g_return_val_if_fail (bs != NULL, 0); + g_return_val_if_fail (data != NULL, 0); g_return_val_if_fail (len > 0, 0); GST_DEBUG ("peek_bytes: asking for %d bytes", len); @@ -761,7 +763,6 @@ GST_PLUGIN_DEFINE ( plugin_init, VERSION, GST_LICENSE, - GST_COPYRIGHT, GST_PACKAGE, GST_ORIGIN ) diff --git a/libs/gst/bytestream/bytestream.h b/libs/gst/bytestream/bytestream.h index 82ac0ec7b3..08ae068a37 100644 --- a/libs/gst/bytestream/bytestream.h +++ b/libs/gst/bytestream/bytestream.h @@ -48,7 +48,7 @@ struct _GstByteStream { /* if we are in the seek state (waiting for DISCONT) */ gboolean in_seek; - GST_OBJECT_PADDING + gpointer _gst_reserved[GST_PADDING]; }; GstByteStream* gst_bytestream_new (GstPad *pad); diff --git a/libs/gst/getbits/getbits.c b/libs/gst/getbits/getbits.c index 419015cb87..6c521013bc 100644 --- a/libs/gst/getbits/getbits.c +++ b/libs/gst/getbits/getbits.c @@ -227,7 +227,6 @@ GST_PLUGIN_DEFINE ( plugin_init, VERSION, GST_LICENSE, - GST_COPYRIGHT, GST_PACKAGE, GST_ORIGIN ) diff --git a/plugins/elements/gstaggregator.c b/plugins/elements/gstaggregator.c index b15eaffd2f..2c30e62c66 100644 --- a/plugins/elements/gstaggregator.c +++ b/plugins/elements/gstaggregator.c @@ -335,7 +335,7 @@ gst_aggregator_loop (GstElement *element) debug = "loop_select"; - pad = gst_pad_select (aggregator->sinkpads); + pad = gst_pad_selectv (aggregator->sinkpads); buf = GST_BUFFER (gst_pad_pull (pad)); gst_aggregator_push (aggregator, pad, buf, debug); diff --git a/plugins/elements/gstelements.c b/plugins/elements/gstelements.c index 909b88392c..3b30483535 100644 --- a/plugins/elements/gstelements.c +++ b/plugins/elements/gstelements.c @@ -95,7 +95,6 @@ GST_PLUGIN_DEFINE ( plugin_init, VERSION, GST_LICENSE, - GST_COPYRIGHT, GST_PACKAGE, GST_ORIGIN ) diff --git a/plugins/elements/gstqueue.c b/plugins/elements/gstqueue.c index 76a93b09d6..e62c413a7f 100644 --- a/plugins/elements/gstqueue.c +++ b/plugins/elements/gstqueue.c @@ -39,54 +39,75 @@ static GstElementDetails gst_queue_details = GST_ELEMENT_DETAILS ( /* Queue signals and args */ enum { - FULL, + SIGNAL_UNDERRUN, + SIGNAL_RUNNING, + SIGNAL_OVERRUN, LAST_SIGNAL }; enum { ARG_0, - ARG_LEVEL_BUFFERS, - ARG_LEVEL_BYTES, - ARG_LEVEL_TIME, - ARG_SIZE_BUFFERS, - ARG_SIZE_BYTES, - ARG_SIZE_TIME, + /* FIXME: don't we have another way of doing this + * "Gstreamer format" (frame/byte/time) queries? */ + ARG_CUR_LEVEL_BUFFERS, + ARG_CUR_LEVEL_BYTES, + ARG_CUR_LEVEL_TIME, + ARG_MAX_SIZE_BUFFERS, + ARG_MAX_SIZE_BYTES, + ARG_MAX_SIZE_TIME, + ARG_MIN_TRESHOLD_BUFFERS, + ARG_MIN_TRESHOLD_BYTES, + ARG_MIN_TRESHOLD_TIME, ARG_LEAKY, - ARG_LEVEL, - ARG_MAX_LEVEL, - ARG_MIN_THRESHOLD_BYTES, ARG_MAY_DEADLOCK, - ARG_BLOCK_TIMEOUT, + ARG_BLOCK_TIMEOUT + /* FILL ME */ }; -static void gst_queue_base_init (gpointer g_class); -static void gst_queue_class_init (gpointer g_class, - gpointer class_data); -static void gst_queue_init (GTypeInstance *instance, - gpointer g_class); -static void gst_queue_dispose (GObject *object); +typedef struct _GstQueueEventResponse { + GstEvent *event; + gboolean ret, handled; +} GstQueueEventResponse; -static void gst_queue_set_property (GObject *object, guint prop_id, - const GValue *value, GParamSpec *pspec); -static void gst_queue_get_property (GObject *object, guint prop_id, - GValue *value, GParamSpec *pspec); +static void gst_queue_base_init (GstQueueClass *klass); +static void gst_queue_class_init (GstQueueClass *klass); +static void gst_queue_init (GstQueue *queue); +static void gst_queue_dispose (GObject *object); -static void gst_queue_chain (GstPad *pad, GstData *data); -static GstData * gst_queue_get (GstPad *pad); -static GstBufferPool* gst_queue_get_bufferpool (GstPad *pad); +static void gst_queue_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec); +static void gst_queue_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec); + +static GstCaps2 *gst_queue_getcaps (GstPad *pad); +static GstPadLinkReturn + gst_queue_link (GstPad *pad, + const GstCaps2 *caps); +static void gst_queue_chain (GstPad *pad, + GstData *data); +static GstData *gst_queue_get (GstPad *pad); +static GstBufferPool * + gst_queue_get_bufferpool (GstPad *pad); -static gboolean gst_queue_handle_src_event (GstPad *pad, GstEvent *event); +static gboolean gst_queue_handle_src_event (GstPad *pad, + GstEvent *event); +static void gst_queue_locked_flush (GstQueue *queue); -static void gst_queue_locked_flush (GstQueue *queue); - -static GstElementStateReturn gst_queue_change_state (GstElement *element); -static gboolean gst_queue_release_locks (GstElement *element); +static GstElementStateReturn + gst_queue_change_state (GstElement *element); +static gboolean gst_queue_release_locks (GstElement *element); -#define GST_TYPE_QUEUE_LEAKY (queue_leaky_get_type()) +#define GST_TYPE_QUEUE_LEAKY (queue_leaky_get_type ()) + static GType -queue_leaky_get_type(void) { +queue_leaky_get_type (void) +{ static GType queue_leaky_type = 0; static GEnumValue queue_leaky[] = { { GST_QUEUE_NO_LEAK, "0", "Not Leaky" }, @@ -104,115 +125,127 @@ static GstElementClass *parent_class = NULL; static guint gst_queue_signals[LAST_SIGNAL] = { 0 }; GType -gst_queue_get_type(void) +gst_queue_get_type (void) { static GType queue_type = 0; if (!queue_type) { static const GTypeInfo queue_info = { - sizeof(GstQueueClass), - gst_queue_base_init, + sizeof (GstQueueClass), + (GBaseInitFunc) gst_queue_base_init, NULL, - gst_queue_class_init, + (GClassInitFunc) gst_queue_class_init, NULL, NULL, - sizeof(GstQueue), + sizeof (GstQueue), 4, - gst_queue_init, + (GInstanceInitFunc) gst_queue_init, NULL }; - queue_type = g_type_register_static (GST_TYPE_ELEMENT, "GstQueue", &queue_info, 0); + + queue_type = g_type_register_static (GST_TYPE_ELEMENT, + "GstQueue", &queue_info, 0); } + return queue_type; } static void -gst_queue_base_init (gpointer g_class) +gst_queue_base_init (GstQueueClass *klass) { - GstElementClass *gstelement_class = GST_ELEMENT_CLASS (g_class); + GstElementClass *gstelement_class = GST_ELEMENT_CLASS (klass); gst_element_class_set_details (gstelement_class, &gst_queue_details); } static void -gst_queue_class_init (gpointer g_class, gpointer class_data) +gst_queue_class_init (GstQueueClass *klass) { - GObjectClass *gobject_class = G_OBJECT_CLASS (g_class); - GstElementClass *gstelement_class = GST_ELEMENT_CLASS (g_class); - GstQueueClass *gstqueue_class = GST_QUEUE_CLASS (g_class); + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + GstElementClass *gstelement_class = GST_ELEMENT_CLASS (klass); - parent_class = g_type_class_peek_parent (g_class); + parent_class = g_type_class_peek_parent (klass); - gst_queue_signals[FULL] = - g_signal_new ("full", G_TYPE_FROM_CLASS (gstqueue_class), G_SIGNAL_RUN_FIRST, - G_STRUCT_OFFSET (GstQueueClass, full), NULL, NULL, + /* signals */ + gst_queue_signals[SIGNAL_UNDERRUN] = + g_signal_new ("underrun", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (GstQueueClass, underrun), NULL, NULL, + g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); + gst_queue_signals[SIGNAL_RUNNING] = + g_signal_new ("running", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (GstQueueClass, running), NULL, NULL, + g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); + gst_queue_signals[SIGNAL_OVERRUN] = + g_signal_new ("overrun", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_FIRST, + G_STRUCT_OFFSET (GstQueueClass, overrun), NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); - g_object_class_install_property (G_OBJECT_CLASS (gstqueue_class), ARG_LEAKY, - g_param_spec_enum ("leaky", "Leaky", "Where the queue leaks, if at all.", - GST_TYPE_QUEUE_LEAKY, GST_QUEUE_NO_LEAK, G_PARAM_READWRITE)); - g_object_class_install_property (G_OBJECT_CLASS (gstqueue_class), ARG_LEVEL, - g_param_spec_int ("level", "Level", "How many buffers are in the queue.", - 0, G_MAXINT, 0, G_PARAM_READABLE)); - g_object_class_install_property (G_OBJECT_CLASS (gstqueue_class), ARG_MAX_LEVEL, - g_param_spec_int ("max_level", "Maximum Level", "How many buffers the queue holds.", - 0, G_MAXINT, 100, G_PARAM_READWRITE)); - g_object_class_install_property (G_OBJECT_CLASS (gstqueue_class), ARG_MIN_THRESHOLD_BYTES, - g_param_spec_int ("min_threshold_bytes", "Minimum Threshold", - "Minimum bytes required before signalling not_empty to reader.", - 0, G_MAXINT, 0, G_PARAM_READWRITE)); - g_object_class_install_property (G_OBJECT_CLASS (gstqueue_class), ARG_MAY_DEADLOCK, - g_param_spec_boolean ("may_deadlock", "May Deadlock", "The queue may deadlock if it's full and not PLAYING", - TRUE, G_PARAM_READWRITE)); - g_object_class_install_property (G_OBJECT_CLASS (gstqueue_class), ARG_BLOCK_TIMEOUT, - g_param_spec_int ("block_timeout", "Timeout for Block", - "Microseconds until blocked queue times out and returns filler event. " - "Value of -1 disables timeout", - -1, G_MAXINT, -1, G_PARAM_READWRITE)); - gobject_class->dispose = GST_DEBUG_FUNCPTR (gst_queue_dispose); - gobject_class->set_property = GST_DEBUG_FUNCPTR (gst_queue_set_property); - gobject_class->get_property = GST_DEBUG_FUNCPTR (gst_queue_get_property); + /* properties */ + g_object_class_install_property (gobject_class, ARG_CUR_LEVEL_BYTES, + g_param_spec_uint ("current-level-bytes", "Current level (kB)", + "Current amount of data in the queue (bytes)", + 0, G_MAXUINT, 0, G_PARAM_READABLE)); + g_object_class_install_property (gobject_class, ARG_CUR_LEVEL_BUFFERS, + g_param_spec_uint ("current-level-buffers", "Current level (buffers)", + "Current number of buffers in the queue", + 0, G_MAXUINT, 0, G_PARAM_READABLE)); + g_object_class_install_property (gobject_class, ARG_CUR_LEVEL_TIME, + g_param_spec_uint64 ("current-level-time", "Current level (ns)", + "Current amount of data in the queue (in ns)", + 0, G_MAXUINT64, 0, G_PARAM_READABLE)); - gstelement_class->change_state = GST_DEBUG_FUNCPTR(gst_queue_change_state); - gstelement_class->release_locks = GST_DEBUG_FUNCPTR(gst_queue_release_locks); -} + g_object_class_install_property (gobject_class, ARG_MAX_SIZE_BYTES, + g_param_spec_uint ("max-size-bytes", "Max. size (kB)", + "Max. amount of data in the queue (bytes, 0=disable)", + 0, G_MAXUINT, 0, G_PARAM_READWRITE)); + g_object_class_install_property (gobject_class, ARG_MAX_SIZE_BUFFERS, + g_param_spec_uint ("max-size-buffers", "Max. size (buffers)", + "Max. number of buffers in the queue (0=disable)", + 0, G_MAXUINT, 0, G_PARAM_READWRITE)); + g_object_class_install_property (gobject_class, ARG_MAX_SIZE_TIME, + g_param_spec_uint64 ("max-size-time", "Max. size (ns)", + "Max. amount of data in the queue (in ns, 0=disable)", + 0, G_MAXUINT64, 0, G_PARAM_READWRITE)); -static GstPadLinkReturn -gst_queue_link (GstPad *pad, const GstCaps2 *caps) -{ - GstQueue *queue = GST_QUEUE (gst_pad_get_parent (pad)); - GstPad *otherpad; + g_object_class_install_property (gobject_class, ARG_MIN_TRESHOLD_BYTES, + g_param_spec_uint ("min-treshold-bytes", "Min. treshold (kB)", + "Min. amount of data in the queue to allow reading (bytes, 0=disable)", + 0, G_MAXUINT, 0, G_PARAM_READWRITE)); + g_object_class_install_property (gobject_class, ARG_MIN_TRESHOLD_BUFFERS, + g_param_spec_uint ("min-treshold-buffers", "Min. treshold (buffers)", + "Min. number of buffers in the queue to allow reading (0=disable)", + 0, G_MAXUINT, 0, G_PARAM_READWRITE)); + g_object_class_install_property (gobject_class, ARG_MIN_TRESHOLD_TIME, + g_param_spec_uint64 ("min-treshold-time", "Min. treshold (ns)", + "Min. amount of data in the queue to allow reading (in ns, 0=disable)", + 0, G_MAXUINT64, 0, G_PARAM_READWRITE)); - if (pad == queue->srcpad) - otherpad = queue->sinkpad; - else - otherpad = queue->srcpad; + g_object_class_install_property (gobject_class, ARG_LEAKY, + g_param_spec_enum ("leaky", "Leaky", + "Where the queue leaks, if at all", + GST_TYPE_QUEUE_LEAKY, GST_QUEUE_NO_LEAK, G_PARAM_READWRITE)); + g_object_class_install_property (gobject_class, ARG_MAY_DEADLOCK, + g_param_spec_boolean ("may_deadlock", "May Deadlock", + "The queue may deadlock if it's full and not PLAYING", + TRUE, G_PARAM_READWRITE)); + g_object_class_install_property (gobject_class, ARG_BLOCK_TIMEOUT, + g_param_spec_uint64 ("block_timeout", "Timeout for Block", + "Nanoseconds until blocked queue times out and returns filler event. " + "Value of -1 disables timeout", + 0, G_MAXUINT64, -1, G_PARAM_READWRITE)); - return gst_pad_proxy_link (otherpad, caps); -} + /* set several parent class virtual functions */ + gobject_class->dispose = GST_DEBUG_FUNCPTR (gst_queue_dispose); + gobject_class->set_property = GST_DEBUG_FUNCPTR (gst_queue_set_property); + gobject_class->get_property = GST_DEBUG_FUNCPTR (gst_queue_get_property); -static GstCaps2 * -gst_queue_getcaps (GstPad *pad) -{ - GstQueue *queue = GST_QUEUE (gst_pad_get_parent (pad)); - GstPad *otherpad; - - if (pad == queue->srcpad) - otherpad = GST_PAD_PEER (queue->sinkpad); - else - otherpad = GST_PAD_PEER (queue->srcpad); - - if (otherpad) - return gst_pad_get_allowed_caps (otherpad); - - return gst_caps2_new_any (); + gstelement_class->change_state = GST_DEBUG_FUNCPTR (gst_queue_change_state); + gstelement_class->release_locks = GST_DEBUG_FUNCPTR (gst_queue_release_locks); } static void -gst_queue_init (GTypeInstance *instance, gpointer g_class) +gst_queue_init (GstQueue *queue) { - GstQueue *queue = GST_QUEUE (instance); - /* scheduling on this kind of element is, well, interesting */ GST_FLAG_SET (queue, GST_ELEMENT_DECOUPLED); GST_FLAG_SET (queue, GST_ELEMENT_EVENT_AWARE); @@ -233,26 +266,31 @@ gst_queue_init (GTypeInstance *instance, gpointer g_class) gst_pad_set_event_function (queue->srcpad, GST_DEBUG_FUNCPTR (gst_queue_handle_src_event)); gst_pad_set_active (queue->srcpad, TRUE); + queue->cur_level.buffers = 0; /* no content */ + queue->cur_level.bytes = 0; /* no content */ + queue->cur_level.time = 0; /* no content */ + queue->max_size.buffers = 100; /* max. 100 buffers */ + queue->max_size.bytes = 1024 * 1024; /* max. 1 MB */ + queue->max_size.time = GST_SECOND; /* max. 1 sec. */ + queue->min_treshold.buffers = 0; /* no treshold */ + queue->min_treshold.bytes = 0; /* no treshold */ + queue->min_treshold.time = 0; /* no treshold */ + queue->leaky = GST_QUEUE_NO_LEAK; - queue->queue = NULL; - queue->level_buffers = 0; - queue->level_bytes = 0; - queue->level_time = G_GINT64_CONSTANT (0); - queue->size_buffers = 100; /* 100 buffers */ - queue->size_bytes = 100 * 1024; /* 100KB */ - queue->size_time = GST_SECOND; /* 1sec */ - queue->min_threshold_bytes = 0; queue->may_deadlock = TRUE; - queue->block_timeout = -1; + queue->block_timeout = GST_CLOCK_TIME_NONE; queue->interrupt = FALSE; queue->flush = FALSE; queue->qlock = g_mutex_new (); - queue->not_empty = g_cond_new (); - queue->not_full = g_cond_new (); - queue->events = g_async_queue_new(); + queue->item_add = g_cond_new (); + queue->item_del = g_cond_new (); + queue->event_done = g_cond_new (); + queue->events = g_queue_new (); queue->queue = g_queue_new (); - GST_CAT_DEBUG_OBJECT (GST_CAT_THREAD, queue, "initialized queue's not_empty & not_full conditions"); + + GST_CAT_DEBUG_OBJECT (GST_CAT_THREAD, queue, + "initialized queue's not_empty & not_full conditions"); } static void @@ -262,54 +300,114 @@ gst_queue_dispose (GObject *object) gst_element_set_state (GST_ELEMENT (queue), GST_STATE_NULL); - g_mutex_free (queue->qlock); - g_cond_free (queue->not_empty); - g_cond_free (queue->not_full); + while (!g_queue_is_empty (queue->queue)) { + GstData *data = g_queue_pop_head (queue->queue); + gst_data_unref (data); + } g_queue_free (queue->queue); + g_mutex_free (queue->qlock); + g_cond_free (queue->item_add); + g_cond_free (queue->item_del); + g_cond_free (queue->event_done); + while (!g_queue_is_empty (queue->events)) { + GstEvent *event = g_queue_pop_head (queue->events); + gst_event_unref (event); + } - g_async_queue_unref(queue->events); - - G_OBJECT_CLASS (parent_class)->dispose (object); + if (G_OBJECT_CLASS (parent_class)->dispose) + G_OBJECT_CLASS (parent_class)->dispose (object); } -static GstBufferPool* +static GstPad * +gst_queue_otherpad (GstPad *pad) +{ + GstQueue *queue = GST_QUEUE (gst_pad_get_parent (pad)); + GstPad *otherpad; + + if (pad == queue->srcpad) + otherpad = queue->sinkpad; + else + otherpad = queue->srcpad; + + return otherpad; +} + +static GstPadLinkReturn +gst_queue_link (GstPad *pad, const GstCaps2 *caps) +{ + return gst_pad_proxy_link (gst_queue_otherpad (pad), caps); +} + +static GstCaps2 * +gst_queue_getcaps (GstPad *pad) +{ + GstPad *otherpad = GST_PAD_PEER (gst_queue_otherpad (pad)); + + if (otherpad) + return gst_pad_get_caps (otherpad); + + return gst_caps2_new_any (); +} + +static GstBufferPool * gst_queue_get_bufferpool (GstPad *pad) { - GstQueue *queue; - - queue = GST_QUEUE (GST_OBJECT_PARENT (pad)); - - return gst_pad_get_bufferpool (queue->srcpad); -} - -static void -gst_queue_cleanup_data (gpointer data, const gpointer user_data) -{ - GST_CAT_DEBUG_OBJECT (GST_CAT_DATAFLOW, user_data, "cleaning buffer %p", data); - - gst_data_unref (GST_DATA (data)); + return gst_pad_get_bufferpool (gst_queue_otherpad (pad)); } static void gst_queue_locked_flush (GstQueue *queue) { - gpointer data; - - while ((data = g_queue_pop_head (queue->queue))) { - gst_queue_cleanup_data (data, (gpointer) queue); + while (!g_queue_is_empty (queue->queue)) { + GstData *data = g_queue_pop_head (queue->queue); + gst_data_unref (data); } queue->timeval = NULL; - queue->level_buffers = 0; - queue->level_bytes = 0; - queue->level_time = G_GINT64_CONSTANT (0); + queue->cur_level.buffers = 0; + queue->cur_level.bytes = 0; + queue->cur_level.time = 0; + /* make sure any pending buffers to be added are flushed too */ queue->flush = TRUE; - /* signal not_full, since we apparently aren't full anymore */ - g_cond_signal (queue->not_full); + + /* we deleted something... */ + g_cond_signal (queue->item_del); } static void -gst_queue_chain (GstPad *pad, GstData *data) +gst_queue_handle_pending_events (GstQueue *queue) +{ + /* check for events to send upstream */ + while (!g_queue_is_empty (queue->events)){ + GstQueueEventResponse *er = g_queue_pop_head (queue->events); + GST_CAT_DEBUG_OBJECT (GST_CAT_DATAFLOW, queue, "sending event upstream"); + er->ret = gst_pad_event_default (GST_PAD_PEER (queue->sinkpad), er->event); + er->handled = TRUE; + g_cond_signal (queue->event_done); + GST_CAT_DEBUG_OBJECT (GST_CAT_DATAFLOW, queue, "event sent"); + } +} + +#define STATUS(queue, msg) \ + GST_CAT_LOG_OBJECT (GST_CAT_DATAFLOW, queue, \ + "(%s:%s) " msg ": %u of %u-%u buffers, %u of %u-%u " \ + "bytes, %" G_GUINT64_FORMAT " of %" G_GUINT64_FORMAT \ + "-%" G_GUINT64_FORMAT " ns, %u elements", \ + GST_DEBUG_PAD_NAME (pad), \ + queue->cur_level.buffers, \ + queue->min_treshold.buffers, \ + queue->max_size.buffers, \ + queue->cur_level.bytes, \ + queue->min_treshold.bytes, \ + queue->max_size.bytes, \ + queue->cur_level.time, \ + queue->min_treshold.time, \ + queue->max_size.time, \ + queue->queue->length) + +static void +gst_queue_chain (GstPad *pad, + GstData *data) { GstQueue *queue; @@ -319,147 +417,201 @@ gst_queue_chain (GstPad *pad, GstData *data) queue = GST_QUEUE (GST_OBJECT_PARENT (pad)); - /* check for events to send upstream */ - g_async_queue_lock(queue->events); - while (g_async_queue_length_unlocked(queue->events) > 0){ - GstEvent *event = (GstEvent*)g_async_queue_pop_unlocked(queue->events); - GST_CAT_DEBUG_OBJECT (GST_CAT_DATAFLOW, queue, "sending event upstream\n"); - gst_pad_event_default (pad, event); - GST_CAT_DEBUG_OBJECT (GST_CAT_DATAFLOW, queue, "event sent\n"); - } - g_async_queue_unlock(queue->events); - restart: /* we have to lock the queue since we span threads */ GST_CAT_LOG_OBJECT (GST_CAT_DATAFLOW, queue, "locking t:%p", g_thread_self ()); g_mutex_lock (queue->qlock); GST_CAT_LOG_OBJECT (GST_CAT_DATAFLOW, queue, "locked t:%p", g_thread_self ()); - + + gst_queue_handle_pending_events (queue); + /* assume don't need to flush this buffer when the queue is filled */ queue->flush = FALSE; if (GST_IS_EVENT (data)) { switch (GST_EVENT_TYPE (data)) { case GST_EVENT_FLUSH: - GST_CAT_DEBUG_OBJECT (GST_CAT_DATAFLOW, queue, "FLUSH event, flushing queue\n"); + STATUS (queue, "received flush event"); gst_queue_locked_flush (queue); break; case GST_EVENT_EOS: - GST_CAT_DEBUG_OBJECT (GST_CAT_DATAFLOW, queue, "eos in on %s %d\n", - GST_ELEMENT_NAME (queue), queue->level_buffers); + STATUS (queue, "received EOS"); break; default: /* we put the event in the queue, we don't have to act ourselves */ + GST_CAT_LOG_OBJECT (GST_CAT_DATAFLOW, queue, + "adding event %p of type %d", + data, GST_EVENT_TYPE (data)); break; } } if (GST_IS_BUFFER (data)) GST_CAT_LOG_OBJECT (GST_CAT_DATAFLOW, queue, - "adding buffer %p of size %d", data, GST_BUFFER_SIZE (data)); + "adding buffer %p of size %d", + data, GST_BUFFER_SIZE (data)); - if (queue->level_buffers == queue->size_buffers) { + /* We make space available if we're "full" according to whatever + * the user defined as "full". Note that this only applies to buffers. + * We always handle events and they don't count in our statistics. */ + if (GST_IS_BUFFER (data) && + ((queue->max_size.buffers > 0 && + queue->cur_level.buffers >= queue->max_size.buffers) || + (queue->max_size.bytes > 0 && + queue->cur_level.bytes >= queue->max_size.bytes) || + (queue->max_size.time > 0 && + queue->cur_level.time >= queue->max_size.time))) { g_mutex_unlock (queue->qlock); - g_signal_emit (G_OBJECT (queue), gst_queue_signals[FULL], 0); + g_signal_emit (G_OBJECT (queue), gst_queue_signals[SIGNAL_OVERRUN], 0); g_mutex_lock (queue->qlock); - /* if this is a leaky queue... */ - if (queue->leaky) { - /* FIXME don't want to leak events! */ - /* if we leak on the upstream side, drop the current buffer */ - if (queue->leaky == GST_QUEUE_LEAK_UPSTREAM) { - GST_CAT_DEBUG_OBJECT (GST_CAT_DATAFLOW, queue, "queue is full, leaking buffer on upstream end"); - if (GST_IS_EVENT (data)) - fprintf(stderr, "Error: queue [%s] leaked an event, type:%d\n", - GST_ELEMENT_NAME(GST_ELEMENT(queue)), - GST_EVENT_TYPE(GST_EVENT(data))); - /* now we have to clean up and exit right away */ + /* how are we going to make space for this buffer? */ + switch (queue->leaky) { + /* leak current buffer */ + case GST_QUEUE_LEAK_UPSTREAM: + GST_CAT_DEBUG_OBJECT (GST_CAT_DATAFLOW, queue, + "queue is full, leaking buffer on upstream end"); + /* now we can clean up and exit right away */ g_mutex_unlock (queue->qlock); goto out_unref; - } - /* otherwise we have to push a buffer off the other end */ - else { - gpointer front; - GstData *leak; - GST_CAT_DEBUG_OBJECT (GST_CAT_DATAFLOW, queue, "queue is full, leaking buffer on downstream end"); + /* leak first buffer in the queue */ + case GST_QUEUE_LEAK_DOWNSTREAM: { + /* this is a bit hacky. We'll manually iterate the list + * and find the first buffer from the head on. We'll + * unref that and "fix up" the GQueue object... */ + GList *item; + GstData *leak = NULL; - front = g_queue_pop_head (queue->queue); - leak = GST_DATA (front); + GST_CAT_DEBUG_OBJECT (GST_CAT_DATAFLOW, queue, + "queue is full, leaking buffer on downstream end"); - queue->level_buffers--; - if (GST_IS_EVENT (leak)) { - fprintf(stderr, "Error: queue [%s] leaked an event, type:%d\n", - GST_ELEMENT_NAME(GST_ELEMENT(queue)), - GST_EVENT_TYPE(GST_EVENT(leak))); - } else { - queue->level_bytes -= GST_BUFFER_SIZE(leak); + for (item = queue->queue->head; item != NULL; item = item->next) { + if (GST_IS_BUFFER (item->data)) { + leak = item->data; + break; + } } - gst_data_unref (leak); + /* if we didn't find anything, it means we have no buffers + * in here. That cannot happen, since we had >= 1 bufs */ + g_assert (leak); + + /* Now remove it from the list, fixing up the GQueue + * CHECKME: is a queue->head the first or the last item? */ + item = g_list_delete_link (queue->queue->head, item); + queue->queue->head = g_list_first (item); + queue->queue->tail = g_list_last (item); + queue->queue->length--; + + /* and unref the data at the end. Twice, because we keep a ref + * to make things read-only. Also keep our list uptodate. */ + queue->cur_level.bytes -= GST_BUFFER_SIZE (data); + queue->cur_level.buffers --; + if (GST_BUFFER_DURATION (data) != GST_CLOCK_TIME_NONE) + queue->cur_level.time -= GST_BUFFER_DURATION (data); + + gst_data_unref (data); + gst_data_unref (data); + break; } - } - GST_CAT_LOG_OBJECT (GST_CAT_DATAFLOW, queue, "pre full wait, level:%d/%d buffers, %d bytes", - queue->level_buffers, queue->size_buffers, queue->level_bytes); + default: + g_warning ("Unknown leaky type, using default"); + /* fall-through */ - 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 (queue->interrupt) { - GST_CAT_DEBUG_OBJECT (GST_CAT_DATAFLOW, queue, "interrupted!!"); + /* don't leak. Instead, wait for space to be available */ + case GST_QUEUE_NO_LEAK: + STATUS (queue, "pre-full wait"); + + while ((queue->max_size.buffers > 0 && + queue->cur_level.buffers >= queue->max_size.buffers) || + (queue->max_size.bytes > 0 && + queue->cur_level.bytes >= queue->max_size.bytes) || + (queue->max_size.time > 0 && + queue->cur_level.time >= queue->max_size.time)) { + /* 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 (queue->interrupt) { + GST_CAT_DEBUG_OBJECT (GST_CAT_DATAFLOW, queue, "interrupted"); + g_mutex_unlock (queue->qlock); + if (gst_scheduler_interrupt (gst_pad_get_scheduler (queue->sinkpad), + GST_ELEMENT (queue))) { + goto out_unref; + } + /* if we got here because we were unlocked after a + * flush, we don't need to add the buffer to the + * queue again */ + if (queue->flush) { + GST_CAT_DEBUG_OBJECT (GST_CAT_DATAFLOW, queue, + "not adding pending buffer after flush"); + goto out_unref; + } + GST_CAT_DEBUG_OBJECT (GST_CAT_DATAFLOW, queue, + "adding pending buffer after interrupt"); + goto restart; + } + + if (GST_STATE (queue) != GST_STATE_PLAYING) { + /* this means the other end is shut down. Try to + * signal to resolve the error */ + if (!queue->may_deadlock) { + g_mutex_unlock (queue->qlock); + gst_data_unref (data); + gst_element_error (GST_ELEMENT (queue), + "deadlock found, source pad elements are shut down"); + /* we don't go to out_unref here, since we want to + * unref the buffer *before* calling gst_element_error */ + return; + } else { + GST_CAT_WARNING_OBJECT (GST_CAT_DATAFLOW, queue, + "%s: waiting for the app to restart " + "source pad elements", + GST_ELEMENT_NAME (queue)); + } + } + + /* OK, we've got a serious issue here. Imagine the situation + * where the puller (next element) is sending an event here, + * so it cannot pull events from the queue, and we cannot + * push data further because the queue is 'full' and therefore, + * we wait here (and do not handle events): deadlock! to solve + * that, we handle pending upstream events here, too. */ + gst_queue_handle_pending_events (queue); + + STATUS (queue, "waiting for item_del signal"); + g_cond_wait (queue->item_del, queue->qlock); + STATUS (queue, "received item_del signal"); + } + + STATUS (queue, "post-full wait"); g_mutex_unlock (queue->qlock); - if (gst_scheduler_interrupt (gst_pad_get_scheduler (queue->sinkpad), GST_ELEMENT (queue))) - goto out_unref; - /* if we got here because we were unlocked after a flush, we don't need - * to add the buffer to the queue again */ - if (queue->flush) { - GST_CAT_DEBUG_OBJECT (GST_CAT_DATAFLOW, queue, "not adding pending buffer after flush"); - goto out_unref; - } - GST_CAT_DEBUG_OBJECT (GST_CAT_DATAFLOW, queue, "adding pending buffer after interrupt"); - goto restart; - } - if (GST_STATE (queue) != GST_STATE_PLAYING) { - /* this means the other end is shut down */ - /* try to signal to resolve the error */ - if (!queue->may_deadlock) { - g_mutex_unlock (queue->qlock); - gst_data_unref (data); - gst_element_error (GST_ELEMENT (queue), "deadlock found, source pad elements are shut down"); - /* we don't want to goto out_unref here, since we want to clean up before calling gst_element_error */ - return; - } - else { - g_print ("%s: waiting for the app to restart source pad elements\n", GST_ELEMENT_NAME (queue)); - } - } - - GST_CAT_DEBUG_OBJECT (GST_CAT_DATAFLOW, queue, "waiting for not_full, level:%d/%d buffers, %d bytes", - queue->level_buffers, queue->size_buffers, queue->level_bytes); - g_cond_wait (queue->not_full, queue->qlock); - GST_CAT_DEBUG_OBJECT (GST_CAT_DATAFLOW, queue, "got not_full signal"); + g_signal_emit (G_OBJECT (queue), gst_queue_signals[SIGNAL_RUNNING], 0); + g_mutex_lock (queue->qlock); + break; } - GST_CAT_LOG_OBJECT (GST_CAT_DATAFLOW, queue, "post full wait, level:%d/%d buffers, %d bytes", - queue->level_buffers, queue->size_buffers, queue->level_bytes); } - /* put the buffer on the tail of the list */ + /* put the buffer on the tail of the list. We keep a reference, + * so that the data is read-only while in here. There's a good + * reason to do so: we have a size and time counter, and any + * modification to the content could change any of the two. */ + gst_data_ref (data); g_queue_push_tail (queue->queue, data); - queue->level_buffers++; - if (GST_IS_BUFFER (data)) - queue->level_bytes += GST_BUFFER_SIZE (data); + /* Note that we only add buffers (not events) to the statistics */ + if (GST_IS_BUFFER (data)) { + queue->cur_level.buffers++; + queue->cur_level.bytes += GST_BUFFER_SIZE (data); + if (GST_BUFFER_DURATION (data) != GST_CLOCK_TIME_NONE) + queue->cur_level.time += GST_BUFFER_DURATION (data); + } - /* this assertion _has_ to hold */ - g_assert (queue->queue->length == queue->level_buffers); + STATUS (queue, "+ level"); - GST_CAT_LOG_OBJECT (GST_CAT_DATAFLOW, queue, "(%s:%s)+ level:%d/%d buffers, %d bytes", - GST_DEBUG_PAD_NAME(pad), - queue->level_buffers, queue->size_buffers, queue->level_bytes); - - GST_CAT_LOG_OBJECT (GST_CAT_DATAFLOW, queue, "signalling not_empty"); - g_cond_signal (queue->not_empty); + GST_CAT_LOG_OBJECT (GST_CAT_DATAFLOW, queue, "signalling item_add"); + g_cond_signal (queue->item_add); g_mutex_unlock (queue->qlock); return; @@ -473,96 +625,123 @@ static GstData * gst_queue_get (GstPad *pad) { GstQueue *queue; - GstData *data = NULL; - gpointer front; + GstData *data; - g_assert(pad != NULL); - g_assert(GST_IS_PAD(pad)); g_return_val_if_fail (pad != NULL, NULL); g_return_val_if_fail (GST_IS_PAD (pad), NULL); - queue = GST_QUEUE (GST_OBJECT_PARENT (pad)); + queue = GST_QUEUE (gst_pad_get_parent (pad)); restart: /* have to lock for thread-safety */ - GST_CAT_LOG_OBJECT (GST_CAT_DATAFLOW, queue, "locking t:%p", g_thread_self ()); + GST_CAT_LOG_OBJECT (GST_CAT_DATAFLOW, queue, + "locking t:%p", g_thread_self ()); g_mutex_lock (queue->qlock); - GST_CAT_LOG_OBJECT (GST_CAT_DATAFLOW, queue, "locked t:%p %p", g_thread_self (), queue->not_empty); + GST_CAT_LOG_OBJECT (GST_CAT_DATAFLOW, queue, + "locked t:%p", g_thread_self ()); - GST_CAT_LOG_OBJECT (GST_CAT_DATAFLOW, queue, "pre empty wait, level:%d/%d buffers, %d bytes", - queue->level_buffers, queue->size_buffers, queue->level_bytes); - 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 - */ - //while (GST_STATE_PENDING (queue) != GST_STATE_VOID_PENDING) { - if (queue->interrupt) { - GST_CAT_DEBUG_OBJECT (GST_CAT_DATAFLOW, queue, "interrupted!!"); - g_mutex_unlock (queue->qlock); - if (gst_scheduler_interrupt (gst_pad_get_scheduler (queue->srcpad), GST_ELEMENT (queue))) - return GST_DATA (gst_event_new (GST_EVENT_INTERRUPT)); - goto restart; - } - if (GST_STATE (queue) != GST_STATE_PLAYING) { - /* this means the other end is shut down */ - if (!queue->may_deadlock) { + if (queue->queue->length == 0 || + (queue->min_treshold.buffers > 0 && + queue->cur_level.buffers < queue->min_treshold.buffers) || + (queue->min_treshold.bytes > 0 && + queue->cur_level.bytes < queue->min_treshold.bytes) || + (queue->min_treshold.time > 0 && + queue->cur_level.time < queue->min_treshold.time)) { + g_mutex_unlock (queue->qlock); + g_signal_emit (G_OBJECT (queue), gst_queue_signals[SIGNAL_UNDERRUN], 0); + g_mutex_lock (queue->qlock); + + STATUS (queue, "pre-empty wait"); + while (queue->queue->length == 0 || + (queue->min_treshold.buffers > 0 && + queue->cur_level.buffers < queue->min_treshold.buffers) || + (queue->min_treshold.bytes > 0 && + queue->cur_level.bytes < queue->min_treshold.bytes) || + (queue->min_treshold.time > 0 && + queue->cur_level.time < queue->min_treshold.time)) { + /* 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 (queue->interrupt) { + GST_CAT_DEBUG_OBJECT (GST_CAT_DATAFLOW, queue, "interrupted"); g_mutex_unlock (queue->qlock); - gst_element_error (GST_ELEMENT (queue), "deadlock found, sink pad elements are shut down"); + if (gst_scheduler_interrupt (gst_pad_get_scheduler (queue->srcpad), + GST_ELEMENT (queue))) + return GST_DATA (gst_event_new (GST_EVENT_INTERRUPT)); goto restart; } - else { - g_print ("%s: waiting for the app to restart source pad elements\n", GST_ELEMENT_NAME (queue)); + if (GST_STATE (queue) != GST_STATE_PLAYING) { + /* this means the other end is shut down */ + if (!queue->may_deadlock) { + g_mutex_unlock (queue->qlock); + gst_element_error (GST_ELEMENT (queue), + "deadlock found, sink pad elements are shut down"); + goto restart; + } else { + GST_CAT_WARNING_OBJECT (GST_CAT_DATAFLOW, queue, + "%s: waiting for the app to restart " + "source pad elements", + GST_ELEMENT_NAME (queue)); + } } - } - GST_CAT_DEBUG_OBJECT (GST_CAT_DATAFLOW, queue, "waiting for not_empty, level:%d/%d buffers, %d bytes", - queue->level_buffers, queue->size_buffers, queue->level_bytes); + STATUS (queue, "waiting for item_add"); - /* if (queue->block_timeout > -1){ */ - if (FALSE) { - GTimeVal timeout; - g_get_current_time(&timeout); - g_time_val_add(&timeout, queue->block_timeout); - if (!g_cond_timed_wait (queue->not_empty, queue->qlock, &timeout)){ - g_mutex_unlock (queue->qlock); - g_warning ("filler"); - return GST_DATA (gst_event_new_filler()); + if (queue->block_timeout != GST_CLOCK_TIME_NONE) { + GTimeVal timeout; + g_get_current_time (&timeout); + g_time_val_add (&timeout, queue->block_timeout / 1000); + if (!g_cond_timed_wait (queue->item_add, queue->qlock, &timeout)){ + g_mutex_unlock (queue->qlock); + GST_CAT_WARNING_OBJECT (GST_CAT_DATAFLOW, queue, + "Sending filler event"); + return GST_DATA (gst_event_new_filler ()); + } + } else { + g_cond_wait (queue->item_add, queue->qlock); } + STATUS (queue, "got item_add signal"); } - else { - g_cond_wait (queue->not_empty, queue->qlock); - } - GST_CAT_DEBUG_OBJECT (GST_CAT_DATAFLOW, queue, "got not_empty signal"); + + STATUS (queue, "post-empty wait"); + g_mutex_unlock (queue->qlock); + g_signal_emit (G_OBJECT (queue), gst_queue_signals[SIGNAL_RUNNING], 0); + g_mutex_lock (queue->qlock); } - GST_CAT_LOG_OBJECT (GST_CAT_DATAFLOW, queue, "post empty wait, level:%d/%d buffers, %d bytes", - queue->level_buffers, queue->size_buffers, queue->level_bytes); - front = g_queue_pop_head (queue->queue); - data = GST_DATA (front); - GST_CAT_LOG_OBJECT (GST_CAT_DATAFLOW, queue, "retrieved data %p from queue", data); + /* There's something in the list now, whatever it is */ + data = g_queue_pop_head (queue->queue); + GST_CAT_LOG_OBJECT (GST_CAT_DATAFLOW, queue, + "retrieved data %p from queue", data); - queue->level_buffers--; - if (GST_IS_BUFFER (data)) - queue->level_bytes -= GST_BUFFER_SIZE (data); + if (GST_IS_BUFFER (data)) { + /* Update statistics */ + queue->cur_level.buffers--; + queue->cur_level.bytes -= GST_BUFFER_SIZE (data); + if (GST_BUFFER_DURATION (data) != GST_CLOCK_TIME_NONE) + queue->cur_level.time -= GST_BUFFER_DURATION (data); + } - GST_CAT_LOG_OBJECT (GST_CAT_DATAFLOW, queue, "(%s:%s)- level:%d/%d buffers, %d bytes", - GST_DEBUG_PAD_NAME(pad), - queue->level_buffers, queue->size_buffers, queue->level_bytes); + /* Now that we're done, we can lose our own reference to + * the item, since we're no longer in danger. */ + gst_data_unref (data); - /* this assertion _has_ to hold */ - g_assert (queue->queue->length == queue->level_buffers); - - GST_CAT_LOG_OBJECT (GST_CAT_DATAFLOW, queue, "signalling not_full"); - g_cond_signal (queue->not_full); + STATUS (queue, "after _get()"); + GST_CAT_LOG_OBJECT (GST_CAT_DATAFLOW, queue, "signalling item_del"); + g_cond_signal (queue->item_del); g_mutex_unlock (queue->qlock); - /* FIXME where should this be? locked? */ + /* FIXME: I suppose this needs to be locked, since the EOS + * bit affects the pipeline state. However, that bit is + * locked too so it'd cause a deadlock. */ if (GST_IS_EVENT (data)) { GstEvent *event = GST_EVENT (data); - switch (GST_EVENT_TYPE(event)) { + switch (GST_EVENT_TYPE (event)) { case GST_EVENT_EOS: - GST_CAT_DEBUG_OBJECT (GST_CAT_DATAFLOW, queue, "queue \"%s\" eos", GST_ELEMENT_NAME (queue)); + GST_CAT_DEBUG_OBJECT (GST_CAT_DATAFLOW, queue, + "queue \"%s\" eos", + GST_ELEMENT_NAME (queue)); gst_element_set_eos (GST_ELEMENT (queue)); break; default: @@ -575,47 +754,49 @@ restart: static gboolean -gst_queue_handle_src_event (GstPad *pad, GstEvent *event) +gst_queue_handle_src_event (GstPad *pad, + GstEvent *event) { - GstQueue *queue; + GstQueue *queue = GST_QUEUE (gst_pad_get_parent (pad)); gboolean res; - gint event_type; - gint flag_flush = 0; - - queue = GST_QUEUE (GST_OBJECT_PARENT (pad)); g_mutex_lock (queue->qlock); if (gst_element_get_state (GST_ELEMENT (queue)) == GST_STATE_PLAYING) { - /* push the event to the queue for upstream consumption */ - g_async_queue_push(queue->events, event); - g_warning ("FIXME: sending event in a running queue"); - /* FIXME wait for delivery of the event here, then return the result - * instead of FALSE */ - res = FALSE; - goto done; - } + GstQueueEventResponse er; - event_type = GST_EVENT_TYPE (event); - if (event_type == GST_EVENT_SEEK) - flag_flush = GST_EVENT_SEEK_FLAGS (event) & GST_SEEK_FLAG_FLUSH; + /* push the event to the queue and wait for upstream consumption */ + er.event = event; + er.handled = FALSE; + g_queue_push_tail (queue->events, &er); + GST_CAT_WARNING_OBJECT (GST_CAT_DATAFLOW, queue, + "Preparing for loop for event handler"); + /* see the chain function on why this is here - it prevents a deadlock */ + g_cond_signal (queue->item_del); + while (!er.handled) { + g_cond_wait (queue->event_done, queue->qlock); + } + GST_CAT_WARNING_OBJECT (GST_CAT_DATAFLOW, queue, + "Event handled"); + res = er.ret; + } else { + res = gst_pad_event_default (pad, event); - res = gst_pad_event_default (pad, event); - - switch (event_type) { - case GST_EVENT_FLUSH: - GST_CAT_DEBUG_OBJECT (GST_CAT_DATAFLOW, queue, "FLUSH event, flushing queue\n"); - gst_queue_locked_flush (queue); - break; - case GST_EVENT_SEEK: - if (flag_flush) { + switch (GST_EVENT_TYPE (event)) { + case GST_EVENT_FLUSH: + GST_CAT_DEBUG_OBJECT (GST_CAT_DATAFLOW, queue, + "FLUSH event, flushing queue\n"); gst_queue_locked_flush (queue); - } - default: - break; + break; + case GST_EVENT_SEEK: + if (GST_EVENT_SEEK_FLAGS (event) & GST_SEEK_FLAG_FLUSH) { + gst_queue_locked_flush (queue); + } + default: + break; + } } -done: g_mutex_unlock (queue->qlock); /* we have to claim success, but we don't really know */ @@ -631,8 +812,8 @@ gst_queue_release_locks (GstElement *element) g_mutex_lock (queue->qlock); queue->interrupt = TRUE; - g_cond_signal (queue->not_full); - g_cond_signal (queue->not_empty); + g_cond_signal (queue->item_add); + g_cond_signal (queue->item_del); g_mutex_unlock (queue->qlock); return TRUE; @@ -642,7 +823,7 @@ static GstElementStateReturn gst_queue_change_state (GstElement *element) { GstQueue *queue; - GstElementStateReturn ret; + GstElementStateReturn ret = GST_STATE_SUCCESS; queue = GST_QUEUE (element); @@ -657,29 +838,29 @@ gst_queue_change_state (GstElement *element) case GST_STATE_NULL_TO_READY: gst_queue_locked_flush (queue); break; - case GST_STATE_READY_TO_PAUSED: - break; case GST_STATE_PAUSED_TO_PLAYING: if (!GST_PAD_IS_LINKED (queue->sinkpad)) { - GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, queue, "queue %s is not linked", GST_ELEMENT_NAME (queue)); + GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, queue, + "queue %s is not linked", + GST_ELEMENT_NAME (queue)); /* FIXME can this be? */ - g_cond_signal (queue->not_empty); + g_cond_signal (queue->item_add); ret = GST_STATE_FAILURE; goto error; - } - else { + } else { GstScheduler *src_sched, *sink_sched; - src_sched = gst_pad_get_scheduler (GST_PAD_CAST (queue->srcpad)); - sink_sched = gst_pad_get_scheduler (GST_PAD_CAST (queue->sinkpad)); + src_sched = gst_pad_get_scheduler (GST_PAD (queue->srcpad)); + sink_sched = gst_pad_get_scheduler (GST_PAD (queue->sinkpad)); if (src_sched == sink_sched) { - GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, queue, "queue %s does not connect different schedulers", - GST_ELEMENT_NAME (queue)); + GST_CAT_DEBUG_OBJECT (GST_CAT_STATES, queue, + "queue %s does not connect different schedulers", + GST_ELEMENT_NAME (queue)); g_warning ("queue %s does not connect different schedulers", - GST_ELEMENT_NAME (queue)); + GST_ELEMENT_NAME (queue)); ret = GST_STATE_FAILURE; goto error; @@ -687,18 +868,19 @@ gst_queue_change_state (GstElement *element) } queue->interrupt = FALSE; break; - case GST_STATE_PLAYING_TO_PAUSED: - break; case GST_STATE_PAUSED_TO_READY: gst_queue_locked_flush (queue); break; - case GST_STATE_READY_TO_NULL: + default: break; } - ret = GST_ELEMENT_CLASS (parent_class)->change_state (element); - /* this is an ugly hack to make sure our pads are always active. Reason for this is that - * pad activation for the queue element depends on 2 schedulers (ugh) */ + if (GST_ELEMENT_CLASS (parent_class)->change_state) + ret = GST_ELEMENT_CLASS (parent_class)->change_state (element); + + /* this is an ugly hack to make sure our pads are always active. + * Reason for this is that pad activation for the queue element + * depends on 2 schedulers (ugh) */ gst_pad_set_active (queue->sinkpad, TRUE); gst_pad_set_active (queue->srcpad, TRUE); @@ -706,70 +888,103 @@ error: g_mutex_unlock (queue->qlock); GST_CAT_LOG_OBJECT (GST_CAT_STATES, element, "done with state change"); + return ret; } static void -gst_queue_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) +gst_queue_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) { - GstQueue *queue; + GstQueue *queue = GST_QUEUE (object); - /* it's not null if we got it, but it might not be ours */ - g_return_if_fail (GST_IS_QUEUE (object)); - - queue = GST_QUEUE (object); + /* someone could change levels here, and since this + * affects the get/put funcs, we need to lock for safety. */ + g_mutex_lock (queue->qlock); switch (prop_id) { + case ARG_MAX_SIZE_BYTES: + queue->max_size.bytes = g_value_get_uint (value); + break; + case ARG_MAX_SIZE_BUFFERS: + queue->max_size.buffers = g_value_get_uint (value); + break; + case ARG_MAX_SIZE_TIME: + queue->max_size.time = g_value_get_uint64 (value); + break; + case ARG_MIN_TRESHOLD_BYTES: + queue->max_size.bytes = g_value_get_uint (value); + break; + case ARG_MIN_TRESHOLD_BUFFERS: + queue->max_size.buffers = g_value_get_uint (value); + break; + case ARG_MIN_TRESHOLD_TIME: + queue->max_size.time = g_value_get_uint64 (value); + break; case ARG_LEAKY: queue->leaky = g_value_get_enum (value); break; - case ARG_MAX_LEVEL: - queue->size_buffers = g_value_get_int (value); - break; - case ARG_MIN_THRESHOLD_BYTES: - queue->min_threshold_bytes = g_value_get_int (value); - break; case ARG_MAY_DEADLOCK: queue->may_deadlock = g_value_get_boolean (value); break; case ARG_BLOCK_TIMEOUT: - queue->block_timeout = g_value_get_int (value); + queue->block_timeout = g_value_get_uint64 (value); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } + + g_mutex_unlock (queue->qlock); } static void -gst_queue_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) +gst_queue_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) { - GstQueue *queue; - - /* it's not null if we got it, but it might not be ours */ - g_return_if_fail (GST_IS_QUEUE (object)); - - queue = GST_QUEUE (object); + GstQueue *queue = GST_QUEUE (object); switch (prop_id) { + case ARG_CUR_LEVEL_BYTES: + g_value_set_uint (value, queue->cur_level.bytes); + break; + case ARG_CUR_LEVEL_BUFFERS: + g_value_set_uint (value, queue->cur_level.buffers); + break; + case ARG_CUR_LEVEL_TIME: + g_value_set_uint64 (value, queue->cur_level.time); + break; + case ARG_MAX_SIZE_BYTES: + g_value_set_uint (value, queue->max_size.bytes); + break; + case ARG_MAX_SIZE_BUFFERS: + g_value_set_uint (value, queue->max_size.buffers); + break; + case ARG_MAX_SIZE_TIME: + g_value_set_uint64 (value, queue->max_size.time); + break; + case ARG_MIN_TRESHOLD_BYTES: + g_value_set_uint (value, queue->min_treshold.bytes); + break; + case ARG_MIN_TRESHOLD_BUFFERS: + g_value_set_uint (value, queue->min_treshold.buffers); + break; + case ARG_MIN_TRESHOLD_TIME: + g_value_set_uint64 (value, queue->min_treshold.time); + break; case ARG_LEAKY: g_value_set_enum (value, queue->leaky); break; - case ARG_LEVEL: - g_value_set_int (value, queue->level_buffers); - break; - case ARG_MAX_LEVEL: - g_value_set_int (value, queue->size_buffers); - break; - case ARG_MIN_THRESHOLD_BYTES: - g_value_set_int (value, queue->min_threshold_bytes); - break; case ARG_MAY_DEADLOCK: g_value_set_boolean (value, queue->may_deadlock); break; case ARG_BLOCK_TIMEOUT: - g_value_set_int (value, queue->block_timeout); + g_value_set_uint64 (value, queue->block_timeout); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); diff --git a/plugins/elements/gstqueue.h b/plugins/elements/gstqueue.h index c52d637730..5e87b899e5 100644 --- a/plugins/elements/gstqueue.h +++ b/plugins/elements/gstqueue.h @@ -56,43 +56,51 @@ struct _GstQueue { GstPad *sinkpad; GstPad *srcpad; - /* the queue of buffers we're keeping our grubby hands on */ + /* the queue of data we're keeping our grubby hands on */ GQueue *queue; - guint level_buffers; /* number of buffers queued here */ - guint level_bytes; /* number of bytes queued here */ - guint64 level_time; /* amount of time queued here */ + struct { + guint buffers; /* no. of buffers */ + guint bytes; /* no. of bytes */ + guint64 time; /* amount of time */ + } cur_level, /* currently in the queue */ + max_size, /* max. amount of data allowed in the queue */ + min_treshold; /* min. amount of data required to wake reader */ - guint size_buffers; /* size of queue in buffers */ - guint size_bytes; /* size of queue in bytes */ - guint64 size_time; /* size of queue in time */ + /* whether we leak data, and at which end */ + gint leaky; + + /* number of nanoseconds until a blocked queue 'times out' + * to receive data and returns a filler event. -1 = disable */ + guint64 block_timeout; + + /* it the queue should fail on possible deadlocks */ + gboolean may_deadlock; - gint leaky; /* whether the queue is leaky, and if so at which end */ - gint block_timeout; /* microseconds until a blocked queue times out and returns GST_EVENT_FILLER. - * A value of -1 will block forever. */ - guint min_threshold_bytes; /* the minimum number of bytes required before - * waking up the reader thread */ - gboolean may_deadlock; /* it the queue should fail on possible deadlocks */ gboolean interrupt; gboolean flush; GMutex *qlock; /* lock for queue (vs object lock) */ - GCond *not_empty; /* signals buffers now available for reading */ - GCond *not_full; /* signals space now available for writing */ + GCond *item_add; /* signals buffers now available for reading */ + GCond *item_del; /* signals space now available for writing */ + GCond *event_done; /* upstream event signaller */ GTimeVal *timeval; /* the timeout for the queue locking */ - GAsyncQueue *events; /* upstream events get decoupled here */ + GQueue *events; /* upstream events get decoupled here */ - GST_OBJECT_PADDING + gpointer _gst_reserved[GST_PADDING]; }; struct _GstQueueClass { GstElementClass parent_class; - /* signal callbacks */ - void (*full) (GstQueue *queue); + /* signals - 'running' is called from both sides + * which might make it sort of non-useful... */ + void (*underrun) (GstQueue *queue); + void (*running) (GstQueue *queue); + void (*overrun) (GstQueue *queue); - GST_CLASS_PADDING + gpointer _gst_reserved[GST_PADDING]; }; GType gst_queue_get_type (void); diff --git a/plugins/elements/gsttee.c b/plugins/elements/gsttee.c index 533a907281..c5d03cb21a 100644 --- a/plugins/elements/gsttee.c +++ b/plugins/elements/gsttee.c @@ -195,7 +195,7 @@ gst_tee_getcaps (GstPad *pad) pads = gst_element_get_pad_list (GST_ELEMENT (tee)); while (pads) { - GstPad *srcpad = GST_PAD_CAST (pads->data); + GstPad *srcpad = GST_PAD (pads->data); GstPad *peer; const GstCaps2 *peercaps; GstCaps2 *newcaps; diff --git a/plugins/elements/gsttypefind.c b/plugins/elements/gsttypefind.c index 066ecf19dd..565758d09c 100644 --- a/plugins/elements/gsttypefind.c +++ b/plugins/elements/gsttypefind.c @@ -367,16 +367,17 @@ stop_typefinding (GstTypeFindElement *typefind) if (push_cached_buffers) { GstBuffer *buffer; guint size = gst_buffer_store_get_size (typefind->store, 0); - if (size && (buffer = gst_buffer_store_get_buffer (typefind->store, 0, size))) { - gst_pad_push (typefind->src, GST_DATA (buffer)); - } else { - size = 0; - } + GST_LOG_OBJECT (typefind, "seeking back to current position %u", size); if (!gst_pad_send_event (GST_PAD_PEER (typefind->sink), gst_event_new_seek (GST_SEEK_METHOD_SET | GST_FORMAT_BYTES, size))) { GST_WARNING_OBJECT (typefind, "could not seek to required position %u, hope for the best", size); } + if (size && (buffer = gst_buffer_store_get_buffer (typefind->store, 0, size))) { + gst_pad_push (typefind->src, GST_DATA (buffer)); + } else { + size = 0; + } } gst_buffer_store_clear (typefind->store); } diff --git a/plugins/elements/gsttypefindelement.c b/plugins/elements/gsttypefindelement.c index 066ecf19dd..565758d09c 100644 --- a/plugins/elements/gsttypefindelement.c +++ b/plugins/elements/gsttypefindelement.c @@ -367,16 +367,17 @@ stop_typefinding (GstTypeFindElement *typefind) if (push_cached_buffers) { GstBuffer *buffer; guint size = gst_buffer_store_get_size (typefind->store, 0); - if (size && (buffer = gst_buffer_store_get_buffer (typefind->store, 0, size))) { - gst_pad_push (typefind->src, GST_DATA (buffer)); - } else { - size = 0; - } + GST_LOG_OBJECT (typefind, "seeking back to current position %u", size); if (!gst_pad_send_event (GST_PAD_PEER (typefind->sink), gst_event_new_seek (GST_SEEK_METHOD_SET | GST_FORMAT_BYTES, size))) { GST_WARNING_OBJECT (typefind, "could not seek to required position %u, hope for the best", size); } + if (size && (buffer = gst_buffer_store_get_buffer (typefind->store, 0, size))) { + gst_pad_push (typefind->src, GST_DATA (buffer)); + } else { + size = 0; + } } gst_buffer_store_clear (typefind->store); } diff --git a/plugins/indexers/gstindexers.c b/plugins/indexers/gstindexers.c index 6894202a4d..5d4c4afff7 100644 --- a/plugins/indexers/gstindexers.c +++ b/plugins/indexers/gstindexers.c @@ -39,11 +39,10 @@ GST_PLUGIN_DEFINE ( GST_VERSION_MAJOR, GST_VERSION_MINOR, "gstindexers", - "Gstremaer core indexers", + "GStreamer core indexers", plugin_init, VERSION, GST_LICENSE, - GST_COPYRIGHT, GST_PACKAGE, GST_ORIGIN ) diff --git a/po/Makefile.in.in b/po/Makefile.in.in index 343b743fe8..e413a0c24b 100644 --- a/po/Makefile.in.in +++ b/po/Makefile.in.in @@ -108,6 +108,12 @@ stamp-po: $(srcdir)/$(DOMAIN).pot # otherwise packages like GCC can not be built if only parts of the source # have been downloaded. +# thomasvs, 11/12/03: this option has been added in gettext 0.12 +# if we really need this, then we should add a check for the version, +# but for now it doesn't seem to be worth the hassle, so I'm commenting +# this option to the gettext incantation below +# --msgid-bugs-address='$(MSGID_BUGS_ADDRESS)' + # This target rebuilds $(DOMAIN).pot; it is an expensive operation. # Note that $(DOMAIN).pot is not touched if it doesn't need to be changed. $(DOMAIN).pot-update: $(POTFILES) $(srcdir)/POTFILES.in remove-potcdate.sed @@ -115,7 +121,7 @@ $(DOMAIN).pot-update: $(POTFILES) $(srcdir)/POTFILES.in remove-potcdate.sed --add-comments=TRANSLATORS: $(XGETTEXT_OPTIONS) \ --files-from=$(srcdir)/POTFILES.in \ --copyright-holder='$(COPYRIGHT_HOLDER)' \ - --msgid-bugs-address='$(MSGID_BUGS_ADDRESS)' + test ! -f $(DOMAIN).po || { \ if test -f $(srcdir)/$(DOMAIN).pot; then \ sed -f remove-potcdate.sed < $(srcdir)/$(DOMAIN).pot > $(DOMAIN).1po && \ diff --git a/po/de.po b/po/de.po index a4b91f39e9..c387af5a89 100644 --- a/po/de.po +++ b/po/de.po @@ -6,8 +6,8 @@ msgid "" msgstr "" "Project-Id-Version: gstreamer-0.7 0.7.0.1\n" -"Report-Msgid-Bugs-To: \"http://bugzilla.gnome.org\"\n" -"POT-Creation-Date: 2003-11-22 17:49+0100\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2003-12-17 21:27-0800\n" "PO-Revision-Date: 2003-10-08 15:36-0700\n" "Last-Translator: David Schleef \n" "Language-Team: Gnome Translators \n" @@ -15,69 +15,73 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -#: gst/gst.c:112 +#: gst/gst.c:116 msgid "Print the GStreamer version" msgstr "druck die GStreamer Version" -#: gst/gst.c:113 +#: gst/gst.c:117 msgid "Make all warnings fatal" msgstr "macht alle Achtunge toedlich" -#: gst/gst.c:115 +#: gst/gst.c:119 msgid "" "default debug level from 1 (only error) to 5 (anything) or 0 for no output" msgstr "" -#: gst/gst.c:116 +#: gst/gst.c:120 msgid "" "colon-seperated list of category_name=level pairs to set specific levels for " "the individual categories.\n" "Example:GST_AUTOPLUG=5:GST_ELEMENT_*=3" msgstr "" -#: gst/gst.c:117 +#: gst/gst.c:121 msgid "disable color debugging output" msgstr "abschalt Farbe in Fehlersucheausgabe" -#: gst/gst.c:118 +#: gst/gst.c:122 msgid "disable debugging" msgstr "abschalt die Fehlersuche" -#: gst/gst.c:119 +#: gst/gst.c:123 msgid "print available debug categories and exit" msgstr "" -#: gst/gst.c:121 +#: gst/gst.c:125 msgid "Disable accelerated CPU instructions" msgstr "" -#: gst/gst.c:122 +#: gst/gst.c:126 msgid "enable verbose plugin loading diagnostics" msgstr "" -#: gst/gst.c:123 +#: gst/gst.c:127 msgid "'" msgstr "" -#: gst/gst.c:123 +#: gst/gst.c:127 msgid "'--separated path list for loading plugins" msgstr "" -#: gst/gst.c:124 +#: gst/gst.c:128 msgid "" "comma-separated list of plugins to preload in addition to the list stored in " "env variable GST_PLUGIN_PATH" msgstr "" -#: gst/gst.c:125 +#: gst/gst.c:129 +msgid "disable trapping of segmentation faults during plugin loading" +msgstr "" + +#: gst/gst.c:130 msgid "scheduler to use ('" msgstr "" -#: gst/gst.c:125 +#: gst/gst.c:130 msgid "' is the default)" msgstr "" -#: gst/gst.c:126 +#: gst/gst.c:131 msgid "registry to use" msgstr "" diff --git a/po/es.po b/po/es.po index 8b01f72a37..9016bbde74 100644 --- a/po/es.po +++ b/po/es.po @@ -6,8 +6,8 @@ msgid "" msgstr "" "Project-Id-Version: GStreamer 0.7.0.1\n" -"Report-Msgid-Bugs-To: \"http://bugzilla.gnome.org\"\n" -"POT-Creation-Date: 2003-11-22 17:49+0100\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2003-12-17 21:27-0800\n" "PO-Revision-Date: 2003-10-09 14:10-0700\n" "Last-Translator: David Schleef \n" "Language-Team: translators \n" @@ -15,68 +15,72 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -#: gst/gst.c:112 +#: gst/gst.c:116 msgid "Print the GStreamer version" msgstr "" -#: gst/gst.c:113 +#: gst/gst.c:117 msgid "Make all warnings fatal" msgstr "" -#: gst/gst.c:115 +#: gst/gst.c:119 msgid "" "default debug level from 1 (only error) to 5 (anything) or 0 for no output" msgstr "" -#: gst/gst.c:116 +#: gst/gst.c:120 msgid "" "colon-seperated list of category_name=level pairs to set specific levels for " "the individual categories.\n" "Example:GST_AUTOPLUG=5:GST_ELEMENT_*=3" msgstr "" -#: gst/gst.c:117 +#: gst/gst.c:121 msgid "disable color debugging output" msgstr "" -#: gst/gst.c:118 +#: gst/gst.c:122 msgid "disable debugging" msgstr "" -#: gst/gst.c:119 +#: gst/gst.c:123 msgid "print available debug categories and exit" msgstr "" -#: gst/gst.c:121 +#: gst/gst.c:125 msgid "Disable accelerated CPU instructions" msgstr "" -#: gst/gst.c:122 +#: gst/gst.c:126 msgid "enable verbose plugin loading diagnostics" msgstr "" -#: gst/gst.c:123 +#: gst/gst.c:127 msgid "'" msgstr "" -#: gst/gst.c:123 +#: gst/gst.c:127 msgid "'--separated path list for loading plugins" msgstr "" -#: gst/gst.c:124 +#: gst/gst.c:128 msgid "" "comma-separated list of plugins to preload in addition to the list stored in " "env variable GST_PLUGIN_PATH" msgstr "" -#: gst/gst.c:125 +#: gst/gst.c:129 +msgid "disable trapping of segmentation faults during plugin loading" +msgstr "" + +#: gst/gst.c:130 msgid "scheduler to use ('" msgstr "" -#: gst/gst.c:125 +#: gst/gst.c:130 msgid "' is the default)" msgstr "" -#: gst/gst.c:126 +#: gst/gst.c:131 msgid "registry to use" msgstr "" diff --git a/po/nl.po b/po/nl.po index 8b01f72a37..9016bbde74 100644 --- a/po/nl.po +++ b/po/nl.po @@ -6,8 +6,8 @@ msgid "" msgstr "" "Project-Id-Version: GStreamer 0.7.0.1\n" -"Report-Msgid-Bugs-To: \"http://bugzilla.gnome.org\"\n" -"POT-Creation-Date: 2003-11-22 17:49+0100\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2003-12-17 21:27-0800\n" "PO-Revision-Date: 2003-10-09 14:10-0700\n" "Last-Translator: David Schleef \n" "Language-Team: translators \n" @@ -15,68 +15,72 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -#: gst/gst.c:112 +#: gst/gst.c:116 msgid "Print the GStreamer version" msgstr "" -#: gst/gst.c:113 +#: gst/gst.c:117 msgid "Make all warnings fatal" msgstr "" -#: gst/gst.c:115 +#: gst/gst.c:119 msgid "" "default debug level from 1 (only error) to 5 (anything) or 0 for no output" msgstr "" -#: gst/gst.c:116 +#: gst/gst.c:120 msgid "" "colon-seperated list of category_name=level pairs to set specific levels for " "the individual categories.\n" "Example:GST_AUTOPLUG=5:GST_ELEMENT_*=3" msgstr "" -#: gst/gst.c:117 +#: gst/gst.c:121 msgid "disable color debugging output" msgstr "" -#: gst/gst.c:118 +#: gst/gst.c:122 msgid "disable debugging" msgstr "" -#: gst/gst.c:119 +#: gst/gst.c:123 msgid "print available debug categories and exit" msgstr "" -#: gst/gst.c:121 +#: gst/gst.c:125 msgid "Disable accelerated CPU instructions" msgstr "" -#: gst/gst.c:122 +#: gst/gst.c:126 msgid "enable verbose plugin loading diagnostics" msgstr "" -#: gst/gst.c:123 +#: gst/gst.c:127 msgid "'" msgstr "" -#: gst/gst.c:123 +#: gst/gst.c:127 msgid "'--separated path list for loading plugins" msgstr "" -#: gst/gst.c:124 +#: gst/gst.c:128 msgid "" "comma-separated list of plugins to preload in addition to the list stored in " "env variable GST_PLUGIN_PATH" msgstr "" -#: gst/gst.c:125 +#: gst/gst.c:129 +msgid "disable trapping of segmentation faults during plugin loading" +msgstr "" + +#: gst/gst.c:130 msgid "scheduler to use ('" msgstr "" -#: gst/gst.c:125 +#: gst/gst.c:130 msgid "' is the default)" msgstr "" -#: gst/gst.c:126 +#: gst/gst.c:131 msgid "registry to use" msgstr "" diff --git a/po/no.po b/po/no.po index 8b01f72a37..9016bbde74 100644 --- a/po/no.po +++ b/po/no.po @@ -6,8 +6,8 @@ msgid "" msgstr "" "Project-Id-Version: GStreamer 0.7.0.1\n" -"Report-Msgid-Bugs-To: \"http://bugzilla.gnome.org\"\n" -"POT-Creation-Date: 2003-11-22 17:49+0100\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2003-12-17 21:27-0800\n" "PO-Revision-Date: 2003-10-09 14:10-0700\n" "Last-Translator: David Schleef \n" "Language-Team: translators \n" @@ -15,68 +15,72 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -#: gst/gst.c:112 +#: gst/gst.c:116 msgid "Print the GStreamer version" msgstr "" -#: gst/gst.c:113 +#: gst/gst.c:117 msgid "Make all warnings fatal" msgstr "" -#: gst/gst.c:115 +#: gst/gst.c:119 msgid "" "default debug level from 1 (only error) to 5 (anything) or 0 for no output" msgstr "" -#: gst/gst.c:116 +#: gst/gst.c:120 msgid "" "colon-seperated list of category_name=level pairs to set specific levels for " "the individual categories.\n" "Example:GST_AUTOPLUG=5:GST_ELEMENT_*=3" msgstr "" -#: gst/gst.c:117 +#: gst/gst.c:121 msgid "disable color debugging output" msgstr "" -#: gst/gst.c:118 +#: gst/gst.c:122 msgid "disable debugging" msgstr "" -#: gst/gst.c:119 +#: gst/gst.c:123 msgid "print available debug categories and exit" msgstr "" -#: gst/gst.c:121 +#: gst/gst.c:125 msgid "Disable accelerated CPU instructions" msgstr "" -#: gst/gst.c:122 +#: gst/gst.c:126 msgid "enable verbose plugin loading diagnostics" msgstr "" -#: gst/gst.c:123 +#: gst/gst.c:127 msgid "'" msgstr "" -#: gst/gst.c:123 +#: gst/gst.c:127 msgid "'--separated path list for loading plugins" msgstr "" -#: gst/gst.c:124 +#: gst/gst.c:128 msgid "" "comma-separated list of plugins to preload in addition to the list stored in " "env variable GST_PLUGIN_PATH" msgstr "" -#: gst/gst.c:125 +#: gst/gst.c:129 +msgid "disable trapping of segmentation faults during plugin loading" +msgstr "" + +#: gst/gst.c:130 msgid "scheduler to use ('" msgstr "" -#: gst/gst.c:125 +#: gst/gst.c:130 msgid "' is the default)" msgstr "" -#: gst/gst.c:126 +#: gst/gst.c:131 msgid "registry to use" msgstr "" diff --git a/tests/bufspeed/Makefile.am b/tests/bufspeed/Makefile.am index e42a756bc5..fdb4202423 100644 --- a/tests/bufspeed/Makefile.am +++ b/tests/bufspeed/Makefile.am @@ -1,9 +1,14 @@ noinst_PROGRAMS = test1 test2 -test1_SOURCES = test1.c $(top_srcdir)/gst/gstbuffer.c gstmempool.c +test1_SOURCES = test1.c gstbuffer.c gstmempool.c -EXTRA_DIST = gstbuffer.h gstmempool.h +BUILT_SOURCES = gstbuffer.c + +gstbuffer.c: + cp $(top_srcdir)/gst/gstbuffer.c . + +EXTRA_DIST = gstmempool.h LDADD = $(GST_LIBS) -AM_CFLAGS = $(GST_CFLAGS) +AM_CFLAGS = $(GST_CFLAGS) -I$(top_srcdir)/gst diff --git a/tests/bufspeed/gstbuffer.c b/tests/bufspeed/gstbuffer.c deleted file mode 100644 index cb2cfe89cf..0000000000 --- a/tests/bufspeed/gstbuffer.c +++ /dev/null @@ -1,495 +0,0 @@ -/* GStreamer - * Copyright (C) 1999,2000 Erik Walthinsen - * 2000 Wim Taymans - * - * gstbuffer.c: Buffer operations - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -/* this file makes too much noise for most debugging sessions */ -#define GST_DEBUG_FORCE_DISABLE -#include "gst/gst_private.h" - -#include "gstbuffer.h" -#include "gstmempool.h" - -GType _gst_buffer_type; - -static GstMemPool *_gst_buffer_pool; - -static void -gst_buffer_alloc_func (GstMemPool *pool, gpointer data) -{ - GstBuffer *buffer = GST_BUFFER (data); - - GST_DATA_TYPE(buffer) = _gst_buffer_type; - buffer->lock = g_mutex_new (); -} - -static void -gst_buffer_free_func (GstMemPool *pool, gpointer data) -{ - GstBuffer *buffer = GST_BUFFER (data); - - g_mutex_free (buffer->lock); -} - -void -_gst_buffer_initialize (void) -{ - int buffersize = sizeof(GstBuffer); - static const GTypeInfo buffer_info = { - 0, /* sizeof(class), */ - NULL, - NULL, - NULL, - NULL, - NULL, - 0, /* sizeof(object), */ - 0, - NULL, - }; - - /* round up to the nearest 32 bytes for cache-line and other efficiencies */ - buffersize = (((buffersize-1) / 32) + 1) * 32; - - _gst_buffer_pool = gst_mem_pool_new ("GstBuffer", buffersize, - buffersize * 32, G_ALLOC_AND_FREE, gst_buffer_alloc_func, gst_buffer_free_func); - - _gst_buffer_type = g_type_register_static (G_TYPE_INT, "GstBuffer", &buffer_info, 0); -} - -/** - * gst_buffer_new: - * - * Create a new buffer. - * - * Returns: new buffer - */ -GstBuffer* -gst_buffer_new (void) -{ - GstBuffer *buffer; - - buffer = gst_mem_pool_alloc (_gst_buffer_pool); - - GST_CAT_INFO (GST_CAT_BUFFER,"creating new buffer %p",buffer); - -#ifdef HAVE_ATOMIC_H - atomic_set (&buffer->refcount, 1); -#else - buffer->refcount = 1; -#endif - buffer->offset = -1; - buffer->flags = 0; - buffer->data = NULL; - buffer->size = 0; - buffer->maxsize = 0; - buffer->timestamp = 0; - buffer->parent = NULL; - buffer->pool = NULL; - buffer->pool_private = NULL; - buffer->free = NULL; - buffer->copy = NULL; - - return buffer; -} - -/** - * gst_buffer_new_from_pool: - * @pool: the buffer pool to use - * - * Create a new buffer using the specified bufferpool. - * - * Returns: new buffer - */ -GstBuffer* -gst_buffer_new_from_pool (GstBufferPool *pool, guint32 offset, guint32 size) -{ - GstBuffer *buffer; - - g_return_val_if_fail (pool != NULL, NULL); - g_return_val_if_fail (pool->buffer_new != NULL, NULL); - - buffer = pool->buffer_new (pool, offset, size, pool->user_data); - buffer->pool = pool; - buffer->free = pool->buffer_free; - buffer->copy = pool->buffer_copy; - - GST_CAT_INFO (GST_CAT_BUFFER,"creating new buffer %p from pool %p (size %x, offset %x)", - buffer, pool, size, offset); - - return buffer; -} - -/** - * gst_buffer_create_sub: - * @parent: parent buffer - * @offset: offset into parent buffer - * @size: size of new subbuffer - * - * Creates a sub-buffer from the parent at a given offset. - * - * Returns: new buffer - */ -GstBuffer* -gst_buffer_create_sub (GstBuffer *parent, - guint32 offset, - guint32 size) -{ - GstBuffer *buffer; - - g_return_val_if_fail (parent != NULL, NULL); - g_return_val_if_fail (GST_BUFFER_REFCOUNT(parent) > 0, NULL); - g_return_val_if_fail (size > 0, NULL); - g_return_val_if_fail ((offset+size) <= parent->size, NULL); - - buffer = gst_mem_pool_alloc (_gst_buffer_pool); - GST_DATA_TYPE(buffer) = _gst_buffer_type; - - GST_CAT_INFO (GST_CAT_BUFFER,"creating new subbuffer %p from parent %p (size %u, offset %u)", - buffer, parent, size, offset); - -#ifdef HAVE_ATOMIC_H - atomic_set (&buffer->refcount, 1); -#else - buffer->refcount = 1; -#endif - - /* copy flags and type from parent, for lack of better */ - buffer->flags = parent->flags; - - /* set the data pointer, size, offset, and maxsize */ - buffer->data = parent->data + offset; - buffer->size = size; - buffer->maxsize = parent->size - offset; - - /* deal with bogus/unknown offsets */ - if (parent->offset != -1) - buffer->offset = parent->offset + offset; - else - buffer->offset = -1; - - /* again, for lack of better, copy parent's timestamp */ - buffer->timestamp = parent->timestamp; - buffer->maxage = parent->maxage; - - /* if the parent buffer is a subbuffer itself, use its parent, a real buffer */ - if (parent->parent != NULL) - parent = parent->parent; - - /* set parentage and reference the parent */ - buffer->parent = parent; - gst_buffer_ref (parent); - - buffer->pool = NULL; - - return buffer; -} - - -/* FIXME FIXME: how does this overlap with the newly-added gst_buffer_span() ??? */ -/** - * gst_buffer_append: - * @buffer: a buffer - * @append: the buffer to append - * - * Creates a new buffer by appending the data of append to the - * existing data of buffer. - * - * Returns: new buffer - */ -GstBuffer* -gst_buffer_append (GstBuffer *buffer, - GstBuffer *append) -{ - guint size; - GstBuffer *newbuf; - - g_return_val_if_fail (buffer != NULL, NULL); - g_return_val_if_fail (append != NULL, NULL); - g_return_val_if_fail (buffer->pool == NULL, NULL); - g_return_val_if_fail (GST_BUFFER_REFCOUNT(buffer) > 0, NULL); - g_return_val_if_fail (GST_BUFFER_REFCOUNT(append) > 0, NULL); - - GST_CAT_INFO (GST_CAT_BUFFER,"appending buffers %p and %p",buffer,append); - - GST_BUFFER_LOCK (buffer); - /* the buffer is not used by anyone else */ - if (GST_BUFFER_REFCOUNT (buffer) == 1 && buffer->parent == NULL - && !GST_BUFFER_FLAG_IS_SET (buffer, GST_BUFFER_DONTFREE)) { - /* save the old size */ - size = buffer->size; - buffer->size += append->size; - buffer->data = g_realloc (buffer->data, buffer->size); - memcpy(buffer->data + size, append->data, append->size); - GST_BUFFER_UNLOCK (buffer); - } - /* the buffer is used, create a new one */ - else { - newbuf = gst_buffer_new (); - newbuf->size = buffer->size+append->size; - newbuf->data = g_malloc (newbuf->size); - memcpy (newbuf->data, buffer->data, buffer->size); - memcpy (newbuf->data+buffer->size, append->data, append->size); - GST_BUFFER_UNLOCK (buffer); - gst_buffer_unref (buffer); - buffer = newbuf; - } - return buffer; -} - -/** - * gst_buffer_destroy: - * @buffer: the GstBuffer to destroy - * - * destroy the buffer - */ -void -gst_buffer_destroy (GstBuffer *buffer) -{ - - g_return_if_fail (buffer != NULL); - - GST_CAT_INFO (GST_CAT_BUFFER, "freeing %sbuffer %p", - (buffer->parent?"sub":""), - buffer); - - /* free the data only if there is some, DONTFREE isn't set, and not sub */ - if (GST_BUFFER_DATA (buffer) && - !GST_BUFFER_FLAG_IS_SET (buffer, GST_BUFFER_DONTFREE) && - (buffer->parent == NULL)) { - /* if there's a free function, use it */ - if (buffer->free != NULL) { - (buffer->free)(buffer); - } else { - g_free (GST_BUFFER_DATA (buffer)); - } - } - - /* unreference the parent if there is one */ - if (buffer->parent != NULL) - gst_buffer_unref (buffer->parent); - - /* remove it entirely from memory */ - gst_mem_pool_free (_gst_buffer_pool,buffer); -} - -/** - * gst_buffer_ref: - * @buffer: the GstBuffer to reference - * - * Increment the refcount of this buffer. - */ -void -gst_buffer_ref (GstBuffer *buffer) -{ - g_return_if_fail (buffer != NULL); - g_return_if_fail (GST_BUFFER_REFCOUNT(buffer) > 0); - - GST_CAT_INFO (GST_CAT_BUFFER, "ref buffer %p\n", buffer); - -#ifdef HAVE_ATOMIC_H - atomic_inc (&(buffer->refcount)); -#else - GST_BUFFER_LOCK (buffer); - buffer->refcount++; - GST_BUFFER_UNLOCK (buffer); -#endif -} - -/** - * gst_buffer_unref: - * @buffer: the GstBuffer to unref - * - * Decrement the refcount of this buffer. If the refcount is - * zero, the buffer will be destroyed. - */ -void -gst_buffer_unref (GstBuffer *buffer) -{ - gint zero; - - g_return_if_fail (buffer != NULL); - g_return_if_fail (GST_BUFFER_REFCOUNT(buffer) > 0); - - GST_CAT_INFO (GST_CAT_BUFFER, "unref buffer %p\n", buffer); - -#ifdef HAVE_ATOMIC_H - zero = atomic_dec_and_test (&(buffer->refcount)); -#else - GST_BUFFER_LOCK (buffer); - buffer->refcount--; - zero = (buffer->refcount == 0); - GST_BUFFER_UNLOCK (buffer); -#endif - - /* if we ended up with the refcount at zero, destroy the buffer */ - if (zero) { - gst_buffer_destroy (buffer); - } -} - -/** - * gst_buffer_copy: - * @buffer: the orignal GstBuffer to make a copy of - * - * Make a full copy of the give buffer, data and all. - * - * Returns: new buffer - */ -GstBuffer * -gst_buffer_copy (GstBuffer *buffer) -{ - GstBuffer *newbuf; - - g_return_val_if_fail (GST_BUFFER_REFCOUNT(buffer) > 0, NULL); - - /* if a copy function exists, use it, else copy the bytes */ - if (buffer->copy != NULL) { - newbuf = (buffer->copy)(buffer); - } else { - /* allocate a new buffer */ - newbuf = gst_buffer_new(); - - /* copy the absolute size */ - newbuf->size = buffer->size; - /* allocate space for the copy */ - newbuf->data = (guchar *)g_malloc (buffer->size); - /* copy the data straight across */ - memcpy(newbuf->data,buffer->data,buffer->size); - /* the new maxsize is the same as the size, since we just malloc'd it */ - newbuf->maxsize = newbuf->size; - } - newbuf->offset = buffer->offset; - newbuf->timestamp = buffer->timestamp; - newbuf->maxage = buffer->maxage; - - /* since we just created a new buffer, so we have no ties to old stuff */ - newbuf->parent = NULL; - newbuf->pool = NULL; - - return newbuf; -} - -/* - * gst_buffer_is_span_fast - * @buf1: first source buffer - * @buf2: second source buffer - * - * Determines whether a gst_buffer_span is free, or requires a memcpy. - * - * Returns: TRUE if the buffers are contiguous, FALSE if a copy would be required. - */ -gboolean -gst_buffer_is_span_fast (GstBuffer *buf1, GstBuffer *buf2) -{ - g_return_val_if_fail (GST_BUFFER_REFCOUNT(buf1) > 0, FALSE); - g_return_val_if_fail (GST_BUFFER_REFCOUNT(buf2) > 0, FALSE); - - return (buf1->parent && buf2->parent && - (buf1->parent == buf2->parent) && - ((buf1->data + buf1->size) == buf2->data)); -} - - -/** - * gst_buffer_span: - * @buf1: first source buffer to merge - * @offset: offset in first buffer to start new buffer - * @buf2: second source buffer to merge - * @len: length of new buffer - * - * Create a new buffer that consists of part of buf1 and buf2. - * Logically, buf1 and buf2 are concatenated into a single larger - * buffer, and a new buffer is created at the given offset inside - * this space, with a given length. - * - * If the two source buffers are children of the same larger buffer, - * and are contiguous, the new buffer will be a child of the shared - * parent, and thus no copying is necessary. - * - * Returns: new buffer that spans the two source buffers - */ -/* FIXME need to think about CoW and such... */ -GstBuffer * -gst_buffer_span (GstBuffer *buf1, guint32 offset, GstBuffer *buf2, guint32 len) -{ - GstBuffer *newbuf; - - g_return_val_if_fail (GST_BUFFER_REFCOUNT(buf1) > 0, NULL); - g_return_val_if_fail (GST_BUFFER_REFCOUNT(buf2) > 0, NULL); - - /* make sure buf1 has a lower address than buf2 */ - if (buf1->data > buf2->data) { - GstBuffer *tmp = buf1; - g_print ("swapping buffers\n"); - buf1 = buf2; - buf2 = tmp; - } - - /* if the two buffers have the same parent and are adjacent */ - if (gst_buffer_is_span_fast(buf1,buf2)) { - /* we simply create a subbuffer of the common parent */ - newbuf = gst_buffer_create_sub (buf1->parent, buf1->data - (buf1->parent->data) + offset, len); - } - else { - g_print ("slow path taken in buffer_span\n"); - /* otherwise we simply have to brute-force copy the buffers */ - newbuf = gst_buffer_new (); - - /* put in new size */ - newbuf->size = len; - /* allocate space for the copy */ - newbuf->data = (guchar *)g_malloc(len); - /* copy the first buffer's data across */ - memcpy(newbuf->data, buf1->data + offset, buf1->size - offset); - /* copy the second buffer's data across */ - memcpy(newbuf->data + (buf1->size - offset), buf2->data, len - (buf1->size - offset)); - - if (newbuf->offset != -1) - newbuf->offset = buf1->offset + offset; - newbuf->timestamp = buf1->timestamp; - if (buf2->maxage > buf1->maxage) newbuf->maxage = buf2->maxage; - else newbuf->maxage = buf1->maxage; - - } - - return newbuf; -} - - -/** - * gst_buffer_merge: - * @buf1: first source buffer to merge - * @buf2: second source buffer to merge - * - * Create a new buffer that is the concatenation of the two source - * buffers. The original source buffers will not be modified or - * unref'd. - * - * Internally is nothing more than a specialized gst_buffer_span, - * so the same optimizations can occur. - * - * Returns: new buffer that's the concatenation of the source buffers - */ -GstBuffer * -gst_buffer_merge (GstBuffer *buf1, GstBuffer *buf2) -{ - /* we're just a specific case of the more general gst_buffer_span() */ - return gst_buffer_span (buf1, 0, buf2, buf1->size + buf2->size); -} diff --git a/tests/bufspeed/gstbuffer.h b/tests/bufspeed/gstbuffer.h deleted file mode 100644 index 5a766957f0..0000000000 --- a/tests/bufspeed/gstbuffer.h +++ /dev/null @@ -1,164 +0,0 @@ -/* GStreamer - * Copyright (C) 1999,2000 Erik Walthinsen - * 2000 Wim Taymans - * - * gstbuffer.h: Header for GstBuffer object - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - - -#ifndef __GST_BUFFER_H__ -#define __GST_BUFFER_H__ - -/* */ -/* Define this to add file:line info to each GstBuffer showing */ -/* the location in the source code where the buffer was created. */ -/* */ -/* #define GST_BUFFER_WHERE */ -/* */ -/* Then in gdb, you can `call gst_buffer_print_live()' to get a list */ -/* of allocated GstBuffers and also the file:line where they were */ -/* allocated. */ -/* */ - -#include - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#ifdef HAVE_ATOMIC_H -#include -#endif - -G_BEGIN_DECLS - -extern GType _gst_buffer_type; - -#define GST_TYPE_BUFFER (_gst_buffer_type) -#define GST_BUFFER(buf) ((GstBuffer *)(buf)) -#define GST_IS_BUFFER(buf) (GST_DATA_TYPE(buf) == GST_TYPE_BUFFER) - -#define GST_BUFFER_FLAGS(buf) (GST_BUFFER(buf)->flags) -#define GST_BUFFER_FLAG_IS_SET(buf,flag) (GST_BUFFER_FLAGS(buf) & (1<<(flag))) -#define GST_BUFFER_FLAG_SET(buf,flag) G_STMT_START{ (GST_BUFFER_FLAGS(buf) |= (1<<(flag))); }G_STMT_END -#define GST_BUFFER_FLAG_UNSET(buf,flag) G_STMT_START{ (GST_BUFFER_FLAGS(buf) &= ~(1<<(flag))); }G_STMT_END - - -#define GST_BUFFER_DATA(buf) (GST_BUFFER(buf)->data) -#define GST_BUFFER_SIZE(buf) (GST_BUFFER(buf)->size) -#define GST_BUFFER_OFFSET(buf) (GST_BUFFER(buf)->offset) -#define GST_BUFFER_MAXSIZE(buf) (GST_BUFFER(buf)->maxsize) -#define GST_BUFFER_TIMESTAMP(buf) (GST_BUFFER(buf)->timestamp) -#define GST_BUFFER_MAXAGE(buf) (GST_BUFFER(buf)->maxage) -#define GST_BUFFER_BUFFERPOOL(buf) (GST_BUFFER(buf)->pool) -#define GST_BUFFER_PARENT(buf) (GST_BUFFER(buf)->parent) -#define GST_BUFFER_POOL_PRIVATE(buf) (GST_BUFFER(buf)->pool_private) -#define GST_BUFFER_COPY_FUNC(buf) (GST_BUFFER(buf)->copy) -#define GST_BUFFER_FREE_FUNC(buf) (GST_BUFFER(buf)->free) - - -#define GST_BUFFER_LOCK(buf) (g_mutex_lock(GST_BUFFER(buf)->lock)) -#define GST_BUFFER_TRYLOCK(buf) (g_mutex_trylock(GST_BUFFER(buf)->lock)) -#define GST_BUFFER_UNLOCK(buf) (g_mutex_unlock(GST_BUFFER(buf)->lock)) - - -typedef enum { - GST_BUFFER_READONLY, - GST_BUFFER_ORIGINAL, - GST_BUFFER_DONTFREE, - -} GstBufferFlags; - - -typedef struct _GstBuffer GstBuffer; - - -typedef void (*GstBufferFreeFunc) (GstBuffer *buf); -typedef GstBuffer *(*GstBufferCopyFunc) (GstBuffer *srcbuf); - - - -struct _GstBuffer { - GstData data_type; - - /* locking */ - GMutex *lock; - - /* refcounting */ -#ifdef HAVE_ATOMIC_H - atomic_t refcount; -#define GST_BUFFER_REFCOUNT(buf) (atomic_read(&(GST_BUFFER((buf))->refcount))) -#else - int refcount; -#define GST_BUFFER_REFCOUNT(buf) (GST_BUFFER(buf)->refcount) -#endif - - /* flags */ - guint16 flags; - - /* pointer to data, its size, and offset in original source if known */ - guchar *data; - guint32 size; - guint32 maxsize; - guint32 offset; - - /* timestamp */ - gint64 timestamp; - gint64 maxage; - - /* subbuffer support, who's my parent? */ - GstBuffer *parent; - - /* this is a pointer to the buffer pool (if any) */ - GstBufferPool *pool; - gpointer pool_private; - - /* utility function pointers */ - GstBufferFreeFunc free; /* free the data associated with the buffer */ - GstBufferCopyFunc copy; /* copy the data from one buffer to another */ -}; - -/* initialisation */ -void _gst_buffer_initialize (void); -/* creating a new buffer from scratch */ -GstBuffer* gst_buffer_new (void); -GstBuffer* gst_buffer_new_from_pool (GstBufferPool *pool, guint32 offset, guint32 size); - -/* creating a subbuffer */ -GstBuffer* gst_buffer_create_sub (GstBuffer *parent, guint32 offset, guint32 size); - -/* refcounting */ -void gst_buffer_ref (GstBuffer *buffer); -void gst_buffer_unref (GstBuffer *buffer); - -/* destroying the buffer */ -void gst_buffer_destroy (GstBuffer *buffer); - -/* copy buffer */ -GstBuffer* gst_buffer_copy (GstBuffer *buffer); - -/* merge, span, or append two buffers, intelligently */ -GstBuffer* gst_buffer_merge (GstBuffer *buf1, GstBuffer *buf2); -GstBuffer* gst_buffer_span (GstBuffer *buf1,guint32 offset,GstBuffer *buf2,guint32 len); -GstBuffer* gst_buffer_append (GstBuffer *buf, GstBuffer *buf2); - -gboolean gst_buffer_is_span_fast (GstBuffer *buf1, GstBuffer *buf2); - -G_END_DECLS - -#endif /* __GST_BUFFER_H__ */ diff --git a/tests/bufspeed/gstmempool.c b/tests/bufspeed/gstmempool.c index da4542d26e..32e792c458 100644 --- a/tests/bufspeed/gstmempool.c +++ b/tests/bufspeed/gstmempool.c @@ -118,7 +118,7 @@ gst_mem_pool_destroy (GstMemPool *mem_pool) gpointer gst_mem_pool_alloc (GstMemPool *mem_pool) { - GstMemPoolElement *pool = NULL; + volatile GstMemPoolElement *pool = NULL; g_return_val_if_fail (mem_pool != NULL, NULL); @@ -187,7 +187,7 @@ gst_mem_pool_free (GstMemPool *mem_pool, gpointer mem) :"m" (*mem_pool), "r" (pool), "a" (mem_pool->free)); #else g_mutex_lock (mem_pool->chunk_lock); - pool->link = mem_pool->free; + pool->link = (GstMemPoolElement *) mem_pool->free; mem_pool->free = pool; g_mutex_unlock (mem_pool->chunk_lock); #endif diff --git a/tests/old/examples/Makefile.am b/tests/old/examples/Makefile.am index c7d650c31b..ed48293d69 100644 --- a/tests/old/examples/Makefile.am +++ b/tests/old/examples/Makefile.am @@ -4,7 +4,7 @@ else GST_LOADSAVE_DIRS = xml typefind endif -SUBDIRS = \ +dirs = \ helloworld \ queue \ queue2 \ @@ -17,22 +17,9 @@ SUBDIRS = \ cutter \ pingpong \ manual \ - retag \ - $(GST_LOADSAVE_DIRS) - -DIST_SUBDIRS = helloworld \ - queue \ - queue2 \ - queue3 \ - queue4 \ - launch \ - thread \ - plugins \ - mixer \ - cutter \ - pingpong \ - manual \ - xml \ - typefind \ retag +SUBDIRS = $(dirs) \ + $(GST_LOADSAVE_DIRS) + +DIST_SUBDIRS = $(dirs) xml typefind diff --git a/tests/old/examples/autoplug/.gitignore b/tests/old/examples/autoplug/.gitignore deleted file mode 100644 index f76c31a123..0000000000 --- a/tests/old/examples/autoplug/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -autoplug -xmlTest.gst diff --git a/tests/old/examples/autoplug/Makefile.am b/tests/old/examples/autoplug/Makefile.am deleted file mode 100644 index efba8b2c41..0000000000 --- a/tests/old/examples/autoplug/Makefile.am +++ /dev/null @@ -1,4 +0,0 @@ -noinst_PROGRAMS = autoplug - -autoplug_LDADD = $(GST_LIBS) -autoplug_CFLAGS = $(GST_CFLAGS) diff --git a/tests/old/examples/autoplug/autoplug.c b/tests/old/examples/autoplug/autoplug.c deleted file mode 100644 index dc9296d986..0000000000 --- a/tests/old/examples/autoplug/autoplug.c +++ /dev/null @@ -1,152 +0,0 @@ -#include - -static void -gst_play_have_type (GstElement *typefind, GstCaps *caps, GstElement *pipeline) -{ - GstElement *osssink, *videosink, *videoelement, *colorspace; - GstElement *new_element; - GstAutoplug *autoplug; - GstElement *autobin; - GstElement *filesrc; - GstElement *cache; - - GST_DEBUG ("GstPipeline: play have type"); - - gst_element_set_state (pipeline, GST_STATE_PAUSED); - - filesrc = gst_bin_get_by_name (GST_BIN (pipeline), "disk_source"); - autobin = gst_bin_get_by_name (GST_BIN (pipeline), "autobin"); - cache = gst_bin_get_by_name (GST_BIN (autobin), "cache"); - - /* unlink the typefind from the pipeline and remove it */ - gst_element_unlink_pads (cache, "src", typefind, "sink"); - gst_bin_remove (GST_BIN (autobin), typefind); - - /* and an audio sink */ - osssink = gst_element_factory_make ("osssink", "play_audio"); - g_assert (osssink != NULL); - - videosink = gst_bin_new ("videosink"); - /* and an video sink */ - videoelement = gst_element_factory_make ("xvideosink", "play_video"); - g_assert (videosink != NULL); - - colorspace = gst_element_factory_make ("colorspace", "colorspace"); - g_assert (colorspace != NULL); - - gst_element_link_pads (colorspace, "src", videoelement, "sink"); - gst_bin_add (GST_BIN (videosink), colorspace); - gst_bin_add (GST_BIN (videosink), videoelement); - - gst_element_add_ghost_pad (videosink, - gst_element_get_pad (colorspace, "sink"), "sink"); - - autoplug = gst_autoplug_factory_make ("staticrender"); - g_assert (autoplug != NULL); - - new_element = gst_autoplug_to_renderers (autoplug, - caps, - videosink, - osssink, - NULL); - - if (!new_element) { - g_print ("could not autoplug, no suitable codecs found...\n"); - exit (-1); - } - - gst_element_set_name (new_element, "new_element"); - - gst_bin_add (GST_BIN (autobin), new_element); - - g_object_set (G_OBJECT (cache), "reset", TRUE, NULL); - - gst_element_link_pads (cache, "src", new_element, "sink"); - - gst_element_set_state (pipeline, GST_STATE_PLAYING); - -#ifndef GST_DISABLE_LOADSAVE - gst_xml_write_file (GST_ELEMENT (pipeline), fopen ("xmlTest.gst", "w")); -#endif -} - -static void -gst_play_cache_empty (GstElement *element, GstElement *pipeline) -{ - GstElement *autobin; - GstElement *filesrc; - GstElement *cache; - GstElement *new_element; - - fprintf (stderr, "have cache empty\n"); - - gst_element_set_state (pipeline, GST_STATE_PAUSED); - - filesrc = gst_bin_get_by_name (GST_BIN (pipeline), "disk_source"); - autobin = gst_bin_get_by_name (GST_BIN (pipeline), "autobin"); - cache = gst_bin_get_by_name (GST_BIN (autobin), "cache"); - new_element = gst_bin_get_by_name (GST_BIN (autobin), "new_element"); - - gst_element_unlink_many (filesrc, cache, new_element, NULL); - gst_bin_remove (GST_BIN (autobin), cache); - gst_element_link_pads (filesrc, "src", new_element, "sink"); - - gst_element_set_state (pipeline, GST_STATE_PLAYING); - - fprintf (stderr, "done with cache_empty\n"); -} - -int main(int argc,char *argv[]) -{ - GstElement *filesrc; - GstElement *pipeline; - GstElement *autobin; - GstElement *typefind; - GstElement *cache; - - g_thread_init(NULL); - gst_init(&argc,&argv); - - if (argc != 2) { - g_print("usage: %s \n", argv[0]); - exit(-1); - } - - /* create a new pipeline to hold the elements */ - pipeline = gst_pipeline_new("pipeline"); - g_assert(pipeline != NULL); - - /* create a disk reader */ - filesrc = gst_element_factory_make("filesrc", "disk_source"); - g_assert(filesrc != NULL); - g_object_set(G_OBJECT(filesrc),"location", argv[1],NULL); - gst_bin_add (GST_BIN (pipeline), filesrc); - - autobin = gst_bin_new ("autobin"); - cache = gst_element_factory_make ("autoplugcache", "cache"); - g_signal_connect (G_OBJECT (cache), "cache_empty", G_CALLBACK (gst_play_cache_empty), pipeline); - - typefind = gst_element_factory_make ("typefind", "typefind"); - g_signal_connect (G_OBJECT (typefind), "have_type", G_CALLBACK (gst_play_have_type), pipeline); - gst_bin_add (GST_BIN (autobin), cache); - gst_bin_add (GST_BIN (autobin), typefind); - - gst_element_link_pads (cache, "src", typefind, "sink"); - gst_element_add_ghost_pad (autobin, gst_element_get_pad (cache, "sink"), "sink"); - - gst_bin_add (GST_BIN( pipeline), autobin); - gst_element_link_pads (filesrc, "src", autobin, "sink"); - - /* start playing */ - gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_PLAYING); - - while (gst_bin_iterate (GST_BIN (pipeline))); - - /* stop the pipeline */ - gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_NULL); - - gst_object_unref (GST_OBJECT (pipeline)); - - exit(0); -} - diff --git a/tests/old/examples/plugins/example.c b/tests/old/examples/plugins/example.c index ec1ee1c158..ad47dcdc9a 100644 --- a/tests/old/examples/plugins/example.c +++ b/tests/old/examples/plugins/example.c @@ -422,11 +422,6 @@ GST_PLUGIN_DEFINE ( "0.1", /* The version number of the plugin */ "LGPL", /* ieffective license the plugin can be shipped with. Must be * valid for all libraries it links to, too. */ - "(c) 2003 E. Xamplewriter", - /* Copyright holder for this plugin. This does not include - * the libraries it links to, contrary to the license. This - * field should be considered informational and not legally - * binding */ "my nifty plugin package", /* package this plugin belongs to. */ "http://www.mydomain.com" diff --git a/tests/old/testsuite/Makefile.am b/tests/old/testsuite/Makefile.am index 10eb0e111a..8755521f2a 100644 --- a/tests/old/testsuite/Makefile.am +++ b/tests/old/testsuite/Makefile.am @@ -13,11 +13,11 @@ else GST_DEBUG_DIRS = debug endif -SUBDIRS = bytestream cleanup dynparams \ +SUBDIRS = bins bytestream cleanup dynparams \ caps caps2 plugin elements clock refcounting tags threads \ indexers debug $(GST_PARSE_DIRS) $(GST_DEBUG_DIRS) -DIST_SUBDIRS = bytestream caps caps2 cleanup clock dynparams elements indexers \ +DIST_SUBDIRS = bins bytestream caps caps2 cleanup clock dynparams elements indexers \ plugin refcounting tags threads parse debug tests_pass = test_gst_init diff --git a/tests/old/testsuite/bins/.gitignore b/tests/old/testsuite/bins/.gitignore new file mode 100644 index 0000000000..b529896ae8 --- /dev/null +++ b/tests/old/testsuite/bins/.gitignore @@ -0,0 +1 @@ +interface diff --git a/tests/old/testsuite/bins/Makefile.am b/tests/old/testsuite/bins/Makefile.am new file mode 100644 index 0000000000..a4a86711b4 --- /dev/null +++ b/tests/old/testsuite/bins/Makefile.am @@ -0,0 +1,7 @@ +include ../Rules + +tests_pass = interface +tests_fail = + +interface_SOURCES = interface.c + diff --git a/tests/old/testsuite/bins/interface.c b/tests/old/testsuite/bins/interface.c new file mode 100644 index 0000000000..61f948d283 --- /dev/null +++ b/tests/old/testsuite/bins/interface.c @@ -0,0 +1,81 @@ +/* GStreamer + * Copyright (C) <1999> Erik Walthinsen + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include + +/* tests if gst_bin_get_(all_)by_interface works */ + +gint +main (gint argc, gchar *argv[]) +{ + GstBin *bin, *bin2; + GList *list; + GstElement *filesrc; + + gst_init (&argc, &argv); + + bin = GST_BIN (gst_bin_new (NULL)); + g_assert (bin); + + filesrc = gst_element_factory_make ("filesrc", NULL); + g_assert (filesrc); + g_assert (GST_IS_URI_HANDLER (filesrc)); + gst_bin_add (bin, filesrc); + + g_assert (gst_bin_get_by_interface (bin, GST_TYPE_URI_HANDLER) == filesrc); + list = gst_bin_get_all_by_interface (bin, GST_TYPE_URI_HANDLER); + g_assert (g_list_length (list) == 1); + g_assert (list->data == (gpointer) filesrc); + g_list_free (list); + + gst_bin_add_many (bin, + gst_element_factory_make ("identity", NULL), + gst_element_factory_make ("identity", NULL), + gst_element_factory_make ("identity", NULL), + NULL); + g_assert (gst_bin_get_by_interface (bin, GST_TYPE_URI_HANDLER) == filesrc); + list = gst_bin_get_all_by_interface (bin, GST_TYPE_URI_HANDLER); + g_assert (g_list_length (list) == 1); + g_assert (list->data == (gpointer) filesrc); + g_list_free (list); + + bin2 = bin; + bin = GST_BIN (gst_bin_new (NULL)); + g_assert (bin); + gst_bin_add_many (bin, + gst_element_factory_make ("identity", NULL), + gst_element_factory_make ("identity", NULL), + GST_ELEMENT (bin2), + gst_element_factory_make ("identity", NULL), + NULL); + g_assert (gst_bin_get_by_interface (bin, GST_TYPE_URI_HANDLER) == filesrc); + list = gst_bin_get_all_by_interface (bin, GST_TYPE_URI_HANDLER); + g_assert (g_list_length (list) == 1); + g_assert (list->data == (gpointer) filesrc); + g_list_free (list); + + gst_bin_add (bin, gst_element_factory_make ("filesrc", NULL)); + gst_bin_add (bin2, gst_element_factory_make ("filesrc", NULL)); + list = gst_bin_get_all_by_interface (bin, GST_TYPE_URI_HANDLER); + g_assert (g_list_length (list) == 3); + g_list_free (list); + + g_object_unref (bin); + return 0; +} diff --git a/tests/old/testsuite/bytestream/gstbstest.c b/tests/old/testsuite/bytestream/gstbstest.c index 90d3c0b61c..b47a0ffc32 100644 --- a/tests/old/testsuite/bytestream/gstbstest.c +++ b/tests/old/testsuite/bytestream/gstbstest.c @@ -403,7 +403,6 @@ GST_PLUGIN_DEFINE ( plugin_init, VERSION, GST_LICENSE, - GST_COPYRIGHT, GST_PACKAGE, GST_ORIGIN ) diff --git a/tests/old/testsuite/dynparams/dparamstest.c b/tests/old/testsuite/dynparams/dparamstest.c index 160afe313b..db05eb2cd5 100644 --- a/tests/old/testsuite/dynparams/dparamstest.c +++ b/tests/old/testsuite/dynparams/dparamstest.c @@ -222,7 +222,6 @@ static GstPluginDesc plugin_desc = { NULL, VERSION, GST_LICENSE, - GST_COPYRIGHT, GST_PACKAGE, GST_ORIGIN }; diff --git a/tests/old/testsuite/plugin/static2.c b/tests/old/testsuite/plugin/static2.c index 1434fc5083..a19551b4a7 100644 --- a/tests/old/testsuite/plugin/static2.c +++ b/tests/old/testsuite/plugin/static2.c @@ -18,7 +18,6 @@ GST_PLUGIN_DEFINE_STATIC ( plugin_init, VERSION, GST_LICENSE, - GST_COPYRIGHT, GST_PACKAGE, GST_ORIGIN ); @@ -37,7 +36,6 @@ GST_PLUGIN_DEFINE_STATIC ( plugin2_init, VERSION, GST_LICENSE, - GST_COPYRIGHT, GST_PACKAGE, GST_ORIGIN ); diff --git a/tests/old/testsuite/plugin/testplugin.c b/tests/old/testsuite/plugin/testplugin.c index e834c8eeda..24e8614058 100644 --- a/tests/old/testsuite/plugin/testplugin.c +++ b/tests/old/testsuite/plugin/testplugin.c @@ -19,7 +19,6 @@ GST_PLUGIN_DEFINE ( plugin_init, VERSION, GST_LICENSE, - GST_COPYRIGHT, GST_PACKAGE, GST_ORIGIN ); diff --git a/tests/old/testsuite/plugin/testplugin2.c b/tests/old/testsuite/plugin/testplugin2.c index 97b9bcf17a..69c71d8e14 100644 --- a/tests/old/testsuite/plugin/testplugin2.c +++ b/tests/old/testsuite/plugin/testplugin2.c @@ -19,7 +19,6 @@ GST_PLUGIN_DEFINE ( plugin_init, VERSION, GST_LICENSE, - GST_COPYRIGHT, GST_PACKAGE, GST_ORIGIN ); diff --git a/testsuite/Makefile.am b/testsuite/Makefile.am index 10eb0e111a..8755521f2a 100644 --- a/testsuite/Makefile.am +++ b/testsuite/Makefile.am @@ -13,11 +13,11 @@ else GST_DEBUG_DIRS = debug endif -SUBDIRS = bytestream cleanup dynparams \ +SUBDIRS = bins bytestream cleanup dynparams \ caps caps2 plugin elements clock refcounting tags threads \ indexers debug $(GST_PARSE_DIRS) $(GST_DEBUG_DIRS) -DIST_SUBDIRS = bytestream caps caps2 cleanup clock dynparams elements indexers \ +DIST_SUBDIRS = bins bytestream caps caps2 cleanup clock dynparams elements indexers \ plugin refcounting tags threads parse debug tests_pass = test_gst_init diff --git a/testsuite/bins/.gitignore b/testsuite/bins/.gitignore new file mode 100644 index 0000000000..b529896ae8 --- /dev/null +++ b/testsuite/bins/.gitignore @@ -0,0 +1 @@ +interface diff --git a/testsuite/bins/Makefile.am b/testsuite/bins/Makefile.am new file mode 100644 index 0000000000..a4a86711b4 --- /dev/null +++ b/testsuite/bins/Makefile.am @@ -0,0 +1,7 @@ +include ../Rules + +tests_pass = interface +tests_fail = + +interface_SOURCES = interface.c + diff --git a/testsuite/bins/interface.c b/testsuite/bins/interface.c new file mode 100644 index 0000000000..61f948d283 --- /dev/null +++ b/testsuite/bins/interface.c @@ -0,0 +1,81 @@ +/* GStreamer + * Copyright (C) <1999> Erik Walthinsen + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include + +/* tests if gst_bin_get_(all_)by_interface works */ + +gint +main (gint argc, gchar *argv[]) +{ + GstBin *bin, *bin2; + GList *list; + GstElement *filesrc; + + gst_init (&argc, &argv); + + bin = GST_BIN (gst_bin_new (NULL)); + g_assert (bin); + + filesrc = gst_element_factory_make ("filesrc", NULL); + g_assert (filesrc); + g_assert (GST_IS_URI_HANDLER (filesrc)); + gst_bin_add (bin, filesrc); + + g_assert (gst_bin_get_by_interface (bin, GST_TYPE_URI_HANDLER) == filesrc); + list = gst_bin_get_all_by_interface (bin, GST_TYPE_URI_HANDLER); + g_assert (g_list_length (list) == 1); + g_assert (list->data == (gpointer) filesrc); + g_list_free (list); + + gst_bin_add_many (bin, + gst_element_factory_make ("identity", NULL), + gst_element_factory_make ("identity", NULL), + gst_element_factory_make ("identity", NULL), + NULL); + g_assert (gst_bin_get_by_interface (bin, GST_TYPE_URI_HANDLER) == filesrc); + list = gst_bin_get_all_by_interface (bin, GST_TYPE_URI_HANDLER); + g_assert (g_list_length (list) == 1); + g_assert (list->data == (gpointer) filesrc); + g_list_free (list); + + bin2 = bin; + bin = GST_BIN (gst_bin_new (NULL)); + g_assert (bin); + gst_bin_add_many (bin, + gst_element_factory_make ("identity", NULL), + gst_element_factory_make ("identity", NULL), + GST_ELEMENT (bin2), + gst_element_factory_make ("identity", NULL), + NULL); + g_assert (gst_bin_get_by_interface (bin, GST_TYPE_URI_HANDLER) == filesrc); + list = gst_bin_get_all_by_interface (bin, GST_TYPE_URI_HANDLER); + g_assert (g_list_length (list) == 1); + g_assert (list->data == (gpointer) filesrc); + g_list_free (list); + + gst_bin_add (bin, gst_element_factory_make ("filesrc", NULL)); + gst_bin_add (bin2, gst_element_factory_make ("filesrc", NULL)); + list = gst_bin_get_all_by_interface (bin, GST_TYPE_URI_HANDLER); + g_assert (g_list_length (list) == 3); + g_list_free (list); + + g_object_unref (bin); + return 0; +} diff --git a/testsuite/bytestream/gstbstest.c b/testsuite/bytestream/gstbstest.c index 90d3c0b61c..b47a0ffc32 100644 --- a/testsuite/bytestream/gstbstest.c +++ b/testsuite/bytestream/gstbstest.c @@ -403,7 +403,6 @@ GST_PLUGIN_DEFINE ( plugin_init, VERSION, GST_LICENSE, - GST_COPYRIGHT, GST_PACKAGE, GST_ORIGIN ) diff --git a/testsuite/dynparams/dparamstest.c b/testsuite/dynparams/dparamstest.c index 160afe313b..db05eb2cd5 100644 --- a/testsuite/dynparams/dparamstest.c +++ b/testsuite/dynparams/dparamstest.c @@ -222,7 +222,6 @@ static GstPluginDesc plugin_desc = { NULL, VERSION, GST_LICENSE, - GST_COPYRIGHT, GST_PACKAGE, GST_ORIGIN }; diff --git a/testsuite/plugin/static2.c b/testsuite/plugin/static2.c index 1434fc5083..a19551b4a7 100644 --- a/testsuite/plugin/static2.c +++ b/testsuite/plugin/static2.c @@ -18,7 +18,6 @@ GST_PLUGIN_DEFINE_STATIC ( plugin_init, VERSION, GST_LICENSE, - GST_COPYRIGHT, GST_PACKAGE, GST_ORIGIN ); @@ -37,7 +36,6 @@ GST_PLUGIN_DEFINE_STATIC ( plugin2_init, VERSION, GST_LICENSE, - GST_COPYRIGHT, GST_PACKAGE, GST_ORIGIN ); diff --git a/testsuite/plugin/testplugin.c b/testsuite/plugin/testplugin.c index e834c8eeda..24e8614058 100644 --- a/testsuite/plugin/testplugin.c +++ b/testsuite/plugin/testplugin.c @@ -19,7 +19,6 @@ GST_PLUGIN_DEFINE ( plugin_init, VERSION, GST_LICENSE, - GST_COPYRIGHT, GST_PACKAGE, GST_ORIGIN ); diff --git a/testsuite/plugin/testplugin2.c b/testsuite/plugin/testplugin2.c index 97b9bcf17a..69c71d8e14 100644 --- a/testsuite/plugin/testplugin2.c +++ b/testsuite/plugin/testplugin2.c @@ -19,7 +19,6 @@ GST_PLUGIN_DEFINE ( plugin_init, VERSION, GST_LICENSE, - GST_COPYRIGHT, GST_PACKAGE, GST_ORIGIN ); diff --git a/tools/gst-inspect.c b/tools/gst-inspect.c index 26f94c3c34..1a3daa22b3 100644 --- a/tools/gst-inspect.c +++ b/tools/gst-inspect.c @@ -779,7 +779,6 @@ print_plugin_info (GstPlugin *plugin) g_print (" Filename:\t%s\n", plugin->filename); g_print (" Version:\t%s\n", plugin->desc.version); g_print (" License:\t%s\n", plugin->desc.license); - g_print (" Copyright:\t%s\n", plugin->desc.copyright); g_print (" Package:\t%s\n", plugin->desc.package); g_print (" Origin URL:\t%s\n", plugin->desc.origin); g_print ("\n"); diff --git a/tools/gst-launch.1.in b/tools/gst-launch.1.in index f55dec0ce3..12e46fcb34 100644 --- a/tools/gst-launch.1.in +++ b/tools/gst-launch.1.in @@ -72,7 +72,7 @@ being 0. .B \-\-gst\-debug\-no\-color \fIGStreamer\fP normally prints debugging messages so that the messages are color-coded when printed to a terminal that handles -ANSI escape sequences. Using this option causes \fIGstreamer\fP +ANSI escape sequences. Using this option causes \fIGStreamer\fP to print messages without color. .TP 8 .B \-\-gst\-disable\-debug diff --git a/tools/gst-xmlinspect.c b/tools/gst-xmlinspect.c index 4a5ea991a0..604a0c4b41 100644 --- a/tools/gst-xmlinspect.c +++ b/tools/gst-xmlinspect.c @@ -782,7 +782,6 @@ print_plugin_info (GstPlugin *plugin) g_print (" Filename:\t%s\n", plugin->filename); g_print (" Version:\t%s\n", plugin->desc.version); g_print (" License:\t%s\n", plugin->desc.license); - g_print (" Copyright:\t%s\n", plugin->desc.copyright); g_print (" Package:\t%s\n", plugin->desc.package); g_print (" Origin URL:\t%s\n", plugin->desc.origin); g_print ("\n");