Merge HEAD from CAPS-ROOT to CAPS-MERGE-1

Original commit message from CVS:
Merge HEAD from CAPS-ROOT to CAPS-MERGE-1
This commit is contained in:
David Schleef 2003-11-29 04:09:27 +00:00
parent 159f5098db
commit 1a3888c760
112 changed files with 4188 additions and 996 deletions

View file

@ -1,3 +1,13 @@
2003-11-14 Thomas Vander Stichele <thomas at apestaart dot org>
* put GST_CACHE_DIR in config.h, as ordered by iain
2003-11-14 Thomas Vander Stichele <thomas at apestaart dot org>
* Slap walters back into place.
* remove GST_CONFIG_DIR, it isn't used anymore, and it looks like
GST_CACHE_DIR replaces it (which is up for fixing next)
2003-06-02 Colin Walters <walters@verbum.org>
* Take over the world.

View file

@ -28,17 +28,18 @@ aclocaldir = $(datadir)/aclocal
aclocal_DATA = gst-element-check-@GST_MAJORMINOR@.m4
SUBDIRS = include gst libs tools \
$(SUBDIRS_TESTS) $(SUBDIRS_EXAMPLES) $(SUBDIRS_DOCS) \
pkgconfig po
$(SUBDIRS_TESTS) $(SUBDIRS_EXAMPLES) \
pkgconfig po \
$(SUBDIRS_DOCS)
# These are all the possible subdirs
DIST_SUBDIRS = include libs gst \
tools \
tests testsuite \
examples \
docs \
pkgconfig \
po
po \
docs
EXTRA_DIST = gstreamer.spec.in gst-element-check.m4 \
configure.ac autogen.sh depcomp \

View file

