diff --git a/ChangeLog b/ChangeLog index a6e3542ad9..8c122d4ed1 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,227 @@ +2005-05-29 Benjamin Otte + + ORGANIZATIONAL CHANGES: + + * configure.ac: + remove leftover valgrind stuff, fix GST_OBJ_*FLAGS + * gst/cothreads.c: + * gst/cothreads.h: + remove cothreads + * gst/thread.h: + * gst/thread.c: + remove GstThread + * gst/gstschedulerfactory.h: + * gst/gstschedulerfactory.c: + * gst/registries/gstlibxmlregistry.c: + split out registry specific stuff from gstscheduler.[ch] + * gst/Makefile.am: + * gst/gst.h: + remove cothread.[ch] and gstthread.[ch], add gstaction.[ch] and + gstschedulerfactory.[ch] + * gst/gstcompat.h: + add a gst_bin_iterate macro, remove old 0.5 macros + * gst/gst.c: (gst_register_core_elements): + remove registering GstThread + * gst/gst_private.h: + add some functions here that shouldn't be exported + * gst/gstclock.c: (gst_clock_class_init): + remove thread initing, it's done in gst.c + * gst/gstclock.h: + * gst/gsttypes.h: + move some more types to gsttypes.h: GstRealPad(Class), + GstClockTime and GstAction + + NEW SCHEDULING MODEL: + + * gst/gstaction.h: + * gst/gstaction.c: + implement actions. These were formally known as triggers. They + implement the different callback types used by elements. + * gst/gstbin.c: (gst_bin_class_init), (gst_bin_set_element_sched), + (gst_bin_unset_element_sched), (gst_bin_iterate): + * gst/gstbin.h: + - remove gst_bin_iterate + - remove code for decoupled elements + * gst/gstelement.c: (gst_element_add_pad), (gst_element_remove_pad), + (gst_element_reset_actions), (gst_element_change_state), + (gst_element_found_tags_for_pad): + add action support. Adding/removing pads adds/removes their actions + from the element automatically. Allow resetting actions which sets + all actions to their initial state. + * gst/gstelement.c: + * gst/gstelement.h: + remove lots of functions related to the old scheduling code, like + _yield, _interrupt etc + * gst/gstpad.c: (gst_pad_push), (gst_real_pad_set_active), + (gst_real_pad_is_active), (gst_real_pad_set_initially_active), + (gst_src_pad_set_action_handler), + (gst_sink_pad_set_action_handler): + add functions to interact with pad actions. + * gst/gstpad.c: + * gst/gstpad.h: + remove lots of stuff related to old scheduling, like DECOUPLED, the + active property, chainhandlers etc + * gst/gstpipeline.c: (gst_pipeline_class_init), + (gst_pipeline_dispose): + remove old scheduling specific calls + * gst/gstscheduler.c: (gst_scheduler_class_init), + (gst_scheduler_init), (gst_scheduler_dispose), + (gst_scheduler_real_add_element), + (gst_scheduler_real_remove_element), (gst_scheduler_marshal), + (gst_scheduler_add_element), (gst_scheduler_remove_element), + (gst_scheduler_state_transition), (gst_scheduler_get_clock), + (gst_scheduler_set_clock), (gst_scheduler_auto_clock), + (gst_scheduler_pad_push): + * gst/gstscheduler.h: + remove old scheduling code and add new one, which is basically + add_action, remove_action (obvious), toggle_active (to indicate + changing the activity state of an action) and update_values (to + indicate that an action changed the values it was configured with + + ELEMENTS: + + * gst/gstqueue.c: + * gst/gstqueue.h: + nearly reimplement. Throw out all the threading specific code. + * gst/elements/gstfakesink.c: (gst_fakesink_init), + (gst_fakesink_request_new_pad), (gst_fakesink_chain): + * gst/elements/gstfdsink.c: (gst_fdsink_init), (gst_fdsink_chain): + * gst/elements/gstfdsrc.c: (gst_fdsrc_init), (gst_fdsrc_get): + * gst/elements/gstfilesink.c: (gst_filesink_init), + (gst_filesink_handle_event), (gst_filesink_chain): + * gst/elements/gstfilesrc.c: (gst_filesrc_init), (gst_filesrc_get): + replace get/chainfunction with a src/sinkpad action. + * gst/elements/gstfakesrc.c: (gst_fakesrc_class_init), + (gst_fakesrc_init), (gst_fakesrc_request_new_pad), + (gst_fakesrc_update_functions), (gst_fakesrc_set_property), + (gst_fakesrc_get_property), (gst_fakesrc_get): + * gst/elements/gstfakesrc.h: + replace getfunction with a srcpad action. Remove "loopbased" + property. + * gst/elements/gstidentity.c: (gst_identity_base_init), + (gst_identity_class_init), (gst_identity_init), + (gst_identity_push), (gst_identity_chain), (gst_identity_wakeup), + (gst_identity_set_property), (gst_identity_get_property), + (gst_identity_change_state): + * gst/elements/gstidentity.h: + make this a PUSH-based element. Remove "loopbased" property and + other scheduling specific stuff. + * gst/elements/gsttee.c: (gst_tee_base_init), (gst_tee_class_init), + (gst_tee_init), (gst_tee_request_new_pad), (gst_tee_get), + (gst_tee_chain), (gst_tee_change_state): + * gst/elements/gsttee.h: + implement using pad actions + * gst/elements/gsttypefindelement.c: (gst_type_find_element_init), + (push_buffer_store), (stop_typefinding), + (gst_type_find_element_wakeup), + (gst_type_find_element_handle_event), + (gst_type_find_element_chain): + * gst/elements/gsttypefindelement.h: + make this a push-based element + + SCHEDULERS: + + * gst/schedulers/Makefile.am: + * gst/schedulers/cothreads_compat.h: + * gst/schedulers/entryscheduler.c: + * gst/schedulers/faircothreads.c: + * gst/schedulers/faircothreads.h: + * gst/schedulers/fairscheduler.c: + * gst/schedulers/gstbasicscheduler.c: + * gst/schedulers/gstoptimalscheduler.c: + * gst/schedulers/gthread-cothreads.h: + remove + * gst/schedulers/gstsimplescheduler.c: + implement a simple scheduler. It's supposed to be as simple as + possible (code-size). It's as fast as opt in 0.8. + + LIBS: + + * libs/gst/bytestream/Makefile.am: + * libs/gst/bytestream/gstbytestream.c: + * libs/gst/bytestream/gstbytestream.h: + remove bytestream + * libs/gst/bytestream/filepad.c: (gst_file_pad_init), + (gst_file_pad_chain), (gst_file_pad_parent_set): + make this a sinkpad-action using pad. + + TOOLS: + + * tools/Makefile.am: + * tools/gst-md5sum.1.in: + * tools/gst-md5sum.c: + * tools/gst-xmlinspect.1.in: + * tools/gst-xmlinspect.c: + * tools/gst-xmllaunch.1.in: + remove gst-xml-* tools and gst-md5sum. + * tools/gst-inspect.c: (print_element_flag_info), + (print_implementation_info), (print_pad_info): + fix to show current scheduling information. + * tools/gst-launch.c: (fault_handler_sighandler), + (fault_handler_sigaction), (fault_spin), (print_tag), + (play_handler), (should_quit), (quit_cb), (launch_poll), (main): + implement new scheduling. + * tools/gst-typefind.c: (have_type_handler), (main): + make work with new scheduling + + TESTSUITE: + + * tests/Makefile.am: + * tests/lat.c: + * tests/muxing/Makefile.am: + * tests/muxing/case1.c: + * tests/sched/.cvsignore: + * tests/sched/Makefile.am: + * tests/sched/dynamic-pipeline.c: + * tests/sched/interrupt1.c: + * tests/sched/interrupt2.c: + * tests/sched/interrupt3.c: + * tests/sched/runtestcases: + * tests/sched/runxml.c: + * tests/sched/sched-stress.c: + * tests/sched/testcases: + * tests/sched/testcases1.tc: + * tests/threadstate/.cvsignore: + * tests/threadstate/Makefile.am: + * tests/threadstate/test1.c: + * tests/threadstate/test2.c: + * tests/threadstate/threadstate1.c: + * tests/threadstate/threadstate2.c: + * tests/threadstate/threadstate3.c: + * tests/threadstate/threadstate4.c: + * tests/threadstate/threadstate5.c: + * testsuite/Makefile.am: + * testsuite/bytestream/Makefile.am: + * testsuite/cleanup/Makefile.am: + * testsuite/clock/Makefile.am: + * testsuite/clock/clock1.c: (main): + * testsuite/dlopen/loadgst.c: (do_test): + * testsuite/elements/fake.c: (main): + * testsuite/elements/struct_i386.h: + * testsuite/elements/tee.c: (main): + * testsuite/ghostpads/ghostpads.c: (main): + * testsuite/pad/Makefile.am: + * testsuite/pad/getnopush.c: (gst_test_src_get), + (gst_test_src_init), (main): + * testsuite/parse/parse1.c: + * testsuite/schedulers/142183-2.c: (main): + * testsuite/schedulers/143777-2.c: (main): + * testsuite/schedulers/143777.c: (main): + * testsuite/schedulers/147819.c: (handoff_identity1), + (handoff_identity2), (main): + * testsuite/schedulers/Makefile.am: + * testsuite/schedulers/group_link.c: (main): + * testsuite/schedulers/queue_link.c: (main): + * testsuite/schedulers/relink.c: (cb_handoff), (main): + * testsuite/schedulers/unlink.c: (main): + * testsuite/schedulers/unref.c: (cb_handoff), (main): + * testsuite/schedulers/useless_iteration.c: (main): + - make work with new scheduling (mostly by making fakesrc only send + a fixed number of buffers so we hit EOS and uising the _iterate + compat macro. + - remove tests that test the old scheduling model + - remove tests that test threading + 2005-05-17 Benjamin Otte * gst/gstobject.c: (gst_object_ref), (gst_object_unref): diff --git a/common b/common index 131c263212..67b7e6c0db 160000 --- a/common +++ b/common @@ -1 +1 @@ -Subproject commit 131c2632127e6f061b5270d8f80651782a4fdd13 +Subproject commit 67b7e6c0db99415e0440d0c576495641b53e976a diff --git a/configure.ac b/configure.ac index 4a5c3b7894..d6bc7f952e 100644 --- a/configure.ac +++ b/configure.ac @@ -560,15 +560,14 @@ AC_SUBST(GST_PKG_DEPS) dnl flags shared for all internal objects (core libs, elements, applications) dnl we disable deprecated internally -dnl XML, GLib, popt, GST_INT, VALGRIND, and the right include for CFLAGS +dnl XML, GLib, popt, GST_INT, and the right include for CFLAGS dnl no need to add XML, GLib, popt explicitly since libgstreamer pulls them in GST_INT_CFLAGS="$GLIB_CFLAGS $XML_CFLAGS $GST_PKG_CFLAGS \ $GST_INT_CFLAGS $GST_ERROR_CFLAGS -DGST_DISABLE_DEPRECATED" dnl Private vars for libgst only -GST_LIB_CFLAGS="$GST_PKG_CFLAGS $GST_INT_CFLAGS \ - $VALGRIND_CFLAGS -I\$(top_srcdir)" -GST_LIB_LIBS="$XML_LIBS $GLIB_LIBS -lpopt $GST_PKG_LIBS $LTLIBINTL $VALGRIND_LIBS -lm" +GST_LIB_CFLAGS="$GST_PKG_CFLAGS $GST_INT_CFLAGS -I\$(top_srcdir)" +GST_LIB_LIBS="$XML_LIBS $GLIB_LIBS -lpopt $GST_PKG_LIBS $LTLIBINTL -lm" GST_LIB_LDFLAGS="$GST_LT_LDFLAGS -version-info $GST_LIBVERSION $EXPORT_LDFLAGS" AC_SUBST(GST_LIB_CFLAGS) AC_SUBST(GST_LIB_LIBS) @@ -576,10 +575,11 @@ AC_SUBST(GST_LIB_LDFLAGS) dnl Vars for all internal objects built on libgstreamer GST_OBJ_CFLAGS="$GST_INT_CFLAGS -I\$(top_srcdir)/libs -I\$(top_srcdir)" -GST_OBJ_LIBS="\$(top_builddir)/gst/libgstreamer-$GST_MAJORMINOR.la" - -AC_SUBST(GST_OBJ_CFLAGS, "$GST_OBJ_CFLAGS") -AC_SUBST(GST_OBJ_LIBS, "$GST_OBJ_LIBS") +GST_OBJ_LIBS="\$(top_builddir)/gst/libgstreamer-$GST_MAJORMINOR.la $GLIB_LIBS $LTLIBINTL" +GST_OBJ_LDFLAGS="$GST_LT_LDFLAGS -version-info $GST_LIBVERSION $EXPORT_LDFLAGS" +AC_SUBST(GST_OBJ_CFLAGS) +AC_SUBST(GST_OBJ_LIBS) +AC_SUBST(GST_OBJ_LDFLAGS) dnl specific additional LDFLAGS for plugins GST_PLUGIN_LDFLAGS="-module -avoid-version $EXPORT_LDFLAGS" @@ -646,10 +646,7 @@ tests/Makefile tests/bufspeed/Makefile tests/instantiate/Makefile tests/memchunk/Makefile -tests/muxing/Makefile tests/seeking/Makefile -tests/sched/Makefile -tests/threadstate/Makefile testsuite/Makefile testsuite/bins/Makefile testsuite/bytestream/Makefile diff --git a/gst/Makefile.am b/gst/Makefile.am index 3370a027cc..c837f4cbae 100644 --- a/gst/Makefile.am +++ b/gst/Makefile.am @@ -1,10 +1,5 @@ lib_LTLIBRARIES = libgstreamer-@GST_MAJORMINOR@.la AS_LIBTOOL_LIB = libgstreamer-@GST_MAJORMINOR@ -if GST_DISABLE_OMEGA_COTHREADS -noinst_LTLIBRARIES = -else -noinst_LTLIBRARIES = libcothreads.la -endif #GST_INSTRUMENT_FLAGS = -finstrument-functions -DGST_ENABLE_FUNC_INSTRUMENTATION @@ -82,6 +77,7 @@ EXTRA_libgstreamer_@GST_MAJORMINOR@_la_SOURCES = \ libgstreamer_@GST_MAJORMINOR@_la_SOURCES = \ gst.c \ gstobject.c \ + gstaction.c \ gstbin.c \ gstbuffer.c \ gstcaps.c \ @@ -104,11 +100,11 @@ libgstreamer_@GST_MAJORMINOR@_la_SOURCES = \ gstqueue.c \ gstquery.c \ gstscheduler.c \ + gstschedulerfactory.c \ gststructure.c \ gstsystemclock.c \ gsttag.c \ gsttaginterface.c \ - gstthread.c \ $(GST_TRACE_SRC) \ gsttypefind.c \ $(GST_URI_SRC) \ @@ -150,6 +146,7 @@ libgstreamer_@GST_MAJORMINOR@includedir = $(includedir)/gstreamer-@GST_MAJORMINO gst_headers = \ gst.h \ + gstaction.h \ gstobject.h \ gstbin.h \ gstbuffer.h \ @@ -174,11 +171,11 @@ gst_headers = \ gstqueue.h \ gstquery.h \ gstscheduler.h \ + gstschedulerfactory.h \ gststructure.h \ gstsystemclock.h \ gsttag.h \ gsttaginterface.h \ - gstthread.h \ gsttrace.h \ gsttypefind.h \ gsttypes.h \ @@ -201,16 +198,7 @@ noinst_HEADERS = \ gst-i18n-app.h \ gst_private.h \ gstdata_private.h \ - gstarch.h \ - cothreads.h - -if GST_DISABLE_OMEGA_COTHREADS -#libcothreads_la_SOURCES = -#libcothreads_la_CFLAGS = -else -libcothreads_la_SOURCES = cothreads.c -libcothreads_la_CFLAGS = $(libgstreamer_@GST_MAJORMINOR@_la_CFLAGS) -endif + gstarch.h gstmarshal.h: gstmarshal.list diff --git a/gst/cothreads.c b/gst/cothreads.c deleted file mode 100644 index 625e02a3c2..0000000000 --- a/gst/cothreads.c +++ /dev/null @@ -1,679 +0,0 @@ -/* GStreamer - * Copyright (C) 1999,2000 Erik Walthinsen - * 2000 Wim Taymans - * - * cothreads.c: Cothreading routines - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - - -#include "gst_private.h" -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "cothreads.h" -#include "gstarch.h" -#include "gstinfo.h" -#include "gstutils.h" - -#ifdef HAVE_UCONTEXT_H -#include -#endif - -#ifndef MAP_ANONYMOUS -#ifdef MAP_ANON -/* older glibc's have MAP_ANON instead of MAP_ANONYMOUS */ -#define MAP_ANONYMOUS MAP_ANON -#else -/* make due without. If this fails, we need to open and map /dev/zero */ -#define MAP_ANONYMOUS 0 -#endif -#endif - -#define STACK_SIZE 0x200000 - -#define COTHREAD_MAGIC_NUMBER 0xabcdef - -#define COTHREAD_MAXTHREADS 16 -#define COTHREAD_STACKSIZE (STACK_SIZE/COTHREAD_MAXTHREADS) - -static void cothread_destroy (cothread_state * cothread); - -struct _cothread_context -{ - cothread_state *cothreads[COTHREAD_MAXTHREADS]; /* array of cothread states */ - int ncothreads; - int current; - unsigned long stack_top; - GHashTable *data; - GThread *thread; -}; - -/* Disabling this define allows you to shut off a few checks in - * cothread_switch. This likely will speed things up fractionally */ -#define COTHREAD_PARANOID - - -/* this _cothread_ctx_key is used as a GThread key to the thread's context - * a GThread key is a "pointer" to memory space that is/can be different - * (ie. private) for each thread. The key itself is shared among threads, - * so it only needs to be initialized once. - */ -static GStaticPrivate _cothread_ctx_key = G_STATIC_PRIVATE_INIT; - -/* - * This should only after context init, since we do checking. - */ -static cothread_context * -cothread_get_current_context (void) -{ - cothread_context *ctx; - - ctx = g_static_private_get (&_cothread_ctx_key); - g_assert (ctx); - -#ifdef COTHREAD_PARANOID - g_assert (ctx->thread == g_thread_self ()); -#endif - - return ctx; -} - -/** - * cothread_context_init: - * - * Create and initialize a new cothread context - * - * Returns: the new cothread context - */ -cothread_context * -cothread_context_init (void) -{ - char __csf; - void *current_stack_frame = &__csf; /* Get pointer inside current stack frame */ - cothread_context *ctx; - - /* if there already is a cotread context for this thread, - * just return it */ - ctx = g_static_private_get (&_cothread_ctx_key); - if (ctx) { - GST_CAT_INFO (GST_CAT_COTHREADS, - "returning private _cothread_ctx_key %p", ctx); - return ctx; - } - - /* - * initalize the whole of the cothreads context - */ - ctx = (cothread_context *) g_malloc (sizeof (cothread_context)); - - /* we consider the initiating process to be cothread 0 */ - ctx->ncothreads = 1; - ctx->current = 0; - ctx->data = g_hash_table_new (g_str_hash, g_str_equal); - ctx->thread = g_thread_self (); - - GST_CAT_INFO (GST_CAT_COTHREADS, "initializing cothreads"); - - /* set this thread's context pointer */ - GST_CAT_INFO (GST_CAT_COTHREADS, - "setting private _cothread_ctx_key to %p in thread %p", ctx, - g_thread_self ()); - g_static_private_set (&_cothread_ctx_key, ctx, NULL); - - g_assert (ctx == cothread_get_current_context ()); - - /* clear the cothread data */ - memset (ctx->cothreads, 0, sizeof (ctx->cothreads)); - - /* FIXME this may not be 64bit clean - * could use casts to uintptr_t from inttypes.h - * if only all platforms had inttypes.h - */ - /* stack_top is the address of the first byte past our stack segment. */ - /* FIXME: an assumption is made that the stack segment is STACK_SIZE - * aligned. */ - ctx->stack_top = ((gulong) current_stack_frame | (STACK_SIZE - 1)) + 1; - GST_CAT_DEBUG (GST_CAT_COTHREADS, "stack top is 0x%08lx", ctx->stack_top); - - /* - * initialize the 0th cothread - */ - ctx->cothreads[0] = (cothread_state *) g_malloc0 (sizeof (cothread_state)); - ctx->cothreads[0]->ctx = ctx; - ctx->cothreads[0]->cothreadnum = 0; - ctx->cothreads[0]->func = NULL; - ctx->cothreads[0]->argc = 0; - ctx->cothreads[0]->argv = NULL; - ctx->cothreads[0]->priv = NULL; - ctx->cothreads[0]->flags = COTHREAD_STARTED; - ctx->cothreads[0]->sp = (void *) current_stack_frame; - - GST_CAT_INFO (GST_CAT_COTHREADS, "0th cothread is %p at sp:%p", - ctx->cothreads[0], ctx->cothreads[0]->sp); - - return ctx; -} - -/** - * cothread_context_free: - * @ctx: the cothread context to free - * - * Free the cothread context. - */ -void -cothread_context_free (cothread_context * ctx) -{ - gint i; - - g_return_if_fail (ctx != NULL); - g_assert (ctx->thread == g_thread_self ()); - g_assert (ctx->current == 0); - - GST_CAT_INFO (GST_CAT_COTHREADS, "free cothread context"); - - for (i = 1; i < COTHREAD_MAXTHREADS; i++) { - if (ctx->cothreads[i]) { - cothread_destroy (ctx->cothreads[i]); - } - } - if (ctx->cothreads[0]) { - g_free (ctx->cothreads[0]); - ctx->cothreads[0] = NULL; - } - g_hash_table_destroy (ctx->data); - /* make sure we free the private key for cothread context */ - GST_CAT_INFO (GST_CAT_COTHREADS, - "setting private _cothread_ctx_key to NULL in thread %p", - g_thread_self ()); - g_static_private_set (&_cothread_ctx_key, NULL, NULL); - g_free (ctx); -} - -/** - * cothread_create: - * @ctx: the cothread context - * - * Create a new cothread state in the given context - * - * Returns: the new cothread state or NULL on error - */ -cothread_state * -cothread_create (cothread_context * ctx) -{ - cothread_state *cothread; - void *mmaped = NULL; - gint slot = 0; - unsigned long page_size; - - g_return_val_if_fail (ctx != NULL, NULL); - - GST_CAT_DEBUG (GST_CAT_COTHREADS, "manager sef %p, cothread self %p", - ctx->thread, g_thread_self ()); - - if (ctx->ncothreads == COTHREAD_MAXTHREADS) { - /* this is pretty fatal */ - g_warning ("cothread_create: attempt to create > COTHREAD_MAXTHREADS"); - return NULL; - } - /* find a free spot in the stack, note slot 0 has the main thread */ - for (slot = 1; slot < ctx->ncothreads; slot++) { - if (ctx->cothreads[slot] == NULL) - break; - else if (ctx->cothreads[slot]->flags & COTHREAD_DESTROYED && - slot != ctx->current) { - cothread_destroy (ctx->cothreads[slot]); - break; - } - } - - GST_CAT_DEBUG (GST_CAT_COTHREADS, "Found free cothread slot %d", slot); - - /* cothread stack space of the thread is mapped in reverse, with cothread 0 - * stack space at the top */ - cothread = - (cothread_state *) (ctx->stack_top - (slot + 1) * COTHREAD_STACKSIZE); - GST_CAT_DEBUG (GST_CAT_COTHREADS, "cothread pointer is %p", cothread); - -#if 0 - /* This tests to see whether or not we can grow down the stack */ - { - unsigned long ptr; - - for (ptr = ctx->stack_top - 4096; ptr > (unsigned long) cothread; - ptr -= 4096) { - GST_CAT_DEBUG (GST_CAT_COTHREADS, "touching location 0x%08lx", ptr); - *(volatile unsigned int *) ptr = *(volatile unsigned int *) ptr; - GST_CAT_DEBUG (GST_CAT_COTHREADS, "ok (0x%08x)", *(unsigned int *) ptr); - } - } -#endif - -#ifdef _SC_PAGESIZE - page_size = sysconf (_SC_PAGESIZE); -#else - page_size = getpagesize (); -#endif - - /* The mmap is necessary on Linux/i386, and possibly others, since the - * kernel is picky about when we can expand our stack. */ - GST_CAT_DEBUG (GST_CAT_COTHREADS, "mmaping %p, size 0x%08x", cothread, - COTHREAD_STACKSIZE); - /* Remap with a guard page. This decreases our stack size by 8 kB (for - * 4 kB pages) and also wastes almost 4 kB for the cothreads - * structure */ - munmap ((void *) cothread, COTHREAD_STACKSIZE); - mmaped = mmap ((void *) cothread, page_size, - PROT_READ | PROT_WRITE, MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); - mmaped = mmap (((void *) cothread) + page_size * 2, - COTHREAD_STACKSIZE - page_size * 2, - PROT_READ | PROT_WRITE | PROT_EXEC, - MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); - GST_CAT_DEBUG (GST_CAT_COTHREADS, "coming out of mmap"); - if (mmaped == MAP_FAILED) { - perror ("mmap'ing cothread stack space"); - return NULL; - } - if (mmaped != (void *) cothread + page_size * 2) { - g_warning ("could not mmap requested memory for cothread"); - return NULL; - } - - cothread->magic_number = COTHREAD_MAGIC_NUMBER; - GST_CAT_DEBUG (GST_CAT_COTHREADS, - "create cothread %d with magic number 0x%x", slot, - cothread->magic_number); - cothread->ctx = ctx; - cothread->cothreadnum = slot; - cothread->flags = 0; - cothread->priv = NULL; - cothread->sp = ((guchar *) cothread + COTHREAD_STACKSIZE); - cothread->stack_size = COTHREAD_STACKSIZE - page_size * 2; - cothread->stack_base = (void *) cothread + 2 * page_size; - - GST_CAT_INFO (GST_CAT_COTHREADS, - "created cothread #%d in slot %d: %p at sp:%p", - ctx->ncothreads, slot, cothread, cothread->sp); - - ctx->cothreads[slot] = cothread; - ctx->ncothreads++; - - return cothread; -} - -/** - * cothread_free: - * @cothread: the cothread state - * - * Free the given cothread state - */ -void -cothread_free (cothread_state * cothread) -{ - g_return_if_fail (cothread != NULL); - - GST_CAT_INFO (GST_CAT_COTHREADS, "flag cothread %d for destruction", - cothread->cothreadnum); - - /* we simply flag the cothread for destruction here */ - if (cothread) - cothread->flags |= COTHREAD_DESTROYED; - else - g_warning ("somebody set up us the bomb"); -} - -static void -cothread_destroy (cothread_state * cothread) -{ - cothread_context *ctx; - gint cothreadnum; - - g_return_if_fail (cothread != NULL); - - cothreadnum = cothread->cothreadnum; - ctx = cothread->ctx; - g_assert (ctx->thread == g_thread_self ()); - g_assert (ctx == cothread_get_current_context ()); - - GST_CAT_INFO (GST_CAT_COTHREADS, "destroy cothread %d %p %d", - cothreadnum, cothread, ctx->current); - - /* cothread 0 needs to be destroyed specially */ - g_assert (cothreadnum != 0); - - /* doing cleanups of the cothread create */ - GST_CAT_DEBUG (GST_CAT_COTHREADS, - "destroy cothread %d with magic number 0x%x", cothreadnum, - cothread->magic_number); - g_assert (cothread->magic_number == COTHREAD_MAGIC_NUMBER); - - g_assert (cothread->priv == NULL); - - memset (cothread, 0, sizeof (*cothread)); - - ctx->cothreads[cothreadnum] = NULL; - ctx->ncothreads--; -} - -/** - * cothread_setfunc: - * @cothread: the cothread state - * @func: the function to call - * @argc: argument count for the cothread function - * @argv: arguments for the cothread function - * - * Set the cothread function - */ -void -cothread_setfunc (cothread_state * cothread, cothread_func func, int argc, - char **argv) -{ - cothread->func = func; - cothread->argc = argc; - cothread->argv = argv; -} - -/** - * cothread_stop: - * @cothread: the cothread to stop - * - * Stop the cothread and reset the stack and program counter. - */ -void -cothread_stop (cothread_state * cothread) -{ - cothread->flags &= ~COTHREAD_STARTED; -} - -/** - * cothread_main: - * @ctx: cothread context to find main cothread of. - * - * Gets the main thread. - * - * Returns: the #cothread_state of the main (0th) cothread. - */ -cothread_state * -cothread_main (cothread_context * ctx) -{ - g_assert (ctx->thread == g_thread_self ()); - - GST_CAT_DEBUG (GST_CAT_COTHREADS, "returning %p, the 0th cothread", - ctx->cothreads[0]); - return ctx->cothreads[0]; -} - -/** - * cothread_current_main: - * - * Get the main thread in the current GThread. - * - * Returns: the #cothread_state of the main (0th) thread in the current GThread - */ -cothread_state * -cothread_current_main (void) -{ - cothread_context *ctx = cothread_get_current_context (); - - return ctx->cothreads[0]; -} - -/** - * cothread_current: - * - * Get the currenttly executing cothread - * - * Returns: the #cothread_state of the current cothread - */ -cothread_state * -cothread_current (void) -{ - cothread_context *ctx = cothread_get_current_context (); - - return ctx->cothreads[ctx->current]; -} - -static void -cothread_stub (void) -{ - cothread_context *ctx = cothread_get_current_context (); - cothread_state *cothread = ctx->cothreads[ctx->current]; - -#ifndef GST_DISABLE_GST_DEBUG - char __csf; - void *current_stack_frame = &__csf; -#endif - - GST_CAT_DEBUG (GST_CAT_COTHREADS, "stack addr %p", &ctx); - - cothread->flags |= COTHREAD_STARTED; - - while (TRUE) { - cothread->func (cothread->argc, cothread->argv); - - GST_CAT_DEBUG (GST_CAT_COTHREADS, "cothread[%d] thread->func exited", - ctx->current); - - GST_CAT_DEBUG (GST_CAT_COTHREADS, "sp=%p", current_stack_frame); - GST_CAT_DEBUG (GST_CAT_COTHREADS, "ctx=%p current=%p", ctx, - cothread_get_current_context ()); - g_assert (ctx == cothread_get_current_context ()); - - g_assert (ctx->current != 0); - - /* we do this to avoid ever returning, we just switch to 0th thread */ - cothread_switch (cothread_main (ctx)); - } -} - -/** - * cothread_getcurrent: - * - * Get the current cothread id - * - * Returns: the current cothread id - */ -int -cothread_getcurrent (void) - G_GNUC_NO_INSTRUMENT; - - int cothread_getcurrent (void) -{ - cothread_context *ctx = cothread_get_current_context (); - - if (!ctx) - return -1; - - return ctx->current; -} - -/** - * cothread_set_private: - * @cothread: the cothread state - * @data: the data - * - * set private data for the cothread. - */ -void -cothread_set_private (cothread_state * cothread, gpointer data) -{ - cothread->priv = data; -} - -/** - * cothread_context_set_data: - * @cothread: the cothread state - * @key: a key for the data - * @data: the data - * - * adds data to a cothread - */ -void -cothread_context_set_data (cothread_state * cothread, gchar * key, - gpointer data) -{ - cothread_context *ctx = cothread_get_current_context (); - - g_hash_table_insert (ctx->data, key, data); -} - -/** - * cothread_get_private: - * @cothread: the cothread state - * - * get the private data from the cothread - * - * Returns: the private data of the cothread - */ -gpointer -cothread_get_private (cothread_state * cothread) -{ - return cothread->priv; -} - -/** - * cothread_context_get_data: - * @cothread: the cothread state - * @key: a key for the data - * - * get data from the cothread - * - * Returns: the data associated with the key - */ -gpointer -cothread_context_get_data (cothread_state * cothread, gchar * key) -{ - cothread_context *ctx = cothread_get_current_context (); - - return g_hash_table_lookup (ctx->data, key); -} - -/** - * cothread_switch: - * @cothread: cothread state to switch to - * - * Switches to the given cothread state - */ -void -cothread_switch (cothread_state * cothread) -{ - cothread_context *ctx; - cothread_state *current; - int enter; - -#ifdef COTHREAD_PARANOID - if (cothread == NULL) - goto nothread; -#endif - ctx = cothread->ctx; - - /* paranoia check to make sure we're in the right thread */ - g_assert (ctx->thread == g_thread_self ()); - -#ifdef COTHREAD_PARANOID - if (ctx == NULL) - goto nocontext; -#endif - - current = ctx->cothreads[ctx->current]; -#ifdef COTHREAD_PARANOID - if (current == NULL) - goto nocurrent; -#endif - if (current == cothread) - goto selfswitch; - - - /* find the number of the thread to switch to */ - GST_CAT_INFO (GST_CAT_COTHREAD_SWITCH, - "switching from cothread #%d to cothread #%d", - ctx->current, cothread->cothreadnum); - ctx->current = cothread->cothreadnum; - - /* save the current stack pointer, frame pointer, and pc */ -#ifdef GST_ARCH_PRESETJMP - GST_ARCH_PRESETJMP (); -#endif - enter = setjmp (current->jmp); - if (enter != 0) { - GST_CAT_DEBUG (GST_CAT_COTHREADS, - "enter cothread #%d %d sp=%p jmpbuf=%p", - current->cothreadnum, enter, current->sp, current->jmp); - return; - } - GST_CAT_DEBUG (GST_CAT_COTHREADS, "exit cothread #%d %d sp=%p jmpbuf=%p", - current->cothreadnum, enter, current->sp, current->jmp); - enter = 1; - - if (current->flags & COTHREAD_DESTROYED) { - cothread_destroy (current); - } - - GST_CAT_DEBUG (GST_CAT_COTHREADS, "set stack to %p", cothread->sp); - /* restore stack pointer and other stuff of new cothread */ - if (cothread->flags & COTHREAD_STARTED) { - GST_CAT_DEBUG (GST_CAT_COTHREADS, "via longjmp() jmpbuf %p", cothread->jmp); - /* switch to it */ - longjmp (cothread->jmp, 1); - } else { -#ifdef HAVE_MAKECONTEXT - ucontext_t ucp; - - GST_CAT_DEBUG (GST_CAT_COTHREADS, "making context"); - - g_assert (cothread != cothread_main (ctx)); - - getcontext (&ucp); - ucp.uc_stack.ss_sp = (void *) cothread->stack_base; - ucp.uc_stack.ss_size = cothread->stack_size; - makecontext (&ucp, cothread_stub, 0); - setcontext (&ucp); -#else - GST_ARCH_SETUP_STACK ((char *) cothread->sp); - GST_ARCH_SET_SP (cothread->sp); - /* start it */ - GST_ARCH_CALL (cothread_stub); -#endif - - GST_CAT_DEBUG (GST_CAT_COTHREADS, "exit thread "); - ctx->current = 0; - } - - return; - -#ifdef COTHREAD_PARANOID -nothread: - g_warning ("cothread: can't switch to NULL cothread!"); - return; -nocontext: - g_warning ("cothread: there's no context, help!"); - exit (2); -nocurrent: - g_warning ("cothread: there's no current thread, help!"); - exit (2); -#endif /* COTHREAD_PARANOID */ -selfswitch: - return; -} diff --git a/gst/cothreads.h b/gst/cothreads.h deleted file mode 100644 index cc15682d76..0000000000 --- a/gst/cothreads.h +++ /dev/null @@ -1,77 +0,0 @@ -/* GStreamer - * Copyright (C) 1999,2000 Erik Walthinsen - * 2000 Wim Taymans - * - * cothreads.h: Header for cothreading routines - * - * 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 __COTHREADS_H__ -#define __COTHREADS_H__ - -#include -#include - -typedef struct _cothread_state cothread_state; -typedef struct _cothread_context cothread_context; - -typedef int (*cothread_func) (int argc,char **argv); - -#define COTHREAD_STARTED 0x01 -#define COTHREAD_DESTROYED 0x02 - -struct _cothread_state { - cothread_context *ctx; - int cothreadnum; - gpointer priv; - - cothread_func func; - int argc; - char **argv; - - int flags; - void *sp; - jmp_buf jmp; - void *stack_base; - unsigned long stack_size; - - int magic_number; -}; - - -cothread_context* cothread_context_init (void); -void cothread_context_free (cothread_context *ctx); -void cothread_context_set_data (cothread_state *cothread, - gchar *key, gpointer data); -gpointer cothread_context_get_data (cothread_state *cothread, gchar *key); - -cothread_state* cothread_create (cothread_context *ctx); -void cothread_free (cothread_state *cothread); -void cothread_setfunc (cothread_state *cothread, cothread_func func, - int argc, char **argv); -void cothread_stop (cothread_state *cothread); - -void cothread_switch (cothread_state *cothread); -void cothread_set_private (cothread_state *cothread, - gpointer data); -gpointer cothread_get_private (cothread_state *cothread); - -cothread_state* cothread_main (cothread_context *ctx); -cothread_state* cothread_current_main (void); -cothread_state* cothread_current (void); - -#endif /* __COTHREAD_H__ */ diff --git a/gst/elements/gstfakesink.c b/gst/elements/gstfakesink.c index c06ecf51e7..6295763676 100644 --- a/gst/elements/gstfakesink.c +++ b/gst/elements/gstfakesink.c @@ -113,7 +113,8 @@ static void gst_fakesink_get_property (GObject * object, guint prop_id, static GstElementStateReturn gst_fakesink_change_state (GstElement * element); -static void gst_fakesink_chain (GstPad * pad, GstData * _data); +static void gst_fakesink_chain (GstAction * action, GstRealPad * pad, + GstData * _data); static guint gst_fakesink_signals[LAST_SIGNAL] = { 0 }; @@ -187,8 +188,8 @@ gst_fakesink_init (GstFakeSink * fakesink) pad = gst_pad_new_from_template (gst_static_pad_template_get (&sinktemplate), "sink"); + gst_sink_pad_set_action_handler (pad, GST_DEBUG_FUNCPTR (gst_fakesink_chain)); gst_element_add_pad (GST_ELEMENT (fakesink), pad); - gst_pad_set_chain_function (pad, GST_DEBUG_FUNCPTR (gst_fakesink_chain)); fakesink->silent = FALSE; fakesink->dump = FALSE; @@ -231,7 +232,8 @@ gst_fakesink_request_new_pad (GstElement * element, GstPadTemplate * templ, sinkpad = gst_pad_new_from_template (templ, name); g_free (name); - gst_pad_set_chain_function (sinkpad, GST_DEBUG_FUNCPTR (gst_fakesink_chain)); + gst_sink_pad_set_action_handler (sinkpad, + GST_DEBUG_FUNCPTR (gst_fakesink_chain)); gst_element_add_pad (GST_ELEMENT (fakesink), sinkpad); @@ -309,7 +311,7 @@ gst_fakesink_get_property (GObject * object, guint prop_id, GValue * value, } static void -gst_fakesink_chain (GstPad * pad, GstData * _data) +gst_fakesink_chain (GstAction * action, GstRealPad * pad, GstData * _data) { GstBuffer *buf = GST_BUFFER (_data); GstFakeSink *fakesink; @@ -341,7 +343,7 @@ gst_fakesink_chain (GstPad * pad, GstData * _data) gst_element_set_time (GST_ELEMENT (fakesink), value); } default: - gst_pad_event_default (pad, event); + gst_pad_event_default (GST_PAD (pad), event); break; } return; diff --git a/gst/elements/gstfakesrc.c b/gst/elements/gstfakesrc.c index 0b64860e90..6c3b04f24a 100644 --- a/gst/elements/gstfakesrc.c +++ b/gst/elements/gstfakesrc.c @@ -64,7 +64,6 @@ enum { ARG_0, ARG_NUM_SOURCES, - ARG_LOOP_BASED, ARG_OUTPUT, ARG_DATA, ARG_SIZETYPE, @@ -179,7 +178,7 @@ GST_BOILERPLATE_FULL (GstFakeSrc, gst_fakesrc, GstElement, GST_TYPE_ELEMENT, static GstPad *gst_fakesrc_request_new_pad (GstElement * element, GstPadTemplate * templ, const gchar * unused); -static void gst_fakesrc_update_functions (GstFakeSrc * src); +static void gst_fakesrc_update_functions (GstFakeSrc * src, GstPad * pad); static void gst_fakesrc_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec); static void gst_fakesrc_get_property (GObject * object, guint prop_id, @@ -188,8 +187,7 @@ static void gst_fakesrc_set_clock (GstElement * element, GstClock * clock); static GstElementStateReturn gst_fakesrc_change_state (GstElement * element); -static GstData *gst_fakesrc_get (GstPad * pad); -static void gst_fakesrc_loop (GstElement * element); +static GstData *gst_fakesrc_get (GstAction * action, GstRealPad * pad); static guint gst_fakesrc_signals[LAST_SIGNAL] = { 0 }; @@ -214,13 +212,9 @@ gst_fakesrc_class_init (GstFakeSrcClass * klass) gobject_class = (GObjectClass *) klass; gstelement_class = (GstElementClass *) klass; - g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_NUM_SOURCES, g_param_spec_int ("num-sources", "num-sources", "Number of sources", 1, G_MAXINT, 1, G_PARAM_READABLE)); - g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_LOOP_BASED, - g_param_spec_boolean ("loop-based", "loop-based", - "Enable loop-based operation", FALSE, G_PARAM_READWRITE)); g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_OUTPUT, g_param_spec_enum ("output", "output", "Output method (currently unused)", GST_TYPE_FAKESRC_OUTPUT, FAKESRC_FIRST_LAST_LOOP, G_PARAM_READWRITE)); @@ -299,11 +293,9 @@ gst_fakesrc_init (GstFakeSrc * fakesrc) pad = gst_pad_new_from_template (gst_static_pad_template_get (&srctemplate), "src"); + gst_fakesrc_update_functions (fakesrc, pad); gst_element_add_pad (GST_ELEMENT (fakesrc), pad); - fakesrc->loop_based = FALSE; - gst_fakesrc_update_functions (fakesrc); - fakesrc->output = FAKESRC_FIRST_LAST_LOOP; fakesrc->segment_start = -1; fakesrc->segment_end = -1; @@ -358,39 +350,14 @@ gst_fakesrc_request_new_pad (GstElement * element, GstPadTemplate * templ, name = g_strdup_printf ("src%d", GST_ELEMENT (fakesrc)->numsrcpads); srcpad = gst_pad_new_from_template (templ, name); + gst_fakesrc_update_functions (fakesrc, srcpad); gst_element_add_pad (GST_ELEMENT (fakesrc), srcpad); - gst_fakesrc_update_functions (fakesrc); g_free (name); return srcpad; } -static const GstFormat * -gst_fakesrc_get_formats (GstPad * pad) -{ - static const GstFormat formats[] = { - GST_FORMAT_DEFAULT, - 0, - }; - - return formats; -} - -static const GstQueryType * -gst_fakesrc_get_query_types (GstPad * pad) -{ - static const GstQueryType types[] = { - GST_QUERY_TOTAL, - GST_QUERY_POSITION, - GST_QUERY_START, - GST_QUERY_SEGMENT_END, - 0, - }; - - return types; -} - static gboolean gst_fakesrc_query (GstPad * pad, GstQueryType type, GstFormat * format, gint64 * value) @@ -416,19 +383,6 @@ gst_fakesrc_query (GstPad * pad, GstQueryType type, return TRUE; } -static const GstEventMask * -gst_fakesrc_get_event_mask (GstPad * pad) -{ - static const GstEventMask masks[] = { - {GST_EVENT_SEEK, GST_SEEK_FLAG_FLUSH}, - {GST_EVENT_SEEK_SEGMENT, GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_SEGMENT_LOOP}, - {GST_EVENT_FLUSH, 0}, - {0, 0}, - }; - - return masks; -} - static gboolean gst_fakesrc_event_handler (GstPad * pad, GstEvent * event) { @@ -463,34 +417,12 @@ gst_fakesrc_event_handler (GstPad * pad, GstEvent * event) } static void -gst_fakesrc_update_functions (GstFakeSrc * src) +gst_fakesrc_update_functions (GstFakeSrc * src, GstPad * pad) { - GList *pads; - - if (src->loop_based) { - gst_element_set_loop_function (GST_ELEMENT (src), - GST_DEBUG_FUNCPTR (gst_fakesrc_loop)); - } else { - gst_element_set_loop_function (GST_ELEMENT (src), NULL); - } - - pads = GST_ELEMENT (src)->pads; - while (pads) { - GstPad *pad = GST_PAD (pads->data); - - if (src->loop_based) { - gst_pad_set_get_function (pad, NULL); - } else { - gst_pad_set_get_function (pad, GST_DEBUG_FUNCPTR (gst_fakesrc_get)); - } - - gst_pad_set_event_function (pad, gst_fakesrc_event_handler); - gst_pad_set_event_mask_function (pad, gst_fakesrc_get_event_mask); - gst_pad_set_query_function (pad, gst_fakesrc_query); - gst_pad_set_query_type_function (pad, gst_fakesrc_get_query_types); - gst_pad_set_formats_function (pad, gst_fakesrc_get_formats); - pads = g_list_next (pads); - } + gst_src_pad_set_action_handler (pad, gst_fakesrc_get); + gst_real_pad_set_initially_active (GST_REAL_PAD (pad), TRUE); + gst_pad_set_event_function (pad, gst_fakesrc_event_handler); + gst_pad_set_query_function (pad, gst_fakesrc_query); } static void @@ -516,10 +448,6 @@ gst_fakesrc_set_property (GObject * object, guint prop_id, const GValue * value, src = GST_FAKESRC (object); switch (prop_id) { - case ARG_LOOP_BASED: - src->loop_based = g_value_get_boolean (value); - gst_fakesrc_update_functions (src); - break; case ARG_OUTPUT: g_warning ("not yet implemented"); break; @@ -596,9 +524,6 @@ gst_fakesrc_get_property (GObject * object, guint prop_id, GValue * value, case ARG_NUM_SOURCES: g_value_set_int (value, GST_ELEMENT (src)->numsrcpads); break; - case ARG_LOOP_BASED: - g_value_set_boolean (value, src->loop_based); - break; case ARG_OUTPUT: g_value_set_enum (value, src->output); break; @@ -791,7 +716,7 @@ gst_fakesrc_create_buffer (GstFakeSrc * src) } static GstData * -gst_fakesrc_get (GstPad * pad) +gst_fakesrc_get (GstAction * action, GstRealPad * pad) { GstFakeSrc *src; GstBuffer *buf; @@ -870,40 +795,6 @@ gst_fakesrc_get (GstPad * pad) return GST_DATA (buf); } -/** - * gst_fakesrc_loop: - * @element: the faksesrc to loop - * - * generate an empty buffer and push it to the next element. - */ -static void -gst_fakesrc_loop (GstElement * element) -{ - GstFakeSrc *src; - const GList *pads; - - g_return_if_fail (element != NULL); - g_return_if_fail (GST_IS_FAKESRC (element)); - - src = GST_FAKESRC (element); - - pads = gst_element_get_pad_list (element); - - while (pads) { - GstPad *pad = GST_PAD (pads->data); - GstData *data; - - data = gst_fakesrc_get (pad); - gst_pad_push (pad, data); - - if (src->eos) { - return; - } - - pads = g_list_next (pads); - } -} - static GstElementStateReturn gst_fakesrc_change_state (GstElement * element) { diff --git a/gst/elements/gstfakesrc.h b/gst/elements/gstfakesrc.h index 5214f0bb7c..c317acc75e 100644 --- a/gst/elements/gstfakesrc.h +++ b/gst/elements/gstfakesrc.h @@ -76,7 +76,6 @@ typedef struct _GstFakeSrcClass GstFakeSrcClass; struct _GstFakeSrc { GstElement element; - gboolean loop_based; gboolean eos; GstFakeSrcOutputType output; diff --git a/gst/elements/gstfdsink.c b/gst/elements/gstfdsink.c index 411dd0a32e..f9ab6fa091 100644 --- a/gst/elements/gstfdsink.c +++ b/gst/elements/gstfdsink.c @@ -69,7 +69,8 @@ static void gst_fdsink_set_property (GObject * object, guint prop_id, static void gst_fdsink_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec); -static void gst_fdsink_chain (GstPad * pad, GstData * _data); +static void gst_fdsink_chain (GstAction * action, GstRealPad * pad, + GstData * _data); static void @@ -103,14 +104,14 @@ gst_fdsink_init (GstFdSink * fdsink) fdsink->sinkpad = gst_pad_new_from_template (gst_static_pad_template_get (&sinktemplate), "sink"); + gst_sink_pad_set_action_handler (fdsink->sinkpad, gst_fdsink_chain); gst_element_add_pad (GST_ELEMENT (fdsink), fdsink->sinkpad); - gst_pad_set_chain_function (fdsink->sinkpad, gst_fdsink_chain); fdsink->fd = 1; } static void -gst_fdsink_chain (GstPad * pad, GstData * _data) +gst_fdsink_chain (GstAction * action, GstRealPad * pad, GstData * _data) { GstBuffer *buf = GST_BUFFER (_data); GstFdSink *fdsink; @@ -119,7 +120,7 @@ gst_fdsink_chain (GstPad * pad, GstData * _data) g_return_if_fail (GST_IS_PAD (pad)); g_return_if_fail (buf != NULL); - fdsink = GST_FDSINK (gst_pad_get_parent (pad)); + fdsink = GST_FDSINK (gst_pad_get_parent (GST_PAD (pad))); g_return_if_fail (fdsink->fd >= 0); diff --git a/gst/elements/gstfdsrc.c b/gst/elements/gstfdsrc.c index ce1d76a10a..4308d7c3cd 100644 --- a/gst/elements/gstfdsrc.c +++ b/gst/elements/gstfdsrc.c @@ -102,7 +102,7 @@ static void gst_fdsrc_get_property (GObject * object, guint prop_id, static GstElementStateReturn gst_fdsrc_change_state (GstElement * element); static gboolean gst_fdsrc_release_locks (GstElement * element); -static GstData *gst_fdsrc_get (GstPad * pad); +static GstData *gst_fdsrc_get (GstAction * action, GstRealPad * pad); static void @@ -164,7 +164,8 @@ gst_fdsrc_init (GstFdSrc * fdsrc) gst_pad_new_from_template (gst_static_pad_template_get (&srctemplate), "src"); - gst_pad_set_get_function (fdsrc->srcpad, gst_fdsrc_get); + gst_src_pad_set_action_handler (fdsrc->srcpad, gst_fdsrc_get); + gst_real_pad_set_initially_active (GST_REAL_PAD (fdsrc->srcpad), TRUE); gst_element_add_pad (GST_ELEMENT (fdsrc), fdsrc->srcpad); fdsrc->fd = 0; @@ -265,7 +266,7 @@ gst_fdsrc_release_locks (GstElement * element) } static GstData * -gst_fdsrc_get (GstPad * pad) +gst_fdsrc_get (GstAction * action, GstRealPad * pad) { GstFdSrc *src; GstBuffer *buf; @@ -277,7 +278,7 @@ gst_fdsrc_get (GstPad * pad) gint retval; #endif - src = GST_FDSRC (gst_pad_get_parent (pad)); + src = GST_FDSRC (gst_pad_get_parent (GST_PAD (pad))); /* create the buffer */ buf = gst_buffer_new_and_alloc (src->blocksize); diff --git a/gst/elements/gstfilesink.c b/gst/elements/gstfilesink.c index a575d5a363..6b43163536 100644 --- a/gst/elements/gstfilesink.c +++ b/gst/elements/gstfilesink.c @@ -66,29 +66,6 @@ enum ARG_LOCATION }; -static const GstFormat * -gst_filesink_get_formats (GstPad * pad) -{ - static const GstFormat formats[] = { - GST_FORMAT_BYTES, - 0, - }; - - return formats; -} - -static const GstQueryType * -gst_filesink_get_query_types (GstPad * pad) -{ - static const GstQueryType types[] = { - GST_QUERY_TOTAL, - GST_QUERY_POSITION, - 0 - }; - - return types; -} - static void gst_filesink_dispose (GObject * object); static void gst_filesink_set_property (GObject * object, guint prop_id, @@ -99,10 +76,11 @@ static void gst_filesink_get_property (GObject * object, guint prop_id, static gboolean gst_filesink_open_file (GstFileSink * sink); static void gst_filesink_close_file (GstFileSink * sink); -static gboolean gst_filesink_handle_event (GstPad * pad, GstEvent * event); +static gboolean gst_filesink_handle_event (GstRealPad * pad, GstEvent * event); static gboolean gst_filesink_pad_query (GstPad * pad, GstQueryType type, GstFormat * format, gint64 * value); -static void gst_filesink_chain (GstPad * pad, GstData * _data); +static void gst_filesink_chain (GstAction * action, GstRealPad * pad, + GstData * _data); static void gst_filesink_uri_handler_init (gpointer g_iface, gpointer iface_data); @@ -167,14 +145,12 @@ gst_filesink_init (GstFileSink * filesink) pad = gst_pad_new_from_template (gst_static_pad_template_get (&sinktemplate), "sink"); + gst_sink_pad_set_action_handler (pad, gst_filesink_chain); gst_element_add_pad (GST_ELEMENT (filesink), pad); - gst_pad_set_chain_function (pad, gst_filesink_chain); GST_FLAG_SET (GST_ELEMENT (filesink), GST_ELEMENT_EVENT_AWARE); gst_pad_set_query_function (pad, gst_filesink_pad_query); - gst_pad_set_query_type_function (pad, gst_filesink_get_query_types); - gst_pad_set_formats_function (pad, gst_filesink_get_formats); filesink->filename = NULL; filesink->file = NULL; @@ -336,12 +312,12 @@ gst_filesink_pad_query (GstPad * pad, GstQueryType type, /* handle events (search) */ static gboolean -gst_filesink_handle_event (GstPad * pad, GstEvent * event) +gst_filesink_handle_event (GstRealPad * pad, GstEvent * event) { GstEventType type; GstFileSink *filesink; - filesink = GST_FILESINK (gst_pad_get_parent (pad)); + filesink = GST_FILESINK (gst_pad_get_parent (GST_PAD (pad))); if (!(GST_FLAG_IS_SET (filesink, GST_FILESINK_OPEN))) { gst_event_unref (event); @@ -407,7 +383,7 @@ gst_filesink_handle_event (GstPad * pad, GstEvent * event) gst_element_set_eos (GST_ELEMENT (filesink)); break; default: - gst_pad_event_default (pad, event); + gst_pad_event_default (GST_PAD (pad), event); break; } @@ -422,7 +398,7 @@ gst_filesink_handle_event (GstPad * pad, GstEvent * event) * take the buffer from the pad and write to file if it's open */ static void -gst_filesink_chain (GstPad * pad, GstData * _data) +gst_filesink_chain (GstAction * action, GstRealPad * pad, GstData * _data) { GstBuffer *buf = GST_BUFFER (_data); GstFileSink *filesink; @@ -431,7 +407,7 @@ gst_filesink_chain (GstPad * pad, GstData * _data) g_return_if_fail (GST_IS_PAD (pad)); g_return_if_fail (buf != NULL); - filesink = GST_FILESINK (gst_pad_get_parent (pad)); + filesink = GST_FILESINK (gst_pad_get_parent (GST_PAD (pad))); if (GST_IS_EVENT (buf)) { gst_filesink_handle_event (pad, GST_EVENT (buf)); diff --git a/gst/elements/gstfilesrc.c b/gst/elements/gstfilesrc.c index 98105cc6ec..e120eac8b8 100644 --- a/gst/elements/gstfilesrc.c +++ b/gst/elements/gstfilesrc.c @@ -125,43 +125,6 @@ enum ARG_TOUCH }; -static const GstEventMask * -gst_filesrc_get_event_mask (GstPad * pad) -{ - static const GstEventMask masks[] = { - {GST_EVENT_SEEK, GST_SEEK_METHOD_CUR | - GST_SEEK_METHOD_SET | GST_SEEK_METHOD_END | GST_SEEK_FLAG_FLUSH}, - {GST_EVENT_FLUSH, 0}, - {GST_EVENT_SIZE, 0}, - {0, 0} - }; - - return masks; -} - -static const GstQueryType * -gst_filesrc_get_query_types (GstPad * pad) -{ - static const GstQueryType types[] = { - GST_QUERY_TOTAL, - GST_QUERY_POSITION, - 0 - }; - - return types; -} - -static const GstFormat * -gst_filesrc_get_formats (GstPad * pad) -{ - static const GstFormat formats[] = { - GST_FORMAT_BYTES, - 0, - }; - - return formats; -} - static void gst_filesrc_dispose (GObject * object); static void gst_filesrc_set_property (GObject * object, guint prop_id, @@ -170,7 +133,7 @@ static void gst_filesrc_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec); static gboolean gst_filesrc_check_filesize (GstFileSrc * src); -static GstData *gst_filesrc_get (GstPad * pad); +static GstData *gst_filesrc_get (GstAction * action, GstRealPad * pad); static gboolean gst_filesrc_srcpad_event (GstPad * pad, GstEvent * event); static gboolean gst_filesrc_srcpad_query (GstPad * pad, GstQueryType type, GstFormat * format, gint64 * value); @@ -247,12 +210,10 @@ gst_filesrc_init (GstFileSrc * src) src->srcpad = gst_pad_new_from_template (gst_static_pad_template_get (&srctemplate), "src"); - gst_pad_set_get_function (src->srcpad, gst_filesrc_get); + gst_src_pad_set_action_handler (src->srcpad, gst_filesrc_get); + gst_real_pad_set_initially_active (GST_REAL_PAD (src->srcpad), TRUE); gst_pad_set_event_function (src->srcpad, gst_filesrc_srcpad_event); - gst_pad_set_event_mask_function (src->srcpad, gst_filesrc_get_event_mask); gst_pad_set_query_function (src->srcpad, gst_filesrc_srcpad_query); - gst_pad_set_query_type_function (src->srcpad, gst_filesrc_get_query_types); - gst_pad_set_formats_function (src->srcpad, gst_filesrc_get_formats); gst_element_add_pad (GST_ELEMENT (src), src->srcpad); #ifdef HAVE_MMAP @@ -686,12 +647,12 @@ gst_filesrc_get_read (GstFileSrc * src) } static GstData * -gst_filesrc_get (GstPad * pad) +gst_filesrc_get (GstAction * action, GstRealPad * pad) { GstFileSrc *src; g_return_val_if_fail (pad != NULL, NULL); - src = GST_FILESRC (gst_pad_get_parent (pad)); + src = GST_FILESRC (gst_pad_get_parent (GST_PAD (pad))); g_return_val_if_fail (GST_FLAG_IS_SET (src, GST_FILESRC_OPEN), NULL); /* check for flush */ diff --git a/gst/elements/gstidentity.c b/gst/elements/gstidentity.c index 5221b6f41a..244109f3d8 100644 --- a/gst/elements/gstidentity.c +++ b/gst/elements/gstidentity.c @@ -31,18 +31,10 @@ #include "gstidentity.h" #include -static GstStaticPadTemplate sinktemplate = GST_STATIC_PAD_TEMPLATE ("sink", - GST_PAD_SINK, - GST_PAD_ALWAYS, - GST_STATIC_CAPS_ANY); - -static GstStaticPadTemplate srctemplate = GST_STATIC_PAD_TEMPLATE ("src", - GST_PAD_SRC, - GST_PAD_ALWAYS, - GST_STATIC_CAPS_ANY); - -GST_DEBUG_CATEGORY_STATIC (gst_identity_debug); +/* +GST_DEBUG_CATEGORY_STATIC (gst_identity_debug, "identity", 0, "identity element"); #define GST_CAT_DEFAULT gst_identity_debug +*/ GstElementDetails gst_identity_details = GST_ELEMENT_DETAILS ("Identity", "Generic", @@ -58,49 +50,32 @@ enum LAST_SIGNAL }; -#define DEFAULT_LOOP_BASED FALSE -#define DEFAULT_SLEEP_TIME 0 -#define DEFAULT_DUPLICATE 1 -#define DEFAULT_ERROR_AFTER -1 -#define DEFAULT_DROP_PROBABILITY 0.0 -#define DEFAULT_DATARATE 0 -#define DEFAULT_SILENT FALSE -#define DEFAULT_DUMP FALSE -#define DEFAULT_SYNC FALSE -#define DEFAULT_CHECK_PERFECT FALSE - enum { ARG_0, - ARG_LOOP_BASED, ARG_SLEEP_TIME, ARG_DUPLICATE, ARG_ERROR_AFTER, ARG_DROP_PROBABILITY, - ARG_DATARATE, ARG_SILENT, ARG_LAST_MESSAGE, ARG_DUMP, - ARG_SYNC, ARG_CHECK_PERFECT }; - -#define _do_init(bla) \ - GST_DEBUG_CATEGORY_INIT (gst_identity_debug, "identity", 0, "identity element"); - -GST_BOILERPLATE_FULL (GstIdentity, gst_identity, GstElement, GST_TYPE_ELEMENT, - _do_init); +GST_BOILERPLATE (GstIdentity, gst_identity, GstElement, GST_TYPE_ELEMENT); static void gst_identity_finalize (GObject * object); static void gst_identity_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec); static void gst_identity_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec); -static GstElementStateReturn gst_identity_change_state (GstElement * element); -static void gst_identity_chain (GstPad * pad, GstData * _data); -static void gst_identity_set_clock (GstElement * element, GstClock * clock); +static GstElementStateReturn gst_identity_change_state (GstElement * element); +static void gst_identity_chain (GstAction * action, GstRealPad * pad, + GstData * data); +static void gst_identity_wakeup (GstAction * action, GstElement * element, + gpointer unused); static guint gst_identity_signals[LAST_SIGNAL] = { 0 }; @@ -110,10 +85,6 @@ gst_identity_base_init (gpointer g_class) { GstElementClass *gstelement_class = GST_ELEMENT_CLASS (g_class); - gst_element_class_add_pad_template (gstelement_class, - gst_static_pad_template_get (&srctemplate)); - gst_element_class_add_pad_template (gstelement_class, - gst_static_pad_template_get (&sinktemplate)); gst_element_class_set_details (gstelement_class, &gst_identity_details); } @@ -138,45 +109,36 @@ gst_identity_class_init (GstIdentityClass * klass) gobject_class = G_OBJECT_CLASS (klass); gstelement_class = GST_ELEMENT_CLASS (klass); - g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_LOOP_BASED, - g_param_spec_boolean ("loop-based", "Loop-based", - "Set to TRUE to use loop-based rather than chain-based scheduling", - DEFAULT_LOOP_BASED, G_PARAM_READWRITE)); + gobject_class->get_property = GST_DEBUG_FUNCPTR (gst_identity_get_property); + gobject_class->set_property = GST_DEBUG_FUNCPTR (gst_identity_set_property); + g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_SLEEP_TIME, g_param_spec_uint ("sleep-time", "Sleep time", - "Microseconds to sleep between processing", 0, G_MAXUINT, - DEFAULT_SLEEP_TIME, G_PARAM_READWRITE)); + "Microseconds to sleep between processing", 0, G_MAXUINT, 0, + G_PARAM_READWRITE)); g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_DUPLICATE, g_param_spec_uint ("duplicate", "Duplicate Buffers", - "Push the buffers N times", 0, G_MAXUINT, DEFAULT_DUPLICATE, - G_PARAM_READWRITE)); + "Push the buffers N times", 0, G_MAXUINT, 1, G_PARAM_READWRITE)); g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_ERROR_AFTER, g_param_spec_int ("error_after", "Error After", "Error after N buffers", - G_MININT, G_MAXINT, DEFAULT_ERROR_AFTER, G_PARAM_READWRITE)); + G_MININT, G_MAXINT, -1, G_PARAM_READWRITE)); g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_DROP_PROBABILITY, g_param_spec_float ("drop_probability", "Drop Probability", - "The Probability a buffer is dropped", 0.0, 1.0, - DEFAULT_DROP_PROBABILITY, G_PARAM_READWRITE)); - g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_DATARATE, - g_param_spec_int ("datarate", "Datarate", - "(Re)timestamps buffers with number of bytes per second (0 = inactive)", - 0, G_MAXINT, DEFAULT_DATARATE, G_PARAM_READWRITE)); + "The Probability a buffer is dropped", 0.0, 1.0, 0.0, + G_PARAM_READWRITE)); g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_SILENT, - g_param_spec_boolean ("silent", "silent", "silent", DEFAULT_SILENT, + g_param_spec_boolean ("silent", "silent", "silent", FALSE, G_PARAM_READWRITE)); g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_LAST_MESSAGE, g_param_spec_string ("last-message", "last-message", "last-message", NULL, G_PARAM_READABLE)); g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_DUMP, - g_param_spec_boolean ("dump", "Dump", "Dump buffer contents", - DEFAULT_DUMP, G_PARAM_READWRITE)); - g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_SYNC, - g_param_spec_boolean ("sync", "Synchronize", - "Synchronize to pipeline clock", DEFAULT_SYNC, G_PARAM_READWRITE)); + g_param_spec_boolean ("dump", "Dump", "Dump buffer contents", FALSE, + G_PARAM_READWRITE)); g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_CHECK_PERFECT, g_param_spec_boolean ("check-perfect", "Check For Perfect Stream", - "Verify that the stream is time- and data-contiguous", - DEFAULT_CHECK_PERFECT, G_PARAM_READWRITE)); + "Verify that the stream is time- and data-contiguous", FALSE, + G_PARAM_READWRITE)); gst_identity_signals[SIGNAL_HANDOFF] = g_signal_new ("handoff", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, @@ -185,74 +147,82 @@ gst_identity_class_init (GstIdentityClass * klass) GST_TYPE_BUFFER | G_SIGNAL_TYPE_STATIC_SCOPE); gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_identity_finalize); - gobject_class->set_property = GST_DEBUG_FUNCPTR (gst_identity_set_property); - gobject_class->get_property = GST_DEBUG_FUNCPTR (gst_identity_get_property); - gstelement_class->set_clock = GST_DEBUG_FUNCPTR (gst_identity_set_clock); gstelement_class->change_state = GST_DEBUG_FUNCPTR (gst_identity_change_state); - } static void gst_identity_init (GstIdentity * identity) { - identity->sinkpad = - gst_pad_new_from_template (gst_static_pad_template_get (&sinktemplate), - "sink"); + GST_FLAG_SET (identity, GST_ELEMENT_EVENT_AWARE); + GST_FLAG_SET (identity, GST_ELEMENT_PUSHING); + + identity->sinkpad = gst_pad_new ("sink", GST_PAD_SINK); + gst_sink_pad_set_action_handler (identity->sinkpad, gst_identity_chain); gst_element_add_pad (GST_ELEMENT (identity), identity->sinkpad); - gst_pad_set_chain_function (identity->sinkpad, - GST_DEBUG_FUNCPTR (gst_identity_chain)); gst_pad_set_link_function (identity->sinkpad, gst_pad_proxy_pad_link); gst_pad_set_getcaps_function (identity->sinkpad, gst_pad_proxy_getcaps); - identity->srcpad = - gst_pad_new_from_template (gst_static_pad_template_get (&srctemplate), - "src"); + identity->srcpad = gst_pad_new ("src", GST_PAD_SRC); gst_element_add_pad (GST_ELEMENT (identity), identity->srcpad); gst_pad_set_link_function (identity->srcpad, gst_pad_proxy_pad_link); gst_pad_set_getcaps_function (identity->srcpad, gst_pad_proxy_getcaps); - identity->loop_based = DEFAULT_LOOP_BASED; - identity->sleep_time = DEFAULT_SLEEP_TIME; - identity->duplicate = DEFAULT_DUPLICATE; - identity->error_after = DEFAULT_ERROR_AFTER; - identity->drop_probability = DEFAULT_DROP_PROBABILITY; - identity->datarate = DEFAULT_DATARATE; - identity->silent = DEFAULT_SILENT; - identity->sync = DEFAULT_SYNC; - identity->check_perfect = DEFAULT_CHECK_PERFECT; - identity->dump = DEFAULT_DUMP; + identity->wakeup = gst_element_add_wakeup (GST_ELEMENT (identity), FALSE, + gst_identity_wakeup, NULL); + + identity->loop_based = FALSE; + identity->sleep_time = 0; + identity->duplicate = 1; + identity->error_after = -1; + identity->drop_probability = 0.0; + identity->silent = FALSE; + identity->check_perfect = FALSE; + identity->prev_timestamp = GST_CLOCK_TIME_NONE; + identity->prev_duration = GST_CLOCK_TIME_NONE; + identity->prev_offset_end = -1; + identity->dump = FALSE; identity->last_message = NULL; identity->srccaps = NULL; - - GST_FLAG_SET (identity, GST_ELEMENT_EVENT_AWARE); - GST_FLAG_SET (identity, GST_ELEMENT_WORK_IN_PLACE); - } static void -gst_identity_set_clock (GstElement * element, GstClock * clock) +gst_identity_push (GstIdentity * identity, GstBuffer * buf) { - GstIdentity *identity = GST_IDENTITY (element); + if (!identity->silent) { + g_free (identity->last_message); + identity->last_message = + g_strdup_printf ("chain ******* (%s:%s)i (%d bytes, timestamp: %" + GST_TIME_FORMAT ", duration: %" GST_TIME_FORMAT ", offset: %" + G_GINT64_FORMAT ", offset_end: % " G_GINT64_FORMAT ", flags: %d) %p", + GST_DEBUG_PAD_NAME (identity->sinkpad), GST_BUFFER_SIZE (buf), + GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)), + GST_TIME_ARGS (GST_BUFFER_DURATION (buf)), GST_BUFFER_OFFSET (buf), + GST_BUFFER_OFFSET_END (buf), GST_BUFFER_FLAGS (buf), buf); + g_object_notify (G_OBJECT (identity), "last-message"); + } - gst_object_replace ((GstObject **) & identity->clock, (GstObject *) clock); + gst_object_ref (GST_OBJECT (identity)); + g_signal_emit (G_OBJECT (identity), gst_identity_signals[SIGNAL_HANDOFF], 0, + buf); + + if (identity->sleep_time) + g_usleep (identity->sleep_time); + + /* things may happen in handoff signals... */ + if (GST_ELEMENT_SCHED (identity)) + gst_pad_push (identity->srcpad, GST_DATA (buf)); + gst_object_unref (GST_OBJECT (identity)); } - static void -gst_identity_chain (GstPad * pad, GstData * _data) +gst_identity_chain (GstAction * action, GstRealPad * pad, GstData * data) { - GstBuffer *buf = GST_BUFFER (_data); - GstIdentity *identity; - guint i; - - g_return_if_fail (pad != NULL); - g_return_if_fail (GST_IS_PAD (pad)); - g_return_if_fail (buf != NULL); - - identity = GST_IDENTITY (gst_pad_get_parent (pad)); + GstBuffer *buf; + GstIdentity *identity = GST_IDENTITY (gst_pad_get_parent (GST_PAD (pad))); + buf = GST_BUFFER (data); if (GST_IS_EVENT (buf)) { GstEvent *event = GST_EVENT (buf); @@ -261,11 +231,12 @@ gst_identity_chain (GstPad * pad, GstData * _data) identity->last_message = g_strdup_printf ("chain ******* (%s:%s)E (type: %d) %p", - GST_DEBUG_PAD_NAME (pad), GST_EVENT_TYPE (event), event); + GST_DEBUG_PAD_NAME (identity->sinkpad), GST_EVENT_TYPE (event), + event); g_object_notify (G_OBJECT (identity), "last_message"); } - gst_pad_event_default (pad, event); + gst_pad_event_default (identity->sinkpad, event); return; } @@ -328,75 +299,31 @@ gst_identity_chain (GstPad * pad, GstData * _data) gst_util_dump_mem (GST_BUFFER_DATA (buf), GST_BUFFER_SIZE (buf)); } - for (i = identity->duplicate; i; i--) { - GstClockTime time; - - if (!identity->silent) { - g_free (identity->last_message); - identity->last_message = - g_strdup_printf ("chain ******* (%s:%s)i (%d bytes, timestamp: %" - GST_TIME_FORMAT ", duration: %" GST_TIME_FORMAT ", offset: %" - G_GINT64_FORMAT ", offset_end: % " G_GINT64_FORMAT ", flags: %d) %p", - GST_DEBUG_PAD_NAME (identity->sinkpad), GST_BUFFER_SIZE (buf), - GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)), - GST_TIME_ARGS (GST_BUFFER_DURATION (buf)), GST_BUFFER_OFFSET (buf), - GST_BUFFER_OFFSET_END (buf), GST_BUFFER_FLAGS (buf), buf); - g_object_notify (G_OBJECT (identity), "last-message"); - } - - time = GST_BUFFER_TIMESTAMP (buf); - - if (identity->datarate > 0) { - time = identity->bytes_handled * GST_SECOND / identity->datarate; - - GST_BUFFER_TIMESTAMP (buf) = time; - GST_BUFFER_DURATION (buf) = - GST_BUFFER_SIZE (buf) * GST_SECOND / identity->datarate; - } - - g_signal_emit (G_OBJECT (identity), gst_identity_signals[SIGNAL_HANDOFF], 0, - buf); - - if (i > 1) - gst_buffer_ref (buf); - - if (identity->sync) { - if (identity->clock) { - gst_element_wait (GST_ELEMENT (identity), time); - } - } - - identity->bytes_handled += GST_BUFFER_SIZE (buf); - gst_pad_push (identity->srcpad, GST_DATA (buf)); - - if (identity->sleep_time) - g_usleep (identity->sleep_time); + if (identity->duplicate > 1) { + identity->current = buf; + gst_data_ref (GST_DATA (buf)); + identity->missing = identity->duplicate - 1; + gst_action_set_active (action, FALSE); + gst_action_set_active (identity->wakeup, TRUE); } + gst_identity_push (identity, buf); } static void -gst_identity_loop (GstElement * element) +gst_identity_wakeup (GstAction * action, GstElement * element, gpointer unused) { - GstIdentity *identity; - GstBuffer *buf; + GstIdentity *identity = GST_IDENTITY (element); + GstBuffer *buf = identity->current; - g_return_if_fail (element != NULL); - g_return_if_fail (GST_IS_IDENTITY (element)); - - identity = GST_IDENTITY (element); - - buf = GST_BUFFER (gst_pad_pull (identity->sinkpad)); - if (GST_IS_EVENT (buf)) { - GstEvent *event = GST_EVENT (buf); - - if (GST_EVENT_IS_INTERRUPT (event)) { - gst_event_unref (event); - } else { - gst_pad_event_default (identity->sinkpad, event); - } + g_assert (buf); + if (--identity->missing) { + gst_data_ref (GST_DATA (buf)); } else { - gst_identity_chain (identity->sinkpad, GST_DATA (buf)); + identity->current = NULL; + gst_action_set_active (action, FALSE); + gst_real_pad_set_active (GST_REAL_PAD (identity->sinkpad), TRUE); } + gst_identity_push (identity, buf); } static void @@ -411,17 +338,6 @@ gst_identity_set_property (GObject * object, guint prop_id, identity = GST_IDENTITY (object); switch (prop_id) { - case ARG_LOOP_BASED: - identity->loop_based = g_value_get_boolean (value); - if (identity->loop_based) { - gst_element_set_loop_function (GST_ELEMENT (identity), - gst_identity_loop); - gst_pad_set_chain_function (identity->sinkpad, NULL); - } else { - gst_pad_set_chain_function (identity->sinkpad, gst_identity_chain); - gst_element_set_loop_function (GST_ELEMENT (identity), NULL); - } - break; case ARG_SLEEP_TIME: identity->sleep_time = g_value_get_uint (value); break; @@ -440,12 +356,6 @@ gst_identity_set_property (GObject * object, guint prop_id, case ARG_DROP_PROBABILITY: identity->drop_probability = g_value_get_float (value); break; - case ARG_DATARATE: - identity->datarate = g_value_get_int (value); - break; - case ARG_SYNC: - identity->sync = g_value_get_boolean (value); - break; case ARG_CHECK_PERFECT: identity->check_perfect = g_value_get_boolean (value); break; @@ -467,9 +377,6 @@ gst_identity_get_property (GObject * object, guint prop_id, GValue * value, identity = GST_IDENTITY (object); switch (prop_id) { - case ARG_LOOP_BASED: - g_value_set_boolean (value, identity->loop_based); - break; case ARG_SLEEP_TIME: g_value_set_uint (value, identity->sleep_time); break; @@ -482,9 +389,6 @@ gst_identity_get_property (GObject * object, guint prop_id, GValue * value, case ARG_DROP_PROBABILITY: g_value_set_float (value, identity->drop_probability); break; - case ARG_DATARATE: - g_value_set_int (value, identity->datarate); - break; case ARG_SILENT: g_value_set_boolean (value, identity->silent); break; @@ -494,9 +398,6 @@ gst_identity_get_property (GObject * object, guint prop_id, GValue * value, case ARG_LAST_MESSAGE: g_value_set_string (value, identity->last_message); break; - case ARG_SYNC: - g_value_set_boolean (value, identity->sync); - break; case ARG_CHECK_PERFECT: g_value_set_boolean (value, identity->check_perfect); break; @@ -509,29 +410,14 @@ gst_identity_get_property (GObject * object, guint prop_id, GValue * value, static GstElementStateReturn gst_identity_change_state (GstElement * element) { - GstIdentity *identity; - - g_return_val_if_fail (GST_IS_IDENTITY (element), GST_STATE_FAILURE); - - identity = GST_IDENTITY (element); + GstIdentity *identity = GST_IDENTITY (element); switch (GST_STATE_TRANSITION (element)) { - case GST_STATE_NULL_TO_READY: - break; - case GST_STATE_READY_TO_PAUSED: - identity->bytes_handled = 0; - identity->prev_timestamp = GST_CLOCK_TIME_NONE; - identity->prev_duration = GST_CLOCK_TIME_NONE; - identity->prev_offset_end = -1; - break; - case GST_STATE_PAUSED_TO_PLAYING: - case GST_STATE_PLAYING_TO_PAUSED: - break; case GST_STATE_PAUSED_TO_READY: - g_free (identity->last_message); - identity->last_message = NULL; - break; - case GST_STATE_READY_TO_NULL: + if (identity->current) { + gst_data_unref (GST_DATA (identity->current)); + identity->current = NULL; + } break; default: break; diff --git a/gst/elements/gstidentity.h b/gst/elements/gstidentity.h index 00203beed5..c81cd0b12a 100644 --- a/gst/elements/gstidentity.h +++ b/gst/elements/gstidentity.h @@ -47,27 +47,27 @@ typedef struct _GstIdentityClass GstIdentityClass; struct _GstIdentity { GstElement element; - GstPad *sinkpad; - GstPad *srcpad; + GstPad * sinkpad; + GstPad * srcpad; + + GstAction * wakeup; gboolean loop_based; guint duplicate; gint error_after; gfloat drop_probability; - gint datarate; guint sleep_time; gboolean silent; gboolean dump; - gboolean sync; gboolean check_perfect; GstClockTime prev_timestamp; GstClockTime prev_duration; guint64 prev_offset_end; - GstClock *clock; gchar *last_message; GstCaps *srccaps; - guint64 bytes_handled; + GstBuffer * current; + guint missing; }; struct _GstIdentityClass { diff --git a/gst/elements/gsttee.c b/gst/elements/gsttee.c index a046ed3635..a0ae285b48 100644 --- a/gst/elements/gsttee.c +++ b/gst/elements/gsttee.c @@ -27,15 +27,10 @@ #include "gsttee.h" #include - -static GstStaticPadTemplate sinktemplate = GST_STATIC_PAD_TEMPLATE ("sink", - GST_PAD_SINK, - GST_PAD_ALWAYS, - GST_STATIC_CAPS_ANY); - -GST_DEBUG_CATEGORY_STATIC (gst_tee_debug); +#if 0 +GST_DEBUG_CATEGORY_STATIC (gst_tee_debug, "tee", 0, "tee element"); #define GST_CAT_DEFAULT gst_tee_debug - +#endif GstElementDetails gst_tee_details = GST_ELEMENT_DETAILS ("Tee pipe fitting", "Generic", "1-to-N pipe fitting", @@ -63,10 +58,7 @@ GstStaticPadTemplate tee_src_template = GST_STATIC_PAD_TEMPLATE ("src%d", GST_PAD_REQUEST, GST_STATIC_CAPS_ANY); -#define _do_init(bla) \ - GST_DEBUG_CATEGORY_INIT (gst_tee_debug, "tee", 0, "tee element"); - -GST_BOILERPLATE_FULL (GstTee, gst_tee, GstElement, GST_TYPE_ELEMENT, _do_init); +GST_BOILERPLATE (GstTee, gst_tee, GstElement, GST_TYPE_ELEMENT); static GstPad *gst_tee_request_new_pad (GstElement * element, GstPadTemplate * temp, const gchar * unused); @@ -77,7 +69,10 @@ static void gst_tee_set_property (GObject * object, guint prop_id, static void gst_tee_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec); -static void gst_tee_chain (GstPad * pad, GstData * _data); +static void gst_tee_chain (GstAction * action, GstRealPad * pad, + GstData * data); +static GstData *gst_tee_get (GstAction * action, GstRealPad * pad); +static GstElementStateReturn gst_tee_change_state (GstElement * element); static void @@ -85,8 +80,6 @@ gst_tee_base_init (gpointer g_class) { GstElementClass *gstelement_class = GST_ELEMENT_CLASS (g_class); - gst_element_class_add_pad_template (gstelement_class, - gst_static_pad_template_get (&sinktemplate)); gst_element_class_set_details (gstelement_class, &gst_tee_details); gst_element_class_add_pad_template (gstelement_class, gst_static_pad_template_get (&tee_src_template)); @@ -114,6 +107,9 @@ gst_tee_class_init (GstTeeClass * klass) gstelement_class = (GstElementClass *) klass; + gobject_class->get_property = GST_DEBUG_FUNCPTR (gst_tee_get_property); + gobject_class->set_property = GST_DEBUG_FUNCPTR (gst_tee_set_property); + g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_NUM_PADS, g_param_spec_int ("num_pads", "num_pads", "num_pads", 0, G_MAXINT, 0, G_PARAM_READABLE)); @@ -126,9 +122,8 @@ gst_tee_class_init (GstTeeClass * klass) gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_tee_finalize); - gobject_class->set_property = GST_DEBUG_FUNCPTR (gst_tee_set_property); - gobject_class->get_property = GST_DEBUG_FUNCPTR (gst_tee_get_property); + gstelement_class->change_state = gst_tee_change_state; gstelement_class->request_new_pad = GST_DEBUG_FUNCPTR (gst_tee_request_new_pad); } @@ -136,17 +131,16 @@ gst_tee_class_init (GstTeeClass * klass) static void gst_tee_init (GstTee * tee) { - tee->sinkpad = - gst_pad_new_from_template (gst_static_pad_template_get (&sinktemplate), - "sink"); + tee->sinkpad = gst_pad_new ("sink", GST_PAD_SINK); + gst_sink_pad_set_action_handler (tee->sinkpad, gst_tee_chain); gst_element_add_pad (GST_ELEMENT (tee), tee->sinkpad); - gst_pad_set_chain_function (tee->sinkpad, GST_DEBUG_FUNCPTR (gst_tee_chain)); gst_pad_set_link_function (tee->sinkpad, GST_DEBUG_FUNCPTR (gst_pad_proxy_pad_link)); gst_pad_set_getcaps_function (tee->sinkpad, GST_DEBUG_FUNCPTR (gst_pad_proxy_getcaps)); tee->last_message = NULL; + GST_FLAG_SET (tee, GST_ELEMENT_EVENT_AWARE); } /* helper compare function */ @@ -161,56 +155,6 @@ name_pad_compare (gconstpointer a, gconstpointer b) return strcmp (name, gst_pad_get_name (pad)); /* returns 0 if match */ } -static GstCaps * -gst_tee_getcaps (GstPad * _pad) -{ - GstTee *tee = GST_TEE (gst_pad_get_parent (_pad)); - GstCaps *caps = gst_caps_new_any (), *tmp, *res; - GstPad *pad; - const GList *pads; - - for (pads = gst_element_get_pad_list (GST_ELEMENT (tee)); - pads != NULL; pads = pads->next) { - pad = GST_PAD (pads->data); - if (pad == _pad) - continue; - - tmp = gst_pad_get_allowed_caps (pad); - res = gst_caps_intersect (caps, tmp); - gst_caps_free (tmp); - gst_caps_free (caps); - caps = res; - } - - return caps; -} - -static GstPadLinkReturn -gst_tee_link (GstPad * _pad, const GstCaps * caps) -{ - GstTee *tee = GST_TEE (gst_pad_get_parent (_pad)); - GstPadLinkReturn res; - GstPad *pad; - const GList *pads; - - GST_DEBUG_OBJECT (tee, "Forwarding link to all other pads"); - - for (pads = gst_element_get_pad_list (GST_ELEMENT (tee)); - pads != NULL; pads = pads->next) { - pad = GST_PAD (pads->data); - if (pad == _pad) - continue; - - res = gst_pad_try_set_caps (pad, caps); - GST_DEBUG_OBJECT (tee, "Pad %s:%s gave response %d", - GST_DEBUG_PAD_NAME (pad), res); - if (GST_PAD_LINK_FAILED (res)) - return res; - } - - return GST_PAD_LINK_OK; -} - static GstPad * gst_tee_request_new_pad (GstElement * element, GstPadTemplate * templ, const gchar * unused) @@ -252,8 +196,11 @@ gst_tee_request_new_pad (GstElement * element, GstPadTemplate * templ, srcpad = gst_pad_new_from_template (templ, name); g_free (name); - gst_pad_set_link_function (srcpad, GST_DEBUG_FUNCPTR (gst_tee_link)); - gst_pad_set_getcaps_function (srcpad, GST_DEBUG_FUNCPTR (gst_tee_getcaps)); + gst_src_pad_set_action_handler (srcpad, gst_tee_get); + gst_pad_set_link_function (srcpad, + GST_DEBUG_FUNCPTR (gst_pad_proxy_pad_link)); + gst_pad_set_getcaps_function (srcpad, + GST_DEBUG_FUNCPTR (gst_pad_proxy_getcaps)); gst_element_add_pad (GST_ELEMENT (tee), srcpad); GST_PAD_ELEMENT_PRIVATE (srcpad) = NULL; @@ -313,50 +260,82 @@ gst_tee_get_property (GObject * object, guint prop_id, GValue * value, } } -/** - * gst_tee_chain: - * @pad: the pad to follow - * @buf: the buffer to pass - * - * Chain a buffer on a pad. - */ -static void -gst_tee_chain (GstPad * pad, GstData * _data) +static GstData * +gst_tee_get (GstAction * action, GstRealPad * pad) +{ + GstData *data; + GstTee *tee = GST_TEE (gst_action_get_element (action)); + + g_assert (tee->current); + if (!tee->silent) { + GstData *data = tee->current; + + g_free (tee->last_message); + tee->last_message = + g_strdup_printf ("request ******* (%s:%s)t (%d bytes, %" + G_GUINT64_FORMAT ") %p", GST_DEBUG_PAD_NAME (pad), + GST_IS_BUFFER (data) ? GST_BUFFER_SIZE (data) : 0, + GST_IS_BUFFER (data) ? GST_BUFFER_TIMESTAMP (data) : + GST_CLOCK_TIME_NONE, data); + g_object_notify (G_OBJECT (tee), "last_message"); + } + data = tee->current; + gst_action_set_active (action, FALSE); + tee->missing_pads--; + if (tee->missing_pads == 0) { + gst_real_pad_set_active (GST_REAL_PAD (tee->sinkpad), TRUE); + if (GST_IS_EVENT (tee->current) && + GST_EVENT_TYPE (tee->current) == GST_EVENT_EOS) { + gst_element_set_eos (GST_ELEMENT (tee)); + } + tee->current = NULL; + } else { + gst_data_ref (tee->current); + } + return data; +} + +static void +gst_tee_chain (GstAction * action, GstRealPad * pad, GstData * data) { - GstBuffer *buf = GST_BUFFER (_data); - GstTee *tee; const GList *pads; + GstTee *tee = GST_TEE (gst_action_get_element (action)); - g_return_if_fail (pad != NULL); - g_return_if_fail (GST_IS_PAD (pad)); - g_return_if_fail (buf != NULL); - - tee = GST_TEE (gst_pad_get_parent (pad)); - - gst_buffer_ref_by_count (buf, GST_ELEMENT (tee)->numsrcpads - 1); - - pads = gst_element_get_pad_list (GST_ELEMENT (tee)); - - while (pads) { + g_assert (tee->current == NULL); + g_assert (tee->missing_pads == 0); + tee->current = data; + for (pads = gst_element_get_pad_list (GST_ELEMENT (tee)); pads; + pads = g_list_next (pads)) { GstPad *outpad = GST_PAD (pads->data); - pads = g_list_next (pads); - if (GST_PAD_DIRECTION (outpad) != GST_PAD_SRC) continue; - if (!tee->silent) { - g_free (tee->last_message); - tee->last_message = - g_strdup_printf ("chain ******* (%s:%s)t (%d bytes, %" - G_GUINT64_FORMAT ") %p", GST_DEBUG_PAD_NAME (outpad), - GST_BUFFER_SIZE (buf), GST_BUFFER_TIMESTAMP (buf), buf); - g_object_notify (G_OBJECT (tee), "last_message"); - } - - if (GST_PAD_IS_USABLE (outpad)) - gst_pad_push (outpad, GST_DATA (buf)); - else - gst_buffer_unref (buf); + gst_real_pad_set_active (GST_REAL_PAD (outpad), TRUE); + tee->missing_pads++; } + gst_real_pad_set_active (GST_REAL_PAD (tee->sinkpad), FALSE); +} + +static GstElementStateReturn +gst_tee_change_state (GstElement * element) +{ + GstTee *tee = GST_TEE (element); + + switch (GST_STATE_TRANSITION (element)) { + case GST_STATE_PAUSED_TO_READY: + if (tee->current) { + gst_data_unref (tee->current); + tee->current = NULL; + tee->missing_pads = 0; + } + break; + default: + break; + } + + if (GST_ELEMENT_CLASS (parent_class)->change_state) + return GST_ELEMENT_CLASS (parent_class)->change_state (element); + + return GST_STATE_SUCCESS; } diff --git a/gst/elements/gsttee.h b/gst/elements/gsttee.h index f28b09d9d5..547f96d012 100644 --- a/gst/elements/gsttee.h +++ b/gst/elements/gsttee.h @@ -48,6 +48,9 @@ struct _GstTee { GstPad *sinkpad; + GstData *current; /* current data peers should pull */ + gint missing_pads; /* number of pads that haven't pulled yet */ + gboolean silent; gchar *last_message; }; diff --git a/gst/elements/gsttypefindelement.c b/gst/elements/gsttypefindelement.c index 8c0c001c6f..1c766d9766 100644 --- a/gst/elements/gsttypefindelement.c +++ b/gst/elements/gsttypefindelement.c @@ -45,6 +45,7 @@ #include #include #include +#include GST_DEBUG_CATEGORY_STATIC (gst_type_find_element_debug); #define GST_CAT_DEFAULT gst_type_find_element_debug @@ -103,16 +104,17 @@ static void gst_type_find_element_set_property (GObject * object, static void gst_type_find_element_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec); -static const GstEventMask *gst_type_find_element_src_event_mask (GstPad * pad); static gboolean gst_type_find_element_src_event (GstPad * pad, GstEvent * event); static gboolean gst_type_find_handle_src_query (GstPad * pad, GstQueryType type, GstFormat * fmt, gint64 * value); -static void push_buffer_store (GstTypeFindElement * typefind); -static void gst_type_find_element_chain (GstPad * sinkpad, GstData * data); -static GstElementStateReturn -gst_type_find_element_change_state (GstElement * element); +static void gst_type_find_element_wakeup (GstAction * action, + GstElement * element, gpointer unused); +static void gst_type_find_element_chain (GstAction * action, + GstRealPad * sinkpad, GstData * data); +static GstElementStateReturn gst_type_find_element_change_state (GstElement * + element); static guint gst_type_find_element_signals[LAST_SIGNAL] = { 0 }; @@ -178,33 +180,35 @@ gst_type_find_element_class_init (GstTypeFindElementClass * typefind_class) static void gst_type_find_element_init (GstTypeFindElement * typefind) { + GST_FLAG_SET (typefind, GST_ELEMENT_EVENT_AWARE); + GST_FLAG_SET (typefind, GST_ELEMENT_PUSHING); + /* sinkpad */ typefind->sink = gst_pad_new_from_template (gst_static_pad_template_get (&type_find_element_sink_template), "sink"); - gst_pad_set_chain_function (typefind->sink, gst_type_find_element_chain); + gst_sink_pad_set_action_handler (typefind->sink, gst_type_find_element_chain); gst_element_add_pad (GST_ELEMENT (typefind), typefind->sink); /* srcpad */ typefind->src = gst_pad_new_from_template (gst_static_pad_template_get (&type_find_element_src_template), "src"); gst_pad_set_event_function (typefind->src, gst_type_find_element_src_event); - gst_pad_set_event_mask_function (typefind->src, - gst_type_find_element_src_event_mask); gst_pad_set_query_function (typefind->src, GST_DEBUG_FUNCPTR (gst_type_find_handle_src_query)); gst_pad_use_explicit_caps (typefind->src); gst_element_add_pad (GST_ELEMENT (typefind), typefind->src); + typefind->wakeup = gst_element_add_wakeup (GST_ELEMENT (typefind), FALSE, + gst_type_find_element_wakeup, NULL); typefind->caps = NULL; typefind->pending_events = NULL; typefind->min_probability = 1; typefind->max_probability = GST_TYPE_FIND_MAXIMUM; typefind->store = gst_buffer_store_new (); - - GST_FLAG_SET (typefind, GST_ELEMENT_EVENT_AWARE); } + static void gst_type_find_element_dispose (GObject * object) { @@ -294,20 +298,6 @@ gst_type_find_handle_src_query (GstPad * pad, return TRUE; } -static const GstEventMask * -gst_type_find_element_src_event_mask (GstPad * pad) -{ - static const GstEventMask mask[] = { - {GST_EVENT_SEEK, - GST_SEEK_METHOD_SET | GST_SEEK_METHOD_CUR | GST_SEEK_METHOD_END | - GST_SEEK_FLAG_FLUSH}, - /* add more if you want, event masks suck and need to die anyway */ - {0,} - }; - - return mask; -} - static gboolean gst_type_find_element_src_event (GstPad * pad, GstEvent * event) { @@ -368,6 +358,19 @@ start_typefinding (GstTypeFindElement * typefind) typefind->stream_length_available = TRUE; typefind->stream_length = 0; } + +static void +push_buffer_store (GstTypeFindElement * typefind, GstEvent * event) +{ + if (!event) + event = gst_event_new_discontinuous (TRUE, + GST_FORMAT_DEFAULT, (guint64) 0, GST_FORMAT_BYTES, (guint64) 0, + GST_FORMAT_UNDEFINED); + typefind->pending_events = g_list_append (typefind->pending_events, event); + gst_real_pad_set_active (GST_REAL_PAD (typefind->sink), FALSE); + gst_action_set_active (typefind->wakeup, TRUE); +} + static void stop_typefinding (GstTypeFindElement * typefind) { @@ -401,7 +404,7 @@ stop_typefinding (GstTypeFindElement * typefind) "could not seek to required position %u, hope for the best", size); typefind->mode = MODE_NORMAL; /* push out our queued buffers here */ - push_buffer_store (typefind); + push_buffer_store (typefind, NULL); } else { typefind->waiting_for_discont_offset = size; } @@ -409,25 +412,26 @@ stop_typefinding (GstTypeFindElement * typefind) } static void -push_buffer_store (GstTypeFindElement * typefind) +gst_type_find_element_wakeup (GstAction * action, GstElement * element, + gpointer unused) { - guint size = gst_buffer_store_get_size (typefind->store, 0); + guint size; GstBuffer *buffer; const GList *item; + GstTypeFindElement *typefind = GST_TYPE_FIND_ELEMENT (element); /* handle pending events */ - for (item = typefind->pending_events; item; item = item->next) { + if (typefind->pending_events) { GstEvent *e = item->data; + typefind->pending_events = g_list_remove (typefind->pending_events, + typefind->pending_events->data); gst_pad_push (typefind->src, GST_DATA (e)); + return; } - g_list_free (typefind->pending_events); - typefind->pending_events = NULL; /* data */ - gst_pad_push (typefind->src, GST_DATA (gst_event_new_discontinuous (TRUE, - GST_FORMAT_DEFAULT, (guint64) 0, GST_FORMAT_BYTES, (guint64) 0, - GST_FORMAT_UNDEFINED))); + size = gst_buffer_store_get_size (typefind->store, 0); if (size && (buffer = gst_buffer_store_get_buffer (typefind->store, 0, size))) { GST_DEBUG_OBJECT (typefind, "pushing cached data (%u bytes)", size); gst_pad_push (typefind->src, GST_DATA (buffer)); @@ -437,6 +441,8 @@ push_buffer_store (GstTypeFindElement * typefind) } gst_buffer_store_clear (typefind->store); + gst_action_set_active (action, FALSE); + gst_real_pad_set_active (GST_REAL_PAD (typefind->sink), TRUE); } static guint64 @@ -496,8 +502,7 @@ gst_type_find_element_handle_event (GstPad * pad, GstEvent * event) g_signal_emit (typefind, gst_type_find_element_signals[HAVE_TYPE], 0, entry->probability, entry->caps); stop_typefinding (typefind); - push_buffer_store (typefind); - gst_pad_event_default (pad, event); + push_buffer_store (typefind, event); } else { gst_pad_event_default (pad, event); GST_ELEMENT_ERROR (typefind, STREAM, TYPE_NOT_FOUND, (NULL), @@ -526,13 +531,11 @@ gst_type_find_element_handle_event (GstPad * pad, GstEvent * event) if (gst_event_discont_get_value (event, GST_FORMAT_BYTES, &off) && off == typefind->waiting_for_discont_offset) { typefind->mode = MODE_NORMAL; - push_buffer_store (typefind); + push_buffer_store (typefind, NULL); } - gst_event_unref (event); } } else if (GST_EVENT_TYPE (event) == GST_EVENT_EOS) { - push_buffer_store (typefind); - gst_pad_event_default (pad, event); + push_buffer_store (typefind, event); } else { gst_event_unref (event); } @@ -618,7 +621,8 @@ compare_type_find_factory (gconstpointer fac1, gconstpointer fac2) return GST_PLUGIN_FEATURE (fac1)->rank - GST_PLUGIN_FEATURE (fac2)->rank; } static void -gst_type_find_element_chain (GstPad * pad, GstData * data) +gst_type_find_element_chain (GstAction * action, GstRealPad * pad, + GstData * data) { GstTypeFindElement *typefind; GList *entries; @@ -626,9 +630,9 @@ gst_type_find_element_chain (GstPad * pad, GstData * data) GList *walk; GstTypeFind find = { find_peek, find_suggest, NULL, find_element_get_length }; - typefind = GST_TYPE_FIND_ELEMENT (GST_PAD_PARENT (pad)); + typefind = GST_TYPE_FIND_ELEMENT (GST_PAD_PARENT (GST_PAD (pad))); if (GST_IS_EVENT (data)) { - gst_type_find_element_handle_event (pad, GST_EVENT (data)); + gst_type_find_element_handle_event (GST_PAD (pad), GST_EVENT (data)); return; } switch (typefind->mode) { diff --git a/gst/elements/gsttypefindelement.h b/gst/elements/gsttypefindelement.h index 0b243dbd94..ce1f94aacb 100644 --- a/gst/elements/gsttypefindelement.h +++ b/gst/elements/gsttypefindelement.h @@ -48,6 +48,8 @@ struct _GstTypeFindElement { GstPad * sink; GstPad * src; + GstAction * wakeup; + guint min_probability; guint max_probability; GstCaps * caps; diff --git a/gst/gst.c b/gst/gst.c index f3db38b4b3..4bec18c77b 100644 --- a/gst/gst.c +++ b/gst/gst.c @@ -450,11 +450,8 @@ init_pre (void) { g_type_init (); - if (g_thread_supported ()) { - /* somebody already initialized threading */ - } else { + if (!g_thread_supported ()) g_thread_init (NULL); - } /* we need threading to be enabled right here */ _gst_debug_init (); @@ -526,8 +523,6 @@ gst_register_core_elements (GstPlugin * plugin) GST_TYPE_BIN) || !gst_element_register (plugin, "pipeline", GST_RANK_PRIMARY, GST_TYPE_PIPELINE) || - !gst_element_register (plugin, "thread", GST_RANK_PRIMARY, - GST_TYPE_THREAD) || !gst_element_register (plugin, "queue", GST_RANK_NONE, GST_TYPE_QUEUE)) g_assert_not_reached (); diff --git a/gst/gst.h b/gst/gst.h index b5fc84c27a..4c2627a3d8 100644 --- a/gst/gst.h +++ b/gst/gst.h @@ -31,6 +31,7 @@ #include #include +#include #include #include #include @@ -48,11 +49,11 @@ #include #include #include +#include #include #include #include #include -#include #include #include #include diff --git a/gst/gst_private.h b/gst/gst_private.h index 802d71e3e8..156336a0c6 100644 --- a/gst/gst_private.h +++ b/gst/gst_private.h @@ -36,6 +36,10 @@ extern const char *g_log_domain_gstreamer; #include #include +#include "gstaction.h" + +GstAction *gst_action_new (GstActionType type); +#define gst_action_free(action) g_free (action) /*** debugging categories *****************************************************/ diff --git a/gst/gstaction.c b/gst/gstaction.c new file mode 100644 index 0000000000..5c1ece155e --- /dev/null +++ b/gst/gstaction.c @@ -0,0 +1,404 @@ +/* GStreamer + * Copyright (C) 2004 Benjamin Otte + * + * gstaction.c: base class for main actions/loops + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include "gst_private.h" + +#include "gstaction.h" +#include "gstelement.h" +#include "gstpad.h" +#include "gstinfo.h" +#include "gstscheduler.h" + +/* +GST_DEBUG_CATEGORY_STATIC (debug, "GST_ACTION", + GST_DEBUG_BOLD | GST_DEBUG_FG_RED, "action handling"); +#define GST_CAT_DEFAULT debug +*/ +#if 1 +# define RELEASE(action) +#else +# define RELEASE(action) G_STMT_START{\ + gchar *_str; \ + \ + g_assert (action->any.active); \ + _str = gst_action_to_string (action); \ + g_print ("releasing %s\n", _str); \ + g_free (_str); \ +}G_STMT_END +#endif +GType +gst_action_get_type (void) +{ + g_assert_not_reached (); + return 0; +} + +#define GST_ACTION_SCHEDULER_CALL(action, call) G_STMT_START{ \ + GstScheduler *sched = action->any.element->sched; \ + if (sched) { \ + GstSchedulerClass *klass = GST_SCHEDULER_GET_CLASS (sched); \ + g_assert (klass->call); \ + klass->call (sched, action); \ + } \ +}G_STMT_END + +GstAction * +gst_action_new (GstActionType type) +{ + GstAction *action = g_new0 (GstAction, 1); + + action->type = type; + action->any.active = FALSE; + action->any.coupled = TRUE; + + return action; +} + +void +gst_element_add_action (GstElement * element, GstAction * action) +{ + g_return_if_fail (action->any.element == NULL); + + action->any.element = element; + element->actions = g_slist_prepend (element->actions, action); + +#ifndef GST_DISABLE_GST_DEBUG + /* FIXME: make this work with %P */ + G_STMT_START { + gchar *str = gst_action_to_string (action); + + GST_DEBUG_OBJECT (element, "adding action: %s", str); + g_free (str); + } G_STMT_END; +#endif + + GST_ACTION_SCHEDULER_CALL (action, add_action); +} + +void +gst_element_remove_action (GstAction * action) +{ + GstElement *element; + + g_return_if_fail (action->any.element != NULL); + + element = gst_action_get_element (action); + GST_ACTION_SCHEDULER_CALL (action, remove_action); + g_assert (g_slist_find (element->actions, action)); + element->actions = g_slist_remove (element->actions, action); + +#ifndef GST_DISABLE_GST_DEBUG + /* FIXME: make this work with %P */ + G_STMT_START { + gchar *str = gst_action_to_string (action); + + GST_DEBUG ("removing action: %s", str); + g_free (str); + } G_STMT_END; +#endif + + action->any.element = NULL; + /* FIXME: pads manage their actions themselves - which kinda sucks */ + if (action->type != GST_ACTION_SRC_PAD && action->type != GST_ACTION_SINK_PAD) + gst_action_free (action); +} + +GstElement * +gst_action_get_element (const GstAction * action) +{ + g_return_val_if_fail (GST_IS_ACTION (action), NULL); + + return action->any.element; +} + +void +gst_action_set_active (GstAction * action, gboolean active) +{ + g_return_if_fail (GST_IS_ACTION (action)); + + if (action->any.active == active) + return; + action->any.active = active; + GST_ACTION_SCHEDULER_CALL (action, toggle_active); +} + +gboolean +gst_action_is_active (GstAction * action) +{ + g_return_val_if_fail (GST_IS_ACTION (action), FALSE); + + return action->any.active; +} + +/** + * gst_action_set_initially_active: + * @action: ithe action to set + * @active: whether or not the action should be initially active + * + * Initially active actions are activated by default when elements reset their + * actions. This happens during the state change from READY to PAUSED for + * example. This function allows modifying that behaviour for an action. + **/ +void +gst_action_set_initially_active (GstAction * action, gboolean active) +{ + g_return_if_fail (GST_IS_ACTION (action)); + + action->any.initially_active = active; +} + +/** + * gst_action_is_initially_active: + * @action: #GstAction to check + * + * Retruns if the @action is initially active or not. + * + * Returns: TRUE if the @action is initially active, FALSE otherwise + **/ +gboolean +gst_action_is_initially_active (GstAction * action) +{ + g_return_val_if_fail (GST_IS_ACTION (action), FALSE); + + return action->any.initially_active; +} + +/** + * gst_action_set_coupled: + * @action: action to set + * @coupled: new value + * + * Makes an action coupled or not. A coupled action's activity depends on the + * state of the element it belongs to. It gets deactivated automatically when + * the element changes state to READY or below and it gets reset to its initial + * state by gst_element_reset_actions (). Activity of coupled actions must be + * set manually by the element at all times. + **/ +void +gst_action_set_coupled (GstAction * action, gboolean coupled) +{ + g_return_if_fail (GST_IS_ACTION (action)); + + if (action->any.coupled == coupled) + return; + action->any.coupled = coupled; +} + +gboolean +gst_action_is_coupled (GstAction * action) +{ + g_return_val_if_fail (GST_IS_ACTION (action), FALSE); + + return action->any.coupled; +} + +GstAction * +gst_element_add_wakeup (GstElement * element, gboolean active, + GstActionWakeupFunc release, gpointer user_data) +{ + GstAction *action; + GstActionWakeup *wakeup; + + g_return_val_if_fail (GST_IS_ELEMENT (element), NULL); + g_return_val_if_fail (release != NULL, NULL); + + action = gst_action_new (GST_ACTION_WAKEUP); + action->any.initially_active = active; + wakeup = &action->wakeup; + wakeup->release = release; + wakeup->user_data = user_data; + gst_element_add_action (element, action); + + return action; +} + +void +gst_action_wakeup_release (GstAction * action) +{ + g_return_if_fail (GST_IS_ACTION_TYPE (action, GST_ACTION_WAKEUP)); + + RELEASE (action); + action->wakeup.release (action, action->any.element, + action->wakeup.user_data); +} + +GstRealPad * +gst_action_get_pad (const GstAction * action) +{ + g_return_val_if_fail (GST_IS_ACTION (action), NULL); + g_return_val_if_fail (action->type == GST_ACTION_SINK_PAD + || action->type == GST_ACTION_SRC_PAD, NULL); + + if (action->type == GST_ACTION_SINK_PAD) { + g_assert (action->sinkpad.pad != NULL); + return action->sinkpad.pad; + } else if (action->type == GST_ACTION_SRC_PAD) { + g_assert (action->srcpad.pad != NULL); + return action->srcpad.pad; + } else { + g_assert_not_reached (); + return NULL; + } +} + +void +gst_action_release_sink_pad (GstAction * action, GstData * data) +{ + g_return_if_fail (GST_IS_ACTION_TYPE (action, GST_ACTION_SINK_PAD)); + + RELEASE (action); + action->sinkpad.release (action, action->sinkpad.pad, data); +} + +GstData * +gst_action_release_src_pad (GstAction * action) +{ + g_return_val_if_fail (GST_IS_ACTION_TYPE (action, GST_ACTION_SRC_PAD), NULL); + + RELEASE (action); + return action->srcpad.release (action, action->srcpad.pad); +} + +GstAction * +gst_real_pad_get_action (GstRealPad * pad) +{ + g_return_val_if_fail (GST_IS_REAL_PAD (pad), NULL); + + g_assert_not_reached (); + + return NULL; +} + +GstAction * +gst_element_add_wait (GstElement * element, gboolean active, + GstClockTime start_time, GstClockTime interval, GstActionWaitFunc release) +{ + GstAction *action; + GstActionWait *wait; + + g_return_val_if_fail (GST_IS_ELEMENT (element), NULL); + g_return_val_if_fail (release != NULL, NULL); + g_return_val_if_fail (GST_CLOCK_TIME_IS_VALID (start_time), NULL); + g_return_val_if_fail (GST_CLOCK_TIME_IS_VALID (interval), NULL); + + action = gst_action_new (GST_ACTION_WAIT); + action->any.initially_active = active; + wait = &action->wait; + wait->time = start_time; + wait->interval = interval; + wait->release = release; + gst_element_add_action (element, action); + + return action; +} + +void +gst_action_wait_change (GstAction * action, GstClockTime start_time, + GstClockTime interval) +{ + g_return_if_fail (GST_IS_ACTION_TYPE (action, GST_ACTION_WAIT)); + + action->wait.time = start_time; + action->wait.interval = interval; + GST_ACTION_SCHEDULER_CALL (action, update_values); +} + +void +gst_action_wait_release (GstAction * action) +{ + GstClockTime time; + + g_return_if_fail (GST_IS_ACTION_TYPE (action, GST_ACTION_WAIT)); + + RELEASE (action); + time = action->wait.time; + action->wait.time += action->wait.interval; + action->wait.release (action, action->any.element, time); +} + +GstAction * +gst_element_add_fd (GstElement * element, gboolean active, + gint fd, gushort condition, GstActionFdFunc release) +{ + GstAction *action; + GstActionFd *afd; + + g_return_val_if_fail (GST_IS_ELEMENT (element), NULL); + g_return_val_if_fail (release != NULL, NULL); + g_return_val_if_fail (condition != 0, NULL); + + action = gst_action_new (GST_ACTION_FD); + action->any.initially_active = active; + afd = &action->fd; + afd->fd = fd; + afd->condition = condition; + gst_element_add_action (element, action); + + return action; +} + +void +gst_action_fd_release (GstAction * action, GIOCondition condition) +{ + g_return_if_fail (GST_IS_ACTION_TYPE (action, GST_ACTION_FD)); + + RELEASE (action); + action->fd.release (action, action->any.element, action->fd.fd, condition); +} + +void +gst_action_fd_change (GstAction * action, gint fd, gushort condition) +{ + g_return_if_fail (GST_IS_ACTION_TYPE (action, GST_ACTION_FD)); + + action->fd.fd = fd; + action->fd.condition = condition; + GST_ACTION_SCHEDULER_CALL (action, update_values); +} + +static const gchar * +gst_action_type_to_string (GstActionType type) +{ + switch (type) { + case GST_ACTION_WAKEUP: + return "WAKEUP"; + case GST_ACTION_SINK_PAD: + return "SINKPAD"; + case GST_ACTION_SRC_PAD: + return "SRCPAD"; + case GST_ACTION_FD: + return "FD"; + case GST_ACTION_WAIT: + return "TIME"; + default: + g_return_val_if_reached (NULL); + } +} + +gchar * +gst_action_to_string (const GstAction * action) +{ + g_return_val_if_fail (GST_IS_ACTION (action), NULL); + + return g_strdup_printf ("%s for %s", + gst_action_type_to_string (action->type), + GST_ELEMENT_NAME (gst_action_get_element (action))); +} diff --git a/gst/gstaction.h b/gst/gstaction.h new file mode 100644 index 0000000000..21ea523e55 --- /dev/null +++ b/gst/gstaction.h @@ -0,0 +1,182 @@ +/* GStreamer + * Copyright (C) 2004-2005 Benjamin Otte + * + * gstaction.h: base class for main actions/loops + * + * 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_ACTION_H__ +#define __GST_ACTION_H__ + +#include +#include +#include + +G_BEGIN_DECLS + + +#define GST_TYPE_ACTION (gst_action_get_type ()) +#define GST_IS_ACTION(action) ((action) != NULL && \ + (action)->type > GST_ACTION_INVALID && \ + (action)->type < GST_ACTION_TYPE_COUNT) +#define GST_IS_ACTION_TYPE(action, _type) ((action) != NULL && \ + (action)->type == _type) + +typedef enum { + GST_ACTION_INVALID = 0, + GST_ACTION_WAKEUP, + GST_ACTION_SINK_PAD, + GST_ACTION_SRC_PAD, + GST_ACTION_FD, + GST_ACTION_WAIT, + /* add more */ + GST_ACTION_TYPE_COUNT +} GstActionType; + +typedef struct _GstActionAny GstActionAny; +typedef struct _GstActionWakeup GstActionWakeup; +typedef struct _GstActionSinkPad GstActionSinkPad; +typedef struct _GstActionSrcPad GstActionSrcPad; +typedef struct _GstActionFd GstActionFd; +typedef struct _GstActionWait GstActionWait; + +typedef void (* GstActionWakeupFunc) (GstAction * action, + GstElement * element, + gpointer user_data); +typedef GstData * (* GstActionSrcPadFunc) (GstAction * action, + GstRealPad * pad); +typedef void (* GstActionSinkPadFunc) (GstAction * action, + GstRealPad * pad, + GstData * data); +typedef void (* GstActionFdFunc) (GstAction * action, + GstElement * element, + gint fd, + GIOCondition condition); +typedef void (* GstActionWaitFunc) (GstAction * action, + GstElement * element, + GstClockTime time); + +#define GST_ACTION_HEAD \ + GstActionType type; \ + guint active : 1; \ + guint initially_active : 1; \ + guint coupled : 1; \ + guint padding : 13; \ + GstElement * element; +struct _GstActionAny { + GST_ACTION_HEAD +}; + +struct _GstActionWakeup { + GST_ACTION_HEAD + GstActionWakeupFunc release; + gpointer user_data; +}; + +struct _GstActionSrcPad { + GST_ACTION_HEAD + GstRealPad * pad; + GstActionSrcPadFunc release; +}; + +struct _GstActionSinkPad { + GST_ACTION_HEAD + GstRealPad * pad; + GstActionSinkPadFunc release; +}; + +struct _GstActionFd { + GST_ACTION_HEAD + int fd; + gushort condition; + GstActionFdFunc release; +}; + +struct _GstActionWait { + GST_ACTION_HEAD + GstClockTime time; + GstClockTime interval; + GstActionWaitFunc release; +}; + +/* FIXME: padding? */ +union _GstAction { + GstActionType type; + GstActionAny any; + GstActionWakeup wakeup; + GstActionSinkPad sinkpad; + GstActionSrcPad srcpad; + GstActionFd fd; + GstActionWait wait; +}; + +GType gst_action_get_type (void); + +GstElement * gst_action_get_element (const GstAction * action); +void gst_action_set_active (GstAction * action, + gboolean active); +gboolean gst_action_is_active (GstAction * action); +void gst_action_set_initially_active (GstAction * action, + gboolean active); +gboolean gst_action_is_initially_active (GstAction * action); +void gst_action_set_coupled (GstAction * action, + gboolean coupled); +gboolean gst_action_is_coupled (GstAction * action); +void gst_element_add_action (GstElement * element, + GstAction * action); +void gst_element_remove_action (GstAction * action); + +GstAction * gst_element_add_wakeup (GstElement * element, + gboolean active, + GstActionWakeupFunc release, + gpointer user_data); +void gst_action_wakeup_release (GstAction * action); + +GstRealPad * gst_action_get_pad (const GstAction * action); +void gst_action_release_sink_pad (GstAction * action, + GstData * data); +GstData * gst_action_release_src_pad (GstAction * action); +GstAction * gst_real_pad_get_action (GstRealPad * pad); + +GstAction * gst_element_add_wait (GstElement * element, + gboolean active, + GstClockTime start_time, + GstClockTime interval, + GstActionWaitFunc release); +void gst_action_wait_change (GstAction * action, + /* FIXME: better name? */ GstClockTime start_time, + GstClockTime interval); +void gst_action_wait_release (GstAction * action); + +GstAction * gst_element_add_fd (GstElement * element, + gboolean active, + gint fd, + gushort condition, + GstActionFdFunc release); +void gst_action_fd_release (GstAction * action, + GIOCondition condition); +void gst_action_fd_change (GstAction * action, + gint fd, + gushort condition); + +gchar * gst_action_to_string (const GstAction * action); + + +G_END_DECLS + +#endif /* __GST_ACTION_H__ */ diff --git a/gst/gstbin.c b/gst/gstbin.c index 6eadac7ad3..5412bc0106 100644 --- a/gst/gstbin.c +++ b/gst/gstbin.c @@ -51,9 +51,6 @@ static GstElementDetails gst_bin_details = GST_ELEMENT_DETAILS ("Generic bin", GType _gst_bin_type = 0; -static gboolean _gst_boolean_did_something_accumulator (GSignalInvocationHint * - ihint, GValue * return_accu, const GValue * handler_return, gpointer dummy); - static void gst_bin_dispose (GObject * object); static GstElementStateReturn gst_bin_change_state (GstElement * element); @@ -73,8 +70,6 @@ GstElementStateReturn gst_bin_set_state (GstElement * element, static GstClock *gst_bin_get_clock_func (GstElement * element); static void gst_bin_set_clock_func (GstElement * element, GstClock * clock); -static gboolean gst_bin_iterate_func (GstBin * bin); - #ifndef GST_DISABLE_LOADSAVE static xmlNodePtr gst_bin_save_thyself (GstObject * object, xmlNodePtr parent); static void gst_bin_restore_thyself (GstObject * object, xmlNodePtr self); @@ -172,11 +167,6 @@ gst_bin_class_init (GstBinClass * klass) g_signal_new ("element-removed", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET (GstBinClass, element_removed), NULL, NULL, gst_marshal_VOID__OBJECT, G_TYPE_NONE, 1, GST_TYPE_ELEMENT); - gst_bin_signals[ITERATE] = - g_signal_new ("iterate", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, - G_STRUCT_OFFSET (GstBinClass, iterate), - _gst_boolean_did_something_accumulator, NULL, gst_marshal_BOOLEAN__VOID, - G_TYPE_BOOLEAN, 0); gobject_class->dispose = GST_DEBUG_FUNCPTR (gst_bin_dispose); @@ -196,22 +186,6 @@ gst_bin_class_init (GstBinClass * klass) klass->remove_element = GST_DEBUG_FUNCPTR (gst_bin_remove_func); klass->child_state_change = GST_DEBUG_FUNCPTR (gst_bin_child_state_change_func); - klass->iterate = GST_DEBUG_FUNCPTR (gst_bin_iterate_func); -} - -static gboolean -_gst_boolean_did_something_accumulator (GSignalInvocationHint * ihint, - GValue * return_accu, const GValue * handler_return, gpointer dummy) -{ - gboolean did_something; - - did_something = g_value_get_boolean (handler_return); - if (did_something) { - g_value_set_boolean (return_accu, TRUE); - } - - /* always continue emission */ - return TRUE; } static void @@ -347,8 +321,6 @@ gst_bin_set_element_sched (GstElement * element, GstScheduler * sched) if (GST_FLAG_IS_SET (element, GST_BIN_FLAG_MANAGER)) { GST_CAT_DEBUG_OBJECT (GST_CAT_PARENTAGE, element, "child is already a manager, not resetting sched"); - if (GST_ELEMENT_SCHED (element)) - gst_scheduler_add_scheduler (sched, GST_ELEMENT_SCHED (element)); return; } @@ -365,30 +337,28 @@ gst_bin_set_element_sched (GstElement * element, GstScheduler * sched) gst_scheduler_add_element (sched, element); - if (!GST_FLAG_IS_SET (element, GST_ELEMENT_DECOUPLED)) { - /* set the sched pointer in all the pads */ - pads = element->pads; - while (pads) { - GstPad *pad; + /* set the sched pointer in all the pads */ + pads = element->pads; + while (pads) { + GstPad *pad; - pad = GST_PAD (pads->data); - pads = g_list_next (pads); + pad = GST_PAD (pads->data); + pads = g_list_next (pads); - /* we only operate on real pads */ - if (!GST_IS_REAL_PAD (pad)) - continue; + /* we only operate on real pads */ + if (!GST_IS_REAL_PAD (pad)) + continue; - /* if the peer element exists and is a candidate */ - if (GST_PAD_PEER (pad)) { - if (gst_pad_get_scheduler (GST_PAD_PEER (pad)) == sched) { - GST_CAT_LOG (GST_CAT_SCHEDULING, - "peer is in same scheduler, telling scheduler"); + /* if the peer element exists and is a candidate */ + if (GST_PAD_PEER (pad)) { + if (gst_pad_get_scheduler (GST_PAD_PEER (pad)) == sched) { + GST_CAT_LOG (GST_CAT_SCHEDULING, + "peer is in same scheduler, telling scheduler"); - if (GST_PAD_IS_SRC (pad)) - gst_scheduler_pad_link (sched, pad, GST_PAD_PEER (pad)); - else - gst_scheduler_pad_link (sched, GST_PAD_PEER (pad), pad); - } + if (GST_PAD_IS_SRC (pad)) + gst_scheduler_pad_link (sched, pad, GST_PAD_PEER (pad)); + else + gst_scheduler_pad_link (sched, GST_PAD_PEER (pad), pad); } } } @@ -414,9 +384,6 @@ gst_bin_unset_element_sched (GstElement * element, GstScheduler * sched) if (GST_FLAG_IS_SET (element, GST_BIN_FLAG_MANAGER)) { GST_CAT_DEBUG_OBJECT (GST_CAT_PARENTAGE, element, "child is already a manager, not unsetting sched"); - if (sched) { - gst_scheduler_remove_scheduler (sched, GST_ELEMENT_SCHED (element)); - } return; } /* for each child, remove them from their schedule */ @@ -428,30 +395,28 @@ gst_bin_unset_element_sched (GstElement * element, GstScheduler * sched) /* otherwise, if it's just a regular old element */ GList *pads; - if (!GST_FLAG_IS_SET (element, GST_ELEMENT_DECOUPLED)) { - /* unset the sched pointer in all the pads */ - pads = element->pads; - while (pads) { - GstPad *pad; + /* unset the sched pointer in all the pads */ + pads = element->pads; + while (pads) { + GstPad *pad; - pad = GST_PAD (pads->data); - pads = g_list_next (pads); + pad = GST_PAD (pads->data); + pads = g_list_next (pads); - /* we only operate on real pads */ - if (!GST_IS_REAL_PAD (pad)) - continue; + /* we only operate on real pads */ + if (!GST_IS_REAL_PAD (pad)) + continue; - /* if the peer element exists and is a candidate */ - if (GST_PAD_PEER (pad)) { - if (gst_pad_get_scheduler (GST_PAD_PEER (pad)) == sched) { - GST_CAT_LOG (GST_CAT_SCHEDULING, - "peer is in same scheduler, telling scheduler"); + /* if the peer element exists and is a candidate */ + if (GST_PAD_PEER (pad)) { + if (gst_pad_get_scheduler (GST_PAD_PEER (pad)) == sched) { + GST_CAT_LOG (GST_CAT_SCHEDULING, + "peer is in same scheduler, telling scheduler"); - if (GST_PAD_IS_SRC (pad)) - gst_scheduler_pad_unlink (sched, pad, GST_PAD_PEER (pad)); - else - gst_scheduler_pad_unlink (sched, GST_PAD_PEER (pad), pad); - } + if (GST_PAD_IS_SRC (pad)) + gst_scheduler_pad_unlink (sched, pad, GST_PAD_PEER (pad)); + else + gst_scheduler_pad_unlink (sched, GST_PAD_PEER (pad), pad); } } } @@ -1265,84 +1230,24 @@ gst_bin_restore_thyself (GstObject * object, xmlNodePtr self) } #endif /* GST_DISABLE_LOADSAVE */ -static GStaticRecMutex iterate_lock = G_STATIC_REC_MUTEX_INIT; - -static gboolean -gst_bin_iterate_func (GstBin * bin) -{ - GstScheduler *sched = GST_ELEMENT_SCHED (bin); - - g_static_rec_mutex_unlock (&iterate_lock); - - /* only iterate if this is the manager bin */ - if (sched && sched->parent == GST_ELEMENT (bin)) { - GstSchedulerState state; - - state = gst_scheduler_iterate (sched); - - if (state == GST_SCHEDULER_STATE_RUNNING) { - goto done; - } else if (state == GST_SCHEDULER_STATE_ERROR) { - gst_element_set_state (GST_ELEMENT (bin), GST_STATE_PAUSED); - } else if (state == GST_SCHEDULER_STATE_STOPPED) { - /* check if we have children scheds that are still running */ - /* FIXME: remove in 0.9? autouseless because iterations gone? */ - GList *walk; - - for (walk = sched->schedulers; walk; walk = g_list_next (walk)) { - GstScheduler *test = walk->data; - - g_return_val_if_fail (test->parent, FALSE); - if (GST_STATE (test->parent) == GST_STATE_PLAYING) { - GST_CAT_DEBUG_OBJECT (GST_CAT_SCHEDULING, bin, - "current bin is not iterating, but children are, " - "so returning TRUE anyway..."); - g_usleep (1); - goto done; - } - } - } - } else { - g_warning ("bin \"%s\" is not the managing bin, can't be iterated on!\n", - GST_ELEMENT_NAME (bin)); - } - - g_static_rec_mutex_lock (&iterate_lock); - - return FALSE; - -done: - g_static_rec_mutex_lock (&iterate_lock); - return TRUE; -} - -/** - * gst_bin_iterate: - * @bin: a#GstBin to iterate. - * - * Iterates over the elements in this bin. - * - * Returns: TRUE if the bin did something useful. This value - * can be used to determine it the bin is in EOS. - */ gboolean gst_bin_iterate (GstBin * bin) { - gboolean running; + gulong eos, error; + GMainLoop *loop; - g_return_val_if_fail (bin != NULL, FALSE); g_return_val_if_fail (GST_IS_BIN (bin), FALSE); - GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, bin, "starting iteration"); - gst_object_ref (GST_OBJECT (bin)); - - g_static_rec_mutex_lock (&iterate_lock); - running = FALSE; - g_signal_emit (G_OBJECT (bin), gst_bin_signals[ITERATE], 0, &running); - g_static_rec_mutex_unlock (&iterate_lock); - - gst_object_unref (GST_OBJECT (bin)); - GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, bin, "finished iteration"); - - return running; + loop = g_main_loop_new (NULL, FALSE); + eos = + g_signal_connect_swapped (bin, "error", G_CALLBACK (g_main_loop_quit), + loop); + error = + g_signal_connect_swapped (bin, "eos", G_CALLBACK (g_main_loop_quit), + loop); + g_main_loop_run (loop); + g_main_loop_unref (loop); + g_signal_handler_disconnect (bin, eos); + g_signal_handler_disconnect (bin, error); + return FALSE; } diff --git a/gst/gstbin.h b/gst/gstbin.h index a7333e66e0..15927820ce 100644 --- a/gst/gstbin.h +++ b/gst/gstbin.h @@ -41,7 +41,6 @@ GST_EXPORT GType _gst_bin_type; * GstBinFlags: * @GST_BIN_FLAG_MANAGER: this bin is a manager of child elements, i.e. * a pipeline or thread. - * @GST_BIN_SELF_SCHEDULABLE: the bin iterates itself. * @GST_BIN_FLAG_PREFER_COTHREADS: we prefer to have cothreads when its * an option, over chain-based. * @GST_BIN_FLAG_FIXED_CLOCK: bin has one clock that cannot be changed. @@ -59,7 +58,6 @@ GST_EXPORT GType _gst_bin_type; */ typedef enum { GST_BIN_FLAG_MANAGER = GST_ELEMENT_FLAG_LAST, - GST_BIN_SELF_SCHEDULABLE, GST_BIN_FLAG_PREFER_COTHREADS, GST_BIN_FLAG_FIXED_CLOCK, GST_BIN_STATE_LOCKED, @@ -90,9 +88,6 @@ struct _GstBinClass { void (*child_state_change) (GstBin *bin, GstElementState oldstate, GstElementState newstate, GstElement *element); - /* run a full iteration of operation */ - gboolean (*iterate) (GstBin *bin); - /* signals */ void (*element_added) (GstBin *bin, GstElement *child); void (*element_removed) (GstBin *bin, GstElement *child); @@ -117,8 +112,6 @@ G_CONST_RETURN GList* GstElement* gst_bin_get_by_interface (GstBin *bin, GType interface); GList * gst_bin_get_all_by_interface (GstBin *bin, GType interface); -gboolean gst_bin_iterate (GstBin *bin); - void gst_bin_use_clock (GstBin *bin, GstClock *clock); GstClock* gst_bin_get_clock (GstBin *bin); void gst_bin_auto_clock (GstBin *bin); diff --git a/gst/gstclock.c b/gst/gstclock.c index 599afcb664..aa3f946335 100644 --- a/gst/gstclock.c +++ b/gst/gstclock.c @@ -362,9 +362,6 @@ gst_clock_class_init (GstClockClass * klass) parent_class = g_type_class_ref (GST_TYPE_OBJECT); - if (!g_thread_supported ()) - g_thread_init (NULL); - #ifndef GST_DISABLE_TRACE _gst_clock_entry_trace = gst_alloc_trace_register (GST_CLOCK_ENTRY_TRACE_NAME); diff --git a/gst/gstclock.h b/gst/gstclock.h index dabb624bd7..b8de0c307f 100644 --- a/gst/gstclock.h +++ b/gst/gstclock.h @@ -35,8 +35,6 @@ G_BEGIN_DECLS #define GST_IS_CLOCK_CLASS(cclass) (G_TYPE_CHECK_CLASS_TYPE ((cclass), GST_TYPE_CLOCK)) #define GST_CLOCK_GET_CLASS(clock) (G_TYPE_INSTANCE_GET_CLASS ((clock), GST_TYPE_CLOCK, GstClockClass)) -typedef guint64 GstClockTime; -typedef gint64 GstClockTimeDiff; typedef gpointer GstClockID; #define GST_CLOCK_TIME_NONE ((GstClockTime)-1) diff --git a/gst/gstcompat.h b/gst/gstcompat.h index dd47c17a51..d61f023b21 100644 --- a/gst/gstcompat.h +++ b/gst/gstcompat.h @@ -27,60 +27,13 @@ G_BEGIN_DECLS -#ifndef GST_DISABLE_DEPRECATED -/* 0.5.2 changes; remove these ASAP */ +//#ifndef GST_DISABLE_DEPRECATED -/* element functions */ -#define gst_element_connect(a,b) gst_element_link(a,b) -#define gst_element_connect_pads(a,b,c,d) \ - gst_element_link_pads(a,b,c,d) -#ifdef G_HAVE_ISO_VARARGS -#define gst_element_connect_many(a,...) gst_element_link_many(a,__VA_ARGS__) -#elif defined(G_HAVE_GNUC_VARARGS) -#define gst_element_connect_many(a,args...) \ - gst_element_link_many(a, ## args) -#else -/* FIXME: need an inline function */ -#endif -#define gst_element_connect_filtered(a,b,c) \ - gst_element_link_filtered(a,b,c) -#define gst_element_disconnect(a,b) gst_element_unlink(a,b) -/* pad functions */ -#define gst_pad_connect(a,b) gst_pad_link(a,b) -#define gst_pad_connect_filtered(a,b,c) gst_pad_link_filtered(a,b,c) -#define gst_pad_disconnect(a,b) gst_pad_unlink(a,b) -#define gst_pad_proxy_connect(a,b) gst_pad_proxy_link(a,b) -#define gst_pad_set_connect_function(a,b) \ - gst_pad_set_link_function(a,b) +gboolean gst_bin_iterate (GstBin *bin); -/* pad macros */ -#define GST_PAD_IS_CONNECTED(a) GST_PAD_IS_LINKED(a) -/* pad enums */ -#define GST_PAD_CONNECT_REFUSED GST_PAD_LINK_REFUSED -#define GST_PAD_CONNECT_DELAYED GST_PAD_LINK_DELAYED -#define GST_PAD_CONNECT_OK GST_PAD_LINK_OK -#define GST_PAD_CONNECT_DONE GST_PAD_LINK_DONE -typedef GstPadLinkReturn GstPadConnectReturn; - -/* pad function types */ -typedef GstPadLinkFunction GstPadConnectFunction; - -/* probably not used */ -/* - * GST_RPAD_LINKFUNC - */ - -/* 0.8.1.1 removal; remove completely in 0.9 */ -/* information messages */ -# ifdef G_HAVE_ISO_VARARGS -#define gst_info(...) GST_INFO(__VA_ARGS__) -# elif defined(G_HAVE_GNUC_VARARGS) -#define gst_info(format,args...) GST_INFO(format,##args) -# endif - -#endif /* not GST_DISABLE_DEPRECATED */ +//#endif /* not GST_DISABLE_DEPRECATED */ G_END_DECLS diff --git a/gst/gstelement.c b/gst/gstelement.c index 61cf789ff5..c87a7c415d 100644 --- a/gst/gstelement.c +++ b/gst/gstelement.c @@ -26,6 +26,7 @@ #include #include "gstelement.h" +#include "gstaction.h" #include "gstbin.h" #include "gstmarshal.h" #include "gsterror.h" @@ -263,7 +264,6 @@ gst_element_init (GstElement * element) element->numsrcpads = 0; element->numsinkpads = 0; element->pads = NULL; - element->loopfunc = NULL; element->sched = NULL; element->clock = NULL; element->sched_private = NULL; @@ -834,37 +834,6 @@ gst_element_get_clock (GstElement * element) return NULL; } -/** - * gst_element_clock_wait: - * @element: a #GstElement. - * @id: the #GstClock to use. - * @jitter: the difference between requested time and actual time. - * - * Waits for a specific time on the clock. - * - * Returns: the #GstClockReturn result of the wait operation. - */ -GstClockReturn -gst_element_clock_wait (GstElement * element, GstClockID id, - GstClockTimeDiff * jitter) -{ - GstClockReturn res; - - g_return_val_if_fail (GST_IS_ELEMENT (element), GST_CLOCK_ERROR); - - if (GST_ELEMENT_SCHED (element)) { - GST_CAT_DEBUG (GST_CAT_CLOCK, "waiting on scheduler clock with id %d"); - res = - gst_scheduler_clock_wait (GST_ELEMENT_SCHED (element), element, id, - jitter); - } else { - GST_CAT_DEBUG (GST_CAT_CLOCK, "no scheduler, returning GST_CLOCK_TIMEOUT"); - res = GST_CLOCK_TIMEOUT; - } - - return res; -} - #undef GST_CAT_DEFAULT #define GST_CAT_DEFAULT GST_CAT_CLOCK /** @@ -907,51 +876,6 @@ gst_element_get_time (GstElement * element) } } -/** - * gst_element_wait: - * @element: element that should wait - * @timestamp: what timestamp to wait on - * - * Waits until the given relative time stamp for the element has arrived. - * When this function returns successfully, the relative time point specified - * in the timestamp has passed for this element. - * This function can only be called on elements in - * #GST_STATE_PLAYING - * - * Returns: TRUE on success. - */ -gboolean -gst_element_wait (GstElement * element, GstClockTime timestamp) -{ - GstClockID id; - GstClockReturn ret; - GstClockTime time; - - g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE); - g_return_val_if_fail (GST_IS_CLOCK (element->clock), FALSE); - g_return_val_if_fail (element->current_state == GST_STATE_PLAYING, FALSE); - g_return_val_if_fail (GST_CLOCK_TIME_IS_VALID (timestamp), FALSE); - - /* shortcut when we're already late... */ - time = gst_element_get_time (element); - GST_CAT_LOG_OBJECT (GST_CAT_CLOCK, element, "element time %" GST_TIME_FORMAT, - GST_TIME_ARGS (time)); - if (time >= timestamp) { - GST_CAT_INFO_OBJECT (GST_CAT_CLOCK, element, - "called gst_element_wait (%" GST_TIME_FORMAT ") and was late (%" - GST_TIME_FORMAT, GST_TIME_ARGS (timestamp), - GST_TIME_ARGS (gst_element_get_time (element))); - return TRUE; - } - - id = gst_clock_new_single_shot_id (element->clock, - element->base_time + timestamp); - ret = gst_element_clock_wait (element, id, NULL); - gst_clock_id_free (id); - - return ret == GST_CLOCK_STOPPED; -} - /** * gst_element_set_time: * @element: element to set time on @@ -1171,6 +1095,16 @@ gst_element_add_pad (GstElement * element, GstPad * pad) g_return_if_fail (gst_object_check_uniqueness (element->pads, GST_PAD_NAME (pad)) == TRUE); + if (GST_IS_REAL_PAD (pad)) { + /* append the pad's action to the element */ + if (GST_ELEMENT_IS_PUSHING (element) && GST_PAD_IS_SRC (pad)) { + g_return_if_fail (GST_REAL_PAD (pad)->action == NULL); + } else { + g_return_if_fail (GST_REAL_PAD (pad)->action != NULL); + gst_element_add_action (element, GST_REAL_PAD (pad)->action); + } + } + GST_CAT_INFO_OBJECT (GST_CAT_ELEMENT_PADS, element, "adding pad '%s'", GST_STR_NULL (GST_OBJECT_NAME (pad))); @@ -1193,10 +1127,6 @@ gst_element_add_pad (GstElement * element, GstPad * pad) break; } - /* activate element when we are playing */ - if (GST_STATE (element) == GST_STATE_PLAYING) - gst_pad_set_active (pad, TRUE); - /* emit the NEW_PAD signal */ g_signal_emit (G_OBJECT (element), gst_element_signals[NEW_PAD], 0, pad); } @@ -1257,6 +1187,9 @@ gst_element_remove_pad (GstElement * element, GstPad * pad) gst_pad_unlink (pad, GST_PAD (GST_RPAD_PEER (pad))); } gst_caps_replace (&GST_RPAD_EXPLICIT_CAPS (pad), NULL); + + if (GST_REAL_PAD (pad)->action) + gst_element_remove_action (GST_REAL_PAD (pad)->action); } else if (GST_IS_GHOST_PAD (pad)) { g_object_set (pad, "real-pad", NULL, NULL); } @@ -2297,37 +2230,6 @@ gst_element_get_random_pad (GstElement * element, GstPadDirection dir) return NULL; } -/** - * gst_element_get_event_masks: - * @element: a #GstElement to query - * - * Get an array of event masks from the element. - * If the element doesn't implement an event masks function, - * the query will be forwarded to a random linked sink pad. - * - * Returns: An array of #GstEventMask elements. - */ -const GstEventMask * -gst_element_get_event_masks (GstElement * element) -{ - GstElementClass *oclass; - - g_return_val_if_fail (GST_IS_ELEMENT (element), NULL); - - oclass = GST_ELEMENT_GET_CLASS (element); - - if (oclass->get_event_masks) - return oclass->get_event_masks (element); - else { - GstPad *pad = gst_element_get_random_pad (element, GST_PAD_SINK); - - if (pad) - return gst_pad_get_event_masks (GST_PAD_PEER (pad)); - } - - return NULL; -} - /** * gst_element_send_event: * @element: a #GstElement to send the event to. @@ -2383,37 +2285,6 @@ gst_element_seek (GstElement * element, GstSeekType seek_type, guint64 offset) return gst_element_send_event (element, event); } -/** - * gst_element_get_query_types: - * @element: a #GstElement to query - * - * Get an array of query types from the element. - * If the element doesn't implement a query types function, - * the query will be forwarded to a random sink pad. - * - * Returns: An array of #GstQueryType elements. - */ -const GstQueryType * -gst_element_get_query_types (GstElement * element) -{ - GstElementClass *oclass; - - g_return_val_if_fail (GST_IS_ELEMENT (element), NULL); - - oclass = GST_ELEMENT_GET_CLASS (element); - - if (oclass->get_query_types) - return oclass->get_query_types (element); - else { - GstPad *pad = gst_element_get_random_pad (element, GST_PAD_SINK); - - if (pad) - return gst_pad_get_query_types (GST_PAD_PEER (pad)); - } - - return NULL; -} - /** * gst_element_query: * @element: a #GstElement to perform the query on. @@ -2456,37 +2327,6 @@ gst_element_query (GstElement * element, GstQueryType type, return FALSE; } -/** - * gst_element_get_formats: - * @element: a #GstElement to query - * - * Get an array of formats from the element. - * If the element doesn't implement a formats function, - * the query will be forwarded to a random sink pad. - * - * Returns: An array of #GstFormat elements. - */ -const GstFormat * -gst_element_get_formats (GstElement * element) -{ - GstElementClass *oclass; - - g_return_val_if_fail (GST_IS_ELEMENT (element), NULL); - - oclass = GST_ELEMENT_GET_CLASS (element); - - if (oclass->get_formats) - return oclass->get_formats (element); - else { - GstPad *pad = gst_element_get_random_pad (element, GST_PAD_SINK); - - if (pad) - return gst_pad_get_formats (GST_PAD_PEER (pad)); - } - - return NULL; -} - /** * gst_element_convert: * @element: a #GstElement to invoke the converter on. @@ -2934,20 +2774,18 @@ gst_element_clear_pad_caps (GstElement * element) } } -static void -gst_element_pads_activate (GstElement * element, gboolean active) +void +gst_element_reset_actions (GstElement * element) { - GList *pads = element->pads; + GSList *walk; + GstAction *action; - while (pads) { - GstPad *pad = GST_PAD (pads->data); - - pads = g_list_next (pads); - - if (!GST_IS_REAL_PAD (pad)) - continue; - - gst_pad_set_active (pad, active); + for (walk = element->actions; walk; walk = g_slist_next (walk)) { + action = walk->data; + if (gst_action_is_coupled (action)) { + //g_print ("resetting %s to %s\n", gst_action_to_string (action), action->any.initially_active ? "TRUE" : "FALSE"); + gst_action_set_active (action, action->any.initially_active); + } } } @@ -2957,6 +2795,7 @@ gst_element_change_state (GstElement * element) GstElementState old_state, old_pending; GstObject *parent; gint old_transition; + GSList *walk; g_return_val_if_fail (GST_IS_ELEMENT (element), GST_STATE_FAILURE); @@ -2995,10 +2834,8 @@ gst_element_change_state (GstElement * element) GST_CAT_LOG_OBJECT (GST_CAT_CLOCK, element, "setting base time to %" G_GINT64_FORMAT, element->base_time); } - gst_element_pads_activate (element, FALSE); break; case GST_STATE_PAUSED_TO_PLAYING: - gst_element_pads_activate (element, TRUE); if (element->clock) { GstClockTime time = gst_clock_get_event_time (element->clock); @@ -3015,12 +2852,19 @@ gst_element_change_state (GstElement * element) "failed state change, could not negotiate pads"); goto failure; } + gst_element_reset_actions (element); break; /* going to the READY state clears all pad caps */ /* FIXME: Why doesn't this happen on READY => NULL? -- Company */ case GST_STATE_PAUSED_TO_READY: element->base_time = 0; gst_element_clear_pad_caps (element); + for (walk = element->actions; walk; walk = g_slist_next (walk)) { + GstAction *action = walk->data; + + if (gst_action_is_coupled (action)) + gst_action_set_active (action, FALSE); + } break; case GST_STATE_NULL_TO_READY: case GST_STATE_READY_TO_NULL: @@ -3269,40 +3113,6 @@ gst_element_restore_thyself (GstObject * object, xmlNodePtr self) } #endif /* GST_DISABLE_LOADSAVE */ -/** - * gst_element_yield: - * @element: a #GstElement to yield. - * - * Requests a yield operation for the element. The scheduler will typically - * give control to another element. - */ -void -gst_element_yield (GstElement * element) -{ - if (GST_ELEMENT_SCHED (element)) { - gst_scheduler_yield (GST_ELEMENT_SCHED (element), element); - } -} - -/** - * gst_element_interrupt: - * @element: a #GstElement to interrupt. - * - * Requests the scheduler of this element to interrupt the execution of - * this element and scheduler another one. - * - * Returns: TRUE if the element should exit its chain/loop/get - * function ASAP, depending on the scheduler implementation. - */ -gboolean -gst_element_interrupt (GstElement * element) -{ - if (GST_ELEMENT_SCHED (element)) { - return gst_scheduler_interrupt (GST_ELEMENT_SCHED (element), element); - } else - return TRUE; -} - /** * gst_element_set_scheduler: * @element: a #GstElement to set the scheduler of. @@ -3339,46 +3149,6 @@ gst_element_get_scheduler (GstElement * element) return GST_ELEMENT_SCHED (element); } -/** - * gst_element_set_loop_function: - * @element: a #GstElement to set the loop function of. - * @loop: Pointer to #GstElementLoopFunction. - * - * This sets the loop function for the element. The function pointed to - * can deviate from the GstElementLoopFunction definition in type of - * pointer only. - * - * NOTE: in order for this to take effect, the current loop function *must* - * exit. Assuming the loop function itself is the only one who will cause - * a new loopfunc to be assigned, this should be no problem. - */ -void -gst_element_set_loop_function (GstElement * element, - GstElementLoopFunction loop) -{ - gboolean need_notify = FALSE; - - g_return_if_fail (GST_IS_ELEMENT (element)); - - /* if the element changed from loop based to chain/get based - * or vice versa, we need to inform the scheduler about that */ - if ((element->loopfunc == NULL && loop != NULL) || - (element->loopfunc != NULL && loop == NULL)) { - need_notify = TRUE; - } - - /* set the loop function */ - element->loopfunc = loop; - - if (need_notify) { - /* set the NEW_LOOPFUNC flag so everyone knows to go try again */ - GST_FLAG_SET (element, GST_ELEMENT_NEW_LOOPFUNC); - - if (GST_ELEMENT_SCHED (element)) { - gst_scheduler_scheduling_change (GST_ELEMENT_SCHED (element), element); - } - } -} static inline void gst_element_emit_found_tag (GstElement * element, GstElement * source, const GstTagList * tag_list) @@ -3387,6 +3157,7 @@ gst_element_emit_found_tag (GstElement * element, GstElement * source, g_signal_emit (element, gst_element_signals[FOUND_TAG], 0, source, tag_list); gst_object_unref (GST_OBJECT (element)); } + static void gst_element_found_tag_func (GstElement * element, GstElement * source, const GstTagList * tag_list) @@ -3448,11 +3219,7 @@ gst_element_found_tags_for_pad (GstElement * element, GstPad * pad, GST_EVENT_SRC (tag_event) = gst_object_ref (GST_OBJECT (element)); GST_EVENT_TIMESTAMP (tag_event) = timestamp; gst_element_found_tags (element, gst_event_tag_get_list (tag_event)); - if (GST_PAD_IS_USABLE (pad)) { - gst_pad_push (pad, GST_DATA (tag_event)); - } else { - gst_data_unref (GST_DATA (tag_event)); - } + gst_pad_push (pad, GST_DATA (tag_event)); } static inline void diff --git a/gst/gstelement.h b/gst/gstelement.h index f341184aba..8d60a2f17d 100644 --- a/gst/gstelement.h +++ b/gst/gstelement.h @@ -79,38 +79,9 @@ GST_EXPORT GType _gst_element_type; #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 */ -#ifndef GST_DISABLE_DEPRECATED -#ifdef G_HAVE_ISO_VARARGS -#define GST_ELEMENT_QUERY_TYPE_FUNCTION(functionname, ...) \ - GST_QUERY_TYPE_FUNCTION (GstElement*, functionname, __VA_ARGS__); -#define GST_ELEMENT_FORMATS_FUNCTION(functionname, ...) \ - GST_FORMATS_FUNCTION (GstElement*, functionname, __VA_ARGS__); -#define GST_ELEMENT_EVENT_MASK_FUNCTION(functionname, ...) \ - GST_EVENT_MASK_FUNCTION (GstElement*, functionname, __VA_ARGS__); -#elif defined(G_HAVE_GNUC_VARARGS) -#define GST_ELEMENT_QUERY_TYPE_FUNCTION(functionname, a...) \ - GST_QUERY_TYPE_FUNCTION (GstElement*, functionname, a); -#define GST_ELEMENT_FORMATS_FUNCTION(functionname, a...) \ - GST_FORMATS_FUNCTION (GstElement*, functionname, a); -#define GST_ELEMENT_EVENT_MASK_FUNCTION(functionname, a...) \ - GST_EVENT_MASK_FUNCTION (GstElement*, functionname, a); -#endif -#endif - typedef enum { - /* element is complex (for some def.) and generally require a cothread */ - GST_ELEMENT_COMPLEX = GST_OBJECT_FLAG_LAST, - /* input and output pads aren't directly coupled to each other - examples: queues, multi-output async readers, etc. */ - GST_ELEMENT_DECOUPLED, - /* this element should be placed in a thread if at all possible */ - GST_ELEMENT_THREAD_SUGGESTED, - /* this element, for some reason, has a loop function that performs - * an infinite loop without calls to gst_element_yield () */ - GST_ELEMENT_INFINITE_LOOP, - /* there is a new loopfunction ready for placement */ - GST_ELEMENT_NEW_LOOPFUNC, + /* element pushes new data, srcpads aren't scheduled */ + GST_ELEMENT_PUSHING = GST_OBJECT_FLAG_LAST, /* if this element can handle events */ GST_ELEMENT_EVENT_AWARE, /* use threadsafe property get/set implementation */ @@ -133,9 +104,8 @@ typedef enum { GST_ELEMENT_FLAG_LAST = GST_OBJECT_FLAG_LAST + 16 } GstElementFlags; -#define GST_ELEMENT_IS_THREAD_SUGGESTED(obj) (GST_FLAG_IS_SET(obj,GST_ELEMENT_THREAD_SUGGESTED)) +#define GST_ELEMENT_IS_PUSHING(obj) (GST_FLAG_IS_SET(obj,GST_ELEMENT_PUSHING)) #define GST_ELEMENT_IS_EVENT_AWARE(obj) (GST_FLAG_IS_SET(obj,GST_ELEMENT_EVENT_AWARE)) -#define GST_ELEMENT_IS_DECOUPLED(obj) (GST_FLAG_IS_SET(obj,GST_ELEMENT_DECOUPLED)) #define GST_ELEMENT_NAME(obj) (GST_OBJECT_NAME(obj)) #define GST_ELEMENT_PARENT(obj) (GST_OBJECT_PARENT(obj)) @@ -170,7 +140,6 @@ typedef enum { typedef struct _GstElementFactory GstElementFactory; typedef struct _GstElementFactoryClass GstElementFactoryClass; -typedef void (*GstElementLoopFunction) (GstElement *element); typedef void (*GstElementPreRunFunction) (GstElement *element); typedef void (*GstElementPostRunFunction) (GstElement *element); @@ -180,10 +149,10 @@ struct _GstElement { /* element state and scheduling */ guint8 current_state; guint8 pending_state; - GstElementLoopFunction loopfunc; GstScheduler *sched; gpointer sched_private; + GSList * actions; /* allocated clock */ GstClock *clock; @@ -235,7 +204,6 @@ struct _GstElementClass { gboolean (*release_locks) (GstElement *element); /* query/convert/events functions */ - const GstEventMask* (*get_event_masks) (GstElement *element); gboolean (*send_event) (GstElement *element, GstEvent *event); const GstFormat* (*get_formats) (GstElement *element); gboolean (*convert) (GstElement *element, @@ -279,8 +247,6 @@ void gst_element_class_set_details (GstElementClass *klass, void gst_element_default_error (GObject *object, GstObject *orig, GError *error, gchar *debug); GType gst_element_get_type (void); -void gst_element_set_loop_function (GstElement *element, - GstElementLoopFunction loop); #define gst_element_get_name(elem) gst_object_get_name(GST_OBJECT(elem)) #define gst_element_set_name(elem,name) gst_object_set_name(GST_OBJECT(elem),name) @@ -372,17 +338,11 @@ gboolean gst_element_link_pads_filtered (GstElement *src, const gchar *srcpadn void gst_element_unlink_pads (GstElement *src, const gchar *srcpadname, GstElement *dest, const gchar *destpadname); -G_CONST_RETURN GstEventMask* - gst_element_get_event_masks (GstElement *element); gboolean gst_element_send_event (GstElement *element, GstEvent *event); gboolean gst_element_seek (GstElement *element, GstSeekType seek_type, guint64 offset); -G_CONST_RETURN GstQueryType* - gst_element_get_query_types (GstElement *element); gboolean gst_element_query (GstElement *element, GstQueryType type, GstFormat *format, gint64 *value); -G_CONST_RETURN GstFormat* - gst_element_get_formats (GstElement *element); gboolean gst_element_convert (GstElement *element, GstFormat src_format, gint64 src_value, GstFormat *dest_format, gint64 *dest_value); diff --git a/gst/gstpad.c b/gst/gstpad.c index d479fcf6ae..b0acac4f4a 100644 --- a/gst/gstpad.c +++ b/gst/gstpad.c @@ -163,8 +163,7 @@ enum enum { REAL_ARG_0, - REAL_ARG_CAPS, - REAL_ARG_ACTIVE + REAL_ARG_CAPS /* FILL ME */ }; @@ -232,9 +231,6 @@ gst_real_pad_class_init (GstRealPadClass * klass) gst_marshal_BOXED__BOXED, GST_TYPE_CAPS, 1, GST_TYPE_CAPS | G_SIGNAL_TYPE_STATIC_SCOPE); - g_object_class_install_property (G_OBJECT_CLASS (klass), REAL_ARG_ACTIVE, - g_param_spec_boolean ("active", "Active", "Whether the pad is active.", - TRUE, G_PARAM_READWRITE)); g_object_class_install_property (G_OBJECT_CLASS (klass), REAL_ARG_CAPS, g_param_spec_boxed ("caps", "Caps", "The capabilities of the pad", GST_TYPE_CAPS, G_PARAM_READABLE)); @@ -261,31 +257,11 @@ static void gst_real_pad_init (GstRealPad * pad) { pad->direction = GST_PAD_UNKNOWN; - pad->peer = NULL; - pad->chainfunc = NULL; - pad->getfunc = NULL; - - pad->chainhandler = NULL; - pad->gethandler = NULL; - - pad->ghostpads = NULL; - pad->caps = NULL; - - pad->linkfunc = NULL; - pad->getcapsfunc = NULL; - - pad->eventfunc = gst_pad_event_default; + pad->eventhandler = gst_pad_event_default; pad->convertfunc = gst_pad_convert_default; pad->queryfunc = gst_pad_query_default; pad->intlinkfunc = gst_pad_get_internal_links_default; - - pad->eventmaskfunc = gst_pad_get_event_masks_default; - pad->formatsfunc = gst_pad_get_formats_default; - pad->querytypefunc = gst_pad_get_query_types_default; - - GST_FLAG_SET (pad, GST_PAD_DISABLED); - GST_FLAG_UNSET (pad, GST_PAD_NEGOTIATING); } static void @@ -295,9 +271,6 @@ gst_real_pad_set_property (GObject * object, guint prop_id, g_return_if_fail (GST_IS_PAD (object)); switch (prop_id) { - case REAL_ARG_ACTIVE: - gst_pad_set_active (GST_PAD (object), g_value_get_boolean (value)); - break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -311,9 +284,6 @@ gst_real_pad_get_property (GObject * object, guint prop_id, g_return_if_fail (GST_IS_PAD (object)); switch (prop_id) { - case REAL_ARG_ACTIVE: - g_value_set_boolean (value, !GST_FLAG_IS_SET (object, GST_PAD_DISABLED)); - break; case REAL_ARG_CAPS: g_value_set_boxed (value, GST_PAD_CAPS (GST_REAL_PAD (object))); break; @@ -323,6 +293,44 @@ gst_real_pad_get_property (GObject * object, guint prop_id, } } +/** + * gst_pad_push: + * @pad: a source #GstPad. + * @data: the #GstData to push. + * + * Pushes a buffer or an event to the peer of @pad. @pad must be negotiated. + * May only be called by @pad's parent and only if the parent has the + * GST_ELEMENT_PUSHING flag set. + */ +void +gst_pad_push (GstPad * pad, GstData * data) +{ + GstElement *parent; + GstScheduler *sched; + + g_return_if_fail (GST_IS_REAL_PAD (pad)); + g_return_if_fail (GST_PAD_IS_SRC (pad)); + g_return_if_fail (data != NULL); + + parent = gst_pad_get_parent (pad); + g_return_if_fail (GST_IS_ELEMENT (parent)); + g_return_if_fail (GST_ELEMENT_IS_PUSHING (parent)); + //DEBUG_DATA (pad, data, "gst_pad_push"); + + if (!gst_pad_is_negotiated (pad)) { + g_warning ("pushing data on non-negotiated pad %s:%s, not allowed.", + GST_DEBUG_PAD_NAME (pad)); + gst_data_unref (data); + return; + } + + GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad, "pushing"); + + sched = GST_ELEMENT_SCHED (parent); + g_return_if_fail (sched); + gst_scheduler_pad_push (sched, GST_REAL_PAD (pad), data); +} + /* FIXME-0.9: Replace these custom functions with proper inheritance via _init functions and object properties */ /** @@ -433,99 +441,23 @@ gst_pad_get_direction (GstPad * pad) } /** - * gst_pad_set_active: + * gst_real_pad_set_active: * @pad: the #GstPad to activate or deactivate. * @active: TRUE to activate the pad. * * Activates or deactivates the given pad. */ void -gst_pad_set_active (GstPad * pad, gboolean active) +gst_real_pad_set_active (GstRealPad * pad, gboolean active) { - GstRealPad *realpad; - gboolean old; - GstPadLink *link; + g_return_if_fail (GST_IS_REAL_PAD (pad)); - g_return_if_fail (GST_IS_PAD (pad)); - - old = GST_PAD_IS_ACTIVE (pad); - - if (old == active) - return; - - realpad = GST_PAD_REALIZE (pad); - - if (active) { - GST_CAT_DEBUG (GST_CAT_PADS, "activating pad %s:%s", - GST_DEBUG_PAD_NAME (realpad)); - GST_FLAG_UNSET (realpad, GST_PAD_DISABLED); - } else { - GST_CAT_DEBUG (GST_CAT_PADS, "de-activating pad %s:%s", - GST_DEBUG_PAD_NAME (realpad)); - GST_FLAG_SET (realpad, GST_PAD_DISABLED); - } - link = GST_RPAD_LINK (realpad); - if (link) { - if (link->temp_store) { - GST_CAT_INFO (GST_CAT_PADS, - "deleting cached data %p from bufpen of pad %s:%s", link->temp_store, - GST_DEBUG_PAD_NAME (realpad)); - gst_data_unref (link->temp_store); - link->temp_store = NULL; - } - } - - g_object_notify (G_OBJECT (realpad), "active"); + g_return_if_fail (pad->action != NULL); + gst_action_set_active (pad->action, active); } /** - * gst_pad_set_active_recursive: - * @pad: the #GstPad to activate or deactivate. - * @active: TRUE to activate the pad. - * - * Activates or deactivates the given pad and all internally linked - * pads upstream until it finds an element with multiple source pads. - */ -void -gst_pad_set_active_recursive (GstPad * pad, gboolean active) -{ - GstElement *parent; - const GList *int_links; - - g_return_if_fail (GST_IS_PAD (pad)); - g_return_if_fail (GST_PAD_IS_SRC (pad)); - - GST_CAT_DEBUG_OBJECT (GST_CAT_PADS, pad, - "Recursively %s pad %s:%s", active ? "activating" : "deactivating", - GST_DEBUG_PAD_NAME (pad)); - - gst_pad_set_active (pad, active); - - /* If we have more than one sourcepad, then the other pads should - * possibly be kept active. FIXME: maybe we should recurse - * activation if any one pad is active and recurse deactivation - * if no single pad is active? */ - parent = gst_pad_get_parent (pad); - if (!parent || parent->numsrcpads > 1) - return; - - for (int_links = gst_pad_get_internal_links (pad); - int_links; int_links = g_list_next (int_links)) { - GstPad *sinkpad = GST_PAD (int_links->data); - GstPad *peer = GST_PAD_PEER (sinkpad); - - GST_CAT_DEBUG_OBJECT (GST_CAT_PADS, sinkpad, - "Recursing %s on pad %s:%s", - active ? "activation" : "deactivation", GST_DEBUG_PAD_NAME (sinkpad)); - - gst_pad_set_active (sinkpad, active); - if (peer) - gst_pad_set_active_recursive (peer, active); - } -} - -/** - * gst_pad_is_active: + * gst_real_pad_is_active: * @pad: the #GstPad to query * * Query if a pad is active @@ -533,11 +465,35 @@ gst_pad_set_active_recursive (GstPad * pad, gboolean active) * Returns: TRUE if the pad is active. */ gboolean -gst_pad_is_active (GstPad * pad) +gst_real_pad_is_active (GstRealPad * pad) { - g_return_val_if_fail (GST_IS_PAD (pad), FALSE); + g_return_val_if_fail (GST_IS_REAL_PAD (pad), FALSE); - return !GST_FLAG_IS_SET (pad, GST_PAD_DISABLED); + if (pad->action == NULL) + return FALSE; + + return gst_action_is_active (pad->action); +} + +/** + * gst_real_pad_set_initially_active: + * @pad: a #GstPad + * @active: whether the pad should be initially active or not + * + * Sets if the pad should be initially active. This sets the pad's action to + * initially active. See gst_action_set_initially_active() for details. The + * default behaviour is that sink pads are initially active while source pads + * are not, since this works for most general purpose elements. Other elements, + * most likely sources, will need to call this function on its pads. + * The pad must have an action handler set when calling this function. + **/ +void +gst_real_pad_set_initially_active (GstRealPad * pad, gboolean active) +{ + g_return_if_fail (GST_IS_REAL_PAD (pad)); + + g_return_if_fail (pad->action != NULL); + gst_action_set_initially_active (pad->action, active); } /** @@ -574,46 +530,6 @@ gst_pad_get_name (GstPad * pad) return GST_OBJECT_NAME (pad); } -/** - * gst_pad_set_chain_function: - * @pad: a real sink #GstPad. - * @chain: the #GstPadChainFunction to set. - * - * Sets the given chain function for the pad. The chain function is called to - * process a #GstData input buffer. - */ -void -gst_pad_set_chain_function (GstPad * pad, GstPadChainFunction chain) -{ - g_return_if_fail (GST_IS_REAL_PAD (pad)); - g_return_if_fail (GST_RPAD_DIRECTION (pad) == GST_PAD_SINK); - - GST_RPAD_CHAINFUNC (pad) = chain; - GST_CAT_DEBUG (GST_CAT_PADS, "chainfunc for %s:%s set to %s", - GST_DEBUG_PAD_NAME (pad), GST_DEBUG_FUNCPTR_NAME (chain)); -} - -/** - * gst_pad_set_get_function: - * @pad: a real source #GstPad. - * @get: the #GstPadGetFunction to set. - * - * Sets the given get function for the pad. The get function is called to - * produce a new #GstData to start the processing pipeline. Get functions cannot - * return %NULL. - */ -void -gst_pad_set_get_function (GstPad * pad, GstPadGetFunction get) -{ - g_return_if_fail (GST_IS_REAL_PAD (pad)); - g_return_if_fail (GST_RPAD_DIRECTION (pad) == GST_PAD_SRC); - - GST_RPAD_GETFUNC (pad) = get; - - GST_CAT_DEBUG (GST_CAT_PADS, "getfunc for %s:%s set to %s", - GST_DEBUG_PAD_NAME (pad), GST_DEBUG_FUNCPTR_NAME (get)); -} - /** * gst_pad_set_event_function: * @pad: a real source #GstPad. @@ -624,90 +540,18 @@ gst_pad_set_get_function (GstPad * pad, GstPadGetFunction get) void gst_pad_set_event_function (GstPad * pad, GstPadEventFunction event) { + GstRealPad *real; + g_return_if_fail (GST_IS_REAL_PAD (pad)); g_return_if_fail (GST_RPAD_DIRECTION (pad) == GST_PAD_SRC); - GST_RPAD_EVENTFUNC (pad) = event; + real = GST_REAL_PAD (pad); + real->eventhandler = event; GST_CAT_DEBUG (GST_CAT_PADS, "eventfunc for %s:%s set to %s", GST_DEBUG_PAD_NAME (pad), GST_DEBUG_FUNCPTR_NAME (event)); } -/** - * gst_pad_set_event_mask_function: - * @pad: a real #GstPad of either direction. - * @mask_func: the #GstPadEventMaskFunction to set. - * - * Sets the given event mask function for the pad. - */ -void -gst_pad_set_event_mask_function (GstPad * pad, - GstPadEventMaskFunction mask_func) -{ - g_return_if_fail (GST_IS_REAL_PAD (pad)); - - GST_RPAD_EVENTMASKFUNC (pad) = mask_func; - - GST_CAT_DEBUG (GST_CAT_PADS, "eventmaskfunc for %s:%s set to %s", - GST_DEBUG_PAD_NAME (pad), GST_DEBUG_FUNCPTR_NAME (mask_func)); -} - -/** - * gst_pad_get_event_masks: - * @pad: a #GstPad. - * - * Gets the array of eventmasks from the given pad. - * - * Returns: a zero-terminated array of #GstEventMask, or NULL if the pad does - * not have an event mask function. - */ -const GstEventMask * -gst_pad_get_event_masks (GstPad * pad) -{ - GstRealPad *rpad; - - g_return_val_if_fail (GST_IS_PAD (pad), NULL); - - rpad = GST_PAD_REALIZE (pad); - - g_return_val_if_fail (rpad, NULL); - - if (GST_RPAD_EVENTMASKFUNC (rpad)) - return GST_RPAD_EVENTMASKFUNC (rpad) (GST_PAD (pad)); - - return NULL; -} - -static gboolean -gst_pad_get_event_masks_dispatcher (GstPad * pad, const GstEventMask ** data) -{ - *data = gst_pad_get_event_masks (pad); - - return TRUE; -} - -/** - * gst_pad_get_event_masks_default: - * @pad: a #GstPad. - * - * Invokes the default event masks dispatcher on the pad. - * - * Returns: a zero-terminated array of #GstEventMask, or NULL if none of the - * internally-linked pads have an event mask function. - */ -const GstEventMask * -gst_pad_get_event_masks_default (GstPad * pad) -{ - GstEventMask *result = NULL; - - g_return_val_if_fail (GST_IS_PAD (pad), NULL); - - gst_pad_dispatcher (pad, (GstPadDispatcherFunction) - gst_pad_get_event_masks_dispatcher, &result); - - return result; -} - /** * gst_pad_set_convert_function: * @pad: a real #GstPad of either direction. @@ -744,82 +588,6 @@ gst_pad_set_query_function (GstPad * pad, GstPadQueryFunction query) GST_DEBUG_PAD_NAME (pad), GST_DEBUG_FUNCPTR_NAME (query)); } -/** - * gst_pad_set_query_type_function: - * @pad: a real #GstPad of either direction. - * @type_func: the #GstPadQueryTypeFunction to set. - * - * Set the given query type function for the pad. - */ -void -gst_pad_set_query_type_function (GstPad * pad, - GstPadQueryTypeFunction type_func) -{ - g_return_if_fail (GST_IS_REAL_PAD (pad)); - - GST_RPAD_QUERYTYPEFUNC (pad) = type_func; - - GST_CAT_DEBUG (GST_CAT_PADS, "querytypefunc for %s:%s set to %s", - GST_DEBUG_PAD_NAME (pad), GST_DEBUG_FUNCPTR_NAME (type_func)); -} - -/** - * gst_pad_get_query_types: - * @pad: a #GstPad. - * - * Get an array of supported queries that can be performed - * on this pad. - * - * Returns: a zero-terminated array of #GstQueryType. - */ -const GstQueryType * -gst_pad_get_query_types (GstPad * pad) -{ - GstRealPad *rpad; - - g_return_val_if_fail (GST_IS_PAD (pad), NULL); - - rpad = GST_PAD_REALIZE (pad); - - g_return_val_if_fail (rpad, NULL); - - if (GST_RPAD_QUERYTYPEFUNC (rpad)) - return GST_RPAD_QUERYTYPEFUNC (rpad) (GST_PAD (pad)); - - return NULL; -} - -static gboolean -gst_pad_get_query_types_dispatcher (GstPad * pad, const GstQueryType ** data) -{ - *data = gst_pad_get_query_types (pad); - - return TRUE; -} - -/** - * gst_pad_get_query_types_default: - * @pad: a #GstPad. - * - * Invoke the default dispatcher for the query types on - * the pad. - * - * Returns: an zero-terminated array of #GstQueryType, or NULL if none of the - * internally-linked pads has a query types function. - */ -const GstQueryType * -gst_pad_get_query_types_default (GstPad * pad) -{ - GstQueryType *result = NULL; - - g_return_val_if_fail (GST_IS_PAD (pad), NULL); - - gst_pad_dispatcher (pad, (GstPadDispatcherFunction) - gst_pad_get_query_types_dispatcher, &result); - - return result; -} - /** * gst_pad_set_internal_link_function: * @pad: a real #GstPad of either direction. @@ -837,23 +605,6 @@ gst_pad_set_internal_link_function (GstPad * pad, GstPadIntLinkFunction intlink) GST_DEBUG_PAD_NAME (pad), GST_DEBUG_FUNCPTR_NAME (intlink)); } -/** - * gst_pad_set_formats_function: - * @pad: a real #GstPad of either direction. - * @formats: the #GstPadFormatsFunction to set. - * - * Sets the given formats function for the pad. - */ -void -gst_pad_set_formats_function (GstPad * pad, GstPadFormatsFunction formats) -{ - g_return_if_fail (GST_IS_REAL_PAD (pad)); - - GST_RPAD_FORMATSFUNC (pad) = formats; - GST_CAT_DEBUG (GST_CAT_PADS, "formats function for %s:%s set to %s", - GST_DEBUG_PAD_NAME (pad), GST_DEBUG_FUNCPTR_NAME (formats)); -} - /** * gst_pad_set_link_function: * @pad: a real #GstPad. @@ -1092,18 +843,12 @@ static gboolean 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 (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)) - num_decoupled++; - if (GST_FLAG_IS_SET (GST_PAD_PARENT (realsink), GST_ELEMENT_DECOUPLED)) - num_decoupled++; - - if (src_sched != sink_sched && num_decoupled != 1) { + if (src_sched != sink_sched) { return FALSE; } } @@ -2014,18 +1759,8 @@ gst_pad_get_scheduler (GstPad * pad) g_return_val_if_fail (GST_IS_PAD (pad), NULL); parent = gst_pad_get_parent (pad); - if (parent) { - if (GST_FLAG_IS_SET (parent, GST_ELEMENT_DECOUPLED)) { - GstRealPad *peer = GST_RPAD_PEER (pad); - - if (peer) { - scheduler = - gst_element_get_scheduler (gst_pad_get_parent (GST_PAD (peer))); - } - } else { - scheduler = gst_element_get_scheduler (parent); - } - } + if (parent) + scheduler = gst_element_get_scheduler (parent); return scheduler; } @@ -3079,6 +2814,11 @@ gst_real_pad_dispose (GObject * object) gst_element_remove_pad (GST_ELEMENT (GST_OBJECT_PARENT (pad)), pad); } + if (GST_REAL_PAD (pad)->action) { + gst_action_free (GST_REAL_PAD (pad)->action); + GST_REAL_PAD (pad)->action = NULL; + } + if (GST_RPAD_EXPLICIT_CAPS (pad)) { GST_ERROR_OBJECT (pad, "still explicit caps %" GST_PTR_FORMAT " set", GST_RPAD_EXPLICIT_CAPS (pad)); @@ -3088,6 +2828,43 @@ gst_real_pad_dispose (GObject * object) G_OBJECT_CLASS (real_pad_parent_class)->dispose (object); } +void +gst_src_pad_set_action_handler (GstPad * pad, GstActionSrcPadFunc func) +{ + GstRealPad *real; + + g_return_if_fail (GST_IS_REAL_PAD (pad)); + g_return_if_fail (func != NULL); + + real = GST_REAL_PAD (pad); + if (!real->action) { + /* actions may only be set (not reset) before being added to an element */ + g_return_if_fail (GST_OBJECT_PARENT (pad) == NULL); + real->action = gst_action_new (GST_ACTION_SRC_PAD); + real->action->any.initially_active = FALSE; + real->action->srcpad.pad = GST_REAL_PAD (pad); + } + real->action->srcpad.release = func; +} + +void +gst_sink_pad_set_action_handler (GstPad * pad, GstActionSinkPadFunc func) +{ + GstRealPad *real; + + g_return_if_fail (GST_IS_REAL_PAD (pad)); + g_return_if_fail (func != NULL); + + real = GST_REAL_PAD (pad); + if (!real->action) { + /* actions may only be set (not reset) before being added to an element */ + g_return_if_fail (GST_OBJECT_PARENT (pad) == NULL); + real->action = gst_action_new (GST_ACTION_SINK_PAD); + real->action->any.initially_active = TRUE; + real->action->sinkpad.pad = GST_REAL_PAD (pad); + } + real->action->sinkpad.release = func; +} #ifndef GST_DISABLE_LOADSAVE /* FIXME: why isn't this on a GstElement ? */ @@ -3228,388 +3005,6 @@ gst_ghost_pad_save_thyself (GstPad * pad, xmlNodePtr parent) } #endif /* GST_DISABLE_LOADSAVE */ -static GstData * -_invent_event (GstPad * pad, GstBuffer * buffer) -{ - GstEvent *event; - GstEventType event_type; - guint64 offset; - - if (GST_BUFFER_OFFSET_IS_VALID (buffer)) - event_type = GST_FORMAT_DEFAULT; - else - event_type = GST_FORMAT_UNDEFINED; - - offset = GST_BUFFER_OFFSET (buffer); - - if (GST_BUFFER_TIMESTAMP_IS_VALID (buffer)) { - GstClockTime timestamp = GST_BUFFER_TIMESTAMP (buffer); - - event = gst_event_new_discontinuous (TRUE, - GST_FORMAT_TIME, timestamp, event_type, offset, GST_FORMAT_UNDEFINED); - GST_CAT_WARNING (GST_CAT_SCHEDULING, - "needed to invent a DISCONT %p (time %" G_GUINT64_FORMAT - ") for %s:%s => %s:%s", event, timestamp, - GST_DEBUG_PAD_NAME (GST_PAD_PEER (pad)), GST_DEBUG_PAD_NAME (pad)); - } else { - event = gst_event_new_discontinuous (TRUE, - event_type, offset, GST_FORMAT_UNDEFINED); - GST_CAT_WARNING (GST_CAT_SCHEDULING, - "needed to invent a DISCONT %p (no time) for %s:%s => %s:%s", event, - GST_DEBUG_PAD_NAME (GST_PAD_PEER (pad)), GST_DEBUG_PAD_NAME (pad)); - } - - return GST_DATA (event); -} - -/** - * gst_pad_push: - * @pad: a source #GstPad. - * @data: the #GstData to push. - * - * Pushes a buffer or an event to the peer of @pad. @pad must be linked. May - * only be called by @pad's parent. - */ -void -gst_pad_push (GstPad * pad, GstData * data) -{ - GstRealPad *peer; - - g_return_if_fail (GST_IS_PAD (pad)); - g_return_if_fail (GST_PAD_DIRECTION (pad) == GST_PAD_SRC); - g_return_if_fail (!GST_FLAG_IS_SET (GST_PAD_REALIZE (pad), - GST_RPAD_IN_GETFUNC)); - g_return_if_fail (data != NULL); - - DEBUG_DATA (pad, data, "gst_pad_push"); - - if (!GST_PAD_IS_LINKED (pad)) { - GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad, - "not pushing data %p as pad is unconnected", data); - gst_data_unref (data); - return; - } - - if (GST_IS_BUFFER (data) && !gst_pad_is_negotiated (pad)) { - g_warning ("pushing data on non-negotiated pad %s:%s, not allowed.", - GST_DEBUG_PAD_NAME (pad)); - gst_data_unref (data); - return; - } - - GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad, "pushing"); - peer = GST_RPAD_PEER (pad); - - if (!peer) { - g_warning ("push on pad %s:%s but it is unlinked", - GST_DEBUG_PAD_NAME (pad)); - } else { - if (!GST_IS_EVENT (data) && !GST_PAD_IS_ACTIVE (peer)) { - g_warning ("push on peer of pad %s:%s but peer is not active", - GST_DEBUG_PAD_NAME (pad)); - return; - } - - if (peer->chainhandler) { - if (data) { - GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad, - "calling chainhandler &%s of peer pad %s:%s", - GST_DEBUG_FUNCPTR_NAME (peer->chainhandler), - GST_DEBUG_PAD_NAME (GST_PAD (peer))); - (peer->chainhandler) (GST_PAD (peer), data); - return; - } else { - g_warning ("trying to push a NULL buffer on pad %s:%s", - GST_DEBUG_PAD_NAME (peer)); - return; - } - } else { - g_warning ("internal error: push on pad %s:%s but it has no chainhandler", - GST_DEBUG_PAD_NAME (peer)); - } - } - /* clean up the mess here */ - if (data != NULL) - gst_data_unref (data); -} - -/** - * gst_pad_pull: - * @pad: a sink #GstPad. - * - * Pulls an event or a buffer from the peer pad. May only be called by @pad's - * parent. - * - * Returns: a new #GstData from the peer pad. - */ -GstData * -gst_pad_pull (GstPad * pad) -{ - GstRealPad *peer; - GstData *data; - - g_return_val_if_fail (GST_PAD_DIRECTION (pad) == GST_PAD_SINK, - GST_DATA (gst_event_new (GST_EVENT_INTERRUPT))); - g_return_val_if_fail (!GST_FLAG_IS_SET (GST_PAD_REALIZE (pad), - GST_RPAD_IN_CHAINFUNC), - GST_DATA (gst_event_new (GST_EVENT_INTERRUPT))); - - peer = GST_RPAD_PEER (pad); - - if (!peer) { - GST_ELEMENT_ERROR (GST_PAD_PARENT (pad), CORE, PAD, (NULL), - ("pull on pad %s:%s but it was unlinked", GST_DEBUG_PAD_NAME (pad))); - } else { - if (peer->gethandler) { - GstPadLink *link = GST_RPAD_LINK (pad); - - GST_CAT_LOG_OBJECT (GST_CAT_SCHEDULING, pad, - "calling gethandler %s of peer pad %s:%s", - GST_DEBUG_FUNCPTR_NAME (peer->gethandler), GST_DEBUG_PAD_NAME (peer)); - - if (link->temp_store) { - g_assert (link->engaged); - GST_DEBUG ("moving temp_store %p to data", link->temp_store); - data = link->temp_store; - link->temp_store = NULL; - } else { - data = (peer->gethandler) (GST_PAD (peer)); - /* refetch - we might have been relinked */ - link = GST_RPAD_LINK (pad); - peer = GST_RPAD_PEER (pad); - if (!peer) { - /* Our peer disa-peer-ed ;) */ - goto int_out; - } - } - - if (data) { - if (!link->engaged) { - g_assert (link->temp_store == NULL); - if (GST_IS_BUFFER (data)) { - GST_DEBUG ("moving data buffer %p back to temp_store", data); - link->temp_store = data; - link->engaged = TRUE; - data = _invent_event (pad, GST_BUFFER (data)); - } else if (GST_IS_EVENT (data) && - GST_EVENT_TYPE (data) == GST_EVENT_DISCONTINUOUS && - GST_EVENT_DISCONT_NEW_MEDIA (data)) { - link->engaged = TRUE; - GST_CAT_LOG (GST_CAT_SCHEDULING, - "link engaged by discont event %p for pad %s:%s", data, - GST_DEBUG_PAD_NAME (pad)); - } - } - DEBUG_DATA (pad, data, "gst_pad_pull returned"); - return data; - } - - /* no null buffers allowed */ - GST_ELEMENT_ERROR (GST_PAD_PARENT (pad), CORE, PAD, (NULL), - ("NULL buffer during pull on %s:%s", GST_DEBUG_PAD_NAME (pad))); - } else { - GST_ELEMENT_ERROR (GST_PAD_PARENT (pad), CORE, PAD, (NULL), - ("pull on pad %s:%s but the peer pad %s:%s has no gethandler", - GST_DEBUG_PAD_NAME (pad), GST_DEBUG_PAD_NAME (peer))); - } - } - -int_out: - data = GST_DATA (gst_event_new (GST_EVENT_INTERRUPT)); - DEBUG_DATA (pad, data, "gst_pad_pull returning INTERRUPT"); - return data; -} - -GstData * -gst_pad_collect_array (GstScheduler * scheduler, GstPad ** selected, - GstPad ** padlist) -{ - GstSchedulerClass *klass = GST_SCHEDULER_GET_CLASS (scheduler); - - if (!GST_FLAG_IS_SET (scheduler, GST_SCHEDULER_FLAG_NEW_API) || - !klass->pad_select) { - /* better randomness? */ - if (selected) - *selected = padlist[0]; - return gst_pad_pull (padlist[0]); - } else { - GstPad *select; - - return klass->pad_select (scheduler, selected ? selected : &select, - padlist); - } -} - -/** - * gst_pad_collectv: - * @selected: set to the pad the buffer comes from if not NULL - * @padlist: a #GList of sink pads. - * - * Waits for a buffer on any of the list of pads. Each #GstPad in @padlist must - * belong to the same element and be owned by the caller. - * - * Returns: the #GstData that was available - */ -GstData * -gst_pad_collectv (GstPad ** selected, const GList * padlist) -{ - /* need to use alloca here because we must not leak data */ - GstPad **pads; - GstPad *test; - GstElement *element = NULL; - int i = 0; - - g_return_val_if_fail (padlist != NULL, NULL); - pads = g_alloca (sizeof (gpointer) * (g_list_length ((GList *) padlist) + 1)); - for (; padlist; padlist = g_list_next (padlist)) { - test = GST_PAD (padlist->data); - g_return_val_if_fail (GST_IS_PAD (test), NULL); - g_return_val_if_fail (GST_PAD_IS_SINK (test), NULL); - if (element) { - g_return_val_if_fail (element == gst_pad_get_parent (test), NULL); - } else { - element = gst_pad_get_parent (test); - } - pads[i++] = test; - } - pads[i] = NULL; - - return gst_pad_collect_array (GST_ELEMENT_SCHED (element), selected, pads); -} - -/** - * gst_pad_collect: - * @selected: set to the pad the buffer comes from if not NULL - * @pad: first pad - * @...: more sink pads. - * - * Waits for a buffer on the given set of pads. - * - * Returns: the #GstData that was available. - */ -GstData * -gst_pad_collect (GstPad ** selected, GstPad * pad, ...) -{ - GstData *result; - va_list var_args; - - g_return_val_if_fail (GST_IS_PAD (pad), NULL); - - va_start (var_args, pad); - - result = gst_pad_collect_valist (selected, pad, var_args); - - va_end (var_args); - - return result; -} - -/** - * gst_pad_collect_valist: - * @selected: set to the pad the buffer comes from if not NULL - * @pad: first pad - * @...: more sink pads. - * - * Waits for a buffer on the given set of pads. - * - * Returns: the #GstData that was available. - */ -GstData * -gst_pad_collect_valist (GstPad ** selected, GstPad * pad, va_list var_args) -{ - GstPad **padlist; - GstElement *element = NULL; - gint i = 0, maxlength; - - g_return_val_if_fail (GST_IS_PAD (pad), NULL); - - element = gst_pad_get_parent (pad); - maxlength = element->numsinkpads; - /* can we make this list a bit smaller than this upper limit? */ - padlist = g_alloca (sizeof (gpointer) * (maxlength + 1)); - while (pad) { - g_return_val_if_fail (i < maxlength, NULL); - g_return_val_if_fail (element == gst_pad_get_parent (pad), NULL); - padlist[i++] = pad; - pad = va_arg (var_args, GstPad *); - } - padlist[i] = NULL; - return gst_pad_collect_array (GST_ELEMENT_SCHED (element), selected, padlist); -} - -/** - * gst_pad_selectv: - * @padlist: a #GList of sink pads. - * - * Waits for a buffer on any of the list of pads. Each #GstPad in @padlist must - * be owned by the calling code. - * - * Returns: the #GstPad that has a buffer available. - * Use #gst_pad_pull() to get the buffer. - */ -GstPad * -gst_pad_selectv (GList * padlist) -{ - return NULL; -} - -/** - * 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_selectv (padlist); - g_list_free (padlist); - - return result; -} - -/** - * gst_pad_select: - * @pad: a first sink #GstPad to perform the select on. - * @...: A NULL-terminated 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 (GstPad * pad, ...) -{ - GstPad *result; - va_list var_args; - - if (pad == NULL) - return NULL; - - va_start (var_args, pad); - - result = gst_pad_select_valist (pad, var_args); - - va_end (var_args); - - return result; -} - /************************************************************************ * * templates @@ -4405,138 +3800,3 @@ gst_pad_query (GstPad * pad, GstQueryType type, return FALSE; } - -static gboolean -gst_pad_get_formats_dispatcher (GstPad * pad, const GstFormat ** data) -{ - *data = gst_pad_get_formats (pad); - - return TRUE; -} - -/** - * gst_pad_get_formats_default: - * @pad: a #GstPad to query - * - * Invoke the default format dispatcher for the pad. - * - * Returns: An array of GstFormats ended with a 0 value. - */ -const GstFormat * -gst_pad_get_formats_default (GstPad * pad) -{ - GstFormat *result = NULL; - - g_return_val_if_fail (GST_IS_PAD (pad), NULL); - - gst_pad_dispatcher (pad, (GstPadDispatcherFunction) - gst_pad_get_formats_dispatcher, &result); - - return result; -} - -/** - * gst_pad_get_formats: - * @pad: a #GstPad to query - * - * Gets the list of supported formats from the pad. - * - * Returns: An array of GstFormats ended with a 0 value. - */ -const GstFormat * -gst_pad_get_formats (GstPad * pad) -{ - GstRealPad *rpad; - - g_return_val_if_fail (GST_IS_PAD (pad), NULL); - - rpad = GST_PAD_REALIZE (pad); - - if (GST_RPAD_FORMATSFUNC (rpad)) - return GST_RPAD_FORMATSFUNC (rpad) (GST_PAD (pad)); - - return NULL; -} - -#define CALL_CHAINFUNC(pad, data) G_STMT_START {\ - GstData *__temp = (data); \ - DEBUG_DATA (pad, __temp, "calling chain function with "); \ - if (GST_IS_EVENT (__temp) && \ - !GST_FLAG_IS_SET (gst_pad_get_parent (pad), GST_ELEMENT_EVENT_AWARE)) { \ - gst_pad_send_event (pad, GST_EVENT (__temp)); \ - } else { \ - GST_FLAG_SET (pad, GST_RPAD_IN_CHAINFUNC); \ - GST_RPAD_CHAINFUNC (pad) (pad, __temp); \ - GST_FLAG_UNSET (pad, GST_RPAD_IN_CHAINFUNC); \ - } \ -}G_STMT_END -/** - * gst_pad_call_chain_function: - * @pad: sink pad to call chain function on - * @data: data to call the chain function with - * - * Calls the chain function of the given pad while making sure the internal - * consistency is kept. Use this function inside schedulers instead of calling - * the chain function yourself. - */ -void -gst_pad_call_chain_function (GstPad * pad, GstData * data) -{ - GstPadLink *link; - - g_return_if_fail (GST_IS_REAL_PAD (pad)); - g_return_if_fail (GST_PAD_IS_SINK (pad)); - g_return_if_fail (data != NULL); - g_return_if_fail (GST_RPAD_CHAINFUNC (pad) != NULL); - g_return_if_fail (GST_RPAD_LINK (pad) != NULL); - - link = GST_RPAD_LINK (pad); - if (!link->engaged) { - g_assert (link->temp_store == NULL); - if (GST_IS_BUFFER (data)) { - GST_DEBUG ("moving data buffer %p back to temp_store", data); - link->temp_store = data; - link->engaged = TRUE; - CALL_CHAINFUNC (pad, _invent_event (pad, GST_BUFFER (data))); - link = GST_RPAD_LINK (pad); - if (link->temp_store == NULL) /* happens after relinking in chainfunc */ - return; - g_assert (link->temp_store == data); - link->temp_store = NULL; - } else if (GST_IS_EVENT (data) && - GST_EVENT_TYPE (data) == GST_EVENT_DISCONTINUOUS && - GST_EVENT_DISCONT_NEW_MEDIA (data)) { - link->engaged = TRUE; - GST_CAT_LOG (GST_CAT_SCHEDULING, - "link engaged by discont event %p for pad %s:%s", data, - GST_DEBUG_PAD_NAME (pad)); - } - } - CALL_CHAINFUNC (pad, data); -} - -/** - * gst_pad_call_get_function: - * @pad: sink pad to call chain function on - * - * Calls the get function of the given pad while making sure the internal - * consistency is kept. Use this function inside schedulers instead of calling - * the get function yourself. - * - * Returns: the data provided by the pad or NULL if no data was available. - */ -GstData * -gst_pad_call_get_function (GstPad * pad) -{ - GstData *data; - - g_return_val_if_fail (GST_IS_REAL_PAD (pad), NULL); - g_return_val_if_fail (GST_PAD_IS_SRC (pad), NULL); - g_return_val_if_fail (GST_RPAD_GETFUNC (pad) != NULL, NULL); - - GST_FLAG_SET (pad, GST_RPAD_IN_GETFUNC); - data = GST_RPAD_GETFUNC (pad) (pad); - GST_FLAG_UNSET (pad, GST_RPAD_IN_GETFUNC); - DEBUG_DATA (pad, data, "getfunction returned"); - return data; -} diff --git a/gst/gstpad.h b/gst/gstpad.h index 1fda5c9756..3eaa786148 100644 --- a/gst/gstpad.h +++ b/gst/gstpad.h @@ -27,6 +27,7 @@ #include #include +#include #include #include #include @@ -71,14 +72,8 @@ GST_EXPORT GType _gst_ghost_pad_type; #define GST_GHOST_PAD_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_GHOST_PAD, GstGhostPadClass)) -/*typedef struct _GstPad GstPad; */ -/*typedef struct _GstPadClass GstPadClass;*/ -typedef struct _GstRealPad GstRealPad; -typedef struct _GstRealPadClass GstRealPadClass; typedef struct _GstGhostPad GstGhostPad; typedef struct _GstGhostPadClass GstGhostPadClass; -/*typedef struct _GstPadTemplate GstPadTemplate;*/ -/*typedef struct _GstPadTemplateClass GstPadTemplateClass;*/ typedef struct _GstStaticPadTemplate GstStaticPadTemplate; typedef struct _GstPadLink GstPadLink; @@ -119,7 +114,6 @@ typedef gboolean (*GstPadQueryFunction) (GstPad *pad, GstQueryType type, GstFormat *format, gint64 *value); typedef GList* (*GstPadIntLinkFunction) (GstPad *pad); typedef const GstFormat* (*GstPadFormatsFunction) (GstPad *pad); -typedef const GstEventMask* (*GstPadEventMaskFunction) (GstPad *pad); typedef const GstQueryType* (*GstPadQueryTypeFunction) (GstPad *pad); typedef GstPadLinkReturn (*GstPadLinkFunction) (GstPad *pad, const GstCaps *caps); @@ -137,8 +131,7 @@ typedef enum { } GstPadDirection; typedef enum { - GST_PAD_DISABLED = GST_OBJECT_FLAG_LAST, - GST_PAD_NEGOTIATING, + GST_PAD_NEGOTIATING = GST_OBJECT_FLAG_LAST, GST_PAD_DISPATCHING, GST_PAD_FLAG_LAST = GST_OBJECT_FLAG_LAST + 4 @@ -185,13 +178,8 @@ struct _GstRealPad { gpointer sched_private; /* data transport functions */ - GstPadChainFunction chainfunc; - GstPadChainFunction chainhandler; - GstPadGetFunction getfunc; - GstPadGetFunction gethandler; - GstPadEventFunction eventfunc; - GstPadEventFunction eventhandler; - GstPadEventMaskFunction eventmaskfunc; + GstAction * action; + GstPadEventFunction eventhandler; GList *ghostpads; @@ -250,18 +238,10 @@ struct _GstGhostPadClass { #define GST_RPAD_CAPS(pad) (((GstRealPad *)(pad))->caps) #define GST_RPAD_APPFILTER(pad) (((GstRealPad *)(pad))->appfilter) #define GST_RPAD_PEER(pad) (((GstRealPad *)(pad))->peer) -#define GST_RPAD_CHAINFUNC(pad) (((GstRealPad *)(pad))->chainfunc) -#define GST_RPAD_CHAINHANDLER(pad) (((GstRealPad *)(pad))->chainhandler) -#define GST_RPAD_GETFUNC(pad) (((GstRealPad *)(pad))->getfunc) -#define GST_RPAD_GETHANDLER(pad) (((GstRealPad *)(pad))->gethandler) -#define GST_RPAD_EVENTFUNC(pad) (((GstRealPad *)(pad))->eventfunc) #define GST_RPAD_EVENTHANDLER(pad) (((GstRealPad *)(pad))->eventhandler) #define GST_RPAD_CONVERTFUNC(pad) (((GstRealPad *)(pad))->convertfunc) #define GST_RPAD_QUERYFUNC(pad) (((GstRealPad *)(pad))->queryfunc) #define GST_RPAD_INTLINKFUNC(pad) (((GstRealPad *)(pad))->intlinkfunc) -#define GST_RPAD_FORMATSFUNC(pad) (((GstRealPad *)(pad))->formatsfunc) -#define GST_RPAD_QUERYTYPEFUNC(pad) (((GstRealPad *)(pad))->querytypefunc) -#define GST_RPAD_EVENTMASKFUNC(pad) (((GstRealPad *)(pad))->eventmaskfunc) #define GST_RPAD_LINKFUNC(pad) (((GstRealPad *)(pad))->linkfunc) #define GST_RPAD_UNLINKFUNC(pad) (((GstRealPad *)(pad))->unlinkfunc) @@ -282,12 +262,8 @@ struct _GstGhostPadClass { /* Some check functions (unused?) */ #define GST_PAD_IS_LINKED(pad) (GST_PAD_PEER(pad) != NULL) -#define GST_PAD_IS_ACTIVE(pad) (!GST_FLAG_IS_SET(GST_PAD_REALIZE(pad), GST_PAD_DISABLED)) #define GST_PAD_IS_NEGOTIATING(pad) (GST_FLAG_IS_SET (pad, GST_PAD_NEGOTIATING)) #define GST_PAD_IS_DISPATCHING(pad) (GST_FLAG_IS_SET (pad, GST_PAD_DISPATCHING)) -#define GST_PAD_IS_USABLE(pad) (GST_PAD_IS_LINKED (pad) && \ - GST_PAD_IS_ACTIVE(pad) && GST_PAD_IS_ACTIVE(GST_PAD_PEER (pad))) -#define GST_PAD_CAN_PULL(pad) (GST_IS_REAL_PAD(pad) && GST_REAL_PAD(pad)->gethandler != NULL) #define GST_PAD_IS_SRC(pad) (GST_PAD_DIRECTION(pad) == GST_PAD_SRC) #define GST_PAD_IS_SINK(pad) (GST_PAD_DIRECTION(pad) == GST_PAD_SINK) @@ -368,9 +344,9 @@ G_CONST_RETURN gchar* gst_pad_get_name (GstPad *pad); GstPadDirection gst_pad_get_direction (GstPad *pad); -void gst_pad_set_active (GstPad *pad, gboolean active); -void gst_pad_set_active_recursive (GstPad *pad, gboolean active); -gboolean gst_pad_is_active (GstPad *pad); +void gst_real_pad_set_active (GstRealPad *pad, gboolean active); +gboolean gst_real_pad_is_active (GstRealPad *pad); +void gst_real_pad_set_initially_active (GstRealPad *pad, gboolean active); void gst_pad_set_element_private (GstPad *pad, gpointer priv); gpointer gst_pad_get_element_private (GstPad *pad); @@ -391,14 +367,9 @@ void gst_pad_set_bufferalloc_function (GstPad *pad, GstPadBufferAllocFunction GstBuffer* gst_pad_alloc_buffer (GstPad *pad, guint64 offset, gint size); /* data passing setup functions */ -void gst_pad_set_chain_function (GstPad *pad, GstPadChainFunction chain); -void gst_pad_set_get_function (GstPad *pad, GstPadGetFunction get); +void gst_src_pad_set_action_handler (GstPad *pad, GstActionSrcPadFunc func); +void gst_sink_pad_set_action_handler (GstPad *pad, GstActionSinkPadFunc func); void gst_pad_set_event_function (GstPad *pad, GstPadEventFunction event); -void gst_pad_set_event_mask_function (GstPad *pad, GstPadEventMaskFunction mask_func); -G_CONST_RETURN GstEventMask* - gst_pad_get_event_masks (GstPad *pad); -G_CONST_RETURN GstEventMask* - gst_pad_get_event_masks_default (GstPad *pad); /* pad links */ void gst_pad_set_link_function (GstPad *pad, GstPadLinkFunction link); @@ -446,27 +417,10 @@ gboolean gst_pad_recover_caps_error (GstPad *pad, const GstCaps *allowed); /* data passing functions */ 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); -#ifndef GST_DISABLE_DEPRECATED -GstPad* gst_pad_selectv (GList *padlist); -GstPad* gst_pad_select (GstPad *pad, ...); -GstPad* gst_pad_select_valist (GstPad *pad, va_list varargs); -#endif -/* FIXME 0.9: rename to _select? Otherwise rename SchedulerClass pointer */ -GstData * gst_pad_collectv (GstPad **selected, const GList *padlist); -GstData * gst_pad_collect (GstPad **selected, GstPad *pad, ...); -GstData * gst_pad_collect_valist (GstPad **selected, GstPad *pad, va_list varargs); - -/* convert/query/format functions */ -void gst_pad_set_formats_function (GstPad *pad, - GstPadFormatsFunction formats); -G_CONST_RETURN GstFormat* - gst_pad_get_formats (GstPad *pad); -G_CONST_RETURN GstFormat* - gst_pad_get_formats_default (GstPad *pad); +/* convert/query functions */ void gst_pad_set_convert_function (GstPad *pad, GstPadConvertFunction convert); gboolean gst_pad_convert (GstPad *pad, GstFormat src_format, gint64 src_value, @@ -476,11 +430,6 @@ gboolean gst_pad_convert_default (GstPad *pad, GstFormat *dest_format, gint64 *dest_value); void gst_pad_set_query_function (GstPad *pad, GstPadQueryFunction query); -void gst_pad_set_query_type_function (GstPad *pad, GstPadQueryTypeFunction type_func); -G_CONST_RETURN GstQueryType* - gst_pad_get_query_types (GstPad *pad); -G_CONST_RETURN GstQueryType* - gst_pad_get_query_types_default (GstPad *pad); gboolean gst_pad_query (GstPad *pad, GstQueryType type, GstFormat *format, gint64 *value); gboolean gst_pad_query_default (GstPad *pad, GstQueryType type, diff --git a/gst/gstpipeline.c b/gst/gstpipeline.c index acfb8f3991..17a2a5e0b7 100644 --- a/gst/gstpipeline.c +++ b/gst/gstpipeline.c @@ -25,6 +25,7 @@ #include "gstpipeline.h" #include "gstinfo.h" #include "gstscheduler.h" +#include "gstschedulerfactory.h" static GstElementDetails gst_pipeline_details = GST_ELEMENT_DETAILS ("Pipeline object", @@ -52,8 +53,6 @@ static void gst_pipeline_init (GTypeInstance * instance, gpointer g_class); static void gst_pipeline_dispose (GObject * object); -static GstElementStateReturn gst_pipeline_change_state (GstElement * element); - static GstBinClass *parent_class = NULL; /* static guint gst_pipeline_signals[LAST_SIGNAL] = { 0 }; */ @@ -95,15 +94,11 @@ static void gst_pipeline_class_init (gpointer g_class, gpointer class_data) { GObjectClass *gobject_class = G_OBJECT_CLASS (g_class); - GstElementClass *gstelement_class = GST_ELEMENT_CLASS (g_class); GstPipelineClass *klass = GST_PIPELINE_CLASS (g_class); parent_class = g_type_class_peek_parent (klass); gobject_class->dispose = GST_DEBUG_FUNCPTR (gst_pipeline_dispose); - - gstelement_class->change_state = - GST_DEBUG_FUNCPTR (gst_pipeline_change_state); } static void @@ -137,7 +132,6 @@ gst_pipeline_dispose (GObject * object) g_assert (GST_IS_SCHEDULER (GST_ELEMENT_SCHED (pipeline))); sched = GST_ELEMENT_SCHED (pipeline); - gst_scheduler_reset (sched); G_OBJECT_CLASS (parent_class)->dispose (object); } @@ -154,24 +148,3 @@ gst_pipeline_new (const gchar * name) { return gst_element_factory_make ("pipeline", name); } - -static GstElementStateReturn -gst_pipeline_change_state (GstElement * element) -{ - switch (GST_STATE_TRANSITION (element)) { - case GST_STATE_NULL_TO_READY: - gst_scheduler_setup (GST_ELEMENT_SCHED (element)); - break; - case GST_STATE_READY_TO_PAUSED: - case GST_STATE_PAUSED_TO_PLAYING: - case GST_STATE_PLAYING_TO_PAUSED: - case GST_STATE_PAUSED_TO_READY: - case GST_STATE_READY_TO_NULL: - break; - } - - if (GST_ELEMENT_CLASS (parent_class)->change_state) - return GST_ELEMENT_CLASS (parent_class)->change_state (element); - - return GST_STATE_SUCCESS; -} diff --git a/gst/gstqueue.c b/gst/gstqueue.c index 1e1b803ad0..a6c13f87b3 100644 --- a/gst/gstqueue.c +++ b/gst/gstqueue.c @@ -2,6 +2,7 @@ * Copyright (C) 1999,2000 Erik Walthinsen * 2000 Wim Taymans * 2003 Colin Walters + * 2004 Benjamin Otte * * gstqueue.c: * @@ -29,41 +30,17 @@ #include "gstevent.h" #include "gstinfo.h" #include "gsterror.h" +#include "gstaction.h" -static GstStaticPadTemplate sinktemplate = GST_STATIC_PAD_TEMPLATE ("sink", - GST_PAD_SINK, - GST_PAD_ALWAYS, - GST_STATIC_CAPS_ANY); - -static GstStaticPadTemplate srctemplate = GST_STATIC_PAD_TEMPLATE ("src", - GST_PAD_SRC, - GST_PAD_ALWAYS, - GST_STATIC_CAPS_ANY); - -GST_DEBUG_CATEGORY_STATIC (queue_dataflow); -#define GST_CAT_DEFAULT (queue_dataflow) - -#define STATUS(queue, msg) \ - GST_CAT_LOG_OBJECT (queue_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_threshold.buffers, \ - queue->max_size.buffers, \ - queue->cur_level.bytes, \ - queue->min_threshold.bytes, \ - queue->max_size.bytes, \ - queue->cur_level.time, \ - queue->min_threshold.time, \ - queue->max_size.time, \ - queue->queue->length) - +/* +GST_DEBUG_CATEGORY_STATIC (queue_dataflow, "queue_dataflow", 0, + "dataflow inside the queue element"); +#define GST_CAT_DEFAULT queue_dataflow +*/ static GstElementDetails gst_queue_details = GST_ELEMENT_DETAILS ("Queue", "Generic", "Simple data queue", - "Erik Walthinsen "); + "Erik Walthinsen , " "Benjamin Otte "); /* Queue signals and args */ @@ -89,30 +66,13 @@ enum ARG_MIN_THRESHOLD_BUFFERS, ARG_MIN_THRESHOLD_BYTES, ARG_MIN_THRESHOLD_TIME, + ARG_MAX_THRESHOLD_BUFFERS, + ARG_MAX_THRESHOLD_BYTES, + ARG_MAX_THRESHOLD_TIME, ARG_LEAKY, - ARG_MAY_DEADLOCK, - ARG_BLOCK_TIMEOUT - /* FILL ME */ + /* FILL ME */ }; -#define GST_QUEUE_MUTEX_LOCK G_STMT_START { \ - GST_CAT_LOG_OBJECT (queue_dataflow, queue, \ - "locking qlock from thread %p", \ - g_thread_self ()); \ - g_mutex_lock (queue->qlock); \ - GST_CAT_LOG_OBJECT (queue_dataflow, queue, \ - "locked qlock from thread %p", \ - g_thread_self ()); \ -} G_STMT_END - -#define GST_QUEUE_MUTEX_UNLOCK G_STMT_START { \ - GST_CAT_LOG_OBJECT (queue_dataflow, queue, \ - "unlocking qlock from thread %p", \ - g_thread_self ()); \ - g_mutex_unlock (queue->qlock); \ -} G_STMT_END - - typedef struct _GstQueueEventResponse { GstEvent *event; @@ -130,21 +90,17 @@ static void gst_queue_set_property (GObject * object, static void gst_queue_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec); -static void gst_queue_chain (GstPad * pad, GstData * data); -static GstData *gst_queue_get (GstPad * pad); +static GstData *gst_queue_release_srcpad (GstAction * action, GstRealPad * pad); +static void gst_queue_release_sinkpad (GstAction * action, GstRealPad * pad, + GstData * data); static gboolean gst_queue_handle_src_event (GstPad * pad, GstEvent * event); -static gboolean gst_queue_handle_src_query (GstPad * pad, - GstQueryType type, GstFormat * fmt, gint64 * value); static GstCaps *gst_queue_getcaps (GstPad * pad); -static GstPadLinkReturn -gst_queue_link_sink (GstPad * pad, const GstCaps * caps); -static GstPadLinkReturn gst_queue_link_src (GstPad * pad, const GstCaps * caps); +static GstPadLinkReturn gst_queue_link (GstPad * pad, const GstCaps * caps); static void gst_queue_locked_flush (GstQueue * queue); 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 ()) @@ -190,8 +146,6 @@ gst_queue_get_type (void) queue_type = g_type_register_static (GST_TYPE_ELEMENT, "GstQueue", &queue_info, 0); - GST_DEBUG_CATEGORY_INIT (queue_dataflow, "queue_dataflow", 0, - "dataflow inside the queue element"); } return queue_type; @@ -202,10 +156,6 @@ gst_queue_base_init (GstQueueClass * klass) { GstElementClass *gstelement_class = GST_ELEMENT_CLASS (klass); - gst_element_class_add_pad_template (gstelement_class, - gst_static_pad_template_get (&srctemplate)); - gst_element_class_add_pad_template (gstelement_class, - gst_static_pad_template_get (&sinktemplate)); gst_element_class_set_details (gstelement_class, &gst_queue_details); } @@ -231,6 +181,11 @@ gst_queue_class_init (GstQueueClass * klass) G_STRUCT_OFFSET (GstQueueClass, overrun), NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); + /* set several parent class virtual functions */ + gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_queue_finalize); + 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)", @@ -271,62 +226,48 @@ gst_queue_class_init (GstQueueClass * klass) "Min. amount of data in the queue to allow reading (in ns, 0=disable)", 0, G_MAXUINT64, 0, G_PARAM_READWRITE)); + g_object_class_install_property (gobject_class, ARG_MAX_THRESHOLD_BYTES, + g_param_spec_uint ("max-threshold-bytes", "Max. threshold (kB)", + "Max. amount of data in the queue to allow writing (bytes, 0=disable)", + 0, G_MAXUINT, 0, G_PARAM_READWRITE)); + g_object_class_install_property (gobject_class, ARG_MAX_THRESHOLD_BUFFERS, + g_param_spec_uint ("max-threshold-buffers", "Max. threshold (buffers)", + "Max. number of buffers in the queue to allow writing (0=disable)", + 0, G_MAXUINT, 0, G_PARAM_READWRITE)); + g_object_class_install_property (gobject_class, ARG_MAX_THRESHOLD_TIME, + g_param_spec_uint64 ("max-threshold-time", "Max. threshold (ns)", + "Max. amount of data in the queue to allow writing (in ns, 0=disable)", + 0, G_MAXUINT64, 0, G_PARAM_READWRITE)); + 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)); - - /* set several parent class virtual functions */ - gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_queue_finalize); - gobject_class->set_property = GST_DEBUG_FUNCPTR (gst_queue_set_property); - gobject_class->get_property = GST_DEBUG_FUNCPTR (gst_queue_get_property); 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 (GstQueue * queue) { - /* scheduling on this kind of element is, well, interesting */ - GST_FLAG_SET (queue, GST_ELEMENT_DECOUPLED); GST_FLAG_SET (queue, GST_ELEMENT_EVENT_AWARE); - queue->sinkpad = - gst_pad_new_from_template (gst_static_pad_template_get (&sinktemplate), - "sink"); - gst_pad_set_chain_function (queue->sinkpad, - GST_DEBUG_FUNCPTR (gst_queue_chain)); + queue->sinkpad = gst_pad_new ("sink", GST_PAD_SINK); + gst_sink_pad_set_action_handler (queue->sinkpad, gst_queue_release_sinkpad); gst_element_add_pad (GST_ELEMENT (queue), queue->sinkpad); gst_pad_set_link_function (queue->sinkpad, - GST_DEBUG_FUNCPTR (gst_queue_link_sink)); + GST_DEBUG_FUNCPTR (gst_queue_link)); gst_pad_set_getcaps_function (queue->sinkpad, GST_DEBUG_FUNCPTR (gst_queue_getcaps)); - gst_pad_set_active (queue->sinkpad, TRUE); - queue->srcpad = - gst_pad_new_from_template (gst_static_pad_template_get (&srctemplate), - "src"); - gst_pad_set_get_function (queue->srcpad, GST_DEBUG_FUNCPTR (gst_queue_get)); + queue->srcpad = gst_pad_new ("src", GST_PAD_SRC); + gst_src_pad_set_action_handler (queue->srcpad, gst_queue_release_srcpad); gst_element_add_pad (GST_ELEMENT (queue), queue->srcpad); - gst_pad_set_link_function (queue->srcpad, - GST_DEBUG_FUNCPTR (gst_queue_link_src)); + gst_pad_set_link_function (queue->srcpad, GST_DEBUG_FUNCPTR (gst_queue_link)); gst_pad_set_getcaps_function (queue->srcpad, GST_DEBUG_FUNCPTR (gst_queue_getcaps)); gst_pad_set_event_function (queue->srcpad, GST_DEBUG_FUNCPTR (gst_queue_handle_src_event)); - gst_pad_set_query_function (queue->srcpad, - GST_DEBUG_FUNCPTR (gst_queue_handle_src_query)); - gst_pad_set_active (queue->srcpad, TRUE); queue->cur_level.buffers = 0; /* no content */ queue->cur_level.bytes = 0; /* no content */ @@ -337,25 +278,17 @@ gst_queue_init (GstQueue * queue) queue->min_threshold.buffers = 0; /* no threshold */ queue->min_threshold.bytes = 0; /* no threshold */ queue->min_threshold.time = 0; /* no threshold */ + queue->max_threshold.buffers = 0; /* no threshold */ + queue->max_threshold.bytes = 0; /* no threshold */ + queue->max_threshold.time = 0; /* no threshold */ queue->leaky = GST_QUEUE_NO_LEAK; - queue->may_deadlock = TRUE; - queue->block_timeout = GST_CLOCK_TIME_NONE; - queue->interrupt = FALSE; - queue->flush = FALSE; queue->qlock = g_mutex_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->event_lock = g_mutex_new (); queue->queue = g_queue_new (); GST_CAT_DEBUG_OBJECT (GST_CAT_THREAD, queue, "initialized queue's not_empty & not_full conditions"); - - GST_FLAG_SET (queue, GST_ELEMENT_WORK_IN_PLACE); } /* called only once, as opposed to dispose */ @@ -373,19 +306,6 @@ gst_queue_finalize (GObject * object) } 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); - g_mutex_lock (queue->event_lock); - while (!g_queue_is_empty (queue->events)) { - GstQueueEventResponse *er = g_queue_pop_head (queue->events); - - gst_event_unref (er->event); - g_free (er); - } - g_mutex_unlock (queue->event_lock); - g_mutex_free (queue->event_lock); - g_queue_free (queue->events); if (G_OBJECT_CLASS (parent_class)->finalize) G_OBJECT_CLASS (parent_class)->finalize (object); @@ -398,7 +318,7 @@ gst_queue_getcaps (GstPad * pad) queue = GST_QUEUE (gst_pad_get_parent (pad)); - if (pad == queue->srcpad && queue->cur_level.bytes > 0) { + if (queue->cur_level.bytes > 0) { return gst_caps_copy (queue->negotiated_caps); } @@ -406,53 +326,11 @@ gst_queue_getcaps (GstPad * pad) } static GstPadLinkReturn -gst_queue_link_sink (GstPad * pad, const GstCaps * caps) +gst_queue_link (GstPad * pad, const GstCaps * caps) { GstQueue *queue; - GstPadLinkReturn link_ret; - - queue = GST_QUEUE (gst_pad_get_parent (pad)); - - if (queue->cur_level.bytes > 0) { - if (gst_caps_is_equal (caps, queue->negotiated_caps)) { - return GST_PAD_LINK_OK; - } else if (GST_STATE (queue) != GST_STATE_PLAYING) { - return GST_PAD_LINK_DELAYED; - } - - /* Wait until the queue is empty before attempting the pad - negotiation. */ - GST_QUEUE_MUTEX_LOCK; - - STATUS (queue, "waiting for queue to get empty"); - while (queue->cur_level.bytes > 0) { - g_cond_wait (queue->item_del, queue->qlock); - if (queue->interrupt) { - GST_QUEUE_MUTEX_UNLOCK; - return GST_PAD_LINK_DELAYED; - } - } - STATUS (queue, "queue is now empty"); - - GST_QUEUE_MUTEX_UNLOCK; - } - - link_ret = gst_pad_proxy_pad_link (pad, caps); - - if (GST_PAD_LINK_SUCCESSFUL (link_ret)) { - /* we store an extra copy of the negotiated caps, just in case - * the pads become unnegotiated while we have buffers */ - gst_caps_replace (&queue->negotiated_caps, gst_caps_copy (caps)); - } - - return link_ret; -} - -static GstPadLinkReturn -gst_queue_link_src (GstPad * pad, const GstCaps * caps) -{ - GstQueue *queue; - GstPadLinkReturn link_ret; + GstPadLinkReturn ret; + GstPad *otherpad; queue = GST_QUEUE (gst_pad_get_parent (pad)); @@ -463,105 +341,140 @@ gst_queue_link_src (GstPad * pad, const GstCaps * caps) return GST_PAD_LINK_REFUSED; } - link_ret = gst_pad_proxy_pad_link (pad, caps); + otherpad = (pad == queue->srcpad) ? queue->sinkpad : queue->srcpad; + ret = gst_pad_try_set_caps (otherpad, caps); - if (GST_PAD_LINK_SUCCESSFUL (link_ret)) { + if (GST_PAD_LINK_SUCCESSFUL (ret)) { /* we store an extra copy of the negotiated caps, just in case * the pads become unnegotiated while we have buffers */ gst_caps_replace (&queue->negotiated_caps, gst_caps_copy (caps)); } - return link_ret; + return ret; } static void gst_queue_locked_flush (GstQueue * queue) { - GST_CAT_LOG_OBJECT (queue_dataflow, queue, "Flushing contents..."); + GstData *data; - while (!g_queue_is_empty (queue->queue)) { - GstData *data = g_queue_pop_head (queue->queue); - - /* First loose the reference we added when putting that data in the queue */ - gst_data_unref (data); - /* Then loose another reference because we are supposed to destroy that - data when flushing */ + while ((data = g_queue_pop_head (queue->queue))) { gst_data_unref (data); } - queue->timeval = NULL; + g_assert (g_queue_is_empty (queue->queue)); 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; - - /* we deleted something... */ - g_cond_signal (queue->item_del); + GST_DEBUG_OBJECT (queue, "flushed"); + /* FIXME: wakeup sinkpad here? */ } +/* holds lock */ static void -gst_queue_handle_pending_events (GstQueue * queue) +gst_queue_add_data (GstQueue * queue, GstData * data) { - /* check for events to send upstream */ - /* g_queue_get_length is glib 2.4, so don't depend on it yet, use ->length */ - GST_CAT_DEBUG_OBJECT (queue_dataflow, queue, - "handling pending events, events queue of size %d", - queue->events->length); - g_mutex_lock (queue->event_lock); - while (!g_queue_is_empty (queue->events)) { - GstQueueEventResponse *er; - gboolean need_response; + g_queue_push_tail (queue->queue, data); - er = g_queue_pop_head (queue->events); - - GST_CAT_DEBUG_OBJECT (queue_dataflow, queue, - "sending event %p (%d) from event response %p upstream", - er->event, GST_EVENT_TYPE (er->event), er); - if (er->handled) { - /* change this to an assert when this file gets reviewed properly. */ - GST_ELEMENT_ERROR (queue, CORE, EVENT, (NULL), - ("already handled event %p (%d) from event response %p upstream", - er->event, GST_EVENT_TYPE (er->event), er)); - break; - } - g_mutex_unlock (queue->event_lock); - - need_response = - GST_DATA_FLAG_IS_SET (GST_DATA (er->event), - GST_EVENT_COMMON_FLAG_NEED_RESPONSE); - er->ret = gst_pad_event_default (queue->srcpad, er->event); - if (need_response) { - er->handled = TRUE; - g_cond_signal (queue->event_done); - } else { - g_free (er); - } - g_mutex_lock (queue->event_lock); - GST_CAT_DEBUG_OBJECT (queue_dataflow, queue, "event sent"); + queue->cur_level.items++; + 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); } - g_mutex_unlock (queue->event_lock); +} + +/* holds lock */ +static GstData * +gst_queue_remove_data (GstQueue * queue, GstData * data) +{ + if (data == NULL) { + data = g_queue_pop_head (queue->queue); + } else { + g_queue_remove (queue->queue, data); + } + if (!data) { + return NULL; + } + queue->cur_level.items--; + 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); + } + return data; +} + +/* check if one of the sizes is smaller than the current size */ +static gboolean +gst_queue_is_smaller (GstQueue * queue, GstQueueSize * size) +{ + if (size->items > 0 && size->items < queue->cur_level.items) + return TRUE; + if (size->buffers > 0 && size->buffers < queue->cur_level.buffers) + return TRUE; + if (size->bytes > 0 && size->bytes < queue->cur_level.bytes) + return TRUE; + if (size->time > 0 && size->time < queue->cur_level.time) + return TRUE; + return FALSE; +} + +/* check if one of the sizes is bigger than the current size */ +static gboolean +gst_queue_is_bigger (GstQueue * queue, GstQueueSize * size) +{ + if (size->items > 0 && size->items >= queue->cur_level.items) + return TRUE; + if (size->buffers > 0 && size->buffers >= queue->cur_level.buffers) + return TRUE; + if (size->bytes > 0 && size->bytes >= queue->cur_level.bytes) + return TRUE; + if (size->time > 0 && size->time >= queue->cur_level.time) + return TRUE; + return FALSE; +} + +#define STATUS(queue, msg) \ + GST_LOG_OBJECT (queue, \ + msg ": %u of %u-%u buffers, %u of %u-%u " \ + "bytes, %" G_GUINT64_FORMAT " of %" G_GUINT64_FORMAT \ + "-%" G_GUINT64_FORMAT " ns, %u elements", \ + queue->cur_level.buffers, \ + queue->min_threshold.buffers, \ + queue->max_size.buffers, \ + queue->cur_level.bytes, \ + queue->min_threshold.bytes, \ + queue->max_size.bytes, \ + queue->cur_level.time, \ + queue->min_threshold.time, \ + queue->max_size.time, \ + queue->queue->length) + +static gint +is_buffer (gconstpointer buf, gconstpointer unused) +{ + if (GST_IS_BUFFER (buf)); + return 0; + return 1; +} + +static gint +is_buffer_last (gconstpointer buf, gconstpointer datap) +{ + GstData **data = (GstData **) datap; + + if (GST_IS_BUFFER (buf)); + *data = (GstData *) buf; + return 1; } static void -gst_queue_chain (GstPad * pad, GstData * data) +gst_queue_release_sinkpad (GstAction * action, GstRealPad * pad, GstData * data) { - GstQueue *queue; - - g_return_if_fail (pad != NULL); - g_return_if_fail (GST_IS_PAD (pad)); - g_return_if_fail (data != NULL); - - queue = GST_QUEUE (GST_OBJECT_PARENT (pad)); - -restart: - /* we have to lock the queue since we span threads */ - GST_QUEUE_MUTEX_LOCK; - - gst_queue_handle_pending_events (queue); - - /* assume don't need to flush this buffer when the queue is filled */ - queue->flush = FALSE; + gboolean ret = TRUE; + GstQueue *queue = GST_QUEUE (gst_pad_get_parent (GST_PAD (pad))); if (GST_IS_EVENT (data)) { switch (GST_EVENT_TYPE (data)) { @@ -572,485 +485,171 @@ restart: break; case GST_EVENT_EOS: STATUS (queue, "received EOS"); + queue->got_eos = TRUE; + ret = FALSE; break; default: /* we put the event in the queue, we don't have to act ourselves */ - GST_CAT_LOG_OBJECT (queue_dataflow, queue, + GST_LOG_OBJECT (queue, "adding event %p of type %d", data, GST_EVENT_TYPE (data)); break; } } - if (GST_IS_BUFFER (data)) - GST_CAT_LOG_OBJECT (queue_dataflow, queue, - "adding buffer %p of size %d and time %" GST_TIME_FORMAT, - data, GST_BUFFER_SIZE (data), - GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (data))); + gst_queue_add_data (queue, data); + + if (GST_IS_BUFFER (data)) { + GST_LOG_OBJECT (queue, + "adding buffer %p of size %d", data, GST_BUFFER_SIZE (data)); + } else { + GST_LOG_OBJECT (queue, + "adding event %p of type %d", data, GST_EVENT_TYPE (data)); + } + STATUS (queue, "+ level"); /* 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))) { - GST_QUEUE_MUTEX_UNLOCK; + * We always handle events and they don't count in our statistics. + * We still check, it could be someone changed properties */ + if (gst_queue_is_smaller (queue, &queue->max_size)) { g_signal_emit (G_OBJECT (queue), gst_queue_signals[SIGNAL_OVERRUN], 0); - GST_QUEUE_MUTEX_LOCK; + /* FIXME: need to recheck no buffers got processed? */ /* how are we going to make space for this buffer? */ switch (queue->leaky) { - /* leak current buffer */ + /* leak buffers from end of queue */ case GST_QUEUE_LEAK_UPSTREAM: - GST_CAT_DEBUG_OBJECT (queue_dataflow, queue, - "queue is full, leaking buffer on upstream end"); - /* now we can clean up and exit right away */ - GST_QUEUE_MUTEX_UNLOCK; - goto out_unref; + do { + GstData *leak; - /* 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; + g_queue_find_custom (queue->queue, &leak, is_buffer_last); + g_assert (leak); - GST_CAT_DEBUG_OBJECT (queue_dataflow, queue, - "queue is full, leaking buffer on downstream end"); + GST_DEBUG_OBJECT (queue, + "queue is full, leaking buffer %p on upstream end", leak); + gst_queue_remove_data (queue, leak); + gst_data_unref (leak); + } while (gst_queue_is_smaller (queue, &queue->max_size)); - for (item = queue->queue->head; item != NULL; item = item->next) { - if (GST_IS_BUFFER (item->data)) { - leak = item->data; - break; - } - } + case GST_QUEUE_LEAK_DOWNSTREAM: + /* leak buffers from front of the queue */ + do { + GList *item = g_queue_find_custom (queue->queue, NULL, is_buffer); + GstData *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); + g_assert (item); + leak = item->data; - /* 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--; + GST_DEBUG_OBJECT (queue, + "queue is full, leaking buffer %p on downstream end", leak); + gst_queue_remove_data (queue, leak); + gst_data_unref (leak); + } while (gst_queue_is_smaller (queue, &queue->max_size)); - /* 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; - } default: g_warning ("Unknown leaky type, using default"); /* fall-through */ - /* 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) { - GstScheduler *sched; - - GST_CAT_DEBUG_OBJECT (queue_dataflow, queue, "interrupted"); - sched = gst_pad_get_scheduler (queue->sinkpad); - if (!sched || gst_scheduler_interrupt (sched, GST_ELEMENT (queue))) { - goto ignore_interrupt; - } - GST_QUEUE_MUTEX_UNLOCK; - /* 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 (queue_dataflow, queue, - "not adding pending buffer after flush"); - goto out_unref; - } - GST_CAT_DEBUG_OBJECT (queue_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) { - GST_QUEUE_MUTEX_UNLOCK; - gst_data_unref (data); - GST_ELEMENT_ERROR (queue, CORE, THREAD, (NULL), - ("deadlock found, shutting down source pad elements")); - /* 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 (queue_dataflow, queue, - "%s: waiting for the app to restart " - "source pad elements", GST_ELEMENT_NAME (queue)); - } - } - - ignore_interrupt: - /* 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); - - if (!queue->interrupt) { - STATUS (queue, - "waiting for item_del signal from thread using qlock"); - g_cond_wait (queue->item_del, queue->qlock); - STATUS (queue, "received item_del signal from thread using qlock"); - } else { - GST_CAT_DEBUG_OBJECT (queue_dataflow, queue, - "Not waiting, just adding buffer, after interrupt (bad!)"); - break; - } - } - - STATUS (queue, "post-full wait"); - GST_QUEUE_MUTEX_UNLOCK; - g_signal_emit (G_OBJECT (queue), gst_queue_signals[SIGNAL_RUNNING], 0); - GST_QUEUE_MUTEX_LOCK; - break; + /* don't leak. Instead, wait for space to be available */ + /* wake up other pad in any case */ + gst_real_pad_set_active (GST_REAL_PAD (queue->srcpad), TRUE); + gst_real_pad_set_active (GST_REAL_PAD (queue->sinkpad), FALSE); } } - /* 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); - - /* 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); + if (gst_queue_is_smaller (queue, &queue->max_threshold) || + queue->max_threshold.items + queue->max_threshold.buffers + + queue->max_threshold.bytes + queue->max_threshold.time == 0) { + gst_real_pad_set_active (GST_REAL_PAD (queue->srcpad), TRUE); } - STATUS (queue, "+ level"); - - GST_CAT_LOG_OBJECT (queue_dataflow, queue, "signalling item_add"); - g_cond_signal (queue->item_add); - GST_QUEUE_MUTEX_UNLOCK; - - return; - -out_unref: - gst_data_unref (data); - return; + if (!ret) + gst_real_pad_set_active (GST_REAL_PAD (queue->sinkpad), FALSE); } static GstData * -gst_queue_get (GstPad * pad) +gst_queue_release_srcpad (GstAction * action, GstRealPad * pad) { - GstQueue *queue; GstData *data; - - g_return_val_if_fail (pad != NULL, NULL); - g_return_val_if_fail (GST_IS_PAD (pad), NULL); - - queue = GST_QUEUE (gst_pad_get_parent (pad)); - -restart: - /* have to lock for thread-safety */ - GST_QUEUE_MUTEX_LOCK; - - if (queue->queue->length == 0 || - (queue->min_threshold.buffers > 0 && - queue->cur_level.buffers < queue->min_threshold.buffers) || - (queue->min_threshold.bytes > 0 && - queue->cur_level.bytes < queue->min_threshold.bytes) || - (queue->min_threshold.time > 0 && - queue->cur_level.time < queue->min_threshold.time)) { - GST_QUEUE_MUTEX_UNLOCK; - g_signal_emit (G_OBJECT (queue), gst_queue_signals[SIGNAL_UNDERRUN], 0); - GST_QUEUE_MUTEX_LOCK; - - STATUS (queue, "pre-empty wait"); - while (queue->queue->length == 0 || - (queue->min_threshold.buffers > 0 && - queue->cur_level.buffers < queue->min_threshold.buffers) || - (queue->min_threshold.bytes > 0 && - queue->cur_level.bytes < queue->min_threshold.bytes) || - (queue->min_threshold.time > 0 && - queue->cur_level.time < queue->min_threshold.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) { - GstScheduler *sched; - - GST_CAT_DEBUG_OBJECT (queue_dataflow, queue, "interrupted"); - GST_QUEUE_MUTEX_UNLOCK; - sched = gst_pad_get_scheduler (queue->srcpad); - if (!sched || gst_scheduler_interrupt (sched, 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) { - GST_QUEUE_MUTEX_UNLOCK; - GST_ELEMENT_ERROR (queue, CORE, THREAD, (NULL), - ("deadlock found, shutting down sink pad elements")); - goto restart; - } else { - GST_CAT_WARNING_OBJECT (queue_dataflow, queue, - "%s: waiting for the app to restart " - "source pad elements", GST_ELEMENT_NAME (queue)); - } - } - - STATUS (queue, "waiting for item_add"); - - if (queue->block_timeout != GST_CLOCK_TIME_NONE) { - GTimeVal timeout; - - g_get_current_time (&timeout); - g_time_val_add (&timeout, queue->block_timeout / 1000); - GST_LOG_OBJECT (queue, "g_cond_time_wait using qlock from thread %p", - g_thread_self ()); - if (!g_cond_timed_wait (queue->item_add, queue->qlock, &timeout)) { - GST_QUEUE_MUTEX_UNLOCK; - GST_CAT_WARNING_OBJECT (queue_dataflow, queue, - "Sending filler event"); - return GST_DATA (gst_event_new_filler ()); - } - } else { - GST_LOG_OBJECT (queue, "doing g_cond_wait using qlock from thread %p", - g_thread_self ()); - g_cond_wait (queue->item_add, queue->qlock); - GST_LOG_OBJECT (queue, "done g_cond_wait using qlock from thread %p", - g_thread_self ()); - } - STATUS (queue, "got item_add signal"); - } - - STATUS (queue, "post-empty wait"); - GST_QUEUE_MUTEX_UNLOCK; - g_signal_emit (G_OBJECT (queue), gst_queue_signals[SIGNAL_RUNNING], 0); - GST_QUEUE_MUTEX_LOCK; - } + GstQueue *queue = GST_QUEUE (gst_pad_get_parent (GST_PAD (pad))); /* There's something in the list now, whatever it is */ - data = g_queue_pop_head (queue->queue); - GST_CAT_LOG_OBJECT (queue_dataflow, queue, - "retrieved data %p from queue", data); + GST_DEBUG_OBJECT (queue, "calling get function with %u elements in queue", + queue->cur_level.items); + data = gst_queue_remove_data (queue, NULL); + GST_LOG_OBJECT (queue, "retrieved data %p from queue", *data); + + if (data == NULL) { + /* queue is empty and we pulled? */ + GST_WARNING_OBJECT (queue, "queue is empty and we pulled?"); + gst_real_pad_set_active (GST_REAL_PAD (queue->sinkpad), TRUE); + gst_real_pad_set_active (GST_REAL_PAD (queue->srcpad), FALSE); + g_signal_emit (G_OBJECT (queue), gst_queue_signals[SIGNAL_UNDERRUN], 0); - if (data == NULL) return NULL; - - 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 (queue_dataflow, queue, - "Got buffer of time %" GST_TIME_FORMAT, - GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (data))); } - /* 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); + if ((gst_queue_is_bigger (queue, &queue->min_threshold) || + queue->min_threshold.items + queue->min_threshold.buffers + + queue->min_threshold.bytes + queue->min_threshold.time == 0) && + !queue->got_eos) { + gst_real_pad_set_active (GST_REAL_PAD (queue->sinkpad), TRUE); + } - STATUS (queue, "after _get()"); - - GST_CAT_LOG_OBJECT (queue_dataflow, queue, "signalling item_del"); - g_cond_signal (queue->item_del); - GST_QUEUE_MUTEX_UNLOCK; - - /* 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)) { case GST_EVENT_EOS: - GST_CAT_DEBUG_OBJECT (queue_dataflow, queue, - "queue \"%s\" eos", GST_ELEMENT_NAME (queue)); + GST_DEBUG_OBJECT (queue, "eos", GST_ELEMENT_NAME (queue)); gst_element_set_eos (GST_ELEMENT (queue)); + queue->got_eos = FALSE; + gst_real_pad_set_active (GST_REAL_PAD (queue->sinkpad), TRUE); break; default: break; } } + if (g_queue_is_empty (queue->queue)) { + g_signal_emit (G_OBJECT (queue), gst_queue_signals[SIGNAL_UNDERRUN], 0); + gst_real_pad_set_active (GST_REAL_PAD (queue->sinkpad), TRUE); + gst_real_pad_set_active (GST_REAL_PAD (queue->srcpad), FALSE); + } + return data; } - static gboolean gst_queue_handle_src_event (GstPad * pad, GstEvent * event) { GstQueue *queue = GST_QUEUE (gst_pad_get_parent (pad)); - gboolean res; - GstQueueEventResponse *er = NULL; + gboolean ret; - GST_CAT_DEBUG_OBJECT (queue_dataflow, queue, "got event %p (%d)", - event, GST_EVENT_TYPE (event)); - GST_QUEUE_MUTEX_LOCK; + GST_DEBUG_OBJECT (queue, "got event %p (%d)", event, GST_EVENT_TYPE (event)); - if (gst_element_get_state (GST_ELEMENT (queue)) == GST_STATE_PLAYING) { - gboolean need_response = GST_DATA_FLAG_IS_SET (GST_DATA (event), - GST_EVENT_COMMON_FLAG_NEED_RESPONSE); + ret = + gst_pad_send_event ((pad == + queue->srcpad) ? queue->sinkpad : queue->srcpad, event); + if (!ret) + return FALSE; - er = g_new (GstQueueEventResponse, 1); - - /* push the event to the queue and wait for upstream consumption */ - er->event = event; - er->handled = FALSE; - - g_mutex_lock (queue->event_lock); - GST_CAT_DEBUG_OBJECT (queue_dataflow, queue, - "putting event %p (%d) on internal queue", event, - GST_EVENT_TYPE (event)); - g_queue_push_tail (queue->events, er); - g_mutex_unlock (queue->event_lock); - - if (!need_response) { - /* Leave for upstream to delete */ - er = NULL; - res = TRUE; - goto handled; - } - - GST_CAT_WARNING_OBJECT (queue_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) { - GTimeVal timeout; - - g_get_current_time (&timeout); - g_time_val_add (&timeout, 500 * 1000); /* half a second */ - GST_LOG_OBJECT (queue, "doing g_cond_wait using qlock from thread %p", - g_thread_self ()); - if (!g_cond_timed_wait (queue->event_done, queue->qlock, &timeout) && - !er->handled) { - GST_CAT_WARNING_OBJECT (queue_dataflow, queue, - "timeout in upstream event handling, dropping event %p (%d)", - er->event, GST_EVENT_TYPE (er->event)); - g_mutex_lock (queue->event_lock); - /* since this queue is for src events (ie upstream), this thread is - * the only one that is pushing stuff on it, so we're sure that - * it's still the tail element. FIXME: But in practice, we should use - * GList instead of GQueue for this so we can remove any element in - * the list. */ - g_queue_pop_tail (queue->events); - g_mutex_unlock (queue->event_lock); - gst_event_unref (er->event); - res = FALSE; - goto handled; - } - } - GST_CAT_WARNING_OBJECT (queue_dataflow, queue, "Event handled"); - res = er->ret; - } else { - res = gst_pad_event_default (pad, event); - - switch (GST_EVENT_TYPE (event)) { - case GST_EVENT_FLUSH: - GST_CAT_DEBUG_OBJECT (queue_dataflow, queue, - "FLUSH event, flushing queue\n"); + switch (GST_EVENT_TYPE (event)) { + case GST_EVENT_FLUSH: + GST_DEBUG_OBJECT (queue, "FLUSH event, flushing queue\n"); + gst_queue_locked_flush (queue); + break; + case GST_EVENT_SEEK: + if (GST_EVENT_SEEK_FLAGS (event) & GST_SEEK_FLAG_FLUSH) { gst_queue_locked_flush (queue); - break; - case GST_EVENT_SEEK: - if (GST_EVENT_SEEK_FLAGS (event) & GST_SEEK_FLAG_FLUSH) { - gst_queue_locked_flush (queue); - } - break; - default: - break; - } + } + break; + default: + break; } -handled: - GST_QUEUE_MUTEX_UNLOCK; - - if (er) - g_free (er); - - return res; -} - -static gboolean -gst_queue_handle_src_query (GstPad * pad, - GstQueryType type, GstFormat * fmt, gint64 * value) -{ - GstQueue *queue = GST_QUEUE (gst_pad_get_parent (pad)); - gboolean res; - - if (!GST_PAD_PEER (queue->sinkpad)) - return FALSE; - res = gst_pad_query (GST_PAD_PEER (queue->sinkpad), type, fmt, value); - if (!res) - return FALSE; - - if (type == GST_QUERY_POSITION) { - /* FIXME: this code assumes that there's no discont in the queue */ - switch (*fmt) { - case GST_FORMAT_BYTES: - if (*value >= queue->cur_level.bytes) - *value -= queue->cur_level.bytes; - else - *value = 0; - break; - case GST_FORMAT_TIME: - if (*value >= queue->cur_level.time) - *value -= queue->cur_level.time; - else - *value = 0; - break; - default: - /* FIXME */ - break; - } - } - - return TRUE; -} - -static gboolean -gst_queue_release_locks (GstElement * element) -{ - GstQueue *queue; - - queue = GST_QUEUE (element); - - GST_QUEUE_MUTEX_LOCK; - queue->interrupt = TRUE; - g_cond_signal (queue->item_add); - g_cond_signal (queue->item_del); - GST_QUEUE_MUTEX_UNLOCK; - return TRUE; } @@ -1059,50 +658,16 @@ gst_queue_change_state (GstElement * element) { GstQueue *queue; GstElementStateReturn ret = GST_STATE_SUCCESS; + guint transition = GST_STATE_TRANSITION (element); queue = GST_QUEUE (element); - GST_CAT_LOG_OBJECT (GST_CAT_STATES, element, - "starting state change 0x%x", GST_STATE_TRANSITION (element)); + GST_CAT_LOG_OBJECT (GST_CAT_STATES, element, "starting state change"); - /* lock the queue so another thread (not in sync with this thread's state) - * can't call this queue's _get (or whatever) - */ - GST_QUEUE_MUTEX_LOCK; + if (GST_ELEMENT_CLASS (parent_class)->change_state) + ret = GST_ELEMENT_CLASS (parent_class)->change_state (element); - switch (GST_STATE_TRANSITION (element)) { - case GST_STATE_NULL_TO_READY: - gst_queue_locked_flush (queue); - 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)); - /* FIXME can this be? */ - g_cond_signal (queue->item_add); - - ret = GST_STATE_FAILURE; - goto unlock; - } else { - GstScheduler *src_sched, *sink_sched; - - 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)); - - g_warning ("queue %s does not connect different schedulers", - GST_ELEMENT_NAME (queue)); - - ret = GST_STATE_FAILURE; - goto unlock; - } - } - queue->interrupt = FALSE; - break; + switch (transition) { case GST_STATE_PAUSED_TO_READY: gst_queue_locked_flush (queue); gst_caps_replace (&queue->negotiated_caps, NULL); @@ -1111,40 +676,17 @@ gst_queue_change_state (GstElement * element) break; } - GST_QUEUE_MUTEX_UNLOCK; - - 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); - - GST_CAT_LOG_OBJECT (GST_CAT_STATES, element, "done with state change"); - - return ret; - -unlock: - GST_QUEUE_MUTEX_UNLOCK; - 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) { GstQueue *queue = GST_QUEUE (object); - /* someone could change levels here, and since this - * affects the get/put funcs, we need to lock for safety. */ - GST_QUEUE_MUTEX_LOCK; - switch (prop_id) { case ARG_MAX_SIZE_BYTES: queue->max_size.bytes = g_value_get_uint (value); @@ -1164,21 +706,22 @@ gst_queue_set_property (GObject * object, case ARG_MIN_THRESHOLD_TIME: queue->min_threshold.time = g_value_get_uint64 (value); break; + case ARG_MAX_THRESHOLD_BYTES: + queue->max_threshold.bytes = g_value_get_uint (value); + break; + case ARG_MAX_THRESHOLD_BUFFERS: + queue->max_threshold.buffers = g_value_get_uint (value); + break; + case ARG_MAX_THRESHOLD_TIME: + queue->max_threshold.time = g_value_get_uint64 (value); + break; case ARG_LEAKY: queue->leaky = g_value_get_enum (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_uint64 (value); - break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } - - GST_QUEUE_MUTEX_UNLOCK; } static void @@ -1215,15 +758,18 @@ gst_queue_get_property (GObject * object, case ARG_MIN_THRESHOLD_TIME: g_value_set_uint64 (value, queue->min_threshold.time); break; + case ARG_MAX_THRESHOLD_BYTES: + g_value_set_uint (value, queue->max_threshold.bytes); + break; + case ARG_MAX_THRESHOLD_BUFFERS: + g_value_set_uint (value, queue->max_threshold.buffers); + break; + case ARG_MAX_THRESHOLD_TIME: + g_value_set_uint64 (value, queue->max_threshold.time); + break; case ARG_LEAKY: g_value_set_enum (value, queue->leaky); break; - case ARG_MAY_DEADLOCK: - g_value_set_boolean (value, queue->may_deadlock); - break; - case ARG_BLOCK_TIMEOUT: - g_value_set_uint64 (value, queue->block_timeout); - break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; diff --git a/gst/gstqueue.h b/gst/gstqueue.h index e473f404ef..feabbbdd0b 100644 --- a/gst/gstqueue.h +++ b/gst/gstqueue.h @@ -1,6 +1,7 @@ /* GStreamer * Copyright (C) 1999,2000 Erik Walthinsen * 2000 Wim Taymans + * 2004,2005 Benjamin Otte * * gstqueue.h: * @@ -52,9 +53,10 @@ typedef struct _GstQueueSize GstQueueSize; typedef struct _GstQueueClass GstQueueClass; struct _GstQueueSize { - guint buffers; /* no. of buffers */ - guint bytes; /* no. of bytes */ - guint64 time; /* amount of time */ + guint items; /* no. of items */ + guint buffers; /* no. of buffers */ + guint bytes; /* no. of bytes */ + GstClockTime time; /* amount of time */ }; struct _GstQueue { @@ -69,39 +71,25 @@ struct _GstQueue { GstQueueSize cur_level, /* currently in the queue */ max_size, /* max. amount of data allowed in the queue */ - min_threshold; /* min. amount of data required to wake reader */ + min_threshold, /* min. amount of data required to wake reader */ + max_threshold; /* min. amount of data required to wake writer */ /* 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; - - gboolean interrupt; - gboolean flush; + gboolean got_eos; GMutex *qlock; /* lock for queue (vs object lock) */ - 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 */ - GQueue *events; /* upstream events get decoupled here */ GstCaps *negotiated_caps; - GMutex *event_lock; /* lock when handling the events queue */ - gpointer _gst_reserved[GST_PADDING - 1]; }; struct _GstQueueClass { GstElementClass parent_class; + /* vtable */ + /* signals - 'running' is called from both sides * which might make it sort of non-useful... */ void (*underrun) (GstQueue *queue); diff --git a/gst/gstscheduler.c b/gst/gstscheduler.c index 1bc7c15b61..f630539a97 100644 --- a/gst/gstscheduler.c +++ b/gst/gstscheduler.c @@ -1,6 +1,7 @@ /* GStreamer * Copyright (C) 1999,2000 Erik Walthinsen * 2000 Wim Taymans + * 2004 Benjamin Otte * * gstscheduler.c: Default scheduling code for most cases * @@ -27,13 +28,22 @@ #include "gstinfo.h" #include "gstregistrypool.h" +/* +GST_DEBUG_CATEGORY_STATIC (sched_debug, "GST_SCHEDULER", + GST_DEBUG_BOLD | GST_DEBUG_FG_BLUE, "scheduler base class"); +#define GST_CAT_DEFAULT sched_debug +*/ + static void gst_scheduler_class_init (GstSchedulerClass * klass); static void gst_scheduler_init (GstScheduler * sched); static void gst_scheduler_dispose (GObject * object); -static GstObjectClass *parent_class = NULL; +static void gst_scheduler_real_add_element (GstScheduler * scheduler, + GstElement * element); +static void gst_scheduler_real_remove_element (GstScheduler * scheduler, + GstElement * element); -static gchar *_default_name = NULL; +static GstObjectClass *parent_class = NULL; GType gst_scheduler_get_type (void) @@ -64,13 +74,14 @@ gst_scheduler_get_type (void) static void gst_scheduler_class_init (GstSchedulerClass * klass) { - GObjectClass *gobject_class; + GObjectClass *gobject = G_OBJECT_CLASS (klass); - gobject_class = (GObjectClass *) klass; + parent_class = g_type_class_peek_parent (klass); - parent_class = g_type_class_ref (GST_TYPE_OBJECT); + gobject->dispose = gst_scheduler_dispose; - gobject_class->dispose = GST_DEBUG_FUNCPTR (gst_scheduler_dispose); + klass->add_element = gst_scheduler_real_add_element; + klass->remove_element = gst_scheduler_real_remove_element; } static void @@ -78,10 +89,6 @@ gst_scheduler_init (GstScheduler * sched) { sched->clock_providers = NULL; sched->clock_receivers = NULL; - sched->schedulers = NULL; - sched->state = GST_SCHEDULER_STATE_NONE; - sched->parent = NULL; - sched->parent_sched = NULL; sched->clock = NULL; } @@ -91,58 +98,62 @@ gst_scheduler_dispose (GObject * object) GstScheduler *sched = GST_SCHEDULER (object); /* thse lists should all be NULL */ - GST_DEBUG ("scheduler %p dispose %p %p %p", - object, - sched->clock_providers, sched->clock_receivers, sched->schedulers); + GST_DEBUG ("scheduler %p dispose %p %p", + object, sched->clock_providers, sched->clock_receivers); gst_object_replace ((GstObject **) & sched->current_clock, NULL); gst_object_replace ((GstObject **) & sched->clock, NULL); - /* kids are held reference to, so dereference here. */ - while (sched->schedulers != NULL) { - gst_scheduler_remove_scheduler (sched, - GST_SCHEDULER (sched->schedulers->data)); - } - G_OBJECT_CLASS (parent_class)->dispose (object); } -/** - * gst_scheduler_setup: - * @sched: the scheduler - * - * Prepare the scheduler. - */ -void -gst_scheduler_setup (GstScheduler * sched) +static void +gst_scheduler_real_add_element (GstScheduler * scheduler, GstElement * element) { - GstSchedulerClass *sclass; + GSList *walk; + GstSchedulerClass *klass = GST_SCHEDULER_GET_CLASS (scheduler); - g_return_if_fail (GST_IS_SCHEDULER (sched)); + g_assert (klass->add_element); + for (walk = element->actions; walk; walk = g_slist_next (walk)) { + klass->add_action (scheduler, walk->data); + } +} - sclass = GST_SCHEDULER_GET_CLASS (sched); +static void +gst_scheduler_real_remove_element (GstScheduler * scheduler, + GstElement * element) +{ + GSList *walk; + GstSchedulerClass *klass = GST_SCHEDULER_GET_CLASS (scheduler); - if (sclass->setup) - sclass->setup (sched); + g_assert (klass->remove_element); + for (walk = element->actions; walk; walk = g_slist_next (walk)) { + klass->remove_action (scheduler, walk->data); + } } /** - * gst_scheduler_reset: - * @sched: a #GstScheduler to reset. + * gst_scheduler_marshal: + * @sched: #GstScheduler to marshal to + * @func: function to be called + * @data: user data provided to the function * - * Reset the schedulers. - */ + * This function is meant to be used from a different thread. Use this whenever + * you need to marshal function calls into the thread this scheduler is running + * in. Note that there are no guarantees made as to when the provided function + * will be exected, though schedulers will make a best effort to execute it as + * soon as possible. + **/ void -gst_scheduler_reset (GstScheduler * sched) +gst_scheduler_marshal (GstScheduler * sched, GstMarshalFunc func, gpointer data) { - GstSchedulerClass *sclass; + GstSchedulerClass *klass; g_return_if_fail (GST_IS_SCHEDULER (sched)); - - sclass = GST_SCHEDULER_GET_CLASS (sched); - - if (sclass->reset) - sclass->reset (sched); + g_return_if_fail (func != NULL); + klass = GST_SCHEDULER_GET_CLASS (sched); + g_return_if_fail (klass->marshal != NULL); + klass->marshal (sched, func, data); } /** @@ -221,7 +232,6 @@ void gst_scheduler_add_element (GstScheduler * sched, GstElement * element) { GstSchedulerClass *sclass; - gboolean redistribute_clock = FALSE; g_return_if_fail (GST_IS_SCHEDULER (sched)); g_return_if_fail (GST_IS_ELEMENT (element)); @@ -240,24 +250,15 @@ gst_scheduler_add_element (GstScheduler * sched, GstElement * element) sched->clock_providers = g_list_prepend (sched->clock_providers, element); GST_CAT_DEBUG (GST_CAT_CLOCK, "added clock provider %s", GST_ELEMENT_NAME (element)); - redistribute_clock = TRUE; } if (gst_element_requires_clock (element)) { sched->clock_receivers = g_list_prepend (sched->clock_receivers, element); GST_CAT_DEBUG (GST_CAT_CLOCK, "added clock receiver %s", GST_ELEMENT_NAME (element)); - redistribute_clock = TRUE; } gst_element_set_scheduler (element, sched); - if (redistribute_clock) { - GstClock *clock; - - clock = gst_scheduler_get_clock (sched); - gst_scheduler_set_clock (sched, clock); - } - sclass = GST_SCHEDULER_GET_CLASS (sched); if (sclass->add_element) @@ -275,33 +276,12 @@ void gst_scheduler_remove_element (GstScheduler * sched, GstElement * element) { GstSchedulerClass *sclass; - GList *link; - gboolean redistribute_clock = FALSE; g_return_if_fail (GST_IS_SCHEDULER (sched)); g_return_if_fail (GST_IS_ELEMENT (element)); - link = g_list_find (sched->clock_providers, element); - if (link) { - sched->clock_providers = g_list_delete_link (sched->clock_providers, link); - GST_CAT_DEBUG (GST_CAT_CLOCK, "removed clock provider %s", - GST_ELEMENT_NAME (element)); - redistribute_clock = TRUE; - } - link = g_list_find (sched->clock_receivers, element); - if (link) { - sched->clock_receivers = g_list_delete_link (sched->clock_receivers, link); - GST_CAT_DEBUG (GST_CAT_CLOCK, "removed clock receiver %s", - GST_ELEMENT_NAME (element)); - redistribute_clock = TRUE; - } - - if (redistribute_clock) { - GstClock *clock; - - clock = gst_scheduler_get_clock (sched); - gst_scheduler_set_clock (sched, clock); - } + sched->clock_providers = g_list_remove (sched->clock_providers, element); + sched->clock_receivers = g_list_remove (sched->clock_receivers, element); sclass = GST_SCHEDULER_GET_CLASS (sched); @@ -331,9 +311,7 @@ gst_scheduler_state_transition (GstScheduler * sched, GstElement * element, g_return_val_if_fail (GST_IS_SCHEDULER (sched), GST_STATE_FAILURE); g_return_val_if_fail (GST_IS_ELEMENT (element), GST_STATE_FAILURE); - if (element == sched->parent && sched->parent_sched == NULL) { - /* FIXME is distributing the clock in the state change still needed - * when we distribute as soon as we add/remove elements? I think not.*/ + if (GST_OBJECT (element) == gst_object_get_parent (GST_OBJECT (sched))) { switch (transition) { case GST_STATE_READY_TO_PAUSED: { @@ -357,121 +335,6 @@ gst_scheduler_state_transition (GstScheduler * sched, GstElement * element, return GST_STATE_SUCCESS; } -/** - * gst_scheduler_scheduling_change: - * @sched: the scheduler - * @element: the element that changed its scheduling strategy - * - * Tell the scheduler that an element changed its scheduling strategy. - * An element could, for example, change its loop function or changes - * from a loop based element to a chain based element. - */ -void -gst_scheduler_scheduling_change (GstScheduler * sched, GstElement * element) -{ - GstSchedulerClass *sclass; - - g_return_if_fail (GST_IS_SCHEDULER (sched)); - g_return_if_fail (GST_IS_ELEMENT (element)); - - sclass = GST_SCHEDULER_GET_CLASS (sched); - - if (sclass->scheduling_change) - sclass->scheduling_change (sched, element); -} - -/** - * gst_scheduler_add_scheduler: - * @sched: a #GstScheduler to add to - * @sched2: the #GstScheduler to add - * - * Notifies the scheduler that it has to monitor this scheduler. - */ -void -gst_scheduler_add_scheduler (GstScheduler * sched, GstScheduler * sched2) -{ - GstSchedulerClass *sclass; - - g_return_if_fail (GST_IS_SCHEDULER (sched)); - g_return_if_fail (GST_IS_SCHEDULER (sched2)); - g_return_if_fail (sched2->parent_sched == NULL); - - GST_DEBUG ("gstscheduler: %p add scheduler %p", sched, sched2); - - gst_object_ref (GST_OBJECT (sched2)); - gst_object_ref (GST_OBJECT (sched)); - - sched->schedulers = g_list_prepend (sched->schedulers, sched2); - sched2->parent_sched = sched; - - sclass = GST_SCHEDULER_GET_CLASS (sched); - - if (sclass->add_scheduler) - sclass->add_scheduler (sched, sched2); -} - -/** - * gst_scheduler_remove_scheduler: - * @sched: the scheduler - * @sched2: the scheduler to remove - * - a Notifies the scheduler that it can stop monitoring this scheduler. - */ -void -gst_scheduler_remove_scheduler (GstScheduler * sched, GstScheduler * sched2) -{ - GstSchedulerClass *sclass; - - g_return_if_fail (GST_IS_SCHEDULER (sched)); - g_return_if_fail (GST_IS_SCHEDULER (sched2)); - g_return_if_fail (sched2->parent_sched == sched); - - GST_DEBUG ("gstscheduler: %p remove scheduler %p", sched, sched2); - - sclass = GST_SCHEDULER_GET_CLASS (sched); - - if (sclass->remove_scheduler) - sclass->remove_scheduler (sched, sched2); - - sched->schedulers = g_list_remove (sched->schedulers, sched2); - sched2->parent_sched = NULL; - - gst_object_unref (GST_OBJECT (sched2)); - gst_object_unref (GST_OBJECT (sched)); -} - -/** - * gst_scheduler_lock_element: - * @sched: the scheduler - * @element: the element to lock - * - * Acquire a lock on the given element in the given scheduler. - */ -void -gst_scheduler_lock_element (GstScheduler * sched, GstElement * element) -{ - g_return_if_fail (GST_IS_SCHEDULER (sched)); - g_return_if_fail (GST_IS_ELEMENT (element)); -} - -/** - * gst_scheduler_unlock_element: - * @sched: the scheduler - * @element: the element to unlock - * - * Release the lock on the given element in the given scheduler. - */ -void -gst_scheduler_unlock_element (GstScheduler * sched, GstElement * element) -{ - GstSchedulerClass *sclass; - - g_return_if_fail (GST_IS_SCHEDULER (sched)); - g_return_if_fail (GST_IS_ELEMENT (element)); - - sclass = GST_SCHEDULER_GET_CLASS (sched); -} - /** * gst_scheduler_error: * @sched: the scheduler @@ -493,58 +356,6 @@ gst_scheduler_error (GstScheduler * sched, GstElement * element) sclass->error (sched, element); } -/** - * gst_scheduler_yield: - * @sched: the scheduler - * @element: the element requesting a yield - * - * Tell the scheduler to schedule another element. - * - * Returns: TRUE if the element should save its state, FALSE - * if the scheduler can perform this action itself. - */ -gboolean -gst_scheduler_yield (GstScheduler * sched, GstElement * element) -{ - GstSchedulerClass *sclass; - - g_return_val_if_fail (GST_IS_SCHEDULER (sched), TRUE); - g_return_val_if_fail (GST_IS_ELEMENT (element), TRUE); - - sclass = GST_SCHEDULER_GET_CLASS (sched); - - if (sclass->yield) - return sclass->yield (sched, element); - - return TRUE; -} - -/** - * gst_scheduler_interrupt: - * @sched: the scheduler - * @element: the element requesting an interrupt - * - * Tell the scheduler to interrupt execution of this element. - * - * Returns: TRUE if the element should return NULL from the chain/get - * function. - */ -gboolean -gst_scheduler_interrupt (GstScheduler * sched, GstElement * element) -{ - GstSchedulerClass *sclass; - - g_return_val_if_fail (GST_IS_SCHEDULER (sched), FALSE); - g_return_val_if_fail (GST_IS_ELEMENT (element), FALSE); - - sclass = GST_SCHEDULER_GET_CLASS (sched); - - if (sclass->interrupt) - return sclass->interrupt (sched, element); - - return FALSE; -} - /** * gst_scheduler_get_clock: * @sched: the scheduler @@ -565,23 +376,8 @@ gst_scheduler_get_clock (GstScheduler * sched) GST_CAT_DEBUG (GST_CAT_CLOCK, "scheduler using fixed clock %p (%s)", clock, clock ? GST_STR_NULL (GST_OBJECT_NAME (clock)) : "-"); } else { - GList *schedulers = sched->schedulers; GList *providers = sched->clock_providers; - /* try to get a clock from one of the schedulers we manage first */ - while (schedulers) { - GstScheduler *scheduler = GST_SCHEDULER (schedulers->data); - - clock = gst_scheduler_get_clock (scheduler); - if (clock) { - GST_CAT_DEBUG (GST_CAT_CLOCK, - "scheduler found managed sched clock %p (%s)", - clock, clock ? GST_STR_NULL (GST_OBJECT_NAME (clock)) : "-"); - break; - } - - schedulers = g_list_next (schedulers); - } /* still no clock, try to find one in the providers */ while (!clock && providers) { clock = gst_element_get_clock (GST_ELEMENT (providers->data)); @@ -591,7 +387,7 @@ gst_scheduler_get_clock (GstScheduler * sched) providers = g_list_next (providers); } /* still no clock, use a system clock */ - if (!clock && sched->parent_sched == NULL) { + if (!clock) { clock = gst_system_clock_obtain (); /* we unref since this function is not supposed to increase refcount * of clock object returned; this is ok since the systemclock always @@ -640,14 +436,11 @@ void gst_scheduler_set_clock (GstScheduler * sched, GstClock * clock) { GList *receivers; - GList *schedulers; g_return_if_fail (sched != NULL); g_return_if_fail (GST_IS_SCHEDULER (sched)); receivers = sched->clock_receivers; - schedulers = sched->schedulers; - gst_object_replace ((GstObject **) & sched->current_clock, (GstObject *) clock); @@ -661,15 +454,6 @@ gst_scheduler_set_clock (GstScheduler * sched, GstClock * clock) gst_element_set_clock (element, clock); receivers = g_list_next (receivers); } - while (schedulers) { - GstScheduler *scheduler = GST_SCHEDULER (schedulers->data); - - GST_CAT_DEBUG (GST_CAT_CLOCK, - "scheduler setting clock %p (%s) on scheduler %p", clock, - (clock ? GST_OBJECT_NAME (clock) : "nil"), scheduler); - gst_scheduler_set_clock (scheduler, clock); - schedulers = g_list_next (schedulers); - } } /** @@ -688,66 +472,24 @@ gst_scheduler_auto_clock (GstScheduler * sched) gst_object_replace ((GstObject **) & sched->clock, NULL); - GST_CAT_DEBUG (GST_CAT_CLOCK, "scheduler using automatic clock"); + GST_DEBUG_OBJECT (sched, "using automatic clock"); } -GstClockReturn gst_clock_id_wait (GstClockID id, GstClockTimeDiff * jitter); - -/** - * gst_scheduler_clock_wait: - * @sched: the scheduler - * @element: the element that wants to wait - * @id: the clockid to use - * @jitter: the time difference between requested time and actual time - * - * Wait till the clock reaches a specific time. The ClockID can - * be obtained from #gst_clock_new_single_shot_id. - * - * Returns: the status of the operation - */ -GstClockReturn -gst_scheduler_clock_wait (GstScheduler * sched, GstElement * element, - GstClockID id, GstClockTimeDiff * jitter) +void +gst_scheduler_pad_push (GstScheduler * sched, GstRealPad * pad, GstData * data) { - GstSchedulerClass *sclass; + GstSchedulerClass *klass; - g_return_val_if_fail (GST_IS_SCHEDULER (sched), GST_CLOCK_ERROR); - g_return_val_if_fail (id != NULL, GST_CLOCK_ERROR); + g_return_if_fail (GST_IS_SCHEDULER (sched)); + g_return_if_fail (GST_IS_REAL_PAD (pad)); + g_return_if_fail (GST_PAD_IS_SRC (pad)); + g_return_if_fail (data != NULL); - sclass = GST_SCHEDULER_GET_CLASS (sched); - - if (sclass->clock_wait) - return sclass->clock_wait (sched, element, id, jitter); - else - return gst_clock_id_wait (id, jitter); + klass = GST_SCHEDULER_GET_CLASS (sched); + g_return_if_fail (klass->pad_push); + klass->pad_push (sched, pad, data); } -/** - * gst_scheduler_iterate: - * @sched: the scheduler - * - * Perform one iteration on the scheduler. - * - * Returns: a boolean indicating something usefull has happened. - */ -gboolean -gst_scheduler_iterate (GstScheduler * sched) -{ - GstSchedulerClass *sclass; - gboolean res = FALSE; - - g_return_val_if_fail (GST_IS_SCHEDULER (sched), FALSE); - - sclass = GST_SCHEDULER_GET_CLASS (sched); - - if (sclass->iterate) { - res = sclass->iterate (sched); - } - - return res; -} - - /** * gst_scheduler_show: * @sched: the scheduler @@ -766,277 +508,3 @@ gst_scheduler_show (GstScheduler * sched) if (sclass->show) sclass->show (sched); } - -/* - * Factory stuff starts here - * - */ -static void gst_scheduler_factory_class_init (GstSchedulerFactoryClass * klass); -static void gst_scheduler_factory_init (GstSchedulerFactory * factory); - -static GstPluginFeatureClass *factory_parent_class = NULL; - -/* static guint gst_scheduler_factory_signals[LAST_SIGNAL] = { 0 }; */ - -GType -gst_scheduler_factory_get_type (void) -{ - static GType schedulerfactory_type = 0; - - if (!schedulerfactory_type) { - static const GTypeInfo schedulerfactory_info = { - sizeof (GstSchedulerFactoryClass), - NULL, - NULL, - (GClassInitFunc) gst_scheduler_factory_class_init, - NULL, - NULL, - sizeof (GstSchedulerFactory), - 0, - (GInstanceInitFunc) gst_scheduler_factory_init, - NULL - }; - - schedulerfactory_type = g_type_register_static (GST_TYPE_PLUGIN_FEATURE, - "GstSchedulerFactory", &schedulerfactory_info, 0); - } - return schedulerfactory_type; -} - -static void -gst_scheduler_factory_class_init (GstSchedulerFactoryClass * klass) -{ - GObjectClass *gobject_class; - GstObjectClass *gstobject_class; - GstPluginFeatureClass *gstpluginfeature_class; - - gobject_class = (GObjectClass *) klass; - gstobject_class = (GstObjectClass *) klass; - gstpluginfeature_class = (GstPluginFeatureClass *) klass; - - factory_parent_class = g_type_class_ref (GST_TYPE_PLUGIN_FEATURE); - - 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 -gst_scheduler_factory_init (GstSchedulerFactory * factory) -{ -} - - -/** - * gst_scheduler_register: - * @plugin: a #GstPlugin - * @name: name of the scheduler to register - * @longdesc: description of the scheduler - * @type: #GType of the scheduler to register - * - * Registers a scheduler with GStreamer. - * - * Returns: TRUE, if the registering succeeded, FALSE on error. - * - * Since: 0.8.5 - **/ -gboolean -gst_scheduler_register (GstPlugin * plugin, const gchar * name, - const gchar * longdesc, GType type) -{ - GstSchedulerFactory *factory; - - g_return_val_if_fail (plugin != NULL, FALSE); - g_return_val_if_fail (name != NULL, FALSE); - g_return_val_if_fail (longdesc != NULL, FALSE); - g_return_val_if_fail (g_type_is_a (type, GST_TYPE_SCHEDULER), FALSE); - - factory = gst_scheduler_factory_find (name); - if (factory) { - g_return_val_if_fail (factory->type == 0, FALSE); - g_free (factory->longdesc); - factory->longdesc = g_strdup (longdesc); - factory->type = type; - } else { - factory = gst_scheduler_factory_new (name, longdesc, type); - g_return_val_if_fail (factory, FALSE); - gst_plugin_add_feature (plugin, GST_PLUGIN_FEATURE (factory)); - } - - return TRUE; -} - -/** - * gst_scheduler_factory_new: - * @name: name of schedulerfactory to create - * @longdesc: long description of schedulerfactory to create - * @type: the gtk type of the GstScheduler element of this factory - * - * Create a new schedulerfactory with the given parameters - * - * Returns: a new #GstSchedulerFactory. - */ -GstSchedulerFactory * -gst_scheduler_factory_new (const gchar * name, const gchar * longdesc, - GType type) -{ - GstSchedulerFactory *factory; - - g_return_val_if_fail (name != NULL, NULL); - - factory = gst_scheduler_factory_find (name); - - if (!factory) { - factory = - GST_SCHEDULER_FACTORY (g_object_new (GST_TYPE_SCHEDULER_FACTORY, NULL)); - GST_PLUGIN_FEATURE_NAME (factory) = g_strdup (name); - } else { - g_free (factory->longdesc); - } - - factory->longdesc = g_strdup (longdesc); - factory->type = type; - - return factory; -} - -/** - * gst_scheduler_factory_destroy: - * @factory: factory to destroy - * - * Removes the scheduler from the global list. - */ -void -gst_scheduler_factory_destroy (GstSchedulerFactory * factory) -{ - g_return_if_fail (factory != NULL); - - /* we don't free the struct bacause someone might have a handle to it.. */ -} - -/** - * gst_scheduler_factory_find: - * @name: name of schedulerfactory to find - * - * Search for an schedulerfactory of the given name. - * - * Returns: #GstSchedulerFactory if found, NULL otherwise - */ -GstSchedulerFactory * -gst_scheduler_factory_find (const gchar * name) -{ - GstPluginFeature *feature; - - g_return_val_if_fail (name != NULL, NULL); - - GST_DEBUG ("gstscheduler: find \"%s\"", name); - - feature = gst_registry_pool_find_feature (name, GST_TYPE_SCHEDULER_FACTORY); - - if (feature) - return GST_SCHEDULER_FACTORY (feature); - - return NULL; -} - -/** - * gst_scheduler_factory_create: - * @factory: the factory used to create the instance - * @parent: the parent element of this scheduler - * - * Create a new #GstScheduler instance from the - * given schedulerfactory with the given parent. @parent will - * have its scheduler set to the returned #GstScheduler instance. - * - * Returns: A new #GstScheduler instance with a reference count of %1. - */ -GstScheduler * -gst_scheduler_factory_create (GstSchedulerFactory * factory, - GstElement * parent) -{ - GstScheduler *sched = NULL; - - g_return_val_if_fail (factory != NULL, NULL); - g_return_val_if_fail (GST_IS_ELEMENT (parent), NULL); - - if (gst_plugin_feature_ensure_loaded (GST_PLUGIN_FEATURE (factory))) { - g_return_val_if_fail (factory->type != 0, NULL); - - sched = GST_SCHEDULER (g_object_new (factory->type, NULL)); - sched->parent = parent; - - GST_ELEMENT_SCHED (parent) = sched; - - /* let's refcount the scheduler */ - gst_object_ref (GST_OBJECT (sched)); - gst_object_sink (GST_OBJECT (sched)); - } - - return sched; -} - -/** - * gst_scheduler_factory_make: - * @name: the name of the factory used to create the instance - * @parent: the parent element of this scheduler - * - * Create a new #GstScheduler instance from the - * schedulerfactory with the given name and parent. @parent will - * have its scheduler set to the returned #GstScheduler instance. - * If %NULL is passed as @name, the default scheduler name will - * be used. - * - * Returns: A new #GstScheduler instance with a reference count of %1. - */ -GstScheduler * -gst_scheduler_factory_make (const gchar * name, GstElement * parent) -{ - GstSchedulerFactory *factory; - const gchar *default_name = gst_scheduler_factory_get_default_name (); - - if (name) - factory = gst_scheduler_factory_find (name); - else { - /* FIXME: do better error handling */ - if (default_name == NULL) - g_error ("No default scheduler name - do you have a registry ?"); - factory = gst_scheduler_factory_find (default_name); - } - - if (factory == NULL) - return NULL; - - return gst_scheduler_factory_create (factory, parent); -} - -/** - * gst_scheduler_factory_set_default_name: - * @name: the name of the factory used as a default - * - * Set the default schedulerfactory name. - */ -void -gst_scheduler_factory_set_default_name (const gchar * name) -{ - g_free (_default_name); - - _default_name = g_strdup (name); -} - -/** - * gst_scheduler_factory_get_default_name: - * - * Get the default schedulerfactory name. - * - * Returns: the name of the default scheduler. - */ -const gchar * -gst_scheduler_factory_get_default_name (void) -{ - return _default_name; -} diff --git a/gst/gstscheduler.h b/gst/gstscheduler.h index 9cca5ad1d6..b793ec2c74 100644 --- a/gst/gstscheduler.h +++ b/gst/gstscheduler.h @@ -26,7 +26,7 @@ #include #include -#include +#include G_BEGIN_DECLS @@ -40,40 +40,21 @@ G_BEGIN_DECLS typedef enum { /* this scheduler works with a fixed clock */ GST_SCHEDULER_FLAG_FIXED_CLOCK = GST_OBJECT_FLAG_LAST, - /* this scheduler supports select and lock calls */ - GST_SCHEDULER_FLAG_NEW_API, /* padding */ GST_SCHEDULER_FLAG_LAST = GST_OBJECT_FLAG_LAST + 4 } GstSchedulerFlags; -#define GST_SCHEDULER_PARENT(sched) ((sched)->parent) -#define GST_SCHEDULER_STATE(sched) ((sched)->state) - -/*typedef struct _GstScheduler GstScheduler; */ -/*typedef struct _GstSchedulerClass GstSchedulerClass; */ -typedef enum { - GST_SCHEDULER_STATE_NONE, - GST_SCHEDULER_STATE_RUNNING, - GST_SCHEDULER_STATE_STOPPED, - GST_SCHEDULER_STATE_ERROR -} GstSchedulerState; - +typedef (*GstMarshalFunc) (gpointer data); struct _GstScheduler { - GstObject object; + GstObject object; - GstElement *parent; - GstScheduler *parent_sched; - - GstSchedulerState state; GstClock *clock; GstClock *current_clock; GList *clock_providers; GList *clock_receivers; - GList *schedulers; - gpointer _gst_reserved[GST_PADDING]; }; @@ -81,64 +62,39 @@ struct _GstSchedulerClass { GstObjectClass parent_class; /* virtual methods */ - void (*setup) (GstScheduler *sched); - void (*reset) (GstScheduler *sched); + /* required */ + void (*marshal) (GstScheduler *sched, GstMarshalFunc func, gpointer data); + void (*add_action) (GstScheduler *sched, GstAction *action); + void (*remove_action) (GstScheduler *sched, GstAction *action); + /* FIXME: can/want this optional, too? */ + void (*pad_push) (GstScheduler *sched, GstRealPad *pad, GstData *data); + /* optional */ + void (*update_values) (GstScheduler *sched, GstAction *action); + void (*toggle_active) (GstScheduler *sched, GstAction *action); void (*add_element) (GstScheduler *sched, GstElement *element); void (*remove_element) (GstScheduler *sched, GstElement *element); - void (*add_scheduler) (GstScheduler *sched, GstScheduler *sched2); - void (*remove_scheduler) (GstScheduler *sched, GstScheduler *sched2); GstElementStateReturn (*state_transition) (GstScheduler *sched, GstElement *element, gint transition); - void (*scheduling_change) (GstScheduler *sched, GstElement *element); - /* next two are optional, require NEW_API flag */ - /* FIXME 0.9: rename to (un)lock_object */ - void (*lock_element) (GstScheduler *sched, GstObject *object); - void (*unlock_element) (GstScheduler *sched, GstObject *object); - gboolean (*yield) (GstScheduler *sched, GstElement *element); - gboolean (*interrupt) (GstScheduler *sched, GstElement *element); void (*error) (GstScheduler *sched, GstElement *element); + /* FIXME: make this GstRealPad */ void (*pad_link) (GstScheduler *sched, GstPad *srcpad, GstPad *sinkpad); void (*pad_unlink) (GstScheduler *sched, GstPad *srcpad, GstPad *sinkpad); - /* optional, requires NEW_API flag */ - GstData * (*pad_select) (GstScheduler *sched, GstPad **selected, GstPad **pads); - GstClockReturn (*clock_wait) (GstScheduler *sched, GstElement *element, - GstClockID id, GstClockTimeDiff *jitter); - GstSchedulerState (*iterate) (GstScheduler *sched); /* for debugging */ void (*show) (GstScheduler *sched); - /* signals */ - void (*object_sync) (GstScheduler *sched, GstClock *clock, GstObject *object, - GstClockID id); - gpointer _gst_reserved[GST_PADDING]; }; GType gst_scheduler_get_type (void); - -void gst_scheduler_setup (GstScheduler *sched); -void gst_scheduler_reset (GstScheduler *sched); void gst_scheduler_add_element (GstScheduler *sched, GstElement *element); void gst_scheduler_remove_element (GstScheduler *sched, GstElement *element); -void gst_scheduler_add_scheduler (GstScheduler *sched, GstScheduler *sched2); -void gst_scheduler_remove_scheduler (GstScheduler *sched, GstScheduler *sched2); +void gst_scheduler_marshal (GstScheduler *sched, GstMarshalFunc func, gpointer data); +/* FIXME: make private? */ GstElementStateReturn gst_scheduler_state_transition (GstScheduler *sched, GstElement *element, gint transition); -void gst_scheduler_scheduling_change (GstScheduler *sched, GstElement *element); -#ifndef GST_DISABLE_DEPRECATED -void gst_scheduler_lock_element (GstScheduler *sched, GstElement *element); -void gst_scheduler_unlock_element (GstScheduler *sched, GstElement *element); -#endif -gboolean gst_scheduler_yield (GstScheduler *sched, GstElement *element); -gboolean gst_scheduler_interrupt (GstScheduler *sched, GstElement *element); void gst_scheduler_error (GstScheduler *sched, GstElement *element); void gst_scheduler_pad_link (GstScheduler *sched, GstPad *srcpad, GstPad *sinkpad); void gst_scheduler_pad_unlink (GstScheduler *sched, GstPad *srcpad, GstPad *sinkpad); -#ifndef GST_DISABLE_DEPRECATED -GstPad* gst_scheduler_pad_select (GstScheduler *sched, GList *padlist); -#endif -GstClockReturn gst_scheduler_clock_wait (GstScheduler *sched, GstElement *element, - GstClockID id, GstClockTimeDiff *jitter); -gboolean gst_scheduler_iterate (GstScheduler *sched); +void gst_scheduler_pad_push (GstScheduler *sched, GstRealPad *pad, GstData *data); void gst_scheduler_use_clock (GstScheduler *sched, GstClock *clock); void gst_scheduler_set_clock (GstScheduler *sched, GstClock *clock); @@ -147,53 +103,6 @@ void gst_scheduler_auto_clock (GstScheduler *sched); void gst_scheduler_show (GstScheduler *sched); -/* - * creating schedulers - * - */ -#define GST_TYPE_SCHEDULER_FACTORY (gst_scheduler_factory_get_type ()) -#define GST_SCHEDULER_FACTORY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_SCHEDULER_FACTORY, GstSchedulerFactory)) -#define GST_IS_SCHEDULER_FACTORY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_SCHEDULER_FACTORY)) -#define GST_SCHEDULER_FACTORY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_SCHEDULER_FACTORY, GstSchedulerFactoryClass)) -#define GST_IS_SCHEDULER_FACTORY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_SCHEDULER_FACTORY)) -#define GST_SCHEDULER_FACTORY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_SCHEDULER_FACTORY, GstSchedulerFactoryClass)) - -/* change this to change the default scheduler */ -#define GST_SCHEDULER_DEFAULT_NAME "opt" - -typedef struct _GstSchedulerFactory GstSchedulerFactory; -typedef struct _GstSchedulerFactoryClass GstSchedulerFactoryClass; - -struct _GstSchedulerFactory { - GstPluginFeature feature; - - gchar *longdesc; /* long description of the scheduler (well, don't overdo it..) */ - GType type; /* unique GType of the scheduler */ - - gpointer _gst_reserved[GST_PADDING]; -}; - -struct _GstSchedulerFactoryClass { - GstPluginFeatureClass parent; - - gpointer _gst_reserved[GST_PADDING]; -}; - -GType gst_scheduler_factory_get_type (void); - -gboolean gst_scheduler_register (GstPlugin *plugin, const gchar *name, - const gchar *longdesc, GType type); -GstSchedulerFactory* gst_scheduler_factory_new (const gchar *name, const gchar *longdesc, GType type); -void gst_scheduler_factory_destroy (GstSchedulerFactory *factory); - -GstSchedulerFactory* gst_scheduler_factory_find (const gchar *name); - -GstScheduler* gst_scheduler_factory_create (GstSchedulerFactory *factory, GstElement *parent); -GstScheduler* gst_scheduler_factory_make (const gchar *name, GstElement *parent); - -void gst_scheduler_factory_set_default_name (const gchar* name); -G_CONST_RETURN gchar* gst_scheduler_factory_get_default_name (void); - G_END_DECLS diff --git a/gst/gstschedulerfactory.c b/gst/gstschedulerfactory.c new file mode 100644 index 0000000000..2014476e42 --- /dev/null +++ b/gst/gstschedulerfactory.c @@ -0,0 +1,295 @@ +/* GStreamer + * Copyright (C) 1999,2000 Erik Walthinsen + * 2000 Wim Taymans + * 2004 Benjamin Otte + * + * gstschedulerfactory.c: code for registering schedulers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include "gst_private.h" + +#include "gstscheduler.h" +#include "gstschedulerfactory.h" +#include "gstinfo.h" +#include "gstregistrypool.h" + +static gchar *_default_name = NULL; + +static void gst_scheduler_factory_class_init (GstSchedulerFactoryClass * klass); +static void gst_scheduler_factory_init (GstSchedulerFactory * factory); + +static GstPluginFeatureClass *factory_parent_class = NULL; + +/* static guint gst_scheduler_factory_signals[LAST_SIGNAL] = { 0 }; */ + +GType +gst_scheduler_factory_get_type (void) +{ + static GType schedulerfactory_type = 0; + + if (!schedulerfactory_type) { + static const GTypeInfo schedulerfactory_info = { + sizeof (GstSchedulerFactoryClass), + NULL, + NULL, + (GClassInitFunc) gst_scheduler_factory_class_init, + NULL, + NULL, + sizeof (GstSchedulerFactory), + 0, + (GInstanceInitFunc) gst_scheduler_factory_init, + NULL + }; + + schedulerfactory_type = g_type_register_static (GST_TYPE_PLUGIN_FEATURE, + "GstSchedulerFactory", &schedulerfactory_info, 0); + } + return schedulerfactory_type; +} + +static void +gst_scheduler_factory_class_init (GstSchedulerFactoryClass * klass) +{ + GObjectClass *gobject_class; + GstObjectClass *gstobject_class; + GstPluginFeatureClass *gstpluginfeature_class; + + gobject_class = (GObjectClass *) klass; + gstobject_class = (GstObjectClass *) klass; + gstpluginfeature_class = (GstPluginFeatureClass *) klass; + + factory_parent_class = g_type_class_ref (GST_TYPE_PLUGIN_FEATURE); + + 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 +gst_scheduler_factory_init (GstSchedulerFactory * factory) +{ +} + + +/** + * gst_scheduler_register: + * @plugin: a #GstPlugin + * @name: name of the scheduler to register + * @longdesc: description of the scheduler + * @type: #GType of the scheduler to register + * + * Registers a scheduler with GStreamer. + * + * Returns: TRUE, if the registering succeeded, FALSE on error + **/ +gboolean +gst_scheduler_register (GstPlugin * plugin, const gchar * name, + const gchar * longdesc, GType type) +{ + GstSchedulerFactory *factory; + + g_return_val_if_fail (plugin != NULL, FALSE); + g_return_val_if_fail (name != NULL, FALSE); + g_return_val_if_fail (longdesc != NULL, FALSE); + g_return_val_if_fail (g_type_is_a (type, GST_TYPE_SCHEDULER), FALSE); + + factory = gst_scheduler_factory_find (name); + if (factory) { + g_return_val_if_fail (factory->type == 0, FALSE); + g_free (factory->longdesc); + factory->longdesc = g_strdup (longdesc); + factory->type = type; + } else { + factory = gst_scheduler_factory_new (name, longdesc, type); + g_return_val_if_fail (factory, FALSE); + gst_plugin_add_feature (plugin, GST_PLUGIN_FEATURE (factory)); + } + + return TRUE; +} + +/** + * gst_scheduler_factory_new: + * @name: name of schedulerfactory to create + * @longdesc: long description of schedulerfactory to create + * @type: the gtk type of the GstScheduler element of this factory + * + * Create a new schedulerfactory with the given parameters + * + * Returns: a new #GstSchedulerFactory. + */ +GstSchedulerFactory * +gst_scheduler_factory_new (const gchar * name, const gchar * longdesc, + GType type) +{ + GstSchedulerFactory *factory; + + g_return_val_if_fail (name != NULL, NULL); + + factory = gst_scheduler_factory_find (name); + + if (!factory) { + factory = + GST_SCHEDULER_FACTORY (g_object_new (GST_TYPE_SCHEDULER_FACTORY, NULL)); + GST_PLUGIN_FEATURE_NAME (factory) = g_strdup (name); + } else { + g_free (factory->longdesc); + } + + factory->longdesc = g_strdup (longdesc); + factory->type = type; + + return factory; +} + +/** + * gst_scheduler_factory_destroy: + * @factory: factory to destroy + * + * Removes the scheduler from the global list. + */ +void +gst_scheduler_factory_destroy (GstSchedulerFactory * factory) +{ + g_return_if_fail (factory != NULL); + + /* we don't free the struct bacause someone might have a handle to it.. */ +} + +/** + * gst_scheduler_factory_find: + * @name: name of schedulerfactory to find + * + * Search for an schedulerfactory of the given name. + * + * Returns: #GstSchedulerFactory if found, NULL otherwise + */ +GstSchedulerFactory * +gst_scheduler_factory_find (const gchar * name) +{ + GstPluginFeature *feature; + + g_return_val_if_fail (name != NULL, NULL); + + GST_DEBUG ("gstscheduler: find \"%s\"", name); + + feature = gst_registry_pool_find_feature (name, GST_TYPE_SCHEDULER_FACTORY); + + if (feature) + return GST_SCHEDULER_FACTORY (feature); + + return NULL; +} + +/** + * gst_scheduler_factory_create: + * @factory: the factory used to create the instance + * @parent: the parent element of this scheduler + * + * Create a new #GstScheduler instance from the + * given schedulerfactory with the given parent. @parent will + * have its scheduler set to the returned #GstScheduler instance. + * + * Returns: A new #GstScheduler instance with a reference count of %1. + */ +GstScheduler * +gst_scheduler_factory_create (GstSchedulerFactory * factory, + GstElement * parent) +{ + GstScheduler *sched = NULL; + + g_return_val_if_fail (factory != NULL, NULL); + g_return_val_if_fail (GST_IS_ELEMENT (parent), NULL); + + if (gst_plugin_feature_ensure_loaded (GST_PLUGIN_FEATURE (factory))) { + g_return_val_if_fail (factory->type != 0, NULL); + + sched = GST_SCHEDULER (g_object_new (factory->type, NULL)); + gst_object_set_parent (GST_OBJECT (sched), GST_OBJECT (parent)); + + GST_ELEMENT_SCHED (parent) = sched; + } + + return sched; +} + +/** + * gst_scheduler_factory_make: + * @name: the name of the factory used to create the instance + * @parent: the parent element of this scheduler + * + * Create a new #GstScheduler instance from the + * schedulerfactory with the given name and parent. @parent will + * have its scheduler set to the returned #GstScheduler instance. + * If %NULL is passed as @name, the default scheduler name will + * be used. + * + * Returns: A new #GstScheduler instance with a reference count of %1. + */ +GstScheduler * +gst_scheduler_factory_make (const gchar * name, GstElement * parent) +{ + GstSchedulerFactory *factory; + const gchar *default_name = gst_scheduler_factory_get_default_name (); + + if (name) + factory = gst_scheduler_factory_find (name); + else { + /* FIXME: do better error handling */ + if (default_name == NULL) + g_error ("No default scheduler name - do you have a registry ?"); + factory = gst_scheduler_factory_find (default_name); + } + + if (factory == NULL) + return NULL; + + return gst_scheduler_factory_create (factory, parent); +} + +/** + * gst_scheduler_factory_set_default_name: + * @name: the name of the factory used as a default + * + * Set the default schedulerfactory name. + */ +void +gst_scheduler_factory_set_default_name (const gchar * name) +{ + g_free (_default_name); + + _default_name = g_strdup (name); +} + +/** + * gst_scheduler_factory_get_default_name: + * + * Get the default schedulerfactory name. + * + * Returns: the name of the default scheduler. + */ +const gchar * +gst_scheduler_factory_get_default_name (void) +{ + return _default_name; +} diff --git a/gst/gstschedulerfactory.h b/gst/gstschedulerfactory.h new file mode 100644 index 0000000000..985ac4fa87 --- /dev/null +++ b/gst/gstschedulerfactory.h @@ -0,0 +1,81 @@ +/* GStreamer + * Copyright (C) 1999,2000 Erik Walthinsen + * 2000 Wim Taymans + * 2004 Benjamin Otte + * + * gstschedulerfactory.h: Header for default scheduler factories + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + + +#include +#include +#include + +#ifndef __GST_SCHEDULER_FACTORY_H__ +#define __GST_SCHEDULER_FACTORY_H__ + +G_BEGIN_DECLS + + +#define GST_TYPE_SCHEDULER_FACTORY (gst_scheduler_factory_get_type ()) +#define GST_SCHEDULER_FACTORY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_SCHEDULER_FACTORY, GstSchedulerFactory)) +#define GST_IS_SCHEDULER_FACTORY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_SCHEDULER_FACTORY)) +#define GST_SCHEDULER_FACTORY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_SCHEDULER_FACTORY, GstSchedulerFactoryClass)) +#define GST_IS_SCHEDULER_FACTORY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_SCHEDULER_FACTORY)) +#define GST_SCHEDULER_FACTORY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_SCHEDULER_FACTORY, GstSchedulerFactoryClass)) + +/* change this to change the default scheduler */ +/* FIXME: use ranks and determine the best scheduler automagically */ +#define GST_SCHEDULER_DEFAULT_NAME "simple" + +typedef struct _GstSchedulerFactory GstSchedulerFactory; +typedef struct _GstSchedulerFactoryClass GstSchedulerFactoryClass; + +struct _GstSchedulerFactory { + GstPluginFeature feature; + + gchar *longdesc; /* long description of the scheduler (well, don't overdo it..) */ + GType type; /* unique GType of the scheduler */ + + gpointer _gst_reserved[GST_PADDING]; +}; + +struct _GstSchedulerFactoryClass { + GstPluginFeatureClass parent; + + gpointer _gst_reserved[GST_PADDING]; +}; + +GType gst_scheduler_factory_get_type (void); + +gboolean gst_scheduler_register (GstPlugin *plugin, const gchar *name, + const gchar *longdesc, GType type); +GstSchedulerFactory* gst_scheduler_factory_new (const gchar *name, const gchar *longdesc, GType type); + +GstSchedulerFactory* gst_scheduler_factory_find (const gchar *name); + +GstScheduler* gst_scheduler_factory_create (GstSchedulerFactory *factory, GstElement *parent); +GstScheduler* gst_scheduler_factory_make (const gchar *name, GstElement *parent); + +void gst_scheduler_factory_set_default_name (const gchar* name); +G_CONST_RETURN gchar* gst_scheduler_factory_get_default_name (void); + + +G_END_DECLS + +#endif /* __GST_SCHEDULER_FACTORY_H__ */ diff --git a/gst/gsttypes.h b/gst/gsttypes.h index 0c091cba1b..bb68ed3e6e 100644 --- a/gst/gsttypes.h +++ b/gst/gsttypes.h @@ -24,10 +24,13 @@ G_BEGIN_DECLS +typedef union _GstAction GstAction; typedef struct _GstObject GstObject; typedef struct _GstObjectClass GstObjectClass; typedef struct _GstPad GstPad; typedef struct _GstPadClass GstPadClass; +typedef struct _GstRealPad GstRealPad; +typedef struct _GstRealPadClass GstRealPadClass; typedef struct _GstPadTemplate GstPadTemplate; typedef struct _GstPadTemplateClass GstPadTemplateClass; typedef struct _GstElement GstElement; @@ -37,6 +40,8 @@ typedef struct _GstBinClass GstBinClass; typedef struct _GstScheduler GstScheduler; typedef struct _GstSchedulerClass GstSchedulerClass; typedef struct _GstEvent GstEvent; +typedef guint64 GstClockTime; +typedef gint64 GstClockTimeDiff; typedef enum { GST_STATE_VOID_PENDING = 0, diff --git a/gst/registries/gstlibxmlregistry.c b/gst/registries/gstlibxmlregistry.c index 966bc113f1..a69d94c5fb 100644 --- a/gst/registries/gstlibxmlregistry.c +++ b/gst/registries/gstlibxmlregistry.c @@ -54,7 +54,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/gst/schedulers/Makefile.am b/gst/schedulers/Makefile.am index b67ccf691a..8fdb728522 100644 --- a/gst/schedulers/Makefile.am +++ b/gst/schedulers/Makefile.am @@ -1,82 +1,16 @@ -if GST_DISABLE_OMEGA_COTHREADS -omegaschedulers = -omegaschedulers_nola = -else -omegaschedulers = \ - libgstbasicomegascheduler.la \ - libgstentryomegascheduler.la \ - libgstoptomegascheduler.la -omegaschedulers_nola = \ - libgstbasicomegascheduler \ - libgstentryomegascheduler \ - libgstoptomegascheduler -endif plugin_LTLIBRARIES = \ - $(omegaschedulers) \ - libgstbasicgthreadscheduler.la \ - libgstentrygthreadscheduler.la \ - libgstoptscheduler.la \ - libgstoptgthreadscheduler.la \ - libgstfairgthreadscheduler.la + libgstsimplescheduler.la + AS_LIBTOOL_LIBS = \ - $(omegaschedulers_nola) \ - libgstbasicgthreadscheduler \ - libgstentrygthreadscheduler \ - libgstoptscheduler \ - libgstoptgthreadscheduler \ - libgstfairgthreadscheduler + libgstsimplescheduler -if GST_DISABLE_OMEGA_COTHREADS -else -libgstbasicomegascheduler_la_SOURCES = gstbasicscheduler.c -libgstbasicomegascheduler_la_CFLAGS = $(GST_OBJ_CFLAGS) -D_COTHREADS_OMEGA -libgstbasicomegascheduler_la_LIBADD = $(GST_OBJ_LIBS) ../libcothreads.la -libgstbasicomegascheduler_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) $(as_libtool_LDFLAGS) -endif -libgstbasicgthreadscheduler_la_SOURCES = gstbasicscheduler.c -libgstbasicgthreadscheduler_la_CFLAGS = $(GST_OBJ_CFLAGS) -D_COTHREADS_GTHREAD -libgstbasicgthreadscheduler_la_LIBADD = $(GST_OBJ_LIBS) -libgstbasicgthreadscheduler_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) $(as_libtool_LDFLAGS) +libgstsimplescheduler_la_SOURCES = gstsimplescheduler.c +libgstsimplescheduler_la_CFLAGS = $(GST_OBJ_CFLAGS) +libgstsimplescheduler_la_LIBADD = $(GST_OBJ_LIBS) +libgstsimplescheduler_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) $(as_libtool_LDFLAGS) -libgstentrygthreadscheduler_la_SOURCES = entryscheduler.c -libgstentrygthreadscheduler_la_CFLAGS = $(GST_OBJ_CFLAGS) -D_COTHREADS_GTHREAD -libgstentrygthreadscheduler_la_LIBADD = $(GST_OBJ_LIBS) -libgstentrygthreadscheduler_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) $(as_libtool_LDFLAGS) - -if GST_DISABLE_OMEGA_COTHREADS -else -libgstentryomegascheduler_la_SOURCES = entryscheduler.c -libgstentryomegascheduler_la_CFLAGS = $(GST_OBJ_CFLAGS) -D_COTHREADS_OMEGA -libgstentryomegascheduler_la_LIBADD = $(GST_OBJ_LIBS) ../libcothreads.la -libgstentryomegascheduler_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) $(as_libtool_LDFLAGS) -endif - -libgstoptscheduler_la_SOURCES = gstoptimalscheduler.c -libgstoptscheduler_la_CFLAGS = $(GST_OBJ_CFLAGS) -libgstoptscheduler_la_LIBADD = $(GST_OBJ_LIBS) -libgstoptscheduler_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) $(as_libtool_LDFLAGS) - -if GST_DISABLE_OMEGA_COTHREADS -else -libgstoptomegascheduler_la_SOURCES = gstoptimalscheduler.c -libgstoptomegascheduler_la_CFLAGS = $(GST_OBJ_CFLAGS) -D_COTHREADS_OMEGA -DUSE_COTHREADS -libgstoptomegascheduler_la_LIBADD = $(GST_OBJ_LIBS) ../libcothreads.la -libgstoptomegascheduler_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) $(as_libtool_LDFLAGS) -endif - -libgstoptgthreadscheduler_la_SOURCES = gstoptimalscheduler.c -libgstoptgthreadscheduler_la_CFLAGS = $(GST_OBJ_CFLAGS) -D_COTHREADS_GTHREAD -DUSE_COTHREADS -libgstoptgthreadscheduler_la_LIBADD = $(GST_OBJ_LIBS) -libgstoptgthreadscheduler_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) $(as_libtool_LDFLAGS) - -libgstfairgthreadscheduler_la_SOURCES = fairscheduler.c faircothreads.c -libgstfairgthreadscheduler_la_CFLAGS = $(GST_OBJ_CFLAGS) -D_COTHREADS_GTHREAD -libgstfairgthreadscheduler_la_LIBADD = $(GST_OBJ_LIBS) -libgstfairgthreadscheduler_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) $(as_libtool_LDFLAGS) - -noinst_HEADERS = cothreads_compat.h gthread-cothreads.h faircothreads.h if AS_LIBTOOL_WIN32 @@ -106,6 +40,8 @@ as-libtool-uninstall-local: endif + + %.lib: %.def dlltool -S $(CC) -f "-c" --export-all-symbols --input-def \ %.def --output-lib %.lib @@ -117,3 +53,4 @@ endif awk '{ print $$3 }' | \ sed 's/^/ /' >>%.def.tmp mv %.def.tmp %.def + diff --git a/gst/schedulers/cothreads_compat.h b/gst/schedulers/cothreads_compat.h deleted file mode 100644 index 41d0cdf4a8..0000000000 --- a/gst/schedulers/cothreads_compat.h +++ /dev/null @@ -1,79 +0,0 @@ -/* GStreamer - * Copyright (C) 1999,2000 Erik Walthinsen - * 2000 Wim Taymans - * - * cothreads_compat.h: Compatibility macros between cothreads packages - * - * 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. - */ - -/* use the old cothreads implementation in gst/cothreads.[ch] */ -#if defined(_COTHREADS_OMEGA) - -#include "../cothreads.h" - -/* the name of this cothreads type */ -#define COTHREADS_TYPE omega -#define COTHREADS_NAME "omega" -#define COTHREADS_NAME_CAPITAL "Omega" - -/* unify the structs - * - * "cothread" and "cothread_context" need to be defined - */ -typedef struct _cothread_state cothread; - -/* define functions - * the macros are prepended with "do_" - */ -#define do_cothreads_init(x) /* NOP */ - -#define do_cothreads_stackquery(stack,size) cothread_stackquery(stack,size) - -#define do_cothread_switch(to) cothread_switch(to) - -#define do_cothread_create(new_cothread, context, func, argc, argv) \ - G_STMT_START{ \ - new_cothread = cothread_create (context); \ - if (new_cothread) { \ - cothread_setfunc (new_cothread, (func), (argc), (argv)); \ - } \ - }G_STMT_END - -#define do_cothread_setfunc(cothread, context, func, argc, argv) \ - cothread_setfunc ((cothread), (func), (argc), (argv)) - -#define do_cothread_destroy(cothread) cothread_free(cothread) - -#define do_cothread_context_init() (cothread_context_init ()) -#define do_cothread_context_destroy(context) cothread_context_free (context) - -#define do_cothread_get_current(context) (cothread_current()) -#define do_cothread_get_main(context) (cothread_current_main()) - - - - -/* use the gthread-based cothreads implementation */ -#elif defined(_COTHREADS_GTHREAD) - -#include "gthread-cothreads.h" - - -/* bail out with an error if no cothreads package is defined */ -#else -#error "No cothreads package defined" -#endif diff --git a/gst/schedulers/entryscheduler.c b/gst/schedulers/entryscheduler.c deleted file mode 100644 index e9dac3fb50..0000000000 --- a/gst/schedulers/entryscheduler.c +++ /dev/null @@ -1,1175 +0,0 @@ -/* GStreamer - * Copyright (C) 2004 Benjamin Otte - * - * gstentryscheduler.c: A scheduler based on entries - * - * 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. - */ - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - -#include -#include "cothreads_compat.h" -#include "../gst-i18n-lib.h" - -GST_DEBUG_CATEGORY_STATIC (debug_scheduler); -#define GST_CAT_DEFAULT debug_scheduler - - -#define GET_TYPE(x) gst_entry_ ## x ## _scheduler_get_type -#define GST_TYPE_ENTRY_SCHEDULER \ - (GET_TYPE (COTHREADS_TYPE) ()) -#define GST_ENTRY_SCHEDULER(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_ENTRY_SCHEDULER,GstEntryScheduler)) -#define GST_ENTRY_SCHEDULER_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_ENTRY_SCHEDULER,GstEntrySchedulerClass)) -#define GST_IS_ENTRY_SCHEDULER(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_ENTRY_SCHEDULER)) -#define GST_IS_ENTRY_SCHEDULER_CLASS(obj) \ - (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_ENTRY_SCHEDULER)) - -#define SCHED_ASSERT(sched, assertion) G_STMT_START{ \ - if (!(assertion)) \ - gst_scheduler_show (GST_SCHEDULER (sched)); \ - g_assert (assertion); \ -}G_STMT_END - -typedef enum -{ - WAIT_FOR_NOTHING, - WAIT_FOR_MUM, - WAIT_FOR_PADS, /* pad must be scheduled */ - /* add more */ - WAIT_FOR_ANYTHING -} -WaitInfo; - -typedef enum -{ - ENTRY_UNDEFINED, - ENTRY_COTHREAD, - ENTRY_LINK -} -EntryType; - -typedef struct -{ - EntryType type; -} -Entry; - -#define ENTRY_IS_COTHREAD(x) (((Entry *)(x))->type == ENTRY_COTHREAD) -#define ENTRY_IS_LINK(x) (((Entry *)(x))->type == ENTRY_LINK) - -typedef struct _GstEntryScheduler GstEntryScheduler; -typedef struct _GstEntrySchedulerClass GstEntrySchedulerClass; - -typedef struct -{ - Entry entry; - /* pointer to scheduler */ - GstEntryScheduler *sched; - /* pointer to element */ - GstElement *element; - /* the main function of the cothread */ - int (*main) (int argc, gchar ** argv); - /* wether the given pad is schedulable */ - gboolean (*can_schedule) (GstRealPad * pad); - /* what the element is currently waiting for */ - WaitInfo wait; - /* cothread of element */ - cothread *thread; - /* pad to schedule next */ - GstRealPad *schedule_pad; -} -CothreadPrivate; - -#define ELEMENT_PRIVATE(element) ((CothreadPrivate *) GST_ELEMENT (element)->sched_private) -#define SCHED(element) (GST_ENTRY_SCHEDULER ((element)->sched)) - -typedef struct -{ - Entry entry; - /* pads */ - GstRealPad *srcpad; - GstRealPad *sinkpad; - /* private struct of srcpad's element, needed for decoupled elements */ - CothreadPrivate *src; - /* private struct of sinkpad's element */ - CothreadPrivate *sink; - /* current data */ - GstData *bufpen; -} -LinkPrivate; - -#define PAD_PRIVATE(pad) ((LinkPrivate *) (GST_REAL_PAD (pad))->sched_private) - -struct _GstEntryScheduler -{ - GstScheduler scheduler; - - cothread_context *context; - - GList *schedule_now; /* entry points that must be scheduled this - iteration */ - GList *schedule_possible; /* possible entry points */ - GList *waiting; /* elements waiting for the clock */ - gboolean error; /* if an element threw an error */ - - GSList *reaping; /* cothreads we need to destroy but can't */ -}; - -struct _GstEntrySchedulerClass -{ - GstSchedulerClass scheduler_class; -}; - -static void gst_entry_scheduler_class_init (gpointer g_class, gpointer data); -static void gst_entry_scheduler_init (GstEntryScheduler * object); - - -GType GET_TYPE (COTHREADS_TYPE) (void) -{ - static GType object_type = 0; - - if (object_type == 0) { - static const GTypeInfo object_info = { - sizeof (GstEntrySchedulerClass), - NULL, - NULL, - gst_entry_scheduler_class_init, - NULL, - NULL, - sizeof (GstEntryScheduler), - 0, - (GInstanceInitFunc) gst_entry_scheduler_init - }; - - object_type = - g_type_register_static (GST_TYPE_SCHEDULER, - "GstEntry" COTHREADS_NAME_CAPITAL "Scheduler", &object_info, 0); - } - return object_type; -} - -static int gst_entry_scheduler_loop_wrapper (int argc, char **argv); -static int gst_entry_scheduler_get_wrapper (int argc, char **argv); -static int gst_entry_scheduler_chain_wrapper (int argc, char **argv); - -static void gst_entry_scheduler_setup (GstScheduler * sched); -static void gst_entry_scheduler_reset (GstScheduler * sched); -static void gst_entry_scheduler_add_element (GstScheduler * sched, - GstElement * element); -static void gst_entry_scheduler_remove_element (GstScheduler * sched, - GstElement * element); -static GstElementStateReturn gst_entry_scheduler_state_transition (GstScheduler - * sched, GstElement * element, gint transition); -static gboolean gst_entry_scheduler_yield (GstScheduler * sched, - GstElement * element); -static gboolean gst_entry_scheduler_interrupt (GstScheduler * sched, - GstElement * element); -static void gst_entry_scheduler_error (GstScheduler * sched, - GstElement * element); -static void gst_entry_scheduler_pad_link (GstScheduler * sched, GstPad * srcpad, - GstPad * sinkpad); -static void gst_entry_scheduler_pad_unlink (GstScheduler * sched, - GstPad * srcpad, GstPad * sinkpad); -static GstData *gst_entry_scheduler_pad_select (GstScheduler * sched, - GstPad ** pulled_from, GstPad ** pads); -static GstSchedulerState gst_entry_scheduler_iterate (GstScheduler * sched); -static void gst_entry_scheduler_show (GstScheduler * scheduler); - -static gboolean can_schedule_pad (GstRealPad * pad); -static void schedule_next_element (GstEntryScheduler * sched); - -static void -gst_entry_scheduler_class_init (gpointer klass, gpointer class_data) -{ - GstSchedulerClass *scheduler = GST_SCHEDULER_CLASS (klass); - - scheduler->setup = gst_entry_scheduler_setup; - scheduler->reset = gst_entry_scheduler_reset; - scheduler->add_element = gst_entry_scheduler_add_element; - scheduler->remove_element = gst_entry_scheduler_remove_element; - scheduler->state_transition = gst_entry_scheduler_state_transition; - scheduler->yield = gst_entry_scheduler_yield; - scheduler->interrupt = gst_entry_scheduler_interrupt; - scheduler->error = gst_entry_scheduler_error; - scheduler->pad_link = gst_entry_scheduler_pad_link; - scheduler->pad_unlink = gst_entry_scheduler_pad_unlink; - scheduler->pad_select = gst_entry_scheduler_pad_select; - scheduler->clock_wait = NULL; - scheduler->iterate = gst_entry_scheduler_iterate; - scheduler->show = gst_entry_scheduler_show; - - do_cothreads_init (NULL); -} - -static void -gst_entry_scheduler_init (GstEntryScheduler * scheduler) -{ - GST_FLAG_SET (scheduler, GST_SCHEDULER_FLAG_NEW_API); -} - -/* - * We've got to setup 5 different element types here: - * - loopbased - * - chainbased - * - chainbased PADS of decoupled elements - * - getbased - * - getbased PADS of decoupled elements - */ - -/* - * LOOPBASED - */ - -typedef struct -{ - CothreadPrivate element; - GstPad **sinkpads; -} -LoopPrivate; - -#define LOOP_PRIVATE(x) ((LoopPrivate *) ELEMENT_PRIVATE (x)) - -static gboolean -_can_schedule_loop (GstRealPad * pad) -{ - LoopPrivate *priv; - gint i = 0; - - g_assert (PAD_PRIVATE (pad)); - - if (GST_PAD_IS_SRC (pad)) - return FALSE; - - priv = LOOP_PRIVATE (gst_pad_get_parent (GST_PAD (pad))); - g_assert (priv); - if (!priv->sinkpads) - return FALSE; - - while (priv->sinkpads[i]) { - if (pad == GST_REAL_PAD (priv->sinkpads[i++])) - return TRUE; - } - return FALSE; -} - -static int -gst_entry_scheduler_loop_wrapper (int argc, char **argv) -{ - CothreadPrivate *priv = (CothreadPrivate *) argv; - GstElement *element = priv->element; - - priv->wait = WAIT_FOR_NOTHING; - do { - g_assert (priv->wait == WAIT_FOR_NOTHING); - GST_LOG_OBJECT (SCHED (element), "calling loopfunc for element %s", - GST_ELEMENT_NAME (element)); - if (element->loopfunc) { - element->loopfunc (element); - } else { - GST_ELEMENT_ERROR (element, CORE, SCHEDULER, (_("badly behaving plugin")), - ("loop-based element %s removed loopfunc during processing", - GST_OBJECT_NAME (element))); - } - GST_LOG_OBJECT (SCHED (element), "done calling loopfunc for element %s", - GST_OBJECT_NAME (element)); - priv->wait = WAIT_FOR_NOTHING; - schedule_next_element (SCHED (element)); - } while (TRUE); - - return 0; -} - -static CothreadPrivate * -setup_loop (GstEntryScheduler * sched, GstElement * element) -{ - /* the types not matching is intentional, that's why it's g_new0 */ - CothreadPrivate *priv = (CothreadPrivate *) g_new0 (LoopPrivate, 1); - - priv->element = element; - priv->main = gst_entry_scheduler_loop_wrapper; - priv->wait = WAIT_FOR_NOTHING; - priv->can_schedule = _can_schedule_loop; - - return priv; -} - -/* - * CHAINBASED - */ - -static GstData * -get_buffer (GstEntryScheduler * sched, GstRealPad * pad) -{ - LinkPrivate *priv = PAD_PRIVATE (pad); - GstData *data = priv->bufpen; - - priv->bufpen = NULL; - g_assert (data); - return data; -} - -static int -gst_entry_scheduler_chain_wrapper (int argc, char **argv) -{ - CothreadPrivate *priv = (CothreadPrivate *) argv; - GstElement *element = priv->element; - - priv->wait = WAIT_FOR_PADS; - do { - GstRealPad *pad = priv->schedule_pad; - - g_assert (priv->wait == WAIT_FOR_PADS); - g_assert (pad); - g_assert (GST_PAD_IS_SINK (pad)); - g_assert (PAD_PRIVATE (pad)->bufpen != NULL); - GST_LOG_OBJECT (priv->sched, "calling chainfunc for pad %s:%s", - GST_DEBUG_PAD_NAME (pad)); - if (pad->chainfunc) { - GstData *data = get_buffer (priv->sched, pad); - - gst_pad_call_chain_function (GST_PAD (pad), data); - /* don't do anything after here with the pad, it might already be dead! - the element is still alive though */ - } else { - GST_ELEMENT_ERROR (element, CORE, SCHEDULER, (_("badly behaving plugin")), - ("chain-based element %s removed chainfunc of pad during processing", - GST_OBJECT_NAME (element))); - gst_data_unref (PAD_PRIVATE (pad)->bufpen); - PAD_PRIVATE (pad)->bufpen = NULL; - } - GST_LOG_OBJECT (priv->sched, "done calling chainfunc for element %s", - GST_OBJECT_NAME (element)); - priv->wait = WAIT_FOR_PADS; - schedule_next_element (priv->sched); - } while (TRUE); - - return 0; -} - -static gboolean -_can_schedule_chain (GstRealPad * pad) -{ - g_assert (PAD_PRIVATE (pad)); - - if (GST_PAD_IS_SRC (pad)) - return FALSE; - - g_assert (PAD_PRIVATE (pad)); - return PAD_PRIVATE (pad)->sink->wait == WAIT_FOR_PADS; -} - -static CothreadPrivate * -setup_chain (GstEntryScheduler * sched, GstElement * element) -{ - CothreadPrivate *priv = g_new0 (CothreadPrivate, 1); - - priv->main = gst_entry_scheduler_chain_wrapper; - priv->wait = WAIT_FOR_PADS; - priv->can_schedule = _can_schedule_chain; - - return priv; -} - -/* - * GETBASED - */ - -static int -gst_entry_scheduler_get_wrapper (int argc, char **argv) -{ - CothreadPrivate *priv = (CothreadPrivate *) argv; - GstElement *element = priv->element; - - priv->wait = WAIT_FOR_PADS; - do { - GstRealPad *pad = priv->schedule_pad; - - g_assert (pad); - g_assert (GST_PAD_IS_SRC (pad)); - g_assert (PAD_PRIVATE (pad)->bufpen == NULL); - GST_LOG_OBJECT (priv->sched, "calling getfunc for pad %s:%s", - GST_DEBUG_PAD_NAME (pad)); - if (pad->getfunc) { - GstData *data = gst_pad_call_get_function (GST_PAD (pad)); - - /* make sure the pad still exists and is linked */ - if (!g_list_find (element->pads, pad)) { - GST_ELEMENT_ERROR (element, CORE, SCHEDULER, - (_("badly behaving plugin")), - ("get-based element %s removed pad during getfunc", - GST_OBJECT_NAME (element))); - gst_data_unref (data); - } else if (!GST_PAD_PEER (pad)) { - GST_ELEMENT_ERROR (element, CORE, SCHEDULER, - (_("badly behaving plugin")), - ("get-based element %s unlinked pad during getfunc", - GST_OBJECT_NAME (element))); - gst_data_unref (data); - } else { - PAD_PRIVATE (pad)->bufpen = data; - priv->sched->schedule_now = - g_list_prepend (priv->sched->schedule_now, PAD_PRIVATE (pad)); - } - } else { - GST_ELEMENT_ERROR (element, CORE, SCHEDULER, (_("badly behaving plugin")), - ("get-based element %s removed getfunc during processing", - GST_OBJECT_NAME (element))); - } - GST_LOG_OBJECT (priv->sched, "done calling getfunc for element %s", - GST_ELEMENT_NAME (element)); - - priv->wait = WAIT_FOR_PADS; - schedule_next_element (priv->sched); - } while (TRUE); - - return 0; -} - -static gboolean -_can_schedule_get (GstRealPad * pad) -{ - g_assert (PAD_PRIVATE (pad)); - g_assert (GST_PAD_IS_SRC (pad)); - - g_assert (PAD_PRIVATE (pad)); - return PAD_PRIVATE (pad)->bufpen == NULL && - PAD_PRIVATE (pad)->src->wait == WAIT_FOR_PADS && - can_schedule_pad (PAD_PRIVATE (pad)->sinkpad); -} - -static CothreadPrivate * -setup_get (GstEntryScheduler * sched, GstElement * element) -{ - CothreadPrivate *priv = g_new0 (CothreadPrivate, 1); - - priv->main = gst_entry_scheduler_get_wrapper; - priv->wait = WAIT_FOR_PADS; - priv->can_schedule = _can_schedule_get; - - return priv; -} - -/* - * scheduling functions - */ - -static gboolean -can_schedule_pad (GstRealPad * pad) -{ - LinkPrivate *link = PAD_PRIVATE (pad); - - g_assert (link); - if (GST_STATE (gst_pad_get_parent (GST_PAD (pad))) != GST_STATE_PLAYING) - return FALSE; - if (GST_PAD_IS_SINK (pad)) { - return link->sink->can_schedule (pad); - } else { - return link->src->can_schedule (pad); - } -} - -static gboolean -can_schedule (Entry * entry) -{ - if (ENTRY_IS_LINK (entry)) { - LinkPrivate *link = (LinkPrivate *) entry; - CothreadPrivate *priv; - GstRealPad *pad; - - if (link->bufpen) { - priv = link->sink; - pad = link->sinkpad; - } else { - priv = link->src; - pad = link->srcpad; - } - if (priv->wait != WAIT_FOR_PADS) - return FALSE; - return can_schedule_pad (pad); - } else if (ENTRY_IS_COTHREAD (entry)) { - CothreadPrivate *priv = (CothreadPrivate *) entry; - GList *list; - - if (priv->wait != WAIT_FOR_NOTHING) - return FALSE; - if (GST_STATE (priv->element) != GST_STATE_PLAYING) - return FALSE; - if (GST_FLAG_IS_SET (priv->element, GST_ELEMENT_DECOUPLED)) { - g_assert (PAD_PRIVATE (priv->schedule_pad)); - return TRUE; - } - for (list = priv->element->pads; list; list = g_list_next (list)) { - GstPad *pad = GST_PAD (list->data); - - if (GST_PAD_IS_SRC (pad) && PAD_PRIVATE (pad) && - PAD_PRIVATE (pad)->bufpen != NULL) - return FALSE; - } - return TRUE; - } else { - g_assert_not_reached (); - return FALSE; - } -} - -static void -safe_cothread_switch (GstEntryScheduler * scheduler, cothread * thread) -{ - GList *list; - cothread *cur = do_cothread_get_current (scheduler->context); - - if (cur == thread) { - GST_LOG_OBJECT (scheduler, "switch to same cothread, ignoring"); - } - - for (list = scheduler->schedule_possible; list; list = g_list_next (list)) { - if (ENTRY_IS_COTHREAD (list->data)) { - CothreadPrivate *priv = (CothreadPrivate *) list->data; - - if (priv->thread == thread) - gst_object_ref (GST_OBJECT (priv->element)); - if (priv->thread == cur) - gst_object_unref (GST_OBJECT (priv->element)); - } - } - do_cothread_switch (thread); - if (cur == do_cothread_get_main (scheduler->context)) { - GSList *walk; - - for (walk = scheduler->reaping; walk; walk = g_slist_next (walk)) { - do_cothread_destroy (walk->data); - } - g_slist_free (scheduler->reaping); - scheduler->reaping = NULL; - } -} - -/* the meat - no guarantee as to which cothread this function is called */ -static void -schedule (GstEntryScheduler * sched, Entry * entry) -{ - CothreadPrivate *schedule_me; - - g_assert (can_schedule (entry)); - sched->schedule_now = g_list_remove (sched->schedule_now, entry); - sched->schedule_possible = g_list_remove (sched->schedule_possible, entry); - sched->schedule_possible = g_list_append (sched->schedule_possible, entry); - if (ENTRY_IS_LINK (entry)) { - LinkPrivate *link = (LinkPrivate *) entry; - - if (link->bufpen) { - schedule_me = link->sink; - schedule_me->schedule_pad = link->sinkpad; - } else { - schedule_me = link->src; - schedule_me->schedule_pad = link->srcpad; - } - GST_DEBUG_OBJECT (sched, "scheduling pad %s:%s", - GST_DEBUG_PAD_NAME (schedule_me->schedule_pad)); - } else if (ENTRY_IS_COTHREAD (entry)) { - schedule_me = (CothreadPrivate *) entry; - GST_DEBUG_OBJECT (sched, "scheduling element %s", - GST_OBJECT_NAME (schedule_me->element)); - } else { - g_assert_not_reached (); - GST_DEBUG_OBJECT (sched, "scheduling main after error"); - sched->error = TRUE; - safe_cothread_switch (sched, do_cothread_get_main (sched->context)); - return; - } - - if (!schedule_me->thread) { - GST_LOG_OBJECT (sched, "creating cothread for %p (element %s)", schedule_me, - GST_OBJECT_NAME (schedule_me->element)); - do_cothread_create (schedule_me->thread, sched->context, schedule_me->main, - 0, (gchar **) schedule_me); - } - - safe_cothread_switch (sched, schedule_me->thread); -} - -/* this function will die a horrible death if you have cyclic pipelines */ -static Entry * -schedule_forward (Entry * entry) -{ - if (can_schedule (entry)) - return entry; - if (ENTRY_IS_LINK (entry)) { - return schedule_forward ((Entry *) ((LinkPrivate *) entry)->sink); - } else if (ENTRY_IS_COTHREAD (entry)) { - GList *list; - GstElement *element = ((CothreadPrivate *) entry)->element; - - if (GST_FLAG_IS_SET (element, GST_ELEMENT_DECOUPLED)) - return NULL; - for (list = element->pads; list; list = g_list_next (list)) { - if (GST_PAD_IS_SINK (list->data) || !PAD_PRIVATE (list->data)) - continue; - entry = schedule_forward ((Entry *) PAD_PRIVATE (list->data)); - if (entry) - return entry; - } - } else { - g_assert_not_reached (); - } - return NULL; -} - -static void -schedule_next_element (GstEntryScheduler * scheduler) -{ - if (scheduler->error) { - GST_DEBUG_OBJECT (scheduler, "scheduling main after error"); - safe_cothread_switch (scheduler, do_cothread_get_main (scheduler->context)); - } else if (scheduler->waiting) { - /* FIXME: write me */ - g_assert_not_reached (); - } else if (scheduler->schedule_now) { - GList *test; - - for (test = scheduler->schedule_now; test; test = g_list_next (test)) { - Entry *entry = schedule_forward ((Entry *) test->data); - - if (entry) { - schedule (scheduler, entry); - return; - } - } - if (!scheduler->waiting) { - GST_ERROR_OBJECT (scheduler, - "have stuff that must be scheduled, but nothing that can be scheduled"); - scheduler->error = TRUE; - } - } - GST_DEBUG_OBJECT (scheduler, "scheduling main"); - safe_cothread_switch (scheduler, do_cothread_get_main (scheduler->context)); -} - -/* - * handlers to attach to pads - */ - -static void -gst_entry_scheduler_chain_handler (GstPad * pad, GstData * data) -{ - LinkPrivate *priv = PAD_PRIVATE (pad); - CothreadPrivate *thread = priv->src; - GstEntryScheduler *sched = thread->sched; - - GST_LOG_OBJECT (sched, "putting data %p in pen of pad %s:%s", - data, GST_DEBUG_PAD_NAME (pad)); - - if (priv->bufpen != NULL) { - GST_ERROR_OBJECT (sched, "scheduling error: trying to push data in bufpen" - "of pad %s:%s, but bufpen was full", GST_DEBUG_PAD_NAME (pad)); - sched->error = TRUE; - gst_data_unref (data); - } else { - priv->bufpen = data; - sched->schedule_now = g_list_append (sched->schedule_now, priv); - } - - thread->wait = WAIT_FOR_NOTHING; - schedule_next_element (sched); - - GST_LOG_OBJECT (sched, "done"); -} - -static GstData * -gst_entry_scheduler_get_handler (GstPad * pad) -{ - GstData *data; - GstEntryScheduler *sched = GST_ENTRY_SCHEDULER (gst_pad_get_scheduler (pad)); - GstPad *pads[2] = { NULL, NULL }; - GstPad *ret; - - pad = GST_PAD_PEER (pad); - pads[0] = pad; - GST_LOG_OBJECT (sched, "pad %s:%s pulls", GST_DEBUG_PAD_NAME (pad)); - - data = gst_entry_scheduler_pad_select (GST_SCHEDULER (sched), &ret, pads); - g_assert (pad == ret); - - GST_LOG_OBJECT (sched, "done with %s:%s", GST_DEBUG_PAD_NAME (pad)); - return data; -} - -static gboolean -gst_entry_scheduler_event_handler (GstPad * srcpad, GstEvent * event) -{ - /* FIXME: need to do more here? */ - return GST_RPAD_EVENTFUNC (srcpad) (srcpad, event); -} - -/* - * Entry points for this scheduler. - */ - -static GstData * -gst_entry_scheduler_pad_select (GstScheduler * scheduler, GstPad ** pulled_from, - GstPad ** pads) -{ - GstData *data; - GstRealPad *pad = NULL; - GstElement *element = NULL; - GstEntryScheduler *sched = GST_ENTRY_SCHEDULER (scheduler); - gint i = 0; - - /* sanity check */ - while (pads[i]) { - pad = GST_REAL_PAD (pads[i++]); - if (PAD_PRIVATE (pad)->bufpen) { - sched->schedule_now = - g_list_remove (sched->schedule_now, PAD_PRIVATE (pad)); - goto found; - } - } - element = gst_pad_get_parent (GST_PAD (pad)); - g_assert (element); - g_assert (ELEMENT_PRIVATE (element)->main == - gst_entry_scheduler_loop_wrapper); - LOOP_PRIVATE (element)->sinkpads = pads; - ELEMENT_PRIVATE (element)->wait = WAIT_FOR_PADS; - schedule_next_element (SCHED (element)); - LOOP_PRIVATE (element)->sinkpads = NULL; - pad = ELEMENT_PRIVATE (element)->schedule_pad; - g_assert (PAD_PRIVATE (pad)->bufpen); -found: - data = get_buffer (sched, pad); - g_return_val_if_fail (pulled_from, data); - *pulled_from = GST_PAD (pad); - return data; -} - -static void -gst_entry_scheduler_setup (GstScheduler * sched) -{ - /* first create thread context */ - if (GST_ENTRY_SCHEDULER (sched)->context == NULL) { - GST_DEBUG_OBJECT (sched, "initializing cothread context"); - GST_ENTRY_SCHEDULER (sched)->context = do_cothread_context_init (); - } -} - -static void -safe_cothread_destroy (CothreadPrivate * thread) -{ - GstEntryScheduler *scheduler = thread->sched; - - if (do_cothread_get_current (scheduler->context) == - do_cothread_get_main (scheduler->context)) { - do_cothread_destroy (thread->thread); - } else { - GST_WARNING_OBJECT (scheduler, "delaying destruction of cothread %p", - thread->thread); - scheduler->reaping = g_slist_prepend (scheduler->reaping, thread->thread); - } - thread->thread = NULL; -} - -static void -gst_entry_scheduler_remove_all_cothreads (GstEntryScheduler * scheduler) -{ - GList *list; - - for (list = scheduler->schedule_possible; list; list = g_list_next (list)) { - if (ENTRY_IS_COTHREAD (list->data)) { - CothreadPrivate *priv = (CothreadPrivate *) list->data; - - if (priv->thread) - safe_cothread_destroy (priv); - } - } -} - -static void -gst_entry_scheduler_reset (GstScheduler * sched) -{ - GstEntryScheduler *scheduler = GST_ENTRY_SCHEDULER (sched); - - if (scheduler->context) { - g_return_if_fail (scheduler->reaping == NULL); - gst_entry_scheduler_remove_all_cothreads (scheduler); - do_cothread_context_destroy (scheduler->context); - scheduler->context = NULL; - } -} - -static CothreadPrivate * -_setup_cothread (GstEntryScheduler * sched, GstElement * element, - CothreadPrivate * (*setup_func) (GstEntryScheduler *, GstElement *)) -{ - CothreadPrivate *priv = setup_func (sched, element); - - priv->entry.type = ENTRY_COTHREAD; - priv->sched = sched; - priv->element = element; - sched->schedule_possible = g_list_prepend (sched->schedule_possible, priv); - - if (GST_STATE (element) >= GST_STATE_READY) - gst_entry_scheduler_state_transition (GST_SCHEDULER (sched), element, - GST_STATE_NULL_TO_READY); - if (GST_STATE (element) >= GST_STATE_PAUSED) - gst_entry_scheduler_state_transition (GST_SCHEDULER (sched), element, - GST_STATE_READY_TO_PAUSED); - if (GST_STATE (element) >= GST_STATE_PLAYING) - gst_entry_scheduler_state_transition (GST_SCHEDULER (sched), element, - GST_STATE_PAUSED_TO_PLAYING); - - return priv; -} - -static void -gst_entry_scheduler_add_element (GstScheduler * scheduler, GstElement * element) -{ - GstEntryScheduler *sched = GST_ENTRY_SCHEDULER (scheduler); - - if (GST_FLAG_IS_SET (element, GST_ELEMENT_DECOUPLED)) { - GST_INFO_OBJECT (sched, "decoupled element %s added, ignoring", - GST_OBJECT_NAME (element)); - return; - } - - g_assert (element->sched_private == NULL); - if (element->loopfunc) { - element->sched_private = _setup_cothread (sched, element, setup_loop); - } -} - -static void -_remove_cothread (CothreadPrivate * priv) -{ - GstEntryScheduler *sched = priv->sched; - - sched->waiting = g_list_remove (sched->waiting, priv); - sched->schedule_now = g_list_remove (sched->schedule_now, priv); - sched->schedule_possible = g_list_remove (sched->schedule_possible, priv); - - if (priv->thread) - safe_cothread_destroy (priv); - g_free (priv); -} - -static void -gst_entry_scheduler_remove_element (GstScheduler * scheduler, - GstElement * element) -{ - if (GST_FLAG_IS_SET (element, GST_ELEMENT_DECOUPLED)) { - GST_INFO_OBJECT (scheduler, "decoupled element %s added, ignoring", - GST_OBJECT_NAME (element)); - return; - } - - if (element->sched_private) { - _remove_cothread (element->sched_private); - element->sched_private = NULL; - } -} - -static GstElementStateReturn -gst_entry_scheduler_state_transition (GstScheduler * scheduler, - GstElement * element, gint transition) -{ - GstEntryScheduler *sched = GST_ENTRY_SCHEDULER (scheduler); - - if (GST_FLAG_IS_SET (element, GST_ELEMENT_DECOUPLED)) - return GST_STATE_SUCCESS; - - /* check if our parent changed state */ - switch (transition) { - case GST_STATE_NULL_TO_READY: - break; - case GST_STATE_READY_TO_PAUSED: - break; - case GST_STATE_PAUSED_TO_PLAYING: - break; - case GST_STATE_PLAYING_TO_PAUSED: - break; - case GST_STATE_PAUSED_TO_READY: - if (element == scheduler->parent) { - gst_entry_scheduler_remove_all_cothreads (sched); - } - if (element->sched_private != NULL - && ELEMENT_PRIVATE (element)->thread != NULL) { - safe_cothread_destroy (ELEMENT_PRIVATE (element)); - } - break; - case GST_STATE_READY_TO_NULL: - break; - default: - g_warning ("invalid state change %d for element %s", transition, - GST_OBJECT_NAME (element)); - return GST_STATE_FAILURE; - } - - return GST_STATE_SUCCESS; -} - -static gboolean -gst_entry_scheduler_yield (GstScheduler * sched, GstElement * element) -{ - /* g_assert (ELEMENT_PRIVATE (element)); */ - /* FIXME: queue thinks it may just interrupt, is that ok? */ - if (!ELEMENT_PRIVATE (element)) - return TRUE; - ELEMENT_PRIVATE (element)->wait = WAIT_FOR_NOTHING; - schedule_next_element (GST_ENTRY_SCHEDULER (sched)); - return FALSE; -} - -static gboolean -gst_entry_scheduler_interrupt (GstScheduler * sched, GstElement * element) -{ - /* FIXME? */ - return gst_entry_scheduler_yield (sched, element); -} - -static void -gst_entry_scheduler_error (GstScheduler * scheduler, GstElement * element) -{ - GST_ENTRY_SCHEDULER (scheduler)->error = TRUE; -} - -static void -gst_entry_scheduler_pad_link (GstScheduler * scheduler, GstPad * srcpad, - GstPad * sinkpad) -{ - GstEntryScheduler *sched = GST_ENTRY_SCHEDULER (scheduler); - LinkPrivate *priv; - GstElement *element; - - priv = g_new0 (LinkPrivate, 1); - priv->entry.type = ENTRY_LINK; - /* wrap srcpad */ - element = gst_pad_get_parent (srcpad); - priv->srcpad = GST_REAL_PAD (srcpad); - if (GST_FLAG_IS_SET (element, GST_ELEMENT_DECOUPLED)) { - priv->src = _setup_cothread (sched, element, setup_get); - } else { - priv->src = ELEMENT_PRIVATE (element); - if (!priv->src) { - GList *list; - - for (list = element->pads; list; list = g_list_next (list)) { - if (GST_PAD_IS_SINK (list->data)) { - priv->src = _setup_cothread (sched, element, setup_chain); - break; - } - } - if (!priv->src) - priv->src = _setup_cothread (sched, element, setup_get); - element->sched_private = priv->src; - } - } - GST_RPAD_GETHANDLER (srcpad) = gst_entry_scheduler_get_handler; - GST_RPAD_EVENTHANDLER (srcpad) = gst_entry_scheduler_event_handler; - GST_REAL_PAD (srcpad)->sched_private = priv; - /* wrap sinkpad */ - element = gst_pad_get_parent (sinkpad); - priv->sinkpad = GST_REAL_PAD (sinkpad); - if (GST_FLAG_IS_SET (element, GST_ELEMENT_DECOUPLED)) { - priv->sink = _setup_cothread (sched, element, setup_chain); - } else { - priv->sink = ELEMENT_PRIVATE (element); - if (priv->sink) { - /* LOOP or CHAIN */ - g_assert (priv->sink->main != gst_entry_scheduler_get_wrapper); - } else { - priv->sink = _setup_cothread (sched, element, setup_chain); - element->sched_private = priv->sink; - } - } - GST_RPAD_CHAINHANDLER (sinkpad) = gst_entry_scheduler_chain_handler; - GST_RPAD_EVENTHANDLER (sinkpad) = gst_entry_scheduler_event_handler; - GST_REAL_PAD (sinkpad)->sched_private = priv; - - sched->schedule_possible = g_list_prepend (sched->schedule_possible, priv); -} - -static void -gst_entry_scheduler_pad_unlink (GstScheduler * scheduler, GstPad * srcpad, - GstPad * sinkpad) -{ - GstEntryScheduler *sched = GST_ENTRY_SCHEDULER (scheduler); - LinkPrivate *priv; - GstElement *element; - - priv = PAD_PRIVATE (srcpad); - /* wrap srcpad */ - element = gst_pad_get_parent (srcpad); - if (GST_FLAG_IS_SET (element, GST_ELEMENT_DECOUPLED)) - _remove_cothread (priv->src); - GST_RPAD_GETHANDLER (srcpad) = NULL; - GST_RPAD_EVENTHANDLER (srcpad) = NULL; - GST_REAL_PAD (srcpad)->sched_private = NULL; - /* wrap sinkpad */ - element = gst_pad_get_parent (sinkpad); - if (GST_FLAG_IS_SET (element, GST_ELEMENT_DECOUPLED)) - _remove_cothread (priv->sink); - GST_RPAD_CHAINHANDLER (sinkpad) = NULL; - GST_RPAD_EVENTHANDLER (sinkpad) = NULL; - GST_REAL_PAD (sinkpad)->sched_private = NULL; - - if (priv->bufpen) { - GST_WARNING_OBJECT (sched, - "found data in bufpen while unlinking %s:%s and %s:%s, discarding", - GST_DEBUG_PAD_NAME (srcpad), GST_DEBUG_PAD_NAME (sinkpad)); - gst_data_unref (priv->bufpen); - } - sched->schedule_now = g_list_remove (sched->schedule_now, priv); - sched->schedule_possible = g_list_remove (sched->schedule_possible, priv); - g_free (priv); -} - -static GstSchedulerState -gst_entry_scheduler_iterate (GstScheduler * scheduler) -{ - GstEntryScheduler *sched = GST_ENTRY_SCHEDULER (scheduler); - GList *entries = sched->schedule_possible; - GstSchedulerState ret = GST_SCHEDULER_STATE_STOPPED; - - GST_LOG_OBJECT (sched, "starting iteration in bin %s", - GST_ELEMENT_NAME (scheduler->parent)); - sched->error = FALSE; - - if (sched->schedule_now) { - ret = GST_SCHEDULER_STATE_RUNNING; - } else { - while (entries) { - if (can_schedule ((Entry *) entries->data)) { - Entry *entry = entries->data; - - ret = GST_SCHEDULER_STATE_RUNNING; - sched->schedule_now = g_list_prepend (sched->schedule_now, entry); - sched->schedule_possible = - g_list_remove (sched->schedule_possible, entry); - sched->schedule_possible = - g_list_append (sched->schedule_possible, entry); - break; - } - entries = g_list_next (entries); - } - } - if (ret == GST_SCHEDULER_STATE_RUNNING) - schedule_next_element (sched); - if (sched->error || sched->schedule_now) { - GST_ERROR_OBJECT (sched, "returning error because of %s", - sched->error ? "element error" : "unschedulable elements"); -#if 0 - gst_entry_scheduler_show (scheduler); -#endif - return GST_SCHEDULER_STATE_ERROR; -#if 0 - } else if (GST_STATE (GST_SCHEDULER (sched)->parent) == GST_STATE_PLAYING && - ret == GST_SCHEDULER_STATE_STOPPED && scheduler->schedulers == NULL) { - GST_ERROR_OBJECT (sched, - "returning error because we contain running elements and we didn't do a thing"); - gst_entry_scheduler_show (scheduler); - return GST_SCHEDULER_STATE_ERROR; -#endif - } else if (ret == GST_SCHEDULER_STATE_STOPPED) { - GST_INFO_OBJECT (sched, "done iterating returning STOPPED"); - return GST_SCHEDULER_STATE_STOPPED; - } else { - return ret; - } -} - -static const gchar * -print_state (CothreadPrivate * priv) -{ - switch (priv->wait) { - case WAIT_FOR_NOTHING: - return "runnable"; - case WAIT_FOR_PADS: - return "waiting for pads"; - case WAIT_FOR_ANYTHING: - case WAIT_FOR_MUM: - default: - g_assert_not_reached (); - } - return ""; -} - -static void -print_entry (GstEntryScheduler * sched, Entry * entry) -{ - if (ENTRY_IS_LINK (entry)) { - LinkPrivate *link = (LinkPrivate *) entry; - - g_print (" %s", can_schedule (entry) ? "OK" : " "); - g_print (" %s:%s%s =>", GST_DEBUG_PAD_NAME (link->srcpad), - can_schedule_pad (link->srcpad) ? " (active)" : ""); - g_print (" %s:%s%s", GST_DEBUG_PAD_NAME (link->sinkpad), - can_schedule_pad (link->sinkpad) ? " (active)" : ""); - g_print ("%s\n", link->bufpen ? " FILLED" : ""); -/* g_print (" %s %s:%s%s => %s:%s%s%s\n", can_schedule (entry) ? "OK" : " ", GST_DEBUG_PAD_NAME (link->srcpad), - link->src->can_schedule (link->srcpad) ? " (active)" : "", - GST_DEBUG_PAD_NAME (link->sink), - link->sink->can_schedule (link->sinkpad) ? "(active) " : "", - link->bufpen ? " FILLED" : ""); -*/ } else if (ENTRY_IS_COTHREAD (entry)) { - CothreadPrivate *priv = (CothreadPrivate *) entry; - - g_print (" %s %s (%s)\n", can_schedule (entry) ? "OK" : " ", - GST_ELEMENT_NAME (priv->element), print_state (priv)); - } else { - g_assert_not_reached (); - } -} - -static void -gst_entry_scheduler_show (GstScheduler * scheduler) -{ - GstEntryScheduler *sched = GST_ENTRY_SCHEDULER (scheduler); - GList *list; - - g_print ("entry points waiting:\n"); - for (list = sched->waiting; list; list = g_list_next (list)) { - print_entry (sched, (Entry *) list->data); - } - g_print ("entry points to schedule now:\n"); - for (list = sched->schedule_now; list; list = g_list_next (list)) { - print_entry (sched, (Entry *) list->data); - } - g_print ("entry points that might be scheduled:\n"); - for (list = sched->schedule_possible; list; list = g_list_next (list)) { - print_entry (sched, (Entry *) list->data); - } -} - -static gboolean -plugin_init (GstPlugin * plugin) -{ - if (!gst_scheduler_register (plugin, "entry" COTHREADS_NAME, - "A entry scheduler using " COTHREADS_NAME " cothreads", - GST_TYPE_ENTRY_SCHEDULER)) - return FALSE; - - GST_DEBUG_CATEGORY_INIT (debug_scheduler, "entry" COTHREADS_NAME, 0, - "entry " COTHREADS_NAME "scheduler"); - - return TRUE; -} - -GST_PLUGIN_DEFINE (GST_VERSION_MAJOR, GST_VERSION_MINOR, "gstentry" COTHREADS_NAME "scheduler", "an entry scheduler using " COTHREADS_NAME " cothreads", /* FIXME */ - plugin_init, VERSION, GST_LICENSE, GST_PACKAGE, GST_ORIGIN) diff --git a/gst/schedulers/faircothreads.c b/gst/schedulers/faircothreads.c deleted file mode 100644 index c5c0f667ef..0000000000 --- a/gst/schedulers/faircothreads.c +++ /dev/null @@ -1,615 +0,0 @@ -/* GStreamer - * Copyright (C) 2004 Martin Soto - * - * faircothread.c: High level cothread implementation for the fair scheduler. - * - * 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. - */ - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - -#include - -#include - -#ifdef _COTHREADS_PTH -#include "pth-cothreads.h" -#else -#include "cothreads_compat.h" -#endif - -#include "faircothreads.h" - -#if !defined(GST_DISABLE_GST_DEBUG) && defined(FAIRSCHEDULER_USE_GETTID) -#include -#include - -_syscall0 (pid_t, gettid) -#endif - GST_DEBUG_CATEGORY_EXTERN (debug_fair_ct); -#define GST_CAT_DEFAULT debug_fair_ct - - -/* - * Support for Asynchronous Operations - */ - - enum - { - ASYNC_OP_CHANGE_STATE = 1, - ASYNC_OP_AWAKE - }; - - typedef struct _AsyncOp AsyncOp; - typedef struct _AsyncOpChangeState AsyncOpChangeState; - typedef struct _AsyncOpAwake AsyncOpAwake; - - struct _AsyncOp - { - int type; - }; - - struct _AsyncOpChangeState - { - AsyncOp parent; - GstFairSchedulerCothread *ct; /* Cothread whose state will be - changed. */ - gint new_state; /* New state for the cothread. */ - }; - - struct _AsyncOpAwake - { - AsyncOp parent; - GstFairSchedulerCothread *ct; /* Cothread to awake. */ - gint priority; /* Priority for the cothread. */ - }; - - -#ifndef GST_DISABLE_GST_DEBUG - static gchar *gst_fairscheduler_ct_state_names[] = { - "stopped", - "suspended", - "running" - }; -#endif - - -/* - * Helpers - */ - -static int -cothread_base_func (int argc, char **argv) -{ - GstFairSchedulerCothread *ct; - - g_return_val_if_fail (argc >= 1, -1); - - ct = (GstFairSchedulerCothread *) argv[0]; - - GST_INFO ("queue %p: Cothread %p starting", ct->queue, ct); -#ifndef GST_DISABLE_GST_DEBUG -#ifdef FAIRSCHEDULER_USE_GETTID - ct->pid = gettid (); -#else - ct->pid = 0; -#endif -#endif - - /* Call the thread function. This looks sort of funny, but there's - no other way I know of doing it. */ - switch (argc - 1) { - case 0: - ct->func (ct, NULL); - break; - case 1: - ct->func (ct, argv[1], NULL); - break; - case 2: - ct->func (ct, argv[1], argv[2], NULL); - break; - case 3: - ct->func (ct, argv[1], argv[2], argv[3], NULL); - break; - case 4: - ct->func (ct, argv[1], argv[2], argv[3], argv[4], NULL); - break; - case 5: - ct->func (ct, argv[1], argv[2], argv[3], argv[4], argv[5], NULL); - break; - case 6: - ct->func (ct, argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], NULL); - break; - case 7: - ct->func (ct, argv[1], argv[2], argv[3], argv[4], argv[5], - argv[6], argv[7], NULL); - break; - default: - g_return_val_if_reached (-1); - break; - } - - /* After the cothread function is finished, we go to the stopped - state. */ - gst_fair_scheduler_cothread_change_state (ct, - GST_FAIRSCHEDULER_CTSTATE_STOPPED); - - return 0; -} - - -static void -cothread_activate (GstFairSchedulerCothread * ct, gint priority) -{ - GST_DEBUG ("queue %p: activating cothread %p", ct->queue, ct); - - if (priority > 0) { - g_queue_push_head (ct->queue->ct_queue, ct); - } else { - g_queue_push_tail (ct->queue->ct_queue, ct); - } -} - - -static void -cothread_deactivate (GstFairSchedulerCothread * ct) -{ - GList *node; - - GST_DEBUG ("queue %p: deactivating cothread %p", ct->queue, ct); - - /* Find the node. */ - node = g_list_find (ct->queue->ct_queue->head, ct); - if (node == NULL) { - return; - } - - if (node->next == NULL) { - g_queue_pop_tail (ct->queue->ct_queue); - } else { - ct->queue->ct_queue->head = - g_list_remove_link (ct->queue->ct_queue->head, node); - } -} - - -static void -queue_async_op (GstFairSchedulerCothreadQueue * queue, AsyncOp * op) -{ - g_mutex_lock (queue->async_mutex); - g_queue_push_tail (queue->async_queue, op); - g_cond_signal (queue->new_async_op); - g_mutex_unlock (queue->async_mutex); -} - - -/* - * Cothreads API - */ - -extern GstFairSchedulerCothreadQueue * -gst_fair_scheduler_cothread_queue_new (void) -{ - GstFairSchedulerCothreadQueue *new; - - new = g_malloc (sizeof (GstFairSchedulerCothreadQueue)); - - new->context = NULL; - new->ct_queue = g_queue_new (); - - new->async_queue = g_queue_new (); - new->async_mutex = g_mutex_new (); - new->new_async_op = g_cond_new (); - - return new; -} - - -extern void -gst_fair_scheduler_cothread_queue_destroy (GstFairSchedulerCothreadQueue * - queue) -{ - GList *iter; - - /* Destroy all remaining cothreads. */ - for (iter = queue->ct_queue->head; iter != NULL; iter = iter->next) { - gst_fair_scheduler_cothread_destroy ( - (GstFairSchedulerCothread *) iter->data); - } - g_queue_free (queue->ct_queue); - - for (iter = queue->async_queue->head; iter != NULL; iter = iter->next) { - g_free (iter->data); - } - g_queue_free (queue->async_queue); - - g_mutex_free (queue->async_mutex); - g_cond_free (queue->new_async_op); - - g_free (queue); -} - - -extern void -gst_fair_scheduler_cothread_queue_start (GstFairSchedulerCothreadQueue * queue) -{ - if (queue->context == NULL) { - do_cothreads_init (NULL); - queue->context = do_cothread_context_init (); - } -} - - -extern void -gst_fair_scheduler_cothread_queue_stop (GstFairSchedulerCothreadQueue * queue) -{ - if (queue->context != NULL) { - do_cothread_context_destroy (queue->context); - } -} - - -gboolean -gst_fair_scheduler_cothread_queue_iterate (GstFairSchedulerCothreadQueue * - queue) -{ - GstFairSchedulerCothread *ct; - - g_return_val_if_fail (queue->context != NULL, FALSE); - - GST_LOG ("queue %p: iterating", queue); - - /* Perform any pending asynchronous operations. Checking the queue - is safe and more efficient without locking the mutex. */ - if (!g_queue_is_empty (queue->async_queue)) { - AsyncOp *basic_op; - - GST_LOG ("queue %p: processing asynchronous operations", queue); - - g_mutex_lock (queue->async_mutex); - - while (!g_queue_is_empty (queue->async_queue)) { - basic_op = (AsyncOp *) g_queue_pop_head (queue->async_queue); - - switch (basic_op->type) { - case ASYNC_OP_CHANGE_STATE: - { - AsyncOpChangeState *op = (AsyncOpChangeState *) basic_op; - - gst_fair_scheduler_cothread_change_state (op->ct, op->new_state); - } - break; - case ASYNC_OP_AWAKE: - { - AsyncOpAwake *op = (AsyncOpAwake *) basic_op; - - gst_fair_scheduler_cothread_awake (op->ct, op->priority); - } - break; - default: - g_return_val_if_reached (FALSE); - break; - } - - g_free (basic_op); - } - - g_mutex_unlock (queue->async_mutex); - } - - /* First cothread in the queue (if any) should get control. */ - ct = g_queue_peek_head (queue->ct_queue); - - if (ct == NULL) { - GTimeVal timeout; - - g_get_current_time (&timeout); - g_time_val_add (&timeout, 5000); - - /* No cothread available, wait until some other thread queues an - operation. */ - g_mutex_lock (queue->async_mutex); - g_cond_timed_wait (queue->new_async_op, queue->async_mutex, &timeout); - g_mutex_unlock (queue->async_mutex); - - return FALSE; - } - - g_return_val_if_fail (ct->state == GST_FAIRSCHEDULER_CTSTATE_RUNNING, FALSE); - - /* Check for a cothread mutex. */ - if (ct->mutex != NULL) { - g_mutex_lock (ct->mutex); - ct->mutex = NULL; - } - - GST_LOG ("queue %p: giving control to %p", queue, ct); - - /* Handle control to the cothread. */ - do_cothread_switch (ct->execst); - - return TRUE; -} - - -void -gst_fair_scheduler_cothread_queue_show (GstFairSchedulerCothreadQueue * queue) -{ - GList *iter; - GstFairSchedulerCothread *ct; - - g_print ("\n Running cothreads (last is active):\n"); - - for (iter = queue->ct_queue->tail; iter != NULL; iter = iter->prev) { - ct = (GstFairSchedulerCothread *) iter->data; -#ifndef GST_DISABLE_GST_DEBUG - g_print (" %p: %s (%d)\n", ct, ct->readable_name->str, ct->pid); -#endif - } -} - - -GstFairSchedulerCothread * -gst_fair_scheduler_cothread_new (GstFairSchedulerCothreadQueue * queue, - GstFairSchedulerCtFunc function, gpointer first_arg, ...) -{ - GstFairSchedulerCothread *new; - va_list ap; - gpointer arg; - - new = g_malloc (sizeof (GstFairSchedulerCothread)); - - new->queue = queue; - new->func = function; - - /* The first parameter is always the cothread structure itself. */ - new->argv[0] = (char *) new; - new->argc = 1; - - /* Store the parameters. */ - va_start (ap, first_arg); - arg = first_arg; - while (new->argc < GST_FAIRSCHEDULER_MAX_CTARGS && arg != NULL) { - new->argv[new->argc] = (char *) arg; - new->argc++; - arg = va_arg (ap, gpointer); - } - - /* Make sure we don't have more parameters than we can handle. */ - g_return_val_if_fail (arg == NULL, NULL); - - /* Creation of the actual execution state is defered to transition - to running/suspended. */ - new->execst = NULL; - - /* All cothreads are created in the stopped state. */ - new->state = GST_FAIRSCHEDULER_CTSTATE_STOPPED; - - new->mutex = NULL; - -#ifndef GST_DISABLE_GST_DEBUG - new->readable_name = g_string_new (""); - new->pid = 0; -#endif - - GST_DEBUG ("queue %p: cothread %p created", queue, new); - - return new; -} - - -void -gst_fair_scheduler_cothread_destroy (GstFairSchedulerCothread * ct) -{ - GST_DEBUG ("queue %p: destroying cothread %p", ct->queue, ct); - - if (ct->state != GST_FAIRSCHEDULER_CTSTATE_STOPPED) { - cothread_deactivate (ct); - } - - if (ct->execst != NULL) { - do_cothread_destroy (ct->execst); - } -#ifndef GST_DISABLE_GST_DEBUG - g_string_free (ct->readable_name, TRUE); -#endif - - g_free (ct); -} - - -void -gst_fair_scheduler_cothread_change_state (GstFairSchedulerCothread * ct, - gint new_state) -{ - if (new_state == ct->state) { - return; - } - - GST_DEBUG ("queue %p: changing state of %p from %s to %s", ct->queue, ct, - gst_fairscheduler_ct_state_names[ct->state], - gst_fairscheduler_ct_state_names[new_state]); - - switch (ct->state) { - case GST_FAIRSCHEDULER_CTSTATE_STOPPED: - /* (Re)Initialize the cothread. */ - if (ct->execst == NULL) { - /* Initialize cothread's execution state. */ - do_cothread_create (ct->execst, ct->queue->context, - cothread_base_func, ct->argc, ct->argv); - GST_LOG_OBJECT (ct->queue, - "cothread %p has exec state %p", ct, ct->execst); - } else { - /* Reset cothread's execution state. */ - do_cothread_setfunc (ct->execst, ct->queue->context, - cothread_base_func, ct->argc, ct->argv); - } - - ct->sleeping = FALSE; - - if (new_state == GST_FAIRSCHEDULER_CTSTATE_RUNNING) { - cothread_activate (ct, 0); - } - - break; - - case GST_FAIRSCHEDULER_CTSTATE_RUNNING: - if (!ct->sleeping) { - cothread_deactivate (ct); - } - break; - - case GST_FAIRSCHEDULER_CTSTATE_SUSPENDED: - if (new_state == GST_FAIRSCHEDULER_CTSTATE_RUNNING && !ct->sleeping) { - cothread_activate (ct, 0); - } - break; - } - - ct->state = new_state; -} - - -void -gst_fair_scheduler_cothread_change_state_async (GstFairSchedulerCothread * ct, - gint new_state) -{ - AsyncOpChangeState *op; - - /* Queue an asynchronous operation. */ - op = g_new (AsyncOpChangeState, 1); - op->parent.type = ASYNC_OP_CHANGE_STATE; - op->ct = ct; - op->new_state = new_state; - - queue_async_op (ct->queue, (AsyncOp *) op); -} - - -void -gst_fair_scheduler_cothread_sleep (GstFairSchedulerCothreadQueue * queue) -{ - gst_fair_scheduler_cothread_sleep_mutex (queue, NULL); -} - - -/* - * Go to sleep but unblock the mutex while sleeping. - */ -void -gst_fair_scheduler_cothread_sleep_mutex (GstFairSchedulerCothreadQueue * queue, - GMutex * mutex) -{ - GstFairSchedulerCothread *ct; - - g_return_if_fail (queue->context != NULL); - - /* The sleep operation can be invoked when the cothread is already - deactivated. */ - ct = gst_fair_scheduler_cothread_current (queue); - if (ct != NULL && ct->execst == do_cothread_get_current (queue->context)) { - ct = g_queue_pop_head (queue->ct_queue); - ct->sleeping = TRUE; - } - - ct->mutex = mutex; - if (mutex != NULL) { - g_mutex_unlock (mutex); - } - - GST_LOG ("queue %p: cothread going to sleep", queue); - - /* Switch back to the main cothread. */ - do_cothread_switch (do_cothread_get_main (queue->context)); -} - - -void -gst_fair_scheduler_cothread_yield (GstFairSchedulerCothreadQueue * queue) -{ - gst_fair_scheduler_cothread_yield_mutex (queue, NULL); -} - - -void -gst_fair_scheduler_cothread_yield_mutex (GstFairSchedulerCothreadQueue * queue, - GMutex * mutex) -{ - GstFairSchedulerCothread *ct; - - g_return_if_fail (queue->context != NULL); - - /* The yield operation can be invoked when the cothread is already - deactivated. */ - ct = gst_fair_scheduler_cothread_current (queue); - if (ct != NULL && ct->execst == do_cothread_get_current (queue->context)) { - ct = g_queue_pop_head (queue->ct_queue); - g_queue_push_tail (queue->ct_queue, ct); - } - - ct->mutex = mutex; - if (mutex != NULL) { - g_mutex_unlock (mutex); - } - - GST_LOG ("queue %p: cothread yielding control", queue); - - /* Switch back to the main cothread. */ - do_cothread_switch (do_cothread_get_main (queue->context)); -} - - -void -gst_fair_scheduler_cothread_awake (GstFairSchedulerCothread * ct, gint priority) -{ - g_return_if_fail (ct->state != GST_FAIRSCHEDULER_CTSTATE_STOPPED); - - if (!ct->sleeping) { - /* Cothread is already awake. */ - return; - } - - ct->sleeping = FALSE; - - if (ct->state == GST_FAIRSCHEDULER_CTSTATE_RUNNING) { - cothread_activate (ct, priority); - } -} - - -void -gst_fair_scheduler_cothread_awake_async (GstFairSchedulerCothread * ct, - gint priority) -{ - AsyncOpAwake *op; - - /* Queue an asynchronous operation. */ - op = g_new (AsyncOpAwake, 1); - op->parent.type = ASYNC_OP_AWAKE; - op->ct = ct; - op->priority = priority; - - queue_async_op (ct->queue, (AsyncOp *) op); -} - - -GstFairSchedulerCothread * -gst_fair_scheduler_cothread_current (GstFairSchedulerCothreadQueue * queue) -{ - return g_queue_peek_head (queue->ct_queue); -} diff --git a/gst/schedulers/faircothreads.h b/gst/schedulers/faircothreads.h deleted file mode 100644 index 98faeca730..0000000000 --- a/gst/schedulers/faircothreads.h +++ /dev/null @@ -1,163 +0,0 @@ -/* GStreamer - * Copyright (C) 2004 Martin Soto - * - * faircothread.h: High level cothread implementation for the fair scheduler. - * - * 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 __FAIRCOTHREADS_H__ -#define __FAIRCOTHREADS_H__ - - -#ifdef _COTHREADS_PTH -#include "pth-cothreads.h" -#else -#define GTHREAD_COTHREADS_NO_DEFINITIONS -#include "cothreads_compat.h" -#endif - - -typedef struct _GstFairSchedulerCothread GstFairSchedulerCothread; -typedef struct _GstFairSchedulerCothreadQueue GstFairSchedulerCothreadQueue; - -/* Possible states of a cothread. */ -enum -{ - GST_FAIRSCHEDULER_CTSTATE_STOPPED, - GST_FAIRSCHEDULER_CTSTATE_SUSPENDED, - GST_FAIRSCHEDULER_CTSTATE_RUNNING, -}; - -/* Maximum number of cothread parameters. */ -#define GST_FAIRSCHEDULER_MAX_CTARGS 7 - -/* Cothread function type. */ -typedef void (*GstFairSchedulerCtFunc) (GstFairSchedulerCothread * ct, - gpointer first_arg, ...); - -struct _GstFairSchedulerCothread { - GstFairSchedulerCothreadQueue *queue; - /* Cothread queue this cothread - belongs to. */ - GstFairSchedulerCtFunc func; /* Cothread function. */ - char *argv[1 + GST_FAIRSCHEDULER_MAX_CTARGS]; /* - Arguments for the cothread function. - argv[0] is always the cothread - object itself. */ - int argc; /* Number of stored parameters. */ - - cothread *execst; /* Execution state for this cothread. */ - gint state; /* Current cothread state. */ - gboolean sleeping; /* Is this cothread sleeping? */ - - GMutex *mutex; /* If not null, a mutex to lock before - giving control to this cothread. */ - -#ifndef GST_DISABLE_GST_DEBUG - GString *readable_name; /* Readable name for this cothread. */ - gint pid; /* Process or thread id associated to - this cothread. */ -#endif -}; - -struct _GstFairSchedulerCothreadQueue { - cothread_context *context; /* Cothread context. */ - GQueue *ct_queue; /* Queue of currently running - cothreads. New cothreads are pushed - on the tail. If a cothread is - executing, it is the one in the - head. */ - - /* Asynchronous support. */ - GQueue *async_queue; /* Queue storing asynchronous - operations (operations on the queue - requested potentially from other - threads. */ - GMutex *async_mutex; /* Mutex to protect acceses to - async_queue. */ - GCond *new_async_op; /* Condition variable to signal the - presence of a new asynchronous - operation in the queue. */ -}; - - -extern GstFairSchedulerCothreadQueue * -gst_fair_scheduler_cothread_queue_new (void); - -extern void -gst_fair_scheduler_cothread_queue_destroy ( - GstFairSchedulerCothreadQueue * queue); - -extern void -gst_fair_scheduler_cothread_queue_start ( - GstFairSchedulerCothreadQueue * queue); - -extern void -gst_fair_scheduler_cothread_queue_stop ( - GstFairSchedulerCothreadQueue * queue); - -extern gboolean -gst_fair_scheduler_cothread_queue_iterate ( - GstFairSchedulerCothreadQueue * queue); - -extern void -gst_fair_scheduler_cothread_queue_show ( - GstFairSchedulerCothreadQueue * queue); - - -extern GstFairSchedulerCothread * -gst_fair_scheduler_cothread_new (GstFairSchedulerCothreadQueue * queue, - GstFairSchedulerCtFunc function, gpointer first_arg, ...); - -extern void -gst_fair_scheduler_cothread_destroy (GstFairSchedulerCothread * ct); - -extern void -gst_fair_scheduler_cothread_change_state (GstFairSchedulerCothread * ct, - gint new_state); - -extern void -gst_fair_scheduler_cothread_change_state_async ( - GstFairSchedulerCothread * ct, gint new_state); - -extern void -gst_fair_scheduler_cothread_sleep (GstFairSchedulerCothreadQueue * queue); - -extern void -gst_fair_scheduler_cothread_sleep_mutex ( - GstFairSchedulerCothreadQueue * queue, GMutex * mutex); - -extern void -gst_fair_scheduler_cothread_yield (GstFairSchedulerCothreadQueue * queue); - -extern void -gst_fair_scheduler_cothread_yield_mutex ( - GstFairSchedulerCothreadQueue * queue, GMutex * mutex); - -extern void -gst_fair_scheduler_cothread_awake (GstFairSchedulerCothread * ct, - gint priority); - -extern void -gst_fair_scheduler_cothread_awake_async (GstFairSchedulerCothread * ct, - gint priority); - -extern GstFairSchedulerCothread * -gst_fair_scheduler_cothread_current (GstFairSchedulerCothreadQueue * queue); - - -#endif /* __FAIRCOTHREADS_H__ */ diff --git a/gst/schedulers/fairscheduler.c b/gst/schedulers/fairscheduler.c deleted file mode 100644 index 51765863c3..0000000000 --- a/gst/schedulers/fairscheduler.c +++ /dev/null @@ -1,1415 +0,0 @@ -/* GStreamer - * Copyright (C) 2004 Martin Soto - * - * gstfairscheduler.c: Fair cothread based scheduler - * - * 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. - */ - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - -#include - -#include -#include - -#include "faircothreads.h" - - -GST_DEBUG_CATEGORY_STATIC (debug_fair); -#define GST_CAT_DEFAULT debug_fair -GST_DEBUG_CATEGORY (debug_fair_ct); -GST_DEBUG_CATEGORY_STATIC (debug_fair_queues); - - -typedef struct _GstFairScheduler GstFairScheduler; -typedef struct _GstFairSchedulerClass GstFairSchedulerClass; -typedef struct _GstFairSchedulerPrivElem GstFairSchedulerPrivElem; -typedef struct _GstFairSchedulerPrivLink GstFairSchedulerPrivLink; -typedef struct _GstFairSchedulerWaitEntry GstFairSchedulerWaitEntry; - - -#define GST_TYPE_FAIR_SCHEDULER \ - (gst_fair_scheduler_get_type()) -#define GST_FAIR_SCHEDULER(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_FAIR_SCHEDULER,GstFairScheduler)) -#define GST_FAIR_SCHEDULER_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_FAIR_SCHEDULER,GstFairSchedulerClass)) -#define GST_IS_FAIR_SCHEDULER(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_FAIR_SCHEDULER)) -#define GST_IS_FAIR_SCHEDULER_CLASS(obj) \ - (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_FAIR_SCHEDULER)) - - -/* Private scheduler data associated to an element. */ -struct _GstFairSchedulerPrivElem -{ - GstFairSchedulerCothread *elem_ct; - /* Element's cothread. */ - GArray *chain_get_pads; /* Pads in this element with either a - get or a chain function. */ -}; - -#define ELEM_PRIVATE(element) \ - ((GstFairSchedulerPrivElem *) GST_ELEMENT(element)->sched_private) - - -/* Private scheduler data associated to a pad link. This structure is - always stored in the source pad of the link. */ -struct _GstFairSchedulerPrivLink -{ - GstFairScheduler *owner; /* The "owner" of this link. */ - - GstData *bufpen; /* A placeholder for one buffer. */ - GstFairSchedulerCothread *waiting_writer; - /* Cothread waiting to write. */ - GstFairSchedulerCothread *waiting_reader; - /* Cothread waiting to read. */ - - GstFairSchedulerCothread *decoupled_ct; - /* Cothread to handle the decoupled - pad in this link (if any). */ - gulong decoupled_signal_id; /* Id for the signal handler - responsible for managing the - cothread. */ - - /* Queue optimizations. */ - gulong queue_blocked_signal_id; - /* Id for the signal handler connected - to the under/overrun signal of a - queue. */ - GstFairSchedulerCothread *waiting_for_queue; - /* Cothread waiting for a queue to - unblock. */ -}; - -#define LINK_PRIVATE(pad) \ - ((GstFairSchedulerPrivLink *) \ - (GST_PAD_IS_SRC (pad) ? \ - GST_REAL_PAD(pad)->sched_private : \ - GST_RPAD_PEER (GST_REAL_PAD(pad))->sched_private)) - - -/* An entry in the clock wait list. */ -struct _GstFairSchedulerWaitEntry -{ - GstFairSchedulerCothread *ct; /* The waiting cothread. */ - GstClockTime time; /* The clock time it should wake up - on. */ -}; - - -struct _GstFairScheduler -{ - GstScheduler parent; - - GstFairSchedulerCothreadQueue *cothreads; - /* The queue handling the cothreads - for the scheduler. */ - - /* Scheduling control. */ - gboolean in_element; /* True if we are running element - code. */ - - /* Clock wait support. */ - GSList *waiting; /* List of waiting cothreads. Elements - are GstFairSchedulerWaitEntry - structures. */ - - /* Timing statistics. */ - GTimer *iter_timer; /* Iteration timer. */ - guint iter_count; /* Iteration count. */ - -#ifndef GST_DISABLE_GST_DEBUG - GList *elements; /* List of all registered elements - (needed only for debugging. */ - GList *sources; /* List of all source pads involved in - registered links (needed only for - debugging. */ -#endif -}; - - -struct _GstFairSchedulerClass -{ - GstSchedulerClass parent_class; -}; - - -static GType _gst_fair_scheduler_type = 0; - - -enum -{ - ARG_0, -}; - - -/* Standard GObject Operations */ - -static GType gst_fair_scheduler_get_type (void); - -static void gst_fair_scheduler_class_init (GstFairSchedulerClass * klass); - -static void gst_fair_scheduler_init (GObject * object); - -static void gst_fair_scheduler_dispose (GObject * object); - -static void -gst_fair_scheduler_get_property (GObject * object, guint prop_id, - GValue * value, GParamSpec * pspec); - -static void -gst_fair_scheduler_set_property (GObject * object, guint prop_id, - const GValue * value, GParamSpec * pspec); - - -/* Cothread Function Wrappers */ - -static void -gst_fair_scheduler_loop_wrapper (GstFairSchedulerCothread * ct, - GstElement * element); - - -/* Chain, Get and Event Handlers */ - -static void gst_fair_scheduler_chain_handler (GstPad * pad, GstData * data); - -static GstData *gst_fair_scheduler_get_handler (GstPad * pad); - - -/* GstScheduler Operations */ - -static void gst_fair_scheduler_setup (GstScheduler * sched); - -static void gst_fair_scheduler_reset (GstScheduler * sched); - -static void -gst_fair_scheduler_add_element (GstScheduler * sched, GstElement * element); - -static void -gst_fair_scheduler_remove_element (GstScheduler * sched, GstElement * element); - -static GstElementStateReturn -gst_fair_scheduler_state_transition (GstScheduler * sched, - GstElement * element, gint transition); - -static void -decoupled_state_transition (GstElement * element, gint old_state, - gint new_state, gpointer user_data); - -static void -gst_fair_scheduler_scheduling_change (GstScheduler * sched, - GstElement * element); - -static gboolean -gst_fair_scheduler_yield (GstScheduler * sched, GstElement * element); - -static gboolean -gst_fair_scheduler_interrupt (GstScheduler * sched, GstElement * element); - -static void -gst_fair_scheduler_error (GstScheduler * sched, GstElement * element); - -static void -gst_fair_scheduler_pad_link (GstScheduler * sched, GstPad * srcpad, - GstPad * sinkpad); - -static void -gst_fair_scheduler_pad_unlink (GstScheduler * sched, GstPad * srcpad, - GstPad * sinkpad); - -static GstData *gst_fair_scheduler_pad_select (GstScheduler * sched, - GstPad ** pulled_from, GstPad ** pads); - -static GstClockReturn -gst_fair_scheduler_clock_wait (GstScheduler * sched, GstElement * element, - GstClockID id, GstClockTimeDiff * jitter); - -static GstSchedulerState gst_fair_scheduler_iterate (GstScheduler * sched); - -static void gst_fair_scheduler_show (GstScheduler * sched); - - -static GstSchedulerClass *parent_class = NULL; - - -/* - * Standard GObject Operations - */ - -static GType -gst_fair_scheduler_get_type (void) -{ - if (!_gst_fair_scheduler_type) { - static const GTypeInfo scheduler_info = { - sizeof (GstFairSchedulerClass), - NULL, - NULL, - (GClassInitFunc) gst_fair_scheduler_class_init, - NULL, - NULL, - sizeof (GstFairScheduler), - 0, - (GInstanceInitFunc) gst_fair_scheduler_init, - NULL - }; - - _gst_fair_scheduler_type = g_type_register_static (GST_TYPE_SCHEDULER, - "GstFair" COTHREADS_NAME_CAPITAL "Scheduler", &scheduler_info, 0); - } - return _gst_fair_scheduler_type; -} - - -static void -gst_fair_scheduler_class_init (GstFairSchedulerClass * klass) -{ - GObjectClass *gobject_class; - GstObjectClass *gstobject_class; - GstSchedulerClass *gstscheduler_class; - - gobject_class = (GObjectClass *) klass; - gstobject_class = (GstObjectClass *) klass; - gstscheduler_class = (GstSchedulerClass *) klass; - - parent_class = g_type_class_ref (GST_TYPE_SCHEDULER); - - gobject_class->set_property = gst_fair_scheduler_set_property; - gobject_class->get_property = gst_fair_scheduler_get_property; - gobject_class->dispose = gst_fair_scheduler_dispose; - - gstscheduler_class->setup = gst_fair_scheduler_setup; - gstscheduler_class->reset = gst_fair_scheduler_reset; - gstscheduler_class->add_element = gst_fair_scheduler_add_element; - gstscheduler_class->remove_element = gst_fair_scheduler_remove_element; - gstscheduler_class->state_transition = gst_fair_scheduler_state_transition; - gstscheduler_class->scheduling_change = gst_fair_scheduler_scheduling_change; - gstscheduler_class->yield = gst_fair_scheduler_yield; - gstscheduler_class->interrupt = gst_fair_scheduler_interrupt; - gstscheduler_class->error = gst_fair_scheduler_error; - gstscheduler_class->pad_link = gst_fair_scheduler_pad_link; - gstscheduler_class->pad_unlink = gst_fair_scheduler_pad_unlink; - gstscheduler_class->pad_select = gst_fair_scheduler_pad_select; - gstscheduler_class->clock_wait = gst_fair_scheduler_clock_wait; - gstscheduler_class->iterate = gst_fair_scheduler_iterate; - gstscheduler_class->show = gst_fair_scheduler_show; -} - - -static void -gst_fair_scheduler_init (GObject * object) -{ - GstFairScheduler *fsched = GST_FAIR_SCHEDULER (object); - - fsched->cothreads = gst_fair_scheduler_cothread_queue_new (); - - /* Proudly suporting the select operation since 2004! */ - GST_FLAG_SET (fsched, GST_SCHEDULER_FLAG_NEW_API); - - fsched->in_element = FALSE; - - fsched->waiting = NULL; - - fsched->iter_timer = g_timer_new (); - -#ifndef GST_DISABLE_GST_DEBUG - fsched->elements = NULL; - fsched->sources = NULL; -#endif -} - - -static void -gst_fair_scheduler_dispose (GObject * object) -{ - GstFairScheduler *fsched = GST_FAIR_SCHEDULER (object); - - GST_WARNING_OBJECT (fsched, "disposing"); - - g_slist_free (fsched->waiting); - - g_timer_destroy (fsched->iter_timer); - - gst_fair_scheduler_cothread_queue_destroy (fsched->cothreads); - -#ifndef GST_DISABLE_GST_DEBUG - g_list_free (fsched->elements); - g_list_free (fsched->sources); -#endif - - G_OBJECT_CLASS (parent_class)->dispose (object); -} - - -static void -gst_fair_scheduler_get_property (GObject * object, guint prop_id, - GValue * value, GParamSpec * pspec) -{ - /*GstFairScheduler *fsched = GST_FAIR_SCHEDULER (object); */ - - switch (prop_id) { - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - - -static void -gst_fair_scheduler_set_property (GObject * object, guint prop_id, - const GValue * value, GParamSpec * pspec) -{ - /*GstFairScheduler *fsched = GST_FAIR_SCHEDULER (object); */ - - switch (prop_id) { - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - - -/* - * Helpers - */ - -static GstFairSchedulerPrivLink * -get_link_priv (GstPad * pad) -{ - GstFairSchedulerPrivLink *priv; - - GstRealPad *real = GST_PAD_REALIZE (pad); - - if (GST_RPAD_DIRECTION (real) == GST_PAD_SINK) { - real = GST_RPAD_PEER (real); - } - - priv = LINK_PRIVATE (real); - g_return_val_if_fail (priv != NULL, NULL); - - return priv; -} - - -static void -set_cothread_state (GstFairSchedulerCothread * ct, GstElementState state) -{ - guint ct_state; - - switch (state) { - case GST_STATE_PLAYING: - ct_state = GST_FAIRSCHEDULER_CTSTATE_RUNNING; - break; - case GST_STATE_PAUSED: - ct_state = GST_FAIRSCHEDULER_CTSTATE_SUSPENDED; - break; - default: - ct_state = GST_FAIRSCHEDULER_CTSTATE_STOPPED; - break; - } - - gst_fair_scheduler_cothread_change_state_async (ct, ct_state); -} - - -static GstPad * -find_ready_pad (GstPad ** pads) -{ - GstPad *pad; - GstFairSchedulerPrivLink *priv; - int i; - - for (i = 0; pads[i] != NULL; i++) { - pad = pads[i]; - priv = LINK_PRIVATE (pad); - - if (GST_PAD_IS_SRC (pad) && priv->bufpen == NULL) { - return pad; - } else if (GST_PAD_IS_SINK (pad) && priv->bufpen != NULL) { - return pad; - } - } - - return NULL; -} - - -static GstPad * -gst_fair_scheduler_internal_select (GstFairScheduler * fsched, GstPad ** pads) -{ - GstPad *pad; - GstFairSchedulerPrivLink *priv; - int i; - - pad = find_ready_pad (pads); - if (pad == NULL) { - /* Register the current cothread as waiting writer/reader for - every pad on the list. */ - for (i = 0; pads[i] != NULL; i++) { - pad = pads[i]; - priv = LINK_PRIVATE (pad); - - if (GST_PAD_IS_SRC (pad)) { - g_return_val_if_fail (priv->waiting_writer == NULL, NULL); - priv->waiting_writer = - gst_fair_scheduler_cothread_current (fsched->cothreads); - } else { - g_return_val_if_fail (priv->waiting_reader == NULL, NULL); - priv->waiting_reader = - gst_fair_scheduler_cothread_current (fsched->cothreads); - } - } - - /* Sleep until at least one of the pads becomes ready. */ - gst_fair_scheduler_cothread_sleep (fsched->cothreads); - - /* Deregister from all pads. */ - for (i = 0; pads[i] != NULL; i++) { - pad = pads[i]; - priv = LINK_PRIVATE (pad); - - if (GST_PAD_IS_SRC (pad)) { - priv->waiting_writer = NULL; - } else { - priv->waiting_reader = NULL; - } - } - - /* This time it should work. */ - pad = find_ready_pad (pads); - } - - /* At this point, we must have a pad to return. */ - g_return_val_if_fail (pad != NULL, NULL); - - return pad; -} - - -/* - * Cothread Function Wrappers - */ - -static void -gst_fair_scheduler_loop_wrapper (GstFairSchedulerCothread * ct, - GstElement * element) -{ - GST_DEBUG ("Queue %p: entering loop wrapper for '%s'", ct->queue, - GST_OBJECT_NAME (element)); - - g_return_if_fail (element->loopfunc != NULL); - - gst_object_ref (GST_OBJECT (element)); - - while (gst_element_get_state (element) == GST_STATE_PLAYING) { - element->loopfunc (element); - } - - gst_object_unref (GST_OBJECT (element)); - - GST_DEBUG ("Queue %p: leaving loop wrapper for '%s'", ct->queue, - GST_OBJECT_NAME (element)); -} - - -static void -gst_fair_scheduler_chain_get_wrapper (GstFairSchedulerCothread * ct, - GstElement * element) -{ - GstData *data; - GstPad *pad; - GstFairScheduler *fsched = - GST_FAIR_SCHEDULER (gst_element_get_scheduler (element)); - - GST_DEBUG ("Queue %p: entering chain/get wrapper for '%s'", ct->queue, - GST_OBJECT_NAME (element)); - - gst_object_ref (GST_OBJECT (element)); - - while (gst_element_get_state (element) == GST_STATE_PLAYING) { - /* Run a select on the pad list. */ - pad = gst_fair_scheduler_internal_select (fsched, - (GstPad **) ELEM_PRIVATE (element)->chain_get_pads->data); - - if (GST_PAD_IS_SRC (pad)) { - g_return_if_fail (GST_RPAD_GETFUNC (pad) != NULL); - data = gst_pad_call_get_function (pad); - gst_pad_push (pad, data); - } else { - g_return_if_fail (GST_RPAD_CHAINFUNC (pad) != NULL); - data = gst_pad_pull (pad); - gst_pad_call_chain_function (pad, data); - } - } - - gst_object_unref (GST_OBJECT (element)); - - GST_DEBUG ("Queue %p: leaving chain/get wrapper for '%s'", ct->queue, - GST_OBJECT_NAME (element)); -} - - -static void -gst_fair_scheduler_queue_read_blocked_handler (GstQueue * queue, GstPad * pad) -{ - GstFairSchedulerPrivLink *priv; - - priv = LINK_PRIVATE (pad); - - GST_CAT_LOG_OBJECT (debug_fair_queues, priv->owner, - "entering \"blocked\" handler for pad '%s:%s'", GST_DEBUG_PAD_NAME (pad)); - - gst_fair_scheduler_cothread_sleep (priv->owner->cothreads); - - GST_CAT_LOG_OBJECT (debug_fair_queues, priv->owner, - "leaving \"blocked\" handler for queue '%s:%s'", - GST_DEBUG_PAD_NAME (pad)); -} - - -static void -gst_fair_scheduler_decoupled_chain_wrapper (GstFairSchedulerCothread * ct, - GstPad * pad) -{ - GstElement *parent = GST_PAD_PARENT (pad); - GstFairSchedulerPrivLink *priv; - GstData *data; - - g_return_if_fail (GST_RPAD_CHAINFUNC (pad) != NULL); - - priv = LINK_PRIVATE (pad); - - GST_DEBUG ("Queue %p: entering chain wrapper loop for '%s:%s'", ct->queue, - GST_DEBUG_PAD_NAME (pad)); - - gst_object_ref (GST_OBJECT (parent)); - - while (gst_element_get_state (parent) == GST_STATE_PLAYING) { - data = gst_pad_pull (pad); - - gst_pad_call_chain_function (pad, data); - - if (priv->waiting_for_queue != NULL) { - gst_fair_scheduler_cothread_awake_async (priv->waiting_for_queue, 0); - } - } - - gst_object_unref (GST_OBJECT (parent)); - - GST_DEBUG ("Queue %p: leaving chain wrapper loop for '%s:%s'", - ct->queue, GST_DEBUG_PAD_NAME (pad)); -} - - -static void -gst_fair_scheduler_decoupled_get_wrapper (GstFairSchedulerCothread * ct, - GstPad * pad) -{ - GstElement *parent = GST_PAD_PARENT (pad); - GstFairSchedulerPrivLink *priv, *sink_priv = NULL; - GstData *data; - - g_return_if_fail (GST_RPAD_GETFUNC (pad) != NULL); - - priv = LINK_PRIVATE (pad); - - if (GST_IS_QUEUE (parent)) { - /* Decoupled elements are almost always queues. We optimize for - this case. The signal handler stops the cothread when the queue - has no material available. */ - - priv->queue_blocked_signal_id = g_signal_connect (parent, - "underrun", - (GCallback) gst_fair_scheduler_queue_read_blocked_handler, pad); - - /* Register this cothread at the opposite side of the queue. */ - sink_priv = LINK_PRIVATE (gst_element_get_pad (parent, "sink")); - sink_priv->waiting_for_queue = ct; - } - - GST_DEBUG ("Queue %p: entering get wrapper loop for '%s:%s'", ct->queue, - GST_DEBUG_PAD_NAME (pad)); - - gst_object_ref (GST_OBJECT (parent)); - - while (gst_element_get_state (parent) == GST_STATE_PLAYING) { - data = gst_pad_call_get_function (pad); - gst_pad_push (pad, data); - } - - gst_object_unref (GST_OBJECT (parent)); - - GST_DEBUG ("Queue %p: leaving get wrapper loop for '%s:%s'", ct->queue, - GST_DEBUG_PAD_NAME (pad)); - - if (GST_IS_QUEUE (parent)) { - sink_priv->waiting_for_queue = NULL; - - /* Disconnect from the signal. */ - g_signal_handler_disconnect (parent, priv->queue_blocked_signal_id); - priv->queue_blocked_signal_id = 0; - } -} - - -/* - * Chain and Get Handlers - */ - -static void -gst_fair_scheduler_chain_handler (GstPad * pad, GstData * data) -{ - GstFairSchedulerPrivLink *priv = get_link_priv (pad); - GstFairScheduler *fsched = priv->owner; - - while (priv->bufpen != NULL) { - /* The buffer is full. Sleep until it's available again. */ - if (priv->waiting_writer != NULL) { - GST_ERROR_OBJECT (fsched, - "concurrent writers not supported, pad '%s:%s', waiting %p, " - "current %p, ", GST_DEBUG_PAD_NAME (pad), - priv->waiting_writer, - gst_fair_scheduler_cothread_current (fsched->cothreads)); - return; - } - priv->waiting_writer = - gst_fair_scheduler_cothread_current (fsched->cothreads); - gst_fair_scheduler_cothread_sleep (fsched->cothreads); - - /* After sleeping we must be at the head. */ - g_return_if_fail (priv->waiting_writer == - gst_fair_scheduler_cothread_current (fsched->cothreads)); - priv->waiting_writer = NULL; - } - - g_return_if_fail (priv->bufpen == NULL); - - /* Fill the bufpen. */ - priv->bufpen = data; - - /* If there's a waiting reader, wake it up. */ - if (priv->waiting_reader != NULL) { - gst_fair_scheduler_cothread_awake (priv->waiting_reader, 0); - } - - GST_LOG_OBJECT (fsched, "pushed data <%p> on pad '%s:%s'", - data, GST_DEBUG_PAD_NAME (GST_RPAD_PEER (pad))); -} - - -static GstData * -gst_fair_scheduler_get_handler (GstPad * pad) -{ - GstFairSchedulerPrivLink *priv = get_link_priv (pad); - GstFairScheduler *fsched = priv->owner; - GstData *ret; - - while (priv->bufpen == NULL) { - /* The buffer is empty. Sleep until there's something to read. */ - if (priv->waiting_reader != NULL) { - GST_ERROR_OBJECT (fsched, "concurrent readers not supported"); - return NULL; - } - priv->waiting_reader = - gst_fair_scheduler_cothread_current (fsched->cothreads); - gst_fair_scheduler_cothread_sleep (fsched->cothreads); - - /* We should still be there after sleeping. */ - g_return_val_if_fail (priv->waiting_reader == - gst_fair_scheduler_cothread_current (fsched->cothreads), NULL); - priv->waiting_reader = NULL; - } - - g_return_val_if_fail (priv->bufpen != NULL, NULL); - - /* Empty the bufpen. */ - ret = priv->bufpen; - priv->bufpen = NULL; - - /* If there's a waiting writer, wake it up. */ - if (priv->waiting_writer != NULL) { - gst_fair_scheduler_cothread_awake (priv->waiting_writer, 0); - } - - GST_LOG_OBJECT (fsched, "pulled data <%p> from pad '%s:%s'", - ret, GST_DEBUG_PAD_NAME (GST_RPAD_PEER (pad))); - - return ret; -} - - -/* - * GstScheduler Entry Points - */ - -static void -gst_fair_scheduler_setup (GstScheduler * sched) -{ - GstFairScheduler *fsched = GST_FAIR_SCHEDULER (sched); - - GST_DEBUG_OBJECT (fsched, "setting up scheduler"); - - /* Initialize the cothread system. */ - gst_fair_scheduler_cothread_queue_start (fsched->cothreads); - - fsched->iter_count = 0; - g_timer_start (fsched->iter_timer); -} - - -static void -gst_fair_scheduler_reset (GstScheduler * sched) -{ - GstFairScheduler *fsched = GST_FAIR_SCHEDULER (sched); - - GST_DEBUG_OBJECT (fsched, "resetting scheduler"); - - g_timer_stop (fsched->iter_timer); - { -#ifndef GST_DISABLE_GST_DEBUG - gulong msecs; - double elapsed = g_timer_elapsed (fsched->iter_timer, &msecs); -#endif - - GST_INFO_OBJECT (fsched, - "%u iterations in %0.3fs, %.0f iterations/sec.", - fsched->iter_count, elapsed, fsched->iter_count / elapsed); - } - - /* Shut down the cothreads system. */ - gst_fair_scheduler_cothread_queue_stop (fsched->cothreads); -} - - -static void -gst_fair_scheduler_add_element (GstScheduler * sched, GstElement * element) -{ - GstFairScheduler *fsched = GST_FAIR_SCHEDULER (sched); - GstFairSchedulerPrivElem *priv; - - if (GST_FLAG_IS_SET (element, GST_ELEMENT_DECOUPLED)) { - /* Decoupled elements don't have their own cothread. Their pads do - have one, though, but it is assigned in the link operation. */ - return; - } - - GST_DEBUG_OBJECT (fsched, "adding element '%s'", GST_OBJECT_NAME (element)); - - g_return_if_fail (ELEM_PRIVATE (element) == NULL); - - priv = g_malloc (sizeof (GstFairSchedulerPrivElem)); - - /* Create the element's cothread. */ - if (element->loopfunc != NULL) { - priv->elem_ct = - gst_fair_scheduler_cothread_new (fsched->cothreads, - (GstFairSchedulerCtFunc) gst_fair_scheduler_loop_wrapper, - element, NULL); -#ifndef GST_DISABLE_GST_DEBUG - g_string_printf (priv->elem_ct->readable_name, "%s:loop", - GST_OBJECT_NAME (element)); -#endif - GST_CAT_INFO_OBJECT (debug_fair_ct, fsched, - "cothread %p is loop for element '%s'", - priv->elem_ct, GST_OBJECT_NAME (element)); - } else { - priv->elem_ct = - gst_fair_scheduler_cothread_new (fsched->cothreads, - (GstFairSchedulerCtFunc) gst_fair_scheduler_chain_get_wrapper, - element, NULL); -#ifndef GST_DISABLE_GST_DEBUG - g_string_printf (priv->elem_ct->readable_name, "%s:chain/get", - GST_OBJECT_NAME (element)); -#endif - GST_CAT_INFO_OBJECT (debug_fair_ct, fsched, - "cothread %p is chain/get for element '%s'", - priv->elem_ct, GST_OBJECT_NAME (element)); - } - - set_cothread_state (priv->elem_ct, gst_element_get_state (element)); - - priv->chain_get_pads = g_array_new (TRUE, FALSE, sizeof (GstPad *)); - - element->sched_private = priv; - -#ifndef GST_DISABLE_GST_DEBUG - fsched->elements = g_list_prepend (fsched->elements, element); -#endif -} - - -static void -gst_fair_scheduler_remove_element (GstScheduler * sched, GstElement * element) -{ -#ifndef GST_DISABLE_GST_DEBUG - GstFairScheduler *fsched = GST_FAIR_SCHEDULER (sched); -#endif - GstFairSchedulerPrivElem *priv = ELEM_PRIVATE (element); - - if (GST_FLAG_IS_SET (element, GST_ELEMENT_DECOUPLED)) { - return; - } - - GST_DEBUG_OBJECT (fsched, "removing element '%s'", GST_OBJECT_NAME (element)); - - g_return_if_fail (priv != NULL); - - /* Clean up the cothread. */ - g_return_if_fail (priv->elem_ct != NULL); - gst_fair_scheduler_cothread_destroy (priv->elem_ct); - -#ifndef GST_DISABLE_GST_DEBUG - fsched->elements = g_list_remove (fsched->elements, element); -#endif - - g_free (priv); - element->sched_private = NULL; -} - - -static void -gst_fair_scheduler_pad_link (GstScheduler * sched, GstPad * srcpad, - GstPad * sinkpad) -{ - GstFairScheduler *fsched = GST_FAIR_SCHEDULER (sched); - GstFairSchedulerPrivLink *priv; - GstElement *src_parent, *sink_parent; - - g_return_if_fail (LINK_PRIVATE (srcpad) == NULL); - - GST_DEBUG_OBJECT (fsched, "linking pads '%s:%s' and '%s:%s'", - GST_DEBUG_PAD_NAME (srcpad), GST_DEBUG_PAD_NAME (sinkpad)); - - /* Initialize the private information block. */ - priv = g_malloc (sizeof (GstFairSchedulerPrivLink)); - - priv->owner = fsched; - priv->bufpen = NULL; - priv->waiting_writer = NULL; - priv->waiting_reader = NULL; - priv->decoupled_ct = NULL; - priv->decoupled_signal_id = 0; - priv->queue_blocked_signal_id = 0; - priv->waiting_for_queue = NULL; - - GST_REAL_PAD (srcpad)->sched_private = priv; - - src_parent = GST_PAD_PARENT (srcpad); - sink_parent = GST_PAD_PARENT (sinkpad); - - if (GST_RPAD_GETFUNC (srcpad) != NULL) { - if (GST_FLAG_IS_SET (src_parent, GST_ELEMENT_DECOUPLED)) { - /* Pad is decoupled. Create a separate cothread to run its get - function. */ - priv->decoupled_ct = - gst_fair_scheduler_cothread_new (fsched->cothreads, - (GstFairSchedulerCtFunc) gst_fair_scheduler_decoupled_get_wrapper, - srcpad, NULL); -#ifndef GST_DISABLE_GST_DEBUG - g_string_printf (priv->decoupled_ct->readable_name, "%s:%s:get", - GST_DEBUG_PAD_NAME (srcpad)); -#endif - GST_CAT_INFO_OBJECT (debug_fair_ct, fsched, - "cothread %p is get for pad '%s:%s'", - priv->decoupled_ct, GST_DEBUG_PAD_NAME (srcpad)); - - /* Connect to the state change signal of the decoupled element - in order to manage the state of this cothread. */ - priv->decoupled_signal_id = g_signal_connect (src_parent, - "state-change", (GCallback) decoupled_state_transition, - priv->decoupled_ct); - - set_cothread_state (priv->decoupled_ct, - gst_element_get_state (src_parent)); - } else { - g_array_append_val (ELEM_PRIVATE (src_parent)->chain_get_pads, srcpad); - } - } - - if (GST_RPAD_CHAINFUNC (sinkpad) != NULL) { - if (GST_FLAG_IS_SET (sink_parent, GST_ELEMENT_DECOUPLED)) { - /* Pad is decoupled. Create a separate cothread to run its chain - function. */ - priv->decoupled_ct = - gst_fair_scheduler_cothread_new (fsched->cothreads, - (GstFairSchedulerCtFunc) gst_fair_scheduler_decoupled_chain_wrapper, - sinkpad, NULL); -#ifndef GST_DISABLE_GST_DEBUG - g_string_printf (priv->decoupled_ct->readable_name, "%s:%s:chain", - GST_DEBUG_PAD_NAME (srcpad)); -#endif - GST_CAT_INFO_OBJECT (debug_fair_ct, fsched, - "cothread %p is chain for pad '%s:%s'", - priv->decoupled_ct, GST_DEBUG_PAD_NAME (sinkpad)); - - /* Connect to the state change signal of the decoupled element - in order to manage the state of this cothread. */ - priv->decoupled_signal_id = g_signal_connect (sink_parent, - "state-change", (GCallback) decoupled_state_transition, - priv->decoupled_ct); - - set_cothread_state (priv->decoupled_ct, - gst_element_get_state (sink_parent)); - } else { - g_array_append_val (ELEM_PRIVATE (sink_parent)->chain_get_pads, sinkpad); - } - } - - /* Set the data handlers. */ - GST_RPAD_GETHANDLER (srcpad) = gst_fair_scheduler_get_handler; - GST_RPAD_EVENTHANDLER (srcpad) = GST_RPAD_EVENTFUNC (srcpad); - - GST_RPAD_CHAINHANDLER (sinkpad) = gst_fair_scheduler_chain_handler; - GST_RPAD_EVENTHANDLER (sinkpad) = GST_RPAD_EVENTFUNC (sinkpad); - -#ifndef GST_DISABLE_GST_DEBUG - fsched->sources = g_list_prepend (fsched->sources, srcpad); -#endif -} - - -static void -array_remove_pad (GArray * array, GstPad * pad) -{ - int i; - - for (i = 0; i < array->len; i++) { - if (g_array_index (array, GstPad *, i) == pad) { - g_array_remove_index_fast (array, i); - break; - } - } -} - - -static void -gst_fair_scheduler_pad_unlink (GstScheduler * sched, GstPad * srcpad, - GstPad * sinkpad) -{ -#ifndef GST_DISABLE_GST_DEBUG - GstFairScheduler *fsched = GST_FAIR_SCHEDULER (sched); -#endif - GstFairSchedulerPrivLink *priv; - GstElement *src_parent, *sink_parent; - - priv = LINK_PRIVATE (srcpad); - g_return_if_fail (priv != NULL); - - GST_DEBUG_OBJECT (fsched, "unlinking pads '%s:%s' and '%s:%s'", - GST_DEBUG_PAD_NAME (srcpad), GST_DEBUG_PAD_NAME (sinkpad)); - - src_parent = GST_PAD_PARENT (srcpad); - sink_parent = GST_PAD_PARENT (sinkpad); - - if (GST_RPAD_GETFUNC (srcpad) != NULL) { - if (GST_FLAG_IS_SET (src_parent, GST_ELEMENT_DECOUPLED)) { - gst_fair_scheduler_cothread_destroy (priv->decoupled_ct); - } else { - array_remove_pad (ELEM_PRIVATE (src_parent)->chain_get_pads, srcpad); - } - } - - if (GST_RPAD_CHAINFUNC (sinkpad) != NULL) { - if (GST_FLAG_IS_SET (sink_parent, GST_ELEMENT_DECOUPLED)) { - gst_fair_scheduler_cothread_destroy (priv->decoupled_ct); - } else { - array_remove_pad (ELEM_PRIVATE (sink_parent)->chain_get_pads, sinkpad); - } - } - - if (priv->decoupled_signal_id != 0) { - g_signal_handler_disconnect (sink_parent, priv->decoupled_signal_id); - } - if (priv->queue_blocked_signal_id != 0) { - g_signal_handler_disconnect (sink_parent, priv->queue_blocked_signal_id); - } - - if (priv->bufpen != NULL) { - gst_data_unref (priv->bufpen); - } - g_free (priv); - - GST_REAL_PAD (srcpad)->sched_private = NULL; - -#ifndef GST_DISABLE_GST_DEBUG - fsched->sources = g_list_remove (fsched->sources, srcpad); -#endif -} - - -static GstElementStateReturn -gst_fair_scheduler_state_transition (GstScheduler * sched, - GstElement * element, gint transition) -{ -#ifndef GST_DISABLE_GST_DEBUG - GstFairScheduler *fsched = GST_FAIR_SCHEDULER (sched); -#endif - gint old_state, new_state; - - GST_DEBUG_OBJECT (sched, "Element %s changing from %s to %s", - GST_ELEMENT_NAME (element), - gst_element_state_get_name (transition >> 8), - gst_element_state_get_name (transition & 0xff)); - - if (GST_FLAG_IS_SET (element, GST_ELEMENT_DECOUPLED)) { - return GST_STATE_SUCCESS; - } - - /* The parent element must be handled specially. */ - if (GST_IS_BIN (element)) { - if (GST_SCHEDULER_PARENT (sched) == element) { - switch (transition) { - case GST_STATE_PLAYING_TO_PAUSED: - GST_INFO_OBJECT (fsched, "setting scheduler state to stopped"); - GST_SCHEDULER_STATE (sched) = GST_SCHEDULER_STATE_STOPPED; - break; - case GST_STATE_PAUSED_TO_PLAYING: - GST_INFO_OBJECT (fsched, "setting scheduler state to running"); - GST_SCHEDULER_STATE (sched) = GST_SCHEDULER_STATE_RUNNING; - break; - } - } - return GST_STATE_SUCCESS; - } - - /* FIXME: Are there eny GStreamer macros for doing this? */ - old_state = transition >> 8; - new_state = transition & 0xff; - if (old_state < new_state) { - set_cothread_state (ELEM_PRIVATE (element)->elem_ct, transition & 0xff); - } - - return GST_STATE_SUCCESS; -} - - -static void -decoupled_state_transition (GstElement * element, gint old_state, - gint new_state, gpointer user_data) -{ - GstFairSchedulerCothread *ct = (GstFairSchedulerCothread *) user_data; - - /* This function is only responsible for activating the - cothread. The wrapper function itself does the deactivation. This - is necessary to avoid weird interactions between multiple - threads. */ - if (old_state < new_state) { - set_cothread_state (ct, new_state); - } -} - - -static void -gst_fair_scheduler_scheduling_change (GstScheduler * sched, - GstElement * element) -{ -#ifndef GST_DISABLE_GST_DEBUG - GstFairScheduler *fsched = GST_FAIR_SCHEDULER (sched); -#endif - - GST_WARNING_OBJECT (fsched, "operation not implemented"); -} - - -static gboolean -gst_fair_scheduler_yield (GstScheduler * sched, GstElement * element) -{ - GstFairScheduler *fsched = GST_FAIR_SCHEDULER (sched); - - g_return_val_if_fail (fsched->in_element, FALSE); - - /* FIXME: What's the difference between yield and interrupt? */ - gst_fair_scheduler_cothread_yield (fsched->cothreads); - - return FALSE; -} - - -static gboolean -gst_fair_scheduler_interrupt (GstScheduler * sched, GstElement * element) -{ - GstFairScheduler *fsched = GST_FAIR_SCHEDULER (sched); - - g_return_val_if_fail (fsched->in_element, FALSE); - - gst_fair_scheduler_cothread_yield (fsched->cothreads); - - return FALSE; -} - - -static void -gst_fair_scheduler_error (GstScheduler * sched, GstElement * element) -{ - GstFairScheduler *fsched = GST_FAIR_SCHEDULER (sched); - - GST_SCHEDULER_STATE (sched) = GST_SCHEDULER_STATE_STOPPED; - if (fsched->in_element) { - gst_fair_scheduler_cothread_yield (fsched->cothreads); - } -} - - -static gint -wait_entry_compare (const GstFairSchedulerWaitEntry * first, - const GstFairSchedulerWaitEntry * second) -{ - if (first->time < second->time) { - return -1; - } else if (first->time == second->time) { - return 0; - } else { - return 1; - } -} - - -static GstData * -gst_fair_scheduler_pad_select (GstScheduler * sched, - GstPad ** pulled_from, GstPad ** pads) -{ - GstFairScheduler *fsched = GST_FAIR_SCHEDULER (sched); - - *pulled_from = gst_fair_scheduler_internal_select (fsched, pads); - g_return_val_if_fail (GST_PAD_IS_SINK (*pulled_from), NULL); - - return gst_pad_pull (*pulled_from); -} - - -static GstClockReturn -gst_fair_scheduler_clock_wait (GstScheduler * sched, GstElement * element, - GstClockID id, GstClockTimeDiff * jitter) -{ - GstFairScheduler *fsched = GST_FAIR_SCHEDULER (sched); - GstClockEntry *clock_entry = (GstClockEntry *) id; - GstClockTime requested, now; - GstFairSchedulerWaitEntry *entry; - - g_return_val_if_fail (sched->current_clock != NULL, GST_CLOCK_ERROR); - g_return_val_if_fail (sched->current_clock == - GST_CLOCK_ENTRY_CLOCK (clock_entry), GST_CLOCK_ERROR); - - now = gst_clock_get_time (sched->current_clock); - requested = GST_CLOCK_ENTRY_TIME (clock_entry); - - if (requested <= now) { - /* It is already too late. */ - if (jitter) { - *jitter = now - requested; - } - return GST_CLOCK_EARLY; - } - - /* Insert a wait entry. */ - entry = g_malloc (sizeof (GstFairSchedulerWaitEntry)); - entry->ct = gst_fair_scheduler_cothread_current (fsched->cothreads); - entry->time = requested; - fsched->waiting = g_slist_insert_sorted (fsched->waiting, entry, - (GCompareFunc) wait_entry_compare); - - /* Go to sleep until it is time... */ - gst_fair_scheduler_cothread_sleep (fsched->cothreads); - - if (jitter) { - now = gst_clock_get_time (sched->current_clock); - *jitter = now - requested; - } - - /* FIXME: Is this the right value to return? */ - return GST_CLOCK_EARLY; -} - - -static GstSchedulerState -gst_fair_scheduler_iterate (GstScheduler * sched) -{ - GstFairScheduler *fsched = GST_FAIR_SCHEDULER (sched); - GstFairSchedulerWaitEntry *entry; - GSList *activate = NULL, *node; - GstClockTime now; - gboolean res; - - /* Count a new iteration for the stats. */ - ++fsched->iter_count; - - /* Check for waiting cothreads. */ - if (fsched->waiting != NULL && sched->current_clock != NULL) { - now = gst_clock_get_time (sched->current_clock); - - /* We need to activate all cothreads whose waiting time was - already reached by the clock. The following code makes sure - that the cothread with the earlier waiting time will be - scheduled first. */ - - /* Move all ready cothreads to the activate list. */ - while (fsched->waiting != NULL) { - entry = (GstFairSchedulerWaitEntry *) fsched->waiting->data; - - if (entry->time > now) { - break; - } - - /* Extract a node from the begining of the waiting - list. */ - node = fsched->waiting; - fsched->waiting = fsched->waiting->next; - - /* Add it to the beginning of the activate list. */ - node->next = activate; - activate = node; - } - - /* Activate the threads in the activate list. */ - while (activate != NULL) { - entry = (GstFairSchedulerWaitEntry *) activate->data; - gst_fair_scheduler_cothread_awake (entry->ct, 1); - activate = g_slist_delete_link (activate, activate); - g_free (entry); - } - } - - /* Handle control to the next cothread. */ - fsched->in_element = TRUE; - res = gst_fair_scheduler_cothread_queue_iterate (fsched->cothreads); - fsched->in_element = FALSE; - - return res ? GST_SCHEDULER_STATE_RUNNING : GST_SCHEDULER_STATE_STOPPED; -} - - -static void -gst_fair_scheduler_show (GstScheduler * sched) -{ -#ifndef GST_DISABLE_GST_DEBUG - GstFairScheduler *fsched = GST_FAIR_SCHEDULER (sched); - GstElement *element; - GstPad *pad; - GstFairSchedulerPrivLink *link_priv; - GstFairSchedulerWaitEntry *entry; - GList *iter1; - GSList *iter2; - GList *iterpads; - - g_print ("Fair scheduler at %p:\n", fsched); - - g_print ("\n Registered elements:\n"); - - for (iter1 = fsched->elements; iter1 != NULL; iter1 = iter1->next) { - element = GST_ELEMENT (iter1->data); - - g_print ("\n %p: %s (%s)\n", element, GST_ELEMENT_NAME (element), - g_type_name (G_OBJECT_TYPE (element))); - - if (GST_IS_BIN (element)) { - continue; - } - - for (iterpads = GST_ELEMENT_PADS (element); iterpads != NULL; - iterpads = iterpads->next) { - pad = GST_PAD (iterpads->data); - - if (GST_IS_GHOST_PAD (pad)) { - continue; - } - - if (GST_PAD_IS_SINK (pad)) { - g_print (" Sink "); - } else { - g_print (" Source "); - } - - g_print ("'%s'", GST_PAD_NAME (pad)); - - link_priv = LINK_PRIVATE (pad); - - if (link_priv == NULL) { - g_print (", unlinked"); - } else { - if (link_priv->bufpen != NULL) { - g_print (", buffer in bufpen"); - } - if (link_priv->waiting_writer != NULL) { - g_print (", waiting writer '%s'", - link_priv->waiting_writer->readable_name->str); - } - if (link_priv->waiting_reader != NULL) { - g_print (", waiting reader '%s'", - link_priv->waiting_reader->readable_name->str); - } - if (link_priv->waiting_for_queue != NULL) { - g_print (", waiting for queue '%s'", - link_priv->waiting_for_queue->readable_name->str); - } - } - - g_print ("\n"); - } - } - - gst_fair_scheduler_cothread_queue_show (fsched->cothreads); - - g_print ("\n Waiting cothreads (current time %" GST_TIME_FORMAT "):\n", - GST_TIME_ARGS (gst_clock_get_time (sched->current_clock))); - - for (iter2 = fsched->waiting; iter2 != NULL; iter2 = iter2->next) { - entry = (GstFairSchedulerWaitEntry *) iter2->data; - g_print (" %p: %s (%d), time = %" GST_TIME_FORMAT "\n", entry->ct, - entry->ct->readable_name->str, entry->ct->pid, - GST_TIME_ARGS (entry->time)); - } -#else - g_print ("Sorry, the 'show' method only works when " - "debugging is activated."); -#endif -} - - -/* - * Plugin Initialization - */ -static gboolean -plugin_init (GstPlugin * plugin) -{ - GstSchedulerFactory *factory; - - GST_DEBUG_CATEGORY_INIT (debug_fair, "fair", 0, "fair scheduler"); - GST_DEBUG_CATEGORY_INIT (debug_fair_ct, "fairct", 0, - "fair scheduler cothreads"); - GST_DEBUG_CATEGORY_INIT (debug_fair_queues, "fairqueues", 0, - "fair scheduler queue related optimizations"); - - factory = gst_scheduler_factory_new ("fair" COTHREADS_NAME, - "A fair scheduler based on " COTHREADS_NAME " cothreads", - gst_fair_scheduler_get_type ()); - - if (factory != NULL) { - gst_plugin_add_feature (plugin, GST_PLUGIN_FEATURE (factory)); - } else { - g_warning ("could not register scheduler: fair"); - } - return TRUE; -} - - -GST_PLUGIN_DEFINE (GST_VERSION_MAJOR, - GST_VERSION_MINOR, - "gstfair" COTHREADS_NAME "scheduler", - "A 'fair' type scheduler based on " COTHREADS_NAME " cothreads", - plugin_init, VERSION, GST_LICENSE, GST_PACKAGE, GST_ORIGIN); diff --git a/gst/schedulers/gstbasicscheduler.c b/gst/schedulers/gstbasicscheduler.c deleted file mode 100644 index d82be10ced..0000000000 --- a/gst/schedulers/gstbasicscheduler.c +++ /dev/null @@ -1,1514 +0,0 @@ -/* GStreamer - * Copyright (C) 1999,2000 Erik Walthinsen - * 2000 Wim Taymans - * - * gstscheduler.c: Default scheduling code for most cases - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - -#include - -#include "cothreads_compat.h" - -GST_DEBUG_CATEGORY_STATIC (debug_dataflow); -GST_DEBUG_CATEGORY_STATIC (debug_scheduler); -#define GST_CAT_DEFAULT debug_scheduler - -typedef struct _GstSchedulerChain GstSchedulerChain; - -#define GST_ELEMENT_THREADSTATE(elem) (GST_ELEMENT (elem)->sched_private) -#define GST_RPAD_BUFPEN(pad) (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) - -typedef struct _GstBasicScheduler GstBasicScheduler; -typedef struct _GstBasicSchedulerClass GstBasicSchedulerClass; - -#ifdef _COTHREADS_STANDARD -# define _SCHEDULER_NAME "standard" -#else -# define _SCHEDULER_NAME "basic" -#endif - -struct _GstSchedulerChain -{ - GstBasicScheduler *sched; - - GList *disabled; - - GList *elements; - gint num_elements; - - GstElement *entry; - - gint cothreaded_elements; - gboolean schedule; -}; - -#define GST_TYPE_BASIC_SCHEDULER \ - (gst_basic_scheduler_get_type()) -#define GST_BASIC_SCHEDULER(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_BASIC_SCHEDULER,GstBasicScheduler)) -#define GST_BASIC_SCHEDULER_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_BASIC_SCHEDULER,GstBasicSchedulerClass)) -#define GST_IS_BASIC_SCHEDULER(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_BASIC_SCHEDULER)) -#define GST_IS_BASIC_SCHEDULER_CLASS(obj) \ - (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_BASIC_SCHEDULER)) - -#define SCHED(element) GST_BASIC_SCHEDULER (GST_ELEMENT_SCHED (element)) - -typedef enum -{ - GST_BASIC_SCHEDULER_STATE_NONE, - GST_BASIC_SCHEDULER_STATE_STOPPED, - GST_BASIC_SCHEDULER_STATE_ERROR, - GST_BASIC_SCHEDULER_STATE_RUNNING -} -GstBasicSchedulerState; - -typedef enum -{ - /* something important has changed inside the scheduler */ - GST_BASIC_SCHEDULER_CHANGE = GST_SCHEDULER_FLAG_LAST -} -GstBasicSchedulerFlags; - -struct _GstBasicScheduler -{ - GstScheduler parent; - - GList *elements; - gint num_elements; - - GList *chains; - gint num_chains; - - GstBasicSchedulerState state; - - cothread_context *context; - GstElement *current; -}; - -struct _GstBasicSchedulerClass -{ - GstSchedulerClass parent_class; -}; - -static GType _gst_basic_scheduler_type = 0; - -static void gst_basic_scheduler_class_init (GstBasicSchedulerClass * klass); -static void gst_basic_scheduler_init (GstBasicScheduler * scheduler); - -static void gst_basic_scheduler_dispose (GObject * object); - -static void gst_basic_scheduler_setup (GstScheduler * sched); -static void gst_basic_scheduler_reset (GstScheduler * sched); -static void gst_basic_scheduler_add_element (GstScheduler * sched, - GstElement * element); -static void gst_basic_scheduler_remove_element (GstScheduler * sched, - GstElement * element); -static GstElementStateReturn gst_basic_scheduler_state_transition (GstScheduler - * sched, GstElement * element, gint transition); -static gboolean gst_basic_scheduler_yield (GstScheduler * sched, - GstElement * element); -static gboolean gst_basic_scheduler_interrupt (GstScheduler * sched, - GstElement * element); -static void gst_basic_scheduler_error (GstScheduler * sched, - GstElement * element); -static void gst_basic_scheduler_pad_link (GstScheduler * sched, GstPad * srcpad, - GstPad * sinkpad); -static void gst_basic_scheduler_pad_unlink (GstScheduler * sched, - GstPad * srcpad, GstPad * sinkpad); -static GstData *gst_basic_scheduler_pad_select (GstScheduler * sched, - GstPad ** selected, GstPad ** padlist); -static GstSchedulerState gst_basic_scheduler_iterate (GstScheduler * sched); - -static void gst_basic_scheduler_show (GstScheduler * sched); - -static GstSchedulerClass *parent_class = NULL; - -/* for threaded bins, these pre- and post-run functions lock and unlock the - * elements. we have to avoid deadlocks, so we make these convenience macros - * that will avoid using do_cothread_switch from within the scheduler. */ - -#define do_element_switch(element) G_STMT_START{ \ - GstElement *from = SCHED (element)->current; \ - if (from && from->post_run_func) \ - from->post_run_func (from); \ - SCHED (element)->current = element; \ - if (element->pre_run_func) \ - element->pre_run_func (element); \ - do_cothread_switch (GST_ELEMENT_THREADSTATE (element)); \ -}G_STMT_END - -#define do_switch_to_main(sched) G_STMT_START{ \ - GstElement *current = ((GstBasicScheduler*)sched)->current; \ - if (current && current->post_run_func) \ - current->post_run_func (current); \ - ((GstBasicScheduler*) sched)->current = NULL; \ - do_cothread_switch \ - (do_cothread_get_main \ - (((GstBasicScheduler*)sched)->context)); \ -}G_STMT_END - -#define do_switch_from_main(entry) G_STMT_START{ \ - if (entry->pre_run_func) \ - entry->pre_run_func (entry); \ - SCHED (entry)->current = entry; \ - do_cothread_switch (GST_ELEMENT_THREADSTATE (entry)); \ -}G_STMT_END - -static GType -gst_basic_scheduler_get_type (void) -{ - if (!_gst_basic_scheduler_type) { - static const GTypeInfo scheduler_info = { - sizeof (GstBasicSchedulerClass), - NULL, - NULL, - (GClassInitFunc) gst_basic_scheduler_class_init, - NULL, - NULL, - sizeof (GstBasicScheduler), - 0, - (GInstanceInitFunc) gst_basic_scheduler_init, - NULL - }; - - _gst_basic_scheduler_type = - g_type_register_static (GST_TYPE_SCHEDULER, - "Gst" COTHREADS_NAME_CAPITAL "Scheduler", &scheduler_info, 0); - } - return _gst_basic_scheduler_type; -} - -static void -gst_basic_scheduler_class_init (GstBasicSchedulerClass * klass) -{ - GObjectClass *gobject_class; - GstObjectClass *gstobject_class; - GstSchedulerClass *gstscheduler_class; - - gobject_class = (GObjectClass *) klass; - gstobject_class = (GstObjectClass *) klass; - gstscheduler_class = (GstSchedulerClass *) klass; - - parent_class = g_type_class_ref (GST_TYPE_SCHEDULER); - - gobject_class->dispose = GST_DEBUG_FUNCPTR (gst_basic_scheduler_dispose); - - gstscheduler_class->setup = GST_DEBUG_FUNCPTR (gst_basic_scheduler_setup); - gstscheduler_class->reset = GST_DEBUG_FUNCPTR (gst_basic_scheduler_reset); - gstscheduler_class->add_element = - GST_DEBUG_FUNCPTR (gst_basic_scheduler_add_element); - gstscheduler_class->remove_element = - GST_DEBUG_FUNCPTR (gst_basic_scheduler_remove_element); - gstscheduler_class->state_transition = - GST_DEBUG_FUNCPTR (gst_basic_scheduler_state_transition); - gstscheduler_class->yield = GST_DEBUG_FUNCPTR (gst_basic_scheduler_yield); - gstscheduler_class->interrupt = - GST_DEBUG_FUNCPTR (gst_basic_scheduler_interrupt); - gstscheduler_class->error = GST_DEBUG_FUNCPTR (gst_basic_scheduler_error); - gstscheduler_class->pad_link = - GST_DEBUG_FUNCPTR (gst_basic_scheduler_pad_link); - gstscheduler_class->pad_unlink = - GST_DEBUG_FUNCPTR (gst_basic_scheduler_pad_unlink); - gstscheduler_class->pad_select = - GST_DEBUG_FUNCPTR (gst_basic_scheduler_pad_select); - gstscheduler_class->clock_wait = NULL; - gstscheduler_class->iterate = GST_DEBUG_FUNCPTR (gst_basic_scheduler_iterate); - - gstscheduler_class->show = GST_DEBUG_FUNCPTR (gst_basic_scheduler_show); - - do_cothreads_init (NULL); -} - -static void -gst_basic_scheduler_init (GstBasicScheduler * scheduler) -{ - scheduler->elements = NULL; - scheduler->num_elements = 0; - scheduler->chains = NULL; - scheduler->num_chains = 0; - - GST_FLAG_SET (scheduler, GST_SCHEDULER_FLAG_NEW_API); -} - -static void -gst_basic_scheduler_dispose (GObject * object) -{ - G_OBJECT_CLASS (parent_class)->dispose (object); -} - -static gboolean -plugin_init (GstPlugin * plugin) -{ - if (!gst_scheduler_register (plugin, "basic" COTHREADS_NAME, - "A basic scheduler using " COTHREADS_NAME " cothreads", - gst_basic_scheduler_get_type ())) - return FALSE; - - GST_DEBUG_CATEGORY_INIT (debug_dataflow, "basic_dataflow", 0, - "basic scheduler dataflow"); - GST_DEBUG_CATEGORY_INIT (debug_scheduler, "basic_scheduler", 0, - "basic scheduler general information"); - - return TRUE; -} - -GST_PLUGIN_DEFINE (GST_VERSION_MAJOR, - GST_VERSION_MINOR, - "gstbasic" COTHREADS_NAME "scheduler", - "a basic scheduler using " COTHREADS_NAME " cothreads", - plugin_init, VERSION, GST_LICENSE, GST_PACKAGE, GST_ORIGIN) - - static int gst_basic_scheduler_loopfunc_wrapper (int argc, char **argv) -{ - GstElement *element = GST_ELEMENT (argv); - G_GNUC_UNUSED const gchar *name = GST_ELEMENT_NAME (element); - - GST_DEBUG ("entering loopfunc wrapper of %s", name); - - gst_object_ref (GST_OBJECT (element)); - do { - GST_CAT_DEBUG (debug_dataflow, "calling loopfunc %s for element %s", - GST_DEBUG_FUNCPTR_NAME (element->loopfunc), name); - (element->loopfunc) (element); - GST_CAT_DEBUG (debug_dataflow, "element %s ended loop function", name); - - } while (!GST_ELEMENT_IS_COTHREAD_STOPPING (element)); - GST_FLAG_UNSET (element, GST_ELEMENT_COTHREAD_STOPPING); - - /* due to oddities in the cothreads code, when this function returns it will - * switch to the main cothread. thus, we need to unlock the current element. */ - if (SCHED (element)) { - if (SCHED (element)->current && SCHED (element)->current->post_run_func) { - SCHED (element)->current->post_run_func (SCHED (element)->current); - } - SCHED (element)->current = NULL; - } - - GST_DEBUG ("leaving loopfunc wrapper of %s", name); - gst_object_unref (GST_OBJECT (element)); - - return 0; -} - -static int -gst_basic_scheduler_chain_wrapper (int argc, char **argv) -{ - GSList *already_iterated = NULL; - GstElement *element = GST_ELEMENT (argv); - G_GNUC_UNUSED const gchar *name = GST_ELEMENT_NAME (element); - - GST_DEBUG ("entered chain wrapper of element %s", name); - - GST_CAT_DEBUG (debug_dataflow, "stepping through pads"); - - gst_object_ref (GST_OBJECT (element)); - do { - GList *pads; - - do { - pads = element->pads; - - while (pads) { - GstPad *pad = GST_PAD (pads->data); - GstRealPad *realpad; - - if (!GST_IS_REAL_PAD (pad)) - continue; - - realpad = GST_REAL_PAD (pad); - - if (GST_RPAD_DIRECTION (realpad) == GST_PAD_SINK && - GST_PAD_IS_LINKED (realpad) && - g_slist_find (already_iterated, pad) == NULL) { - GstData *data; - - GST_CAT_DEBUG (debug_dataflow, "pulling data from %s:%s", name, - GST_PAD_NAME (pad)); - data = gst_pad_pull (pad); - if (data) { - if (GST_IS_EVENT (data) && !GST_ELEMENT_IS_EVENT_AWARE (element)) { - gst_pad_send_event (pad, GST_EVENT (data)); - } else { - GST_CAT_DEBUG (debug_dataflow, - "calling chain function of %s:%s %p", name, - GST_PAD_NAME (pad), data); - gst_pad_call_chain_function (GST_PAD (realpad), data); - GST_CAT_DEBUG (debug_dataflow, - "calling chain function of element %s done", name); - } - } - already_iterated = g_slist_prepend (already_iterated, pad); - break; - } - pads = g_list_next (pads); - } - } while (pads != NULL); - if (already_iterated == NULL) { - GST_DEBUG_OBJECT (SCHED (element), "nothing to iterate for element %s", - GST_ELEMENT_NAME (element)); - break; - } - g_slist_free (already_iterated); - already_iterated = NULL; - } while (!GST_ELEMENT_IS_COTHREAD_STOPPING (element)); - - GST_FLAG_UNSET (element, GST_ELEMENT_COTHREAD_STOPPING); - - /* due to oddities in the cothreads code, when this function returns it will - * switch to the main cothread. thus, we need to unlock the current element. */ - if (SCHED (element)) { - if (SCHED (element)->current && SCHED (element)->current->post_run_func) { - SCHED (element)->current->post_run_func (SCHED (element)->current); - } - SCHED (element)->current = NULL; - } - - GST_CAT_DEBUG (debug_dataflow, "leaving chain wrapper of element %s", name); - gst_object_unref (GST_OBJECT (element)); - - return 0; -} - -static int -gst_basic_scheduler_src_wrapper (int argc, char **argv) -{ - GstElement *element = GST_ELEMENT (argv); - GList *pads; - GstRealPad *realpad; - GstData *data = NULL; - gboolean inf_loop; - G_GNUC_UNUSED const gchar *name = GST_ELEMENT_NAME (element); - - GST_DEBUG ("entering src wrapper of element %s", name); - - do { - inf_loop = TRUE; - pads = element->pads; - while (pads) { - - if (!GST_IS_REAL_PAD (pads->data)) - continue; - - realpad = GST_REAL_PAD (pads->data); - - pads = g_list_next (pads); - if (GST_RPAD_DIRECTION (realpad) == GST_PAD_SRC) { - inf_loop = FALSE; - GST_CAT_DEBUG (debug_dataflow, "calling _getfunc for %s:%s", - GST_DEBUG_PAD_NAME (realpad)); - data = gst_pad_call_get_function (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 (realpad), data); - } - } - } - } while (!GST_ELEMENT_IS_COTHREAD_STOPPING (element) && !inf_loop); - - GST_FLAG_UNSET (element, GST_ELEMENT_COTHREAD_STOPPING); - - /* due to oddities in the cothreads code, when this function returns it will - * switch to the main cothread. thus, we need to unlock the current element. */ - if (SCHED (element)->current->post_run_func) - SCHED (element)->current->post_run_func (SCHED (element)->current); - SCHED (element)->current = NULL; - - GST_DEBUG ("leaving src wrapper of element %s", name); - - return 0; -} - -static void -gst_basic_scheduler_chainhandler_proxy (GstPad * pad, GstData * data) -{ - gint loop_count = 100; - GstElement *parent; - GstRealPad *peer; - - parent = GST_PAD_PARENT (pad); - peer = GST_RPAD_PEER (pad); - - GST_CAT_DEBUG (debug_dataflow, "putting buffer %p in peer \"%s:%s\"'s pen", - data, GST_DEBUG_PAD_NAME (peer)); - - /* - * loop until the bufferpen is empty so we can fill it up again - */ - while (GST_RPAD_BUFPEN (GST_RPAD_PEER (pad)) != NULL && --loop_count) { - GST_CAT_DEBUG (debug_dataflow, "switching to %p to empty bufpen %d", - GST_ELEMENT_THREADSTATE (parent), loop_count); - - do_element_switch (parent); - - /* we may no longer be the same pad, check. */ - if (GST_RPAD_PEER (peer) != (GstRealPad *) pad) { - GST_CAT_DEBUG (debug_dataflow, "new pad in mid-switch!"); - pad = (GstPad *) GST_RPAD_PEER (peer); - } - parent = GST_PAD_PARENT (pad); - peer = GST_RPAD_PEER (pad); - } - - if (loop_count == 0) { - GST_ELEMENT_ERROR (parent, CORE, SCHEDULER, (NULL), - ("(internal error) basic: maximum number of switches exceeded")); - return; - } - - g_assert (GST_RPAD_BUFPEN (GST_RPAD_PEER (pad)) == NULL); - - /* now fill the bufferpen and switch so it can be consumed */ - GST_RPAD_BUFPEN (GST_RPAD_PEER (pad)) = data; - GST_CAT_DEBUG (debug_dataflow, "switching to %p to consume buffer %p", - GST_ELEMENT_THREADSTATE (GST_PAD_PARENT (pad)), data); - - do_element_switch (parent); - - GST_CAT_DEBUG (debug_dataflow, "leaving chainhandler proxy of %s:%s", - GST_DEBUG_PAD_NAME (pad)); -} - -static void -gst_basic_scheduler_select_proxy (GstPad * pad, GstData * data) -{ - GstElement *parent; - - parent = GST_PAD_PARENT (pad); - - GST_CAT_DEBUG (debug_dataflow, "putting buffer %p in peer's pen of pad %s:%s", - data, GST_DEBUG_PAD_NAME (pad)); - - g_assert (GST_RPAD_BUFPEN (GST_RPAD_PEER (pad)) == NULL); - /* now fill the bufferpen and switch so it can be consumed */ - GST_RPAD_BUFPEN (GST_RPAD_PEER (pad)) = data; - GST_CAT_DEBUG (debug_dataflow, "switching to %p", - GST_ELEMENT_THREADSTATE (parent)); - /* FIXME temporarily diabled */ - /* parent->select_pad = pad; */ - - do_element_switch (parent); - - GST_CAT_DEBUG (debug_dataflow, "done switching"); -} - - -static GstData * -gst_basic_scheduler_gethandler_proxy (GstPad * pad) -{ - GstData *data; - GstElement *parent; - GstRealPad *peer; - - GST_CAT_DEBUG (debug_dataflow, "entering gethandler proxy of %s:%s", - GST_DEBUG_PAD_NAME (pad)); - - parent = GST_PAD_PARENT (pad); - peer = GST_RPAD_PEER (pad); - - /* FIXME this should be bounded */ - /* we will loop switching to the peer until it's filled up the bufferpen */ - while (GST_RPAD_BUFPEN (pad) == NULL) { - - GST_CAT_DEBUG (debug_dataflow, "switching to \"%s\": %p to fill bufpen", - GST_ELEMENT_NAME (parent), GST_ELEMENT_THREADSTATE (parent)); - - do_element_switch (parent); - - /* we may no longer be the same pad, check. */ - if (GST_RPAD_PEER (peer) != (GstRealPad *) pad) { - GST_CAT_DEBUG (debug_dataflow, "new pad in mid-switch!"); - pad = (GstPad *) GST_RPAD_PEER (peer); - if (!pad) { - GST_ELEMENT_ERROR (parent, CORE, PAD, (NULL), ("pad unlinked")); - } - parent = GST_PAD_PARENT (pad); - peer = GST_RPAD_PEER (pad); - } - } - GST_CAT_DEBUG (debug_dataflow, "done switching"); - - /* now grab the buffer from the pen, clear the pen, and return the buffer */ - data = GST_RPAD_BUFPEN (pad); - GST_RPAD_BUFPEN (pad) = NULL; - - GST_CAT_DEBUG (debug_dataflow, "leaving gethandler proxy of %s:%s", - GST_DEBUG_PAD_NAME (pad)); - - return data; -} - -static gboolean -gst_basic_scheduler_eventhandler_proxy (GstPad * srcpad, GstEvent * event) -{ - gboolean flush; - - GST_CAT_INFO (debug_dataflow, "intercepting event %d on pad %s:%s", - GST_EVENT_TYPE (event), GST_DEBUG_PAD_NAME (srcpad)); - - /* figure out if we need to flush */ - switch (GST_EVENT_TYPE (event)) { - case GST_EVENT_FLUSH: - flush = TRUE; - break; - case GST_EVENT_SEEK: - case GST_EVENT_SEEK_SEGMENT: - flush = GST_EVENT_SEEK_FLAGS (event) & GST_SEEK_FLAG_FLUSH; - break; - default: - flush = FALSE; - break; - } - - if (flush) { - GstData *data = GST_RPAD_BUFPEN (srcpad); - - GST_CAT_INFO (debug_dataflow, "event is flush"); - - if (data) { - GST_CAT_INFO (debug_dataflow, "need to clear some buffers"); - - gst_data_unref (data); - GST_RPAD_BUFPEN (srcpad) = NULL; - } - } - return GST_RPAD_EVENTFUNC (srcpad) (srcpad, event); -} - -static gboolean -gst_basic_scheduler_cothreaded_chain (GstBin * bin, GstSchedulerChain * chain) -{ - GList *elements; - GstElement *element; - cothread_func wrapper_function; - const GList *pads; - GstPad *pad; - - GST_DEBUG ("chain is using COTHREADS"); - - g_assert (chain->sched->context != NULL); - - /* walk through all the chain's elements */ - elements = chain->elements; - while (elements) { - gboolean decoupled; - - element = GST_ELEMENT (elements->data); - elements = g_list_next (elements); - - decoupled = GST_FLAG_IS_SET (element, GST_ELEMENT_DECOUPLED); - - /* start out without a wrapper function, we select it later */ - wrapper_function = NULL; - - /* if the element has a loopfunc... */ - if (element->loopfunc != NULL) { - wrapper_function = - GST_DEBUG_FUNCPTR (gst_basic_scheduler_loopfunc_wrapper); - GST_DEBUG ("element '%s' is a loop-based", GST_ELEMENT_NAME (element)); - } else { - /* otherwise we need to decide what kind of cothread - * if it's not DECOUPLED, we decide based on - * whether it's a source or not */ - if (!decoupled) { - /* if it doesn't have any sinks, it must be a source (duh) */ - if (element->numsinkpads == 0) { - wrapper_function = - GST_DEBUG_FUNCPTR (gst_basic_scheduler_src_wrapper); - GST_DEBUG ("element '%s' is a source, using _src_wrapper", - GST_ELEMENT_NAME (element)); - } else { - wrapper_function = - GST_DEBUG_FUNCPTR (gst_basic_scheduler_chain_wrapper); - GST_DEBUG ("element '%s' is a filter, using _chain_wrapper", - GST_ELEMENT_NAME (element)); - } - } - } - - /* now we have to walk through the pads to set up their state */ - pads = gst_element_get_pad_list (element); - while (pads) { - GstPad *peerpad; - - pad = GST_PAD (pads->data); - pads = g_list_next (pads); - - if (!GST_IS_REAL_PAD (pad)) - continue; - - peerpad = GST_PAD_PEER (pad); - if (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); - - GST_DEBUG ("inspecting pad %s:%s", GST_DEBUG_PAD_NAME (peerpad)); - - /* we don't need to check this for decoupled elements */ - if (!decoupled) { - /* if the peer element is in another schedule, - * it's not decoupled and we are not decoupled - * either, we have an error */ - if (different_sched && !peer_decoupled) { - GST_ELEMENT_ERROR (element, CORE, SCHEDULER, (NULL), - ("element \"%s\" is not decoupled but has pads in different schedulers", - GST_ELEMENT_NAME (element))); - return FALSE; - } - /* ok, the peer is in a different scheduler and is decoupled, - * we need to set the - * handlers so we can talk with it */ - else if (different_sched) { - if (GST_RPAD_DIRECTION (peerpad) == GST_PAD_SINK) { - GST_DEBUG ("copying chain func into push proxy for peer %s:%s", - GST_DEBUG_PAD_NAME (peerpad)); - GST_RPAD_CHAINHANDLER (peerpad) = gst_pad_call_chain_function; - } else { - GST_DEBUG ("copying get func into pull proxy for peer %s:%s", - GST_DEBUG_PAD_NAME (peerpad)); - GST_RPAD_GETHANDLER (peerpad) = gst_pad_call_get_function; - } - } - } - /* in any case we need to copy the eventfunc into the handler */ - GST_RPAD_EVENTHANDLER (peerpad) = GST_RPAD_EVENTFUNC (peerpad); - } - - /* if the element is DECOUPLED or outside the manager, we have to chain */ - if (decoupled) { - /* set the chain proxies */ - if (GST_RPAD_DIRECTION (pad) == GST_PAD_SINK) { - GST_DEBUG ("copying chain function into push proxy for %s:%s", - GST_DEBUG_PAD_NAME (pad)); - GST_RPAD_CHAINHANDLER (pad) = gst_pad_call_chain_function; - } else { - GST_DEBUG ("copying get function into pull proxy for %s:%s", - GST_DEBUG_PAD_NAME (pad)); - GST_RPAD_GETHANDLER (pad) = gst_pad_call_get_function; - } - } - /* otherwise we really are a cothread */ - else { - if (GST_RPAD_DIRECTION (pad) == GST_PAD_SINK) { - GST_DEBUG ("setting cothreaded push proxy for sinkpad %s:%s", - GST_DEBUG_PAD_NAME (pad)); - GST_RPAD_CHAINHANDLER (pad) = - GST_DEBUG_FUNCPTR (gst_basic_scheduler_chainhandler_proxy); - GST_RPAD_EVENTHANDLER (pad) = GST_RPAD_EVENTFUNC (pad); - } else { - GST_DEBUG ("setting cothreaded pull proxy for srcpad %s:%s", - GST_DEBUG_PAD_NAME (pad)); - GST_RPAD_GETHANDLER (pad) = - GST_DEBUG_FUNCPTR (gst_basic_scheduler_gethandler_proxy); - /* the gethandler proxy function can queue a buffer in the bufpen, we need - * to remove this buffer when a flush event is sent on the pad */ - GST_RPAD_EVENTHANDLER (pad) = - GST_DEBUG_FUNCPTR (gst_basic_scheduler_eventhandler_proxy); - } - } - } - - /* need to set up the cothread now */ - if (wrapper_function != NULL) { - if (GST_ELEMENT_THREADSTATE (element) == NULL) { - GST_DEBUG ("about to create a cothread, wrapper for '%s' is &%s", - GST_ELEMENT_NAME (element), - GST_DEBUG_FUNCPTR_NAME (wrapper_function)); - do_cothread_create (GST_ELEMENT_THREADSTATE (element), - chain->sched->context, wrapper_function, 0, (char **) element); - if (GST_ELEMENT_THREADSTATE (element) == NULL) { - GST_ELEMENT_ERROR (element, RESOURCE, TOO_LAZY, (NULL), - ("could not create cothread for \"%s\"", - GST_ELEMENT_NAME (element))); - return FALSE; - } - GST_DEBUG ("created cothread %p for '%s'", - GST_ELEMENT_THREADSTATE (element), GST_ELEMENT_NAME (element)); - } else { - /* set the cothread wrapper function */ - GST_DEBUG ("about to set the wrapper function for '%s' to &%s", - GST_ELEMENT_NAME (element), - GST_DEBUG_FUNCPTR_NAME (wrapper_function)); - do_cothread_setfunc (GST_ELEMENT_THREADSTATE (element), - chain->sched->context, wrapper_function, 0, (char **) element); - GST_DEBUG ("set wrapper function for '%s' to &%s", - GST_ELEMENT_NAME (element), - GST_DEBUG_FUNCPTR_NAME (wrapper_function)); - } - } - } - - return TRUE; -} - -static GstSchedulerChain * -gst_basic_scheduler_chain_new (GstBasicScheduler * sched) -{ - GstSchedulerChain *chain = g_new (GstSchedulerChain, 1); - - /* initialize the chain with sane values */ - chain->sched = sched; - chain->disabled = NULL; - chain->elements = NULL; - chain->num_elements = 0; - chain->entry = NULL; - chain->cothreaded_elements = 0; - chain->schedule = FALSE; - - /* add the chain to the schedulers' list of chains */ - sched->chains = g_list_prepend (sched->chains, chain); - sched->num_chains++; - - /* notify the scheduler that something changed */ - GST_FLAG_SET (sched, GST_BASIC_SCHEDULER_CHANGE); - - GST_INFO ("created new chain %p, now are %d chains in sched %p", - chain, sched->num_chains, sched); - - return chain; -} - -static void -gst_basic_scheduler_chain_destroy (GstSchedulerChain * chain) -{ - GstBasicScheduler *sched = chain->sched; - - /* remove the chain from the schedulers' list of chains */ - sched->chains = g_list_remove (sched->chains, chain); - sched->num_chains--; - - /* destroy the chain */ - g_list_free (chain->disabled); /* should be empty... */ - g_list_free (chain->elements); /* ditto */ - - GST_INFO ("destroyed chain %p, now are %d chains in sched %p", chain, - sched->num_chains, sched); - - g_free (chain); - - /* notify the scheduler that something changed */ - GST_FLAG_SET (sched, GST_BASIC_SCHEDULER_CHANGE); -} - -static void -gst_basic_scheduler_chain_add_element (GstSchedulerChain * chain, - GstElement * element) -{ - /* set the sched pointer for the element */ - element->sched = GST_SCHEDULER (chain->sched); - - /* add the element to either the main list or the disabled list */ - if (GST_STATE (element) == GST_STATE_PLAYING) { - GST_INFO ("adding element \"%s\" to chain %p enabled", - GST_ELEMENT_NAME (element), chain); - chain->elements = g_list_prepend (chain->elements, element); - } else { - GST_INFO ("adding element \"%s\" to chain %p disabled", - GST_ELEMENT_NAME (element), chain); - chain->disabled = g_list_prepend (chain->disabled, element); - } - chain->num_elements++; - - /* notify the scheduler that something changed */ - GST_FLAG_SET (chain->sched, GST_BASIC_SCHEDULER_CHANGE); -} - -static gboolean -gst_basic_scheduler_chain_enable_element (GstSchedulerChain * chain, - GstElement * element) -{ - GST_INFO ("enabling element \"%s\" in chain %p", - GST_ELEMENT_NAME (element), chain); - - /* remove from disabled list */ - chain->disabled = g_list_remove (chain->disabled, element); - - /* add to elements list */ - chain->elements = g_list_prepend (chain->elements, element); - - /* notify the scheduler that something changed */ - GST_FLAG_SET (chain->sched, GST_BASIC_SCHEDULER_CHANGE); - /* GST_FLAG_UNSET(element, GST_ELEMENT_COTHREAD_STOPPING); */ - - /* reschedule the chain */ - return gst_basic_scheduler_cothreaded_chain (GST_BIN (GST_SCHEDULER (chain-> - sched)->parent), chain); -} - -static void -gst_basic_scheduler_chain_disable_element (GstSchedulerChain * chain, - GstElement * element) -{ - GST_INFO ("disabling element \"%s\" in chain %p", - GST_ELEMENT_NAME (element), chain); - - /* remove from elements list */ - chain->elements = g_list_remove (chain->elements, element); - - /* add to disabled list */ - chain->disabled = g_list_prepend (chain->disabled, element); - - /* notify the scheduler that something changed */ - GST_FLAG_SET (chain->sched, GST_BASIC_SCHEDULER_CHANGE); - GST_FLAG_SET (element, GST_ELEMENT_COTHREAD_STOPPING); - - /* reschedule the chain */ -/* FIXME this should be done only if manager state != NULL */ -/* gst_basic_scheduler_cothreaded_chain(GST_BIN(chain->sched->parent),chain); */ -} - -static void -gst_basic_scheduler_chain_remove_element (GstSchedulerChain * chain, - GstElement * element) -{ - GST_INFO ("removing element \"%s\" from chain %p", GST_ELEMENT_NAME (element), - chain); - - /* if it's active, deactivate it */ - if (g_list_find (chain->elements, element)) { - gst_basic_scheduler_chain_disable_element (chain, element); - } - /* we have to check for a threadstate here because a queue doesn't have one */ - if (GST_ELEMENT_THREADSTATE (element)) { - do_cothread_destroy (GST_ELEMENT_THREADSTATE (element)); - GST_ELEMENT_THREADSTATE (element) = NULL; - } - - /* remove the element from the list of elements */ - chain->disabled = g_list_remove (chain->disabled, element); - chain->num_elements--; - - /* notify the scheduler that something changed */ - GST_FLAG_SET (chain->sched, GST_BASIC_SCHEDULER_CHANGE); - - /* if there are no more elements in the chain, destroy the chain */ - if (chain->num_elements == 0) - gst_basic_scheduler_chain_destroy (chain); - -} - -static void -gst_basic_scheduler_chain_elements (GstBasicScheduler * sched, - GstElement * element1, GstElement * element2) -{ - GList *chains; - GstSchedulerChain *chain; - GstSchedulerChain *chain1 = NULL, *chain2 = NULL; - GstElement *element; - - /* first find the chains that hold the two */ - chains = sched->chains; - while (chains) { - chain = (GstSchedulerChain *) (chains->data); - chains = g_list_next (chains); - - if (g_list_find (chain->disabled, element1)) - chain1 = chain; - else if (g_list_find (chain->elements, element1)) - chain1 = chain; - - if (g_list_find (chain->disabled, element2)) - chain2 = chain; - else if (g_list_find (chain->elements, element2)) - chain2 = chain; - } - - /* first check to see if they're in the same chain, we're done if that's the case */ - if ((chain1 != NULL) && (chain1 == chain2)) { - GST_INFO ("elements are already in the same chain"); - return; - } - - /* now, if neither element has a chain, create one */ - if ((chain1 == NULL) && (chain2 == NULL)) { - GST_INFO ("creating new chain to hold two new elements"); - chain = gst_basic_scheduler_chain_new (sched); - gst_basic_scheduler_chain_add_element (chain, element1); - gst_basic_scheduler_chain_add_element (chain, element2); - /* FIXME chain changed here */ -/* gst_basic_scheduler_cothreaded_chain(chain->sched->parent,chain); */ - - /* otherwise if both have chains already, join them */ - } else if ((chain1 != NULL) && (chain2 != NULL)) { - GST_INFO ("merging chain %p into chain %p", chain2, chain1); - /* take the contents of chain2 and merge them into chain1 */ - chain1->disabled = - g_list_concat (chain1->disabled, g_list_copy (chain2->disabled)); - chain1->elements = - g_list_concat (chain1->elements, g_list_copy (chain2->elements)); - chain1->num_elements += chain2->num_elements; - gst_basic_scheduler_chain_destroy (chain2); - if (sched->context) - - gst_basic_scheduler_cothreaded_chain (GST_BIN (GST_SCHEDULER (chain1-> - sched)->parent), chain1); - - /* otherwise one has a chain already, the other doesn't */ - } else { - /* pick out which one has the chain, and which doesn't */ - if (chain1 != NULL) - chain = chain1, element = element2; - else - chain = chain2, element = element1; - - GST_INFO ("adding element to existing chain"); - gst_basic_scheduler_chain_add_element (chain, element); - /* FIXME chain changed here */ -/* gst_basic_scheduler_cothreaded_chain(chain->sched->parent,chain); */ - } - -} - - -/* find the chain within the scheduler that holds the element, if any */ -static GstSchedulerChain * -gst_basic_scheduler_find_chain (GstBasicScheduler * sched, GstElement * element) -{ - GList *chains; - GstSchedulerChain *chain; - - GST_INFO ("searching for element \"%s\" in chains", - GST_ELEMENT_NAME (element)); - - chains = sched->chains; - while (chains) { - chain = (GstSchedulerChain *) (chains->data); - chains = g_list_next (chains); - - if (g_list_find (chain->elements, element)) - return chain; - if (g_list_find (chain->disabled, element)) - return chain; - } - - return NULL; -} - -static void -gst_basic_scheduler_chain_recursive_add (GstSchedulerChain * chain, - GstElement * element, gboolean remove) -{ - GList *pads; - GstPad *pad; - GstElement *peerelement; - GstSchedulerChain *prevchain; - - /* check to see if it's in a chain already */ - prevchain = gst_basic_scheduler_find_chain (chain->sched, element); - /* if it's already in another chain, either remove or punt */ - if (prevchain != NULL) { - if (remove == TRUE) - gst_basic_scheduler_chain_remove_element (prevchain, element); - else - return; - } - - /* add it to this one */ - gst_basic_scheduler_chain_add_element (chain, element); - - GST_DEBUG ("recursing on element \"%s\"", GST_ELEMENT_NAME (element)); - /* now go through all the pads and see which peers can be added */ - pads = element->pads; - while (pads) { - pad = GST_PAD (pads->data); - pads = g_list_next (pads); - - GST_DEBUG ("have pad %s:%s, checking for valid peer", - GST_DEBUG_PAD_NAME (pad)); - /* if the peer exists and could be in the same chain */ - if (GST_PAD_PEER (pad)) { - GST_DEBUG ("has peer %s:%s", GST_DEBUG_PAD_NAME (GST_PAD_PEER (pad))); - peerelement = GST_PAD_PARENT (GST_PAD_PEER (pad)); - if (GST_ELEMENT_SCHED (GST_PAD_PARENT (pad)) == - GST_ELEMENT_SCHED (peerelement)) { - GST_DEBUG ("peer \"%s\" is valid for same chain", - GST_ELEMENT_NAME (peerelement)); - gst_basic_scheduler_chain_recursive_add (chain, peerelement, remove); - } - } - } -} - -/* - * Entry points for this scheduler. - */ -static void -gst_basic_scheduler_setup (GstScheduler * sched) -{ - /* first create thread context */ - if (GST_BASIC_SCHEDULER (sched)->context == NULL) { - GST_DEBUG ("initializing cothread context"); - GST_BASIC_SCHEDULER (sched)->context = do_cothread_context_init (); - } -} - -static void -gst_basic_scheduler_reset (GstScheduler * sched) -{ - cothread_context *ctx; - GList *elements = GST_BASIC_SCHEDULER (sched)->elements; - - while (elements) { - GstElement *element = GST_ELEMENT (elements->data); - - if (GST_ELEMENT_THREADSTATE (element)) { - do_cothread_destroy (GST_ELEMENT_THREADSTATE (element)); - GST_ELEMENT_THREADSTATE (element) = NULL; - } - elements = g_list_next (elements); - } - - ctx = GST_BASIC_SCHEDULER (sched)->context; - - do_cothread_context_destroy (ctx); - - GST_BASIC_SCHEDULER (sched)->context = NULL; -} - -static void -gst_basic_scheduler_add_element (GstScheduler * sched, GstElement * element) -{ - GstSchedulerChain *chain; - GstBasicScheduler *bsched = GST_BASIC_SCHEDULER (sched); - - GST_INFO ("adding element \"%s\" to scheduler", GST_ELEMENT_NAME (element)); - - /* only deal with elements after this point, not bins */ - /* exception is made for Bin's that are schedulable, like the autoplugger */ - if (GST_IS_BIN (element) - && !GST_FLAG_IS_SET (element, GST_BIN_SELF_SCHEDULABLE)) - return; - - /* first add it to the list of elements that are to be scheduled */ - bsched->elements = g_list_prepend (bsched->elements, element); - bsched->num_elements++; - - /* create a chain to hold it, and add */ - chain = gst_basic_scheduler_chain_new (bsched); - gst_basic_scheduler_chain_add_element (chain, element); -} - -static void -gst_basic_scheduler_remove_element (GstScheduler * sched, GstElement * element) -{ - GstSchedulerChain *chain; - GstBasicScheduler *bsched = GST_BASIC_SCHEDULER (sched); - - if (g_list_find (bsched->elements, element)) { - GST_INFO ("removing element \"%s\" from scheduler", - GST_ELEMENT_NAME (element)); - - /* if we are removing the currently scheduled element */ - if (bsched->current == element) { - GST_FLAG_SET (element, GST_ELEMENT_COTHREAD_STOPPING); - if (element->post_run_func) - element->post_run_func (element); - bsched->current = NULL; - } - /* find what chain the element is in */ - chain = gst_basic_scheduler_find_chain (bsched, element); - - /* remove it from its chain */ - if (chain != NULL) { - gst_basic_scheduler_chain_remove_element (chain, element); - } - - /* remove it from the list of elements */ - bsched->elements = g_list_remove (bsched->elements, element); - bsched->num_elements--; - - /* unset the scheduler pointer in the element */ - } -} - -static GstElementStateReturn -gst_basic_scheduler_state_transition (GstScheduler * sched, - GstElement * element, gint transition) -{ - GstSchedulerChain *chain; - GstBasicScheduler *bsched = GST_BASIC_SCHEDULER (sched); - - /* check if our parent changed state */ - if (GST_SCHEDULER_PARENT (sched) == element) { - GST_INFO ("parent \"%s\" changed state", GST_ELEMENT_NAME (element)); - if (transition == GST_STATE_PLAYING_TO_PAUSED) { - GST_INFO ("setting scheduler state to stopped"); - GST_SCHEDULER_STATE (sched) = GST_SCHEDULER_STATE_STOPPED; - } else if (transition == GST_STATE_PAUSED_TO_PLAYING) { - GST_INFO ("setting scheduler state to running"); - GST_SCHEDULER_STATE (sched) = GST_SCHEDULER_STATE_RUNNING; - } else { - GST_INFO ("no interesting state change, doing nothing"); - } - } else if (transition == GST_STATE_PLAYING_TO_PAUSED || - transition == GST_STATE_PAUSED_TO_PLAYING) { - /* find the chain the element is in */ - chain = gst_basic_scheduler_find_chain (bsched, element); - - /* remove it from the chain */ - if (chain) { - if (transition == GST_STATE_PLAYING_TO_PAUSED) { - gst_basic_scheduler_chain_disable_element (chain, element); - } else if (transition == GST_STATE_PAUSED_TO_PLAYING) { - if (!gst_basic_scheduler_chain_enable_element (chain, element)) { - GST_INFO ("could not enable element \"%s\"", - GST_ELEMENT_NAME (element)); - return GST_STATE_FAILURE; - } - } - } else { - GST_INFO ("element \"%s\" not found in any chain, no state change", - GST_ELEMENT_NAME (element)); - } - } - - return GST_STATE_SUCCESS; -} - -static gboolean -gst_basic_scheduler_yield (GstScheduler * sched, GstElement * element) -{ - if (GST_ELEMENT_IS_COTHREAD_STOPPING (element)) { - - do_switch_to_main (sched); - - /* no need to do a pre_run, the cothread is stopping */ - } - return FALSE; -} - -static gboolean -gst_basic_scheduler_interrupt (GstScheduler * sched, GstElement * element) -{ - - GST_FLAG_SET (element, GST_ELEMENT_COTHREAD_STOPPING); - do_switch_to_main (sched); - - return FALSE; -} - -static void -gst_basic_scheduler_error (GstScheduler * sched, GstElement * element) -{ - GstBasicScheduler *bsched = GST_BASIC_SCHEDULER (sched); - - if (GST_ELEMENT_THREADSTATE (element)) { - GstSchedulerChain *chain; - - chain = gst_basic_scheduler_find_chain (bsched, element); - if (chain) - gst_basic_scheduler_chain_disable_element (chain, element); - - GST_SCHEDULER_STATE (sched) = GST_SCHEDULER_STATE_ERROR; - - do_switch_to_main (sched); - } -} - -static void -gst_basic_scheduler_pad_link (GstScheduler * sched, GstPad * srcpad, - GstPad * sinkpad) -{ - GstElement *srcelement, *sinkelement; - GstBasicScheduler *bsched = GST_BASIC_SCHEDULER (sched); - - srcelement = GST_PAD_PARENT (srcpad); - g_return_if_fail (srcelement != NULL); - sinkelement = GST_PAD_PARENT (sinkpad); - g_return_if_fail (sinkelement != NULL); - - GST_INFO ("have pad linked callback on %s:%s to %s:%s", - GST_DEBUG_PAD_NAME (srcpad), GST_DEBUG_PAD_NAME (sinkpad)); - GST_DEBUG ("srcpad sched is %p, sinkpad sched is %p", - GST_ELEMENT_SCHED (srcelement), GST_ELEMENT_SCHED (sinkelement)); - - gst_basic_scheduler_chain_elements (bsched, srcelement, sinkelement); -} - -static void -gst_basic_scheduler_pad_unlink (GstScheduler * sched, GstPad * srcpad, - GstPad * sinkpad) -{ - GstElement *element1, *element2; - GstSchedulerChain *chain1, *chain2; - GstBasicScheduler *bsched = GST_BASIC_SCHEDULER (sched); - - GST_INFO ("unlinking pads %s:%s and %s:%s", - GST_DEBUG_PAD_NAME (srcpad), GST_DEBUG_PAD_NAME (sinkpad)); - - /* we need to have the parent elements of each pad */ - element1 = GST_ELEMENT (GST_PAD_PARENT (srcpad)); - element2 = GST_ELEMENT (GST_PAD_PARENT (sinkpad)); - - /* first task is to remove the old chain they belonged to. - * this can be accomplished by taking either of the elements, - * since they are guaranteed to be in the same chain - * FIXME is it potentially better to make an attempt at splitting cleaner?? - */ - chain1 = gst_basic_scheduler_find_chain (bsched, element1); - chain2 = gst_basic_scheduler_find_chain (bsched, element2); - -/* FIXME: The old code still works in most cases, but does not deal with - * the problem of screwed up sched chains in some autoplugging cases. - * The new code has an infinite recursion bug during pipeline shutdown, - * which must be fixed before it can be enabled again. - */ -#if 1 - if (chain1 != chain2) { - /* elements not in the same chain don't need to be separated */ - GST_INFO ("elements not in the same chain"); - return; - } - - if (chain1) { - GST_INFO ("destroying chain"); - gst_basic_scheduler_chain_destroy (chain1); - - /* now create a new chain to hold element1 and build it from scratch */ - chain1 = gst_basic_scheduler_chain_new (bsched); - gst_basic_scheduler_chain_recursive_add (chain1, element1, FALSE); - } - - /* check the other element to see if it landed in the newly created chain */ - if (gst_basic_scheduler_find_chain (bsched, element2) == NULL) { - /* if not in chain, create chain and build from scratch */ - chain2 = gst_basic_scheduler_chain_new (bsched); - gst_basic_scheduler_chain_recursive_add (chain2, element2, FALSE); - } -#else - - /* if they're both in the same chain, move second set of elements to a new chain */ - if (chain1 && (chain1 == chain2)) { - GST_INFO ("creating new chain for second element and peers"); - chain2 = gst_basic_scheduler_chain_new (bsched); - gst_basic_scheduler_chain_recursive_add (chain2, element2, TRUE); - } -#endif -} - -static GstData * -gst_basic_scheduler_pad_select (GstScheduler * sched, GstPad ** selected, - GstPad ** padlist) -{ - GstData *data = NULL; - gint i = 0; - - GST_INFO ("performing select"); - - while (padlist[i]) { - GstPad *pad = padlist[i]; - - GST_RPAD_CHAINHANDLER (pad) = - GST_DEBUG_FUNCPTR (gst_basic_scheduler_select_proxy); - } - - do_element_switch (GST_PAD_PARENT (GST_PAD_PEER (padlist[0]))); - - i = 0; - while (padlist[i]) { - GstPad *pad = padlist[i]; - - if (GST_RPAD_BUFPEN (pad)) { - *selected = pad; - data = GST_RPAD_BUFPEN (pad); - GST_RPAD_BUFPEN (pad) = NULL; - } - - GST_RPAD_CHAINHANDLER (pad) = - GST_DEBUG_FUNCPTR (gst_basic_scheduler_chainhandler_proxy); - } - - g_assert (data != NULL); - return data; -} - -static GstSchedulerState -gst_basic_scheduler_iterate (GstScheduler * sched) -{ - GList *chains; - GstSchedulerChain *chain; - GstElement *entry; - GList *elements; - gint scheduled = 0; - GstBasicScheduler *bsched = GST_BASIC_SCHEDULER (sched); - - GST_CAT_LOG_OBJECT (debug_dataflow, sched, - "starting iteration in bin %s", GST_ELEMENT_NAME (sched->parent)); - - /* clear the changes flag */ - GST_FLAG_UNSET (bsched, GST_BASIC_SCHEDULER_CHANGE); - - /* step through all the chains */ - chains = bsched->chains; - - if (chains == NULL) - return GST_SCHEDULER_STATE_STOPPED; - - while (chains) { - chain = (GstSchedulerChain *) (chains->data); - chains = g_list_next (chains); - - /* all we really have to do is switch to the first child */ - /* FIXME this should be lots more intelligent about where to start */ - GST_CAT_DEBUG (debug_dataflow, - "starting iteration via cothreads using %s scheduler", _SCHEDULER_NAME); - - if (chain->elements) { - entry = NULL; /*MattH ADDED? */ - GST_DEBUG ("there are %d elements in this chain", chain->num_elements); - elements = chain->elements; - while (elements) { - entry = GST_ELEMENT (elements->data); - elements = g_list_next (elements); - if (GST_FLAG_IS_SET (entry, GST_ELEMENT_DECOUPLED)) { - GST_DEBUG ("entry \"%s\" is DECOUPLED, skipping", - GST_ELEMENT_NAME (entry)); - entry = NULL; - } else if (GST_FLAG_IS_SET (entry, GST_ELEMENT_INFINITE_LOOP)) { - GST_DEBUG ("entry \"%s\" is not valid, skipping", - GST_ELEMENT_NAME (entry)); - entry = NULL; - } else - break; - } - if (entry) { - GstSchedulerState state; - - GST_FLAG_SET (entry, GST_ELEMENT_COTHREAD_STOPPING); - - GST_CAT_DEBUG (debug_dataflow, - "set COTHREAD_STOPPING flag on \"%s\"(@%p)", - GST_ELEMENT_NAME (entry), entry); - if (GST_ELEMENT_THREADSTATE (entry)) { - - do_switch_from_main (entry); - - state = GST_SCHEDULER_STATE (sched); - /* if something changed, return - go on else */ - if (GST_FLAG_IS_SET (bsched, GST_BASIC_SCHEDULER_CHANGE) && - state != GST_SCHEDULER_STATE_ERROR) - return GST_SCHEDULER_STATE_RUNNING; - } else { - GST_CAT_DEBUG (debug_dataflow, - "cothread switch not possible, element has no threadstate"); - return GST_SCHEDULER_STATE_ERROR; - } - - /* following is a check to see if the chain was interrupted due to a - * top-half state_change(). (i.e., if there's a pending state.) - * - * if it was, return to gstthread.c::gst_thread_main_loop() to - * execute the state change. - */ - GST_CAT_DEBUG (debug_dataflow, "cothread switch ended or interrupted"); - - if (state != GST_SCHEDULER_STATE_RUNNING) { - GST_CAT_INFO (debug_dataflow, "scheduler is not running, in state %d", - state); - return state; - } - - scheduled++; - } else { - GST_CAT_INFO (debug_dataflow, - "no entry in this chain, trying the next one"); - } - } else { - GST_CAT_INFO (debug_dataflow, - "no enabled elements in this chain, trying the next one"); - } - } - - GST_CAT_LOG_OBJECT (debug_dataflow, sched, "leaving (%s)", - GST_ELEMENT_NAME (sched->parent)); - if (scheduled == 0) { - GST_CAT_INFO (debug_dataflow, "nothing was scheduled, return STOPPED"); - return GST_SCHEDULER_STATE_STOPPED; - } else { - GST_CAT_INFO (debug_dataflow, "scheduler still running, return RUNNING"); - return GST_SCHEDULER_STATE_RUNNING; - } -} - - -static void -gst_basic_scheduler_show (GstScheduler * sched) -{ - GList *chains, *elements; - GstElement *element; - GstSchedulerChain *chain; - GstBasicScheduler *bsched = GST_BASIC_SCHEDULER (sched); - - if (sched == NULL) { - g_print ("scheduler doesn't exist for this element\n"); - return; - } - - g_return_if_fail (GST_IS_SCHEDULER (sched)); - - g_print ("SCHEDULER DUMP FOR MANAGING BIN \"%s\"\n", - GST_ELEMENT_NAME (sched->parent)); - - g_print ("scheduler has %d elements in it: ", bsched->num_elements); - elements = bsched->elements; - while (elements) { - element = GST_ELEMENT (elements->data); - elements = g_list_next (elements); - - g_print ("%s, ", GST_ELEMENT_NAME (element)); - } - g_print ("\n"); - - g_print ("scheduler has %d chains in it\n", bsched->num_chains); - chains = bsched->chains; - while (chains) { - chain = (GstSchedulerChain *) (chains->data); - chains = g_list_next (chains); - - g_print ("%p: ", chain); - - elements = chain->disabled; - while (elements) { - element = GST_ELEMENT (elements->data); - elements = g_list_next (elements); - - g_print ("!%s, ", GST_ELEMENT_NAME (element)); - } - - elements = chain->elements; - while (elements) { - element = GST_ELEMENT (elements->data); - elements = g_list_next (elements); - - g_print ("%s, ", GST_ELEMENT_NAME (element)); - } - g_print ("\n"); - } -} diff --git a/gst/schedulers/gstoptimalscheduler.c b/gst/schedulers/gstoptimalscheduler.c deleted file mode 100644 index e683ed131c..0000000000 --- a/gst/schedulers/gstoptimalscheduler.c +++ /dev/null @@ -1,2939 +0,0 @@ -/* GStreamer - * Copyright (C) 1999,2000 Erik Walthinsen - * 2000 Wim Taymans - * - * gstoptimalscheduler.c: Default scheduling code for most cases - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - -#include - -GST_DEBUG_CATEGORY_STATIC (debug_scheduler); -#define GST_CAT_DEFAULT debug_scheduler - -#ifdef USE_COTHREADS -# include "cothreads_compat.h" -#else -# define COTHREADS_NAME_CAPITAL "" -# define COTHREADS_NAME "" -#endif - -#define GST_ELEMENT_SCHED_CONTEXT(elem) ((GstOptSchedulerCtx*) (GST_ELEMENT (elem)->sched_private)) -#define GST_ELEMENT_SCHED_GROUP(elem) (GST_ELEMENT_SCHED_CONTEXT (elem)->group) -/* need this first macro to not run into lvalue casts */ -#define GST_PAD_DATAPEN(pad) (GST_REAL_PAD(pad)->sched_private) -#define GST_PAD_DATALIST(pad) ((GList*) GST_PAD_DATAPEN(pad)) - -#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) -#define GST_ELEMENT_VISITED GST_ELEMENT_SCHEDULER_PRIVATE2 -#define GST_ELEMENT_IS_VISITED(element) GST_FLAG_IS_SET((element), GST_ELEMENT_VISITED) -#define GST_ELEMENT_SET_VISITED(element) GST_FLAG_SET((element), GST_ELEMENT_VISITED) -#define GST_ELEMENT_UNSET_VISITED(element) GST_FLAG_UNSET((element), GST_ELEMENT_VISITED) - -typedef struct _GstOptScheduler GstOptScheduler; -typedef struct _GstOptSchedulerClass GstOptSchedulerClass; - -#define GST_TYPE_OPT_SCHEDULER \ - (gst_opt_scheduler_get_type()) -#define GST_OPT_SCHEDULER(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_OPT_SCHEDULER,GstOptScheduler)) -#define GST_OPT_SCHEDULER_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_OPT_SCHEDULER,GstOptSchedulerClass)) -#define GST_IS_OPT_SCHEDULER(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_OPT_SCHEDULER)) -#define GST_IS_OPT_SCHEDULER_CLASS(obj) \ - (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_OPT_SCHEDULER)) - -typedef enum -{ - GST_OPT_SCHEDULER_STATE_NONE, - GST_OPT_SCHEDULER_STATE_STOPPED, - GST_OPT_SCHEDULER_STATE_ERROR, - GST_OPT_SCHEDULER_STATE_RUNNING, - GST_OPT_SCHEDULER_STATE_INTERRUPTED -} -GstOptSchedulerState; - -#define GST_OPT_LOCK(sched) (g_static_rec_mutex_lock (&((GstOptScheduler *)sched)->lock)) -#define GST_OPT_UNLOCK(sched) (g_static_rec_mutex_unlock (&((GstOptScheduler *)sched)->lock)) - -struct _GstOptScheduler -{ - GstScheduler parent; - - GStaticRecMutex lock; - - GstOptSchedulerState state; - -#ifdef USE_COTHREADS - cothread_context *context; -#endif - gint iterations; - - GSList *elements; - GSList *chains; - - GList *runqueue; - gint recursion; - - gint max_recursion; - gint live_groups; - gint live_chains; - gint live_links; -}; - -struct _GstOptSchedulerClass -{ - GstSchedulerClass parent_class; -}; - -static GType _gst_opt_scheduler_type = 0; - -typedef enum -{ - GST_OPT_SCHEDULER_CHAIN_DIRTY = (1 << 1), - GST_OPT_SCHEDULER_CHAIN_DISABLED = (1 << 2), - GST_OPT_SCHEDULER_CHAIN_RUNNING = (1 << 3) -} -GstOptSchedulerChainFlags; - -#define GST_OPT_SCHEDULER_CHAIN_SET_DIRTY(chain) ((chain)->flags |= GST_OPT_SCHEDULER_CHAIN_DIRTY) -#define GST_OPT_SCHEDULER_CHAIN_SET_CLEAN(chain) ((chain)->flags &= ~GST_OPT_SCHEDULER_CHAIN_DIRTY) -#define GST_OPT_SCHEDULER_CHAIN_IS_DIRTY(chain) ((chain)->flags & GST_OPT_SCHEDULER_CHAIN_DIRTY) - -#define GST_OPT_SCHEDULER_CHAIN_DISABLE(chain) ((chain)->flags |= GST_OPT_SCHEDULER_CHAIN_DISABLED) -#define GST_OPT_SCHEDULER_CHAIN_ENABLE(chain) ((chain)->flags &= ~GST_OPT_SCHEDULER_CHAIN_DISABLED) -#define GST_OPT_SCHEDULER_CHAIN_IS_DISABLED(chain) ((chain)->flags & GST_OPT_SCHEDULER_CHAIN_DISABLED) - -typedef struct _GstOptSchedulerChain GstOptSchedulerChain; - -struct _GstOptSchedulerChain -{ - gint refcount; - - GstOptScheduler *sched; - - GstOptSchedulerChainFlags flags; - - GSList *groups; /* the groups in this chain */ - gint num_groups; - gint num_enabled; -}; - -/* - * elements that are scheduled in one cothread - */ -typedef enum -{ - GST_OPT_SCHEDULER_GROUP_DIRTY = (1 << 1), /* this group has been modified */ - GST_OPT_SCHEDULER_GROUP_COTHREAD_STOPPING = (1 << 2), /* the group's cothread stops after one iteration */ - GST_OPT_SCHEDULER_GROUP_DISABLED = (1 << 3), /* this group is disabled */ - GST_OPT_SCHEDULER_GROUP_RUNNING = (1 << 4), /* this group is running */ - GST_OPT_SCHEDULER_GROUP_SCHEDULABLE = (1 << 5), /* this group is schedulable */ - GST_OPT_SCHEDULER_GROUP_VISITED = (1 << 6) /* this group is visited when finding links */ -} -GstOptSchedulerGroupFlags; - -typedef enum -{ - GST_OPT_SCHEDULER_GROUP_UNKNOWN = 3, - GST_OPT_SCHEDULER_GROUP_GET = 1, - GST_OPT_SCHEDULER_GROUP_LOOP = 2 -} -GstOptSchedulerGroupType; - -#define GST_OPT_SCHEDULER_GROUP_SET_FLAG(group,flag) ((group)->flags |= (flag)) -#define GST_OPT_SCHEDULER_GROUP_UNSET_FLAG(group,flag) ((group)->flags &= ~(flag)) -#define GST_OPT_SCHEDULER_GROUP_IS_FLAG_SET(group,flag) ((group)->flags & (flag)) - -#define GST_OPT_SCHEDULER_GROUP_DISABLE(group) ((group)->flags |= GST_OPT_SCHEDULER_GROUP_DISABLED) -#define GST_OPT_SCHEDULER_GROUP_ENABLE(group) ((group)->flags &= ~GST_OPT_SCHEDULER_GROUP_DISABLED) -#define GST_OPT_SCHEDULER_GROUP_IS_ENABLED(group) (!((group)->flags & GST_OPT_SCHEDULER_GROUP_DISABLED)) -#define GST_OPT_SCHEDULER_GROUP_IS_DISABLED(group) ((group)->flags & GST_OPT_SCHEDULER_GROUP_DISABLED) - - -typedef struct _GstOptSchedulerGroup GstOptSchedulerGroup; -typedef struct _GstOptSchedulerGroupLink GstOptSchedulerGroupLink; - -/* used to keep track of links with other groups */ -struct _GstOptSchedulerGroupLink -{ - GstOptSchedulerGroup *src; /* the group we are linked with */ - GstOptSchedulerGroup *sink; /* the group we are linked with */ - gint count; /* the number of links with the group */ -}; - -#define IS_GROUP_LINK(link, srcg, sinkg) ((link->src == srcg && link->sink == sinkg) || \ - (link->sink == srcg && link->src == sinkg)) -#define OTHER_GROUP_LINK(link, group) (link->src == group ? link->sink : link->src) - -typedef int (*GroupScheduleFunction) (int argc, char *argv[]); - -struct _GstOptSchedulerGroup -{ - GstOptSchedulerChain *chain; /* the chain this group belongs to */ - GstOptSchedulerGroupFlags flags; /* flags for this group */ - GstOptSchedulerGroupType type; /* flags for this group */ - GstOptScheduler *sched; /* the scheduler */ - - gint refcount; - - GSList *elements; /* elements of this group */ - gint num_elements; - gint num_enabled; - GstElement *entry; /* the group's entry point */ - - GSList *group_links; /* other groups that are linked with this group */ - -#ifdef USE_COTHREADS - cothread *cothread; /* the cothread of this group */ -#else - GroupScheduleFunction schedulefunc; -#endif - int argc; - char **argv; -}; - -/* - * A group is a set of elements through which data can flow without switching - * cothreads or without invoking the scheduler's run queue. - */ -static GstOptSchedulerGroup *ref_group (GstOptSchedulerGroup * group); -static GstOptSchedulerGroup *unref_group (GstOptSchedulerGroup * group); -static GstOptSchedulerGroup *create_group (GstOptSchedulerChain * chain, - GstElement * element, GstOptSchedulerGroupType type); -static void destroy_group (GstOptSchedulerGroup * group); -static GstOptSchedulerGroup *add_to_group (GstOptSchedulerGroup * group, - GstElement * element, gboolean with_links); -static GstOptSchedulerGroup *remove_from_group (GstOptSchedulerGroup * group, - GstElement * element); -static void group_dec_links_for_element (GstOptSchedulerGroup * group, - GstElement * element); -static void group_inc_links_for_element (GstOptSchedulerGroup * group, - GstElement * element); -static GstOptSchedulerGroup *merge_groups (GstOptSchedulerGroup * group1, - GstOptSchedulerGroup * group2); -static void setup_group_scheduler (GstOptScheduler * osched, - GstOptSchedulerGroup * group); -static void destroy_group_scheduler (GstOptSchedulerGroup * group); -static void group_error_handler (GstOptSchedulerGroup * group); -static void group_element_set_enabled (GstOptSchedulerGroup * group, - GstElement * element, gboolean enabled); -static gboolean schedule_group (GstOptSchedulerGroup * group); -static void get_group (GstElement * element, GstOptSchedulerGroup ** group); - - -/* - * A chain is a set of groups that are linked to each other. - */ -static void destroy_chain (GstOptSchedulerChain * chain); -static GstOptSchedulerChain *create_chain (GstOptScheduler * osched); -static GstOptSchedulerChain *ref_chain (GstOptSchedulerChain * chain); -static GstOptSchedulerChain *unref_chain (GstOptSchedulerChain * chain); -static GstOptSchedulerChain *add_to_chain (GstOptSchedulerChain * chain, - GstOptSchedulerGroup * group); -static GstOptSchedulerChain *remove_from_chain (GstOptSchedulerChain * chain, - GstOptSchedulerGroup * group); -static GstOptSchedulerChain *merge_chains (GstOptSchedulerChain * chain1, - GstOptSchedulerChain * chain2); -static void chain_recursively_migrate_group (GstOptSchedulerChain * chain, - GstOptSchedulerGroup * group); -static void chain_group_set_enabled (GstOptSchedulerChain * chain, - GstOptSchedulerGroup * group, gboolean enabled); -static gboolean schedule_chain (GstOptSchedulerChain * chain); - - -/* - * The schedule functions are the entry points for cothreads, or called directly - * by gst_opt_scheduler_schedule_run_queue - */ -static int get_group_schedule_function (int argc, char *argv[]); -static int loop_group_schedule_function (int argc, char *argv[]); -static int unknown_group_schedule_function (int argc, char *argv[]); - - -/* - * These wrappers are set on the pads as the chain handler (what happens when - * gst_pad_push is called) or get handler (for gst_pad_pull). - */ -static void gst_opt_scheduler_loop_wrapper (GstPad * sinkpad, GstData * data); -static GstData *gst_opt_scheduler_get_wrapper (GstPad * srcpad); - - -/* - * Without cothreads, gst_pad_push or gst_pad_pull on a loop-based group will - * just queue the peer element on a list. We need to actually run the queue - * instead of relying on cothreads to do the switch for us. - */ -#ifndef USE_COTHREADS -static void gst_opt_scheduler_schedule_run_queue (GstOptScheduler * osched, - GstOptSchedulerGroup * only_group); -#endif - - -/* - * Scheduler private data for an element - */ -typedef struct _GstOptSchedulerCtx GstOptSchedulerCtx; - -typedef enum -{ - GST_OPT_SCHEDULER_CTX_DISABLED = (1 << 1) /* the element is disabled */ -} -GstOptSchedulerCtxFlags; - -struct _GstOptSchedulerCtx -{ - GstOptSchedulerGroup *group; /* the group this element belongs to */ - - GstOptSchedulerCtxFlags flags; /* flags for this element */ -}; - - -/* - * Implementation of GstScheduler - */ -enum -{ - ARG_0, - ARG_ITERATIONS, - ARG_MAX_RECURSION -}; - -static void gst_opt_scheduler_class_init (GstOptSchedulerClass * klass); -static void gst_opt_scheduler_init (GstOptScheduler * scheduler); - -static void gst_opt_scheduler_set_property (GObject * object, guint prop_id, - const GValue * value, GParamSpec * pspec); -static void gst_opt_scheduler_get_property (GObject * object, guint prop_id, - GValue * value, GParamSpec * pspec); - -static void gst_opt_scheduler_dispose (GObject * object); -static void gst_opt_scheduler_finalize (GObject * object); - -static void gst_opt_scheduler_setup (GstScheduler * sched); -static void gst_opt_scheduler_reset (GstScheduler * sched); -static void gst_opt_scheduler_add_element (GstScheduler * sched, - GstElement * element); -static void gst_opt_scheduler_remove_element (GstScheduler * sched, - GstElement * element); -static GstElementStateReturn gst_opt_scheduler_state_transition (GstScheduler * - sched, GstElement * element, gint transition); -static void gst_opt_scheduler_scheduling_change (GstScheduler * sched, - GstElement * element); -static gboolean gst_opt_scheduler_yield (GstScheduler * sched, - GstElement * element); -static gboolean gst_opt_scheduler_interrupt (GstScheduler * sched, - GstElement * element); -static void gst_opt_scheduler_error (GstScheduler * sched, - GstElement * element); -static void gst_opt_scheduler_pad_link (GstScheduler * sched, GstPad * srcpad, - GstPad * sinkpad); -static void gst_opt_scheduler_pad_unlink (GstScheduler * sched, GstPad * srcpad, - GstPad * sinkpad); -static GstSchedulerState gst_opt_scheduler_iterate (GstScheduler * sched); - -static void gst_opt_scheduler_show (GstScheduler * sched); - -static GstSchedulerClass *parent_class = NULL; - -static GType -gst_opt_scheduler_get_type (void) -{ - if (!_gst_opt_scheduler_type) { - static const GTypeInfo scheduler_info = { - sizeof (GstOptSchedulerClass), - NULL, - NULL, - (GClassInitFunc) gst_opt_scheduler_class_init, - NULL, - NULL, - sizeof (GstOptScheduler), - 0, - (GInstanceInitFunc) gst_opt_scheduler_init, - NULL - }; - - _gst_opt_scheduler_type = g_type_register_static (GST_TYPE_SCHEDULER, - "GstOpt" COTHREADS_NAME_CAPITAL "Scheduler", &scheduler_info, 0); - } - return _gst_opt_scheduler_type; -} - -static void -gst_opt_scheduler_class_init (GstOptSchedulerClass * klass) -{ - GObjectClass *gobject_class; - GstObjectClass *gstobject_class; - GstSchedulerClass *gstscheduler_class; - - gobject_class = (GObjectClass *) klass; - gstobject_class = (GstObjectClass *) klass; - gstscheduler_class = (GstSchedulerClass *) klass; - - parent_class = g_type_class_ref (GST_TYPE_SCHEDULER); - - gobject_class->set_property = - GST_DEBUG_FUNCPTR (gst_opt_scheduler_set_property); - gobject_class->get_property = - GST_DEBUG_FUNCPTR (gst_opt_scheduler_get_property); - gobject_class->dispose = GST_DEBUG_FUNCPTR (gst_opt_scheduler_dispose); - gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_opt_scheduler_finalize); - - g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_ITERATIONS, - g_param_spec_int ("iterations", "Iterations", - "Number of groups to schedule in one iteration (-1 == until EOS/error)", - -1, G_MAXINT, 1, G_PARAM_READWRITE)); -#ifndef USE_COTHREADS - g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_MAX_RECURSION, - g_param_spec_int ("max_recursion", "Max recursion", - "Maximum number of recursions", 1, G_MAXINT, 100, G_PARAM_READWRITE)); -#endif - - gstscheduler_class->setup = GST_DEBUG_FUNCPTR (gst_opt_scheduler_setup); - gstscheduler_class->reset = GST_DEBUG_FUNCPTR (gst_opt_scheduler_reset); - gstscheduler_class->add_element = - GST_DEBUG_FUNCPTR (gst_opt_scheduler_add_element); - gstscheduler_class->remove_element = - GST_DEBUG_FUNCPTR (gst_opt_scheduler_remove_element); - gstscheduler_class->state_transition = - GST_DEBUG_FUNCPTR (gst_opt_scheduler_state_transition); - gstscheduler_class->scheduling_change = - GST_DEBUG_FUNCPTR (gst_opt_scheduler_scheduling_change); - gstscheduler_class->yield = GST_DEBUG_FUNCPTR (gst_opt_scheduler_yield); - gstscheduler_class->interrupt = - GST_DEBUG_FUNCPTR (gst_opt_scheduler_interrupt); - gstscheduler_class->error = GST_DEBUG_FUNCPTR (gst_opt_scheduler_error); - gstscheduler_class->pad_link = GST_DEBUG_FUNCPTR (gst_opt_scheduler_pad_link); - gstscheduler_class->pad_unlink = - GST_DEBUG_FUNCPTR (gst_opt_scheduler_pad_unlink); - gstscheduler_class->clock_wait = NULL; - gstscheduler_class->iterate = GST_DEBUG_FUNCPTR (gst_opt_scheduler_iterate); - gstscheduler_class->show = GST_DEBUG_FUNCPTR (gst_opt_scheduler_show); - -#ifdef USE_COTHREADS - do_cothreads_init (NULL); -#endif -} - -static void -gst_opt_scheduler_init (GstOptScheduler * scheduler) -{ - g_static_rec_mutex_init (&scheduler->lock); - - scheduler->elements = NULL; - scheduler->iterations = 1; - scheduler->max_recursion = 100; - scheduler->live_groups = 0; - scheduler->live_chains = 0; - scheduler->live_links = 0; -} - -static void -gst_opt_scheduler_dispose (GObject * object) -{ - G_OBJECT_CLASS (parent_class)->dispose (object); -} - -static void -gst_opt_scheduler_finalize (GObject * object) -{ - GstOptScheduler *osched = GST_OPT_SCHEDULER (object); - - g_static_rec_mutex_free (&osched->lock); - - G_OBJECT_CLASS (parent_class)->finalize (object); -} - -static gboolean -plugin_init (GstPlugin * plugin) -{ -#ifdef USE_COTHREADS - if (!gst_scheduler_register (plugin, "opt" COTHREADS_NAME, - "An optimal scheduler using " COTHREADS_NAME " cothreads", - gst_opt_scheduler_get_type ())) -#else - if (!gst_scheduler_register (plugin, "opt", - "An optimal scheduler using no cothreads", - gst_opt_scheduler_get_type ())) -#endif - return FALSE; - - GST_DEBUG_CATEGORY_INIT (debug_scheduler, "scheduler", 0, - "optimal scheduler"); - - return TRUE; -} - -GST_PLUGIN_DEFINE (GST_VERSION_MAJOR, - GST_VERSION_MINOR, - "gstopt" COTHREADS_NAME "scheduler", - "An optimal scheduler using " COTHREADS_NAME " cothreads", - plugin_init, VERSION, GST_LICENSE, GST_PACKAGE, GST_ORIGIN); - - -static GstOptSchedulerChain * -ref_chain (GstOptSchedulerChain * chain) -{ - GST_LOG ("ref chain %p %d->%d", chain, chain->refcount, chain->refcount + 1); - chain->refcount++; - - return chain; -} - -static GstOptSchedulerChain * -unref_chain (GstOptSchedulerChain * chain) -{ - GST_LOG ("unref chain %p %d->%d", chain, - chain->refcount, chain->refcount - 1); - - if (--chain->refcount == 0) { - destroy_chain (chain); - chain = NULL; - } - - return chain; -} - -static GstOptSchedulerChain * -create_chain (GstOptScheduler * osched) -{ - GstOptSchedulerChain *chain; - - chain = g_new0 (GstOptSchedulerChain, 1); - chain->sched = osched; - chain->refcount = 1; - chain->flags = GST_OPT_SCHEDULER_CHAIN_DISABLED; - osched->live_chains++; - - gst_object_ref (GST_OBJECT (osched)); - osched->chains = g_slist_prepend (osched->chains, chain); - - GST_LOG ("new chain %p, %d live chains now", chain, osched->live_chains); - - return chain; -} - -static void -destroy_chain (GstOptSchedulerChain * chain) -{ - GstOptScheduler *osched; - - GST_LOG ("destroy chain %p", chain); - - g_assert (chain->num_groups == 0); - g_assert (chain->groups == NULL); - - osched = chain->sched; - osched->chains = g_slist_remove (osched->chains, chain); - osched->live_chains--; - - GST_LOG ("%d live chains now", osched->live_chains); - - gst_object_unref (GST_OBJECT (osched)); - - g_free (chain); -} - -static GstOptSchedulerChain * -add_to_chain (GstOptSchedulerChain * chain, GstOptSchedulerGroup * group) -{ - gboolean enabled; - - GST_LOG ("adding group %p to chain %p", group, chain); - - g_assert (group->chain == NULL); - - group = ref_group (group); - - group->chain = ref_chain (chain); - chain->groups = g_slist_prepend (chain->groups, group); - chain->num_groups++; - - enabled = GST_OPT_SCHEDULER_GROUP_IS_ENABLED (group); - - if (enabled) { - /* we can now setup the scheduling of the group */ - setup_group_scheduler (chain->sched, group); - - chain->num_enabled++; - if (chain->num_enabled == chain->num_groups) { - GST_LOG ("enabling chain %p after adding of enabled group", chain); - GST_OPT_SCHEDULER_CHAIN_ENABLE (chain); - } - } - - /* queue a resort of the group list, which determines which group will be run - * first. */ - GST_OPT_SCHEDULER_CHAIN_SET_DIRTY (chain); - - return chain; -} - -static GstOptSchedulerChain * -remove_from_chain (GstOptSchedulerChain * chain, GstOptSchedulerGroup * group) -{ - gboolean enabled; - - GST_LOG ("removing group %p from chain %p", group, chain); - - if (!chain) - return NULL; - - g_assert (group); - g_assert (group->chain == chain); - - enabled = GST_OPT_SCHEDULER_GROUP_IS_ENABLED (group); - - group->chain = NULL; - chain->groups = g_slist_remove (chain->groups, group); - chain->num_groups--; - unref_group (group); - - if (chain->num_groups == 0) - chain = unref_chain (chain); - else { - /* removing an enabled group from the chain decrements the - * enabled counter */ - if (enabled) { - chain->num_enabled--; - if (chain->num_enabled == 0) { - GST_LOG ("disabling chain %p after removal of the only enabled group", - chain); - GST_OPT_SCHEDULER_CHAIN_DISABLE (chain); - } - } else { - if (chain->num_enabled == chain->num_groups) { - GST_LOG ("enabling chain %p after removal of the only disabled group", - chain); - GST_OPT_SCHEDULER_CHAIN_ENABLE (chain); - } - } - } - - GST_OPT_SCHEDULER_CHAIN_SET_DIRTY (chain); - - chain = unref_chain (chain); - return chain; -} - -static GstOptSchedulerChain * -merge_chains (GstOptSchedulerChain * chain1, GstOptSchedulerChain * chain2) -{ - GSList *walk; - - g_assert (chain1 != NULL); - - GST_LOG ("merging chain %p and %p", chain1, chain2); - - /* FIXME: document how chain2 can be NULL */ - if (chain1 == chain2 || chain2 == NULL) - return chain1; - - /* switch if it's more efficient */ - if (chain1->num_groups < chain2->num_groups) { - GstOptSchedulerChain *tmp = chain2; - - chain2 = chain1; - chain1 = tmp; - } - - walk = chain2->groups; - while (walk) { - GstOptSchedulerGroup *group = (GstOptSchedulerGroup *) walk->data; - - walk = g_slist_next (walk); - - GST_LOG ("reparenting group %p from chain %p to %p", group, chain2, chain1); - - ref_group (group); - - remove_from_chain (chain2, group); - add_to_chain (chain1, group); - - unref_group (group); - } - - /* chain2 is now freed, if nothing else was referencing it before */ - - return chain1; -} - -/* sorts the group list so that terminal sinks come first -- prevents pileup of - * datas in datapens */ -static void -sort_chain (GstOptSchedulerChain * chain) -{ - GSList *original = chain->groups; - GSList *new = NULL; - GSList *walk, *links, *this; - - /* if there's only one group, just return */ - if (!original->next) - return; - /* otherwise, we know that all groups are somehow linked together */ - - GST_LOG ("sorting chain %p (%d groups)", chain, g_slist_length (original)); - - /* first find the terminal sinks */ - for (walk = original; walk;) { - GstOptSchedulerGroup *group = (GstOptSchedulerGroup *) walk->data; - - this = walk; - walk = walk->next; - if (group->group_links) { - gboolean is_sink = TRUE; - - for (links = group->group_links; links; links = links->next) - if (((GstOptSchedulerGroupLink *) links->data)->src == group) - is_sink = FALSE; - if (is_sink) { - /* found one */ - original = g_slist_remove_link (original, this); - new = g_slist_concat (new, this); - } - } - } - g_assert (new != NULL); - - /* now look for the elements that are linked to the terminal sinks */ - for (walk = new; walk; walk = walk->next) { - GstOptSchedulerGroup *group = (GstOptSchedulerGroup *) walk->data; - - for (links = group->group_links; links; links = links->next) { - this = - g_slist_find (original, - ((GstOptSchedulerGroupLink *) links->data)->src); - if (this) { - original = g_slist_remove_link (original, this); - new = g_slist_concat (new, this); - } - } - } - g_assert (original == NULL); - - chain->groups = new; -} - -static void -chain_group_set_enabled (GstOptSchedulerChain * chain, - GstOptSchedulerGroup * group, gboolean enabled) -{ - gboolean oldstate; - - g_assert (group != NULL); - g_assert (chain != NULL); - - GST_LOG - ("request to %d group %p in chain %p, have %d groups enabled out of %d", - enabled, group, chain, chain->num_enabled, chain->num_groups); - - oldstate = (GST_OPT_SCHEDULER_GROUP_IS_ENABLED (group) ? TRUE : FALSE); - if (oldstate == enabled) { - GST_LOG ("group %p in chain %p was in correct state", group, chain); - return; - } - - if (enabled) - GST_OPT_SCHEDULER_GROUP_ENABLE (group); - else - GST_OPT_SCHEDULER_GROUP_DISABLE (group); - - if (enabled) { - g_assert (chain->num_enabled < chain->num_groups); - - chain->num_enabled++; - - GST_DEBUG ("enable group %p in chain %p, now %d groups enabled out of %d", - group, chain, chain->num_enabled, chain->num_groups); - - /* OK to call even if the scheduler (cothread context / schedulerfunc) was - setup already -- will get destroyed when the group is destroyed */ - setup_group_scheduler (chain->sched, group); - - if (chain->num_enabled == chain->num_groups) { - GST_DEBUG ("enable chain %p", chain); - GST_OPT_SCHEDULER_CHAIN_ENABLE (chain); - } - } else { - g_assert (chain->num_enabled > 0); - - chain->num_enabled--; - GST_DEBUG ("disable group %p in chain %p, now %d groups enabled out of %d", - group, chain, chain->num_enabled, chain->num_groups); - - if (chain->num_enabled == 0) { - GST_DEBUG ("disable chain %p", chain); - GST_OPT_SCHEDULER_CHAIN_DISABLE (chain); - } - } -} - -/* recursively migrate the group and all connected groups into the new chain */ -static void -chain_recursively_migrate_group (GstOptSchedulerChain * chain, - GstOptSchedulerGroup * group) -{ - GSList *links; - - /* group already in chain */ - if (group->chain == chain) - return; - - /* first remove the group from its old chain */ - remove_from_chain (group->chain, group); - /* add to new chain */ - add_to_chain (chain, group); - - /* then follow all links */ - for (links = group->group_links; links; links = g_slist_next (links)) { - GstOptSchedulerGroupLink *link = (GstOptSchedulerGroupLink *) links->data; - - chain_recursively_migrate_group (chain, OTHER_GROUP_LINK (link, group)); - } -} - -static GstOptSchedulerGroup * -ref_group (GstOptSchedulerGroup * group) -{ - GST_LOG ("ref group %p %d->%d", group, group->refcount, group->refcount + 1); - - group->refcount++; - - return group; -} - -static GstOptSchedulerGroup * -unref_group (GstOptSchedulerGroup * group) -{ - GST_LOG ("unref group %p %d->%d", group, - group->refcount, group->refcount - 1); - - if (--group->refcount == 0) { - destroy_group (group); - group = NULL; - } - - return group; -} - -static GstOptSchedulerGroup * -create_group (GstOptSchedulerChain * chain, GstElement * element, - GstOptSchedulerGroupType type) -{ - GstOptSchedulerGroup *group; - - group = g_new0 (GstOptSchedulerGroup, 1); - GST_LOG ("new group %p, type %d", group, type); - group->refcount = 1; /* float... */ - group->flags = GST_OPT_SCHEDULER_GROUP_DISABLED; - group->type = type; - group->sched = chain->sched; - group->sched->live_groups++; - - add_to_group (group, element, FALSE); - add_to_chain (chain, group); - group = unref_group (group); /* ...and sink. */ - - GST_LOG ("%d live groups now", group->sched->live_groups); - /* group's refcount is now 2 (one for the element, one for the chain) */ - - return group; -} - -static void -destroy_group (GstOptSchedulerGroup * group) -{ - GST_LOG ("destroy group %p", group); - - g_assert (group != NULL); - g_assert (group->elements == NULL); - g_assert (group->chain == NULL); - g_assert (group->group_links == NULL); - - if (group->flags & GST_OPT_SCHEDULER_GROUP_SCHEDULABLE) - destroy_group_scheduler (group); - - group->sched->live_groups--; - GST_LOG ("%d live groups now", group->sched->live_groups); - - g_free (group); -} - -static GstOptSchedulerGroup * -add_to_group (GstOptSchedulerGroup * group, GstElement * element, - gboolean with_links) -{ - g_assert (group != NULL); - g_assert (element != NULL); - - GST_DEBUG ("adding element %p \"%s\" to group %p", element, - GST_ELEMENT_NAME (element), group); - - if (GST_ELEMENT_IS_DECOUPLED (element)) { - GST_DEBUG ("element \"%s\" is decoupled, not adding to group %p", - GST_ELEMENT_NAME (element), group); - return group; - } - - g_assert (GST_ELEMENT_SCHED_GROUP (element) == NULL); - - /* first increment the links that this group has with other groups through - * this element */ - if (with_links) - group_inc_links_for_element (group, element); - - /* Ref the group... */ - GST_ELEMENT_SCHED_GROUP (element) = ref_group (group); - - gst_object_ref (GST_OBJECT (element)); - group->elements = g_slist_prepend (group->elements, element); - group->num_elements++; - - if (gst_element_get_state (element) == GST_STATE_PLAYING) { - group_element_set_enabled (group, element, TRUE); - } - - return group; -} - -/* we need to remove a decoupled element from the scheduler, this - * involves finding all the groups that have this element as an - * entry point and disabling them. */ -static void -remove_decoupled (GstScheduler * sched, GstElement * element) -{ - GSList *chains; - GList *schedulers; - GstOptScheduler *osched = GST_OPT_SCHEDULER (sched); - - GST_DEBUG_OBJECT (sched, "removing decoupled element \"%s\"", - GST_OBJECT_NAME (element)); - - for (chains = osched->chains; chains; chains = g_slist_next (chains)) { - GstOptSchedulerChain *chain = (GstOptSchedulerChain *) chains->data; - GSList *groups; - - for (groups = chain->groups; groups; groups = g_slist_next (groups)) { - GstOptSchedulerGroup *group = (GstOptSchedulerGroup *) groups->data; - - if (group->entry) { - GST_DEBUG_OBJECT (sched, "group %p, entry %s", group, - GST_STR_NULL (GST_OBJECT_NAME (group->entry))); - } - - if (group->entry == element) { - GST_DEBUG ("clearing element %p \"%s\" as entry from group %p", - element, GST_ELEMENT_NAME (element), group); - group->entry = NULL; - group->type = GST_OPT_SCHEDULER_GROUP_UNKNOWN; - } - } - } - /* and remove from any child scheduler */ - for (schedulers = sched->schedulers; schedulers; - schedulers = g_list_next (schedulers)) { - remove_decoupled (GST_SCHEDULER (schedulers->data), element); - } -} - -static GstOptSchedulerGroup * -remove_from_group (GstOptSchedulerGroup * group, GstElement * element) -{ - GST_DEBUG ("removing element %p \"%s\" from group %p", - element, GST_ELEMENT_NAME (element), group); - - g_assert (group != NULL); - g_assert (element != NULL); - /* this assert also catches the decoupled elements */ - g_assert (GST_ELEMENT_SCHED_GROUP (element) == group); - - /* first decrement the links that this group has with other groups through - * this element */ - group_dec_links_for_element (group, element); - - if (gst_element_get_state (element) == GST_STATE_PLAYING) { - group_element_set_enabled (group, element, FALSE); - } - - group->elements = g_slist_remove (group->elements, element); - group->num_elements--; - - /* if the element was an entry point in the group, clear the group's - * entry point, and mark it as unknown */ - if (group->entry == element) { - GST_DEBUG ("clearing element %p \"%s\" as entry from group %p", - element, GST_ELEMENT_NAME (element), group); - group->entry = NULL; - group->type = GST_OPT_SCHEDULER_GROUP_UNKNOWN; - } - - GST_ELEMENT_SCHED_GROUP (element) = NULL; - gst_object_unref (GST_OBJECT (element)); - - if (group->num_elements == 0) { - GST_LOG ("group %p is now empty", group); - /* don't know in what case group->chain would be NULL, but putting this here - in deference to 0.8 -- remove me in 0.9 */ - if (group->chain) { - GST_LOG ("removing group %p from its chain", group); - chain_group_set_enabled (group->chain, group, FALSE); - remove_from_chain (group->chain, group); - } - } - group = unref_group (group); - - return group; -} - -/* check if an element is part of the given group. We have to be carefull - * as decoupled elements are added as entry but are not added to the elements - * list */ -static gboolean -group_has_element (GstOptSchedulerGroup * group, GstElement * element) -{ - if (group->entry == element) - return TRUE; - - return (g_slist_find (group->elements, element) != NULL); -} - -/* FIXME need to check if the groups are of the same type -- otherwise need to - setup the scheduler again, if it is setup */ -static GstOptSchedulerGroup * -merge_groups (GstOptSchedulerGroup * group1, GstOptSchedulerGroup * group2) -{ - g_assert (group1 != NULL); - - GST_DEBUG ("merging groups %p and %p", group1, group2); - - if (group1 == group2 || group2 == NULL) - return group1; - - /* make sure they end up in the same chain */ - merge_chains (group1->chain, group2->chain); - - while (group2 && group2->elements) { - GstElement *element = (GstElement *) group2->elements->data; - - group2 = remove_from_group (group2, element); - add_to_group (group1, element, TRUE); - } - - return group1; -} - -/* setup the scheduler context for a group. The right schedule function - * is selected based on the group type and cothreads are created if - * needed */ -static void -setup_group_scheduler (GstOptScheduler * osched, GstOptSchedulerGroup * group) -{ - GroupScheduleFunction wrapper; - - GST_DEBUG ("setup group %p scheduler, type %d", group, group->type); - - wrapper = unknown_group_schedule_function; - - /* figure out the wrapper function for this group */ - if (group->type == GST_OPT_SCHEDULER_GROUP_GET) - wrapper = get_group_schedule_function; - else if (group->type == GST_OPT_SCHEDULER_GROUP_LOOP) - wrapper = loop_group_schedule_function; - -#ifdef USE_COTHREADS - /* we can only initialize the cothread stuff when we have - * a cothread context */ - if (osched->context) { - if (!(group->flags & GST_OPT_SCHEDULER_GROUP_SCHEDULABLE)) { - do_cothread_create (group->cothread, osched->context, - (cothread_func) wrapper, 0, (char **) group); - } else { - do_cothread_setfunc (group->cothread, osched->context, - (cothread_func) wrapper, 0, (char **) group); - } - } -#else - group->schedulefunc = wrapper; - group->argc = 0; - group->argv = (char **) group; -#endif - group->flags |= GST_OPT_SCHEDULER_GROUP_SCHEDULABLE; -} - -static void -destroy_group_scheduler (GstOptSchedulerGroup * group) -{ - g_assert (group); - - if (group->flags & GST_OPT_SCHEDULER_GROUP_RUNNING) - g_warning ("destroying running group scheduler"); - -#ifdef USE_COTHREADS - if (group->cothread) { - do_cothread_destroy (group->cothread); - group->cothread = NULL; - } -#else - group->schedulefunc = NULL; - group->argc = 0; - group->argv = NULL; -#endif - - group->flags &= ~GST_OPT_SCHEDULER_GROUP_SCHEDULABLE; -} - -static void -group_error_handler (GstOptSchedulerGroup * group) -{ - GST_DEBUG ("group %p has errored", group); - - chain_group_set_enabled (group->chain, group, FALSE); - group->chain->sched->state = GST_OPT_SCHEDULER_STATE_ERROR; -} - -/* this function enables/disables an element, it will set/clear a flag on the element - * and tells the chain that the group is enabled if all elements inside the group are - * enabled */ -static void -group_element_set_enabled (GstOptSchedulerGroup * group, GstElement * element, - gboolean enabled) -{ - g_assert (group != NULL); - g_assert (element != NULL); - - GST_LOG - ("request to %d element %s in group %p, have %d elements enabled out of %d", - enabled, GST_ELEMENT_NAME (element), group, group->num_enabled, - group->num_elements); - - /* Note that if an unlinked PLAYING element is added to a bin, we have to - create a new group to hold the element, and this function will be called - before the group is added to the chain. Thus we have a valid case for - group->chain==NULL. */ - - if (enabled) { - g_assert (group->num_enabled < group->num_elements); - - group->num_enabled++; - - GST_DEBUG - ("enable element %s in group %p, now %d elements enabled out of %d", - GST_ELEMENT_NAME (element), group, group->num_enabled, - group->num_elements); - - if (group->num_enabled == group->num_elements) { - if (!group->chain) { - GST_DEBUG ("enable chainless group %p", group); - GST_OPT_SCHEDULER_GROUP_ENABLE (group); - } else { - GST_LOG ("enable group %p", group); - chain_group_set_enabled (group->chain, group, TRUE); - } - } - } else { - g_assert (group->num_enabled > 0); - - group->num_enabled--; - - GST_DEBUG - ("disable element %s in group %p, now %d elements enabled out of %d", - GST_ELEMENT_NAME (element), group, group->num_enabled, - group->num_elements); - - if (group->num_enabled == 0) { - if (!group->chain) { - GST_DEBUG ("disable chainless group %p", group); - GST_OPT_SCHEDULER_GROUP_DISABLE (group); - } else { - GST_LOG ("disable group %p", group); - chain_group_set_enabled (group->chain, group, FALSE); - } - } - } -} - -/* a group is scheduled by doing a cothread switch to it or - * by calling the schedule function. In the non-cothread case - * we cannot run already running groups so we return FALSE here - * to indicate this to the caller */ -static gboolean -schedule_group (GstOptSchedulerGroup * group) -{ - if (!group->entry) { - GST_INFO ("not scheduling group %p without entry", group); - /* FIXME, we return true here, while the group is actually - * not schedulable. We might want to disable the element that caused - * this group to be scheduled instead */ - return TRUE; - } -#ifdef USE_COTHREADS - if (group->cothread) - do_cothread_switch (group->cothread); - else - g_warning ("(internal error): trying to schedule group without cothread"); - return TRUE; -#else - /* cothreads automatically call the pre- and post-run functions for us; - * without cothreads we need to call them manually */ - if (group->schedulefunc == NULL) { - GST_INFO ("not scheduling group %p without schedulefunc", group); - return FALSE; - } else { - GSList *l, *lcopy; - GstElement *entry = NULL; - - lcopy = g_slist_copy (group->elements); - /* also add entry point, this is made so that decoupled elements - * are also reffed since they are not added to the list of group - * elements. */ - if (group->entry && GST_ELEMENT_IS_DECOUPLED (group->entry)) { - entry = group->entry; - gst_object_ref (GST_OBJECT (entry)); - } - - for (l = lcopy; l; l = l->next) { - GstElement *e = (GstElement *) l->data; - - gst_object_ref (GST_OBJECT (e)); - if (e->pre_run_func) - e->pre_run_func (e); - } - - group->schedulefunc (group->argc, group->argv); - - for (l = lcopy; l; l = l->next) { - GstElement *e = (GstElement *) l->data; - - if (e->post_run_func) - e->post_run_func (e); - - gst_object_unref (GST_OBJECT (e)); - } - if (entry) - gst_object_unref (GST_OBJECT (entry)); - g_slist_free (lcopy); - } - return TRUE; -#endif -} - -#ifndef USE_COTHREADS -static void -gst_opt_scheduler_schedule_run_queue (GstOptScheduler * osched, - GstOptSchedulerGroup * only_group) -{ - GST_LOG_OBJECT (osched, "running queue: %d groups, recursed %d times", - g_list_length (osched->runqueue), - osched->recursion, g_list_length (osched->runqueue)); - - /* note that we have a ref on each group on the queue (unref after running) */ - - /* make sure we don't exceed max_recursion */ - if (osched->recursion > osched->max_recursion) { - osched->state = GST_OPT_SCHEDULER_STATE_ERROR; - return; - } - - osched->recursion++; - - do { - GstOptSchedulerGroup *group; - gboolean res; - - if (only_group) - group = only_group; - else - group = (GstOptSchedulerGroup *) osched->runqueue->data; - - /* runqueue holds refcount to group */ - osched->runqueue = g_list_remove (osched->runqueue, group); - - GST_LOG_OBJECT (osched, "scheduling group %p", group); - - if (GST_OPT_SCHEDULER_GROUP_IS_ENABLED (group)) { - res = schedule_group (group); - } else { - GST_INFO_OBJECT (osched, - "group was disabled while it was on the queue, not scheduling"); - res = TRUE; - } - if (!res) { - g_warning ("error scheduling group %p", group); - group_error_handler (group); - } else { - GST_LOG_OBJECT (osched, "done scheduling group %p", group); - } - unref_group (group); - } while (osched->runqueue && !only_group); - - GST_LOG_OBJECT (osched, "run queue length after scheduling %d", - g_list_length (osched->runqueue)); - - osched->recursion--; -} -#endif - -/* a chain is scheduled by picking the first active group and scheduling it */ -static gboolean -schedule_chain (GstOptSchedulerChain * chain) -{ - GSList *groups; - GstOptScheduler *osched; - gboolean scheduled = FALSE; - - osched = chain->sched; - - /* if the chain has changed, we need to resort the groups so we enter in the - proper place */ - if (GST_OPT_SCHEDULER_CHAIN_IS_DIRTY (chain)) - sort_chain (chain); - GST_OPT_SCHEDULER_CHAIN_SET_CLEAN (chain); - - /* since the lock on the group list is only released when we schedule - * a group and since we only schedule one group, we don't need to - * worry about the list getting corrupted. */ - groups = chain->groups; - while (groups) { - GstOptSchedulerGroup *group = (GstOptSchedulerGroup *) groups->data; - - if (!GST_OPT_SCHEDULER_GROUP_IS_DISABLED (group)) { - ref_group (group); - GST_LOG ("scheduling group %p in chain %p", group, chain); - -#ifdef USE_COTHREADS - schedule_group (group); -#else - osched->recursion = 0; - if (!g_list_find (osched->runqueue, group)) { - ref_group (group); - osched->runqueue = g_list_append (osched->runqueue, group); - } - gst_opt_scheduler_schedule_run_queue (osched, NULL); -#endif - - scheduled = TRUE; - - GST_LOG ("done scheduling group %p in chain %p", group, chain); - unref_group (group); - /* stop scheduling more groups */ - break; - } - - groups = g_slist_next (groups); - } - return scheduled; -} - -/* this function is inserted in the gethandler when you are not - * supposed to call _pull on the pad. */ -static GstData * -get_invalid_call (GstPad * pad) -{ - GST_ELEMENT_ERROR (GST_PAD_PARENT (pad), CORE, PAD, (NULL), - ("get on pad %s:%s but the peer is operating chain based and so is not " - "allowed to pull, fix the element.", GST_DEBUG_PAD_NAME (pad))); - - return GST_DATA (gst_event_new (GST_EVENT_INTERRUPT)); -} - -/* this function is inserted in the chainhandler when you are not - * supposed to call _push on the pad. */ -static void -chain_invalid_call (GstPad * pad, GstData * data) -{ - GST_ELEMENT_ERROR (GST_PAD_PARENT (pad), CORE, PAD, (NULL), - ("chain on pad %s:%s but the pad is get based", - GST_DEBUG_PAD_NAME (pad))); - - gst_data_unref (data); -} - -/* a get-based group is scheduled by getting a buffer from the get based - * entry point and by pushing the buffer to the peer. - * We also set the running flag on this group for as long as this - * function is running. */ -static int -get_group_schedule_function (int argc, char *argv[]) -{ - GstOptSchedulerGroup *group = (GstOptSchedulerGroup *) argv; - GstElement *entry = group->entry; - const GList *pads; - GstOptScheduler *osched; - - /* what if the entry point disappeared? */ - if (entry == NULL || group->chain == NULL) - return 0; - - osched = group->chain->sched; - - pads = gst_element_get_pad_list (entry); - - GST_LOG ("executing get-based group %p", group); - - group->flags |= GST_OPT_SCHEDULER_GROUP_RUNNING; - - GST_OPT_UNLOCK (osched); - while (pads) { - GstData *data; - GstPad *pad = GST_PAD (pads->data); - - pads = g_list_next (pads); - - /* skip sinks and ghostpads */ - if (!GST_PAD_IS_SRC (pad) || !GST_IS_REAL_PAD (pad)) - continue; - - GST_DEBUG ("doing get and push on pad \"%s:%s\" in group %p", - GST_DEBUG_PAD_NAME (pad), group); - - data = gst_pad_call_get_function (pad); - if (data) { - if (GST_EVENT_IS_INTERRUPT (data)) { - GST_DEBUG ("unreffing interrupt event %p", data); - gst_event_unref (GST_EVENT (data)); - break; - } - gst_pad_push (pad, data); - } - } - GST_OPT_LOCK (osched); - - group->flags &= ~GST_OPT_SCHEDULER_GROUP_RUNNING; - - return 0; -} - -/* a loop-based group is scheduled by calling the loop function - * on the entry point. - * We also set the running flag on this group for as long as this - * function is running. - * This function should be called with the scheduler lock held. */ -static int -loop_group_schedule_function (int argc, char *argv[]) -{ - GstOptSchedulerGroup *group = (GstOptSchedulerGroup *) argv; - GstElement *entry = group->entry; - - GST_LOG ("executing loop-based group %p", group); - - group->flags |= GST_OPT_SCHEDULER_GROUP_RUNNING; - - GST_DEBUG ("calling loopfunc of element %s in group %p", - GST_ELEMENT_NAME (entry), group); - - if (group->chain == NULL) - return 0; - - if (entry->loopfunc) { - GstOptScheduler *osched = group->chain->sched; - - GST_OPT_UNLOCK (osched); - entry->loopfunc (entry); - GST_OPT_LOCK (osched); - } else - group_error_handler (group); - - GST_LOG ("returned from loopfunc of element %s in group %p", - GST_ELEMENT_NAME (entry), group); - - group->flags &= ~GST_OPT_SCHEDULER_GROUP_RUNNING; - - return 0; - -} - -/* the function to schedule an unknown group, which just gives an error */ -static int -unknown_group_schedule_function (int argc, char *argv[]) -{ - GstOptSchedulerGroup *group = (GstOptSchedulerGroup *) argv; - - g_warning ("(internal error) unknown group type %d, disabling\n", - group->type); - group_error_handler (group); - - return 0; -} - -/* this function is called when the first element of a chain-loop or a loop-loop - * link performs a push to the loop element. We then schedule the - * group with the loop-based element until the datapen is empty */ -static void -gst_opt_scheduler_loop_wrapper (GstPad * sinkpad, GstData * data) -{ - GstOptSchedulerGroup *group; - GstOptScheduler *osched; - GstRealPad *peer; - - group = GST_ELEMENT_SCHED_GROUP (GST_PAD_PARENT (sinkpad)); - osched = group->chain->sched; - peer = GST_RPAD_PEER (sinkpad); - - GST_LOG ("chain handler for loop-based pad %" GST_PTR_FORMAT, sinkpad); - - GST_OPT_LOCK (osched); -#ifdef USE_COTHREADS - if (GST_PAD_DATALIST (peer)) { - g_warning ("deadlock detected, disabling group %p", group); - group_error_handler (group); - } else { - GST_LOG ("queueing data %p on %s:%s's datapen", data, - GST_DEBUG_PAD_NAME (peer)); - GST_PAD_DATAPEN (peer) = g_list_append (GST_PAD_DATALIST (peer), data); - schedule_group (group); - } -#else - GST_LOG ("queueing data %p on %s:%s's datapen", data, - GST_DEBUG_PAD_NAME (peer)); - GST_PAD_DATAPEN (peer) = g_list_append (GST_PAD_DATALIST (peer), data); - if (!(group->flags & GST_OPT_SCHEDULER_GROUP_RUNNING)) { - GST_LOG ("adding group %p to runqueue", group); - if (!g_list_find (osched->runqueue, group)) { - ref_group (group); - osched->runqueue = g_list_append (osched->runqueue, group); - } - } -#endif - GST_OPT_UNLOCK (osched); - - GST_LOG ("%d datas left on %s:%s's datapen after chain handler", - g_list_length (GST_PAD_DATALIST (peer)), GST_DEBUG_PAD_NAME (peer)); -} - -/* this function is called by a loop based element that performs a - * pull on a sinkpad. We schedule the peer group until the datapen - * is filled with the data so that this function can return */ -static GstData * -gst_opt_scheduler_get_wrapper (GstPad * srcpad) -{ - GstData *data; - GstOptSchedulerGroup *group; - GstOptScheduler *osched; - gboolean disabled; - - GST_LOG ("get handler for %" GST_PTR_FORMAT, srcpad); - - /* first try to grab a queued data */ - if (GST_PAD_DATALIST (srcpad)) { - data = GST_PAD_DATALIST (srcpad)->data; - GST_PAD_DATAPEN (srcpad) = g_list_remove (GST_PAD_DATALIST (srcpad), data); - - GST_LOG ("returning popped queued data %p", data); - - return data; - } - GST_LOG ("need to schedule the peer element"); - - /* else we need to schedule the peer element */ - get_group (GST_PAD_PARENT (srcpad), &group); - if (group == NULL) { - /* wow, peer has no group */ - GST_LOG ("peer without group detected"); - //group_error_handler (group); - return GST_DATA (gst_event_new (GST_EVENT_INTERRUPT)); - } - osched = group->chain->sched; - data = NULL; - disabled = FALSE; - - GST_OPT_LOCK (osched); - do { - GST_LOG ("scheduling upstream group %p to fill datapen", group); -#ifdef USE_COTHREADS - schedule_group (group); -#else - if (!(group->flags & GST_OPT_SCHEDULER_GROUP_RUNNING)) { - ref_group (group); - - if (!g_list_find (osched->runqueue, group)) { - ref_group (group); - osched->runqueue = g_list_append (osched->runqueue, group); - } - - GST_LOG ("recursing into scheduler group %p", group); - gst_opt_scheduler_schedule_run_queue (osched, group); - GST_LOG ("return from recurse group %p", group); - - /* if the other group was disabled we might have to break out of the loop */ - disabled = GST_OPT_SCHEDULER_GROUP_IS_DISABLED (group); - group = unref_group (group); - /* group is gone */ - if (group == NULL) { - /* if the group was gone we also might have to break out of the loop */ - disabled = TRUE; - } - } else { - /* in this case, the group was running and we wanted to swtich to it, - * this is not allowed in the optimal scheduler (yet) */ - g_warning ("deadlock detected, disabling group %p", group); - group_error_handler (group); - data = GST_DATA (gst_event_new (GST_EVENT_INTERRUPT)); - goto done; - } -#endif - /* if the scheduler interrupted, make sure we send an INTERRUPTED event - * to the loop based element */ - if (osched->state == GST_OPT_SCHEDULER_STATE_INTERRUPTED) { - GST_INFO ("scheduler interrupted, return interrupt event"); - data = GST_DATA (gst_event_new (GST_EVENT_INTERRUPT)); - } else { - if (GST_PAD_DATALIST (srcpad)) { - data = GST_PAD_DATALIST (srcpad)->data; - GST_PAD_DATAPEN (srcpad) = - g_list_remove (GST_PAD_DATALIST (srcpad), data); - } else if (disabled) { - /* no data in queue and peer group was disabled */ - data = GST_DATA (gst_event_new (GST_EVENT_INTERRUPT)); - } - } - } - while (data == NULL); - -#ifndef USE_COTHREADS -done: -#endif - GST_OPT_UNLOCK (osched); - - GST_LOG ("get handler, returning data %p, queue length %d", - data, g_list_length (GST_PAD_DATALIST (srcpad))); - - return data; -} - -static void -pad_clear_queued (GstPad * srcpad, gpointer user_data) -{ - GList *datalist = GST_PAD_DATALIST (srcpad); - - if (datalist) { - GST_LOG ("need to clear some datas"); - g_list_foreach (datalist, (GFunc) gst_data_unref, NULL); - g_list_free (datalist); - GST_PAD_DATAPEN (srcpad) = NULL; - } -} - -static gboolean -gst_opt_scheduler_event_wrapper (GstPad * srcpad, GstEvent * event) -{ - gboolean flush; - - GST_DEBUG ("intercepting event type %d on pad %s:%s", - GST_EVENT_TYPE (event), GST_DEBUG_PAD_NAME (srcpad)); - - /* figure out if this is a flush event */ - switch (GST_EVENT_TYPE (event)) { - case GST_EVENT_FLUSH: - flush = TRUE; - break; - case GST_EVENT_SEEK: - case GST_EVENT_SEEK_SEGMENT: - flush = GST_EVENT_SEEK_FLAGS (event) & GST_SEEK_FLAG_FLUSH; - break; - default: - flush = FALSE; - break; - } - - if (flush) { - GST_LOG ("event triggers a flush"); - - pad_clear_queued (srcpad, NULL); - } - return GST_RPAD_EVENTFUNC (srcpad) (srcpad, event); -} - -static GstElementStateReturn -gst_opt_scheduler_state_transition (GstScheduler * sched, GstElement * element, - gint transition) -{ - GstOptSchedulerGroup *group; - GstElementStateReturn res = GST_STATE_SUCCESS; - - GST_DEBUG ("element \"%s\" state change (%04x)", - GST_ELEMENT_NAME (element) ? GST_ELEMENT_NAME (element) : "(null)", - transition); - - GST_OPT_LOCK (sched); - /* we check the state of the managing pipeline here */ - if (GST_IS_BIN (element)) { - if (GST_SCHEDULER_PARENT (sched) == element) { - GST_LOG ("parent \"%s\" changed state", - GST_ELEMENT_NAME (element) ? GST_ELEMENT_NAME (element) : "(null)"); - - switch (transition) { - case GST_STATE_PLAYING_TO_PAUSED: - GST_INFO ("setting scheduler state to stopped"); - GST_SCHEDULER_STATE (sched) = GST_SCHEDULER_STATE_STOPPED; - break; - case GST_STATE_PAUSED_TO_PLAYING: - GST_INFO ("setting scheduler state to running"); - GST_SCHEDULER_STATE (sched) = GST_SCHEDULER_STATE_RUNNING; - break; - default: - GST_LOG ("no interesting state change, doing nothing"); - } - } - goto done; - } - - /* we don't care about decoupled elements after this */ - if (GST_ELEMENT_IS_DECOUPLED (element)) { - res = GST_STATE_SUCCESS; - goto done; - } - - /* get the group of the element */ - group = GST_ELEMENT_SCHED_GROUP (element); - - switch (transition) { - case GST_STATE_PAUSED_TO_PLAYING: - /* an element without a group has to be an unlinked src, sink - * filter element */ - if (!group) { - GST_INFO ("element \"%s\" has no group", GST_ELEMENT_NAME (element)); - } - /* else construct the scheduling context of this group and enable it */ - else { - group_element_set_enabled (group, element, TRUE); - } - break; - case GST_STATE_PLAYING_TO_PAUSED: - /* if the element still has a group, we disable it */ - if (group) - group_element_set_enabled (group, element, FALSE); - break; - case GST_STATE_PAUSED_TO_READY: - { - GList *pads = (GList *) gst_element_get_pad_list (element); - - g_list_foreach (pads, (GFunc) pad_clear_queued, NULL); - break; - } - default: - break; - } - - //gst_scheduler_show (sched); - -done: - GST_OPT_UNLOCK (sched); - - return res; -} - -static void -gst_opt_scheduler_scheduling_change (GstScheduler * sched, GstElement * element) -{ - g_warning ("scheduling change, implement me"); -} - -static void -get_group (GstElement * element, GstOptSchedulerGroup ** group) -{ - GstOptSchedulerCtx *ctx; - - ctx = GST_ELEMENT_SCHED_CONTEXT (element); - if (ctx) - *group = ctx->group; - else - *group = NULL; -} - -/* - * the idea is to put the two elements into the same group. - * - When no element is inside a group, we create a new group and add - * the elements to it. - * - When one of the elements has a group, add the other element to - * that group - * - if both of the elements have a group, we merge the groups, which - * will also merge the chains. - * Group links must be managed by the caller. - */ -static GstOptSchedulerGroup * -group_elements (GstOptScheduler * osched, GstElement * element1, - GstElement * element2, GstOptSchedulerGroupType type) -{ - GstOptSchedulerGroup *group1, *group2, *group = NULL; - - get_group (element1, &group1); - get_group (element2, &group2); - - /* none of the elements is added to a group, create a new group - * and chain to add the elements to */ - if (!group1 && !group2) { - GstOptSchedulerChain *chain; - - GST_DEBUG ("creating new group to hold \"%s\" and \"%s\"", - GST_ELEMENT_NAME (element1), GST_ELEMENT_NAME (element2)); - - chain = create_chain (osched); - group = create_group (chain, element1, type); - add_to_group (group, element2, TRUE); - } - /* the first element has a group */ - else if (group1) { - GST_DEBUG ("adding \"%s\" to \"%s\"'s group", - GST_ELEMENT_NAME (element2), GST_ELEMENT_NAME (element1)); - - /* the second element also has a group, merge */ - if (group2) - merge_groups (group1, group2); - /* the second element has no group, add it to the group - * of the first element */ - else - add_to_group (group1, element2, TRUE); - - group = group1; - } - /* element1 has no group, element2 does. Add element1 to the - * group of element2 */ - else { - GST_DEBUG ("adding \"%s\" to \"%s\"'s group", - GST_ELEMENT_NAME (element1), GST_ELEMENT_NAME (element2)); - add_to_group (group2, element1, TRUE); - group = group2; - } - return group; -} - -/* - * increment link counts between groups -- it's important that src is actually - * the src group, so we can introspect the topology later - */ -static void -group_inc_link (GstOptSchedulerGroup * src, GstOptSchedulerGroup * sink) -{ - GSList *links = src->group_links; - gboolean done = FALSE; - GstOptSchedulerGroupLink *link; - - /* first try to find a previous link */ - while (links && !done) { - link = (GstOptSchedulerGroupLink *) links->data; - links = g_slist_next (links); - - if (IS_GROUP_LINK (link, src, sink)) { - /* we found a link to this group, increment the link count */ - link->count++; - GST_LOG ("incremented group link count between %p and %p to %d", - src, sink, link->count); - done = TRUE; - } - } - if (!done) { - /* no link was found, create a new one */ - link = g_new0 (GstOptSchedulerGroupLink, 1); - - link->src = src; - link->sink = sink; - link->count = 1; - - src->group_links = g_slist_prepend (src->group_links, link); - sink->group_links = g_slist_prepend (sink->group_links, link); - - src->sched->live_links++; - - GST_DEBUG ("added group link between %p and %p, %d live links now", - src, sink, src->sched->live_links); - } -} - -/* - * decrement link counts between groups, returns TRUE if the link count reaches - * 0 -- note that the groups are not necessarily ordered as (src, sink) like - * inc_link requires - */ -static gboolean -group_dec_link (GstOptSchedulerGroup * group1, GstOptSchedulerGroup * group2) -{ - GSList *links = group1->group_links; - gboolean res = FALSE; - GstOptSchedulerGroupLink *link; - - while (links) { - link = (GstOptSchedulerGroupLink *) links->data; - links = g_slist_next (links); - - if (IS_GROUP_LINK (link, group1, group2)) { - g_assert (link->count > 0); - link->count--; - GST_LOG ("link count between %p and %p is now %d", - group1, group2, link->count); - if (link->count == 0) { - GstOptSchedulerGroup *iso_group = NULL; - - group1->group_links = g_slist_remove (group1->group_links, link); - group2->group_links = g_slist_remove (group2->group_links, link); - group1->sched->live_links--; - - GST_LOG ("%d live links now", group1->sched->live_links); - - g_free (link); - GST_DEBUG ("removed group link between %p and %p", group1, group2); - if (group1->group_links == NULL) { - /* group1 has no more links with other groups */ - iso_group = group1; - } else if (group2->group_links == NULL) { - /* group2 has no more links with other groups */ - iso_group = group2; - } - if (iso_group) { - GstOptSchedulerChain *chain; - - GST_DEBUG ("group %p has become isolated, moving to new chain", - iso_group); - - chain = create_chain (iso_group->chain->sched); - remove_from_chain (iso_group->chain, iso_group); - add_to_chain (chain, iso_group); - } - res = TRUE; - } - break; - } - } - return res; -} - - -typedef enum -{ - GST_OPT_INVALID, - GST_OPT_GET_TO_CHAIN, - GST_OPT_LOOP_TO_CHAIN, - GST_OPT_GET_TO_LOOP, - GST_OPT_CHAIN_TO_CHAIN, - GST_OPT_CHAIN_TO_LOOP, - GST_OPT_LOOP_TO_LOOP -} -LinkType; - -/* - * Entry points for this scheduler. - */ -static void -gst_opt_scheduler_setup (GstScheduler * sched) -{ -#ifdef USE_COTHREADS - GstOptScheduler *osched = GST_OPT_SCHEDULER (sched); - - /* first create thread context */ - if (osched->context == NULL) { - GST_DEBUG ("initializing cothread context"); - osched->context = do_cothread_context_init (); - } -#endif -} - -static void -gst_opt_scheduler_reset (GstScheduler * sched) -{ -#ifdef USE_COTHREADS - GstOptScheduler *osched = GST_OPT_SCHEDULER (sched); - GSList *chains = osched->chains; - - while (chains) { - GstOptSchedulerChain *chain = (GstOptSchedulerChain *) chains->data; - GSList *groups = chain->groups; - - while (groups) { - GstOptSchedulerGroup *group = (GstOptSchedulerGroup *) groups->data; - - destroy_group_scheduler (group); - groups = groups->next; - } - chains = chains->next; - } - - if (osched->context) { - do_cothread_context_destroy (osched->context); - osched->context = NULL; - } -#endif -} - -static void -gst_opt_scheduler_add_element (GstScheduler * sched, GstElement * element) -{ - GstOptScheduler *osched = GST_OPT_SCHEDULER (sched); - GstOptSchedulerCtx *ctx; - const GList *pads; - - GST_DEBUG_OBJECT (sched, "adding element \"%s\"", GST_OBJECT_NAME (element)); - - /* decoupled elements are not added to the scheduler lists */ - if (GST_ELEMENT_IS_DECOUPLED (element)) - return; - - ctx = g_new0 (GstOptSchedulerCtx, 1); - GST_ELEMENT (element)->sched_private = ctx; - ctx->flags = GST_OPT_SCHEDULER_CTX_DISABLED; - - /* set event handler on all pads here so events work unconnected too; - * in _link, it can be overruled if need be */ - /* FIXME: we should also do this when new pads on the element are created; - but there are no hooks, so we do it again in _link */ - pads = gst_element_get_pad_list (element); - while (pads) { - GstPad *pad = GST_PAD (pads->data); - - pads = g_list_next (pads); - - if (!GST_IS_REAL_PAD (pad)) - continue; - GST_RPAD_EVENTHANDLER (pad) = GST_RPAD_EVENTFUNC (pad); - } - - /* loop based elements *always* end up in their own group. It can eventually - * be merged with another group when a link is made */ - if (element->loopfunc) { - GstOptSchedulerGroup *group; - GstOptSchedulerChain *chain; - - GST_OPT_LOCK (sched); - chain = create_chain (osched); - - group = create_group (chain, element, GST_OPT_SCHEDULER_GROUP_LOOP); - group->entry = element; - GST_OPT_UNLOCK (sched); - - GST_LOG ("added element \"%s\" as loop based entry", - GST_ELEMENT_NAME (element)); - } -} - -static void -gst_opt_scheduler_remove_element (GstScheduler * sched, GstElement * element) -{ - GstOptSchedulerGroup *group; - - GST_DEBUG_OBJECT (sched, "removing element \"%s\"", - GST_OBJECT_NAME (element)); - - GST_OPT_LOCK (sched); - /* decoupled elements are not added to the scheduler lists and should therefore - * not be removed */ - if (GST_ELEMENT_IS_DECOUPLED (element)) { - remove_decoupled (sched, element); - goto done; - } - - /* the element is guaranteed to live in it's own group/chain now */ - get_group (element, &group); - if (group) { - remove_from_group (group, element); - } - - g_free (GST_ELEMENT (element)->sched_private); - GST_ELEMENT (element)->sched_private = NULL; - -done: - GST_OPT_UNLOCK (sched); -} - -static gboolean -gst_opt_scheduler_yield (GstScheduler * sched, GstElement * element) -{ -#ifdef USE_COTHREADS - /* yield hands control to the main cothread context if the requesting - * element is the entry point of the group */ - GstOptSchedulerGroup *group; - - get_group (element, &group); - if (group && group->entry == element) - do_cothread_switch (do_cothread_get_main (((GstOptScheduler *) sched)-> - context)); - - return FALSE; -#else - g_warning ("element %s performs a yield, please fix the element", - GST_ELEMENT_NAME (element)); - return TRUE; -#endif -} - -static gboolean -gst_opt_scheduler_interrupt (GstScheduler * sched, GstElement * element) -{ - GST_INFO ("interrupt from \"%s\"", GST_OBJECT_NAME (element)); - -#ifdef USE_COTHREADS - do_cothread_switch (do_cothread_get_main (((GstOptScheduler *) sched)-> - context)); - return FALSE; -#else - { - GstOptScheduler *osched = GST_OPT_SCHEDULER (sched); - - GST_OPT_LOCK (sched); - GST_INFO ("scheduler set interrupted state"); - osched->state = GST_OPT_SCHEDULER_STATE_INTERRUPTED; - GST_OPT_UNLOCK (sched); - } - return TRUE; -#endif -} - -static void -gst_opt_scheduler_error (GstScheduler * sched, GstElement * element) -{ - GstOptScheduler *osched = GST_OPT_SCHEDULER (sched); - GstOptSchedulerGroup *group; - - GST_OPT_LOCK (sched); - get_group (element, &group); - if (group) - group_error_handler (group); - - osched->state = GST_OPT_SCHEDULER_STATE_ERROR; - GST_OPT_UNLOCK (sched); -} - -/* link pads, merge groups and chains */ -static void -gst_opt_scheduler_pad_link (GstScheduler * sched, GstPad * srcpad, - GstPad * sinkpad) -{ - GstOptScheduler *osched = GST_OPT_SCHEDULER (sched); - LinkType type = GST_OPT_INVALID; - GstElement *src_element, *sink_element; - - GST_INFO ("scheduling link between %s:%s and %s:%s", - GST_DEBUG_PAD_NAME (srcpad), GST_DEBUG_PAD_NAME (sinkpad)); - - src_element = GST_PAD_PARENT (srcpad); - sink_element = GST_PAD_PARENT (sinkpad); - - GST_OPT_LOCK (sched); - /* first we need to figure out what type of link we're dealing - * with */ - if (src_element->loopfunc && sink_element->loopfunc) - type = GST_OPT_LOOP_TO_LOOP; - else { - if (src_element->loopfunc) { - if (GST_RPAD_CHAINFUNC (sinkpad)) - type = GST_OPT_LOOP_TO_CHAIN; - } else if (sink_element->loopfunc) { - if (GST_RPAD_GETFUNC (srcpad)) { - type = GST_OPT_GET_TO_LOOP; - /* this could be tricky, the get based source could - * already be part of a loop based group in another pad, - * we assert on that for now */ - if (GST_ELEMENT_SCHED_CONTEXT (src_element) != NULL && - GST_ELEMENT_SCHED_GROUP (src_element) != NULL) { - GstOptSchedulerGroup *group = GST_ELEMENT_SCHED_GROUP (src_element); - - /* if the loop based element is the entry point we're ok, if it - * isn't then we have multiple loop based elements in this group */ - if (group->entry != sink_element) { - g_error - ("internal error: cannot schedule get to loop in multi-loop based group"); - goto done; - } - } - } else - type = GST_OPT_CHAIN_TO_LOOP; - } else { - if (GST_RPAD_GETFUNC (srcpad) && GST_RPAD_CHAINFUNC (sinkpad)) { - type = GST_OPT_GET_TO_CHAIN; - /* the get based source could already be part of a loop - * based group in another pad, we assert on that for now */ - if (GST_ELEMENT_SCHED_CONTEXT (src_element) != NULL && - GST_ELEMENT_SCHED_GROUP (src_element) != NULL) { - GstOptSchedulerGroup *group = GST_ELEMENT_SCHED_GROUP (src_element); - - /* if the get based element is the entry point we're ok, if it - * isn't then we have a mixed loop/chain based group */ - if (group->entry != src_element) { - g_error ("internal error: cannot schedule get to chain " - "with mixed loop/chain based group"); - goto done; - } - } - } else - type = GST_OPT_CHAIN_TO_CHAIN; - } - } - - /* since we can't set event handlers on pad creation after addition, it is - * best we set all of them again to the default before linking */ - GST_RPAD_EVENTHANDLER (srcpad) = GST_RPAD_EVENTFUNC (srcpad); - GST_RPAD_EVENTHANDLER (sinkpad) = GST_RPAD_EVENTFUNC (sinkpad); - - /* for each link type, perform specific actions */ - switch (type) { - case GST_OPT_GET_TO_CHAIN: - { - GstOptSchedulerGroup *group = NULL; - - GST_LOG ("get to chain based link"); - - /* setup get/chain handlers */ - GST_RPAD_GETHANDLER (srcpad) = get_invalid_call; - GST_RPAD_CHAINHANDLER (sinkpad) = gst_pad_call_chain_function; - - /* the two elements should be put into the same group, - * this also means that they are in the same chain automatically */ - group = group_elements (osched, src_element, sink_element, - GST_OPT_SCHEDULER_GROUP_GET); - - /* if there is not yet an entry in the group, select the source - * element as the entry point and mark the group as a get based - * group */ - if (!group->entry) { - group->entry = src_element; - group->type = GST_OPT_SCHEDULER_GROUP_GET; - - GST_DEBUG ("setting \"%s\" as entry point of _get-based group %p", - GST_ELEMENT_NAME (src_element), group); - - setup_group_scheduler (osched, group); - } - break; - } - case GST_OPT_LOOP_TO_CHAIN: - case GST_OPT_CHAIN_TO_CHAIN: - GST_LOG ("loop/chain to chain based link"); - - GST_RPAD_GETHANDLER (srcpad) = get_invalid_call; - GST_RPAD_CHAINHANDLER (sinkpad) = gst_pad_call_chain_function; - - /* the two elements should be put into the same group, this also means - * that they are in the same chain automatically, in case of a loop-based - * src_element, there will be a group for src_element and sink_element - * will be added to it. In the case a new group is created, we can't know - * the type so we pass UNKNOWN as an arg */ - group_elements (osched, src_element, sink_element, - GST_OPT_SCHEDULER_GROUP_UNKNOWN); - break; - case GST_OPT_GET_TO_LOOP: - GST_LOG ("get to loop based link"); - - GST_RPAD_GETHANDLER (srcpad) = gst_pad_call_get_function; - GST_RPAD_CHAINHANDLER (sinkpad) = chain_invalid_call; - - /* the two elements should be put into the same group, this also means - * that they are in the same chain automatically, sink_element is - * loop-based so it already has a group where src_element will be added - * to */ - group_elements (osched, src_element, sink_element, - GST_OPT_SCHEDULER_GROUP_LOOP); - break; - case GST_OPT_CHAIN_TO_LOOP: - case GST_OPT_LOOP_TO_LOOP: - { - GstOptSchedulerGroup *group1, *group2; - - GST_LOG ("chain/loop to loop based link"); - - GST_RPAD_GETHANDLER (srcpad) = gst_opt_scheduler_get_wrapper; - GST_RPAD_CHAINHANDLER (sinkpad) = gst_opt_scheduler_loop_wrapper; - /* events on the srcpad have to be intercepted as we might need to - * flush the buffer lists, so override the given eventfunc */ - GST_RPAD_EVENTHANDLER (srcpad) = gst_opt_scheduler_event_wrapper; - - group1 = GST_ELEMENT_SCHED_GROUP (src_element); - group2 = GST_ELEMENT_SCHED_GROUP (sink_element); - - g_assert (group2 != NULL); - - /* group2 is guaranteed to exist as it contains a loop-based element. - * group1 only exists if src_element is linked to some other element */ - if (!group1) { - /* create a new group for src_element as it cannot be merged into another group - * here. we create the group in the same chain as the loop-based element. note - * that creating a new group will not increment the links with other groups */ - GST_DEBUG ("creating new group for element %s", - GST_ELEMENT_NAME (src_element)); - group1 = - create_group (group2->chain, src_element, - GST_OPT_SCHEDULER_GROUP_LOOP); - } else { - /* both elements are already in a group, make sure they are added to - * the same chain */ - merge_chains (group1->chain, group2->chain); - } - /* increment the group link counters */ - group_inc_link (group1, group2); - break; - } - case GST_OPT_INVALID: - g_error ("(internal error) invalid element link, what are you doing?"); - break; - } -done: - GST_OPT_UNLOCK (sched); -} - -static void -group_elements_set_visited (GstOptSchedulerGroup * group, gboolean visited) -{ - GSList *elements; - - for (elements = group->elements; elements; elements = g_slist_next (elements)) { - GstElement *element = GST_ELEMENT (elements->data); - - if (visited) { - GST_ELEMENT_SET_VISITED (element); - } else { - GST_ELEMENT_UNSET_VISITED (element); - } - } - /* don't forget to set any decoupled entry points that are not accounted for in the - * element list (since they belong to two groups). */ - if (group->entry) { - if (visited) { - GST_ELEMENT_SET_VISITED (group->entry); - } else { - GST_ELEMENT_UNSET_VISITED (group->entry); - } - } -} - -static GList * -element_get_reachables_func (GstElement * element, GstOptSchedulerGroup * group, - GstPad * brokenpad) -{ - GList *result = NULL; - const GList *pads; - - /* if no element or element not in group or been there, return NULL */ - if (element == NULL || !group_has_element (group, element) || - GST_ELEMENT_IS_VISITED (element)) - return NULL; - - GST_ELEMENT_SET_VISITED (element); - - result = g_list_prepend (result, element); - - pads = gst_element_get_pad_list (element); - while (pads) { - GstPad *pad = GST_PAD (pads->data); - GstPad *peer; - - pads = g_list_next (pads); - - /* we only operate on real pads and on the pad that is not broken */ - if (!GST_IS_REAL_PAD (pad) || pad == brokenpad) - continue; - - peer = GST_PAD_PEER (pad); - if (!GST_IS_REAL_PAD (peer) || peer == brokenpad) - continue; - - if (peer) { - GstElement *parent; - GList *res; - - parent = GST_PAD_PARENT (peer); - - res = element_get_reachables_func (parent, group, brokenpad); - - result = g_list_concat (result, res); - } - } - - return result; -} - -static GList * -element_get_reachables (GstElement * element, GstOptSchedulerGroup * group, - GstPad * brokenpad) -{ - GList *result; - - /* reset visited flags */ - group_elements_set_visited (group, FALSE); - - result = element_get_reachables_func (element, group, brokenpad); - - /* and reset visited flags again */ - group_elements_set_visited (group, FALSE); - - return result; -} - -/* - * checks if a target group is still reachable from the group without taking the broken - * group link into account. - */ -static gboolean -group_can_reach_group (GstOptSchedulerGroup * group, - GstOptSchedulerGroup * target) -{ - gboolean reachable = FALSE; - const GSList *links = group->group_links; - - GST_LOG ("checking if group %p can reach %p", group, target); - - /* seems like we found the target element */ - if (group == target) { - GST_LOG ("found way to reach %p", target); - return TRUE; - } - - /* if the group is marked as visited, we don't need to check here */ - if (GST_OPT_SCHEDULER_GROUP_IS_FLAG_SET (group, - GST_OPT_SCHEDULER_GROUP_VISITED)) { - GST_LOG ("already visited %p", group); - return FALSE; - } - - /* mark group as visited */ - GST_OPT_SCHEDULER_GROUP_SET_FLAG (group, GST_OPT_SCHEDULER_GROUP_VISITED); - - while (links && !reachable) { - GstOptSchedulerGroupLink *link = (GstOptSchedulerGroupLink *) links->data; - GstOptSchedulerGroup *other; - - links = g_slist_next (links); - - /* find other group in this link */ - other = OTHER_GROUP_LINK (link, group); - - GST_LOG ("found link from %p to %p, count %d", group, other, link->count); - - /* check if we can reach the target recursively */ - reachable = group_can_reach_group (other, target); - } - /* unset the visited flag, note that this is not optimal as we might be checking - * groups several times when they are reachable with a loop. An alternative would be - * to not clear the group flag at this stage but clear all flags in the chain when - * all groups are checked. */ - GST_OPT_SCHEDULER_GROUP_UNSET_FLAG (group, GST_OPT_SCHEDULER_GROUP_VISITED); - - GST_LOG ("leaving group %p with %s", group, (reachable ? "TRUE" : "FALSE")); - - return reachable; -} - -/* - * Go through all the pads of the given element and decrement the links that - * this group has with the group of the peer element. This function is mainly used - * to update the group connections before we remove the element from the group. - */ -static void -group_dec_links_for_element (GstOptSchedulerGroup * group, GstElement * element) -{ - GList *l; - GstPad *pad; - GstOptSchedulerGroup *peer_group; - - for (l = GST_ELEMENT_PADS (element); l; l = l->next) { - pad = (GstPad *) l->data; - if (GST_IS_REAL_PAD (pad) && GST_PAD_PEER (pad)) { - get_group (GST_PAD_PARENT (GST_PAD_PEER (pad)), &peer_group); - if (peer_group && peer_group != group) - group_dec_link (group, peer_group); - } - } -} - -/* - * Go through all the pads of the given element and increment the links that - * this group has with the group of the peer element. This function is mainly used - * to update the group connections before we add the element to the group. - */ -static void -group_inc_links_for_element (GstOptSchedulerGroup * group, GstElement * element) -{ - GList *l; - GstPad *pad; - GstOptSchedulerGroup *peer_group; - - GST_DEBUG ("group %p, element %s ", group, gst_element_get_name (element)); - - for (l = GST_ELEMENT_PADS (element); l; l = l->next) { - pad = (GstPad *) l->data; - if (GST_IS_REAL_PAD (pad) && GST_PAD_PEER (pad)) { - get_group (GST_PAD_PARENT (GST_PAD_PEER (pad)), &peer_group); - if (peer_group && peer_group != group) { - if (GST_PAD_DIRECTION (pad) == GST_PAD_SRC) - group_inc_link (group, peer_group); - else - group_inc_link (peer_group, group); - } - } - } -} - -static void -debug_element (GstElement * element, GstOptScheduler * osched) -{ - GST_LOG ("element %s", gst_element_get_name (element)); -} - -/* move this group in the chain of the groups it has links with */ -static void -rechain_group (GstOptSchedulerGroup * group) -{ - GstOptSchedulerChain *chain = NULL; - GSList *links; - - GST_LOG ("checking if this group needs rechaining"); - - /* follow all links */ - for (links = group->group_links; links; links = g_slist_next (links)) { - GstOptSchedulerGroupLink *link = (GstOptSchedulerGroupLink *) links->data; - GstOptSchedulerGroup *other; - - other = OTHER_GROUP_LINK (link, group); - GST_LOG ("found link with other group %p with chain %p", other, - other->chain); - - /* first time, take chain */ - if (chain == NULL) { - chain = other->chain; - } - /* second time, chain should be the same */ - else if (other->chain != chain) { - g_warning ("(internal error): chain inconsistency"); - } - } - if (!chain) { - GST_LOG ("no new chain found, not rechaining"); - } else if (chain != group->chain) { - GST_LOG ("need to move group %p to chain %p", group, chain); - /* remove from old chain */ - remove_from_chain (group->chain, group); - /* and move to new chain */ - add_to_chain (chain, group); - } else { - GST_LOG ("group %p is in correct chain %p", group, chain); - } -} - -/* make sure that the group does not contain only single element. - * Only loop-based groups can contain a single element. */ -static GstOptSchedulerGroup * -normalize_group (GstOptSchedulerGroup * group) -{ - gint num; - gboolean have_decoupled = FALSE; - - if (group == NULL) - return NULL; - - num = group->num_elements; - /* decoupled elements are not added to the group but are - * added as an entry */ - if (group->entry && GST_ELEMENT_IS_DECOUPLED (group->entry)) { - num++; - have_decoupled = TRUE; - } - - if (num == 1 && group->type != GST_OPT_SCHEDULER_GROUP_LOOP) { - GST_LOG ("removing last element from group %p", group); - if (have_decoupled) { - group->entry = NULL; - if (group->chain) { - GST_LOG ("removing group %p from its chain", group); - chain_group_set_enabled (group->chain, group, FALSE); - remove_from_chain (group->chain, group); - } - group = unref_group (group); - } else { - group = remove_from_group (group, GST_ELEMENT (group->elements->data)); - } - } - return group; -} - -/* migrate the element and all connected elements to a new group without looking at - * the brokenpad */ -static GstOptSchedulerGroup * -group_migrate_connected (GstOptScheduler * osched, GstElement * element, - GstOptSchedulerGroup * group, GstPad * brokenpad) -{ - GList *connected, *c; - GstOptSchedulerGroup *new_group = NULL, *tst; - GstOptSchedulerChain *chain; - gint len; - - if (GST_ELEMENT_IS_DECOUPLED (element)) { - GST_LOG ("element is decoupled and thus not in the group"); - /* the element is decoupled and is therefore not in the group */ - return NULL; - } - - get_group (element, &tst); - if (tst == NULL) { - GST_LOG ("element has no group, not interesting"); - return NULL; - } - - GST_LOG ("migrate connected elements to new group"); - connected = element_get_reachables (element, group, brokenpad); - GST_LOG ("elements to move to new group:"); - g_list_foreach (connected, (GFunc) debug_element, NULL); - - len = g_list_length (connected); - - if (len == 0) { - g_warning ("(internal error) found lost element %s", - gst_element_get_name (element)); - return NULL; - } else if (len == 1) { - group = remove_from_group (group, GST_ELEMENT (connected->data)); - GST_LOG - ("not migrating to new group as the group would only contain 1 element"); - g_list_free (connected); - GST_LOG ("new group is old group now"); - new_group = group; - } else { - /* we create a new chain to hold the new group */ - chain = create_chain (osched); - - for (c = connected; c; c = g_list_next (c)) { - GstElement *element = GST_ELEMENT (c->data); - - group = remove_from_group (group, element); - if (new_group == NULL) { - new_group = - create_group (chain, element, GST_OPT_SCHEDULER_GROUP_UNKNOWN); - } else { - add_to_group (new_group, element, TRUE); - } - } - g_list_free (connected); - - /* remove last element from the group if any. Make sure not to remove - * the loop based entry point of a group as this always needs one group */ - if (group != NULL) { - group = normalize_group (group); - } - } - - if (new_group != NULL) { - new_group = normalize_group (new_group); - if (new_group == NULL) - return NULL; - /* at this point the new group lives in its own chain but might - * have to be merged with another chain, this happens when the new - * group has a link with another group in another chain */ - rechain_group (new_group); - } - - - return new_group; -} - -static void -gst_opt_scheduler_pad_unlink (GstScheduler * sched, - GstPad * srcpad, GstPad * sinkpad) -{ - GstOptScheduler *osched = GST_OPT_SCHEDULER (sched); - GstElement *src_element, *sink_element; - GstOptSchedulerGroup *group1, *group2; - - GST_INFO ("unscheduling link between %s:%s and %s:%s", - GST_DEBUG_PAD_NAME (srcpad), GST_DEBUG_PAD_NAME (sinkpad)); - - src_element = GST_PAD_PARENT (srcpad); - sink_element = GST_PAD_PARENT (sinkpad); - - GST_OPT_LOCK (sched); - get_group (src_element, &group1); - get_group (sink_element, &group2); - - /* for decoupled elements (that are never put into a group) we use the - * group of the peer element for the remainder of the algorithm */ - if (GST_ELEMENT_IS_DECOUPLED (src_element)) { - group1 = group2; - } - if (GST_ELEMENT_IS_DECOUPLED (sink_element)) { - group2 = group1; - } - - /* if one the elements has no group (anymore) we don't really care - * about the link */ - if (!group1 || !group2) { - GST_LOG - ("one (or both) of the elements is not in a group, not interesting"); - goto done; - } - - /* easy part, groups are different */ - if (group1 != group2) { - gboolean zero; - - GST_LOG ("elements are in different groups"); - - /* we can remove the links between the groups now */ - zero = group_dec_link (group1, group2); - - /* if the groups are not directly connected anymore, we have to perform a - * recursive check to see if they are really unlinked */ - if (zero) { - gboolean still_link; - GstOptSchedulerChain *chain; - - /* see if group1 and group2 are still connected in any indirect way */ - still_link = group_can_reach_group (group1, group2); - - GST_DEBUG ("group %p %s reach group %p", group1, - (still_link ? "can" : "can't"), group2); - if (!still_link) { - /* groups are really disconnected, migrate one group to a new chain */ - chain = create_chain (osched); - chain_recursively_migrate_group (chain, group1); - - GST_DEBUG ("migrated group %p to new chain %p", group1, chain); - } - } else { - GST_DEBUG ("group %p still has direct link with group %p", group1, - group2); - } - } - /* hard part, groups are equal */ - else { - GstOptSchedulerGroup *group; - - /* since group1 == group2, it doesn't matter which group we take */ - group = group1; - - GST_LOG ("elements are in the same group %p", group); - - if (group->entry == NULL) { - /* it doesn't really matter, we just have to make sure that both - * elements end up in another group if they are not connected */ - GST_LOG ("group %p has no entry, moving source element to new group", - group); - group_migrate_connected (osched, src_element, group, srcpad); - } else { - GList *reachables; - - GST_LOG ("group %p has entry %p", group, group->entry); - - /* get of a list of all elements that are still managed by the old - * entry element */ - reachables = element_get_reachables (group->entry, group, srcpad); - GST_LOG ("elements still reachable from the entry:"); - g_list_foreach (reachables, (GFunc) debug_element, sched); - - /* if the source is reachable from the entry, we can leave it in the group */ - if (g_list_find (reachables, src_element)) { - GST_LOG - ("source element still reachable from the entry, leaving in group"); - } else { - GST_LOG - ("source element not reachable from the entry, moving to new group"); - group_migrate_connected (osched, src_element, group, srcpad); - } - - /* if the sink is reachable from the entry, we can leave it in the group */ - if (g_list_find (reachables, sink_element)) { - GST_LOG - ("sink element still reachable from the entry, leaving in group"); - } else { - GST_LOG - ("sink element not reachable from the entry, moving to new group"); - group_migrate_connected (osched, sink_element, group, srcpad); - } - g_list_free (reachables); - } - /* at this point the group can be freed and gone, so don't touch */ - } -done: - GST_OPT_UNLOCK (sched); -} - -/* a scheduler iteration is done by looping and scheduling the active chains */ -static GstSchedulerState -gst_opt_scheduler_iterate (GstScheduler * sched) -{ - GstSchedulerState state = GST_SCHEDULER_STATE_STOPPED; - GstOptScheduler *osched = GST_OPT_SCHEDULER (sched); - gint iterations; - - GST_OPT_LOCK (sched); - iterations = osched->iterations; - - osched->state = GST_OPT_SCHEDULER_STATE_RUNNING; - - GST_DEBUG_OBJECT (sched, "iterating"); - - while (iterations) { - gboolean scheduled = FALSE; - GSList *chains; - - /* we have to schedule each of the scheduler chains now. */ - chains = osched->chains; - while (chains) { - GstOptSchedulerChain *chain = (GstOptSchedulerChain *) chains->data; - - ref_chain (chain); - /* if the chain is not disabled, schedule it */ - if (!GST_OPT_SCHEDULER_CHAIN_IS_DISABLED (chain)) { - GST_LOG ("scheduling chain %p", chain); - scheduled = schedule_chain (chain); - GST_LOG ("scheduled chain %p", chain); - } else { - GST_LOG ("not scheduling disabled chain %p", chain); - } - - /* don't schedule any more chains when in error */ - if (osched->state == GST_OPT_SCHEDULER_STATE_ERROR) { - GST_ERROR_OBJECT (sched, "in error state"); - /* unref the chain here as we move out of the while loop */ - unref_chain (chain); - break; - } else if (osched->state == GST_OPT_SCHEDULER_STATE_INTERRUPTED) { - GST_DEBUG_OBJECT (osched, "got interrupted, continue with next chain"); - osched->state = GST_OPT_SCHEDULER_STATE_RUNNING; - } - - /* grab the next chain before we unref, the list we are iterating - * can only be updated in the unref method */ - chains = g_slist_next (chains); - unref_chain (chain); - } - - /* at this point it's possible that the scheduler state is - * in error, we then return an error */ - if (osched->state == GST_OPT_SCHEDULER_STATE_ERROR) { - state = GST_SCHEDULER_STATE_ERROR; - break; - } else { - /* if chains were scheduled, return our current state */ - if (scheduled) - state = GST_SCHEDULER_STATE (sched); - /* if no chains were scheduled, we say we are stopped */ - else { - state = GST_SCHEDULER_STATE_STOPPED; - break; - } - } - if (iterations > 0) - iterations--; - } - GST_OPT_UNLOCK (sched); - - return state; -} - - -static void -gst_opt_scheduler_show (GstScheduler * sched) -{ - GstOptScheduler *osched = GST_OPT_SCHEDULER (sched); - GSList *chains; - - GST_OPT_LOCK (sched); - - g_print ("iterations: %d\n", osched->iterations); - g_print ("max recursion: %d\n", osched->max_recursion); - - chains = osched->chains; - while (chains) { - GstOptSchedulerChain *chain = (GstOptSchedulerChain *) chains->data; - GSList *groups = chain->groups; - - chains = g_slist_next (chains); - - g_print ("+- chain %p: refcount %d, %d groups, %d enabled, flags %d\n", - chain, chain->refcount, chain->num_groups, chain->num_enabled, - chain->flags); - - while (groups) { - GstOptSchedulerGroup *group = (GstOptSchedulerGroup *) groups->data; - GSList *elements = group->elements; - GSList *group_links = group->group_links; - - groups = g_slist_next (groups); - - g_print - (" +- group %p: refcount %d, %d elements, %d enabled, flags %d, entry %s, %s\n", - group, group->refcount, group->num_elements, group->num_enabled, - group->flags, - (group->entry ? GST_ELEMENT_NAME (group->entry) : "(none)"), - (group->type == - GST_OPT_SCHEDULER_GROUP_GET ? "get-based" : "loop-based")); - - while (elements) { - GstElement *element = (GstElement *) elements->data; - - elements = g_slist_next (elements); - - g_print (" +- element %s\n", GST_ELEMENT_NAME (element)); - } - while (group_links) { - GstOptSchedulerGroupLink *link = - (GstOptSchedulerGroupLink *) group_links->data; - - group_links = g_slist_next (group_links); - - g_print ("group link %p between %p and %p, count %d\n", - link, link->src, link->sink, link->count); - } - } - } - GST_OPT_UNLOCK (sched); -} - -static void -gst_opt_scheduler_get_property (GObject * object, guint prop_id, - GValue * value, GParamSpec * pspec) -{ - GstOptScheduler *osched; - - g_return_if_fail (GST_IS_OPT_SCHEDULER (object)); - - osched = GST_OPT_SCHEDULER (object); - - switch (prop_id) { - case ARG_ITERATIONS: - g_value_set_int (value, osched->iterations); - break; - case ARG_MAX_RECURSION: - g_value_set_int (value, osched->max_recursion); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -gst_opt_scheduler_set_property (GObject * object, guint prop_id, - const GValue * value, GParamSpec * pspec) -{ - GstOptScheduler *osched; - - g_return_if_fail (GST_IS_OPT_SCHEDULER (object)); - - osched = GST_OPT_SCHEDULER (object); - - switch (prop_id) { - case ARG_ITERATIONS: - osched->iterations = g_value_get_int (value); - break; - case ARG_MAX_RECURSION: - osched->max_recursion = g_value_get_int (value); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} diff --git a/gst/schedulers/gstsimplescheduler.c b/gst/schedulers/gstsimplescheduler.c new file mode 100644 index 0000000000..514a764962 --- /dev/null +++ b/gst/schedulers/gstsimplescheduler.c @@ -0,0 +1,474 @@ +/* GStreamer + * Copyright (C) 2004 Benjamin Otte + * + * gstsimplesimple_scheduler.c: A simple_scheduler as simple as possible + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include "gst/gst_private.h" + +#include + +/*** GstCheckSource ***/ + +typedef struct +{ + GSource source; + GSourceFunc check; + gpointer check_data; +} GstCheckSource; + +static gboolean +gst_check_prepare (GSource * source, gint * timeout) +{ + GstCheckSource *s = (GstCheckSource *) source; + + if (s->check (s->check_data)) { + *timeout = 0; + return TRUE; + } else { + *timeout = -1; + return FALSE; + } +} + +static gboolean +gst_check_check (GSource * source) +{ + GstCheckSource *s = (GstCheckSource *) source; + + if (s->check (s->check_data)) { + return TRUE; + } + return FALSE; +} + +static gboolean +gst_check_dispatch (GSource * source, GSourceFunc callback, gpointer user_data) +{ + if (!callback) { + g_warning ("Check source dispatched without callback\n" + "You must call g_source_set_callback()."); + return FALSE; + } + + return callback (user_data); +} + +static GSourceFuncs gst_check_funcs = { + gst_check_prepare, + gst_check_check, + gst_check_dispatch, + NULL +}; + +GSource * +gst_check_source_new (GSourceFunc check, gpointer check_data) +{ + GSource *source; + + g_return_val_if_fail (check, NULL); + source = g_source_new (&gst_check_funcs, sizeof (GstCheckSource)); + ((GstCheckSource *) source)->check = check; + ((GstCheckSource *) source)->check_data = check_data; + + return source; +} + +/*** the scheduler ***/ + +/* +GST_DEBUG_CATEGORY_STATIC (sched_debug, "simplescheduler", GST_DEBUG_BOLD, + "the simplest possible scheduler"); +#define GST_CAT_DEFAULT sched_debug +*/ + +#define GST_TYPE_SIMPLE_SCHEDULER (gst_simple_scheduler_get_type ()) +#define GST_SIMPLE_SCHEDULER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_SIMPLE_SCHEDULER, GstSimpleScheduler)) +#define GST_IS_SIMPLE_SCHEDULER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_SIMPLE_SCHEDULER)) +#define GST_SIMPLE_SCHEDULER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_SIMPLE_SCHEDULER,GstSimpleSchedulerClass)) +#define GST_IS_SIMPLE_SCHEDULER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_SIMPLE_SCHEDULER)) +#define GST_SIMPLE_SCHEDULER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_SIMPLE_SCHEDULER, GstSimpleSchedulerClass)) + +typedef struct _GstSimpleScheduler GstSimpleScheduler; +typedef struct _GstSimpleSchedulerClass GstSimpleSchedulerClass; + +struct _GstSimpleScheduler +{ + GstScheduler object; + + GHashTable *sources_for_actions; + + gpointer _gst_reserved[GST_PADDING]; +}; + +struct _GstSimpleSchedulerClass +{ + GstSchedulerClass parent_class; + + gpointer _gst_reserved[GST_PADDING]; +}; + + +static void gst_simple_scheduler_class_init (GstSimpleSchedulerClass * klass); +static void gst_simple_scheduler_init (GstSimpleScheduler * sched); +static void gst_simple_scheduler_finalize (GObject * object); + +static void gst_simple_scheduler_add_action (GstScheduler * scheduler, + GstAction * action); +static void gst_simple_scheduler_remove_action (GstScheduler * scheduler, + GstAction * action); +static void gst_simple_scheduler_pad_push (GstScheduler * scheduler, + GstRealPad * pad, GstData * data); +static void gst_simple_scheduler_toggle_active (GstScheduler * scheduler, + GstAction * action); +static void gst_simple_scheduler_update_values (GstScheduler * scheduler, + GstAction * action); + +GstSchedulerClass *parent_class; + +GType +gst_simple_scheduler_get_type (void) +{ + static GType _gst_simple_scheduler_type = 0; + + if (!_gst_simple_scheduler_type) { + static const GTypeInfo simple_scheduler_info = { + sizeof (GstSimpleSchedulerClass), + NULL, + NULL, + (GClassInitFunc) gst_simple_scheduler_class_init, + NULL, + NULL, + sizeof (GstSimpleScheduler), + 0, + (GInstanceInitFunc) gst_simple_scheduler_init, + NULL + }; + + _gst_simple_scheduler_type = + g_type_register_static (GST_TYPE_SCHEDULER, "GstSimpleScheduler", + &simple_scheduler_info, 0); + } + return _gst_simple_scheduler_type; +} + +static void +gst_simple_scheduler_class_init (GstSimpleSchedulerClass * klass) +{ + GObjectClass *object = G_OBJECT_CLASS (klass); + GstSchedulerClass *sched = GST_SCHEDULER_CLASS (klass); + + parent_class = g_type_class_peek_parent (klass); + + object->finalize = gst_simple_scheduler_finalize; + + sched->add_action = gst_simple_scheduler_add_action; + sched->remove_action = gst_simple_scheduler_remove_action; + sched->pad_push = gst_simple_scheduler_pad_push; + sched->toggle_active = gst_simple_scheduler_toggle_active; + sched->update_values = gst_simple_scheduler_update_values; +} + +static void +gst_simple_scheduler_init (GstSimpleScheduler * sched) +{ + sched->sources_for_actions = g_hash_table_new (g_direct_hash, g_direct_equal); +} + +#ifndef G_DISABLE_ASSERT +static void +print_all_actions (gpointer key, gpointer value, gpointer unused) +{ + GstAction *action = key; + gchar *str = gst_action_to_string (action); + + g_print (" action %p: %s --- source %p\n", action, str, value); + g_free (str); +} +#endif + +static void +gst_simple_scheduler_finalize (GObject * object) +{ + GstSimpleScheduler *sched = GST_SIMPLE_SCHEDULER (object); + + /* all actions must have been removed by the scheduler's parent before + * disposing */ +#ifndef G_DISABLE_ASSERT + if (g_hash_table_size (sched->sources_for_actions) != 0) { + g_printerr ("scheduler %p has %u items left:\n", sched, + g_hash_table_size (sched->sources_for_actions)); + g_hash_table_foreach (sched->sources_for_actions, print_all_actions, NULL); + g_assert_not_reached (); + } +#endif + g_hash_table_destroy (sched->sources_for_actions); + + G_OBJECT_CLASS (parent_class)->finalize (object); +} + +static gboolean +release_wakeup_cb (gpointer data) +{ + GstAction *action = data; + + gst_action_wakeup_release (action); + return TRUE; +} + +static gboolean +timeout_elapsed_cb (gpointer data) +{ + GstAction *action = data; + +#ifndef G_DISABLE_CHECKS + GstClockTime time = gst_element_get_time (action->any.element); + + if (action->wait.time > time) { + GST_WARNING ("time on element %s is %" GST_TIME_FORMAT " too short (it's %" + GST_TIME_FORMAT ".\n", GST_ELEMENT_NAME (action->wait.element), + GST_TIME_ARGS (action->wait.time - time), GST_TIME_ARGS (time)); + } +#endif + gst_action_wait_release (action); + return TRUE; +} + +static gboolean +release_fd_cb (GIOChannel * source, GIOCondition condition, gpointer data) +{ + GstAction *action = data; + + gst_action_fd_release (action, condition); + return TRUE; +} + +static gboolean +push_cb (gpointer action) +{ + GstRealPad *pad = gst_action_get_pad (action); + GstData *data; + + GST_LOG ("pushing on %s:%s...", GST_DEBUG_PAD_NAME (pad)); + if (GST_RPAD_PEER (pad)) { + GstRealPad *peer = GST_RPAD_PEER (pad); + + g_assert (peer->sched_private); /* FIXME: relinking in callback? */ + data = ((GList *) peer->sched_private)->data; + peer->sched_private = g_list_remove (peer->sched_private, data); + if (peer->sched_private) + GST_ERROR ("pad %s:%s had multiple (%u) GstData queued.", + GST_DEBUG_PAD_NAME (peer), g_list_length (peer->sched_private) + 1); + } else { + data = GST_DATA (gst_event_new (GST_EVENT_EOS)); + } + gst_action_release_sink_pad (action, data); + + return TRUE; +} + +static void +gst_simple_scheduler_do_push (GstRealPad * pad, GstData * data) +{ + g_assert (GST_PAD_IS_SRC (pad)); + if (!GST_PAD_PEER (pad)) { + g_assert (pad->sched_private == NULL); + gst_data_unref (data); + return; + } + pad->sched_private = g_list_append (pad->sched_private, data); +} + +static gboolean +pull_cb (gpointer action) +{ + GstData *data; + GstRealPad *pad = gst_action_get_pad (action); + GstScheduler *sched; + + GST_LOG ("pulling..."); + gst_object_ref (pad); + sched = gst_pad_get_scheduler (GST_PAD (pad)); + data = gst_action_release_src_pad (action); + if (sched == gst_pad_get_scheduler (GST_PAD (pad))) + gst_simple_scheduler_do_push (pad, data); + gst_object_unref (pad); + + return TRUE; +} + +static gboolean +check_no_data (gpointer action) +{ + return !(gst_action_get_element (action)->sched_private); +} + +static gboolean +check_no_data_srcpad (gpointer action) +{ + return !(gst_action_get_pad (action)->sched_private); +} + +static gboolean +check_data_sinkpad (gpointer action) +{ + GstRealPad *pad = gst_action_get_pad (action); + + if (!GST_RPAD_PEER (pad)) + return TRUE; + return GST_RPAD_PEER (pad)->sched_private != NULL; +} + +static void +gst_simple_scheduler_activate_action (GstScheduler * scheduler, + GstAction * action) +{ + GSource *source; + GstSimpleScheduler *sched = GST_SIMPLE_SCHEDULER (scheduler); + + g_assert (gst_action_is_active (action)); + switch (action->type) { + case GST_ACTION_WAKEUP: + source = gst_check_source_new (check_no_data, action); + g_source_set_priority (source, G_PRIORITY_DEFAULT); + g_source_set_callback (source, release_wakeup_cb, action, NULL); + break; + case GST_ACTION_SRC_PAD: + source = gst_check_source_new (check_no_data_srcpad, action); + g_source_set_callback (source, pull_cb, action, NULL); + break; + case GST_ACTION_SINK_PAD: + source = gst_check_source_new (check_data_sinkpad, action); + g_source_set_callback (source, push_cb, action, NULL); + break; + case GST_ACTION_FD: + { + GIOChannel *channel = g_io_channel_unix_new (action->fd.fd); + + source = g_io_create_watch (channel, action->fd.condition); + g_source_set_callback (source, (GSourceFunc) release_fd_cb, action, NULL); + g_io_channel_unref (channel); + } + break; + case GST_ACTION_WAIT: + { + GstClockTime time = gst_element_get_time (action->any.element); + + GST_LOG_OBJECT (sched, + "time is %" GST_TIME_FORMAT ", waiting for %" GST_TIME_FORMAT "\n", + GST_TIME_ARGS (time), GST_TIME_ARGS (action->wait.time)); + if (action->wait.time > time) { + time = action->wait.time - time; + /* FIXME: make this adjustable by the element's clock */ + } else { + time = 0; + } + source = g_timeout_source_new (time / (GST_SECOND / 1000)); + g_source_set_callback (source, timeout_elapsed_cb, action, NULL); + } + break; + default: + g_assert_not_reached (); + break; + } + /* FIXME: LEAKS */ + GST_DEBUG_OBJECT (sched, "adding source %p for action %s\n", source, + gst_action_to_string (action)); + g_hash_table_insert (sched->sources_for_actions, action, source); + g_source_attach (source, NULL); + g_source_unref (source); /* FIXME: need better refcount management? */ + GST_LOG_OBJECT (sched, "%u active sources now", + g_hash_table_size (sched->sources_for_actions)); +} + +static void +gst_simple_scheduler_add_action (GstScheduler * scheduler, GstAction * action) +{ + if (gst_action_is_active (action)) + gst_simple_scheduler_activate_action (scheduler, action); +} + +static void +gst_simple_scheduler_deactivate_action (GstScheduler * scheduler, + GstAction * action) +{ + GSource *source; + GstSimpleScheduler *sched = GST_SIMPLE_SCHEDULER (scheduler); + + source = g_hash_table_lookup (sched->sources_for_actions, action); + g_assert (source); + g_source_destroy (source); + if (!g_hash_table_remove (sched->sources_for_actions, action)) + g_assert_not_reached (); + GST_DEBUG_OBJECT (sched, "%p removed for action %p, %u active sources now", + source, action, g_hash_table_size (sched->sources_for_actions)); +} + +static void +gst_simple_scheduler_remove_action (GstScheduler * scheduler, + GstAction * action) +{ + if (gst_action_is_active (action)) + gst_simple_scheduler_deactivate_action (scheduler, action); +} + +static void +gst_simple_scheduler_toggle_active (GstScheduler * scheduler, + GstAction * action) +{ + //g_print ("toggling action %s to be %sactive now\n", gst_action_to_string (action), + // gst_action_is_active (action) ? "" : "NOT "); + if (gst_action_is_active (action)) { + gst_simple_scheduler_activate_action (scheduler, action); + } else { + gst_simple_scheduler_deactivate_action (scheduler, action); + } +} + +static void +gst_simple_scheduler_update_values (GstScheduler * scheduler, + GstAction * action) +{ + if (gst_action_is_active (action)) { + gst_simple_scheduler_deactivate_action (scheduler, action); + gst_simple_scheduler_activate_action (scheduler, action); + } +} + +static void +gst_simple_scheduler_pad_push (GstScheduler * scheduler, GstRealPad * pad, + GstData * data) +{ + GST_LOG_OBJECT (scheduler, "pad %s:%s pushed %p", GST_DEBUG_PAD_NAME (pad), + data); + gst_simple_scheduler_do_push (pad, data); +} + +static gboolean +plugin_init (GstPlugin * plugin) +{ + if (!gst_scheduler_register (plugin, "simple", + "A scheduler as simple as possible", GST_TYPE_SIMPLE_SCHEDULER)) + return FALSE; + + return TRUE; +} + +GST_PLUGIN_DEFINE (GST_VERSION_MAJOR, GST_VERSION_MINOR, "gstsimplescheduler", + "A scheduler as simple as possible", plugin_init, VERSION, GST_LICENSE, + GST_PACKAGE, GST_ORIGIN) diff --git a/gst/schedulers/gthread-cothreads.h b/gst/schedulers/gthread-cothreads.h deleted file mode 100644 index 8051cfa509..0000000000 --- a/gst/schedulers/gthread-cothreads.h +++ /dev/null @@ -1,221 +0,0 @@ -/* GStreamer - * Copyright (C) 2003 Benjamin Otte - * - * gthread-cothreads.c: cothreads implemented via GThread for compatibility - * They're probably slooooooow - * - * 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 __GTHREAD_COTHREADS_H__ -#define __GTHREAD_COTHREADS_H__ - -#include -#include - -/* the name of this cothreads */ -#define COTHREADS_TYPE gthread -#define COTHREADS_NAME "gthread" -#define COTHREADS_NAME_CAPITAL "GThread" - -/* - * Theory of operation: - * Instead of using cothreads, GThreads and 1 mutex are used. - * Every thread may only run if it holds the mutex. Otherwise it holds its own - * cond which has to be signaled to wakeit up. - */ - -/* define "cothread", "cothread_context" and "cothread_func" */ -typedef int (*cothread_func) (int, char **); - -typedef struct _cothread cothread; -typedef struct _cothread_context cothread_context; - -struct _cothread_context { - GSList * cothreads; /* contains all threads but main */ - cothread * main; - cothread * current; - GMutex * mutex; - GstThread * gst_thread; /* the GstThread we're running from */ -}; - -struct _cothread { - GThread * thread; - GCond * cond; - cothread_func run; - int argc; - char ** argv; - cothread * creator; - gboolean die; - cothread_context * context; -}; - -#ifndef GTHREAD_COTHREADS_NO_DEFINITIONS - -/* define functions - * Functions starting with "do_" are used by the scheduler. - */ -static void do_cothreads_init (void *unused); -static cothread_context *do_cothread_context_init (void); -static void do_cothread_context_destroy (cothread_context *context); -static cothread * cothread_create (cothread_context *context, - cothread_func func, - int argc, - char **argv); -#define do_cothread_create(new_cothread, context, func, argc, argv) \ - G_STMT_START{ \ - new_cothread = cothread_create ((context), (func), argc, (char**) (argv)); \ - }G_STMT_END -static void do_cothread_switch (cothread *to); -static void do_cothread_destroy (cothread *thread); -#define do_cothread_get_current(context) ((context)->current) -#define do_cothread_get_main(context) ((context)->main) - -static void -do_cothreads_init (void *unused) -{ - if (!g_thread_supported ()) g_thread_init (NULL); -} -static cothread_context * -do_cothread_context_init (void) -{ - cothread_context *ret = g_new0 (cothread_context, 1); - - ret->main = g_new0 (cothread, 1); - ret->main->thread = g_thread_self (); - ret->main->cond = g_cond_new (); - ret->main->die = FALSE; - ret->main->context = ret; - ret->mutex = g_mutex_new (); - ret->cothreads = NULL; - ret->current = ret->main; - ret->gst_thread = gst_thread_get_current(); - g_mutex_lock (ret->mutex); - - return ret; -} -static void -do_cothread_context_destroy (cothread_context *context) -{ - g_assert (g_thread_self() == context->main->thread); - - while (context->cothreads) { - do_cothread_destroy ((cothread *) context->cothreads->data); - } - g_mutex_unlock (context->mutex); - g_mutex_free (context->mutex); - g_cond_free (context->main->cond); - g_free (context->main); - - g_free (context); -} -static void -die (cothread *to_die) { - g_cond_free (to_die->cond); - to_die->context->cothreads = g_slist_remove (to_die->context->cothreads, to_die); - g_free (to_die); - g_thread_exit (to_die); - /* don't unlock the mutex here, the thread waiting for us to die is gonna take it */ -} -static gpointer -run_new_thread (gpointer data) -{ - cothread *self = (cothread *) data; - - g_mutex_lock (self->context->mutex); - g_private_set (gst_thread_current, self->context->gst_thread); - g_cond_signal (self->creator->cond); - g_cond_wait (self->cond, self->context->mutex); - if (self->die) - die (self); - while (TRUE) { - self->run (self->argc, self->argv); - /* compatibility */ - do_cothread_switch (do_cothread_get_main (self->context)); - } - g_assert_not_reached (); - return NULL; -} -static cothread * -cothread_create (cothread_context *context, cothread_func func, int argc, char **argv) -{ - cothread *ret; - - if ((ret = g_new (cothread, 1)) == NULL) { - goto out1; - } - ret->cond = g_cond_new (); - ret->run = func; - ret->argc = argc; - ret->argv = argv; - ret->creator = do_cothread_get_current (context); - ret->die = FALSE; - ret->context = context; - context->cothreads = g_slist_prepend (context->cothreads, ret); - ret->thread = g_thread_create (run_new_thread, ret, TRUE, NULL); - if (ret->thread == NULL) goto out2; - g_cond_wait (do_cothread_get_current (context)->cond, context->mutex); - return ret; - -out2: - context->cothreads = g_slist_remove (context->cothreads, ret); - g_free (ret); -out1: - return NULL; -} - -static void do_cothread_switch (cothread *to) -{ - cothread *self = do_cothread_get_current(to->context); - - if (self != to) { - self->context->current = to; - g_cond_signal (to->cond); - g_cond_wait (self->cond, self->context->mutex); - if (self->die) - die (self); - } -} - -#define do_cothread_setfunc(thread,context,_func,_argc,_argv) G_STMT_START {\ - ((cothread *)(thread))->run = (_func); \ - ((cothread *)(thread))->argc = _argc; \ - ((cothread *)(thread))->argv = _argv; \ -}G_STMT_END - -static void -do_cothread_destroy (cothread *thread) -{ - GThread *join; - cothread_context *context; - g_return_if_fail (thread != thread->context->main); - g_return_if_fail (thread != thread->context->current); - - thread->die = TRUE; - join = thread->thread; - context = thread->context; - g_cond_signal (thread->cond); - g_mutex_unlock (thread->context->mutex); - g_thread_join (join); - /* the mutex was locked by the thread that we joined, no need to lock again */ -} - -#define do_cothread_get_current(context) ((context)->current) -#define do_cothread_get_main(context) ((context)->main) - -#endif /* GTHREAD_COTHREADS_NO_DEFINITIONS */ - -#endif /* __GTHREAD_COTHREADS_H__ */ diff --git a/libs/gst/bytestream/Makefile.am b/libs/gst/bytestream/Makefile.am index 1e61fe9610..0e32e2ddc1 100644 --- a/libs/gst/bytestream/Makefile.am +++ b/libs/gst/bytestream/Makefile.am @@ -1,16 +1,16 @@ -plugin_LTLIBRARIES = libgstbytestream.la -AS_LIBTOOL_LIB = libgstbytestream +lib_LTLIBRARIES = libgstbytestream-@GST_MAJORMINOR@.la +AS_LIBTOOL_LIB = libgstbytestream-@GST_MAJORMINOR@ EXTRA_DIST = $(as_libtool_EXTRA_DIST) noinst_DATA = $(as_libtool_noinst_DATA_files) libgstbytestreamincludedir = $(includedir)/gstreamer-@GST_MAJORMINOR@/gst/bytestream -libgstbytestreaminclude_HEADERS = bytestream.h adapter.h filepad.h +libgstbytestreaminclude_HEADERS = adapter.h filepad.h -libgstbytestream_la_SOURCES = bytestream.c adapter.c filepad.c -libgstbytestream_la_CFLAGS = $(GST_OBJ_CFLAGS) -libgstbytestream_la_LIBS = $(GST_OBJ_LIBS) -libgstbytestream_la_LDFLAGS = $(GST_PLUGIN_LDFLAGS) $(as_libtool_LDFLAGS) +libgstbytestream_@GST_MAJORMINOR@_la_SOURCES = adapter.c filepad.c +libgstbytestream_@GST_MAJORMINOR@_la_CFLAGS = $(GST_OBJ_CFLAGS) +libgstbytestream_@GST_MAJORMINOR@_la_LIBS = $(GST_OBJ_LIBS) +libgstbytestream_@GST_MAJORMINOR@_la_LDFLAGS = $(GST_OBJ_LDFLAGS) $(as_libtool_LDFLAGS) install-data-local: as-libtool-install-data-local diff --git a/libs/gst/bytestream/filepad.c b/libs/gst/bytestream/filepad.c index ee93f36574..cb7a027f21 100644 --- a/libs/gst/bytestream/filepad.c +++ b/libs/gst/bytestream/filepad.c @@ -39,7 +39,8 @@ GST_BOILERPLATE_FULL (GstFilePad, gst_file_pad, GstRealPad, GST_TYPE_REAL_PAD, static void gst_file_pad_dispose (GObject * object); static void gst_file_pad_finalize (GObject * object); - static void gst_file_pad_chain (GstPad * pad, GstData * data); + static void gst_file_pad_chain (GstAction * action, GstRealPad * gst_pad, + GstData * data); static void gst_file_pad_parent_set (GstObject * object, GstObject * parent); @@ -65,10 +66,9 @@ gst_file_pad_init (GstFilePad * pad) { GstRealPad *real = GST_REAL_PAD (pad); - /* must do this for set_chain_function to work */ + /* must do this for set_action_handler to work */ real->direction = GST_PAD_SINK; - - gst_pad_set_chain_function (GST_PAD (real), gst_file_pad_chain); + gst_sink_pad_set_action_handler (GST_PAD (pad), gst_file_pad_chain); pad->adapter = gst_adapter_new (); pad->in_seek = FALSE; @@ -99,7 +99,7 @@ gst_file_pad_finalize (GObject * object) } static void -gst_file_pad_chain (GstPad * gst_pad, GstData * data) +gst_file_pad_chain (GstAction * action, GstRealPad * gst_pad, GstData * data) { GstFilePad *pad = GST_FILE_PAD (gst_pad); gboolean got_value; @@ -162,7 +162,7 @@ gst_file_pad_chain (GstPad * gst_pad, GstData * data) } g_return_if_fail (pad->event_func); - pad->event_func (gst_pad, event); + pad->event_func (GST_PAD (pad), event); } else { if (pad->in_seek) { GST_DEBUG_OBJECT (pad, "discarding buffer %p, we're seeking", data); @@ -183,8 +183,6 @@ gst_file_pad_parent_set (GstObject * object, GstObject * parent) /* FIXME: we can only be added to elements, right? */ element = GST_ELEMENT (parent); - if (element->loopfunc) - g_warning ("attempt to add a GstFilePad to a loopbased element."); if (!GST_FLAG_IS_SET (element, GST_ELEMENT_EVENT_AWARE)) g_warning ("elements using GstFilePad must be event-aware."); diff --git a/plugins/elements/gstfakesink.c b/plugins/elements/gstfakesink.c index c06ecf51e7..6295763676 100644 --- a/plugins/elements/gstfakesink.c +++ b/plugins/elements/gstfakesink.c @@ -113,7 +113,8 @@ static void gst_fakesink_get_property (GObject * object, guint prop_id, static GstElementStateReturn gst_fakesink_change_state (GstElement * element); -static void gst_fakesink_chain (GstPad * pad, GstData * _data); +static void gst_fakesink_chain (GstAction * action, GstRealPad * pad, + GstData * _data); static guint gst_fakesink_signals[LAST_SIGNAL] = { 0 }; @@ -187,8 +188,8 @@ gst_fakesink_init (GstFakeSink * fakesink) pad = gst_pad_new_from_template (gst_static_pad_template_get (&sinktemplate), "sink"); + gst_sink_pad_set_action_handler (pad, GST_DEBUG_FUNCPTR (gst_fakesink_chain)); gst_element_add_pad (GST_ELEMENT (fakesink), pad); - gst_pad_set_chain_function (pad, GST_DEBUG_FUNCPTR (gst_fakesink_chain)); fakesink->silent = FALSE; fakesink->dump = FALSE; @@ -231,7 +232,8 @@ gst_fakesink_request_new_pad (GstElement * element, GstPadTemplate * templ, sinkpad = gst_pad_new_from_template (templ, name); g_free (name); - gst_pad_set_chain_function (sinkpad, GST_DEBUG_FUNCPTR (gst_fakesink_chain)); + gst_sink_pad_set_action_handler (sinkpad, + GST_DEBUG_FUNCPTR (gst_fakesink_chain)); gst_element_add_pad (GST_ELEMENT (fakesink), sinkpad); @@ -309,7 +311,7 @@ gst_fakesink_get_property (GObject * object, guint prop_id, GValue * value, } static void -gst_fakesink_chain (GstPad * pad, GstData * _data) +gst_fakesink_chain (GstAction * action, GstRealPad * pad, GstData * _data) { GstBuffer *buf = GST_BUFFER (_data); GstFakeSink *fakesink; @@ -341,7 +343,7 @@ gst_fakesink_chain (GstPad * pad, GstData * _data) gst_element_set_time (GST_ELEMENT (fakesink), value); } default: - gst_pad_event_default (pad, event); + gst_pad_event_default (GST_PAD (pad), event); break; } return; diff --git a/plugins/elements/gstfakesrc.c b/plugins/elements/gstfakesrc.c index 0b64860e90..6c3b04f24a 100644 --- a/plugins/elements/gstfakesrc.c +++ b/plugins/elements/gstfakesrc.c @@ -64,7 +64,6 @@ enum { ARG_0, ARG_NUM_SOURCES, - ARG_LOOP_BASED, ARG_OUTPUT, ARG_DATA, ARG_SIZETYPE, @@ -179,7 +178,7 @@ GST_BOILERPLATE_FULL (GstFakeSrc, gst_fakesrc, GstElement, GST_TYPE_ELEMENT, static GstPad *gst_fakesrc_request_new_pad (GstElement * element, GstPadTemplate * templ, const gchar * unused); -static void gst_fakesrc_update_functions (GstFakeSrc * src); +static void gst_fakesrc_update_functions (GstFakeSrc * src, GstPad * pad); static void gst_fakesrc_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec); static void gst_fakesrc_get_property (GObject * object, guint prop_id, @@ -188,8 +187,7 @@ static void gst_fakesrc_set_clock (GstElement * element, GstClock * clock); static GstElementStateReturn gst_fakesrc_change_state (GstElement * element); -static GstData *gst_fakesrc_get (GstPad * pad); -static void gst_fakesrc_loop (GstElement * element); +static GstData *gst_fakesrc_get (GstAction * action, GstRealPad * pad); static guint gst_fakesrc_signals[LAST_SIGNAL] = { 0 }; @@ -214,13 +212,9 @@ gst_fakesrc_class_init (GstFakeSrcClass * klass) gobject_class = (GObjectClass *) klass; gstelement_class = (GstElementClass *) klass; - g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_NUM_SOURCES, g_param_spec_int ("num-sources", "num-sources", "Number of sources", 1, G_MAXINT, 1, G_PARAM_READABLE)); - g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_LOOP_BASED, - g_param_spec_boolean ("loop-based", "loop-based", - "Enable loop-based operation", FALSE, G_PARAM_READWRITE)); g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_OUTPUT, g_param_spec_enum ("output", "output", "Output method (currently unused)", GST_TYPE_FAKESRC_OUTPUT, FAKESRC_FIRST_LAST_LOOP, G_PARAM_READWRITE)); @@ -299,11 +293,9 @@ gst_fakesrc_init (GstFakeSrc * fakesrc) pad = gst_pad_new_from_template (gst_static_pad_template_get (&srctemplate), "src"); + gst_fakesrc_update_functions (fakesrc, pad); gst_element_add_pad (GST_ELEMENT (fakesrc), pad); - fakesrc->loop_based = FALSE; - gst_fakesrc_update_functions (fakesrc); - fakesrc->output = FAKESRC_FIRST_LAST_LOOP; fakesrc->segment_start = -1; fakesrc->segment_end = -1; @@ -358,39 +350,14 @@ gst_fakesrc_request_new_pad (GstElement * element, GstPadTemplate * templ, name = g_strdup_printf ("src%d", GST_ELEMENT (fakesrc)->numsrcpads); srcpad = gst_pad_new_from_template (templ, name); + gst_fakesrc_update_functions (fakesrc, srcpad); gst_element_add_pad (GST_ELEMENT (fakesrc), srcpad); - gst_fakesrc_update_functions (fakesrc); g_free (name); return srcpad; } -static const GstFormat * -gst_fakesrc_get_formats (GstPad * pad) -{ - static const GstFormat formats[] = { - GST_FORMAT_DEFAULT, - 0, - }; - - return formats; -} - -static const GstQueryType * -gst_fakesrc_get_query_types (GstPad * pad) -{ - static const GstQueryType types[] = { - GST_QUERY_TOTAL, - GST_QUERY_POSITION, - GST_QUERY_START, - GST_QUERY_SEGMENT_END, - 0, - }; - - return types; -} - static gboolean gst_fakesrc_query (GstPad * pad, GstQueryType type, GstFormat * format, gint64 * value) @@ -416,19 +383,6 @@ gst_fakesrc_query (GstPad * pad, GstQueryType type, return TRUE; } -static const GstEventMask * -gst_fakesrc_get_event_mask (GstPad * pad) -{ - static const GstEventMask masks[] = { - {GST_EVENT_SEEK, GST_SEEK_FLAG_FLUSH}, - {GST_EVENT_SEEK_SEGMENT, GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_SEGMENT_LOOP}, - {GST_EVENT_FLUSH, 0}, - {0, 0}, - }; - - return masks; -} - static gboolean gst_fakesrc_event_handler (GstPad * pad, GstEvent * event) { @@ -463,34 +417,12 @@ gst_fakesrc_event_handler (GstPad * pad, GstEvent * event) } static void -gst_fakesrc_update_functions (GstFakeSrc * src) +gst_fakesrc_update_functions (GstFakeSrc * src, GstPad * pad) { - GList *pads; - - if (src->loop_based) { - gst_element_set_loop_function (GST_ELEMENT (src), - GST_DEBUG_FUNCPTR (gst_fakesrc_loop)); - } else { - gst_element_set_loop_function (GST_ELEMENT (src), NULL); - } - - pads = GST_ELEMENT (src)->pads; - while (pads) { - GstPad *pad = GST_PAD (pads->data); - - if (src->loop_based) { - gst_pad_set_get_function (pad, NULL); - } else { - gst_pad_set_get_function (pad, GST_DEBUG_FUNCPTR (gst_fakesrc_get)); - } - - gst_pad_set_event_function (pad, gst_fakesrc_event_handler); - gst_pad_set_event_mask_function (pad, gst_fakesrc_get_event_mask); - gst_pad_set_query_function (pad, gst_fakesrc_query); - gst_pad_set_query_type_function (pad, gst_fakesrc_get_query_types); - gst_pad_set_formats_function (pad, gst_fakesrc_get_formats); - pads = g_list_next (pads); - } + gst_src_pad_set_action_handler (pad, gst_fakesrc_get); + gst_real_pad_set_initially_active (GST_REAL_PAD (pad), TRUE); + gst_pad_set_event_function (pad, gst_fakesrc_event_handler); + gst_pad_set_query_function (pad, gst_fakesrc_query); } static void @@ -516,10 +448,6 @@ gst_fakesrc_set_property (GObject * object, guint prop_id, const GValue * value, src = GST_FAKESRC (object); switch (prop_id) { - case ARG_LOOP_BASED: - src->loop_based = g_value_get_boolean (value); - gst_fakesrc_update_functions (src); - break; case ARG_OUTPUT: g_warning ("not yet implemented"); break; @@ -596,9 +524,6 @@ gst_fakesrc_get_property (GObject * object, guint prop_id, GValue * value, case ARG_NUM_SOURCES: g_value_set_int (value, GST_ELEMENT (src)->numsrcpads); break; - case ARG_LOOP_BASED: - g_value_set_boolean (value, src->loop_based); - break; case ARG_OUTPUT: g_value_set_enum (value, src->output); break; @@ -791,7 +716,7 @@ gst_fakesrc_create_buffer (GstFakeSrc * src) } static GstData * -gst_fakesrc_get (GstPad * pad) +gst_fakesrc_get (GstAction * action, GstRealPad * pad) { GstFakeSrc *src; GstBuffer *buf; @@ -870,40 +795,6 @@ gst_fakesrc_get (GstPad * pad) return GST_DATA (buf); } -/** - * gst_fakesrc_loop: - * @element: the faksesrc to loop - * - * generate an empty buffer and push it to the next element. - */ -static void -gst_fakesrc_loop (GstElement * element) -{ - GstFakeSrc *src; - const GList *pads; - - g_return_if_fail (element != NULL); - g_return_if_fail (GST_IS_FAKESRC (element)); - - src = GST_FAKESRC (element); - - pads = gst_element_get_pad_list (element); - - while (pads) { - GstPad *pad = GST_PAD (pads->data); - GstData *data; - - data = gst_fakesrc_get (pad); - gst_pad_push (pad, data); - - if (src->eos) { - return; - } - - pads = g_list_next (pads); - } -} - static GstElementStateReturn gst_fakesrc_change_state (GstElement * element) { diff --git a/plugins/elements/gstfakesrc.h b/plugins/elements/gstfakesrc.h index 5214f0bb7c..c317acc75e 100644 --- a/plugins/elements/gstfakesrc.h +++ b/plugins/elements/gstfakesrc.h @@ -76,7 +76,6 @@ typedef struct _GstFakeSrcClass GstFakeSrcClass; struct _GstFakeSrc { GstElement element; - gboolean loop_based; gboolean eos; GstFakeSrcOutputType output; diff --git a/plugins/elements/gstfdsink.c b/plugins/elements/gstfdsink.c index 411dd0a32e..f9ab6fa091 100644 --- a/plugins/elements/gstfdsink.c +++ b/plugins/elements/gstfdsink.c @@ -69,7 +69,8 @@ static void gst_fdsink_set_property (GObject * object, guint prop_id, static void gst_fdsink_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec); -static void gst_fdsink_chain (GstPad * pad, GstData * _data); +static void gst_fdsink_chain (GstAction * action, GstRealPad * pad, + GstData * _data); static void @@ -103,14 +104,14 @@ gst_fdsink_init (GstFdSink * fdsink) fdsink->sinkpad = gst_pad_new_from_template (gst_static_pad_template_get (&sinktemplate), "sink"); + gst_sink_pad_set_action_handler (fdsink->sinkpad, gst_fdsink_chain); gst_element_add_pad (GST_ELEMENT (fdsink), fdsink->sinkpad); - gst_pad_set_chain_function (fdsink->sinkpad, gst_fdsink_chain); fdsink->fd = 1; } static void -gst_fdsink_chain (GstPad * pad, GstData * _data) +gst_fdsink_chain (GstAction * action, GstRealPad * pad, GstData * _data) { GstBuffer *buf = GST_BUFFER (_data); GstFdSink *fdsink; @@ -119,7 +120,7 @@ gst_fdsink_chain (GstPad * pad, GstData * _data) g_return_if_fail (GST_IS_PAD (pad)); g_return_if_fail (buf != NULL); - fdsink = GST_FDSINK (gst_pad_get_parent (pad)); + fdsink = GST_FDSINK (gst_pad_get_parent (GST_PAD (pad))); g_return_if_fail (fdsink->fd >= 0); diff --git a/plugins/elements/gstfdsrc.c b/plugins/elements/gstfdsrc.c index ce1d76a10a..4308d7c3cd 100644 --- a/plugins/elements/gstfdsrc.c +++ b/plugins/elements/gstfdsrc.c @@ -102,7 +102,7 @@ static void gst_fdsrc_get_property (GObject * object, guint prop_id, static GstElementStateReturn gst_fdsrc_change_state (GstElement * element); static gboolean gst_fdsrc_release_locks (GstElement * element); -static GstData *gst_fdsrc_get (GstPad * pad); +static GstData *gst_fdsrc_get (GstAction * action, GstRealPad * pad); static void @@ -164,7 +164,8 @@ gst_fdsrc_init (GstFdSrc * fdsrc) gst_pad_new_from_template (gst_static_pad_template_get (&srctemplate), "src"); - gst_pad_set_get_function (fdsrc->srcpad, gst_fdsrc_get); + gst_src_pad_set_action_handler (fdsrc->srcpad, gst_fdsrc_get); + gst_real_pad_set_initially_active (GST_REAL_PAD (fdsrc->srcpad), TRUE); gst_element_add_pad (GST_ELEMENT (fdsrc), fdsrc->srcpad); fdsrc->fd = 0; @@ -265,7 +266,7 @@ gst_fdsrc_release_locks (GstElement * element) } static GstData * -gst_fdsrc_get (GstPad * pad) +gst_fdsrc_get (GstAction * action, GstRealPad * pad) { GstFdSrc *src; GstBuffer *buf; @@ -277,7 +278,7 @@ gst_fdsrc_get (GstPad * pad) gint retval; #endif - src = GST_FDSRC (gst_pad_get_parent (pad)); + src = GST_FDSRC (gst_pad_get_parent (GST_PAD (pad))); /* create the buffer */ buf = gst_buffer_new_and_alloc (src->blocksize); diff --git a/plugins/elements/gstfilesink.c b/plugins/elements/gstfilesink.c index a575d5a363..6b43163536 100644 --- a/plugins/elements/gstfilesink.c +++ b/plugins/elements/gstfilesink.c @@ -66,29 +66,6 @@ enum ARG_LOCATION }; -static const GstFormat * -gst_filesink_get_formats (GstPad * pad) -{ - static const GstFormat formats[] = { - GST_FORMAT_BYTES, - 0, - }; - - return formats; -} - -static const GstQueryType * -gst_filesink_get_query_types (GstPad * pad) -{ - static const GstQueryType types[] = { - GST_QUERY_TOTAL, - GST_QUERY_POSITION, - 0 - }; - - return types; -} - static void gst_filesink_dispose (GObject * object); static void gst_filesink_set_property (GObject * object, guint prop_id, @@ -99,10 +76,11 @@ static void gst_filesink_get_property (GObject * object, guint prop_id, static gboolean gst_filesink_open_file (GstFileSink * sink); static void gst_filesink_close_file (GstFileSink * sink); -static gboolean gst_filesink_handle_event (GstPad * pad, GstEvent * event); +static gboolean gst_filesink_handle_event (GstRealPad * pad, GstEvent * event); static gboolean gst_filesink_pad_query (GstPad * pad, GstQueryType type, GstFormat * format, gint64 * value); -static void gst_filesink_chain (GstPad * pad, GstData * _data); +static void gst_filesink_chain (GstAction * action, GstRealPad * pad, + GstData * _data); static void gst_filesink_uri_handler_init (gpointer g_iface, gpointer iface_data); @@ -167,14 +145,12 @@ gst_filesink_init (GstFileSink * filesink) pad = gst_pad_new_from_template (gst_static_pad_template_get (&sinktemplate), "sink"); + gst_sink_pad_set_action_handler (pad, gst_filesink_chain); gst_element_add_pad (GST_ELEMENT (filesink), pad); - gst_pad_set_chain_function (pad, gst_filesink_chain); GST_FLAG_SET (GST_ELEMENT (filesink), GST_ELEMENT_EVENT_AWARE); gst_pad_set_query_function (pad, gst_filesink_pad_query); - gst_pad_set_query_type_function (pad, gst_filesink_get_query_types); - gst_pad_set_formats_function (pad, gst_filesink_get_formats); filesink->filename = NULL; filesink->file = NULL; @@ -336,12 +312,12 @@ gst_filesink_pad_query (GstPad * pad, GstQueryType type, /* handle events (search) */ static gboolean -gst_filesink_handle_event (GstPad * pad, GstEvent * event) +gst_filesink_handle_event (GstRealPad * pad, GstEvent * event) { GstEventType type; GstFileSink *filesink; - filesink = GST_FILESINK (gst_pad_get_parent (pad)); + filesink = GST_FILESINK (gst_pad_get_parent (GST_PAD (pad))); if (!(GST_FLAG_IS_SET (filesink, GST_FILESINK_OPEN))) { gst_event_unref (event); @@ -407,7 +383,7 @@ gst_filesink_handle_event (GstPad * pad, GstEvent * event) gst_element_set_eos (GST_ELEMENT (filesink)); break; default: - gst_pad_event_default (pad, event); + gst_pad_event_default (GST_PAD (pad), event); break; } @@ -422,7 +398,7 @@ gst_filesink_handle_event (GstPad * pad, GstEvent * event) * take the buffer from the pad and write to file if it's open */ static void -gst_filesink_chain (GstPad * pad, GstData * _data) +gst_filesink_chain (GstAction * action, GstRealPad * pad, GstData * _data) { GstBuffer *buf = GST_BUFFER (_data); GstFileSink *filesink; @@ -431,7 +407,7 @@ gst_filesink_chain (GstPad * pad, GstData * _data) g_return_if_fail (GST_IS_PAD (pad)); g_return_if_fail (buf != NULL); - filesink = GST_FILESINK (gst_pad_get_parent (pad)); + filesink = GST_FILESINK (gst_pad_get_parent (GST_PAD (pad))); if (GST_IS_EVENT (buf)) { gst_filesink_handle_event (pad, GST_EVENT (buf)); diff --git a/plugins/elements/gstfilesrc.c b/plugins/elements/gstfilesrc.c index 98105cc6ec..e120eac8b8 100644 --- a/plugins/elements/gstfilesrc.c +++ b/plugins/elements/gstfilesrc.c @@ -125,43 +125,6 @@ enum ARG_TOUCH }; -static const GstEventMask * -gst_filesrc_get_event_mask (GstPad * pad) -{ - static const GstEventMask masks[] = { - {GST_EVENT_SEEK, GST_SEEK_METHOD_CUR | - GST_SEEK_METHOD_SET | GST_SEEK_METHOD_END | GST_SEEK_FLAG_FLUSH}, - {GST_EVENT_FLUSH, 0}, - {GST_EVENT_SIZE, 0}, - {0, 0} - }; - - return masks; -} - -static const GstQueryType * -gst_filesrc_get_query_types (GstPad * pad) -{ - static const GstQueryType types[] = { - GST_QUERY_TOTAL, - GST_QUERY_POSITION, - 0 - }; - - return types; -} - -static const GstFormat * -gst_filesrc_get_formats (GstPad * pad) -{ - static const GstFormat formats[] = { - GST_FORMAT_BYTES, - 0, - }; - - return formats; -} - static void gst_filesrc_dispose (GObject * object); static void gst_filesrc_set_property (GObject * object, guint prop_id, @@ -170,7 +133,7 @@ static void gst_filesrc_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec); static gboolean gst_filesrc_check_filesize (GstFileSrc * src); -static GstData *gst_filesrc_get (GstPad * pad); +static GstData *gst_filesrc_get (GstAction * action, GstRealPad * pad); static gboolean gst_filesrc_srcpad_event (GstPad * pad, GstEvent * event); static gboolean gst_filesrc_srcpad_query (GstPad * pad, GstQueryType type, GstFormat * format, gint64 * value); @@ -247,12 +210,10 @@ gst_filesrc_init (GstFileSrc * src) src->srcpad = gst_pad_new_from_template (gst_static_pad_template_get (&srctemplate), "src"); - gst_pad_set_get_function (src->srcpad, gst_filesrc_get); + gst_src_pad_set_action_handler (src->srcpad, gst_filesrc_get); + gst_real_pad_set_initially_active (GST_REAL_PAD (src->srcpad), TRUE); gst_pad_set_event_function (src->srcpad, gst_filesrc_srcpad_event); - gst_pad_set_event_mask_function (src->srcpad, gst_filesrc_get_event_mask); gst_pad_set_query_function (src->srcpad, gst_filesrc_srcpad_query); - gst_pad_set_query_type_function (src->srcpad, gst_filesrc_get_query_types); - gst_pad_set_formats_function (src->srcpad, gst_filesrc_get_formats); gst_element_add_pad (GST_ELEMENT (src), src->srcpad); #ifdef HAVE_MMAP @@ -686,12 +647,12 @@ gst_filesrc_get_read (GstFileSrc * src) } static GstData * -gst_filesrc_get (GstPad * pad) +gst_filesrc_get (GstAction * action, GstRealPad * pad) { GstFileSrc *src; g_return_val_if_fail (pad != NULL, NULL); - src = GST_FILESRC (gst_pad_get_parent (pad)); + src = GST_FILESRC (gst_pad_get_parent (GST_PAD (pad))); g_return_val_if_fail (GST_FLAG_IS_SET (src, GST_FILESRC_OPEN), NULL); /* check for flush */ diff --git a/plugins/elements/gstidentity.c b/plugins/elements/gstidentity.c index 5221b6f41a..244109f3d8 100644 --- a/plugins/elements/gstidentity.c +++ b/plugins/elements/gstidentity.c @@ -31,18 +31,10 @@ #include "gstidentity.h" #include -static GstStaticPadTemplate sinktemplate = GST_STATIC_PAD_TEMPLATE ("sink", - GST_PAD_SINK, - GST_PAD_ALWAYS, - GST_STATIC_CAPS_ANY); - -static GstStaticPadTemplate srctemplate = GST_STATIC_PAD_TEMPLATE ("src", - GST_PAD_SRC, - GST_PAD_ALWAYS, - GST_STATIC_CAPS_ANY); - -GST_DEBUG_CATEGORY_STATIC (gst_identity_debug); +/* +GST_DEBUG_CATEGORY_STATIC (gst_identity_debug, "identity", 0, "identity element"); #define GST_CAT_DEFAULT gst_identity_debug +*/ GstElementDetails gst_identity_details = GST_ELEMENT_DETAILS ("Identity", "Generic", @@ -58,49 +50,32 @@ enum LAST_SIGNAL }; -#define DEFAULT_LOOP_BASED FALSE -#define DEFAULT_SLEEP_TIME 0 -#define DEFAULT_DUPLICATE 1 -#define DEFAULT_ERROR_AFTER -1 -#define DEFAULT_DROP_PROBABILITY 0.0 -#define DEFAULT_DATARATE 0 -#define DEFAULT_SILENT FALSE -#define DEFAULT_DUMP FALSE -#define DEFAULT_SYNC FALSE -#define DEFAULT_CHECK_PERFECT FALSE - enum { ARG_0, - ARG_LOOP_BASED, ARG_SLEEP_TIME, ARG_DUPLICATE, ARG_ERROR_AFTER, ARG_DROP_PROBABILITY, - ARG_DATARATE, ARG_SILENT, ARG_LAST_MESSAGE, ARG_DUMP, - ARG_SYNC, ARG_CHECK_PERFECT }; - -#define _do_init(bla) \ - GST_DEBUG_CATEGORY_INIT (gst_identity_debug, "identity", 0, "identity element"); - -GST_BOILERPLATE_FULL (GstIdentity, gst_identity, GstElement, GST_TYPE_ELEMENT, - _do_init); +GST_BOILERPLATE (GstIdentity, gst_identity, GstElement, GST_TYPE_ELEMENT); static void gst_identity_finalize (GObject * object); static void gst_identity_set_property (GObject * object, guint prop_id, const GValue * value, GParamSpec * pspec); static void gst_identity_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec); -static GstElementStateReturn gst_identity_change_state (GstElement * element); -static void gst_identity_chain (GstPad * pad, GstData * _data); -static void gst_identity_set_clock (GstElement * element, GstClock * clock); +static GstElementStateReturn gst_identity_change_state (GstElement * element); +static void gst_identity_chain (GstAction * action, GstRealPad * pad, + GstData * data); +static void gst_identity_wakeup (GstAction * action, GstElement * element, + gpointer unused); static guint gst_identity_signals[LAST_SIGNAL] = { 0 }; @@ -110,10 +85,6 @@ gst_identity_base_init (gpointer g_class) { GstElementClass *gstelement_class = GST_ELEMENT_CLASS (g_class); - gst_element_class_add_pad_template (gstelement_class, - gst_static_pad_template_get (&srctemplate)); - gst_element_class_add_pad_template (gstelement_class, - gst_static_pad_template_get (&sinktemplate)); gst_element_class_set_details (gstelement_class, &gst_identity_details); } @@ -138,45 +109,36 @@ gst_identity_class_init (GstIdentityClass * klass) gobject_class = G_OBJECT_CLASS (klass); gstelement_class = GST_ELEMENT_CLASS (klass); - g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_LOOP_BASED, - g_param_spec_boolean ("loop-based", "Loop-based", - "Set to TRUE to use loop-based rather than chain-based scheduling", - DEFAULT_LOOP_BASED, G_PARAM_READWRITE)); + gobject_class->get_property = GST_DEBUG_FUNCPTR (gst_identity_get_property); + gobject_class->set_property = GST_DEBUG_FUNCPTR (gst_identity_set_property); + g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_SLEEP_TIME, g_param_spec_uint ("sleep-time", "Sleep time", - "Microseconds to sleep between processing", 0, G_MAXUINT, - DEFAULT_SLEEP_TIME, G_PARAM_READWRITE)); + "Microseconds to sleep between processing", 0, G_MAXUINT, 0, + G_PARAM_READWRITE)); g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_DUPLICATE, g_param_spec_uint ("duplicate", "Duplicate Buffers", - "Push the buffers N times", 0, G_MAXUINT, DEFAULT_DUPLICATE, - G_PARAM_READWRITE)); + "Push the buffers N times", 0, G_MAXUINT, 1, G_PARAM_READWRITE)); g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_ERROR_AFTER, g_param_spec_int ("error_after", "Error After", "Error after N buffers", - G_MININT, G_MAXINT, DEFAULT_ERROR_AFTER, G_PARAM_READWRITE)); + G_MININT, G_MAXINT, -1, G_PARAM_READWRITE)); g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_DROP_PROBABILITY, g_param_spec_float ("drop_probability", "Drop Probability", - "The Probability a buffer is dropped", 0.0, 1.0, - DEFAULT_DROP_PROBABILITY, G_PARAM_READWRITE)); - g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_DATARATE, - g_param_spec_int ("datarate", "Datarate", - "(Re)timestamps buffers with number of bytes per second (0 = inactive)", - 0, G_MAXINT, DEFAULT_DATARATE, G_PARAM_READWRITE)); + "The Probability a buffer is dropped", 0.0, 1.0, 0.0, + G_PARAM_READWRITE)); g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_SILENT, - g_param_spec_boolean ("silent", "silent", "silent", DEFAULT_SILENT, + g_param_spec_boolean ("silent", "silent", "silent", FALSE, G_PARAM_READWRITE)); g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_LAST_MESSAGE, g_param_spec_string ("last-message", "last-message", "last-message", NULL, G_PARAM_READABLE)); g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_DUMP, - g_param_spec_boolean ("dump", "Dump", "Dump buffer contents", - DEFAULT_DUMP, G_PARAM_READWRITE)); - g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_SYNC, - g_param_spec_boolean ("sync", "Synchronize", - "Synchronize to pipeline clock", DEFAULT_SYNC, G_PARAM_READWRITE)); + g_param_spec_boolean ("dump", "Dump", "Dump buffer contents", FALSE, + G_PARAM_READWRITE)); g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_CHECK_PERFECT, g_param_spec_boolean ("check-perfect", "Check For Perfect Stream", - "Verify that the stream is time- and data-contiguous", - DEFAULT_CHECK_PERFECT, G_PARAM_READWRITE)); + "Verify that the stream is time- and data-contiguous", FALSE, + G_PARAM_READWRITE)); gst_identity_signals[SIGNAL_HANDOFF] = g_signal_new ("handoff", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, @@ -185,74 +147,82 @@ gst_identity_class_init (GstIdentityClass * klass) GST_TYPE_BUFFER | G_SIGNAL_TYPE_STATIC_SCOPE); gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_identity_finalize); - gobject_class->set_property = GST_DEBUG_FUNCPTR (gst_identity_set_property); - gobject_class->get_property = GST_DEBUG_FUNCPTR (gst_identity_get_property); - gstelement_class->set_clock = GST_DEBUG_FUNCPTR (gst_identity_set_clock); gstelement_class->change_state = GST_DEBUG_FUNCPTR (gst_identity_change_state); - } static void gst_identity_init (GstIdentity * identity) { - identity->sinkpad = - gst_pad_new_from_template (gst_static_pad_template_get (&sinktemplate), - "sink"); + GST_FLAG_SET (identity, GST_ELEMENT_EVENT_AWARE); + GST_FLAG_SET (identity, GST_ELEMENT_PUSHING); + + identity->sinkpad = gst_pad_new ("sink", GST_PAD_SINK); + gst_sink_pad_set_action_handler (identity->sinkpad, gst_identity_chain); gst_element_add_pad (GST_ELEMENT (identity), identity->sinkpad); - gst_pad_set_chain_function (identity->sinkpad, - GST_DEBUG_FUNCPTR (gst_identity_chain)); gst_pad_set_link_function (identity->sinkpad, gst_pad_proxy_pad_link); gst_pad_set_getcaps_function (identity->sinkpad, gst_pad_proxy_getcaps); - identity->srcpad = - gst_pad_new_from_template (gst_static_pad_template_get (&srctemplate), - "src"); + identity->srcpad = gst_pad_new ("src", GST_PAD_SRC); gst_element_add_pad (GST_ELEMENT (identity), identity->srcpad); gst_pad_set_link_function (identity->srcpad, gst_pad_proxy_pad_link); gst_pad_set_getcaps_function (identity->srcpad, gst_pad_proxy_getcaps); - identity->loop_based = DEFAULT_LOOP_BASED; - identity->sleep_time = DEFAULT_SLEEP_TIME; - identity->duplicate = DEFAULT_DUPLICATE; - identity->error_after = DEFAULT_ERROR_AFTER; - identity->drop_probability = DEFAULT_DROP_PROBABILITY; - identity->datarate = DEFAULT_DATARATE; - identity->silent = DEFAULT_SILENT; - identity->sync = DEFAULT_SYNC; - identity->check_perfect = DEFAULT_CHECK_PERFECT; - identity->dump = DEFAULT_DUMP; + identity->wakeup = gst_element_add_wakeup (GST_ELEMENT (identity), FALSE, + gst_identity_wakeup, NULL); + + identity->loop_based = FALSE; + identity->sleep_time = 0; + identity->duplicate = 1; + identity->error_after = -1; + identity->drop_probability = 0.0; + identity->silent = FALSE; + identity->check_perfect = FALSE; + identity->prev_timestamp = GST_CLOCK_TIME_NONE; + identity->prev_duration = GST_CLOCK_TIME_NONE; + identity->prev_offset_end = -1; + identity->dump = FALSE; identity->last_message = NULL; identity->srccaps = NULL; - - GST_FLAG_SET (identity, GST_ELEMENT_EVENT_AWARE); - GST_FLAG_SET (identity, GST_ELEMENT_WORK_IN_PLACE); - } static void -gst_identity_set_clock (GstElement * element, GstClock * clock) +gst_identity_push (GstIdentity * identity, GstBuffer * buf) { - GstIdentity *identity = GST_IDENTITY (element); + if (!identity->silent) { + g_free (identity->last_message); + identity->last_message = + g_strdup_printf ("chain ******* (%s:%s)i (%d bytes, timestamp: %" + GST_TIME_FORMAT ", duration: %" GST_TIME_FORMAT ", offset: %" + G_GINT64_FORMAT ", offset_end: % " G_GINT64_FORMAT ", flags: %d) %p", + GST_DEBUG_PAD_NAME (identity->sinkpad), GST_BUFFER_SIZE (buf), + GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)), + GST_TIME_ARGS (GST_BUFFER_DURATION (buf)), GST_BUFFER_OFFSET (buf), + GST_BUFFER_OFFSET_END (buf), GST_BUFFER_FLAGS (buf), buf); + g_object_notify (G_OBJECT (identity), "last-message"); + } - gst_object_replace ((GstObject **) & identity->clock, (GstObject *) clock); + gst_object_ref (GST_OBJECT (identity)); + g_signal_emit (G_OBJECT (identity), gst_identity_signals[SIGNAL_HANDOFF], 0, + buf); + + if (identity->sleep_time) + g_usleep (identity->sleep_time); + + /* things may happen in handoff signals... */ + if (GST_ELEMENT_SCHED (identity)) + gst_pad_push (identity->srcpad, GST_DATA (buf)); + gst_object_unref (GST_OBJECT (identity)); } - static void -gst_identity_chain (GstPad * pad, GstData * _data) +gst_identity_chain (GstAction * action, GstRealPad * pad, GstData * data) { - GstBuffer *buf = GST_BUFFER (_data); - GstIdentity *identity; - guint i; - - g_return_if_fail (pad != NULL); - g_return_if_fail (GST_IS_PAD (pad)); - g_return_if_fail (buf != NULL); - - identity = GST_IDENTITY (gst_pad_get_parent (pad)); + GstBuffer *buf; + GstIdentity *identity = GST_IDENTITY (gst_pad_get_parent (GST_PAD (pad))); + buf = GST_BUFFER (data); if (GST_IS_EVENT (buf)) { GstEvent *event = GST_EVENT (buf); @@ -261,11 +231,12 @@ gst_identity_chain (GstPad * pad, GstData * _data) identity->last_message = g_strdup_printf ("chain ******* (%s:%s)E (type: %d) %p", - GST_DEBUG_PAD_NAME (pad), GST_EVENT_TYPE (event), event); + GST_DEBUG_PAD_NAME (identity->sinkpad), GST_EVENT_TYPE (event), + event); g_object_notify (G_OBJECT (identity), "last_message"); } - gst_pad_event_default (pad, event); + gst_pad_event_default (identity->sinkpad, event); return; } @@ -328,75 +299,31 @@ gst_identity_chain (GstPad * pad, GstData * _data) gst_util_dump_mem (GST_BUFFER_DATA (buf), GST_BUFFER_SIZE (buf)); } - for (i = identity->duplicate; i; i--) { - GstClockTime time; - - if (!identity->silent) { - g_free (identity->last_message); - identity->last_message = - g_strdup_printf ("chain ******* (%s:%s)i (%d bytes, timestamp: %" - GST_TIME_FORMAT ", duration: %" GST_TIME_FORMAT ", offset: %" - G_GINT64_FORMAT ", offset_end: % " G_GINT64_FORMAT ", flags: %d) %p", - GST_DEBUG_PAD_NAME (identity->sinkpad), GST_BUFFER_SIZE (buf), - GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (buf)), - GST_TIME_ARGS (GST_BUFFER_DURATION (buf)), GST_BUFFER_OFFSET (buf), - GST_BUFFER_OFFSET_END (buf), GST_BUFFER_FLAGS (buf), buf); - g_object_notify (G_OBJECT (identity), "last-message"); - } - - time = GST_BUFFER_TIMESTAMP (buf); - - if (identity->datarate > 0) { - time = identity->bytes_handled * GST_SECOND / identity->datarate; - - GST_BUFFER_TIMESTAMP (buf) = time; - GST_BUFFER_DURATION (buf) = - GST_BUFFER_SIZE (buf) * GST_SECOND / identity->datarate; - } - - g_signal_emit (G_OBJECT (identity), gst_identity_signals[SIGNAL_HANDOFF], 0, - buf); - - if (i > 1) - gst_buffer_ref (buf); - - if (identity->sync) { - if (identity->clock) { - gst_element_wait (GST_ELEMENT (identity), time); - } - } - - identity->bytes_handled += GST_BUFFER_SIZE (buf); - gst_pad_push (identity->srcpad, GST_DATA (buf)); - - if (identity->sleep_time) - g_usleep (identity->sleep_time); + if (identity->duplicate > 1) { + identity->current = buf; + gst_data_ref (GST_DATA (buf)); + identity->missing = identity->duplicate - 1; + gst_action_set_active (action, FALSE); + gst_action_set_active (identity->wakeup, TRUE); } + gst_identity_push (identity, buf); } static void -gst_identity_loop (GstElement * element) +gst_identity_wakeup (GstAction * action, GstElement * element, gpointer unused) { - GstIdentity *identity; - GstBuffer *buf; + GstIdentity *identity = GST_IDENTITY (element); + GstBuffer *buf = identity->current; - g_return_if_fail (element != NULL); - g_return_if_fail (GST_IS_IDENTITY (element)); - - identity = GST_IDENTITY (element); - - buf = GST_BUFFER (gst_pad_pull (identity->sinkpad)); - if (GST_IS_EVENT (buf)) { - GstEvent *event = GST_EVENT (buf); - - if (GST_EVENT_IS_INTERRUPT (event)) { - gst_event_unref (event); - } else { - gst_pad_event_default (identity->sinkpad, event); - } + g_assert (buf); + if (--identity->missing) { + gst_data_ref (GST_DATA (buf)); } else { - gst_identity_chain (identity->sinkpad, GST_DATA (buf)); + identity->current = NULL; + gst_action_set_active (action, FALSE); + gst_real_pad_set_active (GST_REAL_PAD (identity->sinkpad), TRUE); } + gst_identity_push (identity, buf); } static void @@ -411,17 +338,6 @@ gst_identity_set_property (GObject * object, guint prop_id, identity = GST_IDENTITY (object); switch (prop_id) { - case ARG_LOOP_BASED: - identity->loop_based = g_value_get_boolean (value); - if (identity->loop_based) { - gst_element_set_loop_function (GST_ELEMENT (identity), - gst_identity_loop); - gst_pad_set_chain_function (identity->sinkpad, NULL); - } else { - gst_pad_set_chain_function (identity->sinkpad, gst_identity_chain); - gst_element_set_loop_function (GST_ELEMENT (identity), NULL); - } - break; case ARG_SLEEP_TIME: identity->sleep_time = g_value_get_uint (value); break; @@ -440,12 +356,6 @@ gst_identity_set_property (GObject * object, guint prop_id, case ARG_DROP_PROBABILITY: identity->drop_probability = g_value_get_float (value); break; - case ARG_DATARATE: - identity->datarate = g_value_get_int (value); - break; - case ARG_SYNC: - identity->sync = g_value_get_boolean (value); - break; case ARG_CHECK_PERFECT: identity->check_perfect = g_value_get_boolean (value); break; @@ -467,9 +377,6 @@ gst_identity_get_property (GObject * object, guint prop_id, GValue * value, identity = GST_IDENTITY (object); switch (prop_id) { - case ARG_LOOP_BASED: - g_value_set_boolean (value, identity->loop_based); - break; case ARG_SLEEP_TIME: g_value_set_uint (value, identity->sleep_time); break; @@ -482,9 +389,6 @@ gst_identity_get_property (GObject * object, guint prop_id, GValue * value, case ARG_DROP_PROBABILITY: g_value_set_float (value, identity->drop_probability); break; - case ARG_DATARATE: - g_value_set_int (value, identity->datarate); - break; case ARG_SILENT: g_value_set_boolean (value, identity->silent); break; @@ -494,9 +398,6 @@ gst_identity_get_property (GObject * object, guint prop_id, GValue * value, case ARG_LAST_MESSAGE: g_value_set_string (value, identity->last_message); break; - case ARG_SYNC: - g_value_set_boolean (value, identity->sync); - break; case ARG_CHECK_PERFECT: g_value_set_boolean (value, identity->check_perfect); break; @@ -509,29 +410,14 @@ gst_identity_get_property (GObject * object, guint prop_id, GValue * value, static GstElementStateReturn gst_identity_change_state (GstElement * element) { - GstIdentity *identity; - - g_return_val_if_fail (GST_IS_IDENTITY (element), GST_STATE_FAILURE); - - identity = GST_IDENTITY (element); + GstIdentity *identity = GST_IDENTITY (element); switch (GST_STATE_TRANSITION (element)) { - case GST_STATE_NULL_TO_READY: - break; - case GST_STATE_READY_TO_PAUSED: - identity->bytes_handled = 0; - identity->prev_timestamp = GST_CLOCK_TIME_NONE; - identity->prev_duration = GST_CLOCK_TIME_NONE; - identity->prev_offset_end = -1; - break; - case GST_STATE_PAUSED_TO_PLAYING: - case GST_STATE_PLAYING_TO_PAUSED: - break; case GST_STATE_PAUSED_TO_READY: - g_free (identity->last_message); - identity->last_message = NULL; - break; - case GST_STATE_READY_TO_NULL: + if (identity->current) { + gst_data_unref (GST_DATA (identity->current)); + identity->current = NULL; + } break; default: break; diff --git a/plugins/elements/gstidentity.h b/plugins/elements/gstidentity.h index 00203beed5..c81cd0b12a 100644 --- a/plugins/elements/gstidentity.h +++ b/plugins/elements/gstidentity.h @@ -47,27 +47,27 @@ typedef struct _GstIdentityClass GstIdentityClass; struct _GstIdentity { GstElement element; - GstPad *sinkpad; - GstPad *srcpad; + GstPad * sinkpad; + GstPad * srcpad; + + GstAction * wakeup; gboolean loop_based; guint duplicate; gint error_after; gfloat drop_probability; - gint datarate; guint sleep_time; gboolean silent; gboolean dump; - gboolean sync; gboolean check_perfect; GstClockTime prev_timestamp; GstClockTime prev_duration; guint64 prev_offset_end; - GstClock *clock; gchar *last_message; GstCaps *srccaps; - guint64 bytes_handled; + GstBuffer * current; + guint missing; }; struct _GstIdentityClass { diff --git a/plugins/elements/gstqueue.c b/plugins/elements/gstqueue.c index 1e1b803ad0..a6c13f87b3 100644 --- a/plugins/elements/gstqueue.c +++ b/plugins/elements/gstqueue.c @@ -2,6 +2,7 @@ * Copyright (C) 1999,2000 Erik Walthinsen * 2000 Wim Taymans * 2003 Colin Walters + * 2004 Benjamin Otte * * gstqueue.c: * @@ -29,41 +30,17 @@ #include "gstevent.h" #include "gstinfo.h" #include "gsterror.h" +#include "gstaction.h" -static GstStaticPadTemplate sinktemplate = GST_STATIC_PAD_TEMPLATE ("sink", - GST_PAD_SINK, - GST_PAD_ALWAYS, - GST_STATIC_CAPS_ANY); - -static GstStaticPadTemplate srctemplate = GST_STATIC_PAD_TEMPLATE ("src", - GST_PAD_SRC, - GST_PAD_ALWAYS, - GST_STATIC_CAPS_ANY); - -GST_DEBUG_CATEGORY_STATIC (queue_dataflow); -#define GST_CAT_DEFAULT (queue_dataflow) - -#define STATUS(queue, msg) \ - GST_CAT_LOG_OBJECT (queue_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_threshold.buffers, \ - queue->max_size.buffers, \ - queue->cur_level.bytes, \ - queue->min_threshold.bytes, \ - queue->max_size.bytes, \ - queue->cur_level.time, \ - queue->min_threshold.time, \ - queue->max_size.time, \ - queue->queue->length) - +/* +GST_DEBUG_CATEGORY_STATIC (queue_dataflow, "queue_dataflow", 0, + "dataflow inside the queue element"); +#define GST_CAT_DEFAULT queue_dataflow +*/ static GstElementDetails gst_queue_details = GST_ELEMENT_DETAILS ("Queue", "Generic", "Simple data queue", - "Erik Walthinsen "); + "Erik Walthinsen , " "Benjamin Otte "); /* Queue signals and args */ @@ -89,30 +66,13 @@ enum ARG_MIN_THRESHOLD_BUFFERS, ARG_MIN_THRESHOLD_BYTES, ARG_MIN_THRESHOLD_TIME, + ARG_MAX_THRESHOLD_BUFFERS, + ARG_MAX_THRESHOLD_BYTES, + ARG_MAX_THRESHOLD_TIME, ARG_LEAKY, - ARG_MAY_DEADLOCK, - ARG_BLOCK_TIMEOUT - /* FILL ME */ + /* FILL ME */ }; -#define GST_QUEUE_MUTEX_LOCK G_STMT_START { \ - GST_CAT_LOG_OBJECT (queue_dataflow, queue, \ - "locking qlock from thread %p", \ - g_thread_self ()); \ - g_mutex_lock (queue->qlock); \ - GST_CAT_LOG_OBJECT (queue_dataflow, queue, \ - "locked qlock from thread %p", \ - g_thread_self ()); \ -} G_STMT_END - -#define GST_QUEUE_MUTEX_UNLOCK G_STMT_START { \ - GST_CAT_LOG_OBJECT (queue_dataflow, queue, \ - "unlocking qlock from thread %p", \ - g_thread_self ()); \ - g_mutex_unlock (queue->qlock); \ -} G_STMT_END - - typedef struct _GstQueueEventResponse { GstEvent *event; @@ -130,21 +90,17 @@ static void gst_queue_set_property (GObject * object, static void gst_queue_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec); -static void gst_queue_chain (GstPad * pad, GstData * data); -static GstData *gst_queue_get (GstPad * pad); +static GstData *gst_queue_release_srcpad (GstAction * action, GstRealPad * pad); +static void gst_queue_release_sinkpad (GstAction * action, GstRealPad * pad, + GstData * data); static gboolean gst_queue_handle_src_event (GstPad * pad, GstEvent * event); -static gboolean gst_queue_handle_src_query (GstPad * pad, - GstQueryType type, GstFormat * fmt, gint64 * value); static GstCaps *gst_queue_getcaps (GstPad * pad); -static GstPadLinkReturn -gst_queue_link_sink (GstPad * pad, const GstCaps * caps); -static GstPadLinkReturn gst_queue_link_src (GstPad * pad, const GstCaps * caps); +static GstPadLinkReturn gst_queue_link (GstPad * pad, const GstCaps * caps); static void gst_queue_locked_flush (GstQueue * queue); 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 ()) @@ -190,8 +146,6 @@ gst_queue_get_type (void) queue_type = g_type_register_static (GST_TYPE_ELEMENT, "GstQueue", &queue_info, 0); - GST_DEBUG_CATEGORY_INIT (queue_dataflow, "queue_dataflow", 0, - "dataflow inside the queue element"); } return queue_type; @@ -202,10 +156,6 @@ gst_queue_base_init (GstQueueClass * klass) { GstElementClass *gstelement_class = GST_ELEMENT_CLASS (klass); - gst_element_class_add_pad_template (gstelement_class, - gst_static_pad_template_get (&srctemplate)); - gst_element_class_add_pad_template (gstelement_class, - gst_static_pad_template_get (&sinktemplate)); gst_element_class_set_details (gstelement_class, &gst_queue_details); } @@ -231,6 +181,11 @@ gst_queue_class_init (GstQueueClass * klass) G_STRUCT_OFFSET (GstQueueClass, overrun), NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); + /* set several parent class virtual functions */ + gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_queue_finalize); + 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)", @@ -271,62 +226,48 @@ gst_queue_class_init (GstQueueClass * klass) "Min. amount of data in the queue to allow reading (in ns, 0=disable)", 0, G_MAXUINT64, 0, G_PARAM_READWRITE)); + g_object_class_install_property (gobject_class, ARG_MAX_THRESHOLD_BYTES, + g_param_spec_uint ("max-threshold-bytes", "Max. threshold (kB)", + "Max. amount of data in the queue to allow writing (bytes, 0=disable)", + 0, G_MAXUINT, 0, G_PARAM_READWRITE)); + g_object_class_install_property (gobject_class, ARG_MAX_THRESHOLD_BUFFERS, + g_param_spec_uint ("max-threshold-buffers", "Max. threshold (buffers)", + "Max. number of buffers in the queue to allow writing (0=disable)", + 0, G_MAXUINT, 0, G_PARAM_READWRITE)); + g_object_class_install_property (gobject_class, ARG_MAX_THRESHOLD_TIME, + g_param_spec_uint64 ("max-threshold-time", "Max. threshold (ns)", + "Max. amount of data in the queue to allow writing (in ns, 0=disable)", + 0, G_MAXUINT64, 0, G_PARAM_READWRITE)); + 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)); - - /* set several parent class virtual functions */ - gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_queue_finalize); - gobject_class->set_property = GST_DEBUG_FUNCPTR (gst_queue_set_property); - gobject_class->get_property = GST_DEBUG_FUNCPTR (gst_queue_get_property); 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 (GstQueue * queue) { - /* scheduling on this kind of element is, well, interesting */ - GST_FLAG_SET (queue, GST_ELEMENT_DECOUPLED); GST_FLAG_SET (queue, GST_ELEMENT_EVENT_AWARE); - queue->sinkpad = - gst_pad_new_from_template (gst_static_pad_template_get (&sinktemplate), - "sink"); - gst_pad_set_chain_function (queue->sinkpad, - GST_DEBUG_FUNCPTR (gst_queue_chain)); + queue->sinkpad = gst_pad_new ("sink", GST_PAD_SINK); + gst_sink_pad_set_action_handler (queue->sinkpad, gst_queue_release_sinkpad); gst_element_add_pad (GST_ELEMENT (queue), queue->sinkpad); gst_pad_set_link_function (queue->sinkpad, - GST_DEBUG_FUNCPTR (gst_queue_link_sink)); + GST_DEBUG_FUNCPTR (gst_queue_link)); gst_pad_set_getcaps_function (queue->sinkpad, GST_DEBUG_FUNCPTR (gst_queue_getcaps)); - gst_pad_set_active (queue->sinkpad, TRUE); - queue->srcpad = - gst_pad_new_from_template (gst_static_pad_template_get (&srctemplate), - "src"); - gst_pad_set_get_function (queue->srcpad, GST_DEBUG_FUNCPTR (gst_queue_get)); + queue->srcpad = gst_pad_new ("src", GST_PAD_SRC); + gst_src_pad_set_action_handler (queue->srcpad, gst_queue_release_srcpad); gst_element_add_pad (GST_ELEMENT (queue), queue->srcpad); - gst_pad_set_link_function (queue->srcpad, - GST_DEBUG_FUNCPTR (gst_queue_link_src)); + gst_pad_set_link_function (queue->srcpad, GST_DEBUG_FUNCPTR (gst_queue_link)); gst_pad_set_getcaps_function (queue->srcpad, GST_DEBUG_FUNCPTR (gst_queue_getcaps)); gst_pad_set_event_function (queue->srcpad, GST_DEBUG_FUNCPTR (gst_queue_handle_src_event)); - gst_pad_set_query_function (queue->srcpad, - GST_DEBUG_FUNCPTR (gst_queue_handle_src_query)); - gst_pad_set_active (queue->srcpad, TRUE); queue->cur_level.buffers = 0; /* no content */ queue->cur_level.bytes = 0; /* no content */ @@ -337,25 +278,17 @@ gst_queue_init (GstQueue * queue) queue->min_threshold.buffers = 0; /* no threshold */ queue->min_threshold.bytes = 0; /* no threshold */ queue->min_threshold.time = 0; /* no threshold */ + queue->max_threshold.buffers = 0; /* no threshold */ + queue->max_threshold.bytes = 0; /* no threshold */ + queue->max_threshold.time = 0; /* no threshold */ queue->leaky = GST_QUEUE_NO_LEAK; - queue->may_deadlock = TRUE; - queue->block_timeout = GST_CLOCK_TIME_NONE; - queue->interrupt = FALSE; - queue->flush = FALSE; queue->qlock = g_mutex_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->event_lock = g_mutex_new (); queue->queue = g_queue_new (); GST_CAT_DEBUG_OBJECT (GST_CAT_THREAD, queue, "initialized queue's not_empty & not_full conditions"); - - GST_FLAG_SET (queue, GST_ELEMENT_WORK_IN_PLACE); } /* called only once, as opposed to dispose */ @@ -373,19 +306,6 @@ gst_queue_finalize (GObject * object) } 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); - g_mutex_lock (queue->event_lock); - while (!g_queue_is_empty (queue->events)) { - GstQueueEventResponse *er = g_queue_pop_head (queue->events); - - gst_event_unref (er->event); - g_free (er); - } - g_mutex_unlock (queue->event_lock); - g_mutex_free (queue->event_lock); - g_queue_free (queue->events); if (G_OBJECT_CLASS (parent_class)->finalize) G_OBJECT_CLASS (parent_class)->finalize (object); @@ -398,7 +318,7 @@ gst_queue_getcaps (GstPad * pad) queue = GST_QUEUE (gst_pad_get_parent (pad)); - if (pad == queue->srcpad && queue->cur_level.bytes > 0) { + if (queue->cur_level.bytes > 0) { return gst_caps_copy (queue->negotiated_caps); } @@ -406,53 +326,11 @@ gst_queue_getcaps (GstPad * pad) } static GstPadLinkReturn -gst_queue_link_sink (GstPad * pad, const GstCaps * caps) +gst_queue_link (GstPad * pad, const GstCaps * caps) { GstQueue *queue; - GstPadLinkReturn link_ret; - - queue = GST_QUEUE (gst_pad_get_parent (pad)); - - if (queue->cur_level.bytes > 0) { - if (gst_caps_is_equal (caps, queue->negotiated_caps)) { - return GST_PAD_LINK_OK; - } else if (GST_STATE (queue) != GST_STATE_PLAYING) { - return GST_PAD_LINK_DELAYED; - } - - /* Wait until the queue is empty before attempting the pad - negotiation. */ - GST_QUEUE_MUTEX_LOCK; - - STATUS (queue, "waiting for queue to get empty"); - while (queue->cur_level.bytes > 0) { - g_cond_wait (queue->item_del, queue->qlock); - if (queue->interrupt) { - GST_QUEUE_MUTEX_UNLOCK; - return GST_PAD_LINK_DELAYED; - } - } - STATUS (queue, "queue is now empty"); - - GST_QUEUE_MUTEX_UNLOCK; - } - - link_ret = gst_pad_proxy_pad_link (pad, caps); - - if (GST_PAD_LINK_SUCCESSFUL (link_ret)) { - /* we store an extra copy of the negotiated caps, just in case - * the pads become unnegotiated while we have buffers */ - gst_caps_replace (&queue->negotiated_caps, gst_caps_copy (caps)); - } - - return link_ret; -} - -static GstPadLinkReturn -gst_queue_link_src (GstPad * pad, const GstCaps * caps) -{ - GstQueue *queue; - GstPadLinkReturn link_ret; + GstPadLinkReturn ret; + GstPad *otherpad; queue = GST_QUEUE (gst_pad_get_parent (pad)); @@ -463,105 +341,140 @@ gst_queue_link_src (GstPad * pad, const GstCaps * caps) return GST_PAD_LINK_REFUSED; } - link_ret = gst_pad_proxy_pad_link (pad, caps); + otherpad = (pad == queue->srcpad) ? queue->sinkpad : queue->srcpad; + ret = gst_pad_try_set_caps (otherpad, caps); - if (GST_PAD_LINK_SUCCESSFUL (link_ret)) { + if (GST_PAD_LINK_SUCCESSFUL (ret)) { /* we store an extra copy of the negotiated caps, just in case * the pads become unnegotiated while we have buffers */ gst_caps_replace (&queue->negotiated_caps, gst_caps_copy (caps)); } - return link_ret; + return ret; } static void gst_queue_locked_flush (GstQueue * queue) { - GST_CAT_LOG_OBJECT (queue_dataflow, queue, "Flushing contents..."); + GstData *data; - while (!g_queue_is_empty (queue->queue)) { - GstData *data = g_queue_pop_head (queue->queue); - - /* First loose the reference we added when putting that data in the queue */ - gst_data_unref (data); - /* Then loose another reference because we are supposed to destroy that - data when flushing */ + while ((data = g_queue_pop_head (queue->queue))) { gst_data_unref (data); } - queue->timeval = NULL; + g_assert (g_queue_is_empty (queue->queue)); 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; - - /* we deleted something... */ - g_cond_signal (queue->item_del); + GST_DEBUG_OBJECT (queue, "flushed"); + /* FIXME: wakeup sinkpad here? */ } +/* holds lock */ static void -gst_queue_handle_pending_events (GstQueue * queue) +gst_queue_add_data (GstQueue * queue, GstData * data) { - /* check for events to send upstream */ - /* g_queue_get_length is glib 2.4, so don't depend on it yet, use ->length */ - GST_CAT_DEBUG_OBJECT (queue_dataflow, queue, - "handling pending events, events queue of size %d", - queue->events->length); - g_mutex_lock (queue->event_lock); - while (!g_queue_is_empty (queue->events)) { - GstQueueEventResponse *er; - gboolean need_response; + g_queue_push_tail (queue->queue, data); - er = g_queue_pop_head (queue->events); - - GST_CAT_DEBUG_OBJECT (queue_dataflow, queue, - "sending event %p (%d) from event response %p upstream", - er->event, GST_EVENT_TYPE (er->event), er); - if (er->handled) { - /* change this to an assert when this file gets reviewed properly. */ - GST_ELEMENT_ERROR (queue, CORE, EVENT, (NULL), - ("already handled event %p (%d) from event response %p upstream", - er->event, GST_EVENT_TYPE (er->event), er)); - break; - } - g_mutex_unlock (queue->event_lock); - - need_response = - GST_DATA_FLAG_IS_SET (GST_DATA (er->event), - GST_EVENT_COMMON_FLAG_NEED_RESPONSE); - er->ret = gst_pad_event_default (queue->srcpad, er->event); - if (need_response) { - er->handled = TRUE; - g_cond_signal (queue->event_done); - } else { - g_free (er); - } - g_mutex_lock (queue->event_lock); - GST_CAT_DEBUG_OBJECT (queue_dataflow, queue, "event sent"); + queue->cur_level.items++; + 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); } - g_mutex_unlock (queue->event_lock); +} + +/* holds lock */ +static GstData * +gst_queue_remove_data (GstQueue * queue, GstData * data) +{ + if (data == NULL) { + data = g_queue_pop_head (queue->queue); + } else { + g_queue_remove (queue->queue, data); + } + if (!data) { + return NULL; + } + queue->cur_level.items--; + 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); + } + return data; +} + +/* check if one of the sizes is smaller than the current size */ +static gboolean +gst_queue_is_smaller (GstQueue * queue, GstQueueSize * size) +{ + if (size->items > 0 && size->items < queue->cur_level.items) + return TRUE; + if (size->buffers > 0 && size->buffers < queue->cur_level.buffers) + return TRUE; + if (size->bytes > 0 && size->bytes < queue->cur_level.bytes) + return TRUE; + if (size->time > 0 && size->time < queue->cur_level.time) + return TRUE; + return FALSE; +} + +/* check if one of the sizes is bigger than the current size */ +static gboolean +gst_queue_is_bigger (GstQueue * queue, GstQueueSize * size) +{ + if (size->items > 0 && size->items >= queue->cur_level.items) + return TRUE; + if (size->buffers > 0 && size->buffers >= queue->cur_level.buffers) + return TRUE; + if (size->bytes > 0 && size->bytes >= queue->cur_level.bytes) + return TRUE; + if (size->time > 0 && size->time >= queue->cur_level.time) + return TRUE; + return FALSE; +} + +#define STATUS(queue, msg) \ + GST_LOG_OBJECT (queue, \ + msg ": %u of %u-%u buffers, %u of %u-%u " \ + "bytes, %" G_GUINT64_FORMAT " of %" G_GUINT64_FORMAT \ + "-%" G_GUINT64_FORMAT " ns, %u elements", \ + queue->cur_level.buffers, \ + queue->min_threshold.buffers, \ + queue->max_size.buffers, \ + queue->cur_level.bytes, \ + queue->min_threshold.bytes, \ + queue->max_size.bytes, \ + queue->cur_level.time, \ + queue->min_threshold.time, \ + queue->max_size.time, \ + queue->queue->length) + +static gint +is_buffer (gconstpointer buf, gconstpointer unused) +{ + if (GST_IS_BUFFER (buf)); + return 0; + return 1; +} + +static gint +is_buffer_last (gconstpointer buf, gconstpointer datap) +{ + GstData **data = (GstData **) datap; + + if (GST_IS_BUFFER (buf)); + *data = (GstData *) buf; + return 1; } static void -gst_queue_chain (GstPad * pad, GstData * data) +gst_queue_release_sinkpad (GstAction * action, GstRealPad * pad, GstData * data) { - GstQueue *queue; - - g_return_if_fail (pad != NULL); - g_return_if_fail (GST_IS_PAD (pad)); - g_return_if_fail (data != NULL); - - queue = GST_QUEUE (GST_OBJECT_PARENT (pad)); - -restart: - /* we have to lock the queue since we span threads */ - GST_QUEUE_MUTEX_LOCK; - - gst_queue_handle_pending_events (queue); - - /* assume don't need to flush this buffer when the queue is filled */ - queue->flush = FALSE; + gboolean ret = TRUE; + GstQueue *queue = GST_QUEUE (gst_pad_get_parent (GST_PAD (pad))); if (GST_IS_EVENT (data)) { switch (GST_EVENT_TYPE (data)) { @@ -572,485 +485,171 @@ restart: break; case GST_EVENT_EOS: STATUS (queue, "received EOS"); + queue->got_eos = TRUE; + ret = FALSE; break; default: /* we put the event in the queue, we don't have to act ourselves */ - GST_CAT_LOG_OBJECT (queue_dataflow, queue, + GST_LOG_OBJECT (queue, "adding event %p of type %d", data, GST_EVENT_TYPE (data)); break; } } - if (GST_IS_BUFFER (data)) - GST_CAT_LOG_OBJECT (queue_dataflow, queue, - "adding buffer %p of size %d and time %" GST_TIME_FORMAT, - data, GST_BUFFER_SIZE (data), - GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (data))); + gst_queue_add_data (queue, data); + + if (GST_IS_BUFFER (data)) { + GST_LOG_OBJECT (queue, + "adding buffer %p of size %d", data, GST_BUFFER_SIZE (data)); + } else { + GST_LOG_OBJECT (queue, + "adding event %p of type %d", data, GST_EVENT_TYPE (data)); + } + STATUS (queue, "+ level"); /* 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))) { - GST_QUEUE_MUTEX_UNLOCK; + * We always handle events and they don't count in our statistics. + * We still check, it could be someone changed properties */ + if (gst_queue_is_smaller (queue, &queue->max_size)) { g_signal_emit (G_OBJECT (queue), gst_queue_signals[SIGNAL_OVERRUN], 0); - GST_QUEUE_MUTEX_LOCK; + /* FIXME: need to recheck no buffers got processed? */ /* how are we going to make space for this buffer? */ switch (queue->leaky) { - /* leak current buffer */ + /* leak buffers from end of queue */ case GST_QUEUE_LEAK_UPSTREAM: - GST_CAT_DEBUG_OBJECT (queue_dataflow, queue, - "queue is full, leaking buffer on upstream end"); - /* now we can clean up and exit right away */ - GST_QUEUE_MUTEX_UNLOCK; - goto out_unref; + do { + GstData *leak; - /* 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; + g_queue_find_custom (queue->queue, &leak, is_buffer_last); + g_assert (leak); - GST_CAT_DEBUG_OBJECT (queue_dataflow, queue, - "queue is full, leaking buffer on downstream end"); + GST_DEBUG_OBJECT (queue, + "queue is full, leaking buffer %p on upstream end", leak); + gst_queue_remove_data (queue, leak); + gst_data_unref (leak); + } while (gst_queue_is_smaller (queue, &queue->max_size)); - for (item = queue->queue->head; item != NULL; item = item->next) { - if (GST_IS_BUFFER (item->data)) { - leak = item->data; - break; - } - } + case GST_QUEUE_LEAK_DOWNSTREAM: + /* leak buffers from front of the queue */ + do { + GList *item = g_queue_find_custom (queue->queue, NULL, is_buffer); + GstData *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); + g_assert (item); + leak = item->data; - /* 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--; + GST_DEBUG_OBJECT (queue, + "queue is full, leaking buffer %p on downstream end", leak); + gst_queue_remove_data (queue, leak); + gst_data_unref (leak); + } while (gst_queue_is_smaller (queue, &queue->max_size)); - /* 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; - } default: g_warning ("Unknown leaky type, using default"); /* fall-through */ - /* 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) { - GstScheduler *sched; - - GST_CAT_DEBUG_OBJECT (queue_dataflow, queue, "interrupted"); - sched = gst_pad_get_scheduler (queue->sinkpad); - if (!sched || gst_scheduler_interrupt (sched, GST_ELEMENT (queue))) { - goto ignore_interrupt; - } - GST_QUEUE_MUTEX_UNLOCK; - /* 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 (queue_dataflow, queue, - "not adding pending buffer after flush"); - goto out_unref; - } - GST_CAT_DEBUG_OBJECT (queue_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) { - GST_QUEUE_MUTEX_UNLOCK; - gst_data_unref (data); - GST_ELEMENT_ERROR (queue, CORE, THREAD, (NULL), - ("deadlock found, shutting down source pad elements")); - /* 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 (queue_dataflow, queue, - "%s: waiting for the app to restart " - "source pad elements", GST_ELEMENT_NAME (queue)); - } - } - - ignore_interrupt: - /* 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); - - if (!queue->interrupt) { - STATUS (queue, - "waiting for item_del signal from thread using qlock"); - g_cond_wait (queue->item_del, queue->qlock); - STATUS (queue, "received item_del signal from thread using qlock"); - } else { - GST_CAT_DEBUG_OBJECT (queue_dataflow, queue, - "Not waiting, just adding buffer, after interrupt (bad!)"); - break; - } - } - - STATUS (queue, "post-full wait"); - GST_QUEUE_MUTEX_UNLOCK; - g_signal_emit (G_OBJECT (queue), gst_queue_signals[SIGNAL_RUNNING], 0); - GST_QUEUE_MUTEX_LOCK; - break; + /* don't leak. Instead, wait for space to be available */ + /* wake up other pad in any case */ + gst_real_pad_set_active (GST_REAL_PAD (queue->srcpad), TRUE); + gst_real_pad_set_active (GST_REAL_PAD (queue->sinkpad), FALSE); } } - /* 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); - - /* 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); + if (gst_queue_is_smaller (queue, &queue->max_threshold) || + queue->max_threshold.items + queue->max_threshold.buffers + + queue->max_threshold.bytes + queue->max_threshold.time == 0) { + gst_real_pad_set_active (GST_REAL_PAD (queue->srcpad), TRUE); } - STATUS (queue, "+ level"); - - GST_CAT_LOG_OBJECT (queue_dataflow, queue, "signalling item_add"); - g_cond_signal (queue->item_add); - GST_QUEUE_MUTEX_UNLOCK; - - return; - -out_unref: - gst_data_unref (data); - return; + if (!ret) + gst_real_pad_set_active (GST_REAL_PAD (queue->sinkpad), FALSE); } static GstData * -gst_queue_get (GstPad * pad) +gst_queue_release_srcpad (GstAction * action, GstRealPad * pad) { - GstQueue *queue; GstData *data; - - g_return_val_if_fail (pad != NULL, NULL); - g_return_val_if_fail (GST_IS_PAD (pad), NULL); - - queue = GST_QUEUE (gst_pad_get_parent (pad)); - -restart: - /* have to lock for thread-safety */ - GST_QUEUE_MUTEX_LOCK; - - if (queue->queue->length == 0 || - (queue->min_threshold.buffers > 0 && - queue->cur_level.buffers < queue->min_threshold.buffers) || - (queue->min_threshold.bytes > 0 && - queue->cur_level.bytes < queue->min_threshold.bytes) || - (queue->min_threshold.time > 0 && - queue->cur_level.time < queue->min_threshold.time)) { - GST_QUEUE_MUTEX_UNLOCK; - g_signal_emit (G_OBJECT (queue), gst_queue_signals[SIGNAL_UNDERRUN], 0); - GST_QUEUE_MUTEX_LOCK; - - STATUS (queue, "pre-empty wait"); - while (queue->queue->length == 0 || - (queue->min_threshold.buffers > 0 && - queue->cur_level.buffers < queue->min_threshold.buffers) || - (queue->min_threshold.bytes > 0 && - queue->cur_level.bytes < queue->min_threshold.bytes) || - (queue->min_threshold.time > 0 && - queue->cur_level.time < queue->min_threshold.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) { - GstScheduler *sched; - - GST_CAT_DEBUG_OBJECT (queue_dataflow, queue, "interrupted"); - GST_QUEUE_MUTEX_UNLOCK; - sched = gst_pad_get_scheduler (queue->srcpad); - if (!sched || gst_scheduler_interrupt (sched, 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) { - GST_QUEUE_MUTEX_UNLOCK; - GST_ELEMENT_ERROR (queue, CORE, THREAD, (NULL), - ("deadlock found, shutting down sink pad elements")); - goto restart; - } else { - GST_CAT_WARNING_OBJECT (queue_dataflow, queue, - "%s: waiting for the app to restart " - "source pad elements", GST_ELEMENT_NAME (queue)); - } - } - - STATUS (queue, "waiting for item_add"); - - if (queue->block_timeout != GST_CLOCK_TIME_NONE) { - GTimeVal timeout; - - g_get_current_time (&timeout); - g_time_val_add (&timeout, queue->block_timeout / 1000); - GST_LOG_OBJECT (queue, "g_cond_time_wait using qlock from thread %p", - g_thread_self ()); - if (!g_cond_timed_wait (queue->item_add, queue->qlock, &timeout)) { - GST_QUEUE_MUTEX_UNLOCK; - GST_CAT_WARNING_OBJECT (queue_dataflow, queue, - "Sending filler event"); - return GST_DATA (gst_event_new_filler ()); - } - } else { - GST_LOG_OBJECT (queue, "doing g_cond_wait using qlock from thread %p", - g_thread_self ()); - g_cond_wait (queue->item_add, queue->qlock); - GST_LOG_OBJECT (queue, "done g_cond_wait using qlock from thread %p", - g_thread_self ()); - } - STATUS (queue, "got item_add signal"); - } - - STATUS (queue, "post-empty wait"); - GST_QUEUE_MUTEX_UNLOCK; - g_signal_emit (G_OBJECT (queue), gst_queue_signals[SIGNAL_RUNNING], 0); - GST_QUEUE_MUTEX_LOCK; - } + GstQueue *queue = GST_QUEUE (gst_pad_get_parent (GST_PAD (pad))); /* There's something in the list now, whatever it is */ - data = g_queue_pop_head (queue->queue); - GST_CAT_LOG_OBJECT (queue_dataflow, queue, - "retrieved data %p from queue", data); + GST_DEBUG_OBJECT (queue, "calling get function with %u elements in queue", + queue->cur_level.items); + data = gst_queue_remove_data (queue, NULL); + GST_LOG_OBJECT (queue, "retrieved data %p from queue", *data); + + if (data == NULL) { + /* queue is empty and we pulled? */ + GST_WARNING_OBJECT (queue, "queue is empty and we pulled?"); + gst_real_pad_set_active (GST_REAL_PAD (queue->sinkpad), TRUE); + gst_real_pad_set_active (GST_REAL_PAD (queue->srcpad), FALSE); + g_signal_emit (G_OBJECT (queue), gst_queue_signals[SIGNAL_UNDERRUN], 0); - if (data == NULL) return NULL; - - 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 (queue_dataflow, queue, - "Got buffer of time %" GST_TIME_FORMAT, - GST_TIME_ARGS (GST_BUFFER_TIMESTAMP (data))); } - /* 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); + if ((gst_queue_is_bigger (queue, &queue->min_threshold) || + queue->min_threshold.items + queue->min_threshold.buffers + + queue->min_threshold.bytes + queue->min_threshold.time == 0) && + !queue->got_eos) { + gst_real_pad_set_active (GST_REAL_PAD (queue->sinkpad), TRUE); + } - STATUS (queue, "after _get()"); - - GST_CAT_LOG_OBJECT (queue_dataflow, queue, "signalling item_del"); - g_cond_signal (queue->item_del); - GST_QUEUE_MUTEX_UNLOCK; - - /* 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)) { case GST_EVENT_EOS: - GST_CAT_DEBUG_OBJECT (queue_dataflow, queue, - "queue \"%s\" eos", GST_ELEMENT_NAME (queue)); + GST_DEBUG_OBJECT (queue, "eos", GST_ELEMENT_NAME (queue)); gst_element_set_eos (GST_ELEMENT (queue)); + queue->got_eos = FALSE; + gst_real_pad_set_active (GST_REAL_PAD (queue->sinkpad), TRUE); break; default: break; } } + if (g_queue_is_empty (queue->queue)) { + g_signal_emit (G_OBJECT (queue), gst_queue_signals[SIGNAL_UNDERRUN], 0); + gst_real_pad_set_active (GST_REAL_PAD (queue->sinkpad), TRUE); + gst_real_pad_set_active (GST_REAL_PAD (queue->srcpad), FALSE); + } + return data; } - static gboolean gst_queue_handle_src_event (GstPad * pad, GstEvent * event) { GstQueue *queue = GST_QUEUE (gst_pad_get_parent (pad)); - gboolean res; - GstQueueEventResponse *er = NULL; + gboolean ret; - GST_CAT_DEBUG_OBJECT (queue_dataflow, queue, "got event %p (%d)", - event, GST_EVENT_TYPE (event)); - GST_QUEUE_MUTEX_LOCK; + GST_DEBUG_OBJECT (queue, "got event %p (%d)", event, GST_EVENT_TYPE (event)); - if (gst_element_get_state (GST_ELEMENT (queue)) == GST_STATE_PLAYING) { - gboolean need_response = GST_DATA_FLAG_IS_SET (GST_DATA (event), - GST_EVENT_COMMON_FLAG_NEED_RESPONSE); + ret = + gst_pad_send_event ((pad == + queue->srcpad) ? queue->sinkpad : queue->srcpad, event); + if (!ret) + return FALSE; - er = g_new (GstQueueEventResponse, 1); - - /* push the event to the queue and wait for upstream consumption */ - er->event = event; - er->handled = FALSE; - - g_mutex_lock (queue->event_lock); - GST_CAT_DEBUG_OBJECT (queue_dataflow, queue, - "putting event %p (%d) on internal queue", event, - GST_EVENT_TYPE (event)); - g_queue_push_tail (queue->events, er); - g_mutex_unlock (queue->event_lock); - - if (!need_response) { - /* Leave for upstream to delete */ - er = NULL; - res = TRUE; - goto handled; - } - - GST_CAT_WARNING_OBJECT (queue_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) { - GTimeVal timeout; - - g_get_current_time (&timeout); - g_time_val_add (&timeout, 500 * 1000); /* half a second */ - GST_LOG_OBJECT (queue, "doing g_cond_wait using qlock from thread %p", - g_thread_self ()); - if (!g_cond_timed_wait (queue->event_done, queue->qlock, &timeout) && - !er->handled) { - GST_CAT_WARNING_OBJECT (queue_dataflow, queue, - "timeout in upstream event handling, dropping event %p (%d)", - er->event, GST_EVENT_TYPE (er->event)); - g_mutex_lock (queue->event_lock); - /* since this queue is for src events (ie upstream), this thread is - * the only one that is pushing stuff on it, so we're sure that - * it's still the tail element. FIXME: But in practice, we should use - * GList instead of GQueue for this so we can remove any element in - * the list. */ - g_queue_pop_tail (queue->events); - g_mutex_unlock (queue->event_lock); - gst_event_unref (er->event); - res = FALSE; - goto handled; - } - } - GST_CAT_WARNING_OBJECT (queue_dataflow, queue, "Event handled"); - res = er->ret; - } else { - res = gst_pad_event_default (pad, event); - - switch (GST_EVENT_TYPE (event)) { - case GST_EVENT_FLUSH: - GST_CAT_DEBUG_OBJECT (queue_dataflow, queue, - "FLUSH event, flushing queue\n"); + switch (GST_EVENT_TYPE (event)) { + case GST_EVENT_FLUSH: + GST_DEBUG_OBJECT (queue, "FLUSH event, flushing queue\n"); + gst_queue_locked_flush (queue); + break; + case GST_EVENT_SEEK: + if (GST_EVENT_SEEK_FLAGS (event) & GST_SEEK_FLAG_FLUSH) { gst_queue_locked_flush (queue); - break; - case GST_EVENT_SEEK: - if (GST_EVENT_SEEK_FLAGS (event) & GST_SEEK_FLAG_FLUSH) { - gst_queue_locked_flush (queue); - } - break; - default: - break; - } + } + break; + default: + break; } -handled: - GST_QUEUE_MUTEX_UNLOCK; - - if (er) - g_free (er); - - return res; -} - -static gboolean -gst_queue_handle_src_query (GstPad * pad, - GstQueryType type, GstFormat * fmt, gint64 * value) -{ - GstQueue *queue = GST_QUEUE (gst_pad_get_parent (pad)); - gboolean res; - - if (!GST_PAD_PEER (queue->sinkpad)) - return FALSE; - res = gst_pad_query (GST_PAD_PEER (queue->sinkpad), type, fmt, value); - if (!res) - return FALSE; - - if (type == GST_QUERY_POSITION) { - /* FIXME: this code assumes that there's no discont in the queue */ - switch (*fmt) { - case GST_FORMAT_BYTES: - if (*value >= queue->cur_level.bytes) - *value -= queue->cur_level.bytes; - else - *value = 0; - break; - case GST_FORMAT_TIME: - if (*value >= queue->cur_level.time) - *value -= queue->cur_level.time; - else - *value = 0; - break; - default: - /* FIXME */ - break; - } - } - - return TRUE; -} - -static gboolean -gst_queue_release_locks (GstElement * element) -{ - GstQueue *queue; - - queue = GST_QUEUE (element); - - GST_QUEUE_MUTEX_LOCK; - queue->interrupt = TRUE; - g_cond_signal (queue->item_add); - g_cond_signal (queue->item_del); - GST_QUEUE_MUTEX_UNLOCK; - return TRUE; } @@ -1059,50 +658,16 @@ gst_queue_change_state (GstElement * element) { GstQueue *queue; GstElementStateReturn ret = GST_STATE_SUCCESS; + guint transition = GST_STATE_TRANSITION (element); queue = GST_QUEUE (element); - GST_CAT_LOG_OBJECT (GST_CAT_STATES, element, - "starting state change 0x%x", GST_STATE_TRANSITION (element)); + GST_CAT_LOG_OBJECT (GST_CAT_STATES, element, "starting state change"); - /* lock the queue so another thread (not in sync with this thread's state) - * can't call this queue's _get (or whatever) - */ - GST_QUEUE_MUTEX_LOCK; + if (GST_ELEMENT_CLASS (parent_class)->change_state) + ret = GST_ELEMENT_CLASS (parent_class)->change_state (element); - switch (GST_STATE_TRANSITION (element)) { - case GST_STATE_NULL_TO_READY: - gst_queue_locked_flush (queue); - 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)); - /* FIXME can this be? */ - g_cond_signal (queue->item_add); - - ret = GST_STATE_FAILURE; - goto unlock; - } else { - GstScheduler *src_sched, *sink_sched; - - 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)); - - g_warning ("queue %s does not connect different schedulers", - GST_ELEMENT_NAME (queue)); - - ret = GST_STATE_FAILURE; - goto unlock; - } - } - queue->interrupt = FALSE; - break; + switch (transition) { case GST_STATE_PAUSED_TO_READY: gst_queue_locked_flush (queue); gst_caps_replace (&queue->negotiated_caps, NULL); @@ -1111,40 +676,17 @@ gst_queue_change_state (GstElement * element) break; } - GST_QUEUE_MUTEX_UNLOCK; - - 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); - - GST_CAT_LOG_OBJECT (GST_CAT_STATES, element, "done with state change"); - - return ret; - -unlock: - GST_QUEUE_MUTEX_UNLOCK; - 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) { GstQueue *queue = GST_QUEUE (object); - /* someone could change levels here, and since this - * affects the get/put funcs, we need to lock for safety. */ - GST_QUEUE_MUTEX_LOCK; - switch (prop_id) { case ARG_MAX_SIZE_BYTES: queue->max_size.bytes = g_value_get_uint (value); @@ -1164,21 +706,22 @@ gst_queue_set_property (GObject * object, case ARG_MIN_THRESHOLD_TIME: queue->min_threshold.time = g_value_get_uint64 (value); break; + case ARG_MAX_THRESHOLD_BYTES: + queue->max_threshold.bytes = g_value_get_uint (value); + break; + case ARG_MAX_THRESHOLD_BUFFERS: + queue->max_threshold.buffers = g_value_get_uint (value); + break; + case ARG_MAX_THRESHOLD_TIME: + queue->max_threshold.time = g_value_get_uint64 (value); + break; case ARG_LEAKY: queue->leaky = g_value_get_enum (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_uint64 (value); - break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; } - - GST_QUEUE_MUTEX_UNLOCK; } static void @@ -1215,15 +758,18 @@ gst_queue_get_property (GObject * object, case ARG_MIN_THRESHOLD_TIME: g_value_set_uint64 (value, queue->min_threshold.time); break; + case ARG_MAX_THRESHOLD_BYTES: + g_value_set_uint (value, queue->max_threshold.bytes); + break; + case ARG_MAX_THRESHOLD_BUFFERS: + g_value_set_uint (value, queue->max_threshold.buffers); + break; + case ARG_MAX_THRESHOLD_TIME: + g_value_set_uint64 (value, queue->max_threshold.time); + break; case ARG_LEAKY: g_value_set_enum (value, queue->leaky); break; - case ARG_MAY_DEADLOCK: - g_value_set_boolean (value, queue->may_deadlock); - break; - case ARG_BLOCK_TIMEOUT: - g_value_set_uint64 (value, queue->block_timeout); - break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; diff --git a/plugins/elements/gstqueue.h b/plugins/elements/gstqueue.h index e473f404ef..feabbbdd0b 100644 --- a/plugins/elements/gstqueue.h +++ b/plugins/elements/gstqueue.h @@ -1,6 +1,7 @@ /* GStreamer * Copyright (C) 1999,2000 Erik Walthinsen * 2000 Wim Taymans + * 2004,2005 Benjamin Otte * * gstqueue.h: * @@ -52,9 +53,10 @@ typedef struct _GstQueueSize GstQueueSize; typedef struct _GstQueueClass GstQueueClass; struct _GstQueueSize { - guint buffers; /* no. of buffers */ - guint bytes; /* no. of bytes */ - guint64 time; /* amount of time */ + guint items; /* no. of items */ + guint buffers; /* no. of buffers */ + guint bytes; /* no. of bytes */ + GstClockTime time; /* amount of time */ }; struct _GstQueue { @@ -69,39 +71,25 @@ struct _GstQueue { GstQueueSize cur_level, /* currently in the queue */ max_size, /* max. amount of data allowed in the queue */ - min_threshold; /* min. amount of data required to wake reader */ + min_threshold, /* min. amount of data required to wake reader */ + max_threshold; /* min. amount of data required to wake writer */ /* 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; - - gboolean interrupt; - gboolean flush; + gboolean got_eos; GMutex *qlock; /* lock for queue (vs object lock) */ - 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 */ - GQueue *events; /* upstream events get decoupled here */ GstCaps *negotiated_caps; - GMutex *event_lock; /* lock when handling the events queue */ - gpointer _gst_reserved[GST_PADDING - 1]; }; struct _GstQueueClass { GstElementClass parent_class; + /* vtable */ + /* signals - 'running' is called from both sides * which might make it sort of non-useful... */ void (*underrun) (GstQueue *queue); diff --git a/plugins/elements/gsttee.c b/plugins/elements/gsttee.c index a046ed3635..a0ae285b48 100644 --- a/plugins/elements/gsttee.c +++ b/plugins/elements/gsttee.c @@ -27,15 +27,10 @@ #include "gsttee.h" #include - -static GstStaticPadTemplate sinktemplate = GST_STATIC_PAD_TEMPLATE ("sink", - GST_PAD_SINK, - GST_PAD_ALWAYS, - GST_STATIC_CAPS_ANY); - -GST_DEBUG_CATEGORY_STATIC (gst_tee_debug); +#if 0 +GST_DEBUG_CATEGORY_STATIC (gst_tee_debug, "tee", 0, "tee element"); #define GST_CAT_DEFAULT gst_tee_debug - +#endif GstElementDetails gst_tee_details = GST_ELEMENT_DETAILS ("Tee pipe fitting", "Generic", "1-to-N pipe fitting", @@ -63,10 +58,7 @@ GstStaticPadTemplate tee_src_template = GST_STATIC_PAD_TEMPLATE ("src%d", GST_PAD_REQUEST, GST_STATIC_CAPS_ANY); -#define _do_init(bla) \ - GST_DEBUG_CATEGORY_INIT (gst_tee_debug, "tee", 0, "tee element"); - -GST_BOILERPLATE_FULL (GstTee, gst_tee, GstElement, GST_TYPE_ELEMENT, _do_init); +GST_BOILERPLATE (GstTee, gst_tee, GstElement, GST_TYPE_ELEMENT); static GstPad *gst_tee_request_new_pad (GstElement * element, GstPadTemplate * temp, const gchar * unused); @@ -77,7 +69,10 @@ static void gst_tee_set_property (GObject * object, guint prop_id, static void gst_tee_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec); -static void gst_tee_chain (GstPad * pad, GstData * _data); +static void gst_tee_chain (GstAction * action, GstRealPad * pad, + GstData * data); +static GstData *gst_tee_get (GstAction * action, GstRealPad * pad); +static GstElementStateReturn gst_tee_change_state (GstElement * element); static void @@ -85,8 +80,6 @@ gst_tee_base_init (gpointer g_class) { GstElementClass *gstelement_class = GST_ELEMENT_CLASS (g_class); - gst_element_class_add_pad_template (gstelement_class, - gst_static_pad_template_get (&sinktemplate)); gst_element_class_set_details (gstelement_class, &gst_tee_details); gst_element_class_add_pad_template (gstelement_class, gst_static_pad_template_get (&tee_src_template)); @@ -114,6 +107,9 @@ gst_tee_class_init (GstTeeClass * klass) gstelement_class = (GstElementClass *) klass; + gobject_class->get_property = GST_DEBUG_FUNCPTR (gst_tee_get_property); + gobject_class->set_property = GST_DEBUG_FUNCPTR (gst_tee_set_property); + g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_NUM_PADS, g_param_spec_int ("num_pads", "num_pads", "num_pads", 0, G_MAXINT, 0, G_PARAM_READABLE)); @@ -126,9 +122,8 @@ gst_tee_class_init (GstTeeClass * klass) gobject_class->finalize = GST_DEBUG_FUNCPTR (gst_tee_finalize); - gobject_class->set_property = GST_DEBUG_FUNCPTR (gst_tee_set_property); - gobject_class->get_property = GST_DEBUG_FUNCPTR (gst_tee_get_property); + gstelement_class->change_state = gst_tee_change_state; gstelement_class->request_new_pad = GST_DEBUG_FUNCPTR (gst_tee_request_new_pad); } @@ -136,17 +131,16 @@ gst_tee_class_init (GstTeeClass * klass) static void gst_tee_init (GstTee * tee) { - tee->sinkpad = - gst_pad_new_from_template (gst_static_pad_template_get (&sinktemplate), - "sink"); + tee->sinkpad = gst_pad_new ("sink", GST_PAD_SINK); + gst_sink_pad_set_action_handler (tee->sinkpad, gst_tee_chain); gst_element_add_pad (GST_ELEMENT (tee), tee->sinkpad); - gst_pad_set_chain_function (tee->sinkpad, GST_DEBUG_FUNCPTR (gst_tee_chain)); gst_pad_set_link_function (tee->sinkpad, GST_DEBUG_FUNCPTR (gst_pad_proxy_pad_link)); gst_pad_set_getcaps_function (tee->sinkpad, GST_DEBUG_FUNCPTR (gst_pad_proxy_getcaps)); tee->last_message = NULL; + GST_FLAG_SET (tee, GST_ELEMENT_EVENT_AWARE); } /* helper compare function */ @@ -161,56 +155,6 @@ name_pad_compare (gconstpointer a, gconstpointer b) return strcmp (name, gst_pad_get_name (pad)); /* returns 0 if match */ } -static GstCaps * -gst_tee_getcaps (GstPad * _pad) -{ - GstTee *tee = GST_TEE (gst_pad_get_parent (_pad)); - GstCaps *caps = gst_caps_new_any (), *tmp, *res; - GstPad *pad; - const GList *pads; - - for (pads = gst_element_get_pad_list (GST_ELEMENT (tee)); - pads != NULL; pads = pads->next) { - pad = GST_PAD (pads->data); - if (pad == _pad) - continue; - - tmp = gst_pad_get_allowed_caps (pad); - res = gst_caps_intersect (caps, tmp); - gst_caps_free (tmp); - gst_caps_free (caps); - caps = res; - } - - return caps; -} - -static GstPadLinkReturn -gst_tee_link (GstPad * _pad, const GstCaps * caps) -{ - GstTee *tee = GST_TEE (gst_pad_get_parent (_pad)); - GstPadLinkReturn res; - GstPad *pad; - const GList *pads; - - GST_DEBUG_OBJECT (tee, "Forwarding link to all other pads"); - - for (pads = gst_element_get_pad_list (GST_ELEMENT (tee)); - pads != NULL; pads = pads->next) { - pad = GST_PAD (pads->data); - if (pad == _pad) - continue; - - res = gst_pad_try_set_caps (pad, caps); - GST_DEBUG_OBJECT (tee, "Pad %s:%s gave response %d", - GST_DEBUG_PAD_NAME (pad), res); - if (GST_PAD_LINK_FAILED (res)) - return res; - } - - return GST_PAD_LINK_OK; -} - static GstPad * gst_tee_request_new_pad (GstElement * element, GstPadTemplate * templ, const gchar * unused) @@ -252,8 +196,11 @@ gst_tee_request_new_pad (GstElement * element, GstPadTemplate * templ, srcpad = gst_pad_new_from_template (templ, name); g_free (name); - gst_pad_set_link_function (srcpad, GST_DEBUG_FUNCPTR (gst_tee_link)); - gst_pad_set_getcaps_function (srcpad, GST_DEBUG_FUNCPTR (gst_tee_getcaps)); + gst_src_pad_set_action_handler (srcpad, gst_tee_get); + gst_pad_set_link_function (srcpad, + GST_DEBUG_FUNCPTR (gst_pad_proxy_pad_link)); + gst_pad_set_getcaps_function (srcpad, + GST_DEBUG_FUNCPTR (gst_pad_proxy_getcaps)); gst_element_add_pad (GST_ELEMENT (tee), srcpad); GST_PAD_ELEMENT_PRIVATE (srcpad) = NULL; @@ -313,50 +260,82 @@ gst_tee_get_property (GObject * object, guint prop_id, GValue * value, } } -/** - * gst_tee_chain: - * @pad: the pad to follow - * @buf: the buffer to pass - * - * Chain a buffer on a pad. - */ -static void -gst_tee_chain (GstPad * pad, GstData * _data) +static GstData * +gst_tee_get (GstAction * action, GstRealPad * pad) +{ + GstData *data; + GstTee *tee = GST_TEE (gst_action_get_element (action)); + + g_assert (tee->current); + if (!tee->silent) { + GstData *data = tee->current; + + g_free (tee->last_message); + tee->last_message = + g_strdup_printf ("request ******* (%s:%s)t (%d bytes, %" + G_GUINT64_FORMAT ") %p", GST_DEBUG_PAD_NAME (pad), + GST_IS_BUFFER (data) ? GST_BUFFER_SIZE (data) : 0, + GST_IS_BUFFER (data) ? GST_BUFFER_TIMESTAMP (data) : + GST_CLOCK_TIME_NONE, data); + g_object_notify (G_OBJECT (tee), "last_message"); + } + data = tee->current; + gst_action_set_active (action, FALSE); + tee->missing_pads--; + if (tee->missing_pads == 0) { + gst_real_pad_set_active (GST_REAL_PAD (tee->sinkpad), TRUE); + if (GST_IS_EVENT (tee->current) && + GST_EVENT_TYPE (tee->current) == GST_EVENT_EOS) { + gst_element_set_eos (GST_ELEMENT (tee)); + } + tee->current = NULL; + } else { + gst_data_ref (tee->current); + } + return data; +} + +static void +gst_tee_chain (GstAction * action, GstRealPad * pad, GstData * data) { - GstBuffer *buf = GST_BUFFER (_data); - GstTee *tee; const GList *pads; + GstTee *tee = GST_TEE (gst_action_get_element (action)); - g_return_if_fail (pad != NULL); - g_return_if_fail (GST_IS_PAD (pad)); - g_return_if_fail (buf != NULL); - - tee = GST_TEE (gst_pad_get_parent (pad)); - - gst_buffer_ref_by_count (buf, GST_ELEMENT (tee)->numsrcpads - 1); - - pads = gst_element_get_pad_list (GST_ELEMENT (tee)); - - while (pads) { + g_assert (tee->current == NULL); + g_assert (tee->missing_pads == 0); + tee->current = data; + for (pads = gst_element_get_pad_list (GST_ELEMENT (tee)); pads; + pads = g_list_next (pads)) { GstPad *outpad = GST_PAD (pads->data); - pads = g_list_next (pads); - if (GST_PAD_DIRECTION (outpad) != GST_PAD_SRC) continue; - if (!tee->silent) { - g_free (tee->last_message); - tee->last_message = - g_strdup_printf ("chain ******* (%s:%s)t (%d bytes, %" - G_GUINT64_FORMAT ") %p", GST_DEBUG_PAD_NAME (outpad), - GST_BUFFER_SIZE (buf), GST_BUFFER_TIMESTAMP (buf), buf); - g_object_notify (G_OBJECT (tee), "last_message"); - } - - if (GST_PAD_IS_USABLE (outpad)) - gst_pad_push (outpad, GST_DATA (buf)); - else - gst_buffer_unref (buf); + gst_real_pad_set_active (GST_REAL_PAD (outpad), TRUE); + tee->missing_pads++; } + gst_real_pad_set_active (GST_REAL_PAD (tee->sinkpad), FALSE); +} + +static GstElementStateReturn +gst_tee_change_state (GstElement * element) +{ + GstTee *tee = GST_TEE (element); + + switch (GST_STATE_TRANSITION (element)) { + case GST_STATE_PAUSED_TO_READY: + if (tee->current) { + gst_data_unref (tee->current); + tee->current = NULL; + tee->missing_pads = 0; + } + break; + default: + break; + } + + if (GST_ELEMENT_CLASS (parent_class)->change_state) + return GST_ELEMENT_CLASS (parent_class)->change_state (element); + + return GST_STATE_SUCCESS; } diff --git a/plugins/elements/gsttee.h b/plugins/elements/gsttee.h index f28b09d9d5..547f96d012 100644 --- a/plugins/elements/gsttee.h +++ b/plugins/elements/gsttee.h @@ -48,6 +48,9 @@ struct _GstTee { GstPad *sinkpad; + GstData *current; /* current data peers should pull */ + gint missing_pads; /* number of pads that haven't pulled yet */ + gboolean silent; gchar *last_message; }; diff --git a/plugins/elements/gsttypefindelement.c b/plugins/elements/gsttypefindelement.c index 8c0c001c6f..1c766d9766 100644 --- a/plugins/elements/gsttypefindelement.c +++ b/plugins/elements/gsttypefindelement.c @@ -45,6 +45,7 @@ #include #include #include +#include GST_DEBUG_CATEGORY_STATIC (gst_type_find_element_debug); #define GST_CAT_DEFAULT gst_type_find_element_debug @@ -103,16 +104,17 @@ static void gst_type_find_element_set_property (GObject * object, static void gst_type_find_element_get_property (GObject * object, guint prop_id, GValue * value, GParamSpec * pspec); -static const GstEventMask *gst_type_find_element_src_event_mask (GstPad * pad); static gboolean gst_type_find_element_src_event (GstPad * pad, GstEvent * event); static gboolean gst_type_find_handle_src_query (GstPad * pad, GstQueryType type, GstFormat * fmt, gint64 * value); -static void push_buffer_store (GstTypeFindElement * typefind); -static void gst_type_find_element_chain (GstPad * sinkpad, GstData * data); -static GstElementStateReturn -gst_type_find_element_change_state (GstElement * element); +static void gst_type_find_element_wakeup (GstAction * action, + GstElement * element, gpointer unused); +static void gst_type_find_element_chain (GstAction * action, + GstRealPad * sinkpad, GstData * data); +static GstElementStateReturn gst_type_find_element_change_state (GstElement * + element); static guint gst_type_find_element_signals[LAST_SIGNAL] = { 0 }; @@ -178,33 +180,35 @@ gst_type_find_element_class_init (GstTypeFindElementClass * typefind_class) static void gst_type_find_element_init (GstTypeFindElement * typefind) { + GST_FLAG_SET (typefind, GST_ELEMENT_EVENT_AWARE); + GST_FLAG_SET (typefind, GST_ELEMENT_PUSHING); + /* sinkpad */ typefind->sink = gst_pad_new_from_template (gst_static_pad_template_get (&type_find_element_sink_template), "sink"); - gst_pad_set_chain_function (typefind->sink, gst_type_find_element_chain); + gst_sink_pad_set_action_handler (typefind->sink, gst_type_find_element_chain); gst_element_add_pad (GST_ELEMENT (typefind), typefind->sink); /* srcpad */ typefind->src = gst_pad_new_from_template (gst_static_pad_template_get (&type_find_element_src_template), "src"); gst_pad_set_event_function (typefind->src, gst_type_find_element_src_event); - gst_pad_set_event_mask_function (typefind->src, - gst_type_find_element_src_event_mask); gst_pad_set_query_function (typefind->src, GST_DEBUG_FUNCPTR (gst_type_find_handle_src_query)); gst_pad_use_explicit_caps (typefind->src); gst_element_add_pad (GST_ELEMENT (typefind), typefind->src); + typefind->wakeup = gst_element_add_wakeup (GST_ELEMENT (typefind), FALSE, + gst_type_find_element_wakeup, NULL); typefind->caps = NULL; typefind->pending_events = NULL; typefind->min_probability = 1; typefind->max_probability = GST_TYPE_FIND_MAXIMUM; typefind->store = gst_buffer_store_new (); - - GST_FLAG_SET (typefind, GST_ELEMENT_EVENT_AWARE); } + static void gst_type_find_element_dispose (GObject * object) { @@ -294,20 +298,6 @@ gst_type_find_handle_src_query (GstPad * pad, return TRUE; } -static const GstEventMask * -gst_type_find_element_src_event_mask (GstPad * pad) -{ - static const GstEventMask mask[] = { - {GST_EVENT_SEEK, - GST_SEEK_METHOD_SET | GST_SEEK_METHOD_CUR | GST_SEEK_METHOD_END | - GST_SEEK_FLAG_FLUSH}, - /* add more if you want, event masks suck and need to die anyway */ - {0,} - }; - - return mask; -} - static gboolean gst_type_find_element_src_event (GstPad * pad, GstEvent * event) { @@ -368,6 +358,19 @@ start_typefinding (GstTypeFindElement * typefind) typefind->stream_length_available = TRUE; typefind->stream_length = 0; } + +static void +push_buffer_store (GstTypeFindElement * typefind, GstEvent * event) +{ + if (!event) + event = gst_event_new_discontinuous (TRUE, + GST_FORMAT_DEFAULT, (guint64) 0, GST_FORMAT_BYTES, (guint64) 0, + GST_FORMAT_UNDEFINED); + typefind->pending_events = g_list_append (typefind->pending_events, event); + gst_real_pad_set_active (GST_REAL_PAD (typefind->sink), FALSE); + gst_action_set_active (typefind->wakeup, TRUE); +} + static void stop_typefinding (GstTypeFindElement * typefind) { @@ -401,7 +404,7 @@ stop_typefinding (GstTypeFindElement * typefind) "could not seek to required position %u, hope for the best", size); typefind->mode = MODE_NORMAL; /* push out our queued buffers here */ - push_buffer_store (typefind); + push_buffer_store (typefind, NULL); } else { typefind->waiting_for_discont_offset = size; } @@ -409,25 +412,26 @@ stop_typefinding (GstTypeFindElement * typefind) } static void -push_buffer_store (GstTypeFindElement * typefind) +gst_type_find_element_wakeup (GstAction * action, GstElement * element, + gpointer unused) { - guint size = gst_buffer_store_get_size (typefind->store, 0); + guint size; GstBuffer *buffer; const GList *item; + GstTypeFindElement *typefind = GST_TYPE_FIND_ELEMENT (element); /* handle pending events */ - for (item = typefind->pending_events; item; item = item->next) { + if (typefind->pending_events) { GstEvent *e = item->data; + typefind->pending_events = g_list_remove (typefind->pending_events, + typefind->pending_events->data); gst_pad_push (typefind->src, GST_DATA (e)); + return; } - g_list_free (typefind->pending_events); - typefind->pending_events = NULL; /* data */ - gst_pad_push (typefind->src, GST_DATA (gst_event_new_discontinuous (TRUE, - GST_FORMAT_DEFAULT, (guint64) 0, GST_FORMAT_BYTES, (guint64) 0, - GST_FORMAT_UNDEFINED))); + size = gst_buffer_store_get_size (typefind->store, 0); if (size && (buffer = gst_buffer_store_get_buffer (typefind->store, 0, size))) { GST_DEBUG_OBJECT (typefind, "pushing cached data (%u bytes)", size); gst_pad_push (typefind->src, GST_DATA (buffer)); @@ -437,6 +441,8 @@ push_buffer_store (GstTypeFindElement * typefind) } gst_buffer_store_clear (typefind->store); + gst_action_set_active (action, FALSE); + gst_real_pad_set_active (GST_REAL_PAD (typefind->sink), TRUE); } static guint64 @@ -496,8 +502,7 @@ gst_type_find_element_handle_event (GstPad * pad, GstEvent * event) g_signal_emit (typefind, gst_type_find_element_signals[HAVE_TYPE], 0, entry->probability, entry->caps); stop_typefinding (typefind); - push_buffer_store (typefind); - gst_pad_event_default (pad, event); + push_buffer_store (typefind, event); } else { gst_pad_event_default (pad, event); GST_ELEMENT_ERROR (typefind, STREAM, TYPE_NOT_FOUND, (NULL), @@ -526,13 +531,11 @@ gst_type_find_element_handle_event (GstPad * pad, GstEvent * event) if (gst_event_discont_get_value (event, GST_FORMAT_BYTES, &off) && off == typefind->waiting_for_discont_offset) { typefind->mode = MODE_NORMAL; - push_buffer_store (typefind); + push_buffer_store (typefind, NULL); } - gst_event_unref (event); } } else if (GST_EVENT_TYPE (event) == GST_EVENT_EOS) { - push_buffer_store (typefind); - gst_pad_event_default (pad, event); + push_buffer_store (typefind, event); } else { gst_event_unref (event); } @@ -618,7 +621,8 @@ compare_type_find_factory (gconstpointer fac1, gconstpointer fac2) return GST_PLUGIN_FEATURE (fac1)->rank - GST_PLUGIN_FEATURE (fac2)->rank; } static void -gst_type_find_element_chain (GstPad * pad, GstData * data) +gst_type_find_element_chain (GstAction * action, GstRealPad * pad, + GstData * data) { GstTypeFindElement *typefind; GList *entries; @@ -626,9 +630,9 @@ gst_type_find_element_chain (GstPad * pad, GstData * data) GList *walk; GstTypeFind find = { find_peek, find_suggest, NULL, find_element_get_length }; - typefind = GST_TYPE_FIND_ELEMENT (GST_PAD_PARENT (pad)); + typefind = GST_TYPE_FIND_ELEMENT (GST_PAD_PARENT (GST_PAD (pad))); if (GST_IS_EVENT (data)) { - gst_type_find_element_handle_event (pad, GST_EVENT (data)); + gst_type_find_element_handle_event (GST_PAD (pad), GST_EVENT (data)); return; } switch (typefind->mode) { diff --git a/plugins/elements/gsttypefindelement.h b/plugins/elements/gsttypefindelement.h index 0b243dbd94..ce1f94aacb 100644 --- a/plugins/elements/gsttypefindelement.h +++ b/plugins/elements/gsttypefindelement.h @@ -48,6 +48,8 @@ struct _GstTypeFindElement { GstPad * sink; GstPad * src; + GstAction * wakeup; + guint min_probability; guint max_probability; GstCaps * caps; diff --git a/po/af.po b/po/af.po index e329096f31..bc8341ba09 100644 --- a/po/af.po +++ b/po/af.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: gstreamer 0.8.0\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2005-05-02 19:36+0200\n" +"POT-Creation-Date: 2005-05-17 18:37+0200\n" "PO-Revision-Date: 2004-03-24 11:28+0200\n" "Last-Translator: Petri Jooste \n" "Language-Team: Afrikaans \n" @@ -15,30 +15,30 @@ msgstr "" "Content-Type: text/plain; charset=ISO-8859-1\n" "Content-Transfer-Encoding: 8bit\n" -#: gst/gst.c:160 +#: gst/gst.c:157 msgid "Print the GStreamer version" msgstr "Vertoon die GStreamer weergawe" -#: gst/gst.c:162 +#: gst/gst.c:159 msgid "Make all warnings fatal" msgstr "Maak alle waarskuwings fataal" -#: gst/gst.c:166 +#: gst/gst.c:163 msgid "Print available debug categories and exit" msgstr "Vertoon beskikbare ontfoutkategorië en stop" -#: gst/gst.c:169 +#: gst/gst.c:166 msgid "" "Default debug level from 1 (only error) to 5 (anything) or 0 for no output" msgstr "" "Verstek ontfoutvlak vanaf 1 (slegs fout) tot 5 (enigiets) of 0 vir geen " "afvoer" -#: gst/gst.c:171 +#: gst/gst.c:168 msgid "LEVEL" msgstr "VLAK" -#: gst/gst.c:173 +#: gst/gst.c:170 msgid "" "Comma-separated list of category_name:level pairs to set specific levels for " "the individual categories. Example: GST_AUTOPLUG:5,GST_ELEMENT_*:3" @@ -46,31 +46,27 @@ msgstr "" "Komma-geskeide lys van kategorie_naam:vlak pare om die individuele " "kategorieë op te stel. Byvoorbeeld: GST_AUTOPLUG:5,GST_ELEMENT_*:3" -#: gst/gst.c:176 +#: gst/gst.c:173 msgid "LIST" msgstr "LYS" -#: gst/gst.c:178 +#: gst/gst.c:175 msgid "Disable colored debugging output" msgstr "Skakel gekleurde ontfout-afvoer af" -#: gst/gst.c:180 +#: gst/gst.c:177 msgid "Disable debugging" msgstr "Skakel ontfouting af" -#: gst/gst.c:184 -msgid "Disable accelerated CPU instructions" -msgstr "Skakel versnelde SVE-instruksies af" - -#: gst/gst.c:186 +#: gst/gst.c:181 msgid "Enable verbose plugin loading diagnostics" msgstr "Aktiveer volledige diagnostiese boodskappe vir inproplaaiing" -#: gst/gst.c:188 +#: gst/gst.c:183 msgid "PATHS" msgstr "PAAIE" -#: gst/gst.c:191 +#: gst/gst.c:186 #, fuzzy msgid "" "Comma-separated list of plugins to preload in addition to the list stored in " @@ -79,32 +75,32 @@ msgstr "" "Komma-geskeide lys van inproppe om vooraf te laai by die lys gestoor in die " "omgewingsveranderlike GST_PLUGIN_PATH" -#: gst/gst.c:193 +#: gst/gst.c:188 msgid "PLUGINS" msgstr "INPROPPE" -#: gst/gst.c:196 +#: gst/gst.c:191 msgid "Disable trapping of segmentation faults during plugin loading" msgstr "Moenie segmenteringsfoute tydens inproplaaiing ondervang nie" -#: gst/gst.c:199 +#: gst/gst.c:194 msgid "SCHEDULER" msgstr "SKEDULEERDER" -#: gst/gst.c:201 +#: gst/gst.c:196 msgid "Registry to use" msgstr "Register om te gebruik" -#: gst/gst.c:201 +#: gst/gst.c:196 msgid "REGISTRY" msgstr "REGISTER" -#: gst/gst.c:214 +#: gst/gst.c:209 #, fuzzy, c-format msgid "path list for loading plugins (separated by '%s')" msgstr "lys van paaie waaruit inproppe gelaai word (geskei met '" -#: gst/gst.c:218 +#: gst/gst.c:213 #, fuzzy, c-format msgid "Scheduler to use (default is '%s')" msgstr "Skeduleerder om te gebruik ('" @@ -586,52 +582,46 @@ msgstr "" msgid ", " msgstr ", " -#: gst/autoplug/gstspider.c:466 -#, c-format -msgid "There is no element present to handle the stream's mime type %s." -msgstr "" -"Daar is geen element beskikbaar om die stroom se mime-tipe %s te hanteer nie." - -#: gst/elements/gstfilesink.c:268 +#: gst/elements/gstfilesink.c:243 msgid "No file name specified for writing." msgstr "Geen lêernaam om heen te skryf nie." -#: gst/elements/gstfilesink.c:275 +#: gst/elements/gstfilesink.c:250 #, c-format msgid "Could not open file \"%s\" for writing." msgstr "Kon nie lêer \"%s\" oopmaak om in te skryf nie." -#: gst/elements/gstfilesink.c:294 +#: gst/elements/gstfilesink.c:269 #, c-format msgid "Error closing file \"%s\"." msgstr "Fout met toemaak van lêer \"%s\"." -#: gst/elements/gstfilesink.c:364 gst/elements/gstfilesink.c:400 -#: gst/elements/gstfilesink.c:453 +#: gst/elements/gstfilesink.c:339 gst/elements/gstfilesink.c:375 +#: gst/elements/gstfilesink.c:428 #, c-format msgid "Error while writing to file \"%s\"." msgstr "Fout tydens skryf na lêer \"%s\"." -#: gst/elements/gstfilesrc.c:764 gst/elements/gstmultifilesrc.c:298 +#: gst/elements/gstfilesrc.c:725 msgid "No file name specified for reading." msgstr "Geen lêernaam om uit te lees nie." -#: gst/elements/gstfilesrc.c:779 gst/elements/gstmultifilesrc.c:306 +#: gst/elements/gstfilesrc.c:740 #, c-format msgid "Could not open file \"%s\" for reading." msgstr "Kon nie lêer \"%s\" oopmaak om te lees nie." -#: gst/elements/gstfilesrc.c:790 +#: gst/elements/gstfilesrc.c:751 #, c-format msgid "\"%s\" is a directory." msgstr "" -#: gst/elements/gstfilesrc.c:796 +#: gst/elements/gstfilesrc.c:757 #, fuzzy, c-format msgid "File \"%s\" is a socket." msgstr "Lêer \"%s\" is nie 'n gewone lêer nie." -#: gst/elements/gstidentity.c:306 +#: gst/elements/gstidentity.c:276 msgid "Failed after iterations as requested." msgstr "Mislukking na die vasgestelde aantal probeerslae." @@ -720,123 +710,79 @@ msgstr "kon nie aan bestemming-element vir URI \"%s\" verbind nie" msgid "empty pipeline not allowed" msgstr "leë pyplyn word nie toegelaat nie" -#: tools/gst-inspect.c:1151 +#: tools/gst-inspect.c:1032 #, fuzzy msgid "Print all elements" msgstr "geen element \"%s\"" -#: tools/gst-launch.c:114 -#, c-format -msgid "" -"Execution ended after %s iterations (sum %s ns, average %s ns, min %s ns, " -"max %s ns).\n" -msgstr "" - -#: tools/gst-launch.c:141 -msgid "Usage: gst-xmllaunch [ element.property=value ... ]\n" -msgstr "Gebruik so: gst-xmllaunch [ element.eienskap=waarde ... ]\n" - -#: tools/gst-launch.c:149 -#, c-format -msgid "ERROR: parse of xml file '%s' failed.\n" -msgstr "FOUT: ontleding van xml-lêer '%s' het misluk.\n" - -#: tools/gst-launch.c:155 -#, c-format -msgid "ERROR: no toplevel pipeline element in file '%s'.\n" -msgstr "FOUT: geen topvlak pyplynelement in lêer '%s' nie.\n" - -#: tools/gst-launch.c:162 -#, c-format -msgid "WARNING: only one toplevel element is supported at this time." -msgstr "WAARSKUWING: slegs een topvlak element word tans ondersteun." - -#: tools/gst-launch.c:173 -#, c-format -msgid "ERROR: could not parse command line argument %d: %s.\n" -msgstr "FOUT: onverstaanbare bevellynparameter %d: %s.\n" - -#: tools/gst-launch.c:184 -#, c-format -msgid "WARNING: element named '%s' not found.\n" -msgstr "WAARSKUWING: element genaamd '%s' nie gevind nie.\n" - -#: tools/gst-launch.c:327 +#: tools/gst-launch.c:190 #, c-format msgid "FOUND TAG : found by element \"%s\".\n" msgstr "ETIKET GEVIND : gevind by element \"%s\".\n" -#: tools/gst-launch.c:412 +#: tools/gst-launch.c:304 msgid "Output tags (also known as metadata)" msgstr "Wys etikette (ook bekend as metadata)" -#: tools/gst-launch.c:414 +#: tools/gst-launch.c:306 msgid "Output status information and property notifications" msgstr "Wys statusinligting en kennisgewings van eienskappe" -#: tools/gst-launch.c:416 +#: tools/gst-launch.c:308 msgid "Do not output status information of TYPE" msgstr "Moenie statusinligting van TIPE wys nie" -#: tools/gst-launch.c:416 +#: tools/gst-launch.c:308 msgid "TYPE1,TYPE2,..." msgstr "TIPE1, TIPE2,..." -#: tools/gst-launch.c:419 -msgid "Save xml representation of pipeline to FILE and exit" -msgstr "Stoor xml-voorstelling van pyplyn na LÊER en stop" - -#: tools/gst-launch.c:419 -msgid "FILE" -msgstr "LÊER" - -#: tools/gst-launch.c:422 +#: tools/gst-launch.c:310 msgid "Do not install a fault handler" msgstr "Moenie 'n fouthanteerder installeer nie" -#: tools/gst-launch.c:424 +#: tools/gst-launch.c:312 msgid "Print alloc trace (if enabled at compile time)" msgstr "Druk \"alloc trace\" (indien aangeskakel tydens kompilering)" -#: tools/gst-launch.c:426 +#: tools/gst-launch.c:314 msgid "Number of times to iterate pipeline" msgstr "Aantal kere wat pyplyn herhaal moet word" -#: tools/gst-launch.c:496 +#: tools/gst-launch.c:379 #, c-format msgid "ERROR: pipeline could not be constructed: %s.\n" msgstr "FOUT: pyplyn kon nie opgestel word nie: %s.\n" -#: tools/gst-launch.c:500 -#, c-format +#: tools/gst-launch.c:383 msgid "ERROR: pipeline could not be constructed.\n" msgstr "FOUT: pyplyn kon nie opgestel word nie.\n" -#: tools/gst-launch.c:504 +#: tools/gst-launch.c:387 #, c-format msgid "WARNING: erroneous pipeline: %s\n" msgstr "WAARSKUWING: foutiewe pyplyn: %s\n" -#: tools/gst-launch.c:505 -#, c-format +#: tools/gst-launch.c:388 msgid " Trying to run anyway.\n" msgstr " Probeer om weg te hardloop.\n" -#: tools/gst-launch.c:532 -#, c-format +#: tools/gst-launch.c:408 msgid "ERROR: the 'pipeline' element wasn't found.\n" msgstr "FOUT: die pyplynelement kon nie gevind word nie.\n" -#: tools/gst-launch.c:539 -#, c-format +#: tools/gst-launch.c:417 msgid "RUNNING pipeline ...\n" msgstr "LOOP pyplyn ...\n" -#: tools/gst-launch.c:542 -#, c-format +#: tools/gst-launch.c:421 msgid "ERROR: pipeline doesn't want to play.\n" msgstr "FOUT: pyplyn wil nie speel nie.\n" +#: tools/gst-launch.c:445 +#, c-format +msgid "Execution ended after %.2fs (%.2fs or %.2f%% idling).\n" +msgstr "" + #: tools/gst-register.c:49 #, c-format msgid "Added plugin %s with %d feature.\n" @@ -871,6 +817,39 @@ msgid_plural "Loaded %d plugins with %d features.\n" msgstr[0] "" msgstr[1] "" +#~ msgid "Disable accelerated CPU instructions" +#~ msgstr "Skakel versnelde SVE-instruksies af" + +#~ msgid "There is no element present to handle the stream's mime type %s." +#~ msgstr "" +#~ "Daar is geen element beskikbaar om die stroom se mime-tipe %s te hanteer " +#~ "nie." + +#~ msgid "Usage: gst-xmllaunch [ element.property=value ... ]\n" +#~ msgstr "" +#~ "Gebruik so: gst-xmllaunch [ element.eienskap=waarde ... ]\n" + +#~ msgid "ERROR: parse of xml file '%s' failed.\n" +#~ msgstr "FOUT: ontleding van xml-lêer '%s' het misluk.\n" + +#~ msgid "ERROR: no toplevel pipeline element in file '%s'.\n" +#~ msgstr "FOUT: geen topvlak pyplynelement in lêer '%s' nie.\n" + +#~ msgid "WARNING: only one toplevel element is supported at this time." +#~ msgstr "WAARSKUWING: slegs een topvlak element word tans ondersteun." + +#~ msgid "ERROR: could not parse command line argument %d: %s.\n" +#~ msgstr "FOUT: onverstaanbare bevellynparameter %d: %s.\n" + +#~ msgid "WARNING: element named '%s' not found.\n" +#~ msgstr "WAARSKUWING: element genaamd '%s' nie gevind nie.\n" + +#~ msgid "Save xml representation of pipeline to FILE and exit" +#~ msgstr "Stoor xml-voorstelling van pyplyn na LÊER en stop" + +#~ msgid "FILE" +#~ msgstr "LÊER" + #~ msgid "caps" #~ msgstr "caps" diff --git a/po/az.po b/po/az.po index 4aa7ae98d0..3d644e4f05 100644 --- a/po/az.po +++ b/po/az.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: gstreamer-0.8.0\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2005-05-02 19:36+0200\n" +"POT-Creation-Date: 2005-05-17 18:37+0200\n" "PO-Revision-Date: 2004-03-19 18:40+0200\n" "Last-Translator: Metin Amiroff \n" "Language-Team: Azerbaijani \n" @@ -16,89 +16,85 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "X-Generator: KBabel 1.0.2\n" -#: gst/gst.c:160 +#: gst/gst.c:157 msgid "Print the GStreamer version" msgstr "GStreamer buraxılışını göstÉ™r" -#: gst/gst.c:162 +#: gst/gst.c:159 msgid "Make all warnings fatal" msgstr "Bütün xÉ™taları ölümcül et" -#: gst/gst.c:166 +#: gst/gst.c:163 msgid "Print available debug categories and exit" msgstr "" -#: gst/gst.c:169 +#: gst/gst.c:166 msgid "" "Default debug level from 1 (only error) to 5 (anything) or 0 for no output" msgstr "" -#: gst/gst.c:171 +#: gst/gst.c:168 msgid "LEVEL" msgstr "SÆVÄ°YYÆ" -#: gst/gst.c:173 +#: gst/gst.c:170 msgid "" "Comma-separated list of category_name:level pairs to set specific levels for " "the individual categories. Example: GST_AUTOPLUG:5,GST_ELEMENT_*:3" msgstr "" -#: gst/gst.c:176 +#: gst/gst.c:173 msgid "LIST" msgstr "SÄ°YAHI" -#: gst/gst.c:178 +#: gst/gst.c:175 msgid "Disable colored debugging output" msgstr "" -#: gst/gst.c:180 +#: gst/gst.c:177 msgid "Disable debugging" msgstr "XÉ™ta ayırmasını baÄŸla" -#: gst/gst.c:184 -msgid "Disable accelerated CPU instructions" -msgstr "" - -#: gst/gst.c:186 +#: gst/gst.c:181 msgid "Enable verbose plugin loading diagnostics" msgstr "" -#: gst/gst.c:188 +#: gst/gst.c:183 msgid "PATHS" msgstr "CIÄžIRLAR" -#: gst/gst.c:191 +#: gst/gst.c:186 msgid "" "Comma-separated list of plugins to preload in addition to the list stored in " "environment variable GST_PLUGIN_PATH" msgstr "" -#: gst/gst.c:193 +#: gst/gst.c:188 msgid "PLUGINS" msgstr "ÆLAVÆLÆR" -#: gst/gst.c:196 +#: gst/gst.c:191 msgid "Disable trapping of segmentation faults during plugin loading" msgstr "" -#: gst/gst.c:199 +#: gst/gst.c:194 msgid "SCHEDULER" msgstr "VAXTLAÅžDIRICI" -#: gst/gst.c:201 +#: gst/gst.c:196 msgid "Registry to use" msgstr "Ä°ÅŸlÉ™dilÉ™cÉ™k qeyd bazası" -#: gst/gst.c:201 +#: gst/gst.c:196 msgid "REGISTRY" msgstr "QEYDBAZASI" -#: gst/gst.c:214 +#: gst/gst.c:209 #, c-format msgid "path list for loading plugins (separated by '%s')" msgstr "" -#: gst/gst.c:218 +#: gst/gst.c:213 #, c-format msgid "Scheduler to use (default is '%s')" msgstr "" @@ -563,51 +559,46 @@ msgstr "" msgid ", " msgstr ", " -#: gst/autoplug/gstspider.c:466 -#, c-format -msgid "There is no element present to handle the stream's mime type %s." -msgstr "" - -#: gst/elements/gstfilesink.c:268 +#: gst/elements/gstfilesink.c:243 msgid "No file name specified for writing." msgstr "" -#: gst/elements/gstfilesink.c:275 +#: gst/elements/gstfilesink.c:250 #, c-format msgid "Could not open file \"%s\" for writing." msgstr "" -#: gst/elements/gstfilesink.c:294 +#: gst/elements/gstfilesink.c:269 #, c-format msgid "Error closing file \"%s\"." msgstr "" -#: gst/elements/gstfilesink.c:364 gst/elements/gstfilesink.c:400 -#: gst/elements/gstfilesink.c:453 +#: gst/elements/gstfilesink.c:339 gst/elements/gstfilesink.c:375 +#: gst/elements/gstfilesink.c:428 #, c-format msgid "Error while writing to file \"%s\"." msgstr "" -#: gst/elements/gstfilesrc.c:764 gst/elements/gstmultifilesrc.c:298 +#: gst/elements/gstfilesrc.c:725 msgid "No file name specified for reading." msgstr "" -#: gst/elements/gstfilesrc.c:779 gst/elements/gstmultifilesrc.c:306 +#: gst/elements/gstfilesrc.c:740 #, c-format msgid "Could not open file \"%s\" for reading." msgstr "" -#: gst/elements/gstfilesrc.c:790 +#: gst/elements/gstfilesrc.c:751 #, c-format msgid "\"%s\" is a directory." msgstr "" -#: gst/elements/gstfilesrc.c:796 +#: gst/elements/gstfilesrc.c:757 #, c-format msgid "File \"%s\" is a socket." msgstr "" -#: gst/elements/gstidentity.c:306 +#: gst/elements/gstidentity.c:276 msgid "Failed after iterations as requested." msgstr "" @@ -695,122 +686,78 @@ msgstr "" msgid "empty pipeline not allowed" msgstr "" -#: tools/gst-inspect.c:1151 +#: tools/gst-inspect.c:1032 msgid "Print all elements" msgstr "" -#: tools/gst-launch.c:114 -#, c-format -msgid "" -"Execution ended after %s iterations (sum %s ns, average %s ns, min %s ns, " -"max %s ns).\n" -msgstr "" - -#: tools/gst-launch.c:141 -msgid "Usage: gst-xmllaunch [ element.property=value ... ]\n" -msgstr "" - -#: tools/gst-launch.c:149 -#, c-format -msgid "ERROR: parse of xml file '%s' failed.\n" -msgstr "" - -#: tools/gst-launch.c:155 -#, c-format -msgid "ERROR: no toplevel pipeline element in file '%s'.\n" -msgstr "" - -#: tools/gst-launch.c:162 -#, c-format -msgid "WARNING: only one toplevel element is supported at this time." -msgstr "" - -#: tools/gst-launch.c:173 -#, c-format -msgid "ERROR: could not parse command line argument %d: %s.\n" -msgstr "" - -#: tools/gst-launch.c:184 -#, c-format -msgid "WARNING: element named '%s' not found.\n" -msgstr "" - -#: tools/gst-launch.c:327 +#: tools/gst-launch.c:190 #, c-format msgid "FOUND TAG : found by element \"%s\".\n" msgstr "" -#: tools/gst-launch.c:412 +#: tools/gst-launch.c:304 msgid "Output tags (also known as metadata)" msgstr "" -#: tools/gst-launch.c:414 +#: tools/gst-launch.c:306 msgid "Output status information and property notifications" msgstr "" -#: tools/gst-launch.c:416 +#: tools/gst-launch.c:308 msgid "Do not output status information of TYPE" msgstr "" -#: tools/gst-launch.c:416 +#: tools/gst-launch.c:308 msgid "TYPE1,TYPE2,..." msgstr "" -#: tools/gst-launch.c:419 -msgid "Save xml representation of pipeline to FILE and exit" -msgstr "" - -#: tools/gst-launch.c:419 -msgid "FILE" -msgstr "FAYL" - -#: tools/gst-launch.c:422 +#: tools/gst-launch.c:310 msgid "Do not install a fault handler" msgstr "" -#: tools/gst-launch.c:424 +#: tools/gst-launch.c:312 msgid "Print alloc trace (if enabled at compile time)" msgstr "" -#: tools/gst-launch.c:426 +#: tools/gst-launch.c:314 msgid "Number of times to iterate pipeline" msgstr "" -#: tools/gst-launch.c:496 +#: tools/gst-launch.c:379 #, c-format msgid "ERROR: pipeline could not be constructed: %s.\n" msgstr "" -#: tools/gst-launch.c:500 -#, c-format +#: tools/gst-launch.c:383 msgid "ERROR: pipeline could not be constructed.\n" msgstr "" -#: tools/gst-launch.c:504 +#: tools/gst-launch.c:387 #, c-format msgid "WARNING: erroneous pipeline: %s\n" msgstr "" -#: tools/gst-launch.c:505 -#, c-format +#: tools/gst-launch.c:388 msgid " Trying to run anyway.\n" msgstr "" -#: tools/gst-launch.c:532 -#, c-format +#: tools/gst-launch.c:408 msgid "ERROR: the 'pipeline' element wasn't found.\n" msgstr "" -#: tools/gst-launch.c:539 -#, c-format +#: tools/gst-launch.c:417 msgid "RUNNING pipeline ...\n" msgstr "" -#: tools/gst-launch.c:542 -#, c-format +#: tools/gst-launch.c:421 msgid "ERROR: pipeline doesn't want to play.\n" msgstr "" +#: tools/gst-launch.c:445 +#, c-format +msgid "Execution ended after %.2fs (%.2fs or %.2f%% idling).\n" +msgstr "" + #: tools/gst-register.c:49 #, c-format msgid "Added plugin %s with %d feature.\n" @@ -845,5 +792,8 @@ msgid_plural "Loaded %d plugins with %d features.\n" msgstr[0] "" msgstr[1] "" +#~ msgid "FILE" +#~ msgstr "FAYL" + #~ msgid "')" #~ msgstr "')" diff --git a/po/ca.po b/po/ca.po index 2ebbb790c0..ec17073463 100644 --- a/po/ca.po +++ b/po/ca.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: gstreamer 0.8.7pre2\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2005-05-02 19:36+0200\n" +"POT-Creation-Date: 2005-05-17 18:37+0200\n" "PO-Revision-Date: 2004-12-22 17:44+0100\n" "Last-Translator: Jordi Mallach \n" "Language-Team: Catalan \n" @@ -16,30 +16,30 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n!=1;\n" -#: gst/gst.c:160 +#: gst/gst.c:157 msgid "Print the GStreamer version" msgstr "Imprimeix la versió de GStreamer" -#: gst/gst.c:162 +#: gst/gst.c:159 msgid "Make all warnings fatal" msgstr "Fes fatals tots els avisos" -#: gst/gst.c:166 +#: gst/gst.c:163 msgid "Print available debug categories and exit" msgstr "Imprimeix les categories de depuració disponibles i surt" -#: gst/gst.c:169 +#: gst/gst.c:166 msgid "" "Default debug level from 1 (only error) to 5 (anything) or 0 for no output" msgstr "" "Nivell de depuració per defecte des de 1 (només errors) a 5 (tot) o 0 per a " "cap sortida" -#: gst/gst.c:171 +#: gst/gst.c:168 msgid "LEVEL" msgstr "NIVELL" -#: gst/gst.c:173 +#: gst/gst.c:170 msgid "" "Comma-separated list of category_name:level pairs to set specific levels for " "the individual categories. Example: GST_AUTOPLUG:5,GST_ELEMENT_*:3" @@ -48,31 +48,27 @@ msgstr "" "nivells específics per a les categories individuals. Per exemple: " "GST_AUTOPLUG:5, GST_ELEMENT_*:3" -#: gst/gst.c:176 +#: gst/gst.c:173 msgid "LIST" msgstr "LLISTA" -#: gst/gst.c:178 +#: gst/gst.c:175 msgid "Disable colored debugging output" msgstr "Inhabilita la sortida de depuració colorejada" -#: gst/gst.c:180 +#: gst/gst.c:177 msgid "Disable debugging" msgstr "Inhabilita la depuració" -#: gst/gst.c:184 -msgid "Disable accelerated CPU instructions" -msgstr "Inhabilita les intruccions d'UCP accelerades" - -#: gst/gst.c:186 +#: gst/gst.c:181 msgid "Enable verbose plugin loading diagnostics" msgstr "Habilita els diagnòstics detallats de càrrega de connectors" -#: gst/gst.c:188 +#: gst/gst.c:183 msgid "PATHS" msgstr "CAMINS" -#: gst/gst.c:191 +#: gst/gst.c:186 #, fuzzy msgid "" "Comma-separated list of plugins to preload in addition to the list stored in " @@ -81,34 +77,34 @@ msgstr "" "Llista separada per comes de connectors a precarregar a més de la llista " "emmagatzemada en la variable d'entorn GST_PLUGIN_PATH" -#: gst/gst.c:193 +#: gst/gst.c:188 msgid "PLUGINS" msgstr "CONNECTORS" -#: gst/gst.c:196 +#: gst/gst.c:191 msgid "Disable trapping of segmentation faults during plugin loading" msgstr "" "Inhabilita la captura de violacions de segment durant la càrrega de " "connectors" -#: gst/gst.c:199 +#: gst/gst.c:194 msgid "SCHEDULER" msgstr "PLANIFICADOR" -#: gst/gst.c:201 +#: gst/gst.c:196 msgid "Registry to use" msgstr "Registre a utilitzar" -#: gst/gst.c:201 +#: gst/gst.c:196 msgid "REGISTRY" msgstr "REGISTRE" -#: gst/gst.c:214 +#: gst/gst.c:209 #, c-format msgid "path list for loading plugins (separated by '%s')" msgstr "llista de camins per a carregar connectors (separats per «%s»)" -#: gst/gst.c:218 +#: gst/gst.c:213 #, c-format msgid "Scheduler to use (default is '%s')" msgstr "Planificador a utilitzar (per defecte és «%s»)" @@ -605,52 +601,46 @@ msgstr "" msgid ", " msgstr ", " -#: gst/autoplug/gstspider.c:466 -#, c-format -msgid "There is no element present to handle the stream's mime type %s." -msgstr "" -"No hi ha cap element present per a gestionar el tipus mime %s del flux." - -#: gst/elements/gstfilesink.c:268 +#: gst/elements/gstfilesink.c:243 msgid "No file name specified for writing." msgstr "No s'ha especificat cap nom de fitxer per a l'escriptura." -#: gst/elements/gstfilesink.c:275 +#: gst/elements/gstfilesink.c:250 #, c-format msgid "Could not open file \"%s\" for writing." msgstr "No s'ha pogut obrir «%s» per a l'escriptura." -#: gst/elements/gstfilesink.c:294 +#: gst/elements/gstfilesink.c:269 #, c-format msgid "Error closing file \"%s\"." msgstr "S'ha produït un error en tancar el fitxer «%s»." -#: gst/elements/gstfilesink.c:364 gst/elements/gstfilesink.c:400 -#: gst/elements/gstfilesink.c:453 +#: gst/elements/gstfilesink.c:339 gst/elements/gstfilesink.c:375 +#: gst/elements/gstfilesink.c:428 #, c-format msgid "Error while writing to file \"%s\"." msgstr "S'ha produït un error en escriure al fitxer «%s»." -#: gst/elements/gstfilesrc.c:764 gst/elements/gstmultifilesrc.c:298 +#: gst/elements/gstfilesrc.c:725 msgid "No file name specified for reading." msgstr "No s'ha especificat cap fitxer per a llegir." -#: gst/elements/gstfilesrc.c:779 gst/elements/gstmultifilesrc.c:306 +#: gst/elements/gstfilesrc.c:740 #, c-format msgid "Could not open file \"%s\" for reading." msgstr "No s'ha pogut obrir el fitxer «%s» per a la lectura." -#: gst/elements/gstfilesrc.c:790 +#: gst/elements/gstfilesrc.c:751 #, c-format msgid "\"%s\" is a directory." msgstr "«%s» és un directori." -#: gst/elements/gstfilesrc.c:796 +#: gst/elements/gstfilesrc.c:757 #, c-format msgid "File \"%s\" is a socket." msgstr "El fitxer «%s» és un sòcol." -#: gst/elements/gstidentity.c:306 +#: gst/elements/gstidentity.c:276 msgid "Failed after iterations as requested." msgstr "Ha fallat després de les iteracions com s'ha demanat." @@ -739,125 +729,78 @@ msgstr "No s'ha pogut enllaçar l'element de sortida per a l'URI «%s»" msgid "empty pipeline not allowed" msgstr "no es permet un conducte buit" -#: tools/gst-inspect.c:1151 +#: tools/gst-inspect.c:1032 msgid "Print all elements" msgstr "Imprimeix tots els elements" -#: tools/gst-launch.c:114 -#, c-format -msgid "" -"Execution ended after %s iterations (sum %s ns, average %s ns, min %s ns, " -"max %s ns).\n" -msgstr "" -"L'execució ha finalitzat després de %s iteracions (suma %s ns, mitja %s ns, " -"mín %s, màx %s).\n" - -#: tools/gst-launch.c:141 -msgid "Usage: gst-xmllaunch [ element.property=value ... ]\n" -msgstr "Forma d'ús: gst-xmllaunch [ element.propietat=valor ... ]\n" - -#: tools/gst-launch.c:149 -#, c-format -msgid "ERROR: parse of xml file '%s' failed.\n" -msgstr "ERROR: l'anàlisi del fitxer xml «%s» ha fallat.\n" - -#: tools/gst-launch.c:155 -#, c-format -msgid "ERROR: no toplevel pipeline element in file '%s'.\n" -msgstr "ERROR: no hi ha cap conducte de nivell superior en el fitxer «%s».\n" - -#: tools/gst-launch.c:162 -#, c-format -msgid "WARNING: only one toplevel element is supported at this time." -msgstr "AVÃS: només es gestiona un element de primer nivell ara mateix." - -#: tools/gst-launch.c:173 -#, c-format -msgid "ERROR: could not parse command line argument %d: %s.\n" -msgstr "" -"ERROR: no s'ha pogut analitzar l'argument de la línia d'ordres %d: %s.\n" - -#: tools/gst-launch.c:184 -#, c-format -msgid "WARNING: element named '%s' not found.\n" -msgstr "AVÃS: no s'ha trobat l'element anomenat «%s».\n" - -#: tools/gst-launch.c:327 +#: tools/gst-launch.c:190 #, c-format msgid "FOUND TAG : found by element \"%s\".\n" msgstr "MARCADOR TROBAT: trobat per l'element «%s».\n" -#: tools/gst-launch.c:412 +#: tools/gst-launch.c:304 msgid "Output tags (also known as metadata)" msgstr "Mostra els marcadors (també coneguts com metadades)" -#: tools/gst-launch.c:414 +#: tools/gst-launch.c:306 msgid "Output status information and property notifications" msgstr "Mostra la informació d'estat i notificacions de propietats" -#: tools/gst-launch.c:416 +#: tools/gst-launch.c:308 msgid "Do not output status information of TYPE" msgstr "No mostres informació d'estat de TIPUS" -#: tools/gst-launch.c:416 +#: tools/gst-launch.c:308 msgid "TYPE1,TYPE2,..." msgstr "TIPUS1,TIPUS2,..." -#: tools/gst-launch.c:419 -msgid "Save xml representation of pipeline to FILE and exit" -msgstr "Desa la representació xml del conducte a FITXER i surt" - -#: tools/gst-launch.c:419 -msgid "FILE" -msgstr "FITXER" - -#: tools/gst-launch.c:422 +#: tools/gst-launch.c:310 msgid "Do not install a fault handler" msgstr "No instal·les un gestor de fallades" -#: tools/gst-launch.c:424 +#: tools/gst-launch.c:312 msgid "Print alloc trace (if enabled at compile time)" msgstr "Imprimeix una traça d'alloc (si s'ha habilitat al compilar)" -#: tools/gst-launch.c:426 +#: tools/gst-launch.c:314 msgid "Number of times to iterate pipeline" msgstr "Nombre de vegades a iterar el conducte" -#: tools/gst-launch.c:496 +#: tools/gst-launch.c:379 #, c-format msgid "ERROR: pipeline could not be constructed: %s.\n" msgstr "ERROR: no s'ha pogut construir el conducte: %s.\n" -#: tools/gst-launch.c:500 -#, c-format +#: tools/gst-launch.c:383 msgid "ERROR: pipeline could not be constructed.\n" msgstr "ERROR: no s'ha pogut construir el conducte.\n" -#: tools/gst-launch.c:504 +#: tools/gst-launch.c:387 #, c-format msgid "WARNING: erroneous pipeline: %s\n" msgstr "AVÃS: el conducte és erroni: %s\n" -#: tools/gst-launch.c:505 -#, c-format +#: tools/gst-launch.c:388 msgid " Trying to run anyway.\n" msgstr " S'està intentant executar tot i així.\n" -#: tools/gst-launch.c:532 -#, c-format +#: tools/gst-launch.c:408 msgid "ERROR: the 'pipeline' element wasn't found.\n" msgstr "ERROR: l'element «conducte» no s'ha trobat.\n" -#: tools/gst-launch.c:539 -#, c-format +#: tools/gst-launch.c:417 msgid "RUNNING pipeline ...\n" msgstr "S'ESTÀ EXECUTANT el conducte ...\n" -#: tools/gst-launch.c:542 -#, c-format +#: tools/gst-launch.c:421 msgid "ERROR: pipeline doesn't want to play.\n" msgstr "ERROR: el conducte no vol reproduir-se.\n" +#: tools/gst-launch.c:445 +#, c-format +msgid "Execution ended after %.2fs (%.2fs or %.2f%% idling).\n" +msgstr "" + #: tools/gst-register.c:49 #, fuzzy, c-format msgid "Added plugin %s with %d feature.\n" @@ -892,6 +835,47 @@ msgid_plural "Loaded %d plugins with %d features.\n" msgstr[0] "S'han carregat %d connectors amb %d %s.\n" msgstr[1] "S'han carregat %d connectors amb %d %s.\n" +#~ msgid "Disable accelerated CPU instructions" +#~ msgstr "Inhabilita les intruccions d'UCP accelerades" + +#~ msgid "There is no element present to handle the stream's mime type %s." +#~ msgstr "" +#~ "No hi ha cap element present per a gestionar el tipus mime %s del flux." + +#~ msgid "" +#~ "Execution ended after %s iterations (sum %s ns, average %s ns, min %s ns, " +#~ "max %s ns).\n" +#~ msgstr "" +#~ "L'execució ha finalitzat després de %s iteracions (suma %s ns, mitja %s " +#~ "ns, mín %s, màx %s).\n" + +#~ msgid "Usage: gst-xmllaunch [ element.property=value ... ]\n" +#~ msgstr "" +#~ "Forma d'ús: gst-xmllaunch [ element.propietat=valor ... ]\n" + +#~ msgid "ERROR: parse of xml file '%s' failed.\n" +#~ msgstr "ERROR: l'anàlisi del fitxer xml «%s» ha fallat.\n" + +#~ msgid "ERROR: no toplevel pipeline element in file '%s'.\n" +#~ msgstr "" +#~ "ERROR: no hi ha cap conducte de nivell superior en el fitxer «%s».\n" + +#~ msgid "WARNING: only one toplevel element is supported at this time." +#~ msgstr "AVÃS: només es gestiona un element de primer nivell ara mateix." + +#~ msgid "ERROR: could not parse command line argument %d: %s.\n" +#~ msgstr "" +#~ "ERROR: no s'ha pogut analitzar l'argument de la línia d'ordres %d: %s.\n" + +#~ msgid "WARNING: element named '%s' not found.\n" +#~ msgstr "AVÃS: no s'ha trobat l'element anomenat «%s».\n" + +#~ msgid "Save xml representation of pipeline to FILE and exit" +#~ msgstr "Desa la representació xml del conducte a FITXER i surt" + +#~ msgid "FILE" +#~ msgstr "FITXER" + #~ msgid "caps" #~ msgstr "capacitats" diff --git a/po/cs.po b/po/cs.po index db3921d9eb..0e413d688e 100644 --- a/po/cs.po +++ b/po/cs.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: gstreamer 0.8.8\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2005-05-02 19:36+0200\n" +"POT-Creation-Date: 2005-05-17 18:37+0200\n" "PO-Revision-Date: 2005-04-15 14:36+0200\n" "Last-Translator: Miloslav Trmac \n" "Language-Team: Czech \n" @@ -18,29 +18,29 @@ msgstr "" "Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%" "10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" -#: gst/gst.c:160 +#: gst/gst.c:157 msgid "Print the GStreamer version" msgstr "Vypsat verzi GStreamer" -#: gst/gst.c:162 +#: gst/gst.c:159 msgid "Make all warnings fatal" msgstr "Chápat vÅ¡echna varování jako fatální" -#: gst/gst.c:166 +#: gst/gst.c:163 msgid "Print available debug categories and exit" msgstr "Vypsat dostupné kategorie ladÄ›ní a skonÄit" -#: gst/gst.c:169 +#: gst/gst.c:166 msgid "" "Default debug level from 1 (only error) to 5 (anything) or 0 for no output" msgstr "" "Implicitní úroveň ladÄ›ní od 1 (jen chyby) do 5 (vÅ¡e) nebo 0 pro žádný výstup" -#: gst/gst.c:171 +#: gst/gst.c:168 msgid "LEVEL" msgstr "ÚROVEŇ" -#: gst/gst.c:173 +#: gst/gst.c:170 msgid "" "Comma-separated list of category_name:level pairs to set specific levels for " "the individual categories. Example: GST_AUTOPLUG:5,GST_ELEMENT_*:3" @@ -49,31 +49,27 @@ msgstr "" "konkrétních úrovní pro jednotlivé kategorie. Příklad: GST_AUTOPLUG:5," "GST_ELEMENT_*:3" -#: gst/gst.c:176 +#: gst/gst.c:173 msgid "LIST" msgstr "SEZNAM" -#: gst/gst.c:178 +#: gst/gst.c:175 msgid "Disable colored debugging output" msgstr "Zakázat obarvený ladicí výstup" -#: gst/gst.c:180 +#: gst/gst.c:177 msgid "Disable debugging" msgstr "Zakázat ladÄ›ní" -#: gst/gst.c:184 -msgid "Disable accelerated CPU instructions" -msgstr "Zakázat akcelerované instrukce CPU" - -#: gst/gst.c:186 +#: gst/gst.c:181 msgid "Enable verbose plugin loading diagnostics" msgstr "Povolit podrobnou diagnostiku naÄítání modulů" -#: gst/gst.c:188 +#: gst/gst.c:183 msgid "PATHS" msgstr "CESTY" -#: gst/gst.c:191 +#: gst/gst.c:186 #, fuzzy msgid "" "Comma-separated list of plugins to preload in addition to the list stored in " @@ -82,32 +78,32 @@ msgstr "" "Čárkami oddÄ›lený seznam modulů, které pÅ™ednaÄíst kromÄ› seznamu uloženém v " "promÄ›nné prostÅ™edí GST_PLUGIN_PATH" -#: gst/gst.c:193 +#: gst/gst.c:188 msgid "PLUGINS" msgstr "MODULY" -#: gst/gst.c:196 +#: gst/gst.c:191 msgid "Disable trapping of segmentation faults during plugin loading" msgstr "Zakázat zachycování poruÅ¡ení segmentace pÅ™i naÄítání modulů" -#: gst/gst.c:199 +#: gst/gst.c:194 msgid "SCHEDULER" msgstr "PLÃNOVAÄŒ" -#: gst/gst.c:201 +#: gst/gst.c:196 msgid "Registry to use" msgstr "Registr, který používat" -#: gst/gst.c:201 +#: gst/gst.c:196 msgid "REGISTRY" msgstr "REGISTR" -#: gst/gst.c:214 +#: gst/gst.c:209 #, c-format msgid "path list for loading plugins (separated by '%s')" msgstr "seznam cest pro naÄítání modulů (oddÄ›lený '%s')" -#: gst/gst.c:218 +#: gst/gst.c:213 #, c-format msgid "Scheduler to use (default is '%s')" msgstr "PlánovaÄ, který používat (implicitní je '%s')" @@ -581,51 +577,46 @@ msgstr "" msgid ", " msgstr ", " -#: gst/autoplug/gstspider.c:466 -#, c-format -msgid "There is no element present to handle the stream's mime type %s." -msgstr "Není přítomen žádý element pro obsloužení proudu s typem mime %s." - -#: gst/elements/gstfilesink.c:268 +#: gst/elements/gstfilesink.c:243 msgid "No file name specified for writing." msgstr "Nezadán název souboru pro zápis." -#: gst/elements/gstfilesink.c:275 +#: gst/elements/gstfilesink.c:250 #, c-format msgid "Could not open file \"%s\" for writing." msgstr "Nemohu otevřít soubor \"%s\" pro zápis." -#: gst/elements/gstfilesink.c:294 +#: gst/elements/gstfilesink.c:269 #, c-format msgid "Error closing file \"%s\"." msgstr "Chyba pÅ™i zavírání souboru \"%s\"." -#: gst/elements/gstfilesink.c:364 gst/elements/gstfilesink.c:400 -#: gst/elements/gstfilesink.c:453 +#: gst/elements/gstfilesink.c:339 gst/elements/gstfilesink.c:375 +#: gst/elements/gstfilesink.c:428 #, c-format msgid "Error while writing to file \"%s\"." msgstr "Chyba pÅ™i zápisu do souboru \"%s\"." -#: gst/elements/gstfilesrc.c:764 gst/elements/gstmultifilesrc.c:298 +#: gst/elements/gstfilesrc.c:725 msgid "No file name specified for reading." msgstr "Nezadán název souboru pro Ätení." -#: gst/elements/gstfilesrc.c:779 gst/elements/gstmultifilesrc.c:306 +#: gst/elements/gstfilesrc.c:740 #, c-format msgid "Could not open file \"%s\" for reading." msgstr "Nemohu otevřít soubor \"%s\" pro Ätení." -#: gst/elements/gstfilesrc.c:790 +#: gst/elements/gstfilesrc.c:751 #, c-format msgid "\"%s\" is a directory." msgstr "\"%s\" je adresář." -#: gst/elements/gstfilesrc.c:796 +#: gst/elements/gstfilesrc.c:757 #, c-format msgid "File \"%s\" is a socket." msgstr "Soubor \"%s\" je socket." -#: gst/elements/gstidentity.c:306 +#: gst/elements/gstidentity.c:276 msgid "Failed after iterations as requested." msgstr "Selhání po iteracích podle požadavku." @@ -714,127 +705,79 @@ msgstr "nemohu pÅ™ipojit element spotÅ™ebiÄe pro URI \"%s\"" msgid "empty pipeline not allowed" msgstr "prázdná roura není povolena" -#: tools/gst-inspect.c:1151 +#: tools/gst-inspect.c:1032 msgid "Print all elements" msgstr "Vypsat vÅ¡echny elementy" -#: tools/gst-launch.c:114 -#, c-format -msgid "" -"Execution ended after %s iterations (sum %s ns, average %s ns, min %s ns, " -"max %s ns).\n" -msgstr "" -"ProvádÄ›ní skonÄilo po %s iteracích (celkem %s ns, průmÄ›r %s ns, min %s ns, " -"max %s ns).\n" - -#: tools/gst-launch.c:141 -msgid "Usage: gst-xmllaunch [ element.property=value ... ]\n" -msgstr "" -"Použití: gst-xmllaunch [ element.vlastnost=hodnota ... ]\n" - -#: tools/gst-launch.c:149 -#, c-format -msgid "ERROR: parse of xml file '%s' failed.\n" -msgstr "CHYBA: zpracovávání xml souboru '%s' selhalo.\n" - -#: tools/gst-launch.c:155 -#, c-format -msgid "ERROR: no toplevel pipeline element in file '%s'.\n" -msgstr "CHYBA: v souboru '%s' není element nejvyšší úrovnÄ› pipeline.\n" - -#: tools/gst-launch.c:162 -#, c-format -msgid "WARNING: only one toplevel element is supported at this time." -msgstr "" -"VAROVÃNÃ: v souÄasné dobÄ› je podporován jen jeden element nejvyšší úrovnÄ›." - -#: tools/gst-launch.c:173 -#, c-format -msgid "ERROR: could not parse command line argument %d: %s.\n" -msgstr "CHYBA: nemohu zpracovat argument %d na příkazovém řádku: %s.\n" - -#: tools/gst-launch.c:184 -#, c-format -msgid "WARNING: element named '%s' not found.\n" -msgstr "VAROVÃNÃ: element nazvaný '%s' nenalezen.\n" - -#: tools/gst-launch.c:327 +#: tools/gst-launch.c:190 #, c-format msgid "FOUND TAG : found by element \"%s\".\n" msgstr "NALEZEN TAG : nalezen elementem \"%s\".\n" -#: tools/gst-launch.c:412 +#: tools/gst-launch.c:304 msgid "Output tags (also known as metadata)" msgstr "Vypsat tagy (také známé jako metadata)" -#: tools/gst-launch.c:414 +#: tools/gst-launch.c:306 msgid "Output status information and property notifications" msgstr "Vypsat informace o stavu a upozornÄ›ní na vlastnosti" -#: tools/gst-launch.c:416 +#: tools/gst-launch.c:308 msgid "Do not output status information of TYPE" msgstr "Nevypisovat informace o stavu s TYPEM" -#: tools/gst-launch.c:416 +#: tools/gst-launch.c:308 msgid "TYPE1,TYPE2,..." msgstr "TYP1,TYP2,..." -#: tools/gst-launch.c:419 -msgid "Save xml representation of pipeline to FILE and exit" -msgstr "Uložit reprezentaci roury v xml do SOUBORu a skonÄit" - -#: tools/gst-launch.c:419 -msgid "FILE" -msgstr "SOUBOR" - -#: tools/gst-launch.c:422 +#: tools/gst-launch.c:310 msgid "Do not install a fault handler" msgstr "Neinstalovat obsluhu výjimek" -#: tools/gst-launch.c:424 +#: tools/gst-launch.c:312 msgid "Print alloc trace (if enabled at compile time)" msgstr "Vypisovat stopu alokace (je-li povoleno pÅ™i kompilaci)" -#: tools/gst-launch.c:426 +#: tools/gst-launch.c:314 msgid "Number of times to iterate pipeline" msgstr "Kolikrát iterovat rouru" -#: tools/gst-launch.c:496 +#: tools/gst-launch.c:379 #, c-format msgid "ERROR: pipeline could not be constructed: %s.\n" msgstr "CHYBA: nelze vytvoÅ™it rouru: %s.\n" -#: tools/gst-launch.c:500 -#, c-format +#: tools/gst-launch.c:383 msgid "ERROR: pipeline could not be constructed.\n" msgstr "CHYBA: nelze vytvoÅ™it rouru.\n" -#: tools/gst-launch.c:504 +#: tools/gst-launch.c:387 #, c-format msgid "WARNING: erroneous pipeline: %s\n" msgstr "VAROVÃNÃ: chybná roura: %s\n" -#: tools/gst-launch.c:505 -#, c-format +#: tools/gst-launch.c:388 msgid " Trying to run anyway.\n" msgstr " PÅ™esto se ji pokouším spustit.\n" -#: tools/gst-launch.c:532 -#, c-format +#: tools/gst-launch.c:408 msgid "ERROR: the 'pipeline' element wasn't found.\n" msgstr "CHYBA: element 'pipeline' nebyl nalezen.\n" -#: tools/gst-launch.c:539 -#, c-format +#: tools/gst-launch.c:417 msgid "RUNNING pipeline ...\n" msgstr "SPOUÅ TÃM rouru ...\n" # On strike? -#: tools/gst-launch.c:542 -#, c-format +#: tools/gst-launch.c:421 msgid "ERROR: pipeline doesn't want to play.\n" msgstr "CHYBA: roura nechce hrát.\n" +#: tools/gst-launch.c:445 +#, c-format +msgid "Execution ended after %.2fs (%.2fs or %.2f%% idling).\n" +msgstr "" + #: tools/gst-register.c:49 #, fuzzy, c-format msgid "Added plugin %s with %d feature.\n" @@ -871,6 +814,45 @@ msgstr[0] "NaÄteno %d modulů s %d %s.\n" msgstr[1] "NaÄteno %d modulů s %d %s.\n" msgstr[2] "NaÄteno %d modulů s %d %s.\n" +#~ msgid "Disable accelerated CPU instructions" +#~ msgstr "Zakázat akcelerované instrukce CPU" + +#~ msgid "There is no element present to handle the stream's mime type %s." +#~ msgstr "Není přítomen žádý element pro obsloužení proudu s typem mime %s." + +#~ msgid "" +#~ "Execution ended after %s iterations (sum %s ns, average %s ns, min %s ns, " +#~ "max %s ns).\n" +#~ msgstr "" +#~ "ProvádÄ›ní skonÄilo po %s iteracích (celkem %s ns, průmÄ›r %s ns, min %s " +#~ "ns, max %s ns).\n" + +#~ msgid "Usage: gst-xmllaunch [ element.property=value ... ]\n" +#~ msgstr "" +#~ "Použití: gst-xmllaunch [ element.vlastnost=hodnota ... ]\n" + +#~ msgid "ERROR: parse of xml file '%s' failed.\n" +#~ msgstr "CHYBA: zpracovávání xml souboru '%s' selhalo.\n" + +#~ msgid "ERROR: no toplevel pipeline element in file '%s'.\n" +#~ msgstr "CHYBA: v souboru '%s' není element nejvyšší úrovnÄ› pipeline.\n" + +#~ msgid "WARNING: only one toplevel element is supported at this time." +#~ msgstr "" +#~ "VAROVÃNÃ: v souÄasné dobÄ› je podporován jen jeden element nejvyšší úrovnÄ›." + +#~ msgid "ERROR: could not parse command line argument %d: %s.\n" +#~ msgstr "CHYBA: nemohu zpracovat argument %d na příkazovém řádku: %s.\n" + +#~ msgid "WARNING: element named '%s' not found.\n" +#~ msgstr "VAROVÃNÃ: element nazvaný '%s' nenalezen.\n" + +#~ msgid "Save xml representation of pipeline to FILE and exit" +#~ msgstr "Uložit reprezentaci roury v xml do SOUBORu a skonÄit" + +#~ msgid "FILE" +#~ msgstr "SOUBOR" + #~ msgid "caps" #~ msgstr "schopnosti" diff --git a/po/de.po b/po/de.po index d4b71593e5..50065c4541 100644 --- a/po/de.po +++ b/po/de.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: gstreamer 0.8.1\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2005-05-02 19:36+0200\n" +"POT-Creation-Date: 2005-05-17 18:37+0200\n" "PO-Revision-Date: 2004-06-05 09:32+0100\n" "Last-Translator: Roland Illig \n" "Language-Team: German \n" @@ -15,30 +15,30 @@ msgstr "" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" -#: gst/gst.c:160 +#: gst/gst.c:157 msgid "Print the GStreamer version" msgstr "Die Version von GStreamer ausgeben" -#: gst/gst.c:162 +#: gst/gst.c:159 msgid "Make all warnings fatal" msgstr "Alle Warnungen wie Fehler behandeln" -#: gst/gst.c:166 +#: gst/gst.c:163 msgid "Print available debug categories and exit" msgstr "Verfügbare Debuggingkategorien ausgeben und Programm beenden" -#: gst/gst.c:169 +#: gst/gst.c:166 msgid "" "Default debug level from 1 (only error) to 5 (anything) or 0 for no output" msgstr "" "Standarddebugginglevel von 1 (nur Fehler) bis 5 (Alles) oder 0 für keine " "Ausgabe" -#: gst/gst.c:171 +#: gst/gst.c:168 msgid "LEVEL" msgstr "LEVEL" -#: gst/gst.c:173 +#: gst/gst.c:170 msgid "" "Comma-separated list of category_name:level pairs to set specific levels for " "the individual categories. Example: GST_AUTOPLUG:5,GST_ELEMENT_*:3" @@ -47,31 +47,27 @@ msgstr "" "Meldungsarten individuelle Level zuzuordnen. Beispiel: GST_AUTOPLUG:5," "GST_ELEMENT_*:3" -#: gst/gst.c:176 +#: gst/gst.c:173 msgid "LIST" msgstr "LIST" -#: gst/gst.c:178 +#: gst/gst.c:175 msgid "Disable colored debugging output" msgstr "Farbige Debuggingausgabe deaktivieren" -#: gst/gst.c:180 +#: gst/gst.c:177 msgid "Disable debugging" msgstr "Debugging deaktivieren" -#: gst/gst.c:184 -msgid "Disable accelerated CPU instructions" -msgstr "Beschleunigte CPU-Befehle deaktivieren" - -#: gst/gst.c:186 +#: gst/gst.c:181 msgid "Enable verbose plugin loading diagnostics" msgstr "Gesprächige Meldungen beim Laden von Plugins aktivieren" -#: gst/gst.c:188 +#: gst/gst.c:183 msgid "PATHS" msgstr "PATHS" -#: gst/gst.c:191 +#: gst/gst.c:186 #, fuzzy msgid "" "Comma-separated list of plugins to preload in addition to the list stored in " @@ -80,32 +76,32 @@ msgstr "" "Kommagetrennte Liste von Plugins, die zusätzliche zu den Plugins in der " "Umgebungsvariable GST_PLUGIN_PATH geladen werden" -#: gst/gst.c:193 +#: gst/gst.c:188 msgid "PLUGINS" msgstr "PLUGINS" -#: gst/gst.c:196 +#: gst/gst.c:191 msgid "Disable trapping of segmentation faults during plugin loading" msgstr "Verfolgen von Speicherfehlern beim Laden von Plugins deaktivieren" -#: gst/gst.c:199 +#: gst/gst.c:194 msgid "SCHEDULER" msgstr "SCHEDULER" -#: gst/gst.c:201 +#: gst/gst.c:196 msgid "Registry to use" msgstr "Zu benutzende Registry" -#: gst/gst.c:201 +#: gst/gst.c:196 msgid "REGISTRY" msgstr "REGISTRY" -#: gst/gst.c:214 +#: gst/gst.c:209 #, c-format msgid "path list for loading plugins (separated by '%s')" msgstr "Pfadliste zum Laden von Plugins (Durch »%s« getrennt)" -#: gst/gst.c:218 +#: gst/gst.c:213 #, c-format msgid "Scheduler to use (default is '%s')" msgstr "Zu benutzender Scheduler (Standard: »%s«)" @@ -615,53 +611,46 @@ msgstr "" msgid ", " msgstr ", " -#: gst/autoplug/gstspider.c:466 -#, c-format -msgid "There is no element present to handle the stream's mime type %s." -msgstr "" -"Es gibt kein Element, das den MIME-Typ »%s« dieses Datenstroms verarbeiten " -"kann." - -#: gst/elements/gstfilesink.c:268 +#: gst/elements/gstfilesink.c:243 msgid "No file name specified for writing." msgstr "Kein Dateiname zum Schreiben angegeben." -#: gst/elements/gstfilesink.c:275 +#: gst/elements/gstfilesink.c:250 #, c-format msgid "Could not open file \"%s\" for writing." msgstr "Konnte Datei »%s« nicht zum Schreiben öffnen." -#: gst/elements/gstfilesink.c:294 +#: gst/elements/gstfilesink.c:269 #, c-format msgid "Error closing file \"%s\"." msgstr "Fehler beim Schließen der Datei »%s«." -#: gst/elements/gstfilesink.c:364 gst/elements/gstfilesink.c:400 -#: gst/elements/gstfilesink.c:453 +#: gst/elements/gstfilesink.c:339 gst/elements/gstfilesink.c:375 +#: gst/elements/gstfilesink.c:428 #, c-format msgid "Error while writing to file \"%s\"." msgstr "Fehler beim Schreiben der Daten »%s«." -#: gst/elements/gstfilesrc.c:764 gst/elements/gstmultifilesrc.c:298 +#: gst/elements/gstfilesrc.c:725 msgid "No file name specified for reading." msgstr "Kein Dateiname zum Lesen angegeben." -#: gst/elements/gstfilesrc.c:779 gst/elements/gstmultifilesrc.c:306 +#: gst/elements/gstfilesrc.c:740 #, c-format msgid "Could not open file \"%s\" for reading." msgstr "Konnte die Datei »%s« nicht zum Lesen öffnen." -#: gst/elements/gstfilesrc.c:790 +#: gst/elements/gstfilesrc.c:751 #, c-format msgid "\"%s\" is a directory." msgstr "" -#: gst/elements/gstfilesrc.c:796 +#: gst/elements/gstfilesrc.c:757 #, fuzzy, c-format msgid "File \"%s\" is a socket." msgstr "Die Datei »%s« ist keine normale Datei." -#: gst/elements/gstidentity.c:306 +#: gst/elements/gstidentity.c:276 msgid "Failed after iterations as requested." msgstr "Nach dem Durchlaufen fehlgeschlagen. Wie gewünscht." @@ -750,124 +739,80 @@ msgstr "Konnte Zielelement für URI »%s« nicht verbinden" msgid "empty pipeline not allowed" msgstr "Leere Leitung ist nicht erlaubt" -#: tools/gst-inspect.c:1151 +#: tools/gst-inspect.c:1032 #, fuzzy msgid "Print all elements" msgstr "Kein Element »%s«" -#: tools/gst-launch.c:114 -#, c-format -msgid "" -"Execution ended after %s iterations (sum %s ns, average %s ns, min %s ns, " -"max %s ns).\n" -msgstr "" - -#: tools/gst-launch.c:141 -msgid "Usage: gst-xmllaunch [ element.property=value ... ]\n" -msgstr "Aufruf: gst-xmllaunch [ element.eigenschaft=wert ...]\n" - -#: tools/gst-launch.c:149 -#, c-format -msgid "ERROR: parse of xml file '%s' failed.\n" -msgstr "FEHLER: Parsen der XML-Datei »%s« fehlgeschlagen.\n" - -#: tools/gst-launch.c:155 -#, c-format -msgid "ERROR: no toplevel pipeline element in file '%s'.\n" -msgstr "FEHLER: Kein Hauptleitungselement in Datei »%s«.\n" - -#: tools/gst-launch.c:162 -#, c-format -msgid "WARNING: only one toplevel element is supported at this time." -msgstr "WARNUNG: Zur Zeit wird nur ein Hauptleitungselement unterstützt." - -#: tools/gst-launch.c:173 -#, c-format -msgid "ERROR: could not parse command line argument %d: %s.\n" -msgstr "FEHLER: Konnte das Kommandozeilenargument %d nicht parsen: %s.\n" - -#: tools/gst-launch.c:184 -#, c-format -msgid "WARNING: element named '%s' not found.\n" -msgstr "WARNUNG: Element namens »%s« nicht gefunden.\n" - -#: tools/gst-launch.c:327 +#: tools/gst-launch.c:190 #, c-format msgid "FOUND TAG : found by element \"%s\".\n" msgstr "KENNZEICHEN GEFUNDEN: Von Element »%s« gefunden.\n" -#: tools/gst-launch.c:412 +#: tools/gst-launch.c:304 msgid "Output tags (also known as metadata)" msgstr "Kennzeichen (auch bekannt als Metadaten) ausgeben" -#: tools/gst-launch.c:414 +#: tools/gst-launch.c:306 msgid "Output status information and property notifications" msgstr "Zustandsinformation und Eigenschaftsmitteilungen ausgeben" -#: tools/gst-launch.c:416 +#: tools/gst-launch.c:308 msgid "Do not output status information of TYPE" msgstr "Zustandsinformation der Art ART nicht ausgeben" -#: tools/gst-launch.c:416 +#: tools/gst-launch.c:308 msgid "TYPE1,TYPE2,..." msgstr "ART1,ART2,..." -#: tools/gst-launch.c:419 -msgid "Save xml representation of pipeline to FILE and exit" -msgstr "XML-Repräsentation der Pipeline in DATEI speichern und beenden" - -#: tools/gst-launch.c:419 -msgid "FILE" -msgstr "DATEI" - -#: tools/gst-launch.c:422 +#: tools/gst-launch.c:310 msgid "Do not install a fault handler" msgstr "Keine Routine zum Abfangen von Fehlern installieren" -#: tools/gst-launch.c:424 +#: tools/gst-launch.c:312 msgid "Print alloc trace (if enabled at compile time)" msgstr "" "Speicherzuordnungsverfolgung ausgeben (falls zur Compilierzeit aktiviert)" -#: tools/gst-launch.c:426 +#: tools/gst-launch.c:314 msgid "Number of times to iterate pipeline" msgstr "Anzahl, wie oft die Leitung durchlaufen wird" -#: tools/gst-launch.c:496 +#: tools/gst-launch.c:379 #, c-format msgid "ERROR: pipeline could not be constructed: %s.\n" msgstr "FEHLER: Leitung konnte nicht konstruiert werden: %s.\n" -#: tools/gst-launch.c:500 -#, c-format +#: tools/gst-launch.c:383 msgid "ERROR: pipeline could not be constructed.\n" msgstr "FEHLER: Leitung konnte nicht konstruiert werden.\n" -#: tools/gst-launch.c:504 +#: tools/gst-launch.c:387 #, c-format msgid "WARNING: erroneous pipeline: %s\n" msgstr "WARNUNG: Fehlerhafte Leitung: %s\n" -#: tools/gst-launch.c:505 -#, c-format +#: tools/gst-launch.c:388 msgid " Trying to run anyway.\n" msgstr " Versuche trotzdem zu laufen.\n" -#: tools/gst-launch.c:532 -#, c-format +#: tools/gst-launch.c:408 msgid "ERROR: the 'pipeline' element wasn't found.\n" msgstr "FEHLER: Das »pipeline«-Element wurde nicht gefunden.\n" -#: tools/gst-launch.c:539 -#, c-format +#: tools/gst-launch.c:417 msgid "RUNNING pipeline ...\n" msgstr "FÃœHRE Leitung AUS ...\n" -#: tools/gst-launch.c:542 -#, c-format +#: tools/gst-launch.c:421 msgid "ERROR: pipeline doesn't want to play.\n" msgstr "FEHLER: Leitung möchte nicht abgespielt werden.\n" +#: tools/gst-launch.c:445 +#, c-format +msgid "Execution ended after %.2fs (%.2fs or %.2f%% idling).\n" +msgstr "" + #: tools/gst-register.c:49 #, c-format msgid "Added plugin %s with %d feature.\n" @@ -902,6 +847,38 @@ msgid_plural "Loaded %d plugins with %d features.\n" msgstr[0] "" msgstr[1] "" +#~ msgid "Disable accelerated CPU instructions" +#~ msgstr "Beschleunigte CPU-Befehle deaktivieren" + +#~ msgid "There is no element present to handle the stream's mime type %s." +#~ msgstr "" +#~ "Es gibt kein Element, das den MIME-Typ »%s« dieses Datenstroms " +#~ "verarbeiten kann." + +#~ msgid "Usage: gst-xmllaunch [ element.property=value ... ]\n" +#~ msgstr "Aufruf: gst-xmllaunch [ element.eigenschaft=wert ...]\n" + +#~ msgid "ERROR: parse of xml file '%s' failed.\n" +#~ msgstr "FEHLER: Parsen der XML-Datei »%s« fehlgeschlagen.\n" + +#~ msgid "ERROR: no toplevel pipeline element in file '%s'.\n" +#~ msgstr "FEHLER: Kein Hauptleitungselement in Datei »%s«.\n" + +#~ msgid "WARNING: only one toplevel element is supported at this time." +#~ msgstr "WARNUNG: Zur Zeit wird nur ein Hauptleitungselement unterstützt." + +#~ msgid "ERROR: could not parse command line argument %d: %s.\n" +#~ msgstr "FEHLER: Konnte das Kommandozeilenargument %d nicht parsen: %s.\n" + +#~ msgid "WARNING: element named '%s' not found.\n" +#~ msgstr "WARNUNG: Element namens »%s« nicht gefunden.\n" + +#~ msgid "Save xml representation of pipeline to FILE and exit" +#~ msgstr "XML-Repräsentation der Pipeline in DATEI speichern und beenden" + +#~ msgid "FILE" +#~ msgstr "DATEI" + #~ msgid "caps" #~ msgstr "Fähigkeiten" diff --git a/po/en_GB.po b/po/en_GB.po index 68f4231dc5..8f8a3676e7 100644 --- a/po/en_GB.po +++ b/po/en_GB.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: gstreamer 0.8.1\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2005-05-02 19:36+0200\n" +"POT-Creation-Date: 2005-05-17 18:37+0200\n" "PO-Revision-Date: 2004-04-26 10:36-0400\n" "Last-Translator: Gareth Owen \n" "Language-Team: English (British) \n" @@ -14,29 +14,29 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -#: gst/gst.c:160 +#: gst/gst.c:157 msgid "Print the GStreamer version" msgstr "Print the GStreamer version" -#: gst/gst.c:162 +#: gst/gst.c:159 msgid "Make all warnings fatal" msgstr "Make all warnings fatal" -#: gst/gst.c:166 +#: gst/gst.c:163 msgid "Print available debug categories and exit" msgstr "Print available debug categories and exit" -#: gst/gst.c:169 +#: gst/gst.c:166 msgid "" "Default debug level from 1 (only error) to 5 (anything) or 0 for no output" msgstr "" "Default debug level from 1 (only error) to 5 (anything) or 0 for no output" -#: gst/gst.c:171 +#: gst/gst.c:168 msgid "LEVEL" msgstr "LEVEL" -#: gst/gst.c:173 +#: gst/gst.c:170 msgid "" "Comma-separated list of category_name:level pairs to set specific levels for " "the individual categories. Example: GST_AUTOPLUG:5,GST_ELEMENT_*:3" @@ -44,31 +44,27 @@ msgstr "" "Comma-separated list of category_name:level pairs to set specific levels for " "the individual categories. Example: GST_AUTOPLUG:5,GST_ELEMENT_*:3" -#: gst/gst.c:176 +#: gst/gst.c:173 msgid "LIST" msgstr "LIST" -#: gst/gst.c:178 +#: gst/gst.c:175 msgid "Disable colored debugging output" msgstr "Disable coloured debugging output" -#: gst/gst.c:180 +#: gst/gst.c:177 msgid "Disable debugging" msgstr "Disable debugging" -#: gst/gst.c:184 -msgid "Disable accelerated CPU instructions" -msgstr "Disable accelerated CPU instructions" - -#: gst/gst.c:186 +#: gst/gst.c:181 msgid "Enable verbose plugin loading diagnostics" msgstr "Enable verbose plugin loading diagnostics" -#: gst/gst.c:188 +#: gst/gst.c:183 msgid "PATHS" msgstr "PATHS" -#: gst/gst.c:191 +#: gst/gst.c:186 #, fuzzy msgid "" "Comma-separated list of plugins to preload in addition to the list stored in " @@ -77,32 +73,32 @@ msgstr "" "Comma-separated list of plugins to preload in addition to the list stored in " "environment variable GST_PLUGIN_PATH" -#: gst/gst.c:193 +#: gst/gst.c:188 msgid "PLUGINS" msgstr "PLUGINS" -#: gst/gst.c:196 +#: gst/gst.c:191 msgid "Disable trapping of segmentation faults during plugin loading" msgstr "Disable trapping of segmentation faults during plugin loading" -#: gst/gst.c:199 +#: gst/gst.c:194 msgid "SCHEDULER" msgstr "SCHEDULER" -#: gst/gst.c:201 +#: gst/gst.c:196 msgid "Registry to use" msgstr "Registry to use" -#: gst/gst.c:201 +#: gst/gst.c:196 msgid "REGISTRY" msgstr "REGISTRY" -#: gst/gst.c:214 +#: gst/gst.c:209 #, c-format msgid "path list for loading plugins (separated by '%s')" msgstr "path list for loading plugins (separated by '%s')" -#: gst/gst.c:218 +#: gst/gst.c:213 #, c-format msgid "Scheduler to use (default is '%s')" msgstr "Scheduler to use (default is '%s')" @@ -575,51 +571,46 @@ msgstr "" msgid ", " msgstr ", " -#: gst/autoplug/gstspider.c:466 -#, c-format -msgid "There is no element present to handle the stream's mime type %s." -msgstr "There is no element present to handle the stream's mime type %s." - -#: gst/elements/gstfilesink.c:268 +#: gst/elements/gstfilesink.c:243 msgid "No file name specified for writing." msgstr "No file name specified for writing." -#: gst/elements/gstfilesink.c:275 +#: gst/elements/gstfilesink.c:250 #, c-format msgid "Could not open file \"%s\" for writing." msgstr "Could not open file \"%s\" for writing." -#: gst/elements/gstfilesink.c:294 +#: gst/elements/gstfilesink.c:269 #, c-format msgid "Error closing file \"%s\"." msgstr "Error closing file \"%s\"." -#: gst/elements/gstfilesink.c:364 gst/elements/gstfilesink.c:400 -#: gst/elements/gstfilesink.c:453 +#: gst/elements/gstfilesink.c:339 gst/elements/gstfilesink.c:375 +#: gst/elements/gstfilesink.c:428 #, c-format msgid "Error while writing to file \"%s\"." msgstr "Error while writing to file \"%s\"." -#: gst/elements/gstfilesrc.c:764 gst/elements/gstmultifilesrc.c:298 +#: gst/elements/gstfilesrc.c:725 msgid "No file name specified for reading." msgstr "No file name specified for reading." -#: gst/elements/gstfilesrc.c:779 gst/elements/gstmultifilesrc.c:306 +#: gst/elements/gstfilesrc.c:740 #, c-format msgid "Could not open file \"%s\" for reading." msgstr "Could not open file \"%s\" for reading." -#: gst/elements/gstfilesrc.c:790 +#: gst/elements/gstfilesrc.c:751 #, c-format msgid "\"%s\" is a directory." msgstr "" -#: gst/elements/gstfilesrc.c:796 +#: gst/elements/gstfilesrc.c:757 #, fuzzy, c-format msgid "File \"%s\" is a socket." msgstr "File \"%s\" isn't a regular file." -#: gst/elements/gstidentity.c:306 +#: gst/elements/gstidentity.c:276 msgid "Failed after iterations as requested." msgstr "Failed after iterations as requested." @@ -708,123 +699,79 @@ msgstr "could not link sink element for URI \"%s\"" msgid "empty pipeline not allowed" msgstr "empty pipeline not allowed" -#: tools/gst-inspect.c:1151 +#: tools/gst-inspect.c:1032 #, fuzzy msgid "Print all elements" msgstr "no element \"%s\"" -#: tools/gst-launch.c:114 -#, c-format -msgid "" -"Execution ended after %s iterations (sum %s ns, average %s ns, min %s ns, " -"max %s ns).\n" -msgstr "" - -#: tools/gst-launch.c:141 -msgid "Usage: gst-xmllaunch [ element.property=value ... ]\n" -msgstr "Usage: gst-xmllaunch [ element.property=value ... ]\n" - -#: tools/gst-launch.c:149 -#, c-format -msgid "ERROR: parse of xml file '%s' failed.\n" -msgstr "ERROR: parsing of xml file '%s' failed.\n" - -#: tools/gst-launch.c:155 -#, c-format -msgid "ERROR: no toplevel pipeline element in file '%s'.\n" -msgstr "ERROR: no toplevel pipeline element in file '%s'.\n" - -#: tools/gst-launch.c:162 -#, c-format -msgid "WARNING: only one toplevel element is supported at this time." -msgstr "WARNING: only one toplevel element is supported at this time." - -#: tools/gst-launch.c:173 -#, c-format -msgid "ERROR: could not parse command line argument %d: %s.\n" -msgstr "ERROR: could not parse command line argument %d: %s.\n" - -#: tools/gst-launch.c:184 -#, c-format -msgid "WARNING: element named '%s' not found.\n" -msgstr "WARNING: element named '%s' not found.\n" - -#: tools/gst-launch.c:327 +#: tools/gst-launch.c:190 #, c-format msgid "FOUND TAG : found by element \"%s\".\n" msgstr "FOUND TAG : found by element \"%s\".\n" -#: tools/gst-launch.c:412 +#: tools/gst-launch.c:304 msgid "Output tags (also known as metadata)" msgstr "Output tags (also known as metadata)" -#: tools/gst-launch.c:414 +#: tools/gst-launch.c:306 msgid "Output status information and property notifications" msgstr "Output status information and property notifications" -#: tools/gst-launch.c:416 +#: tools/gst-launch.c:308 msgid "Do not output status information of TYPE" msgstr "Do not output status information of TYPE" -#: tools/gst-launch.c:416 +#: tools/gst-launch.c:308 msgid "TYPE1,TYPE2,..." msgstr "TYPE1,TYPE2,..." -#: tools/gst-launch.c:419 -msgid "Save xml representation of pipeline to FILE and exit" -msgstr "Save xml representation of pipeline to FILE and exit" - -#: tools/gst-launch.c:419 -msgid "FILE" -msgstr "FILE" - -#: tools/gst-launch.c:422 +#: tools/gst-launch.c:310 msgid "Do not install a fault handler" msgstr "Do not install a fault handler" -#: tools/gst-launch.c:424 +#: tools/gst-launch.c:312 msgid "Print alloc trace (if enabled at compile time)" msgstr "Print alloc trace (if enabled at compile time)" -#: tools/gst-launch.c:426 +#: tools/gst-launch.c:314 msgid "Number of times to iterate pipeline" msgstr "Number of times to iterate pipeline" -#: tools/gst-launch.c:496 +#: tools/gst-launch.c:379 #, c-format msgid "ERROR: pipeline could not be constructed: %s.\n" msgstr "ERROR: pipeline could not be constructed: %s.\n" -#: tools/gst-launch.c:500 -#, c-format +#: tools/gst-launch.c:383 msgid "ERROR: pipeline could not be constructed.\n" msgstr "ERROR: pipeline could not be constructed.\n" -#: tools/gst-launch.c:504 +#: tools/gst-launch.c:387 #, c-format msgid "WARNING: erroneous pipeline: %s\n" msgstr "WARNING: erroneous pipeline: %s\n" -#: tools/gst-launch.c:505 -#, c-format +#: tools/gst-launch.c:388 msgid " Trying to run anyway.\n" msgstr " Trying to run anyway.\n" -#: tools/gst-launch.c:532 -#, c-format +#: tools/gst-launch.c:408 msgid "ERROR: the 'pipeline' element wasn't found.\n" msgstr "ERROR: the 'pipeline' element wasn't found.\n" -#: tools/gst-launch.c:539 -#, c-format +#: tools/gst-launch.c:417 msgid "RUNNING pipeline ...\n" msgstr "RUNNING pipeline ...\n" -#: tools/gst-launch.c:542 -#, c-format +#: tools/gst-launch.c:421 msgid "ERROR: pipeline doesn't want to play.\n" msgstr "ERROR: pipeline doesn't want to play.\n" +#: tools/gst-launch.c:445 +#, c-format +msgid "Execution ended after %.2fs (%.2fs or %.2f%% idling).\n" +msgstr "" + #: tools/gst-register.c:49 #, c-format msgid "Added plugin %s with %d feature.\n" @@ -859,6 +806,36 @@ msgid_plural "Loaded %d plugins with %d features.\n" msgstr[0] "" msgstr[1] "" +#~ msgid "Disable accelerated CPU instructions" +#~ msgstr "Disable accelerated CPU instructions" + +#~ msgid "There is no element present to handle the stream's mime type %s." +#~ msgstr "There is no element present to handle the stream's mime type %s." + +#~ msgid "Usage: gst-xmllaunch [ element.property=value ... ]\n" +#~ msgstr "Usage: gst-xmllaunch [ element.property=value ... ]\n" + +#~ msgid "ERROR: parse of xml file '%s' failed.\n" +#~ msgstr "ERROR: parsing of xml file '%s' failed.\n" + +#~ msgid "ERROR: no toplevel pipeline element in file '%s'.\n" +#~ msgstr "ERROR: no toplevel pipeline element in file '%s'.\n" + +#~ msgid "WARNING: only one toplevel element is supported at this time." +#~ msgstr "WARNING: only one toplevel element is supported at this time." + +#~ msgid "ERROR: could not parse command line argument %d: %s.\n" +#~ msgstr "ERROR: could not parse command line argument %d: %s.\n" + +#~ msgid "WARNING: element named '%s' not found.\n" +#~ msgstr "WARNING: element named '%s' not found.\n" + +#~ msgid "Save xml representation of pipeline to FILE and exit" +#~ msgstr "Save xml representation of pipeline to FILE and exit" + +#~ msgid "FILE" +#~ msgstr "FILE" + #~ msgid "caps" #~ msgstr "caps" diff --git a/po/fr.po b/po/fr.po index b23e0687aa..edf3a23d02 100644 --- a/po/fr.po +++ b/po/fr.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: GStreamer\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2005-05-02 19:36+0200\n" +"POT-Creation-Date: 2005-05-17 18:37+0200\n" "PO-Revision-Date: 2004-01-13 16:52+0100\n" "Last-Translator: Julien Moutte \n" "Language-Team: French \n" @@ -15,30 +15,30 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -#: gst/gst.c:160 +#: gst/gst.c:157 msgid "Print the GStreamer version" msgstr "Afficher la version de GStreamer" -#: gst/gst.c:162 +#: gst/gst.c:159 msgid "Make all warnings fatal" msgstr "Rendre tout les avertissements bloquants" -#: gst/gst.c:166 +#: gst/gst.c:163 msgid "Print available debug categories and exit" msgstr "Afficher les catégories de deboguage disponibles et quitter" -#: gst/gst.c:169 +#: gst/gst.c:166 msgid "" "Default debug level from 1 (only error) to 5 (anything) or 0 for no output" msgstr "" "Niveau de deboguage par defaut de 1 (que les erreurs) a 5 (tout) ou 0 pour " "n'avoir aucun affichage" -#: gst/gst.c:171 +#: gst/gst.c:168 msgid "LEVEL" msgstr "NIVEAU" -#: gst/gst.c:173 +#: gst/gst.c:170 #, fuzzy msgid "" "Comma-separated list of category_name:level pairs to set specific levels for " @@ -48,32 +48,28 @@ msgstr "" "des niveaux spécifiques pour chaque catégorie.\n" "Exemple: GST_AUTOPLUG:5,GST_ELEMENT_*:3" -#: gst/gst.c:176 +#: gst/gst.c:173 msgid "LIST" msgstr "" -#: gst/gst.c:178 +#: gst/gst.c:175 #, fuzzy msgid "Disable colored debugging output" msgstr "Désactiver la couleur dans la sortie de deboguage" -#: gst/gst.c:180 +#: gst/gst.c:177 msgid "Disable debugging" msgstr "Désactiver la sortie de deboguage" -#: gst/gst.c:184 -msgid "Disable accelerated CPU instructions" -msgstr "Désactiver les instructions accélerées du processeur" - -#: gst/gst.c:186 +#: gst/gst.c:181 msgid "Enable verbose plugin loading diagnostics" msgstr "Activer un diagnostique détaillé du chargement des plugins" -#: gst/gst.c:188 +#: gst/gst.c:183 msgid "PATHS" msgstr "CHEMINS" -#: gst/gst.c:191 +#: gst/gst.c:186 #, fuzzy msgid "" "Comma-separated list of plugins to preload in addition to the list stored in " @@ -82,34 +78,34 @@ msgstr "" "Liste séparée par des virgules de plugins a precharger en plus de la liste " "contenue dans la variable d'environnement GST_PLUGIN_PATH" -#: gst/gst.c:193 +#: gst/gst.c:188 msgid "PLUGINS" msgstr "PLUGINS" -#: gst/gst.c:196 +#: gst/gst.c:191 msgid "Disable trapping of segmentation faults during plugin loading" msgstr "" "Désactiver la detection des erreurs de segmentation pendant le chargement " "des plugins" -#: gst/gst.c:199 +#: gst/gst.c:194 msgid "SCHEDULER" msgstr "PLANIFICATEUR" -#: gst/gst.c:201 +#: gst/gst.c:196 msgid "Registry to use" msgstr "Registre a utiliser" -#: gst/gst.c:201 +#: gst/gst.c:196 msgid "REGISTRY" msgstr "REGISTRE" -#: gst/gst.c:214 +#: gst/gst.c:209 #, fuzzy, c-format msgid "path list for loading plugins (separated by '%s')" msgstr "liste de chemins pour le chargement des plugins (séparés par '" -#: gst/gst.c:218 +#: gst/gst.c:213 #, fuzzy, c-format msgid "Scheduler to use (default is '%s')" msgstr "Planificateur a utiliser ('" @@ -606,53 +602,48 @@ msgstr "" msgid ", " msgstr ", " -#: gst/autoplug/gstspider.c:466 -#, c-format -msgid "There is no element present to handle the stream's mime type %s." -msgstr "" - -#: gst/elements/gstfilesink.c:268 +#: gst/elements/gstfilesink.c:243 #, fuzzy msgid "No file name specified for writing." msgstr "Echoué a déterminer le type du flux" -#: gst/elements/gstfilesink.c:275 +#: gst/elements/gstfilesink.c:250 #, c-format msgid "Could not open file \"%s\" for writing." msgstr "" -#: gst/elements/gstfilesink.c:294 +#: gst/elements/gstfilesink.c:269 #, c-format msgid "Error closing file \"%s\"." msgstr "" -#: gst/elements/gstfilesink.c:364 gst/elements/gstfilesink.c:400 -#: gst/elements/gstfilesink.c:453 +#: gst/elements/gstfilesink.c:339 gst/elements/gstfilesink.c:375 +#: gst/elements/gstfilesink.c:428 #, c-format msgid "Error while writing to file \"%s\"." msgstr "" -#: gst/elements/gstfilesrc.c:764 gst/elements/gstmultifilesrc.c:298 +#: gst/elements/gstfilesrc.c:725 #, fuzzy msgid "No file name specified for reading." msgstr "Echoué a déterminer le type du flux" -#: gst/elements/gstfilesrc.c:779 gst/elements/gstmultifilesrc.c:306 +#: gst/elements/gstfilesrc.c:740 #, fuzzy, c-format msgid "Could not open file \"%s\" for reading." msgstr "Echoué a déterminer le type du flux" -#: gst/elements/gstfilesrc.c:790 +#: gst/elements/gstfilesrc.c:751 #, c-format msgid "\"%s\" is a directory." msgstr "" -#: gst/elements/gstfilesrc.c:796 +#: gst/elements/gstfilesrc.c:757 #, c-format msgid "File \"%s\" is a socket." msgstr "" -#: gst/elements/gstidentity.c:306 +#: gst/elements/gstidentity.c:276 msgid "Failed after iterations as requested." msgstr "" @@ -742,129 +733,80 @@ msgstr "impossible de lier un element destination pour l'URI \"%s\"" msgid "empty pipeline not allowed" msgstr "tube vide non autorisé" -#: tools/gst-inspect.c:1151 +#: tools/gst-inspect.c:1032 #, fuzzy msgid "Print all elements" msgstr "pas d'element \"%s\"" -#: tools/gst-launch.c:114 -#, c-format -msgid "" -"Execution ended after %s iterations (sum %s ns, average %s ns, min %s ns, " -"max %s ns).\n" -msgstr "" - -#: tools/gst-launch.c:141 -msgid "Usage: gst-xmllaunch [ element.property=value ... ]\n" -msgstr "" -"Utilisation: gst-xmllaunch [ element.property=valeur ... ]\n" - -#: tools/gst-launch.c:149 -#, c-format -msgid "ERROR: parse of xml file '%s' failed.\n" -msgstr "ERREUR: l'interpretation du fichier xml '%s' a echoué.\n" - -#: tools/gst-launch.c:155 -#, c-format -msgid "ERROR: no toplevel pipeline element in file '%s'.\n" -msgstr "ERREUR: pas d'element tube de plus haut niveau dans le fichier '%s'.\n" - -#: tools/gst-launch.c:162 -#, c-format -msgid "WARNING: only one toplevel element is supported at this time." -msgstr "" -"AVERTISSEMENT: actuellement seul un element tube de plus haut niveau est " -"supporté." - -#: tools/gst-launch.c:173 -#, c-format -msgid "ERROR: could not parse command line argument %d: %s.\n" -msgstr "" -"ERREUR: impossible d'interpreter l'argument de la ligne de commande numero %" -"d: %s.\n" - -#: tools/gst-launch.c:184 -#, c-format -msgid "WARNING: element named '%s' not found.\n" -msgstr "AVERTISSEMENT: l'element nommé '%s' est introuvable.\n" - -#: tools/gst-launch.c:327 +#: tools/gst-launch.c:190 #, c-format msgid "FOUND TAG : found by element \"%s\".\n" msgstr "TAG DECOUVERT : decouvert par l'element \"%s\".\n" -#: tools/gst-launch.c:412 +#: tools/gst-launch.c:304 msgid "Output tags (also known as metadata)" msgstr "tags de sortie (aussi connus sous le nom de metadata)" -#: tools/gst-launch.c:414 +#: tools/gst-launch.c:306 msgid "Output status information and property notifications" msgstr "" "Afficher des informations sur le status et les notifications de proprietés" -#: tools/gst-launch.c:416 +#: tools/gst-launch.c:308 msgid "Do not output status information of TYPE" msgstr "Ne pas afficher d'informations sur les status de TYPE" -#: tools/gst-launch.c:416 +#: tools/gst-launch.c:308 msgid "TYPE1,TYPE2,..." msgstr "TYPE1,TYPE2,..." -#: tools/gst-launch.c:419 -msgid "Save xml representation of pipeline to FILE and exit" -msgstr "Sauvegarder la representation xml du tube dans FICHIER et quitter" - -#: tools/gst-launch.c:419 -msgid "FILE" -msgstr "FICHIER" - -#: tools/gst-launch.c:422 +#: tools/gst-launch.c:310 msgid "Do not install a fault handler" msgstr "Ne pas installer un gestionaire de dysfonctionement" -#: tools/gst-launch.c:424 +#: tools/gst-launch.c:312 msgid "Print alloc trace (if enabled at compile time)" msgstr "Imprimer les traces d'allocations (si activées lors de la compilation)" -#: tools/gst-launch.c:426 +#: tools/gst-launch.c:314 msgid "Number of times to iterate pipeline" msgstr "Nombres d'iterations du tube a accomplir" -#: tools/gst-launch.c:496 +#: tools/gst-launch.c:379 #, c-format msgid "ERROR: pipeline could not be constructed: %s.\n" msgstr "ERREUR: le tube n'a pas pu etre construit: %s.\n" -#: tools/gst-launch.c:500 -#, c-format +#: tools/gst-launch.c:383 msgid "ERROR: pipeline could not be constructed.\n" msgstr "ERREUR: le tube n'a pas pu etre construit.\n" -#: tools/gst-launch.c:504 +#: tools/gst-launch.c:387 #, c-format msgid "WARNING: erroneous pipeline: %s\n" msgstr "AVERTISSEMENT: tube erroné: %s\n" -#: tools/gst-launch.c:505 -#, c-format +#: tools/gst-launch.c:388 msgid " Trying to run anyway.\n" msgstr " Tentative d'execution malgrè tout.\n" -#: tools/gst-launch.c:532 -#, c-format +#: tools/gst-launch.c:408 msgid "ERROR: the 'pipeline' element wasn't found.\n" msgstr "ERREUR: l'element 'tube' est introuvable.\n" -#: tools/gst-launch.c:539 -#, c-format +#: tools/gst-launch.c:417 msgid "RUNNING pipeline ...\n" msgstr "EXECUTION du tube en cours ...\n" -#: tools/gst-launch.c:542 -#, c-format +#: tools/gst-launch.c:421 msgid "ERROR: pipeline doesn't want to play.\n" msgstr "ERREUR: le tube refuse de s'executer.\n" +#: tools/gst-launch.c:445 +#, c-format +msgid "Execution ended after %.2fs (%.2fs or %.2f%% idling).\n" +msgstr "" + #: tools/gst-register.c:49 #, c-format msgid "Added plugin %s with %d feature.\n" @@ -899,6 +841,39 @@ msgid_plural "Loaded %d plugins with %d features.\n" msgstr[0] "" msgstr[1] "" +#~ msgid "Disable accelerated CPU instructions" +#~ msgstr "Désactiver les instructions accélerées du processeur" + +#~ msgid "Usage: gst-xmllaunch [ element.property=value ... ]\n" +#~ msgstr "" +#~ "Utilisation: gst-xmllaunch [ element.property=valeur ... ]\n" + +#~ msgid "ERROR: parse of xml file '%s' failed.\n" +#~ msgstr "ERREUR: l'interpretation du fichier xml '%s' a echoué.\n" + +#~ msgid "ERROR: no toplevel pipeline element in file '%s'.\n" +#~ msgstr "" +#~ "ERREUR: pas d'element tube de plus haut niveau dans le fichier '%s'.\n" + +#~ msgid "WARNING: only one toplevel element is supported at this time." +#~ msgstr "" +#~ "AVERTISSEMENT: actuellement seul un element tube de plus haut niveau est " +#~ "supporté." + +#~ msgid "ERROR: could not parse command line argument %d: %s.\n" +#~ msgstr "" +#~ "ERREUR: impossible d'interpreter l'argument de la ligne de commande " +#~ "numero %d: %s.\n" + +#~ msgid "WARNING: element named '%s' not found.\n" +#~ msgstr "AVERTISSEMENT: l'element nommé '%s' est introuvable.\n" + +#~ msgid "Save xml representation of pipeline to FILE and exit" +#~ msgstr "Sauvegarder la representation xml du tube dans FICHIER et quitter" + +#~ msgid "FILE" +#~ msgstr "FICHIER" + #~ msgid "caps" #~ msgstr "capacités" diff --git a/po/it.po b/po/it.po index ea0d5fdd2f..e540843383 100644 --- a/po/it.po +++ b/po/it.po @@ -108,7 +108,7 @@ msgid "" msgstr "" "Project-Id-Version: gstreamer 0.8.7pre2\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2005-05-02 19:36+0200\n" +"POT-Creation-Date: 2005-05-17 18:37+0200\n" "PO-Revision-Date: 2004-12-21 08:23+0100\n" "Last-Translator: Luca Ferretti \n" "Language-Team: Italian \n" @@ -117,30 +117,30 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: gst/gst.c:160 +#: gst/gst.c:157 msgid "Print the GStreamer version" msgstr "Stampa la versione di GStreamer" -#: gst/gst.c:162 +#: gst/gst.c:159 msgid "Make all warnings fatal" msgstr "Rende tutti i warning fatali" -#: gst/gst.c:166 +#: gst/gst.c:163 msgid "Print available debug categories and exit" msgstr "Stampa le categorie di debug disponibili ed esce" -#: gst/gst.c:169 +#: gst/gst.c:166 msgid "" "Default debug level from 1 (only error) to 5 (anything) or 0 for no output" msgstr "" "Livello di debug predefinito da 1 (solo errori) a 5 (tutto), oppure 0 per " "nessun output" -#: gst/gst.c:171 +#: gst/gst.c:168 msgid "LEVEL" msgstr "LIVELLO" -#: gst/gst.c:173 +#: gst/gst.c:170 msgid "" "Comma-separated list of category_name:level pairs to set specific levels for " "the individual categories. Example: GST_AUTOPLUG:5,GST_ELEMENT_*:3" @@ -149,31 +149,27 @@ msgstr "" "impostare i livelli specifici per ogni singola categoria. Esempio: " "GST_AUTOPLUG:5,GST_ELEMENT_*:3" -#: gst/gst.c:176 +#: gst/gst.c:173 msgid "LIST" msgstr "ELENCO" -#: gst/gst.c:178 +#: gst/gst.c:175 msgid "Disable colored debugging output" msgstr "Disabilita output di debug colorato" -#: gst/gst.c:180 +#: gst/gst.c:177 msgid "Disable debugging" msgstr "Disabilita debug" -#: gst/gst.c:184 -msgid "Disable accelerated CPU instructions" -msgstr "Disabilita istruzioni accelerate CPU" - -#: gst/gst.c:186 +#: gst/gst.c:181 msgid "Enable verbose plugin loading diagnostics" msgstr "Abilita diagnostica prolissa del caricamento plugin" -#: gst/gst.c:188 +#: gst/gst.c:183 msgid "PATHS" msgstr "PERCORSI" -#: gst/gst.c:191 +#: gst/gst.c:186 #, fuzzy msgid "" "Comma-separated list of plugins to preload in addition to the list stored in " @@ -182,32 +178,32 @@ msgstr "" "Elenco separato da virgole dei plugin da pre-caricare in aggiunta all'elenco " "memorizzato nella variabile d'ambiente GST_PLUGIN_PATH" -#: gst/gst.c:193 +#: gst/gst.c:188 msgid "PLUGINS" msgstr "PLUGIN" -#: gst/gst.c:196 +#: gst/gst.c:191 msgid "Disable trapping of segmentation faults during plugin loading" msgstr "Disabilita il trapping dei segfault durante il caricamento dei plugin" -#: gst/gst.c:199 +#: gst/gst.c:194 msgid "SCHEDULER" msgstr "SCHEDULER" -#: gst/gst.c:201 +#: gst/gst.c:196 msgid "Registry to use" msgstr "Registro da usare" -#: gst/gst.c:201 +#: gst/gst.c:196 msgid "REGISTRY" msgstr "REGISTRO" -#: gst/gst.c:214 +#: gst/gst.c:209 #, c-format msgid "path list for loading plugins (separated by '%s')" msgstr "elenco dei percorsi per caricare i plugin (separati da '%s')" -#: gst/gst.c:218 +#: gst/gst.c:213 #, c-format msgid "Scheduler to use (default is '%s')" msgstr "Scheduler da usare (predefinito è '%s')" @@ -693,52 +689,46 @@ msgstr "" msgid ", " msgstr ", " -#: gst/autoplug/gstspider.c:466 -#, c-format -msgid "There is no element present to handle the stream's mime type %s." -msgstr "" -"Non vi è alcun elemento presente per gestire il tipo MIME %s dello stream." - -#: gst/elements/gstfilesink.c:268 +#: gst/elements/gstfilesink.c:243 msgid "No file name specified for writing." msgstr "Nessun nome di file specificato per la scrittura." -#: gst/elements/gstfilesink.c:275 +#: gst/elements/gstfilesink.c:250 #, c-format msgid "Could not open file \"%s\" for writing." msgstr "Impossibile aprire il file «%s» in scrittura." -#: gst/elements/gstfilesink.c:294 +#: gst/elements/gstfilesink.c:269 #, c-format msgid "Error closing file \"%s\"." msgstr "Errore nel chiudere il file «%s»." -#: gst/elements/gstfilesink.c:364 gst/elements/gstfilesink.c:400 -#: gst/elements/gstfilesink.c:453 +#: gst/elements/gstfilesink.c:339 gst/elements/gstfilesink.c:375 +#: gst/elements/gstfilesink.c:428 #, c-format msgid "Error while writing to file \"%s\"." msgstr "Errore durante la scrittura sul file «%s»." -#: gst/elements/gstfilesrc.c:764 gst/elements/gstmultifilesrc.c:298 +#: gst/elements/gstfilesrc.c:725 msgid "No file name specified for reading." msgstr "Nessun nome di file specificato per la lettura." -#: gst/elements/gstfilesrc.c:779 gst/elements/gstmultifilesrc.c:306 +#: gst/elements/gstfilesrc.c:740 #, c-format msgid "Could not open file \"%s\" for reading." msgstr "Impossibile aprire il file «%s» in lettura." -#: gst/elements/gstfilesrc.c:790 +#: gst/elements/gstfilesrc.c:751 #, c-format msgid "\"%s\" is a directory." msgstr "«%s» è una directory." -#: gst/elements/gstfilesrc.c:796 +#: gst/elements/gstfilesrc.c:757 #, c-format msgid "File \"%s\" is a socket." msgstr "Il file «%s» è un socket." -#: gst/elements/gstidentity.c:306 +#: gst/elements/gstidentity.c:276 msgid "Failed after iterations as requested." msgstr "Fallito dopo le iterazioni come richiesto." @@ -827,125 +817,78 @@ msgstr "impossibile collegare l'elemento sink per l'URI «%s»" msgid "empty pipeline not allowed" msgstr "pipeline vuota non consentito" -#: tools/gst-inspect.c:1151 +#: tools/gst-inspect.c:1032 msgid "Print all elements" msgstr "Stampa tutti gli elementi" -#: tools/gst-launch.c:114 -#, c-format -msgid "" -"Execution ended after %s iterations (sum %s ns, average %s ns, min %s ns, " -"max %s ns).\n" -msgstr "" -"Eseuzione terminata dopo %s iterazioni (somma %s ns, media %s ns, min %s ns, " -"max %s ns).\n" - -#: tools/gst-launch.c:141 -msgid "Usage: gst-xmllaunch [ element.property=value ... ]\n" -msgstr "Uso: gst-xmllaunch [ ELEMENTO.PROPRIETA=VALORE ... ]\n" - -#: tools/gst-launch.c:149 -#, c-format -msgid "ERROR: parse of xml file '%s' failed.\n" -msgstr "ERRORE: analisi del file xml «%s» fallita.\n" - -#: tools/gst-launch.c:155 -#, c-format -msgid "ERROR: no toplevel pipeline element in file '%s'.\n" -msgstr "ERRORE: nessun elemento pipeline toplevel nel file «%s».\n" - -#: tools/gst-launch.c:162 -#, c-format -msgid "WARNING: only one toplevel element is supported at this time." -msgstr "AVVISO: al momento è supportato sono un elemento toplevel." - -#: tools/gst-launch.c:173 -#, c-format -msgid "ERROR: could not parse command line argument %d: %s.\n" -msgstr "" -"ERRORE: impossibile analizzare l'argomento %d della riga di comando: %s.\n" - -#: tools/gst-launch.c:184 -#, c-format -msgid "WARNING: element named '%s' not found.\n" -msgstr "AVVISO: elemento di nome «%s» non trovato.\n" - -#: tools/gst-launch.c:327 +#: tools/gst-launch.c:190 #, c-format msgid "FOUND TAG : found by element \"%s\".\n" msgstr "TAG TROVATO : trovato dall'elemento «%s».\n" -#: tools/gst-launch.c:412 +#: tools/gst-launch.c:304 msgid "Output tags (also known as metadata)" msgstr "Stampa i tag (anche noti come metadati)" -#: tools/gst-launch.c:414 +#: tools/gst-launch.c:306 msgid "Output status information and property notifications" msgstr "Stampa informazioni di stato e notifiche delle proprietà" -#: tools/gst-launch.c:416 +#: tools/gst-launch.c:308 msgid "Do not output status information of TYPE" msgstr "Non fornisce informazioni di stato per TIPO" -#: tools/gst-launch.c:416 +#: tools/gst-launch.c:308 msgid "TYPE1,TYPE2,..." msgstr "TIPO1,TIPO2,..." -#: tools/gst-launch.c:419 -msgid "Save xml representation of pipeline to FILE and exit" -msgstr "Salva su FILE una rappresentazione xml della pipeline ed esce" - -#: tools/gst-launch.c:419 -msgid "FILE" -msgstr "FILE" - -#: tools/gst-launch.c:422 +#: tools/gst-launch.c:310 msgid "Do not install a fault handler" msgstr "Non installa un gestore di fault" -#: tools/gst-launch.c:424 +#: tools/gst-launch.c:312 msgid "Print alloc trace (if enabled at compile time)" msgstr "Stampa traccia di alloc (se abilitato in compilazione)" -#: tools/gst-launch.c:426 +#: tools/gst-launch.c:314 msgid "Number of times to iterate pipeline" msgstr "Numero di iterazioni della pipeline" -#: tools/gst-launch.c:496 +#: tools/gst-launch.c:379 #, c-format msgid "ERROR: pipeline could not be constructed: %s.\n" msgstr "ERRORE: impossibile costruire la pipeline: %s.\n" -#: tools/gst-launch.c:500 -#, c-format +#: tools/gst-launch.c:383 msgid "ERROR: pipeline could not be constructed.\n" msgstr "ERRORE: impossibile costruire la pipeline.\n" -#: tools/gst-launch.c:504 +#: tools/gst-launch.c:387 #, c-format msgid "WARNING: erroneous pipeline: %s\n" msgstr "AVVISO: pipeline errata: %s.\n" -#: tools/gst-launch.c:505 -#, c-format +#: tools/gst-launch.c:388 msgid " Trying to run anyway.\n" msgstr " Tentata esecuzione in ogni caso.\n" -#: tools/gst-launch.c:532 -#, c-format +#: tools/gst-launch.c:408 msgid "ERROR: the 'pipeline' element wasn't found.\n" msgstr "ERRORE: l'elemento «pipeline» non è stato trovato.\n" -#: tools/gst-launch.c:539 -#, c-format +#: tools/gst-launch.c:417 msgid "RUNNING pipeline ...\n" msgstr "ESECUZIONE della pipeline...\n" -#: tools/gst-launch.c:542 -#, c-format +#: tools/gst-launch.c:421 msgid "ERROR: pipeline doesn't want to play.\n" msgstr "ERRORE: la pipeline non vuole riprodurre.\n" +#: tools/gst-launch.c:445 +#, c-format +msgid "Execution ended after %.2fs (%.2fs or %.2f%% idling).\n" +msgstr "" + #: tools/gst-register.c:49 #, fuzzy, c-format msgid "Added plugin %s with %d feature.\n" @@ -980,6 +923,45 @@ msgid_plural "Loaded %d plugins with %d features.\n" msgstr[0] "Caricati %d plugin con %d %s.\n" msgstr[1] "Caricati %d plugin con %d %s.\n" +#~ msgid "Disable accelerated CPU instructions" +#~ msgstr "Disabilita istruzioni accelerate CPU" + +#~ msgid "There is no element present to handle the stream's mime type %s." +#~ msgstr "" +#~ "Non vi è alcun elemento presente per gestire il tipo MIME %s dello stream." + +#~ msgid "" +#~ "Execution ended after %s iterations (sum %s ns, average %s ns, min %s ns, " +#~ "max %s ns).\n" +#~ msgstr "" +#~ "Eseuzione terminata dopo %s iterazioni (somma %s ns, media %s ns, min %s " +#~ "ns, max %s ns).\n" + +#~ msgid "Usage: gst-xmllaunch [ element.property=value ... ]\n" +#~ msgstr "Uso: gst-xmllaunch [ ELEMENTO.PROPRIETA=VALORE ... ]\n" + +#~ msgid "ERROR: parse of xml file '%s' failed.\n" +#~ msgstr "ERRORE: analisi del file xml «%s» fallita.\n" + +#~ msgid "ERROR: no toplevel pipeline element in file '%s'.\n" +#~ msgstr "ERRORE: nessun elemento pipeline toplevel nel file «%s».\n" + +#~ msgid "WARNING: only one toplevel element is supported at this time." +#~ msgstr "AVVISO: al momento è supportato sono un elemento toplevel." + +#~ msgid "ERROR: could not parse command line argument %d: %s.\n" +#~ msgstr "" +#~ "ERRORE: impossibile analizzare l'argomento %d della riga di comando: %s.\n" + +#~ msgid "WARNING: element named '%s' not found.\n" +#~ msgstr "AVVISO: elemento di nome «%s» non trovato.\n" + +#~ msgid "Save xml representation of pipeline to FILE and exit" +#~ msgstr "Salva su FILE una rappresentazione xml della pipeline ed esce" + +#~ msgid "FILE" +#~ msgstr "FILE" + #~ msgid "caps" #~ msgstr "caps" diff --git a/po/nb.po b/po/nb.po index 213ca7f602..f000af0006 100644 --- a/po/nb.po +++ b/po/nb.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: gstreamer 0.8.8\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2005-05-02 19:36+0200\n" +"POT-Creation-Date: 2005-05-17 18:37+0200\n" "PO-Revision-Date: 2005-02-17 12:00+0100\n" "Last-Translator: Kjartan Maraas \n" "Language-Team: Norwegian Bokmaal \n" @@ -14,89 +14,85 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -#: gst/gst.c:160 +#: gst/gst.c:157 msgid "Print the GStreamer version" msgstr "Skriv ut versjonsnummer for GStreamer" -#: gst/gst.c:162 +#: gst/gst.c:159 msgid "Make all warnings fatal" msgstr "La alle advarsler være fatale" -#: gst/gst.c:166 +#: gst/gst.c:163 msgid "Print available debug categories and exit" msgstr "Skriv ut tilgjengelige feilsøkingskategorier og avslutt" -#: gst/gst.c:169 +#: gst/gst.c:166 msgid "" "Default debug level from 1 (only error) to 5 (anything) or 0 for no output" msgstr "" -#: gst/gst.c:171 +#: gst/gst.c:168 msgid "LEVEL" msgstr "NIVÃ…" -#: gst/gst.c:173 +#: gst/gst.c:170 msgid "" "Comma-separated list of category_name:level pairs to set specific levels for " "the individual categories. Example: GST_AUTOPLUG:5,GST_ELEMENT_*:3" msgstr "" -#: gst/gst.c:176 +#: gst/gst.c:173 msgid "LIST" msgstr "LISTE" -#: gst/gst.c:178 +#: gst/gst.c:175 msgid "Disable colored debugging output" msgstr "Deaktiver farget feilsøkingsinformasjon" -#: gst/gst.c:180 +#: gst/gst.c:177 msgid "Disable debugging" msgstr "SlÃ¥ av feilsøking" -#: gst/gst.c:184 -msgid "Disable accelerated CPU instructions" -msgstr "" - -#: gst/gst.c:186 +#: gst/gst.c:181 msgid "Enable verbose plugin loading diagnostics" msgstr "" -#: gst/gst.c:188 +#: gst/gst.c:183 msgid "PATHS" msgstr "STIER" -#: gst/gst.c:191 +#: gst/gst.c:186 msgid "" "Comma-separated list of plugins to preload in addition to the list stored in " "environment variable GST_PLUGIN_PATH" msgstr "" -#: gst/gst.c:193 +#: gst/gst.c:188 msgid "PLUGINS" msgstr "TILLEGG" -#: gst/gst.c:196 +#: gst/gst.c:191 msgid "Disable trapping of segmentation faults during plugin loading" msgstr "" -#: gst/gst.c:199 +#: gst/gst.c:194 msgid "SCHEDULER" msgstr "PLANLEGGER" -#: gst/gst.c:201 +#: gst/gst.c:196 msgid "Registry to use" msgstr "Register som skal brukes" -#: gst/gst.c:201 +#: gst/gst.c:196 msgid "REGISTRY" msgstr "REGISTER" -#: gst/gst.c:214 +#: gst/gst.c:209 #, c-format msgid "path list for loading plugins (separated by '%s')" msgstr "" -#: gst/gst.c:218 +#: gst/gst.c:213 #, c-format msgid "Scheduler to use (default is '%s')" msgstr "Planlegger som skal brukes («%s» er forvalgt)" @@ -565,51 +561,46 @@ msgstr "" msgid ", " msgstr ", " -#: gst/autoplug/gstspider.c:466 -#, c-format -msgid "There is no element present to handle the stream's mime type %s." -msgstr "" - -#: gst/elements/gstfilesink.c:268 +#: gst/elements/gstfilesink.c:243 msgid "No file name specified for writing." msgstr "Ingen filnavn oppgitt for skriving." -#: gst/elements/gstfilesink.c:275 +#: gst/elements/gstfilesink.c:250 #, c-format msgid "Could not open file \"%s\" for writing." msgstr "Kunne ikke Ã¥pne fil «%s» for skriving." -#: gst/elements/gstfilesink.c:294 +#: gst/elements/gstfilesink.c:269 #, c-format msgid "Error closing file \"%s\"." msgstr "Feil ved lukking av fil «%s»." -#: gst/elements/gstfilesink.c:364 gst/elements/gstfilesink.c:400 -#: gst/elements/gstfilesink.c:453 +#: gst/elements/gstfilesink.c:339 gst/elements/gstfilesink.c:375 +#: gst/elements/gstfilesink.c:428 #, c-format msgid "Error while writing to file \"%s\"." msgstr "Feil ved skriving til fil «%s»." -#: gst/elements/gstfilesrc.c:764 gst/elements/gstmultifilesrc.c:298 +#: gst/elements/gstfilesrc.c:725 msgid "No file name specified for reading." msgstr "Ingen filnavn oppgitt for lesing." -#: gst/elements/gstfilesrc.c:779 gst/elements/gstmultifilesrc.c:306 +#: gst/elements/gstfilesrc.c:740 #, c-format msgid "Could not open file \"%s\" for reading." msgstr "Kunne ikke Ã¥pne fil «%s» for lesing." -#: gst/elements/gstfilesrc.c:790 +#: gst/elements/gstfilesrc.c:751 #, c-format msgid "\"%s\" is a directory." msgstr "«%s» er en katalog." -#: gst/elements/gstfilesrc.c:796 +#: gst/elements/gstfilesrc.c:757 #, c-format msgid "File \"%s\" is a socket." msgstr "Fil «%s» er en plugg." -#: gst/elements/gstidentity.c:306 +#: gst/elements/gstidentity.c:276 msgid "Failed after iterations as requested." msgstr "" @@ -698,122 +689,78 @@ msgstr "" msgid "empty pipeline not allowed" msgstr "" -#: tools/gst-inspect.c:1151 +#: tools/gst-inspect.c:1032 msgid "Print all elements" msgstr "" -#: tools/gst-launch.c:114 -#, c-format -msgid "" -"Execution ended after %s iterations (sum %s ns, average %s ns, min %s ns, " -"max %s ns).\n" -msgstr "" - -#: tools/gst-launch.c:141 -msgid "Usage: gst-xmllaunch [ element.property=value ... ]\n" -msgstr "" - -#: tools/gst-launch.c:149 -#, c-format -msgid "ERROR: parse of xml file '%s' failed.\n" -msgstr "" - -#: tools/gst-launch.c:155 -#, c-format -msgid "ERROR: no toplevel pipeline element in file '%s'.\n" -msgstr "" - -#: tools/gst-launch.c:162 -#, c-format -msgid "WARNING: only one toplevel element is supported at this time." -msgstr "" - -#: tools/gst-launch.c:173 -#, c-format -msgid "ERROR: could not parse command line argument %d: %s.\n" -msgstr "" - -#: tools/gst-launch.c:184 -#, c-format -msgid "WARNING: element named '%s' not found.\n" -msgstr "" - -#: tools/gst-launch.c:327 +#: tools/gst-launch.c:190 #, c-format msgid "FOUND TAG : found by element \"%s\".\n" msgstr "" -#: tools/gst-launch.c:412 +#: tools/gst-launch.c:304 msgid "Output tags (also known as metadata)" msgstr "" -#: tools/gst-launch.c:414 +#: tools/gst-launch.c:306 msgid "Output status information and property notifications" msgstr "" -#: tools/gst-launch.c:416 +#: tools/gst-launch.c:308 msgid "Do not output status information of TYPE" msgstr "" -#: tools/gst-launch.c:416 +#: tools/gst-launch.c:308 msgid "TYPE1,TYPE2,..." msgstr "TYPE1,TYPE2,..." -#: tools/gst-launch.c:419 -msgid "Save xml representation of pipeline to FILE and exit" -msgstr "" - -#: tools/gst-launch.c:419 -msgid "FILE" -msgstr "FIL" - -#: tools/gst-launch.c:422 +#: tools/gst-launch.c:310 msgid "Do not install a fault handler" msgstr "" -#: tools/gst-launch.c:424 +#: tools/gst-launch.c:312 msgid "Print alloc trace (if enabled at compile time)" msgstr "" -#: tools/gst-launch.c:426 +#: tools/gst-launch.c:314 msgid "Number of times to iterate pipeline" msgstr "" -#: tools/gst-launch.c:496 +#: tools/gst-launch.c:379 #, c-format msgid "ERROR: pipeline could not be constructed: %s.\n" msgstr "" -#: tools/gst-launch.c:500 -#, c-format +#: tools/gst-launch.c:383 msgid "ERROR: pipeline could not be constructed.\n" msgstr "" -#: tools/gst-launch.c:504 +#: tools/gst-launch.c:387 #, c-format msgid "WARNING: erroneous pipeline: %s\n" msgstr "" -#: tools/gst-launch.c:505 -#, c-format +#: tools/gst-launch.c:388 msgid " Trying to run anyway.\n" msgstr "" -#: tools/gst-launch.c:532 -#, c-format +#: tools/gst-launch.c:408 msgid "ERROR: the 'pipeline' element wasn't found.\n" msgstr "" -#: tools/gst-launch.c:539 -#, c-format +#: tools/gst-launch.c:417 msgid "RUNNING pipeline ...\n" msgstr "" -#: tools/gst-launch.c:542 -#, c-format +#: tools/gst-launch.c:421 msgid "ERROR: pipeline doesn't want to play.\n" msgstr "" +#: tools/gst-launch.c:445 +#, c-format +msgid "Execution ended after %.2fs (%.2fs or %.2f%% idling).\n" +msgstr "" + #: tools/gst-register.c:49 #, fuzzy, c-format msgid "Added plugin %s with %d feature.\n" @@ -847,3 +794,6 @@ msgid "Loaded %d plugins with %d feature.\n" msgid_plural "Loaded %d plugins with %d features.\n" msgstr[0] "Lastet %d tillegg med %d %s.\n" msgstr[1] "Lastet %d tillegg med %d %s.\n" + +#~ msgid "FILE" +#~ msgstr "FIL" diff --git a/po/nl.po b/po/nl.po index 0f26e6f3f4..1fb2c90f05 100644 --- a/po/nl.po +++ b/po/nl.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: gstreamer 0.8.4\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2005-05-02 19:36+0200\n" +"POT-Creation-Date: 2005-05-17 18:37+0200\n" "PO-Revision-Date: 2004-08-05 16:56+0200\n" "Last-Translator: Elros Cyriatan \n" "Language-Team: Dutch \n" @@ -17,30 +17,30 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: gst/gst.c:160 +#: gst/gst.c:157 msgid "Print the GStreamer version" msgstr "Geeft de GStreamer versie weer" -#: gst/gst.c:162 +#: gst/gst.c:159 msgid "Make all warnings fatal" msgstr "Alle waarschuwingen fataal maken" -#: gst/gst.c:166 +#: gst/gst.c:163 msgid "Print available debug categories and exit" msgstr "Beschikbare debug-categorieën weergeven en afsluiten" -#: gst/gst.c:169 +#: gst/gst.c:166 msgid "" "Default debug level from 1 (only error) to 5 (anything) or 0 for no output" msgstr "" "Standaard debug-niveau van 1 (enkel fouten) tot 5 (alles) of 0 voor geen " "uitvoer" -#: gst/gst.c:171 +#: gst/gst.c:168 msgid "LEVEL" msgstr "NIVEAU" -#: gst/gst.c:173 +#: gst/gst.c:170 msgid "" "Comma-separated list of category_name:level pairs to set specific levels for " "the individual categories. Example: GST_AUTOPLUG:5,GST_ELEMENT_*:3" @@ -49,31 +49,27 @@ msgstr "" "niveau's in te stellen voor de individuele categorieën. Voorbeeld: " "GST_AUTOPLUG:5,GST_ELEMENT_*:3" -#: gst/gst.c:176 +#: gst/gst.c:173 msgid "LIST" msgstr "LIJST" -#: gst/gst.c:178 +#: gst/gst.c:175 msgid "Disable colored debugging output" msgstr "Kleuren uit zetten in debug-uitvoer" -#: gst/gst.c:180 +#: gst/gst.c:177 msgid "Disable debugging" msgstr "Debugging uit zetten" -#: gst/gst.c:184 -msgid "Disable accelerated CPU instructions" -msgstr "Versnelde CPU-instructies uit zetten" - -#: gst/gst.c:186 +#: gst/gst.c:181 msgid "Enable verbose plugin loading diagnostics" msgstr "Uitgebreide diagnostiek voor het laden van plugins aan zetten" -#: gst/gst.c:188 +#: gst/gst.c:183 msgid "PATHS" msgstr "PADEN" -#: gst/gst.c:191 +#: gst/gst.c:186 #, fuzzy msgid "" "Comma-separated list of plugins to preload in addition to the list stored in " @@ -82,33 +78,33 @@ msgstr "" "Komma-gescheiden lijst van plugins om voor te laden naast de lijst " "opgeslagen in omgevingsvariable GST_PLUGIN_PATH" -#: gst/gst.c:193 +#: gst/gst.c:188 msgid "PLUGINS" msgstr "PLUGINS" -#: gst/gst.c:196 +#: gst/gst.c:191 msgid "Disable trapping of segmentation faults during plugin loading" msgstr "" "Het opvangen van segmentatiefouten uit zetten tijdens laden van plugins" -#: gst/gst.c:199 +#: gst/gst.c:194 msgid "SCHEDULER" msgstr "PLANNER" -#: gst/gst.c:201 +#: gst/gst.c:196 msgid "Registry to use" msgstr "Register om te gebruiken" -#: gst/gst.c:201 +#: gst/gst.c:196 msgid "REGISTRY" msgstr "REGISTER" -#: gst/gst.c:214 +#: gst/gst.c:209 #, c-format msgid "path list for loading plugins (separated by '%s')" msgstr "padlijst voor het laden van plugins (gescheiden door '%s')" -#: gst/gst.c:218 +#: gst/gst.c:213 #, c-format msgid "Scheduler to use (default is '%s')" msgstr "Planner om te gebruiken (standaard is '%s')" @@ -585,52 +581,46 @@ msgstr "" msgid ", " msgstr ", " -#: gst/autoplug/gstspider.c:466 -#, c-format -msgid "There is no element present to handle the stream's mime type %s." -msgstr "" -"Er is geen element aanwezig dat de MIME-soort %s van de stroom kan verwerken." - -#: gst/elements/gstfilesink.c:268 +#: gst/elements/gstfilesink.c:243 msgid "No file name specified for writing." msgstr "Geen bestandsnaam gegeven om te schrijven." -#: gst/elements/gstfilesink.c:275 +#: gst/elements/gstfilesink.c:250 #, c-format msgid "Could not open file \"%s\" for writing." msgstr "Kon bestand \"%s\" niet openen om te schrijven." -#: gst/elements/gstfilesink.c:294 +#: gst/elements/gstfilesink.c:269 #, c-format msgid "Error closing file \"%s\"." msgstr "Fout bij het sluiten van bestand \"%s\"." -#: gst/elements/gstfilesink.c:364 gst/elements/gstfilesink.c:400 -#: gst/elements/gstfilesink.c:453 +#: gst/elements/gstfilesink.c:339 gst/elements/gstfilesink.c:375 +#: gst/elements/gstfilesink.c:428 #, c-format msgid "Error while writing to file \"%s\"." msgstr "Fout bij het schrijven naar bestand \"%s\"." -#: gst/elements/gstfilesrc.c:764 gst/elements/gstmultifilesrc.c:298 +#: gst/elements/gstfilesrc.c:725 msgid "No file name specified for reading." msgstr "Geen bestandsnaam gegeven om te lezen." -#: gst/elements/gstfilesrc.c:779 gst/elements/gstmultifilesrc.c:306 +#: gst/elements/gstfilesrc.c:740 #, c-format msgid "Could not open file \"%s\" for reading." msgstr "Kon bestand \"%s\" niet openen om te lezen." -#: gst/elements/gstfilesrc.c:790 +#: gst/elements/gstfilesrc.c:751 #, c-format msgid "\"%s\" is a directory." msgstr "\"%s\" is een map." -#: gst/elements/gstfilesrc.c:796 +#: gst/elements/gstfilesrc.c:757 #, c-format msgid "File \"%s\" is a socket." msgstr "Bestand \"%s\" is een socket." -#: gst/elements/gstidentity.c:306 +#: gst/elements/gstidentity.c:276 msgid "Failed after iterations as requested." msgstr "Mislukt na iteraties zoals gevraagd." @@ -719,125 +709,78 @@ msgstr "kon doelelement niet verbinden voor URI \"%s\"" msgid "empty pipeline not allowed" msgstr "lege pijplijn niet toegelaten" -#: tools/gst-inspect.c:1151 +#: tools/gst-inspect.c:1032 msgid "Print all elements" msgstr "Alle elementen weergeven" -#: tools/gst-launch.c:114 -#, c-format -msgid "" -"Execution ended after %s iterations (sum %s ns, average %s ns, min %s ns, " -"max %s ns).\n" -msgstr "" - -#: tools/gst-launch.c:141 -msgid "Usage: gst-xmllaunch [ element.property=value ... ]\n" -msgstr "" -"Gebruik: gst-xmllaunch [ element.eigenschap=waarde ... ]\n" - -#: tools/gst-launch.c:149 -#, c-format -msgid "ERROR: parse of xml file '%s' failed.\n" -msgstr "FOUT: verwerken van xml-bestand '%s' mislukt.\n" - -#: tools/gst-launch.c:155 -#, c-format -msgid "ERROR: no toplevel pipeline element in file '%s'.\n" -msgstr "FOUT: geen bovenste pijplijn-element gevonden in file '%s'.\n" - -#: tools/gst-launch.c:162 -#, c-format -msgid "WARNING: only one toplevel element is supported at this time." -msgstr "" -"WAARSCHUWING: slechts één element op het hoogste niveau ondersteund op dit " -"moment." - -#: tools/gst-launch.c:173 -#, c-format -msgid "ERROR: could not parse command line argument %d: %s.\n" -msgstr "FOUT: kon argument %d op opdrachtregel niet verwerken: %s.\n" - -#: tools/gst-launch.c:184 -#, c-format -msgid "WARNING: element named '%s' not found.\n" -msgstr "WAARSCHUWING: element met naam '%s' niet gevonden.\n" - -#: tools/gst-launch.c:327 +#: tools/gst-launch.c:190 #, c-format msgid "FOUND TAG : found by element \"%s\".\n" msgstr "TAG GEVONDEN : gevonden door element \"%s\".\n" -#: tools/gst-launch.c:412 +#: tools/gst-launch.c:304 msgid "Output tags (also known as metadata)" msgstr "Tags (ook bekend als metadata) weergeven" -#: tools/gst-launch.c:414 +#: tools/gst-launch.c:306 msgid "Output status information and property notifications" msgstr "Statusinformatie en eigenschapswaarschuwingen weergeven" -#: tools/gst-launch.c:416 +#: tools/gst-launch.c:308 msgid "Do not output status information of TYPE" msgstr "Statusinformatie van soort SOORT niet weergeven" -#: tools/gst-launch.c:416 +#: tools/gst-launch.c:308 msgid "TYPE1,TYPE2,..." msgstr "SOORT1,SOORT2,..." -#: tools/gst-launch.c:419 -msgid "Save xml representation of pipeline to FILE and exit" -msgstr "XML-representatie van pijplijn in BESTAND opslaan en afsluiten" - -#: tools/gst-launch.c:419 -msgid "FILE" -msgstr "BESTAND" - -#: tools/gst-launch.c:422 +#: tools/gst-launch.c:310 msgid "Do not install a fault handler" msgstr "Geen foutafhandelaar installeren" -#: tools/gst-launch.c:424 +#: tools/gst-launch.c:312 msgid "Print alloc trace (if enabled at compile time)" msgstr "Toewijzingsspoor weergeven (indien aangezet tijdens compileren)" -#: tools/gst-launch.c:426 +#: tools/gst-launch.c:314 msgid "Number of times to iterate pipeline" msgstr "Aantal keren om de pijplijn te herhalen" -#: tools/gst-launch.c:496 +#: tools/gst-launch.c:379 #, c-format msgid "ERROR: pipeline could not be constructed: %s.\n" msgstr "FOUT: pijplijn kon niet gemaakt worden: %s.\n" -#: tools/gst-launch.c:500 -#, c-format +#: tools/gst-launch.c:383 msgid "ERROR: pipeline could not be constructed.\n" msgstr "FOUT: pijplijn kon niet gemaakt worden.\n" -#: tools/gst-launch.c:504 +#: tools/gst-launch.c:387 #, c-format msgid "WARNING: erroneous pipeline: %s\n" msgstr "WAARSCHUWING: foutieve pijplijn: %s\n" -#: tools/gst-launch.c:505 -#, c-format +#: tools/gst-launch.c:388 msgid " Trying to run anyway.\n" msgstr " Probeer toch uit te voeren.\n" -#: tools/gst-launch.c:532 -#, c-format +#: tools/gst-launch.c:408 msgid "ERROR: the 'pipeline' element wasn't found.\n" msgstr "FOUT: het 'pijplijn' element werd niet gevonden.\n" -#: tools/gst-launch.c:539 -#, c-format +#: tools/gst-launch.c:417 msgid "RUNNING pipeline ...\n" msgstr "BEZIG met pijplijn ...\n" -#: tools/gst-launch.c:542 -#, c-format +#: tools/gst-launch.c:421 msgid "ERROR: pipeline doesn't want to play.\n" msgstr "FOUT: pijplijn wil niet spelen.\n" +#: tools/gst-launch.c:445 +#, c-format +msgid "Execution ended after %.2fs (%.2fs or %.2f%% idling).\n" +msgstr "" + #: tools/gst-register.c:49 #, fuzzy, c-format msgid "Added plugin %s with %d feature.\n" @@ -872,6 +815,41 @@ msgid_plural "Loaded %d plugins with %d features.\n" msgstr[0] "%d plugins geladen met %d %s.\n" msgstr[1] "%d plugins geladen met %d %s.\n" +#~ msgid "Disable accelerated CPU instructions" +#~ msgstr "Versnelde CPU-instructies uit zetten" + +#~ msgid "There is no element present to handle the stream's mime type %s." +#~ msgstr "" +#~ "Er is geen element aanwezig dat de MIME-soort %s van de stroom kan " +#~ "verwerken." + +#~ msgid "Usage: gst-xmllaunch [ element.property=value ... ]\n" +#~ msgstr "" +#~ "Gebruik: gst-xmllaunch [ element.eigenschap=waarde ... ]\n" + +#~ msgid "ERROR: parse of xml file '%s' failed.\n" +#~ msgstr "FOUT: verwerken van xml-bestand '%s' mislukt.\n" + +#~ msgid "ERROR: no toplevel pipeline element in file '%s'.\n" +#~ msgstr "FOUT: geen bovenste pijplijn-element gevonden in file '%s'.\n" + +#~ msgid "WARNING: only one toplevel element is supported at this time." +#~ msgstr "" +#~ "WAARSCHUWING: slechts één element op het hoogste niveau ondersteund op " +#~ "dit moment." + +#~ msgid "ERROR: could not parse command line argument %d: %s.\n" +#~ msgstr "FOUT: kon argument %d op opdrachtregel niet verwerken: %s.\n" + +#~ msgid "WARNING: element named '%s' not found.\n" +#~ msgstr "WAARSCHUWING: element met naam '%s' niet gevonden.\n" + +#~ msgid "Save xml representation of pipeline to FILE and exit" +#~ msgstr "XML-representatie van pijplijn in BESTAND opslaan en afsluiten" + +#~ msgid "FILE" +#~ msgstr "BESTAND" + #~ msgid "caps" #~ msgstr "mogelijkheden" diff --git a/po/ru.po b/po/ru.po index 613758c213..0047389f90 100644 --- a/po/ru.po +++ b/po/ru.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: gstreamer 0.8.8\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2005-05-02 19:36+0200\n" +"POT-Creation-Date: 2005-05-17 18:37+0200\n" "PO-Revision-Date: 2005-02-15 22:33+0300\n" "Last-Translator: Peter Astakhov \n" "Language-Team: Russian \n" @@ -18,30 +18,30 @@ msgstr "" "100<10||n%100>=20)?1:2);\n" "X-Generator: KBabel 1.9.1\n" -#: gst/gst.c:160 +#: gst/gst.c:157 msgid "Print the GStreamer version" msgstr "Печатает верÑию GStreamer" -#: gst/gst.c:162 +#: gst/gst.c:159 msgid "Make all warnings fatal" msgstr "РаÑценивать вÑе Ð¿Ñ€ÐµÐ´ÑƒÐ¿Ñ€ÐµÐ¶Ð´ÐµÐ½Ð¸Ñ ÐºÐ°Ðº фатальные" -#: gst/gst.c:166 +#: gst/gst.c:163 msgid "Print available debug categories and exit" msgstr "Печатает доÑтупные категории отладки и выходит" -#: gst/gst.c:169 +#: gst/gst.c:166 msgid "" "Default debug level from 1 (only error) to 5 (anything) or 0 for no output" msgstr "" "Уровень отладки по умолчанию от 1 (только ошибки) до 5(вÑе) или 0 - ничего " "не печатать" -#: gst/gst.c:171 +#: gst/gst.c:168 msgid "LEVEL" msgstr "УРОВЕÐЬ" -#: gst/gst.c:173 +#: gst/gst.c:170 msgid "" "Comma-separated list of category_name:level pairs to set specific levels for " "the individual categories. Example: GST_AUTOPLUG:5,GST_ELEMENT_*:3" @@ -49,31 +49,27 @@ msgstr "" "СпиÑок пар, разделенных запÑтыми вида имÑ_категории:уровень Ð´Ð»Ñ ÑƒÑтановки " "уровнейотдельных категорий. Пример: GST_AUTOPLUG:5,GST_ELEMENT_*:3" -#: gst/gst.c:176 +#: gst/gst.c:173 msgid "LIST" msgstr "СПИСОК" -#: gst/gst.c:178 +#: gst/gst.c:175 msgid "Disable colored debugging output" msgstr "Отключить раÑкрашенный вывод отладочных Ñообщений" -#: gst/gst.c:180 +#: gst/gst.c:177 msgid "Disable debugging" msgstr "Отключить отладку" -#: gst/gst.c:184 -msgid "Disable accelerated CPU instructions" -msgstr "Отключить ÑпецифичеÑкие команды процеÑÑора" - -#: gst/gst.c:186 +#: gst/gst.c:181 msgid "Enable verbose plugin loading diagnostics" msgstr "Разрешить раÑширенную диагноÑтику при загрузке раÑширений" -#: gst/gst.c:188 +#: gst/gst.c:183 msgid "PATHS" msgstr "ПУТИ" -#: gst/gst.c:191 +#: gst/gst.c:186 #, fuzzy msgid "" "Comma-separated list of plugins to preload in addition to the list stored in " @@ -82,32 +78,32 @@ msgstr "" "СпиÑок раÑширений (через запÑтую) Ð´Ð»Ñ Ð·Ð°Ð³Ñ€ÑƒÐ·ÐºÐ¸, вдобавок к ÑпиÑку, " "Ñохраненному в переменной Ð¾ÐºÑ€ÑƒÐ¶ÐµÐ½Ð¸Ñ GST_PLUGIN_PATH" -#: gst/gst.c:193 +#: gst/gst.c:188 msgid "PLUGINS" msgstr "РÐСШИРЕÐИЯ" -#: gst/gst.c:196 +#: gst/gst.c:191 msgid "Disable trapping of segmentation faults during plugin loading" msgstr "" -#: gst/gst.c:199 +#: gst/gst.c:194 msgid "SCHEDULER" msgstr "ПЛÐÐИРОВЩИК" -#: gst/gst.c:201 +#: gst/gst.c:196 msgid "Registry to use" msgstr "" -#: gst/gst.c:201 +#: gst/gst.c:196 msgid "REGISTRY" msgstr "" -#: gst/gst.c:214 +#: gst/gst.c:209 #, c-format msgid "path list for loading plugins (separated by '%s')" msgstr "ÑпиÑок путей Ð´Ð»Ñ Ð·Ð°Ð³Ñ€ÑƒÐ·ÐºÐ¸ раÑширений (разделенных '%s')" -#: gst/gst.c:218 +#: gst/gst.c:213 #, c-format msgid "Scheduler to use (default is '%s')" msgstr "Планировщик Ð´Ð»Ñ Ð¸ÑÐ¿Ð¾Ð»ÑŒÐ·Ð¾Ð²Ð°Ð½Ð¸Ñ (по умолчанию - '%s')" @@ -588,51 +584,46 @@ msgstr "" msgid ", " msgstr ", " -#: gst/autoplug/gstspider.c:466 -#, c-format -msgid "There is no element present to handle the stream's mime type %s." -msgstr "" - -#: gst/elements/gstfilesink.c:268 +#: gst/elements/gstfilesink.c:243 msgid "No file name specified for writing." msgstr "Ðе указано Ð¸Ð¼Ñ Ñ„Ð°Ð¹Ð»Ð° Ð´Ð»Ñ Ð·Ð°Ð¿Ð¸Ñи." -#: gst/elements/gstfilesink.c:275 +#: gst/elements/gstfilesink.c:250 #, c-format msgid "Could not open file \"%s\" for writing." msgstr "Ðе могу открыть файл \"%s\" Ð´Ð»Ñ Ð·Ð°Ð¿Ð¸Ñи." -#: gst/elements/gstfilesink.c:294 +#: gst/elements/gstfilesink.c:269 #, c-format msgid "Error closing file \"%s\"." msgstr "Ошибка Ð·Ð°ÐºÑ€Ñ‹Ñ‚Ð¸Ñ Ñ„Ð°Ð¹Ð»Ð° \"%s\"." -#: gst/elements/gstfilesink.c:364 gst/elements/gstfilesink.c:400 -#: gst/elements/gstfilesink.c:453 +#: gst/elements/gstfilesink.c:339 gst/elements/gstfilesink.c:375 +#: gst/elements/gstfilesink.c:428 #, c-format msgid "Error while writing to file \"%s\"." msgstr "Ошибка запиÑи в файл \"%s\"." -#: gst/elements/gstfilesrc.c:764 gst/elements/gstmultifilesrc.c:298 +#: gst/elements/gstfilesrc.c:725 msgid "No file name specified for reading." msgstr "Ðе указано Ð¸Ð¼Ñ Ñ„Ð°Ð¹Ð»Ð° Ð´Ð»Ñ Ñ‡Ñ‚ÐµÐ½Ð¸Ñ." -#: gst/elements/gstfilesrc.c:779 gst/elements/gstmultifilesrc.c:306 +#: gst/elements/gstfilesrc.c:740 #, c-format msgid "Could not open file \"%s\" for reading." msgstr "Ðе могу открыть файл \"%s\" Ð´Ð»Ñ Ñ‡Ñ‚ÐµÐ½Ð¸Ñ." -#: gst/elements/gstfilesrc.c:790 +#: gst/elements/gstfilesrc.c:751 #, c-format msgid "\"%s\" is a directory." msgstr "\"%s\" - Ñто каталог." -#: gst/elements/gstfilesrc.c:796 +#: gst/elements/gstfilesrc.c:757 #, c-format msgid "File \"%s\" is a socket." msgstr "Файл \"%s\" ÑвлÑетÑÑ Ñокетом." -#: gst/elements/gstidentity.c:306 +#: gst/elements/gstidentity.c:276 msgid "Failed after iterations as requested." msgstr "" @@ -721,125 +712,78 @@ msgstr "" msgid "empty pipeline not allowed" msgstr "" -#: tools/gst-inspect.c:1151 +#: tools/gst-inspect.c:1032 msgid "Print all elements" msgstr "Печатать вÑе Ñлементы" -#: tools/gst-launch.c:114 -#, c-format -msgid "" -"Execution ended after %s iterations (sum %s ns, average %s ns, min %s ns, " -"max %s ns).\n" -msgstr "" -"Выполнение завершилоÑÑŒ поÑле %s итераций (вÑего %s ns, Ñреднее %s ns, " -"минимум %s ns, макÑимум %s ns).\n" - -#: tools/gst-launch.c:141 -msgid "Usage: gst-xmllaunch [ element.property=value ... ]\n" -msgstr "" -"ИÑпользование: gst-xmllaunch <файл.xml> [ Ñлемент.поле=значение ... ]\n" - -#: tools/gst-launch.c:149 -#, c-format -msgid "ERROR: parse of xml file '%s' failed.\n" -msgstr "ОШИБКÐ: не могу разобрать xml файл '%s'.\n" - -#: tools/gst-launch.c:155 -#, c-format -msgid "ERROR: no toplevel pipeline element in file '%s'.\n" -msgstr "" - -#: tools/gst-launch.c:162 -#, c-format -msgid "WARNING: only one toplevel element is supported at this time." -msgstr "" - -#: tools/gst-launch.c:173 -#, c-format -msgid "ERROR: could not parse command line argument %d: %s.\n" -msgstr "ОШИБКÐ: не могу разобрать аргумент командной Ñтроки %d: %s.\n" - -#: tools/gst-launch.c:184 -#, c-format -msgid "WARNING: element named '%s' not found.\n" -msgstr "ПРЕДУПРЕЖДЕÐИЕ: Ñлемент '%s' не найден.\n" - -#: tools/gst-launch.c:327 +#: tools/gst-launch.c:190 #, c-format msgid "FOUND TAG : found by element \"%s\".\n" msgstr "" -#: tools/gst-launch.c:412 +#: tools/gst-launch.c:304 msgid "Output tags (also known as metadata)" msgstr "Выводить Ñ‚Ñги (такжи называемые 'метаданные')" -#: tools/gst-launch.c:414 +#: tools/gst-launch.c:306 msgid "Output status information and property notifications" msgstr "" -#: tools/gst-launch.c:416 +#: tools/gst-launch.c:308 msgid "Do not output status information of TYPE" msgstr "" -#: tools/gst-launch.c:416 +#: tools/gst-launch.c:308 msgid "TYPE1,TYPE2,..." msgstr "ТИП1, ТИП2,..." -#: tools/gst-launch.c:419 -msgid "Save xml representation of pipeline to FILE and exit" -msgstr "" - -#: tools/gst-launch.c:419 -msgid "FILE" -msgstr "ФÐЙЛ" - -#: tools/gst-launch.c:422 +#: tools/gst-launch.c:310 msgid "Do not install a fault handler" msgstr "Ðе уÑтанавливать ошибочный обработчик" -#: tools/gst-launch.c:424 +#: tools/gst-launch.c:312 msgid "Print alloc trace (if enabled at compile time)" msgstr "" -#: tools/gst-launch.c:426 +#: tools/gst-launch.c:314 msgid "Number of times to iterate pipeline" msgstr "" -#: tools/gst-launch.c:496 +#: tools/gst-launch.c:379 #, c-format msgid "ERROR: pipeline could not be constructed: %s.\n" msgstr "" -#: tools/gst-launch.c:500 -#, c-format +#: tools/gst-launch.c:383 msgid "ERROR: pipeline could not be constructed.\n" msgstr "" -#: tools/gst-launch.c:504 +#: tools/gst-launch.c:387 #, c-format msgid "WARNING: erroneous pipeline: %s\n" msgstr "" -#: tools/gst-launch.c:505 -#, c-format +#: tools/gst-launch.c:388 msgid " Trying to run anyway.\n" msgstr " Ð’Ñе равно пытаюÑÑŒ запуÑтить.\n" -#: tools/gst-launch.c:532 -#, c-format +#: tools/gst-launch.c:408 msgid "ERROR: the 'pipeline' element wasn't found.\n" msgstr "" -#: tools/gst-launch.c:539 -#, c-format +#: tools/gst-launch.c:417 msgid "RUNNING pipeline ...\n" msgstr "" -#: tools/gst-launch.c:542 -#, c-format +#: tools/gst-launch.c:421 msgid "ERROR: pipeline doesn't want to play.\n" msgstr "" +#: tools/gst-launch.c:445 +#, c-format +msgid "Execution ended after %.2fs (%.2fs or %.2f%% idling).\n" +msgstr "" + #: tools/gst-register.c:49 #, fuzzy, c-format msgid "Added plugin %s with %d feature.\n" @@ -875,3 +819,29 @@ msgid_plural "Loaded %d plugins with %d features.\n" msgstr[0] "Загружено %d раÑширений Ñ %d %s.\n" msgstr[1] "Загружено %d раÑширений Ñ %d %s.\n" msgstr[2] "Загружено %d раÑширений Ñ %d %s.\n" + +#~ msgid "Disable accelerated CPU instructions" +#~ msgstr "Отключить ÑпецифичеÑкие команды процеÑÑора" + +#~ msgid "" +#~ "Execution ended after %s iterations (sum %s ns, average %s ns, min %s ns, " +#~ "max %s ns).\n" +#~ msgstr "" +#~ "Выполнение завершилоÑÑŒ поÑле %s итераций (вÑего %s ns, Ñреднее %s ns, " +#~ "минимум %s ns, макÑимум %s ns).\n" + +#~ msgid "Usage: gst-xmllaunch [ element.property=value ... ]\n" +#~ msgstr "" +#~ "ИÑпользование: gst-xmllaunch <файл.xml> [ Ñлемент.поле=значение ... ]\n" + +#~ msgid "ERROR: parse of xml file '%s' failed.\n" +#~ msgstr "ОШИБКÐ: не могу разобрать xml файл '%s'.\n" + +#~ msgid "ERROR: could not parse command line argument %d: %s.\n" +#~ msgstr "ОШИБКÐ: не могу разобрать аргумент командной Ñтроки %d: %s.\n" + +#~ msgid "WARNING: element named '%s' not found.\n" +#~ msgstr "ПРЕДУПРЕЖДЕÐИЕ: Ñлемент '%s' не найден.\n" + +#~ msgid "FILE" +#~ msgstr "ФÐЙЛ" diff --git a/po/sq.po b/po/sq.po index a62bec8a1c..5b7b63f722 100644 --- a/po/sq.po +++ b/po/sq.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: gstreamer 0.8.4\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2005-05-02 19:36+0200\n" +"POT-Creation-Date: 2005-05-17 18:37+0200\n" "PO-Revision-Date: 2004-08-07 23:46+0200\n" "Last-Translator: Laurent Dhima \n" "Language-Team: Albanian \n" @@ -15,30 +15,30 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: gst/gst.c:160 +#: gst/gst.c:157 msgid "Print the GStreamer version" msgstr "Printo versionin e GStreamer" -#: gst/gst.c:162 +#: gst/gst.c:159 msgid "Make all warnings fatal" msgstr "Bëj që të gjithë paralajmërimet të jenë fatale" -#: gst/gst.c:166 +#: gst/gst.c:163 msgid "Print available debug categories and exit" msgstr "Printo kategoritë e debug në dispozicion dhe dil" -#: gst/gst.c:169 +#: gst/gst.c:166 msgid "" "Default debug level from 1 (only error) to 5 (anything) or 0 for no output" msgstr "" "Niveli i prezgjedhur i debug nga 1 (vetëm gabimi) në 5 (gjithçka) ose 0 për " "jo output" -#: gst/gst.c:171 +#: gst/gst.c:168 msgid "LEVEL" msgstr "NIVELI" -#: gst/gst.c:173 +#: gst/gst.c:170 msgid "" "Comma-separated list of category_name:level pairs to set specific levels for " "the individual categories. Example: GST_AUTOPLUG:5,GST_ELEMENT_*:3" @@ -47,31 +47,27 @@ msgstr "" "etiketa specifike për kategoritë individuale. Shembull: GST_AUTOPLUG:5," "GST_ELEMENT_*:3" -#: gst/gst.c:176 +#: gst/gst.c:173 msgid "LIST" msgstr "LISTË" -#: gst/gst.c:178 +#: gst/gst.c:175 msgid "Disable colored debugging output" msgstr "Ç'aktivo output shumëngjyrësh të debug" -#: gst/gst.c:180 +#: gst/gst.c:177 msgid "Disable debugging" msgstr "Ç'aktivo debug" -#: gst/gst.c:184 -msgid "Disable accelerated CPU instructions" -msgstr "Ç'aktivo instruksionet e përshpejtimit të CPU" - -#: gst/gst.c:186 +#: gst/gst.c:181 msgid "Enable verbose plugin loading diagnostics" msgstr "Aktivo kërkesën e plugin të ngarkimit të diagnostikimeve" -#: gst/gst.c:188 +#: gst/gst.c:183 msgid "PATHS" msgstr "POZICIONET" -#: gst/gst.c:191 +#: gst/gst.c:186 #, fuzzy msgid "" "Comma-separated list of plugins to preload in addition to the list stored in " @@ -80,33 +76,33 @@ msgstr "" "Lista e plugin, të ndarë me presje, që duhen parangarkuar në plotësim të " "listës së regjistruar tek e ndryshueshmja e ambientit GST_PLUGIN_PATH" -#: gst/gst.c:193 +#: gst/gst.c:188 msgid "PLUGINS" msgstr "PLUGINS" -#: gst/gst.c:196 +#: gst/gst.c:191 msgid "Disable trapping of segmentation faults during plugin loading" msgstr "" "Ç'aktivo regjistrimin e dështimeve të segmentuara gjatë ngarkimit të plugin" -#: gst/gst.c:199 +#: gst/gst.c:194 msgid "SCHEDULER" msgstr "PLANIFIKUES" -#: gst/gst.c:201 +#: gst/gst.c:196 msgid "Registry to use" msgstr "Regjistri që duhet përdorur" -#: gst/gst.c:201 +#: gst/gst.c:196 msgid "REGISTRY" msgstr "REGJISTRI" -#: gst/gst.c:214 +#: gst/gst.c:209 #, c-format msgid "path list for loading plugins (separated by '%s')" msgstr "pozicioni i listës për ngarkimin e plugins (ndarë me '%s')" -#: gst/gst.c:218 +#: gst/gst.c:213 #, c-format msgid "Scheduler to use (default is '%s')" msgstr "Planifikuesi që duhet përdorur (i prezgjedhuri është '%s')" @@ -582,51 +578,46 @@ msgstr "" msgid ", " msgstr ", " -#: gst/autoplug/gstspider.c:466 -#, c-format -msgid "There is no element present to handle the stream's mime type %s." -msgstr "Nuk ekziston asnjë element për të trajtuar llojin mime %s të fluksit." - -#: gst/elements/gstfilesink.c:268 +#: gst/elements/gstfilesink.c:243 msgid "No file name specified for writing." msgstr "Nuk është përcaktuar asnjë emër file për tu shkruar." -#: gst/elements/gstfilesink.c:275 +#: gst/elements/gstfilesink.c:250 #, c-format msgid "Could not open file \"%s\" for writing." msgstr "E pamundur hapja e file \"%s\" në shkrim." -#: gst/elements/gstfilesink.c:294 +#: gst/elements/gstfilesink.c:269 #, c-format msgid "Error closing file \"%s\"." msgstr "Gabim gjatë mbylljes së file \"%s\"." -#: gst/elements/gstfilesink.c:364 gst/elements/gstfilesink.c:400 -#: gst/elements/gstfilesink.c:453 +#: gst/elements/gstfilesink.c:339 gst/elements/gstfilesink.c:375 +#: gst/elements/gstfilesink.c:428 #, c-format msgid "Error while writing to file \"%s\"." msgstr "Gabim gjatë shkrimit tek file \"%s\"." -#: gst/elements/gstfilesrc.c:764 gst/elements/gstmultifilesrc.c:298 +#: gst/elements/gstfilesrc.c:725 msgid "No file name specified for reading." msgstr "Nuk është përcaktuar asnjë emër file për tu lexuar." -#: gst/elements/gstfilesrc.c:779 gst/elements/gstmultifilesrc.c:306 +#: gst/elements/gstfilesrc.c:740 #, c-format msgid "Could not open file \"%s\" for reading." msgstr "E pamundur hapja e file \"%s\" për lexim." -#: gst/elements/gstfilesrc.c:790 +#: gst/elements/gstfilesrc.c:751 #, c-format msgid "\"%s\" is a directory." msgstr "\"%s\" është një directory." -#: gst/elements/gstfilesrc.c:796 +#: gst/elements/gstfilesrc.c:757 #, c-format msgid "File \"%s\" is a socket." msgstr "File \"%s\" është një socket." -#: gst/elements/gstidentity.c:306 +#: gst/elements/gstidentity.c:276 msgid "Failed after iterations as requested." msgstr "Dështoi mbas përsëritjeve sikurse të kërkuara." @@ -715,123 +706,78 @@ msgstr "e pamundur lidhja e elementit sink për URI \"%s\"" msgid "empty pipeline not allowed" msgstr "nuk lejohet konduktori bosh" -#: tools/gst-inspect.c:1151 +#: tools/gst-inspect.c:1032 msgid "Print all elements" msgstr "Printo të gjithë elementët" -#: tools/gst-launch.c:114 -#, c-format -msgid "" -"Execution ended after %s iterations (sum %s ns, average %s ns, min %s ns, " -"max %s ns).\n" -msgstr "" - -#: tools/gst-launch.c:141 -msgid "Usage: gst-xmllaunch [ element.property=value ... ]\n" -msgstr "Përdorimi: gst-xmllaunch [ element.property=vlera ... ]\n" - -#: tools/gst-launch.c:149 -#, c-format -msgid "ERROR: parse of xml file '%s' failed.\n" -msgstr "GABIM: analizimi i file xml '%s' dështoi.\n" - -#: tools/gst-launch.c:155 -#, c-format -msgid "ERROR: no toplevel pipeline element in file '%s'.\n" -msgstr "GABIM: asnjë element i pipline të toplevel tek file '%s'.\n" - -#: tools/gst-launch.c:162 -#, c-format -msgid "WARNING: only one toplevel element is supported at this time." -msgstr "KUJDES: vetëm një element toplevel suportohet aktualisht." - -#: tools/gst-launch.c:173 -#, c-format -msgid "ERROR: could not parse command line argument %d: %s.\n" -msgstr "" -"GABIM: i pamundur analizimi i argumentit %d të rreshtit të komandës: %s.\n" - -#: tools/gst-launch.c:184 -#, c-format -msgid "WARNING: element named '%s' not found.\n" -msgstr "KUJDES: elementi me emrin '%s' nuk u gjet.\n" - -#: tools/gst-launch.c:327 +#: tools/gst-launch.c:190 #, c-format msgid "FOUND TAG : found by element \"%s\".\n" msgstr "NDRYSHIM I GJETUR : u gjet nga elementi \"%s\".\n" -#: tools/gst-launch.c:412 +#: tools/gst-launch.c:304 msgid "Output tags (also known as metadata)" msgstr "Tags e output (njohur gjithashtu si metadata)" -#: tools/gst-launch.c:414 +#: tools/gst-launch.c:306 msgid "Output status information and property notifications" msgstr "Njoftime të informacioneve dhe pronësisë së kondicionit të daljes" -#: tools/gst-launch.c:416 +#: tools/gst-launch.c:308 msgid "Do not output status information of TYPE" msgstr "Mos jep informacionin e gjendjes së LLOJIT" -#: tools/gst-launch.c:416 +#: tools/gst-launch.c:308 msgid "TYPE1,TYPE2,..." msgstr "LLOJI1,LLOJI2,..." -#: tools/gst-launch.c:419 -msgid "Save xml representation of pipeline to FILE and exit" -msgstr "Ruaj prezantimin xml të pipeline tek FILE dhe dil" - -#: tools/gst-launch.c:419 -msgid "FILE" -msgstr "FILE" - -#: tools/gst-launch.c:422 +#: tools/gst-launch.c:310 msgid "Do not install a fault handler" msgstr "Mos instalo një ushqyes të dëmtuar" -#: tools/gst-launch.c:424 +#: tools/gst-launch.c:312 msgid "Print alloc trace (if enabled at compile time)" msgstr "Printo shenjat e alloc (nëse aktivuar në kohën e kompilimit)" -#: tools/gst-launch.c:426 +#: tools/gst-launch.c:314 msgid "Number of times to iterate pipeline" msgstr "Numri i herëve të përsëritjes së kanalit" -#: tools/gst-launch.c:496 +#: tools/gst-launch.c:379 #, c-format msgid "ERROR: pipeline could not be constructed: %s.\n" msgstr "GABIM: i pamundur ndërtimi i pipeline: %s.\n" -#: tools/gst-launch.c:500 -#, c-format +#: tools/gst-launch.c:383 msgid "ERROR: pipeline could not be constructed.\n" msgstr "GABIM: i pamundur ndërtimi i pipeline.\n" -#: tools/gst-launch.c:504 +#: tools/gst-launch.c:387 #, c-format msgid "WARNING: erroneous pipeline: %s\n" msgstr "KUJDES: pipline e gabuar: %s\n" -#: tools/gst-launch.c:505 -#, c-format +#: tools/gst-launch.c:388 msgid " Trying to run anyway.\n" msgstr " Duke u përpjekur të zbatohet sidoqoftë.\n" -#: tools/gst-launch.c:532 -#, c-format +#: tools/gst-launch.c:408 msgid "ERROR: the 'pipeline' element wasn't found.\n" msgstr "GABIM: elementi 'konduktor' nuk u gjet.\n" -#: tools/gst-launch.c:539 -#, c-format +#: tools/gst-launch.c:417 msgid "RUNNING pipeline ...\n" msgstr "DUKE ZBATUAR pipeline ...\n" -#: tools/gst-launch.c:542 -#, c-format +#: tools/gst-launch.c:421 msgid "ERROR: pipeline doesn't want to play.\n" msgstr "GABIM: pipeline nuk dëshiron të luajë.\n" +#: tools/gst-launch.c:445 +#, c-format +msgid "Execution ended after %.2fs (%.2fs or %.2f%% idling).\n" +msgstr "" + #: tools/gst-register.c:49 #, fuzzy, c-format msgid "Added plugin %s with %d feature.\n" @@ -866,6 +812,39 @@ msgid_plural "Loaded %d plugins with %d features.\n" msgstr[0] "U ngarkuan %d plugins me %d %s.\n" msgstr[1] "U ngarkuan %d plugins me %d %s.\n" +#~ msgid "Disable accelerated CPU instructions" +#~ msgstr "Ç'aktivo instruksionet e përshpejtimit të CPU" + +#~ msgid "There is no element present to handle the stream's mime type %s." +#~ msgstr "" +#~ "Nuk ekziston asnjë element për të trajtuar llojin mime %s të fluksit." + +#~ msgid "Usage: gst-xmllaunch [ element.property=value ... ]\n" +#~ msgstr "" +#~ "Përdorimi: gst-xmllaunch [ element.property=vlera ... ]\n" + +#~ msgid "ERROR: parse of xml file '%s' failed.\n" +#~ msgstr "GABIM: analizimi i file xml '%s' dështoi.\n" + +#~ msgid "ERROR: no toplevel pipeline element in file '%s'.\n" +#~ msgstr "GABIM: asnjë element i pipline të toplevel tek file '%s'.\n" + +#~ msgid "WARNING: only one toplevel element is supported at this time." +#~ msgstr "KUJDES: vetëm një element toplevel suportohet aktualisht." + +#~ msgid "ERROR: could not parse command line argument %d: %s.\n" +#~ msgstr "" +#~ "GABIM: i pamundur analizimi i argumentit %d të rreshtit të komandës: %s.\n" + +#~ msgid "WARNING: element named '%s' not found.\n" +#~ msgstr "KUJDES: elementi me emrin '%s' nuk u gjet.\n" + +#~ msgid "Save xml representation of pipeline to FILE and exit" +#~ msgstr "Ruaj prezantimin xml të pipeline tek FILE dhe dil" + +#~ msgid "FILE" +#~ msgstr "FILE" + #~ msgid "caps" #~ msgstr "mbrojtëse" diff --git a/po/sr.po b/po/sr.po index 7190175d14..60fd0369df 100644 --- a/po/sr.po +++ b/po/sr.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: gstreamer 0.8.8\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2005-05-02 19:36+0200\n" +"POT-Creation-Date: 2005-05-17 18:37+0200\n" "PO-Revision-Date: 2005-01-27 16:58+0100\n" "Last-Translator: Danilo Segan \n" "Language-Team: Serbian \n" @@ -16,30 +16,30 @@ msgstr "" "Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && " "n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" -#: gst/gst.c:160 +#: gst/gst.c:157 msgid "Print the GStreamer version" msgstr "ИÑпиши издање ГÑтримера" -#: gst/gst.c:162 +#: gst/gst.c:159 msgid "Make all warnings fatal" msgstr "Учини Ñва упозорења кобним" -#: gst/gst.c:166 +#: gst/gst.c:163 msgid "Print available debug categories and exit" msgstr "ИÑпиши доÑтупне категорије за налажење грешака и заврши" -#: gst/gst.c:169 +#: gst/gst.c:166 msgid "" "Default debug level from 1 (only error) to 5 (anything) or 0 for no output" msgstr "" "Подразумевани ниво опширноÑти од 1 (Ñамо грешке) до 5 (Ñве) или 0 (без " "излаза)" -#: gst/gst.c:171 +#: gst/gst.c:168 msgid "LEVEL" msgstr "ÐИВО" -#: gst/gst.c:173 +#: gst/gst.c:170 msgid "" "Comma-separated list of category_name:level pairs to set specific levels for " "the individual categories. Example: GST_AUTOPLUG:5,GST_ELEMENT_*:3" @@ -47,31 +47,27 @@ msgstr "" "Запетом раздвојени ÑпиÑак парова име_категорије:ниво за поÑтављање нарочитих " "нивоа за појединачне категорије. Пример: GST_AUTOPLUG:5,GST_ELEMENT_*:3" -#: gst/gst.c:176 +#: gst/gst.c:173 msgid "LIST" msgstr "СПИСÐК" -#: gst/gst.c:178 +#: gst/gst.c:175 msgid "Disable colored debugging output" msgstr "ИÑкључи обојени излаз за иÑправљање грешака" -#: gst/gst.c:180 +#: gst/gst.c:177 msgid "Disable debugging" msgstr "ИÑкључи иÑправљање грешака" -#: gst/gst.c:184 -msgid "Disable accelerated CPU instructions" -msgstr "ИÑкључи убрзане инÑтрукције процеÑора" - -#: gst/gst.c:186 +#: gst/gst.c:181 msgid "Enable verbose plugin loading diagnostics" msgstr "Укључи опширну дијагноÑтику при учитавању додатка" -#: gst/gst.c:188 +#: gst/gst.c:183 msgid "PATHS" msgstr "ПУТÐЊЕ" -#: gst/gst.c:191 +#: gst/gst.c:186 #, fuzzy msgid "" "Comma-separated list of plugins to preload in addition to the list stored in " @@ -80,32 +76,32 @@ msgstr "" "Запетом раздвојен ÑпиÑак додатака који Ñе предучитавају поред ÑпиÑка из " "променљиве окружења GST_PLUGIN_PATH" -#: gst/gst.c:193 +#: gst/gst.c:188 msgid "PLUGINS" msgstr "ДОДÐЦИ" -#: gst/gst.c:196 +#: gst/gst.c:191 msgid "Disable trapping of segmentation faults during plugin loading" msgstr "ИÑкључи преÑретање погрешних приÑтупа меморији при учитавању додатака" -#: gst/gst.c:199 +#: gst/gst.c:194 msgid "SCHEDULER" msgstr "РÐСПОРЕЂИВÐЧ" -#: gst/gst.c:201 +#: gst/gst.c:196 msgid "Registry to use" msgstr "КориÑти региÑтар" -#: gst/gst.c:201 +#: gst/gst.c:196 msgid "REGISTRY" msgstr "РЕГИСТÐР" -#: gst/gst.c:214 +#: gst/gst.c:209 #, c-format msgid "path list for loading plugins (separated by '%s')" msgstr "ÑпиÑак путања за учитавање додатака (раздвојених Ñа '%s')" -#: gst/gst.c:218 +#: gst/gst.c:213 #, c-format msgid "Scheduler to use (default is '%s')" msgstr "КориÑти раÑпоређивач (подразумева Ñе '%s')" @@ -591,51 +587,46 @@ msgstr "" msgid ", " msgstr ", " -#: gst/autoplug/gstspider.c:466 -#, c-format -msgid "There is no element present to handle the stream's mime type %s." -msgstr "Ðије приÑутан елемент за баратање током МИМЕ врÑте %s." - -#: gst/elements/gstfilesink.c:268 +#: gst/elements/gstfilesink.c:243 msgid "No file name specified for writing." msgstr "Ðије наведено име датотеке за упиÑ." -#: gst/elements/gstfilesink.c:275 +#: gst/elements/gstfilesink.c:250 #, c-format msgid "Could not open file \"%s\" for writing." msgstr "Ðе могу да отворим датотеку „%s“ ради упиÑа." -#: gst/elements/gstfilesink.c:294 +#: gst/elements/gstfilesink.c:269 #, c-format msgid "Error closing file \"%s\"." msgstr "Грешка при затварању датотеке „%s“." -#: gst/elements/gstfilesink.c:364 gst/elements/gstfilesink.c:400 -#: gst/elements/gstfilesink.c:453 +#: gst/elements/gstfilesink.c:339 gst/elements/gstfilesink.c:375 +#: gst/elements/gstfilesink.c:428 #, c-format msgid "Error while writing to file \"%s\"." msgstr "Грешка при упиÑу у датотеку „%s“." -#: gst/elements/gstfilesrc.c:764 gst/elements/gstmultifilesrc.c:298 +#: gst/elements/gstfilesrc.c:725 msgid "No file name specified for reading." msgstr "Ðије наведено име датотеке за читање." -#: gst/elements/gstfilesrc.c:779 gst/elements/gstmultifilesrc.c:306 +#: gst/elements/gstfilesrc.c:740 #, c-format msgid "Could not open file \"%s\" for reading." msgstr "Ðе могу да отворим датотеку „%s“ ради читања." -#: gst/elements/gstfilesrc.c:790 +#: gst/elements/gstfilesrc.c:751 #, c-format msgid "\"%s\" is a directory." msgstr "\"%s\" је директоријум." -#: gst/elements/gstfilesrc.c:796 +#: gst/elements/gstfilesrc.c:757 #, c-format msgid "File \"%s\" is a socket." msgstr "Датотека „%s“ је Ñокет." -#: gst/elements/gstidentity.c:306 +#: gst/elements/gstidentity.c:276 msgid "Failed after iterations as requested." msgstr "ÐеуÑпех након траженог броја покушаја." @@ -724,125 +715,78 @@ msgstr "не могу да вежем завршни елемент за адр msgid "empty pipeline not allowed" msgstr "није допуштен празан цевовод" -#: tools/gst-inspect.c:1151 +#: tools/gst-inspect.c:1032 msgid "Print all elements" msgstr "ИÑпиши Ñве елементе" -#: tools/gst-launch.c:114 -#, c-format -msgid "" -"Execution ended after %s iterations (sum %s ns, average %s ns, min %s ns, " -"max %s ns).\n" -msgstr "" -"Извршавање завршено након %s покушаја (збир %s ns, проÑек %s ns, мин %s ns, " -"Ð¼Ð°ÐºÑ %s ns).\n" - -#: tools/gst-launch.c:141 -msgid "Usage: gst-xmllaunch [ element.property=value ... ]\n" -msgstr "" -"Употреба: gst-xmllaunch <датотека.xml> [ елемент.оÑобина=вредноÑÑ‚ ... ]\n" - -#: tools/gst-launch.c:149 -#, c-format -msgid "ERROR: parse of xml file '%s' failed.\n" -msgstr "ГРЕШКÐ: неуÑпешно рашчлањивање xml датотеке „%s“.\n" - -#: tools/gst-launch.c:155 -#, c-format -msgid "ERROR: no toplevel pipeline element in file '%s'.\n" -msgstr "ГРЕШКÐ: нема врховног елемента цевовода у датотеци „%s“.\n" - -#: tools/gst-launch.c:162 -#, c-format -msgid "WARNING: only one toplevel element is supported at this time." -msgstr "УПОЗОРЕЊЕ: тренутно је подржан Ñамо један врховни елемент." - -#: tools/gst-launch.c:173 -#, c-format -msgid "ERROR: could not parse command line argument %d: %s.\n" -msgstr "ГРЕШКÐ: не могу да рашчланим %d. аргумент наредбе: %s.\n" - -#: tools/gst-launch.c:184 -#, c-format -msgid "WARNING: element named '%s' not found.\n" -msgstr "УПОЗОРЕЊЕ: елемент Ñа именом „%s“ није нађен.\n" - -#: tools/gst-launch.c:327 +#: tools/gst-launch.c:190 #, c-format msgid "FOUND TAG : found by element \"%s\".\n" msgstr "ÐÐЂОХ ОЗÐÐКУ : нашао је елемент „%s“.\n" -#: tools/gst-launch.c:412 +#: tools/gst-launch.c:304 msgid "Output tags (also known as metadata)" msgstr "Излазне ознаке (такође познато и као метаподаци)" -#: tools/gst-launch.c:414 +#: tools/gst-launch.c:306 msgid "Output status information and property notifications" msgstr "ИÑпиши податке о Ñтању и обавештења о оÑобинама" -#: tools/gst-launch.c:416 +#: tools/gst-launch.c:308 msgid "Do not output status information of TYPE" msgstr "Ðе иÑпиÑуј податке о Ñтању за ВРСТУ" -#: tools/gst-launch.c:416 +#: tools/gst-launch.c:308 msgid "TYPE1,TYPE2,..." msgstr "ВРСТÐ1,ВРСТÐ2,..." -#: tools/gst-launch.c:419 -msgid "Save xml representation of pipeline to FILE and exit" -msgstr "Сачувај xml облик цевовода у ДÐТОТЕКУ и заврши" - -#: tools/gst-launch.c:419 -msgid "FILE" -msgstr "ДÐТОТЕКÐ" - -#: tools/gst-launch.c:422 +#: tools/gst-launch.c:310 msgid "Do not install a fault handler" msgstr "Ðе поÑтављај руковаоца грешкама" -#: tools/gst-launch.c:424 +#: tools/gst-launch.c:312 msgid "Print alloc trace (if enabled at compile time)" msgstr "ИÑпиши траг доделе меморије (ако је укључено при превођењу)" -#: tools/gst-launch.c:426 +#: tools/gst-launch.c:314 msgid "Number of times to iterate pipeline" msgstr "Број покушаја пуштања цевовода" -#: tools/gst-launch.c:496 +#: tools/gst-launch.c:379 #, c-format msgid "ERROR: pipeline could not be constructed: %s.\n" msgstr "ГРЕШКÐ: не могу да ÑаÑтавим цевовод: %s.\n" -#: tools/gst-launch.c:500 -#, c-format +#: tools/gst-launch.c:383 msgid "ERROR: pipeline could not be constructed.\n" msgstr "ГРЕШКÐ: не могу да ÑаÑтавим цевовод.\n" -#: tools/gst-launch.c:504 +#: tools/gst-launch.c:387 #, c-format msgid "WARNING: erroneous pipeline: %s\n" msgstr "УПОЗОРЕЊЕ: неиÑправан цевовод: %s\n" -#: tools/gst-launch.c:505 -#, c-format +#: tools/gst-launch.c:388 msgid " Trying to run anyway.\n" msgstr " Ипак покушавам да покренем.\n" -#: tools/gst-launch.c:532 -#, c-format +#: tools/gst-launch.c:408 msgid "ERROR: the 'pipeline' element wasn't found.\n" msgstr "ГРЕШКÐ: елемент „pipeline“ није нађен.\n" -#: tools/gst-launch.c:539 -#, c-format +#: tools/gst-launch.c:417 msgid "RUNNING pipeline ...\n" msgstr "Покрећем цевовод...\n" -#: tools/gst-launch.c:542 -#, c-format +#: tools/gst-launch.c:421 msgid "ERROR: pipeline doesn't want to play.\n" msgstr "ГРЕШКÐ: цевовод не жели да пуÑти.\n" +#: tools/gst-launch.c:445 +#, c-format +msgid "Execution ended after %.2fs (%.2fs or %.2f%% idling).\n" +msgstr "" + #: tools/gst-register.c:49 #, fuzzy, c-format msgid "Added plugin %s with %d feature.\n" @@ -879,6 +823,44 @@ msgstr[0] "Учитано %d додатака Ñа %d %s.\n" msgstr[1] "Учитано %d додатака Ñа %d %s.\n" msgstr[2] "Учитано %d додатака Ñа %d %s.\n" +#~ msgid "Disable accelerated CPU instructions" +#~ msgstr "ИÑкључи убрзане инÑтрукције процеÑора" + +#~ msgid "There is no element present to handle the stream's mime type %s." +#~ msgstr "Ðије приÑутан елемент за баратање током МИМЕ врÑте %s." + +#~ msgid "" +#~ "Execution ended after %s iterations (sum %s ns, average %s ns, min %s ns, " +#~ "max %s ns).\n" +#~ msgstr "" +#~ "Извршавање завршено након %s покушаја (збир %s ns, проÑек %s ns, мин %s " +#~ "ns, Ð¼Ð°ÐºÑ %s ns).\n" + +#~ msgid "Usage: gst-xmllaunch [ element.property=value ... ]\n" +#~ msgstr "" +#~ "Употреба: gst-xmllaunch <датотека.xml> [ елемент.оÑобина=вредноÑÑ‚ ... ]\n" + +#~ msgid "ERROR: parse of xml file '%s' failed.\n" +#~ msgstr "ГРЕШКÐ: неуÑпешно рашчлањивање xml датотеке „%s“.\n" + +#~ msgid "ERROR: no toplevel pipeline element in file '%s'.\n" +#~ msgstr "ГРЕШКÐ: нема врховног елемента цевовода у датотеци „%s“.\n" + +#~ msgid "WARNING: only one toplevel element is supported at this time." +#~ msgstr "УПОЗОРЕЊЕ: тренутно је подржан Ñамо један врховни елемент." + +#~ msgid "ERROR: could not parse command line argument %d: %s.\n" +#~ msgstr "ГРЕШКÐ: не могу да рашчланим %d. аргумент наредбе: %s.\n" + +#~ msgid "WARNING: element named '%s' not found.\n" +#~ msgstr "УПОЗОРЕЊЕ: елемент Ñа именом „%s“ није нађен.\n" + +#~ msgid "Save xml representation of pipeline to FILE and exit" +#~ msgstr "Сачувај xml облик цевовода у ДÐТОТЕКУ и заврши" + +#~ msgid "FILE" +#~ msgstr "ДÐТОТЕКÐ" + # bug: this should be full word #~ msgid "caps" #~ msgstr "могућноÑти" diff --git a/po/sv.po b/po/sv.po index e6b6b01b6b..1c09aa3f37 100644 --- a/po/sv.po +++ b/po/sv.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: gstreamer 0.8.7pre2\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2005-05-02 19:36+0200\n" +"POT-Creation-Date: 2005-05-17 18:37+0200\n" "PO-Revision-Date: 2004-12-21 14:49+0100\n" "Last-Translator: Christian Rose \n" "Language-Team: Swedish \n" @@ -17,30 +17,30 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: gst/gst.c:160 +#: gst/gst.c:157 msgid "Print the GStreamer version" msgstr "Skriv ut Gstreamer-versionen" -#: gst/gst.c:162 +#: gst/gst.c:159 msgid "Make all warnings fatal" msgstr "Gör alla varningar ödesdigra" -#: gst/gst.c:166 +#: gst/gst.c:163 msgid "Print available debug categories and exit" msgstr "Skriv ut tillgängliga felsökningskategorier och avsluta" -#: gst/gst.c:169 +#: gst/gst.c:166 msgid "" "Default debug level from 1 (only error) to 5 (anything) or 0 for no output" msgstr "" "StandardfelsökningsnivÃ¥ frÃ¥n 1 (endast fel) till 5 (allting) eller 0 för " "ingen utmatning" -#: gst/gst.c:171 +#: gst/gst.c:168 msgid "LEVEL" msgstr "NIVÃ…" -#: gst/gst.c:173 +#: gst/gst.c:170 msgid "" "Comma-separated list of category_name:level pairs to set specific levels for " "the individual categories. Example: GST_AUTOPLUG:5,GST_ELEMENT_*:3" @@ -48,31 +48,27 @@ msgstr "" "Kommaseparerad lista med kategorinamn:nivÃ¥-par för att ställa in specifika " "nivÃ¥er för de enskilda kategorierna. Exempel: GST_AUTOPLUG:5,GST_ELEMENT_*:3" -#: gst/gst.c:176 +#: gst/gst.c:173 msgid "LIST" msgstr "LISTA" -#: gst/gst.c:178 +#: gst/gst.c:175 msgid "Disable colored debugging output" msgstr "Inaktivera färglagd felsökningsutmatning" -#: gst/gst.c:180 +#: gst/gst.c:177 msgid "Disable debugging" msgstr "Inaktivera felsökning" -#: gst/gst.c:184 -msgid "Disable accelerated CPU instructions" -msgstr "Inaktivera accelererade processorinstruktioner" - -#: gst/gst.c:186 +#: gst/gst.c:181 msgid "Enable verbose plugin loading diagnostics" msgstr "Aktivera utförlig diagnostik vid inläsning av insticksmoduler" -#: gst/gst.c:188 +#: gst/gst.c:183 msgid "PATHS" msgstr "SÖKVÄGAR" -#: gst/gst.c:191 +#: gst/gst.c:186 msgid "" "Comma-separated list of plugins to preload in addition to the list stored in " "environment variable GST_PLUGIN_PATH" @@ -80,33 +76,33 @@ msgstr "" "Kommaseparerad lista med insticksmoduler att förhandsinläsa utöver listan " "som lagras i miljövariabeln GST_PLUGIN_PATH" -#: gst/gst.c:193 +#: gst/gst.c:188 msgid "PLUGINS" msgstr "INSTICKSMODULER" -#: gst/gst.c:196 +#: gst/gst.c:191 msgid "Disable trapping of segmentation faults during plugin loading" msgstr "" "Inaktivera fÃ¥ngst av segmenteringsfel under inläsning av insticksmoduler" -#: gst/gst.c:199 +#: gst/gst.c:194 msgid "SCHEDULER" msgstr "SCHEMALÄGGARE" -#: gst/gst.c:201 +#: gst/gst.c:196 msgid "Registry to use" msgstr "Register att använda" -#: gst/gst.c:201 +#: gst/gst.c:196 msgid "REGISTRY" msgstr "REGISTER" -#: gst/gst.c:214 +#: gst/gst.c:209 #, c-format msgid "path list for loading plugins (separated by '%s')" msgstr "sökvägslista för inläsning av insticksmoduler (Ã¥tskild av \"%s\")" -#: gst/gst.c:218 +#: gst/gst.c:213 #, c-format msgid "Scheduler to use (default is '%s')" msgstr "Schemaläggare att använda (standardvärdet är \"%s\")" @@ -585,52 +581,46 @@ msgstr "" msgid ", " msgstr ", " -#: gst/autoplug/gstspider.c:466 -#, c-format -msgid "There is no element present to handle the stream's mime type %s." -msgstr "" -"Det finns inget element tillgängligt för att hantera flödets mime-typ %s." - -#: gst/elements/gstfilesink.c:268 +#: gst/elements/gstfilesink.c:243 msgid "No file name specified for writing." msgstr "Inget filnamn angivet för skrivning." -#: gst/elements/gstfilesink.c:275 +#: gst/elements/gstfilesink.c:250 #, c-format msgid "Could not open file \"%s\" for writing." msgstr "Kunde inte öppna filen \"%s\" för skrivning." -#: gst/elements/gstfilesink.c:294 +#: gst/elements/gstfilesink.c:269 #, c-format msgid "Error closing file \"%s\"." msgstr "Fel vid stängning av filen \"%s\"." -#: gst/elements/gstfilesink.c:364 gst/elements/gstfilesink.c:400 -#: gst/elements/gstfilesink.c:453 +#: gst/elements/gstfilesink.c:339 gst/elements/gstfilesink.c:375 +#: gst/elements/gstfilesink.c:428 #, c-format msgid "Error while writing to file \"%s\"." msgstr "Fel vid skrivning till filen \"%s\"." -#: gst/elements/gstfilesrc.c:764 gst/elements/gstmultifilesrc.c:298 +#: gst/elements/gstfilesrc.c:725 msgid "No file name specified for reading." msgstr "Inget filnamn angivet för läsning." -#: gst/elements/gstfilesrc.c:779 gst/elements/gstmultifilesrc.c:306 +#: gst/elements/gstfilesrc.c:740 #, c-format msgid "Could not open file \"%s\" for reading." msgstr "Kunde inte öppna filen \"%s\" för läsning." -#: gst/elements/gstfilesrc.c:790 +#: gst/elements/gstfilesrc.c:751 #, c-format msgid "\"%s\" is a directory." msgstr "\"%s\" är en katalog." -#: gst/elements/gstfilesrc.c:796 +#: gst/elements/gstfilesrc.c:757 #, c-format msgid "File \"%s\" is a socket." msgstr "Filen \"%s\" är ett uttag." -#: gst/elements/gstidentity.c:306 +#: gst/elements/gstidentity.c:276 msgid "Failed after iterations as requested." msgstr "Misslyckades efter iterationer som begärt." @@ -721,126 +711,80 @@ msgstr "kunde inte länka utgÃ¥ngselementet för URI:n \"%s\"" msgid "empty pipeline not allowed" msgstr "tom rörledning är inte tillÃ¥tet" -#: tools/gst-inspect.c:1151 +#: tools/gst-inspect.c:1032 msgid "Print all elements" msgstr "Skriv ut alla element" -#: tools/gst-launch.c:114 -#, c-format -msgid "" -"Execution ended after %s iterations (sum %s ns, average %s ns, min %s ns, " -"max %s ns).\n" -msgstr "" -"Körning avslutades efter %s iterationer (totalt %s ns, medel %s ns, min %s " -"ns, max %s ns).\n" - -#: tools/gst-launch.c:141 -msgid "Usage: gst-xmllaunch [ element.property=value ... ]\n" -msgstr "Användning: gst-xmllaunch [ element.egenskap=värde ... ]\n" - -#: tools/gst-launch.c:149 -#, c-format -msgid "ERROR: parse of xml file '%s' failed.\n" -msgstr "FEL: tolkning av xml-filen \"%s\" misslyckades.\n" - -#: tools/gst-launch.c:155 -#, c-format -msgid "ERROR: no toplevel pipeline element in file '%s'.\n" -msgstr "FEL: inget rörledningselement pÃ¥ översta nivÃ¥n i filen \"%s\".\n" - -#: tools/gst-launch.c:162 -#, c-format -msgid "WARNING: only one toplevel element is supported at this time." -msgstr "VARNING: endast ett element pÃ¥ översta nivÃ¥n stöds just nu." - -#: tools/gst-launch.c:173 -#, c-format -msgid "ERROR: could not parse command line argument %d: %s.\n" -msgstr "FEL: kunde inte tolka kommandoradsargumentet %d: %s.\n" - -#: tools/gst-launch.c:184 -#, c-format -msgid "WARNING: element named '%s' not found.\n" -msgstr "VARNING: elementet med namnet \"%s\" hittades inte.\n" - -#: tools/gst-launch.c:327 +#: tools/gst-launch.c:190 #, c-format msgid "FOUND TAG : found by element \"%s\".\n" msgstr "HITTADE TAGG : hittat av elementet \"%s\".\n" -#: tools/gst-launch.c:412 +#: tools/gst-launch.c:304 msgid "Output tags (also known as metadata)" msgstr "Utmatningstaggar (även känt som metadata)" -#: tools/gst-launch.c:414 +#: tools/gst-launch.c:306 msgid "Output status information and property notifications" msgstr "Skriv ut statusinformation och egenskapsnotifieringar" -#: tools/gst-launch.c:416 +#: tools/gst-launch.c:308 msgid "Do not output status information of TYPE" msgstr "Skriv inte ut statusinformation av TYP" -#: tools/gst-launch.c:416 +#: tools/gst-launch.c:308 msgid "TYPE1,TYPE2,..." msgstr "TYP1,TYP2,..." -#: tools/gst-launch.c:419 -msgid "Save xml representation of pipeline to FILE and exit" -msgstr "Spara xml-representation av rörledningen i FIL och avsluta" - -#: tools/gst-launch.c:419 -msgid "FILE" -msgstr "FIL" - -#: tools/gst-launch.c:422 +#: tools/gst-launch.c:310 msgid "Do not install a fault handler" msgstr "Installera inte en felhanterare" -#: tools/gst-launch.c:424 +#: tools/gst-launch.c:312 msgid "Print alloc trace (if enabled at compile time)" msgstr "Skriv ut alloc-spÃ¥r (om aktiverat vid kompileringen)" -#: tools/gst-launch.c:426 +#: tools/gst-launch.c:314 msgid "Number of times to iterate pipeline" msgstr "Antalet gÃ¥nger som rörledningen ska itereras" -#: tools/gst-launch.c:496 +#: tools/gst-launch.c:379 #, c-format msgid "ERROR: pipeline could not be constructed: %s.\n" msgstr "FEL: rörledningen kunde inte konstrueras: %s.\n" -#: tools/gst-launch.c:500 -#, c-format +#: tools/gst-launch.c:383 msgid "ERROR: pipeline could not be constructed.\n" msgstr "FEL: rörledningen kunde inte konstrueras.\n" # Felrapporterat i http://bugzilla.gnome.org/show_bug.cgi?id=137431 -#: tools/gst-launch.c:504 +#: tools/gst-launch.c:387 #, c-format msgid "WARNING: erroneous pipeline: %s\n" msgstr "VARNING: felaktig rörledning: %s\n" # Felrapporterat i http://bugzilla.gnome.org/show_bug.cgi?id=137431 -#: tools/gst-launch.c:505 -#, c-format +#: tools/gst-launch.c:388 msgid " Trying to run anyway.\n" msgstr " Försöker köra ändÃ¥.\n" -#: tools/gst-launch.c:532 -#, c-format +#: tools/gst-launch.c:408 msgid "ERROR: the 'pipeline' element wasn't found.\n" msgstr "FEL: \"pipeline\"-elementet hittades inte.\n" -#: tools/gst-launch.c:539 -#, c-format +#: tools/gst-launch.c:417 msgid "RUNNING pipeline ...\n" msgstr "KÖR rörledning...\n" -#: tools/gst-launch.c:542 -#, c-format +#: tools/gst-launch.c:421 msgid "ERROR: pipeline doesn't want to play.\n" msgstr "FEL: rörledningen vill inte spela.\n" +#: tools/gst-launch.c:445 +#, c-format +msgid "Execution ended after %.2fs (%.2fs or %.2f%% idling).\n" +msgstr "" + #: tools/gst-register.c:49 #, fuzzy, c-format msgid "Added plugin %s with %d feature.\n" @@ -875,6 +819,45 @@ msgid_plural "Loaded %d plugins with %d features.\n" msgstr[0] "Läste in %d insticksmoduler med %d %s.\n" msgstr[1] "Läste in %d insticksmoduler med %d %s.\n" +#~ msgid "Disable accelerated CPU instructions" +#~ msgstr "Inaktivera accelererade processorinstruktioner" + +#~ msgid "There is no element present to handle the stream's mime type %s." +#~ msgstr "" +#~ "Det finns inget element tillgängligt för att hantera flödets mime-typ %s." + +#~ msgid "" +#~ "Execution ended after %s iterations (sum %s ns, average %s ns, min %s ns, " +#~ "max %s ns).\n" +#~ msgstr "" +#~ "Körning avslutades efter %s iterationer (totalt %s ns, medel %s ns, min %" +#~ "s ns, max %s ns).\n" + +#~ msgid "Usage: gst-xmllaunch [ element.property=value ... ]\n" +#~ msgstr "" +#~ "Användning: gst-xmllaunch [ element.egenskap=värde ... ]\n" + +#~ msgid "ERROR: parse of xml file '%s' failed.\n" +#~ msgstr "FEL: tolkning av xml-filen \"%s\" misslyckades.\n" + +#~ msgid "ERROR: no toplevel pipeline element in file '%s'.\n" +#~ msgstr "FEL: inget rörledningselement pÃ¥ översta nivÃ¥n i filen \"%s\".\n" + +#~ msgid "WARNING: only one toplevel element is supported at this time." +#~ msgstr "VARNING: endast ett element pÃ¥ översta nivÃ¥n stöds just nu." + +#~ msgid "ERROR: could not parse command line argument %d: %s.\n" +#~ msgstr "FEL: kunde inte tolka kommandoradsargumentet %d: %s.\n" + +#~ msgid "WARNING: element named '%s' not found.\n" +#~ msgstr "VARNING: elementet med namnet \"%s\" hittades inte.\n" + +#~ msgid "Save xml representation of pipeline to FILE and exit" +#~ msgstr "Spara xml-representation av rörledningen i FIL och avsluta" + +#~ msgid "FILE" +#~ msgstr "FIL" + # Osäker. Jag tror "caps" är kort för "capabilities". #~ msgid "Internal GStreamer error: caps problem. File a bug." #~ msgstr "Internt GStreamer-fel: förmÃ¥geproblem. Skicka en felrapport." diff --git a/po/tr.po b/po/tr.po index c38c298e36..facc1adaac 100644 --- a/po/tr.po +++ b/po/tr.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: gstreamer 0.8.0\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2005-05-02 19:36+0200\n" +"POT-Creation-Date: 2005-05-17 18:37+0200\n" "PO-Revision-Date: 2004-04-03 03:14+0300\n" "Last-Translator: Baris Cicek \n" "Language-Team: Turkish \n" @@ -14,30 +14,30 @@ msgstr "" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -#: gst/gst.c:160 +#: gst/gst.c:157 msgid "Print the GStreamer version" msgstr "GStreamer sürünümü yazdır" -#: gst/gst.c:162 +#: gst/gst.c:159 msgid "Make all warnings fatal" msgstr "Tüm uyarıları ölümcül yap" -#: gst/gst.c:166 +#: gst/gst.c:163 msgid "Print available debug categories and exit" msgstr "Geçerli hata ayıklama sınıflarını yazdır ve çık" -#: gst/gst.c:169 +#: gst/gst.c:166 msgid "" "Default debug level from 1 (only error) to 5 (anything) or 0 for no output" msgstr "" "Öntanımlı hata ayıklama seviyesi 1'den (sadece hatalar) 5'e (her ÅŸey) kadar " "ya da çıktı olmaması için 0" -#: gst/gst.c:171 +#: gst/gst.c:168 msgid "LEVEL" msgstr "SEVÄ°YE" -#: gst/gst.c:173 +#: gst/gst.c:170 msgid "" "Comma-separated list of category_name:level pairs to set specific levels for " "the individual categories. Example: GST_AUTOPLUG:5,GST_ELEMENT_*:3" @@ -45,31 +45,27 @@ msgstr "" "Ayrı sınıfların belirli seviyeleri için sınıf_ismi:seviye çiftlerinin virgül " "ile ayrılmış listesi. Örnek: GST_AUTOPLUG:5,GST_ELEMENT_*:3" -#: gst/gst.c:176 +#: gst/gst.c:173 msgid "LIST" msgstr "LÄ°STE" -#: gst/gst.c:178 +#: gst/gst.c:175 msgid "Disable colored debugging output" msgstr "Renkli hata ayıklama çıktısını kapat" -#: gst/gst.c:180 +#: gst/gst.c:177 msgid "Disable debugging" msgstr "Hata ayıklamayı kapat" -#: gst/gst.c:184 -msgid "Disable accelerated CPU instructions" -msgstr "Hızlandırılmış CPU iÅŸlemlerini kapat" - -#: gst/gst.c:186 +#: gst/gst.c:181 msgid "Enable verbose plugin loading diagnostics" msgstr "Ayrıntılı eklenti yükleme detaylarını etkinleÅŸtir" -#: gst/gst.c:188 +#: gst/gst.c:183 msgid "PATHS" msgstr "YOLLAR" -#: gst/gst.c:191 +#: gst/gst.c:186 #, fuzzy msgid "" "Comma-separated list of plugins to preload in addition to the list stored in " @@ -78,32 +74,32 @@ msgstr "" "Çevre deÄŸiÅŸkeni GST_PLUGIN_PATH içinde saklanan listeye ek olarak önceden " "yüklenecek eklentilerin virgün ile ayırılmış listesi" -#: gst/gst.c:193 +#: gst/gst.c:188 msgid "PLUGINS" msgstr "EKLENTÄ°LER" -#: gst/gst.c:196 +#: gst/gst.c:191 msgid "Disable trapping of segmentation faults during plugin loading" msgstr "Eklenti yüklenirken kesimleme hatalarını yakalamayı kapat" -#: gst/gst.c:199 +#: gst/gst.c:194 msgid "SCHEDULER" msgstr "ZAMANLANDIRICI" -#: gst/gst.c:201 +#: gst/gst.c:196 msgid "Registry to use" msgstr "Kullanılacak kayıt" -#: gst/gst.c:201 +#: gst/gst.c:196 msgid "REGISTRY" msgstr "KAYIT" -#: gst/gst.c:214 +#: gst/gst.c:209 #, fuzzy, c-format msgid "path list for loading plugins (separated by '%s')" msgstr "eklenti yüklemek için yol listesi (' ile ayırılmış" -#: gst/gst.c:218 +#: gst/gst.c:213 #, fuzzy, c-format msgid "Scheduler to use (default is '%s')" msgstr "Kullanılacak zamanlandırıcı ('" @@ -583,51 +579,46 @@ msgstr "" msgid ", " msgstr ", " -#: gst/autoplug/gstspider.c:466 -#, c-format -msgid "There is no element present to handle the stream's mime type %s." -msgstr "Akımın %s mime türünü iÅŸleyebilecek hiç bir öğe yok." - -#: gst/elements/gstfilesink.c:268 +#: gst/elements/gstfilesink.c:243 msgid "No file name specified for writing." msgstr "Yazım için hiç bir dosya adı belirtilmedi." -#: gst/elements/gstfilesink.c:275 +#: gst/elements/gstfilesink.c:250 #, c-format msgid "Could not open file \"%s\" for writing." msgstr "\"%s\" dosyası yazım için açılamadı." -#: gst/elements/gstfilesink.c:294 +#: gst/elements/gstfilesink.c:269 #, c-format msgid "Error closing file \"%s\"." msgstr "\"%s\" kapatılırken hata." -#: gst/elements/gstfilesink.c:364 gst/elements/gstfilesink.c:400 -#: gst/elements/gstfilesink.c:453 +#: gst/elements/gstfilesink.c:339 gst/elements/gstfilesink.c:375 +#: gst/elements/gstfilesink.c:428 #, c-format msgid "Error while writing to file \"%s\"." msgstr "\"%s\" dosyası yazılırken hata." -#: gst/elements/gstfilesrc.c:764 gst/elements/gstmultifilesrc.c:298 +#: gst/elements/gstfilesrc.c:725 msgid "No file name specified for reading." msgstr "Okuma için hiç bir dosya adı belirtilmedi." -#: gst/elements/gstfilesrc.c:779 gst/elements/gstmultifilesrc.c:306 +#: gst/elements/gstfilesrc.c:740 #, c-format msgid "Could not open file \"%s\" for reading." msgstr "\"%s\" dosyası okuma için açılamadı." -#: gst/elements/gstfilesrc.c:790 +#: gst/elements/gstfilesrc.c:751 #, c-format msgid "\"%s\" is a directory." msgstr "" -#: gst/elements/gstfilesrc.c:796 +#: gst/elements/gstfilesrc.c:757 #, fuzzy, c-format msgid "File \"%s\" is a socket." msgstr "\"%s\" dosyası düzenli bir dosya deÄŸil." -#: gst/elements/gstidentity.c:306 +#: gst/elements/gstidentity.c:276 msgid "Failed after iterations as requested." msgstr "Ä°stenildiÄŸi gibi tekrarlama baÅŸarısız oldu." @@ -716,123 +707,79 @@ msgstr "\"%s\" URI'si için 'sink' öğesi baÄŸlanamadı" msgid "empty pipeline not allowed" msgstr "boÅŸ boruhattına izin verilmiyor" -#: tools/gst-inspect.c:1151 +#: tools/gst-inspect.c:1032 #, fuzzy msgid "Print all elements" msgstr "\"%s\" öğesi yok" -#: tools/gst-launch.c:114 -#, c-format -msgid "" -"Execution ended after %s iterations (sum %s ns, average %s ns, min %s ns, " -"max %s ns).\n" -msgstr "" - -#: tools/gst-launch.c:141 -msgid "Usage: gst-xmllaunch [ element.property=value ... ]\n" -msgstr "Kullanım: gst-xmllaunch [ öğe.özellik=deÄŸer ... ]\n" - -#: tools/gst-launch.c:149 -#, c-format -msgid "ERROR: parse of xml file '%s' failed.\n" -msgstr "HATA: xml dosyası '%s' ayrıştırması baÅŸarısız.\n" - -#: tools/gst-launch.c:155 -#, c-format -msgid "ERROR: no toplevel pipeline element in file '%s'.\n" -msgstr "HATA: '%s' dosyasında üst seviye öğesi bulunamadı.\n" - -#: tools/gst-launch.c:162 -#, c-format -msgid "WARNING: only one toplevel element is supported at this time." -msgstr "UYARI: Åžu anda sadece bir tane üst seviye öğesi destekleniyor." - -#: tools/gst-launch.c:173 -#, c-format -msgid "ERROR: could not parse command line argument %d: %s.\n" -msgstr "HATA: komut satırı argümanı %d ayrıştırılamadı: %s.\n" - -#: tools/gst-launch.c:184 -#, c-format -msgid "WARNING: element named '%s' not found.\n" -msgstr "UYARI: '%s' isimli öğe bulunamadı.\n" - -#: tools/gst-launch.c:327 +#: tools/gst-launch.c:190 #, c-format msgid "FOUND TAG : found by element \"%s\".\n" msgstr "ETÄ°KET BULUNDU : \"%s\" öğesi tarafından bulundu.\n" -#: tools/gst-launch.c:412 +#: tools/gst-launch.c:304 msgid "Output tags (also known as metadata)" msgstr "Çıktı etiketleri (metadata olarak da bilinir)" -#: tools/gst-launch.c:414 +#: tools/gst-launch.c:306 msgid "Output status information and property notifications" msgstr "Çıktı durum bilgisi ve özellik uyarıları" -#: tools/gst-launch.c:416 +#: tools/gst-launch.c:308 msgid "Do not output status information of TYPE" msgstr "TÃœRÃœN durum bilgisini gösterme" -#: tools/gst-launch.c:416 +#: tools/gst-launch.c:308 msgid "TYPE1,TYPE2,..." msgstr "TÃœR1,TÃœR2,..." -#: tools/gst-launch.c:419 -msgid "Save xml representation of pipeline to FILE and exit" -msgstr "Boruhattının xml belirtimini DOSYA'ya kaydet ve çık" - -#: tools/gst-launch.c:419 -msgid "FILE" -msgstr "DOSYA" - -#: tools/gst-launch.c:422 +#: tools/gst-launch.c:310 msgid "Do not install a fault handler" msgstr "Hatalı iÅŸleticiyi kurma" -#: tools/gst-launch.c:424 +#: tools/gst-launch.c:312 msgid "Print alloc trace (if enabled at compile time)" msgstr "'alloc' takibini yazdır (derleme sırasında etkinleÅŸtirilmiÅŸse)" -#: tools/gst-launch.c:426 +#: tools/gst-launch.c:314 msgid "Number of times to iterate pipeline" msgstr "Boruhattının kaç defa tekrarlanacağı" -#: tools/gst-launch.c:496 +#: tools/gst-launch.c:379 #, c-format msgid "ERROR: pipeline could not be constructed: %s.\n" msgstr "HATA: boruhattı oluÅŸturulamadı: %s.\n" -#: tools/gst-launch.c:500 -#, c-format +#: tools/gst-launch.c:383 msgid "ERROR: pipeline could not be constructed.\n" msgstr "HATA: boruhattı oluÅŸturulamadı.\n" -#: tools/gst-launch.c:504 +#: tools/gst-launch.c:387 #, c-format msgid "WARNING: erroneous pipeline: %s\n" msgstr "UYARI: hatalı boruhattı: %s\n" -#: tools/gst-launch.c:505 -#, c-format +#: tools/gst-launch.c:388 msgid " Trying to run anyway.\n" msgstr " Gene de çalıştırma deneniyor.\n" -#: tools/gst-launch.c:532 -#, c-format +#: tools/gst-launch.c:408 msgid "ERROR: the 'pipeline' element wasn't found.\n" msgstr "HATA: 'pipeline' öğesi bulunamadı.\n" -#: tools/gst-launch.c:539 -#, c-format +#: tools/gst-launch.c:417 msgid "RUNNING pipeline ...\n" msgstr "BORUHATTI çalıştırılıyor ...\n" -#: tools/gst-launch.c:542 -#, c-format +#: tools/gst-launch.c:421 msgid "ERROR: pipeline doesn't want to play.\n" msgstr "HATA: boruhattı çalmak istemiyor.\n" +#: tools/gst-launch.c:445 +#, c-format +msgid "Execution ended after %.2fs (%.2fs or %.2f%% idling).\n" +msgstr "" + #: tools/gst-register.c:49 #, c-format msgid "Added plugin %s with %d feature.\n" @@ -867,6 +814,36 @@ msgid_plural "Loaded %d plugins with %d features.\n" msgstr[0] "" msgstr[1] "" +#~ msgid "Disable accelerated CPU instructions" +#~ msgstr "Hızlandırılmış CPU iÅŸlemlerini kapat" + +#~ msgid "There is no element present to handle the stream's mime type %s." +#~ msgstr "Akımın %s mime türünü iÅŸleyebilecek hiç bir öğe yok." + +#~ msgid "Usage: gst-xmllaunch [ element.property=value ... ]\n" +#~ msgstr "Kullanım: gst-xmllaunch [ öğe.özellik=deÄŸer ... ]\n" + +#~ msgid "ERROR: parse of xml file '%s' failed.\n" +#~ msgstr "HATA: xml dosyası '%s' ayrıştırması baÅŸarısız.\n" + +#~ msgid "ERROR: no toplevel pipeline element in file '%s'.\n" +#~ msgstr "HATA: '%s' dosyasında üst seviye öğesi bulunamadı.\n" + +#~ msgid "WARNING: only one toplevel element is supported at this time." +#~ msgstr "UYARI: Åžu anda sadece bir tane üst seviye öğesi destekleniyor." + +#~ msgid "ERROR: could not parse command line argument %d: %s.\n" +#~ msgstr "HATA: komut satırı argümanı %d ayrıştırılamadı: %s.\n" + +#~ msgid "WARNING: element named '%s' not found.\n" +#~ msgstr "UYARI: '%s' isimli öğe bulunamadı.\n" + +#~ msgid "Save xml representation of pipeline to FILE and exit" +#~ msgstr "Boruhattının xml belirtimini DOSYA'ya kaydet ve çık" + +#~ msgid "FILE" +#~ msgstr "DOSYA" + #~ msgid "caps" #~ msgstr "kabiliyetler" diff --git a/po/uk.po b/po/uk.po index a2314050b0..819dfe5895 100644 --- a/po/uk.po +++ b/po/uk.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: gstreamer 0.8.4\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2005-05-02 19:36+0200\n" +"POT-Creation-Date: 2005-05-17 18:37+0200\n" "PO-Revision-Date: 2004-09-06 15:16+0300\n" "Last-Translator: Maxim V. Dziumanenko \n" "Language-Team: Ukrainian \n" @@ -17,30 +17,30 @@ msgstr "" "Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%" "10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" -#: gst/gst.c:160 +#: gst/gst.c:157 msgid "Print the GStreamer version" msgstr "ВивеÑти верÑÑ–ÑŽ GStreamer" -#: gst/gst.c:162 +#: gst/gst.c:159 msgid "Make all warnings fatal" msgstr "Вважати вÑÑ– Ð¿Ð¾Ð¿ÐµÑ€ÐµÐ´Ð¶ÐµÐ½Ð½Ñ Ð¿Ð¾Ð¼Ð¸Ð»ÐºÐ°Ð¼Ð¸" -#: gst/gst.c:166 +#: gst/gst.c:163 msgid "Print available debug categories and exit" msgstr "ВивеÑти наÑвні категорії Ð½Ð°Ð»Ð°Ð³Ð¾Ð´Ð¶ÐµÐ½Ð½Ñ Ñ‚Ð° вийти" -#: gst/gst.c:169 +#: gst/gst.c:166 msgid "" "Default debug level from 1 (only error) to 5 (anything) or 0 for no output" msgstr "" "Типовий рівень Ð½Ð°Ð»Ð°Ð³Ð¾Ð´Ð¶ÐµÐ½Ð½Ñ Ð²Ñ–Ð´ 1 (лише помилки) до 5 (уÑе), або 0 - без " "налагодженнÑ" -#: gst/gst.c:171 +#: gst/gst.c:168 msgid "LEVEL" msgstr "РІВЕÐЬ" -#: gst/gst.c:173 +#: gst/gst.c:170 msgid "" "Comma-separated list of category_name:level pairs to set specific levels for " "the individual categories. Example: GST_AUTOPLUG:5,GST_ELEMENT_*:3" @@ -48,31 +48,27 @@ msgstr "" "Перелік розділених комою пар \"назва_категорії:рівень\" Ð´Ð»Ñ Ð²ÑÑ‚Ð°Ð½Ð¾Ð²Ð»ÐµÐ½Ð½Ñ " "певних рівнів окремим категоріÑм. Ðаприклад: GST_AUTOPLUG:5,GST_ELEMENT_*:3" -#: gst/gst.c:176 +#: gst/gst.c:173 msgid "LIST" msgstr "ПЕРЕЛІК" -#: gst/gst.c:178 +#: gst/gst.c:175 msgid "Disable colored debugging output" msgstr "Вимкнути Ð¾Ñ„Ð¾Ñ€Ð¼Ð»ÐµÐ½Ð½Ñ ÐºÐ¾Ð»ÑŒÐ¾Ñ€Ð¾Ð¼ налагоджувальних повідомлень" -#: gst/gst.c:180 +#: gst/gst.c:177 msgid "Disable debugging" msgstr "Вимкнути налагодженнÑ" -#: gst/gst.c:184 -msgid "Disable accelerated CPU instructions" -msgstr "Вимкнути приÑкорені інÑтрукції процеÑора" - -#: gst/gst.c:186 +#: gst/gst.c:181 msgid "Enable verbose plugin loading diagnostics" msgstr "Вимкнути докладну діагноÑтику Ð·Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶ÐµÐ½Ð½Ñ Ð¼Ð¾Ð´ÑƒÐ»Ñ–Ð²" -#: gst/gst.c:188 +#: gst/gst.c:183 msgid "PATHS" msgstr "ШЛЯХИ" -#: gst/gst.c:191 +#: gst/gst.c:186 #, fuzzy msgid "" "Comma-separated list of plugins to preload in addition to the list stored in " @@ -81,32 +77,32 @@ msgstr "" "Перелік розділених комою назв модулів, додаткових до переліку, що " "зберігаєтьÑÑ Ñƒ змінній Ð¾Ñ‚Ð¾Ñ‡ÐµÐ½Ð½Ñ GST_PLUGIN_PATH" -#: gst/gst.c:193 +#: gst/gst.c:188 msgid "PLUGINS" msgstr "МОДУЛІ" -#: gst/gst.c:196 +#: gst/gst.c:191 msgid "Disable trapping of segmentation faults during plugin loading" msgstr "Вимкнути Ð¿ÐµÑ€ÐµÑ…Ð¾Ð¿Ð»ÐµÐ½Ð½Ñ Ð¿Ð¾Ð¼Ð¸Ð»Ð¾Ðº Ñегментації при завантаженні модулів" -#: gst/gst.c:199 +#: gst/gst.c:194 msgid "SCHEDULER" msgstr "ПЛÐÐУВÐЛЬÐИК" -#: gst/gst.c:201 +#: gst/gst.c:196 msgid "Registry to use" msgstr "РеєÑÑ‚Ñ€, що викориÑтовуєтьÑÑ" -#: gst/gst.c:201 +#: gst/gst.c:196 msgid "REGISTRY" msgstr "РЕЄСТР" -#: gst/gst.c:214 +#: gst/gst.c:209 #, c-format msgid "path list for loading plugins (separated by '%s')" msgstr "перелік шлÑхів у Ñких шукаютьÑÑ Ð¼Ð¾Ð´ÑƒÐ»Ñ– (розділюютьÑÑ Ñимволом '%s')" -#: gst/gst.c:218 +#: gst/gst.c:213 #, c-format msgid "Scheduler to use (default is '%s')" msgstr "Планувальник, що викориÑтовуєтьÑÑ (типовий '%s')" @@ -591,51 +587,46 @@ msgstr "" msgid ", " msgstr ", " -#: gst/autoplug/gstspider.c:466 -#, c-format -msgid "There is no element present to handle the stream's mime type %s." -msgstr "Ðемає елементу Ð´Ð»Ñ Ð¾Ð±Ñ€Ð¾Ð±ÐºÐ¸ потоку з MIME типом %s." - -#: gst/elements/gstfilesink.c:268 +#: gst/elements/gstfilesink.c:243 msgid "No file name specified for writing." msgstr "Ðе вказана назва файлу Ð´Ð»Ñ Ð·Ð°Ð¿Ð¸Ñу." -#: gst/elements/gstfilesink.c:275 +#: gst/elements/gstfilesink.c:250 #, c-format msgid "Could not open file \"%s\" for writing." msgstr "Ðе вдаєтьÑÑ Ð²Ñ–Ð´ÐºÑ€Ð¸Ñ‚Ð¸ файл \"%s\" Ð´Ð»Ñ Ð·Ð°Ð¿Ð¸Ñу." -#: gst/elements/gstfilesink.c:294 +#: gst/elements/gstfilesink.c:269 #, c-format msgid "Error closing file \"%s\"." msgstr "Помилка Ð·Ð°ÐºÑ€Ð¸Ð²Ð°Ð½Ð½Ñ Ñ„Ð°Ð¹Ð»Ñƒ \"%s\"." -#: gst/elements/gstfilesink.c:364 gst/elements/gstfilesink.c:400 -#: gst/elements/gstfilesink.c:453 +#: gst/elements/gstfilesink.c:339 gst/elements/gstfilesink.c:375 +#: gst/elements/gstfilesink.c:428 #, c-format msgid "Error while writing to file \"%s\"." msgstr "Помилка при запиÑуванні у файл \"%s\"." -#: gst/elements/gstfilesrc.c:764 gst/elements/gstmultifilesrc.c:298 +#: gst/elements/gstfilesrc.c:725 msgid "No file name specified for reading." msgstr "Ðе вказана назва файлу Ð´Ð»Ñ Ñ‡Ð¸Ñ‚Ð°Ð½Ð½Ñ." -#: gst/elements/gstfilesrc.c:779 gst/elements/gstmultifilesrc.c:306 +#: gst/elements/gstfilesrc.c:740 #, c-format msgid "Could not open file \"%s\" for reading." msgstr "Ðе вдаєтьÑÑ Ð²Ñ–Ð´ÐºÑ€Ð¸Ñ‚Ð¸ файл \"%s\" Ð´Ð»Ñ Ñ‡Ð¸Ñ‚Ð°Ð½Ð½Ñ." -#: gst/elements/gstfilesrc.c:790 +#: gst/elements/gstfilesrc.c:751 #, c-format msgid "\"%s\" is a directory." msgstr "\"%s\" Ñ” каталогом." -#: gst/elements/gstfilesrc.c:796 +#: gst/elements/gstfilesrc.c:757 #, c-format msgid "File \"%s\" is a socket." msgstr "Файл \"%s\" Ñ” Ñокетом." -#: gst/elements/gstidentity.c:306 +#: gst/elements/gstidentity.c:276 msgid "Failed after iterations as requested." msgstr "Помилка піÑÐ»Ñ Ñ–Ñ‚ÐµÑ€Ð°Ñ†Ñ–Ð¹ у запитаному порÑдку." @@ -725,124 +716,78 @@ msgstr "не вдаєтьÑÑ Ð¿Ñ€Ð¸Ð²'Ñзати елемент-Ñпожива msgid "empty pipeline not allowed" msgstr "порожній канал не допуÑкаєтьÑÑ" -#: tools/gst-inspect.c:1151 +#: tools/gst-inspect.c:1032 msgid "Print all elements" msgstr "ВивеÑти уÑÑ– елементи" -#: tools/gst-launch.c:114 -#, c-format -msgid "" -"Execution ended after %s iterations (sum %s ns, average %s ns, min %s ns, " -"max %s ns).\n" -msgstr "" - -#: tools/gst-launch.c:141 -msgid "Usage: gst-xmllaunch [ element.property=value ... ]\n" -msgstr "" -"ВикориÑтаннÑ: gst-xmllaunch [ елемент.влаÑтивіÑÑ‚ÑŒ=Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ ... ]\n" - -#: tools/gst-launch.c:149 -#, c-format -msgid "ERROR: parse of xml file '%s' failed.\n" -msgstr "ПОМИЛКÐ: помилка при аналізі xml файлу \"%s\".\n" - -#: tools/gst-launch.c:155 -#, c-format -msgid "ERROR: no toplevel pipeline element in file '%s'.\n" -msgstr "ПОМИЛКÐ: немає верхнього елементу каналу у файлі \"%s\".\n" - -#: tools/gst-launch.c:162 -#, c-format -msgid "WARNING: only one toplevel element is supported at this time." -msgstr "ПОПЕРЕДЖЕÐÐЯ: наразі підтримуєтьÑÑ Ð»Ð¸ÑˆÐµ один верхній елемент." - -#: tools/gst-launch.c:173 -#, c-format -msgid "ERROR: could not parse command line argument %d: %s.\n" -msgstr "" -"ПОМИЛКÐ: не вдаєтьÑÑ Ð¿Ñ€Ð¾Ð°Ð½Ð°Ð»Ñ–Ð·ÑƒÐ²Ð°Ñ‚Ð¸ аргумент командного Ñ€Ñдка %d: %s.\n" - -#: tools/gst-launch.c:184 -#, c-format -msgid "WARNING: element named '%s' not found.\n" -msgstr "ПОПЕРЕДЖЕÐÐЯ: елемент з назвою \"%s\" не Ñ–Ñнує.\n" - -#: tools/gst-launch.c:327 +#: tools/gst-launch.c:190 #, c-format msgid "FOUND TAG : found by element \"%s\".\n" msgstr "ЗÐÐЙДЕÐО ТЕГ : знайдено у елементі \"%s\".\n" -#: tools/gst-launch.c:412 +#: tools/gst-launch.c:304 msgid "Output tags (also known as metadata)" msgstr "ВивеÑти теги (також відомі Ñк метадані)" -#: tools/gst-launch.c:414 +#: tools/gst-launch.c:306 msgid "Output status information and property notifications" msgstr "ВивеÑти інформацію про ÑÑ‚Ð°Ñ‚ÑƒÑ Ñ‚Ð° ÑÐ¿Ð¾Ð²Ñ–Ñ‰ÐµÐ½Ð½Ñ Ð²Ð»Ð°ÑтивоÑтей" -#: tools/gst-launch.c:416 +#: tools/gst-launch.c:308 msgid "Do not output status information of TYPE" msgstr "Ðе виводити інформацію про ÑÑ‚Ð°Ñ‚ÑƒÑ Ñ‚Ð¸Ð¿Ñƒ ТИП" -#: tools/gst-launch.c:416 +#: tools/gst-launch.c:308 msgid "TYPE1,TYPE2,..." msgstr "ТИП1,ТИП2,..." -#: tools/gst-launch.c:419 -msgid "Save xml representation of pipeline to FILE and exit" -msgstr "Зберегти xml предÑÑ‚Ð°Ð²Ð»ÐµÐ½Ð½Ñ ÐºÐ°Ð½Ð°Ð»Ñƒ у файл ФÐЙЛ та завершитиÑÑŒ" - -#: tools/gst-launch.c:419 -msgid "FILE" -msgstr "ФÐЙЛ" - -#: tools/gst-launch.c:422 +#: tools/gst-launch.c:310 msgid "Do not install a fault handler" msgstr "Ðе вÑтановлювати обробник збоїв" -#: tools/gst-launch.c:424 +#: tools/gst-launch.c:312 msgid "Print alloc trace (if enabled at compile time)" msgstr "ВивеÑти траÑу розподілу (Ñкщо ввімкнено при компілÑції)" -#: tools/gst-launch.c:426 +#: tools/gst-launch.c:314 msgid "Number of times to iterate pipeline" msgstr "КількіÑÑ‚ÑŒ ітерацій каналу" -#: tools/gst-launch.c:496 +#: tools/gst-launch.c:379 #, c-format msgid "ERROR: pipeline could not be constructed: %s.\n" msgstr "ПОМИЛКÐ: канал не може бути ÑконÑтруйований: %s.\n" -#: tools/gst-launch.c:500 -#, c-format +#: tools/gst-launch.c:383 msgid "ERROR: pipeline could not be constructed.\n" msgstr "ПОМИЛКÐ: канал не може бути ÑконÑтруйований.\n" -#: tools/gst-launch.c:504 +#: tools/gst-launch.c:387 #, c-format msgid "WARNING: erroneous pipeline: %s\n" msgstr "ПОПЕРЕДЖЕÐÐЯ: помилковий канал: %s\n" -#: tools/gst-launch.c:505 -#, c-format +#: tools/gst-launch.c:388 msgid " Trying to run anyway.\n" msgstr " Спроба запуÑтитиÑÑŒ у будь-Ñкому разі.\n" -#: tools/gst-launch.c:532 -#, c-format +#: tools/gst-launch.c:408 msgid "ERROR: the 'pipeline' element wasn't found.\n" msgstr "ПОМИЛКÐ: не знайдений елемент \"pipeline\".\n" -#: tools/gst-launch.c:539 -#, c-format +#: tools/gst-launch.c:417 msgid "RUNNING pipeline ...\n" msgstr "ЗÐПУСКÐЄТЬСЯ канал ...\n" -#: tools/gst-launch.c:542 -#, c-format +#: tools/gst-launch.c:421 msgid "ERROR: pipeline doesn't want to play.\n" msgstr "ПОМИЛКÐ: канал не може почати відтвореннÑ.\n" +#: tools/gst-launch.c:445 +#, c-format +msgid "Execution ended after %.2fs (%.2fs or %.2f%% idling).\n" +msgstr "" + #: tools/gst-register.c:49 #, fuzzy, c-format msgid "Added plugin %s with %d feature.\n" @@ -879,6 +824,39 @@ msgstr[0] "Завантажено %d модулів з %d %s.\n" msgstr[1] "Завантажено %d модулів з %d %s.\n" msgstr[2] "Завантажено %d модулів з %d %s.\n" +#~ msgid "Disable accelerated CPU instructions" +#~ msgstr "Вимкнути приÑкорені інÑтрукції процеÑора" + +#~ msgid "There is no element present to handle the stream's mime type %s." +#~ msgstr "Ðемає елементу Ð´Ð»Ñ Ð¾Ð±Ñ€Ð¾Ð±ÐºÐ¸ потоку з MIME типом %s." + +#~ msgid "Usage: gst-xmllaunch [ element.property=value ... ]\n" +#~ msgstr "" +#~ "ВикориÑтаннÑ: gst-xmllaunch [ елемент." +#~ "влаÑтивіÑÑ‚ÑŒ=Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ ... ]\n" + +#~ msgid "ERROR: parse of xml file '%s' failed.\n" +#~ msgstr "ПОМИЛКÐ: помилка при аналізі xml файлу \"%s\".\n" + +#~ msgid "ERROR: no toplevel pipeline element in file '%s'.\n" +#~ msgstr "ПОМИЛКÐ: немає верхнього елементу каналу у файлі \"%s\".\n" + +#~ msgid "WARNING: only one toplevel element is supported at this time." +#~ msgstr "ПОПЕРЕДЖЕÐÐЯ: наразі підтримуєтьÑÑ Ð»Ð¸ÑˆÐµ один верхній елемент." + +#~ msgid "ERROR: could not parse command line argument %d: %s.\n" +#~ msgstr "" +#~ "ПОМИЛКÐ: не вдаєтьÑÑ Ð¿Ñ€Ð¾Ð°Ð½Ð°Ð»Ñ–Ð·ÑƒÐ²Ð°Ñ‚Ð¸ аргумент командного Ñ€Ñдка %d: %s.\n" + +#~ msgid "WARNING: element named '%s' not found.\n" +#~ msgstr "ПОПЕРЕДЖЕÐÐЯ: елемент з назвою \"%s\" не Ñ–Ñнує.\n" + +#~ msgid "Save xml representation of pipeline to FILE and exit" +#~ msgstr "Зберегти xml предÑÑ‚Ð°Ð²Ð»ÐµÐ½Ð½Ñ ÐºÐ°Ð½Ð°Ð»Ñƒ у файл ФÐЙЛ та завершитиÑÑŒ" + +#~ msgid "FILE" +#~ msgstr "ФÐЙЛ" + #~ msgid "caps" #~ msgstr "можливоÑÑ‚Ñ–" diff --git a/po/vi.po b/po/vi.po index 4558619c86..554ab33703 100644 --- a/po/vi.po +++ b/po/vi.po @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: gstreamer 0.8.8\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2005-05-02 19:36+0200\n" +"POT-Creation-Date: 2005-05-17 18:37+0200\n" "PO-Revision-Date: 2005-02-05 16:35+1030\n" "Last-Translator: Clytie Siddall \n" "Language-Team: Vietnamese \n" @@ -15,30 +15,30 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" -#: gst/gst.c:160 +#: gst/gst.c:157 msgid "Print the GStreamer version" msgstr "Hiển thị phiên bản GStreamer" -#: gst/gst.c:162 +#: gst/gst.c:159 msgid "Make all warnings fatal" msgstr "Lập tất cả cảnh báo là nghiêm trá»ng" -#: gst/gst.c:166 +#: gst/gst.c:163 msgid "Print available debug categories and exit" msgstr "Hiển thị tất cả loại gỡ lá»—i sẵn sàng rồi thoát" -#: gst/gst.c:169 +#: gst/gst.c:166 msgid "" "Default debug level from 1 (only error) to 5 (anything) or 0 for no output" msgstr "" "Mức gỡ lá»—i mặc định từ 1 (chỉ lá»—i) đến 5 (bất cứ Ä‘iá»u nào) hay 0 (không xuất " "gì)" -#: gst/gst.c:171 +#: gst/gst.c:168 msgid "LEVEL" msgstr "MỨC" -#: gst/gst.c:173 +#: gst/gst.c:170 msgid "" "Comma-separated list of category_name:level pairs to set specific levels for " "the individual categories. Example: GST_AUTOPLUG:5,GST_ELEMENT_*:3" @@ -46,31 +46,27 @@ msgstr "" "Danh sách định giá»›i bằng dấu phẩy của đôi tên_loại:mức để lập mức dứt khoát " "cho má»—i loại. Thí dụ: GST_AUTOPLUG:5,GST_ELEMENT_*:3" -#: gst/gst.c:176 +#: gst/gst.c:173 msgid "LIST" msgstr "DANH SÃCH" -#: gst/gst.c:178 +#: gst/gst.c:175 msgid "Disable colored debugging output" msgstr "Không xuất dữ liệu gỡ lá»—i vá»›i màu" -#: gst/gst.c:180 +#: gst/gst.c:177 msgid "Disable debugging" msgstr "Không gỡ lá»—i" -#: gst/gst.c:184 -msgid "Disable accelerated CPU instructions" -msgstr "Không gởi lệnh CPU đã tăng tốc" - -#: gst/gst.c:186 +#: gst/gst.c:181 msgid "Enable verbose plugin loading diagnostics" msgstr "Chẩn Ä‘oán chi tiết việc tải trình cầm phít" -#: gst/gst.c:188 +#: gst/gst.c:183 msgid "PATHS" msgstr "ÄƯỜNG DẪN" -#: gst/gst.c:191 +#: gst/gst.c:186 #, fuzzy msgid "" "Comma-separated list of plugins to preload in addition to the list stored in " @@ -79,32 +75,32 @@ msgstr "" "Danh sách định giá»›i bằng dấu phẩy của các trình cầm phít để tải trÆ°á»›c, thêm " "vào danh sách được cất giữ trong biến môi trÆ°á»ng GST_PLUGIN_PATH" -#: gst/gst.c:193 +#: gst/gst.c:188 msgid "PLUGINS" msgstr "CẦM PHÃT" -#: gst/gst.c:196 +#: gst/gst.c:191 msgid "Disable trapping of segmentation faults during plugin loading" msgstr "Không bắt lá»—i phân Ä‘oạn trong khi tải trình cầm phít" -#: gst/gst.c:199 +#: gst/gst.c:194 msgid "SCHEDULER" msgstr "TRÃŒNH ÄỊNH" -#: gst/gst.c:201 +#: gst/gst.c:196 msgid "Registry to use" msgstr "CÆ¡ quan đăng ký để sá»­ dụng" -#: gst/gst.c:201 +#: gst/gst.c:196 msgid "REGISTRY" msgstr "CÆ  QUAN ÄÄ‚NG KÃ" -#: gst/gst.c:214 +#: gst/gst.c:209 #, c-format msgid "path list for loading plugins (separated by '%s')" msgstr "danh sách Ä‘Æ°á»ng dẫn để tải trình cầm phít (định giá»›i bằng '%s')" -#: gst/gst.c:218 +#: gst/gst.c:213 #, c-format msgid "Scheduler to use (default is '%s')" msgstr "Sá»­ dụng trình định này (mặc định là '%s')" @@ -587,51 +583,46 @@ msgstr "" msgid ", " msgstr ", " -#: gst/autoplug/gstspider.c:466 -#, c-format -msgid "There is no element present to handle the stream's mime type %s." -msgstr "Hiện không có yếu tố có thể quản lý loại mime %s của dòng này." - -#: gst/elements/gstfilesink.c:268 +#: gst/elements/gstfilesink.c:243 msgid "No file name specified for writing." msgstr "ChÆ°a ghi rõ tên tập tin để ghi vào." -#: gst/elements/gstfilesink.c:275 +#: gst/elements/gstfilesink.c:250 #, c-format msgid "Could not open file \"%s\" for writing." msgstr "Không mở được tập tin \"%s\" để ghi." -#: gst/elements/gstfilesink.c:294 +#: gst/elements/gstfilesink.c:269 #, c-format msgid "Error closing file \"%s\"." msgstr "Gặp lá»—i khi đóng tập tin \"%s\"." -#: gst/elements/gstfilesink.c:364 gst/elements/gstfilesink.c:400 -#: gst/elements/gstfilesink.c:453 +#: gst/elements/gstfilesink.c:339 gst/elements/gstfilesink.c:375 +#: gst/elements/gstfilesink.c:428 #, c-format msgid "Error while writing to file \"%s\"." msgstr "Gặp lá»—i khi ghi vào tập tin \"%s\"." -#: gst/elements/gstfilesrc.c:764 gst/elements/gstmultifilesrc.c:298 +#: gst/elements/gstfilesrc.c:725 msgid "No file name specified for reading." msgstr "ChÆ°a ghi rõ tên tập tin để Ä‘á»c." -#: gst/elements/gstfilesrc.c:779 gst/elements/gstmultifilesrc.c:306 +#: gst/elements/gstfilesrc.c:740 #, c-format msgid "Could not open file \"%s\" for reading." msgstr "Không mở được tập tin \"%s\" để Ä‘á»c." -#: gst/elements/gstfilesrc.c:790 +#: gst/elements/gstfilesrc.c:751 #, c-format msgid "\"%s\" is a directory." msgstr " \"%s\" là thÆ° mục." -#: gst/elements/gstfilesrc.c:796 +#: gst/elements/gstfilesrc.c:757 #, c-format msgid "File \"%s\" is a socket." msgstr "Tập tin \"%s\" là ổ cắm." -#: gst/elements/gstidentity.c:306 +#: gst/elements/gstidentity.c:276 msgid "Failed after iterations as requested." msgstr "Không làm được sau khi làm việc ấy số lần được chá»n." @@ -725,125 +716,78 @@ msgstr "" msgid "empty pipeline not allowed" msgstr "không cho phép Ä‘Æ°á»ng ống trống" -#: tools/gst-inspect.c:1151 +#: tools/gst-inspect.c:1032 msgid "Print all elements" msgstr "Hiển thị tất cả yếu tố" -#: tools/gst-launch.c:114 -#, c-format -msgid "" -"Execution ended after %s iterations (sum %s ns, average %s ns, min %s ns, " -"max %s ns).\n" -msgstr "" -"Thi hành xong sau khi làm việc ấy %s lần (tổng số %s ns (phần tá»· giây), số " -"trung bình %s ns, tối thiểu %s ns, tối Ä‘a %s ns).\n" - -#: tools/gst-launch.c:141 -msgid "Usage: gst-xmllaunch [ element.property=value ... ]\n" -msgstr "" -"Cách sá»­ dụng: gst-xmllaunch [ yếu_tố.đặc_tính=trị_số ...]\n" - -#: tools/gst-launch.c:149 -#, c-format -msgid "ERROR: parse of xml file '%s' failed.\n" -msgstr "Lá»–I: không phân tách được tập tin xml '%s'.\n" - -#: tools/gst-launch.c:155 -#, c-format -msgid "ERROR: no toplevel pipeline element in file '%s'.\n" -msgstr "Lá»–I: không có yếu tố Ä‘Æ°á»ng ống mức đầu trong tập tin '%s'.\n" - -#: tools/gst-launch.c:162 -#, c-format -msgid "WARNING: only one toplevel element is supported at this time." -msgstr "CẢNH BÃO: hiện há»— trợ chỉ má»™t yếu tố mức đầu riêng lẻ." - -#: tools/gst-launch.c:173 -#, c-format -msgid "ERROR: could not parse command line argument %d: %s.\n" -msgstr "Lá»–I: không phân tách được đối số Ä‘Æ°á»ng lệnh %d: %s.\n" - -#: tools/gst-launch.c:184 -#, c-format -msgid "WARNING: element named '%s' not found.\n" -msgstr "CẢNH BÃO: chÆ°a tìm được yếu tố có tên '%s'.\n" - -#: tools/gst-launch.c:327 +#: tools/gst-launch.c:190 #, c-format msgid "FOUND TAG : found by element \"%s\".\n" msgstr "THẺ Äà TÃŒM : được tìm do yếu tố \"%s\".\n" -#: tools/gst-launch.c:412 +#: tools/gst-launch.c:304 msgid "Output tags (also known as metadata)" msgstr "Thể xuất (cÅ©ng được biết là metadata, dữ liệu vá» dữ liệu)" -#: tools/gst-launch.c:414 +#: tools/gst-launch.c:306 msgid "Output status information and property notifications" msgstr "Xuất thông tin trạng thái và thông báo đặc tính" -#: tools/gst-launch.c:416 +#: tools/gst-launch.c:308 msgid "Do not output status information of TYPE" msgstr "Không xuất thông tin trạng thái LOẠI" -#: tools/gst-launch.c:416 +#: tools/gst-launch.c:308 msgid "TYPE1,TYPE2,..." msgstr "LOẠI1,LOẠI2,..." -#: tools/gst-launch.c:419 -msgid "Save xml representation of pipeline to FILE and exit" -msgstr "LÆ°u Ä‘Æ°á»ng ống dạng xml vào TẬP_TIN rồi thoát" - -#: tools/gst-launch.c:419 -msgid "FILE" -msgstr "TẬP_TIN" - -#: tools/gst-launch.c:422 +#: tools/gst-launch.c:310 msgid "Do not install a fault handler" msgstr "Không cài trình quản lý lá»—i" -#: tools/gst-launch.c:424 +#: tools/gst-launch.c:312 msgid "Print alloc trace (if enabled at compile time)" msgstr "Hiển thị việc chỉ theo cấp phát (nếu được hiệu lá»±c khi biên dich)" -#: tools/gst-launch.c:426 +#: tools/gst-launch.c:314 msgid "Number of times to iterate pipeline" msgstr "Số lần sá»­ dụng Ä‘Æ°á»ng ống" -#: tools/gst-launch.c:496 +#: tools/gst-launch.c:379 #, c-format msgid "ERROR: pipeline could not be constructed: %s.\n" msgstr "Lá»–I: không cấu tạo Ä‘Æ°á»ng ống được: %s.\n" -#: tools/gst-launch.c:500 -#, c-format +#: tools/gst-launch.c:383 msgid "ERROR: pipeline could not be constructed.\n" msgstr "Lá»–I: không cấu tạo Ä‘Æ°á»ng ống được.\n" -#: tools/gst-launch.c:504 +#: tools/gst-launch.c:387 #, c-format msgid "WARNING: erroneous pipeline: %s\n" msgstr "CẢNH BÃO: Ä‘Æ°á»ng ống có lá»—i: %s\n" -#: tools/gst-launch.c:505 -#, c-format +#: tools/gst-launch.c:388 msgid " Trying to run anyway.\n" msgstr " Dù sao Ä‘ang thá»­ chạy.\n" -#: tools/gst-launch.c:532 -#, c-format +#: tools/gst-launch.c:408 msgid "ERROR: the 'pipeline' element wasn't found.\n" msgstr "Lá»–I: chÆ°a tìm được yếu tố 'Ä‘Æ°á»ng ống'.\n" -#: tools/gst-launch.c:539 -#, c-format +#: tools/gst-launch.c:417 msgid "RUNNING pipeline ...\n" msgstr "ÄANG CHẠY Ä‘Æ°á»ng ống ...\n" -#: tools/gst-launch.c:542 -#, c-format +#: tools/gst-launch.c:421 msgid "ERROR: pipeline doesn't want to play.\n" msgstr "Lá»–I: Ä‘Æ°á»ng ống không phát được.\n" +#: tools/gst-launch.c:445 +#, c-format +msgid "Execution ended after %.2fs (%.2fs or %.2f%% idling).\n" +msgstr "" + #: tools/gst-register.c:49 #, fuzzy, c-format msgid "Added plugin %s with %d feature.\n" @@ -876,6 +820,44 @@ msgid "Loaded %d plugins with %d feature.\n" msgid_plural "Loaded %d plugins with %d features.\n" msgstr[0] "Má»›i tải %d trình cầm phít vá»›i %d %s.\n" +#~ msgid "Disable accelerated CPU instructions" +#~ msgstr "Không gởi lệnh CPU đã tăng tốc" + +#~ msgid "There is no element present to handle the stream's mime type %s." +#~ msgstr "Hiện không có yếu tố có thể quản lý loại mime %s của dòng này." + +#~ msgid "" +#~ "Execution ended after %s iterations (sum %s ns, average %s ns, min %s ns, " +#~ "max %s ns).\n" +#~ msgstr "" +#~ "Thi hành xong sau khi làm việc ấy %s lần (tổng số %s ns (phần tá»· giây), " +#~ "số trung bình %s ns, tối thiểu %s ns, tối Ä‘a %s ns).\n" + +#~ msgid "Usage: gst-xmllaunch [ element.property=value ... ]\n" +#~ msgstr "" +#~ "Cách sá»­ dụng: gst-xmllaunch [ yếu_tố.đặc_tính=trị_số ...]\n" + +#~ msgid "ERROR: parse of xml file '%s' failed.\n" +#~ msgstr "Lá»–I: không phân tách được tập tin xml '%s'.\n" + +#~ msgid "ERROR: no toplevel pipeline element in file '%s'.\n" +#~ msgstr "Lá»–I: không có yếu tố Ä‘Æ°á»ng ống mức đầu trong tập tin '%s'.\n" + +#~ msgid "WARNING: only one toplevel element is supported at this time." +#~ msgstr "CẢNH BÃO: hiện há»— trợ chỉ má»™t yếu tố mức đầu riêng lẻ." + +#~ msgid "ERROR: could not parse command line argument %d: %s.\n" +#~ msgstr "Lá»–I: không phân tách được đối số Ä‘Æ°á»ng lệnh %d: %s.\n" + +#~ msgid "WARNING: element named '%s' not found.\n" +#~ msgstr "CẢNH BÃO: chÆ°a tìm được yếu tố có tên '%s'.\n" + +#~ msgid "Save xml representation of pipeline to FILE and exit" +#~ msgstr "LÆ°u Ä‘Æ°á»ng ống dạng xml vào TẬP_TIN rồi thoát" + +#~ msgid "FILE" +#~ msgstr "TẬP_TIN" + #~ msgid "caps" #~ msgstr "khả năng" diff --git a/tests/Makefile.am b/tests/Makefile.am index 4cf093c462..68cb4fb84a 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -1,12 +1,5 @@ -SUBDIRS = instantiate memchunk muxing sched threadstate seeking # bufspeed - -if GST_DISABLE_TRACE -LAT = -else -LAT = lat - -endif +SUBDIRS = instantiate memchunk seeking # bufspeed noinst_PROGRAMS = $(LAT) spidey_bench mass_elements @@ -14,4 +7,4 @@ AM_CFLAGS = $(GST_OBJ_CFLAGS) LIBS = $(GST_OBJ_LIBS) EXTRA_DIST = README -DIST_SUBDIRS= bufspeed instantiate memchunk muxing sched threadstate seeking +DIST_SUBDIRS= bufspeed instantiate memchunk sched threadstate seeking diff --git a/tests/lat.c b/tests/lat.c deleted file mode 100644 index c542b6eb66..0000000000 --- a/tests/lat.c +++ /dev/null @@ -1,237 +0,0 @@ -#include -#include -#include - -/* FIXME: WTF does this do? */ - -static guint64 max = 0, min = -1, total = 0; -static guint count = 0; -static guint print_del = 1; -static guint iterations = 0; -static guint mhz = 0; - -void -handoff_src (GstElement * src, GstBuffer * buf, gpointer user_data) -{ - gst_trace_read_tsc (&GST_BUFFER_TIMESTAMP (buf)); -} - -void -handoff_sink (GstElement * sink, GstBuffer * buf, gpointer user_data) -{ - guint64 end, d, avg; - guint avg_ns; - - gst_trace_read_tsc (&end); - d = end - GST_BUFFER_TIMESTAMP (buf); - if (d > max) - max = d; - if (d < min) - min = d; - total += d; - count++; - avg = total / count; - avg_ns = (guint) (1000.0 * (double) avg / (double) mhz); - - if ((count % print_del) == 0) { - g_print ("%07d:%08" G_GUINT64_FORMAT " min:%08" G_GUINT64_FORMAT " max:%08" - G_GUINT64_FORMAT " avg:%08" G_GUINT64_FORMAT " avg-s:0.%09d\r", count, - d, min, max, avg, avg_ns); - } -} - -GstElement * -identity_add (GstPipeline * pipeline, GstElement * first, int count) -{ - GstElement *last, *ident; - int i; - char buf[20]; - - last = first; - - for (i = 0; i < count; i++) { - snprintf (buf, 20, "identity_%03d", i); - ident = gst_element_factory_make ("identity", buf); - g_return_val_if_fail (ident != NULL, NULL); - g_object_set (G_OBJECT (ident), "silent", TRUE, NULL); - gst_bin_add (GST_BIN (pipeline), GST_ELEMENT (ident)); - gst_pad_link (gst_element_get_pad (last, "src"), - gst_element_get_pad (ident, "sink")); - last = ident; - } - - return last; -} - -GstElement * -fakesrc (void) -{ - GstElement *src; - - src = gst_element_factory_make ("fakesrc", "src"); - g_return_val_if_fail (src != NULL, NULL); - g_object_set (G_OBJECT (src), "silent", TRUE, NULL); - g_object_set (G_OBJECT (src), "num_buffers", iterations, NULL); - g_signal_connect (G_OBJECT (src), "handoff", G_CALLBACK (handoff_src), NULL); - - return src; -} - -GstElement * -fakesink (void) -{ - GstElement *sink; - - sink = gst_element_factory_make ("fakesink", "fakesink"); - g_return_val_if_fail (sink != NULL, NULL); - g_object_set (G_OBJECT (sink), "silent", TRUE, NULL); - g_signal_connect (G_OBJECT (sink), - "handoff", G_CALLBACK (handoff_sink), NULL); - - return sink; -} - -GstPipeline * -simple (int argc, int argi, char *argv[]) -{ - GstPipeline *pipeline; - GstElement *last, *src, *sink; - int idents; - - if ((argc - argi) < 1) { - fprintf (stderr, "bad params"); - return NULL; - } - idents = atoi (argv[argi]); - if ((argc - argi) == 2) { - gst_scheduler_factory_set_default_name (argv[argi + 1]); - } - - pipeline = GST_PIPELINE (gst_pipeline_new ("pipeline")); - g_return_val_if_fail (pipeline != NULL, NULL); - - src = fakesrc (); - gst_bin_add (GST_BIN (pipeline), GST_ELEMENT (src)); - last = identity_add (pipeline, src, idents); - sink = fakesink (); - gst_bin_add (GST_BIN (pipeline), GST_ELEMENT (sink)); - gst_pad_link (gst_element_get_pad (last, "src"), - gst_element_get_pad (sink, "sink")); - - return pipeline; -} - -GstPipeline * -queue (int argc, int argi, char *argv[]) -{ - GstPipeline *pipeline; - GstElement *last, *src, *sink, *src_thr, *src_q, *sink_q, *sink_thr; - int idents; - - if ((argc - argi) < 1) { - fprintf (stderr, "bad params"); - return NULL; - } - idents = atoi (argv[argi]); - - if ((argc - argi) == 2) { - gst_scheduler_factory_set_default_name (argv[argi + 1]); - } - - pipeline = GST_PIPELINE (gst_pipeline_new ("pipeline")); - g_return_val_if_fail (pipeline != NULL, NULL); - - src_thr = GST_ELEMENT (gst_thread_new ("src_thread")); - g_return_val_if_fail (src_thr != NULL, NULL); - - src = fakesrc (); - g_return_val_if_fail (src != NULL, NULL); - gst_bin_add (GST_BIN (src_thr), GST_ELEMENT (src)); - - src_q = gst_element_factory_make ("queue", "src_q"); - g_return_val_if_fail (src_q != NULL, NULL); - gst_bin_add (GST_BIN (src_thr), GST_ELEMENT (src_q)); - gst_pad_link (gst_element_get_pad (src, "src"), - gst_element_get_pad (src_q, "sink")); - - gst_bin_add (GST_BIN (pipeline), GST_ELEMENT (src_thr)); - - last = identity_add (pipeline, src_q, idents); - - sink_q = gst_element_factory_make ("queue", "sink_q"); - g_return_val_if_fail (sink_q != NULL, NULL); - gst_bin_add (GST_BIN (pipeline), GST_ELEMENT (sink_q)); - gst_pad_link (gst_element_get_pad (last, "src"), - gst_element_get_pad (sink_q, "sink")); - - sink_thr = GST_ELEMENT (gst_thread_new ("sink_thread")); - g_return_val_if_fail (sink_thr != NULL, NULL); - - sink = fakesink (); - g_return_val_if_fail (sink != NULL, NULL); - gst_bin_add (GST_BIN (sink_thr), GST_ELEMENT (sink)); - - gst_bin_add (GST_BIN (pipeline), GST_ELEMENT (sink_thr)); - - gst_pad_link (gst_element_get_pad (sink_q, "src"), - gst_element_get_pad (sink, "sink")); - - return pipeline; -} - -struct test -{ - char *name; - char *params; - GstPipeline *(*func) (int argc, int argi, char *argv[]); -}; - -static struct test tests[] = { - {"simple", "ident_count [scheduler_name]", simple}, - {"queue", "ident_count [scheduler_name]", queue}, - {NULL, NULL, NULL} -}; - -int -main (int argc, char *argv[]) -{ - GstPipeline *pipeline; - int i; - char *name; - - gst_init (&argc, &argv); - - if (argc < 3) { - fprintf (stderr, - "usage: %s iterations print_del mhz test_name [test_params...]\n", - argv[0]); - for (i = 0; tests[i].name; i++) { - fprintf (stderr, " %s %s\n", tests[i].name, tests[i].params); - } - exit (1); - } else { - iterations = atoi (argv[1]); - print_del = atoi (argv[2]); - mhz = atoi (argv[3]); - name = argv[4]; - } - - pipeline = NULL; - for (i = 0; tests[i].name && !pipeline; i++) { - if (!strcmp (name, tests[i].name)) { - pipeline = tests[i].func (argc, 5, argv); - } - } - g_return_val_if_fail (pipeline != NULL, -1); - - /*xmlSaveFile("lat.gst", gst_xml_write(GST_ELEMENT(pipeline))); */ - - gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_PLAYING); - - while (count < iterations) { - gst_bin_iterate (GST_BIN (pipeline)); - } - g_print ("\n"); - - return 0; -} diff --git a/tests/muxing/Makefile.am b/tests/muxing/Makefile.am deleted file mode 100644 index 96e5ea6123..0000000000 --- a/tests/muxing/Makefile.am +++ /dev/null @@ -1,4 +0,0 @@ -noinst_PROGRAMS = case1 - -LDADD = $(GST_OBJ_LIBS) -AM_CFLAGS = $(GST_OBJ_CFLAGS) diff --git a/tests/muxing/case1.c b/tests/muxing/case1.c deleted file mode 100644 index 27e940e27b..0000000000 --- a/tests/muxing/case1.c +++ /dev/null @@ -1,74 +0,0 @@ -#include -#include - -gboolean playing = TRUE; - -static void -handoff_signal (GstElement * element, GstBuffer * buf) -{ - g_print ("handoff \"%s\" %" G_GINT64_FORMAT "\n", - gst_element_get_name (element), GST_BUFFER_TIMESTAMP (buf)); -} - -static void -eos_signal (GstElement * element) -{ - g_print ("eos received from \"%s\"\n", gst_element_get_name (element)); - - playing = FALSE; -} - -int -main (int argc, char *argv[]) -{ - GstBin *pipeline; - GstElement *src, *tee, *identity1, *identity2, *aggregator, *sink; - - gst_init (&argc, &argv); - - pipeline = GST_BIN (gst_pipeline_new ("pipeline")); - g_return_val_if_fail (pipeline != NULL, 1); - - src = gst_element_factory_make ("fakesrc", "src"); - g_object_set (G_OBJECT (src), "num_buffers", 40, NULL); - g_return_val_if_fail (src != NULL, 2); - tee = gst_element_factory_make ("tee", "tee"); - g_return_val_if_fail (tee != NULL, 3); - identity1 = gst_element_factory_make ("identity", "identity0"); - g_return_val_if_fail (identity1 != NULL, 3); - identity2 = gst_element_factory_make ("identity", "identity1"); - g_object_set (G_OBJECT (identity2), "duplicate", 2, NULL); - g_object_set (G_OBJECT (identity2), "loop_based", TRUE, NULL); - g_return_val_if_fail (identity2 != NULL, 3); - aggregator = gst_element_factory_make ("aggregator", "aggregator"); - g_object_set (G_OBJECT (aggregator), "sched", 4, NULL); - g_return_val_if_fail (aggregator != NULL, 3); - sink = gst_element_factory_make ("fakesink", "sink"); - g_return_val_if_fail (sink != NULL, 4); - - gst_bin_add_many (pipeline, src, tee, identity1, identity2, aggregator, sink, - NULL); - - gst_element_link_pads (src, "src", tee, "sink"); - gst_pad_link (gst_element_get_request_pad (tee, "src%d"), - gst_element_get_pad (identity1, "sink")); - gst_pad_link (gst_element_get_request_pad (tee, "src%d"), - gst_element_get_pad (identity2, "sink")); - gst_pad_link (gst_element_get_pad (identity1, "src"), - gst_element_get_request_pad (aggregator, "sink%d")); - gst_pad_link (gst_element_get_pad (identity2, "src"), - gst_element_get_request_pad (aggregator, "sink%d")); - gst_element_link_pads (aggregator, "src", sink, "sink"); - - g_signal_connect (G_OBJECT (src), "eos", G_CALLBACK (eos_signal), NULL); - g_signal_connect (G_OBJECT (sink), "handoff", - G_CALLBACK (handoff_signal), NULL); - - gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_PLAYING); - - while (gst_bin_iterate (pipeline)); - - gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_NULL); - - exit (0); -} diff --git a/tests/old/testsuite/Makefile.am b/tests/old/testsuite/Makefile.am index df8249a062..16a2b7dab1 100644 --- a/tests/old/testsuite/Makefile.am +++ b/tests/old/testsuite/Makefile.am @@ -19,7 +19,7 @@ SUBDIRS = \ dlopen dynparams \ elements ghostpads indexers negotiation pad \ $(GST_PARSE_DIRS) \ - plugin refcounting schedulers states tags threads + plugin refcounting schedulers states tags DIST_SUBDIRS = \ bins bytestream caps childproxy cleanup clock \ diff --git a/tests/old/testsuite/bytestream/Makefile.am b/tests/old/testsuite/bytestream/Makefile.am index 790dca8d84..28db18d0b3 100644 --- a/tests/old/testsuite/bytestream/Makefile.am +++ b/tests/old/testsuite/bytestream/Makefile.am @@ -1,11 +1,8 @@ include ../Rules tests_pass = filepadsink -tests_fail = test1 +tests_fail = tests_ignore = -test1_SOURCES = test1.c gstbstest.c -test1_LDFLAGS = $(top_builddir)/libs/gst/bytestream/libgstbytestream.la - filepadsink_CFLAGS = $(AM_CFLAGS) -DTHE_FILE=\""$(top_srcdir)/configure.ac"\" filepadsink_LDFLAGS = $(top_builddir)/libs/gst/bytestream/libgstbytestream.la diff --git a/tests/old/testsuite/bytestream/gstbstest.c b/tests/old/testsuite/bytestream/gstbstest.c deleted file mode 100644 index 3eb6ae4437..0000000000 --- a/tests/old/testsuite/bytestream/gstbstest.c +++ /dev/null @@ -1,419 +0,0 @@ -/* GStreamer - * Copyright (C) 1999,2000 Erik Walthinsen - * 2000 Wim Taymans - * - * gstbstest.c: - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif -#include -#include - -#include -#include - -#define GST_TYPE_BSTEST (gst_bstest_get_type()) -#define GST_BSTEST(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_BSTEST,GstBsTest)) -#define GST_BSTEST_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_BSTEST,GstBsTestClass)) -#define GST_IS_BSTEST(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_BSTEST)) -#define GST_IS_BSTEST_CLASS(obj) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_BSTEST)) - -typedef struct _GstBsTest GstBsTest; -typedef struct _GstBsTestClass GstBsTestClass; - -struct _GstBsTest -{ - GstElement element; - - GstPad *sinkpad; - GstPad *srcpad; - - GstByteStream *bs; - - gchar *accesspattern; - guint num_patterns; - gchar **patterns; - guint sizemin; - guint sizemax; - gint count; - gboolean silent; -}; - -struct _GstBsTestClass -{ - GstElementClass parent_class; -}; - -GType gst_bstest_get_type (void); - - -GstElementDetails gst_bstest_details = GST_ELEMENT_DETAILS ("ByteStreamTest", - "Filter", - "Test for the GstByteStream code", - "Erik Walthinsen , " - "Wim Taymans "); - - -/* BsTest signals and args */ -enum -{ - /* FILL ME */ - LAST_SIGNAL -}; - -enum -{ - ARG_0, - ARG_SIZEMIN, - ARG_SIZEMAX, - ARG_COUNT, - ARG_SILENT, - ARG_ACCESSPATTERN, -}; - - -static void gst_bstest_base_init (gpointer g_class); -static void gst_bstest_class_init (GstBsTestClass * klass); -static void gst_bstest_init (GstBsTest * bstest); - -static void gst_bstest_set_property (GObject * object, guint prop_id, - const GValue * value, GParamSpec * pspec); -static void gst_bstest_get_property (GObject * object, guint prop_id, - GValue * value, GParamSpec * pspec); - -static GstElementStateReturn gst_bstest_change_state (GstElement * element); -static void gst_bstest_loop (GstElement * element); - -static GstElementClass *parent_class = NULL; - -/* static guint gst_bstest_signals[LAST_SIGNAL] = { 0 }; */ - -GType -gst_bstest_get_type (void) -{ - static GType bstest_type = 0; - - if (!bstest_type) { - static const GTypeInfo bstest_info = { - sizeof (GstBsTestClass), - gst_bstest_base_init, - NULL, - (GClassInitFunc) gst_bstest_class_init, - NULL, - NULL, - sizeof (GstBsTest), - 0, - (GInstanceInitFunc) gst_bstest_init, - }; - - bstest_type = - g_type_register_static (GST_TYPE_ELEMENT, "BSTest", &bstest_info, 0); - } - return bstest_type; -} -static void -gst_bstest_base_init (gpointer g_class) -{ - GstElementClass *gstelement_class = GST_ELEMENT_CLASS (g_class); - - gst_element_class_set_details (gstelement_class, &gst_bstest_details); -} - -static void -gst_bstest_class_init (GstBsTestClass * klass) -{ - GObjectClass *gobject_class; - GstElementClass *gstelement_class; - - gobject_class = (GObjectClass *) klass; - gstelement_class = (GstElementClass *) klass; - - parent_class = g_type_class_ref (GST_TYPE_ELEMENT); - - g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_SIZEMIN, - g_param_spec_int ("sizemin", "sizemin", "sizemin", 0, G_MAXINT, - 0, G_PARAM_READWRITE)); - g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_SIZEMAX, - g_param_spec_int ("sizemax", "sizemax", "sizemax", 0, G_MAXINT, - 384, G_PARAM_READWRITE)); - g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_ACCESSPATTERN, - g_param_spec_string ("accesspattern", "accesspattern", "accesspattern", - "r", G_PARAM_READWRITE)); - g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_COUNT, - g_param_spec_uint ("count", "count", "count", - 0, G_MAXUINT, 0, G_PARAM_READWRITE)); - g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_SILENT, - g_param_spec_boolean ("silent", "silent", "silent", - FALSE, G_PARAM_READWRITE)); - - gobject_class->set_property = GST_DEBUG_FUNCPTR (gst_bstest_set_property); - gobject_class->get_property = GST_DEBUG_FUNCPTR (gst_bstest_get_property); - - gstelement_class->change_state = gst_bstest_change_state; - -} - -static GstCaps * -gst_bstest_getcaps (GstPad * pad) -{ - GstBsTest *bstest = GST_BSTEST (gst_pad_get_parent (pad)); - GstPad *otherpad; - - otherpad = (pad == bstest->srcpad) ? bstest->sinkpad : bstest->srcpad; - - return gst_pad_get_allowed_caps (otherpad); -} - -GstStaticPadTemplate srctemplate = GST_STATIC_PAD_TEMPLATE ("src", - GST_PAD_SRC, - GST_PAD_ALWAYS, - GST_STATIC_CAPS_ANY); - -GstStaticPadTemplate sinktemplate = GST_STATIC_PAD_TEMPLATE ("sink", - GST_PAD_SINK, - GST_PAD_ALWAYS, - GST_STATIC_CAPS_ANY); - -static void -gst_bstest_init (GstBsTest * bstest) -{ - bstest->sinkpad = - gst_pad_new_from_template (gst_static_pad_template_get (&sinktemplate), - "sink"); - gst_element_add_pad (GST_ELEMENT (bstest), bstest->sinkpad); - gst_pad_set_getcaps_function (bstest->sinkpad, gst_bstest_getcaps); - - bstest->srcpad = - gst_pad_new_from_template (gst_static_pad_template_get (&srctemplate), - "src"); - gst_element_add_pad (GST_ELEMENT (bstest), bstest->srcpad); - gst_pad_set_getcaps_function (bstest->srcpad, gst_bstest_getcaps); - - gst_element_set_loop_function (GST_ELEMENT (bstest), gst_bstest_loop); - - bstest->sizemin = 0; - bstest->sizemax = 384; - bstest->accesspattern = g_strdup ("r"); - bstest->patterns = g_strsplit (bstest->accesspattern, ":", 0); - bstest->count = 5; - bstest->silent = FALSE; - bstest->bs = NULL; -} - -static guint -gst_bstest_get_size (GstBsTest * bstest, gchar * sizestring, guint prevsize) -{ - guint size; - - if (sizestring[0] == 0) { - size = bstest->sizemax; - } else if (sizestring[0] == 'r') { - size = - bstest->sizemin + - (guint8) (((gfloat) bstest->sizemax) * rand () / (RAND_MAX + - (gfloat) bstest->sizemin)); - } else if (sizestring[0] == '<') { - size = prevsize; - } else { - size = atoi (sizestring); - } - - if (size == 0) - size++; - - return size; -} - -static void -gst_bstest_loop (GstElement * element) -{ - GstBsTest *bstest; - GstBuffer *buf = NULL; - - g_return_if_fail (element != NULL); - g_return_if_fail (GST_IS_BSTEST (element)); - - bstest = GST_BSTEST (element); - - do { - guint size = 0; - guint i = 0; - guint8 *ptr; - - while (i < bstest->num_patterns) { - buf = NULL; - - if (bstest->patterns[i][0] == 'r') { - size = gst_bstest_get_size (bstest, &bstest->patterns[i][1], size); - if (!bstest->silent) - g_print ("bstest: ***** read %d bytes\n", size); - gst_bytestream_read (bstest->bs, &buf, size); - } else if (bstest->patterns[i][0] == 'f') { - size = gst_bstest_get_size (bstest, &bstest->patterns[i][1], size); - if (!bstest->silent) - g_print ("bstest: ***** flush %d bytes\n", size); - gst_bytestream_flush (bstest->bs, size); - } else if (!strncmp (bstest->patterns[i], "pb", 2)) { - size = gst_bstest_get_size (bstest, &bstest->patterns[i][2], size); - if (!bstest->silent) - g_print ("bstest: ***** peek bytes %d bytes\n", size); - gst_bytestream_peek_bytes (bstest->bs, &ptr, size); - } else if (bstest->patterns[i][0] == 'p') { - size = gst_bstest_get_size (bstest, &bstest->patterns[i][1], size); - if (!bstest->silent) - g_print ("bstest: ***** peek %d bytes\n", size); - gst_bytestream_peek (bstest->bs, &buf, size); - gst_buffer_unref (buf); - buf = NULL; - } - - if (buf) - gst_pad_push (bstest->srcpad, GST_DATA (buf)); - - i++; - } -/* } while (!GST_ELEMENT_IS_COTHREAD_STOPPING (element)); */ - - } while (0); -} - -static void -gst_bstest_set_property (GObject * object, guint prop_id, const GValue * value, - GParamSpec * pspec) -{ - GstBsTest *bstest; - - /* it's not null if we got it, but it might not be ours */ - g_return_if_fail (GST_IS_BSTEST (object)); - - bstest = GST_BSTEST (object); - - switch (prop_id) { - case ARG_SIZEMIN: - bstest->sizemin = g_value_get_int (value); - break; - case ARG_SIZEMAX: - bstest->sizemax = g_value_get_int (value); - break; - case ARG_ACCESSPATTERN: - if (bstest->accesspattern) { - g_free (bstest->accesspattern); - g_strfreev (bstest->patterns); - } - if (g_value_get_string (value) == NULL) { - gst_element_set_state (GST_ELEMENT (object), GST_STATE_NULL); - bstest->accesspattern = NULL; - bstest->num_patterns = 0; - } else { - guint i = 0; - - bstest->accesspattern = g_strdup (g_value_get_string (value)); - bstest->patterns = g_strsplit (bstest->accesspattern, ":", 0); - while (bstest->patterns[i++]); - bstest->num_patterns = i - 1; - } - break; - case ARG_COUNT: - bstest->count = g_value_get_uint (value); - break; - case ARG_SILENT: - bstest->silent = g_value_get_boolean (value); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -gst_bstest_get_property (GObject * object, guint prop_id, GValue * value, - GParamSpec * pspec) -{ - GstBsTest *bstest; - - /* it's not null if we got it, but it might not be ours */ - g_return_if_fail (GST_IS_BSTEST (object)); - - bstest = GST_BSTEST (object); - - switch (prop_id) { - case ARG_SIZEMIN: - g_value_set_int (value, bstest->sizemin); - break; - case ARG_SIZEMAX: - g_value_set_int (value, bstest->sizemax); - break; - case ARG_ACCESSPATTERN: - g_value_set_string (value, bstest->accesspattern); - break; - case ARG_COUNT: - g_value_set_uint (value, bstest->count); - break; - case ARG_SILENT: - g_value_set_boolean (value, bstest->silent); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static GstElementStateReturn -gst_bstest_change_state (GstElement * element) -{ - GstBsTest *bstest; - - g_return_val_if_fail (GST_IS_BSTEST (element), GST_STATE_FAILURE); - - bstest = GST_BSTEST (element); - - if (GST_STATE_PENDING (element) == GST_STATE_NULL) { - if (bstest->bs) { - gst_bytestream_destroy (bstest->bs); - bstest->bs = NULL; - } - } else { - if (!bstest->bs) { - bstest->bs = gst_bytestream_new (bstest->sinkpad); - } - } - - if (GST_ELEMENT_CLASS (parent_class)->change_state) - return GST_ELEMENT_CLASS (parent_class)->change_state (element); - - return GST_STATE_SUCCESS; -} - -static gboolean -plugin_init (GstPlugin * plugin) -{ - /* We need to create an ElementFactory for each element we provide. - * This consists of the name of the element, the GType identifier, - * and a pointer to the details structure at the top of the file. - */ - return gst_element_register (plugin, "bstest", GST_RANK_PRIMARY, - GST_TYPE_BSTEST); -} - -GST_PLUGIN_DEFINE (GST_VERSION_MAJOR, - GST_VERSION_MINOR, - "bstest", - "test for the bytestream element", - plugin_init, VERSION, GST_LICENSE, GST_PACKAGE, GST_ORIGIN) diff --git a/tests/old/testsuite/cleanup/Makefile.am b/tests/old/testsuite/cleanup/Makefile.am index ba1e603d54..c8affe9f72 100644 --- a/tests/old/testsuite/cleanup/Makefile.am +++ b/tests/old/testsuite/cleanup/Makefile.am @@ -2,6 +2,3 @@ include ../Rules tests_pass = cleanup1 cleanup2 cleanup4 cleanup5 tests_fail = - -# cleanup3 fails depending on the machine -tests_ignore = cleanup3 diff --git a/tests/old/testsuite/cleanup/cleanup3.c b/tests/old/testsuite/cleanup/cleanup3.c deleted file mode 100644 index 37498ba2b6..0000000000 --- a/tests/old/testsuite/cleanup/cleanup3.c +++ /dev/null @@ -1,68 +0,0 @@ -#include - -static GstElement * -create_pipeline (void) -{ - GstElement *fakesrc, *fakesink; - GstElement *pipeline; - GstElement *thread, *queue; - - pipeline = gst_pipeline_new ("main_pipeline"); - - fakesrc = gst_element_factory_make ("fakesrc", "fakesrc"); - thread = gst_thread_new ("thread"); - fakesink = gst_element_factory_make ("fakesink", "fakesink"); - queue = gst_element_factory_make ("queue", "queue"); - gst_bin_add (GST_BIN (thread), fakesink); - gst_bin_add (GST_BIN (thread), queue); - gst_element_link (queue, fakesink); - gst_element_add_ghost_pad (thread, gst_element_get_pad (queue, "sink"), - "sink"); - - gst_element_link (fakesrc, thread); - - gst_bin_add (GST_BIN (pipeline), fakesrc); - gst_bin_add (GST_BIN (pipeline), thread); - - g_object_set (G_OBJECT (fakesrc), "num_buffers", 5, NULL); - - return pipeline; -} - -gint -main (gint argc, gchar * argv[]) -{ - GstElement *pipeline; - gint i = 10000; - gint step = 100; - - free (malloc (8)); /* -lefence */ - - gst_init (&argc, &argv); - - - g_mem_chunk_info (); - while (i--) { - if (i % step == 0) - fprintf (stderr, "%10d\r", i); - pipeline = create_pipeline (); - - gst_element_set_state (pipeline, GST_STATE_PLAYING); - - while (gst_bin_iterate (GST_BIN (pipeline))); - - gst_element_set_state (pipeline, GST_STATE_NULL); - - gst_element_set_state (pipeline, GST_STATE_PLAYING); - - while (gst_bin_iterate (GST_BIN (pipeline))); - - gst_element_set_state (pipeline, GST_STATE_NULL); - - gst_object_unref (GST_OBJECT (pipeline)); - } - fprintf (stderr, "\n"); - g_mem_chunk_info (); - - return 0; -} diff --git a/tests/old/testsuite/clock/Makefile.am b/tests/old/testsuite/clock/Makefile.am index d7ed02ba05..c455f2b7c6 100644 --- a/tests/old/testsuite/clock/Makefile.am +++ b/tests/old/testsuite/clock/Makefile.am @@ -1,5 +1,5 @@ include ../Rules -tests_pass = signedness clock1 clock2 +tests_pass = signedness clock1 tests_fail = tests_ignore = diff --git a/tests/old/testsuite/clock/clock1.c b/tests/old/testsuite/clock/clock1.c index 7aa9856457..d6cdea820e 100644 --- a/tests/old/testsuite/clock/clock1.c +++ b/tests/old/testsuite/clock/clock1.c @@ -26,6 +26,7 @@ main (int argc, char *argv[]) g_print ("Could not create a fakesrc element !\n"); return 1; } + g_object_set (G_OBJECT (src), "num-buffers", 1, NULL); if ((id = gst_element_factory_make ("identity", "filter")) == NULL) { g_print ("Could not create a identity element !\n"); return 1; diff --git a/tests/old/testsuite/clock/clock2.c b/tests/old/testsuite/clock/clock2.c deleted file mode 100644 index 303b9c20f4..0000000000 --- a/tests/old/testsuite/clock/clock2.c +++ /dev/null @@ -1,55 +0,0 @@ -/* - * testsuite program to test clock behaviour - * - * creates a fakesrc ! identity ! fakesink pipeline - * registers a callback on fakesrc and one on fakesink - * also register a normal GLib timeout which should not be reached - */ - -#include -void -gst_clock_debug (GstClock * clock, GstElement * fakesink) -{ - g_print ("Clock info: time %" G_GUINT64_FORMAT " - Element info: time %" - G_GUINT64_FORMAT "\n", gst_clock_get_time (clock), - gst_element_get_time (fakesink)); -} - -int -main (int argc, char *argv[]) -{ - GstClock *clock = NULL; - GstElement *pipeline, *fakesrc, *fakesink; - - gst_init (&argc, &argv); - - clock = gst_system_clock_obtain (); - g_assert (clock != NULL); - - /* we check the time on an element */ - fakesrc = gst_element_factory_make ("fakesrc", NULL); - g_assert (fakesrc); - fakesink = gst_element_factory_make ("fakesink", NULL); - g_assert (fakesink); - pipeline = gst_element_factory_make ("pipeline", NULL); - g_assert (pipeline); - gst_bin_add_many (GST_BIN (pipeline), fakesink, fakesrc, NULL); - gst_element_link (fakesrc, fakesink); - gst_element_set_state (pipeline, GST_STATE_PLAYING); - - gst_clock_debug (clock, fakesink); - g_usleep (G_USEC_PER_SEC); - gst_clock_debug (clock, fakesink); - - gst_element_wait (fakesink, 2 * GST_SECOND); - gst_clock_debug (clock, fakesink); - - gst_element_wait (fakesink, 5 * GST_SECOND); - gst_clock_debug (clock, fakesink); - - g_usleep (G_USEC_PER_SEC); - gst_clock_debug (clock, fakesink); - - /* success */ - return 0; -} diff --git a/tests/old/testsuite/dlopen/loadgst.c b/tests/old/testsuite/dlopen/loadgst.c index 9bfbd0a12c..f7d0c70541 100644 --- a/tests/old/testsuite/dlopen/loadgst.c +++ b/tests/old/testsuite/dlopen/loadgst.c @@ -6,23 +6,15 @@ void do_test (void) { GstElement *pipeline; - int i; - gboolean ret; gst_init (NULL, NULL); - pipeline = gst_parse_launch ("fakesrc ! fakesink", NULL); + pipeline = gst_parse_launch ("fakesrc num-buffers=100 ! fakesink", NULL); g_assert (pipeline != NULL); gst_element_set_state (pipeline, GST_STATE_PLAYING); - - for (i = 0; i < 100; i++) { - ret = gst_bin_iterate (GST_BIN (pipeline)); - g_assert (ret); - g_print ("%s", (i & 1) ? "+" : "-"); - } - g_print ("\n"); + gst_bin_iterate (GST_BIN (pipeline)); gst_object_unref (GST_OBJECT (pipeline)); } diff --git a/tests/old/testsuite/elements/fake.c b/tests/old/testsuite/elements/fake.c index 43e4c33e3a..ef65afc21f 100644 --- a/tests/old/testsuite/elements/fake.c +++ b/tests/old/testsuite/elements/fake.c @@ -46,9 +46,9 @@ main (int argc, char *argv[]) g_print ("Creating elements\n"); if (!(src = element_create ("src", "fakesrc"))) return 1; - g_object_set (G_OBJECT (src), "sizetype", 2, NULL); if (!(sink = element_create ("sink", "fakesink"))) return 1; + g_object_set (G_OBJECT (src), "sizetype", 2, "num-buffers", 100, NULL); /* add */ g_print ("Adding elements to bin\n"); @@ -59,13 +59,6 @@ main (int argc, char *argv[]) g_print ("Linking elements\n"); gst_element_set_state (pipeline, GST_STATE_PLAYING); - /* we expect this to give an error */ - if (gst_bin_iterate (GST_BIN (pipeline)) != FALSE) { - g_warning - ("Iterating a bin with unlinked elements should return FALSE !\n"); - retval = 1; - } - gst_pad_link (gst_element_get_pad (src, "src"), gst_element_get_pad (sink, "sink")); @@ -73,12 +66,7 @@ main (int argc, char *argv[]) g_print ("Doing 1 iteration\n"); gst_element_set_state (pipeline, GST_STATE_PLAYING); - /* we expect this to work */ - if (gst_bin_iterate (GST_BIN (pipeline)) != TRUE) { - g_error ("Iterating a bin with linked elements should return TRUE !\n"); - retval = 1; - } - + gst_bin_iterate (GST_BIN (pipeline)); g_print ("Done !\n"); return retval; } diff --git a/tests/old/testsuite/elements/struct_i386.h b/tests/old/testsuite/elements/struct_i386.h index 92af51140f..4f817d3994 100644 --- a/tests/old/testsuite/elements/struct_i386.h +++ b/tests/old/testsuite/elements/struct_i386.h @@ -86,10 +86,6 @@ Struct list[] = { , {"GstTagSetterIFace", sizeof (GstTagSetterIFace), 8} , - {"GstThread", sizeof (GstThread), 196} - , - {"GstThreadClass", sizeof (GstThreadClass), 332} - , {"GstTrace", sizeof (GstTrace), 20} , {"GstTraceEntry", sizeof (GstTraceEntry), 128} diff --git a/tests/old/testsuite/elements/tee.c b/tests/old/testsuite/elements/tee.c index 9f4a528e6b..90dff4b73b 100644 --- a/tests/old/testsuite/elements/tee.c +++ b/tests/old/testsuite/elements/tee.c @@ -64,7 +64,7 @@ main (int argc, char *argv[]) return 1; if (!(src = element_create ("src", "fakesrc"))) return 1; - g_object_set (G_OBJECT (src), "sizetype", 2, NULL); + g_object_set (G_OBJECT (src), "sizetype", 2, "num-buffers", 100, NULL); if (!(sink1 = element_create ("sink1", "fakesink"))) return 1; if (!(sink2 = element_create ("sink2", "fakesink"))) @@ -103,54 +103,9 @@ main (int argc, char *argv[]) gst_element_set_state (pipeline, GST_STATE_PLAYING); gst_bin_iterate (GST_BIN (pipeline)); - /* We don't allow apps to call gst_pad_try_set_caps(). */ -#if 0 - /* now we try setting caps on the src pad */ - /* FIXME: should we set to pause here ? */ - src_caps = gst_caps_from_string ("audio/raw, format=(s)\"int\", " - "rate=(i)44100"); - - g_assert (src_caps != NULL); - g_print ("Setting caps on fakesrc's src pad\n"); - pad = gst_element_get_pad (src, "src"); - if ((gst_pad_try_set_caps (pad, src_caps)) <= 0) { - g_print ("Could not set caps !\n"); - } - - /* now iterate and see if it proxies caps ok */ - gst_bin_iterate (GST_BIN (pipeline)); - sink_caps = gst_pad_get_caps (gst_element_get_pad (sink1, "sink")); - if (sink_caps && gst_caps_is_fixed (sink_caps)) { - structure = gst_caps_get_structure (sink_caps, 0); - } else { - structure = NULL; - g_print ("sink_caps is not fixed\n"); - } - if (structure == NULL || !(gst_structure_has_field (structure, "rate"))) { - g_print ("Hm, rate has not been propagated to sink1.\n"); - return 1; - } else { - int rate; - - gst_structure_get_int (structure, "rate", &rate); - g_print ("Rate of pad on sink1 : %d\n", rate); - } - sink_caps = gst_pad_get_caps (gst_element_get_pad (sink2, "sink")); - structure = gst_caps_get_structure (sink_caps, 0); - if (structure != NULL && !(gst_structure_has_field (structure, "rate"))) { - g_print ("Hm, rate has not been propagated to sink2.\n"); - return 1; - } else { - int rate; - - gst_structure_get_int (structure, "rate", &rate); - g_print ("Rate of pad on sink2 : %d\n", rate); - } -#endif - /* remove the first one, iterate */ g_print ("Removing first sink\n"); - gst_element_set_state (pipeline, GST_STATE_PAUSED); + gst_element_set_state (pipeline, GST_STATE_READY); gst_pad_unlink (tee_src1, gst_element_get_pad (sink1, "sink")); gst_bin_remove (GST_BIN (pipeline), sink1); @@ -161,7 +116,7 @@ main (int argc, char *argv[]) /* request another pad */ g_print ("Requesting third pad\n"); - gst_element_set_state (pipeline, GST_STATE_PAUSED); + gst_element_set_state (pipeline, GST_STATE_READY); /* in 0.3.2 the next statement gives an assert error */ tee_src1 = gst_element_get_request_pad (tee, "src%d"); diff --git a/tests/old/testsuite/ghostpads/ghostpads.c b/tests/old/testsuite/ghostpads/ghostpads.c index 7d87782c61..3fc7569953 100644 --- a/tests/old/testsuite/ghostpads/ghostpads.c +++ b/tests/old/testsuite/ghostpads/ghostpads.c @@ -31,6 +31,7 @@ main (gint argc, gchar * argv[]) pipeline = gst_element_factory_make ("pipeline", NULL); bin = gst_element_factory_make ("bin", NULL); fakesrc = gst_element_factory_make ("fakesrc", NULL); + g_object_set (fakesrc, "num-buffers", 100, NULL); fakesink = gst_element_factory_make ("fakesink", NULL); identity = gst_element_factory_make ("identity", NULL); @@ -45,9 +46,7 @@ main (gint argc, gchar * argv[]) gst_element_link_many (fakesrc, bin, fakesink, NULL); gst_element_set_state (pipeline, GST_STATE_PLAYING); - if (!gst_bin_iterate (GST_BIN (pipeline))) - g_assert_not_reached (); - + gst_bin_iterate (GST_BIN (pipeline)); gst_element_set_state (pipeline, GST_STATE_NULL); /* test the cleanup */ diff --git a/tests/old/testsuite/pad/Makefile.am b/tests/old/testsuite/pad/Makefile.am index cb6e84155d..db510f3ede 100644 --- a/tests/old/testsuite/pad/Makefile.am +++ b/tests/old/testsuite/pad/Makefile.am @@ -1,5 +1,5 @@ include ../Rules -tests_pass = link -tests_fail = chainnopull getnopush +tests_pass = +tests_fail = getnopush tests_ignore = diff --git a/tests/old/testsuite/pad/chainnopull.c b/tests/old/testsuite/pad/chainnopull.c deleted file mode 100644 index ed83dfc044..0000000000 --- a/tests/old/testsuite/pad/chainnopull.c +++ /dev/null @@ -1,66 +0,0 @@ -/* - * this tests that chain-based pads don't pull. - */ - -#include - -typedef struct _GstTestSink -{ - GstElement parent; - GstPad *sinkpad; -} GstTestSink; - -typedef GstElementClass GstTestSinkClass; - -static void -gst_test_sink_class_init (GstTestSinkClass * klass) -{ -} - -static void -gst_test_sink_base_init (gpointer klass) -{ -} - -static void -gst_test_sink_chain (GstPad * pad, GstData * data) -{ - data = gst_pad_pull (pad); -} - -static void -gst_test_sink_init (GstTestSink * sink) -{ - sink->sinkpad = gst_pad_new ("sink", GST_PAD_SINK); - gst_pad_set_chain_function (sink->sinkpad, gst_test_sink_chain); - gst_element_add_pad (GST_ELEMENT (sink), sink->sinkpad); -} - -GST_BOILERPLATE (GstTestSink, gst_test_sink, GstElement, GST_TYPE_ELEMENT); - -int -main (int argc, char *argv[]) -{ - GstElement *pipeline, *fakesrc, *testsink; - gint n; - - gst_init (&argc, &argv); - - pipeline = gst_pipeline_new ("p"); - fakesrc = gst_element_factory_make ("fakesrc", "src"); - testsink = g_object_new (gst_test_sink_get_type (), NULL); - gst_object_set_name (GST_OBJECT (testsink), "sink"); - gst_bin_add_many (GST_BIN (pipeline), fakesrc, testsink, NULL); - gst_element_link (fakesrc, testsink); - gst_element_set_state (pipeline, GST_STATE_PLAYING); - - for (n = 0; n < 100; n++) { - if (!gst_bin_iterate (GST_BIN (pipeline))) - break; - } - - gst_element_set_state (pipeline, GST_STATE_NULL); - gst_object_unref (GST_OBJECT (pipeline)); - - return 0; -} diff --git a/tests/old/testsuite/pad/getnopush.c b/tests/old/testsuite/pad/getnopush.c index 7041c90983..ed0eb21c90 100644 --- a/tests/old/testsuite/pad/getnopush.c +++ b/tests/old/testsuite/pad/getnopush.c @@ -22,13 +22,13 @@ gst_test_src_base_init (gpointer klass) } static GstData * -gst_test_src_get (GstPad * pad) +gst_test_src_get (GstAction * action, GstRealPad * pad) { GstEvent *event; event = gst_event_new (GST_EVENT_INTERRUPT); gst_event_ref (event); - gst_pad_push (pad, GST_DATA (event)); + gst_pad_push (GST_PAD (pad), GST_DATA (event)); return GST_DATA (event); } @@ -37,7 +37,8 @@ static void gst_test_src_init (GstTestSrc * src) { src->srcpad = gst_pad_new ("src", GST_PAD_SRC); - gst_pad_set_get_function (src->srcpad, gst_test_src_get); + gst_src_pad_set_action_handler (src->srcpad, gst_test_src_get); + gst_real_pad_set_initially_active (GST_REAL_PAD (src->srcpad), TRUE); gst_element_add_pad (GST_ELEMENT (src), src->srcpad); } @@ -47,22 +48,17 @@ int main (int argc, char *argv[]) { GstElement *pipeline, *testsrc, *fakesink; - gint n; gst_init (&argc, &argv); pipeline = gst_pipeline_new ("p"); testsrc = g_object_new (gst_test_src_get_type (), NULL); - gst_object_set_name (GST_OBJECT (testsrc), "src"); fakesink = gst_element_factory_make ("fakesink", "sink"); gst_bin_add_many (GST_BIN (pipeline), testsrc, fakesink, NULL); gst_element_link (testsrc, fakesink); gst_element_set_state (pipeline, GST_STATE_PLAYING); - for (n = 0; n < 100; n++) { - if (!gst_bin_iterate (GST_BIN (pipeline))) - break; - } + gst_bin_iterate (GST_BIN (pipeline)); gst_element_set_state (pipeline, GST_STATE_NULL); gst_object_unref (GST_OBJECT (pipeline)); diff --git a/tests/old/testsuite/pad/link.c b/tests/old/testsuite/pad/link.c deleted file mode 100644 index 5d22c381f6..0000000000 --- a/tests/old/testsuite/pad/link.c +++ /dev/null @@ -1,194 +0,0 @@ -/* - * Test that: - * - get-based sources can return data, loop-based sources can push. - * - chain-based filters receive/push, loop-based filters can pull/push. - * - chain-based sinks receive, loop-based sinks pull. - */ - -#include - -/* - * Scary type code. - */ - -typedef struct _GstTestElement -{ - GstElement parent; - GstPad *srcpad, *sinkpad; -} GstTestSrc, GstTestFilter, GstTestSink, GstTestElement; - -typedef GstElementClass GstTestSrcClass, GstTestFilterClass, GstTestSinkClass, - GstTestElementClass; - -#define gst_test_src_class_init gst_test_element_class_init -#define gst_test_filter_class_init gst_test_element_class_init -#define gst_test_sink_class_init gst_test_element_class_init - -#define gst_test_src_base_init gst_test_element_base_init -#define gst_test_filter_base_init gst_test_element_base_init -#define gst_test_sink_base_init gst_test_element_base_init - -static void -gst_test_element_class_init (GstTestElementClass * klass) -{ -} -static void -gst_test_element_base_init (gpointer klass) -{ -} - -/* - * Actual element code. - */ - -gboolean loop = FALSE; - -static GstData * -gst_test_src_get (GstPad * pad) -{ - return GST_DATA (gst_event_new (GST_EVENT_INTERRUPT)); -} - -static void -gst_test_src_loop (GstElement * element) -{ - GstTestSrc *src = (GstTestElement *) element; - - gst_pad_push (src->srcpad, gst_test_src_get (src->srcpad)); -} - -static void -gst_test_src_init (GstTestElement * src) -{ - src->srcpad = gst_pad_new ("src", GST_PAD_SRC); - if (loop) { - gst_element_set_loop_function (GST_ELEMENT (src), gst_test_src_loop); - } else { - gst_pad_set_get_function (src->srcpad, gst_test_src_get); - } - gst_element_add_pad (GST_ELEMENT (src), src->srcpad); - - GST_FLAG_SET (src, GST_ELEMENT_EVENT_AWARE); -} - -static void -gst_test_filter_chain (GstPad * pad, GstData * data) -{ - GstTestFilter *filter = (GstTestElement *) gst_pad_get_parent (pad); - - gst_pad_push (filter->srcpad, data); -} - -static void -gst_test_filter_loop (GstElement * element) -{ - GstTestFilter *filter = (GstTestElement *) element; - - gst_test_filter_chain (filter->sinkpad, gst_pad_pull (filter->sinkpad)); -} - -static void -gst_test_filter_init (GstTestElement * filter) -{ - filter->sinkpad = gst_pad_new ("sink", GST_PAD_SINK); - if (loop) { - gst_element_set_loop_function (GST_ELEMENT (filter), gst_test_filter_loop); - } else { - gst_pad_set_chain_function (filter->sinkpad, gst_test_filter_chain); - } - gst_element_add_pad (GST_ELEMENT (filter), filter->sinkpad); - - filter->srcpad = gst_pad_new ("src", GST_PAD_SRC); - gst_element_add_pad (GST_ELEMENT (filter), filter->srcpad); - - GST_FLAG_SET (filter, GST_ELEMENT_EVENT_AWARE); -} - -static void -gst_test_sink_chain (GstPad * pad, GstData * data) -{ - gst_data_unref (data); -} - -static void -gst_test_sink_loop (GstElement * element) -{ - GstTestSink *sink = (GstTestElement *) element; - - gst_test_sink_chain (sink->sinkpad, gst_pad_pull (sink->sinkpad)); -} - -static void -gst_test_sink_init (GstTestElement * sink) -{ - sink->sinkpad = gst_pad_new ("sink", GST_PAD_SINK); - if (loop) { - gst_element_set_loop_function (GST_ELEMENT (sink), gst_test_sink_loop); - } else { - gst_pad_set_chain_function (sink->sinkpad, gst_test_sink_chain); - } - gst_element_add_pad (GST_ELEMENT (sink), sink->sinkpad); - - GST_FLAG_SET (sink, GST_ELEMENT_EVENT_AWARE); -} - -#define parent_class src_parent_class -GST_BOILERPLATE (GstTestSrc, gst_test_src, GstElement, GST_TYPE_ELEMENT); -#undef parent_class -#define parent_class filter_parent_class -GST_BOILERPLATE (GstTestFilter, gst_test_filter, GstElement, GST_TYPE_ELEMENT); -#undef parent_class -#define parent_class sink_parent_class -GST_BOILERPLATE (GstTestSink, gst_test_sink, GstElement, GST_TYPE_ELEMENT); -#undef parent_class - -/* - * Actual test. - */ - -static void -cb_error (GstElement * element) -{ - g_assert_not_reached (); -} - -int -main (int argc, char *argv[]) -{ - GstElement *pipeline, *src, *filter, *sink; - gint n, r; - gboolean res; - - gst_init (&argc, &argv); - - for (r = 0; r < 2; r++) { - pipeline = gst_pipeline_new ("p"); - g_signal_connect (pipeline, "error", G_CALLBACK (cb_error), NULL); - src = g_object_new (gst_test_src_get_type (), NULL); - gst_object_set_name (GST_OBJECT (src), "src"); - filter = g_object_new (gst_test_filter_get_type (), NULL); - gst_object_set_name (GST_OBJECT (filter), "filter"); - sink = g_object_new (gst_test_sink_get_type (), NULL); - gst_object_set_name (GST_OBJECT (sink), "sink"); - gst_bin_add_many (GST_BIN (pipeline), src, filter, sink, NULL); - res = gst_element_link (src, filter); - g_assert (res); - res = gst_element_link (filter, sink); - g_assert (res); - gst_element_set_state (pipeline, GST_STATE_PLAYING); - - for (n = 0; n < 100; n++) { - if (!gst_bin_iterate (GST_BIN (pipeline))) - g_assert_not_reached (); - } - - gst_element_set_state (pipeline, GST_STATE_NULL); - gst_object_unref (GST_OBJECT (pipeline)); - - /* switch element types */ - g_print ("Loop=%s done\n", loop ? "true" : "false"); - loop = !loop; - } - - return 0; -} diff --git a/tests/old/testsuite/parse/parse1.c b/tests/old/testsuite/parse/parse1.c index be4764a944..2919f39e59 100644 --- a/tests/old/testsuite/parse/parse1.c +++ b/tests/old/testsuite/parse/parse1.c @@ -91,7 +91,7 @@ static gchar *s; #define PIPELINE3 "fakesrc identity fakesink" #define PIPELINE4 "fakesrc num-buffers=4 .src ! identity !.sink identity .src ! .sink fakesink" #define PIPELINE5 "fakesrc num-buffers=4 name=src identity name=id1 identity name = id2 fakesink name =sink src. ! id1. id1.! id2.sink id2.src!sink.sink" -#define PIPELINE6 "pipeline.(name=\"john\" fakesrc num-buffers=4 ( thread. ( ! queue ! identity !{ queue ! fakesink }) ))" +#define PIPELINE6 "pipeline.(name=\"john\" fakesrc num-buffers=4 ( bin. ( ! queue ! identity !( queue ! fakesink )) ))" #define PIPELINE7 "fakesrc num-buffers=4 ! tee name=tee .src%d! fakesink tee.src%d ! fakesink fakesink name =\"foo\" tee.src%d ! foo." /* aggregator is borked #define PIPELINE8 "fakesrc num-buffers=4 ! tee name=tee1 .src0,src1 ! .sink0, sink1 aggregator ! fakesink" diff --git a/tests/old/testsuite/schedulers/142183-2.c b/tests/old/testsuite/schedulers/142183-2.c index c472974654..802d79bab1 100644 --- a/tests/old/testsuite/schedulers/142183-2.c +++ b/tests/old/testsuite/schedulers/142183-2.c @@ -43,11 +43,11 @@ main (gint argc, gchar ** argv) g_assert (pipeline); src = gst_element_factory_make ("fakesrc", NULL); g_assert (src); + g_object_set (src, "num-buffers", 10, NULL); id = gst_element_factory_make ("identity", NULL); g_assert (id); g_signal_connect (G_OBJECT (id), "handoff", (GCallback) handoff_identity, NULL); - g_object_set (G_OBJECT (id), "loop-based", TRUE, NULL); sink = gst_element_factory_make ("fakesink", NULL); g_assert (sink); @@ -59,7 +59,6 @@ main (gint argc, gchar ** argv) if (gst_element_set_state (pipeline, GST_STATE_PLAYING) != GST_STATE_SUCCESS) g_assert_not_reached (); - gst_bin_iterate (GST_BIN (pipeline)); gst_bin_iterate (GST_BIN (pipeline)); g_print ("got past iteration, scheduler refs elements correctly\n"); diff --git a/tests/old/testsuite/schedulers/142183.c b/tests/old/testsuite/schedulers/142183.c deleted file mode 100644 index 8f56faf9a0..0000000000 --- a/tests/old/testsuite/schedulers/142183.c +++ /dev/null @@ -1,94 +0,0 @@ -/* GStreamer - * Copyright (C) 2004 Wim Taymans - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU 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 - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this library; if not, write to the Free - * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include - -#include - -static void -handoff_identity (GstElement * element) -{ - GstBin *parent; - - parent = GST_BIN (gst_element_get_parent (element)); - g_print ("identity handoff\n"); - gst_bin_remove (parent, element); -} - -gint -main (gint argc, gchar ** argv) -{ - GstElement *pipeline, *src, *sink, *id; - - gst_init (&argc, &argv); - - g_print ("setting up...\n"); - /* setup pipeline */ - pipeline = gst_element_factory_make ("pipeline", NULL); - g_assert (pipeline); - src = gst_element_factory_make ("fakesrc", NULL); - g_assert (src); - id = gst_element_factory_make ("identity", NULL); - g_assert (id); - /* ref object here as it will be unparented and destroyed in the - * handoff signal, normally the scheduler should keep a ref to the - * currently scheduled elements but that's another bug displayed in - * 142183-2.c */ - gst_object_ref (GST_OBJECT (id)); - g_signal_connect (G_OBJECT (id), "handoff", (GCallback) handoff_identity, - NULL); - g_object_set (G_OBJECT (id), "loop-based", TRUE, NULL); - - sink = gst_element_factory_make ("fakesink", NULL); - g_assert (sink); - - gst_bin_add_many (GST_BIN (pipeline), src, id, sink, NULL); - /* this is what triggers the bug */ - gst_element_enable_threadsafe_properties (GST_ELEMENT (src)); - gst_element_enable_threadsafe_properties (GST_ELEMENT (id)); - gst_element_enable_threadsafe_properties (GST_ELEMENT (sink)); - - gst_element_link_pads (src, "src", id, "sink"); - gst_element_link_pads (id, "src", sink, "sink"); - - if (gst_element_set_state (pipeline, GST_STATE_PLAYING) != GST_STATE_SUCCESS) - g_assert_not_reached (); - - gst_bin_iterate (GST_BIN (pipeline)); - gst_bin_iterate (GST_BIN (pipeline)); - - /* 'cause we're going into deadlock mode */ - alarm (5); - - g_print ("adding identity back...\n"); - /* add identity back in */ - gst_bin_add_many (GST_BIN (pipeline), id, NULL); - - g_print ("going into possible deadlock... alarm at 5 seconds\n"); - gst_bin_iterate (GST_BIN (pipeline)); - gst_bin_iterate (GST_BIN (pipeline)); - g_print ("ok, no deadlock. bug 142183 fixed!\n"); - - g_print ("cleaning up...\n"); - gst_object_unref (GST_OBJECT (pipeline)); - gst_object_unref (GST_OBJECT (id)); - src = id = sink = pipeline = NULL; - - g_print ("done.\n"); - return 0; -} diff --git a/tests/old/testsuite/schedulers/143777-2.c b/tests/old/testsuite/schedulers/143777-2.c index 399bff2039..f45f37bbd1 100644 --- a/tests/old/testsuite/schedulers/143777-2.c +++ b/tests/old/testsuite/schedulers/143777-2.c @@ -6,14 +6,13 @@ main (int argc, char **argv) { GstElement *src, *sink, *enc, *tee; GstElement *pipeline; - int i; - gst_init (&argc, &argv); pipeline = gst_element_factory_make ("pipeline", "pipeline"); src = gst_element_factory_make ("fakesrc", "src"); g_assert (src); + g_object_set (src, "num-buffers", 10, NULL); tee = gst_element_factory_make ("tee", "tee1"); g_assert (tee); enc = gst_element_factory_make ("identity", "enc"); @@ -27,11 +26,7 @@ main (int argc, char **argv) if (gst_element_set_state (pipeline, GST_STATE_PLAYING) != GST_STATE_SUCCESS) g_assert_not_reached (); - for (i = 0; i < 5; i++) { - if (!gst_bin_iterate (GST_BIN (pipeline))) - g_assert_not_reached (); - g_print ("%d\n", i); - } + gst_bin_iterate (GST_BIN (pipeline)); if (gst_element_set_state (pipeline, GST_STATE_PAUSED) != GST_STATE_SUCCESS) g_assert_not_reached (); @@ -48,11 +43,7 @@ main (int argc, char **argv) if (gst_element_set_state (pipeline, GST_STATE_PLAYING) != GST_STATE_SUCCESS) g_assert_not_reached (); - for (i = 5; i < 10; i++) { - if (!gst_bin_iterate (GST_BIN (pipeline))) - g_assert_not_reached (); - g_print ("%d\n", i); - } + gst_bin_iterate (GST_BIN (pipeline)); g_print ("cleaning up...\n"); gst_object_unref (GST_OBJECT (pipeline)); diff --git a/tests/old/testsuite/schedulers/143777.c b/tests/old/testsuite/schedulers/143777.c index 9c33d6ba7c..54a2c8c9b5 100644 --- a/tests/old/testsuite/schedulers/143777.c +++ b/tests/old/testsuite/schedulers/143777.c @@ -32,7 +32,7 @@ gint main (gint argc, gchar ** argv) { GstElement *pipeline, *src, *sink, *id; - guint i = 0, j; + guint i = 0; gst_init (&argc, &argv); @@ -42,20 +42,20 @@ main (gint argc, gchar ** argv) g_assert (pipeline); src = gst_element_factory_make ("fakesrc", NULL); g_assert (src); + g_object_set (src, "num-buffers", 10, NULL); id = gst_element_factory_make ("identity", NULL); g_assert (id); sink = gst_element_factory_make ("fakesink", NULL); g_assert (sink); gst_bin_add_many (GST_BIN (pipeline), src, id, sink, NULL); - while (i < 100) { + while (i < 10) { g_print ("running... (%d iterations)\n", i); if (gst_element_set_state (pipeline, GST_STATE_PLAYING) != GST_STATE_SUCCESS) g_assert_not_reached (); gst_element_link_many (src, id, sink, NULL); - for (j = 0; j < i; j++) - gst_bin_iterate (GST_BIN (pipeline)); + gst_bin_iterate (GST_BIN (pipeline)); if (gst_element_set_state (pipeline, GST_STATE_PAUSED) != GST_STATE_SUCCESS) g_assert_not_reached (); gst_element_unlink_many (src, id, sink, NULL); @@ -63,7 +63,7 @@ main (gint argc, gchar ** argv) } g_print ("cleaning up...\n"); - g_assert (i == 100); + g_assert (i == 10); gst_object_unref (GST_OBJECT (pipeline)); src = id = sink = pipeline = NULL; diff --git a/tests/old/testsuite/schedulers/147713.c b/tests/old/testsuite/schedulers/147713.c deleted file mode 100644 index 0a2dc07dfa..0000000000 --- a/tests/old/testsuite/schedulers/147713.c +++ /dev/null @@ -1,89 +0,0 @@ -/* GStreamer - * Copyright (C) 2004 Wim Taymanse - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU 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 - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this library; if not, write to the Free - * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include - -static gint src_handoff = 0; - -static void -handoff_src (GstElement * element) -{ - g_print ("src handoff\n"); - src_handoff++; -} - -static void -handoff_sink (GstElement * element) -{ - g_print ("sink handoff\n"); - g_assert (src_handoff == 1); -} - -gint -main (gint argc, gchar ** argv) -{ - GstElement *pipeline, *src, *sink, *id1, *id2; - - gst_init (&argc, &argv); - - g_print ("setting up...\n"); - /* setup pipeline */ - pipeline = gst_element_factory_make ("pipeline", NULL); - g_assert (pipeline); - src = gst_element_factory_make ("fakesrc", NULL); - g_assert (src); - g_object_set (G_OBJECT (src), "signal-handoffs", TRUE, NULL); - g_signal_connect (G_OBJECT (src), "handoff", (GCallback) handoff_src, NULL); - id1 = gst_element_factory_make ("identity", NULL); - g_assert (id1); - - id2 = gst_element_factory_make ("identity", NULL); - g_assert (id2); - g_object_set (G_OBJECT (id2), "loop-based", TRUE, NULL); - - sink = gst_element_factory_make ("fakesink", NULL); - g_assert (sink); - g_object_set (G_OBJECT (sink), "signal-handoffs", TRUE, NULL); - g_signal_connect (G_OBJECT (sink), "handoff", (GCallback) handoff_sink, NULL); - - gst_bin_add_many (GST_BIN (pipeline), src, id1, NULL); - gst_element_link_pads (src, "src", id1, "sink"); - - if (gst_element_set_state (pipeline, GST_STATE_PLAYING) != GST_STATE_SUCCESS) - g_assert_not_reached (); - - if (gst_element_set_state (id2, GST_STATE_PLAYING) != GST_STATE_SUCCESS) - g_assert_not_reached (); - if (gst_element_set_state (sink, GST_STATE_PLAYING) != GST_STATE_SUCCESS) - g_assert_not_reached (); - - gst_bin_add_many (GST_BIN (pipeline), sink, NULL); - gst_element_link_pads (id2, "src", sink, "sink"); - gst_element_link_pads (id1, "src", id2, "sink"); - gst_bin_add_many (GST_BIN (pipeline), id2, NULL); - - gst_bin_iterate (GST_BIN (pipeline)); - gst_bin_iterate (GST_BIN (pipeline)); - - g_print ("cleaning up...\n"); - gst_object_unref (GST_OBJECT (pipeline)); - src = id1 = id2 = sink = pipeline = NULL; - - g_print ("done.\n"); - return 0; -} diff --git a/tests/old/testsuite/schedulers/147819.c b/tests/old/testsuite/schedulers/147819.c index d8b30b337b..eb08ae20ba 100644 --- a/tests/old/testsuite/schedulers/147819.c +++ b/tests/old/testsuite/schedulers/147819.c @@ -20,20 +20,16 @@ #include -static gboolean handoff; - static void handoff_identity1 (GstElement * element) { g_print ("identity1 handoff\n"); - handoff = TRUE; } static void handoff_identity2 (GstElement * element) { g_print ("identity2 handoff\n"); - handoff = TRUE; } gint @@ -49,16 +45,15 @@ main (gint argc, gchar ** argv) g_assert (pipeline); src = gst_element_factory_make ("fakesrc", NULL); g_assert (src); + g_object_set (G_OBJECT (src), "num-buffers", 10, NULL); id1 = gst_element_factory_make ("identity", NULL); g_assert (id1); - g_object_set (G_OBJECT (id1), "loop-based", TRUE, NULL); g_object_set (G_OBJECT (id1), "duplicate", 3, NULL); g_signal_connect (G_OBJECT (id1), "handoff", (GCallback) handoff_identity1, NULL); id2 = gst_element_factory_make ("identity", NULL); g_assert (id2); - g_object_set (G_OBJECT (id2), "loop-based", TRUE, NULL); g_signal_connect (G_OBJECT (id2), "handoff", (GCallback) handoff_identity2, NULL); @@ -76,20 +71,6 @@ main (gint argc, gchar ** argv) g_print ("running...\n"); gst_bin_iterate (GST_BIN (pipeline)); - gst_bin_iterate (GST_BIN (pipeline)); - gst_bin_iterate (GST_BIN (pipeline)); - - /* do ugly stuff here */ - gst_object_ref (GST_OBJECT (id1)); - gst_bin_remove (GST_BIN (pipeline), id1); - gst_element_link_pads (src, "src", id1, "sink"); - gst_element_link_pads (id1, "src", id2, "sink"); - - gst_bin_iterate (GST_BIN (pipeline)); - gst_bin_iterate (GST_BIN (pipeline)); - gst_bin_iterate (GST_BIN (pipeline)); - gst_bin_iterate (GST_BIN (pipeline)); - gst_bin_iterate (GST_BIN (pipeline)); g_print ("cleaning up...\n"); gst_object_unref (GST_OBJECT (pipeline)); diff --git a/tests/old/testsuite/schedulers/147894-2.c b/tests/old/testsuite/schedulers/147894-2.c deleted file mode 100644 index 4eab00b057..0000000000 --- a/tests/old/testsuite/schedulers/147894-2.c +++ /dev/null @@ -1,136 +0,0 @@ -/* GStreamer - * Copyright (C) 2004 Wim Taymans - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU 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 - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this library; if not, write to the Free - * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include - -#include - -static gboolean empty; -static gboolean bug; -static gboolean handoff; -static GstElement *pipeline2; - -static void -queue_empty (GstElement * element) -{ - g_print ("queue empty\n"); - if (!handoff) - bug = TRUE; -} - -static void -queue_filled (GstElement * element) -{ - g_print ("queue filled\n"); - empty = FALSE; - - /* read from the other end */ - handoff = FALSE; - bug = FALSE; - - alarm (5); - - g_print ("emptying queue with 5 second timeout...\n"); - while (!bug && !handoff) { - gst_bin_iterate (GST_BIN (pipeline2)); - } -} - -static void -handoff_identity (GstElement * element) -{ - g_print ("identity handoff\n"); - handoff = TRUE; -} - -gint -main (gint argc, gchar ** argv) -{ - GstElement *pipeline, *src, *sink, *queue, *id; - - gst_init (&argc, &argv); - - g_print ("setting up...\n"); - /* setup pipeline */ - pipeline = gst_element_factory_make ("pipeline", NULL); - g_assert (pipeline); - src = gst_element_factory_make ("fakesrc", NULL); - g_assert (src); - queue = gst_element_factory_make ("queue", NULL); - g_assert (queue); - g_signal_connect (G_OBJECT (queue), "overrun", (GCallback) queue_filled, - NULL); - g_signal_connect (G_OBJECT (queue), "underrun", (GCallback) queue_empty, - NULL); - gst_bin_add_many (GST_BIN (pipeline), src, queue, NULL); - - gst_element_link_pads (src, "src", queue, "sink"); - - /* second pipeline for sinks */ - pipeline2 = gst_element_factory_make ("pipeline", NULL); - g_assert (pipeline2); - id = gst_element_factory_make ("identity", NULL); - g_assert (id); - g_signal_connect (G_OBJECT (id), "handoff", (GCallback) handoff_identity, - NULL); - - sink = gst_element_factory_make ("fakesink", NULL); - g_assert (sink); - gst_bin_add_many (GST_BIN (pipeline2), id, sink, NULL); - - gst_element_link_pads (queue, "src", id, "sink"); - gst_element_link_pads (id, "src", sink, "sink"); - - if (gst_element_set_state (pipeline, GST_STATE_PLAYING) != GST_STATE_SUCCESS) - g_assert_not_reached (); - - if (gst_element_set_state (pipeline2, GST_STATE_PLAYING) != GST_STATE_SUCCESS) - g_assert_not_reached (); - - g_print ("running...\n"); - /* fill queue */ - empty = TRUE; - while (empty) { - gst_bin_iterate (GST_BIN (pipeline)); - } - g_assert (!bug); - - g_print ("relinking...\n"); - /* now unlink and link id and sink */ - gst_element_unlink_pads (id, "src", sink, "sink"); - gst_element_link_pads (id, "src", sink, "sink"); - - g_print ("running again...\n"); - /* fill queue */ - empty = TRUE; - while (empty) { - gst_bin_iterate (GST_BIN (pipeline)); - } - g_assert (!bug); - - /* trigger the bug */ - - - g_print ("cleaning up...\n"); - gst_object_unref (GST_OBJECT (pipeline)); - gst_object_unref (GST_OBJECT (pipeline2)); - src = id = sink = pipeline = pipeline2 = NULL; - - g_print ("done.\n"); - return 0; -} diff --git a/tests/old/testsuite/schedulers/147894.c b/tests/old/testsuite/schedulers/147894.c deleted file mode 100644 index e89bf2ac2f..0000000000 --- a/tests/old/testsuite/schedulers/147894.c +++ /dev/null @@ -1,142 +0,0 @@ -/* GStreamer - * Copyright (C) 2004 Wim Taymans - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU 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 - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this library; if not, write to the Free - * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include - -#include - -static gboolean empty; -static gboolean bug; -static gboolean handoff; -static GstElement *pipeline2; - -static void -queue_empty (GstElement * element) -{ - g_print ("queue empty\n"); - if (!handoff) - bug = TRUE; -} - -static void -queue_filled (GstElement * element) -{ - g_print ("queue filled\n"); - empty = FALSE; - - /* read from the other end */ - handoff = FALSE; - bug = FALSE; - - alarm (5); - - g_print ("emptying queue with 5 second timeout...\n"); - while (!bug && !handoff) { - gst_bin_iterate (GST_BIN (pipeline2)); - } -} - -static void -handoff_identity (GstElement * element) -{ - g_print ("identity handoff\n"); - handoff = TRUE; -} - -gint -main (gint argc, gchar ** argv) -{ - GstElement *pipeline, *src, *sink, *queue, *id; - - gst_init (&argc, &argv); - - g_print ("setting up...\n"); - /* setup pipeline */ - pipeline = gst_element_factory_make ("pipeline", NULL); - g_assert (pipeline); - src = gst_element_factory_make ("fakesrc", NULL); - g_assert (src); - queue = gst_element_factory_make ("queue", NULL); - g_assert (queue); - g_signal_connect (G_OBJECT (queue), "overrun", (GCallback) queue_filled, - NULL); - g_signal_connect (G_OBJECT (queue), "underrun", (GCallback) queue_empty, - NULL); - gst_bin_add_many (GST_BIN (pipeline), src, queue, NULL); - - gst_element_link_pads (src, "src", queue, "sink"); - - /* second pipeline for sinks */ - pipeline2 = gst_element_factory_make ("pipeline", NULL); - g_assert (pipeline2); - id = gst_element_factory_make ("identity", NULL); - g_assert (id); - g_signal_connect (G_OBJECT (id), "handoff", (GCallback) handoff_identity, - NULL); - - sink = gst_element_factory_make ("fakesink", NULL); - g_assert (sink); - gst_bin_add_many (GST_BIN (pipeline2), id, sink, NULL); - - gst_element_link_pads (queue, "src", id, "sink"); - gst_element_link_pads (id, "src", sink, "sink"); - - if (gst_element_set_state (pipeline, GST_STATE_PLAYING) != GST_STATE_SUCCESS) - g_assert_not_reached (); - - if (gst_element_set_state (pipeline2, GST_STATE_PLAYING) != GST_STATE_SUCCESS) - g_assert_not_reached (); - - g_print ("running...\n"); - /* fill queue */ - empty = TRUE; - while (empty) { - gst_bin_iterate (GST_BIN (pipeline)); - } - g_assert (!bug); - - if (gst_element_set_state (pipeline2, GST_STATE_READY) != GST_STATE_SUCCESS) - g_assert_not_reached (); - - g_print ("relinking...\n"); - /* now unlink and link id and sink */ - gst_element_unlink_pads (id, "src", sink, "sink"); - gst_element_link_pads (id, "src", sink, "sink"); - - if (gst_element_set_state (pipeline2, GST_STATE_PLAYING) != GST_STATE_SUCCESS) - g_assert_not_reached (); - - g_print ("running again...\n"); - /* fill queue */ - empty = TRUE; - while (empty) { - gst_bin_iterate (GST_BIN (pipeline)); - } - g_assert (!bug); - - /* trigger the bug */ - - - g_print ("cleaning up...\n"); - gst_object_unref (GST_OBJECT (pipeline)); - gst_object_unref (GST_OBJECT (pipeline2)); - src = id = sink = pipeline = pipeline2 = NULL; - - g_print ("done.\n"); - return 0; -} diff --git a/tests/old/testsuite/schedulers/Makefile.am b/tests/old/testsuite/schedulers/Makefile.am index 391ac40476..8ccc80ded2 100644 --- a/tests/old/testsuite/schedulers/Makefile.am +++ b/tests/old/testsuite/schedulers/Makefile.am @@ -4,15 +4,13 @@ tests_pass = \ unlink_src unlink_sink \ relink_src relink_sink \ unref_src unref_sink \ - 142183 142183-2 \ + 142183-2 \ 143777 143777-2 \ - 147713 \ 147819 \ - 147894 147894-2 group_link \ - queue_link + group_link \ + queue_link \ + useless_iteration -# don't enable this one unless it actually works. -# useless_iteration tests_fail = tests_ignore = diff --git a/tests/old/testsuite/schedulers/group_link.c b/tests/old/testsuite/schedulers/group_link.c index e40c84d1ba..82a9d9ee25 100644 --- a/tests/old/testsuite/schedulers/group_link.c +++ b/tests/old/testsuite/schedulers/group_link.c @@ -33,11 +33,11 @@ main (gint argc, gchar ** argv) g_assert (pipeline); src = gst_element_factory_make ("fakesrc", NULL); g_assert (src); + g_object_set (G_OBJECT (src), "num-buffers", 10, NULL); id1 = gst_element_factory_make ("identity", NULL); g_assert (id1); id2 = gst_element_factory_make ("identity", NULL); g_assert (id2); - g_object_set (G_OBJECT (id2), "loop-based", TRUE, NULL); sink = gst_element_factory_make ("fakesink", NULL); g_assert (sink); diff --git a/tests/old/testsuite/schedulers/queue_link.c b/tests/old/testsuite/schedulers/queue_link.c index f14d7b53e8..f4b62091fb 100644 --- a/tests/old/testsuite/schedulers/queue_link.c +++ b/tests/old/testsuite/schedulers/queue_link.c @@ -33,10 +33,11 @@ main (gint argc, gchar ** argv) g_assert (pipeline); src = gst_element_factory_make ("fakesrc", NULL); g_assert (src); + g_object_set (src, "num-buffers", 10, NULL); queue = gst_element_factory_make ("queue", NULL); g_assert (queue); - thread = gst_element_factory_make ("thread", NULL); + thread = gst_element_factory_make ("bin", NULL); g_assert (thread); bin = gst_element_factory_make ("bin", NULL); g_assert (bin); diff --git a/tests/old/testsuite/schedulers/relink.c b/tests/old/testsuite/schedulers/relink.c index a76daf0df1..a0499b536b 100644 --- a/tests/old/testsuite/schedulers/relink.c +++ b/tests/old/testsuite/schedulers/relink.c @@ -30,6 +30,9 @@ cb_handoff (GstElement * element, GstBuffer * buffer, GstPad * pad, gst_bin_remove (GST_BIN (pipeline), OTHER_ELEMENT); OTHER_ELEMENT = gst_element_factory_make ("fake" G_STRINGIFY (OTHER_ELEMENT), NULL); + if (g_str_equal (G_OBJECT_CLASS_NAME (G_OBJECT_GET_CLASS (OTHER_ELEMENT)), + "GstFakeSrc")) + g_object_set (OTHER_ELEMENT, "num-buffers", 10, NULL); g_assert (OTHER_ELEMENT); gst_bin_add (GST_BIN (pipeline), OTHER_ELEMENT); gst_element_sync_state_with_parent (OTHER_ELEMENT); @@ -40,8 +43,6 @@ cb_handoff (GstElement * element, GstBuffer * buffer, GstPad * pad, gint main (gint argc, gchar ** argv) { - guint i = 0; - gst_init (&argc, &argv); g_print ("setting up...\n"); @@ -50,6 +51,7 @@ main (gint argc, gchar ** argv) g_assert (pipeline); src = gst_element_factory_make ("fakesrc", NULL); g_assert (src); + g_object_set (src, "num-buffers", 10, NULL); sink = gst_element_factory_make ("fakesink", NULL); g_assert (sink); gst_bin_add_many (GST_BIN (pipeline), src, sink, NULL); @@ -62,7 +64,7 @@ main (gint argc, gchar ** argv) g_print ("running...\n"); if (gst_element_set_state (pipeline, GST_STATE_PLAYING) != GST_STATE_SUCCESS) g_assert_not_reached (); - while (i++ < 10 && gst_bin_iterate (GST_BIN (pipeline))); + gst_bin_iterate (GST_BIN (pipeline)); g_print ("cleaning up...\n"); gst_object_unref (GST_OBJECT (pipeline)); diff --git a/tests/old/testsuite/schedulers/unlink.c b/tests/old/testsuite/schedulers/unlink.c index 11ae3e5c12..784e9d56c0 100644 --- a/tests/old/testsuite/schedulers/unlink.c +++ b/tests/old/testsuite/schedulers/unlink.c @@ -41,6 +41,7 @@ main (gint argc, gchar ** argv) g_assert (pipeline); src = gst_element_factory_make ("fakesrc", NULL); g_assert (src); + g_object_set (src, "num-buffers", 10, NULL); sink = gst_element_factory_make ("fakesink", NULL); g_assert (sink); gst_bin_add_many (GST_BIN (pipeline), src, sink, NULL); @@ -53,7 +54,7 @@ main (gint argc, gchar ** argv) g_print ("running...\n"); if (gst_element_set_state (pipeline, GST_STATE_PLAYING) != GST_STATE_SUCCESS) g_assert_not_reached (); - while (gst_bin_iterate (GST_BIN (pipeline))); + gst_bin_iterate (GST_BIN (pipeline)); g_print ("cleaning up...\n"); gst_object_unref (GST_OBJECT (pipeline)); diff --git a/tests/old/testsuite/schedulers/unref.c b/tests/old/testsuite/schedulers/unref.c index 543620a7ac..fe55332711 100644 --- a/tests/old/testsuite/schedulers/unref.c +++ b/tests/old/testsuite/schedulers/unref.c @@ -19,6 +19,7 @@ #include GstElement *pipeline, *src, *sink; +GMainLoop *loop; static void cb_handoff (GstElement * element, GstBuffer * buffer, GstPad * pad, @@ -28,6 +29,7 @@ cb_handoff (GstElement * element, GstBuffer * buffer, GstPad * pad, g_print ("unreffing...\n"); gst_object_unref (GST_OBJECT (pipeline)); pipeline = NULL; + g_main_loop_quit (loop); } } @@ -42,6 +44,7 @@ main (gint argc, gchar ** argv) g_assert (pipeline); src = gst_element_factory_make ("fakesrc", NULL); g_assert (src); + g_object_set (src, "num-buffers", 10, NULL); sink = gst_element_factory_make ("fakesink", NULL); g_assert (sink); gst_bin_add_many (GST_BIN (pipeline), src, sink, NULL); @@ -54,7 +57,9 @@ main (gint argc, gchar ** argv) g_print ("running...\n"); if (gst_element_set_state (pipeline, GST_STATE_PLAYING) != GST_STATE_SUCCESS) g_assert_not_reached (); - while (pipeline && gst_bin_iterate (GST_BIN (pipeline))); + loop = g_main_loop_new (NULL, TRUE); + g_main_loop_run (loop); + g_main_loop_unref (loop); g_print ("done.\n"); return 0; diff --git a/tests/old/testsuite/schedulers/useless_iteration.c b/tests/old/testsuite/schedulers/useless_iteration.c index d064c648c6..1afef15647 100644 --- a/tests/old/testsuite/schedulers/useless_iteration.c +++ b/tests/old/testsuite/schedulers/useless_iteration.c @@ -23,13 +23,14 @@ main (gint argc, gchar ** argv) { GstElement *pipeline; GError *error = NULL; - guint i = 0; gst_init (&argc, &argv); g_print ("setting up...\n"); /* setup pipeline */ - pipeline = gst_parse_launch ("pipeline.( { fakesrc ! fakesink } )", &error); + pipeline = + gst_parse_launch + ("pipeline.( pipeline.( fakesrc num-buffers=1000 ! fakesink ) )", &error); g_assert (error == NULL); g_assert (pipeline); @@ -37,11 +38,9 @@ main (gint argc, gchar ** argv) g_print ("running...\n"); if (gst_element_set_state (pipeline, GST_STATE_PLAYING) != GST_STATE_SUCCESS) g_assert_not_reached (); - while (i < 100 && gst_bin_iterate (GST_BIN (pipeline))) - i++; + gst_bin_iterate (GST_BIN (pipeline)); - g_print ("cleaning up... (%d iterations)\n", i); - g_assert (i == 100); + g_print ("cleaning up...\n"); gst_object_unref (GST_OBJECT (pipeline)); pipeline = NULL; diff --git a/tests/sched/.gitignore b/tests/sched/.gitignore deleted file mode 100644 index f563157238..0000000000 --- a/tests/sched/.gitignore +++ /dev/null @@ -1,18 +0,0 @@ -Makefile -Makefile.in -*.o -*.lo -*.la -.deps -.libs - -runxml -log.txt -dynamic-pipeline -interrupt1 -interrupt2 -interrupt3 -sched-stress -*.bb -*.bbg -*.da diff --git a/tests/sched/Makefile.am b/tests/sched/Makefile.am deleted file mode 100644 index e929e062b3..0000000000 --- a/tests/sched/Makefile.am +++ /dev/null @@ -1,12 +0,0 @@ -if GST_DISABLE_LOADSAVE -noinst_PROGRAMS = -else -noinst_PROGRAMS = runxml dynamic-pipeline sched-stress interrupt1 interrupt2 interrupt3 -endif - -dynamic_pipeline_SOURCES = dynamic-pipeline.c -sched_stress_SOURCES = sched-stress.c -sched_stress_LDADD = $(GST_OBJ_LIBS) #-lefence - -LDADD = $(GST_OBJ_LIBS) -AM_CFLAGS = $(GST_OBJ_CFLAGS) diff --git a/tests/sched/dynamic-pipeline.c b/tests/sched/dynamic-pipeline.c deleted file mode 100644 index 46b25c7928..0000000000 --- a/tests/sched/dynamic-pipeline.c +++ /dev/null @@ -1,63 +0,0 @@ -#include - -/* This test will fail because it tries to allocate two cothread_context's in - * one thread. This will cause a segfault. This is a problem with gstreamer's - * cothreading that is fixed in the newer cothreads package. - */ - -int -main (int argc, char *argv[]) -{ - GstElement *fakesrc, *fakesink1, *fakesink2, *pipe1, *pipe2; - - gst_init (&argc, &argv); - - if (argc != 1) { - g_print ("usage: %s\n", argv[0]); - exit (-1); - } - - fakesrc = gst_element_factory_make ("fakesrc", "fakesrc"); - fakesink1 = gst_element_factory_make ("fakesink", "fakesink1"); - fakesink2 = gst_element_factory_make ("fakesink", "fakesink2"); - - /* a crucial part of this test (and one that the old cothreads fails on) is - having two active pipelines in the same thread. */ - pipe1 = gst_pipeline_new ("pipe1"); - pipe2 = gst_pipeline_new ("pipe2"); - - /* make the first pipeline */ - gst_bin_add (GST_BIN (pipe1), fakesrc); - gst_bin_add (GST_BIN (pipe1), fakesink1); - gst_element_link_pads (fakesrc, "src", fakesink1, "sink"); - - /* initialize cothreads */ - gst_element_set_state (pipe1, GST_STATE_PLAYING); - gst_bin_iterate (GST_BIN (pipe1)); - gst_element_set_state (pipe1, GST_STATE_READY); - - /* destroy the fakesink, but keep fakesrc (its state is GST_STATE_READY) */ - gst_element_unlink_pads (fakesrc, "src", fakesink1, "sink"); - gst_object_ref (GST_OBJECT (fakesrc)); - gst_bin_remove (GST_BIN (pipe1), fakesrc); - gst_bin_remove (GST_BIN (pipe1), fakesink1); - - gst_object_unref (GST_OBJECT (pipe1)); - - /* make a new pipeline */ - gst_bin_add (GST_BIN (pipe2), fakesink2); - - /* don't change the new pipeline's state, it should change on the bin_add */ - gst_bin_add (GST_BIN (pipe2), fakesrc); - gst_element_link_pads (fakesrc, "src", fakesink2, "sink"); - - /* show the pipeline state */ - gst_xml_write_file (GST_ELEMENT (pipe2), stdout); - - /* try to iterate the pipeline */ - gst_element_set_state (pipe2, GST_STATE_PLAYING); - gst_bin_iterate (GST_BIN (pipe2)); - gst_element_set_state (pipe2, GST_STATE_NULL); - - return 0; -} diff --git a/tests/sched/interrupt1.c b/tests/sched/interrupt1.c deleted file mode 100644 index 66d6d6844b..0000000000 --- a/tests/sched/interrupt1.c +++ /dev/null @@ -1,38 +0,0 @@ -#include - -int -main (int argc, char *argv[]) -{ - GstElement *pipeline, *thread, *queue, *src, *sink; - - gst_init (&argc, &argv); - - free (malloc (8)); /* -lefence */ - - pipeline = gst_pipeline_new ("pipeline"); - - src = gst_element_factory_make ("fakesrc", "src"); - - thread = gst_thread_new ("thread"); - - queue = gst_element_factory_make ("queue", "queue"); - sink = gst_element_factory_make ("fakesink", "sink"); - - gst_bin_add (GST_BIN (thread), queue); - gst_bin_add (GST_BIN (thread), sink); - gst_bin_add (GST_BIN (pipeline), thread); - gst_bin_add (GST_BIN (pipeline), src); - - gst_element_link_pads (src, "src", queue, "sink"); - gst_element_link_pads (queue, "src", sink, "sink"); - - gst_element_set_state (pipeline, GST_STATE_PLAYING); - g_usleep (G_USEC_PER_SEC); - gst_element_set_state (pipeline, GST_STATE_PAUSED); - - gst_element_set_state (pipeline, GST_STATE_PLAYING); - g_usleep (G_USEC_PER_SEC); - gst_element_set_state (pipeline, GST_STATE_PAUSED); - - return 0; -} diff --git a/tests/sched/interrupt2.c b/tests/sched/interrupt2.c deleted file mode 100644 index 3907e2942d..0000000000 --- a/tests/sched/interrupt2.c +++ /dev/null @@ -1,42 +0,0 @@ -#include - -int -main (int argc, char *argv[]) -{ - GstElement *pipeline, *thread, *queue, *src, *identity, *sink; - - gst_init (&argc, &argv); - - free (malloc (8)); /* -lefence */ - - pipeline = gst_pipeline_new ("pipeline"); - - src = gst_element_factory_make ("fakesrc", "src"); - - thread = gst_thread_new ("thread"); - - queue = gst_element_factory_make ("queue", "queue"); - identity = gst_element_factory_make ("identity", "identity"); - g_object_set (G_OBJECT (identity), "loop_based", TRUE, NULL); - sink = gst_element_factory_make ("fakesink", "sink"); - - gst_bin_add (GST_BIN (thread), queue); - gst_bin_add (GST_BIN (thread), identity); - gst_bin_add (GST_BIN (thread), sink); - gst_bin_add (GST_BIN (pipeline), thread); - gst_bin_add (GST_BIN (pipeline), src); - - gst_element_link_pads (src, "src", queue, "sink"); - gst_element_link_pads (queue, "src", identity, "sink"); - gst_element_link_pads (identity, "src", sink, "sink"); - - gst_element_set_state (pipeline, GST_STATE_PLAYING); - g_usleep (G_USEC_PER_SEC); - gst_element_set_state (pipeline, GST_STATE_PAUSED); - - gst_element_set_state (pipeline, GST_STATE_PLAYING); - g_usleep (G_USEC_PER_SEC); - gst_element_set_state (pipeline, GST_STATE_PAUSED); - - return 0; -} diff --git a/tests/sched/interrupt3.c b/tests/sched/interrupt3.c deleted file mode 100644 index 6b05434eaa..0000000000 --- a/tests/sched/interrupt3.c +++ /dev/null @@ -1,45 +0,0 @@ -#include - -int -main (int argc, char *argv[]) -{ - GstElement *pipeline, *thread, *queue, *src, *adder, *sink; - GstPad *sinkpad; - - gst_init (&argc, &argv); - - free (malloc (8)); /* -lefence */ - - pipeline = gst_pipeline_new ("pipeline"); - - src = gst_element_factory_make ("fakesrc", "src"); - g_object_set (G_OBJECT (src), "sizetype", 2, NULL); - - thread = gst_thread_new ("thread"); - - queue = gst_element_factory_make ("queue", "queue"); - adder = gst_element_factory_make ("adder", "adder"); - sink = gst_element_factory_make ("fakesink", "sink"); - - gst_bin_add (GST_BIN (thread), queue); - gst_bin_add (GST_BIN (thread), adder); - gst_bin_add (GST_BIN (thread), sink); - gst_bin_add (GST_BIN (pipeline), thread); - gst_bin_add (GST_BIN (pipeline), src); - - sinkpad = gst_element_get_request_pad (adder, "sink%d"); - - gst_element_link_pads (src, "src", queue, "sink"); - gst_pad_link (gst_element_get_pad (queue, "src"), sinkpad); - gst_element_link_pads (adder, "src", sink, "sink"); - - gst_element_set_state (pipeline, GST_STATE_PLAYING); - g_usleep (G_USEC_PER_SEC); - gst_element_set_state (pipeline, GST_STATE_PAUSED); - - gst_element_set_state (pipeline, GST_STATE_PLAYING); - g_usleep (G_USEC_PER_SEC); - gst_element_set_state (pipeline, GST_STATE_PAUSED); - - return 0; -} diff --git a/tests/sched/runtestcases b/tests/sched/runtestcases deleted file mode 100755 index c79ee3e92b..0000000000 --- a/tests/sched/runtestcases +++ /dev/null @@ -1,15 +0,0 @@ -#/bin/bash - -echo "log" > log.txt - -for i in cases/*.xml -do - ./runxml $i - error=$? - if test $error -ne 0; - then - echo $i " error," $error >>log.txt - else - echo $i " ok" >>log.txt - fi -done diff --git a/tests/sched/runxml.c b/tests/sched/runxml.c deleted file mode 100644 index 20fca1c148..0000000000 --- a/tests/sched/runxml.c +++ /dev/null @@ -1,96 +0,0 @@ -#include -#include -#include - -static guint outcount, incount; - -static void -buffer_handoff_sink (GstElement * src, GstBuffer * buf, GstElement * bin) -{ - g_print ("\n\n *** buffer arrived in sink ***\n\n"); - gst_element_set_state (bin, GST_STATE_NULL); - - outcount++; -} - -static void -buffer_handoff_src (GstElement * src, GstBuffer * buf, GstElement * bin) -{ - g_print ("\n\n *** buffer started in src ***\n\n"); - incount++; -} - -/* eos will be called when the src element has an end of stream */ -void -eos (GstElement * element, gpointer data) -{ - g_print ("have eos, quitting\n"); -} - -int -main (int argc, char *argv[]) -{ - GstXML *xml; - GList *toplevelelements; - gint i = 1; - - gst_init (&argc, &argv); - - if (argc < 2) { - g_print ("usage: %s \n", argv[0]); - exit (-1); - } - - g_print ("\n *** using testfile %s\n", argv[1]); - - xml = gst_xml_new (); - gst_xml_parse_file (xml, (guchar *) argv[1], NULL); - - toplevelelements = gst_xml_get_topelements (xml); - - while (toplevelelements) { - GstElement *bin = (GstElement *) toplevelelements->data; - GstElement *src, *sink; - - g_print ("\n ***** testcase %d\n", i++); - - src = gst_bin_get_by_name (GST_BIN (bin), "fakesrc"); - if (src) { - g_signal_connect (G_OBJECT (src), "handoff", - G_CALLBACK (buffer_handoff_src), bin); - } else { - g_print ("could not find src element\n"); - exit (-1); - } - - sink = gst_bin_get_by_name (GST_BIN (bin), "fakesink"); - if (sink) { - g_signal_connect (G_OBJECT (sink), "handoff", - G_CALLBACK (buffer_handoff_sink), bin); - } else { - g_print ("could not find sink element\n"); - exit (-1); - } - - incount = 0; - outcount = 0; - -/* gst_element_set_state(bin, GST_STATE_READY); */ - gst_element_set_state (bin, GST_STATE_PLAYING); - - if (GST_IS_THREAD (bin)) { - g_usleep (G_USEC_PER_SEC); - } else { - gst_bin_iterate (GST_BIN (bin)); - } - - if (outcount != 1 && incount != 1) { - g_print ("test failed\n"); - exit (-1); - } - - toplevelelements = g_list_next (toplevelelements); - } - - exit (0); -} diff --git a/tests/sched/sched-stress.c b/tests/sched/sched-stress.c deleted file mode 100644 index b058a41a69..0000000000 --- a/tests/sched/sched-stress.c +++ /dev/null @@ -1,29 +0,0 @@ -#include - -#define TAILLE 100 - -int -main (int argc, char *argv[]) -{ - GstElement *bin, *src, *dec, *sink; - int i, j; - - gst_init (&argc, &argv); - - free (malloc (8)); /* -lefence */ - - for (i = 0; i < TAILLE; i++) { - bin = gst_pipeline_new ("pipeline"); - src = gst_element_factory_make ("fakesrc", "source"); - dec = gst_element_factory_make ("identity", "decoder"); - sink = gst_element_factory_make ("fakesink", "sink"); - gst_bin_add_many (GST_BIN (bin), src, dec, sink, NULL); - gst_element_link_many (src, dec, sink, NULL); - gst_element_set_state (bin, GST_STATE_PLAYING); - for (j = 0; j < 30; j++) - gst_bin_iterate (GST_BIN (bin)); - gst_element_set_state (bin, GST_STATE_PAUSED); - } - - return 0; -} diff --git a/tests/sched/testcases b/tests/sched/testcases deleted file mode 100644 index c91ae3f062..0000000000 --- a/tests/sched/testcases +++ /dev/null @@ -1,1060 +0,0 @@ -* = loopbased - -/**************************************************************************************/ - * 1 bin - **************************************************************************************/ - -1) - - - [-bin-------------------------------] - ! [--------] [--------] ! - ! !faksesrc! !fakesink! ! - ! ! src -------- sink ! ! - ! [--------] [--------] ! - [-----------------------------------] - -fakesrc ! fakesink - -2) - - - [-bin-----------------------------------------------] - ! [--------] [--------] [--------] ! - ! !faksesrc! !identity! !fakesink! ! - ! ! src --- sink src ----- sink ! ! - ! [--------] [--------] [--------] ! - [---------------------------------------------------] - -fakesrc ! identity ! fakesink - -3) - - - [-bin-----------------------------------------------] - ! [--------] [--------] [--------] ! - ! !faksesrc! !identity! !fakesink! ! - ! ! src --- sink * src ----- sink ! ! - ! [--------] [--------] [--------] ! - [---------------------------------------------------] - -fakesrc ! @identity ! fakesink - -4) - - [-bin--------------------------------------------------------------] - ! [--------] [--------] [--------] [--------] ! - ! !faksesrc! !identity! !identity! !fakesink! ! - ! ! src --- sink src -- sink src -- sink ! ! - ! [--------] [--------] [--------] [--------] ! - [------------------------------------------------------------------] - -fakesrc ! identity ! identity ! fakesink - -4b) - - [-bin--------------------------------------------------------------] - ! [--------] [--------] [--------] [--------] ! - ! !faksesrc! !identity! !identity! !fakesink! ! - ! ! src --- sink * src -- sink src -- sink ! ! - ! [--------] [--------] [--------] [--------] ! - [------------------------------------------------------------------] - -fakesrc ! @identity ! identity ! fakesink - -5) - - [------------------------------------------------------------------] - ! [--------] [--------] [--------] [--------] ! - ! !faksesrc! !identity! !identity! !fakesink! ! - ! ! src --- sink src -- sink * src -- sink ! ! - ! [--------] [--------] [--------] [--------] ! - [------------------------------------------------------------------] - -fakesrc ! identity ! @identity ! fakesink - -5b) - - [------------------------------------------------------------------] - ! [--------] [--------] [--------] [--------] ! - ! !faksesrc! !identity! !identity! !fakesink! ! - ! ! src --- sink * src -- sink * src -- sink ! ! - ! [--------] [--------] [--------] [--------] ! - [------------------------------------------------------------------] - -fakesrc ! @identity ! @identity ! fakesink - - -/**************************************************************************************/ - * bin-in-bin based - **************************************************************************************/ - -6) - - [-bin-----------------------------------] - [ [-bin-------------------------------] ] - [ ! [--------] [--------] ! ] - [ ! !faksesrc! !fakesink! ! ] - [ ! ! src -------- sink ! ! ] - [ ! [--------] [--------] ! ] - [ [-----------------------------------] ] - [---------------------------------------] - -(fakesrc ! fakesink) - -7) - - [-bin-----------------------------------] - [ [-bin----------] ] - [ ! [--------] ] [--------] ] - [ ! !faksesrc! ] !fakesink! ] - [ ! ! src -------- sink ! ] - [ ! [--------] ] [--------] ] - [ [--------------] ] - [---------------------------------------] - -(fakesrc) ! fakesink - -8) - - [-bin-----------------------------------] - [ [-bin-------------] ] - [ [--------] [ [--------] ! ] - [ !faksesrc! [ !fakesink! ! ] - [ ! src -------- sink ! ! ] - [ [--------] [ [--------] ! ] - [ [-----------------] ] - [---------------------------------------] - -fakesrc ! (fakesink) - -9) - - [-bin---------------------------------------------------] - [ [-bin-------------] ! - [ [--------] [--------] ! [--------] ! ! - [ !faksesrc! !identity! ! !fakesink! ! ! - [ ! src --- sink src ----- sink ! ! ! - [ [--------] [--------] ! [--------] ! ! - [ [-----------------] ! - [-------------------------------------------------------] - -fakesrc ! identity ! (fakesink) - -10) - - [-bin---------------------------------------------------] - [ [-bin-------------] ! - [ [--------] [--------] ! [--------] ! ! - [ !faksesrc! !identity! ! !fakesink! ! ! - [ ! src --- sink * src ----- sink ! ! ! - [ [--------] [--------] ! [--------] ! ! - [ [-----------------] ! - [-------------------------------------------------------] - -fakesrc ! @identity ! (fakesink) - -11) - - [-bin---------------------------------------------------] - [ [-bin--------------------------------] ! - [ [--------] ! [--------] [--------] ! ! - [ !faksesrc! ! !identity! !fakesink! ! ! - [ ! src --- sink src ----- sink ! ! ! - [ [--------] ! [--------] [--------] ! ! - [ [------------------------------------] ! - [-------------------------------------------------------] - -fakesrc ! (identity ! fakesink) - -12) - - [-bin---------------------------------------------------] - [ [-bin--------------------------------] ! - [ [--------] ! [--------] [--------] ! ! - [ !faksesrc! ! !identity! !fakesink! ! ! - [ ! src --- sink * src ----- sink ! ! ! - [ [--------] ! [--------] [--------] ! ! - [ [------------------------------------] ! - [-------------------------------------------------------] - -fakesrc ! (@identity ! fakesink) - -13) - - [-bin---------------------------------------------------] - [ [-bin-----------------------------] ! - [ [ [--------] [--------] ! [--------] ! - [ [ !faksesrc! !identity! ! !fakesink! ! - [ [ ! src --- sink src ----- sink ! ! - [ [ [--------] [--------] ! [--------] ! - [ [---------------------------------] ! - [-------------------------------------------------------] - -(fakesrc ! identity) ! fakesink - -14) - - [-bin---------------------------------------------------] - ! [-bin-----------------------------] ! - ! ! [--------] [--------] ! [--------] ! - ! ! !faksesrc! !identity! ! !fakesink! ! - ! ! ! src --- sink * src ----- sink ! ! - ! ! [--------] [--------] ! [--------] ! - ! [---------------------------------] ! - [-------------------------------------------------------] - -(fakesrc ! @identity) ! fakesink - -15) - - [-bin----------------------------------------------------------------] - ! [-bin-----------------------------] ! - ! ! [--------] [--------] ! [--------] [--------] ! - ! ! !faksesrc! !identity! ! !identity! !fakesink! ! - ! ! ! src --- sink src -- sink src -- sink ! ! - ! ! [--------] [--------] ! [--------] [--------] ! - ! [---------------------------------] ! - [--------------------------------------------------------------------] - -(fakesrc ! identity) ! identity ! fakesink - -16) - - [-bin----------------------------------------------------------------] - ! [-bin----------------------------] ! - ! [--------] [--------] ! [--------] [--------] ! ! - ! !faksesrc! !identity! ! !identity! !fakesink! ! ! - ! ! src --- sink src -- sink src -- sink ! ! ! - ! [--------] [--------] ! [--------] [--------] ! ! - ! [--------------------------------] ! - [--------------------------------------------------------------------] - -fakesrc ! identity ! (identity ! fakesink) - -17) - - [-bin----------------------------------------------------------------] - ! [-bin----------------------------] ! - ! [--------] [--------] ! [--------] [--------] ! ! - ! !faksesrc! !identity! ! !identity! !fakesink! ! ! - ! ! src --- sink src -- sink * src -- sink ! ! ! - ! [--------] [--------] ! [--------] [--------] ! ! - ! [--------------------------------] ! - [--------------------------------------------------------------------] - -fakesrc ! identity ! (@identity ! fakesink) - -18) - - [-bin----------------------------------------------------------------] - ! [-bin----------------------------] ! - ! [--------] [--------] ! [--------] [--------] ! ! - ! !faksesrc! !identity! ! !identity! !fakesink! ! ! - ! ! src --- sink * src -- sink * src -- sink ! ! ! - ! [--------] [--------] ! [--------] [--------] ! ! - ! [--------------------------------] ! - [--------------------------------------------------------------------] - -fakesrc ! @identity ! @identity ! fakesink - -19) - - [-bin----------------------------------------------------------------] - ! [-bin-----------------------------] ! - ! ! [--------] [--------] ! [--------] [--------] ! - ! ! !faksesrc! !identity! ! !identity! !fakesink! ! - ! ! ! src --- sink * src -- sink src -- sink ! ! - ! ! [--------] [--------] ! [--------] [--------] ! - ! [---------------------------------] ! - [--------------------------------------------------------------------] - -(fakesrc ! @identity) ! identity ! fakesink - -20) - - [-bin----------------------------------------------------------------] - ! [-bin-----------------------------] ! - ! ! [--------] [--------] ! [--------] [--------] ! - ! ! !faksesrc! !identity! ! !identity! !fakesink! ! - ! ! ! src --- sink src -- sink * src -- sink ! ! - ! ! [--------] [--------] ! [--------] [--------] ! - ! [---------------------------------] ! - [--------------------------------------------------------------------] - -(fakesrc ! identity) ! @identity ! fakesink - -21) - - [-bin----------------------------------------------------------------] - ! [-bin-----------------------------] ! - ! ! [--------] [--------] ! [--------] [--------] ! - ! ! !faksesrc! !identity! ! !identity! !fakesink! ! - ! ! ! src --- sink * src -- sink * src -- sink ! ! - ! ! [--------] [--------] ! [--------] [--------] ! - ! [---------------------------------] ! - [--------------------------------------------------------------------] - -(fakesrc ! @identity) ! @identity ! fakesink - -22) - - [-bin--------------------------------------------------------------------] - ! [-bin----------------------------] [-bin-----------------------------] ! - ! ! [--------] [--------] ! ! [--------] [--------] ! ! - ! ! !faksesrc! !identity! ! ! !identity! !fakesink! ! ! - ! ! ! src --- sink src --- sink src -- sink ! ! ! - ! ! [--------] [--------] ! ! [--------] [--------] ! ! - ! [--------------------------------] [---------------------------------] ! - [------------------------------------------------------------------------] - -(fakesrc ! identity) ! (identity ! fakesink) - -23) - - [-bin--------------------------------------------------------------------] - ! [-bin----------------------------] [-bin-----------------------------] ! - ! ! [--------] [--------] ! ! [--------] [--------] ! ! - ! ! !faksesrc! !identity! ! ! !identity! !fakesink! ! ! - ! ! ! src --- sink src --- sink * src -- sink ! ! ! - ! ! [--------] [--------] ! ! [--------] [--------] ! ! - ! [--------------------------------] [---------------------------------] ! - [------------------------------------------------------------------------] - -(fakesrc ! identity) ! (@identity ! fakesink) - -24) - - [-bin--------------------------------------------------------------------] - ! [-bin----------------------------] [-bin-----------------------------] ! - ! ! [--------] [--------] ! ! [--------] [--------] ! ! - ! ! !faksesrc! !identity! ! ! !identity! !fakesink! ! ! - ! ! ! src --- sink * src --- sink src -- sink ! ! ! - ! ! [--------] [--------] ! ! [--------] [--------] ! ! - ! [--------------------------------] [---------------------------------] ! - [------------------------------------------------------------------------] - -(fakesrc ! @identity) ! (identity ! fakesink) - -25) - - [-bin--------------------------------------------------------------------] - ! [-bin----------------------------] [-bin-----------------------------] ! - ! ! [--------] [--------] ! ! [--------] [--------] ! ! - ! ! !faksesrc! !identity! ! ! !identity! !fakesink! ! ! - ! ! ! src --- sink * src --- sink * src -- sink ! ! ! - ! ! [--------] [--------] ! ! [--------] [--------] ! ! - ! [--------------------------------] [---------------------------------] ! - [------------------------------------------------------------------------] - -(fakesrc ! @identity) ! (@identity ! fakesink) - -/**************************************************************************************/ - * threads - **************************************************************************************/ - -26) - - [-bin-----------------------------------] - [ [-thread----------------------------] ] - [ ! [--------] [--------] ! ] - [ ! !faksesrc! !fakesink! ! ] - [ ! ! src -------- sink ! ! ] - [ ! [--------] [--------] ! ] - [ [-----------------------------------] ] - [---------------------------------------] - -[fakesrc ! fakesink] - -27) - - [-thread--------------------------------] - [ [-bin-------------------------------] ] - [ ! [--------] [--------] ! ] - [ ! !faksesrc! !fakesink! ! ] - [ ! ! src -------- sink ! ! ] - [ ! [--------] [--------] ! ] - [ [-----------------------------------] ] - [---------------------------------------] - -28) - - [-bin--------------------------------------------] - [ [-thread-------] ] - [ ! [--------] ] [-----] [--------] ] - [ ! !faksesrc! ] !queue! !fakesink! ] - [ ! ! src --- sink src -- sink ! ] - [ ! [--------] ] [-----] [--------] ] - [ [--------------] ] - [------------------------------------------------] - - -29) - - [-bin--------------------------------------------] - [ [-thread--------] ] - [ [--------] [-----] [ [--------] ! ] - [ !faksesrc! !queue! [ !fakesink! ! ] - [ ! src -- sink src --- sink ! ! ] - [ [--------] [-----] [ [--------] ! ] - [ [---------------] ] - [------------------------------------------------] - - -30) - - [-bin---------------------------------------------------------------] - [ [-thread--------] ! - [ [--------] [--------] [-----] ! [--------] ! ! - [ !faksesrc! !identity! !queue! ! !fakesink! ! ! - [ ! src --- sink src -- sink src --- sink ! ! ! - [ [--------] [--------] [-----] ! [--------] ! ! - [ [---------------] ! - [-------------------------------------------------------------------] - - -31) - - [-bin---------------------------------------------------------------] - [ [-thread--------] ! - [ [--------] [--------] [-----] ! [--------] ! ! - [ !faksesrc! !identity! !queue! ! !fakesink! ! ! - [ ! src --- sink * src -- sink src --- sink ! ! ! - [ [--------] [--------] [-----] ! [--------] ! ! - [ [---------------] ! - [-------------------------------------------------------------------] - - - -32) - - [-bin------------------------------------------------------------------] - [ [-thread-----------------------------] ! - [ [--------] [-----] ! [--------] [--------] ! ! - [ !faksesrc! !queue! ! !identity! !fakesink! ! ! - [ ! src --- sink src --- sink src ----- sink ! ! ! - [ [--------] [-----] ! [--------] [--------] ! ! - [ [------------------------------------] ! - [----------------------------------------------------------------------] - - -33) - - [-bin------------------------------------------------------------------] - [ [-thread-----------------------------] ! - [ [--------] [-----] ! [--------] [--------] ! ! - [ !faksesrc! !queue! ! !identity! !fakesink! ! ! - [ ! src --- sink src --- sink * src ----- sink ! ! ! - [ [--------] [-----] ! [--------] [--------] ! ! - [ [------------------------------------] ! - [----------------------------------------------------------------------] - - -34) - - [-bin---------------------------------------------------------------] - [ [-thread--------------------------] ! - [ [ [--------] [--------] ! [-----] [--------] ! - [ [ !faksesrc! !identity! ! !queue! !fakesink! ! - [ [ ! src --- sink src --- sink src -- sink ! ! - [ [ [--------] [--------] ! [-----] [--------] ! - [ [---------------------------------] ! - [-------------------------------------------------------------------] - - -35) - - [-bin---------------------------------------------------------------] - [ [-thread--------------------------] ! - [ [ [--------] [--------] ! [-----] [--------] ! - [ [ !faksesrc! !identity! ! !queue! !fakesink! ! - [ [ ! src --- sink * src --- sink src -- sink ! ! - [ [ [--------] [--------] ! [-----] [--------] ! - [ [---------------------------------] ! - [-------------------------------------------------------------------] - - -36) - - [-bin------------------------------------------------------------------------------] - ! [-thread--------------------------] ! - ! ! [--------] [--------] ! [-----] [--------] [--------] ! - ! ! !faksesrc! !identity! ! !queue! !identity! !fakesink! ! - ! ! ! src --- sink src -- sink src -- sink src -- sink ! ! - ! ! [--------] [--------] ! [-----] [--------] [--------] ! - ! [---------------------------------] ! - [----------------------------------------------------------------------------------] - - -37) - - [-bin------------------------------------------------------------------------------] - ! [-thread--------------------------] ! - ! ! [--------] [--------] ! [-----] [--------] [--------] ! - ! ! !faksesrc! !identity! ! !queue! !identity! !fakesink! ! - ! ! ! src --- sink * src -- sink src -- sink src -- sink ! ! - ! ! [--------] [--------] ! [-----] [--------] [--------] ! - ! [---------------------------------] ! - [----------------------------------------------------------------------------------] - - -38) - - [-bin------------------------------------------------------------------------------] - ! [-thread--------------------------] ! - ! ! [--------] [--------] ! [-----] [--------] [--------] ! - ! ! !faksesrc! !identity! ! !queue! !identity! !fakesink! ! - ! ! ! src --- sink src -- sink src -- sink * src -- sink ! ! - ! ! [--------] [--------] ! [-----] [--------] [--------] ! - ! [---------------------------------] ! - [----------------------------------------------------------------------------------] - - -39) - - [-bin------------------------------------------------------------------------------] - ! [-thread--------------------------] ! - ! ! [--------] [--------] ! [-----] [--------] [--------] ! - ! ! !faksesrc! !identity! ! !queue! !identity! !fakesink! ! - ! ! ! src --- sink * src -- sink src -- sink * src -- sink ! ! - ! ! [--------] [--------] ! [-----] [--------] [--------] ! - ! [---------------------------------] ! - [----------------------------------------------------------------------------------] - - -40) - - [-bin------------------------------------------------------------------------------] - ! [-thread-------------------------] ! - ! [--------] [--------] [-----] ! [--------] [--------] ! ! - ! !faksesrc! !identity! !queue! ! !identity! !fakesink! ! ! - ! ! src --- sink src -- sink src -- sink src -- sink ! ! ! - ! [--------] [--------] [-----] ! [--------] [--------] ! ! - ! [--------------------------------] ! - [----------------------------------------------------------------------------------] - -41) - - [-bin-------------------------------------------------------------------------------] - ! [-thread--------------------------] ! - ! [--------] [--------] [-----] ! [--------] [--------] ! ! - ! !faksesrc! !identity! !queue! ! !identity! !fakesink! ! ! - ! ! src --- sink src -- sink src -- sink * src -- sink ! ! ! - ! [--------] [--------] [-----] ! [--------] [--------] ! ! - ! [--------------------------------] ! - [-----------------------------------------------------------------------------------] - -42) - - [-bin------------------------------------------------------------------------------] - ! [-thread-------------------------] ! - ! [--------] [--------] [-----] ! [--------] [--------] ! ! - ! !faksesrc! !identity! !queue! ! !identity! !fakesink! ! ! - ! ! src --- sink * src -- sink src -- sink src -- sink ! ! ! - ! [--------] [--------] [-----] ! [--------] [--------] ! ! - ! [--------------------------------] ! - [----------------------------------------------------------------------------------] - - -43) - - [-bin------------------------------------------------------------------------------] - ! [-thread-------------------------] ! - ! [--------] [--------] [-----] ! [--------] [--------] ! ! - ! !faksesrc! !identity! !queue! ! !identity! !fakesink! ! ! - ! ! src --- sink * src -- sink src -- sink * src -- sink ! ! ! - ! [--------] [--------] [-----] ! [--------] [--------] ! ! - ! [--------------------------------] ! - [----------------------------------------------------------------------------------] - - - -/********************************************************************************** - * two threads in bin - **********************************************************************************/ - -44) - - [-bin---------------------------------------------------------------------------------] - ! [-thread-------------------------] [-thread--------------------------] ! - ! ! [--------] [--------] ! [-----] ! [--------] [--------] ! ! - ! ! !faksesrc! !identity! ! !queue! ! !identity! !fakesink! ! ! - ! ! ! src --- sink src --- sink src -- sink src -- sink ! ! ! - ! ! [--------] [--------] ! [-----] ! [--------] [--------] ! ! - ! [--------------------------------] [---------------------------------] ! - [-------------------------------------------------------------------------------------] - - -45) - - [-bin---------------------------------------------------------------------------------] - ! [-thread-------------------------] [-thread--------------------------] ! - ! ! [--------] [--------] ! [-----] ! [--------] [--------] ! ! - ! ! !faksesrc! !identity! ! !queue! ! !identity! !fakesink! ! ! - ! ! ! src --- sink * src --- sink src -- sink src -- sink ! ! ! - ! ! [--------] [--------] ! [-----] ! [--------] [--------] ! ! - ! [--------------------------------] [---------------------------------] ! - [-------------------------------------------------------------------------------------] - - -46) - - [-bin---------------------------------------------------------------------------------] - ! [-thread-------------------------] [-thread--------------------------] ! - ! ! [--------] [--------] ! [-----] ! [--------] [--------] ! ! - ! ! !faksesrc! !identity! ! !queue! ! !identity! !fakesink! ! ! - ! ! ! src --- sink src --- sink src -- sink * src -- sink ! ! ! - ! ! [--------] [--------] ! [-----] ! [--------] [--------] ! ! - ! [--------------------------------] [---------------------------------] ! - [-------------------------------------------------------------------------------------] - - -47) - - [-bin---------------------------------------------------------------------------------] - ! [-thread-------------------------] [-thread--------------------------] ! - ! ! [--------] [--------] ! [-----] ! [--------] [--------] ! ! - ! ! !faksesrc! !identity! ! !queue! ! !identity! !fakesink! ! ! - ! ! ! src --- sink * src --- sink src -- sink * src -- sink ! ! ! - ! ! [--------] [--------] ! [-----] ! [--------] [--------] ! ! - ! [--------------------------------] [---------------------------------] ! - [-------------------------------------------------------------------------------------] - - -48) - - [-bin---------------------------------------------------------------] - ! [-thread-------] [-thread--------------------------] ! - ! ! [--------] ! [-----] ! [--------] [--------] ! ! - ! ! !faksesrc! ! !queue! ! !identity! !fakesink! ! ! - ! ! ! src --- sink src -- sink src -- sink ! ! ! - ! ! [--------] ! [-----] ! [--------] [--------] ! ! - ! [--------------] [---------------------------------] ! - [-------------------------------------------------------------------] - - -49) - - [-bin---------------------------------------------------------------] - ! [-thread-------] [-thread--------------------------] ! - ! ! [--------] ! [-----] ! [--------] [--------] ! ! - ! ! !faksesrc! ! !queue! ! !identity! !fakesink! ! ! - ! ! ! src --- sink src -- sink * src -- sink ! ! ! - ! ! [--------] ! [-----] ! [--------] [--------] ! ! - ! [--------------] [---------------------------------] ! - [-------------------------------------------------------------------] - - -50) - - [-bin----------------------------------------------------------------] - ! [-thread-------------------------] [-thread---------] ! - ! ! [--------] [--------] ! [-----] ! [--------] ! ! - ! ! !faksesrc! !identity! ! !queue! ! !fakesink! ! ! - ! ! ! src --- sink src --- sink src -- sink ! ! ! - ! ! [--------] [--------] ! [-----] ! [--------] ! ! - ! [--------------------------------] [----------------] ! - [--------------------------------------------------------------------] - - -51) - - [-bin----------------------------------------------------------------] - ! [-thread-------------------------] [-thread---------] ! - ! ! [--------] [--------] ! [-----] ! [--------] ! ! - ! ! !faksesrc! !identity! ! !queue! ! !fakesink! ! ! - ! ! ! src --- sink * src --- sink src -- sink ! ! ! - ! ! [--------] [--------] ! [-----] ! [--------] ! ! - ! [--------------------------------] [----------------] ! - [--------------------------------------------------------------------] - - -52) - - [-bin----------------------------------------------] - ! [-thread-------] [-thread---------] ! - ! ! [--------] ! [-----] ! [--------] ! ! - ! ! !faksesrc! ! !queue! ! !fakesink! ! ! - ! ! ! src --- sink src -- sink ! ! ! - ! ! [--------] ! [-----] ! [--------] ! ! - ! [--------------] [----------------] ! - [--------------------------------------------------] - -52b) - - [-bin----------------------------------------------------------------------------------------------] - ! [-thread-------------------------] [-thread---------] ! - ! ! [--------] [--------] ! [-----] [--------] [-----] ! [--------] ! ! - ! ! !faksesrc! !identity! ! !queue! !identity! !queue! ! !fakesink! ! ! - ! ! ! src --- sink src --- sink src -- sink src -- sink src -- sink ! ! ! - ! ! [--------] [--------] ! [-----] [--------] [-----] ! [--------] ! ! - ! [--------------------------------] [----------------] ! - [--------------------------------------------------------------------------------------------------] - - -52c) - - [-bin----------------------------------------------------------------------------------------------] - ! [-thread-------------------------] [-thread---------] ! - ! ! [--------] [--------] ! [-----] [--------] [-----] ! [--------] ! ! - ! ! !faksesrc! !identity! ! !queue! !identity! !queue! ! !fakesink! ! ! - ! ! ! src --- sink * src --- sink src -- sink src -- sink src -- sink ! ! ! - ! ! [--------] [--------] ! [-----] [--------] [-----] ! [--------] ! ! - ! [--------------------------------] [----------------] ! - [--------------------------------------------------------------------------------------------------] - -52d) - - [-bin----------------------------------------------------------------------------------------------] - ! [-thread-------------------------] [-thread---------] ! - ! ! [--------] [--------] ! [-----] [--------] [-----] ! [--------] ! ! - ! ! !faksesrc! !identity! ! !queue! !identity! !queue! ! !fakesink! ! ! - ! ! ! src --- sink src --- sink src -- sink * src -- sink src -- sink ! ! ! - ! ! [--------] [--------] ! [-----] [--------] [-----] ! [--------] ! ! - ! [--------------------------------] [----------------] ! - [--------------------------------------------------------------------------------------------------] - -52e) - - [-bin----------------------------------------------------------------------------------------------] - ! [-thread-------------------------] [-thread---------] ! - ! ! [--------] [--------] ! [-----] [--------] [-----] ! [--------] ! ! - ! ! !faksesrc! !identity! ! !queue! !identity! !queue! ! !fakesink! ! ! - ! ! ! src --- sink * src --- sink src -- sink * src -- sink src -- sink ! ! ! - ! ! [--------] [--------] ! [-----] [--------] [-----] ! [--------] ! ! - ! [--------------------------------] [----------------] ! - [--------------------------------------------------------------------------------------------------] - - - - -/********************************************************************************** - * thread-bin in bin - **********************************************************************************/ - -/** thread first ******/ - -53) - - [-bin---------------------------------------------------------------------------------] - ! [-thread-------------------------] [-bin-----------------------------] ! - ! ! [--------] [--------] ! [-----] ! [--------] [--------] ! ! - ! ! !faksesrc! !identity! ! !queue! ! !identity! !fakesink! ! ! - ! ! ! src --- sink src --- sink src -- sink src -- sink ! ! ! - ! ! [--------] [--------] ! [-----] ! [--------] [--------] ! ! - ! [--------------------------------] [---------------------------------] ! - [-------------------------------------------------------------------------------------] - - -54) - - [-bin---------------------------------------------------------------------------------] - ! [-thread-------------------------] [-bin-----------------------------] ! - ! ! [--------] [--------] ! [-----] ! [--------] [--------] ! ! - ! ! !faksesrc! !identity! ! !queue! ! !identity! !fakesink! ! ! - ! ! ! src --- sink * src --- sink src -- sink src -- sink ! ! ! - ! ! [--------] [--------] ! [-----] ! [--------] [--------] ! ! - ! [--------------------------------] [---------------------------------] ! - [-------------------------------------------------------------------------------------] - - -55) - - [-bin---------------------------------------------------------------------------------] - ! [-thread-------------------------] [-bin-----------------------------] ! - ! ! [--------] [--------] ! [-----] ! [--------] [--------] ! ! - ! ! !faksesrc! !identity! ! !queue! ! !identity! !fakesink! ! ! - ! ! ! src --- sink src --- sink src -- sink * src -- sink ! ! ! - ! ! [--------] [--------] ! [-----] ! [--------] [--------] ! ! - ! [--------------------------------] [---------------------------------] ! - [-------------------------------------------------------------------------------------] - - -56) - - [-bin---------------------------------------------------------------------------------] - ! [-thread-------------------------] [-bin-----------------------------] ! - ! ! [--------] [--------] ! [-----] ! [--------] [--------] ! ! - ! ! !faksesrc! !identity! ! !queue! ! !identity! !fakesink! ! ! - ! ! ! src --- sink * src --- sink src -- sink * src -- sink ! ! ! - ! ! [--------] [--------] ! [-----] ! [--------] [--------] ! ! - ! [--------------------------------] [---------------------------------] ! - [-------------------------------------------------------------------------------------] - -57) - - [-bin----------------------------------------------] - ! [-thread-------] [-bin------------] ! - ! ! [--------] ! [-----] ! [--------] ! ! - ! ! !faksesrc! ! !queue! ! !fakesink! ! ! - ! ! ! src --- sink src -- sink ! ! ! - ! ! [--------] ! [-----] ! [--------] ! ! - ! [--------------] [----------------] ! - [--------------------------------------------------] - - -58) - - [-bin---------------------------------------------------------------] - ! [-thread-------] [-bin-----------------------------] ! - ! ! [--------] ! [-----] ! [--------] [--------] ! ! - ! ! !faksesrc! ! !queue! ! !identity! !fakesink! ! ! - ! ! ! src --- sink src -- sink src -- sink ! ! ! - ! ! [--------] ! [-----] ! [--------] [--------] ! ! - ! [--------------] [---------------------------------] ! - [-------------------------------------------------------------------] - - -59) - - [-bin---------------------------------------------------------------] - ! [-thread-------] [-bin-----------------------------] ! - ! ! [--------] ! [-----] ! [--------] [--------] ! ! - ! ! !faksesrc! ! !queue! ! !identity! !fakesink! ! ! - ! ! ! src --- sink src -- sink * src -- sink ! ! ! - ! ! [--------] ! [-----] ! [--------] [--------] ! ! - ! [--------------] [---------------------------------] ! - [-------------------------------------------------------------------] - - -60) - - [-bin----------------------------------------------------------------] - ! [-thread-------------------------] [-bin------------] ! - ! ! [--------] [--------] ! [-----] ! [--------] ! ! - ! ! !faksesrc! !identity! ! !queue! ! !fakesink! ! ! - ! ! ! src --- sink src --- sink src -- sink ! ! ! - ! ! [--------] [--------] ! [-----] ! [--------] ! ! - ! [--------------------------------] [----------------] ! - [--------------------------------------------------------------------] - - -61) - - [-bin----------------------------------------------------------------] - ! [-thread-------------------------] [-bin------------] ! - ! ! [--------] [--------] ! [-----] ! [--------] ! ! - ! ! !faksesrc! !identity! ! !queue! ! !fakesink! ! ! - ! ! ! src --- sink * src --- sink src -- sink ! ! ! - ! ! [--------] [--------] ! [-----] ! [--------] ! ! - ! [--------------------------------] [----------------] ! - [--------------------------------------------------------------------] - -/* non blocking queue ? */ - -61a) - - [-bin----------------------------------------------------------------------------------------------] - ! [-thread-------------------------] [-bin------------] ! - ! ! [--------] [--------] ! [-----] [--------] [-----] ! [--------] ! ! - ! ! !faksesrc! !identity! ! !queue! !identity! !queue! ! !fakesink! ! ! - ! ! ! src --- sink src --- sink src -- sink src -- sink src -- sink ! ! ! - ! ! [--------] [--------] ! [-----] [--------] [-----] ! [--------] ! ! - ! [--------------------------------] [----------------] ! - [--------------------------------------------------------------------------------------------------] - - -61b) - - [-bin----------------------------------------------------------------------------------------------] - ! [-thread-------------------------] [-bin------------] ! - ! ! [--------] [--------] ! [-----] [--------] [-----] ! [--------] ! ! - ! ! !faksesrc! !identity! ! !queue! !identity! !queue! ! !fakesink! ! ! - ! ! ! src --- sink * src --- sink src -- sink src -- sink src -- sink ! ! ! - ! ! [--------] [--------] ! [-----] [--------] [-----] ! [--------] ! ! - ! [--------------------------------] [----------------] ! - [--------------------------------------------------------------------------------------------------] - - -61c) - - [-bin----------------------------------------------------------------------------------------------] - ! [-thread-------------------------] [-bin------------] ! - ! ! [--------] [--------] ! [-----] [--------] [-----] ! [--------] ! ! - ! ! !faksesrc! !identity! ! !queue! !identity! !queue! ! !fakesink! ! ! - ! ! ! src --- sink src --- sink src -- sink * src -- sink src -- sink ! ! ! - ! ! [--------] [--------] ! [-----] [--------] [-----] ! [--------] ! ! - ! [--------------------------------] [----------------] ! - [--------------------------------------------------------------------------------------------------] - - -61d) - - [-bin----------------------------------------------------------------------------------------------] - ! [-thread-------------------------] [-bin------------] ! - ! ! [--------] [--------] ! [-----] [--------] [-----] ! [--------] ! ! - ! ! !faksesrc! !identity! ! !queue! !identity! !queue! ! !fakesink! ! ! - ! ! ! src --- sink * src --- sink src -- sink * src -- sink src -- sink ! ! ! - ! ! [--------] [--------] ! [-----] [--------] [-----] ! [--------] ! ! - ! [--------------------------------] [----------------] ! - [--------------------------------------------------------------------------------------------------] - - -/** bin first ******/ - -62) - - [-bin---------------------------------------------------------------------------------] - ! [-bin----------------------------] [-thread--------------------------] ! - ! ! [--------] [--------] ! [-----] ! [--------] [--------] ! ! - ! ! !faksesrc! !identity! ! !queue! ! !identity! !fakesink! ! ! - ! ! ! src --- sink src --- sink src -- sink src -- sink ! ! ! - ! ! [--------] [--------] ! [-----] ! [--------] [--------] ! ! - ! [--------------------------------] [---------------------------------] ! - [-------------------------------------------------------------------------------------] - - -63) - - [-bin---------------------------------------------------------------------------------] - ! [-bin----------------------------] [-thread--------------------------] ! - ! ! [--------] [--------] ! [-----] ! [--------] [--------] ! ! - ! ! !faksesrc! !identity! ! !queue! ! !identity! !fakesink! ! ! - ! ! ! src --- sink * src --- sink src -- sink src -- sink ! ! ! - ! ! [--------] [--------] ! [-----] ! [--------] [--------] ! ! - ! [--------------------------------] [---------------------------------] ! - [-------------------------------------------------------------------------------------] - - -64) - - [-bin---------------------------------------------------------------------------------] - ! [-bin----------------------------] [-thread--------------------------] ! - ! ! [--------] [--------] ! [-----] ! [--------] [--------] ! ! - ! ! !faksesrc! !identity! ! !queue! ! !identity! !fakesink! ! ! - ! ! ! src --- sink src --- sink src -- sink * src -- sink ! ! ! - ! ! [--------] [--------] ! [-----] ! [--------] [--------] ! ! - ! [--------------------------------] [---------------------------------] ! - [-------------------------------------------------------------------------------------] - - -65) - - [-bin---------------------------------------------------------------------------------] - ! [-bin----------------------------] [-thread--------------------------] ! - ! ! [--------] [--------] ! [-----] ! [--------] [--------] ! ! - ! ! !faksesrc! !identity! ! !queue! ! !identity! !fakesink! ! ! - ! ! ! src --- sink * src --- sink src -- sink * src -- sink ! ! ! - ! ! [--------] [--------] ! [-----] ! [--------] [--------] ! ! - ! [--------------------------------] [---------------------------------] ! - [-------------------------------------------------------------------------------------] - - -66) - - [-bin----------------------------------------------] - ! [-bin----------] [-thread---------] ! - ! ! [--------] ! [-----] ! [--------] ! ! - ! ! !faksesrc! ! !queue! ! !fakesink! ! ! - ! ! ! src --- sink src -- sink ! ! ! - ! ! [--------] ! [-----] ! [--------] ! ! - ! [--------------] [----------------] ! - [--------------------------------------------------] - - -67) - - [-bin---------------------------------------------------------------] - ! [-bin----------] [-thread--------------------------] ! - ! ! [--------] ! [-----] ! [--------] [--------] ! ! - ! ! !faksesrc! ! !queue! ! !identity! !fakesink! ! ! - ! ! ! src --- sink src -- sink src -- sink ! ! ! - ! ! [--------] ! [-----] ! [--------] [--------] ! ! - ! [--------------] [---------------------------------] ! - [-------------------------------------------------------------------] - - -68) - - [-bin---------------------------------------------------------------] - ! [-bin----------] [-thread--------------------------] ! - ! ! [--------] ! [-----] ! [--------] [--------] ! ! - ! ! !faksesrc! ! !queue! ! !identity! !fakesink! ! ! - ! ! ! src --- sink src -- sink * src -- sink ! ! ! - ! ! [--------] ! [-----] ! [--------] [--------] ! ! - ! [--------------] [---------------------------------] ! - [-------------------------------------------------------------------] - - -69) - - [-bin----------------------------------------------------------------] - ! [-bin----------------------------] [-thread---------] ! - ! ! [--------] [--------] ! [-----] ! [--------] ! ! - ! ! !faksesrc! !identity! ! !queue! ! !fakesink! ! ! - ! ! ! src --- sink src --- sink src -- sink ! ! ! - ! ! [--------] [--------] ! [-----] ! [--------] ! ! - ! [--------------------------------] [----------------] ! - [--------------------------------------------------------------------] - - -70) - - [-bin----------------------------------------------------------------] - ! [-bin----------------------------] [-thread---------] ! - ! ! [--------] [--------] ! [-----] ! [--------] ! ! - ! ! !faksesrc! !identity! ! !queue! ! !fakesink! ! ! - ! ! ! src --- sink * src --- sink src -- sink ! ! ! - ! ! [--------] [--------] ! [-----] ! [--------] ! ! - ! [--------------------------------] [----------------] ! - [--------------------------------------------------------------------] - - -71) - - [-bin----------------------------------------------------------------------------------------------] - ! [-bin----------------------------] [-thread---------] ! - ! ! [--------] [--------] ! [-----] [--------] [-----] ! [--------] ! ! - ! ! !faksesrc! !identity! ! !queue! !identity! !queue! ! !fakesink! ! ! - ! ! ! src --- sink src --- sink src -- sink src -- sink src -- sink ! ! ! - ! ! [--------] [--------] ! [-----] [--------] [-----] ! [--------] ! ! - ! [--------------------------------] [----------------] ! - [--------------------------------------------------------------------------------------------------] - - -72) - - [-bin----------------------------------------------------------------------------------------------] - ! [-bin----------------------------] [-thread---------] ! - ! ! [--------] [--------] ! [-----] [--------] [-----] ! [--------] ! ! - ! ! !faksesrc! !identity! ! !queue! !identity! !queue! ! !fakesink! ! ! - ! ! ! src --- sink * src --- sink src -- sink src -- sink src -- sink ! ! ! - ! ! [--------] [--------] ! [-----] [--------] [-----] ! [--------] ! ! - ! [--------------------------------] [----------------] ! - [--------------------------------------------------------------------------------------------------] - - -73) - - [-bin----------------------------------------------------------------------------------------------] - ! [-bin----------------------------] [-thread---------] ! - ! ! [--------] [--------] ! [-----] [--------] [-----] ! [--------] ! ! - ! ! !faksesrc! !identity! ! !queue! !identity! !queue! ! !fakesink! ! ! - ! ! ! src --- sink src --- sink src -- sink * src -- sink src -- sink ! ! ! - ! ! [--------] [--------] ! [-----] [--------] [-----] ! [--------] ! ! - ! [--------------------------------] [----------------] ! - [--------------------------------------------------------------------------------------------------] - - -74) - - [-bin----------------------------------------------------------------------------------------------] - ! [-bin----------------------------] [-thread---------] ! - ! ! [--------] [--------] ! [-----] [--------] [-----] ! [--------] ! ! - ! ! !faksesrc! !identity! ! !queue! !identity! !queue! ! !fakesink! ! ! - ! ! ! src --- sink * src --- sink src -- sink * src -- sink src -- sink ! ! ! - ! ! [--------] [--------] ! [-----] [--------] [-----] ! [--------] ! ! - ! [--------------------------------] [----------------] ! - [--------------------------------------------------------------------------------------------------] - - -75) - - [-bin----------------------------------------------------------------------------------------------] - ! [-bin----------------------------] [-thread---------] ! - ! ! [--------] [--------] ! [-----] [--------] [-----] ! [--------] ! ! - ! ! !faksesrc! !identity! ! !queue! !identity! !queue! ! !fakesink! ! ! - ! ! ! src --- sink * src --- sink src -- sink * src -- sink src -- sink ! ! ! - ! ! [--------] [--------] ! [-----] [--------] [-----] ! [--------] ! ! - ! [--------------------------------] [----------------] ! - [--------------------------------------------------------------------------------------------------] diff --git a/tests/sched/testcases1.tc b/tests/sched/testcases1.tc deleted file mode 100644 index 28ee331091..0000000000 --- a/tests/sched/testcases1.tc +++ /dev/null @@ -1,18 +0,0 @@ -tcN: fakesrc-fakesink -tcP: fakesrc ! fakesink -tcS: A, fakesrc0, handoff -tcS: B, fakesink0, handoff -tcI: 2 -tcT: 2000 -tcR: A,1,B,1,A,1,B,1 - - -tcN: fakesrc-identity-fakesink -tcP: fakesrc ! identity ! fakesink -tcS: A, fakesrc0, handoff -tcS: B, identity, handoff -tcS: C, fakesink0, handoff -tcI: 2 -tcT: 2000 -tcR: A,1,B,1,C,1,A,1,B,1,C,1 - diff --git a/tests/threadstate/.gitignore b/tests/threadstate/.gitignore deleted file mode 100644 index 1520ff60c8..0000000000 --- a/tests/threadstate/.gitignore +++ /dev/null @@ -1,18 +0,0 @@ -Makefile -Makefile.in -*.o -*.lo -*.la -.deps -.libs - -test1 -test2 -threadstate1 -threadstate2 -threadstate3 -threadstate4 -threadstate5 -*.bb -*.bbg -*.da diff --git a/tests/threadstate/Makefile.am b/tests/threadstate/Makefile.am deleted file mode 100644 index 05e755c982..0000000000 --- a/tests/threadstate/Makefile.am +++ /dev/null @@ -1,4 +0,0 @@ -noinst_PROGRAMS = threadstate1 threadstate2 threadstate3 threadstate4 threadstate5 test1 test2 - -LDADD = $(GST_OBJ_LIBS) -AM_CFLAGS = $(GST_OBJ_CFLAGS) diff --git a/tests/threadstate/test1.c b/tests/threadstate/test1.c deleted file mode 100644 index e4478be599..0000000000 --- a/tests/threadstate/test1.c +++ /dev/null @@ -1,104 +0,0 @@ -/* 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 - -typedef struct -{ - GMutex *mutex; - GCond *cond; - gint var; -} ThreadInfo; - -static void * -thread_loop (void *arg) -{ - ThreadInfo *info = (ThreadInfo *) arg; - - g_print ("thread: entering %p\n", info); - - g_print ("thread: lock\n"); - g_mutex_lock (info->mutex); - g_print ("thread: signal spinup\n"); - g_cond_signal (info->cond); - - g_print ("thread: wait ACK\n"); - g_cond_wait (info->cond, info->mutex); - info->var = 1; - g_print ("thread: signal var change\n"); - g_cond_signal (info->cond); - g_print ("thread: unlock\n"); - g_mutex_unlock (info->mutex); - - g_print ("thread: exit\n"); - return NULL; -} - -gint -main (gint argc, gchar * argv[]) -{ - ThreadInfo *info; - GThread *thread; - GError *error = NULL; - gint res = 0; - - if (!g_thread_supported ()) - g_thread_init (NULL); - - info = g_new (ThreadInfo, 1); - info->mutex = g_mutex_new (); - info->cond = g_cond_new (); - info->var = 0; - - g_print ("main: lock\n"); - g_mutex_lock (info->mutex); - - thread = g_thread_create (thread_loop, info, TRUE, &error); - - if (error != NULL) { - g_print ("Unable to start thread: %s\n", error->message); - g_error_free (error); - res = -1; - goto done; - } - - g_print ("main: wait spinup\n"); - g_cond_wait (info->cond, info->mutex); - - g_print ("main: signal ACK\n"); - g_cond_signal (info->cond); - - g_print ("main: waiting for thread to change var\n"); - g_cond_wait (info->cond, info->mutex); - - g_print ("main: var == %d\n", info->var); - if (info->var != 1) - g_print ("main: !!error!! expected var == 1, got %d\n", info->var); - g_mutex_unlock (info->mutex); - - g_print ("main: join\n"); - g_thread_join (thread); - -done: - g_mutex_free (info->mutex); - g_cond_free (info->cond); - g_free (info); - - return res; -} diff --git a/tests/threadstate/test2.c b/tests/threadstate/test2.c deleted file mode 100644 index 4841cddc25..0000000000 --- a/tests/threadstate/test2.c +++ /dev/null @@ -1,108 +0,0 @@ -/* 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 - -typedef struct -{ - GMutex *mutex; - GCond *cond_t; - GCond *cond_p; - gint var; -} ThreadInfo; - -static void * -thread_loop (void *arg) -{ - ThreadInfo *info = (ThreadInfo *) arg; - - g_print ("thread: entering %p\n", info); - - g_print ("thread: lock\n"); - g_mutex_lock (info->mutex); - g_print ("thread: signal spinup\n"); - g_cond_signal (info->cond_t); - - g_print ("thread: wait ACK\n"); - g_cond_wait (info->cond_p, info->mutex); - info->var = 1; - g_print ("thread: signal var change\n"); - g_cond_signal (info->cond_t); - g_print ("thread: unlock\n"); - g_mutex_unlock (info->mutex); - - g_print ("thread: exit\n"); - return NULL; -} - -gint -main (gint argc, gchar * argv[]) -{ - ThreadInfo *info; - GThread *thread; - GError *error = NULL; - gint res = 0; - - if (!g_thread_supported ()) - g_thread_init (NULL); - - info = g_new (ThreadInfo, 1); - info->mutex = g_mutex_new (); - info->cond_t = g_cond_new (); - info->cond_p = g_cond_new (); - info->var = 0; - - g_print ("main: lock\n"); - g_mutex_lock (info->mutex); - - thread = g_thread_create (thread_loop, info, TRUE, &error); - - if (error != NULL) { - g_print ("Unable to start thread: %s\n", error->message); - g_error_free (error); - res = -1; - goto done; - } - - g_print ("main: wait spinup\n"); - g_cond_wait (info->cond_t, info->mutex); - - g_print ("main: signal ACK\n"); - g_cond_signal (info->cond_p); - - g_print ("main: waiting for thread to change var\n"); - g_cond_wait (info->cond_t, info->mutex); - - g_print ("main: var == %d\n", info->var); - if (info->var != 1) { - g_print ("main: !!error!! expected var == 1, got %d\n", info->var); - } - g_mutex_unlock (info->mutex); - - g_print ("main: join\n"); - g_thread_join (thread); - -done: - g_mutex_free (info->mutex); - g_cond_free (info->cond_t); - g_cond_free (info->cond_p); - g_free (info); - - return res; -} diff --git a/tests/threadstate/threadstate1.c b/tests/threadstate/threadstate1.c deleted file mode 100644 index 2b1e5faabc..0000000000 --- a/tests/threadstate/threadstate1.c +++ /dev/null @@ -1,41 +0,0 @@ -#include -#include - -/* this pipeline is: - * { fakesrc ! fakesink } - */ - - -int -main (int argc, char *argv[]) -{ - GstElement *fakesrc, *fakesink; - GstElement *thread; - gint x; - - gst_init (&argc, &argv); - - thread = gst_thread_new ("thread"); - g_assert (thread != NULL); - - fakesrc = gst_element_factory_make ("fakesrc", "fake_source"); - g_assert (fakesrc != NULL); - - fakesink = gst_element_factory_make ("fakesink", "fake_sink"); - g_assert (fakesink != NULL); - - gst_bin_add_many (GST_BIN (thread), fakesrc, fakesink, NULL); - gst_element_link (fakesrc, fakesink); - - for (x = 0; x < 10; x++) { - g_print ("playing %d\n", x); - gst_element_set_state (GST_ELEMENT (thread), GST_STATE_PLAYING); - g_usleep (G_USEC_PER_SEC); - - g_print ("pausing %d\n", x); - gst_element_set_state (GST_ELEMENT (thread), GST_STATE_PAUSED); - g_usleep (G_USEC_PER_SEC); - } - - exit (0); -} diff --git a/tests/threadstate/threadstate2.c b/tests/threadstate/threadstate2.c deleted file mode 100644 index 15827dbdb1..0000000000 --- a/tests/threadstate/threadstate2.c +++ /dev/null @@ -1,69 +0,0 @@ -#include -#include - -/* this pipeline is: - * { filesrc ! mad ! osssink } - */ - -/* eos will be called when the src element has an end of stream */ -void -eos (GstElement * element, gpointer data) -{ - GstThread *thread = GST_THREAD (data); - - g_print ("have eos, quitting\n"); - - /* stop the bin */ - gst_element_set_state (GST_ELEMENT (thread), GST_STATE_NULL); - - gst_main_quit (); -} - -int -main (int argc, char *argv[]) -{ - GstElement *filesrc, *osssink; - GstElement *thread; - GstElement *mad; - gint x; - - gst_init (&argc, &argv); - - if (argc != 2) { - g_print ("usage: %s \n", argv[0]); - exit (-1); - } - - /* create a new thread to hold the elements */ - thread = gst_thread_new ("thread"); - g_assert (thread != 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); - g_signal_connect (G_OBJECT (filesrc), "eos", G_CALLBACK (eos), thread); - - /* and an audio sink */ - osssink = gst_element_factory_make ("osssink", "play_audio"); - g_assert (osssink != NULL); - - /* did i mention that this is an mp3 player? */ - mad = gst_element_factory_make ("mad", "mp3_decoder"); - g_assert (mad != NULL); - - gst_bin_add_many (GST_BIN (thread), filesrc, mad, osssink, NULL); - gst_element_link_many (filesrc, mad, osssink, NULL); - - for (x = 0; x < 10; x++) { - g_print ("playing %d\n", x); - gst_element_set_state (GST_ELEMENT (thread), GST_STATE_PLAYING); - g_usleep (G_USEC_PER_SEC * 2); - - g_print ("pausing %d\n", x); - gst_element_set_state (GST_ELEMENT (thread), GST_STATE_PAUSED); - g_usleep (G_USEC_PER_SEC * 2); - } - - exit (0); -} diff --git a/tests/threadstate/threadstate3.c b/tests/threadstate/threadstate3.c deleted file mode 100644 index cfabbb3769..0000000000 --- a/tests/threadstate/threadstate3.c +++ /dev/null @@ -1,44 +0,0 @@ -#include -#include - -/* this pipeline is: - * { { fakesrc ! fakesink } } - */ - -int -main (int argc, char *argv[]) -{ - GstElement *fakesrc, *fakesink; - GstElement *thread, *thread2; - gint x; - - gst_init (&argc, &argv); - - thread = gst_thread_new ("thread"); - g_assert (thread != NULL); - - thread2 = gst_thread_new ("thread2"); - g_assert (thread2 != NULL); - - gst_bin_add (GST_BIN (thread), GST_ELEMENT (thread2)); - - fakesrc = gst_element_factory_make ("fakesrc", "fake_source"); - g_assert (fakesrc != NULL); - - fakesink = gst_element_factory_make ("fakesink", "fake_sink"); - g_assert (fakesink != NULL); - - gst_bin_add_many (GST_BIN (thread2), fakesrc, fakesink, NULL); - gst_element_link (fakesrc, fakesink); - - for (x = 0; x < 10; x++) { - g_print ("playing %d\n", x); - gst_element_set_state (GST_ELEMENT (thread), GST_STATE_PLAYING); - g_usleep (G_USEC_PER_SEC); - - g_print ("nulling %d\n", x); - gst_element_set_state (GST_ELEMENT (thread), GST_STATE_NULL); - g_usleep (G_USEC_PER_SEC); - } - exit (0); -} diff --git a/tests/threadstate/threadstate4.c b/tests/threadstate/threadstate4.c deleted file mode 100644 index f96f90ba15..0000000000 --- a/tests/threadstate/threadstate4.c +++ /dev/null @@ -1,52 +0,0 @@ -#include -#include - -/* this pipeline is: - * { { fakesrc } ! queue ! fakesink } - */ - -int -main (int argc, char *argv[]) -{ - GstElement *fakesrc, *fakesink; - GstElement *thread, *thread2; - GstElement *queue; - gint x; - - gst_init (&argc, &argv); - - thread = gst_thread_new ("thread"); - g_assert (thread != NULL); - - thread2 = gst_thread_new ("thread"); - g_assert (thread2 != NULL); - - queue = gst_element_factory_make ("queue", "the_queue"); - g_assert (queue != NULL); - - - fakesrc = gst_element_factory_make ("fakesrc", "fake_source"); - g_assert (fakesrc != NULL); - - fakesink = gst_element_factory_make ("fakesink", "fake_sink"); - g_assert (fakesink != NULL); - - gst_bin_add_many (GST_BIN (thread), thread2, queue, fakesink, NULL); - - gst_bin_add (GST_BIN (thread2), fakesrc); - gst_element_add_ghost_pad (thread2, gst_element_get_pad (fakesrc, "src"), - "src"); - gst_element_link_many (thread2, queue, fakesink, NULL); - - for (x = 0; x < 10; x++) { - g_print ("playing %d\n", x); - gst_element_set_state (thread, GST_STATE_PLAYING); - g_usleep (G_USEC_PER_SEC); - - g_print ("nulling %d\n", x); - gst_element_set_state (thread, GST_STATE_NULL); - g_usleep (G_USEC_PER_SEC); - } - - exit (0); -} diff --git a/tests/threadstate/threadstate5.c b/tests/threadstate/threadstate5.c deleted file mode 100644 index e544d073d8..0000000000 --- a/tests/threadstate/threadstate5.c +++ /dev/null @@ -1,52 +0,0 @@ -#include -#include - -/* this pipeline is: - * { fakesrc ! { queue ! fakesink } } - */ - -int -main (int argc, char *argv[]) -{ - GstElement *fakesrc, *fakesink; - GstElement *thread, *thread2; - GstElement *queue; - gint x; - - gst_init (&argc, &argv); - - thread = gst_thread_new ("thread"); - g_assert (thread != NULL); - - thread2 = gst_thread_new ("thread"); - g_assert (thread2 != NULL); - - queue = gst_element_factory_make ("queue", "the_queue"); - g_assert (queue != NULL); - - fakesrc = gst_element_factory_make ("fakesrc", "fake_source"); - g_assert (fakesrc != NULL); - - fakesink = gst_element_factory_make ("fakesink", "fake_sink"); - g_assert (fakesink != NULL); - - gst_bin_add_many (GST_BIN (thread), fakesrc, thread2, NULL); - gst_bin_add_many (GST_BIN (thread2), queue, fakesink, NULL); - - gst_element_add_ghost_pad (thread2, gst_element_get_pad (queue, "sink"), - "sink"); - gst_element_link_many (queue, fakesink, NULL); - gst_element_link_many (fakesrc, thread2, NULL); - - for (x = 0; x < 10; x++) { - g_print ("playing %d\n", x); - gst_element_set_state (thread, GST_STATE_PLAYING); - g_usleep (G_USEC_PER_SEC); - - g_print ("nulling %d\n", x); - gst_element_set_state (thread, GST_STATE_NULL); - g_usleep (G_USEC_PER_SEC); - } - - exit (0); -} diff --git a/testsuite/Makefile.am b/testsuite/Makefile.am index df8249a062..16a2b7dab1 100644 --- a/testsuite/Makefile.am +++ b/testsuite/Makefile.am @@ -19,7 +19,7 @@ SUBDIRS = \ dlopen dynparams \ elements ghostpads indexers negotiation pad \ $(GST_PARSE_DIRS) \ - plugin refcounting schedulers states tags threads + plugin refcounting schedulers states tags DIST_SUBDIRS = \ bins bytestream caps childproxy cleanup clock \ diff --git a/testsuite/bytestream/Makefile.am b/testsuite/bytestream/Makefile.am index 790dca8d84..28db18d0b3 100644 --- a/testsuite/bytestream/Makefile.am +++ b/testsuite/bytestream/Makefile.am @@ -1,11 +1,8 @@ include ../Rules tests_pass = filepadsink -tests_fail = test1 +tests_fail = tests_ignore = -test1_SOURCES = test1.c gstbstest.c -test1_LDFLAGS = $(top_builddir)/libs/gst/bytestream/libgstbytestream.la - filepadsink_CFLAGS = $(AM_CFLAGS) -DTHE_FILE=\""$(top_srcdir)/configure.ac"\" filepadsink_LDFLAGS = $(top_builddir)/libs/gst/bytestream/libgstbytestream.la diff --git a/testsuite/bytestream/gstbstest.c b/testsuite/bytestream/gstbstest.c deleted file mode 100644 index 3eb6ae4437..0000000000 --- a/testsuite/bytestream/gstbstest.c +++ /dev/null @@ -1,419 +0,0 @@ -/* GStreamer - * Copyright (C) 1999,2000 Erik Walthinsen - * 2000 Wim Taymans - * - * gstbstest.c: - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif -#include -#include - -#include -#include - -#define GST_TYPE_BSTEST (gst_bstest_get_type()) -#define GST_BSTEST(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),GST_TYPE_BSTEST,GstBsTest)) -#define GST_BSTEST_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass),GST_TYPE_BSTEST,GstBsTestClass)) -#define GST_IS_BSTEST(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),GST_TYPE_BSTEST)) -#define GST_IS_BSTEST_CLASS(obj) (G_TYPE_CHECK_CLASS_TYPE((klass),GST_TYPE_BSTEST)) - -typedef struct _GstBsTest GstBsTest; -typedef struct _GstBsTestClass GstBsTestClass; - -struct _GstBsTest -{ - GstElement element; - - GstPad *sinkpad; - GstPad *srcpad; - - GstByteStream *bs; - - gchar *accesspattern; - guint num_patterns; - gchar **patterns; - guint sizemin; - guint sizemax; - gint count; - gboolean silent; -}; - -struct _GstBsTestClass -{ - GstElementClass parent_class; -}; - -GType gst_bstest_get_type (void); - - -GstElementDetails gst_bstest_details = GST_ELEMENT_DETAILS ("ByteStreamTest", - "Filter", - "Test for the GstByteStream code", - "Erik Walthinsen , " - "Wim Taymans "); - - -/* BsTest signals and args */ -enum -{ - /* FILL ME */ - LAST_SIGNAL -}; - -enum -{ - ARG_0, - ARG_SIZEMIN, - ARG_SIZEMAX, - ARG_COUNT, - ARG_SILENT, - ARG_ACCESSPATTERN, -}; - - -static void gst_bstest_base_init (gpointer g_class); -static void gst_bstest_class_init (GstBsTestClass * klass); -static void gst_bstest_init (GstBsTest * bstest); - -static void gst_bstest_set_property (GObject * object, guint prop_id, - const GValue * value, GParamSpec * pspec); -static void gst_bstest_get_property (GObject * object, guint prop_id, - GValue * value, GParamSpec * pspec); - -static GstElementStateReturn gst_bstest_change_state (GstElement * element); -static void gst_bstest_loop (GstElement * element); - -static GstElementClass *parent_class = NULL; - -/* static guint gst_bstest_signals[LAST_SIGNAL] = { 0 }; */ - -GType -gst_bstest_get_type (void) -{ - static GType bstest_type = 0; - - if (!bstest_type) { - static const GTypeInfo bstest_info = { - sizeof (GstBsTestClass), - gst_bstest_base_init, - NULL, - (GClassInitFunc) gst_bstest_class_init, - NULL, - NULL, - sizeof (GstBsTest), - 0, - (GInstanceInitFunc) gst_bstest_init, - }; - - bstest_type = - g_type_register_static (GST_TYPE_ELEMENT, "BSTest", &bstest_info, 0); - } - return bstest_type; -} -static void -gst_bstest_base_init (gpointer g_class) -{ - GstElementClass *gstelement_class = GST_ELEMENT_CLASS (g_class); - - gst_element_class_set_details (gstelement_class, &gst_bstest_details); -} - -static void -gst_bstest_class_init (GstBsTestClass * klass) -{ - GObjectClass *gobject_class; - GstElementClass *gstelement_class; - - gobject_class = (GObjectClass *) klass; - gstelement_class = (GstElementClass *) klass; - - parent_class = g_type_class_ref (GST_TYPE_ELEMENT); - - g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_SIZEMIN, - g_param_spec_int ("sizemin", "sizemin", "sizemin", 0, G_MAXINT, - 0, G_PARAM_READWRITE)); - g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_SIZEMAX, - g_param_spec_int ("sizemax", "sizemax", "sizemax", 0, G_MAXINT, - 384, G_PARAM_READWRITE)); - g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_ACCESSPATTERN, - g_param_spec_string ("accesspattern", "accesspattern", "accesspattern", - "r", G_PARAM_READWRITE)); - g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_COUNT, - g_param_spec_uint ("count", "count", "count", - 0, G_MAXUINT, 0, G_PARAM_READWRITE)); - g_object_class_install_property (G_OBJECT_CLASS (klass), ARG_SILENT, - g_param_spec_boolean ("silent", "silent", "silent", - FALSE, G_PARAM_READWRITE)); - - gobject_class->set_property = GST_DEBUG_FUNCPTR (gst_bstest_set_property); - gobject_class->get_property = GST_DEBUG_FUNCPTR (gst_bstest_get_property); - - gstelement_class->change_state = gst_bstest_change_state; - -} - -static GstCaps * -gst_bstest_getcaps (GstPad * pad) -{ - GstBsTest *bstest = GST_BSTEST (gst_pad_get_parent (pad)); - GstPad *otherpad; - - otherpad = (pad == bstest->srcpad) ? bstest->sinkpad : bstest->srcpad; - - return gst_pad_get_allowed_caps (otherpad); -} - -GstStaticPadTemplate srctemplate = GST_STATIC_PAD_TEMPLATE ("src", - GST_PAD_SRC, - GST_PAD_ALWAYS, - GST_STATIC_CAPS_ANY); - -GstStaticPadTemplate sinktemplate = GST_STATIC_PAD_TEMPLATE ("sink", - GST_PAD_SINK, - GST_PAD_ALWAYS, - GST_STATIC_CAPS_ANY); - -static void -gst_bstest_init (GstBsTest * bstest) -{ - bstest->sinkpad = - gst_pad_new_from_template (gst_static_pad_template_get (&sinktemplate), - "sink"); - gst_element_add_pad (GST_ELEMENT (bstest), bstest->sinkpad); - gst_pad_set_getcaps_function (bstest->sinkpad, gst_bstest_getcaps); - - bstest->srcpad = - gst_pad_new_from_template (gst_static_pad_template_get (&srctemplate), - "src"); - gst_element_add_pad (GST_ELEMENT (bstest), bstest->srcpad); - gst_pad_set_getcaps_function (bstest->srcpad, gst_bstest_getcaps); - - gst_element_set_loop_function (GST_ELEMENT (bstest), gst_bstest_loop); - - bstest->sizemin = 0; - bstest->sizemax = 384; - bstest->accesspattern = g_strdup ("r"); - bstest->patterns = g_strsplit (bstest->accesspattern, ":", 0); - bstest->count = 5; - bstest->silent = FALSE; - bstest->bs = NULL; -} - -static guint -gst_bstest_get_size (GstBsTest * bstest, gchar * sizestring, guint prevsize) -{ - guint size; - - if (sizestring[0] == 0) { - size = bstest->sizemax; - } else if (sizestring[0] == 'r') { - size = - bstest->sizemin + - (guint8) (((gfloat) bstest->sizemax) * rand () / (RAND_MAX + - (gfloat) bstest->sizemin)); - } else if (sizestring[0] == '<') { - size = prevsize; - } else { - size = atoi (sizestring); - } - - if (size == 0) - size++; - - return size; -} - -static void -gst_bstest_loop (GstElement * element) -{ - GstBsTest *bstest; - GstBuffer *buf = NULL; - - g_return_if_fail (element != NULL); - g_return_if_fail (GST_IS_BSTEST (element)); - - bstest = GST_BSTEST (element); - - do { - guint size = 0; - guint i = 0; - guint8 *ptr; - - while (i < bstest->num_patterns) { - buf = NULL; - - if (bstest->patterns[i][0] == 'r') { - size = gst_bstest_get_size (bstest, &bstest->patterns[i][1], size); - if (!bstest->silent) - g_print ("bstest: ***** read %d bytes\n", size); - gst_bytestream_read (bstest->bs, &buf, size); - } else if (bstest->patterns[i][0] == 'f') { - size = gst_bstest_get_size (bstest, &bstest->patterns[i][1], size); - if (!bstest->silent) - g_print ("bstest: ***** flush %d bytes\n", size); - gst_bytestream_flush (bstest->bs, size); - } else if (!strncmp (bstest->patterns[i], "pb", 2)) { - size = gst_bstest_get_size (bstest, &bstest->patterns[i][2], size); - if (!bstest->silent) - g_print ("bstest: ***** peek bytes %d bytes\n", size); - gst_bytestream_peek_bytes (bstest->bs, &ptr, size); - } else if (bstest->patterns[i][0] == 'p') { - size = gst_bstest_get_size (bstest, &bstest->patterns[i][1], size); - if (!bstest->silent) - g_print ("bstest: ***** peek %d bytes\n", size); - gst_bytestream_peek (bstest->bs, &buf, size); - gst_buffer_unref (buf); - buf = NULL; - } - - if (buf) - gst_pad_push (bstest->srcpad, GST_DATA (buf)); - - i++; - } -/* } while (!GST_ELEMENT_IS_COTHREAD_STOPPING (element)); */ - - } while (0); -} - -static void -gst_bstest_set_property (GObject * object, guint prop_id, const GValue * value, - GParamSpec * pspec) -{ - GstBsTest *bstest; - - /* it's not null if we got it, but it might not be ours */ - g_return_if_fail (GST_IS_BSTEST (object)); - - bstest = GST_BSTEST (object); - - switch (prop_id) { - case ARG_SIZEMIN: - bstest->sizemin = g_value_get_int (value); - break; - case ARG_SIZEMAX: - bstest->sizemax = g_value_get_int (value); - break; - case ARG_ACCESSPATTERN: - if (bstest->accesspattern) { - g_free (bstest->accesspattern); - g_strfreev (bstest->patterns); - } - if (g_value_get_string (value) == NULL) { - gst_element_set_state (GST_ELEMENT (object), GST_STATE_NULL); - bstest->accesspattern = NULL; - bstest->num_patterns = 0; - } else { - guint i = 0; - - bstest->accesspattern = g_strdup (g_value_get_string (value)); - bstest->patterns = g_strsplit (bstest->accesspattern, ":", 0); - while (bstest->patterns[i++]); - bstest->num_patterns = i - 1; - } - break; - case ARG_COUNT: - bstest->count = g_value_get_uint (value); - break; - case ARG_SILENT: - bstest->silent = g_value_get_boolean (value); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static void -gst_bstest_get_property (GObject * object, guint prop_id, GValue * value, - GParamSpec * pspec) -{ - GstBsTest *bstest; - - /* it's not null if we got it, but it might not be ours */ - g_return_if_fail (GST_IS_BSTEST (object)); - - bstest = GST_BSTEST (object); - - switch (prop_id) { - case ARG_SIZEMIN: - g_value_set_int (value, bstest->sizemin); - break; - case ARG_SIZEMAX: - g_value_set_int (value, bstest->sizemax); - break; - case ARG_ACCESSPATTERN: - g_value_set_string (value, bstest->accesspattern); - break; - case ARG_COUNT: - g_value_set_uint (value, bstest->count); - break; - case ARG_SILENT: - g_value_set_boolean (value, bstest->silent); - break; - default: - G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); - break; - } -} - -static GstElementStateReturn -gst_bstest_change_state (GstElement * element) -{ - GstBsTest *bstest; - - g_return_val_if_fail (GST_IS_BSTEST (element), GST_STATE_FAILURE); - - bstest = GST_BSTEST (element); - - if (GST_STATE_PENDING (element) == GST_STATE_NULL) { - if (bstest->bs) { - gst_bytestream_destroy (bstest->bs); - bstest->bs = NULL; - } - } else { - if (!bstest->bs) { - bstest->bs = gst_bytestream_new (bstest->sinkpad); - } - } - - if (GST_ELEMENT_CLASS (parent_class)->change_state) - return GST_ELEMENT_CLASS (parent_class)->change_state (element); - - return GST_STATE_SUCCESS; -} - -static gboolean -plugin_init (GstPlugin * plugin) -{ - /* We need to create an ElementFactory for each element we provide. - * This consists of the name of the element, the GType identifier, - * and a pointer to the details structure at the top of the file. - */ - return gst_element_register (plugin, "bstest", GST_RANK_PRIMARY, - GST_TYPE_BSTEST); -} - -GST_PLUGIN_DEFINE (GST_VERSION_MAJOR, - GST_VERSION_MINOR, - "bstest", - "test for the bytestream element", - plugin_init, VERSION, GST_LICENSE, GST_PACKAGE, GST_ORIGIN) diff --git a/testsuite/cleanup/Makefile.am b/testsuite/cleanup/Makefile.am index ba1e603d54..c8affe9f72 100644 --- a/testsuite/cleanup/Makefile.am +++ b/testsuite/cleanup/Makefile.am @@ -2,6 +2,3 @@ include ../Rules tests_pass = cleanup1 cleanup2 cleanup4 cleanup5 tests_fail = - -# cleanup3 fails depending on the machine -tests_ignore = cleanup3 diff --git a/testsuite/cleanup/cleanup3.c b/testsuite/cleanup/cleanup3.c deleted file mode 100644 index 37498ba2b6..0000000000 --- a/testsuite/cleanup/cleanup3.c +++ /dev/null @@ -1,68 +0,0 @@ -#include - -static GstElement * -create_pipeline (void) -{ - GstElement *fakesrc, *fakesink; - GstElement *pipeline; - GstElement *thread, *queue; - - pipeline = gst_pipeline_new ("main_pipeline"); - - fakesrc = gst_element_factory_make ("fakesrc", "fakesrc"); - thread = gst_thread_new ("thread"); - fakesink = gst_element_factory_make ("fakesink", "fakesink"); - queue = gst_element_factory_make ("queue", "queue"); - gst_bin_add (GST_BIN (thread), fakesink); - gst_bin_add (GST_BIN (thread), queue); - gst_element_link (queue, fakesink); - gst_element_add_ghost_pad (thread, gst_element_get_pad (queue, "sink"), - "sink"); - - gst_element_link (fakesrc, thread); - - gst_bin_add (GST_BIN (pipeline), fakesrc); - gst_bin_add (GST_BIN (pipeline), thread); - - g_object_set (G_OBJECT (fakesrc), "num_buffers", 5, NULL); - - return pipeline; -} - -gint -main (gint argc, gchar * argv[]) -{ - GstElement *pipeline; - gint i = 10000; - gint step = 100; - - free (malloc (8)); /* -lefence */ - - gst_init (&argc, &argv); - - - g_mem_chunk_info (); - while (i--) { - if (i % step == 0) - fprintf (stderr, "%10d\r", i); - pipeline = create_pipeline (); - - gst_element_set_state (pipeline, GST_STATE_PLAYING); - - while (gst_bin_iterate (GST_BIN (pipeline))); - - gst_element_set_state (pipeline, GST_STATE_NULL); - - gst_element_set_state (pipeline, GST_STATE_PLAYING); - - while (gst_bin_iterate (GST_BIN (pipeline))); - - gst_element_set_state (pipeline, GST_STATE_NULL); - - gst_object_unref (GST_OBJECT (pipeline)); - } - fprintf (stderr, "\n"); - g_mem_chunk_info (); - - return 0; -} diff --git a/testsuite/clock/Makefile.am b/testsuite/clock/Makefile.am index d7ed02ba05..c455f2b7c6 100644 --- a/testsuite/clock/Makefile.am +++ b/testsuite/clock/Makefile.am @@ -1,5 +1,5 @@ include ../Rules -tests_pass = signedness clock1 clock2 +tests_pass = signedness clock1 tests_fail = tests_ignore = diff --git a/testsuite/clock/clock1.c b/testsuite/clock/clock1.c index 7aa9856457..d6cdea820e 100644 --- a/testsuite/clock/clock1.c +++ b/testsuite/clock/clock1.c @@ -26,6 +26,7 @@ main (int argc, char *argv[]) g_print ("Could not create a fakesrc element !\n"); return 1; } + g_object_set (G_OBJECT (src), "num-buffers", 1, NULL); if ((id = gst_element_factory_make ("identity", "filter")) == NULL) { g_print ("Could not create a identity element !\n"); return 1; diff --git a/testsuite/clock/clock2.c b/testsuite/clock/clock2.c deleted file mode 100644 index 303b9c20f4..0000000000 --- a/testsuite/clock/clock2.c +++ /dev/null @@ -1,55 +0,0 @@ -/* - * testsuite program to test clock behaviour - * - * creates a fakesrc ! identity ! fakesink pipeline - * registers a callback on fakesrc and one on fakesink - * also register a normal GLib timeout which should not be reached - */ - -#include -void -gst_clock_debug (GstClock * clock, GstElement * fakesink) -{ - g_print ("Clock info: time %" G_GUINT64_FORMAT " - Element info: time %" - G_GUINT64_FORMAT "\n", gst_clock_get_time (clock), - gst_element_get_time (fakesink)); -} - -int -main (int argc, char *argv[]) -{ - GstClock *clock = NULL; - GstElement *pipeline, *fakesrc, *fakesink; - - gst_init (&argc, &argv); - - clock = gst_system_clock_obtain (); - g_assert (clock != NULL); - - /* we check the time on an element */ - fakesrc = gst_element_factory_make ("fakesrc", NULL); - g_assert (fakesrc); - fakesink = gst_element_factory_make ("fakesink", NULL); - g_assert (fakesink); - pipeline = gst_element_factory_make ("pipeline", NULL); - g_assert (pipeline); - gst_bin_add_many (GST_BIN (pipeline), fakesink, fakesrc, NULL); - gst_element_link (fakesrc, fakesink); - gst_element_set_state (pipeline, GST_STATE_PLAYING); - - gst_clock_debug (clock, fakesink); - g_usleep (G_USEC_PER_SEC); - gst_clock_debug (clock, fakesink); - - gst_element_wait (fakesink, 2 * GST_SECOND); - gst_clock_debug (clock, fakesink); - - gst_element_wait (fakesink, 5 * GST_SECOND); - gst_clock_debug (clock, fakesink); - - g_usleep (G_USEC_PER_SEC); - gst_clock_debug (clock, fakesink); - - /* success */ - return 0; -} diff --git a/testsuite/dlopen/loadgst.c b/testsuite/dlopen/loadgst.c index 9bfbd0a12c..f7d0c70541 100644 --- a/testsuite/dlopen/loadgst.c +++ b/testsuite/dlopen/loadgst.c @@ -6,23 +6,15 @@ void do_test (void) { GstElement *pipeline; - int i; - gboolean ret; gst_init (NULL, NULL); - pipeline = gst_parse_launch ("fakesrc ! fakesink", NULL); + pipeline = gst_parse_launch ("fakesrc num-buffers=100 ! fakesink", NULL); g_assert (pipeline != NULL); gst_element_set_state (pipeline, GST_STATE_PLAYING); - - for (i = 0; i < 100; i++) { - ret = gst_bin_iterate (GST_BIN (pipeline)); - g_assert (ret); - g_print ("%s", (i & 1) ? "+" : "-"); - } - g_print ("\n"); + gst_bin_iterate (GST_BIN (pipeline)); gst_object_unref (GST_OBJECT (pipeline)); } diff --git a/testsuite/elements/fake.c b/testsuite/elements/fake.c index 43e4c33e3a..ef65afc21f 100644 --- a/testsuite/elements/fake.c +++ b/testsuite/elements/fake.c @@ -46,9 +46,9 @@ main (int argc, char *argv[]) g_print ("Creating elements\n"); if (!(src = element_create ("src", "fakesrc"))) return 1; - g_object_set (G_OBJECT (src), "sizetype", 2, NULL); if (!(sink = element_create ("sink", "fakesink"))) return 1; + g_object_set (G_OBJECT (src), "sizetype", 2, "num-buffers", 100, NULL); /* add */ g_print ("Adding elements to bin\n"); @@ -59,13 +59,6 @@ main (int argc, char *argv[]) g_print ("Linking elements\n"); gst_element_set_state (pipeline, GST_STATE_PLAYING); - /* we expect this to give an error */ - if (gst_bin_iterate (GST_BIN (pipeline)) != FALSE) { - g_warning - ("Iterating a bin with unlinked elements should return FALSE !\n"); - retval = 1; - } - gst_pad_link (gst_element_get_pad (src, "src"), gst_element_get_pad (sink, "sink")); @@ -73,12 +66,7 @@ main (int argc, char *argv[]) g_print ("Doing 1 iteration\n"); gst_element_set_state (pipeline, GST_STATE_PLAYING); - /* we expect this to work */ - if (gst_bin_iterate (GST_BIN (pipeline)) != TRUE) { - g_error ("Iterating a bin with linked elements should return TRUE !\n"); - retval = 1; - } - + gst_bin_iterate (GST_BIN (pipeline)); g_print ("Done !\n"); return retval; } diff --git a/testsuite/elements/struct_i386.h b/testsuite/elements/struct_i386.h index 92af51140f..4f817d3994 100644 --- a/testsuite/elements/struct_i386.h +++ b/testsuite/elements/struct_i386.h @@ -86,10 +86,6 @@ Struct list[] = { , {"GstTagSetterIFace", sizeof (GstTagSetterIFace), 8} , - {"GstThread", sizeof (GstThread), 196} - , - {"GstThreadClass", sizeof (GstThreadClass), 332} - , {"GstTrace", sizeof (GstTrace), 20} , {"GstTraceEntry", sizeof (GstTraceEntry), 128} diff --git a/testsuite/elements/tee.c b/testsuite/elements/tee.c index 9f4a528e6b..90dff4b73b 100644 --- a/testsuite/elements/tee.c +++ b/testsuite/elements/tee.c @@ -64,7 +64,7 @@ main (int argc, char *argv[]) return 1; if (!(src = element_create ("src", "fakesrc"))) return 1; - g_object_set (G_OBJECT (src), "sizetype", 2, NULL); + g_object_set (G_OBJECT (src), "sizetype", 2, "num-buffers", 100, NULL); if (!(sink1 = element_create ("sink1", "fakesink"))) return 1; if (!(sink2 = element_create ("sink2", "fakesink"))) @@ -103,54 +103,9 @@ main (int argc, char *argv[]) gst_element_set_state (pipeline, GST_STATE_PLAYING); gst_bin_iterate (GST_BIN (pipeline)); - /* We don't allow apps to call gst_pad_try_set_caps(). */ -#if 0 - /* now we try setting caps on the src pad */ - /* FIXME: should we set to pause here ? */ - src_caps = gst_caps_from_string ("audio/raw, format=(s)\"int\", " - "rate=(i)44100"); - - g_assert (src_caps != NULL); - g_print ("Setting caps on fakesrc's src pad\n"); - pad = gst_element_get_pad (src, "src"); - if ((gst_pad_try_set_caps (pad, src_caps)) <= 0) { - g_print ("Could not set caps !\n"); - } - - /* now iterate and see if it proxies caps ok */ - gst_bin_iterate (GST_BIN (pipeline)); - sink_caps = gst_pad_get_caps (gst_element_get_pad (sink1, "sink")); - if (sink_caps && gst_caps_is_fixed (sink_caps)) { - structure = gst_caps_get_structure (sink_caps, 0); - } else { - structure = NULL; - g_print ("sink_caps is not fixed\n"); - } - if (structure == NULL || !(gst_structure_has_field (structure, "rate"))) { - g_print ("Hm, rate has not been propagated to sink1.\n"); - return 1; - } else { - int rate; - - gst_structure_get_int (structure, "rate", &rate); - g_print ("Rate of pad on sink1 : %d\n", rate); - } - sink_caps = gst_pad_get_caps (gst_element_get_pad (sink2, "sink")); - structure = gst_caps_get_structure (sink_caps, 0); - if (structure != NULL && !(gst_structure_has_field (structure, "rate"))) { - g_print ("Hm, rate has not been propagated to sink2.\n"); - return 1; - } else { - int rate; - - gst_structure_get_int (structure, "rate", &rate); - g_print ("Rate of pad on sink2 : %d\n", rate); - } -#endif - /* remove the first one, iterate */ g_print ("Removing first sink\n"); - gst_element_set_state (pipeline, GST_STATE_PAUSED); + gst_element_set_state (pipeline, GST_STATE_READY); gst_pad_unlink (tee_src1, gst_element_get_pad (sink1, "sink")); gst_bin_remove (GST_BIN (pipeline), sink1); @@ -161,7 +116,7 @@ main (int argc, char *argv[]) /* request another pad */ g_print ("Requesting third pad\n"); - gst_element_set_state (pipeline, GST_STATE_PAUSED); + gst_element_set_state (pipeline, GST_STATE_READY); /* in 0.3.2 the next statement gives an assert error */ tee_src1 = gst_element_get_request_pad (tee, "src%d"); diff --git a/testsuite/ghostpads/ghostpads.c b/testsuite/ghostpads/ghostpads.c index 7d87782c61..3fc7569953 100644 --- a/testsuite/ghostpads/ghostpads.c +++ b/testsuite/ghostpads/ghostpads.c @@ -31,6 +31,7 @@ main (gint argc, gchar * argv[]) pipeline = gst_element_factory_make ("pipeline", NULL); bin = gst_element_factory_make ("bin", NULL); fakesrc = gst_element_factory_make ("fakesrc", NULL); + g_object_set (fakesrc, "num-buffers", 100, NULL); fakesink = gst_element_factory_make ("fakesink", NULL); identity = gst_element_factory_make ("identity", NULL); @@ -45,9 +46,7 @@ main (gint argc, gchar * argv[]) gst_element_link_many (fakesrc, bin, fakesink, NULL); gst_element_set_state (pipeline, GST_STATE_PLAYING); - if (!gst_bin_iterate (GST_BIN (pipeline))) - g_assert_not_reached (); - + gst_bin_iterate (GST_BIN (pipeline)); gst_element_set_state (pipeline, GST_STATE_NULL); /* test the cleanup */ diff --git a/testsuite/pad/Makefile.am b/testsuite/pad/Makefile.am index cb6e84155d..db510f3ede 100644 --- a/testsuite/pad/Makefile.am +++ b/testsuite/pad/Makefile.am @@ -1,5 +1,5 @@ include ../Rules -tests_pass = link -tests_fail = chainnopull getnopush +tests_pass = +tests_fail = getnopush tests_ignore = diff --git a/testsuite/pad/chainnopull.c b/testsuite/pad/chainnopull.c deleted file mode 100644 index ed83dfc044..0000000000 --- a/testsuite/pad/chainnopull.c +++ /dev/null @@ -1,66 +0,0 @@ -/* - * this tests that chain-based pads don't pull. - */ - -#include - -typedef struct _GstTestSink -{ - GstElement parent; - GstPad *sinkpad; -} GstTestSink; - -typedef GstElementClass GstTestSinkClass; - -static void -gst_test_sink_class_init (GstTestSinkClass * klass) -{ -} - -static void -gst_test_sink_base_init (gpointer klass) -{ -} - -static void -gst_test_sink_chain (GstPad * pad, GstData * data) -{ - data = gst_pad_pull (pad); -} - -static void -gst_test_sink_init (GstTestSink * sink) -{ - sink->sinkpad = gst_pad_new ("sink", GST_PAD_SINK); - gst_pad_set_chain_function (sink->sinkpad, gst_test_sink_chain); - gst_element_add_pad (GST_ELEMENT (sink), sink->sinkpad); -} - -GST_BOILERPLATE (GstTestSink, gst_test_sink, GstElement, GST_TYPE_ELEMENT); - -int -main (int argc, char *argv[]) -{ - GstElement *pipeline, *fakesrc, *testsink; - gint n; - - gst_init (&argc, &argv); - - pipeline = gst_pipeline_new ("p"); - fakesrc = gst_element_factory_make ("fakesrc", "src"); - testsink = g_object_new (gst_test_sink_get_type (), NULL); - gst_object_set_name (GST_OBJECT (testsink), "sink"); - gst_bin_add_many (GST_BIN (pipeline), fakesrc, testsink, NULL); - gst_element_link (fakesrc, testsink); - gst_element_set_state (pipeline, GST_STATE_PLAYING); - - for (n = 0; n < 100; n++) { - if (!gst_bin_iterate (GST_BIN (pipeline))) - break; - } - - gst_element_set_state (pipeline, GST_STATE_NULL); - gst_object_unref (GST_OBJECT (pipeline)); - - return 0; -} diff --git a/testsuite/pad/getnopush.c b/testsuite/pad/getnopush.c index 7041c90983..ed0eb21c90 100644 --- a/testsuite/pad/getnopush.c +++ b/testsuite/pad/getnopush.c @@ -22,13 +22,13 @@ gst_test_src_base_init (gpointer klass) } static GstData * -gst_test_src_get (GstPad * pad) +gst_test_src_get (GstAction * action, GstRealPad * pad) { GstEvent *event; event = gst_event_new (GST_EVENT_INTERRUPT); gst_event_ref (event); - gst_pad_push (pad, GST_DATA (event)); + gst_pad_push (GST_PAD (pad), GST_DATA (event)); return GST_DATA (event); } @@ -37,7 +37,8 @@ static void gst_test_src_init (GstTestSrc * src) { src->srcpad = gst_pad_new ("src", GST_PAD_SRC); - gst_pad_set_get_function (src->srcpad, gst_test_src_get); + gst_src_pad_set_action_handler (src->srcpad, gst_test_src_get); + gst_real_pad_set_initially_active (GST_REAL_PAD (src->srcpad), TRUE); gst_element_add_pad (GST_ELEMENT (src), src->srcpad); } @@ -47,22 +48,17 @@ int main (int argc, char *argv[]) { GstElement *pipeline, *testsrc, *fakesink; - gint n; gst_init (&argc, &argv); pipeline = gst_pipeline_new ("p"); testsrc = g_object_new (gst_test_src_get_type (), NULL); - gst_object_set_name (GST_OBJECT (testsrc), "src"); fakesink = gst_element_factory_make ("fakesink", "sink"); gst_bin_add_many (GST_BIN (pipeline), testsrc, fakesink, NULL); gst_element_link (testsrc, fakesink); gst_element_set_state (pipeline, GST_STATE_PLAYING); - for (n = 0; n < 100; n++) { - if (!gst_bin_iterate (GST_BIN (pipeline))) - break; - } + gst_bin_iterate (GST_BIN (pipeline)); gst_element_set_state (pipeline, GST_STATE_NULL); gst_object_unref (GST_OBJECT (pipeline)); diff --git a/testsuite/pad/link.c b/testsuite/pad/link.c deleted file mode 100644 index 5d22c381f6..0000000000 --- a/testsuite/pad/link.c +++ /dev/null @@ -1,194 +0,0 @@ -/* - * Test that: - * - get-based sources can return data, loop-based sources can push. - * - chain-based filters receive/push, loop-based filters can pull/push. - * - chain-based sinks receive, loop-based sinks pull. - */ - -#include - -/* - * Scary type code. - */ - -typedef struct _GstTestElement -{ - GstElement parent; - GstPad *srcpad, *sinkpad; -} GstTestSrc, GstTestFilter, GstTestSink, GstTestElement; - -typedef GstElementClass GstTestSrcClass, GstTestFilterClass, GstTestSinkClass, - GstTestElementClass; - -#define gst_test_src_class_init gst_test_element_class_init -#define gst_test_filter_class_init gst_test_element_class_init -#define gst_test_sink_class_init gst_test_element_class_init - -#define gst_test_src_base_init gst_test_element_base_init -#define gst_test_filter_base_init gst_test_element_base_init -#define gst_test_sink_base_init gst_test_element_base_init - -static void -gst_test_element_class_init (GstTestElementClass * klass) -{ -} -static void -gst_test_element_base_init (gpointer klass) -{ -} - -/* - * Actual element code. - */ - -gboolean loop = FALSE; - -static GstData * -gst_test_src_get (GstPad * pad) -{ - return GST_DATA (gst_event_new (GST_EVENT_INTERRUPT)); -} - -static void -gst_test_src_loop (GstElement * element) -{ - GstTestSrc *src = (GstTestElement *) element; - - gst_pad_push (src->srcpad, gst_test_src_get (src->srcpad)); -} - -static void -gst_test_src_init (GstTestElement * src) -{ - src->srcpad = gst_pad_new ("src", GST_PAD_SRC); - if (loop) { - gst_element_set_loop_function (GST_ELEMENT (src), gst_test_src_loop); - } else { - gst_pad_set_get_function (src->srcpad, gst_test_src_get); - } - gst_element_add_pad (GST_ELEMENT (src), src->srcpad); - - GST_FLAG_SET (src, GST_ELEMENT_EVENT_AWARE); -} - -static void -gst_test_filter_chain (GstPad * pad, GstData * data) -{ - GstTestFilter *filter = (GstTestElement *) gst_pad_get_parent (pad); - - gst_pad_push (filter->srcpad, data); -} - -static void -gst_test_filter_loop (GstElement * element) -{ - GstTestFilter *filter = (GstTestElement *) element; - - gst_test_filter_chain (filter->sinkpad, gst_pad_pull (filter->sinkpad)); -} - -static void -gst_test_filter_init (GstTestElement * filter) -{ - filter->sinkpad = gst_pad_new ("sink", GST_PAD_SINK); - if (loop) { - gst_element_set_loop_function (GST_ELEMENT (filter), gst_test_filter_loop); - } else { - gst_pad_set_chain_function (filter->sinkpad, gst_test_filter_chain); - } - gst_element_add_pad (GST_ELEMENT (filter), filter->sinkpad); - - filter->srcpad = gst_pad_new ("src", GST_PAD_SRC); - gst_element_add_pad (GST_ELEMENT (filter), filter->srcpad); - - GST_FLAG_SET (filter, GST_ELEMENT_EVENT_AWARE); -} - -static void -gst_test_sink_chain (GstPad * pad, GstData * data) -{ - gst_data_unref (data); -} - -static void -gst_test_sink_loop (GstElement * element) -{ - GstTestSink *sink = (GstTestElement *) element; - - gst_test_sink_chain (sink->sinkpad, gst_pad_pull (sink->sinkpad)); -} - -static void -gst_test_sink_init (GstTestElement * sink) -{ - sink->sinkpad = gst_pad_new ("sink", GST_PAD_SINK); - if (loop) { - gst_element_set_loop_function (GST_ELEMENT (sink), gst_test_sink_loop); - } else { - gst_pad_set_chain_function (sink->sinkpad, gst_test_sink_chain); - } - gst_element_add_pad (GST_ELEMENT (sink), sink->sinkpad); - - GST_FLAG_SET (sink, GST_ELEMENT_EVENT_AWARE); -} - -#define parent_class src_parent_class -GST_BOILERPLATE (GstTestSrc, gst_test_src, GstElement, GST_TYPE_ELEMENT); -#undef parent_class -#define parent_class filter_parent_class -GST_BOILERPLATE (GstTestFilter, gst_test_filter, GstElement, GST_TYPE_ELEMENT); -#undef parent_class -#define parent_class sink_parent_class -GST_BOILERPLATE (GstTestSink, gst_test_sink, GstElement, GST_TYPE_ELEMENT); -#undef parent_class - -/* - * Actual test. - */ - -static void -cb_error (GstElement * element) -{ - g_assert_not_reached (); -} - -int -main (int argc, char *argv[]) -{ - GstElement *pipeline, *src, *filter, *sink; - gint n, r; - gboolean res; - - gst_init (&argc, &argv); - - for (r = 0; r < 2; r++) { - pipeline = gst_pipeline_new ("p"); - g_signal_connect (pipeline, "error", G_CALLBACK (cb_error), NULL); - src = g_object_new (gst_test_src_get_type (), NULL); - gst_object_set_name (GST_OBJECT (src), "src"); - filter = g_object_new (gst_test_filter_get_type (), NULL); - gst_object_set_name (GST_OBJECT (filter), "filter"); - sink = g_object_new (gst_test_sink_get_type (), NULL); - gst_object_set_name (GST_OBJECT (sink), "sink"); - gst_bin_add_many (GST_BIN (pipeline), src, filter, sink, NULL); - res = gst_element_link (src, filter); - g_assert (res); - res = gst_element_link (filter, sink); - g_assert (res); - gst_element_set_state (pipeline, GST_STATE_PLAYING); - - for (n = 0; n < 100; n++) { - if (!gst_bin_iterate (GST_BIN (pipeline))) - g_assert_not_reached (); - } - - gst_element_set_state (pipeline, GST_STATE_NULL); - gst_object_unref (GST_OBJECT (pipeline)); - - /* switch element types */ - g_print ("Loop=%s done\n", loop ? "true" : "false"); - loop = !loop; - } - - return 0; -} diff --git a/testsuite/parse/parse1.c b/testsuite/parse/parse1.c index be4764a944..2919f39e59 100644 --- a/testsuite/parse/parse1.c +++ b/testsuite/parse/parse1.c @@ -91,7 +91,7 @@ static gchar *s; #define PIPELINE3 "fakesrc identity fakesink" #define PIPELINE4 "fakesrc num-buffers=4 .src ! identity !.sink identity .src ! .sink fakesink" #define PIPELINE5 "fakesrc num-buffers=4 name=src identity name=id1 identity name = id2 fakesink name =sink src. ! id1. id1.! id2.sink id2.src!sink.sink" -#define PIPELINE6 "pipeline.(name=\"john\" fakesrc num-buffers=4 ( thread. ( ! queue ! identity !{ queue ! fakesink }) ))" +#define PIPELINE6 "pipeline.(name=\"john\" fakesrc num-buffers=4 ( bin. ( ! queue ! identity !( queue ! fakesink )) ))" #define PIPELINE7 "fakesrc num-buffers=4 ! tee name=tee .src%d! fakesink tee.src%d ! fakesink fakesink name =\"foo\" tee.src%d ! foo." /* aggregator is borked #define PIPELINE8 "fakesrc num-buffers=4 ! tee name=tee1 .src0,src1 ! .sink0, sink1 aggregator ! fakesink" diff --git a/testsuite/schedulers/142183-2.c b/testsuite/schedulers/142183-2.c index c472974654..802d79bab1 100644 --- a/testsuite/schedulers/142183-2.c +++ b/testsuite/schedulers/142183-2.c @@ -43,11 +43,11 @@ main (gint argc, gchar ** argv) g_assert (pipeline); src = gst_element_factory_make ("fakesrc", NULL); g_assert (src); + g_object_set (src, "num-buffers", 10, NULL); id = gst_element_factory_make ("identity", NULL); g_assert (id); g_signal_connect (G_OBJECT (id), "handoff", (GCallback) handoff_identity, NULL); - g_object_set (G_OBJECT (id), "loop-based", TRUE, NULL); sink = gst_element_factory_make ("fakesink", NULL); g_assert (sink); @@ -59,7 +59,6 @@ main (gint argc, gchar ** argv) if (gst_element_set_state (pipeline, GST_STATE_PLAYING) != GST_STATE_SUCCESS) g_assert_not_reached (); - gst_bin_iterate (GST_BIN (pipeline)); gst_bin_iterate (GST_BIN (pipeline)); g_print ("got past iteration, scheduler refs elements correctly\n"); diff --git a/testsuite/schedulers/142183.c b/testsuite/schedulers/142183.c deleted file mode 100644 index 8f56faf9a0..0000000000 --- a/testsuite/schedulers/142183.c +++ /dev/null @@ -1,94 +0,0 @@ -/* GStreamer - * Copyright (C) 2004 Wim Taymans - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU 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 - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this library; if not, write to the Free - * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include - -#include - -static void -handoff_identity (GstElement * element) -{ - GstBin *parent; - - parent = GST_BIN (gst_element_get_parent (element)); - g_print ("identity handoff\n"); - gst_bin_remove (parent, element); -} - -gint -main (gint argc, gchar ** argv) -{ - GstElement *pipeline, *src, *sink, *id; - - gst_init (&argc, &argv); - - g_print ("setting up...\n"); - /* setup pipeline */ - pipeline = gst_element_factory_make ("pipeline", NULL); - g_assert (pipeline); - src = gst_element_factory_make ("fakesrc", NULL); - g_assert (src); - id = gst_element_factory_make ("identity", NULL); - g_assert (id); - /* ref object here as it will be unparented and destroyed in the - * handoff signal, normally the scheduler should keep a ref to the - * currently scheduled elements but that's another bug displayed in - * 142183-2.c */ - gst_object_ref (GST_OBJECT (id)); - g_signal_connect (G_OBJECT (id), "handoff", (GCallback) handoff_identity, - NULL); - g_object_set (G_OBJECT (id), "loop-based", TRUE, NULL); - - sink = gst_element_factory_make ("fakesink", NULL); - g_assert (sink); - - gst_bin_add_many (GST_BIN (pipeline), src, id, sink, NULL); - /* this is what triggers the bug */ - gst_element_enable_threadsafe_properties (GST_ELEMENT (src)); - gst_element_enable_threadsafe_properties (GST_ELEMENT (id)); - gst_element_enable_threadsafe_properties (GST_ELEMENT (sink)); - - gst_element_link_pads (src, "src", id, "sink"); - gst_element_link_pads (id, "src", sink, "sink"); - - if (gst_element_set_state (pipeline, GST_STATE_PLAYING) != GST_STATE_SUCCESS) - g_assert_not_reached (); - - gst_bin_iterate (GST_BIN (pipeline)); - gst_bin_iterate (GST_BIN (pipeline)); - - /* 'cause we're going into deadlock mode */ - alarm (5); - - g_print ("adding identity back...\n"); - /* add identity back in */ - gst_bin_add_many (GST_BIN (pipeline), id, NULL); - - g_print ("going into possible deadlock... alarm at 5 seconds\n"); - gst_bin_iterate (GST_BIN (pipeline)); - gst_bin_iterate (GST_BIN (pipeline)); - g_print ("ok, no deadlock. bug 142183 fixed!\n"); - - g_print ("cleaning up...\n"); - gst_object_unref (GST_OBJECT (pipeline)); - gst_object_unref (GST_OBJECT (id)); - src = id = sink = pipeline = NULL; - - g_print ("done.\n"); - return 0; -} diff --git a/testsuite/schedulers/143777-2.c b/testsuite/schedulers/143777-2.c index 399bff2039..f45f37bbd1 100644 --- a/testsuite/schedulers/143777-2.c +++ b/testsuite/schedulers/143777-2.c @@ -6,14 +6,13 @@ main (int argc, char **argv) { GstElement *src, *sink, *enc, *tee; GstElement *pipeline; - int i; - gst_init (&argc, &argv); pipeline = gst_element_factory_make ("pipeline", "pipeline"); src = gst_element_factory_make ("fakesrc", "src"); g_assert (src); + g_object_set (src, "num-buffers", 10, NULL); tee = gst_element_factory_make ("tee", "tee1"); g_assert (tee); enc = gst_element_factory_make ("identity", "enc"); @@ -27,11 +26,7 @@ main (int argc, char **argv) if (gst_element_set_state (pipeline, GST_STATE_PLAYING) != GST_STATE_SUCCESS) g_assert_not_reached (); - for (i = 0; i < 5; i++) { - if (!gst_bin_iterate (GST_BIN (pipeline))) - g_assert_not_reached (); - g_print ("%d\n", i); - } + gst_bin_iterate (GST_BIN (pipeline)); if (gst_element_set_state (pipeline, GST_STATE_PAUSED) != GST_STATE_SUCCESS) g_assert_not_reached (); @@ -48,11 +43,7 @@ main (int argc, char **argv) if (gst_element_set_state (pipeline, GST_STATE_PLAYING) != GST_STATE_SUCCESS) g_assert_not_reached (); - for (i = 5; i < 10; i++) { - if (!gst_bin_iterate (GST_BIN (pipeline))) - g_assert_not_reached (); - g_print ("%d\n", i); - } + gst_bin_iterate (GST_BIN (pipeline)); g_print ("cleaning up...\n"); gst_object_unref (GST_OBJECT (pipeline)); diff --git a/testsuite/schedulers/143777.c b/testsuite/schedulers/143777.c index 9c33d6ba7c..54a2c8c9b5 100644 --- a/testsuite/schedulers/143777.c +++ b/testsuite/schedulers/143777.c @@ -32,7 +32,7 @@ gint main (gint argc, gchar ** argv) { GstElement *pipeline, *src, *sink, *id; - guint i = 0, j; + guint i = 0; gst_init (&argc, &argv); @@ -42,20 +42,20 @@ main (gint argc, gchar ** argv) g_assert (pipeline); src = gst_element_factory_make ("fakesrc", NULL); g_assert (src); + g_object_set (src, "num-buffers", 10, NULL); id = gst_element_factory_make ("identity", NULL); g_assert (id); sink = gst_element_factory_make ("fakesink", NULL); g_assert (sink); gst_bin_add_many (GST_BIN (pipeline), src, id, sink, NULL); - while (i < 100) { + while (i < 10) { g_print ("running... (%d iterations)\n", i); if (gst_element_set_state (pipeline, GST_STATE_PLAYING) != GST_STATE_SUCCESS) g_assert_not_reached (); gst_element_link_many (src, id, sink, NULL); - for (j = 0; j < i; j++) - gst_bin_iterate (GST_BIN (pipeline)); + gst_bin_iterate (GST_BIN (pipeline)); if (gst_element_set_state (pipeline, GST_STATE_PAUSED) != GST_STATE_SUCCESS) g_assert_not_reached (); gst_element_unlink_many (src, id, sink, NULL); @@ -63,7 +63,7 @@ main (gint argc, gchar ** argv) } g_print ("cleaning up...\n"); - g_assert (i == 100); + g_assert (i == 10); gst_object_unref (GST_OBJECT (pipeline)); src = id = sink = pipeline = NULL; diff --git a/testsuite/schedulers/147713.c b/testsuite/schedulers/147713.c deleted file mode 100644 index 0a2dc07dfa..0000000000 --- a/testsuite/schedulers/147713.c +++ /dev/null @@ -1,89 +0,0 @@ -/* GStreamer - * Copyright (C) 2004 Wim Taymanse - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU 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 - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this library; if not, write to the Free - * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include - -static gint src_handoff = 0; - -static void -handoff_src (GstElement * element) -{ - g_print ("src handoff\n"); - src_handoff++; -} - -static void -handoff_sink (GstElement * element) -{ - g_print ("sink handoff\n"); - g_assert (src_handoff == 1); -} - -gint -main (gint argc, gchar ** argv) -{ - GstElement *pipeline, *src, *sink, *id1, *id2; - - gst_init (&argc, &argv); - - g_print ("setting up...\n"); - /* setup pipeline */ - pipeline = gst_element_factory_make ("pipeline", NULL); - g_assert (pipeline); - src = gst_element_factory_make ("fakesrc", NULL); - g_assert (src); - g_object_set (G_OBJECT (src), "signal-handoffs", TRUE, NULL); - g_signal_connect (G_OBJECT (src), "handoff", (GCallback) handoff_src, NULL); - id1 = gst_element_factory_make ("identity", NULL); - g_assert (id1); - - id2 = gst_element_factory_make ("identity", NULL); - g_assert (id2); - g_object_set (G_OBJECT (id2), "loop-based", TRUE, NULL); - - sink = gst_element_factory_make ("fakesink", NULL); - g_assert (sink); - g_object_set (G_OBJECT (sink), "signal-handoffs", TRUE, NULL); - g_signal_connect (G_OBJECT (sink), "handoff", (GCallback) handoff_sink, NULL); - - gst_bin_add_many (GST_BIN (pipeline), src, id1, NULL); - gst_element_link_pads (src, "src", id1, "sink"); - - if (gst_element_set_state (pipeline, GST_STATE_PLAYING) != GST_STATE_SUCCESS) - g_assert_not_reached (); - - if (gst_element_set_state (id2, GST_STATE_PLAYING) != GST_STATE_SUCCESS) - g_assert_not_reached (); - if (gst_element_set_state (sink, GST_STATE_PLAYING) != GST_STATE_SUCCESS) - g_assert_not_reached (); - - gst_bin_add_many (GST_BIN (pipeline), sink, NULL); - gst_element_link_pads (id2, "src", sink, "sink"); - gst_element_link_pads (id1, "src", id2, "sink"); - gst_bin_add_many (GST_BIN (pipeline), id2, NULL); - - gst_bin_iterate (GST_BIN (pipeline)); - gst_bin_iterate (GST_BIN (pipeline)); - - g_print ("cleaning up...\n"); - gst_object_unref (GST_OBJECT (pipeline)); - src = id1 = id2 = sink = pipeline = NULL; - - g_print ("done.\n"); - return 0; -} diff --git a/testsuite/schedulers/147819.c b/testsuite/schedulers/147819.c index d8b30b337b..eb08ae20ba 100644 --- a/testsuite/schedulers/147819.c +++ b/testsuite/schedulers/147819.c @@ -20,20 +20,16 @@ #include -static gboolean handoff; - static void handoff_identity1 (GstElement * element) { g_print ("identity1 handoff\n"); - handoff = TRUE; } static void handoff_identity2 (GstElement * element) { g_print ("identity2 handoff\n"); - handoff = TRUE; } gint @@ -49,16 +45,15 @@ main (gint argc, gchar ** argv) g_assert (pipeline); src = gst_element_factory_make ("fakesrc", NULL); g_assert (src); + g_object_set (G_OBJECT (src), "num-buffers", 10, NULL); id1 = gst_element_factory_make ("identity", NULL); g_assert (id1); - g_object_set (G_OBJECT (id1), "loop-based", TRUE, NULL); g_object_set (G_OBJECT (id1), "duplicate", 3, NULL); g_signal_connect (G_OBJECT (id1), "handoff", (GCallback) handoff_identity1, NULL); id2 = gst_element_factory_make ("identity", NULL); g_assert (id2); - g_object_set (G_OBJECT (id2), "loop-based", TRUE, NULL); g_signal_connect (G_OBJECT (id2), "handoff", (GCallback) handoff_identity2, NULL); @@ -76,20 +71,6 @@ main (gint argc, gchar ** argv) g_print ("running...\n"); gst_bin_iterate (GST_BIN (pipeline)); - gst_bin_iterate (GST_BIN (pipeline)); - gst_bin_iterate (GST_BIN (pipeline)); - - /* do ugly stuff here */ - gst_object_ref (GST_OBJECT (id1)); - gst_bin_remove (GST_BIN (pipeline), id1); - gst_element_link_pads (src, "src", id1, "sink"); - gst_element_link_pads (id1, "src", id2, "sink"); - - gst_bin_iterate (GST_BIN (pipeline)); - gst_bin_iterate (GST_BIN (pipeline)); - gst_bin_iterate (GST_BIN (pipeline)); - gst_bin_iterate (GST_BIN (pipeline)); - gst_bin_iterate (GST_BIN (pipeline)); g_print ("cleaning up...\n"); gst_object_unref (GST_OBJECT (pipeline)); diff --git a/testsuite/schedulers/147894-2.c b/testsuite/schedulers/147894-2.c deleted file mode 100644 index 4eab00b057..0000000000 --- a/testsuite/schedulers/147894-2.c +++ /dev/null @@ -1,136 +0,0 @@ -/* GStreamer - * Copyright (C) 2004 Wim Taymans - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU 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 - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this library; if not, write to the Free - * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include - -#include - -static gboolean empty; -static gboolean bug; -static gboolean handoff; -static GstElement *pipeline2; - -static void -queue_empty (GstElement * element) -{ - g_print ("queue empty\n"); - if (!handoff) - bug = TRUE; -} - -static void -queue_filled (GstElement * element) -{ - g_print ("queue filled\n"); - empty = FALSE; - - /* read from the other end */ - handoff = FALSE; - bug = FALSE; - - alarm (5); - - g_print ("emptying queue with 5 second timeout...\n"); - while (!bug && !handoff) { - gst_bin_iterate (GST_BIN (pipeline2)); - } -} - -static void -handoff_identity (GstElement * element) -{ - g_print ("identity handoff\n"); - handoff = TRUE; -} - -gint -main (gint argc, gchar ** argv) -{ - GstElement *pipeline, *src, *sink, *queue, *id; - - gst_init (&argc, &argv); - - g_print ("setting up...\n"); - /* setup pipeline */ - pipeline = gst_element_factory_make ("pipeline", NULL); - g_assert (pipeline); - src = gst_element_factory_make ("fakesrc", NULL); - g_assert (src); - queue = gst_element_factory_make ("queue", NULL); - g_assert (queue); - g_signal_connect (G_OBJECT (queue), "overrun", (GCallback) queue_filled, - NULL); - g_signal_connect (G_OBJECT (queue), "underrun", (GCallback) queue_empty, - NULL); - gst_bin_add_many (GST_BIN (pipeline), src, queue, NULL); - - gst_element_link_pads (src, "src", queue, "sink"); - - /* second pipeline for sinks */ - pipeline2 = gst_element_factory_make ("pipeline", NULL); - g_assert (pipeline2); - id = gst_element_factory_make ("identity", NULL); - g_assert (id); - g_signal_connect (G_OBJECT (id), "handoff", (GCallback) handoff_identity, - NULL); - - sink = gst_element_factory_make ("fakesink", NULL); - g_assert (sink); - gst_bin_add_many (GST_BIN (pipeline2), id, sink, NULL); - - gst_element_link_pads (queue, "src", id, "sink"); - gst_element_link_pads (id, "src", sink, "sink"); - - if (gst_element_set_state (pipeline, GST_STATE_PLAYING) != GST_STATE_SUCCESS) - g_assert_not_reached (); - - if (gst_element_set_state (pipeline2, GST_STATE_PLAYING) != GST_STATE_SUCCESS) - g_assert_not_reached (); - - g_print ("running...\n"); - /* fill queue */ - empty = TRUE; - while (empty) { - gst_bin_iterate (GST_BIN (pipeline)); - } - g_assert (!bug); - - g_print ("relinking...\n"); - /* now unlink and link id and sink */ - gst_element_unlink_pads (id, "src", sink, "sink"); - gst_element_link_pads (id, "src", sink, "sink"); - - g_print ("running again...\n"); - /* fill queue */ - empty = TRUE; - while (empty) { - gst_bin_iterate (GST_BIN (pipeline)); - } - g_assert (!bug); - - /* trigger the bug */ - - - g_print ("cleaning up...\n"); - gst_object_unref (GST_OBJECT (pipeline)); - gst_object_unref (GST_OBJECT (pipeline2)); - src = id = sink = pipeline = pipeline2 = NULL; - - g_print ("done.\n"); - return 0; -} diff --git a/testsuite/schedulers/147894.c b/testsuite/schedulers/147894.c deleted file mode 100644 index e89bf2ac2f..0000000000 --- a/testsuite/schedulers/147894.c +++ /dev/null @@ -1,142 +0,0 @@ -/* GStreamer - * Copyright (C) 2004 Wim Taymans - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU 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 - * General Public License for more details. - * - * You should have received a copy of the GNU General Public - * License along with this library; if not, write to the Free - * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include - -#include - -static gboolean empty; -static gboolean bug; -static gboolean handoff; -static GstElement *pipeline2; - -static void -queue_empty (GstElement * element) -{ - g_print ("queue empty\n"); - if (!handoff) - bug = TRUE; -} - -static void -queue_filled (GstElement * element) -{ - g_print ("queue filled\n"); - empty = FALSE; - - /* read from the other end */ - handoff = FALSE; - bug = FALSE; - - alarm (5); - - g_print ("emptying queue with 5 second timeout...\n"); - while (!bug && !handoff) { - gst_bin_iterate (GST_BIN (pipeline2)); - } -} - -static void -handoff_identity (GstElement * element) -{ - g_print ("identity handoff\n"); - handoff = TRUE; -} - -gint -main (gint argc, gchar ** argv) -{ - GstElement *pipeline, *src, *sink, *queue, *id; - - gst_init (&argc, &argv); - - g_print ("setting up...\n"); - /* setup pipeline */ - pipeline = gst_element_factory_make ("pipeline", NULL); - g_assert (pipeline); - src = gst_element_factory_make ("fakesrc", NULL); - g_assert (src); - queue = gst_element_factory_make ("queue", NULL); - g_assert (queue); - g_signal_connect (G_OBJECT (queue), "overrun", (GCallback) queue_filled, - NULL); - g_signal_connect (G_OBJECT (queue), "underrun", (GCallback) queue_empty, - NULL); - gst_bin_add_many (GST_BIN (pipeline), src, queue, NULL); - - gst_element_link_pads (src, "src", queue, "sink"); - - /* second pipeline for sinks */ - pipeline2 = gst_element_factory_make ("pipeline", NULL); - g_assert (pipeline2); - id = gst_element_factory_make ("identity", NULL); - g_assert (id); - g_signal_connect (G_OBJECT (id), "handoff", (GCallback) handoff_identity, - NULL); - - sink = gst_element_factory_make ("fakesink", NULL); - g_assert (sink); - gst_bin_add_many (GST_BIN (pipeline2), id, sink, NULL); - - gst_element_link_pads (queue, "src", id, "sink"); - gst_element_link_pads (id, "src", sink, "sink"); - - if (gst_element_set_state (pipeline, GST_STATE_PLAYING) != GST_STATE_SUCCESS) - g_assert_not_reached (); - - if (gst_element_set_state (pipeline2, GST_STATE_PLAYING) != GST_STATE_SUCCESS) - g_assert_not_reached (); - - g_print ("running...\n"); - /* fill queue */ - empty = TRUE; - while (empty) { - gst_bin_iterate (GST_BIN (pipeline)); - } - g_assert (!bug); - - if (gst_element_set_state (pipeline2, GST_STATE_READY) != GST_STATE_SUCCESS) - g_assert_not_reached (); - - g_print ("relinking...\n"); - /* now unlink and link id and sink */ - gst_element_unlink_pads (id, "src", sink, "sink"); - gst_element_link_pads (id, "src", sink, "sink"); - - if (gst_element_set_state (pipeline2, GST_STATE_PLAYING) != GST_STATE_SUCCESS) - g_assert_not_reached (); - - g_print ("running again...\n"); - /* fill queue */ - empty = TRUE; - while (empty) { - gst_bin_iterate (GST_BIN (pipeline)); - } - g_assert (!bug); - - /* trigger the bug */ - - - g_print ("cleaning up...\n"); - gst_object_unref (GST_OBJECT (pipeline)); - gst_object_unref (GST_OBJECT (pipeline2)); - src = id = sink = pipeline = pipeline2 = NULL; - - g_print ("done.\n"); - return 0; -} diff --git a/testsuite/schedulers/Makefile.am b/testsuite/schedulers/Makefile.am index 391ac40476..8ccc80ded2 100644 --- a/testsuite/schedulers/Makefile.am +++ b/testsuite/schedulers/Makefile.am @@ -4,15 +4,13 @@ tests_pass = \ unlink_src unlink_sink \ relink_src relink_sink \ unref_src unref_sink \ - 142183 142183-2 \ + 142183-2 \ 143777 143777-2 \ - 147713 \ 147819 \ - 147894 147894-2 group_link \ - queue_link + group_link \ + queue_link \ + useless_iteration -# don't enable this one unless it actually works. -# useless_iteration tests_fail = tests_ignore = diff --git a/testsuite/schedulers/group_link.c b/testsuite/schedulers/group_link.c index e40c84d1ba..82a9d9ee25 100644 --- a/testsuite/schedulers/group_link.c +++ b/testsuite/schedulers/group_link.c @@ -33,11 +33,11 @@ main (gint argc, gchar ** argv) g_assert (pipeline); src = gst_element_factory_make ("fakesrc", NULL); g_assert (src); + g_object_set (G_OBJECT (src), "num-buffers", 10, NULL); id1 = gst_element_factory_make ("identity", NULL); g_assert (id1); id2 = gst_element_factory_make ("identity", NULL); g_assert (id2); - g_object_set (G_OBJECT (id2), "loop-based", TRUE, NULL); sink = gst_element_factory_make ("fakesink", NULL); g_assert (sink); diff --git a/testsuite/schedulers/queue_link.c b/testsuite/schedulers/queue_link.c index f14d7b53e8..f4b62091fb 100644 --- a/testsuite/schedulers/queue_link.c +++ b/testsuite/schedulers/queue_link.c @@ -33,10 +33,11 @@ main (gint argc, gchar ** argv) g_assert (pipeline); src = gst_element_factory_make ("fakesrc", NULL); g_assert (src); + g_object_set (src, "num-buffers", 10, NULL); queue = gst_element_factory_make ("queue", NULL); g_assert (queue); - thread = gst_element_factory_make ("thread", NULL); + thread = gst_element_factory_make ("bin", NULL); g_assert (thread); bin = gst_element_factory_make ("bin", NULL); g_assert (bin); diff --git a/testsuite/schedulers/relink.c b/testsuite/schedulers/relink.c index a76daf0df1..a0499b536b 100644 --- a/testsuite/schedulers/relink.c +++ b/testsuite/schedulers/relink.c @@ -30,6 +30,9 @@ cb_handoff (GstElement * element, GstBuffer * buffer, GstPad * pad, gst_bin_remove (GST_BIN (pipeline), OTHER_ELEMENT); OTHER_ELEMENT = gst_element_factory_make ("fake" G_STRINGIFY (OTHER_ELEMENT), NULL); + if (g_str_equal (G_OBJECT_CLASS_NAME (G_OBJECT_GET_CLASS (OTHER_ELEMENT)), + "GstFakeSrc")) + g_object_set (OTHER_ELEMENT, "num-buffers", 10, NULL); g_assert (OTHER_ELEMENT); gst_bin_add (GST_BIN (pipeline), OTHER_ELEMENT); gst_element_sync_state_with_parent (OTHER_ELEMENT); @@ -40,8 +43,6 @@ cb_handoff (GstElement * element, GstBuffer * buffer, GstPad * pad, gint main (gint argc, gchar ** argv) { - guint i = 0; - gst_init (&argc, &argv); g_print ("setting up...\n"); @@ -50,6 +51,7 @@ main (gint argc, gchar ** argv) g_assert (pipeline); src = gst_element_factory_make ("fakesrc", NULL); g_assert (src); + g_object_set (src, "num-buffers", 10, NULL); sink = gst_element_factory_make ("fakesink", NULL); g_assert (sink); gst_bin_add_many (GST_BIN (pipeline), src, sink, NULL); @@ -62,7 +64,7 @@ main (gint argc, gchar ** argv) g_print ("running...\n"); if (gst_element_set_state (pipeline, GST_STATE_PLAYING) != GST_STATE_SUCCESS) g_assert_not_reached (); - while (i++ < 10 && gst_bin_iterate (GST_BIN (pipeline))); + gst_bin_iterate (GST_BIN (pipeline)); g_print ("cleaning up...\n"); gst_object_unref (GST_OBJECT (pipeline)); diff --git a/testsuite/schedulers/unlink.c b/testsuite/schedulers/unlink.c index 11ae3e5c12..784e9d56c0 100644 --- a/testsuite/schedulers/unlink.c +++ b/testsuite/schedulers/unlink.c @@ -41,6 +41,7 @@ main (gint argc, gchar ** argv) g_assert (pipeline); src = gst_element_factory_make ("fakesrc", NULL); g_assert (src); + g_object_set (src, "num-buffers", 10, NULL); sink = gst_element_factory_make ("fakesink", NULL); g_assert (sink); gst_bin_add_many (GST_BIN (pipeline), src, sink, NULL); @@ -53,7 +54,7 @@ main (gint argc, gchar ** argv) g_print ("running...\n"); if (gst_element_set_state (pipeline, GST_STATE_PLAYING) != GST_STATE_SUCCESS) g_assert_not_reached (); - while (gst_bin_iterate (GST_BIN (pipeline))); + gst_bin_iterate (GST_BIN (pipeline)); g_print ("cleaning up...\n"); gst_object_unref (GST_OBJECT (pipeline)); diff --git a/testsuite/schedulers/unref.c b/testsuite/schedulers/unref.c index 543620a7ac..fe55332711 100644 --- a/testsuite/schedulers/unref.c +++ b/testsuite/schedulers/unref.c @@ -19,6 +19,7 @@ #include GstElement *pipeline, *src, *sink; +GMainLoop *loop; static void cb_handoff (GstElement * element, GstBuffer * buffer, GstPad * pad, @@ -28,6 +29,7 @@ cb_handoff (GstElement * element, GstBuffer * buffer, GstPad * pad, g_print ("unreffing...\n"); gst_object_unref (GST_OBJECT (pipeline)); pipeline = NULL; + g_main_loop_quit (loop); } } @@ -42,6 +44,7 @@ main (gint argc, gchar ** argv) g_assert (pipeline); src = gst_element_factory_make ("fakesrc", NULL); g_assert (src); + g_object_set (src, "num-buffers", 10, NULL); sink = gst_element_factory_make ("fakesink", NULL); g_assert (sink); gst_bin_add_many (GST_BIN (pipeline), src, sink, NULL); @@ -54,7 +57,9 @@ main (gint argc, gchar ** argv) g_print ("running...\n"); if (gst_element_set_state (pipeline, GST_STATE_PLAYING) != GST_STATE_SUCCESS) g_assert_not_reached (); - while (pipeline && gst_bin_iterate (GST_BIN (pipeline))); + loop = g_main_loop_new (NULL, TRUE); + g_main_loop_run (loop); + g_main_loop_unref (loop); g_print ("done.\n"); return 0; diff --git a/testsuite/schedulers/useless_iteration.c b/testsuite/schedulers/useless_iteration.c index d064c648c6..1afef15647 100644 --- a/testsuite/schedulers/useless_iteration.c +++ b/testsuite/schedulers/useless_iteration.c @@ -23,13 +23,14 @@ main (gint argc, gchar ** argv) { GstElement *pipeline; GError *error = NULL; - guint i = 0; gst_init (&argc, &argv); g_print ("setting up...\n"); /* setup pipeline */ - pipeline = gst_parse_launch ("pipeline.( { fakesrc ! fakesink } )", &error); + pipeline = + gst_parse_launch + ("pipeline.( pipeline.( fakesrc num-buffers=1000 ! fakesink ) )", &error); g_assert (error == NULL); g_assert (pipeline); @@ -37,11 +38,9 @@ main (gint argc, gchar ** argv) g_print ("running...\n"); if (gst_element_set_state (pipeline, GST_STATE_PLAYING) != GST_STATE_SUCCESS) g_assert_not_reached (); - while (i < 100 && gst_bin_iterate (GST_BIN (pipeline))) - i++; + gst_bin_iterate (GST_BIN (pipeline)); - g_print ("cleaning up... (%d iterations)\n", i); - g_assert (i == 100); + g_print ("cleaning up...\n"); gst_object_unref (GST_OBJECT (pipeline)); pipeline = NULL; diff --git a/tools/Makefile.am b/tools/Makefile.am index f4f09573cb..633329d37f 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -11,26 +11,22 @@ if GST_DISABLE_LOADSAVE GST_LOADSAVE_SRC = GST_LOADSAVE_SRC_V = else -GST_LOADSAVE_SRC = gst-complete gst-compprep gst-xmllaunch +GST_LOADSAVE_SRC = gst-complete gst-compprep GST_LOADSAVE_SRC_V = \ gst-complete-@GST_MAJORMINOR@ \ - gst-compprep-@GST_MAJORMINOR@ \ - gst-xmllaunch-@GST_MAJORMINOR@ + gst-compprep-@GST_MAJORMINOR@ endif GST_OTHER_SRC = \ gst-feedback \ gst-inspect \ gst-launch \ - gst-md5sum \ - gst-typefind \ - gst-xmlinspect + gst-typefind + GST_OTHER_SRC_V = \ gst-inspect-@GST_MAJORMINOR@ \ gst-launch-@GST_MAJORMINOR@ \ - gst-md5sum-@GST_MAJORMINOR@ \ - gst-typefind-@GST_MAJORMINOR@ \ - gst-xmlinspect-@GST_MAJORMINOR@ + gst-typefind-@GST_MAJORMINOR@ ### so all of the programs we want to build bin_PROGRAMS = \ @@ -52,9 +48,6 @@ gst_complete_@GST_MAJORMINOR@_LDFLAGS = $(GST_OBJ_LIBS) gst_compprep_@GST_MAJORMINOR@_SOURCES = gst-compprep.c gst_compprep_@GST_MAJORMINOR@_CFLAGS = $(GST_OBJ_CFLAGS) gst_compprep_@GST_MAJORMINOR@_LDFLAGS = $(GST_OBJ_LIBS) -gst_xmllaunch_@GST_MAJORMINOR@_SOURCES = gst-launch.c -gst_xmllaunch_@GST_MAJORMINOR@_CFLAGS = $(GST_OBJ_CFLAGS) -gst_xmllaunch_@GST_MAJORMINOR@_LDFLAGS = $(GST_OBJ_LIBS) endif gst_inspect_@GST_MAJORMINOR@_SOURCES = gst-inspect.c gst_inspect_@GST_MAJORMINOR@_CFLAGS = $(GST_OBJ_CFLAGS) @@ -62,15 +55,9 @@ gst_inspect_@GST_MAJORMINOR@_LDFLAGS = $(GST_OBJ_LIBS) gst_launch_@GST_MAJORMINOR@_SOURCES = gst-launch.c gst_launch_@GST_MAJORMINOR@_CFLAGS = $(GST_OBJ_CFLAGS) gst_launch_@GST_MAJORMINOR@_LDFLAGS = $(GST_OBJ_LIBS) -gst_md5sum_@GST_MAJORMINOR@_SOURCES = gst-md5sum.c -gst_md5sum_@GST_MAJORMINOR@_CFLAGS = $(GST_OBJ_CFLAGS) -gst_md5sum_@GST_MAJORMINOR@_LDFLAGS = $(GST_OBJ_LIBS) gst_typefind_@GST_MAJORMINOR@_SOURCES = gst-typefind.c gst_typefind_@GST_MAJORMINOR@_CFLAGS = $(GST_OBJ_CFLAGS) gst_typefind_@GST_MAJORMINOR@_LDFLAGS = $(GST_OBJ_LIBS) -gst_xmlinspect_@GST_MAJORMINOR@_SOURCES = gst-xmlinspect.c -gst_xmlinspect_@GST_MAJORMINOR@_CFLAGS = $(GST_OBJ_CFLAGS) -gst_xmlinspect_@GST_MAJORMINOR@_LDFLAGS = $(GST_OBJ_LIBS) gst-feedback-@GST_MAJORMINOR@: gst-feedback-m.m cp $(srcdir)/gst-feedback-m.m $@ @@ -83,18 +70,14 @@ endif if !GST_DISABLE_LOADSAVE gst_complete_SOURCES = gst-run.c gst_compprep_SOURCES = gst-run.c -gst_xmllaunch_SOURCES = gst-run.c endif gst_feedback_SOURCES = gst-run.c gst_inspect_SOURCES = gst-run.c gst_launch_SOURCES = gst-run.c -gst_md5sum_SOURCES = gst-run.c gst_typefind_SOURCES = gst-run.c -gst_xmlinspect_SOURCES = gst-run.c gst_inspect_@GST_MAJORMINOR@_LDADD = ../libs/gst/control/libgstcontrol-@GST_MAJORMINOR@.la -gst_xmlinspect_@GST_MAJORMINOR@_LDADD = ../libs/gst/control/libgstcontrol-@GST_MAJORMINOR@.la # CFLAGS and libs for nonversioned frontend binaries AM_CFLAGS = $(GLIB_ONLY_CFLAGS) $(POPT_CFLAGS) @@ -114,17 +97,14 @@ GST_LOADSAVE_MAN= else GST_LOADSAVE_MAN = \ gst-complete-@GST_MAJORMINOR@.1 \ - gst-compprep-@GST_MAJORMINOR@.1 \ - gst-xmllaunch-@GST_MAJORMINOR@.1 + gst-compprep-@GST_MAJORMINOR@.1 endif GST_OTHER_MAN = \ gst-feedback-@GST_MAJORMINOR@.1 \ gst-inspect-@GST_MAJORMINOR@.1 \ gst-launch-@GST_MAJORMINOR@.1 \ - gst-md5sum-@GST_MAJORMINOR@.1 \ - gst-typefind-@GST_MAJORMINOR@.1 \ - gst-xmlinspect-@GST_MAJORMINOR@.1 + gst-typefind-@GST_MAJORMINOR@.1 manpages = $(GST_REGISTRY_MAN) $(GST_LOADSAVE_MAN) $(GST_OTHER_MAN) @@ -141,11 +121,8 @@ EXTRA_DIST = \ gst-feedback.1.in \ gst-inspect.1.in \ gst-launch.1.in \ - gst-md5sum.1.in \ gst-register.1.in \ gst-typefind.1.in \ - gst-xmlinspect.1.in \ - gst-xmllaunch.1.in \ gst-feedback-m.m %-@GST_MAJORMINOR@.1: %.1.in @@ -155,10 +132,7 @@ EXTRA_DIST = \ -e s,gst-feedback,gst-feedback-@GST_MAJORMINOR@,g \ -e s,gst-inspect,gst-inspect-@GST_MAJORMINOR@,g \ -e s,gst-launch,gst-launch-@GST_MAJORMINOR@,g \ - -e s,gst-md5sum,gst-md5sum-@GST_MAJORMINOR@,g \ -e s,gst-register,gst-register-@GST_MAJORMINOR@,g \ -e s,gst-typefind,gst-typefind-@GST_MAJORMINOR@,g \ - -e s,gst-xmlinspect,gst-xmlinspect-@GST_MAJORMINOR@,g \ - -e s,gst-xmllaunch,gst-xmllaunch-@GST_MAJORMINOR@,g \ $< >$@ diff --git a/tools/gst-inspect.c b/tools/gst-inspect.c index bc6ef3ee86..0880303c27 100644 --- a/tools/gst-inspect.c +++ b/tools/gst-inspect.c @@ -87,95 +87,6 @@ print_caps (const GstCaps * caps, const gchar * pfx) } } -static void -print_formats (const GstFormat * formats) -{ - while (formats && *formats) { - const GstFormatDefinition *definition; - - definition = gst_format_get_details (*formats); - if (definition) - n_print ("\t\t(%d):\t%s (%s)\n", *formats, - definition->nick, definition->description); - else - n_print ("\t\t(%d):\tUnknown format\n", *formats); - - formats++; - } -} - -static void -print_query_types (const GstQueryType * types) -{ - while (types && *types) { - const GstQueryTypeDefinition *definition; - - definition = gst_query_type_get_details (*types); - if (definition) - n_print ("\t\t(%d):\t%s (%s)\n", *types, - definition->nick, definition->description); - else - n_print ("\t\t(%d):\tUnknown query format\n", *types); - - types++; - } -} - -#ifndef GST_DISABLE_ENUMTYPES -static void -print_event_masks (const GstEventMask * masks) -{ - GType event_type; - GEnumClass *klass; - GType event_flags; - GFlagsClass *flags_class = NULL; - - event_type = gst_event_type_get_type (); - klass = (GEnumClass *) g_type_class_ref (event_type); - - while (masks && masks->type) { - GEnumValue *value; - gint flags = 0, index = 0; - - switch (masks->type) { - case GST_EVENT_SEEK: - flags = masks->flags; - event_flags = gst_seek_type_get_type (); - flags_class = (GFlagsClass *) g_type_class_ref (event_flags); - break; - default: - break; - } - - value = g_enum_get_value (klass, masks->type); - g_print ("\t\t%s ", value->value_nick); - - while (flags) { - GFlagsValue *value; - - if (flags & 1) { - value = g_flags_get_first_value (flags_class, 1 << index); - - if (value) - g_print ("| %s ", value->value_nick); - else - g_print ("| ? "); - } - flags >>= 1; - index++; - } - g_print ("\n"); - - masks++; - } -} -#else -static void -print_event_masks (const GstEventMask * masks) -{ -} -#endif - static char * get_rank_name (gint rank) { @@ -525,16 +436,8 @@ print_element_flag_info (GstElement * element) n_print ("\n"); n_print ("Element Flags:\n"); - if (GST_FLAG_IS_SET (element, GST_ELEMENT_COMPLEX)) { - n_print (" GST_ELEMENT_COMPLEX\n"); - have_flags = TRUE; - } - if (GST_FLAG_IS_SET (element, GST_ELEMENT_DECOUPLED)) { - n_print (" GST_ELEMENT_DECOUPLED\n"); - have_flags = TRUE; - } - if (GST_FLAG_IS_SET (element, GST_ELEMENT_THREAD_SUGGESTED)) { - n_print (" GST_ELEMENT_THREADSUGGESTED\n"); + if (GST_FLAG_IS_SET (element, GST_ELEMENT_PUSHING)) { + n_print (" GST_ELEMENT_PUSHING\n"); have_flags = TRUE; } if (GST_FLAG_IS_SET (element, GST_ELEMENT_EVENT_AWARE)) { @@ -551,14 +454,6 @@ print_element_flag_info (GstElement * element) n_print (" GST_BIN_FLAG_MANAGER\n"); have_flags = TRUE; } - if (GST_FLAG_IS_SET (element, GST_BIN_SELF_SCHEDULABLE)) { - n_print (" GST_BIN_SELF_SCHEDULABLE\n"); - have_flags = TRUE; - } - if (GST_FLAG_IS_SET (element, GST_BIN_FLAG_PREFER_COTHREADS)) { - n_print (" GST_BIN_FLAG_PREFER_COTHREADS\n"); - have_flags = TRUE; - } if (!have_flags) n_print (" no flags set\n"); } @@ -569,6 +464,7 @@ print_implementation_info (GstElement * element) { GstObjectClass *gstobject_class; GstElementClass *gstelement_class; + GSList *list; gstobject_class = GST_OBJECT_CLASS (G_OBJECT_GET_CLASS (element)); gstelement_class = GST_ELEMENT_CLASS (G_OBJECT_GET_CLASS (element)); @@ -576,12 +472,14 @@ print_implementation_info (GstElement * element) n_print ("\n"); n_print ("Element Implementation:\n"); - if (element->loopfunc) - n_print (" loopfunc()-based element: %s\n", - GST_DEBUG_FUNCPTR_NAME (element->loopfunc)); - else - n_print (" No loopfunc(), must be chain-based or not configured yet\n"); + n_print ("Element Actions:\n"); + for (list = element->actions; list; list = g_slist_next (list)) { + GstAction *action = list->data; + gchar *str = gst_action_to_string (action); + n_print (" %s %s\n", + gst_action_is_initially_active (action) ? "ACTIVE" : " ", str); + } n_print (" Has change_state() function: %s\n", GST_DEBUG_FUNCPTR_NAME (gstelement_class->change_state)); #ifndef GST_DISABLE_LOADSAVE @@ -676,33 +574,15 @@ print_pad_info (GstElement * element) g_print ("\n"); n_print (" Implementation:\n"); - if (realpad->chainfunc) - n_print (" Has chainfunc(): %s\n", - GST_DEBUG_FUNCPTR_NAME (realpad->chainfunc)); - if (realpad->getfunc) - n_print (" Has getfunc(): %s\n", - GST_DEBUG_FUNCPTR_NAME (realpad->getfunc)); - if (realpad->formatsfunc != gst_pad_get_formats_default) { - n_print (" Supports seeking/conversion/query formats:\n"); - print_formats (gst_pad_get_formats (GST_PAD (realpad))); - } if (realpad->convertfunc != gst_pad_convert_default) n_print (" Has custom convertfunc(): %s\n", GST_DEBUG_FUNCPTR_NAME (realpad->convertfunc)); - if (realpad->eventfunc != gst_pad_event_default) - n_print (" Has custom eventfunc(): %s\n", - GST_DEBUG_FUNCPTR_NAME (realpad->eventfunc)); - if (realpad->eventmaskfunc != gst_pad_get_event_masks_default) { - n_print (" Provides event masks:\n"); - print_event_masks (gst_pad_get_event_masks (GST_PAD (realpad))); - } + if (realpad->eventhandler != gst_pad_event_default) + n_print (" Has custom eventhandler(): %s\n", + GST_DEBUG_FUNCPTR_NAME (realpad->eventhandler)); if (realpad->queryfunc != gst_pad_query_default) n_print (" Has custom queryfunc(): %s\n", GST_DEBUG_FUNCPTR_NAME (realpad->queryfunc)); - if (realpad->querytypefunc != gst_pad_get_query_types_default) { - n_print (" Provides query types:\n"); - print_query_types (gst_pad_get_query_types (GST_PAD (realpad))); - } if (realpad->intlinkfunc != gst_pad_get_internal_links_default) n_print (" Has custom intconnfunc(): %s\n", diff --git a/tools/gst-launch.c b/tools/gst-launch.c index 17393aad18..7ef0b6af53 100644 --- a/tools/gst-launch.c +++ b/tools/gst-launch.c @@ -59,141 +59,9 @@ static void sigint_restore (void); #endif static gint max_iterations = 0; -static guint64 iterations = 0; -static guint64 sum = 0; -static guint64 min = G_MAXINT64; -static guint64 max = 0; -static GstClock *s_clock; static GstElement *pipeline; -static gboolean caught_intr = FALSE; -static gboolean caught_error = FALSE; -static gboolean need_new_state = FALSE; -static GstElementState new_state; - -gboolean -idle_func (gpointer data) -{ - gboolean busy; - GTimeVal tfthen, tfnow; - GstClockTimeDiff diff; - - g_get_current_time (&tfthen); - busy = gst_bin_iterate (GST_BIN (data)); - iterations++; - g_get_current_time (&tfnow); - - diff = GST_TIMEVAL_TO_TIME (tfnow) - GST_TIMEVAL_TO_TIME (tfthen); - - sum += diff; - min = MIN (min, diff); - max = MAX (max, diff); - - if (need_new_state) { - gst_element_set_state (pipeline, new_state); - need_new_state = FALSE; - } - - if (!busy || caught_intr || caught_error || - (max_iterations > 0 && iterations >= max_iterations)) { - char *s_iterations; - char *s_sum; - char *s_ave; - char *s_min; - char *s_max; - - gst_main_quit (); - - /* We write these all to strings first because - * G_GUINT64_FORMAT and gettext mix very poorly */ - s_iterations = g_strdup_printf ("%" G_GUINT64_FORMAT, iterations); - s_sum = g_strdup_printf ("%" G_GUINT64_FORMAT, sum); - s_ave = g_strdup_printf ("%" G_GUINT64_FORMAT, sum / iterations); - s_min = g_strdup_printf ("%" G_GUINT64_FORMAT, min); - s_max = g_strdup_printf ("%" G_GUINT64_FORMAT, max); - - g_print (_("Execution ended after %s iterations (sum %s ns, " - "average %s ns, min %s ns, max %s ns).\n"), - s_iterations, s_sum, s_ave, s_min, s_max); - g_free (s_iterations); - g_free (s_sum); - g_free (s_ave); - g_free (s_min); - g_free (s_max); - } - - return busy; -} - -#ifndef GST_DISABLE_LOADSAVE -static GstElement * -xmllaunch_parse_cmdline (const gchar ** argv) -{ - GstElement *pipeline = NULL, *e; - GstXML *xml; - gboolean err; - const gchar *arg; - gchar *element, *property, *value; - GList *l; - gint i = 0; - - if (!(arg = argv[0])) { - g_print (_ - ("Usage: gst-xmllaunch [ element.property=value ... ]\n")); - exit (1); - } - - xml = gst_xml_new (); - err = gst_xml_parse_file (xml, (guchar *) arg, NULL); - - if (err != TRUE) { - fprintf (stderr, _("ERROR: parse of xml file '%s' failed.\n"), arg); - exit (1); - } - - l = gst_xml_get_topelements (xml); - if (!l) { - fprintf (stderr, _("ERROR: no toplevel pipeline element in file '%s'.\n"), - arg); - exit (1); - } - - if (l->next) - fprintf (stderr, - _("WARNING: only one toplevel element is supported at this time.")); - - pipeline = GST_ELEMENT (l->data); - - while ((arg = argv[++i])) { - element = g_strdup (arg); - property = strchr (element, '.'); - value = strchr (element, '='); - - if (!(element < property && property < value)) { - fprintf (stderr, - _("ERROR: could not parse command line argument %d: %s.\n"), i, - element); - g_free (element); - exit (1); - } - - *property++ = '\0'; - *value++ = '\0'; - - e = gst_bin_get_by_name (GST_BIN (pipeline), element); - if (!e) { - fprintf (stderr, _("WARNING: element named '%s' not found.\n"), element); - } else { - gst_util_set_object_arg (G_OBJECT (e), property, value); - } - g_free (element); - } - - if (!l) - return NULL; - else - return l->data; -} -#endif +gboolean caught_intr = FALSE; +gboolean caught_quit = FALSE; #ifndef DISABLE_FAULT_HANDLER #ifndef USE_SIGINFO @@ -202,17 +70,15 @@ fault_handler_sighandler (int signum) { fault_restore (); - /* printf is used instead of g_print(), since it's less likely to - * deadlock */ switch (signum) { case SIGSEGV: - printf ("Caught SIGSEGV\n"); + g_print ("Caught SIGSEGV\n"); break; case SIGQUIT: - printf ("Caught SIGQUIT\n"); + g_print ("Caught SIGQUIT\n"); break; default: - printf ("signo: %d\n", signum); + g_print ("signo: %d\n", signum); break; } @@ -226,19 +92,17 @@ fault_handler_sigaction (int signum, siginfo_t * si, void *misc) { fault_restore (); - /* printf is used instead of g_print(), since it's less likely to - * deadlock */ switch (si->si_signo) { case SIGSEGV: - printf ("Caught SIGSEGV accessing address %p\n", si->si_addr); + g_print ("Caught SIGSEGV accessing address %p\n", si->si_addr); break; case SIGQUIT: - printf ("Caught SIGQUIT\n"); + g_print ("Caught SIGQUIT\n"); break; default: - printf ("signo: %d\n", si->si_signo); - printf ("errno: %d\n", si->si_errno); - printf ("code: %d\n", si->si_code); + g_print ("signo: %d\n", si->si_signo); + g_print ("errno: %d\n", si->si_errno); + g_print ("code: %d\n", si->si_code); break; } @@ -257,7 +121,7 @@ fault_spin (void) wait (NULL); /* FIXME how do we know if we were run by libtool? */ - printf ("Spinning. Please run 'gdb gst-launch %d' to continue debugging, " + g_print ("Spinning. Please run 'gdb gst-launch %d' to continue debugging, " "Ctrl-C to quit, or Ctrl-\\ to dump core.\n", (gint) getpid ()); while (spinning) g_usleep (1000000); @@ -320,7 +184,6 @@ print_tag (const GstTagList * list, const gchar * tag, gpointer unused) g_free (str); } } - static void found_tag (GObject * pipeline, GstElement * source, GstTagList * tags) { @@ -329,13 +192,6 @@ found_tag (GObject * pipeline, GstElement * source, GstTagList * tags) gst_tag_list_foreach (tags, print_tag, NULL); } -static void -error_cb (GObject * object, GstObject * source, GError * error, gchar * debug) -{ - gst_element_default_error (object, source, error, debug); - caught_error = TRUE; -} - #ifndef DISABLE_FAULT_HANDLER /* we only use sighandler here because the registers are not important */ static void @@ -373,12 +229,12 @@ play_handler (int signum) { switch (signum) { case SIGUSR1: - new_state = GST_STATE_PLAYING; - need_new_state = TRUE; + g_print ("Caught SIGUSR1 - Play request.\n"); + gst_element_set_state (pipeline, GST_STATE_PLAYING); break; case SIGUSR2: - new_state = GST_STATE_NULL; - need_new_state = TRUE; + g_print ("Caught SIGUSR2 - Stop request.\n"); + gst_element_set_state (pipeline, GST_STATE_NULL); break; } } @@ -395,6 +251,43 @@ play_signal_setup (void) } #endif +static gboolean +should_quit (gpointer loop) +{ + if (!caught_intr && !caught_quit) + return TRUE; + + g_main_loop_quit (loop); + if (caught_intr) + g_print ("Caught interrupt.\n"); + return FALSE; +} + +static void +quit_cb (void) +{ + caught_quit = TRUE; +} + +static GPollFunc gpoll; +static GTimer *poll_timer = NULL; + +static gint +launch_poll (GPollFD * ufds, guint nfds, gint timeout_) +{ + gint ret; + + if (G_LIKELY (poll_timer)) { + g_timer_continue (poll_timer); + } else { + poll_timer = g_timer_new (); + g_timer_start (poll_timer); + } + ret = gpoll (ufds, nfds, timeout_); + g_timer_stop (poll_timer); + return ret; +} + int main (int argc, char *argv[]) { @@ -405,7 +298,6 @@ main (int argc, char *argv[]) gboolean tags = FALSE; gboolean no_fault = FALSE; gboolean trace = FALSE; - gchar *savefile = NULL; gchar *exclude_args = NULL; struct poptOption options[] = { {"tags", 't', POPT_ARG_NONE | POPT_ARGFLAG_STRIP, &tags, 0, @@ -414,10 +306,6 @@ main (int argc, char *argv[]) N_("Output status information and property notifications"), NULL}, {"exclude", 'X', POPT_ARG_STRING | POPT_ARGFLAG_STRIP, &exclude_args, 0, N_("Do not output status information of TYPE"), N_("TYPE1,TYPE2,...")}, -#ifndef GST_DISABLE_LOADSAVE - {"output", 'o', POPT_ARG_STRING | POPT_ARGFLAG_STRIP, &savefile, 0, - N_("Save xml representation of pipeline to FILE and exit"), N_("FILE")}, -#endif {"no-fault", 'f', POPT_ARG_NONE | POPT_ARGFLAG_STRIP, &no_fault, 0, N_("Do not install a fault handler"), NULL}, {"trace", 'T', POPT_ARG_NONE | POPT_ARGFLAG_STRIP, &trace, 0, @@ -480,11 +368,6 @@ main (int argc, char *argv[]) /* make a null-terminated version of argv */ argvn = g_new0 (char *, argc); memcpy (argvn, argv + 1, sizeof (char *) * (argc - 1)); -#ifndef GST_DISABLE_LOADSAVE - if (strstr (argv[0], "gst-xmllaunch")) { - pipeline = xmllaunch_parse_cmdline ((const gchar **) argvn); - } else -#endif { pipeline = (GstElement *) gst_parse_launchv ((const gchar **) argvn, &error); @@ -493,16 +376,16 @@ main (int argc, char *argv[]) if (!pipeline) { if (error) { - fprintf (stderr, _("ERROR: pipeline could not be constructed: %s.\n"), + g_printerr (_("ERROR: pipeline could not be constructed: %s.\n"), error->message); g_error_free (error); } else { - fprintf (stderr, _("ERROR: pipeline could not be constructed.\n")); + g_printerr (_("ERROR: pipeline could not be constructed.\n")); } - return 1; + exit (1); } else if (error) { - fprintf (stderr, _("WARNING: erroneous pipeline: %s\n"), error->message); - fprintf (stderr, _(" Trying to run anyway.\n")); + g_printerr (_("WARNING: erroneous pipeline: %s\n"), error->message); + g_printerr (_(" Trying to run anyway.\n")); g_error_free (error); } @@ -515,56 +398,52 @@ main (int argc, char *argv[]) if (tags) { g_signal_connect (pipeline, "found-tag", G_CALLBACK (found_tag), NULL); } - g_signal_connect (pipeline, "error", G_CALLBACK (error_cb), NULL); + g_signal_connect (pipeline, "error", G_CALLBACK (gst_element_default_error), + NULL); -#ifndef GST_DISABLE_LOADSAVE - if (savefile) { - gst_xml_write_file (GST_ELEMENT (pipeline), fopen (savefile, "w")); + if (!GST_IS_BIN (pipeline)) { + GstElement *real_pipeline = gst_element_factory_make ("pipeline", NULL); + + if (real_pipeline == NULL) { + g_printerr (_("ERROR: the 'pipeline' element wasn't found.\n")); + return 1; + } + gst_bin_add (GST_BIN (real_pipeline), pipeline); + pipeline = real_pipeline; } -#endif - if (!savefile) { + g_signal_connect_swapped (pipeline, "eos", G_CALLBACK (quit_cb), NULL); + g_signal_connect_swapped (pipeline, "error", G_CALLBACK (quit_cb), NULL); + g_print (_("RUNNING pipeline ...\n")); - if (!GST_IS_BIN (pipeline)) { - GstElement *real_pipeline = gst_element_factory_make ("pipeline", NULL); + if (gst_element_set_state (pipeline, GST_STATE_PLAYING) == GST_STATE_FAILURE) { + g_printerr (_("ERROR: pipeline doesn't want to play.\n")); + res = -1; + } else { + GTimer *timer = g_timer_new (); + GMainLoop *loop = g_main_loop_new (NULL, FALSE); + gdouble in_poll = 0, duration; - if (real_pipeline == NULL) { - fprintf (stderr, _("ERROR: the 'pipeline' element wasn't found.\n")); - return 1; - } - gst_bin_add (GST_BIN (real_pipeline), pipeline); - pipeline = real_pipeline; + g_timeout_add (1000, should_quit, loop); + + gpoll = g_main_context_get_poll_func (NULL); + g_main_context_set_poll_func (NULL, launch_poll); + g_timer_start (timer); + g_main_loop_run (loop); + g_timer_stop (timer); + g_main_loop_unref (loop); + if (poll_timer) { + in_poll = g_timer_elapsed (poll_timer, NULL); + g_timer_destroy (poll_timer); } - - fprintf (stderr, _("RUNNING pipeline ...\n")); - if (gst_element_set_state (pipeline, - GST_STATE_PLAYING) == GST_STATE_FAILURE) { - fprintf (stderr, _("ERROR: pipeline doesn't want to play.\n")); - res = -1; - goto end; - } - - s_clock = gst_bin_get_clock (GST_BIN (pipeline)); - - if (!GST_FLAG_IS_SET (GST_OBJECT (pipeline), GST_BIN_SELF_SCHEDULABLE)) { - g_idle_add (idle_func, pipeline); - gst_main (); - } else { - g_print ("Waiting for the state change... "); - gst_element_wait_state_change (pipeline); - g_print ("got the state change.\n"); - } - if (caught_intr) { - g_print ("Caught interrupt.\n"); - res = 2; - } - if (caught_error) - res = 3; + duration = g_timer_elapsed (timer, NULL); + g_timer_destroy (timer); gst_element_set_state (pipeline, GST_STATE_NULL); - } -end: + g_print (_("Execution ended after %.2fs (%.2fs or %.2f%% idling).\n"), + duration, in_poll, in_poll * 100 / duration); + } gst_object_unref (GST_OBJECT (pipeline)); diff --git a/tools/gst-md5sum.1.in b/tools/gst-md5sum.1.in deleted file mode 100644 index 90fc69443f..0000000000 --- a/tools/gst-md5sum.1.in +++ /dev/null @@ -1,80 +0,0 @@ -.TH "GStreamer" "1" "September 2002" -.SH "NAME" -gst\-md5sum \- get an md5sum of a GStreamer pipeline through md5sink -.SH "SYNOPSIS" -\fBgst\-md5sum\fR \fI[OPTION...]\fR PARTIAL\-PIPELINE\-DESCRIPTION -.SH "DESCRIPTION" -.LP -\fIgst\-md5sum\fP generates MD5 checksums of the data generated by -a GStreamer pipeline. - -In theory, running - - gst-md5sum filesrc location=music.mp3 - -should print out the same checksum as - - md5sum music.mp3 - -If the pipeline contains an md5sink element, gst-md5sum will query it -for the md5sum at the end of pipeline iteration. - -If it doesn't contain an md5sink element, gst-md5sum will automatically -connect an md5sink to the right hand side of the given pipeline. - -See the man page for gst\-launch or the GStreamer docuementation for -more information on how to create a PARTIAL\-PIPELINE\-DESCRIPTION. -. -.SH "OPTIONS" -.l -\fIgst\-md5sum\fP accepts the following options: -.TP 8 -.B \-\-help -Print help synopsis and available FLAGS -.TP 8 -.B \-v -Output verbose information -.TP 8 -.B \-\-gst\-info\-mask=FLAGS -\fIGStreamer\fP info flags to set (list with \-\-help) -.TP 8 -.B \-\-gst\-debug\-mask=FLAGS -\fIGStreamer\fP debugging flags to set (list with \-\-help) -.TP 8 -.B \-\-gst\-mask=FLAGS -\fIGStreamer\fP info and debugging flags to set (list with \-\-help) -.TP 8 -.B \-\-gst\-plugin\-spew -\fIGStreamer\fP info flags to set -Enable printout of errors while loading \fIGStreamer\fP plugins -.TP 8 -.B \-\-gst\-plugin\-path=PATH -Add directories separated with ':' to the plugin search path -.SH "SEE ALSO" -.BR gst\-launch (1) -.SH "AUTHOR" -The GStreamer team at http://gstreamer.net/ -*************** -*** 16,24 **** - - md5sum music.mp3 - - The pipeline should be incomplete, that is, a final sink element -- should be omitted, so that gst\-md5sum can connect the pipeline to -- an md5sink element. - - See the man page for gst\-launch or the GStreamer docuementation for - more information on how to create a PARTIAL\-PIPELINE\-DESCRIPTION. ---- 16,27 ---- - - md5sum music.mp3 - -+ If the pipeline contains an md5sink element, gst-md5sum will query it -+ for the md5sum at the end of pipeline iteration. -+ -+ If it doesn't contain an md5sink element, gst-md5sum will automatically -+ connect an md5sink to the right hand side of the given pipeline. - The pipeline should be incomplete, that is, a final sink element - - See the man page for gst\-launch or the GStreamer docuementation for - more information on how to create a PARTIAL\-PIPELINE\-DESCRIPTION. diff --git a/tools/gst-md5sum.c b/tools/gst-md5sum.c deleted file mode 100644 index 3101c85679..0000000000 --- a/tools/gst-md5sum.c +++ /dev/null @@ -1,146 +0,0 @@ -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - -#include -#include -#include -#include - -static guint64 iterations = 0; -static guint64 sum = 0; -static guint64 min = G_MAXINT64; -static guint64 max = 0; -static GstClock *s_clock; - -gboolean -idle_func (gpointer data) -{ - gboolean busy; - GTimeVal tfthen, tfnow; - GstClockTimeDiff diff; - - if (s_clock) { - //g_print ("%lld\n", gst_clock_get_time (s_clock)); - } - - g_get_current_time (&tfthen); - busy = gst_bin_iterate (GST_BIN (data)); - iterations++; - g_get_current_time (&tfnow); - - diff = GST_TIMEVAL_TO_TIME (tfnow) - GST_TIMEVAL_TO_TIME (tfthen); - - sum += diff; - min = MIN (min, diff); - max = MAX (max, diff); - - if (!busy) { - gst_main_quit (); - /* - g_print ("execution ended after %llu iterations (sum %llu ns, average %llu ns, min %llu ns, max %llu ns)\n", - iterations, sum, sum/iterations, min, max); - */ - } - - return busy; -} - -int -main (int argc, char *argv[]) -{ - /* options */ - gboolean verbose = FALSE; - gchar *exclude_args = NULL; - struct poptOption options[] = { - {"verbose", 'v', POPT_ARG_NONE | POPT_ARGFLAG_STRIP, &verbose, 0, - "do not output status information", NULL}, - POPT_TABLEEND - }; - - GstElement *pipeline = NULL; - gchar **argvn; - GError *error = NULL; - GstElement *md5sink; - gchar *md5string = g_malloc0 (33); - - free (malloc (8)); /* -lefence */ - - setlocale (LC_ALL, ""); - - gst_init_with_popt_table (&argc, &argv, options); - - /* make a parseable argvn array */ - argvn = g_new0 (char *, argc); - memcpy (argvn, argv + 1, sizeof (char *) * (argc - 1)); - - /* Check if we have an element already that is called md5sink0 - in the pipeline; if not, add one */ - pipeline = (GstElement *) gst_parse_launchv ((const gchar **) argvn, &error); - if (!pipeline) { - if (error) { - g_warning ("pipeline could not be constructed: %s\n", error->message); - g_error_free (error); - } else - g_warning ("pipeline could not be constructed\n"); - return 1; - } - - md5sink = gst_bin_get_by_name (GST_BIN (pipeline), "md5sink0"); - if (md5sink == NULL) { - g_print ("adding an md5sink element to the pipeline\n"); - /* make a null-terminated version of argv with ! md5sink appended - * ! is stored in argvn[argc - 1], md5sink in argvn[argc], - * NULL pointer in argvn[argc + 1] */ - g_free (argvn); - argvn = g_new0 (char *, argc + 2); - memcpy (argvn, argv + 1, sizeof (char *) * (argc - 1)); - argvn[argc - 1] = g_strdup_printf ("!"); - argvn[argc] = g_strdup_printf ("md5sink"); - pipeline = - (GstElement *) gst_parse_launchv ((const gchar **) argvn, &error); - } - - if (!pipeline) { - if (error) { - g_warning ("pipeline could not be constructed: %s\n", error->message); - g_error_free (error); - } else - g_warning ("pipeline could not be constructed\n"); - return 1; - } - - if (verbose) { - gchar **exclude_list = exclude_args ? g_strsplit (exclude_args, ",", 0) - : NULL; - - g_signal_connect (pipeline, "deep_notify", - G_CALLBACK (gst_element_default_deep_notify), exclude_list); - } - g_signal_connect (pipeline, "error", - G_CALLBACK (gst_element_default_error), NULL); - - if (gst_element_set_state (pipeline, GST_STATE_PLAYING) != GST_STATE_SUCCESS) { - g_warning ("pipeline doesn't want to play\n"); - return 0; - } - - if (!GST_FLAG_IS_SET (GST_OBJECT (pipeline), GST_BIN_SELF_SCHEDULABLE)) { - g_idle_add (idle_func, pipeline); - gst_main (); - } else { - gst_element_wait_state_change (pipeline); - } - - gst_element_set_state (pipeline, GST_STATE_NULL); - - /* print out md5sink here */ - md5sink = gst_bin_get_by_name (GST_BIN (pipeline), "md5sink0"); - g_assert (md5sink); - g_object_get (G_OBJECT (md5sink), "md5", &md5string, NULL); - printf ("%s\n", md5string); - - gst_object_unref (GST_OBJECT (pipeline)); - - return 0; -} diff --git a/tools/gst-typefind.c b/tools/gst-typefind.c index 7ea6034e93..20b5c3e0e7 100644 --- a/tools/gst-typefind.c +++ b/tools/gst-typefind.c @@ -11,8 +11,9 @@ * find the type of a media file and display it's properties **/ -gboolean FOUND = FALSE; gchar *filename = NULL; +gboolean FOUND = FALSE; +GMainLoop *loop; void gst_caps_print (const char *filename, const GstCaps * caps) @@ -25,9 +26,10 @@ gst_caps_print (const char *filename, const GstCaps * caps) void have_type_handler (GstElement * typefind, guint probability, - const GstCaps * caps, gpointer unused) + const GstCaps * caps, gpointer loop) { gst_caps_print (filename, caps); + g_main_loop_quit (loop); FOUND = TRUE; } @@ -57,6 +59,11 @@ main (int argc, char *argv[]) g_signal_connect (G_OBJECT (typefind), "have-type", G_CALLBACK (have_type_handler), NULL); + loop = g_main_loop_new (NULL, FALSE); + g_signal_connect_swapped (pipeline, "eos", G_CALLBACK (g_main_loop_quit), + loop); + g_signal_connect_swapped (pipeline, "error", G_CALLBACK (g_main_loop_quit), + loop); while (i < argc) { FOUND = FALSE; gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_NULL); @@ -65,15 +72,13 @@ main (int argc, char *argv[]) /* set to play */ gst_element_set_state (GST_ELEMENT (pipeline), GST_STATE_PLAYING); - while (!FOUND) { - if (!gst_bin_iterate (GST_BIN (pipeline))) - break; - } + g_main_loop_run (loop); if (!FOUND) { g_print ("%s - No type found\n", argv[i]); } i++; } + g_main_loop_unref (loop); g_object_unref (pipeline); return 0; } diff --git a/tools/gst-xmlinspect.1.in b/tools/gst-xmlinspect.1.in deleted file mode 100644 index 429dab0cec..0000000000 --- a/tools/gst-xmlinspect.1.in +++ /dev/null @@ -1,48 +0,0 @@ -.TH GStreamer 1 "March 2001" -.SH NAME -gst\-xmlinspect - print info about a GStreamer plugin or element -.SH SYNOPSIS -.B gst\-xmlinspect [OPTION...] [PLUGIN|ELEMENT] -.SH DESCRIPTION -.PP -\fIgst\-xmlinspect\fP is a tool that prints out information on -available \fIGStreamer\fP plugins, information about a particular -plugin, or information about a particular element. When executed -with no PLUGIN or ELEMENT argument, \fIgst\-xmlinspect\fP will print -a list of all plugins and elements. When executed with a PLUGIN -or ELEMENT argument, \fIgst\-xmlinspect\fP will print information -about that plug-in or element as an XML document. -. -.SH OPTIONS -.l -\fIgst\-xmlinspect\fP accepts the following arguments and options: -.TP 8 -.B PLUGIN -Name of a plugin -.TP 8 -.B ELEMENT -Name of an element -.TP 8 -.B \-\-help -Print help synopsis and available FLAGS -.TP 8 -.B \-\-gst\-info\-mask=FLAGS -\fIGStreamer\fP info flags to set (list with \-\-help) -.TP 8 -.B \-\-gst\-debug\-mask=FLAGS -\fIGStreamer\fP debugging flags to set (list with \-\-help) -.TP 8 -.B \-\-gst\-mask=FLAGS -\fIGStreamer\fP info and debugging flags to set (list with \-\-help) -.TP 8 -.B \-\-gst\-plugin\-spew -\fIGStreamer\fP info flags to set -Enable printout of errors while loading \fIGStreamer\fP plugins -.TP 8 -.B \-\-gst\-plugin\-path=PATH -Add directories separated with ':' to the plugin search path -.SH SEE ALSO -.BR gst\-register (1), -.BR gst\-launch (1) -.SH AUTHOR -The GStreamer team at http://gstreamer.net/ diff --git a/tools/gst-xmlinspect.c b/tools/gst-xmlinspect.c deleted file mode 100644 index 69c59e6d58..0000000000 --- a/tools/gst-xmlinspect.c +++ /dev/null @@ -1,956 +0,0 @@ -#ifdef HAVE_CONFIG_H -# include "config.h" -#endif - -#include -#include -#include -#include -#include - -#define PUT_START_TAG(pfx,tag) \ -G_STMT_START{ \ - g_print ("%*.*s<%s>\n", pfx, pfx, "", tag); \ -}G_STMT_END - -#define PUT_END_TAG(pfx,tag) \ -G_STMT_START{ \ - g_print ("%*.*s\n", pfx, pfx, "", tag); \ -}G_STMT_END - -#define PUT_ESCAPED(pfx,tag,value) \ -G_STMT_START{ \ - const gchar *toconv = value; \ - if (value) { \ - gchar *v = g_markup_escape_text (toconv, strlen (toconv)); \ - g_print ("%*.*s<%s>%s\n", pfx, pfx, "", tag, v, tag); \ - g_free (v); \ - } \ -}G_STMT_END - -#ifdef G_HAVE_ISO_VARARGS - -#define PUT_STRING(pfx, ...) \ -G_STMT_START{ \ - gchar *ps_val = g_strdup_printf(__VA_ARGS__); \ - g_print ("%*.*s%s\n", pfx, pfx, "", ps_val); \ - g_free(ps_val); \ -}G_STMT_END - -#elif defined(G_HAVE_GNUC_VARARGS) - -#define PUT_STRING(pfx, str, a...) \ -G_STMT_START{ \ - g_print ("%*.*s"str"\n", pfx, pfx, "" , ##a); \ -}G_STMT_END - -#else - -static inline void -PUT_STRING (int pfx, const char *format, ...) -{ - va_list varargs; - - g_print ("%*.*s", pfx, pfx, ""); - va_start (varargs, format); - g_vprintf (format, varargs); - va_end (varargs); - g_print ("\n"); -} - -#endif - -static void -print_caps (const GstCaps * caps, gint pfx) -{ - char *s; - - if (!caps) - return; - - s = gst_caps_to_string (caps); - PUT_ESCAPED (pfx, "caps", s); - g_free (s); -} - -static void -print_formats (const GstFormat * formats, gint pfx) -{ - while (formats && *formats) { - const GstFormatDefinition *definition; - - definition = gst_format_get_details (*formats); - if (definition) - PUT_STRING (pfx, "%s", - *formats, definition->nick, definition->description); - else - PUT_STRING (pfx, "unknown", *formats); - - formats++; - } -} - -static void -print_query_types (const GstQueryType * types, gint pfx) -{ - while (types && *types) { - const GstQueryTypeDefinition *definition; - - definition = gst_query_type_get_details (*types); - if (definition) - PUT_STRING (pfx, "%s", - *types, definition->nick, definition->description); - else - PUT_STRING (pfx, "unknown", *types); - - types++; - } -} - -static void -print_event_masks (const GstEventMask * masks, gint pfx) -{ -#ifndef GST_DISABLE_ENUMTYPES - GType event_type; - GEnumClass *klass; - GType event_flags; - GFlagsClass *flags_class = NULL; - - event_type = gst_event_type_get_type (); - klass = (GEnumClass *) g_type_class_ref (event_type); - - while (masks && masks->type) { - GEnumValue *value; - gint flags = 0, index = 0; - - switch (masks->type) { - case GST_EVENT_SEEK: - flags = masks->flags; - event_flags = gst_seek_type_get_type (); - flags_class = (GFlagsClass *) g_type_class_ref (event_flags); - break; - default: - break; - } - - value = g_enum_get_value (klass, masks->type); - PUT_STRING (pfx, "", value->value_nick); - - while (flags) { - GFlagsValue *value; - - if (flags & 1) { - value = g_flags_get_first_value (flags_class, 1 << index); - - if (value) - PUT_ESCAPED (pfx + 1, "flag", value->value_nick); - else - PUT_ESCAPED (pfx + 1, "flag", "?"); - } - flags >>= 1; - index++; - } - PUT_END_TAG (pfx, "event"); - - masks++; - } -#endif -} - -static void -output_hierarchy (GType type, gint level, gint * maxlevel) -{ - GType parent; - - parent = g_type_parent (type); - - *maxlevel = *maxlevel + 1; - level++; - - PUT_STRING (level, "", g_type_name (type)); - - if (parent) - output_hierarchy (parent, level, maxlevel); - - PUT_END_TAG (level, "object"); -} - -static void -print_element_properties (GstElement * element, gint pfx) -{ - GParamSpec **property_specs; - guint num_properties, i; - gboolean readable; - - property_specs = g_object_class_list_properties - (G_OBJECT_GET_CLASS (element), &num_properties); - - PUT_START_TAG (pfx, "element-properties"); - - for (i = 0; i < num_properties; i++) { - GValue value = { 0, }; - GParamSpec *param = property_specs[i]; - - readable = FALSE; - - g_value_init (&value, param->value_type); - if (param->flags & G_PARAM_READABLE) { - g_object_get_property (G_OBJECT (element), param->name, &value); - readable = TRUE; - } - PUT_START_TAG (pfx + 1, "element-property"); - PUT_ESCAPED (pfx + 2, "name", g_param_spec_get_name (param)); - PUT_ESCAPED (pfx + 2, "type", g_type_name (param->value_type)); - PUT_ESCAPED (pfx + 2, "nick", g_param_spec_get_nick (param)); - PUT_ESCAPED (pfx + 2, "blurb", g_param_spec_get_blurb (param)); - if (readable) { - PUT_ESCAPED (pfx + 2, "flags", "RW"); - } else { - PUT_ESCAPED (pfx + 2, "flags", "W"); - } - - switch (G_VALUE_TYPE (&value)) { - case G_TYPE_STRING: - PUT_ESCAPED (pfx + 2, "default", g_strdup_value_contents (&value)); - break; - case G_TYPE_BOOLEAN: - PUT_ESCAPED (pfx + 2, "default", g_strdup_value_contents (&value)); - break; - case G_TYPE_ULONG: - { - GParamSpecULong *pulong = G_PARAM_SPEC_ULONG (param); - - PUT_STRING (pfx + 2, "", - pulong->minimum, pulong->maximum); - PUT_ESCAPED (pfx + 2, "default", g_strdup_value_contents (&value)); - break; - } - case G_TYPE_LONG: - { - GParamSpecLong *plong = G_PARAM_SPEC_LONG (param); - - PUT_STRING (pfx + 2, "", - plong->minimum, plong->maximum); - PUT_ESCAPED (pfx + 2, "default", g_strdup_value_contents (&value)); - break; - } - case G_TYPE_UINT: - { - GParamSpecUInt *puint = G_PARAM_SPEC_UINT (param); - - PUT_STRING (pfx + 2, "", - puint->minimum, puint->maximum); - PUT_ESCAPED (pfx + 2, "default", g_strdup_value_contents (&value)); - break; - } - case G_TYPE_INT: - { - GParamSpecInt *pint = G_PARAM_SPEC_INT (param); - - PUT_STRING (pfx + 2, "", - pint->minimum, pint->maximum); - PUT_ESCAPED (pfx + 2, "default", g_strdup_value_contents (&value)); - break; - } - case G_TYPE_UINT64: - { - GParamSpecUInt64 *puint64 = G_PARAM_SPEC_UINT64 (param); - - PUT_STRING (pfx + 2, - "", puint64->minimum, puint64->maximum); - PUT_ESCAPED (pfx + 2, "default", g_strdup_value_contents (&value)); - break; - } - case G_TYPE_INT64: - { - GParamSpecInt64 *pint64 = G_PARAM_SPEC_INT64 (param); - - PUT_STRING (pfx + 2, - "", pint64->minimum, pint64->maximum); - PUT_ESCAPED (pfx + 2, "default", g_strdup_value_contents (&value)); - break; - } - case G_TYPE_FLOAT: - { - GParamSpecFloat *pfloat = G_PARAM_SPEC_FLOAT (param); - - PUT_STRING (pfx + 2, "", - pfloat->minimum, pfloat->maximum); - PUT_ESCAPED (pfx + 2, "default", g_strdup_value_contents (&value)); - break; - } - case G_TYPE_DOUBLE: - { - GParamSpecDouble *pdouble = G_PARAM_SPEC_DOUBLE (param); - - PUT_STRING (pfx + 2, "", - pdouble->minimum, pdouble->maximum); - PUT_ESCAPED (pfx + 2, "default", g_strdup_value_contents (&value)); - break; - } - default: - if (param->value_type == GST_TYPE_CAPS) { - GstCaps *caps = g_value_peek_pointer (&value); - - if (!caps) - PUT_ESCAPED (pfx + 2, "default", "NULL"); - else { - print_caps (caps, 2); - } - } else if (G_IS_PARAM_SPEC_ENUM (param)) { - GEnumValue *values; - guint j = 0; - gint enum_value; - - values = G_ENUM_CLASS (g_type_class_ref (param->value_type))->values; - enum_value = g_value_get_enum (&value); - - while (values[j].value_name) { - if (values[j].value == enum_value) - break; - j++; - } - PUT_STRING (pfx + 2, "%d", values[j].value); - - PUT_START_TAG (pfx + 2, "enum-values"); - j = 0; - while (values[j].value_name) { - PUT_STRING (pfx + 3, "", - values[j].value, values[j].value_nick); - j++; - } - PUT_END_TAG (pfx + 2, "enum-values"); - } else if (G_IS_PARAM_SPEC_FLAGS (param)) { - GFlagsValue *values; - guint j = 0; - gint flags_value; - - values = G_FLAGS_CLASS (g_type_class_ref (param->value_type))->values; - flags_value = g_value_get_flags (&value); - - PUT_STRING (pfx + 2, "%d", flags_value); - - PUT_START_TAG (pfx + 2, "flags"); - j = 0; - while (values[j].value_name) { - PUT_STRING (pfx + 3, "", - values[j].value, values[j].value_nick); - j++; - } - PUT_END_TAG (pfx + 2, "flags"); - } else if (G_IS_PARAM_SPEC_OBJECT (param)) { - PUT_ESCAPED (pfx + 2, "object-type", g_type_name (param->value_type)); - } - break; - } - - PUT_END_TAG (pfx + 1, "element-property"); - } - PUT_END_TAG (pfx, "element-properties"); -} - -static void -print_element_dynparamaters (GstElement * element, gint pfx) -{ - GstDParamManager *dpman; - GParamSpec **specs; - gint x; - - PUT_START_TAG (pfx, "dyn-params"); - - if ((dpman = gst_dpman_get_manager (element))) { - specs = gst_dpman_list_dparam_specs (dpman); - for (x = 0; specs[x] != NULL; x++) { - PUT_START_TAG (pfx + 1, "dyn-param"); - - PUT_ESCAPED (pfx + 2, "name", g_param_spec_get_name (specs[x])); - PUT_ESCAPED (pfx + 2, "type", g_type_name (specs[x]->value_type)); - PUT_ESCAPED (pfx + 2, "nick", g_param_spec_get_nick (specs[x])); - PUT_ESCAPED (pfx + 2, "blurb", g_param_spec_get_blurb (specs[x])); - - switch (G_PARAM_SPEC_VALUE_TYPE (specs[x])) { - case G_TYPE_INT64: - PUT_STRING (pfx + 2, - "", ((GParamSpecInt64 *) specs[x])->minimum, - ((GParamSpecInt64 *) specs[x])->maximum); - PUT_STRING (pfx + 2, "%" G_GINT64_FORMAT "", - ((GParamSpecInt64 *) specs[x])->default_value); - break; - case G_TYPE_INT: - PUT_STRING (pfx + 2, "", - ((GParamSpecInt *) specs[x])->minimum, - ((GParamSpecInt *) specs[x])->maximum); - PUT_STRING (pfx + 2, "%d", - ((GParamSpecInt *) specs[x])->default_value); - break; - case G_TYPE_FLOAT: - PUT_STRING (pfx + 2, "", - ((GParamSpecFloat *) specs[x])->minimum, - ((GParamSpecFloat *) specs[x])->maximum); - PUT_STRING (pfx + 2, "%f", - ((GParamSpecFloat *) specs[x])->default_value); - break; - default: - break; - } - PUT_END_TAG (pfx + 1, "dyn-param"); - } - g_free (specs); - } - PUT_END_TAG (pfx, "dyn-params"); -} - -static void -print_element_signals (GstElement * element, gint pfx) -{ - guint *signals; - guint nsignals; - gint i, k; - GSignalQuery *query; - - signals = g_signal_list_ids (G_OBJECT_TYPE (element), &nsignals); - for (k = 0; k < 2; k++) { - gint counted = 0; - - if (k == 0) - PUT_START_TAG (pfx, "element-signals"); - else - PUT_START_TAG (pfx, "element-actions"); - - for (i = 0; i < nsignals; i++) { - gint n_params; - GType return_type; - const GType *param_types; - gint j; - - query = g_new0 (GSignalQuery, 1); - g_signal_query (signals[i], query); - - if ((k == 0 && !(query->signal_flags & G_SIGNAL_ACTION)) || - (k == 1 && (query->signal_flags & G_SIGNAL_ACTION))) { - n_params = query->n_params; - return_type = query->return_type; - param_types = query->param_types; - - PUT_START_TAG (pfx + 1, "signal"); - PUT_ESCAPED (pfx + 2, "name", query->signal_name); - PUT_ESCAPED (pfx + 2, "return-type", g_type_name (return_type)); - PUT_ESCAPED (pfx + 2, "object-type", - g_type_name (G_OBJECT_TYPE (element))); - - PUT_START_TAG (pfx + 2, "params"); - for (j = 0; j < n_params; j++) { - PUT_ESCAPED (pfx + 3, "type", g_type_name (param_types[j])); - } - - PUT_END_TAG (pfx + 2, "params"); - - PUT_END_TAG (pfx + 1, "signal"); - - counted++; - } - - g_free (query); - } - if (k == 0) - PUT_END_TAG (pfx, "element-signals"); - else - PUT_END_TAG (pfx, "element-actions"); - } -} - -static gint -print_element_info (GstElementFactory * factory) -{ - GstElement *element; - GstObjectClass *gstobject_class; - GstElementClass *gstelement_class; - GList *pads; - GstPad *pad; - GstRealPad *realpad; - GstPadTemplate *padtemplate; - GList *children; - GstElement *child; - gint maxlevel = 0; - - element = gst_element_factory_create (factory, "element"); - if (!element) { - g_print ("couldn't construct element for some reason\n"); - return -1; - } - PUT_START_TAG (0, "element"); - PUT_ESCAPED (1, "name", GST_PLUGIN_FEATURE_NAME (factory)); - - gstobject_class = GST_OBJECT_CLASS (G_OBJECT_GET_CLASS (element)); - gstelement_class = GST_ELEMENT_CLASS (G_OBJECT_GET_CLASS (element)); - - PUT_START_TAG (1, "details"); - PUT_ESCAPED (2, "long-name", factory->details.longname); - PUT_ESCAPED (2, "class", factory->details.klass); - PUT_ESCAPED (2, "description", factory->details.description); - PUT_ESCAPED (2, "authors", factory->details.author); - PUT_END_TAG (1, "details"); - - output_hierarchy (G_OBJECT_TYPE (element), 0, &maxlevel); - - PUT_START_TAG (1, "pad-templates"); - if (factory->numpadtemplates) { - pads = factory->padtemplates; - while (pads) { - padtemplate = (GstPadTemplate *) (pads->data); - pads = g_list_next (pads); - - PUT_START_TAG (2, "pad-template"); - PUT_ESCAPED (3, "name", padtemplate->name_template); - - if (padtemplate->direction == GST_PAD_SRC) - PUT_ESCAPED (3, "direction", "src"); - else if (padtemplate->direction == GST_PAD_SINK) - PUT_ESCAPED (3, "direction", "sink"); - else - PUT_ESCAPED (3, "direction", "unknown"); - - if (padtemplate->presence == GST_PAD_ALWAYS) - PUT_ESCAPED (3, "presence", "always"); - else if (padtemplate->presence == GST_PAD_SOMETIMES) - PUT_ESCAPED (3, "presence", "sometimes"); - else if (padtemplate->presence == GST_PAD_REQUEST) { - PUT_ESCAPED (3, "presence", "request"); - PUT_ESCAPED (3, "request-function", - GST_DEBUG_FUNCPTR_NAME (gstelement_class->request_new_pad)); - } else - PUT_ESCAPED (3, "presence", "unknown"); - - if (padtemplate->caps) { - print_caps (padtemplate->caps, 3); - } - PUT_END_TAG (2, "pad-template"); - } - } - PUT_END_TAG (1, "pad-templates"); - - PUT_START_TAG (1, "element-flags"); - if (GST_FLAG_IS_SET (element, GST_ELEMENT_COMPLEX)) { - PUT_ESCAPED (2, "flag", "GST_ELEMENT_COMPLEX"); - } - if (GST_FLAG_IS_SET (element, GST_ELEMENT_DECOUPLED)) { - PUT_ESCAPED (2, "flag", "GST_ELEMENT_DECOUPLED"); - } - if (GST_FLAG_IS_SET (element, GST_ELEMENT_THREAD_SUGGESTED)) { - PUT_ESCAPED (2, "flag", "GST_ELEMENT_THREADSUGGESTED"); - } - if (GST_FLAG_IS_SET (element, GST_ELEMENT_EVENT_AWARE)) { - PUT_ESCAPED (2, "flag", "GST_ELEMENT_EVENT_AWARE"); - } - PUT_END_TAG (1, "element-flags"); - - if (GST_IS_BIN (element)) { - PUT_START_TAG (1, "bin-flags"); - - if (GST_FLAG_IS_SET (element, GST_BIN_FLAG_MANAGER)) { - PUT_ESCAPED (2, "flag", "GST_BIN_FLAG_MANAGER"); - } - if (GST_FLAG_IS_SET (element, GST_BIN_SELF_SCHEDULABLE)) { - PUT_ESCAPED (2, "flag", "GST_BIN_SELF_SCHEDULABLE"); - } - if (GST_FLAG_IS_SET (element, GST_BIN_FLAG_PREFER_COTHREADS)) { - PUT_ESCAPED (2, "flag", "GST_BIN_FLAG_PREFER_COTHREADS"); - } - PUT_END_TAG (1, "bin-flags"); - } - - - PUT_START_TAG (1, "element-implementation"); - if (element->loopfunc) - PUT_STRING (2, "", - GST_DEBUG_FUNCPTR_NAME (element->loopfunc)); - - PUT_STRING (2, "", - GST_DEBUG_FUNCPTR_NAME (gstelement_class->change_state)); - -#ifndef GST_DISABLE_LOADSAVE - PUT_STRING (2, "", - GST_DEBUG_FUNCPTR_NAME (gstobject_class->save_thyself)); - PUT_STRING (2, "", - GST_DEBUG_FUNCPTR_NAME (gstobject_class->restore_thyself)); -#endif - PUT_END_TAG (1, "element-implementation"); - - PUT_START_TAG (1, "clocking-interaction"); - if (gst_element_requires_clock (element)) { - PUT_STRING (2, ""); - } - if (gst_element_provides_clock (element)) { - GstClock *clock; - - clock = gst_element_get_clock (element); - if (clock) - PUT_STRING (2, "", GST_OBJECT_NAME (clock)); - } - PUT_END_TAG (1, "clocking-interaction"); - -#ifndef GST_DISABLE_INDEX - if (gst_element_is_indexable (element)) { - PUT_STRING (1, ""); - } -#endif - - PUT_START_TAG (1, "pads"); - if (element->numpads) { - const GList *pads; - - pads = gst_element_get_pad_list (element); - while (pads) { - pad = GST_PAD (pads->data); - pads = g_list_next (pads); - realpad = GST_PAD_REALIZE (pad); - - PUT_START_TAG (2, "pad"); - PUT_ESCAPED (3, "name", gst_pad_get_name (pad)); - - if (gst_pad_get_direction (pad) == GST_PAD_SRC) - PUT_ESCAPED (3, "direction", "src"); - else if (gst_pad_get_direction (pad) == GST_PAD_SINK) - PUT_ESCAPED (3, "direction", "sink"); - else - PUT_ESCAPED (3, "direction", "unknown"); - - if (GST_IS_GHOST_PAD (pad)) - PUT_ESCAPED (3, "ghost", gst_pad_get_name (pad)); - - if (pad->padtemplate) - PUT_ESCAPED (3, "template", pad->padtemplate->name_template); - - PUT_START_TAG (3, "implementation"); - if (realpad->chainfunc) - PUT_STRING (4, "", - GST_DEBUG_FUNCPTR_NAME (realpad->chainfunc)); - if (realpad->getfunc) - PUT_STRING (4, "", - GST_DEBUG_FUNCPTR_NAME (realpad->getfunc)); - if (realpad->formatsfunc != gst_pad_get_formats_default) { - PUT_STRING (4, "", - GST_DEBUG_FUNCPTR_NAME (realpad->formatsfunc)); - print_formats (gst_pad_get_formats (GST_PAD (realpad)), 5); - PUT_END_TAG (4, "formats-function"); - } - if (realpad->convertfunc != gst_pad_convert_default) - PUT_STRING (4, "", - GST_DEBUG_FUNCPTR_NAME (realpad->convertfunc)); - if (realpad->eventfunc != gst_pad_event_default) - PUT_STRING (4, "", - GST_DEBUG_FUNCPTR_NAME (realpad->eventfunc)); - if (realpad->eventmaskfunc != gst_pad_get_event_masks_default) { - PUT_STRING (4, "", - GST_DEBUG_FUNCPTR_NAME (realpad->eventmaskfunc)); - print_event_masks (gst_pad_get_event_masks (GST_PAD (realpad)), 5); - PUT_END_TAG (4, "event-mask-func"); - } - if (realpad->queryfunc != gst_pad_query_default) - PUT_STRING (4, "", - GST_DEBUG_FUNCPTR_NAME (realpad->queryfunc)); - if (realpad->querytypefunc != gst_pad_get_query_types_default) { - PUT_STRING (4, "", - GST_DEBUG_FUNCPTR_NAME (realpad->querytypefunc)); - print_query_types (gst_pad_get_query_types (GST_PAD (realpad)), 5); - PUT_END_TAG (4, "query-type-func"); - } - - if (realpad->intlinkfunc != gst_pad_get_internal_links_default) - PUT_STRING (4, "", - GST_DEBUG_FUNCPTR_NAME (realpad->intlinkfunc)); - - if (realpad->bufferallocfunc) - PUT_STRING (4, "", - GST_DEBUG_FUNCPTR_NAME (realpad->bufferallocfunc)); - PUT_END_TAG (3, "implementation"); - - if (realpad->caps) { - print_caps (realpad->caps, 3); - } - PUT_END_TAG (2, "pad"); - } - } - PUT_END_TAG (1, "pads"); - - print_element_properties (element, 1); - print_element_dynparamaters (element, 1); - print_element_signals (element, 1); - - /* for compound elements */ - if (GST_IS_BIN (element)) { - PUT_START_TAG (1, "children"); - children = (GList *) gst_bin_get_list (GST_BIN (element)); - while (children) { - child = GST_ELEMENT (children->data); - children = g_list_next (children); - - PUT_ESCAPED (2, "child", GST_ELEMENT_NAME (child)); - } - PUT_END_TAG (1, "children"); - } - PUT_END_TAG (0, "element"); - - return 0; -} - -static void -print_element_list (void) -{ - GList *plugins; - - plugins = gst_registry_pool_plugin_list (); - while (plugins) { - GList *features; - GstPlugin *plugin; - - plugin = (GstPlugin *) (plugins->data); - plugins = g_list_next (plugins); - - features = gst_plugin_get_feature_list (plugin); - while (features) { - GstPluginFeature *feature; - - feature = GST_PLUGIN_FEATURE (features->data); - - if (GST_IS_ELEMENT_FACTORY (feature)) { - GstElementFactory *factory; - - factory = GST_ELEMENT_FACTORY (feature); - g_print ("%s: %s: %s\n", plugin->desc.name, - GST_PLUGIN_FEATURE_NAME (factory), factory->details.longname); - } -#ifndef GST_DISABLE_INDEX - else if (GST_IS_INDEX_FACTORY (feature)) { - GstIndexFactory *factory; - - factory = GST_INDEX_FACTORY (feature); - g_print ("%s: %s: %s\n", plugin->desc.name, - GST_PLUGIN_FEATURE_NAME (factory), factory->longdesc); - } -#endif - else if (GST_IS_TYPE_FIND_FACTORY (feature)) { - GstTypeFindFactory *factory; - - factory = GST_TYPE_FIND_FACTORY (feature); - if (factory->extensions) { - guint i = 0; - - g_print ("%s type: ", plugin->desc.name); - while (factory->extensions[i]) { - g_print ("%s%s", i > 0 ? ", " : "", factory->extensions[i]); - i++; - } - } else - g_print ("%s type: N/A\n", plugin->desc.name); - } else if (GST_IS_SCHEDULER_FACTORY (feature)) { - GstSchedulerFactory *factory; - - factory = GST_SCHEDULER_FACTORY (feature); - g_print ("%s: %s: %s\n", plugin->desc.name, - GST_PLUGIN_FEATURE_NAME (factory), factory->longdesc); - } else { - g_print ("%s: %s (%s)\n", plugin->desc.name, - GST_PLUGIN_FEATURE_NAME (feature), - g_type_name (G_OBJECT_TYPE (feature))); - } - - features = g_list_next (features); - } - } -} - -static void -print_plugin_info (GstPlugin * plugin) -{ - GList *features; - gint num_features = 0; - gint num_elements = 0; - gint num_autoplug = 0; - gint num_types = 0; - gint num_schedulers = 0; - gint num_indexes = 0; - gint num_other = 0; - - g_print ("Plugin Details:\n"); - g_print (" Name:\t\t%s\n", plugin->desc.name); - g_print (" Description:\t%s\n", plugin->desc.description); - 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 (" Package:\t%s\n", plugin->desc.package); - g_print (" Origin URL:\t%s\n", plugin->desc.origin); - g_print ("\n"); - - features = gst_plugin_get_feature_list (plugin); - - while (features) { - GstPluginFeature *feature; - - feature = GST_PLUGIN_FEATURE (features->data); - - if (GST_IS_ELEMENT_FACTORY (feature)) { - GstElementFactory *factory; - - factory = GST_ELEMENT_FACTORY (feature); - g_print (" %s: %s\n", GST_OBJECT_NAME (factory), - factory->details.longname); - num_elements++; - } -#ifndef GST_DISABLE_INDEX - else if (GST_IS_INDEX_FACTORY (feature)) { - GstIndexFactory *factory; - - factory = GST_INDEX_FACTORY (feature); - g_print (" %s: %s\n", GST_OBJECT_NAME (factory), factory->longdesc); - num_indexes++; - } -#endif - else if (GST_IS_TYPE_FIND_FACTORY (feature)) { - GstTypeFindFactory *factory; - - factory = GST_TYPE_FIND_FACTORY (feature); - if (factory->extensions) { - guint i = 0; - - g_print ("%s type: ", plugin->desc.name); - while (factory->extensions[i]) { - g_print ("%s%s", i > 0 ? ", " : "", factory->extensions[i]); - i++; - } - } else - g_print ("%s type: N/A\n", plugin->desc.name); - num_types++; - } else if (GST_IS_SCHEDULER_FACTORY (feature)) { - GstSchedulerFactory *factory; - - factory = GST_SCHEDULER_FACTORY (feature); - g_print (" %s: %s\n", GST_OBJECT_NAME (factory), factory->longdesc); - num_schedulers++; - } else { - g_print (" %s (%s)\n", gst_object_get_name (GST_OBJECT (feature)), - g_type_name (G_OBJECT_TYPE (feature))); - num_other++; - } - num_features++; - features = g_list_next (features); - } - g_print ("\n %d features:\n", num_features); - if (num_elements > 0) - g_print (" +-- %d elements\n", num_elements); - if (num_autoplug > 0) - g_print (" +-- %d autopluggers\n", num_autoplug); - if (num_types > 0) - g_print (" +-- %d types\n", num_types); - if (num_schedulers > 0) - g_print (" +-- %d schedulers\n", num_schedulers); - if (num_indexes > 0) - g_print (" +-- %d indexes\n", num_indexes); - if (num_other > 0) - g_print (" +-- %d other objects\n", num_other); - - g_print ("\n"); -} - - -int -main (int argc, char *argv[]) -{ - GstElementFactory *factory; - GstPlugin *plugin; - gchar *so; - struct poptOption options[] = { - {"gst-inspect-plugin", 'p', POPT_ARG_STRING | POPT_ARGFLAG_STRIP, NULL, 0, - "Show plugin details", NULL}, - {"gst-inspect-scheduler", 's', POPT_ARG_STRING | POPT_ARGFLAG_STRIP, NULL, - 0, - "Show scheduler details", NULL}, - POPT_TABLEEND - }; - - setlocale (LC_ALL, ""); - - gst_init_with_popt_table (&argc, &argv, options); - gst_control_init (&argc, &argv); - - PUT_STRING (0, ""); - - /* if no arguments, print out list of elements */ - if (argc == 1) { - print_element_list (); - - /* else we try to get a factory */ - } else { - /* first check for help */ - if (strstr (argv[1], "-help")) { - g_print ("Usage: %s\t\t\tList all registered elements\n", argv[0]); - g_print (" %s element-name\tShow element details\n", argv[0]); - g_print (" %s plugin-name[.so]\tShow information about plugin\n", - argv[0]); - return 0; - } - - /* only search for a factory if there's not a '.so' */ - if (!strstr (argv[1], ".so")) { - factory = gst_element_factory_find (argv[1]); - - /* if there's a factory, print out the info */ - if (factory) - return print_element_info (factory); - else { - GstPluginFeature *feature; - - /* FIXME implement other pretty print function for these */ - feature = gst_registry_pool_find_feature (argv[1], - GST_TYPE_SCHEDULER_FACTORY); - if (feature) { - g_print ("%s: a scheduler\n", argv[1]); - return 0; - } -#ifndef GST_DISABLE_INDEX - feature = gst_registry_pool_find_feature (argv[1], - GST_TYPE_INDEX_FACTORY); - if (feature) { - g_print ("%s: an index\n", argv[1]); - return 0; - } -#endif - feature = gst_registry_pool_find_feature (argv[1], - GST_TYPE_TYPE_FIND_FACTORY); - if (feature) { - g_print ("%s: a type find function\n", argv[1]); - return 0; - } -#ifndef GST_DISABLE_URI - feature = gst_registry_pool_find_feature (argv[1], - GST_TYPE_URI_HANDLER); - if (feature) { - g_print ("%s: an uri handler\n", argv[1]); - return 0; - } -#endif - } - } else { - /* strip the .so */ - so = strstr (argv[1], ".so"); - so[0] = '\0'; - } - - /* otherwise assume it's a plugin */ - plugin = gst_registry_pool_find_plugin (argv[1]); - - /* if there is such a plugin, print out info */ - - if (plugin) { - print_plugin_info (plugin); - } else { - g_print ("no such element or plugin '%s'\n", argv[1]); - return -1; - } - } - - return 0; -} diff --git a/tools/gst-xmllaunch.1.in b/tools/gst-xmllaunch.1.in deleted file mode 100644 index c6a3ba36b7..0000000000 --- a/tools/gst-xmllaunch.1.in +++ /dev/null @@ -1,63 +0,0 @@ -.TH "GStreamer" "1" "March 2001" -.SH "NAME" -gst\-xmllaunch \- build and run a GStreamer pipeline from an XML serialization -.SH "SYNOPSIS" -\fBgst\-xmllaunch\fR \fI[OPTION...]\fR XML\-FILE [ ELEMENT.PROPERTY=VALUE ... ] -.SH "DESCRIPTION" -.LP -\fIgst\-xmllaunch\fP is a tool that is used to build and run a basic -\fIGStreamer\fP pipeline, loading it from an XML description. You can -produce the XML description using gst-launch(1) with the -o option or by -calling gst_xml_write_file() in your own app. - -A simple commandline looks like: - - gst\-xmllaunch my\-pipeline.xml filesrc0.location=music.mp3 - -This sets the location property of the element named filesrc0 to the value -"music.mp3". See gst\-launch(1) for syntax on setting element names, and -gst\-inspect to see what properties various elements have. - -You can pass "-" as the XML\-FILE to read from stdin. - -XML\-FILE can be a URI as well, thanks to the wizardry of libxml. I'm not really -sure what all is supported, it seems http works just fine though. - -. -.SH "OPTIONS" -.l -\fIgst\-xmllaunch\fP accepts the following options: -.TP 8 -.B \-\-help -Print help synopsis and available FLAGS -.TP 8 -.B \-\-silent -Do not output status information -.TP 8 -.B \-\-exclude=TYPE, \-XTYPE -Do not output status information of TYPE -.TP 8 -.B \-\-output=FILE, \-oFILE -Save XML representation of pipeline to FILE and exit -.TP 8 -.B \-\-gst\-info\-mask=FLAGS -\fIGStreamer\fP info flags to set (list with \-\-help) -.TP 8 -.B \-\-gst\-debug\-mask=FLAGS -\fIGStreamer\fP debugging flags to set (list with \-\-help) -.TP 8 -.B \-\-gst\-mask=FLAGS -\fIGStreamer\fP info and debugging flags to set (list with \-\-help) -.TP 8 -.B \-\-gst\-plugin\-spew -\fIGStreamer\fP info flags to set -Enable printout of errors while loading \fIGStreamer\fP plugins -.TP 8 -.B \-\-gst\-plugin\-path=PATH -Add directories separated with ':' to the plugin search path -.SH "SEE ALSO" -.BR gst\-launch (1), -.BR gst\-register (1), -.BR gst\-inspect (1), -.SH "AUTHOR" -The GStreamer team at http://gstreamer.net/