@ -3,7 +3,7 @@ AC_CANONICAL_TARGET([])
dnl when going to/from release please set the nano (fourth number) right !
dnl releases only do Wall, cvs and prerelease does Werror too
AS_VERSION(gstreamer, GST_VERSION, 0, 7, 1, 1, GST_CVS="no", GST_CVS="yes")
AS_VERSION(gstreamer, GST_VERSION, 0, 7, 2, 1, GST_CVS="no", GST_CVS="yes")
if test x$program_suffix = xNONE ; then
program_suffix=-$GST_VERSION_MAJOR.$GST_VERSION_MINOR
@ -168,7 +168,7 @@ dnl ====================================
dnl === GLib 2 ===
dnl Minimum required version of GLib2
dnl required for compilation without warnings
GLIB2_REQ="2.0.1"
GLIB2_REQ="2.2"
AC_SUBST(GLIB2_REQ)
dnl Check for glib2
@ -311,9 +311,9 @@ esac],
[:]) dnl Default value
AS_AC_EXPAND(GST_CACHE_DIR, $GST_CACHE_DIR)
AC_DEFINE_UNQUOTED(GST_CACHE_DIR, "$GST_CACHE_DIR", [Location of registry])
AC_MSG_NOTICE(Using $GST_CACHE_DIR as registry cache dir)
dnl building of tests
AC_ARG_ENABLE(tests,
AC_HELP_STRING([--disable-tests],[disable building test apps]),
@ -616,6 +616,7 @@ testsuite/indexers/Makefile
testsuite/parse/Makefile
testsuite/plugin/Makefile
testsuite/refcounting/Makefile
testsuite/tags/Makefile
testsuite/threads/Makefile
examples/Makefile
examples/autoplug/Makefile
@ -631,20 +632,21 @@ examples/queue/Makefile
examples/queue2/Makefile
examples/queue3/Makefile
examples/queue4/Makefile
examples/retag/Makefile
examples/thread/Makefile
examples/typefind/Makefile
examples/xml/Makefile
tools/Makefile
docs/Makefile
docs/version.entities
docs/faq/Makefile
docs/gst/Makefile
docs/libs/Makefile
docs/manual/Makefile
docs/pwg/Makefile
docs/plugins/Makefile
docs/plugins/gstreamer-plugins.types
docs/pwg/Makefile
docs/xsl/Makefile
docs/version.entities
pkgconfig/Makefile
stamp.h
pkgconfig/gstreamer.pc

1
docs/.gitignore vendored
View file

@ -5,3 +5,4 @@ Makefile.in
*.la
.deps
.libs
version.entities

View file

@ -12,14 +12,14 @@ SUBDIRS_DOCS =
endif
SUBDIRS = $(SUBDIRS_DOCS) $(SUBDIRS_PLUGINS)
DIST_SUBDIRS = faq manual pwg gst libs plugins xsl
DIST_SUBDIRS = gst faq manual pwg libs plugins xsl
EXTRA_DIST = \
slides manuals.mak htmlinstall.mak \
image-png image-pdf image-eps version.entities.in
upload:
@for a in manual pwg faq; do cd $$a; make upload; cd ..; done
@for a in manual faq pwg; do cd $$a; make upload; cd ..; done
dist-hook:
$(RM) -rf $(distdir)/random/CVS

1
docs/gst/.gitignore vendored
View file

@ -12,6 +12,7 @@ gstreamer-unused.txt
gstreamer-undocumented.txt
gstreamer-decl-list.txt
gstreamer-decl.txt
gstreamer-presed-scan.c
gstreamer-scan.c
gstreamer-scan
gstreamer.args

View file

@ -71,7 +71,7 @@ extra_files =
# CFLAGS and LDFLAGS for compiling scan program. Only needed if your app/lib
# contains GtkObjects/GObjects and you want to document signals and properties.
GTKDOC_CFLAGS = $(GST_CFLAGS)
GTKDOC_CFLAGS = $(GST_CFLAGS) -I$(top_builddir)
GTKDOC_LIBS = $(GST_LIBS) $(SCANOBJ_DEPS)
GTKDOC_CC=$(LIBTOOL) --mode=compile $(CC)
@ -126,15 +126,17 @@ all-local: html-build.stamp
scan-build.stamp: $(HFILE_GLOB) $(SCANOBJ_DEPS) $(basefiles)
@echo '*** Scanning header files ***'
if grep -l '^..*$$' $(srcdir)/$(DOC_MODULE).types > /dev/null ; then \
CC="$(GTKDOC_CC)" LD="$(GTKDOC_LD)" CFLAGS="$(GTKDOC_CFLAGS)" LDFLAGS="$(GTKDOC_LIBS)" $(GTK_DOC_SCANOBJ) --module=$(DOC_MODULE) --output-dir=$(srcdir) ; \
if test x"$(srcdir)" != x. ; then \
cp $(srcdir)/$(DOC_MODULE).types . ; \
fi ; \
CC="$(GTKDOC_CC)" LD="$(GTKDOC_LD)" CFLAGS="$(GTKDOC_CFLAGS)" LDFLAGS="$(GTKDOC_LIBS)" $(GTK_DOC_SCANOBJ) --module=$(DOC_MODULE) ; \
else \
cd $(srcdir) ; \
for i in $(SCANOBJ_FILES) ; do \
test -f $$i || touch $$i ; \
done \
fi
cd $(srcdir) && \
gtkdoc-scan --module=$(DOC_MODULE) --source-dir=$(DOC_SOURCE_DIR) --ignore-headers="$(IGNORE_HFILES)" $(SCAN_OPTIONS) $(EXTRA_HFILES)
gtkdoc-scan --module=$(DOC_MODULE) --source-dir=$(DOC_SOURCE_DIR) --ignore-headers="$(IGNORE_HFILES)" $(SCAN_OPTIONS) $(EXTRA_HFILES)
touch scan-build.stamp
$(DOC_MODULE)-decl.txt $(SCANOBJ_FILES): scan-build.stamp
@ -144,7 +146,11 @@ $(DOC_MODULE)-decl.txt $(SCANOBJ_FILES): scan-build.stamp
tmpl-build.stamp: $(DOC_MODULE)-decl.txt $(SCANOBJ_FILES) $(DOC_MODULE)-sections.txt $(DOC_OVERRIDES)
@echo '*** Rebuilding template files ***'
cd $(srcdir) && gtkdoc-mktmpl --module=$(DOC_MODULE)
if test x"$(srcdir)" != x. ; then \
cp $(srcdir)/$(DOC_MODULE)-decl.txt . ; \
cp $(srcdir)/$(DOC_MODULE)-sections.txt . ; \
fi
gtkdoc-mktmpl --module=$(DOC_MODULE)
touch tmpl-build.stamp
tmpl.stamp: tmpl-build.stamp
@ -154,7 +160,6 @@ tmpl.stamp: tmpl-build.stamp
sgml-build.stamp: tmpl.stamp $(CFILE_GLOB)
@echo '*** Building SGML ***'
cd $(srcdir) && \
gtkdoc-mkdb --module=$(DOC_MODULE) --source-dir=$(DOC_SOURCE_DIR) --main-sgml-file=$(DOC_MAIN_SGML_FILE) $(MKDB_OPTIONS)
touch sgml-build.stamp
@ -168,11 +173,12 @@ sgml.stamp: sgml-build.stamp
# use bytes; in gtkdoc-fixxref
html-build.stamp: sgml.stamp $(DOC_MAIN_SGML_FILE) $(content_files)
@echo '*** Building HTML ***'
test -d $(srcdir)/html || mkdir $(srcdir)/html
cd $(srcdir)/html && gtkdoc-mkhtml $(DOC_MODULE) ../$(DOC_MAIN_SGML_FILE)
test "x$(HTML_IMAGES)" = "x" || ( cd $(srcdir) && cp $(HTML_IMAGES) html )
test -d html || mkdir html
cd html && gtkdoc-mkhtml $(DOC_MODULE) $(srcdir)/../$(DOC_MAIN_SGML_FILE)
test "x$(HTML_IMAGES)" = "x" || for i in $(HTML_IMAGES) ; do \
cp $(srcdir)/$$i html ; done
@echo '-- Fixing Crossreferences'
cd $(srcdir) && LANG=C && gtkdoc-fixxref --module-dir=html --html-dir=$(HTML_DIR) $(FIXXREF_OPTIONS)
LANG=C && gtkdoc-fixxref --module-dir=html --html-dir=$(HTML_DIR) $(FIXXREF_OPTIONS)
touch html-build.stamp
endif
@ -194,10 +200,20 @@ distclean-local: clean
rm -rf tmpl/*.sgml.bak
rm -f $(DOC_MODULE).hierarchy
rm -f *.stamp || true
if test x"$(srcdir)" != x. ; then \
rm -f $(DOC_MODULE)-docs.sgml ; \
rm -f $(DOC_MODULE).types ; \
rm -f $(DOC_MODULE).interfaces ; \
rm -f $(DOC_MODULE).prerequisites ; \
rm -f $(DOC_MODULE)-sections.txt ; \
rm -rf tmpl/*.sgml ; \
fi
rm -rf *.o
# thomas: make docs parallel installable; devhelp requires majorminor too
if DOC_HTML
install-data-local:
$(mkinstalldirs) $(DESTDIR)$(TARGET_DIR)
$(mkinstalldirs) $(DESTDIR)$(TARGET_DIR)
(installfiles=`echo $(srcdir)/html/*.html $(srcdir)/html/*.png`; \
if test "$$installfiles" = '$(srcdir)/html/*.html'; \
then echo '-- Nothing to install' ; \
@ -211,7 +227,27 @@ install-data-local:
$(DESTDIR)$(TARGET_DIR)/$(DOC_MODULE)-@GST_MAJORMINOR@.devhelp; \
echo '-- Installing $(srcdir)/html/index.sgml' ; \
$(INSTALL_DATA) $(srcdir)/html/index.sgml $(DESTDIR)$(TARGET_DIR); \
fi)
fi)
uninstall-local:
(installfiles=`echo $(srcdir)/html/*.html $(srcdir)/html/*.png`; \
if test "$$installfiles" = '$(srcdir)/html/*.html'; \
then echo '-- Nothing to uninstall' ; \
else \
for i in $$installfiles; do \
rmfile=`basename $$i` ; \
echo '-- Uninstalling $(DESTDIR)$(TARGET_DIR)/'$$rmfile ; \
rm -f $(DESTDIR)$(TARGET_DIR)/$$rmfile; \
done; \
echo '-- Uninstalling $(DESTDIR)$(TARGET_DIR)/$(DOC_MODULE).devhelp' ; \
rm -f $(DESTDIR)$(TARGET_DIR)/$(DOC_MODULE)-@GST_MAJORMINOR@.devhelp; \
echo '-- Uninstalling $(DESTDIR)$(TARGET_DIR)/index.sgml' ; \
rm -f $(DESTDIR)$(TARGET_DIR)/index.sgml; \
fi)
rmdir -p --ignore-fail-on-non-empty $(DESTDIR)$(TARGET_DIR)
else
install-data-local:
uninstall-local:
endif
#
# Require gtk-doc when making dist

View file

@ -99,6 +99,14 @@ The autoplug object
</para>
<!-- ##### SIGNAL GstAutoplug::new-object ##### -->
<para>
</para>
@gstautoplug: the object which received the signal.
@arg1:
<!-- ##### ENUM GstAutoplugFlags ##### -->
<para>
The type of the autoplugger.
@ -141,11 +149,3 @@ The type of the autoplugger.
@Returns:
<!-- ##### SIGNAL GstAutoplug::new-object ##### -->
<para>
</para>
@gstautoplug: the object which received the signal.
@arg1:

View file

@ -262,6 +262,7 @@ The basic structure of a buffer.
@timestamp:
@duration:
@offset:
@offset_end:
@pool:
@pool_private:

View file

@ -406,24 +406,6 @@ The name used for tracing
@Returns:
<!-- ##### FUNCTION gst_caps_set_type_id ##### -->
<para>
</para>
@caps:
@type_id:
<!-- ##### FUNCTION gst_caps_get_type_id ##### -->
<para>
</para>
@caps:
@Returns:
<!-- ##### FUNCTION gst_caps_set_mime ##### -->
<para>

View file

@ -108,13 +108,6 @@ If this is defined, the <link linkend="gstreamer-gstinfo">debugging subsystem
<!-- ##### MACRO GST_DISABLE_TYPEFIND ##### -->
<para>
</para>
<!-- ##### MACRO GST_DISABLE_URI ##### -->
<para>

View file

@ -880,14 +880,6 @@ Queries if the Element is decoupled.
@obj: a #GstElement to query
<!-- ##### MACRO GST_ELEMENT_IS_EOS ##### -->
<para>
Query wether this element is in the End Of Stream state.
</para>
@obj: a #GstElement to query
<!-- ##### MACRO GST_ELEMENT_IS_EVENT_AWARE ##### -->
<para>
Query wether this element can handle events.
@ -989,6 +981,15 @@ Is triggered whenever an error occured.
@arg1: the error message
@arg2:
<!-- ##### SIGNAL GstElement::found-tag ##### -->
<para>
</para>
@gstelement: the object which received the signal.
@arg1:
@arg2:
<!-- ##### SIGNAL GstElement::new-pad ##### -->
<para>
Is triggered whenever a new pad is added to an element.

View file

@ -62,22 +62,8 @@ describes the element, mostly for the benefit of editors.
@longname:
@klass:
@license:
@description:
@version:
@author:
@copyright:
<!-- ##### FUNCTION gst_element_factory_new ##### -->
<para>
</para>
@name:
@type:
@details:
@Returns:
<!-- ##### FUNCTION gst_element_factory_find ##### -->
<para>
@ -88,15 +74,6 @@ describes the element, mostly for the benefit of editors.
@Returns:
<!-- ##### FUNCTION gst_element_factory_add_pad_template ##### -->
<para>
</para>
@elementfactory:
@templ:
<!-- ##### FUNCTION gst_element_factory_can_src_caps ##### -->
<para>
@ -137,51 +114,3 @@ describes the element, mostly for the benefit of editors.
@Returns:
<!-- ##### FUNCTION gst_element_factory_make_or_warn ##### -->
<para>
</para>
@factoryname:
@name:
@Returns:
<!-- ##### MACRO gst_element_factory_set_rank ##### -->
<para>
</para>
@factory:
@rank:
<!-- ##### MACRO GST_ELEMENT_RANK_MARGINAL ##### -->
<para>
The element is only marginally usefull for autoplugging
</para>
<!-- ##### MACRO GST_ELEMENT_RANK_NONE ##### -->
<para>
The plugin may not be used in autoplugging
</para>
<!-- ##### MACRO GST_ELEMENT_RANK_PRIMARY ##### -->
<para>
The plugin is well suited for autoplugging
</para>
<!-- ##### MACRO GST_ELEMENT_RANK_SECONDARY ##### -->
<para>
The plugin is suited for autoplugging but only as a second
candidate.
</para>

View file

@ -48,6 +48,7 @@ The different major types of events.
@GST_EVENT_INTERRUPT: mainly used by _get based elements when they were interrupted
while waiting for a buffer.
@GST_EVENT_NAVIGATION:
@GST_EVENT_TAG:
<!-- ##### MACRO GST_EVENT_TYPE ##### -->
<para>

View file

@ -233,21 +233,6 @@ default. If you want to define a default category, do it like this:
@Varargs:
<!-- ##### FUNCTION gst_debug_logv ##### -->
<para>
</para>
@category:
@level:
@file:
@function:
@line:
@object:
@format:
@args:
<!-- ##### FUNCTION gst_debug_log_default ##### -->
<para>

View file

@ -56,20 +56,19 @@ The plugin loading errors
@GST_PLUGIN_ERROR_MODULE: The plugin could not be loaded
@GST_PLUGIN_ERROR_DEPENDENCIES: The plugin has unresolved dependencies
@GST_PLUGIN_ERROR_NAME_MISMATCH:
<!-- ##### STRUCT GstPlugin ##### -->
<para>
The plugin object
</para>
@name:
@longname:
@desc:
@filename:
@features:
@numfeatures:
@manager:
@module:
@init_called:
<!-- ##### USER_FUNCTION GstPluginInitFunc ##### -->
<para>
@ -77,9 +76,10 @@ A plugin should provide a pointer to a function of this type in the plugin_desc
It will be called by the loader at statup.
</para>
@module: The <classname>GModule</classname> it was loaded from
@plugin: The plugin object that can be used to register stuff for this plugin.
@Returns: A boolean indicating success or failure.
<!-- # Unused Parameters # -->
@module: The <classname>GModule</classname> it was loaded from
<!-- ##### STRUCT GstPluginDesc ##### -->
@ -91,50 +91,14 @@ loaded will use this variable to initialize the plugin.
@major_version: The minor version of the gstreamer library this plugin was created with
@minor_version: The minor version of the gstreamer library this plugin was created with
@name: The name of the plugin
@description:
@plugin_init: The init function of this plugin.
<!-- ##### MACRO GST_PLUGIN_DESC ##### -->
<para>
A handy macro to define a plugin description. This macro handles with all the issues
involved with the different linking methods for this plugin.
</para>
@major: The major version of GStreamer this plugin was compiled against.
@minor: The minor version of GStreamer this plugin was compiled against.
@name: The name of the plugin.
@init: The init function of this plugin.
<!-- ##### MACRO GST_PLUGIN_DESC_DYNAMIC ##### -->
<para>
The macro used to define dynamically loaded plugins.
</para>
@major: The major version of GStreamer this plugin was compiled against.
@minor: The minor version of GStreamer this plugin was compiled against.
@name: The name of the plugin.
@init: The init function of this plugin.
<!-- ##### MACRO GST_PLUGIN_DESC_STATIC ##### -->
<para>
A macro used to define a statically linked plugin.
</para>
@major: The major version of GStreamer this plugin was compiled against.
@minor: The minor version of GStreamer this plugin was compiled against.
@name: The name of the plugin.
@init: The init function of this plugin.
<!-- ##### FUNCTION gst_plugin_new ##### -->
<para>
</para>
@filename:
@Returns:
@plugin_exit:
@version:
@license:
@copyright:
@package:
@origin:
<!-- ##### FUNCTION gst_plugin_set_name ##### -->
<para>
@ -163,15 +127,6 @@ A macro used to define a statically linked plugin.
@Returns:
<!-- ##### FUNCTION gst_plugin_set_longname ##### -->
<para>
</para>
@plugin:
@longname:
<!-- ##### FUNCTION gst_plugin_get_filename ##### -->
<para>
@ -210,16 +165,6 @@ A macro used to define a statically linked plugin.
@Returns:
<!-- ##### FUNCTION gst_plugin_load_plugin ##### -->
<para>
</para>
@plugin:
@error:
@Returns:
<!-- ##### FUNCTION gst_plugin_unload_plugin ##### -->
<para>

View file

@ -196,6 +196,142 @@ GstAudioSink
GstAudioSrc
<!-- ##### SECTION ./tmpl/gstautoplug.sgml:Long_Description ##### -->
<para>
GstAutoplug is an abstract class that is used for constructing and
linking elements. Two types of autopluggers exist: renderer ones and non
renderer ones. The renderer autopluggers will not have any src pads while the
non renderer ones do.
</para>
<para>
You first need to create a suitable autoplugger with gst_autoplug_factory_make()
(see #GstAutoplugFactory).
The name of the autoplugger must be one of the registered autopluggers
(see #GstStaticAutoplug and #GstStaticAutoplugRender).
</para>
<para>
If the autoplugger supports the RENDERER API, use gst_autoplug_to_renderers() to
create a bin that links the src caps to the specified renderer elements. You can
then add the bin to a pipeline and run it.
<programlisting>
GstAutoplug *autoplug;
GstElement *element;
GstElement *sink;
/* create a static autoplugger */
autoplug = gst_autoplug_factory_make ("staticrender");
/* create an osssink */
sink = gst_element_factory_make ("osssink", "our_sink");
/* create an element that can play audio/mp3 through osssink */
element = gst_autoplug_to_renderers (autoplug,
gst_caps_new (
"sink_audio_caps",
"audio/mp3",
NULL
),
sink,
NULL);
/* add the element to a bin and link the sink pad */
...
</programlisting>
</para>
<para>
If the autoplugger supports the CAPS API, use gst_autoplug_to_caps() to
link the src caps to the destination caps. The created bin will have src caps
compatible with the provided sink caps.
<programlisting>
GstAutoplug *autoplug;
GstElement *element;
/* create a static autoplugger */
autoplug = gst_autoplug_factory_make ("static");
/* create an element that converts audio/mp3 to audio/raw */
element = gst_autoplug_to_caps (autoplug,
gst_caps_new (
"sink_audio_caps",
"audio/mp3",
NULL
),
gst_caps_new (
"src_audio_caps",
"audio/raw",
NULL
),
NULL);
/* add the element to a bin and link the src/sink pads */
...
</programlisting>
</para>
<para>
Optionally you can get a notification when a new object is added to the created
pipeline with a g_signal_connect to the "new_object" signal.
</para>
<para>
Use the regular gst_object_destroy() call to destroy the autoplugger.
</para>
<!-- ##### SECTION ./tmpl/gstautoplug.sgml:See_Also ##### -->
<para>
#GstStaticAutoplug, #GstStaticAutoplugRender
</para>
<!-- ##### SECTION ./tmpl/gstautoplug.sgml:Short_Description ##### -->
Automatically create and link elements
<!-- ##### SECTION ./tmpl/gstautoplug.sgml:Title ##### -->
GstAutoplug
<!-- ##### SECTION ./tmpl/gstautoplugfactory.sgml:Long_Description ##### -->
<para>
An autoplugfactory is used to create instances of an autoplugger. It
can be added to a #GstPlugin as it extends #GstPluginFeature.
</para>
<para>
Use gst_autoplug_factory_new() to create a new autoplugger which can be registered
to a plugin with gst_plugin_add_feature().
</para>
<para>
Use gst_autoplug_factory_find() to find the named autoplugfactory.
or use gst_autoplug_factory_get_list() to get a list of all available autopluggers.
</para>
<para>
Once an autoplugfactory has been obtained use gst_autoplug_factory_create() to
instantiate a real autoplugger. Optionally gst_autoplug_factory_make() to create
a autoplugger from the named factory.
</para>
<para>
Use gst_autoplug_factory_destroy() to remove the factory from the global list.
</para>
<!-- ##### SECTION ./tmpl/gstautoplugfactory.sgml:See_Also ##### -->
<para>
#GstAutoplug, #GstPlugin, #GstPluginFeature.
</para>
<!-- ##### SECTION ./tmpl/gstautoplugfactory.sgml:Short_Description ##### -->
Create autopluggers from a factory.
<!-- ##### SECTION ./tmpl/gstautoplugfactory.sgml:Title ##### -->
GstAutoplugFactory
<!-- ##### SECTION ./tmpl/gstbufferpool-default.sgml:Long_Description ##### -->
<para>
@ -994,6 +1130,48 @@ The start point of a filter graph
GstSrc
<!-- ##### SECTION ./tmpl/gststaticautoplug.sgml:Long_Description ##### -->
<para>
This autoplugger will create a non threaded element before running the
pipeline.
</para>
<!-- ##### SECTION ./tmpl/gststaticautoplug.sgml:See_Also ##### -->
<para>
</para>
<!-- ##### SECTION ./tmpl/gststaticautoplug.sgml:Short_Description ##### -->
A static autoplugger.
<!-- ##### SECTION ./tmpl/gststaticautoplug.sgml:Title ##### -->
GstStaticAutoplug
<!-- ##### SECTION ./tmpl/gststaticautoplugrender.sgml:Long_Description ##### -->
<para>
this autoplugger will create a threaded element that can be used
in media players.
</para>
<!-- ##### SECTION ./tmpl/gststaticautoplugrender.sgml:See_Also ##### -->
<para>
</para>
<!-- ##### SECTION ./tmpl/gststaticautoplugrender.sgml:Short_Description ##### -->
An autoplugger made for media playback
<!-- ##### SECTION ./tmpl/gststaticautoplugrender.sgml:Title ##### -->
GstStaticAutoplugRender
<!-- ##### SECTION ./tmpl/gststatistics.sgml:Long_Description ##### -->
<para>
The plugin doesn't alter the data but provides statistics about
@ -1056,27 +1234,6 @@ Cache time and byteoffsets.
GstTimeCache
<!-- ##### SECTION ./tmpl/gsttypefind.sgml:Long_Description ##### -->
<para>
This element can be added to the pipeline and will notify the listener of
the detected mime type of the stream. It is used in autoplugging.
</para>
<!-- ##### SECTION ./tmpl/gsttypefind.sgml:See_Also ##### -->
<para>
</para>
<!-- ##### SECTION ./tmpl/gsttypefind.sgml:Short_Description ##### -->
Detect the mime type of a media stream
<!-- ##### SECTION ./tmpl/gsttypefind.sgml:Title ##### -->
GstTypeFind
<!-- ##### SECTION ./tmpl/gsttypes.sgml:Long_Description ##### -->
<para>
@ -1835,6 +1992,12 @@ to the current function, i.e. "('element')"
@format: printf-style format string
@args...: printf arguments
<!-- ##### MACRO GST_DISABLE_TYPEFIND ##### -->
<para>
</para>
<!-- ##### MACRO GST_DISKSRC ##### -->
<para>
@ -1898,6 +2061,13 @@ Queries whether the cothread holding this element needs to be stopped.
@obj: The element to query
<!-- ##### MACRO GST_ELEMENT_IS_EOS ##### -->
<para>
Query wether this element is in the End Of Stream state.
</para>
@obj: a #GstElement to query
<!-- ##### MACRO GST_ELEMENT_IS_MULTI_IN ##### -->
<para>
Query whether this object has multiple input pads.
@ -1906,6 +2076,31 @@ Query whether this object has multiple input pads.
@obj: Element to query for multiple input pads.
<!-- ##### MACRO GST_ELEMENT_RANK_MARGINAL ##### -->
<para>
The element is only marginally usefull for autoplugging
</para>
<!-- ##### MACRO GST_ELEMENT_RANK_NONE ##### -->
<para>
The plugin may not be used in autoplugging
</para>
<!-- ##### MACRO GST_ELEMENT_RANK_PRIMARY ##### -->
<para>
The plugin is well suited for autoplugging
</para>
<!-- ##### MACRO GST_ELEMENT_RANK_SECONDARY ##### -->
<para>
The plugin is suited for autoplugging but only as a second
candidate.
</para>
<!-- ##### MACRO GST_ESDSINK ##### -->
<para>
@ -2769,6 +2964,37 @@ Get the flag indicating the properties are fixed from the template.
@plugin:
<!-- ##### MACRO GST_PLUGIN_DESC ##### -->
<para>
A handy macro to define a plugin description. This macro handles with all the issues
involved with the different linking methods for this plugin.
</para>
@major: The major version of GStreamer this plugin was compiled against.
@minor: The minor version of GStreamer this plugin was compiled against.
@name: The name of the plugin.
@init: The init function of this plugin.
<!-- ##### MACRO GST_PLUGIN_DESC_DYNAMIC ##### -->
<para>
The macro used to define dynamically loaded plugins.
</para>
@major: The major version of GStreamer this plugin was compiled against.
@minor: The minor version of GStreamer this plugin was compiled against.
@name: The name of the plugin.
@init: The init function of this plugin.
<!-- ##### MACRO GST_PLUGIN_DESC_STATIC ##### -->
<para>
A macro used to define a statically linked plugin.
</para>
@major: The major version of GStreamer this plugin was compiled against.
@minor: The minor version of GStreamer this plugin was compiled against.
@name: The name of the plugin.
@init: The init function of this plugin.
<!-- ##### MACRO GST_PROPS_BOOL_ID ##### -->
<para>
@ -4242,6 +4468,35 @@ The frequency.
</para>
<!-- ##### STRUCT GstAutoplug ##### -->
<para>
The autoplug object
</para>
<!-- ##### SIGNAL GstAutoplug::new-object ##### -->
<para>
</para>
@gstautoplug: the object which received the signal.
@arg1:
<!-- ##### STRUCT GstAutoplugFactory ##### -->
<para>
The autoplugfactory object
</para>
<!-- ##### ENUM GstAutoplugFlags ##### -->
<para>
The type of the autoplugger.
</para>
@GST_AUTOPLUG_TO_CAPS:
@GST_AUTOPLUG_TO_RENDERER:
@GST_AUTOPLUG_FLAG_LAST:
<!-- ##### STRUCT GstAutoplugNode ##### -->
<para>
@ -7144,6 +7399,29 @@ must be defined to activate the tracing functionality.
@factories:
@Returns:
<!-- ##### FUNCTION gst_autoplug_factory_create ##### -->
<para>
</para>
@factory:
@Returns:
<!-- ##### FUNCTION gst_autoplug_factory_destroy ##### -->
<para>
</para>
@factory:
<!-- ##### FUNCTION gst_autoplug_factory_find ##### -->
<para>
</para>
@name:
@Returns:
<!-- ##### FUNCTION gst_autoplug_factory_get_list ##### -->
<para>
@ -7189,6 +7467,24 @@ must be defined to activate the tracing functionality.
@parent:
@Returns:
<!-- ##### FUNCTION gst_autoplug_factory_make ##### -->
<para>
</para>
@name:
@Returns:
<!-- ##### FUNCTION gst_autoplug_factory_new ##### -->
<para>
</para>
@name:
@longdesc:
@type:
@Returns:
<!-- ##### FUNCTION gst_autoplug_factory_save_thyself ##### -->
<para>
@ -7212,6 +7508,14 @@ must be defined to activate the tracing functionality.
@fac:
<!-- ##### FUNCTION gst_autoplug_signal_new_object ##### -->
<para>
</para>
@autoplug:
@object:
<!-- ##### FUNCTION gst_autoplug_sp ##### -->
<para>
@ -7222,6 +7526,28 @@ must be defined to activate the tracing functionality.
@factories:
@Returns:
<!-- ##### FUNCTION gst_autoplug_to_caps ##### -->
<para>
</para>
@autoplug:
@srccaps:
@sinkcaps:
@Varargs:
@Returns:
<!-- ##### FUNCTION gst_autoplug_to_renderers ##### -->
<para>
</para>
@autoplug:
@srccaps:
@target:
@Varargs:
@Returns:
<!-- ##### FUNCTION gst_bin_add_managed_element ##### -->
<para>
@ -7704,6 +8030,14 @@ safely be modified.
@caps:
<!-- ##### FUNCTION gst_caps_get_type_id ##### -->
<para>
</para>
@caps:
@Returns:
<!-- ##### FUNCTION gst_caps_list_check_compatibility ##### -->
<para>
@ -7741,6 +8075,14 @@ safely be modified.
@Returns:
@count:
<!-- ##### FUNCTION gst_caps_set_type_id ##### -->
<para>
</para>
@caps:
@type_id:
<!-- ##### FUNCTION gst_clock_activate ##### -->
<para>
@ -7915,6 +8257,20 @@ safely be modified.
@data:
@Returns:
<!-- ##### FUNCTION gst_debug_logv ##### -->
<para>
</para>
@category:
@level:
@file:
@function:
@line:
@object:
@format:
@args:
<!-- ##### FUNCTION gst_debug_print_stack_trace ##### -->
<para>
@ -7998,6 +8354,14 @@ of an element he doesn't need anymore.
@a:
@b:
<!-- ##### FUNCTION gst_element_factory_add_pad_template ##### -->
<para>
</para>
@elementfactory:
@templ:
<!-- ##### FUNCTION gst_element_factory_add_sink ##### -->
<para>
@ -8054,6 +8418,25 @@ of an element he doesn't need anymore.
@parent:
@Returns:
<!-- ##### FUNCTION gst_element_factory_make_or_warn ##### -->
<para>
</para>
@factoryname:
@name:
@Returns:
<!-- ##### FUNCTION gst_element_factory_new ##### -->
<para>
</para>
@name:
@type:
@details:
@Returns:
<!-- ##### FUNCTION gst_element_factory_register ##### -->
<para>
@ -8070,6 +8453,14 @@ of an element he doesn't need anymore.
@parent:
@Returns:
<!-- ##### MACRO gst_element_factory_set_rank ##### -->
<para>
</para>
@factory:
@rank:
<!-- ##### FUNCTION gst_element_flags_get_type ##### -->
<para>
@ -9294,6 +9685,15 @@ Destroys the pipeline.
@name:
@Returns:
<!-- ##### FUNCTION gst_plugin_load_plugin ##### -->
<para>
</para>
@plugin:
@error:
@Returns:
<!-- ##### FUNCTION gst_plugin_load_thyself ##### -->
<para>
@ -9308,6 +9708,14 @@ Destroys the pipeline.
@mime:
<!-- ##### FUNCTION gst_plugin_new ##### -->
<para>
</para>
@filename:
@Returns:
<!-- ##### FUNCTION gst_plugin_save_thyself ##### -->
<para>
@ -9316,6 +9724,14 @@ Destroys the pipeline.
@parent:
@Returns:
<!-- ##### FUNCTION gst_plugin_set_longname ##### -->
<para>
</para>
@plugin:
@longname:
<!-- ##### FUNCTION gst_plugin_unload_all ##### -->
<para>
@ -10040,6 +10456,19 @@ Destroy the scheduler
</para>
<!-- ##### FUNCTION gst_type_find_factory_register ##### -->
<para>
</para>
@plugin:
@name:
@rank:
@func:
@extensions:
@possible_caps:
@data:
<!-- ##### FUNCTION gst_type_get_sink_to_src ##### -->
<para>
@ -10088,6 +10517,15 @@ Destroy the scheduler
@parent:
@Returns:
<!-- ##### FUNCTION gst_uri_handler_create ##### -->
<para>
</para>
@handler:
@name:
@Returns:
<!-- ##### FUNCTION gst_uri_handler_destroy ##### -->
<para>
@ -10095,6 +10533,43 @@ Destroy the scheduler
@handler:
<!-- ##### FUNCTION gst_uri_handler_find ##### -->
<para>
</para>
@name:
@Returns:
<!-- ##### FUNCTION gst_uri_handler_find_by_uri ##### -->
<para>
</para>
@uri:
@Returns:
<!-- ##### FUNCTION gst_uri_handler_make_by_uri ##### -->
<para>
</para>
@uri:
@name:
@Returns:
<!-- ##### FUNCTION gst_uri_handler_new ##### -->
<para>
</para>
@name:
@uri:
@longdesc:
@element:
@property:
@Returns:
<!-- ##### FUNCTION gst_util_get_bool_arg ##### -->
<para>

View file

@ -98,17 +98,3 @@ gst_type_find_factory_register()
@Returns:
<!-- ##### FUNCTION gst_type_find_factory_register ##### -->
<para>
</para>
@plugin:
@name:
@rank:
@func:
@extensions:
@possible_caps:
@data:

View file

@ -15,54 +15,3 @@ and the element property that can handle a given URI.
</para>
<!-- ##### FUNCTION gst_uri_handler_new ##### -->
<para>
</para>
@name:
@uri:
@longdesc:
@element:
@property:
@Returns:
<!-- ##### FUNCTION gst_uri_handler_find ##### -->
<para>
</para>
@name:
@Returns:
<!-- ##### FUNCTION gst_uri_handler_find_by_uri ##### -->
<para>
</para>
@uri:
@Returns:
<!-- ##### FUNCTION gst_uri_handler_create ##### -->
<para>
</para>
@handler:
@name:
@Returns:
<!-- ##### FUNCTION gst_uri_handler_make_by_uri ##### -->
<para>
</para>
@uri:
@name:
@Returns:

View file

@ -110,10 +110,6 @@ All GstElements can be serialized to an XML presentation and subsequently loaded
</para>
@:
@:
@:
@gstxml: the object which received the signal.
@arg1:
@arg2:
@ -123,7 +119,7 @@ All GstElements can be serialized to an XML presentation and subsequently loaded
</para>
@gstxml: the object which received the signal.
@arg1:
@arg2:
@:
@:
@:

View file

@ -2,6 +2,7 @@
# I really don't like this hack, but automake doesn't seem to want to
# install directory trees :(
if DOC_HTML
install-data-local: html
mkdir -p $(docdir)
cp -pr $(HTML_DAT) $(docdir)
@ -9,3 +10,7 @@ install-data-local: html
uninstall-local:
for part in $(HTML_DAT); do rm -rf $(docdir)/$$part; done
rmdir $(docdir)
else
install-data-local:
uninstall-local:
endif

13
docs/libs/.gitignore vendored
View file

@ -1,12 +1,15 @@
Makefile
Makefile.in
*.stamp
html
xml
gstreamer-libs-unused.txt
gstreamer-libs-undocumented.txt
Makefile
Makefile.in
gstreamer-libs-decl.txt
gstreamer-libs-decl-list.txt
*.stamp
gstreamer-libs-presed-scan.c
gstreamer-libs-undocumented.txt
gstreamer-libs-unused.txt
gstreamer-libs.args
gstreamer-libs.hierarchy
gstreamer-libs.interfaces
gstreamer-libs.prerequisites
gstreamer-libs.signals

View file

@ -72,7 +72,7 @@ extra_files =
# CFLAGS and LDFLAGS for compiling scan program. Only needed if your app/lib
# contains GtkObjects/GObjects and you want to document signals and properties.
GTKDOC_CFLAGS = $(GST_CFLAGS)
GTKDOC_CFLAGS = $(GST_CFLAGS) -I$(top_builddir)
GTKDOC_LIBS = $(GST_LIBS) $(SCANOBJ_DEPS)
GTKDOC_CC=$(LIBTOOL) --mode=compile $(CC)
@ -126,14 +126,17 @@ scan-build.stamp: $(HFILE_GLOB) $(SCANOBJ_DEPS) $(basefiles)
@echo '*** Scanning header files ***'
if grep -l '^..*$$' $(srcdir)/$(DOC_MODULE).types > /dev/null ; then \
CC="$(GTKDOC_CC)" LD="$(GTKDOC_LD)" CFLAGS="$(GTKDOC_CFLAGS)" LDFLAGS="$(GTKDOC_LIBS)" $(GTK_DOC_SCANOBJ) --module=$(DOC_MODULE) --output-dir=$(srcdir) ; \
if test x"$(srcdir)" != x. ; then \
cp $(srcdir)/$(DOC_MODULE).types . ; \
fi ; \
CC="$(GTKDOC_CC)" LD="$(GTKDOC_LD)" CFLAGS="$(GTKDOC_CFLAGS)" LDFLAGS="$(GTKDOC_LIBS)" $(GTK_DOC_SCANOBJ) --module=$(DOC_MODULE) ; \
else \
cd $(srcdir) ; \
for i in $(SCANOBJ_FILES) ; do \
test -f $$i || touch $$i ; \
done \
fi
cd $(srcdir) && \
gtkdoc-scan --module=$(DOC_MODULE) --source-dir=$(DOC_SOURCE_DIR) --ignore-headers="$(IGNORE_HFILES)" $(SCAN_OPTIONS) $(EXTRA_HFILES)
gtkdoc-scan --module=$(DOC_MODULE) --source-dir=$(DOC_SOURCE_DIR) --ignore-headers="$(IGNORE_HFILES)" $(SCAN_OPTIONS) $(EXTRA_HFILES)
touch scan-build.stamp
$(DOC_MODULE)-decl.txt $(SCANOBJ_FILES): scan-build.stamp
@ -143,7 +146,11 @@ $(DOC_MODULE)-decl.txt $(SCANOBJ_FILES): scan-build.stamp
tmpl-build.stamp: $(DOC_MODULE)-decl.txt $(SCANOBJ_FILES) $(DOC_MODULE)-sections.txt $(DOC_OVERRIDES)
@echo '*** Rebuilding template files ***'
cd $(srcdir) && gtkdoc-mktmpl --module=$(DOC_MODULE)
if test x"$(srcdir)" != x. ; then \
cp $(srcdir)/$(DOC_MODULE)-decl.txt . ; \
cp $(srcdir)/$(DOC_MODULE)-sections.txt . ; \
fi
gtkdoc-mktmpl --module=$(DOC_MODULE)
touch tmpl-build.stamp
tmpl.stamp: tmpl-build.stamp
@ -153,7 +160,6 @@ tmpl.stamp: tmpl-build.stamp
sgml-build.stamp: tmpl.stamp $(CFILE_GLOB)
@echo '*** Building SGML ***'
cd $(srcdir) && \
gtkdoc-mkdb --module=$(DOC_MODULE) --source-dir=$(DOC_SOURCE_DIR) --main-sgml-file=$(DOC_MAIN_SGML_FILE) $(MKDB_OPTIONS)
touch sgml-build.stamp
@ -167,11 +173,12 @@ sgml.stamp: sgml-build.stamp
# use bytes; in gtkdoc-fixxref
html-build.stamp: sgml.stamp $(DOC_MAIN_SGML_FILE) $(content_files)
@echo '*** Building HTML ***'
test -d $(srcdir)/html || mkdir $(srcdir)/html
cd $(srcdir)/html && gtkdoc-mkhtml $(DOC_MODULE) ../$(DOC_MAIN_SGML_FILE)
test "x$(HTML_IMAGES)" = "x" || ( cd $(srcdir) && cp $(HTML_IMAGES) html )
test -d html || mkdir html
cd html && gtkdoc-mkhtml $(DOC_MODULE) $(srcdir)/../$(DOC_MAIN_SGML_FILE)
test "x$(HTML_IMAGES)" = "x" || for i in $(HTML_IMAGES) ; do \
cp $(srcdir)/$$i html ; done
@echo '-- Fixing Crossreferences'
cd $(srcdir) && gtkdoc-fixxref --module-dir=html --html-dir=$(HTML_DIR) $(FIXXREF_OPTIONS)
LANG=C && gtkdoc-fixxref --module-dir=html --html-dir=$(HTML_DIR) $(FIXXREF_OPTIONS)
touch html-build.stamp
endif
@ -192,7 +199,18 @@ distclean-local: clean
rm -rf tmpl/*.sgml.bak
rm -f $(DOC_MODULE).hierarchy
rm -f *.stamp || true
if test x"$(srcdir)" != x. ; then \
rm -f $(DOC_MODULE)-docs.sgml ; \
rm -f $(DOC_MODULE).types ; \
rm -f $(DOC_MODULE).interfaces ; \
rm -f $(DOC_MODULE).prerequisites ; \
rm -f $(DOC_MODULE)-sections.txt ; \
rm -rf tmpl/*.sgml ; \
fi
rm -f *.o
if DOC_HTML
install-data-local:
$(mkinstalldirs) $(DESTDIR)$(TARGET_DIR)
(installfiles=`echo $(srcdir)/html/*.html $(srcdir)/html/*.png`; \
@ -209,6 +227,26 @@ install-data-local:
echo '-- Installing $(srcdir)/html/index.sgml' ; \
$(INSTALL_DATA) $(srcdir)/html/index.sgml $(DESTDIR)$(TARGET_DIR); \
fi)
uninstall-local:
(installfiles=`echo $(srcdir)/html/*.html $(srcdir)/html/*.png`; \
if test "$$installfiles" = '$(srcdir)/html/*.html'; \
then echo '-- Nothing to uninstall' ; \
else \
for i in $$installfiles; do \
rmfile=`basename $$i` ; \
echo '-- Uninstalling $(DESTDIR)$(TARGET_DIR)/'$$rmfile ; \
rm -f $(DESTDIR)$(TARGET_DIR)/$$rmfile; \
done; \
echo '-- Uninstalling $(DESTDIR)$(TARGET_DIR)/$(DOC_MODULE).devhelp' ; \
rm -f $(DESTDIR)$(TARGET_DIR)/$(DOC_MODULE)-@GST_MAJORMINOR@.devhelp; \
echo '-- Uninstalling $(DESTDIR)$(TARGET_DIR)/index.sgml' ; \
rm -f $(DESTDIR)$(TARGET_DIR)/index.sgml; \
fi)
rmdir -p --ignore-fail-on-non-empty $(DESTDIR)$(TARGET_DIR)
else
install-data-local:
uninstall-local:
endif
#
# Require gtk-doc when making dist

View file

@ -11,6 +11,22 @@
</para>
<variablelist>
<varlistentry>
<term>23 Nov 2003</term>
<listitem>
<para>
<emphasis>Uraeus</emphasis>: ah yes, the sleeping part, my mind
is not multitasking so I was still thinking about exercise
</para>
<para>
<emphasis>dolphy</emphasis>: Uraeus: your mind is multitasking
</para>
<para>
<emphasis>dolphy</emphasis>: Uraeus: you just miss low latency patches
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>14 Sep 2002</term>
<listitem>

View file

@ -11,6 +11,22 @@
</para>
<variablelist>
<varlistentry>
<term>23 Nov 2003</term>
<listitem>
<para>
<emphasis>Uraeus</emphasis>: ah yes, the sleeping part, my mind
is not multitasking so I was still thinking about exercise
</para>
<para>
<emphasis>dolphy</emphasis>: Uraeus: your mind is multitasking
</para>
<para>
<emphasis>dolphy</emphasis>: Uraeus: you just miss low latency patches
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>14 Sep 2002</term>
<listitem>

View file

@ -89,7 +89,7 @@ $(BUILDDIR)/$(MAIN): $(XML) $(CSS)
@-mkdir -p $(BUILDDIR)
@for a in $(XML); do cp $(srcdir)/$$a $(BUILDDIR); done
@for a in $(CSS); do cp $(srcdir)/$$a $(BUILDDIR); done
@cp $(srcdir)/../version.entities $(BUILDDIR)
@cp ../version.entities $(BUILDDIR)
html/index.html: $(BUILDDIR)/$(MAIN) $(PNG_BUILT) $(FIG_SRC)
@echo "*** Generating HTML output ***"
@ -120,7 +120,7 @@ $(DOC).pdf: $(DOC).ps
# @export LC_PAPER=$(PAPER_LOCALE) && xmlto pdf $(MAIN)
# @rm image.entities
clean:
clean-local:
-$(RM) -r $(BUILDDIR)
-$(RM) -r html
-$(RM) $(DOC).ps
@ -165,8 +165,8 @@ $(BUILDIMAGESDIR)/%.ps: %.png
@cat $< | pngtopnm | pnmtops -noturn > $@ 2> /dev/null
# make sure xml validates properly
check-local:
xmllint -noout -valid $(MAIN)
#check-local:
# xmllint -noout -valid $(srcdir)/$(MAIN)
### this is a website upload target

View file

@ -1,5 +1,14 @@
Canonical caps/structure strings (those created by gst_caps_to_string()
and gst_structure_to_string()) do not have AUTO_VALUE.
Goals:
- UTF-8 clean
- SIMPLE_STRINGs should cover most simple cases that don't interfere
with other parts of the gst_caps or gst_parse grammar
- forward-parsed grammar
- quoted strings handle backslash escaping as well as XML-style (&ack;)
escaping
CAPS = STRUCTURE [ ';' STRUCTURE ]*
@ -27,12 +36,12 @@ STRING = ["][^"]["]
| ['][^'][']
| SIMPLE_STRING
SIMPLE_STRING = [A-Za-z][A-Za-z0-9]*
SIMPLE_STRING = [A-Za-z0-9_+-:./]+
TYPE = "int" | "i" | "float" | "f" | "double" | "d" | "fourcc" | "4"
| "boolean" | "bool" | "b"
| GTYPE
Canonical Examples:

View file

@ -4,12 +4,35 @@ else
GST_LOADSAVE_DIRS = xml typefind
endif
SUBDIRS = $(GST_LOADSAVE_DIRS) \
helloworld \
queue queue2 queue3 queue4 \
launch thread plugins mixer cutter pingpong manual
SUBDIRS = \
helloworld \
queue \
queue2 \
queue3 \
queue4 \
launch \
thread \
plugins \
mixer \
cutter \
pingpong \
manual \
retag \
$(GST_LOADSAVE_DIRS)
DIST_SUBDIRS = helloworld helloworld2 \
queue queue2 queue3 queue4 \
launch thread xml plugins typefind mixer cutter pingpong manual
DIST_SUBDIRS = helloworld \
queue \
queue2 \
queue3 \
queue4 \
launch \
thread \
plugins \
mixer \
cutter \
pingpong \
manual \
xml \
typefind \
retag

View file

@ -69,7 +69,7 @@ endif
EXTRA_libgstreamer_@GST_MAJORMINOR@_la_SOURCES = gstcpuid_i386.s gstmarshal.list gstxml.c gstparse.c gsttrace.c
SUBDIRS = $(GST_PARSE_DIRS) $(GST_REGISTRY_DIRS) . elements schedulers $(GST_INDEX_DIRS)
SUBDIRS = $(GST_PARSE_DIRS) $(GST_REGISTRY_DIRS) . autoplug elements schedulers $(GST_INDEX_DIRS)
DIST_SUBDIRS = autoplug elements parse registries schedulers indexers
libgstreamer_@GST_MAJORMINOR@_la_SOURCES = \
@ -104,6 +104,8 @@ libgstreamer_@GST_MAJORMINOR@_la_SOURCES = \
gstscheduler.c \
gststructure.c \
gstsystemclock.c \
gsttag.c \
gsttaginterface.c \
gstthread.c \
gstthreaddummy.c \
$(GST_TRACE_SRC) \
@ -121,11 +123,12 @@ libgstreamer_@GST_MAJORMINOR@_la_SOURCES = \
BUILT_SOURCES = gstversion.h gstconfig.h gstmarshal.h gstmarshal.c gstenumtypes.h $(GST_ENUMTYPES_SRC)
CLEANFILES = gstmarshal.h gstmarshal.c gstenumtypes.h $(GST_ENUMTYPES_SRC)
DISTCLEANFILES = gstversion.h gstconfig.h
libgstreamer_@GST_MAJORMINOR@_la_CFLAGS = -D_GNU_SOURCE \
$(GST_CFLAGS) \
-DG_LOG_DOMAIN=g_log_domain_gstreamer \
-DGST_CACHE_DIR=\""$(GST_CACHE_DIR)"\" \
-DGST_MAJORMINOR=\""$(GST_MAJORMINOR)"\"
libgstreamer_@GST_MAJORMINOR@_la_LIBADD = $(LIBGST_LIBS) $(GST_PARSE_LIBADD) $(GST_REGISTRY_LIBADD)
libgstreamer_@GST_MAJORMINOR@_la_LDFLAGS = @GST_LT_LDFLAGS@ -version-info @GST_LIBVERSION@
@ -165,6 +168,8 @@ gst_headers = \
gstscheduler.h \
gststructure.h \
gstsystemclock.h \
gsttag.h \
gsttaginterface.h \
gstthread.h \
gsttrace.h \
gsttrashstack.h \
@ -227,12 +232,4 @@ gstenumtypes.c: $(gst_headers)
--vtail " { 0, NULL, NULL }\n };\n etype = g_@type@_register_static (\"@EnumName@\", values);\n }\n return etype;\n}\n" \
$^ > gstenumtypes.c
# Don't want the generated marshal files in the dist
dist-hook:
rm -f $(distdir)/gstmarshal.c $(distdir)/gstmarshal.h
# Clean generated files
distclean-local:
rm -f $(top_builddir)/gst/gstmarshal.c $(top_builddir)/gst/gstmarshal.h
EXTRA_DIST = ROADMAP

View file

@ -440,7 +440,7 @@ spider_find_suggest (gpointer data, guint probability, const GstCaps2 *caps)
GST_INFO ("suggest %u, %s", probability, caps_str);
g_free (caps_str);
if (probability > find->best_probability) {
gst_caps2_replace (&find->caps, caps);
gst_caps2_replace (&find->caps, gst_caps2_copy (caps));
find->best_probability = probability;
}
}

View file

@ -119,7 +119,7 @@ gst_buffer_store_class_init (gpointer g_class, gpointer class_data)
gst_buffer_store_signals[BUFFER_ADDED] = g_signal_new ("buffer-added",
G_TYPE_FROM_CLASS (g_class), G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GstBufferStoreClass, buffer_added), continue_accu, NULL,
gst_marshal_BOOLEAN__POINTER, G_TYPE_BOOLEAN, 1, G_TYPE_POINTER);
gst_marshal_BOOLEAN__POINTER, G_TYPE_BOOLEAN, 1, GST_TYPE_BUFFER);
store_class->cleared = gst_buffer_store_cleared_func;
store_class->buffer_added = gst_buffer_store_add_buffer_func;

View file

@ -175,8 +175,8 @@ gst_fakesink_class_init (GstFakeSinkClass *klass)
gst_fakesink_signals[SIGNAL_HANDOFF] =
g_signal_new ("handoff", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GstFakeSinkClass, handoff), NULL, NULL,
g_cclosure_marshal_VOID__POINTER, G_TYPE_NONE, 1,
G_TYPE_POINTER);
gst_marshal_VOID__POINTER_OBJECT, G_TYPE_NONE, 2,
GST_TYPE_BUFFER, GST_TYPE_PAD);
gobject_class->set_property = GST_DEBUG_FUNCPTR (gst_fakesink_set_property);
gobject_class->get_property = GST_DEBUG_FUNCPTR (gst_fakesink_get_property);

View file

@ -271,8 +271,8 @@ gst_fakesrc_class_init (GstFakeSrcClass *klass)
gst_fakesrc_signals[SIGNAL_HANDOFF] =
g_signal_new ("handoff", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GstFakeSrcClass, handoff), NULL, NULL,
g_cclosure_marshal_VOID__POINTER, G_TYPE_NONE, 1,
G_TYPE_POINTER);
gst_marshal_VOID__POINTER_OBJECT, G_TYPE_NONE, 2,
GST_TYPE_BUFFER, GST_TYPE_PAD);
gobject_class->set_property = GST_DEBUG_FUNCPTR (gst_fakesrc_set_property);
gobject_class->get_property = GST_DEBUG_FUNCPTR (gst_fakesrc_get_property);

View file

@ -69,6 +69,7 @@ GST_PAD_FORMATS_FUNCTION (gst_filesink_get_formats,
static void gst_filesink_base_init (gpointer g_class);
static void gst_filesink_class_init (GstFileSinkClass *klass);
static void gst_filesink_init (GstFileSink *filesink);
static void gst_filesink_dispose (GObject *object);
static void gst_filesink_set_property (GObject *object, guint prop_id,
const GValue *value, GParamSpec *pspec);
@ -83,6 +84,8 @@ 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_uri_handler_init (gpointer g_iface, gpointer iface_data);
static GstElementStateReturn gst_filesink_change_state (GstElement *element);
static GstElementClass *parent_class = NULL;
@ -105,7 +108,14 @@ gst_filesink_get_type (void)
0,
(GInstanceInitFunc)gst_filesink_init,
};
static const GInterfaceInfo urihandler_info = {
gst_filesink_uri_handler_init,
NULL,
NULL
};
filesink_type = g_type_register_static (GST_TYPE_ELEMENT, "GstFileSink", &filesink_info, 0);
g_type_add_interface_static (filesink_type, GST_TYPE_URI_HANDLER, &urihandler_info);
GST_DEBUG_CATEGORY_INIT (gst_filesink_debug, "filesink", 0, "filesink element");
}
@ -138,8 +148,8 @@ gst_filesink_class_init (GstFileSinkClass *klass)
gobject_class->set_property = gst_filesink_set_property;
gobject_class->get_property = gst_filesink_get_property;
gobject_class->dispose = gst_filesink_dispose;
}
static void
gst_filesink_init (GstFileSink *filesink)
{
@ -158,7 +168,38 @@ gst_filesink_init (GstFileSink *filesink)
filesink->filename = NULL;
filesink->file = NULL;
}
static void
gst_filesink_dispose (GObject *object)
{
GstFileSink *sink = GST_FILESINK (object);
G_OBJECT_CLASS (parent_class)->dispose (object);
g_free (sink->uri);
sink->uri = NULL;
g_free (sink->filename);
sink->filename = NULL;
}
static gboolean
gst_filesink_set_location (GstFileSink *sink, const gchar *location)
{
/* the element must be stopped or paused in order to do this */
if (GST_STATE (sink) > GST_STATE_PAUSED)
return FALSE;
if (GST_STATE (sink) == GST_STATE_PAUSED &&
GST_FLAG_IS_SET (sink, GST_FILESINK_OPEN))
return FALSE;
g_free (sink->filename);
g_free (sink->uri);
sink->filename = g_strdup (location);
sink->uri = gst_uri_construct ("file", location);
if (GST_STATE (sink) == GST_STATE_PAUSED)
gst_filesink_open_file (sink);
return TRUE;
}
static void
gst_filesink_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
{
@ -169,16 +210,7 @@ gst_filesink_set_property (GObject *object, guint prop_id, const GValue *value,
switch (prop_id) {
case ARG_LOCATION:
/* the element must be stopped or paused in order to do this */
g_return_if_fail (GST_STATE (sink) <= GST_STATE_PAUSED);
if (GST_STATE (sink) == GST_STATE_PAUSED)
g_return_if_fail (!GST_FLAG_IS_SET (sink, GST_FILESINK_OPEN));
if (sink->filename)
g_free (sink->filename);
sink->filename = g_strdup (g_value_get_string (value));
if (GST_STATE (sink) == GST_STATE_PAUSED)
gst_filesink_open_file (sink);
gst_filesink_set_location (sink, g_value_get_string (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@ -435,3 +467,54 @@ gst_filesink_change_state (GstElement *element)
return GST_STATE_SUCCESS;
}
/*** GSTURIHANDLER INTERFACE *************************************************/
static guint
gst_filesink_uri_get_type (void)
{
return GST_URI_SINK;
}
static gchar **
gst_filesink_uri_get_protocols(void)
{
static gchar *protocols[] = {"file", NULL};
return protocols;
}
static const gchar *
gst_filesink_uri_get_uri (GstURIHandler *handler)
{
GstFileSink *sink = GST_FILESINK (handler);
return sink->uri;
}
static gboolean
gst_filesink_uri_set_uri (GstURIHandler *handler, const gchar *uri)
{
gchar *protocol, *location;
gboolean ret;
GstFileSink *sink = GST_FILESINK (handler);
protocol = gst_uri_get_protocol (uri);
if (strcmp (protocol, "file") != 0) {
g_free (protocol);
return FALSE;
}
g_free (protocol);
location = gst_uri_get_location (uri);
ret = gst_filesink_set_location (sink, location);
g_free (location);
return ret;
}
static void
gst_filesink_uri_handler_init (gpointer g_iface, gpointer iface_data)
{
GstURIHandlerInterface *iface = (GstURIHandlerInterface *) g_iface;
iface->get_type = gst_filesink_uri_get_type;
iface->get_protocols = gst_filesink_uri_get_protocols;
iface->get_uri = gst_filesink_uri_get_uri;
iface->set_uri = gst_filesink_uri_set_uri;
}

View file

@ -53,6 +53,7 @@ struct _GstFileSink {
GstElement element;
gchar *filename;
gchar *uri;
FILE *file;
guint64 data_written;

View file

@ -128,6 +128,7 @@ static void gst_filesrc_set_property (GObject *object, guint prop_id,
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 gboolean gst_filesrc_srcpad_event (GstPad *pad, GstEvent *event);
static gboolean gst_filesrc_srcpad_query (GstPad *pad, GstQueryType type,
@ -135,6 +136,8 @@ static gboolean gst_filesrc_srcpad_query (GstPad *pad, GstQueryType type,
static GstElementStateReturn gst_filesrc_change_state (GstElement *element);
static void gst_filesrc_uri_handler_init (gpointer g_iface, gpointer iface_data);
static GstElementClass *parent_class = NULL;
/*static guint gst_filesrc_signals[LAST_SIGNAL] = { 0 };*/
@ -156,8 +159,15 @@ gst_filesrc_get_type(void)
0,
(GInstanceInitFunc)gst_filesrc_init,
};
static const GInterfaceInfo urihandler_info = {
gst_filesrc_uri_handler_init,
NULL,
NULL
};
filesrc_type = g_type_register_static (GST_TYPE_ELEMENT, "GstFileSrc", &filesrc_info, 0);
g_type_add_interface_static (filesrc_type, GST_TYPE_URI_HANDLER, &urihandler_info);
GST_DEBUG_CATEGORY_INIT (gst_filesrc_debug, "filesrc", 0, "filesrc element");
}
return filesrc_type;
@ -262,8 +272,32 @@ gst_filesrc_dispose (GObject *object)
g_mutex_free (src->map_regions_lock);
if (src->filename)
g_free (src->filename);
if (src->uri)
g_free (src->uri);
}
static gboolean
gst_filesrc_set_location (GstFileSrc *src, const gchar *location)
{
/* the element must be stopped in order to do this */
if (GST_STATE (src) == GST_STATE_PLAYING)
return FALSE;
if (src->filename) g_free (src->filename);
if (src->uri) g_free (src->uri);
/* clear the filename if we get a NULL (is that possible?) */
if (location == NULL) {
src->filename = NULL;
src->uri = NULL;
} else {
src->filename = g_strdup (location);
src->uri = gst_uri_construct ("file", src->filename);
}
g_object_notify (G_OBJECT (src), "location");
gst_uri_handler_new_uri (GST_URI_HANDLER (src), src->uri);
return TRUE;
}
static void
gst_filesrc_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
@ -277,19 +311,7 @@ gst_filesrc_set_property (GObject *object, guint prop_id, const GValue *value, G
switch (prop_id) {
case ARG_LOCATION:
/* the element must be stopped in order to do this */
g_return_if_fail (GST_STATE (src) < GST_STATE_PLAYING);
if (src->filename) g_free (src->filename);
/* clear the filename if we get a NULL (is that possible?) */
if (g_value_get_string (value) == NULL) {
gst_element_set_state (GST_ELEMENT (object), GST_STATE_NULL);
src->filename = NULL;
/* otherwise set the new filename */
} else {
src->filename = g_strdup (g_value_get_string (value));
}
g_object_notify (G_OBJECT (src), "location");
gst_filesrc_set_location (src, g_value_get_string (value));
break;
case ARG_BLOCKSIZE:
src->block_size = g_value_get_ulong (value);
@ -506,8 +528,10 @@ gst_filesrc_get_mmap (GstFileSrc *src)
/* check to see if we're going to overflow the end of the file */
if (readend > src->filelen) {
readsize = src->filelen - src->curoffset;
readend = src->curoffset + readsize;
if (!gst_filesrc_check_filesize (src) || readend > src->filelen) {
readsize = src->filelen - src->curoffset;
readend = src->curoffset + readsize;
}
}
GST_LOG ("attempting to read %08lx, %08lx, %08lx, %08lx",
@ -599,7 +623,7 @@ gst_filesrc_get_mmap (GstFileSrc *src)
/* subbuffer it */
buf = gst_buffer_create_sub (src->mapbuf, src->curoffset - nextmap, readsize);
GST_BUFFER_OFFSET (buf) = mapstart + src->curoffset - nextmap;
GST_BUFFER_OFFSET (buf) = GST_BUFFER_OFFSET (src->mapbuf) + src->curoffset - nextmap;
}
}
}
@ -613,6 +637,7 @@ gst_filesrc_get_mmap (GstFileSrc *src)
}
/* we're done, return the buffer */
g_assert (src->curoffset == GST_BUFFER_OFFSET (buf));
src->curoffset += GST_BUFFER_SIZE(buf);
return buf;
}
@ -626,7 +651,9 @@ gst_filesrc_get_read (GstFileSrc *src)
readsize = src->block_size;
if (src->curoffset + readsize > src->filelen) {
readsize = src->filelen - src->curoffset;
if (!gst_filesrc_check_filesize (src) || src->curoffset + readsize > src->filelen) {
readsize = src->filelen - src->curoffset;
}
}
buf = gst_buffer_new_and_alloc (readsize);
@ -675,11 +702,14 @@ gst_filesrc_get (GstPad *pad)
}
/* check for EOF */
g_assert (src->curoffset <= src->filelen);
if (src->curoffset == src->filelen) {
GST_DEBUG_OBJECT (src, "eos %" G_GINT64_FORMAT" %" G_GINT64_FORMAT,
src->curoffset, src->filelen);
gst_element_set_eos (GST_ELEMENT (src));
return GST_DATA (gst_event_new (GST_EVENT_EOS));
if (!gst_filesrc_check_filesize (src) || src->curoffset >= src->filelen) {
GST_DEBUG_OBJECT (src, "eos %" G_GINT64_FORMAT" %" G_GINT64_FORMAT,
src->curoffset, src->filelen);
gst_element_set_eos (GST_ELEMENT (src));
return GST_DATA (gst_event_new (GST_EVENT_EOS));
}
}
if (src->using_mmap){
@ -689,6 +719,22 @@ gst_filesrc_get (GstPad *pad)
}
}
/* TRUE if the filesize of the file was updated */
static gboolean
gst_filesrc_check_filesize (GstFileSrc *src)
{
struct stat stat_results;
g_return_val_if_fail (GST_FLAG_IS_SET (src ,GST_FILESRC_OPEN), FALSE);
fstat(src->fd, &stat_results);
GST_DEBUG_OBJECT (src, "checked filesize on %s (was %"G_GUINT64_FORMAT", is %"G_GUINT64_FORMAT")",
src->filename, src->filelen, (guint64) stat_results.st_size);
if (src->filelen == (guint64) stat_results.st_size)
return FALSE;
src->filelen = stat_results.st_size;
return TRUE;
}
/* open the file and mmap it, necessary to go to READY state */
static gboolean
gst_filesrc_open_file (GstFileSrc *src)
@ -799,6 +845,7 @@ gst_filesrc_srcpad_query (GstPad *pad, GstQueryType type,
if (*format != GST_FORMAT_BYTES) {
return FALSE;
}
gst_filesrc_check_filesize (src);
*value = src->filelen;
break;
case GST_QUERY_POSITION:
@ -842,20 +889,25 @@ gst_filesrc_srcpad_event (GstPad *pad, GstEvent *event)
switch (GST_EVENT_SEEK_METHOD (event)) {
case GST_SEEK_METHOD_SET:
if (offset > src->filelen)
goto error;
if (offset > src->filelen && (!gst_filesrc_check_filesize (src) || offset > src->filelen)) {
goto error;
}
src->curoffset = offset;
GST_DEBUG_OBJECT (src, "seek set pending to %" G_GINT64_FORMAT, src->curoffset);
break;
case GST_SEEK_METHOD_CUR:
if (offset + src->curoffset > src->filelen)
goto error;
if (!gst_filesrc_check_filesize (src) || offset + src->curoffset > src->filelen)
goto error;
src->curoffset += offset;
GST_DEBUG_OBJECT (src, "seek cur pending to %" G_GINT64_FORMAT, src->curoffset);
break;
case GST_SEEK_METHOD_END:
if (ABS (offset) > src->filelen)
if (ABS (offset) > src->filelen) {
if (!gst_filesrc_check_filesize (src) || ABS (offset) > src->filelen)
goto error;
goto error;
}
src->curoffset = src->filelen - ABS (offset);
GST_DEBUG_OBJECT (src, "seek end pending to %" G_GINT64_FORMAT, src->curoffset);
break;
@ -888,3 +940,55 @@ error:
gst_event_unref (event);
return FALSE;
}
/*** GSTURIHANDLER INTERFACE *************************************************/
static guint
gst_filesrc_uri_get_type (void)
{
return GST_URI_SRC;
}
static gchar **
gst_filesrc_uri_get_protocols(void)
{
static gchar *protocols[] = {"file", NULL};
return protocols;
}
static const gchar *
gst_filesrc_uri_get_uri (GstURIHandler *handler)
{
GstFileSrc *src = GST_FILESRC (handler);
return src->uri;
}
static gboolean
gst_filesrc_uri_set_uri (GstURIHandler *handler, const gchar *uri)
{
gchar *protocol, *location;
gboolean ret;
GstFileSrc *src = GST_FILESRC (handler);
protocol = gst_uri_get_protocol (uri);
if (strcmp (protocol, "file") != 0) {
g_free (protocol);
return FALSE;
}
g_free (protocol);
location = gst_uri_get_location (uri);
ret = gst_filesrc_set_location (src, location);
g_free (location);
return ret;
}
static void
gst_filesrc_uri_handler_init (gpointer g_iface, gpointer iface_data)
{
GstURIHandlerInterface *iface = (GstURIHandlerInterface *) g_iface;
iface->get_type = gst_filesrc_uri_get_type;
iface->get_protocols = gst_filesrc_uri_get_protocols;
iface->get_uri = gst_filesrc_uri_get_uri;
iface->set_uri = gst_filesrc_uri_set_uri;
}

View file

@ -58,6 +58,7 @@ struct _GstFileSrc {
guint pagesize; /* system page size*/
gchar *filename; /* filename */
gchar *uri; /* caching the URI */
gint fd; /* open file descriptor*/
off_t filelen; /* what's the file length?*/

View file

@ -145,8 +145,8 @@ gst_identity_class_init (GstIdentityClass *klass)
gst_identity_signals[SIGNAL_HANDOFF] =
g_signal_new ("handoff", G_TYPE_FROM_CLASS(klass), G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GstIdentityClass, handoff), NULL, NULL,
g_cclosure_marshal_VOID__POINTER, G_TYPE_NONE, 1,
G_TYPE_POINTER);
gst_marshal_VOID__POINTER, G_TYPE_NONE, 1,
GST_TYPE_BUFFER);
gobject_class->set_property = GST_DEBUG_FUNCPTR (gst_identity_set_property);
gobject_class->get_property = GST_DEBUG_FUNCPTR (gst_identity_get_property);

View file

@ -85,11 +85,13 @@ debug_log_handler (const gchar *log_domain,
enum {
ARG_VERSION=1,
ARG_FATAL_WARNINGS,
#ifndef GST_DISABLE_GST_DEBUG
ARG_DEBUG_LEVEL,
ARG_DEBUG,
ARG_DEBUG_DISABLE,
ARG_DEBUG_NO_COLOR,
ARG_DEBUG_HELP,
#endif
ARG_DISABLE_CPU_OPT,
ARG_PLUGIN_SPEW,
ARG_PLUGIN_PATH,
@ -390,9 +392,11 @@ init_pre (void)
}
/* we need threading to be enabled right here */
_gst_debug_init();
#ifdef ENABLE_NLS
bindtextdomain (GETTEXT_PACKAGE, GST_LOCALEDIR);
bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
#endif /* ENABLE_NLS */
#ifndef GST_DISABLE_REGISTRY
{
@ -529,6 +533,7 @@ init_post (void)
_gst_plugin_initialize ();
_gst_event_initialize ();
_gst_buffer_initialize ();
_gst_tag_initialize ();
#ifndef GST_DISABLE_REGISTRY
if (!_gst_registry_fixed) {
@ -572,20 +577,48 @@ init_post (void)
return TRUE;
}
#ifndef GST_DISABLE_GST_DEBUG
static gint
sort_by_category_name (gconstpointer a, gconstpointer b)
{
return strcmp (gst_debug_category_get_name ((GstDebugCategory *) a),
gst_debug_category_get_name ((GstDebugCategory *) b));
}
static void
gst_debug_help (void)
{
GSList *cats, *walk;
GSList *list, *walk;
GList *list2, *walk2;
if (!init_post ())
exit (1);
walk2 = list2 = gst_registry_pool_plugin_list ();
while (walk2) {
GstPlugin *plugin = GST_PLUGIN (walk2->data);
walk2 = g_list_next (walk2);
if (!gst_plugin_is_loaded (plugin)) {
#ifndef GST_DISABLE_REGISTRY
if (GST_IS_REGISTRY (plugin->manager)) {
GST_CAT_LOG (GST_CAT_PLUGIN_LOADING, "loading plugin %s", plugin->desc.name);
if (gst_registry_load_plugin (GST_REGISTRY (plugin->manager), plugin) != GST_REGISTRY_OK)
GST_CAT_WARNING (GST_CAT_PLUGIN_LOADING, "loading plugin %s failed", plugin->desc.name);
}
#endif /* GST_DISABLE_REGISTRY */
}
}
g_list_free (list2);
list = gst_debug_get_all_categories ();
walk = list = g_slist_sort (list, sort_by_category_name);
walk = cats = gst_debug_get_all_categories ();
g_print ("\n");
g_print ("name level description\n");
g_print ("---------------------+--------+--------------------------------\n");
while (walk) {
/* unused when debugging is disabled */
G_GNUC_UNUSED GstDebugCategory *cat = (GstDebugCategory *) walk->data;
GstDebugCategory *cat = (GstDebugCategory *) walk->data;
if (gst_debug_is_colored ()) {
gchar *color = gst_debug_construct_term_color (cat->color);
@ -605,9 +638,10 @@ gst_debug_help (void)
}
walk = g_slist_next (walk);
}
g_slist_free (list);
g_print ("\n");
}
#endif
static void
init_popt_callback (poptContext context, enum poptCallbackReason reason,
@ -631,6 +665,7 @@ init_popt_callback (poptContext context, enum poptCallbackReason reason,
fatal_mask |= G_LOG_LEVEL_WARNING | G_LOG_LEVEL_CRITICAL;
g_log_set_always_fatal (fatal_mask);
break;
#ifndef GST_DISABLE_GST_DEBUG
case ARG_DEBUG_LEVEL: {
gint tmp = 0;
tmp = strtol (arg, NULL, 0);
@ -651,6 +686,7 @@ init_popt_callback (poptContext context, enum poptCallbackReason reason,
case ARG_DEBUG_HELP:
gst_debug_help ();
exit (0);
#endif
case ARG_DISABLE_CPU_OPT:
_gst_enable_cpu_opt = FALSE;
break;

View file

@ -27,40 +27,42 @@
#include <glib.h>
#include <popt.h>
#include <gst/gstversion.h>
#include <gst/gstenumtypes.h>
#include <gst/gsttypes.h>
#include <gst/gstversion.h>
#include <gst/gstinfo.h>
#include <gst/gstobject.h>
#include <gst/gstpad.h>
#include <gst/gstbin.h>
#include <gst/gstbuffer.h>
#include <gst/gstbufferpool-default.h>
#include <gst/gstcaps2.h>
#include <gst/gstclock.h>
#include <gst/gstcpu.h>
#include <gst/gstelement.h>
#include <gst/gstbin.h>
#include <gst/gstevent.h>
#include <gst/gstindex.h>
#include <gst/gstinfo.h>
#include <gst/gstinterface.h>
#include <gst/gstobject.h>
#include <gst/gstpad.h>
#include <gst/gstpipeline.h>
#include <gst/gstthread.h>
#include <gst/gsttypefind.h>
#include <gst/gstcaps2.h>
#include <gst/gststructure.h>
#include <gst/gstplugin.h>
#include <gst/gstscheduler.h>
#include <gst/gststructure.h>
#include <gst/gstsystemclock.h>
#include <gst/gsttag.h>
#include <gst/gsttaginterface.h>
#include <gst/gstthread.h>
#include <gst/gsttrace.h>
#include <gst/gsttypefind.h>
#include <gst/gsturi.h>
#include <gst/gsturitype.h>
#include <gst/gstutils.h>
#include <gst/gsttrace.h>
#include <gst/gstxml.h>
#include <gst/gstscheduler.h>
#include <gst/gstevent.h>
#include <gst/gstclock.h>
#include <gst/gstsystemclock.h>
#include <gst/gstinterface.h>
#include <gst/gstvalue.h>
#include <gst/gstxml.h>
#include <gst/gstparse.h>
#include <gst/gstregistry.h>
#include <gst/gstregistrypool.h>
#include <gst/gstenumtypes.h>
/* API compatibility stuff */
#include <gst/gstcompat.h>

View file

@ -135,11 +135,11 @@ gst_bin_class_init (GstBinClass * klass)
gst_bin_signals[ELEMENT_ADDED] =
g_signal_new ("element_added", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (GstBinClass, element_added), NULL, NULL,
gst_marshal_VOID__POINTER, G_TYPE_NONE, 1, G_TYPE_POINTER);
gst_marshal_VOID__POINTER, G_TYPE_NONE, 1, GST_TYPE_ELEMENT);
gst_bin_signals[ELEMENT_REMOVED] =
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__POINTER, G_TYPE_NONE, 1, G_TYPE_POINTER);
gst_marshal_VOID__POINTER, 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),

View file

@ -167,6 +167,7 @@ gst_buffer_default_copy (GstBuffer *buffer)
GST_BUFFER_TIMESTAMP (copy) = GST_BUFFER_TIMESTAMP (buffer);
GST_BUFFER_DURATION (copy) = GST_BUFFER_DURATION (buffer);
GST_BUFFER_OFFSET (copy) = GST_BUFFER_OFFSET (buffer);
GST_BUFFER_OFFSET_END (copy) = GST_BUFFER_OFFSET_END (buffer);
GST_BUFFER_BUFFERPOOL (copy) = NULL;
GST_BUFFER_POOL_PRIVATE (copy) = NULL;
@ -204,6 +205,7 @@ gst_buffer_new (void)
GST_BUFFER_TIMESTAMP (newbuf) = GST_CLOCK_TIME_NONE;
GST_BUFFER_DURATION (newbuf) = GST_CLOCK_TIME_NONE;
GST_BUFFER_OFFSET (newbuf) = GST_BUFFER_OFFSET_NONE;
GST_BUFFER_OFFSET_END (newbuf) = GST_BUFFER_OFFSET_NONE;
GST_BUFFER_BUFFERPOOL (newbuf) = NULL;
GST_BUFFER_POOL_PRIVATE (newbuf) = NULL;
@ -335,8 +337,9 @@ gst_buffer_create_sub (GstBuffer *parent, guint offset, guint size)
GST_BUFFER_TIMESTAMP (buffer) = GST_CLOCK_TIME_NONE;
GST_BUFFER_OFFSET (buffer) = GST_BUFFER_OFFSET_NONE;
}
GST_BUFFER_DURATION (buffer) = GST_CLOCK_TIME_NONE;
GST_BUFFER_DURATION (buffer) = GST_CLOCK_TIME_NONE;
GST_BUFFER_OFFSET_END (buffer) = GST_BUFFER_OFFSET_NONE;
/* make sure nobody overwrites data as it would overwrite in the parent.
* data in parent cannot be overwritten because we hold a ref */
GST_DATA_FLAG_SET (parent, GST_DATA_READONLY);
@ -453,13 +456,17 @@ gst_buffer_span (GstBuffer *buf1, guint32 offset, GstBuffer *buf2, guint32 len)
/* if we completely merged the two buffers (appended), we can
* calculate the duration too. Also make sure we's not messing with
* invalid DURATIONS */
if (offset == 0 && buf1->size + buf2->size == len &&
GST_BUFFER_DURATION_IS_VALID (buf1) &&
GST_BUFFER_DURATION_IS_VALID (buf2))
{
/* add duration */
GST_BUFFER_DURATION (newbuf) = GST_BUFFER_DURATION (buf1) +
GST_BUFFER_DURATION (buf2);
if (offset == 0 && buf1->size + buf2->size == len) {
if (GST_BUFFER_DURATION_IS_VALID (buf1) &&
GST_BUFFER_DURATION_IS_VALID (buf2)) {
/* add duration */
GST_BUFFER_DURATION (newbuf) = GST_BUFFER_DURATION (buf1) +
GST_BUFFER_DURATION (buf2);
}
if (GST_BUFFER_OFFSET_END_IS_VALID (buf2)) {
/* add offset_end */
GST_BUFFER_OFFSET_END (newbuf) = GST_BUFFER_OFFSET_END (buf2);
}
}
return newbuf;

View file

@ -63,6 +63,7 @@ extern GType _gst_buffer_pool_type;
#define GST_BUFFER_DURATION(buf) (GST_BUFFER(buf)->duration)
#define GST_BUFFER_FORMAT(buf) (GST_BUFFER(buf)->format)
#define GST_BUFFER_OFFSET(buf) (GST_BUFFER(buf)->offset)
#define GST_BUFFER_OFFSET_END(buf) (GST_BUFFER(buf)->offset_end)
#define GST_BUFFER_BUFFERPOOL(buf) (GST_BUFFER(buf)->pool)
#define GST_BUFFER_POOL_PRIVATE(buf) (GST_BUFFER(buf)->pool_private)
@ -72,6 +73,7 @@ extern GType _gst_buffer_pool_type;
#define GST_BUFFER_DURATION_IS_VALID(buffer) (GST_CLOCK_TIME_IS_VALID (GST_BUFFER_DURATION (buffer)))
#define GST_BUFFER_TIMESTAMP_IS_VALID(buffer) (GST_CLOCK_TIME_IS_VALID (GST_BUFFER_TIMESTAMP (buffer)))
#define GST_BUFFER_OFFSET_IS_VALID(buffer) (GST_BUFFER_OFFSET (buffer) != GST_BUFFER_OFFSET_NONE)
#define GST_BUFFER_OFFSET_END_IS_VALID(buffer) (GST_BUFFER_OFFSET_END (buffer) != GST_BUFFER_OFFSET_NONE)
#define GST_BUFFER_MAXSIZE_IS_VALID(buffer) (GST_BUFFER_MAXSIZE (buffer) != GST_BUFFER_MAXSIZE_NONE)
typedef enum {
@ -101,8 +103,11 @@ struct _GstBuffer {
* for video frames, this could be the number of frames,
* for audio data, this could be the number of audio samples,
* for file data or compressed data, this could be the number of bytes
* offset_end is the last offset contained in the buffer. The format specifies
* the meaning of both of them exactly.
*/
guint64 offset;
guint64 offset_end;
/* this is a pointer to the buffer pool (if any) */
GstBufferPool *pool;

View file

@ -86,10 +86,13 @@ gst_caps_to_string (GstCaps *caps)
g_value_set_boxed (&value, caps->properties);
props = g_strdup_value_contents (&value);
g_value_unset (&value);
g_string_append (result, ", ");
g_string_append (result, props);
g_free (props);
/* this happens with empty (but existing) caps->properties */
if (props[0] != '\0') {
g_value_unset (&value);
g_string_append (result, ", ");
g_string_append (result, props);
g_free (props);
}
}
caps = caps->next;

View file

@ -39,6 +39,8 @@ enum {
PAD_REMOVED,
ERROR,
EOS,
FOUND_TAG,
/* add more above */
LAST_SIGNAL
};
@ -65,6 +67,7 @@ static void gst_element_dispose (GObject *object);
static GstElementStateReturn gst_element_change_state (GstElement *element);
static void gst_element_error_func (GstElement* element, GstElement *source, gchar *errormsg);
static void gst_element_found_tag_func (GstElement* element, GstElement *source, GstTagList *tag_list);
#ifndef GST_DISABLE_LOADSAVE
static xmlNodePtr gst_element_save_thyself (GstObject *object, xmlNodePtr parent);
@ -127,11 +130,16 @@ gst_element_class_init (GstElementClass *klass)
g_signal_new ("error", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GstElementClass, error), NULL, NULL,
gst_marshal_VOID__OBJECT_STRING, G_TYPE_NONE, 2,
G_TYPE_OBJECT, G_TYPE_STRING);
GST_TYPE_ELEMENT, G_TYPE_STRING);
gst_element_signals[EOS] =
g_signal_new ("eos", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GstElementClass,eos), NULL, NULL,
G_STRUCT_OFFSET (GstElementClass, eos), NULL, NULL,
gst_marshal_VOID__VOID, G_TYPE_NONE, 0);
gst_element_signals[FOUND_TAG] =
g_signal_new ("found-tag", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GstElementClass, found_tag), NULL, NULL,
gst_marshal_VOID__OBJECT_POINTER, G_TYPE_NONE, 2,
GST_TYPE_ELEMENT, G_TYPE_POINTER);
gobject_class->set_property = GST_DEBUG_FUNCPTR (gst_element_real_set_property);
gobject_class->get_property = GST_DEBUG_FUNCPTR (gst_element_real_get_property);
@ -145,6 +153,7 @@ gst_element_class_init (GstElementClass *klass)
klass->change_state = GST_DEBUG_FUNCPTR (gst_element_change_state);
klass->error = GST_DEBUG_FUNCPTR (gst_element_error_func);
klass->found_tag = GST_DEBUG_FUNCPTR (gst_element_found_tag_func);
klass->padtemplates = NULL;
klass->numpadtemplates = 0;
@ -931,7 +940,9 @@ gst_element_remove_pad (GstElement *element, GstPad *pad)
/* FIXME: what if someone calls _remove_pad instead of
_remove_ghost_pad? */
if (GST_IS_REAL_PAD (pad)) {
g_return_if_fail (GST_RPAD_PEER (pad) == NULL);
if (GST_RPAD_PEER (pad) != NULL) {
gst_pad_unlink (pad, GST_PAD (GST_RPAD_PEER (pad)));
}
}
/* remove it from the list */
@ -1178,12 +1189,16 @@ void
gst_element_class_add_pad_template (GstElementClass *klass,
GstPadTemplate *templ)
{
GstPadTemplate *templ_copy;
g_return_if_fail (klass != NULL);
g_return_if_fail (GST_IS_ELEMENT_CLASS (klass));
g_return_if_fail (templ != NULL);
g_return_if_fail (GST_IS_PAD_TEMPLATE (templ));
klass->padtemplates = g_list_append (klass->padtemplates, templ);
templ_copy = g_memdup(templ, sizeof(GstPadTemplate));
klass->padtemplates = g_list_append (klass->padtemplates, templ_copy);
klass->numpadtemplates++;
}
@ -1204,11 +1219,63 @@ gst_element_class_set_details (GstElementClass *klass, GstElementDetails *detail
__gst_element_details_set (&klass->details, details);
}
/**
* gst_element_class_get_pad_template_list:
* @element: a #GstElementClass to get pad templates of.
*
* Retrieves a list of the pad templates associated with the element.
*
* Returns: the #GList of padtemplates.
*/
GList*
gst_element_class_get_pad_template_list (GstElementClass *element_class)
{
g_return_val_if_fail (element_class != NULL, NULL);
g_return_val_if_fail (GST_IS_ELEMENT_CLASS (element_class), NULL);
return element_class->padtemplates;
}
/**
* gst_element_class_get_pad_template:
* @element: a #GstElementClass to get the pad template of.
* @name: the name of the #GstPadTemplate to get.
*
* Retrieves a padtemplate from this element with the
* given name.
*
* Returns: the #GstPadTemplate with the given name, or NULL if none was found.
* No unreferencing is necessary.
*/
GstPadTemplate*
gst_element_class_get_pad_template (GstElementClass *element_class, const gchar *name)
{
GList *padlist;
g_return_val_if_fail (element_class != NULL, NULL);
g_return_val_if_fail (GST_IS_ELEMENT_CLASS (element_class), NULL);
g_return_val_if_fail (name != NULL, NULL);
padlist = gst_element_class_get_pad_template_list (element_class);
while (padlist) {
GstPadTemplate *padtempl = (GstPadTemplate*) padlist->data;
if (strcmp (padtempl->name_template, name) == 0)
return padtempl;
padlist = g_list_next (padlist);
}
return NULL;
}
/**
* gst_element_get_pad_template_list:
* @element: a #GstElement to get pad templates of.
*
* Retrieves a list of the pad templates associated with the element.
* (FIXME: Should be deprecated in favor of gst_element_class_get_pad_template_list).
*
* Returns: the #GList of padtemplates.
*/
@ -1228,6 +1295,7 @@ gst_element_get_pad_template_list (GstElement *element)
*
* Retrieves a padtemplate from this element with the
* given name.
* (FIXME: Should be deprecated in favor of gst_element_class_get_pad_template).
*
* Returns: the #GstPadTemplate with the given name, or NULL if none was found.
* No unreferencing is necessary.
@ -1582,7 +1650,7 @@ gst_element_link_pads_filtered (GstElement *src, const gchar *srcpadname,
srctempl = (GstPadTemplate*) srctempls->data;
if (srctempl->presence == GST_PAD_REQUEST) {
for (l=desttempls; l; l=l->next) {
desttempl = (GstPadTemplate*) desttempls->data;
desttempl = (GstPadTemplate*) l->data;
if (desttempl->presence == GST_PAD_REQUEST &&
desttempl->direction != srctempl->direction) {
if (gst_caps2_is_always_compatible (gst_pad_template_get_caps (srctempl),
@ -1598,7 +1666,9 @@ gst_element_link_pads_filtered (GstElement *src, const gchar *srcpadname,
GST_DEBUG_PAD_NAME (destpad));
return TRUE;
}
/* FIXME: we have extraneous request pads lying around */
/* it failed, so we release the request pads */
gst_element_release_request_pad (src, srcpad);
gst_element_release_request_pad (dest, destpad);
}
}
}
@ -2011,7 +2081,10 @@ gst_element_query (GstElement *element, GstQueryType type,
if (oclass->query)
return oclass->query (element, type, format, value);
else {
GstPad *pad = gst_element_get_random_pad (element, GST_PAD_SINK);
GstPad *pad = gst_element_get_random_pad (element, GST_PAD_SRC);
if (pad)
return gst_pad_query (pad, type, format, value);
pad = gst_element_get_random_pad (element, GST_PAD_SINK);
if (pad)
return gst_pad_query (GST_PAD_PEER (pad), type, format, value);
}
@ -2863,6 +2936,71 @@ gst_element_set_loop_function (GstElement *element,
}
}
}
static inline void
gst_element_emit_found_tag (GstElement* element, GstElement *source, GstTagList *tag_list)
{
gst_object_ref (GST_OBJECT (element));
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, GstTagList *tag_list)
{
/* tell the parent */
if (GST_OBJECT_PARENT (element)) {
GST_CAT_LOG_OBJECT (GST_CAT_EVENT, element, "forwarding tag event to %s",
GST_OBJECT_NAME (GST_OBJECT_PARENT (element)));
gst_element_emit_found_tag (GST_ELEMENT (GST_OBJECT_PARENT (element)), source, tag_list);
}
}
/**
* gst_element_found_tags:
* @element: the element that found the tags
* @tag_list: the found tags
*
* This function emits the found_tags signal. This is a recursive signal, so
* every parent will emit that signal, too, before this function returns.
* Only emit this signal, when you extracted these tags out of the data stream,
* not when you handle an event.
*/
void
gst_element_found_tags (GstElement *element, GstTagList *tag_list)
{
gst_element_emit_found_tag (element, element, tag_list);
}
/**
* gst_element_found_tags_for_pad:
* @element: element that found the tag
* @pad: src pad the tags correspond to
* @timestamp: time the tags were found
* @list: the taglist
*
* This is a convenience routine for tag finding. Most of the time you only
* want to push the found tags down one pad, in that case this function is for
* you. It takes ownership of the taglist, emits the found-tag signal and pushes
* a tag event down the pad.
*/
void
gst_element_found_tags_for_pad (GstElement *element, GstPad *pad, GstClockTime timestamp,
GstTagList *list)
{
GstEvent *tag_event;
g_return_if_fail (GST_IS_ELEMENT (element));
g_return_if_fail (GST_IS_REAL_PAD (pad));
g_return_if_fail (GST_PAD_DIRECTION (pad) == GST_PAD_SRC);
g_return_if_fail (element == GST_PAD_PARENT (pad));
g_return_if_fail (list != NULL);
tag_event = gst_event_new_tag (list);
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));
}
}
static inline void
gst_element_set_eos_recursive (GstElement *element)

View file

@ -32,6 +32,7 @@
#include <gst/gstplugin.h>
#include <gst/gstpluginfeature.h>
#include <gst/gstindex.h>
#include <gst/gsttag.h>
G_BEGIN_DECLS
@ -137,7 +138,6 @@ typedef enum {
} GstElementFlags;
#define GST_ELEMENT_IS_THREAD_SUGGESTED(obj) (GST_FLAG_IS_SET(obj,GST_ELEMENT_THREAD_SUGGESTED))
#define GST_ELEMENT_IS_EOS(obj) (GST_FLAG_IS_SET(obj,GST_ELEMENT_EOS))
#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))
@ -206,6 +206,7 @@ struct _GstElementClass {
void (*pad_removed) (GstElement *element, GstPad *pad);
void (*error) (GstElement *element, GstElement *source, gchar *error);
void (*eos) (GstElement *element);
void (*found_tag) (GstElement *element, GstElement *source, GstTagList *tag_list);
/* local pointers for get/set */
void (*set_property) (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec);
@ -254,7 +255,6 @@ void gst_element_class_set_details (GstElementClass *klass,
void gst_element_default_error (GObject *object, GstObject *orig, gchar *error);
GType gst_element_get_type (void);
void gst_element_set_loop_function (GstElement *element,
GstElementLoopFunction loop);
@ -315,6 +315,8 @@ GstPad* gst_element_get_compatible_pad (GstElement *element, GstPad *pad);
GstPad* gst_element_get_compatible_pad_filtered (GstElement *element, GstPad *pad,
const GstCaps2 *filtercaps);
GstPadTemplate* gst_element_class_get_pad_template (GstElementClass *element_class, const gchar *name);
GList* gst_element_class_get_pad_template_list (GstElementClass *element_class);
GstPadTemplate* gst_element_get_pad_template (GstElement *element, const gchar *name);
GList* gst_element_get_pad_template_list (GstElement *element);
GstPadTemplate* gst_element_get_compatible_pad_template (GstElement *element, GstPadTemplate *compattempl);
@ -348,6 +350,10 @@ gboolean gst_element_convert (GstElement *element,
GstFormat src_format, gint64 src_value,
GstFormat *dest_format, gint64 *dest_value);
void gst_element_found_tags (GstElement *element, GstTagList *tag_list);
void gst_element_found_tags_for_pad (GstElement *element, GstPad *pad, GstClockTime timestamp,
GstTagList *list);
void gst_element_set_eos (GstElement *element);
void gst_element_error (GstElement *element, const gchar *error, ...);
@ -392,6 +398,12 @@ struct _GstElementFactory {
GList * padtemplates;
guint numpadtemplates;
/* URI interface stuff */
guint uri_type;
gchar ** uri_protocols;
GList * interfaces; /* interfaces this element implements */
GST_OBJECT_PADDING
};
@ -417,6 +429,8 @@ G_CONST_RETURN gchar * gst_element_factory_get_version (GstElementFactory
G_CONST_RETURN gchar * gst_element_factory_get_author (GstElementFactory *factory);
guint gst_element_factory_get_num_padtemplates (GstElementFactory *factory);
G_CONST_RETURN GList * gst_element_factory_get_padtemplates (GstElementFactory *factory);
guint gst_element_factory_get_uri_type (GstElementFactory *factory);
gchar ** gst_element_factory_get_uri_protocols (GstElementFactory *factory);
GstElement* gst_element_factory_create (GstElementFactory *factory,
const gchar *name);
@ -429,6 +443,8 @@ gboolean gst_element_factory_can_sink_caps (GstElementFactory *factory,
void __gst_element_factory_add_pad_template (GstElementFactory *elementfactory,
GstPadTemplate *templ);
void __gst_element_factory_add_interface (GstElementFactory *elementfactory,
const gchar *interfacename);
G_END_DECLS

View file

@ -26,6 +26,7 @@
#include "gstelement.h"
#include "gstregistrypool.h"
#include "gstinfo.h"
#include "gsturi.h"
GST_DEBUG_CATEGORY_STATIC (element_factory_debug);
#define GST_CAT_DEFAULT element_factory_debug
@ -84,6 +85,11 @@ gst_element_factory_init (GstElementFactory *factory)
{
factory->padtemplates = NULL;
factory->numpadtemplates = 0;
factory->uri_type = GST_URI_UNKNOWN;
factory->uri_protocols = NULL;
factory->interfaces = NULL;
}
/**
* gst_element_factory_find:
@ -148,6 +154,15 @@ gst_element_factory_cleanup (GstElementFactory *factory)
g_list_free (factory->padtemplates);
factory->padtemplates = NULL;
factory->numpadtemplates = 0;
factory->uri_type = GST_URI_UNKNOWN;
if (factory->uri_protocols) {
g_strfreev (factory->uri_protocols);
factory->uri_protocols = NULL;
}
g_list_foreach (factory->interfaces, (GFunc) g_free, NULL);
g_list_free (factory->interfaces);
factory->interfaces = NULL;
}
/**
* gst_element_register:
@ -165,6 +180,8 @@ gboolean
gst_element_register (GstPlugin *plugin, const gchar *name, guint rank, GType type)
{
GstElementFactory *factory;
GType *interfaces;
guint n_interfaces, i;
GstElementClass *klass;
g_return_val_if_fail (name != NULL, FALSE);
@ -190,11 +207,34 @@ gst_element_register (GstPlugin *plugin, const gchar *name, guint rank, GType ty
g_list_foreach (factory->padtemplates, (GFunc) g_object_ref, NULL);
factory->numpadtemplates = klass->numpadtemplates;
gst_plugin_feature_set_rank (GST_PLUGIN_FEATURE (factory), rank);
/* special stuff for URI handling */
if (g_type_is_a (type, GST_TYPE_URI_HANDLER)) {
GstURIHandlerInterface *iface = (GstURIHandlerInterface *)
g_type_interface_peek (klass, GST_TYPE_URI_HANDLER);
if (!iface || !iface->get_type || !iface->get_protocols)
goto error;
factory->uri_type = iface->get_type ();
if (!GST_URI_TYPE_IS_VALID (factory->uri_type))
goto error;
factory->uri_protocols = g_strdupv (iface->get_protocols ());
if (!factory->uri_protocols)
goto error;
}
interfaces = g_type_interfaces (type, &n_interfaces);
for (i = 0; i < n_interfaces; i++) {
__gst_element_factory_add_interface (factory, g_type_name (interfaces[i]));
}
g_free (interfaces);
gst_plugin_feature_set_rank (GST_PLUGIN_FEATURE (factory), rank);
gst_plugin_add_feature (plugin, GST_PLUGIN_FEATURE (factory));
return TRUE;
error:
gst_element_factory_cleanup (factory);
return FALSE;
}
/**
* gst_element_factory_create:
@ -373,35 +413,84 @@ gst_element_factory_get_author (GstElementFactory *factory)
return factory->details.author;
}
/**
* gst_element_factory_get_num_padtemplates:
* gst_element_factory_get_num_pad_templates:
* @factory: a #GstElementFactory
*
* Gets the number of padtemplates in this factory.
* Gets the number of pad_templates in this factory.
*
* Returns: the number of padtemplates
* Returns: the number of pad_templates
*/
guint
gst_element_factory_get_num_padtemplates (GstElementFactory *factory)
gst_element_factory_get_num_pad_templates (GstElementFactory *factory)
{
g_return_val_if_fail (GST_IS_ELEMENT_FACTORY (factory), 0);
return factory->numpadtemplates;
}
/**
* gst_element_factory_get_padtemplates:
* __gst_element_factory_add_interface:
* @elementfactory: The elementfactory to add the interface to
* @interfacename: Name of the interface
*
* Adds the given interfacename to the list of implemented interfaces of the
* element.
*/
void
__gst_element_factory_add_interface (GstElementFactory *elementfactory, const gchar *interfacename)
{
g_return_if_fail (GST_IS_ELEMENT_FACTORY (elementfactory));
g_return_if_fail (interfacename != NULL);
g_return_if_fail (interfacename[0] != '\0'); /* no empty string */
elementfactory->interfaces = g_list_prepend (elementfactory->interfaces, g_strdup (interfacename));
}
/**
* gst_element_factory_get_pad_templates:
* @factory: a #GstElementFactory
*
* Gets the #Glist of padtemplates for this factory.
* Gets the #GList of padtemplates for this factory.
*
* Returns: the padtemplates
*/
G_CONST_RETURN GList *
gst_element_factory_get_padtemplates (GstElementFactory *factory)
gst_element_factory_get_pad_templates (GstElementFactory *factory)
{
g_return_val_if_fail (GST_IS_ELEMENT_FACTORY (factory), NULL);
return factory->padtemplates;
}
/**
* gst_element_factory_get_uri_type:
* @factory: a #GstElementFactory
*
* Gets the type of URIs the element supports or GST_URI_UNKNOWN if none.
*
* Returns: type of URIs this element supports
*/
guint
gst_element_factory_get_uri_type (GstElementFactory *factory)
{
g_return_val_if_fail (GST_IS_ELEMENT_FACTORY (factory), GST_URI_UNKNOWN);
return factory->uri_type;
}
/**
* gst_element_factory_get_uri_protocols:
* @factory: a #GstElementFactory
*
* Gets a NULL-terminated array of protocols this element supports or NULL, if
* no protocols are supported. You may not change the contents of the returned
* array as it is still ownt by the element factory. Use g_strdupv() if you want to.
*
* Returns: the supported protocols or NULL
*/
gchar **
gst_element_factory_get_uri_protocols (GstElementFactory *factory)
{
g_return_val_if_fail (GST_IS_ELEMENT_FACTORY (factory), NULL);
return factory->uri_protocols;
}
/**
* gst_element_factory_can_src_caps :
* @factory: factory to query

View file

@ -29,6 +29,8 @@
#include "gstmemchunk.h"
#include "gstevent.h"
#include "gstlog.h"
#include "gsttag.h"
#ifndef GST_DISABLE_TRACE
/* #define GST_WITH_ALLOC_TRACE */
#include "gsttrace.h"
@ -70,6 +72,12 @@ _gst_event_copy (GstEvent *event)
memcpy (copy, event, sizeof (GstEvent));
/* FIXME copy/ref additional fields */
switch (GST_EVENT_TYPE (event)) {
case GST_EVENT_TAG:
copy->event_data.structure.structure = gst_structure_copy (event->event_data.structure.structure);
default:
break;
}
return copy;
}
@ -83,6 +91,8 @@ _gst_event_free (GstEvent* event)
gst_object_unref (GST_EVENT_SRC (event));
}
switch (GST_EVENT_TYPE (event)) {
case GST_EVENT_TAG:
gst_tag_list_free (event->event_data.structure.structure);
default:
break;
}

View file

@ -28,7 +28,7 @@
#include <gst/gstdata.h>
#include <gst/gstformat.h>
#include <gst/gstobject.h>
#include <gst/gstcaps2.h>
#include <gst/gststructure.h>
G_BEGIN_DECLS
@ -48,7 +48,8 @@ typedef enum {
GST_EVENT_FILLER = 12,
GST_EVENT_TS_OFFSET = 13,
GST_EVENT_INTERRUPT = 14,
GST_EVENT_NAVIGATION = 15
GST_EVENT_NAVIGATION = 15,
GST_EVENT_TAG = 16
} GstEventType;
extern GType _gst_event_type;
@ -181,8 +182,8 @@ struct _GstEvent {
gdouble value;
} rate;
struct {
GstCaps2 *caps;
} caps;
GstStructure *structure;
} structure;
} event_data;
GST_STRUCT_PADDING

View file

@ -88,6 +88,20 @@ gst_index_resolver_get_type (void)
return index_resolver_type;
}
GType
gst_index_entry_get_type (void)
{
static GType index_entry_type = 0;
if (!index_entry_type) {
index_entry_type = g_boxed_type_register_static ("GstIndexEntry",
(GBoxedCopyFunc) gst_index_entry_copy,
(GBoxedFreeFunc) gst_index_entry_free);
}
return index_entry_type;
}
GType
gst_index_get_type (void) {
static GType index_type = 0;
@ -381,6 +395,18 @@ gst_index_set_resolver (GstIndex *index,
index->method = GST_INDEX_RESOLVER_CUSTOM;
}
/**
* gst_index_entry_copy:
* @entry: the entry to copy
*
* Copies an entry and returns the result.
*/
GstIndexEntry *
gst_index_entry_copy (GstIndexEntry *entry)
{
return g_memdup(entry, sizeof(*entry));
}
/**
* gst_index_entry_free:
* @entry: the entry to free

View file

@ -229,6 +229,7 @@ GstIndexEntry* gst_index_get_assoc_entry_full (GstIndex *index, gint id,
gpointer user_data);
/* working with index entries */
GstIndexEntry * gst_index_entry_copy (GstIndexEntry *entry);
void gst_index_entry_free (GstIndexEntry *entry);
gboolean gst_index_entry_assoc_map (GstIndexEntry *entry,
GstFormat format, gint64 *value);

View file

@ -258,11 +258,11 @@ void gst_debug_log (GstDebugCategory *category, GstDebugLevel level,
va_list var_args;
va_start (var_args, format);
gst_debug_logv (category, level, file, function, line, object, format, var_args);
gst_debug_log_valist (category, level, file, function, line, object, format, var_args);
va_end (var_args);
}
/**
* gst_debug_logv:
* gst_debug_log_valist:
* @category: category to log
* @level: level of the message is in
* @file: the file that emitted the message, usually the __FILE__ identifier
@ -274,9 +274,9 @@ void gst_debug_log (GstDebugCategory *category, GstDebugLevel level,
*
* Logs the given message using the currently registered debugging handlers.
*/
void gst_debug_logv (GstDebugCategory *category, GstDebugLevel level,
const gchar *file, const gchar *function, gint line,
GObject *object, gchar *format, va_list args)
void gst_debug_log_valist (GstDebugCategory *category, GstDebugLevel level,
const gchar *file, const gchar *function, gint line,
GObject *object, gchar *format, va_list args)
{
gchar *message;
LogFuncEntry *entry;

View file

@ -162,7 +162,7 @@ void gst_debug_log (GstDebugCategory * category,
GObject * object,
gchar * format,
...) G_GNUC_PRINTF (7, 8) G_GNUC_NO_INSTRUMENT;
void gst_debug_logv (GstDebugCategory * category,
void gst_debug_log_valist (GstDebugCategory * category,
GstDebugLevel level,
const gchar * file,
const gchar * function,
@ -388,7 +388,7 @@ const gchar* _gst_debug_nameof_funcptr (void * ptr);
#ifdef __GNUC__
# pragma GCC poison gst_debug_log
# pragma GCC poison gst_debug_logv
# pragma GCC poison gst_debug_log_valist
# pragma GCC poison gst_debug_log_default
# pragma GCC poison _gst_debug_category_new
#endif

View file

@ -54,6 +54,9 @@ gst_interface_get_type (void)
gst_interface_type = g_type_register_static (G_TYPE_INTERFACE,
"GstInterface",
&gst_interface_info, 0);
g_type_interface_add_prerequisite (gst_interface_type,
GST_TYPE_ELEMENT);
}
return gst_interface_type;

View file

@ -3,6 +3,7 @@ VOID:BOOLEAN
VOID:INT
VOID:STRING
VOID:POINTER
VOID:POINTER,OBJECT
VOID:OBJECT
VOID:OBJECT,PARAM
VOID:OBJECT,POINTER

View file

@ -139,6 +139,7 @@ gst_object_class_init (GstObjectClass *klass)
g_cclosure_marshal_VOID__OBJECT, G_TYPE_NONE, 1,
G_TYPE_OBJECT);
#ifndef GST_DISABLE_LOADSAVE_REGISTRY
/* FIXME This should be the GType of xmlNodePtr instead of G_TYPE_POINTER */
gst_object_signals[OBJECT_SAVED] =
g_signal_new ("object_saved", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GstObjectClass, object_saved), NULL, NULL,

View file

@ -173,17 +173,17 @@ gst_real_pad_class_init (GstRealPadClass *klass)
g_signal_new ("caps_nego_failed", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GstRealPadClass, caps_nego_failed), NULL, NULL,
gst_marshal_VOID__POINTER, G_TYPE_NONE, 1,
G_TYPE_POINTER);
GST_TYPE_CAPS2);
gst_real_pad_signals[REAL_LINKED] =
g_signal_new ("linked", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GstRealPadClass, linked), NULL, NULL,
gst_marshal_VOID__POINTER, G_TYPE_NONE, 1,
G_TYPE_POINTER);
GST_TYPE_PAD);
gst_real_pad_signals[REAL_UNLINKED] =
g_signal_new ("unlinked", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GstRealPadClass, unlinked), NULL, NULL,
gst_marshal_VOID__POINTER, G_TYPE_NONE, 1,
G_TYPE_POINTER);
GST_TYPE_PAD);
/* gtk_object_add_arg_type ("GstRealPad::active", G_TYPE_BOOLEAN, */
/* GTK_ARG_READWRITE, REAL_ARG_ACTIVE); */
@ -865,11 +865,11 @@ gst_pad_unlink (GstPad *srcpad,
g_return_if_fail ((GST_RPAD_DIRECTION (realsrc) == GST_PAD_SRC) &&
(GST_RPAD_DIRECTION (realsink) == GST_PAD_SINK));
if (GST_RPAD_UNLINKFUNC (srcpad)) {
GST_RPAD_UNLINKFUNC (srcpad) (srcpad);
if (GST_RPAD_UNLINKFUNC (realsrc)) {
GST_RPAD_UNLINKFUNC (realsrc) (GST_PAD_CAST (realsrc));
}
if (GST_RPAD_UNLINKFUNC (sinkpad)) {
GST_RPAD_UNLINKFUNC (sinkpad) (sinkpad);
if (GST_RPAD_UNLINKFUNC (realsink)) {
GST_RPAD_UNLINKFUNC (realsink) (GST_PAD_CAST (realsink));
}
/* get the schedulers before we unlink */

View file

@ -63,6 +63,26 @@ static void gst_plugin_desc_copy (GstPluginDesc *dest,
static GstPlugin * gst_plugin_register_func (GstPlugin *plugin,
GModule *module,
GstPluginDesc *desc);
static GstPlugin *
gst_plugin_copy (GstPlugin *plugin)
{
return g_memdup(plugin, sizeof(*plugin));
}
GType
gst_plugin_get_type (void)
{
static GType plugin_type;
if (plugin_type == 0) {
plugin_type = g_boxed_type_register_static ("GstPlugin",
(GBoxedCopyFunc) gst_plugin_copy, g_free);
}
return plugin_type;
}
GQuark
gst_plugin_error_quark (void)
{
@ -248,6 +268,16 @@ gst_plugin_load_file (const gchar *filename, GError **error)
}
GST_LOG ("Plugin %p for file \"%s\" prepared, calling entry function...", plugin, filename);
if (g_module_symbol (module, "plugin_init", &ptr)) {
g_print ("plugin %p from file \"%s\" exports a symbol named plugin_init\n",
plugin, plugin->filename);
g_set_error (error,
GST_PLUGIN_ERROR,
GST_PLUGIN_ERROR_NAME_MISMATCH,
"plugin \"%s\" exports a symbol named plugin_init",
desc->name);
}
if (gst_plugin_register_func (plugin, module, desc)) {
GST_INFO ("plugin \"%s\" loaded", plugin->filename);
return plugin;

View file

@ -120,10 +120,13 @@ _gst_plugin_static_init__ ##init (void) \
#define GST_LICENSE_UNKNOWN "unknown"
/* function for filters */
typedef gboolean (*GstPluginFilter) (GstPlugin *plugin,
gpointer user_data);
#define GST_TYPE_PLUGIN (gst_plugin_get_type())
GType gst_plugin_get_type (void);
void _gst_plugin_initialize (void);
void _gst_plugin_register_static (GstPluginDesc *desc);

View file

@ -147,7 +147,7 @@ gst_plugin_feature_type_name_filter (GstPluginFeature *feature,
* the most appropriate feature.
*/
void
gst_plugin_feature_set_rank (GstPluginFeature *feature, guint16 rank)
gst_plugin_feature_set_rank (GstPluginFeature *feature, guint rank)
{
g_return_if_fail (feature != NULL);
g_return_if_fail (GST_IS_PLUGIN_FEATURE (feature));
@ -155,7 +155,7 @@ gst_plugin_feature_set_rank (GstPluginFeature *feature, guint16 rank)
feature->rank = rank;
}
/**
* gst_plugin_feature_set_rank:
* gst_plugin_feature_set_name:
* @feature: a feature
* @name: the name to set
*
@ -175,4 +175,34 @@ gst_plugin_feature_set_name (GstPluginFeature *feature, const gchar *name)
feature->name = g_strdup (name);
}
}
/**
* gst_plugin_feature_get rank:
* @feature: a feature
*
* Gets the rank of a plugin feature.
*
* Returns: The rank of the feature
*/
guint
gst_plugin_feature_get_rank (GstPluginFeature *feature)
{
g_return_val_if_fail (GST_IS_PLUGIN_FEATURE (feature), GST_RANK_NONE);
return feature->rank;
}
/**
* gst_plugin_feature_set_name:
* @feature: a feature
*
* Gets the name of a pluginfeature.
*
* Returns: the name
*/
G_CONST_RETURN gchar *
gst_plugin_feature_get_name (GstPluginFeature *feature)
{
g_return_val_if_fail (GST_IS_PLUGIN_FEATURE (feature), NULL);
return feature->name;
}

View file

@ -44,10 +44,10 @@ typedef struct _GstPluginFeatureClass GstPluginFeatureClass;
struct _GstPluginFeature {
GObject object;
/*< private >*/
gchar *name;
gint rank;
guint rank;
/* --- private --- */
gpointer manager;
GST_OBJECT_PADDING
@ -79,8 +79,10 @@ void gst_plugin_feature_unload_thyself (GstPluginFeature *feature);
gboolean gst_plugin_feature_type_name_filter (GstPluginFeature *feature,
GstTypeNameData *data);
void gst_plugin_feature_set_rank (GstPluginFeature *feature, guint16 rank);
void gst_plugin_feature_set_rank (GstPluginFeature *feature, guint rank);
void gst_plugin_feature_set_name (GstPluginFeature *feature, const gchar *name);
guint gst_plugin_feature_get_rank (GstPluginFeature *feature);
G_CONST_RETURN gchar *gst_plugin_feature_get_name (GstPluginFeature *feature);
G_END_DECLS

View file

@ -2391,7 +2391,16 @@ G_STMT_START { \
GST_PROPS_FLAG_UNSET ((props), GST_PROPS_FIXED); \
props->properties = g_list_prepend ((props)->properties, toadd); \
} G_STMT_END
static gint
compare_props_entry (gconstpointer one, gconstpointer two)
{
GstPropsEntry *a = (GstPropsEntry *) one;
GstPropsEntry *b = (GstPropsEntry *) two;
if (a->propid > b->propid) return 1;
if (a->propid < b->propid) return -1;
return 0;
}
/**
* gst_props_intersect:
* @props1: a property
@ -2417,6 +2426,9 @@ gst_props_intersect (GstProps *props1, GstProps *props2)
intersection = gst_props_empty_new ();
props1->properties = g_list_sort (props1->properties, compare_props_entry);
props2->properties = g_list_sort (props2->properties, compare_props_entry);
props1list = props1->properties;
props2list = props2->properties;
@ -2445,6 +2457,8 @@ gst_props_intersect (GstProps *props1, GstProps *props2)
entry2 = (GstPropsEntry *)props2list->data;
}
if (entry1->propid < entry2->propid)
continue;
/* at this point we are talking about the same property */
iprops = gst_props_entry_intersect (entry1, entry2);
if (!iprops) {

View file

@ -223,6 +223,7 @@ gst_queue_init (GTypeInstance *instance, gpointer g_class)
gst_pad_set_bufferpool_function (queue->sinkpad, GST_DEBUG_FUNCPTR (gst_queue_get_bufferpool));
gst_pad_set_link_function (queue->sinkpad, 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 ("src", GST_PAD_SRC);
gst_pad_set_get_function (queue->srcpad, GST_DEBUG_FUNCPTR (gst_queue_get));
@ -230,6 +231,7 @@ gst_queue_init (GTypeInstance *instance, gpointer g_class)
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_active (queue->srcpad, TRUE);
queue->leaky = GST_QUEUE_NO_LEAK;
queue->queue = NULL;
@ -695,6 +697,10 @@ gst_queue_change_state (GstElement *element)
}
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);
error:
g_mutex_unlock (queue->qlock);

View file

@ -585,7 +585,7 @@ gst_structure_remove_all_fields(GstStructure *structure)
g_return_if_fail(structure != NULL);
for (i = structure->fields->len - 1; i >= 0; i++ ) {
for (i = structure->fields->len - 1; i >= 0; i-- ) {
field = GST_STRUCTURE_FIELD(structure, i);
if (G_IS_VALUE (&field->value)) {

View file

@ -73,7 +73,8 @@ void gst_structure_set_value(GstStructure *structure, const gchar *field,
void gst_structure_set(GstStructure *structure, const gchar *field, ...);
void gst_structure_set_valist(GstStructure *structure, const gchar *field,
va_list varargs);
G_CONST_RETURN GValue *gst_structure_get_value(const GstStructure *structure, const gchar *field);
G_CONST_RETURN GValue *gst_structure_get_value(const GstStructure *structure,
const gchar *field);
GstStructureField *gst_structure_get_field(const GstStructure *structure,
const gchar *fieldname);
GstStructureField *gst_structure_id_get_field(const GstStructure *structure,

831
gst/gsttag.c Normal file
View file

@ -0,0 +1,831 @@
/* GStreamer
* Copyright (C) 2003 Benjamin Otte <in7y118@public.uni-hamburg.de>
*
* gsttag.c: tag support (aka metadata)
*
* 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_private.h"
#include "gsttag.h"
#include "gstinfo.h"
#include "gstvalue.h"
#include <gobject/gvaluecollector.h>
#include <string.h>
#define GST_TAG_IS_VALID(tag) (gst_tag_get_info (tag) != NULL)
typedef struct {
GType type; /* type the data is in */
gchar * nick; /* translated name */
gchar * blurb; /* translated description of type */
GstTagMergeFunc merge_func; /* functions to merge the values */
} GstTagInfo;
#define TAGLIST "taglist"
static GQuark gst_tag_list_quark;
static GMutex *__tag_mutex;
static GHashTable *__tags;
#define TAG_LOCK g_mutex_lock (__tag_mutex)
#define TAG_UNLOCK g_mutex_unlock (__tag_mutex)
void
_gst_tag_initialize (void)
{
gst_tag_list_quark = g_quark_from_static_string (TAGLIST);
__tag_mutex = g_mutex_new ();
__tags = g_hash_table_new (g_direct_hash, g_direct_equal);
gst_tag_register (GST_TAG_TITLE,
G_TYPE_STRING,
_("title"),
_("commonly used title"),
gst_tag_merge_strings_with_comma);
gst_tag_register (GST_TAG_ARTIST,
G_TYPE_STRING,
_("artist"),
_("person(s) resposible for the recording"),
gst_tag_merge_strings_with_comma);
gst_tag_register (GST_TAG_ALBUM,
G_TYPE_STRING,
_("album"),
_("album containing this data"),
gst_tag_merge_strings_with_comma);
gst_tag_register (GST_TAG_DATE,
G_TYPE_UINT, /* FIXME: own data type for dates? */
_("date"),
_("date the data was created in julien days"),
NULL);
gst_tag_register (GST_TAG_GENRE,
G_TYPE_STRING,
_("genre"),
_("genre this data belongs to"),
gst_tag_merge_strings_with_comma);
gst_tag_register (GST_TAG_COMMENT,
G_TYPE_STRING,
_("comment"),
_("free text commenting the data"),
gst_tag_merge_strings_with_comma);
gst_tag_register (GST_TAG_TRACK_NUMBER,
G_TYPE_UINT,
_("track number"),
_("track number inside a collection"),
gst_tag_merge_use_first);
gst_tag_register (GST_TAG_TRACK_COUNT,
G_TYPE_STRING,
_("track count"),
_("count of tracks inside collection this track belongs to"),
gst_tag_merge_use_first);
gst_tag_register (GST_TAG_LOCATION,
G_TYPE_STRING,
_("loccation"),
_("original location of file as a URI"),
gst_tag_merge_strings_with_comma);
gst_tag_register (GST_TAG_DESCRIPTION,
G_TYPE_STRING,
_("description"),
_("short text describing the content of the data"),
gst_tag_merge_strings_with_comma);
gst_tag_register (GST_TAG_VERSION,
G_TYPE_STRING,
_("version"),
_("version of this data"),
NULL);
gst_tag_register (GST_TAG_ISRC,
G_TYPE_STRING,
_("ISRC"),
_("International Standard Recording Code - see http://www.ifpi.org/isrc/"),
NULL);
gst_tag_register (GST_TAG_ORGANIZATION,
G_TYPE_STRING,
_("organization"),
_("organization"), /* FIXME */
gst_tag_merge_strings_with_comma);
gst_tag_register (GST_TAG_COPYRIGHT,
G_TYPE_STRING,
_("copyright"),
_("copyright notice of the data"),
NULL);
gst_tag_register (GST_TAG_CONTACT,
G_TYPE_STRING,
_("contact"),
_("contact information"),
gst_tag_merge_strings_with_comma);
gst_tag_register (GST_TAG_LICENSE,
G_TYPE_STRING,
_("license"),
_("license of data"),
NULL);
gst_tag_register (GST_TAG_PERFORMER,
G_TYPE_STRING,
_("performer"),
_("person(s) performing"),
gst_tag_merge_strings_with_comma);
gst_tag_register (GST_TAG_DURATION,
G_TYPE_UINT64,
_("duration"),
_("length in GStreamer time units (nanoseconds)"),
NULL);
gst_tag_register (GST_TAG_CODEC,
G_TYPE_STRING,
_("codec"),
_("codec the data is stored in"),
gst_tag_merge_strings_with_comma);
gst_tag_register (GST_TAG_MINIMUM_BITRATE,
G_TYPE_UINT,
_("minimum bitrate"),
_("minimum bitrate in bits/s"),
NULL);
gst_tag_register (GST_TAG_BITRATE,
G_TYPE_UINT,
_("bitrate"),
_("exact or average bitrate in bits/s"),
NULL);
gst_tag_register (GST_TAG_MAXIMUM_BITRATE,
G_TYPE_UINT,
_("maximum bitrate"),
_("maximum bitrate in bits/s"),
NULL);
}
/**
* gst_tag_merge_use_first:
* @dest: uninitialized GValue to store result in
* @src: GValue to copy from
*
* This is a convenience function for the func argument of gst_tag_register().
* It creates a copy of the first value from the list.
*/
void
gst_tag_merge_use_first (GValue *dest, const GValue *src)
{
const GValue *ret = gst_value_list_get_value (src, 0);
g_value_init (dest, G_VALUE_TYPE (ret));
g_value_copy (ret, dest);
}
/**
* gst_tag_merge_strings_with_comma:
* @dest: uninitialized GValue to store result in
* @src: GValue to copy from
*
* This is a convenience function for the func argument of gst_tag_register().
* It concatenates all given strings using a comma. The tag must be registered
* as a G_TYPE_STRING or this function will fail.
*/
void
gst_tag_merge_strings_with_comma (GValue *dest, const GValue *src)
{
GString *str;
gint i, count;
count = gst_value_list_get_size (src);
str = g_string_new (g_value_get_string (gst_value_list_get_value (src, 0)));
for (i = 1; i < count; i++) {
/* seperator between two string */
str = g_string_append (str, _(", "));
str = g_string_append (str, g_value_get_string (gst_value_list_get_value (src, 1)));
}
g_value_init (dest, G_TYPE_STRING);
g_value_set_string_take_ownership (dest, str->str);
g_string_free (str, FALSE);
}
static GstTagInfo *
gst_tag_lookup (GQuark entry)
{
GstTagInfo *ret;
TAG_LOCK;
ret = g_hash_table_lookup (__tags, GUINT_TO_POINTER (entry));
TAG_UNLOCK;
return ret;
}
/**
* gst_tag_register:
* @name: the name or identifier string
* @type: the type this data is in
* @nick: human-readable name
* @blurb: a human-readable description about this tag
* @func: function for merging multiple values of this tag
*
* Registers a new tag type for the use with GStreamer's type system. If a type
* with that name is already registered, that one is used.
* The old registration may have used a different type however. So don't rely
* on youre supplied values.
* If you know the type is already registered, use gst_tag_lookup instead.
* This function takes ownership of all supplied variables.
*/
void
gst_tag_register (gchar *name, GType type, gchar *nick, gchar *blurb,
GstTagMergeFunc func)
{
GQuark key;
GstTagInfo *info;
g_return_if_fail (name != NULL);
g_return_if_fail (nick != NULL);
g_return_if_fail (blurb != NULL);
g_return_if_fail (type != 0 && type != GST_TYPE_LIST);
key = g_quark_from_string (name);
info = gst_tag_lookup (key);
g_return_if_fail (info == NULL);
info = g_new (GstTagInfo, 1);
info->type = type;
info->nick = nick;
info->blurb = blurb;
info->merge_func = func;
TAG_LOCK;
g_hash_table_insert (__tags, GUINT_TO_POINTER (key), info);
TAG_UNLOCK;
}
/**
* gst_tag_exists:
* @tag: name of the tag
*
* Checks if the given type is already registered.
*
* Returns: TRUE if the type is already registered
*/
gboolean
gst_tag_exists (const gchar *tag)
{
g_return_val_if_fail (tag != NULL, FALSE);
return gst_tag_lookup (g_quark_from_string (tag)) != NULL;
}
/**
* gst_tag_get_type:
* @tag: the tag
*
* Gets the #GType used for this tag.
*
* Returns: the #GType of this tag
*/
GType
gst_tag_get_type (const gchar *tag)
{
GstTagInfo *info;
g_return_val_if_fail (tag != NULL, 0);
info = gst_tag_lookup (g_quark_from_string (tag));
g_return_val_if_fail (info != NULL, 0);
return info->type;
}
/**
* gst_tag_get_nick
* @tag: the tag
*
* Returns the human-readable name of this tag, You must not change or free
* this string.
*
* Returns: the human-readable name of this tag
*/
const gchar *
gst_tag_get_nick (const gchar *tag)
{
GstTagInfo *info;
g_return_val_if_fail (tag != NULL, NULL);
info = gst_tag_lookup (g_quark_from_string (tag));
g_return_val_if_fail (info != NULL, NULL);
return info->nick;
}
/**
* gst_tag_get_description:
* @tag: the tag
*
* Returns the human-readable description of this tag, You must not change or
* free this string.
*
* Return the human-readable description of this tag
*/
const gchar *
gst_tag_get_description (const gchar *tag)
{
GstTagInfo *info;
g_return_val_if_fail (tag != NULL, NULL);
info = gst_tag_lookup (g_quark_from_string (tag));
g_return_val_if_fail (info != NULL, NULL);
return info->blurb;
}
/**
* gst_tag_list_is_fixed:
* @tag: tag to check
*
* Checks if the given tag is fixed. A fixed tag can only contain one value.
* Unfixed tags can contain lists of values.
*
* Returns: TRUE, if the given tag is fixed.
*/
gboolean
gst_tag_is_fixed (const gchar *tag)
{
GstTagInfo *info;
g_return_val_if_fail (tag != NULL, FALSE);
info = gst_tag_lookup (g_quark_from_string (tag));
g_return_val_if_fail (info != NULL, FALSE);
return info->merge_func == NULL;
}
/**
* gst_tag_list_new:
*
* Creates a new empty GstTagList.
*
* Returns: An empty tag list
*/
GstTagList *
gst_tag_list_new (void)
{
return GST_TAG_LIST (gst_structure_new (TAGLIST, NULL));
}
/**
* gst_is_tag_list:
* @p: Object that might be a taglist
*
* Checks if the given pointer is a taglist.
*
* Returns: TRUE, if the given pointer is a taglist
*/
gboolean
gst_is_tag_list (gconstpointer p)
{
g_return_val_if_fail (p != NULL, FALSE);
return ((GstStructure *) p)->name == gst_tag_list_quark;
}
typedef struct {
GstStructure * list;
GstTagMergeMode mode;
} GstTagCopyData;
static void
gst_tag_list_add_value_internal (GstStructure *list, GstTagMergeMode mode, GQuark tag, GValue *value)
{
GstTagInfo *info = gst_tag_lookup (tag);
GstStructureField *field;
g_assert (info != NULL);
if (info->merge_func && (field = gst_structure_id_get_field (list, tag)) != NULL) {
GValue value2 = { 0, };
switch (mode) {
case GST_TAG_MERGE_REPLACE_ALL:
case GST_TAG_MERGE_REPLACE:
gst_structure_id_set_value (list, tag, value);
break;
case GST_TAG_MERGE_PREPEND:
gst_value_list_concat (&value2, value, &field->value);
gst_structure_id_set_value (list, tag, &value2);
g_value_unset (&value2);
break;
case GST_TAG_MERGE_APPEND:
gst_value_list_concat (&value2, &field->value, value);
gst_structure_id_set_value (list, tag, &value2);
g_value_unset (&value2);
break;
case GST_TAG_MERGE_KEEP:
case GST_TAG_MERGE_KEEP_ALL:
break;
default:
g_assert_not_reached ();
break;
}
} else {
switch (mode) {
case GST_TAG_MERGE_APPEND:
case GST_TAG_MERGE_KEEP:
if (gst_structure_id_get_field (list, tag) != NULL)
break;
/* fall through */
case GST_TAG_MERGE_REPLACE_ALL:
case GST_TAG_MERGE_REPLACE:
case GST_TAG_MERGE_PREPEND:
gst_structure_id_set_value (list, tag, value);
break;
case GST_TAG_MERGE_KEEP_ALL:
break;
default:
g_assert_not_reached ();
break;
}
}
}
static void
gst_tag_list_copy_foreach (GstStructure *structure, GQuark tag, GValue *value, gpointer user_data)
{
GstTagCopyData *copy = (GstTagCopyData *) user_data;
gst_tag_list_add_value_internal (copy->list, copy->mode, tag, value);
}
/**
* gst_tag_list_insert:
* @into: list to merge into
* @from: list to merge from
* @mode: the mode to use
*
* Inserts the tags of the second list into the first list using the given mode.
*/
void
gst_tag_list_insert (GstTagList *into, const GstTagList *from, GstTagMergeMode mode)
{
GstTagCopyData data;
g_return_if_fail (GST_IS_TAG_LIST (into));
g_return_if_fail (GST_IS_TAG_LIST (from));
g_return_if_fail (GST_TAG_MODE_IS_VALID (mode));
data.list = (GstStructure *) into;
data.mode = mode;
if (mode == GST_TAG_MERGE_REPLACE_ALL) {
gst_structure_remove_all_fields (data.list);
}
gst_structure_field_foreach ((GstStructure *) from, gst_tag_list_copy_foreach, &data);
}
/**
* gst_tag_list_copy:
* @list: list to copy
*
* Copies a given #GstTagList.
*
* Returns: copy of the given list
*/
GstTagList *
gst_tag_list_copy (const GstTagList *list)
{
g_return_val_if_fail (GST_IS_TAG_LIST (list), NULL);
return GST_TAG_LIST (gst_structure_copy ((GstStructure *) list));
}
/**
* gst_tag_list_merge:
* @list1: first list to merge
* @list2: second list to merge
* @mode: the mode to use
*
* Merges the two given lists into a new list. If one of the lists is NULL, a
* copy of the other is returned. If both lists are NULL, NULL is returned.
*
* Returns: the new list
*/
GstTagList *
gst_tag_list_merge (const GstTagList *list1, const GstTagList *list2, GstTagMergeMode mode)
{
g_return_val_if_fail (list1 == NULL || GST_IS_TAG_LIST (list1), NULL);
g_return_val_if_fail (list2 == NULL || GST_IS_TAG_LIST (list2), NULL);
g_return_val_if_fail (GST_TAG_MODE_IS_VALID (mode), NULL);
if (!list1 && !list2) {
return NULL;
} else if (!list1) {
return gst_tag_list_copy (list2);
} else if (!list2) {
return gst_tag_list_copy (list1);
} else {
GstTagList *ret;
ret = gst_tag_list_copy (list1);
gst_tag_list_insert (ret, list2, mode);
return ret;
}
}
/**
* gst_tag_list_free:
* @list: the list to free
*
* Frees the given list and all associated values.
*/
void
gst_tag_list_free (GstTagList *list)
{
g_return_if_fail (GST_IS_TAG_LIST (list));
gst_structure_free ((GstStructure *) list);
}
/**
* gst_tag_list_get_tag_size:
* @list: a taglist
* @tag: the tag to query
*
* Checks how many value are stored in this tag list for the given tag.
*
* Returns: The number of tags stored
*/
guint
gst_tag_list_get_tag_size (const GstTagList *list, const gchar *tag)
{
const GValue *value;
g_return_val_if_fail (GST_IS_TAG_LIST (list), 0);
value = gst_structure_get_value ((GstStructure *) list, tag);
if (value == NULL)
return 0;
if (G_VALUE_TYPE (value) != GST_TYPE_LIST)
return 1;
return gst_value_list_get_size (value);
}
/**
* gst_tag_list_add:
* @list: list to set tags in
* @mode: the mode to use
* @tag: tag
* @...: values to set
*
* Sets the values for the given tags using the specified mode.
*/
void
gst_tag_list_add (GstTagList *list, GstTagMergeMode mode, const gchar *tag, ...)
{
va_list args;
g_return_if_fail (GST_IS_TAG_LIST (list));
g_return_if_fail (GST_TAG_MODE_IS_VALID (mode));
g_return_if_fail (tag != NULL);
va_start (args, tag);
gst_tag_list_add_valist (list, mode, tag, args);
va_end (args);
}
/**
* gst_tag_list_add_valist:
* @list: list to set tags in
* @mode: the mode to use
* @tag: tag
* @var_args: tag / value pairs to set
*
* Sets the values for the given tags using the specified mode.
*/
void
gst_tag_list_add_valist (GstTagList *list, GstTagMergeMode mode, const gchar *tag, va_list var_args)
{
GstTagInfo *info;
GQuark quark;
gchar *error = NULL;
g_return_if_fail (GST_IS_TAG_LIST (list));
g_return_if_fail (GST_TAG_MODE_IS_VALID (mode));
g_return_if_fail (tag != NULL);
while (tag != NULL) {
GValue value = { 0, };
quark = g_quark_from_string (tag);
info = gst_tag_lookup (quark);
g_return_if_fail (info != NULL);
g_value_init (&value, info->type);
G_VALUE_COLLECT (&value, var_args, 0, &error);
if (error) {
g_warning ("%s: %s", G_STRLOC, error);
g_free (error);
/* we purposely leak the value here, it might not be
* in a sane state if an error condition occoured
*/
return;
}
gst_tag_list_add_value_internal (list, mode, quark, &value);
g_value_unset (&value);
tag = va_arg (var_args, gchar *);
}
}
/**
* gst_tag_list_remove_tag:
* @list: list to remove tag from
* @tag: tag to remove
*
* Removes the goven tag from the taglist.
*/
void
gst_tag_list_remove_tag (GstTagList *list, const gchar *tag)
{
g_return_if_fail (GST_IS_TAG_LIST (list));
g_return_if_fail (tag != NULL);
gst_structure_remove_field ((GstStructure *) list, tag);
}
typedef struct {
GstTagForeachFunc func;
gpointer data;
} TagForeachData;
static void
structure_foreach_wrapper (GstStructure *structure, GQuark field_id,
GValue *value, gpointer user_data)
{
TagForeachData *data = (TagForeachData *) user_data;
data->func (GST_TAG_LIST (structure), g_quark_to_string (field_id), data->data);
}
/**
* gst_tag_list_foreach:
* @list: list to iterate over
* @func: function to be called for each tag
* @user_data: user specified data
*
* Calls the given function for each tag inside the tag list. Note that if there
* is no tag, the function won't be called at all.
*/
void
gst_tag_list_foreach (GstTagList *list, GstTagForeachFunc func, gpointer user_data)
{
TagForeachData data;
g_return_if_fail (GST_IS_TAG_LIST (list));
g_return_if_fail (func != NULL);
data.func = func;
data.data = user_data;
gst_structure_field_foreach ((GstStructure *) list, structure_foreach_wrapper, &data);
}
/***** tag events *****/
/**
* gst_event_new_tag:
* @list: the tag list to put into the event or NULL for an empty list
*
* Creates a new tag event with the given list and takes ownership of it.
*
* Returns: a new tag event
*/
GstEvent *
gst_event_new_tag (GstTagList *list)
{
GstEvent *ret;
g_return_val_if_fail (list == NULL || GST_IS_TAG_LIST (list), NULL);
ret = gst_event_new (GST_EVENT_TAG);
if (!list)
list = gst_tag_list_new ();
ret->event_data.structure.structure = (GstStructure *) list;
return ret;
}
/**
* get_event_tag_get_list:
* @tag_event: a tagging #GstEvent
*
* Gets the taglist from a given tagging event.
*
* Returns: The #GstTagList of the event
*/
GstTagList *
gst_event_tag_get_list (GstEvent *tag_event)
{
g_return_val_if_fail (GST_IS_EVENT (tag_event), NULL);
g_return_val_if_fail (GST_EVENT_TYPE (tag_event) == GST_EVENT_TAG, NULL);
return GST_TAG_LIST (tag_event->event_data.structure.structure);
}
/**
* gst_tag_list_get_value_index:
* @list: a #GStTagList
* @tag: tag to read out
* @index: number of entry to read out
*
* Gets the value that is at the given index for the given tag in the given
* list.
*
* Returns: The GValue for the specified entry or NULL if the tag wasn't available
* or the tag doesn't have as many entries
*/
G_CONST_RETURN GValue *
gst_tag_list_get_value_index (const GstTagList *list, const gchar *tag, guint index)
{
const GValue *value;
g_return_val_if_fail (GST_IS_TAG_LIST (list), NULL);
g_return_val_if_fail (tag != NULL, NULL);
value = gst_structure_get_value ((GstStructure *) list, tag);
if (value == NULL) return NULL;
if (GST_VALUE_HOLDS_LIST (value)) {
if (index >= gst_value_list_get_size (value)) return NULL;
return gst_value_list_get_value (value, index);
} else {
if (index > 0) return NULL;
return value;
}
}
/**
* gst_tag_list_copy_value:
* @dest: uninitialized #GValue to copy into
* @list: list to get the tag from
* @tag: tag to read out
*
* Copies the contents for the given tag into the value, merging multiple values
* into one if multiple values are associated with the tag.
* You must g_value_unset() the value after use.
*
* Returns: TRUE, if a value was copied, FALSE if the tag didn't exist in the
* given list.
*/
gboolean
gst_tag_list_copy_value (GValue *dest, const GstTagList *list, const gchar *tag)
{
const GValue *src;
g_return_val_if_fail (GST_IS_TAG_LIST (list), FALSE);
g_return_val_if_fail (tag != NULL, FALSE);
g_return_val_if_fail (dest != NULL, FALSE);
g_return_val_if_fail (G_VALUE_TYPE (dest) == 0, FALSE);
src = gst_structure_get_value ((GstStructure *) list, tag);
if (!src) return FALSE;
if (G_VALUE_TYPE (src) == GST_TYPE_LIST) {
GstTagInfo *info = gst_tag_lookup (g_quark_from_string (tag));
/* must be there or lists aren't allowed */
g_assert (info->merge_func);
info->merge_func (dest, src);
} else {
g_value_init (dest, G_VALUE_TYPE (src));
g_value_copy (src, dest);
}
return TRUE;
}
/***** evil macros to get all the gst_tag_list_get_*() functions right *****/
#define TAG_MERGE_FUNCS(name,type) \
gboolean \
gst_tag_list_get_ ## name (const GstTagList *list, const gchar *tag, \
type *value) \
{ \
GValue v = { 0, }; \
\
g_return_val_if_fail (GST_IS_TAG_LIST (list), FALSE); \
g_return_val_if_fail (tag != NULL, FALSE); \
g_return_val_if_fail (value != NULL, FALSE); \
\
if (!gst_tag_list_copy_value (&v, list, tag)) \
return FALSE; \
*value = COPY_FUNC (g_value_get_ ## name (&v)); \
g_value_unset (&v); \
return TRUE; \
} \
\
gboolean \
gst_tag_list_get_ ## name ## _index (const GstTagList *list, const gchar *tag, \
guint index, type *value) \
{ \
const GValue *v; \
\
g_return_val_if_fail (GST_IS_TAG_LIST (list), FALSE); \
g_return_val_if_fail (tag != NULL, FALSE); \
g_return_val_if_fail (value != NULL, FALSE); \
\
if ((v = gst_tag_list_get_value_index (list, tag, index)) == NULL) \
return FALSE; \
*value = COPY_FUNC (g_value_get_ ## name (v)); \
return TRUE; \
}
#define COPY_FUNC /**/
TAG_MERGE_FUNCS (char, gchar)
TAG_MERGE_FUNCS (uchar, guchar)
TAG_MERGE_FUNCS (boolean, gboolean)
TAG_MERGE_FUNCS (int, gint)
TAG_MERGE_FUNCS (uint, guint)
TAG_MERGE_FUNCS (long, glong)
TAG_MERGE_FUNCS (ulong, gulong)
TAG_MERGE_FUNCS (int64, gint64)
TAG_MERGE_FUNCS (uint64, guint64)
TAG_MERGE_FUNCS (float, gfloat)
TAG_MERGE_FUNCS (double, gdouble)
#undef COPY_FUNC
#define COPY_FUNC g_strdup
TAG_MERGE_FUNCS (string, gchar *)

831
gst/gsttaglist.c Normal file
View file

@ -0,0 +1,831 @@
/* GStreamer
* Copyright (C) 2003 Benjamin Otte <in7y118@public.uni-hamburg.de>
*
* gsttag.c: tag support (aka metadata)
*
* 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_private.h"
#include "gsttag.h"
#include "gstinfo.h"
#include "gstvalue.h"
#include <gobject/gvaluecollector.h>
#include <string.h>
#define GST_TAG_IS_VALID(tag) (gst_tag_get_info (tag) != NULL)
typedef struct {
GType type; /* type the data is in */
gchar * nick; /* translated name */
gchar * blurb; /* translated description of type */
GstTagMergeFunc merge_func; /* functions to merge the values */
} GstTagInfo;
#define TAGLIST "taglist"
static GQuark gst_tag_list_quark;
static GMutex *__tag_mutex;
static GHashTable *__tags;
#define TAG_LOCK g_mutex_lock (__tag_mutex)
#define TAG_UNLOCK g_mutex_unlock (__tag_mutex)
void
_gst_tag_initialize (void)
{
gst_tag_list_quark = g_quark_from_static_string (TAGLIST);
__tag_mutex = g_mutex_new ();
__tags = g_hash_table_new (g_direct_hash, g_direct_equal);
gst_tag_register (GST_TAG_TITLE,
G_TYPE_STRING,
_("title"),
_("commonly used title"),
gst_tag_merge_strings_with_comma);
gst_tag_register (GST_TAG_ARTIST,
G_TYPE_STRING,
_("artist"),
_("person(s) resposible for the recording"),
gst_tag_merge_strings_with_comma);
gst_tag_register (GST_TAG_ALBUM,
G_TYPE_STRING,
_("album"),
_("album containing this data"),
gst_tag_merge_strings_with_comma);
gst_tag_register (GST_TAG_DATE,
G_TYPE_UINT, /* FIXME: own data type for dates? */
_("date"),
_("date the data was created in julien days"),
NULL);
gst_tag_register (GST_TAG_GENRE,
G_TYPE_STRING,
_("genre"),
_("genre this data belongs to"),
gst_tag_merge_strings_with_comma);
gst_tag_register (GST_TAG_COMMENT,
G_TYPE_STRING,
_("comment"),
_("free text commenting the data"),
gst_tag_merge_strings_with_comma);
gst_tag_register (GST_TAG_TRACK_NUMBER,
G_TYPE_UINT,
_("track number"),
_("track number inside a collection"),
gst_tag_merge_use_first);
gst_tag_register (GST_TAG_TRACK_COUNT,
G_TYPE_STRING,
_("track count"),
_("count of tracks inside collection this track belongs to"),
gst_tag_merge_use_first);
gst_tag_register (GST_TAG_LOCATION,
G_TYPE_STRING,
_("loccation"),
_("original location of file as a URI"),
gst_tag_merge_strings_with_comma);
gst_tag_register (GST_TAG_DESCRIPTION,
G_TYPE_STRING,
_("description"),
_("short text describing the content of the data"),
gst_tag_merge_strings_with_comma);
gst_tag_register (GST_TAG_VERSION,
G_TYPE_STRING,
_("version"),
_("version of this data"),
NULL);
gst_tag_register (GST_TAG_ISRC,
G_TYPE_STRING,
_("ISRC"),
_("International Standard Recording Code - see http://www.ifpi.org/isrc/"),
NULL);
gst_tag_register (GST_TAG_ORGANIZATION,
G_TYPE_STRING,
_("organization"),
_("organization"), /* FIXME */
gst_tag_merge_strings_with_comma);
gst_tag_register (GST_TAG_COPYRIGHT,
G_TYPE_STRING,
_("copyright"),
_("copyright notice of the data"),
NULL);
gst_tag_register (GST_TAG_CONTACT,
G_TYPE_STRING,
_("contact"),
_("contact information"),
gst_tag_merge_strings_with_comma);
gst_tag_register (GST_TAG_LICENSE,
G_TYPE_STRING,
_("license"),
_("license of data"),
NULL);
gst_tag_register (GST_TAG_PERFORMER,
G_TYPE_STRING,
_("performer"),
_("person(s) performing"),
gst_tag_merge_strings_with_comma);
gst_tag_register (GST_TAG_DURATION,
G_TYPE_UINT64,
_("duration"),
_("length in GStreamer time units (nanoseconds)"),
NULL);
gst_tag_register (GST_TAG_CODEC,
G_TYPE_STRING,
_("codec"),
_("codec the data is stored in"),
gst_tag_merge_strings_with_comma);
gst_tag_register (GST_TAG_MINIMUM_BITRATE,
G_TYPE_UINT,
_("minimum bitrate"),
_("minimum bitrate in bits/s"),
NULL);
gst_tag_register (GST_TAG_BITRATE,
G_TYPE_UINT,
_("bitrate"),
_("exact or average bitrate in bits/s"),
NULL);
gst_tag_register (GST_TAG_MAXIMUM_BITRATE,
G_TYPE_UINT,
_("maximum bitrate"),
_("maximum bitrate in bits/s"),
NULL);
}
/**
* gst_tag_merge_use_first:
* @dest: uninitialized GValue to store result in
* @src: GValue to copy from
*
* This is a convenience function for the func argument of gst_tag_register().
* It creates a copy of the first value from the list.
*/
void
gst_tag_merge_use_first (GValue *dest, const GValue *src)
{
const GValue *ret = gst_value_list_get_value (src, 0);
g_value_init (dest, G_VALUE_TYPE (ret));
g_value_copy (ret, dest);
}
/**
* gst_tag_merge_strings_with_comma:
* @dest: uninitialized GValue to store result in
* @src: GValue to copy from
*
* This is a convenience function for the func argument of gst_tag_register().
* It concatenates all given strings using a comma. The tag must be registered
* as a G_TYPE_STRING or this function will fail.
*/
void
gst_tag_merge_strings_with_comma (GValue *dest, const GValue *src)
{
GString *str;
gint i, count;
count = gst_value_list_get_size (src);
str = g_string_new (g_value_get_string (gst_value_list_get_value (src, 0)));
for (i = 1; i < count; i++) {
/* seperator between two string */
str = g_string_append (str, _(", "));
str = g_string_append (str, g_value_get_string (gst_value_list_get_value (src, 1)));
}
g_value_init (dest, G_TYPE_STRING);
g_value_set_string_take_ownership (dest, str->str);
g_string_free (str, FALSE);
}
static GstTagInfo *
gst_tag_lookup (GQuark entry)
{
GstTagInfo *ret;
TAG_LOCK;
ret = g_hash_table_lookup (__tags, GUINT_TO_POINTER (entry));
TAG_UNLOCK;
return ret;
}
/**
* gst_tag_register:
* @name: the name or identifier string
* @type: the type this data is in
* @nick: human-readable name
* @blurb: a human-readable description about this tag
* @func: function for merging multiple values of this tag
*
* Registers a new tag type for the use with GStreamer's type system. If a type
* with that name is already registered, that one is used.
* The old registration may have used a different type however. So don't rely
* on youre supplied values.
* If you know the type is already registered, use gst_tag_lookup instead.
* This function takes ownership of all supplied variables.
*/
void
gst_tag_register (gchar *name, GType type, gchar *nick, gchar *blurb,
GstTagMergeFunc func)
{
GQuark key;
GstTagInfo *info;
g_return_if_fail (name != NULL);
g_return_if_fail (nick != NULL);
g_return_if_fail (blurb != NULL);
g_return_if_fail (type != 0 && type != GST_TYPE_LIST);
key = g_quark_from_string (name);
info = gst_tag_lookup (key);
g_return_if_fail (info == NULL);
info = g_new (GstTagInfo, 1);
info->type = type;
info->nick = nick;
info->blurb = blurb;
info->merge_func = func;
TAG_LOCK;
g_hash_table_insert (__tags, GUINT_TO_POINTER (key), info);
TAG_UNLOCK;
}
/**
* gst_tag_exists:
* @tag: name of the tag
*
* Checks if the given type is already registered.
*
* Returns: TRUE if the type is already registered
*/
gboolean
gst_tag_exists (const gchar *tag)
{
g_return_val_if_fail (tag != NULL, FALSE);
return gst_tag_lookup (g_quark_from_string (tag)) != NULL;
}
/**
* gst_tag_get_type:
* @tag: the tag
*
* Gets the #GType used for this tag.
*
* Returns: the #GType of this tag
*/
GType
gst_tag_get_type (const gchar *tag)
{
GstTagInfo *info;
g_return_val_if_fail (tag != NULL, 0);
info = gst_tag_lookup (g_quark_from_string (tag));
g_return_val_if_fail (info != NULL, 0);
return info->type;
}
/**
* gst_tag_get_nick
* @tag: the tag
*
* Returns the human-readable name of this tag, You must not change or free
* this string.
*
* Returns: the human-readable name of this tag
*/
const gchar *
gst_tag_get_nick (const gchar *tag)
{
GstTagInfo *info;
g_return_val_if_fail (tag != NULL, NULL);
info = gst_tag_lookup (g_quark_from_string (tag));
g_return_val_if_fail (info != NULL, NULL);
return info->nick;
}
/**
* gst_tag_get_description:
* @tag: the tag
*
* Returns the human-readable description of this tag, You must not change or
* free this string.
*
* Return the human-readable description of this tag
*/
const gchar *
gst_tag_get_description (const gchar *tag)
{
GstTagInfo *info;
g_return_val_if_fail (tag != NULL, NULL);
info = gst_tag_lookup (g_quark_from_string (tag));
g_return_val_if_fail (info != NULL, NULL);
return info->blurb;
}
/**
* gst_tag_list_is_fixed:
* @tag: tag to check
*
* Checks if the given tag is fixed. A fixed tag can only contain one value.
* Unfixed tags can contain lists of values.
*
* Returns: TRUE, if the given tag is fixed.
*/
gboolean
gst_tag_is_fixed (const gchar *tag)
{
GstTagInfo *info;
g_return_val_if_fail (tag != NULL, FALSE);
info = gst_tag_lookup (g_quark_from_string (tag));
g_return_val_if_fail (info != NULL, FALSE);
return info->merge_func == NULL;
}
/**
* gst_tag_list_new:
*
* Creates a new empty GstTagList.
*
* Returns: An empty tag list
*/
GstTagList *
gst_tag_list_new (void)
{
return GST_TAG_LIST (gst_structure_new (TAGLIST, NULL));
}
/**
* gst_is_tag_list:
* @p: Object that might be a taglist
*
* Checks if the given pointer is a taglist.
*
* Returns: TRUE, if the given pointer is a taglist
*/
gboolean
gst_is_tag_list (gconstpointer p)
{
g_return_val_if_fail (p != NULL, FALSE);
return ((GstStructure *) p)->name == gst_tag_list_quark;
}
typedef struct {
GstStructure * list;
GstTagMergeMode mode;
} GstTagCopyData;
static void
gst_tag_list_add_value_internal (GstStructure *list, GstTagMergeMode mode, GQuark tag, GValue *value)
{
GstTagInfo *info = gst_tag_lookup (tag);
GstStructureField *field;
g_assert (info != NULL);
if (info->merge_func && (field = gst_structure_id_get_field (list, tag)) != NULL) {
GValue value2 = { 0, };
switch (mode) {
case GST_TAG_MERGE_REPLACE_ALL:
case GST_TAG_MERGE_REPLACE:
gst_structure_id_set_value (list, tag, value);
break;
case GST_TAG_MERGE_PREPEND:
gst_value_list_concat (&value2, value, &field->value);
gst_structure_id_set_value (list, tag, &value2);
g_value_unset (&value2);
break;
case GST_TAG_MERGE_APPEND:
gst_value_list_concat (&value2, &field->value, value);
gst_structure_id_set_value (list, tag, &value2);
g_value_unset (&value2);
break;
case GST_TAG_MERGE_KEEP:
case GST_TAG_MERGE_KEEP_ALL:
break;
default:
g_assert_not_reached ();
break;
}
} else {
switch (mode) {
case GST_TAG_MERGE_APPEND:
case GST_TAG_MERGE_KEEP:
if (gst_structure_id_get_field (list, tag) != NULL)
break;
/* fall through */
case GST_TAG_MERGE_REPLACE_ALL:
case GST_TAG_MERGE_REPLACE:
case GST_TAG_MERGE_PREPEND:
gst_structure_id_set_value (list, tag, value);
break;
case GST_TAG_MERGE_KEEP_ALL:
break;
default:
g_assert_not_reached ();
break;
}
}
}
static void
gst_tag_list_copy_foreach (GstStructure *structure, GQuark tag, GValue *value, gpointer user_data)
{
GstTagCopyData *copy = (GstTagCopyData *) user_data;
gst_tag_list_add_value_internal (copy->list, copy->mode, tag, value);
}
/**
* gst_tag_list_insert:
* @into: list to merge into
* @from: list to merge from
* @mode: the mode to use
*
* Inserts the tags of the second list into the first list using the given mode.
*/
void
gst_tag_list_insert (GstTagList *into, const GstTagList *from, GstTagMergeMode mode)
{
GstTagCopyData data;
g_return_if_fail (GST_IS_TAG_LIST (into));
g_return_if_fail (GST_IS_TAG_LIST (from));
g_return_if_fail (GST_TAG_MODE_IS_VALID (mode));
data.list = (GstStructure *) into;
data.mode = mode;
if (mode == GST_TAG_MERGE_REPLACE_ALL) {
gst_structure_remove_all_fields (data.list);
}
gst_structure_field_foreach ((GstStructure *) from, gst_tag_list_copy_foreach, &data);
}
/**
* gst_tag_list_copy:
* @list: list to copy
*
* Copies a given #GstTagList.
*
* Returns: copy of the given list
*/
GstTagList *
gst_tag_list_copy (const GstTagList *list)
{
g_return_val_if_fail (GST_IS_TAG_LIST (list), NULL);
return GST_TAG_LIST (gst_structure_copy ((GstStructure *) list));
}
/**
* gst_tag_list_merge:
* @list1: first list to merge
* @list2: second list to merge
* @mode: the mode to use
*
* Merges the two given lists into a new list. If one of the lists is NULL, a
* copy of the other is returned. If both lists are NULL, NULL is returned.
*
* Returns: the new list
*/
GstTagList *
gst_tag_list_merge (const GstTagList *list1, const GstTagList *list2, GstTagMergeMode mode)
{
g_return_val_if_fail (list1 == NULL || GST_IS_TAG_LIST (list1), NULL);
g_return_val_if_fail (list2 == NULL || GST_IS_TAG_LIST (list2), NULL);
g_return_val_if_fail (GST_TAG_MODE_IS_VALID (mode), NULL);
if (!list1 && !list2) {
return NULL;
} else if (!list1) {
return gst_tag_list_copy (list2);
} else if (!list2) {
return gst_tag_list_copy (list1);
} else {
GstTagList *ret;
ret = gst_tag_list_copy (list1);
gst_tag_list_insert (ret, list2, mode);
return ret;
}
}
/**
* gst_tag_list_free:
* @list: the list to free
*
* Frees the given list and all associated values.
*/
void
gst_tag_list_free (GstTagList *list)
{
g_return_if_fail (GST_IS_TAG_LIST (list));
gst_structure_free ((GstStructure *) list);
}
/**
* gst_tag_list_get_tag_size:
* @list: a taglist
* @tag: the tag to query
*
* Checks how many value are stored in this tag list for the given tag.
*
* Returns: The number of tags stored
*/
guint
gst_tag_list_get_tag_size (const GstTagList *list, const gchar *tag)
{
const GValue *value;
g_return_val_if_fail (GST_IS_TAG_LIST (list), 0);
value = gst_structure_get_value ((GstStructure *) list, tag);
if (value == NULL)
return 0;
if (G_VALUE_TYPE (value) != GST_TYPE_LIST)
return 1;
return gst_value_list_get_size (value);
}
/**
* gst_tag_list_add:
* @list: list to set tags in
* @mode: the mode to use
* @tag: tag
* @...: values to set
*
* Sets the values for the given tags using the specified mode.
*/
void
gst_tag_list_add (GstTagList *list, GstTagMergeMode mode, const gchar *tag, ...)
{
va_list args;
g_return_if_fail (GST_IS_TAG_LIST (list));
g_return_if_fail (GST_TAG_MODE_IS_VALID (mode));
g_return_if_fail (tag != NULL);
va_start (args, tag);
gst_tag_list_add_valist (list, mode, tag, args);
va_end (args);
}
/**
* gst_tag_list_add_valist:
* @list: list to set tags in
* @mode: the mode to use
* @tag: tag
* @var_args: tag / value pairs to set
*
* Sets the values for the given tags using the specified mode.
*/
void
gst_tag_list_add_valist (GstTagList *list, GstTagMergeMode mode, const gchar *tag, va_list var_args)
{
GstTagInfo *info;
GQuark quark;
gchar *error = NULL;
g_return_if_fail (GST_IS_TAG_LIST (list));
g_return_if_fail (GST_TAG_MODE_IS_VALID (mode));
g_return_if_fail (tag != NULL);
while (tag != NULL) {
GValue value = { 0, };
quark = g_quark_from_string (tag);
info = gst_tag_lookup (quark);
g_return_if_fail (info != NULL);
g_value_init (&value, info->type);
G_VALUE_COLLECT (&value, var_args, 0, &error);
if (error) {
g_warning ("%s: %s", G_STRLOC, error);
g_free (error);
/* we purposely leak the value here, it might not be
* in a sane state if an error condition occoured
*/
return;
}
gst_tag_list_add_value_internal (list, mode, quark, &value);
g_value_unset (&value);
tag = va_arg (var_args, gchar *);
}
}
/**
* gst_tag_list_remove_tag:
* @list: list to remove tag from
* @tag: tag to remove
*
* Removes the goven tag from the taglist.
*/
void
gst_tag_list_remove_tag (GstTagList *list, const gchar *tag)
{
g_return_if_fail (GST_IS_TAG_LIST (list));
g_return_if_fail (tag != NULL);
gst_structure_remove_field ((GstStructure *) list, tag);
}
typedef struct {
GstTagForeachFunc func;
gpointer data;
} TagForeachData;
static void
structure_foreach_wrapper (GstStructure *structure, GQuark field_id,
GValue *value, gpointer user_data)
{
TagForeachData *data = (TagForeachData *) user_data;
data->func (GST_TAG_LIST (structure), g_quark_to_string (field_id), data->data);
}
/**
* gst_tag_list_foreach:
* @list: list to iterate over
* @func: function to be called for each tag
* @user_data: user specified data
*
* Calls the given function for each tag inside the tag list. Note that if there
* is no tag, the function won't be called at all.
*/
void
gst_tag_list_foreach (GstTagList *list, GstTagForeachFunc func, gpointer user_data)
{
TagForeachData data;
g_return_if_fail (GST_IS_TAG_LIST (list));
g_return_if_fail (func != NULL);
data.func = func;
data.data = user_data;
gst_structure_field_foreach ((GstStructure *) list, structure_foreach_wrapper, &data);
}
/***** tag events *****/
/**
* gst_event_new_tag:
* @list: the tag list to put into the event or NULL for an empty list
*
* Creates a new tag event with the given list and takes ownership of it.
*
* Returns: a new tag event
*/
GstEvent *
gst_event_new_tag (GstTagList *list)
{
GstEvent *ret;
g_return_val_if_fail (list == NULL || GST_IS_TAG_LIST (list), NULL);
ret = gst_event_new (GST_EVENT_TAG);
if (!list)
list = gst_tag_list_new ();
ret->event_data.structure.structure = (GstStructure *) list;
return ret;
}
/**
* get_event_tag_get_list:
* @tag_event: a tagging #GstEvent
*
* Gets the taglist from a given tagging event.
*
* Returns: The #GstTagList of the event
*/
GstTagList *
gst_event_tag_get_list (GstEvent *tag_event)
{
g_return_val_if_fail (GST_IS_EVENT (tag_event), NULL);
g_return_val_if_fail (GST_EVENT_TYPE (tag_event) == GST_EVENT_TAG, NULL);
return GST_TAG_LIST (tag_event->event_data.structure.structure);
}
/**
* gst_tag_list_get_value_index:
* @list: a #GStTagList
* @tag: tag to read out
* @index: number of entry to read out
*
* Gets the value that is at the given index for the given tag in the given
* list.
*
* Returns: The GValue for the specified entry or NULL if the tag wasn't available
* or the tag doesn't have as many entries
*/
G_CONST_RETURN GValue *
gst_tag_list_get_value_index (const GstTagList *list, const gchar *tag, guint index)
{
const GValue *value;
g_return_val_if_fail (GST_IS_TAG_LIST (list), NULL);
g_return_val_if_fail (tag != NULL, NULL);
value = gst_structure_get_value ((GstStructure *) list, tag);
if (value == NULL) return NULL;
if (GST_VALUE_HOLDS_LIST (value)) {
if (index >= gst_value_list_get_size (value)) return NULL;
return gst_value_list_get_value (value, index);
} else {
if (index > 0) return NULL;
return value;
}
}
/**
* gst_tag_list_copy_value:
* @dest: uninitialized #GValue to copy into
* @list: list to get the tag from
* @tag: tag to read out
*
* Copies the contents for the given tag into the value, merging multiple values
* into one if multiple values are associated with the tag.
* You must g_value_unset() the value after use.
*
* Returns: TRUE, if a value was copied, FALSE if the tag didn't exist in the
* given list.
*/
gboolean
gst_tag_list_copy_value (GValue *dest, const GstTagList *list, const gchar *tag)
{
const GValue *src;
g_return_val_if_fail (GST_IS_TAG_LIST (list), FALSE);
g_return_val_if_fail (tag != NULL, FALSE);
g_return_val_if_fail (dest != NULL, FALSE);
g_return_val_if_fail (G_VALUE_TYPE (dest) == 0, FALSE);
src = gst_structure_get_value ((GstStructure *) list, tag);
if (!src) return FALSE;
if (G_VALUE_TYPE (src) == GST_TYPE_LIST) {
GstTagInfo *info = gst_tag_lookup (g_quark_from_string (tag));
/* must be there or lists aren't allowed */
g_assert (info->merge_func);
info->merge_func (dest, src);
} else {
g_value_init (dest, G_VALUE_TYPE (src));
g_value_copy (src, dest);
}
return TRUE;
}
/***** evil macros to get all the gst_tag_list_get_*() functions right *****/
#define TAG_MERGE_FUNCS(name,type) \
gboolean \
gst_tag_list_get_ ## name (const GstTagList *list, const gchar *tag, \
type *value) \
{ \
GValue v = { 0, }; \
\
g_return_val_if_fail (GST_IS_TAG_LIST (list), FALSE); \
g_return_val_if_fail (tag != NULL, FALSE); \
g_return_val_if_fail (value != NULL, FALSE); \
\
if (!gst_tag_list_copy_value (&v, list, tag)) \
return FALSE; \
*value = COPY_FUNC (g_value_get_ ## name (&v)); \
g_value_unset (&v); \
return TRUE; \
} \
\
gboolean \
gst_tag_list_get_ ## name ## _index (const GstTagList *list, const gchar *tag, \
guint index, type *value) \
{ \
const GValue *v; \
\
g_return_val_if_fail (GST_IS_TAG_LIST (list), FALSE); \
g_return_val_if_fail (tag != NULL, FALSE); \
g_return_val_if_fail (value != NULL, FALSE); \
\
if ((v = gst_tag_list_get_value_index (list, tag, index)) == NULL) \
return FALSE; \
*value = COPY_FUNC (g_value_get_ ## name (v)); \
return TRUE; \
}
#define COPY_FUNC /**/
TAG_MERGE_FUNCS (char, gchar)
TAG_MERGE_FUNCS (uchar, guchar)
TAG_MERGE_FUNCS (boolean, gboolean)
TAG_MERGE_FUNCS (int, gint)
TAG_MERGE_FUNCS (uint, guint)
TAG_MERGE_FUNCS (long, glong)
TAG_MERGE_FUNCS (ulong, gulong)
TAG_MERGE_FUNCS (int64, gint64)
TAG_MERGE_FUNCS (uint64, guint64)
TAG_MERGE_FUNCS (float, gfloat)
TAG_MERGE_FUNCS (double, gdouble)
#undef COPY_FUNC
#define COPY_FUNC g_strdup
TAG_MERGE_FUNCS (string, gchar *)

View file

@ -20,17 +20,22 @@
* Boston, MA 02111-1307, USA.
*/
#include "gst_private.h"
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include "gsturi.h"
#include "gstregistrypool.h"
#include "gstinfo.h"
#include "gstregistrypool.h"
#include "gstmarshal.h"
static void gst_uri_handler_class_init (GstURIHandlerClass *klass);
static void gst_uri_handler_init (GstURIHandler *factory);
#include <string.h>
#include <ctype.h>
static GstPluginFeatureClass *parent_class = NULL;
/* static guint gst_uri_handler_signals[LAST_SIGNAL] = { 0 }; */
GST_DEBUG_CATEGORY_STATIC (gst_uri_handler_debug);
#define GST_CAT_DEFAULT gst_uri_handler_debug
static void gst_uri_handler_base_init (gpointer g_class);
GType
gst_uri_handler_get_type (void)
@ -39,222 +44,346 @@ gst_uri_handler_get_type (void)
if (!urihandler_type) {
static const GTypeInfo urihandler_info = {
sizeof (GstURIHandlerClass),
sizeof (GstURIHandlerInterface),
gst_uri_handler_base_init,
NULL,
NULL,
(GClassInitFunc) gst_uri_handler_class_init,
NULL,
NULL,
sizeof(GstURIHandler),
0,
(GInstanceInitFunc) gst_uri_handler_init,
0,
NULL,
NULL
};
urihandler_type = g_type_register_static (GST_TYPE_PLUGIN_FEATURE,
"GstURIHandler", &urihandler_info, 0);
urihandler_type = g_type_register_static (G_TYPE_INTERFACE,
"GstURIHandler", &urihandler_info, 0);
GST_DEBUG_CATEGORY_INIT (gst_uri_handler_debug, "GST_URI", GST_DEBUG_BOLD, "handling of URIs");
}
return urihandler_type;
}
static void
gst_uri_handler_base_init (gpointer g_class)
{
static gboolean initialized = FALSE;
if (!initialized) {
g_signal_new ("new_uri", GST_TYPE_URI_HANDLER, G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GstURIHandlerInterface, new_uri), NULL, NULL,
gst_marshal_VOID__STRING, G_TYPE_NONE, 1, G_TYPE_STRING);
initialized = TRUE;
}
}
static void
gst_uri_handler_class_init (GstURIHandlerClass *klass)
gst_uri_protocol_check_internal (const gchar *uri, gchar **endptr)
{
GObjectClass *gobject_class;
GstObjectClass *gstobject_class;
GstPluginFeatureClass *gstpluginfeature_class;
gchar *check = (gchar *) uri;
g_assert (uri != NULL);
g_assert (endptr != NULL);
gobject_class = (GObjectClass*)klass;
gstobject_class = (GstObjectClass*)klass;
gstpluginfeature_class = (GstPluginFeatureClass*) klass;
if (isalpha (*check)) {
check++;
while (isalnum (*check)) check++;
}
parent_class = g_type_class_ref (GST_TYPE_PLUGIN_FEATURE);
*endptr = check;
}
static void
gst_uri_handler_init (GstURIHandler *factory)
{
}
/**
* gst_uri_handler_new:
* @name: the name of the feature
* @uri: the uri to register
* @longdesc: a description for this uri
* @element: an element that can handle the uri
* @property: the property on the element to set the uri
* gst_uri_protocol_is_valid:
* @protocol: string to check
*
* Creates a plugin feature to register an element that can
* handle the given uri on the given property.
* Tests if the given string is a valid protocol identifier. Protocols
* must consist of alphanumeric characters and not start with a number.
*
* Returns: the new urihandler
*/
GstURIHandler*
gst_uri_handler_new (const gchar *name,
const gchar *uri, const gchar *longdesc,
const gchar *element, gchar *property)
{
GstURIHandler *factory;
g_return_val_if_fail (name != NULL, NULL);
g_return_val_if_fail (uri != NULL, NULL);
g_return_val_if_fail (element != NULL, NULL);
g_return_val_if_fail (property != NULL, NULL);
factory = gst_uri_handler_find (name);
if (!factory) {
factory = GST_URI_HANDLER (g_object_new (GST_TYPE_URI_HANDLER, NULL));
}
GST_PLUGIN_FEATURE_NAME (factory) = g_strdup (name);
factory->uri = g_strdup (uri);
factory->longdesc = g_strdup (longdesc);
factory->element = g_strdup (element);
factory->property = g_strdup (property);
return factory;
}
/**
* gst_uri_handler_find:
* @name: the name of the urihandler to find
*
* Return the URIHandler with the given name.
*
* Returns: a GstURIHandler with the given name;
*/
GstURIHandler*
gst_uri_handler_find (const gchar *name)
{
GstPluginFeature *feature;
g_return_val_if_fail (name != NULL, NULL);
feature = gst_registry_pool_find_feature (name, GST_TYPE_URI_HANDLER);
if (feature)
return GST_URI_HANDLER (feature);
return NULL;
}
/*
* this is a straight copy from glib 2.2
* remove this function when glib 2.2 is sufficiently widespread and
* then change to using the regular g_str_has_prefix
*/
static gboolean
g_str_has_prefix_glib22 (gchar *haystack, gchar *needle)
{
if (haystack == NULL && needle == NULL) {
return TRUE;
}
if (haystack == NULL || needle == NULL) {
return FALSE;
}
if (strncmp (haystack, needle, strlen (needle)) == 0) {
return TRUE;
}
return FALSE;
}
/**
* gst_uri_handler_uri_filter:
* @feature: the feature to inspect
* @uri: the name of the uri to match
*
* Check if the given pluginfeature is a uri hanler and that
* it can handle the given uri.
*
* Returns: TRUE if the feature can handle the uri.
* Returns: TRUE if the string is a valid protocol identifier
*/
gboolean
gst_uri_handler_uri_filter (GstPluginFeature *feature, const gchar *uri)
gst_uri_protocol_is_valid (const gchar *protocol)
{
if (G_OBJECT_TYPE (feature) == GST_TYPE_URI_HANDLER) {
GstURIHandler *handler = GST_URI_HANDLER (feature);
gchar *endptr;
if (g_str_has_prefix_glib22 ((gchar *) uri, handler->uri)) {
g_return_val_if_fail (protocol != NULL, FALSE);
gst_uri_protocol_check_internal (protocol, &endptr);
return *endptr == '\0' && endptr != protocol;
}
/**
* gst_uri_is_valid:
* @protocol: string to check
*
* Tests if the given string is a valid URI identifier. URIs start with a valid
* protocol followed by "://" and a string identifying the location.
*
* Returns: TRUE if the string is a valid URI
*/
gboolean
gst_uri_is_valid (const gchar *uri)
{
gchar *endptr;
g_return_val_if_fail (uri != NULL, FALSE);
gst_uri_protocol_check_internal (uri, &endptr);
return (*endptr == ':' &&
*(endptr + 1) == '/' &&
*(endptr + 2) == '/');
}
/**
* gst_uri_get_protocol:
* @uri: URI to get protocol from
*
* Extracts the protocol out of a given valid URI. The returned string must be
* freed using g_free().
*
* Returns: The protocol for this URI.
*/
gchar *
gst_uri_get_protocol (const gchar *uri)
{
gchar *colon;
g_return_val_if_fail (uri != NULL, NULL);
g_return_val_if_fail (gst_uri_is_valid (uri), NULL);
colon = strstr (uri, "://");
return g_strndup (uri, colon - uri);
}
/**
* gst_uri_get_location:
* @uri: URI to get the location from
*
* Extracts the location out of a given valid URI. So the protocol and "://"
* are stripped from the URI. The returned string must be freed using
* g_free().
*
* Returns: The location for this URI.
*/
gchar *
gst_uri_get_location (const gchar *uri)
{
gchar *colon;
g_return_val_if_fail (uri != NULL, NULL);
g_return_val_if_fail (gst_uri_is_valid (uri), NULL);
colon = strstr (uri, "://");
return g_strdup (colon + 3);
}
/**
* gst_uri_construct:
* @protocol: protocol for URI
* @location: location for URI
*
* Constructs a URI for a given valid protocol and location.
*
* Returns: a new string for this URI
*/
gchar *
gst_uri_construct (const gchar *protocol, const gchar *location)
{
g_return_val_if_fail (gst_uri_protocol_is_valid (protocol), NULL);
g_return_val_if_fail (location != NULL, NULL);
return g_strdup_printf ("%s://%s", protocol, location);
}
typedef struct{
GstURIType type;
gchar * protocol;
} SearchEntry;
static gboolean
search_by_entry (GstPluginFeature *feature, gpointer search_entry)
{
gchar **protocols;
GstElementFactory *factory;
SearchEntry *entry = (SearchEntry *) search_entry;
if (!GST_IS_ELEMENT_FACTORY (feature))
return FALSE;
factory = GST_ELEMENT_FACTORY (feature);
if (gst_element_factory_get_uri_type (factory) != entry->type)
return FALSE;
protocols = gst_element_factory_get_uri_protocols (factory);
/* must be set when uri type is valid */
g_assert (protocols);
while (*protocols != NULL) {
if (strcmp (*protocols, entry->protocol) == 0)
return TRUE;
}
protocols++;
}
return FALSE;
}
/**
* gst_uri_handler_find_by_uri:
* @uri: the uri to find a handler for
*
* Find a URIHandler for the given uri.
*
* Returns: a GstURIHandler that can handle the given uri.
*/
GstURIHandler*
gst_uri_handler_find_by_uri (const gchar *uri)
static gint
sort_by_rank (gconstpointer a, gconstpointer b)
{
GList *walk;
GstURIHandler *result = NULL;
g_return_val_if_fail (uri != NULL, NULL);
GstPluginFeature *first = GST_PLUGIN_FEATURE (a);
GstPluginFeature *second = GST_PLUGIN_FEATURE (b);
walk = gst_registry_pool_feature_filter (
(GstPluginFeatureFilter) gst_uri_handler_uri_filter, TRUE, (gpointer) uri);
return gst_plugin_feature_get_rank (second) - gst_plugin_feature_get_rank (first);
}
/**
* gst_element_make_from_uri:
* @type: wether to create a source or a sink
* @uri: URI to create element for
* @elementname: optional name of created element
*
* Creates an element for handling the given URI.
*
* Returns: a new element or NULL if none could be created
*/
GstElement *
gst_element_make_from_uri (const GstURIType type, const gchar *uri, const gchar *elementname)
{
GList *possibilities, *walk;
SearchEntry entry;
GstElement *ret = NULL;
if (walk) {
result = GST_URI_HANDLER (walk->data);
g_return_val_if_fail (GST_URI_TYPE_IS_VALID (type), NULL);
g_return_val_if_fail (gst_uri_is_valid (uri), NULL);
entry.type = type;
entry.protocol = gst_uri_get_protocol (uri);
possibilities = gst_registry_pool_feature_filter (search_by_entry, FALSE, &entry);
g_free (entry.protocol);
if (!possibilities) {
GST_DEBUG ("No %s for URI '%s'", type == GST_URI_SINK ? "sink" : "source", uri);
return NULL;
}
g_list_free (walk);
return result;
}
/**
* gst_uri_handler_create:
* @handler: the uri handler to use
* @name: the name of the element
*
* Create an element with the given name from the given handler.
*
* Returns: a new element associated with the handler.
*/
GstElement*
gst_uri_handler_create (GstURIHandler *handler, const gchar *name)
{
GstElement *element = NULL;
g_return_val_if_fail (handler != NULL, NULL);
element = gst_element_factory_make (handler->element, name);
return element;
}
/**
* gst_uri_handler_make_by_uri:
* @uri: the uri
* @name: the name of the element
*
* Create an element with the given name that can handle the given
* uri. This function will also use set the uri on the element.
*
* Returns: a new element that can handle the uri.
*/
GstElement*
gst_uri_handler_make_by_uri (const gchar *uri, const gchar *name)
{
GstElement *element = NULL;
GstURIHandler *handler;
g_return_val_if_fail (uri != NULL, NULL);
handler = gst_uri_handler_find_by_uri (uri);
if (handler) {
element = gst_uri_handler_create (handler, name);
if (element) {
g_object_set (G_OBJECT (element), handler->property, uri, NULL);
possibilities = g_list_sort (possibilities, sort_by_rank);
walk = possibilities;
while (walk) {
if ((ret = gst_element_factory_create (GST_ELEMENT_FACTORY (walk->data),
elementname)) != NULL) {
GstURIHandler *handler = GST_URI_HANDLER (ret);
if (gst_uri_handler_set_uri (handler, uri))
break;
g_object_unref (ret);
ret = NULL;
}
}
return element;
g_list_free (possibilities);
GST_LOG_OBJECT (ret, "created %s for URL '%s'", type == GST_URI_SINK ? "sink" : "source", uri);
return ret;
}
/**
* gst_uri_handler_get_uri_type:
* @handler: Handler to query type of
*
* Gets the type of a URI handler
*
* Returns: the type of the URI handler
*/
guint
gst_uri_handler_get_uri_type (GstURIHandler *handler)
{
GstURIHandlerInterface *iface;
guint ret;
g_return_val_if_fail (GST_IS_URI_HANDLER (handler), GST_URI_UNKNOWN);
iface = GST_URI_HANDLER_GET_INTERFACE (handler);
g_return_val_if_fail (iface != NULL, GST_URI_UNKNOWN);
g_return_val_if_fail (iface->get_type != NULL, GST_URI_UNKNOWN);
ret = iface->get_type ();
g_return_val_if_fail (GST_URI_TYPE_IS_VALID (ret), GST_URI_UNKNOWN);
return ret;
}
/**
* gst_uri_handler_get_protocols:
* @handler: Handler to get protocols for
*
* Gets the list of supported protocols for this handler. This list may not be
* modified.
*
* Returns: the supported protocols
*/
gchar **
gst_uri_handler_get_protocols (GstURIHandler *handler)
{
GstURIHandlerInterface *iface;
gchar **ret;
g_return_val_if_fail (GST_IS_URI_HANDLER (handler), NULL);
iface = GST_URI_HANDLER_GET_INTERFACE (handler);
g_return_val_if_fail (iface != NULL, NULL);
g_return_val_if_fail (iface->get_protocols != NULL, NULL);
ret = iface->get_protocols ();
g_return_val_if_fail (ret != NULL, NULL);
return ret;
}
/**
* gst_uri_handler_get_uri:
* @handler: handler to query URI of
*
* Gets the currently handled URI of the handler or NULL, if none is set.
*
* Returns: the URI
*/
G_CONST_RETURN gchar *
gst_uri_handler_get_uri (GstURIHandler *handler)
{
GstURIHandlerInterface *iface;
const gchar *ret;
g_return_val_if_fail (GST_IS_URI_HANDLER (handler), NULL);
iface = GST_URI_HANDLER_GET_INTERFACE (handler);
g_return_val_if_fail (iface != NULL, NULL);
g_return_val_if_fail (iface->get_uri != NULL, NULL);
ret = iface->get_uri (handler);
if (ret != NULL)
g_return_val_if_fail (gst_uri_is_valid (ret), NULL);
return ret;
}
/**
* gst_uri_handler_set_uri:
* @handler: handler to set URI of
* @uri: URI to set
*
* Tries to set the URI of the given handler and returns TRUE if it succeeded.
*
* Returns: TRUE, if the URI was set successfully
*/
gboolean
gst_uri_handler_set_uri (GstURIHandler *handler, const gchar *uri)
{
GstURIHandlerInterface *iface;
g_return_val_if_fail (GST_IS_URI_HANDLER (handler), FALSE);
g_return_val_if_fail (gst_uri_is_valid (uri), FALSE);
iface = GST_URI_HANDLER_GET_INTERFACE (handler);
g_return_val_if_fail (iface != NULL, FALSE);
g_return_val_if_fail (iface->set_uri != NULL, FALSE);
return iface->set_uri (handler, uri);
}
/**
* gst_uri_handler_new_uri:
* @handler: handler with a new URI
* @uri: new URI or NULL if it was unset
*
* Emits the new-uri event for a given handler, when that handler has a new URI.
* This function should only be called by URI handlers themselves.
*/
void
gst_uri_handler_new_uri (GstURIHandler *handler, const gchar *uri)
{
g_return_if_fail (GST_IS_URI_HANDLER (handler));
g_signal_emit_by_name (handler, "new-uri", uri);
}

View file

@ -30,50 +30,76 @@
G_BEGIN_DECLS
typedef enum {
GST_URI_UNKNOWN,
GST_URI_SINK,
GST_URI_SRC
} GstURIType;
#define GST_URI_TYPE_IS_VALID(type) ((type) == GST_URI_SRC || (type) == GST_URI_SINK)
/* uri handler functions */
#define GST_TYPE_URI_HANDLER (gst_uri_handler_get_type ())
#define GST_URI_HANDLER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GST_TYPE_URI_HANDLER, GstURIHandler))
#define GST_IS_URI_HANDLER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GST_TYPE_URI_HANDLER))
#define GST_URI_HANDLER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GST_TYPE_URI_HANDLER, GstURIHandlerClass))
#define GST_IS_URI_HANDLER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GST_TYPE_URI_HANDLER))
#define GST_URI_HANDLER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GST_TYPE_URI_HANDLER, GstURIHandlerClass))
#define GST_URI_HANDLER_GET_INTERFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), GST_TYPE_URI_HANDLER, GstURIHandlerInterface))
#define GST_URI_HANDLER_CLASS(obj) (G_TYPE_CHECK_CLASS_CAST ((obj), GST_TYPE_URI_HANDLER, GstURIHandler))
typedef struct _GstURIHandler GstURIHandler;
typedef struct _GstURIHandlerClass GstURIHandlerClass;
typedef struct _GstURIHandlerInterface GstURIHandlerInterface;
struct _GstURIHandler {
GstPluginFeature feature;
struct _GstURIHandlerInterface {
GTypeInterface parent;
/* --- public ---- */
gchar *uri; /* The uri that is described */
gchar *longdesc; /* description of the uri */
gchar *element; /* The element that can handle this uri */
gchar *property; /* The property on the element to set the uri */
/* signals */
void (* new_uri) (GstURIHandler * handler,
const gchar * uri);
/* idea for the future ?
gboolean (* require_password) (GstURIHandler * handler,
gchar ** username,
gchar ** password);
*/
GST_OBJECT_PADDING
};
/* vtable */
struct _GstURIHandlerClass {
GstPluginFeatureClass parent;
/* querying capabilities */
GstURIType (* get_type) (void);
gchar ** (* get_protocols) (void);
/* using the interface */
G_CONST_RETURN gchar *(* get_uri) (GstURIHandler * handler);
gboolean (* set_uri) (GstURIHandler * handler,
const gchar * uri);
/* we might want to add functions here to query features, someone with gnome-vfs knowledge go ahead */
GST_CLASS_PADDING
};
GType gst_uri_handler_get_type (void);
/* general URI functions */
GstURIHandler* gst_uri_handler_new (const gchar *name,
const gchar *uri, const gchar *longdesc,
const gchar *element, gchar *property);
gboolean gst_uri_protocol_is_valid (const gchar * protocol);
gboolean gst_uri_is_valid (const gchar * uri);
gchar * gst_uri_get_protocol (const gchar * uri);
gchar * gst_uri_get_location (const gchar * uri);
gchar * gst_uri_construct (const gchar * protocol,
const gchar * location);
GstURIHandler* gst_uri_handler_find (const gchar *name);
GstURIHandler* gst_uri_handler_find_by_uri (const gchar *uri);
GstElement * gst_element_make_from_uri (const GstURIType type,
const gchar * uri,
const gchar * elementname);
GstElement* gst_uri_handler_create (GstURIHandler *handler, const gchar *name);
GstElement* gst_uri_handler_make_by_uri (const gchar *uri, const gchar *name);
/* accessing the interface */
GType gst_uri_handler_get_type (void);
/* filters */
gboolean gst_uri_handler_uri_filter (GstPluginFeature *feature, const gchar *uri);
guint gst_uri_handler_get_uri_type (GstURIHandler * handler);
gchar ** gst_uri_handler_get_protocols (GstURIHandler * handler);
G_CONST_RETURN gchar * gst_uri_handler_get_uri (GstURIHandler * handler);
gboolean gst_uri_handler_set_uri (GstURIHandler * handler,
const gchar * uri);
void gst_uri_handler_new_uri (GstURIHandler * handler,
const gchar * uri);
G_END_DECLS
#endif /* __GST_URI_H */
#endif /* __GST_URI_H__ */

View file

@ -205,6 +205,53 @@ gst_value_union_lists (GValue *dest, const GValue *value1, const GValue *value2)
return TRUE;
}
/**
* gst_value_list_concat:
* @dest: an uninitialized #GValue to take the result
* @value1: first value to put into the union
* @value2: second value to put into the union
*
* Concatenates copies of value1 and value2 into a list. dest will be
* initialized to the type GST_TYPE_LIST.
*/
void
gst_value_list_concat (GValue *dest, const GValue *value1, const GValue *value2)
{
guint i, value1_length, value2_length;
GArray *array;
g_return_if_fail (dest != NULL);
g_return_if_fail (G_VALUE_TYPE (dest) == 0);
g_return_if_fail (G_IS_VALUE (value1));
g_return_if_fail (G_IS_VALUE (value2));
value1_length = (GST_VALUE_HOLDS_LIST (value1) ? gst_value_list_get_size (value1) : 1);
value2_length = (GST_VALUE_HOLDS_LIST (value2) ? gst_value_list_get_size (value2) : 1);
g_value_init (dest, GST_TYPE_LIST);
array = (GArray *) dest->data[0].v_pointer;
g_array_set_size (array, value1_length + value2_length);
if (GST_VALUE_HOLDS_LIST (value1)) {
for (i = 0; i < value1_length; i++) {
g_value_init (&g_array_index(array, GValue, i), G_VALUE_TYPE (gst_value_list_get_value (value1, i)));
g_value_copy (gst_value_list_get_value (value1, i), &g_array_index(array, GValue, i));
}
} else {
g_value_init (&g_array_index(array, GValue, 0), G_VALUE_TYPE (value1));
g_value_copy (value1, &g_array_index(array, GValue, 0));
}
if (GST_VALUE_HOLDS_LIST (value2)) {
for (i = 0; i < value2_length; i++) {
g_value_init (&g_array_index(array, GValue, i + value1_length), G_VALUE_TYPE (gst_value_list_get_value (value2, i)));
g_value_copy (gst_value_list_get_value (value2, i), &g_array_index(array, GValue, i + value1_length));
}
} else {
g_value_init (&g_array_index(array, GValue, value1_length), G_VALUE_TYPE (value2));
g_value_copy (value2, &g_array_index(array, GValue, value1_length));
}
}
/* fourcc */
static void

View file

@ -21,6 +21,7 @@
#define __GST_VALUE_H__
#include <gst/gstconfig.h>
#include <gst/gstcaps2.h>
G_BEGIN_DECLS
@ -76,6 +77,12 @@ double gst_value_get_double_range_max (const GValue *value);
const GstCaps2 *gst_value_get_caps (const GValue *value);
void gst_value_set_caps (GValue *calue, const GstCaps2 *caps);
void gst_value_list_prepend_value (GValue *value, const GValue *prepend_value);
void gst_value_list_append_value (GValue *value, const GValue *prepend_value);
guint gst_value_list_get_size (const GValue *value);
const GValue *gst_value_list_get_value (const GValue *value, guint index);
void gst_value_list_concat (GValue *dest, const GValue *value1, const GValue *value2);
void _gst_value_initialize (void);
int gst_value_compare (const GValue *src1, const GValue *src2);

View file

@ -71,6 +71,7 @@ gst_xml_class_init (GstXMLClass *klass)
parent_class = g_type_class_ref (GST_TYPE_OBJECT);
/* FIXME G_TYPE_POINTER should be GType of xmlNodePtr */
gst_xml_signals[OBJECT_LOADED] =
g_signal_new ("object_loaded", G_TYPE_FROM_CLASS(klass), G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GstXMLClass, object_loaded), NULL, NULL,

View file

@ -7,8 +7,10 @@
#include "../gst_private.h"
#include "../gstconfig.h"
#include "../gstparse.h"
#include "../gstinfo.h"
#include "../gsturi.h"
#include "types.h"
#define YYERROR_VERBOSE 1
@ -97,7 +99,7 @@ typedef struct {
} \
}G_STMT_END
#define ERROR(type, ...) SET_ERROR (((graph_t *) graph)->error, (type), __VA_ARGS__ )
#ifdef GST_DEBUG_ENABLED
#ifndef GST_DISABLE_GST_DEBUG
# define YYDEBUG 1
/* bison 1.35 calls this macro with side effects, we need to make sure the
side effects work - crappy bison
@ -122,7 +124,7 @@ typedef struct {
} \
}G_STMT_END
#define ERROR(type, args...) SET_ERROR (((graph_t *) graph)->error, (type), ## args )
#ifdef GST_DEBUG_ENABLED
#ifndef GST_DISABLE_GST_DEBUG
# define YYDEBUG 1
/* bison 1.35 calls this macro with side effects, we need to make sure the
side effects work - crappy bison
@ -147,7 +149,7 @@ typedef struct {
} \
}G_STMT_END
#define ERROR(type, ...) SET_ERROR (((graph_t *) graph)->error, (type), "error while parsing")
#ifdef GST_DEBUG_ENABLED
#ifndef GST_DISABLE_GST_DEBUG
# define YYDEBUG 1
#endif
@ -210,23 +212,6 @@ typedef struct {
MAKE_LINK (link, NULL, _src, pads, NULL, NULL, NULL); \
}G_STMT_END
static inline void gst_parse_unescape (gchar *str)
{
gchar *walk;
g_return_if_fail (str != NULL);
walk = str;
while (*walk) {
if (*walk == '\\')
walk++;
*str = *walk;
str++;
walk++;
}
*str = '\0';
}
static void
gst_parse_element_set (gchar *value, GstElement *element, graph_t *graph)
{
@ -532,6 +517,7 @@ static int yyerror (const char *s);
graph_t *g;
}
%token <s> PARSE_URL
%token <s> IDENTIFIER
%left <s> REF PADREF BINREF
%token <s> ASSIGNMENT
@ -542,7 +528,7 @@ static int yyerror (const char *s);
%type <l> reference
%type <l> linkpart link
%type <p> linklist
%type <e> element
%type <e> element
%type <p> padlist pads assignments
%left '{' '}' '(' ')'
@ -566,12 +552,11 @@ element: IDENTIFIER { $$ = gst_element_factory_make ($1, NULL);
$$ = $1;
}
;
assignments: /* NOP */ { $$ = NULL; }
| assignments ASSIGNMENT { $$ = g_slist_prepend ($1, $2); }
;
bin: '{' assignments chain '}' { GST_BIN_MAKE ($$, "thread", $3, $2); }
| '(' assignments chain ')' { GST_BIN_MAKE ($$, "bin", $3, $2); }
bin: '{' assignments chain '}' { GST_BIN_MAKE ($$, "thread", $3, $2); }
| '(' assignments chain ')' { GST_BIN_MAKE ($$, "bin", $3, $2); }
| BINREF assignments chain ')' { GST_BIN_MAKE ($$, $1, $3, $2);
gst_parse_strfree ($1);
}
@ -668,21 +653,6 @@ chain: element { $$ = gst_parse_chain_new ();
gst_parse_chain_free ($2);
$$ = $1;
}
| link chain { if ($2->front) {
if (!$2->front->src_name) {
ERROR (GST_PARSE_ERROR_LINK, "link without source element");
gst_parse_free_link ($2->front);
} else {
((graph_t *) graph)->links = g_slist_prepend (((graph_t *) graph)->links, $2->front);
}
}
if (!$1->sink_name) {
$1->sink = $2->first;
}
$2->front = $1;
$$ = $2;
}
| chain linklist { GSList *walk;
if ($1->back) {
$2 = g_slist_prepend ($2, $1->back);
@ -714,8 +684,60 @@ chain: element { $$ = gst_parse_chain_new ();
$$ = $1;
}
| chain error { $$ = $1; }
| link chain { if ($2->front) {
if (!$2->front->src_name) {
ERROR (GST_PARSE_ERROR_LINK, "link without source element");
gst_parse_free_link ($2->front);
} else {
((graph_t *) graph)->links = g_slist_prepend (((graph_t *) graph)->links, $2->front);
}
}
if (!$1->sink_name) {
$1->sink = $2->first;
}
$2->front = $1;
$$ = $2;
}
| PARSE_URL chain { $$ = $2;
if ($$->front) {
GstElement *element =
gst_element_make_from_uri (GST_URI_SRC, $1, NULL);
if (!element) {
ERROR (GST_PARSE_ERROR_NO_SUCH_ELEMENT,
"No source element for URI \"%s\"", $1);
} else {
$$->front->src = element;
((graph_t *) graph)->links = g_slist_prepend (
((graph_t *) graph)->links, $$->front);
$$->front = NULL;
$$->elements = g_slist_prepend ($$->elements, element);
}
} else {
ERROR (GST_PARSE_ERROR_LINK,
"No element to link URI \"%s\" to", $1);
}
g_free ($1);
}
| link PARSE_URL { GstElement *element =
gst_element_make_from_uri (GST_URI_SINK, $2, NULL);
if (!element) {
ERROR (GST_PARSE_ERROR_NO_SUCH_ELEMENT,
"No sink element for URI \"%s\"", $2);
YYERROR;
} else if ($1->sink_name || $1->sink_pads) {
ERROR (GST_PARSE_ERROR_LINK,
"could not link sink element for URI \"%s\"", $2);
YYERROR;
} else {
$$ = gst_parse_chain_new ();
$$->first = $$->last = element;
$$->front = $1;
$$->front->sink = element;
$$->elements = g_slist_prepend (NULL, element);
}
g_free ($2);
}
;
graph: /* NOP */ { ERROR (GST_PARSE_ERROR_EMPTY, "Empty pipeline not allowed");
$$ = (graph_t *) graph;
}
@ -783,7 +805,7 @@ _gst_parse_launch (const gchar *str, GError **error)
dstr = g_strdup (str);
_gst_parse_yy_scan_string (dstr);
#ifdef GST_DEBUG_ENABLED
#ifndef GST_DISABLE_GST_DEBUG
yydebug = 1;
#endif

View file

@ -7,6 +7,7 @@
#include "types.h"
#include "../gstinfo.h"
#include "../gsturi.h"
#include "grammar.tab.h"
#ifdef G_HAVE_ISO_VARARGS
@ -29,6 +30,9 @@ _string {_char}+|("\""([^\"]|"\\\"")*"\"")|("'"([^']|"\\\"")*"'")
_comma [[:space:]]*","[[:space:]]*
_assign [[:space:]]*"="[[:space:]]*
_protocol [[:alpha:]][[:alnum:]+-\.]*
_url {_protocol}"://"{_string}|["."{_identifier}]?"/"{_string}
/* we must do this here, because nearly everything matches a {_string} */
_assignment {_identifier}{_assign}{_string}
@ -106,6 +110,17 @@ _link ("!"[[:space:]]*{_caps}([[:space:]]*";"[[:space:]]*{_caps})*[[:space:]]*"!
BEGIN (INITIAL);
return LINK;
}
{_url} {
PRINT ("URL: %s\n", yytext);
if (gst_uri_is_valid (yytext)) {
lvalp->s = g_strdup (yytext);
} else {
lvalp->s = gst_uri_construct ("file", yytext);
}
gst_parse_unescape (lvalp->s);
BEGIN (INITIAL);
return PARSE_URL;
}
{_operator} { PRINT ("OPERATOR: [%s]\n", yytext); return *yytext; }

View file

@ -66,4 +66,23 @@ void __gst_parse_chain_free (chain_t *data);
# define gst_parse_chain_free g_free
#endif /* __GST_PARSE_TRACE */
static inline void
gst_parse_unescape (gchar *str)
{
gchar *walk;
g_return_if_fail (str != NULL);
walk = str;
while (*walk) {
if (*walk == '\\')
walk++;
*str = *walk;
str++;
walk++;
}
*str = '\0';
}
#endif /* __GST_PARSE_TYPES_H__ */

View file

@ -679,6 +679,26 @@ gst_xml_registry_parse_plugin (GMarkupParseContext *context, const gchar *tag, c
return TRUE;
}
static void
add_to_char_array (gchar ***array, gchar *value)
{
gchar **new;
gchar **old = *array;
gint i = 0;
/* expensive, but cycles are cheap... */
if (old)
while (old[i]) i++;
new = g_new0 (gchar *, i + 2);
new[i] = value;
while (i > 0) {
i--;
new[i] = old[i];
}
g_free (old);
*array = new;
}
static gboolean
gst_xml_registry_parse_element_factory (GMarkupParseContext *context, const gchar *tag, const gchar *text,
gsize text_len, GstXMLRegistry *registry, GError **error)
@ -686,8 +706,9 @@ gst_xml_registry_parse_element_factory (GMarkupParseContext *context, const gcha
GstElementFactory *factory = GST_ELEMENT_FACTORY (registry->current_feature);
if (!strcmp (tag, "name")) {
g_free (registry->current_feature->name);
registry->current_feature->name = g_strndup (text, text_len);
gchar *name = g_strndup (text, text_len);
gst_plugin_feature_set_name (registry->current_feature, name);
g_free (name);
}
else if (!strcmp (tag, "longname")) {
g_free (factory->details.longname);
@ -708,12 +729,26 @@ gst_xml_registry_parse_element_factory (GMarkupParseContext *context, const gcha
else if (!strcmp(tag, "rank")) {
gint rank;
gchar *ret;
rank = strtol (text, &ret, 0);
rank = strtol (text, &ret, 0);
if (ret == text + text_len) {
gst_plugin_feature_set_rank (GST_PLUGIN_FEATURE (factory), rank);
}
} else if (!strcmp (tag, "uri_type")) {
if (strncasecmp (text, "sink", 4) == 0) {
factory->uri_type = GST_URI_SINK;
} else if (strncasecmp (text, "source", 5) == 0) {
factory->uri_type = GST_URI_SRC;
}
} else if (!strcmp (tag, "uri_protocol")) {
add_to_char_array (&factory->uri_protocols, g_strndup (text, text_len));
}
else if (!strcmp(tag, "interface")) {
gchar *tmp = g_strndup (text, text_len);
__gst_element_factory_add_interface (factory, tmp);
g_free (tmp);
}
return TRUE;
}
@ -739,21 +774,7 @@ gst_xml_registry_parse_type_find_factory (GMarkupParseContext *context, const gc
factory->caps = g_strndup (text, text_len);
}*/
else if (!strcmp(tag, "extension")) {
gchar **new;
gchar **old = factory->extensions;
gint i = 0;
/* expensive, but cycles are cheap... */
if (old)
while (old[i]) i++;
new = g_new0 (gchar *, i + 2);
new[i] = g_strndup (text, text_len);
while (i > 0) {
i--;
new[i] = old[i];
}
g_free (old);
factory->extensions = new;
add_to_char_array (&factory->extensions, g_strndup (text, text_len));
}
return TRUE;
@ -806,30 +827,6 @@ gst_xml_registry_parse_index_factory (GMarkupParseContext *context, const gchar
return TRUE;
}
static gboolean
gst_xml_registry_parse_uri_handler (GMarkupParseContext *context, const gchar *tag, const gchar *text,
gsize text_len, GstXMLRegistry *registry, GError **error)
{
GstURIHandler *handler = GST_URI_HANDLER (registry->current_feature);
if (!strcmp (tag, "name")) {
registry->current_feature->name = g_strndup (text, text_len);
}
else if (!strcmp (tag, "uri")) {
handler->uri = g_strndup (text, text_len);
}
else if (!strcmp (tag, "longdesc")) {
handler->longdesc = g_strndup (text, text_len);
}
else if (!strcmp (tag, "element")) {
handler->element = g_strndup (text, text_len);
}
else if (!strcmp (tag, "property")) {
handler->property = g_strndup (text, text_len);
}
return TRUE;
}
static gboolean
gst_xml_registry_parse_padtemplate (GMarkupParseContext *context, const gchar *tag, const gchar *text,
gsize text_len, GstXMLRegistry *registry, GError **error)
@ -948,9 +945,6 @@ gst_xml_registry_start_element (GMarkupParseContext *context,
else if (GST_IS_INDEX_FACTORY (feature)) {
xmlregistry->parser = gst_xml_registry_parse_index_factory;
}
else if (GST_IS_URI_HANDLER (feature)) {
xmlregistry->parser = gst_xml_registry_parse_uri_handler;
}
else {
g_warning ("unkown feature type");
}
@ -1490,23 +1484,41 @@ gst_xml_registry_save_feature (GstXMLRegistry *xmlregistry, GstPluginFeature *fe
if (GST_IS_ELEMENT_FACTORY (feature)) {
GstElementFactory *factory = GST_ELEMENT_FACTORY (feature);
GList *templates;
GList *walk;
PUT_ESCAPED ("longname", factory->details.longname);
PUT_ESCAPED ("class", factory->details.klass);
PUT_ESCAPED ("description", factory->details.description);
PUT_ESCAPED ("author", factory->details.author);
templates = factory->padtemplates;
walk = factory->padtemplates;
while (templates) {
GstPadTemplate *template = GST_PAD_TEMPLATE (templates->data);
while (walk) {
GstPadTemplate *template = GST_PAD_TEMPLATE (walk->data);
CLASS (xmlregistry)->save_func (xmlregistry, "<padtemplate>\n");
gst_xml_registry_save_pad_template (xmlregistry, template);
CLASS (xmlregistry)->save_func (xmlregistry, "</padtemplate>\n");
templates = g_list_next (templates);
walk = g_list_next (walk);
}
walk = factory->interfaces;
while (walk) {
PUT_ESCAPED ("interface", (gchar *) walk->data);
walk = g_list_next (walk);
}
if (GST_URI_TYPE_IS_VALID (factory->uri_type)) {
gchar **protocol;
PUT_ESCAPED ("uri_type", factory->uri_type == GST_URI_SINK ? "sink" : "source");
g_assert (factory->uri_protocols);
protocol = factory->uri_protocols;
while (*protocol) {
PUT_ESCAPED ("uri_protocol", *protocol);
protocol++;
}
}
}
else if (GST_IS_TYPE_FIND_FACTORY (feature)) {
@ -1535,18 +1547,9 @@ gst_xml_registry_save_feature (GstXMLRegistry *xmlregistry, GstPluginFeature *fe
else if (GST_IS_INDEX_FACTORY (feature)) {
PUT_ESCAPED ("longdesc", GST_INDEX_FACTORY (feature)->longdesc);
}
else if (GST_IS_URI_HANDLER (feature)) {
GstURIHandler *handler = GST_URI_HANDLER (feature);
PUT_ESCAPED ("uri", handler->uri);
PUT_ESCAPED ("longdesc", handler->longdesc);
PUT_ESCAPED ("element", handler->element);
PUT_ESCAPED ("property", handler->property);
}
return TRUE;
}
static gboolean
gst_xml_registry_save_plugin (GstXMLRegistry *xmlregistry, GstPlugin *plugin)
{

View file

@ -314,6 +314,7 @@ gst_basic_scheduler_loopfunc_wrapper (int argc, char **argv)
static int
gst_basic_scheduler_chain_wrapper (int argc, char **argv)
{
GSList *already_iterated = NULL;
GstElement *element = GST_ELEMENT_CAST (argv);
G_GNUC_UNUSED const gchar *name = GST_ELEMENT_NAME (element);
@ -323,39 +324,47 @@ gst_basic_scheduler_chain_wrapper (int argc, char **argv)
gst_object_ref (GST_OBJECT (element));
do {
GList *pads = element->pads;
GList *pads;
do {
pads = element->pads;
while (pads) {
GstPad *pad = GST_PAD (pads->data);
GstRealPad *realpad;
while (pads) {
GstPad *pad = GST_PAD (pads->data);
GstRealPad *realpad;
pads = g_list_next (pads);
if (!GST_IS_REAL_PAD (pad))
continue;
if (!GST_IS_REAL_PAD (pad))
continue;
realpad = GST_REAL_PAD_CAST (pad);
realpad = GST_REAL_PAD (pad);
if (GST_RPAD_DIRECTION (realpad) == GST_PAD_SINK &&
GST_PAD_IS_LINKED (realpad)) {
GstData *data;
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_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_RPAD_CHAINFUNC (realpad) (pad, data);
GST_CAT_DEBUG (debug_dataflow,
"calling chain function of element %s done", name);
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_RPAD_CHAINFUNC (realpad) (pad, 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);
g_slist_free (already_iterated);
already_iterated = NULL;
} while (!GST_ELEMENT_IS_COTHREAD_STOPPING (element));
GST_FLAG_UNSET (element, GST_ELEMENT_COTHREAD_STOPPING);

View file

@ -147,11 +147,11 @@ rm -f $RPM_BUILD_ROOT%{_libdir}/*.la
%{_libdir}/gstreamer-%{majorminor}/libgstbasicgthreadscheduler*.so
%{_libdir}/gstreamer-%{majorminor}/libgstoptgthreadscheduler*.so
%{_libdir}/gstreamer-%{majorminor}/libgstelements*.so*
%{_libdir}/gstreamer-%{majorminor}/libgsttypes*.so*
%{_libdir}/gstreamer-%{majorminor}/libgststaticautoplug*.so*
%{_libdir}/gstreamer-%{majorminor}/libgstgetbits*.so*
%{_libdir}/gstreamer-%{majorminor}/libgstspider*.so*
%{_libdir}/gstreamer-%{majorminor}/libgstindexers.so
%{_libdir}/gstreamer-%{majorminor}/libgstindexers.so*
%{_libdir}/gstreamer-%{majorminor}/libgstbytestream.so
%{_datadir}/locale/*
%files tools
@ -184,6 +184,7 @@ rm -f $RPM_BUILD_ROOT%{_libdir}/*.la
%{_includedir}/%{name}-%{majorminor}/gst/control/*.h
%dir %{_includedir}/%{name}-%{majorminor}/gst/getbits
%{_includedir}/%{name}-%{majorminor}/gst/getbits/getbits.h
%{_includedir}/%{name}-%{majorminor}/gst/bytestream/bytestream.h
# %{_libdir}/libgstreamer.a
%{_libdir}/libgstreamer-%{majorminor}.so
%{_libdir}/libgstcontrol-%{majorminor}.so
@ -195,19 +196,21 @@ rm -f $RPM_BUILD_ROOT%{_libdir}/*.la
# we list all of the files we really need to trap incomplete doc builds
# then we catch the rest with *, you can safely ignore the errors from this
## gstreamer API
# %dir %{_datadir}/gtk-doc/html/%{name}-%{majorminor}
# %{_datadir}/gtk-doc/html/%{name}-%{majorminor}/%{name}-%{majorminor}.devhelp
# %{_datadir}/gtk-doc/html/%{name}-%{majorminor}/element-types.html
# %{_datadir}/gtk-doc/html/%{name}-%{majorminor}/gstreamer.html
# %{_datadir}/gtk-doc/html/%{name}-%{majorminor}/index.sgml
%{_datadir}/gtk-doc/html/%{name}-%{majorminor}/*
## gstreamer-libs API
# %dir %{_datadir}/gtk-doc/html/%{name}-libs-%{majorminor}
# %{_datadir}/gtk-doc/html/%{name}-libs-%{majorminor}/index.sgml
%{_datadir}/gtk-doc/html/%{name}-libs-%{majorminor}/*
## this catches all of the rest of the docs we might have forgotten
# %{_datadir}/gtk-doc/html/*
%changelog
* Sun Nov 09 2003 Christian Schaller <Uraeus@gnome.org>
- Fix spec to handle new bytestream library
* Sun Aug 17 2003 Christian Schaller <uraeus@gnome.org>
- Remove docs build from RPM as the build is broken
- Fix stuff since more files are versioned now

View file

@ -1,3 +1,3 @@
SUBDIRS = control getbits bytestream
SUBDIRS = bytestream control getbits
DIST_SUBDIRS = control getbits bytestream
DIST_SUBDIRS = bytestream control getbits

View file

@ -465,7 +465,6 @@ gst_dpman_register_mode (GstDParamManagerClass *klass,
mode->teardownfunc = teardownfunc;
g_hash_table_insert(klass->modes, modename, mode);
GST_DEBUG ("mode '%s' registered", modename);
}
/**

View file

@ -1,10 +1,10 @@
### all of the standard pc files we need to generate
pcfiles = \
gstreamer-@GST_MAJORMINOR@.pc \
pcfiles = \
gstreamer-@GST_MAJORMINOR@.pc \
gstreamer-control-@GST_MAJORMINOR@.pc
pcfiles_uninstalled = \
gstreamer-@GST_MAJORMINOR@-uninstalled.pc \
pcfiles_uninstalled = \
gstreamer-@GST_MAJORMINOR@-uninstalled.pc \
gstreamer-control-@GST_MAJORMINOR@-uninstalled.pc
all-local: $(pcfiles) $(pcfiles_uninstalled)
@ -18,10 +18,10 @@ $(pcfiles_uninstalled): %-@GST_MAJORMINOR@-uninstalled.pc: %-uninstalled.pc
pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA = $(pcfiles)
EXTRA_DIST = \
gstreamer.pc.in \
gstreamer-uninstalled.pc.in \
gstreamer-control.pc.in \
EXTRA_DIST = \
gstreamer.pc.in \
gstreamer-uninstalled.pc.in \
gstreamer-control.pc.in \
gstreamer-control-uninstalled.pc.in
CLEANFILES = $(pcfiles) $(pcfiles_uninstalled)

View file

@ -119,7 +119,7 @@ gst_buffer_store_class_init (gpointer g_class, gpointer class_data)
gst_buffer_store_signals[BUFFER_ADDED] = g_signal_new ("buffer-added",
G_TYPE_FROM_CLASS (g_class), G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GstBufferStoreClass, buffer_added), continue_accu, NULL,
gst_marshal_BOOLEAN__POINTER, G_TYPE_BOOLEAN, 1, G_TYPE_POINTER);
gst_marshal_BOOLEAN__POINTER, G_TYPE_BOOLEAN, 1, GST_TYPE_BUFFER);
store_class->cleared = gst_buffer_store_cleared_func;
store_class->buffer_added = gst_buffer_store_add_buffer_func;

View file

@ -175,8 +175,8 @@ gst_fakesink_class_init (GstFakeSinkClass *klass)
gst_fakesink_signals[SIGNAL_HANDOFF] =
g_signal_new ("handoff", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GstFakeSinkClass, handoff), NULL, NULL,
g_cclosure_marshal_VOID__POINTER, G_TYPE_NONE, 1,
G_TYPE_POINTER);
gst_marshal_VOID__POINTER_OBJECT, G_TYPE_NONE, 2,
GST_TYPE_BUFFER, GST_TYPE_PAD);
gobject_class->set_property = GST_DEBUG_FUNCPTR (gst_fakesink_set_property);
gobject_class->get_property = GST_DEBUG_FUNCPTR (gst_fakesink_get_property);

View file

@ -271,8 +271,8 @@ gst_fakesrc_class_init (GstFakeSrcClass *klass)
gst_fakesrc_signals[SIGNAL_HANDOFF] =
g_signal_new ("handoff", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GstFakeSrcClass, handoff), NULL, NULL,
g_cclosure_marshal_VOID__POINTER, G_TYPE_NONE, 1,
G_TYPE_POINTER);
gst_marshal_VOID__POINTER_OBJECT, G_TYPE_NONE, 2,
GST_TYPE_BUFFER, GST_TYPE_PAD);
gobject_class->set_property = GST_DEBUG_FUNCPTR (gst_fakesrc_set_property);
gobject_class->get_property = GST_DEBUG_FUNCPTR (gst_fakesrc_get_property);

View file

@ -69,6 +69,7 @@ GST_PAD_FORMATS_FUNCTION (gst_filesink_get_formats,
static void gst_filesink_base_init (gpointer g_class);
static void gst_filesink_class_init (GstFileSinkClass *klass);
static void gst_filesink_init (GstFileSink *filesink);
static void gst_filesink_dispose (GObject *object);
static void gst_filesink_set_property (GObject *object, guint prop_id,
const GValue *value, GParamSpec *pspec);
@ -83,6 +84,8 @@ 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_uri_handler_init (gpointer g_iface, gpointer iface_data);
static GstElementStateReturn gst_filesink_change_state (GstElement *element);
static GstElementClass *parent_class = NULL;
@ -105,7 +108,14 @@ gst_filesink_get_type (void)
0,
(GInstanceInitFunc)gst_filesink_init,
};
static const GInterfaceInfo urihandler_info = {
gst_filesink_uri_handler_init,
NULL,
NULL
};
filesink_type = g_type_register_static (GST_TYPE_ELEMENT, "GstFileSink", &filesink_info, 0);
g_type_add_interface_static (filesink_type, GST_TYPE_URI_HANDLER, &urihandler_info);
GST_DEBUG_CATEGORY_INIT (gst_filesink_debug, "filesink", 0, "filesink element");
}
@ -138,8 +148,8 @@ gst_filesink_class_init (GstFileSinkClass *klass)
gobject_class->set_property = gst_filesink_set_property;
gobject_class->get_property = gst_filesink_get_property;
gobject_class->dispose = gst_filesink_dispose;
}
static void
gst_filesink_init (GstFileSink *filesink)
{
@ -158,7 +168,38 @@ gst_filesink_init (GstFileSink *filesink)
filesink->filename = NULL;
filesink->file = NULL;
}
static void
gst_filesink_dispose (GObject *object)
{
GstFileSink *sink = GST_FILESINK (object);
G_OBJECT_CLASS (parent_class)->dispose (object);
g_free (sink->uri);
sink->uri = NULL;
g_free (sink->filename);
sink->filename = NULL;
}
static gboolean
gst_filesink_set_location (GstFileSink *sink, const gchar *location)
{
/* the element must be stopped or paused in order to do this */
if (GST_STATE (sink) > GST_STATE_PAUSED)
return FALSE;
if (GST_STATE (sink) == GST_STATE_PAUSED &&
GST_FLAG_IS_SET (sink, GST_FILESINK_OPEN))
return FALSE;
g_free (sink->filename);
g_free (sink->uri);
sink->filename = g_strdup (location);
sink->uri = gst_uri_construct ("file", location);
if (GST_STATE (sink) == GST_STATE_PAUSED)
gst_filesink_open_file (sink);
return TRUE;
}
static void
gst_filesink_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
{
@ -169,16 +210,7 @@ gst_filesink_set_property (GObject *object, guint prop_id, const GValue *value,
switch (prop_id) {
case ARG_LOCATION:
/* the element must be stopped or paused in order to do this */
g_return_if_fail (GST_STATE (sink) <= GST_STATE_PAUSED);
if (GST_STATE (sink) == GST_STATE_PAUSED)
g_return_if_fail (!GST_FLAG_IS_SET (sink, GST_FILESINK_OPEN));
if (sink->filename)
g_free (sink->filename);
sink->filename = g_strdup (g_value_get_string (value));
if (GST_STATE (sink) == GST_STATE_PAUSED)
gst_filesink_open_file (sink);
gst_filesink_set_location (sink, g_value_get_string (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
@ -435,3 +467,54 @@ gst_filesink_change_state (GstElement *element)
return GST_STATE_SUCCESS;
}
/*** GSTURIHANDLER INTERFACE *************************************************/
static guint
gst_filesink_uri_get_type (void)
{
return GST_URI_SINK;
}
static gchar **
gst_filesink_uri_get_protocols(void)
{
static gchar *protocols[] = {"file", NULL};
return protocols;
}
static const gchar *
gst_filesink_uri_get_uri (GstURIHandler *handler)
{
GstFileSink *sink = GST_FILESINK (handler);
return sink->uri;
}
static gboolean
gst_filesink_uri_set_uri (GstURIHandler *handler, const gchar *uri)
{
gchar *protocol, *location;
gboolean ret;
GstFileSink *sink = GST_FILESINK (handler);
protocol = gst_uri_get_protocol (uri);
if (strcmp (protocol, "file") != 0) {
g_free (protocol);
return FALSE;
}
g_free (protocol);
location = gst_uri_get_location (uri);
ret = gst_filesink_set_location (sink, location);
g_free (location);
return ret;
}
static void
gst_filesink_uri_handler_init (gpointer g_iface, gpointer iface_data)
{
GstURIHandlerInterface *iface = (GstURIHandlerInterface *) g_iface;
iface->get_type = gst_filesink_uri_get_type;
iface->get_protocols = gst_filesink_uri_get_protocols;
iface->get_uri = gst_filesink_uri_get_uri;
iface->set_uri = gst_filesink_uri_set_uri;
}

View file

@ -53,6 +53,7 @@ struct _GstFileSink {
GstElement element;
gchar *filename;
gchar *uri;
FILE *file;
guint64 data_written;

View file

@ -128,6 +128,7 @@ static void gst_filesrc_set_property (GObject *object, guint prop_id,
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 gboolean gst_filesrc_srcpad_event (GstPad *pad, GstEvent *event);
static gboolean gst_filesrc_srcpad_query (GstPad *pad, GstQueryType type,
@ -135,6 +136,8 @@ static gboolean gst_filesrc_srcpad_query (GstPad *pad, GstQueryType type,
static GstElementStateReturn gst_filesrc_change_state (GstElement *element);
static void gst_filesrc_uri_handler_init (gpointer g_iface, gpointer iface_data);
static GstElementClass *parent_class = NULL;
/*static guint gst_filesrc_signals[LAST_SIGNAL] = { 0 };*/
@ -156,8 +159,15 @@ gst_filesrc_get_type(void)
0,
(GInstanceInitFunc)gst_filesrc_init,
};
static const GInterfaceInfo urihandler_info = {
gst_filesrc_uri_handler_init,
NULL,
NULL
};
filesrc_type = g_type_register_static (GST_TYPE_ELEMENT, "GstFileSrc", &filesrc_info, 0);
g_type_add_interface_static (filesrc_type, GST_TYPE_URI_HANDLER, &urihandler_info);
GST_DEBUG_CATEGORY_INIT (gst_filesrc_debug, "filesrc", 0, "filesrc element");
}
return filesrc_type;
@ -262,8 +272,32 @@ gst_filesrc_dispose (GObject *object)
g_mutex_free (src->map_regions_lock);
if (src->filename)
g_free (src->filename);
if (src->uri)
g_free (src->uri);
}
static gboolean
gst_filesrc_set_location (GstFileSrc *src, const gchar *location)
{
/* the element must be stopped in order to do this */
if (GST_STATE (src) == GST_STATE_PLAYING)
return FALSE;
if (src->filename) g_free (src->filename);
if (src->uri) g_free (src->uri);
/* clear the filename if we get a NULL (is that possible?) */
if (location == NULL) {
src->filename = NULL;
src->uri = NULL;
} else {
src->filename = g_strdup (location);
src->uri = gst_uri_construct ("file", src->filename);
}
g_object_notify (G_OBJECT (src), "location");
gst_uri_handler_new_uri (GST_URI_HANDLER (src), src->uri);
return TRUE;
}
static void
gst_filesrc_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec)
@ -277,19 +311,7 @@ gst_filesrc_set_property (GObject *object, guint prop_id, const GValue *value, G
switch (prop_id) {
case ARG_LOCATION:
/* the element must be stopped in order to do this */
g_return_if_fail (GST_STATE (src) < GST_STATE_PLAYING);
if (src->filename) g_free (src->filename);
/* clear the filename if we get a NULL (is that possible?) */
if (g_value_get_string (value) == NULL) {
gst_element_set_state (GST_ELEMENT (object), GST_STATE_NULL);
src->filename = NULL;
/* otherwise set the new filename */
} else {
src->filename = g_strdup (g_value_get_string (value));
}
g_object_notify (G_OBJECT (src), "location");
gst_filesrc_set_location (src, g_value_get_string (value));
break;
case ARG_BLOCKSIZE:
src->block_size = g_value_get_ulong (value);
@ -506,8 +528,10 @@ gst_filesrc_get_mmap (GstFileSrc *src)
/* check to see if we're going to overflow the end of the file */
if (readend > src->filelen) {
readsize = src->filelen - src->curoffset;
readend = src->curoffset + readsize;
if (!gst_filesrc_check_filesize (src) || readend > src->filelen) {
readsize = src->filelen - src->curoffset;
readend = src->curoffset + readsize;
}
}
GST_LOG ("attempting to read %08lx, %08lx, %08lx, %08lx",
@ -599,7 +623,7 @@ gst_filesrc_get_mmap (GstFileSrc *src)
/* subbuffer it */
buf = gst_buffer_create_sub (src->mapbuf, src->curoffset - nextmap, readsize);
GST_BUFFER_OFFSET (buf) = mapstart + src->curoffset - nextmap;
GST_BUFFER_OFFSET (buf) = GST_BUFFER_OFFSET (src->mapbuf) + src->curoffset - nextmap;
}
}
}
@ -613,6 +637,7 @@ gst_filesrc_get_mmap (GstFileSrc *src)
}
/* we're done, return the buffer */
g_assert (src->curoffset == GST_BUFFER_OFFSET (buf));
src->curoffset += GST_BUFFER_SIZE(buf);
return buf;
}
@ -626,7 +651,9 @@ gst_filesrc_get_read (GstFileSrc *src)
readsize = src->block_size;
if (src->curoffset + readsize > src->filelen) {
readsize = src->filelen - src->curoffset;
if (!gst_filesrc_check_filesize (src) || src->curoffset + readsize > src->filelen) {
readsize = src->filelen - src->curoffset;
}
}
buf = gst_buffer_new_and_alloc (readsize);
@ -675,11 +702,14 @@ gst_filesrc_get (GstPad *pad)
}
/* check for EOF */
g_assert (src->curoffset <= src->filelen);
if (src->curoffset == src->filelen) {
GST_DEBUG_OBJECT (src, "eos %" G_GINT64_FORMAT" %" G_GINT64_FORMAT,
src->curoffset, src->filelen);
gst_element_set_eos (GST_ELEMENT (src));
return GST_DATA (gst_event_new (GST_EVENT_EOS));
if (!gst_filesrc_check_filesize (src) || src->curoffset >= src->filelen) {
GST_DEBUG_OBJECT (src, "eos %" G_GINT64_FORMAT" %" G_GINT64_FORMAT,
src->curoffset, src->filelen);
gst_element_set_eos (GST_ELEMENT (src));
return GST_DATA (gst_event_new (GST_EVENT_EOS));
}
}
if (src->using_mmap){
@ -689,6 +719,22 @@ gst_filesrc_get (GstPad *pad)
}
}
/* TRUE if the filesize of the file was updated */
static gboolean
gst_filesrc_check_filesize (GstFileSrc *src)
{
struct stat stat_results;
g_return_val_if_fail (GST_FLAG_IS_SET (src ,GST_FILESRC_OPEN), FALSE);
fstat(src->fd, &stat_results);
GST_DEBUG_OBJECT (src, "checked filesize on %s (was %"G_GUINT64_FORMAT", is %"G_GUINT64_FORMAT")",
src->filename, src->filelen, (guint64) stat_results.st_size);
if (src->filelen == (guint64) stat_results.st_size)
return FALSE;
src->filelen = stat_results.st_size;
return TRUE;
}
/* open the file and mmap it, necessary to go to READY state */
static gboolean
gst_filesrc_open_file (GstFileSrc *src)
@ -799,6 +845,7 @@ gst_filesrc_srcpad_query (GstPad *pad, GstQueryType type,
if (*format != GST_FORMAT_BYTES) {
return FALSE;
}
gst_filesrc_check_filesize (src);
*value = src->filelen;
break;
case GST_QUERY_POSITION:
@ -842,20 +889,25 @@ gst_filesrc_srcpad_event (GstPad *pad, GstEvent *event)
switch (GST_EVENT_SEEK_METHOD (event)) {
case GST_SEEK_METHOD_SET:
if (offset > src->filelen)
goto error;
if (offset > src->filelen && (!gst_filesrc_check_filesize (src) || offset > src->filelen)) {
goto error;
}
src->curoffset = offset;
GST_DEBUG_OBJECT (src, "seek set pending to %" G_GINT64_FORMAT, src->curoffset);
break;
case GST_SEEK_METHOD_CUR:
if (offset + src->curoffset > src->filelen)
goto error;
if (!gst_filesrc_check_filesize (src) || offset + src->curoffset > src->filelen)
goto error;
src->curoffset += offset;
GST_DEBUG_OBJECT (src, "seek cur pending to %" G_GINT64_FORMAT, src->curoffset);
break;
case GST_SEEK_METHOD_END:
if (ABS (offset) > src->filelen)
if (ABS (offset) > src->filelen) {
if (!gst_filesrc_check_filesize (src) || ABS (offset) > src->filelen)
goto error;
goto error;
}
src->curoffset = src->filelen - ABS (offset);
GST_DEBUG_OBJECT (src, "seek end pending to %" G_GINT64_FORMAT, src->curoffset);
break;
@ -888,3 +940,55 @@ error:
gst_event_unref (event);
return FALSE;
}
/*** GSTURIHANDLER INTERFACE *************************************************/
static guint
gst_filesrc_uri_get_type (void)
{
return GST_URI_SRC;
}
static gchar **
gst_filesrc_uri_get_protocols(void)
{
static gchar *protocols[] = {"file", NULL};
return protocols;
}
static const gchar *
gst_filesrc_uri_get_uri (GstURIHandler *handler)
{
GstFileSrc *src = GST_FILESRC (handler);
return src->uri;
}
static gboolean
gst_filesrc_uri_set_uri (GstURIHandler *handler, const gchar *uri)
{
gchar *protocol, *location;
gboolean ret;
GstFileSrc *src = GST_FILESRC (handler);
protocol = gst_uri_get_protocol (uri);
if (strcmp (protocol, "file") != 0) {
g_free (protocol);
return FALSE;
}
g_free (protocol);
location = gst_uri_get_location (uri);
ret = gst_filesrc_set_location (src, location);
g_free (location);
return ret;
}
static void
gst_filesrc_uri_handler_init (gpointer g_iface, gpointer iface_data)
{
GstURIHandlerInterface *iface = (GstURIHandlerInterface *) g_iface;
iface->get_type = gst_filesrc_uri_get_type;
iface->get_protocols = gst_filesrc_uri_get_protocols;
iface->get_uri = gst_filesrc_uri_get_uri;
iface->set_uri = gst_filesrc_uri_set_uri;
}

View file

@ -58,6 +58,7 @@ struct _GstFileSrc {
guint pagesize; /* system page size*/
gchar *filename; /* filename */
gchar *uri; /* caching the URI */
gint fd; /* open file descriptor*/
off_t filelen; /* what's the file length?*/

View file

@ -145,8 +145,8 @@ gst_identity_class_init (GstIdentityClass *klass)
gst_identity_signals[SIGNAL_HANDOFF] =
g_signal_new ("handoff", G_TYPE_FROM_CLASS(klass), G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GstIdentityClass, handoff), NULL, NULL,
g_cclosure_marshal_VOID__POINTER, G_TYPE_NONE, 1,
G_TYPE_POINTER);
gst_marshal_VOID__POINTER, G_TYPE_NONE, 1,
GST_TYPE_BUFFER);
gobject_class->set_property = GST_DEBUG_FUNCPTR (gst_identity_set_property);
gobject_class->get_property = GST_DEBUG_FUNCPTR (gst_identity_get_property);

View file

@ -223,6 +223,7 @@ gst_queue_init (GTypeInstance *instance, gpointer g_class)
gst_pad_set_bufferpool_function (queue->sinkpad, GST_DEBUG_FUNCPTR (gst_queue_get_bufferpool));
gst_pad_set_link_function (queue->sinkpad, 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 ("src", GST_PAD_SRC);
gst_pad_set_get_function (queue->srcpad, GST_DEBUG_FUNCPTR (gst_queue_get));
@ -230,6 +231,7 @@ gst_queue_init (GTypeInstance *instance, gpointer g_class)
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_active (queue->srcpad, TRUE);
queue->leaky = GST_QUEUE_NO_LEAK;
queue->queue = NULL;
@ -695,6 +697,10 @@ gst_queue_change_state (GstElement *element)
}
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);
error:
g_mutex_unlock (queue->qlock);

View file

@ -282,11 +282,11 @@ clean: mostlyclean
distclean: clean
rm -f Makefile Makefile.in POTFILES *.mo
rm -f stamp-po $(GMOFILES)
maintainer-clean: distclean
@echo "This command is intended for maintainers to use;"
@echo "it deletes files that may require special tools to rebuild."
rm -f stamp-po $(GMOFILES)
dist distdir:
$(MAKE) update-po

View file

@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: gstreamer-0.7 0.7.0.1\n"
"Report-Msgid-Bugs-To: \"http://bugzilla.gnome.org\"\n"
"POT-Creation-Date: 2003-10-08 15:36-0700\n"
"POT-Creation-Date: 2003-11-22 17:49+0100\n"
"PO-Revision-Date: 2003-10-08 15:36-0700\n"
"Last-Translator: David Schleef <ds@schleef.org>\n"
"Language-Team: Gnome Translators <i18n@gnome.org>\n"
@ -15,74 +15,71 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
#: gst/gst.c:113
#: gst/gst.c:112
msgid "Print the GStreamer version"
msgstr "druck die GStreamer Version"
#: gst/gst.c:114
#: gst/gst.c:113
msgid "Make all warnings fatal"
msgstr "macht alle Achtunge toedlich"
#: gst/gst.c:116
#: gst/gst.c:115
msgid ""
"default debug level from 1 (only error) to 5 (anything) or 0 for no output"
msgstr ""
#: gst/gst.c:117
#: gst/gst.c:116
msgid ""
"colon-seperated list of category_name=level pairs to set specific levels for "
"the individual categories.\n"
"Example:GST_AUTOPLUG=5:GST_ELEMENT_*=3"
msgstr ""
#: gst/gst.c:118
#: gst/gst.c:117
msgid "disable color debugging output"
msgstr "abschalt Farbe in Fehlersucheausgabe"
#: gst/gst.c:119
#: gst/gst.c:118
msgid "disable debugging"
msgstr "abschalt die Fehlersuche"
#: gst/gst.c:120
#: gst/gst.c:119
msgid "print available debug categories and exit"
msgstr ""
#: gst/gst.c:122
#: gst/gst.c:121
msgid "Disable accelerated CPU instructions"
msgstr ""
#: gst/gst.c:123
#: gst/gst.c:122
msgid "enable verbose plugin loading diagnostics"
msgstr ""
#: gst/gst.c:124
#: gst/gst.c:123
msgid "'"
msgstr ""
#: gst/gst.c:124
#: gst/gst.c:123
msgid "'--separated path list for loading plugins"
msgstr ""
#: gst/gst.c:125
#: gst/gst.c:124
msgid ""
"comma-separated list of plugins to preload in addition to the list stored in "
"env variable GST_PLUGIN_PATH"
msgstr ""
#: gst/gst.c:126
#: gst/gst.c:125
msgid "scheduler to use ('"
msgstr ""
#: gst/gst.c:126
#: gst/gst.c:125
msgid "' is the default)"
msgstr ""
#: gst/gst.c:127
#: gst/gst.c:126
msgid "registry to use"
msgstr ""
#~ msgid "This is a test\n"
#~ msgstr "moo\n"

View file

@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: GStreamer 0.7.0.1\n"
"Report-Msgid-Bugs-To: \"http://bugzilla.gnome.org\"\n"
"POT-Creation-Date: 2003-10-08 16:20-0700\n"
"POT-Creation-Date: 2003-11-22 17:49+0100\n"
"PO-Revision-Date: 2003-10-09 14:10-0700\n"
"Last-Translator: David Schleef <ds@schleef.org>\n"
"Language-Team: translators <translation@gnome.org>\n"
@ -15,68 +15,68 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
#: gst/gst.c:113
#: gst/gst.c:112
msgid "Print the GStreamer version"
msgstr ""
#: gst/gst.c:114
#: gst/gst.c:113
msgid "Make all warnings fatal"
msgstr ""
#: gst/gst.c:116
#: gst/gst.c:115
msgid ""
"default debug level from 1 (only error) to 5 (anything) or 0 for no output"
msgstr ""
#: gst/gst.c:117
#: gst/gst.c:116
msgid ""
"colon-seperated list of category_name=level pairs to set specific levels for "
"the individual categories.\n"
"Example:GST_AUTOPLUG=5:GST_ELEMENT_*=3"
msgstr ""
#: gst/gst.c:118
#: gst/gst.c:117
msgid "disable color debugging output"
msgstr ""
#: gst/gst.c:119
#: gst/gst.c:118
msgid "disable debugging"
msgstr ""
#: gst/gst.c:120
#: gst/gst.c:119
msgid "print available debug categories and exit"
msgstr ""
#: gst/gst.c:122
#: gst/gst.c:121
msgid "Disable accelerated CPU instructions"
msgstr ""
#: gst/gst.c:123
#: gst/gst.c:122
msgid "enable verbose plugin loading diagnostics"
msgstr ""
#: gst/gst.c:124
#: gst/gst.c:123
msgid "'"
msgstr ""
#: gst/gst.c:124
#: gst/gst.c:123
msgid "'--separated path list for loading plugins"
msgstr ""
#: gst/gst.c:125
#: gst/gst.c:124
msgid ""
"comma-separated list of plugins to preload in addition to the list stored in "
"env variable GST_PLUGIN_PATH"
msgstr ""
#: gst/gst.c:126
#: gst/gst.c:125
msgid "scheduler to use ('"
msgstr ""
#: gst/gst.c:126
#: gst/gst.c:125
msgid "' is the default)"
msgstr ""
#: gst/gst.c:127
#: gst/gst.c:126
msgid "registry to use"
msgstr ""

View file

@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: GStreamer 0.7.0.1\n"
"Report-Msgid-Bugs-To: \"http://bugzilla.gnome.org\"\n"
"POT-Creation-Date: 2003-10-08 16:20-0700\n"
"POT-Creation-Date: 2003-11-22 17:49+0100\n"
"PO-Revision-Date: 2003-10-09 14:10-0700\n"
"Last-Translator: David Schleef <ds@schleef.org>\n"
"Language-Team: translators <translation@gnome.org>\n"
@ -15,68 +15,68 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
#: gst/gst.c:113
#: gst/gst.c:112
msgid "Print the GStreamer version"
msgstr ""
#: gst/gst.c:114
#: gst/gst.c:113
msgid "Make all warnings fatal"
msgstr ""
#: gst/gst.c:116
#: gst/gst.c:115
msgid ""
"default debug level from 1 (only error) to 5 (anything) or 0 for no output"
msgstr ""
#: gst/gst.c:117
#: gst/gst.c:116
msgid ""
"colon-seperated list of category_name=level pairs to set specific levels for "
"the individual categories.\n"
"Example:GST_AUTOPLUG=5:GST_ELEMENT_*=3"
msgstr ""
#: gst/gst.c:118
#: gst/gst.c:117
msgid "disable color debugging output"
msgstr ""
#: gst/gst.c:119
#: gst/gst.c:118
msgid "disable debugging"
msgstr ""
#: gst/gst.c:120
#: gst/gst.c:119
msgid "print available debug categories and exit"
msgstr ""
#: gst/gst.c:122
#: gst/gst.c:121
msgid "Disable accelerated CPU instructions"
msgstr ""
#: gst/gst.c:123
#: gst/gst.c:122
msgid "enable verbose plugin loading diagnostics"
msgstr ""
#: gst/gst.c:124
#: gst/gst.c:123
msgid "'"
msgstr ""
#: gst/gst.c:124
#: gst/gst.c:123
msgid "'--separated path list for loading plugins"
msgstr ""
#: gst/gst.c:125
#: gst/gst.c:124
msgid ""
"comma-separated list of plugins to preload in addition to the list stored in "
"env variable GST_PLUGIN_PATH"
msgstr ""
#: gst/gst.c:126
#: gst/gst.c:125
msgid "scheduler to use ('"
msgstr ""
#: gst/gst.c:126
#: gst/gst.c:125
msgid "' is the default)"
msgstr ""
#: gst/gst.c:127
#: gst/gst.c:126
msgid "registry to use"
msgstr ""

View file

@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: GStreamer 0.7.0.1\n"
"Report-Msgid-Bugs-To: \"http://bugzilla.gnome.org\"\n"
"POT-Creation-Date: 2003-10-08 16:20-0700\n"
"POT-Creation-Date: 2003-11-22 17:49+0100\n"
"PO-Revision-Date: 2003-10-09 14:10-0700\n"
"Last-Translator: David Schleef <ds@schleef.org>\n"
"Language-Team: translators <translation@gnome.org>\n"
@ -15,68 +15,68 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
#: gst/gst.c:113
#: gst/gst.c:112
msgid "Print the GStreamer version"
msgstr ""
#: gst/gst.c:114
#: gst/gst.c:113
msgid "Make all warnings fatal"
msgstr ""
#: gst/gst.c:116
#: gst/gst.c:115
msgid ""
"default debug level from 1 (only error) to 5 (anything) or 0 for no output"
msgstr ""
#: gst/gst.c:117
#: gst/gst.c:116
msgid ""
"colon-seperated list of category_name=level pairs to set specific levels for "
"the individual categories.\n"
"Example:GST_AUTOPLUG=5:GST_ELEMENT_*=3"
msgstr ""
#: gst/gst.c:118
#: gst/gst.c:117
msgid "disable color debugging output"
msgstr ""
#: gst/gst.c:119
#: gst/gst.c:118
msgid "disable debugging"
msgstr ""
#: gst/gst.c:120
#: gst/gst.c:119
msgid "print available debug categories and exit"
msgstr ""
#: gst/gst.c:122
#: gst/gst.c:121
msgid "Disable accelerated CPU instructions"
msgstr ""
#: gst/gst.c:123
#: gst/gst.c:122
msgid "enable verbose plugin loading diagnostics"
msgstr ""
#: gst/gst.c:124
#: gst/gst.c:123
msgid "'"
msgstr ""
#: gst/gst.c:124
#: gst/gst.c:123
msgid "'--separated path list for loading plugins"
msgstr ""
#: gst/gst.c:125
#: gst/gst.c:124
msgid ""
"comma-separated list of plugins to preload in addition to the list stored in "
"env variable GST_PLUGIN_PATH"
msgstr ""
#: gst/gst.c:126
#: gst/gst.c:125
msgid "scheduler to use ('"
msgstr ""
#: gst/gst.c:126
#: gst/gst.c:125
msgid "' is the default)"
msgstr ""
#: gst/gst.c:127
#: gst/gst.c:126
msgid "registry to use"
msgstr ""

View file

@ -4,12 +4,35 @@ else
GST_LOADSAVE_DIRS = xml typefind
endif
SUBDIRS = $(GST_LOADSAVE_DIRS) \
helloworld \
queue queue2 queue3 queue4 \
launch thread plugins mixer cutter pingpong manual
SUBDIRS = \
helloworld \
queue \
queue2 \
queue3 \
queue4 \
launch \
thread \
plugins \
mixer \
cutter \
pingpong \
manual \
retag \
$(GST_LOADSAVE_DIRS)
DIST_SUBDIRS = helloworld helloworld2 \
queue queue2 queue3 queue4 \
launch thread xml plugins typefind mixer cutter pingpong manual
DIST_SUBDIRS = helloworld \
queue \
queue2 \
queue3 \
queue4 \
launch \
thread \
plugins \
mixer \
cutter \
pingpong \
manual \
xml \
typefind \
retag

View file

@ -14,11 +14,11 @@ GST_DEBUG_DIRS = debug
endif
SUBDIRS = bytestream cleanup dynparams \
caps caps2 plugin elements clock refcounting threads \
caps caps2 plugin elements clock refcounting tags threads \
indexers debug $(GST_PARSE_DIRS) $(GST_DEBUG_DIRS)
DIST_SUBDIRS = bytestream caps caps2 cleanup clock dynparams elements indexers \
plugin refcounting threads parse debug
plugin refcounting tags threads parse debug
tests_pass = test_gst_init
tests_fail =

View file

@ -4,5 +4,5 @@ tests_pass =
tests_fail = test1
test1_SOURCES = test1.c gstbstest.c
test1_LDFLAGS = -lgstbytestream -L$(top_srcdir)/libs/gst/bytestream
test1_LDFLAGS = $(top_builddir)/libs/gst/bytestream/libgstbytestream.la

View file

@ -11,3 +11,5 @@ intersection
normalisation
union
fixed
string-conversions
intersect2

View file

@ -1,8 +1,10 @@
include ../Rules
tests_pass = cleanup1 cleanup2 cleanup4 cleanup5
tests_fail =
#tests_that_work_sometimes = cleanup3
tests_fail =
# cleanup3 fails depending on the machine
tests_ignore = cleanup3
# we have nothing but apps here, we can do this safely
cleanup1_LDADD = $(GST_LIBS)

Some files were not shown because too many files have changed in this diff Show more